blob: 0398f16728a037e57ec0b9382255b75ebf148b5a [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 {
Wentao MA96f68962022-06-15 19:45:35 +080064 DVB_INFO("invalid demux device number %d, must in(%d~%d)", dev_no, 0, DMX_COUNT-1);
hualing chen002e5b92022-02-23 17:51:21 +080065 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800134 DVB_INFO("ch[%d] not used, not read", fids[i]);
hualing chen002e5b92022-02-23 17:51:21 +0800135 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800142 DVB_INFO("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)
Wentao MA96f68962022-06-15 19:45:35 +0800148 DVB_INFO("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 {
Wentao MA96f68962022-06-15 19:45:35 +0800170 DVB_INFO("wrong filter no");
hualing chen002e5b92022-02-23 17:51:21 +0800171 return NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800172 }
173
174 if (!dev->filter[fhandle].used)
175 {
Wentao MA96f68962022-06-15 19:45:35 +0800176 DVB_INFO("filter %d not allocated", fhandle);
hualing chen002e5b92022-02-23 17:51:21 +0800177 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800195 DVB_INFO("dmx already initialized");
hualing chen002e5b92022-02-23 17:51:21 +0800196 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800224 DVB_INFO("demux allocate failed, wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800225 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800240 DVB_INFO("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 {
Wentao MA96f68962022-06-15 19:45:35 +0800250 DVB_INFO("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
Wentao MA96f68962022-06-15 19:45:35 +0800263 //DVB_INFO("fhandle = %d", fid);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800264 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800281 DVB_INFO("Wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800282 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 {
Wentao MA96f68962022-06-15 19:45:35 +0800295 DVB_INFO("dmx stop filter failed error:%s", strerror(errno));
hualing chen002e5b92022-02-23 17:51:21 +0800296 ret = DVB_FAILURE;
297 }
298 else if (ioctl(filter->fd, DMX_SET_FILTER, params) < 0)
299 {
Wentao MA96f68962022-06-15 19:45:35 +0800300 DVB_INFO("set filter failed error:%s", strerror(errno));
hualing chen002e5b92022-02-23 17:51:21 +0800301 ret = DVB_FAILURE;
302 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800303 }
304
305 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800306 //DVB_INFO("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 {
Wentao MAa3388532022-08-18 15:07:07 +0800324 DVB_ERROR("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800325 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 {
Wentao MAa3388532022-08-18 15:07:07 +0800336 ret = DVB_FAILURE;
337 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
338 {
339 DVB_ERROR("stopping demux filter fails with errno:%d(%s)",errno,strerror(errno));
340 }
341 else if (fcntl(filter->fd, F_SETFL, O_NONBLOCK) < 0)
342 {
343 DVB_ERROR("setting filter non-block flag fails with errno:%d(%s)",errno,strerror(errno));
344 }
345 else if (ioctl(filter->fd, DMX_SET_PES_FILTER, params) < 0)
346 {
347 DVB_ERROR("setting PES filter fails with errno:%d(%s)",errno,strerror(errno));
348 }
349 else
350 {
351 ret = DVB_SUCCESS;
352 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800353 }
354
355 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800356 //DVB_INFO("pid = %x", params->pid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800357 return ret;
358}
359
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800360/**\brief set demux filter buffer
361 * \param dmx device number
362 * \param dmx filter index
363 * \param dmx filter buffer size
364 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
365 */
366DVB_RESULT AML_DMX_SetBufferSize(int dev_no, int fhandle, int size)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800367{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800368 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800369 dvb_dmx_t *dev = NULL;
370 dvb_dmx_filter_t *filter = NULL;
371
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800372 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800373 {
Wentao MA96f68962022-06-15 19:45:35 +0800374 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800375 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800376 }
377
378 pthread_mutex_lock(&dev->lock);
379
380 filter = dmx_get_filter(dev, fhandle);
381 if (filter)
382 {
hualing chen002e5b92022-02-23 17:51:21 +0800383 if (ioctl(filter->fd, DMX_SET_BUFFER_SIZE, size) < 0)
384 {
Wentao MA96f68962022-06-15 19:45:35 +0800385 DVB_INFO("set buf size failed error:%s", strerror(errno));
hualing chen002e5b92022-02-23 17:51:21 +0800386 ret = DVB_FAILURE;
387 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800388 }
389
390 pthread_mutex_unlock(&dev->lock);
391 return ret;
392}
393
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800394/**\brief free demux filter
395 * \param dmx device number
396 * \param dmx filter index
397 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
398 */
399DVB_RESULT AML_DMX_FreeFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800400{
401 dvb_dmx_t *dev = NULL;
402 dvb_dmx_filter_t *filter = NULL;
403
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800404 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800405 {
Wentao MA96f68962022-06-15 19:45:35 +0800406 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800407 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800408 }
409
410 pthread_mutex_lock(&dev->lock);
411
412 filter = dmx_get_filter(dev, fhandle);
413 if (filter)
414 {
hualing chen002e5b92022-02-23 17:51:21 +0800415 filter->need_free = 1;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800416 }
417
418 pthread_mutex_unlock(&dev->lock);
419
Wentao MA96f68962022-06-15 19:45:35 +0800420 //DVB_INFO("fhandle = %d", fhandle);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800421 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800422}
423
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800424/**\brief start demux filter
425 * \param dmx device number
426 * \param dmx filter index
427 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
428 */
429DVB_RESULT AML_DMX_StartFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800430{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800431 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800432 dvb_dmx_t *dev = NULL;
433 dvb_dmx_filter_t *filter = NULL;
434
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800435 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800436 {
Wentao MA96f68962022-06-15 19:45:35 +0800437 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800438 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800439 }
440
441 pthread_mutex_lock(&dev->lock);
442
443 filter = dmx_get_filter(dev, fhandle);
444 if (filter && !filter->enable)
445 {
446 if (ioctl(filter->fd, DMX_START, 0) < 0)
447 {
Wentao MA96f68962022-06-15 19:45:35 +0800448 DVB_INFO("dmx start filter failed error:%s", strerror(errno));
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800449 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800450 }
451 else
452 {
453 filter->enable = 1;
454 }
455 }
456
457 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800458 //DVB_INFO("ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800459 return ret;
460}
461
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800462/**\brief stop demux filter
463 * \param dmx device number
464 * \param dmx filter index
465 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
466 */
467DVB_RESULT AML_DMX_StopFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800468{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800469 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800470 dvb_dmx_t *dev = NULL;
471 dvb_dmx_filter_t *filter = NULL;
472
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800473 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800474 {
Wentao MA96f68962022-06-15 19:45:35 +0800475 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800476 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800477 }
478
479 pthread_mutex_lock(&dev->lock);
480
481 filter = dmx_get_filter(dev, fhandle);
482 if (filter && filter->enable)
483 {
484 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
485 {
Wentao MA96f68962022-06-15 19:45:35 +0800486 DVB_INFO("dmx stop filter failed error:%s", strerror(errno));
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800487 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800488 }
489 else
490 {
491 filter->enable = 0;
492 }
493 }
494
495 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800496 //DVB_INFO("ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800497 return ret;
498}
499
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800500/**\brief set demux callback
501 * \param dmx device number
502 * \param dmx filter index
503 * \param dmx filter callback
504 * \param dmx filter callback param
505 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
506 */
507DVB_RESULT AML_DMX_SetCallback(int dev_no, int fhandle, AML_DMX_DataCb cb, void *user_data)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800508{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800509 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800510 dvb_dmx_t *dev = NULL;
511 dvb_dmx_filter_t *filter = NULL;
512
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800513 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800514 {
Wentao MA96f68962022-06-15 19:45:35 +0800515 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800516 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800517 }
518
519 pthread_mutex_lock(&dev->lock);
520 filter = dmx_get_filter(dev, fhandle);
521 if (filter)
522 {
523 filter->cb = cb;
524 filter->user_data = user_data;
525 }
526 else
527 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800528 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800529 }
530
531 pthread_mutex_unlock(&dev->lock);
532
Wentao MA96f68962022-06-15 19:45:35 +0800533 //DVB_INFO("ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800534 return ret;
535}
536
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800537/**\brief dmx device uninit, destroy dmx thread
538 * \param dmx device number
539 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
540 */
541DVB_RESULT AML_DMX_Close(int dev_no)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800542{
543 int i;
544 int open_count = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800545 dvb_dmx_t *dev = NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800546 dvb_dmx_filter_t *filter = NULL;
Wentao MAa3388532022-08-18 15:07:07 +0800547 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800548
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800549 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800550 {
Wentao MAa3388532022-08-18 15:07:07 +0800551 DVB_ERROR("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800552 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800553 }
554
555 pthread_mutex_lock(&dev->lock);
556
557 for (i = 0; i < DMX_FILTER_COUNT; i++)
558 {
hualing chen002e5b92022-02-23 17:51:21 +0800559 filter = &dev->filter[i];
560 if (filter->used && filter->dev_no == dev_no)
561 {
562 if (filter->enable)
563 {
Wentao MAa3388532022-08-18 15:07:07 +0800564 if (ioctl(filter->fd, DMX_STOP, 0)<0)
565 {
566 DVB_ERROR("fails to stop filter. fd:%d", filter->fd);
567 ret = DVB_FAILURE;
568 }
hualing chen002e5b92022-02-23 17:51:21 +0800569 }
570 close(filter->fd);
571 }
Wentao MAa3388532022-08-18 15:07:07 +0800572 else if (filter->used)
hualing chen002e5b92022-02-23 17:51:21 +0800573 {
574 open_count++;
575 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800576 }
577
578 if (open_count == 0)
579 {
Wentao MAa3388532022-08-18 15:07:07 +0800580 dev->running = 0;
581 pthread_join(dev->thread, NULL);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800582 }
583
584 pthread_mutex_unlock(&dev->lock);
Wentao MA4b8d4752022-09-14 19:03:45 +0800585 pthread_mutex_destroy(&dev->lock);
Wentao MAa3388532022-08-18 15:07:07 +0800586
587 return ret;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800588}