source: svn/newcon3bcm2_21bu/BSEAV/api/src/nexus/bsettop_recpump.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: 27.9 KB
Line 
1/***************************************************************************
2 *  Copyright (c) 2004-2010, Broadcom Corporation
3 *  All Rights Reserved
4 *  Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bsettop_recpump.c $
11 * $brcm_Revision: 25 $
12 * $brcm_Date: 6/22/10 4:34p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/api/src/nexus/bsettop_recpump.c $
19 *
20 * 25   6/22/10 4:34p mphillip
21 * SW7550-463: Clear keyslot when there is security but no DMA
22 *
23 * 24   6/10/10 2:45p mphillip
24 * SW7550-380: Enable non-DMA PVR encryption for 7550 and similar
25 * platforms
26 *
27 * 23   2/11/10 2:54p erickson
28 * SW7550-252: fix dma/security testes
29 *
30 * 22   6/15/09 4:59p jtna
31 * PR43001: add support for TTS+encryption record/playback
32 *
33 * 21   3/9/09 7:00p nickh
34 * PR52996: Fix compilation errors when NEXUS_HAS_SECURITY is disabled
35 *
36 * 20   12/24/08 12:42p mphillip
37 * PR49607: Keyladder key derivation support added for encrypted PVR in
38 * nexus shim
39 *
40 * 19   12/24/08 11:56a jgarrett
41 * PR 50703: Allowing security module to be absent
42 *
43 * 18   10/29/08 4:56p jrubio
44 * PR47690: make sure Playback is taking out if NEXUS_HAS_PLAYBACK is
45 * false
46 *
47 * 17   10/17/08 4:02p katrep
48 * PR47690: Add option to generate index index on video pid during allpass
49 * record, disabled by default.To enable define ALLPASS_RECORD_WITH_INDEX
50 *
51 * 16   10/16/08 6:20p katrep
52 * PR47690: Adding allpass record from playback parser
53 *
54 * 15   10/15/08 2:39p mphillip
55 * PR45211: Disable encryption on clear records
56 *
57 * 14   9/25/08 1:06p katrep
58 * PR47154: Add support for recording with null packets and without null
59 * packets
60 *
61 * 13   9/22/08 1:53p katrep
62 * PR47154: More fine tuning of allpass record
63 *
64 * 12   9/19/08 7:49p katrep
65 * PR47154: Add support for allpass record
66 *
67 * 11   6/27/08 3:36p mphillip
68 * PR42901: Free PVR keyslot on close/stop
69 *
70 * 10   6/26/08 6:21p mphillip
71 * PR42901: Encrypted PVR playback support
72 *
73 * 9   4/10/08 9:56a erickson
74 * PR36068: coverity fixes
75 *
76 * 8   4/7/08 10:40a jgarrett
77 * PR 41362: Revising pid channel management
78 *
79 * 7   4/3/08 5:41p jgarrett
80 * PR 41312: Setting callback events
81 *
82 * 6   3/12/08 6:37p katrep
83 * PR40033: Implemented setttop recpump using nexus
84 *
85 * 5   2/7/08 10:20a erickson
86 * PR39384: added recpump dataReadyThreshold
87 *
88 * 4   1/22/08 9:51a erickson
89 * PR34925: removed numDescriptors
90 *
91 * 3   11/14/07 1:29p erickson
92 * PR36068: added record
93 *
94 * 2   10/16/07 12:35p erickson
95 * PR36068: brutus up over settop api/nexus
96 *
97 *******************************************************************************/
98#include "bsettop_impl.h"
99
100BDBG_MODULE(recpump);
101
102BDBG_OBJECT_ID(brecpump);
103
104/* #define  ALLPASS_RECORD_WITH_INDEX 1 */
105
106static void brecpump_p_data_write_callback(void *context, int param)
107{
108    brecpump_t recpump = context;
109    BDBG_OBJECT_ASSERT(recpump, brecpump);
110    BSTD_UNUSED(param);
111    B_Event_Set(recpump->dataEvent);
112}
113
114static void brecpump_p_data_write_handler(void *context)
115{
116    brecpump_t recpump = context;
117    BDBG_OBJECT_ASSERT(recpump, brecpump);
118    if(recpump->params.data_write_callback)
119    {
120        b_unlock();
121        (*recpump->params.data_write_callback)(recpump->params.callback_context);
122        b_lock();
123    }
124}
125
126static void brecpump_p_index_write_callback(void *context, int param)
127{
128    brecpump_t recpump = context;
129    BDBG_OBJECT_ASSERT(recpump, brecpump);
130    BSTD_UNUSED(param);
131    B_Event_Set(recpump->indexEvent);
132}
133
134static void brecpump_p_index_write_handler(void *context)
135{
136    brecpump_t recpump = context;
137    BDBG_OBJECT_ASSERT(recpump, brecpump);
138    if(recpump->params.index_write_callback)
139    {
140        b_unlock();
141        (*recpump->params.index_write_callback)(recpump->params.callback_context);
142        b_lock();
143    }
144}
145
146static void brecpump_p_overflow_callback(void *context, int param)
147{
148    brecpump_t recpump = context;
149    BDBG_OBJECT_ASSERT(recpump, brecpump);
150    BSTD_UNUSED(param);
151    B_Event_Set(recpump->overflowEvent);
152}
153
154static void brecpump_p_overflow_handler(void *context)
155{
156    brecpump_t recpump = context;
157    BDBG_OBJECT_ASSERT(recpump, brecpump);
158    if(recpump->params.overflow)
159    {
160        b_unlock();
161        (*recpump->params.overflow)(recpump->params.callback_context);
162        b_lock();
163    }
164}
165
166void brecpump_get_open_params(bobject_t id, brecpump_open_params *open_params)
167{
168    BSTD_UNUSED(id);
169    BKNI_Memset(open_params, 0, sizeof(*open_params));
170    /* a small pad is needed for optimal sizing of a 188/4096 byte aligned buffer. any
171    number will work, but the amount unused at the end of the buffer may be undesired. */
172    open_params->data.buffer_size = B_PVR_RECORD_BUFFER + 68;
173    open_params->data.num_descriptors = B_PVR_N_RECORD_DESC;
174    open_params->data.alignment = 12; /* 4K alignment */
175    open_params->scode.buffer_size = (6*4*16)*48; /* 6*4 is a size of the single 6-word SCT entry, 16 is a number of SCT entries per descriptor */
176    open_params->scode.num_descriptors = 48;
177    open_params->scode.alignment = 0; /* unused */
178}
179
180brecpump_t brecpump_open(bobject_t id, const brecpump_open_params *open_params)
181{
182    brecpump_t recpump;
183    unsigned index;
184    brecpump_open_params default_open_params;
185    NEXUS_RecpumpOpenSettings openSettings;
186
187    recpump = BKNI_Malloc(sizeof(*recpump));
188    if ( NULL == recpump )
189    {
190        BSETTOP_ERROR(berr_external_error);
191        return NULL;
192    }
193
194    BKNI_Memset(recpump, 0, sizeof(*recpump));
195    BDBG_OBJECT_SET(recpump, brecpump);
196
197    index = B_ID_GET_INDEX(id);
198
199    if (!open_params) {
200        brecpump_get_open_params(id, &default_open_params);
201        open_params = &default_open_params;
202    }
203
204    NEXUS_Recpump_GetDefaultOpenSettings(&openSettings);
205    openSettings.data.bufferSize = open_params->data.buffer_size;
206    openSettings.data.dataReadyThreshold = openSettings.data.bufferSize / 5; /* 20% */
207    openSettings.data.alignment = open_params->data.alignment;
208    openSettings.index.bufferSize = open_params->scode.buffer_size;
209    openSettings.index.alignment = open_params->scode.alignment;
210    openSettings.index.dataReadyThreshold = openSettings.index.bufferSize / 5; /* 20% */
211
212    recpump->nRecpump = NEXUS_Recpump_Open(index, &openSettings);
213    if (!recpump->nRecpump) {
214        BDBG_OBJECT_DESTROY(recpump, brecpump);
215        BKNI_Free(recpump);
216        return NULL;
217    }
218
219    recpump->dataEvent = B_Event_Create(NULL);
220    if ( NULL == recpump->dataEvent )
221    {
222        BSETTOP_ERROR(berr_external_error);
223        goto err_event;
224    }
225    recpump->indexEvent = B_Event_Create(NULL);
226    if ( NULL == recpump->indexEvent )
227    {
228        BSETTOP_ERROR(berr_external_error);
229        goto err_event;
230    }
231    recpump->overflowEvent = B_Event_Create(NULL);
232    if ( NULL == recpump->overflowEvent )
233    {
234        BSETTOP_ERROR(berr_external_error);
235        goto err_event;
236    }
237
238    recpump->dataEventId = b_event_register(recpump->dataEvent, brecpump_p_data_write_handler, recpump);
239    if ( NULL == recpump->dataEventId )
240    {
241        BSETTOP_ERROR(berr_external_error);
242        goto err_event;
243    }
244
245    recpump->indexEventId = b_event_register(recpump->indexEvent, brecpump_p_index_write_handler, recpump);
246    if ( NULL == recpump->indexEventId )
247    {
248        BSETTOP_ERROR(berr_external_error);
249        goto err_event;
250    }
251
252    recpump->overflowEventId = b_event_register(recpump->overflowEvent, brecpump_p_overflow_handler, recpump);
253    if ( NULL == recpump->overflowEventId )
254    {
255        BSETTOP_ERROR(berr_external_error);
256        goto err_event;
257    }
258
259    return recpump;
260
261err_event:
262    brecpump_close(recpump);
263    return NULL;
264}
265
266void brecpump_close(brecpump_t recpump)
267{
268    BDBG_OBJECT_ASSERT(recpump, brecpump);
269
270    if ( NULL != recpump->overflowEventId )
271        b_event_unregister(recpump->overflowEventId);
272    if ( NULL != recpump->overflowEventId )
273        b_event_unregister(recpump->indexEventId);
274    if ( NULL != recpump->indexEvent )
275        b_event_unregister(recpump->dataEventId);
276
277    if ( NULL != recpump->dataEventId )
278        B_Event_Destroy(recpump->overflowEvent);
279    if ( NULL != recpump->indexEvent )
280        B_Event_Destroy(recpump->indexEvent);
281    if ( NULL != recpump->dataEvent )
282        B_Event_Destroy(recpump->dataEvent);
283
284    NEXUS_Recpump_Close(recpump->nRecpump);
285    BDBG_OBJECT_DESTROY(recpump, brecpump);
286    BKNI_Free(recpump);
287}
288
289void brecpump_params_init(brecpump_params *params,  brecpump_t recpump)
290{
291    BSTD_UNUSED(recpump);
292    BKNI_Memset(params, 0, sizeof(*params));
293    bencryption_params_init(&params->encryption);
294}
295
296bresult brecpump_start(brecpump_t recpump, bstream_t stream, const brecpump_params *params)
297{
298
299    NEXUS_RecpumpSettings recpumpSettings;
300    NEXUS_Error rc=NEXUS_SUCCESS;
301
302    BDBG_OBJECT_ASSERT(recpump, brecpump);
303
304    if (!stream || !stream->parser_band || !params || !params->data_write_callback)
305    {
306        return BSETTOP_ERROR(berr_invalid_parameter);
307    }
308
309    NEXUS_Recpump_GetSettings(recpump->nRecpump, &recpumpSettings);
310    recpumpSettings.data.dataReady.callback = brecpump_p_data_write_callback;
311    recpumpSettings.data.dataReady.context = recpump;
312    recpumpSettings.index.dataReady.callback = brecpump_p_index_write_callback;
313    recpumpSettings.index.dataReady.context = recpump;
314    recpumpSettings.data.overflow.callback = brecpump_p_overflow_callback;
315    recpumpSettings.data.overflow.context = recpump;
316    recpumpSettings.index.overflow.callback = brecpump_p_overflow_callback;
317    recpumpSettings.index.overflow.context = (void*)recpump;
318    if (params->encryption.type != bencryption_type_none) {
319#if NEXUS_HAS_SECURITY
320        if (!params->encryption.key_ladder) {
321            switch (params->encryption.type) {
322            case bencryption_type_des:
323                if (params->encryption.key_length != 64)
324                    return BSETTOP_ERROR(berr_invalid_parameter);
325                break;
326            case bencryption_type_3des:
327                if (params->encryption.key_length != 128)
328                    return BSETTOP_ERROR(berr_invalid_parameter);
329                break;
330            case bencryption_type_aes:
331                if (params->encryption.key_length != 128)
332                    return BSETTOP_ERROR(berr_invalid_parameter);
333                break;
334            default:
335                BDBG_ERR(("Unsupported PVR encryption algorithm"));
336                return BSETTOP_ERROR(berr_invalid_parameter);
337            }
338        } else if (params->encryption.key_length != 8*sizeof(bcrypto_keyladder_data) || !params->encryption.long_key) {
339            return BSETTOP_ERROR(berr_invalid_parameter);
340        }
341        recpumpSettings.securityContext = b_keyslot_m2m_allocate(&params->encryption,true,
342            recpumpSettings.timestampType==NEXUS_TransportTimestampType_eNone?false:true);
343        recpump->hKeySlot = recpumpSettings.securityContext;
344#if NEXUS_HAS_DMA
345        recpumpSettings.securityDma = g_dma.hDma;
346        BDBG_MSG(("Enabling encryption on record: slot: %p, dma: %p",recpumpSettings.securityContext,recpumpSettings.securityDma));
347#else
348        BDBG_MSG(("Enabling encryption on record: slot: %p",recpumpSettings.securityContext));
349#endif
350        if (!recpumpSettings.securityContext
351#if NEXUS_HAS_DMA
352                || !recpumpSettings.securityDma
353#endif
354                ) {
355            BDBG_ERR(("Enabling encryption on record FAILED!"));
356#if NEXUS_HAS_DMA
357            BDBG_ERR(("slot: %p, dma: %p",recpumpSettings.securityContext,recpumpSettings.securityDma));
358#else
359            BDBG_ERR(("slot: %p",recpumpSettings.securityContext));
360#endif
361            return BSETTOP_ERROR(berr_external_error);
362        }
363#else
364        BDBG_ERR(("PVR encryption is not supported"));
365        return BSETTOP_ERROR(berr_invalid_parameter);
366#endif
367    } else {
368#if NEXUS_HAS_SECURITY
369        recpumpSettings.securityContext = NULL;
370#if NEXUS_HAS_DMA
371        recpumpSettings.securityDma = NULL;
372#endif
373#endif
374    }
375    NEXUS_Recpump_SetSettings(recpump->nRecpump, &recpumpSettings);
376
377    if(stream->mpeg.video[0].pid == 0 && (stream->mpeg.audio[0].pid==0 || stream->mpeg.audio[0].pid >= 0x1fff))
378    {
379        BDBG_WRN(("todo add suppport for all pass record"));
380        return BSETTOP_ERROR(berr_not_supported);
381    }
382
383    recpump->params = *params;
384    recpump->stream = stream;
385
386    /* relying on the mpeg structure to give us the pids, starting from video pids */
387    brecpump_p_mpeg_change(recpump, &stream->mpeg);
388
389    rc = NEXUS_Recpump_Start(recpump->nRecpump);
390    if ( rc )
391    {
392        recpump->stream = NULL;
393        brecpump_p_mpeg_change(recpump, NULL);
394        return BSETTOP_ERROR(berr_external_error);
395    }
396
397    return b_ok;
398}
399
400bresult brecpump_stop(brecpump_t recpump)
401{
402    BDBG_OBJECT_ASSERT(recpump, brecpump);
403    /* Remove all pid channels */
404    brecpump_p_mpeg_change(recpump, NULL);
405    NEXUS_Recpump_StopData(recpump->nRecpump);
406    recpump->stream->consumers.recpump = NULL;
407    recpump->stream = NULL;
408
409    if (recpump->hKeySlot) {
410        b_keyslot_m2m_free(recpump->hKeySlot);
411        recpump->hKeySlot = NULL;
412    }
413
414    return b_ok;
415}
416
417void brecpump_immediate_stop(brecpump_t recpump)
418{
419    BDBG_OBJECT_ASSERT(recpump, brecpump);
420    /* Remove all pid channels */
421    brecpump_p_mpeg_change(recpump, NULL);
422    NEXUS_Recpump_Stop(recpump->nRecpump);
423    recpump->stream->consumers.recpump = NULL;
424    recpump->stream = NULL;
425}
426
427bresult brecpump_data_get_buffer(brecpump_t recpump, const void **buffer,  size_t *buffer_size )
428{
429    BDBG_OBJECT_ASSERT(recpump, brecpump);
430    if(NEXUS_Recpump_GetDataBuffer(recpump->nRecpump, buffer, buffer_size))
431    {
432        return BSETTOP_ERROR(berr_external_error);
433    }
434    return b_ok;
435}
436
437bresult brecpump_index_get_buffer(brecpump_t recpump, const void **buffer,  size_t *buffer_size )
438{
439    BDBG_OBJECT_ASSERT(recpump, brecpump);
440    if(NEXUS_Recpump_GetIndexBuffer(recpump->nRecpump, buffer, buffer_size))
441    {
442        return BSETTOP_ERROR(berr_external_error);
443    }
444    return b_ok;
445}
446
447bresult brecpump_data_write_complete(brecpump_t recpump, size_t amount_written)
448{
449    BDBG_OBJECT_ASSERT(recpump, brecpump);
450    if(NEXUS_Recpump_DataWriteComplete(recpump->nRecpump, amount_written))
451    {
452        return BSETTOP_ERROR(berr_external_error);
453    }
454    return b_ok;
455}
456
457bresult brecpump_index_write_complete(brecpump_t recpump, size_t amount_written)
458{
459    BDBG_OBJECT_ASSERT(recpump, brecpump);
460    if(NEXUS_Recpump_IndexWriteComplete(recpump->nRecpump, amount_written))
461    {
462        return BSETTOP_ERROR(berr_external_error);
463    }
464    return b_ok;
465}
466
467void brecpump_get_status(brecpump_t recpump, brecpump_status *status )
468{
469    NEXUS_RecpumpStatus recpumpStatus;
470
471    BDBG_OBJECT_ASSERT(recpump, brecpump);
472    if(NEXUS_Recpump_GetStatus(recpump->nRecpump,&recpumpStatus))
473    {
474        BSETTOP_ERROR(berr_external_error);
475        return;
476    }
477    status->has_index = recpumpStatus.hasIndex;
478    status->index_bytes_recorded = recpumpStatus.index.bytesRecorded;
479    status->index_fifo_depth = recpumpStatus.index.fifoDepth;
480    status->index_fifo_size = recpumpStatus.index.fifoSize;
481    status->last_timestamp = 0; /* not supported in Nexus recpump */
482    status->mpeg_bytes_recorded = recpumpStatus.data.bytesRecorded;
483    status->mpeg_fifo_depth = recpumpStatus.data.fifoDepth;
484    status->mpeg_fifo_size = recpumpStatus.data.fifoSize;
485}
486
487
488static void brecpump_p_mpeg_change_allpass(brecpump_t recpump , const bstream_mpeg *new_settings)
489{
490    uint16_t pid=0;
491    int index=0;
492    NEXUS_Error errCode;
493    bstream_t stream = recpump->stream;
494    NEXUS_RecpumpAddPidChannelSettings *pRecpumpPidChannelSettings=NULL;
495
496#if NEXUS_HAS_PLAYBACK
497    if (stream->producer.playback)
498    {
499        NEXUS_PlaybackSettings playbackSettings;
500        NEXUS_PlaypumpStatus playpumpStatus;
501        NEXUS_Playback_GetSettings(stream->producer.playback->nPlayback, &playbackSettings);
502        NEXUS_Playpump_GetStatus(playbackSettings.playpump,&playpumpStatus);
503        if (new_settings->audio[0].pid == 0xFFFF)
504        {
505            pid = 0xFFFF;
506            playbackSettings.playpumpSettings.acceptNullPackets=false;
507        }
508        else
509        {
510            pid = 0x1FFF;
511            playbackSettings.playpumpSettings.acceptNullPackets=true;
512        }
513        playbackSettings.playpumpSettings.allPass=true;
514        NEXUS_Playback_SetSettings(stream->producer.playback->nPlayback, &playbackSettings);
515        BDBG_WRN(("Setting playback %d to allpass mode %s null packets",playpumpStatus.index,
516                  playbackSettings.playpumpSettings.acceptNullPackets?"with":"without"));
517    }
518    else
519#endif /* Does not have playback support from NEXUS */
520    if (stream->producer.playpump)
521        {
522        NEXUS_PlaypumpSettings playpumpSettings;
523        NEXUS_PlaypumpStatus playpumpStatus;
524        NEXUS_Playpump_GetSettings(stream->producer.playpump->nPlaypump, &playpumpSettings);
525        NEXUS_Playpump_GetStatus(stream->producer.playpump->nPlaypump,&playpumpStatus);
526        if (new_settings->audio[0].pid == 0xFFFF)
527        {
528            pid = 0xFFFF;
529            playpumpSettings.acceptNullPackets=false;
530        }
531        else
532        {
533            pid = 0x1FFF;
534            playpumpSettings.acceptNullPackets=true;
535        }
536        playpumpSettings.allPass=true;
537        NEXUS_Playpump_SetSettings(stream->producer.playpump->nPlaypump, &playpumpSettings);
538        BDBG_WRN(("Setting playpump %d to allpass mode %s null packets",playpumpStatus.index,
539                  playpumpSettings.acceptNullPackets?"with":"without"));
540    }
541    else if (stream->producer.band)
542    {
543        NEXUS_ParserBandSettings parserBandSettings;
544        NEXUS_ParserBand_GetSettings(stream->parser_band->nParserBand, &parserBandSettings);
545        if (new_settings->audio[0].pid == 0xFFFF)
546        {
547            pid = 0xFFFF;
548            parserBandSettings.acceptNullPackets=false;
549        }
550        else
551        {
552            pid = 0x1FFF;
553            parserBandSettings.acceptNullPackets=true;
554        }
555
556        parserBandSettings.allPass=true;
557        NEXUS_ParserBand_SetSettings(stream->parser_band->nParserBand, &parserBandSettings);
558
559        BDBG_WRN(("Setting parser band %d to allpass mode %s null packets",stream->parser_band->nParserBand,
560                  parserBandSettings.acceptNullPackets?"with":"without"));
561    }
562    else
563    {
564        BDBG_ERR(("Unknown producer"));
565        return;
566    }
567
568    /* remove and close pid record pid channels */
569    for ( index=0; index < BSETTOP_MAX_PROGRAMS; index++ )
570    {
571        if ( recpump->videoPid[index] )
572        {
573            NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->videoPid[index]);
574            bstream_p_close_pid(recpump->stream, recpump->videoPid[index]);
575            recpump->videoPid[index] = NULL;
576        }
577        if ( recpump->audioPid[index] )
578        {
579            NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->audioPid[index]);
580            bstream_p_close_pid(recpump->stream, recpump->audioPid[index]);
581            recpump->audioPid[index] = NULL;
582        }
583        if ( recpump->ancillaryPid[index] )
584        {
585            NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->ancillaryPid[index]);
586            bstream_p_close_pid(recpump->stream, recpump->ancillaryPid[index]);
587            recpump->ancillaryPid[index] = NULL;
588        }
589    }
590    /* Add pid channnel to record */
591    recpump->videoPid[0] = bstream_p_open_pid(recpump->stream,pid, bstream_pid_type_other);
592    if ( NULL == recpump->videoPid[0] )
593    {
594        BDBG_WRN(("Unable to allocate record pid channel for all pass record"));
595        BSETTOP_ERROR(berr_external_error);
596    }
597
598#if ALLPASS_RECORD_WITH_INDEX
599    {
600        NEXUS_RecpumpAddPidChannelSettings pidCfg;
601        NEXUS_Recpump_GetDefaultAddPidChannelSettings(&pidCfg);
602        pidCfg.pidType = NEXUS_PidType_eVideo;
603        pidCfg.pidTypeSettings.video.index = true;
604        pidCfg.pidTypeSettings.video.codec = b_videocodec2nexus(new_settings->video[1].format);
605        /* generate index using pid number instead of pid chanel number */
606        pidCfg.pidTypeSettings.video.pid = new_settings->video[1].pid;
607        pRecpumpPidChannelSettings= &pidCfg;
608    }
609#endif
610
611    errCode = NEXUS_Recpump_AddPidChannel(recpump->nRecpump, recpump->videoPid[0], pRecpumpPidChannelSettings);
612    if ( errCode )
613    {
614        BDBG_ERR(("Unable to add record pid channel"));
615        BSETTOP_ERROR(berr_external_error);
616    }
617
618
619    return;
620}
621
622void brecpump_p_mpeg_change(brecpump_t recpump, const bstream_mpeg *new_settings)
623{
624    int index;
625    NEXUS_Error errCode;
626#if 0
627    bstream_mpeg empty_settings;
628#endif
629
630    BDBG_OBJECT_ASSERT(recpump, brecpump);
631    BDBG_ASSERT(NULL != recpump->stream);
632
633
634    /* check to see if we all pass record is requested */
635    if(new_settings)
636    {
637        for ( index=0; index < BSETTOP_MAX_PROGRAMS; index++ )
638        {
639            if(new_settings->ancillary[index].pid)
640                break;
641            if(new_settings->audio[index].pid && new_settings->audio[index].pid != 0xFFFF &&  new_settings->audio[index].pid != 0x1FFF  )
642                break;
643#if ALLPASS_RECORD_WITH_INDEX
644            /* Ignore the video PID */
645            if(index==1)
646                continue;
647#endif
648            if(new_settings->video[index].pid)
649                break;
650        }
651        if(index == BSETTOP_MAX_PROGRAMS)
652        {
653            brecpump_p_mpeg_change_allpass(recpump,new_settings);
654            return;
655        }
656    }
657    else
658    {
659        /* remove and close pid record pid channels */
660        for ( index=0; index < BSETTOP_MAX_PROGRAMS; index++ )
661        {
662            if ( recpump->videoPid[index] )
663            {
664                NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->videoPid[index]);
665                bstream_p_close_pid(recpump->stream, recpump->videoPid[index]);
666                recpump->videoPid[index] = NULL;
667            }
668            if ( recpump->audioPid[index] )
669            {
670                NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->audioPid[index]);
671                bstream_p_close_pid(recpump->stream, recpump->audioPid[index]);
672                recpump->audioPid[index] = NULL;
673            }
674            if ( recpump->ancillaryPid[index] )
675            {
676                NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->ancillaryPid[index]);
677                bstream_p_close_pid(recpump->stream, recpump->ancillaryPid[index]);
678                recpump->ancillaryPid[index] = NULL;
679            }
680        }
681        return;
682    }
683#if 0
684    /* Free all PID channels with NULL settings */
685    if ( NULL == new_settings )
686    {
687        bstream_mpeg_init(&empty_settings);
688        new_settings = &empty_settings;
689    }
690#endif
691
692    for ( index=0; index < BSETTOP_MAX_PROGRAMS; index++ )
693    {
694        if ( (recpump->stream->mpeg.video[index].pid != new_settings->video[index].pid) ||
695             (new_settings->video[index].pid != 0 && new_settings->video[index].pid < 0x1fff &&
696              NULL == recpump->videoPid[index]) )
697        {
698            if ( recpump->videoPid[index] )
699            {
700                NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->videoPid[index]);
701                bstream_p_close_pid(recpump->stream, recpump->videoPid[index]);
702                recpump->videoPid[index] = NULL;
703            }
704            if ( new_settings->video[index].pid != 0 &&
705                 new_settings->video[index].pid < 0x1fff )
706            {
707                recpump->videoPid[index] = bstream_p_open_pid(recpump->stream, new_settings->video[index].pid, bstream_pid_type_video);
708                if ( NULL == recpump->videoPid[index] )
709                {
710                    BDBG_WRN(("Unable to allocate record pid channel for pid 0x%x (%d)", new_settings->video[index].pid, new_settings->video[index].pid));
711                    BSETTOP_ERROR(berr_external_error);
712                }
713                else
714                {
715                    NEXUS_RecpumpAddPidChannelSettings addPidChannelSettings;
716                    NEXUS_Recpump_GetDefaultAddPidChannelSettings(&addPidChannelSettings);
717                    addPidChannelSettings.pidType = NEXUS_PidType_eVideo;
718                    addPidChannelSettings.pidTypeSettings.video.codec = b_videocodec2nexus(new_settings->video[index].format);
719                    if ( 0 == index && recpump->params.index_write_callback )
720                        addPidChannelSettings.pidTypeSettings.video.index = true;
721                    else
722                        addPidChannelSettings.pidTypeSettings.video.index = false;
723
724                    errCode = NEXUS_Recpump_AddPidChannel(recpump->nRecpump, recpump->videoPid[index], &addPidChannelSettings);
725                    if ( errCode )
726                    {
727                        BDBG_ERR(("Unable to add record pid channel"));
728                        BSETTOP_ERROR(berr_external_error);
729                    }
730                }
731            }
732        }
733        if ( (recpump->stream->mpeg.audio[index].pid != new_settings->audio[index].pid) ||
734             (new_settings->audio[index].pid != 0 && new_settings->audio[index].pid < 0x1fff &&
735              NULL == recpump->audioPid[index]) )
736        {
737            if ( recpump->audioPid[index] )
738            {
739                NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->audioPid[index]);
740                bstream_p_close_pid(recpump->stream, recpump->audioPid[index]);
741                recpump->audioPid[index] = NULL;
742            }
743            if ( new_settings->audio[index].pid != 0 &&
744                 new_settings->audio[index].pid < 0x1fff )
745            {
746                recpump->audioPid[index] = bstream_p_open_pid(recpump->stream, new_settings->audio[index].pid, bstream_pid_type_other);
747                if ( NULL == recpump->audioPid[index] )
748                {
749                    BDBG_WRN(("Unable to allocate record pid channel for pid 0x%x (%d)", new_settings->audio[index].pid, new_settings->audio[index].pid));
750                    BSETTOP_ERROR(berr_external_error);
751                }
752                else
753                {
754                    errCode = NEXUS_Recpump_AddPidChannel(recpump->nRecpump, recpump->audioPid[index], NULL);
755                    if ( errCode )
756                    {
757                        BDBG_ERR(("Unable to add record pid channel"));
758                        BSETTOP_ERROR(berr_external_error);
759                    }
760                }
761            }
762        }
763        if ( (recpump->stream->mpeg.ancillary[index].pid != new_settings->ancillary[index].pid) ||
764             (new_settings->ancillary[index].pid != 0 && new_settings->ancillary[index].pid < BSETTOP_PAT_PID &&
765              NULL == recpump->ancillaryPid[index]) )
766        {
767            if ( recpump->ancillaryPid[index] )
768            {
769                NEXUS_Recpump_RemovePidChannel(recpump->nRecpump, recpump->ancillaryPid[index]);
770                bstream_p_close_pid(recpump->stream, recpump->ancillaryPid[index]);
771                recpump->ancillaryPid[index] = NULL;
772            }
773            if ( new_settings->ancillary[index].pid != 0 &&
774                 new_settings->ancillary[index].pid < 0x1fff )
775            {
776                uint16_t pid;
777                pid = new_settings->ancillary[index].pid;
778                if ( pid == BSETTOP_PAT_PID )
779                {
780                    pid = 0;
781                }
782                recpump->ancillaryPid[index] = bstream_p_open_pid(recpump->stream, pid, bstream_pid_type_other);
783                if ( NULL == recpump->ancillaryPid[index] )
784                {
785                    BDBG_WRN(("Unable to allocate record pid channel for pid 0x%x (%d)", new_settings->ancillary[index].pid, new_settings->ancillary[index].pid));
786                    BSETTOP_ERROR(berr_external_error);
787                }
788                else
789                {
790                    errCode = NEXUS_Recpump_AddPidChannel(recpump->nRecpump, recpump->ancillaryPid[index], NULL);
791                    if ( errCode )
792                    {
793                        BDBG_ERR(("Unable to add record pid channel"));
794                        BSETTOP_ERROR(berr_external_error);
795                    }
796                }
797            }
798        }
799    }
800}
801
Note: See TracBrowser for help on using the repository browser.