blob: 87652720e5a2bcae022d734f2775b7f65136c03c [file] [log] [blame]
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +08001/***************************************************************************
2 * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 *
9 * @brief linux dvb demux wrapper
10 * @file dvb_dmx_wrapper.c
11 *
12 * \author Chuanzhi Wang <chuanzhi.wang@amlogic.com>
13 * \date 2020-07-16: create the document
14 ***************************************************************************/
15
16#include <sys/types.h>
17#include <sys/ioctl.h>
18#include <sys/prctl.h>
19
20#include <poll.h>
21#include <fcntl.h>
22#include <errno.h>
23#include <pthread.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27
28#include "dmx.h"
29#include "dvb_dmx_wrapper.h"
30
31#define DMX_COUNT (3)
32#define DMX_FILTER_COUNT (32*DMX_COUNT)
33#define SEC_BUF_SIZE (4096)
34#define DMX_POLL_TIMEOUT (200)
35
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +080036
37typedef struct
38{
39 int dev_no;
40 int fd;
41 int used;
42 int enable;
43 int need_free;
44 AML_DMX_DataCb cb;
45 void *user_data;
46}dvb_dmx_filter_t;
47
48typedef struct
49{
50 int dev_no;
51 int running;
52 pthread_t thread;
53 pthread_mutex_t lock;
54
55 dvb_dmx_filter_t filter[DMX_FILTER_COUNT];
56}dvb_dmx_t;
57
58static dvb_dmx_t dmx_devices[DMX_COUNT];
59
Chuanzhi Wang742ba112020-09-15 11:43:55 +080060static inline DVB_RESULT dmx_get_dev(int dev_no, dvb_dmx_t **dev)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +080061{
hualing chen002e5b92022-02-23 17:51:21 +080062 if ((dev_no < 0) || (dev_no >= DMX_COUNT))
63 {
64 DVB_DEBUG(1, "invalid demux device number %d, must in(%d~%d)", dev_no, 0, DMX_COUNT-1);
65 return DVB_FAILURE;
66 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +080067
hualing chen002e5b92022-02-23 17:51:21 +080068 *dev = &dmx_devices[dev_no];
69 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +080070}
71
72static void* dmx_data_thread(void *arg)
73{
74 int i, fid;
75 int ret;
76 int cnt, len;
77 uint32_t mask;
78 uint8_t *sec_buf = NULL;
79 int fids[DMX_FILTER_COUNT];
80 struct pollfd fds[DMX_FILTER_COUNT];
81 dvb_dmx_filter_t *filter = NULL;
82 dvb_dmx_t *dmx = (dvb_dmx_t *)arg;
83
84 sec_buf = (uint8_t *)malloc(SEC_BUF_SIZE);
85 prctl(PR_SET_NAME, "dmx_data_thread");
86 while (dmx->running)
87 {
88 cnt = 0;
89 mask = 0;
90
91 pthread_mutex_lock(&dmx->lock);
92 for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
93 {
94 if (dmx->filter[fid].need_free)
95 {
96 filter = &dmx->filter[fid];
97 close(filter->fd);
98 filter->used = 0;
99 filter->need_free = 0;
100 filter->cb = NULL;
101 }
102
103 if (dmx->filter[fid].used)
104 {
105 fds[cnt].events = POLLIN | POLLERR;
106 fds[cnt].fd = dmx->filter[fid].fd;
107 fids[cnt] = fid;
108 cnt++;
109 }
110 }
111
hualing chen002e5b92022-02-23 17:51:21 +0800112 pthread_mutex_unlock(&dmx->lock);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800113
hualing chen002e5b92022-02-23 17:51:21 +0800114 if (!cnt)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800115 {
116 usleep(20*1000);
hualing chen002e5b92022-02-23 17:51:21 +0800117 continue;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800118 }
119
hualing chen002e5b92022-02-23 17:51:21 +0800120 ret = poll(fds, cnt, DMX_POLL_TIMEOUT);
121 if (ret <= 0)
122 {
123 continue;
124 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800125
hualing chen002e5b92022-02-23 17:51:21 +0800126 for (i = 0; i < cnt; i++)
127 {
128 if (fds[i].revents & (POLLIN | POLLERR))
129 {
130 pthread_mutex_lock(&dmx->lock);
131 filter = &dmx->filter[fids[i]];
132 if (!filter->enable || !filter->used || filter->need_free)
133 {
134 DVB_DEBUG(1, "ch[%d] not used, not read", fids[i]);
135 len = 0;
136 }
137 else
138 {
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800139 len = read(filter->fd, sec_buf, SEC_BUF_SIZE);
140 if (len <= 0)
141 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800142 DVB_DEBUG(1, "read demux filter[%d] failed (%s) %d", fids[i], strerror(errno), errno);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800143 }
hualing chen002e5b92022-02-23 17:51:21 +0800144 }
145 pthread_mutex_unlock(&dmx->lock);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800146#ifdef DEBUG_DEMUX_DATA
hualing chen002e5b92022-02-23 17:51:21 +0800147 if (len)
148 DVB_DEBUG(1, "tid[%#x] ch[%d] %#x bytes", sec_buf[0], fids[i], len);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800149#endif
hualing chen002e5b92022-02-23 17:51:21 +0800150 if (len > 0 && filter->cb)
151 {
152 filter->cb(filter->dev_no, fids[i], sec_buf, len, filter->user_data);
153 }
154 }
155 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800156 }
157
158 if (sec_buf)
159 {
hualing chen002e5b92022-02-23 17:51:21 +0800160 free(sec_buf);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800161 }
162
163 return NULL;
164}
165
166static dvb_dmx_filter_t* dmx_get_filter(dvb_dmx_t * dev, int fhandle)
167{
168 if (fhandle >= DMX_FILTER_COUNT)
169 {
hualing chen002e5b92022-02-23 17:51:21 +0800170 DVB_DEBUG(1, "wrong filter no");
171 return NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800172 }
173
174 if (!dev->filter[fhandle].used)
175 {
hualing chen002e5b92022-02-23 17:51:21 +0800176 DVB_DEBUG(1, "filter %d not allocated", fhandle);
177 return NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800178 }
179 return &dev->filter[fhandle];
180}
181
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800182/**\brief dmx device init, creat dmx thread
183 * \param dmx device number
184 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
185 */
186DVB_RESULT AML_DMX_Open(int dev_no)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800187{
188 dvb_dmx_t *dev = NULL;
189
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800190 if (dmx_get_dev(dev_no, &dev))
191 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800192
193 if (dev->running)
194 {
hualing chen002e5b92022-02-23 17:51:21 +0800195 DVB_DEBUG(1, "dmx already initialized");
196 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800197 }
198
hualing chen002e5b92022-02-23 17:51:21 +0800199 dev->dev_no = dev_no;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800200
201 pthread_mutex_init(&dev->lock, NULL);
202 dev->running = 1;
203 pthread_create(&dev->thread, NULL, dmx_data_thread, dev);
204
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800205 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800206}
207
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800208/**\brief allocate dmx filter
209 * \param dmx device number
210 * \param get dmx filter index
211 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
212 */
213DVB_RESULT AML_DMX_AllocateFilter(int dev_no, int *fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800214{
215 int fd;
216 int fid;
217 dvb_dmx_filter_t *filter = NULL;
218 char dev_name[32];
219
220 dvb_dmx_t *dev = NULL;
221
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800222 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800223 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800224 DVB_DEBUG(1, "demux allocate failed, wrong dmx device no %d", dev_no);
225 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800226 }
227
228 pthread_mutex_lock(&dev->lock);
229 filter = &dev->filter[0];
230 for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
231 {
hualing chen002e5b92022-02-23 17:51:21 +0800232 if (!filter[fid].used)
233 {
234 break;
235 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800236 }
237
238 if (fid >= DMX_FILTER_COUNT)
239 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800240 DVB_DEBUG(1, "filter id:%d, have no filter to alloc", fid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800241 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800242 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800243 }
244
245 memset(dev_name, 0, sizeof(dev_name));
246 sprintf(dev_name, "/dev/dvb0.demux%d", dev_no);
247 fd = open(dev_name, O_RDWR);
248 if (fd == -1)
249 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800250 DVB_DEBUG(1, "cannot open \"%s\" (%s)", dev_name, strerror(errno));
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800251 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800252 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800253 }
254
255 memset(&filter[fid], 0, sizeof(dvb_dmx_filter_t));
256 filter[fid].dev_no = dev_no;
257 filter[fid].fd = fd;
258 filter[fid].used = 1;
259 *fhandle = fid;
260
261 pthread_mutex_unlock(&dev->lock);
262
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800263 //DVB_DEBUG(1, "fhandle = %d", fid);
264 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800265}
266
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800267/**\brief set demux section filter
268 * \param dmx device number
269 * \param dmx filter index
270 * \param dmx section filter param
271 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
272 */
273DVB_RESULT AML_DMX_SetSecFilter(int dev_no, int fhandle, const struct dmx_sct_filter_params *params)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800274{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800275 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800276 dvb_dmx_t *dev = NULL;
277 dvb_dmx_filter_t *filter = NULL;
278
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800279 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800280 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800281 DVB_DEBUG(1, "Wrong dmx device no %d", dev_no);
282 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800283 }
284
285 if (!params)
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800286 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800287
288 pthread_mutex_lock(&dev->lock);
289
290 filter = dmx_get_filter(dev, fhandle);
291 if (filter)
292 {
hualing chen002e5b92022-02-23 17:51:21 +0800293 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
294 {
295 DVB_DEBUG(1, "dmx stop filter failed error:%s", strerror(errno));
296 ret = DVB_FAILURE;
297 }
298 else if (ioctl(filter->fd, DMX_SET_FILTER, params) < 0)
299 {
300 DVB_DEBUG(1, "set filter failed error:%s", strerror(errno));
301 ret = DVB_FAILURE;
302 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800303 }
304
305 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800306 //DVB_DEBUG(1, "pid = %#x", params->pid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800307 return ret;
308}
309
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800310/**\brief set demux pes filter
311 * \param dmx device number
312 * \param dmx filter index
313 * \param dmx pes filter param
314 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
315 */
316DVB_RESULT AML_DMX_SetPesFilter(int dev_no, int fhandle, const struct dmx_pes_filter_params *params)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800317{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800318 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800319 dvb_dmx_t *dev = NULL;
320 dvb_dmx_filter_t *filter = NULL;
321
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800322 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800323 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800324 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
325 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800326 }
327
328 if (!params)
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800329 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800330
331 pthread_mutex_lock(&dev->lock);
332
333 filter = dmx_get_filter(dev, fhandle);
334 if (filter)
335 {
hualing chen002e5b92022-02-23 17:51:21 +0800336 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
337 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800338 DVB_DEBUG(1, "dmx stop filter failed error:%s", strerror(errno));
339 ret = DVB_FAILURE;
hualing chen002e5b92022-02-23 17:51:21 +0800340 }
341 else
342 {
343 fcntl(filter->fd, F_SETFL, O_NONBLOCK);
344 if (ioctl(filter->fd, DMX_SET_PES_FILTER, params) < 0)
345 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800346 DVB_DEBUG(1, "set filter failed error:%s", strerror(errno));
347 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800348 }
hualing chen002e5b92022-02-23 17:51:21 +0800349 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800350 }
351
352 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800353 //DVB_DEBUG(1, "pid = %#x", params->pid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800354 return ret;
355}
356
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800357/**\brief set demux filter buffer
358 * \param dmx device number
359 * \param dmx filter index
360 * \param dmx filter buffer size
361 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
362 */
363DVB_RESULT AML_DMX_SetBufferSize(int dev_no, int fhandle, int size)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800364{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800365 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800366 dvb_dmx_t *dev = NULL;
367 dvb_dmx_filter_t *filter = NULL;
368
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800369 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800370 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800371 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
372 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800373 }
374
375 pthread_mutex_lock(&dev->lock);
376
377 filter = dmx_get_filter(dev, fhandle);
378 if (filter)
379 {
hualing chen002e5b92022-02-23 17:51:21 +0800380 if (ioctl(filter->fd, DMX_SET_BUFFER_SIZE, size) < 0)
381 {
382 DVB_DEBUG(1, "set buf size failed error:%s", strerror(errno));
383 ret = DVB_FAILURE;
384 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800385 }
386
387 pthread_mutex_unlock(&dev->lock);
388 return ret;
389}
390
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800391/**\brief free demux filter
392 * \param dmx device number
393 * \param dmx filter index
394 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
395 */
396DVB_RESULT AML_DMX_FreeFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800397{
398 dvb_dmx_t *dev = NULL;
399 dvb_dmx_filter_t *filter = NULL;
400
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800401 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800402 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800403 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
404 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800405 }
406
407 pthread_mutex_lock(&dev->lock);
408
409 filter = dmx_get_filter(dev, fhandle);
410 if (filter)
411 {
hualing chen002e5b92022-02-23 17:51:21 +0800412 filter->need_free = 1;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800413 }
414
415 pthread_mutex_unlock(&dev->lock);
416
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800417 //DVB_DEBUG(1, "fhandle = %d", fhandle);
418 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800419}
420
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800421/**\brief start demux filter
422 * \param dmx device number
423 * \param dmx filter index
424 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
425 */
426DVB_RESULT AML_DMX_StartFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800427{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800428 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800429 dvb_dmx_t *dev = NULL;
430 dvb_dmx_filter_t *filter = NULL;
431
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800432 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800433 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800434 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
435 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800436 }
437
438 pthread_mutex_lock(&dev->lock);
439
440 filter = dmx_get_filter(dev, fhandle);
441 if (filter && !filter->enable)
442 {
443 if (ioctl(filter->fd, DMX_START, 0) < 0)
444 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800445 DVB_DEBUG(1, "dmx start filter failed error:%s", strerror(errno));
446 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800447 }
448 else
449 {
450 filter->enable = 1;
451 }
452 }
453
454 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800455 //DVB_DEBUG(1, "ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800456 return ret;
457}
458
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800459/**\brief stop demux filter
460 * \param dmx device number
461 * \param dmx filter index
462 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
463 */
464DVB_RESULT AML_DMX_StopFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800465{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800466 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800467 dvb_dmx_t *dev = NULL;
468 dvb_dmx_filter_t *filter = NULL;
469
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800470 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800471 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800472 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
473 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800474 }
475
476 pthread_mutex_lock(&dev->lock);
477
478 filter = dmx_get_filter(dev, fhandle);
479 if (filter && filter->enable)
480 {
481 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
482 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800483 DVB_DEBUG(1, "dmx stop filter failed error:%s", strerror(errno));
484 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800485 }
486 else
487 {
488 filter->enable = 0;
489 }
490 }
491
492 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800493 //DVB_DEBUG(1, "ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800494 return ret;
495}
496
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800497/**\brief set demux callback
498 * \param dmx device number
499 * \param dmx filter index
500 * \param dmx filter callback
501 * \param dmx filter callback param
502 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
503 */
504DVB_RESULT AML_DMX_SetCallback(int dev_no, int fhandle, AML_DMX_DataCb cb, void *user_data)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800505{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800506 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800507 dvb_dmx_t *dev = NULL;
508 dvb_dmx_filter_t *filter = NULL;
509
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800510 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800511 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800512 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
513 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800514 }
515
516 pthread_mutex_lock(&dev->lock);
517 filter = dmx_get_filter(dev, fhandle);
518 if (filter)
519 {
520 filter->cb = cb;
521 filter->user_data = user_data;
522 }
523 else
524 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800525 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800526 }
527
528 pthread_mutex_unlock(&dev->lock);
529
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800530 //DVB_DEBUG(1, "ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800531 return ret;
532}
533
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800534/**\brief dmx device uninit, destroy dmx thread
535 * \param dmx device number
536 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
537 */
538DVB_RESULT AML_DMX_Close(int dev_no)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800539{
540 int i;
541 int open_count = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800542 dvb_dmx_t *dev = NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800543 dvb_dmx_filter_t *filter = NULL;
544
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800545 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800546 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800547 DVB_DEBUG(1, "wrong dmx device no %d", dev_no);
548 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800549 }
550
551 pthread_mutex_lock(&dev->lock);
552
553 for (i = 0; i < DMX_FILTER_COUNT; i++)
554 {
hualing chen002e5b92022-02-23 17:51:21 +0800555 filter = &dev->filter[i];
556 if (filter->used && filter->dev_no == dev_no)
557 {
558 if (filter->enable)
559 {
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800560 ioctl(filter->fd, DMX_STOP, 0);
hualing chen002e5b92022-02-23 17:51:21 +0800561 }
562 close(filter->fd);
563 }
564 else if (filter->used)
565 {
566 open_count++;
567 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800568 }
569
570 if (open_count == 0)
571 {
572 dev->running = 0;
573 pthread_join(dev->thread, NULL);
574 pthread_mutex_destroy(&dev->lock);
575 }
576
577 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800578 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800579}