source: svn/newcon3bcm2_21bu/dta/src/nexus/bsettop_record.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 9.6 KB
Line 
1
2/***************************************************************************
3 *     Copyright (c) 2012, Broadcom Corporation
4 *     All Rights Reserved
5 *     Confidential Property of Broadcom Corporation
6 *
7 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
8 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
9 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
10 *
11 * $brcm_Workfile:  $
12 * $brcm_Revision:  $
13 * $brcm_Date: $
14 *
15 * Module Description:
16 *
17 * Revision History:
18 *
19 * $brcm_Log:  $
20 *
21 ***************************************************************************/
22#include "nexus_platform.h"
23#include "nexus_ir_input.h"
24#include "nexus_platform.h"
25
26#include "nexus_recpump.h"
27
28#include "bstd.h"
29#include "bkni.h"
30#include "ts_psi.h"
31
32#include "bsettop.h"
33#include "bsettop_stream_n_priv.h"
34#include "bos_task_priorities.h"
35#include "bsettop_record.h"
36#include "ministd.h"
37#include "rtp.h"
38
39#include "genericlist.h"
40BDBG_MODULE(brecord);
41
42#define RECORD_TASK_STACK_WORDS 256
43#define NUM_REC_PKTS    300 /* 1.5M buffer for streaming */
44#define LOCK_TIMEOUT    200
45typedef struct rec_pkt_t
46{
47        LINKS_T links;
48        unsigned int size;
49        unsigned char buf[RTP_PACKET_SIZE];
50} rec_pkt_t;
51
52struct brecord {
53        NEXUS_RecpumpHandle recpumpHandle;
54        bstream_info_t *p_stream_info;
55        bstream_t stream;
56        BKNI_EventHandle event;
57
58        NEXUS_PidChannelHandle patPidChannel;
59        NEXUS_PidChannelHandle pmtPidChannel;
60
61        char dest[16];
62        uint16_t port;
63        unsigned int task_stack[RECORD_TASK_STACK_WORDS];
64        b_task_t task_h;       
65
66        bool started;
67#if defined(NEXUS_LINUXUSER) || defined(CONFIG_LWIP)
68        rtp_t rtp;
69        unsigned int stask_stack[RECORD_TASK_STACK_WORDS];
70        b_task_t stask_h;       
71        b_mutex_t lock;
72        LIST_T pkt_list;
73        LIST_T free_pkt_list;
74        rec_pkt_t rec_pkts[NUM_REC_PKTS];
75#endif
76};
77
78static struct brecord s_record;
79
80static void recpump_dataready_cb(void *context, int param)
81{
82        BSTD_UNUSED(param);
83        BKNI_SetEvent((BKNI_EventHandle)context);
84}
85
86static void recpump_overflow_cb(void *context, int param)
87{
88        BSTD_UNUSED(context);
89        BSTD_UNUSED(param);
90        BDBG_WRN(("recpump overflow"));
91}
92
93#if defined(NEXUS_LINUXUSER) || defined(CONFIG_LWIP)
94static void stream_task(void *arg)
95{
96        brecord_t record = (brecord_t)arg;
97        struct timeval tms, tms0;
98        rec_pkt_t *p_pkt;
99        bresult rc;
100       
101        init_rtp(&record->rtp, RTP_PAYLOAD_SIZE, RTP_MP2T);
102        makesocket_rtp(&record->rtp, record->dest, record->port, 1000);
103        GETTIMEOFDAY(&tms0);
104       
105        while (1) 
106        {
107                if (!record->started) 
108                {
109                        BKNI_Sleep(10);
110                        continue;
111                }
112                rc = bos_acquire_mutex(&record->lock, LOCK_TIMEOUT);
113                if (rc != b_ok) {
114                        BDBG_WRN(("%s:%d fail to acquire mutex", __FUNCTION__, __LINE__));
115                        continue;
116                }       
117                p_pkt = (rec_pkt_t *)remlh(&(record->pkt_list));
118                bos_release_mutex(&record->lock);
119                if (p_pkt) {
120                        GETTIMEOFDAY(&tms);
121                        record->rtp.rtph.timestamp = (tms.tv_sec-tms0.tv_sec)*1000000 + (tms.tv_usec - tms0.tv_usec);
122                        send_rtp(&record->rtp, p_pkt->buf, p_pkt->size);
123                        rc = bos_acquire_mutex(&record->lock, LOCK_TIMEOUT);
124                        if (rc != b_ok) {
125                                BDBG_WRN(("%s:%d fail to acquire mutex", __FUNCTION__, __LINE__));
126                        }
127                        inslt(&(record->free_pkt_list), p_pkt);
128                        bos_release_mutex(&record->lock);
129                }
130                else {
131                        BKNI_Sleep(10);
132                }
133        }
134}
135#endif
136
137static void record_task(void *arg)
138{
139        const void *buffer;
140        size_t buffer_size, len, consumed;
141        brecord_t record = (brecord_t)arg;
142        NEXUS_RecpumpHandle handle = record->recpumpHandle;
143        rec_pkt_t *p_pkt;
144        bresult rc;
145
146        while (1)
147        {
148
149                if (!record->started) {
150                        BKNI_Sleep(10);
151                        continue;
152                }
153                if (NEXUS_Recpump_GetDataBuffer(handle, &buffer, &buffer_size)) {
154                        BDBG_WRN(("Fail to get data buffer."));
155                        continue;
156                }
157                if (buffer_size == 0) {
158                        BKNI_WaitForEvent(record->event, -1);
159                        continue;
160                }
161                if (buffer_size) 
162                {
163#if defined(NEXUS_LINUXUSER) || defined(CONFIG_LWIP)
164                        consumed = 0;
165                        while (consumed<buffer_size) {
166                                rc = bos_acquire_mutex(&record->lock, LOCK_TIMEOUT);
167                                if (rc != b_ok) {
168                                        BDBG_WRN(("%s:%d fail to acquire mutex", __FUNCTION__, __LINE__));
169                                        break;
170                                }
171                                p_pkt = (rec_pkt_t *)remlh(&(record->free_pkt_list));
172                                bos_release_mutex(&record->lock);
173                                if (p_pkt) 
174                                {
175                                        len = buffer_size-consumed;
176                                        len = (len>RTP_PAYLOAD_SIZE)?RTP_PAYLOAD_SIZE:len;     
177                                        p_pkt->size = len;
178                                        BKNI_Memcpy(&p_pkt->buf[RTP_HEADER_SIZE], (unsigned char *)buffer+consumed, len);
179                                        rc = bos_acquire_mutex(&record->lock, LOCK_TIMEOUT);
180                                        if (rc != b_ok) {
181                                                BDBG_WRN(("%s:%d fail to acquire mutex", __FUNCTION__, __LINE__));
182                                        }
183                                        inslt(&(record->pkt_list), p_pkt);
184                                        bos_release_mutex(&record->lock);
185                                        consumed += len;
186                                }
187                                else {
188                                        BDBG_WRN(("no free space for buffering.. dropping recorded data(%d/%d)", consumed, buffer_size));
189                                        break;
190                                }
191                        }
192#endif
193                        NEXUS_Recpump_DataReadComplete(handle, buffer_size);
194                }
195        }
196}
197
198brecord_t brecord_open(bobject_t record_id, const char *dst, uint16_t port)
199{
200        NEXUS_RecpumpSettings recpumpSettings;
201        b_task_params task_params;
202        NEXUS_RecpumpOpenSettings recpumpOpenSettings;
203        int i;
204        BSTD_UNUSED(record_id);
205        BKNI_Memset(&s_record, 0, sizeof(struct brecord));
206
207        BKNI_CreateEvent(&s_record.event);
208
209        NEXUS_Recpump_GetDefaultOpenSettings(&recpumpOpenSettings);
210#if 0
211        recpumpOpenSettings.data.bufferSize *= 2;
212        recpumpOpenSettings.data.dataReadyThreshold = recpumpOpenSettings.data.atomSize*24;
213#endif
214        s_record.recpumpHandle = NEXUS_Recpump_Open(0, &recpumpOpenSettings);
215        NEXUS_Recpump_GetSettings(s_record.recpumpHandle, &recpumpSettings);
216        recpumpSettings.data.dataReady.callback = recpump_dataready_cb;
217        recpumpSettings.data.dataReady.context = s_record.event;
218        recpumpSettings.data.overflow.callback = recpump_overflow_cb; 
219        recpumpSettings.outputTransportType = NEXUS_TransportType_eTs;
220        NEXUS_Recpump_SetSettings(s_record.recpumpHandle, &recpumpSettings);
221
222        strncpy(s_record.dest, dst, 16);
223        s_record.port = port;
224
225        BDBG_WRN(("recpump buffer: %d, dataReadyThreshold: %d", 
226                recpumpOpenSettings.data.bufferSize, recpumpOpenSettings.data.dataReadyThreshold));
227
228#if defined(NEXUS_LINUXUSER) || defined(CONFIG_LWIP)
229        bos_create_mutex(&s_record.lock);
230
231        initl(&s_record.pkt_list);
232        initl(&s_record.free_pkt_list);
233        for (i=0; i<NUM_REC_PKTS; i++) {
234                memset(&s_record.rec_pkts[i], 0, sizeof(rec_pkt_t));
235                inslt(&(s_record.free_pkt_list), &s_record.rec_pkts[i]);
236        }       
237
238        task_params.name = "STREAM_TASK";
239        task_params.priority = STREAM_PRIORITY;
240        task_params.stack_size = RECORD_TASK_STACK_WORDS;
241        task_params.stack = s_record.stask_stack;
242        bos_start_task(&(s_record.stask_h), &task_params, stream_task, &s_record);
243#endif
244
245        task_params.name = "RECORD_TASK";
246        task_params.priority = RECORD_PRIORITY;
247        task_params.stack_size = RECORD_TASK_STACK_WORDS;
248        task_params.stack = s_record.task_stack;
249        bos_start_task(&(s_record.task_h), &task_params, record_task, &s_record);
250
251        return &s_record;
252}
253
254void brecord_close(brecord_t record)
255{
256        if (record->task_h)
257                bos_stop_task(record->task_h);
258#if defined(NEXUS_LINUXUSER) || defined(CONFIG_LWIP)
259        if (record->stask_h)
260                bos_stop_task(record->stask_h);
261        bos_delete_mutex(&record->lock);
262#endif
263        if (record->recpumpHandle) 
264                NEXUS_Recpump_Close(record->recpumpHandle);
265        if (record->event)     
266                BKNI_DestroyEvent(record->event);
267}
268
269bresult brecord_start(
270        brecord_t record,  /* handle returned by brecord_open */
271        bstream_t p_stream, /* source for the record */
272        uint16_t pmt_pid
273        )
274{
275        bstream_status status;
276        NEXUS_RecpumpAddPidChannelSettings addPidChannelSettings;
277        NEXUS_ParserBand parserBand = NEXUS_ParserBand_e0;
278
279        /* init buffer pointer */
280        record->stream = p_stream;
281        bstream_get_status(p_stream, &status);
282        record->p_stream_info = bstream_get_info(p_stream);
283       
284        record->patPidChannel = record->pmtPidChannel = NULL;
285        if (status.mpeg.video[0].pid) { /* video PID is available */
286                NEXUS_Recpump_GetDefaultAddPidChannelSettings(&addPidChannelSettings);
287                addPidChannelSettings.pidType = NEXUS_PidType_eVideo;
288                addPidChannelSettings.pidTypeSettings.video.index = false;
289                addPidChannelSettings.pidTypeSettings.video.codec = status.mpeg.video[0].format;
290                NEXUS_Recpump_AddPidChannel(record->recpumpHandle, record->p_stream_info->videoPidChannel, &addPidChannelSettings);
291        }
292        if (status.mpeg.audio[0].pid) { /* audio PID is avilable */
293                NEXUS_Recpump_AddPidChannel(record->recpumpHandle, record->p_stream_info->audioPidChannel, NULL);
294        }
295        record->patPidChannel = NEXUS_PidChannel_Open(parserBand, 0x0, NULL);
296        record->pmtPidChannel = NEXUS_PidChannel_Open(parserBand, pmt_pid, NULL);
297        NEXUS_Recpump_AddPidChannel(record->recpumpHandle, record->patPidChannel, NULL);
298        NEXUS_Recpump_AddPidChannel(record->recpumpHandle, record->pmtPidChannel, NULL);       
299        NEXUS_Recpump_Start(record->recpumpHandle);     
300        record->started = true;
301        return b_ok;
302}
303
304bresult brecord_stop(
305        brecord_t record /* handle returned by brecord_open */
306        )
307{
308        rec_pkt_t *p_pkt;
309
310        record->started = false;
311
312        if (!record->p_stream_info)
313                return b_ok;
314        if (record->p_stream_info->videoPidChannel)
315                NEXUS_Recpump_RemovePidChannel(record->recpumpHandle, record->p_stream_info->videoPidChannel);
316        if (record->p_stream_info->audioPidChannel)
317                NEXUS_Recpump_RemovePidChannel(record->recpumpHandle, record->p_stream_info->audioPidChannel);
318
319        if (record->patPidChannel) {
320                NEXUS_Recpump_RemovePidChannel(record->recpumpHandle, record->patPidChannel);
321                NEXUS_PidChannel_Close(record->patPidChannel);
322        }
323        if (record->pmtPidChannel) {
324                NEXUS_Recpump_RemovePidChannel(record->recpumpHandle, record->pmtPidChannel);
325                NEXUS_PidChannel_Close(record->pmtPidChannel);
326        }
327        if (record->recpumpHandle)
328                NEXUS_Recpump_Stop(record->recpumpHandle);
329
330#if defined(NEXUS_LINUXUSER) || defined(CONFIG_LWIP)
331        bos_acquire_mutex(&record->lock, LOCK_TIMEOUT);
332        while ((p_pkt = (rec_pkt_t *)remlh(&(record->pkt_list))))
333        {
334                inslt(&(record->free_pkt_list), p_pkt);
335        }
336        bos_release_mutex(&record->lock);
337#endif
338
339        return b_ok;
340}
341
Note: See TracBrowser for help on using the repository browser.