blob: 908762c975a35e57399362887a776d0b8752bca3 [file] [log] [blame]
chuangcheng.peng60c48282024-04-12 10:16:35 +08001#ifdef _FORTIFY_SOURCE
2#undef _FORTIFY_SOURCE
3#endif
4/***************************************************************************
5 * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
6 *
7 * This source code is subject to the terms and conditions defined in the
8 * file 'LICENSE' which is part of this source code package.
9 *
10 * Description:
11 */
12/**\file
13 * \brief
14 *
15 * \author Gong Ke <ke.gong@amlogic.com>
16 * \date 2010-05-21: create the document
17 ***************************************************************************/
18
19#define AM_DEBUG_LEVEL 1
20
21//#include <am_debug.h>
22#include "am_mem.h"
23#include "am_dmx_internal.h"
24#include "am_adp_internal.h"
25#include <string.h>
26#include <assert.h>
27#include <unistd.h>
28#include <stdio.h>
29#include <stdlib.h>
30//#include "am_misc.h"
31
32/****************************************************************************
33 * Macro definitions
34 ***************************************************************************/
35
36//#define DMX_WAIT_CB /*Wait callback function stop in API*/
37
38#define DMX_SYNC
39
40#define DMX_BUF_SIZE (4096)
41#define DMX_POLL_TIMEOUT (200)
42#define DMX_DEV_COUNT (32)
43
44#define DMX_CHAN_ISSET_FILTER(chan,fid) ((chan)->filter_mask[(fid)>>3]&(1<<((fid)&3)))
45#define DMX_CHAN_SET_FILTER(chan,fid) ((chan)->filter_mask[(fid)>>3]|=(1<<((fid)&3)))
46#define DMX_CHAN_CLR_FILTER(chan,fid) ((chan)->filter_mask[(fid)>>3]&=~(1<<((fid)&3)))
47
48/****************************************************************************
49 * Static data
50 ***************************************************************************/
51
52#ifdef EMU_DEMUX
53extern const AM_DMX_Driver_t emu_dmx_drv;
54#define HW_DMX_DRV emu_dmx_drv
55#else
56extern const AM_DMX_Driver_t linux_dvb_dmx_drv;
57#define HW_DMX_DRV linux_dvb_dmx_drv
58#endif
59//extern const AM_DMX_Driver_t dvr_dmx_drv;
60//#define SW_DMX_DRV dvr_dmx_drv
61
62static AM_DMX_Device_t dmx_devices[DMX_DEV_COUNT] =
63{
64#ifdef EMU_DEMUX
65{
66.drv = &emu_dmx_drv,
67.src = AM_DMX_SRC_TS0
68},
69{
70.drv = &emu_dmx_drv,
71.src = AM_DMX_SRC_TS0
72}
73#else
74{
75.drv = &linux_dvb_dmx_drv,
76.src = AM_DMX_SRC_TS0
77},
78{
79.drv = &linux_dvb_dmx_drv,
80.src = AM_DMX_SRC_TS0
81},
82{
83.drv = &linux_dvb_dmx_drv,
84.src = AM_DMX_SRC_TS0
85},
86{
87.drv = &linux_dvb_dmx_drv,
88.src = AM_DMX_SRC_TS0
89}
90#endif
91};
92static void init_dmx_dev() {
93 static int init_dmx_dev_flag = 0;
94 int i = 0;
95
96 if (!init_dmx_dev_flag) {
97 init_dmx_dev_flag = 1;
98
99 for (i = 0; i < DMX_DEV_COUNT; i++) {
100 dmx_devices[i].drv = &linux_dvb_dmx_drv;
101 dmx_devices[i].src = AM_DMX_SRC_TS0;
102 }
103 }
104}
105/****************************************************************************
106 * Static functions
107 ***************************************************************************/
108
109/**\brief 根据设备号取得设备结构指针*/
110static AM_INLINE AM_ErrorCode_t dmx_get_dev(int dev_no, AM_DMX_Device_t **dev)
111{
112 if (dev_no < 0 || dev_no >= DMX_DEV_COUNT) {
113 printf("invalid demux device number %d, must in(%d~%d)", dev_no, 0, DMX_DEV_COUNT-1);
114 return AM_DMX_ERR_INVALID_DEV_NO;
115 }
116
117 *dev = &dmx_devices[dev_no];
118 return AM_SUCCESS;
119}
120
121/**\brief 根据设备号取得设备结构并检查设备是否已经打开*/
122static AM_INLINE AM_ErrorCode_t dmx_get_opened_dev(int dev_no, AM_DMX_Device_t **dev)
123{
124 AM_TRY(dmx_get_dev(dev_no, dev));
125
126 if ((*dev)->open_count <= 0) {
127 printf("demux device %d has not been opened", dev_no);
128 return AM_DMX_ERR_INVALID_DEV_NO;
129 }
130
131 return AM_SUCCESS;
132}
133
134/**\brief 根据ID取得对应filter结构,并检查设备是否在使用*/
135static AM_INLINE AM_ErrorCode_t dmx_get_used_filter(AM_DMX_Device_t *dev, int filter_id, AM_DMX_Filter_t **pf)
136{
137 AM_DMX_Filter_t *filter;
138
139 if (filter_id < 0 || filter_id >= DMX_FILTER_COUNT) {
140 printf("invalid filter id, must in %d~%d", 0, DMX_FILTER_COUNT-1);
141 return AM_DMX_ERR_INVALID_ID;
142 }
143
144 filter = &dev->filters[filter_id];
145
146 if (!filter->used)
147 {
148 printf("filter %d has not been allocated", filter_id);
149 return AM_DMX_ERR_NOT_ALLOCATED;
150 }
151
152 *pf = filter;
153 return AM_SUCCESS;
154}
155
156/**\brief 数据检测线程*/
157static void* dmx_data_thread(void *arg)
158{
159 AM_DMX_Device_t *dev = (AM_DMX_Device_t*)arg;
160 uint8_t *sec_buf;
161 uint8_t *sec;
162 int sec_len;
163 AM_DMX_FilterMask_t mask;
164 AM_ErrorCode_t ret;
165
166#define BUF_SIZE (4096)
167
168 sec_buf = (uint8_t*)malloc(BUF_SIZE);
169
170 while (dev->enable_thread) {
171 AM_DMX_FILTER_MASK_CLEAR(&mask);
172 int id;
173
174 ret = dev->drv->poll(dev, &mask, DMX_POLL_TIMEOUT);
175 if (ret == AM_SUCCESS) {
176 if (AM_DMX_FILTER_MASK_ISEMPTY(&mask))
177 continue;
178
179#if defined(DMX_WAIT_CB) || defined(DMX_SYNC)
180 pthread_mutex_lock(&dev->lock);
181 dev->flags |= DMX_FL_RUN_CB;
182 pthread_mutex_unlock(&dev->lock);
183#endif
184
185 for (id = 0; id < DMX_FILTER_COUNT; id++) {
186 AM_DMX_Filter_t *filter = &dev->filters[id];
187 AM_DMX_DataCb cb;
188 void *data;
189
190 if (!AM_DMX_FILTER_MASK_ISSET(&mask, id))
191 continue;
192
193 if (!filter->enable || !filter->used)
194 continue;
195
196 sec_len = BUF_SIZE;
197
198#ifndef DMX_WAIT_CB
199 pthread_mutex_lock(&dev->lock);
200#endif
201 if (!filter->enable || !filter->used) {
202 ret = AM_FAILURE;
203 } else {
204 cb = filter->cb;
205 data = filter->user_data;
206 ret = dev->drv->read(dev, filter, sec_buf, &sec_len);
207 }
208#ifndef DMX_WAIT_CB
209 pthread_mutex_unlock(&dev->lock);
210#endif
211 if (ret == AM_DMX_ERR_TIMEOUT) {
212 sec = NULL;
213 sec_len = 0;
214 } else if (ret != AM_SUCCESS) {
215 continue;
216 } else {
217 sec = sec_buf;
218 }
219
220 if (cb) {
221 if (id && sec)
222 printf("filter %d data callback len fd:%ld len:%d, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
223 id, (long)filter->drv_data, sec_len,
224 sec[0], sec[1], sec[2], sec[3], sec[4],
225 sec[5], sec[6], sec[7], sec[8], sec[9]);
226 cb(dev->dev_no, id, sec, sec_len, data);
227 if (id && sec)
228 printf("filter %d data callback ok", id);
229 }
230 }
231#if defined(DMX_WAIT_CB) || defined(DMX_SYNC)
232 pthread_mutex_lock(&dev->lock);
233 dev->flags &= ~DMX_FL_RUN_CB;
234 pthread_mutex_unlock(&dev->lock);
235 pthread_cond_broadcast(&dev->cond);
236#endif
237 } else {
238 usleep(10000);
239 }
240 }
241
242 if (sec_buf) {
243 free(sec_buf);
244 }
245
246 return NULL;
247}
248
249/**\brief 等待回调函数停止运行*/
250static AM_INLINE AM_ErrorCode_t dmx_wait_cb(AM_DMX_Device_t *dev)
251{
252#ifdef DMX_WAIT_CB
253 if (dev->thread != pthread_self()) {
254 while (dev->flags & DMX_FL_RUN_CB)
255 pthread_cond_wait(&dev->cond, &dev->lock);
256 }
257#else
258 UNUSED(dev);
259#endif
260 return AM_SUCCESS;
261}
262
263/**\brief 停止Section过滤器*/
264static AM_ErrorCode_t dmx_stop_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
265{
266 AM_ErrorCode_t ret = AM_SUCCESS;
267
268 if (!filter->used || !filter->enable) {
269 return ret;
270 }
271
272 if (dev->drv->enable_filter) {
273 ret = dev->drv->enable_filter(dev, filter, AM_FALSE);
274 }
275
276 if (ret >= 0) {
277 filter->enable = AM_FALSE;
278 }
279
280 return ret;
281}
282
283/**\brief 释放过滤器*/
284static int dmx_free_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
285{
286 AM_ErrorCode_t ret = AM_SUCCESS;
287
288 if (!filter->used)
289 return ret;
290
291 ret = dmx_stop_filter(dev, filter);
292
293 if (ret == AM_SUCCESS) {
294 if (dev->drv->free_filter) {
295 ret = dev->drv->free_filter(dev, filter);
296 }
297 }
298
299 if (ret == AM_SUCCESS) {
300 filter->used = AM_FALSE;
301 }
302
303 return ret;
304}
305
306/****************************************************************************
307 * API functions
308 ***************************************************************************/
309
310/**\brief 打开解复用设备
311 * \param dev_no 解复用设备号
312 * \param[in] para 解复用设备开启参数
313 * \return
314 * - AM_SUCCESS 成功
315 * - 其他值 错误代码(见am_dmx.h)
316 */
317AM_ErrorCode_t AM_DMX_Open(int dev_no, const AM_DMX_OpenPara_t *para)
318{
319 AM_DMX_Device_t *dev;
320 AM_ErrorCode_t ret = AM_SUCCESS;
321
322 assert(para);
323
324 init_dmx_dev();
325
326 AM_TRY(dmx_get_dev(dev_no, &dev));
327
328// pthread_mutex_lock(&am_gAdpLock);
329
330 if (dev->open_count > 0) {
331 printf("demux device %d has already been opened", dev_no);
332 dev->open_count++;
333 ret = AM_SUCCESS;
334 goto final;
335 }
336
337 dev->dev_no = dev_no;
338
339 if (para->use_sw_filter) {
340 // dev->drv = &SW_DMX_DRV;
341 } else {
342 dev->drv = &HW_DMX_DRV;
343 }
344
345 if (dev->drv->open) {
346 ret = dev->drv->open(dev, para);
347 }
348
349 if (ret == AM_SUCCESS) {
350 pthread_mutex_init(&dev->lock, NULL);
351 pthread_cond_init(&dev->cond, NULL);
352 dev->enable_thread = AM_TRUE;
353 dev->flags = 0;
354
355 if (pthread_create(&dev->thread, NULL, dmx_data_thread, dev)) {
356 pthread_mutex_destroy(&dev->lock);
357 pthread_cond_destroy(&dev->cond);
358 ret = AM_DMX_ERR_CANNOT_CREATE_THREAD;
359 }
360 }
361
362 if (ret == AM_SUCCESS) {
363 dev->open_count = 1;
364 }
365final:
366// pthread_mutex_unlock(&am_gAdpLock);
367
368 return ret;
369}
370
371/**\brief 关闭解复用设备
372 * \param dev_no 解复用设备号
373 * \return
374 * - AM_SUCCESS 成功
375 * - 其他值 错误代码(见am_dmx.h)
376 */
377AM_ErrorCode_t AM_DMX_Close(int dev_no)
378{
379 AM_DMX_Device_t *dev;
380 AM_ErrorCode_t ret = AM_SUCCESS;
381 int i;
382
383 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
384
385// pthread_mutex_lock(&am_gAdpLock);
386
387 if (dev->open_count == 1) {
388 dev->enable_thread = AM_FALSE;
389 pthread_join(dev->thread, NULL);
390
391 for (i = 0; i < DMX_FILTER_COUNT; i++) {
392 dmx_free_filter(dev, &dev->filters[i]);
393 }
394
395 if (dev->drv->close) {
396 dev->drv->close(dev);
397 }
398
399 pthread_mutex_destroy(&dev->lock);
400 pthread_cond_destroy(&dev->cond);
401 }
402 dev->open_count--;
403
404 // pthread_mutex_unlock(&am_gAdpLock);
405
406 return ret;
407}
408
409/**\brief 分配一个过滤器
410 * \param dev_no 解复用设备号
411 * \param[out] fhandle 返回过滤器句柄
412 * \return
413 * - AM_SUCCESS 成功
414 * - 其他值 错误代码(见am_dmx.h)
415 */
416AM_ErrorCode_t AM_DMX_AllocateFilter(int dev_no, int *fhandle)
417{
418 AM_DMX_Device_t *dev;
419 AM_ErrorCode_t ret = AM_SUCCESS;
420 int fid;
421
422 assert(fhandle);
423
424 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
425
426 pthread_mutex_lock(&dev->lock);
427
428 for (fid = 0; fid < DMX_FILTER_COUNT; fid++) {
429 if (!dev->filters[fid].used)
430 break;
431 }
432
433 if (fid >= DMX_FILTER_COUNT) {
434 printf("no free section filter");
435 ret = AM_DMX_ERR_NO_FREE_FILTER;
436 }
437
438 if (ret == AM_SUCCESS) {
439 dmx_wait_cb(dev);
440
441 dev->filters[fid].id = fid;
442 if (dev->drv->alloc_filter) {
443 ret = dev->drv->alloc_filter(dev, &dev->filters[fid]);
444 }
445 }
446
447 if (ret == AM_SUCCESS) {
448 dev->filters[fid].used = AM_TRUE;
449 *fhandle = fid;
450 }
451
452 pthread_mutex_unlock(&dev->lock);
453
454 return ret;
455}
456
457/**\brief 设定Section过滤器
458 * \param dev_no 解复用设备号
459 * \param fhandle 过滤器句柄
460 * \param[in] params Section过滤器参数
461 * \return
462 * - AM_SUCCESS 成功
463 * - 其他值 错误代码(见am_dmx.h)
464 */
465AM_ErrorCode_t AM_DMX_SetSecFilter(int dev_no, int fhandle, const struct dmx_sct_filter_params *params)
466{
467 AM_DMX_Device_t *dev;
468 AM_DMX_Filter_t *filter;
469 AM_ErrorCode_t ret = AM_SUCCESS;
470
471 assert(params);
472
473 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
474
475 if (!dev->drv->set_sec_filter) {
476 printf("demux do not support set_sec_filter");
477 return AM_DMX_ERR_NOT_SUPPORTED;
478 }
479
480 pthread_mutex_lock(&dev->lock);
481
482 ret = dmx_get_used_filter(dev, fhandle, &filter);
483
484 if (ret == AM_SUCCESS) {
485 dmx_wait_cb(dev);
486 ret = dmx_stop_filter(dev, filter);
487 }
488
489 if (ret == AM_SUCCESS) {
490 ret = dev->drv->set_sec_filter(dev, filter, params);
491 printf("set sec filter %d PID: %d filter: %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x",
492 fhandle, params->pid,
493 params->filter.filter[0], params->filter.mask[0],
494 params->filter.filter[1], params->filter.mask[1],
495 params->filter.filter[2], params->filter.mask[2],
496 params->filter.filter[3], params->filter.mask[3],
497 params->filter.filter[4], params->filter.mask[4],
498 params->filter.filter[5], params->filter.mask[5],
499 params->filter.filter[6], params->filter.mask[6],
500 params->filter.filter[7], params->filter.mask[7]);
501 }
502
503 pthread_mutex_unlock(&dev->lock);
504
505 return ret;
506}
507
508/**\brief 设定PES过滤器
509 * \param dev_no 解复用设备号
510 * \param fhandle 过滤器句柄
511 * \param[in] params PES过滤器参数
512 * \return
513 * - AM_SUCCESS 成功
514 * - 其他值 错误代码(见am_dmx.h)
515 */
516AM_ErrorCode_t AM_DMX_SetPesFilter(int dev_no, int fhandle, const struct dmx_pes_filter_params *params)
517{
518 AM_DMX_Device_t *dev;
519 AM_DMX_Filter_t *filter;
520 AM_ErrorCode_t ret = AM_SUCCESS;
521
522 assert(params);
523
524 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
525
526 if (!dev->drv->set_pes_filter) {
527 printf("demux do not support set_pes_filter");
528 return AM_DMX_ERR_NOT_SUPPORTED;
529 }
530
531 pthread_mutex_lock(&dev->lock);
532
533 ret = dmx_get_used_filter(dev, fhandle, &filter);
534
535 if (ret == AM_SUCCESS) {
536 dmx_wait_cb(dev);
537 ret = dmx_stop_filter(dev, filter);
538 }
539
540 if (ret == AM_SUCCESS) {
541 ret = dev->drv->set_pes_filter(dev, filter, params);
542 printf("set pes filter %d PID %d", fhandle, params->pid);
543 }
544
545 pthread_mutex_unlock(&dev->lock);
546
547 return ret;
548}
549AM_ErrorCode_t AM_DMX_GetSTC(int dev_no, int fhandle)
550{
551 AM_DMX_Device_t *dev;
552 AM_DMX_Filter_t *filter;
553 AM_ErrorCode_t ret = AM_SUCCESS;
554
555 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
556 printf("%s line:%d\n", __FUNCTION__, __LINE__);
557 if (!dev->drv->get_stc) {
558 printf("demux do not support set_pes_filter");
559 return AM_DMX_ERR_NOT_SUPPORTED;
560 }
561
562 pthread_mutex_lock(&dev->lock);
563
564 ret = dmx_get_used_filter(dev, fhandle, &filter);
565
566 if (ret == AM_SUCCESS) {
567 ret = dev->drv->get_stc(dev, filter);
568 }
569
570 pthread_mutex_unlock(&dev->lock);
571 printf("%s line:%d\n", __FUNCTION__, __LINE__);
572
573 return ret;
574}
575
576
577/**\brief 释放一个过滤器
578 * \param dev_no 解复用设备号
579 * \param fhandle 过滤器句柄
580 * \return
581 * - AM_SUCCESS 成功
582 * - 其他值 错误代码(见am_dmx.h)
583 */
584AM_ErrorCode_t AM_DMX_FreeFilter(int dev_no, int fhandle)
585{
586 AM_DMX_Device_t *dev;
587 AM_DMX_Filter_t *filter;
588 AM_ErrorCode_t ret = AM_SUCCESS;
589
590 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
591
592 pthread_mutex_lock(&dev->lock);
593
594 ret = dmx_get_used_filter(dev, fhandle, &filter);
595
596 if (ret == AM_SUCCESS) {
597 dmx_wait_cb(dev);
598 ret = dmx_free_filter(dev, filter);
599 }
600
601 pthread_mutex_unlock(&dev->lock);
602
603 return ret;
604}
605
606/**\brief 让一个过滤器开始运行
607 * \param dev_no 解复用设备号
608 * \param fhandle 过滤器句柄
609 * \return
610 * - AM_SUCCESS 成功
611 * - 其他值 错误代码(见am_dmx.h)
612 */
613AM_ErrorCode_t AM_DMX_StartFilter(int dev_no, int fhandle)
614{
615 AM_DMX_Device_t *dev;
616 AM_DMX_Filter_t *filter = NULL;
617 AM_ErrorCode_t ret = AM_SUCCESS;
618
619 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
620
621 pthread_mutex_lock(&dev->lock);
622
623 ret = dmx_get_used_filter(dev, fhandle, &filter);
624
625 if (!filter->enable) {
626 if (ret == AM_SUCCESS) {
627 if (dev->drv->enable_filter) {
628 ret = dev->drv->enable_filter(dev, filter, AM_TRUE);
629 }
630 }
631
632 if (ret == AM_SUCCESS) {
633 filter->enable = AM_TRUE;
634 }
635 }
636
637 pthread_mutex_unlock(&dev->lock);
638
639 return ret;
640}
641
642/**\brief 停止一个过滤器
643 * \param dev_no 解复用设备号
644 * \param fhandle 过滤器句柄
645 * \return
646 * - AM_SUCCESS 成功
647 * - 其他值 错误代码(见am_dmx.h)
648 */
649AM_ErrorCode_t AM_DMX_StopFilter(int dev_no, int fhandle)
650{
651 AM_DMX_Device_t *dev;
652 AM_DMX_Filter_t *filter = NULL;
653 AM_ErrorCode_t ret = AM_SUCCESS;
654
655 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
656
657 pthread_mutex_lock(&dev->lock);
658
659 ret = dmx_get_used_filter(dev, fhandle, &filter);
660
661 if (ret == AM_SUCCESS) {
662 if (filter->enable) {
663 dmx_wait_cb(dev);
664 ret = dmx_stop_filter(dev, filter);
665 }
666 }
667
668 pthread_mutex_unlock(&dev->lock);
669
670 return ret;
671}
672
673/**\brief 设置一个过滤器的缓冲区大小
674 * \param dev_no 解复用设备号
675 * \param fhandle 过滤器句柄
676 * \param size 缓冲区大小
677 * \return
678 * - AM_SUCCESS 成功
679 * - 其他值 错误代码(见am_dmx.h)
680 */
681AM_ErrorCode_t AM_DMX_SetBufferSize(int dev_no, int fhandle, int size)
682{
683 AM_DMX_Device_t *dev;
684 AM_DMX_Filter_t *filter;
685 AM_ErrorCode_t ret = AM_SUCCESS;
686
687 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
688
689 pthread_mutex_lock(&dev->lock);
690
691 if (!dev->drv->set_buf_size) {
692 printf("do not support set_buf_size");
693 ret = AM_DMX_ERR_NOT_SUPPORTED;
694 }
695
696 if (ret == AM_SUCCESS)
697 ret = dmx_get_used_filter(dev, fhandle, &filter);
698
699 if (ret == AM_SUCCESS)
700 ret = dev->drv->set_buf_size(dev, filter, size);
701
702 pthread_mutex_unlock(&dev->lock);
703
704 return ret;
705}
706
707/**\brief 取得一个过滤器对应的回调函数和用户参数
708 * \param dev_no 解复用设备号
709 * \param fhandle 过滤器句柄
710 * \param[out] cb 返回过滤器对应的回调函数
711 * \param[out] data 返回用户参数
712 * \return
713 * - AM_SUCCESS 成功
714 * - 其他值 错误代码(见am_dmx.h)
715 */
716AM_ErrorCode_t AM_DMX_GetCallback(int dev_no, int fhandle, AM_DMX_DataCb *cb, void **data)
717{
718 AM_DMX_Device_t *dev;
719 AM_DMX_Filter_t *filter;
720 AM_ErrorCode_t ret = AM_SUCCESS;
721
722 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
723
724 pthread_mutex_lock(&dev->lock);
725
726 ret = dmx_get_used_filter(dev, fhandle, &filter);
727
728 if (ret == AM_SUCCESS) {
729 if (cb)
730 *cb = filter->cb;
731
732 if (data)
733 *data = filter->user_data;
734 }
735
736 pthread_mutex_unlock(&dev->lock);
737
738 return ret;
739}
740
741/**\brief 设置一个过滤器对应的回调函数和用户参数
742 * \param dev_no 解复用设备号
743 * \param fhandle 过滤器句柄
744 * \param[in] cb 回调函数
745 * \param[in] data 回调函数的用户参数
746 * \return
747 * - AM_SUCCESS 成功
748 * - 其他值 错误代码(见am_dmx.h)
749 */
750AM_ErrorCode_t AM_DMX_SetCallback(int dev_no, int fhandle, AM_DMX_DataCb cb, void *data)
751{
752 AM_DMX_Device_t *dev;
753 AM_DMX_Filter_t *filter;
754 AM_ErrorCode_t ret = AM_SUCCESS;
755
756 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
757
758 pthread_mutex_lock(&dev->lock);
759
760 ret = dmx_get_used_filter(dev, fhandle, &filter);
761
762 if (ret == AM_SUCCESS) {
763 dmx_wait_cb(dev);
764
765 filter->cb = cb;
766 filter->user_data = data;
767 }
768
769 pthread_mutex_unlock(&dev->lock);
770
771 return ret;
772}
773
774/**\brief 设置解复用设备的输入源
775 * \param dev_no 解复用设备号
776 * \param src 输入源
777 * \return
778 * - AM_SUCCESS 成功
779 * - 其他值 错误代码(见am_dmx.h)
780 */
781AM_ErrorCode_t AM_DMX_SetSource(int dev_no, AM_DMX_Source_t src)
782{
783 AM_DMX_Device_t *dev;
784 AM_ErrorCode_t ret = AM_SUCCESS;
785
786 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
787
788 pthread_mutex_lock(&dev->lock);
789 if (!dev->drv->set_source) {
790 printf("do not support set_source");
791 ret = AM_DMX_ERR_NOT_SUPPORTED;
792 }
793
794 if (ret == AM_SUCCESS) {
795 ret = dev->drv->set_source(dev, src);
796 }
797
798 pthread_mutex_unlock(&dev->lock);
799
800 if (ret == AM_SUCCESS) {
801 // pthread_mutex_lock(&am_gAdpLock);
802 dev->src = src;
803 // pthread_mutex_unlock(&am_gAdpLock);
804 }
805
806 return ret;
807}
808
809/**\brief DMX同步,可用于等待回调函数执行完毕
810 * \param dev_no 解复用设备号
811 * \return
812 * - AM_SUCCESS 成功
813 * - 其他值 错误代码(见am_dmx.h)
814 */
815AM_ErrorCode_t AM_DMX_Sync(int dev_no)
816{
817 AM_DMX_Device_t *dev;
818 AM_ErrorCode_t ret = AM_SUCCESS;
819
820 AM_TRY(dmx_get_opened_dev(dev_no, &dev));
821
822 pthread_mutex_lock(&dev->lock);
823 if (dev->thread != pthread_self()) {
824 while (dev->flags & DMX_FL_RUN_CB)
825 pthread_cond_wait(&dev->cond, &dev->lock);
826 }
827 pthread_mutex_unlock(&dev->lock);
828
829 return ret;
830}
831
832AM_ErrorCode_t AM_DMX_GetScrambleStatus(int dev_no, AM_Bool_t dev_status[2])
833{
834#if 0
835 char buf[32];
836 char class_file[64];
837 int vflag, aflag;
838 int i;
839
840 dev_status[0] = dev_status[1] = AM_FALSE;
841 snprintf(class_file, sizeof(class_file), "/sys/class/dmx/demux%d_scramble", dev_no);
842 for (i = 0; i < 5; i++) {
843 if (AM_FileRead(class_file, buf, sizeof(buf)) == AM_SUCCESS) {
844 sscanf(buf, "%d %d", &vflag, &aflag);
845 if (!dev_status[0])
846 dev_status[0] = vflag ? AM_TRUE : AM_FALSE;
847 if (!dev_status[1])
848 dev_status[1] = aflag ? AM_TRUE : AM_FALSE;
849 // AM_DEBUG(1, "AM_DMX_GetScrambleStatus video scramble %d, audio scramble %d\n", vflag, aflag);
850 if (dev_status[0] && dev_status[1]) {
851 return AM_SUCCESS;
852 }
853 usleep(10 * 1000);
854 } else {
855 printf("AM_DMX_GetScrambleStatus read scramble status failed\n");
856 return AM_FAILURE;
857 }
858 }
859#endif
860 return AM_SUCCESS;
861}
862
863