blob: 9b321dbb2e28d8ac318ad8d1dc5df57a4c3f67e6 [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;
wentao.maa22bc852022-10-13 12:18:06 +0800106 // It is not necessary to protect code block below with
107 // Record_DeviceContext_t.lock, so the following annotation
wentao.mafd5283f2022-10-14 09:51:13 +0800108 // is given to suppress related Coverity complaint.
wentao.maa22bc852022-10-13 12:18:06 +0800109 // coverity[missing_lock]
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800110 fds[cnt].fd = dmx->filter[fid].fd;
111 fids[cnt] = fid;
112 cnt++;
113 }
114 }
115
hualing chen002e5b92022-02-23 17:51:21 +0800116 pthread_mutex_unlock(&dmx->lock);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800117
hualing chen002e5b92022-02-23 17:51:21 +0800118 if (!cnt)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800119 {
120 usleep(20*1000);
hualing chen002e5b92022-02-23 17:51:21 +0800121 continue;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800122 }
123
hualing chen002e5b92022-02-23 17:51:21 +0800124 ret = poll(fds, cnt, DMX_POLL_TIMEOUT);
125 if (ret <= 0)
126 {
127 continue;
128 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800129
hualing chen002e5b92022-02-23 17:51:21 +0800130 for (i = 0; i < cnt; i++)
131 {
132 if (fds[i].revents & (POLLIN | POLLERR))
133 {
134 pthread_mutex_lock(&dmx->lock);
135 filter = &dmx->filter[fids[i]];
136 if (!filter->enable || !filter->used || filter->need_free)
137 {
Wentao MA96f68962022-06-15 19:45:35 +0800138 DVB_INFO("ch[%d] not used, not read", fids[i]);
hualing chen002e5b92022-02-23 17:51:21 +0800139 len = 0;
140 }
141 else
142 {
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800143 len = read(filter->fd, sec_buf, SEC_BUF_SIZE);
144 if (len <= 0)
145 {
Wentao MA96f68962022-06-15 19:45:35 +0800146 DVB_INFO("read demux filter[%d] failed (%s) %d", fids[i], strerror(errno), errno);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800147 }
hualing chen002e5b92022-02-23 17:51:21 +0800148 }
149 pthread_mutex_unlock(&dmx->lock);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800150#ifdef DEBUG_DEMUX_DATA
hualing chen002e5b92022-02-23 17:51:21 +0800151 if (len)
Wentao MA96f68962022-06-15 19:45:35 +0800152 DVB_INFO("tid[%x] ch[%d] %x bytes", sec_buf[0], fids[i], len);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800153#endif
hualing chen002e5b92022-02-23 17:51:21 +0800154 if (len > 0 && filter->cb)
155 {
156 filter->cb(filter->dev_no, fids[i], sec_buf, len, filter->user_data);
157 }
158 }
159 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800160 }
161
162 if (sec_buf)
163 {
hualing chen002e5b92022-02-23 17:51:21 +0800164 free(sec_buf);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800165 }
166
167 return NULL;
168}
169
170static dvb_dmx_filter_t* dmx_get_filter(dvb_dmx_t * dev, int fhandle)
171{
172 if (fhandle >= DMX_FILTER_COUNT)
173 {
Wentao MA96f68962022-06-15 19:45:35 +0800174 DVB_INFO("wrong filter no");
hualing chen002e5b92022-02-23 17:51:21 +0800175 return NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800176 }
177
178 if (!dev->filter[fhandle].used)
179 {
Wentao MA96f68962022-06-15 19:45:35 +0800180 DVB_INFO("filter %d not allocated", fhandle);
hualing chen002e5b92022-02-23 17:51:21 +0800181 return NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800182 }
183 return &dev->filter[fhandle];
184}
185
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800186/**\brief dmx device init, creat dmx thread
187 * \param dmx device number
188 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
189 */
190DVB_RESULT AML_DMX_Open(int dev_no)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800191{
192 dvb_dmx_t *dev = NULL;
193
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800194 if (dmx_get_dev(dev_no, &dev))
195 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800196
197 if (dev->running)
198 {
Wentao MA96f68962022-06-15 19:45:35 +0800199 DVB_INFO("dmx already initialized");
hualing chen002e5b92022-02-23 17:51:21 +0800200 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800201 }
202
hualing chen002e5b92022-02-23 17:51:21 +0800203 dev->dev_no = dev_no;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800204
205 pthread_mutex_init(&dev->lock, NULL);
206 dev->running = 1;
207 pthread_create(&dev->thread, NULL, dmx_data_thread, dev);
208
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800209 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800210}
211
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800212/**\brief allocate dmx filter
213 * \param dmx device number
214 * \param get dmx filter index
215 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
216 */
217DVB_RESULT AML_DMX_AllocateFilter(int dev_no, int *fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800218{
219 int fd;
220 int fid;
221 dvb_dmx_filter_t *filter = NULL;
222 char dev_name[32];
223
224 dvb_dmx_t *dev = NULL;
225
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800226 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800227 {
Wentao MA96f68962022-06-15 19:45:35 +0800228 DVB_INFO("demux allocate failed, wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800229 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800230 }
231
232 pthread_mutex_lock(&dev->lock);
233 filter = &dev->filter[0];
234 for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
235 {
hualing chen002e5b92022-02-23 17:51:21 +0800236 if (!filter[fid].used)
237 {
238 break;
239 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800240 }
241
242 if (fid >= DMX_FILTER_COUNT)
243 {
Wentao MA96f68962022-06-15 19:45:35 +0800244 DVB_INFO("filter id:%d, have no filter to alloc", fid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800245 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800246 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800247 }
248
249 memset(dev_name, 0, sizeof(dev_name));
250 sprintf(dev_name, "/dev/dvb0.demux%d", dev_no);
251 fd = open(dev_name, O_RDWR);
252 if (fd == -1)
253 {
Wentao MA96f68962022-06-15 19:45:35 +0800254 DVB_INFO("cannot open \"%s\" (%s)", dev_name, strerror(errno));
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800255 pthread_mutex_unlock(&dev->lock);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800256 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800257 }
258
259 memset(&filter[fid], 0, sizeof(dvb_dmx_filter_t));
260 filter[fid].dev_no = dev_no;
261 filter[fid].fd = fd;
262 filter[fid].used = 1;
263 *fhandle = fid;
264
265 pthread_mutex_unlock(&dev->lock);
266
Wentao MA96f68962022-06-15 19:45:35 +0800267 //DVB_INFO("fhandle = %d", fid);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800268 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800269}
270
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800271/**\brief set demux section filter
272 * \param dmx device number
273 * \param dmx filter index
274 * \param dmx section filter param
275 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
276 */
277DVB_RESULT AML_DMX_SetSecFilter(int dev_no, int fhandle, const struct dmx_sct_filter_params *params)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800278{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800279 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800280 dvb_dmx_t *dev = NULL;
281 dvb_dmx_filter_t *filter = NULL;
282
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800283 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800284 {
Wentao MA96f68962022-06-15 19:45:35 +0800285 DVB_INFO("Wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800286 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800287 }
288
289 if (!params)
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800290 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800291
292 pthread_mutex_lock(&dev->lock);
293
294 filter = dmx_get_filter(dev, fhandle);
295 if (filter)
296 {
hualing chen002e5b92022-02-23 17:51:21 +0800297 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
298 {
Wentao MA96f68962022-06-15 19:45:35 +0800299 DVB_INFO("dmx stop filter failed error:%s", strerror(errno));
hualing chen002e5b92022-02-23 17:51:21 +0800300 ret = DVB_FAILURE;
301 }
302 else if (ioctl(filter->fd, DMX_SET_FILTER, params) < 0)
303 {
Wentao MA96f68962022-06-15 19:45:35 +0800304 DVB_INFO("set filter failed error:%s", strerror(errno));
hualing chen002e5b92022-02-23 17:51:21 +0800305 ret = DVB_FAILURE;
306 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800307 }
308
309 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800310 //DVB_INFO("pid = %x", params->pid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800311 return ret;
312}
313
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800314/**\brief set demux pes filter
315 * \param dmx device number
316 * \param dmx filter index
317 * \param dmx pes filter param
318 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
319 */
320DVB_RESULT AML_DMX_SetPesFilter(int dev_no, int fhandle, const struct dmx_pes_filter_params *params)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800321{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800322 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800323 dvb_dmx_t *dev = NULL;
324 dvb_dmx_filter_t *filter = NULL;
325
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800326 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800327 {
Wentao MAa3388532022-08-18 15:07:07 +0800328 DVB_ERROR("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800329 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800330 }
331
332 if (!params)
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800333 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800334
335 pthread_mutex_lock(&dev->lock);
336
337 filter = dmx_get_filter(dev, fhandle);
338 if (filter)
339 {
Wentao MAa3388532022-08-18 15:07:07 +0800340 ret = DVB_FAILURE;
341 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
342 {
343 DVB_ERROR("stopping demux filter fails with errno:%d(%s)",errno,strerror(errno));
344 }
345 else if (fcntl(filter->fd, F_SETFL, O_NONBLOCK) < 0)
346 {
347 DVB_ERROR("setting filter non-block flag fails with errno:%d(%s)",errno,strerror(errno));
348 }
349 else if (ioctl(filter->fd, DMX_SET_PES_FILTER, params) < 0)
350 {
351 DVB_ERROR("setting PES filter fails with errno:%d(%s)",errno,strerror(errno));
352 }
353 else
354 {
355 ret = DVB_SUCCESS;
356 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800357 }
358
359 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800360 //DVB_INFO("pid = %x", params->pid);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800361 return ret;
362}
363
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800364/**\brief set demux filter buffer
365 * \param dmx device number
366 * \param dmx filter index
367 * \param dmx filter buffer size
368 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
369 */
370DVB_RESULT AML_DMX_SetBufferSize(int dev_no, int fhandle, int size)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800371{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800372 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800373 dvb_dmx_t *dev = NULL;
374 dvb_dmx_filter_t *filter = NULL;
375
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800376 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800377 {
Wentao MA96f68962022-06-15 19:45:35 +0800378 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800379 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800380 }
381
382 pthread_mutex_lock(&dev->lock);
383
384 filter = dmx_get_filter(dev, fhandle);
385 if (filter)
386 {
hualing chen002e5b92022-02-23 17:51:21 +0800387 if (ioctl(filter->fd, DMX_SET_BUFFER_SIZE, size) < 0)
388 {
Wentao MA96f68962022-06-15 19:45:35 +0800389 DVB_INFO("set buf size failed error:%s", strerror(errno));
hualing chen002e5b92022-02-23 17:51:21 +0800390 ret = DVB_FAILURE;
391 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800392 }
393
394 pthread_mutex_unlock(&dev->lock);
395 return ret;
396}
397
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800398/**\brief free demux filter
399 * \param dmx device number
400 * \param dmx filter index
401 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
402 */
403DVB_RESULT AML_DMX_FreeFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800404{
405 dvb_dmx_t *dev = NULL;
406 dvb_dmx_filter_t *filter = NULL;
407
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800408 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800409 {
Wentao MA96f68962022-06-15 19:45:35 +0800410 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800411 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800412 }
413
414 pthread_mutex_lock(&dev->lock);
415
416 filter = dmx_get_filter(dev, fhandle);
417 if (filter)
418 {
hualing chen002e5b92022-02-23 17:51:21 +0800419 filter->need_free = 1;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800420 }
421
422 pthread_mutex_unlock(&dev->lock);
423
Wentao MA96f68962022-06-15 19:45:35 +0800424 //DVB_INFO("fhandle = %d", fhandle);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800425 return DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800426}
427
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800428/**\brief start demux filter
429 * \param dmx device number
430 * \param dmx filter index
431 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
432 */
433DVB_RESULT AML_DMX_StartFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800434{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800435 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800436 dvb_dmx_t *dev = NULL;
437 dvb_dmx_filter_t *filter = NULL;
438
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800439 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800440 {
Wentao MA96f68962022-06-15 19:45:35 +0800441 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800442 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800443 }
444
445 pthread_mutex_lock(&dev->lock);
446
447 filter = dmx_get_filter(dev, fhandle);
448 if (filter && !filter->enable)
449 {
450 if (ioctl(filter->fd, DMX_START, 0) < 0)
451 {
Wentao MA96f68962022-06-15 19:45:35 +0800452 DVB_INFO("dmx start filter failed error:%s", strerror(errno));
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800453 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800454 }
455 else
456 {
457 filter->enable = 1;
458 }
459 }
460
461 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800462 //DVB_INFO("ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800463 return ret;
464}
465
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800466/**\brief stop demux filter
467 * \param dmx device number
468 * \param dmx filter index
469 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
470 */
471DVB_RESULT AML_DMX_StopFilter(int dev_no, int fhandle)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800472{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800473 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800474 dvb_dmx_t *dev = NULL;
475 dvb_dmx_filter_t *filter = NULL;
476
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800477 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800478 {
Wentao MA96f68962022-06-15 19:45:35 +0800479 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800480 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800481 }
482
483 pthread_mutex_lock(&dev->lock);
484
485 filter = dmx_get_filter(dev, fhandle);
486 if (filter && filter->enable)
487 {
488 if (ioctl(filter->fd, DMX_STOP, 0) < 0)
489 {
Wentao MA96f68962022-06-15 19:45:35 +0800490 DVB_INFO("dmx stop filter failed error:%s", strerror(errno));
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800491 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800492 }
493 else
494 {
495 filter->enable = 0;
496 }
497 }
498
499 pthread_mutex_unlock(&dev->lock);
Wentao MA96f68962022-06-15 19:45:35 +0800500 //DVB_INFO("ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800501 return ret;
502}
503
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800504/**\brief set demux callback
505 * \param dmx device number
506 * \param dmx filter index
507 * \param dmx filter callback
508 * \param dmx filter callback param
509 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
510 */
511DVB_RESULT AML_DMX_SetCallback(int dev_no, int fhandle, AML_DMX_DataCb cb, void *user_data)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800512{
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800513 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800514 dvb_dmx_t *dev = NULL;
515 dvb_dmx_filter_t *filter = NULL;
516
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800517 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800518 {
Wentao MA96f68962022-06-15 19:45:35 +0800519 DVB_INFO("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800520 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800521 }
522
523 pthread_mutex_lock(&dev->lock);
524 filter = dmx_get_filter(dev, fhandle);
525 if (filter)
526 {
527 filter->cb = cb;
528 filter->user_data = user_data;
529 }
530 else
531 {
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800532 ret = DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800533 }
534
535 pthread_mutex_unlock(&dev->lock);
536
Wentao MA96f68962022-06-15 19:45:35 +0800537 //DVB_INFO("ret = %d", ret);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800538 return ret;
539}
540
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800541/**\brief dmx device uninit, destroy dmx thread
542 * \param dmx device number
543 * \return DVB_SUCCESS On success, DVB_FAILURE on error.
544 */
545DVB_RESULT AML_DMX_Close(int dev_no)
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800546{
547 int i;
548 int open_count = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800549 dvb_dmx_t *dev = NULL;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800550 dvb_dmx_filter_t *filter = NULL;
Wentao MAa3388532022-08-18 15:07:07 +0800551 DVB_RESULT ret = DVB_SUCCESS;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800552
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800553 if (dmx_get_dev(dev_no, &dev))
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800554 {
Wentao MAa3388532022-08-18 15:07:07 +0800555 DVB_ERROR("wrong dmx device no %d", dev_no);
Chuanzhi Wang742ba112020-09-15 11:43:55 +0800556 return DVB_FAILURE;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800557 }
558
559 pthread_mutex_lock(&dev->lock);
560
561 for (i = 0; i < DMX_FILTER_COUNT; i++)
562 {
hualing chen002e5b92022-02-23 17:51:21 +0800563 filter = &dev->filter[i];
564 if (filter->used && filter->dev_no == dev_no)
565 {
566 if (filter->enable)
567 {
Wentao MAa3388532022-08-18 15:07:07 +0800568 if (ioctl(filter->fd, DMX_STOP, 0)<0)
569 {
570 DVB_ERROR("fails to stop filter. fd:%d", filter->fd);
571 ret = DVB_FAILURE;
572 }
hualing chen002e5b92022-02-23 17:51:21 +0800573 }
574 close(filter->fd);
575 }
Wentao MAa3388532022-08-18 15:07:07 +0800576 else if (filter->used)
hualing chen002e5b92022-02-23 17:51:21 +0800577 {
578 open_count++;
579 }
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800580 }
581
582 if (open_count == 0)
583 {
Wentao MAa3388532022-08-18 15:07:07 +0800584 dev->running = 0;
585 pthread_join(dev->thread, NULL);
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800586 }
587
588 pthread_mutex_unlock(&dev->lock);
Wentao MA4b8d4752022-09-14 19:03:45 +0800589 pthread_mutex_destroy(&dev->lock);
Wentao MAa3388532022-08-18 15:07:07 +0800590
591 return ret;
Chuanzhi Wang1b3a5de2020-09-04 17:02:00 +0800592}