source: svn/newcon3bcm2_21bu/BSEAV/api/src/nexus/bsettop_stream.c @ 22

Last change on this file since 22 was 22, checked in by phkim, 11 years ago
  1. phkim
  2. newcon3sk 를 kctv 로 브랜치 함
  • Property svn:executable set to *
File size: 29.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-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_stream.c $
11 * $brcm_Revision: 35 $
12 * $brcm_Date: 3/16/10 10:48a $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/api/src/nexus/bsettop_stream.c $
19 *
20 * 35   3/16/10 10:48a jtna
21 * SW3556-1051: revert back to host-reordering
22 *
23 * 34   2/16/10 5:42p jtna
24 * SW3556-1051: use video decoder timestamp reordering
25 *
26 * 33   12/9/09 12:04p gmohile
27 * SW7408-1 : Add 7408 support
28 *
29 * 32   5/12/09 7:39p bandrews
30 * PR54955: qualify timestamp flag with B_HAS_IP
31 *
32 * 31   5/11/09 4:34p ssood
33 * PR54955: Record TTS streams over HTTP: set flag in stream status to
34 * indicate a TTS stream
35 *
36 * 30   10/16/08 6:20p katrep
37 * PR47690: Adding allpass record from playback parser
38 *
39 * 29   9/25/08 1:06p katrep
40 * PR47154: Add support for recording with null packets and without null
41 * packets
42 *
43 * 28   9/22/08 1:59p katrep
44 * PR47154: Add support for allpass record
45 *
46 * 27   9/19/08 5:06p vishk
47 * PR 47150: Coverity Issues.
48 *
49 * 26   9/15/08 5:40p jrubio
50 * PR46925:  fix PVR_SUPPORT=n compile issue
51 *
52 * 25   8/14/08 11:24a vishk
53 * PR 4537: bstream_vbi_settings structure call-back is not being called
54 * when data is ready
55 *
56 * 24   7/23/08 1:52p erickson
57 * PR44874: fix bstream_close
58 *
59 * 23   7/22/08 2:59p erickson
60 * PR44874: allow static allocation of bstream for playback. this is
61 * required to support bstream_close after a bplayback_stop.
62 *
63 * 22   7/18/08 4:21p erickson
64 * PR44919: improve DBG
65 *
66 * 21   7/2/08 4:59p vishk
67 * PR 40020: bsettop_stream (crypto, network decryption): Develop
68 * SettopAPI-to-Nexus shim layer
69 *
70 * 20   5/2/08 9:20a erickson
71 * PR42339: fix pid channel alloc for PVR
72 *
73 * 19   5/1/08 4:08p erickson
74 * PR42339: remove unnecessary stream.dynamic
75 *
76 * 18   4/28/08 11:54a erickson
77 * PR42197: remove NEXUS_ParserBand_ePlayback enums
78 *
79 * 17   4/25/08 1:01p erickson
80 * PR41951: don't close the nIndexPid if it was reused for video
81 *
82 * 16   4/15/08 12:09p erickson
83 * PR36068: fix analog
84 *
85 * 15   4/10/08 10:02a erickson
86 * PR36068: coverity fix
87 *
88 * 14   4/9/08 5:54p jgarrett
89 * PR 41567: Adding playback video pid management for indexing
90 *
91 * 13   4/7/08 10:40a jgarrett
92 * PR 41362: Revising pid channel management
93 *
94 * 12   3/25/08 10:10a erickson
95 * PR36068: added analog tuner
96 *
97 * 11   3/20/08 12:04p katrep
98 * PR40699: Use a new parser band if stream is opened for same input band
99 * (eg for PIP )
100 *
101 * 10   3/11/08 2:05p jrubio
102 * PR40019: add pcr functions
103 *
104 * 9   3/10/08 4:55p katrep
105 * PR40019: Move the header files to bsettop_impl.h
106 *
107 * 8   3/10/08 4:49p katrep
108 * PR40019: Inputs bands need to configured correctly for the stream types
109 * , mpeg vs dss
110 *
111 * 7   1/24/08 3:13p jgarrett
112 * PR 38919: Renaming NEXUS_Platform_GetStreamerInputBand
113 *
114 * 6   11/13/07 11:58a erickson
115 * PR36068: trick modes working
116 *
117 * 5   11/12/07 5:26p erickson
118 * PR36802: call NEXUS_Platform_GetStreamerInputBand for streamer input
119 * band conversion
120 *
121 * 4   11/12/07 2:34p erickson
122 * PR36068: update
123 *
124 * 3   10/16/07 2:30p erickson
125 * PR36068: added refcnt to parser_band for message filtering
126 *
127 * 2   10/16/07 12:35p erickson
128 * PR36068: brutus up over settop api/nexus
129 *
130 * 1   10/15/07 2:36p erickson
131 * PR36068: initial
132 *
133 ***************************************************************************/
134#include "bsettop_impl.h"
135
136BDBG_MODULE(stream);
137
138#if NEXUS_NUM_INPUT_BANDS
139struct bband g_bands[B_MAX_INPUTS];
140#endif
141#if NEXUS_NUM_PARSER_BANDS
142struct bparser_band g_parserBands[B_MAX_PARSERS];
143#endif
144struct bparser_band g_playbackParserBands[B_PVR_N_PLAYBACKS];
145BDBG_OBJECT_ID(bstream);
146
147unsigned b_get_parser_band(bband_t band)
148{
149#if NEXUS_NUM_PARSER_BANDS
150    unsigned i;
151    for (i=0;i<B_MAX_PARSERS;i++) {
152        if (g_parserBands[i].band == band) {
153            return i;
154        }
155    }
156    BDBG_ERR(("unmapped input band"));
157#else
158    BSTD_UNUSED(band);
159#endif
160
161    return 0;
162}
163
164void bstream_p_init()
165{
166#if NEXUS_NUM_INPUT_BANDS
167    unsigned i;
168    BKNI_Memset(g_bands, 0, sizeof(g_bands));
169    for (i=0;i<B_MAX_INPUTS;i++) {
170        bband_t band = &g_bands[i];
171        band->nInputBand = (NEXUS_InputBand)i;
172        band->mpeg_type = bstream_mpeg_type_ts;
173    }
174#endif
175#if NEXUS_NUM_PARSER_BANDS
176    BKNI_Memset(g_parserBands, 0, sizeof(g_parserBands));
177    for (i=0;i<B_MAX_PARSERS;i++) {
178        struct bparser_band *parser_band = &g_parserBands[i];
179        parser_band->nParserBand = (NEXUS_ParserBand)i;
180    }
181#endif
182    BKNI_Memset(g_playbackParserBands, 0, sizeof(g_playbackParserBands));
183}
184
185void bstream_mpeg_init(bstream_mpeg *mpeg)
186{
187    BKNI_Memset(mpeg, 0, sizeof(*mpeg));
188    mpeg->video[0].format = bvideo_codec_mpeg2;
189    mpeg->audio[0].format = baudio_format_mpeg;
190    mpeg->mpeg_type = bstream_mpeg_type_ts;
191    bencryption_params_init(&mpeg->encryption);
192}
193
194bband_t bstreamer_attach(bobject_t id, bstream_mpeg_type mpeg_type)
195{
196#if NEXUS_NUM_INPUT_BANDS
197    unsigned bandnum = B_ID_GET_INDEX(id);
198    bband_t band = NULL;
199
200    if (bandnum < 100) {
201        NEXUS_Platform_GetStreamerInputBand(bandnum, &bandnum);
202        if (bandnum < B_MAX_INPUTS) {
203            band = &g_bands[bandnum];
204        }
205    }
206    else if (bandnum-100 < B_MAX_INPUTS) {
207        band = &g_bands[bandnum - 100];
208    }
209
210    if (band) {
211        /* TODO: config input band */
212        band->mpeg_type = mpeg_type;
213    }
214    else {
215        BDBG_ERR(("bstreamer_attach failed for %d (max %d)", bandnum, B_MAX_INPUTS));
216        band = NULL;
217        BSETTOP_ERROR(berr_not_available);
218    }
219    return band;
220#else
221    BSTD_UNUSED(id);
222    BSTD_UNUSED(mpeg_type);
223    return NULL;
224#endif
225}
226
227bstream_t bstream_p_open_message(bband_t band, const bstream_mpeg *mpeg)
228{
229#if NEXUS_NUM_PARSER_BANDS
230    unsigned i;
231
232    /* try to use a parser band already in use */
233    for (i=0;i<B_MAX_PARSERS;i++) {
234        if (g_parserBands[i].band == band) {
235            return bstream_p_open(band, NULL, NULL, i, mpeg);
236        }
237    }
238
239    /* otherwise, alloc a new parser band */
240    return bstream_open(band, mpeg);
241#else
242    BSTD_UNUSED(band);
243    BSTD_UNUSED(mpeg);
244    return NULL;
245#endif
246}
247
248bstream_t bstream_open(bband_t band, const bstream_mpeg *mpeg)
249{
250#if NEXUS_NUM_PARSER_BANDS
251    unsigned parser_band, i;
252
253    BDBG_MSG(("bstream_open %d", band->nInputBand));
254    /* assigned parser band, preferring straight mapping first */
255    parser_band = band->nInputBand;
256    /* look for available parser band if this parser band is taken */
257    if (g_parserBands[parser_band].band){
258        for (i=0;i<B_MAX_PARSERS;i++) {
259            if (!g_parserBands[i].band) break;
260        }
261        if (i == B_MAX_PARSERS) {
262            BDBG_ERR(("no more parser bands"));
263            return NULL;
264        }
265        else {
266            BDBG_MSG(("Using parser band %d with input band %d",i,band->nInputBand));
267            parser_band =i;
268        }
269
270    }
271    return bstream_p_open(band, NULL, NULL, parser_band, mpeg);
272#else
273    BSTD_UNUSED(band);
274    BSTD_UNUSED(mpeg);
275    return NULL;
276#endif
277}
278#define BSETTOP_MAX_FCC_STREAMS 3
279bool g_has_fcc = false;
280typedef struct fcc_stream_t
281{
282        bool                in_use;             /* flag indicating the context is in use */
283        int                                     index;          /* stream index */
284        NEXUS_VideoDecoderHandle videoDecoder;
285
286}fcc_stream_t;
287
288static fcc_stream_t s_fcc_streams[BSETTOP_MAX_FCC_STREAMS] =
289{
290        { false, 0, NULL},
291        { false, 1, NULL},
292        { false, 2, NULL}
293};
294
295void bstream_p_fcc_init(NEXUS_VideoDecoderHandle videoDecodeHandle)
296{
297        int i;
298        for (i = 0; i < BSETTOP_MAX_FCC_STREAMS; ++i)
299        {
300                s_fcc_streams[i].videoDecoder = videoDecodeHandle;
301        }
302        g_has_fcc = true;
303}
304
305/*
306Summary:
307        Find available stream.
308 */
309
310static fcc_stream_t *bstream_p_find_fcc_stream(void)
311{
312        int i; 
313
314        for (i = 0; i < BSETTOP_MAX_FCC_STREAMS; ++i)
315        {
316                if (!s_fcc_streams[i].in_use)
317                        return(fcc_stream_t*)&s_fcc_streams[i];
318        }
319        return NULL;
320}
321
322bstream_t bstream_p_open(bband_t band, bplaypump_t playpump, bplayback_t playback,
323    unsigned parser_band, const bstream_mpeg *mpeg)
324{
325    bstream_t stream;
326    bresult result;
327
328    stream = BKNI_Malloc(sizeof(*stream));
329    BKNI_Memset(stream, 0, sizeof(*stream));
330    BDBG_OBJECT_SET(stream, bstream);
331
332    if (!band) {
333        if (playpump) {
334            stream->producer.playpump = playpump;
335        }
336        else {
337            BDBG_ASSERT(playback);
338            stream->producer.playback = playback;
339        }
340    }
341#if NEXUS_NUM_PARSER_BANDS
342    else {
343        BDBG_ASSERT(!playpump && !playback);
344        BDBG_MSG(("map input band %d to live parser band %d", band->nInputBand, parser_band));
345        stream->producer.band = band;
346        stream->parser_band = &g_parserBands[parser_band];
347        stream->parser_band->band = band;
348        stream->parser_band->refcnt++;
349        BDBG_MSG(("  refcnt %d", stream->parser_band->refcnt));
350    }
351#else
352    BSTD_UNUSED(parser_band);
353#endif
354    result = bstream_p_set(stream, mpeg);
355    if (result) {result = BERR_TRACE(result); goto err_set;}
356
357    return stream;
358
359err_set:
360    (void)bstream_p_set(stream, NULL);
361    BDBG_OBJECT_DESTROY(stream, bstream);
362    BKNI_Free(stream);
363    return NULL;
364}
365
366
367static bresult bstream_p_fcc_close(bstream_t stream)
368{
369        fcc_stream_t *p_fcc_stream = &(s_fcc_streams[stream->producer.fcc.index]);
370
371        if (!p_fcc_stream->in_use)
372        {
373                return b_ok;
374        }
375
376        if (stream->producer.fcc.primerHandle)
377        {
378                NEXUS_VideoDecoder_StopPrimer(stream->producer.fcc.videoDecoder, stream->producer.fcc.primerHandle);
379                NEXUS_VideoDecoder_ClosePrimer(stream->producer.fcc.videoDecoder,stream->producer.fcc.primerHandle);
380        }
381        if (stream->producer.fcc.stcChannel)
382                NEXUS_StcChannel_Close(stream->producer.fcc.stcChannel);
383        if (stream->producer.fcc.pcrPidChannel && (stream->producer.fcc.pcrPidChannel != stream->producer.fcc.videoPidChannel))
384                NEXUS_PidChannel_Close(stream->producer.fcc.pcrPidChannel);
385        if (stream->producer.fcc.videoPidChannel)
386                NEXUS_PidChannel_Close(stream->producer.fcc.videoPidChannel);
387        stream->producer.fcc.videoDecoder = NULL;
388        stream->producer.fcc.primerHandle = NULL;
389        stream->producer.fcc.videoPidChannel = NULL;
390        stream->producer.fcc.pcrPidChannel = NULL;
391        stream->producer.fcc.stcChannel = NULL;
392        p_fcc_stream->in_use = false;
393        return b_ok;
394}
395
396
397static bresult bstream_p_fcc_open(bstream_t stream)
398{
399        NEXUS_StcChannelSettings stcSettings;
400        fcc_stream_t *p_fcc_stream;
401    bresult result;
402        p_fcc_stream = bstream_p_find_fcc_stream();
403
404    if ( !g_has_fcc || !p_fcc_stream)
405                return berr_not_available;
406
407        stream->producer.fcc.videoPidChannel = NEXUS_PidChannel_Open(stream->parser_band->nParserBand,stream->mpeg.video[0].pid,NULL);
408        if (!stream->producer.fcc.videoPidChannel)
409        {
410                BDBG_WRN(("NEXUS_PidChannel_Open Video PID = 0x%04x\n",stream->mpeg.video[0].pid));
411                goto err_set;
412        }
413
414        if (stream->mpeg.pcr_pid == stream->mpeg.video[0].pid)
415        {
416                stream->producer.fcc.pcrPidChannel = stream->producer.fcc.videoPidChannel;
417        }
418       
419        if ((stream->mpeg.pcr_pid != 0) && (stream->producer.fcc.pcrPidChannel == NULL))
420        {
421                stream->producer.fcc.pcrPidChannel = NEXUS_PidChannel_Open(stream->parser_band->nParserBand,stream->mpeg.pcr_pid,NULL);
422                if (!stream->producer.fcc.pcrPidChannel)
423                {
424                        BDBG_WRN(("NEXUS_PidChannel_Open PCR PID = 0x%04x\n",stream->mpeg.pcr_pid));
425                        goto err_set;
426                }
427        }
428
429        NEXUS_StcChannel_GetDefaultSettings(0, &stcSettings);
430        stcSettings.autoConfigTimebase = false; /* must do it manually */
431        stcSettings.timebase = NEXUS_Timebase_e0;
432        stcSettings.mode = NEXUS_StcChannelMode_ePcr; /* live */
433        stcSettings.modeSettings.pcr.pidChannel = stream->producer.fcc.pcrPidChannel;
434        stcSettings.modeSettings.pcr.offsetThreshold = 0;
435        stcSettings.stcIndex = 0;
436        stcSettings.modeSettings.Auto.behavior = NEXUS_StcChannelAutoModeBehavior_eFirstAvailable;
437        stcSettings.modeSettings.Auto.transportType = NEXUS_TransportType_eTs;
438        stream->producer.fcc.stcChannel = NEXUS_StcChannel_Open(p_fcc_stream->index, &stcSettings);
439        if (!stream->producer.fcc.stcChannel)
440        {
441                BDBG_WRN(("NEXUS_StcChannel_Open %d\n",p_fcc_stream->index));
442                goto err_set;
443        }
444
445        stream->producer.fcc.videoDecoder = p_fcc_stream->videoDecoder;
446        NEXUS_VideoDecoder_GetDefaultStartSettings(&(stream->producer.fcc.decodeSettings));
447        stream->producer.fcc.decodeSettings.codec = stream->mpeg.video[0].format;
448        stream->producer.fcc.decodeSettings.pidChannel = stream->producer.fcc.videoPidChannel;
449        stream->producer.fcc.decodeSettings.stcChannel = stream->producer.fcc.stcChannel;
450        stream->producer.fcc.decodeSettings.prerollRate = 1;
451        stream->producer.fcc.primerHandle = NEXUS_VideoDecoder_OpenPrimer(stream->producer.fcc.videoDecoder);
452        if (!stream->producer.fcc.primerHandle)
453        {
454                BDBG_WRN(("NEXUS_VideoDecoder_OpenPrimer failed %d\n",p_fcc_stream->index));
455                goto err_set;
456        }
457
458        if (NEXUS_VideoDecoder_StartPrimer(stream->producer.fcc.videoDecoder, 
459                                                                   stream->producer.fcc.primerHandle, &(stream->producer.fcc.decodeSettings)) != NEXUS_SUCCESS)
460        {
461                BDBG_WRN(("NEXUS_VideoDecoder_StartPrimer failed %d\n",p_fcc_stream->index));
462                goto err_set;
463        }
464       
465        p_fcc_stream->in_use = true;
466        return b_ok;
467
468err_set:
469       
470        bstream_p_fcc_close(stream);
471
472        return berr_not_available;
473}
474
475bresult bstream_p_set(bstream_t stream, const bstream_mpeg *mpeg)
476{
477    bresult result;
478    BDBG_OBJECT_ASSERT(stream, bstream);
479
480#if NEXUS_NUM_PARSER_BANDS
481    if (stream->parser_band) {
482            NEXUS_ParserBandSettings parserBandSettings;
483            NEXUS_ParserBand_GetSettings(stream->parser_band->nParserBand, &parserBandSettings);
484        if (mpeg) {
485            /* Map input band and parser band. This could be eliminated because a straight mapping and TS config is a good default. */
486            parserBandSettings.sourceType = NEXUS_ParserBandSourceType_eInputBand;
487            parserBandSettings.sourceTypeSettings.inputBand = stream->parser_band->band->nInputBand;
488            switch(mpeg->mpeg_type)
489            {
490            case bstream_mpeg_type_ts:
491                parserBandSettings.transportType = NEXUS_TransportType_eTs;
492                break;
493            case bstream_mpeg_type_dss_es:
494                parserBandSettings.transportType = NEXUS_TransportType_eDssEs;
495                break;
496            case bstream_mpeg_type_dss_pes:
497                parserBandSettings.transportType = NEXUS_TransportType_eDssPes;
498                break;
499            default:
500                BDBG_ERR(("Unsupported mpeg_type %d",mpeg->mpeg_type));
501            }
502           
503        }
504        else {
505            /* we need parser band get default settings ???? */
506            parserBandSettings.acceptNullPackets=false;
507            parserBandSettings.allPass=false;
508        }
509        NEXUS_ParserBand_SetSettings(stream->parser_band->nParserBand, &parserBandSettings);
510    }
511#endif
512#if NEXUS_HAS_PLAYBACK
513    if ( stream->producer.playback )
514    {
515        if (mpeg)
516        {
517            if ( mpeg->video[0].pid > 0 && mpeg->video[0].pid < 0x1fff )
518            {
519                NEXUS_PlaybackPidChannelSettings pidChannelSettings;
520                NEXUS_Playback_GetDefaultPidChannelSettings(&pidChannelSettings);
521#if 0 /* TODO: decoder feature is being reworked. use host-reordering in the meantime */
522                pidChannelSettings.pidSettings.allowTimestampReordering = false; /* turn it off at host and enable it at decoder. this is the default now */
523#endif
524                pidChannelSettings.pidSettings.pidType = NEXUS_PidType_eVideo;
525                pidChannelSettings.pidTypeSettings.video.codec = b_videocodec2nexus(mpeg->video[0].format);
526                pidChannelSettings.pidTypeSettings.video.decoder = NULL;        /* Decode will set this later */
527                pidChannelSettings.pidTypeSettings.video.index = true;
528                BDBG_ASSERT(!stream->nIndexPid); /* if static_alloc is used correctly in the shim, we will never realloc this */
529                BDBG_MSG(("Opening playback video pid channel for pid 0x%02x(%d)",mpeg->video[0].pid,mpeg->video[0].pid));
530                stream->nIndexPid = NEXUS_Playback_OpenPidChannel(stream->producer.playback->nPlayback, mpeg->video[0].pid, &pidChannelSettings);
531                if ( NULL == stream->nIndexPid )
532                {
533                    BDBG_ERR(("Unable to open video index pid"));
534                    return BSETTOP_ERROR(berr_external_error);
535                }
536            }
537        }
538        else
539        {
540            if ( stream->nIndexPid )
541            {
542                BDBG_ASSERT(NULL != stream->producer.playback);
543                NEXUS_Playback_ClosePidChannel(stream->producer.playback->nPlayback, stream->nIndexPid);
544                stream->nIndexPid = NULL;
545            }
546        }
547    }
548#endif
549
550    /* TODO: should we call bstream_set_mpeg_parameters if mpeg is NULL or not? */
551    if (mpeg) {
552        /* Set settings */
553        result = bstream_set_mpeg_parameters(stream, mpeg);
554        if (result)
555        {
556            BSETTOP_ERROR(result);
557            goto err_set;
558        }
559               
560                if ( g_has_fcc )
561                {
562                        result = bstream_p_fcc_open(stream);
563                        if (result)
564                        {
565                                BSETTOP_ERROR(result);
566                                goto err_set;
567                        }
568                }
569    }
570        else if (g_has_fcc)
571        {
572                result = bstream_p_fcc_close(stream);
573        }
574
575    return 0;
576
577err_set:
578#if NEXUS_HAS_PLAYBACK
579    if ( stream->nIndexPid )
580    {
581        NEXUS_Playback_ClosePidChannel(stream->producer.playback->nPlayback, stream->nIndexPid);
582        stream->nIndexPid = NULL;
583    }
584#endif
585    return result;
586}
587
588void bstream_close(bstream_t stream)
589{
590    BDBG_OBJECT_ASSERT(stream, bstream);
591    /* NOTE: the _p_close adds no value now, but was useful for previous features. it's harmless to keep it. */
592    bstream_p_close(stream);
593}
594
595void bstream_p_close(bstream_t stream)
596{
597    BDBG_OBJECT_ASSERT(stream, bstream);
598   
599    bstream_p_stop_consumers(stream);
600
601    if (stream->cc_data_ready_timer) {
602        stream->vbi_settings.cc_data_ready_callback = NULL;
603        stream->vbi_settings.callback_context = NULL;
604        b_timer_cancel(stream->cc_data_ready_timer);
605        stream->cc_data_ready_timer = NULL;
606    }
607   
608    /* this frees resources allocated by previous sets */
609    (void)bstream_p_set(stream, NULL);
610
611    if (!stream->static_alloc) {
612        if ( stream->parser_band && 0 == --stream->parser_band->refcnt )
613        {
614            stream->parser_band->band = NULL;
615        }
616
617        BDBG_OBJECT_DESTROY(stream, bstream);
618        BKNI_Free(stream);
619    }
620}
621
622bresult bstream_get_mpeg_parameters(bstream_t stream, bstream_status *status)
623{
624    BDBG_OBJECT_ASSERT(stream, bstream);
625    BKNI_Memset(status, 0, sizeof(*status));
626
627    if (stream->parser_band) {
628        status->band = stream->producer.band;
629        status->parser_band = stream->parser_band->nParserBand;
630    }
631    status->mpeg = stream->mpeg;
632    status->decode = stream->consumers.decode;
633#if B_HAS_IP
634    status->timestamp_enabled = stream->producer.timestamp_enabled;
635#endif
636    return 0;
637}
638
639bresult
640bstream_set_mpeg_parameters(bstream_t stream, const bstream_mpeg *mpeg)
641{
642    BDBG_OBJECT_ASSERT(stream, bstream);
643    BDBG_ASSERT(NULL != mpeg);
644
645    /* Notify consumers of change before storing settings */
646    if ( stream->consumers.decode )
647    {
648        bdecode_p_mpeg_change(stream->consumers.decode, mpeg);
649    }
650    if ( stream->consumers.recpump )
651    {
652        brecpump_p_mpeg_change(stream->consumers.recpump, mpeg);
653    }
654    if ( stream->consumers.record )
655    {
656        brecord_p_mpeg_change(stream->consumers.record, mpeg);
657    }
658
659    stream->mpeg = *mpeg;
660
661    return b_ok;
662}
663
664void bband_get(bband_t band, bband_settings *settings)
665{
666    settings->bandnum = band->nInputBand;
667    settings->mpeg_type = band->mpeg_type;
668    settings->tuner = band->tuner;
669}
670
671void bstream_join(bstream_t video_source, bstream_t audio_source)
672{
673    BSTD_UNUSED(video_source);
674    BSTD_UNUSED(audio_source);
675    BSETTOP_ERROR(berr_not_supported);
676}
677
678bstream_t bstream_open_child(bstream_t parent, const bstream_mpeg *mpegparams)
679{
680    BSTD_UNUSED(parent);
681    BSTD_UNUSED(mpegparams);
682    BSETTOP_ERROR(berr_not_supported);
683    return NULL;
684}
685
686bresult bstream_start_pcr_monitor(bstream_t stream)
687{
688    bresult berr = b_ok;
689
690    BDBG_OBJECT_ASSERT(stream, bstream);
691
692    if (stream->consumers.decode) {
693        NEXUS_Error err = NEXUS_SUCCESS;
694        NEXUS_TimebaseStatus pStatus;
695        NEXUS_StcChannelSettings pSettings;
696        NEXUS_StcChannelHandle handle = stream->consumers.decode->stcChannel;
697
698        NEXUS_StcChannel_GetSettings( handle, &pSettings);
699
700        err = NEXUS_Timebase_GetStatus(pSettings.timebase, &pStatus);
701        if (err != NEXUS_SUCCESS)
702            berr = berr_external_error;
703
704        stream->pcr_status.monitor_started = true;
705        stream->pcr_status.pcr_count = pStatus.pcrCount;
706        stream->pcr_status.pcr_valid = pStatus.pcrValid;
707    }
708    else {
709        BKNI_Memset(&stream->pcr_status, 0, sizeof(stream->pcr_status));
710    }
711
712    return berr;
713}
714
715void bstream_stop_pcr_monitor(bstream_t stream)
716{
717    /* Stop the monitoring */
718    stream->pcr_status.monitor_started = false;
719}
720
721bresult bstream_get_pcr_status(bstream_t stream, bstream_pcr_status *status)
722{
723    NEXUS_Error err = NEXUS_SUCCESS;
724    bresult berr = b_ok;
725
726    BDBG_OBJECT_ASSERT(stream, bstream);
727    BKNI_Memset(status, 0, sizeof(*status));
728
729    if (stream->consumers.decode) {
730        NEXUS_TimebaseStatus pStatus;
731        NEXUS_StcChannelSettings pSettings;
732        NEXUS_StcChannelHandle handle;
733
734        handle = stream->consumers.decode->stcChannel;
735        NEXUS_StcChannel_GetSettings( handle, &pSettings);
736
737        err = NEXUS_Timebase_GetStatus(pSettings.timebase, &pStatus);
738        if (err != NEXUS_SUCCESS)
739            berr = berr_external_error;
740
741        if( stream->pcr_status.monitor_started)
742        {
743            status->monitor_started = stream->pcr_status.monitor_started;
744            status->pcr_count = pStatus.pcrCount - stream->pcr_status.pcr_count;
745            status->pcr_valid  = pStatus.pcrValid;
746        }
747    }
748    else {
749        BDBG_WRN(("pcr_status requires current decode"));
750    }
751
752
753    return berr;
754}
755
756NEXUS_PidChannelHandle bstream_p_open_pid(bstream_t stream, uint16_t pid, bstream_pid_type type)
757{
758    NEXUS_PidChannelHandle pidChannel=NULL;
759    NEXUS_PidType nexusType;
760    int index=0;
761    NEXUS_AudioCodec audioCodec=NEXUS_AudioCodec_eUnknown;
762    NEXUS_VideoCodec videoCodec=NEXUS_VideoCodec_eUnknown;
763
764    BDBG_OBJECT_ASSERT(stream, bstream);
765
766    switch ( type )
767    {
768    case bstream_pid_type_audio:
769        nexusType = NEXUS_PidType_eAudio;
770        for ( index=0; index < BSETTOP_MAX_PROGRAMS; index++ )
771        {
772            if ( stream->mpeg.audio[index].pid == pid )
773            {
774                audioCodec = b_audiocodec2nexus(stream->mpeg.audio[index].format);
775                break;
776            }           
777        }
778        if ( index >= BSETTOP_MAX_PROGRAMS )
779        {
780            BDBG_ERR(("Audio program not in bstream_mpeg"));
781            BSETTOP_ERROR(berr_external_error);
782            return NULL;
783        }
784        break;
785    case bstream_pid_type_video:
786        nexusType = NEXUS_PidType_eVideo;
787        for ( index=0; index < BSETTOP_MAX_PROGRAMS; index++ )
788        {
789            if ( stream->mpeg.video[index].pid == pid )
790            {
791                videoCodec = b_videocodec2nexus(stream->mpeg.video[index].format);
792                break;
793            }           
794        }
795        if ( index >= BSETTOP_MAX_PROGRAMS )
796        {
797            BDBG_ERR(("Video program not in bstream_mpeg"));
798            BSETTOP_ERROR(berr_external_error);
799            return NULL;
800        }
801        break;
802    default:
803        /* Shouldn't nexus have a pid type for pcr? */
804        nexusType = NEXUS_PidType_eUnknown;
805        break;
806    }
807
808    if ( stream->producer.band )
809    {
810        NEXUS_PidChannelSettings settings;
811
812        NEXUS_PidChannel_GetDefaultSettings(&settings);
813        BDBG_MSG(("Opening live pid channel for PID 0x%x (%d)", pid, pid));
814        BDBG_ASSERT(stream->parser_band);
815        /* bstream_pid_type_other and 0x1fff,0xffff pid has special meaning, for all pass record */
816        if(type == bstream_pid_type_other && (pid==0x1FFF || pid==0xFFFF))
817        {
818            BDBG_MSG(("Opening pid channnel for allpass mode"));
819            /* pid channel index need to be same as parser  band */
820            settings.pidChannelIndex = stream->parser_band->nParserBand;
821            pid=0x1fff; /* xpt doesnt all pid number 0xffff */
822        }
823        pidChannel = NEXUS_PidChannel_Open(stream->parser_band->nParserBand, pid, &settings);
824    }
825    else if ( stream->producer.playpump )
826    {
827        NEXUS_PlaypumpOpenPidChannelSettings settings;
828
829        BDBG_ASSERT(!stream->parser_band);
830        NEXUS_Playpump_GetDefaultOpenPidChannelSettings(&settings);
831        settings.pidType = nexusType;
832        if ( nexusType == NEXUS_PidType_eAudio )
833        {
834            settings.pidTypeSettings.audio.codec = audioCodec;
835        }
836        else if(type == bstream_pid_type_other && (pid==0x1FFF || pid==0xFFFF))
837        {
838            NEXUS_PlaypumpStatus playpumpStatus;
839            NEXUS_Playpump_GetStatus(stream->producer.playpump->nPlaypump,&playpumpStatus);
840            BDBG_MSG(("Opening pid channnel for allpass mode"));
841            /* pid channel index need to be same as parser  band */
842            settings.pidSettings.pidChannelIndex = 16 + playpumpStatus.index;
843            pid=0x1fff; /* xpt doesnt all pid number 0xffff */
844        }
845        BDBG_MSG(("Opening playpump pid channel for PID 0x%x (%d)", pid, pid));
846        pidChannel = NEXUS_Playpump_OpenPidChannel(stream->producer.playpump->nPlaypump, pid, &settings);
847    }
848#if NEXUS_HAS_PLAYBACK
849    else if (stream->producer.playback)
850    {
851        NEXUS_PlaybackPidChannelSettings settings;
852
853        BDBG_ASSERT(!stream->parser_band);
854        NEXUS_Playback_GetDefaultPidChannelSettings(&settings);
855        settings.pidSettings.pidType = nexusType;
856        settings.pidTypeSettings.video.decoder = NULL; /* this gets set in bsettop_decode */
857
858        if ( nexusType == NEXUS_PidType_eAudio )
859        {
860            settings.pidTypeSettings.audio.primary = NULL; /* this gets set in bsettop_decode */
861            settings.pidTypeSettings.audio.secondary = NULL; /* this gets set in bsettop_decode */
862            settings.pidSettings.pidTypeSettings.audio.codec = audioCodec;
863        }
864        else if ( nexusType == NEXUS_PidType_eVideo )
865        {
866            if ( pid == stream->mpeg.video[0].pid )
867            {
868                return stream->nIndexPid;
869            }
870            else
871            {
872                settings.pidTypeSettings.video.codec = videoCodec;
873                settings.pidTypeSettings.video.index = false;           /* We only index the first video pid by convention */
874            }
875        }
876        else if(type == bstream_pid_type_other && (pid==0x1FFF || pid==0xFFFF))
877        {
878            NEXUS_PlaybackSettings playbackSettings;
879            NEXUS_PlaypumpStatus playpumpStatus;
880            NEXUS_Playback_GetSettings(stream->producer.playback->nPlayback, &playbackSettings);
881            NEXUS_Playpump_GetStatus(playbackSettings.playpump,&playpumpStatus);
882            BDBG_MSG(("Opening pid channnel for allpass mode"));
883            /* pid channel index need to be same as parser  band */
884            settings.pidSettings.pidSettings.pidChannelIndex = 16 + playpumpStatus.index; 
885            pid=0x1fff; /* xpt doesnt all pid number 0xffff */
886        }
887        BDBG_MSG(("Opening playback pid channel for PID 0x%x (%d)", pid, pid));
888        pidChannel = NEXUS_Playback_OpenPidChannel(stream->producer.playback->nPlayback, pid, &settings);
889    }
890#endif
891    else
892    {
893        BDBG_ERR(("Invalid stream configuration"));
894        BSETTOP_ERROR(berr_external_error);
895        return NULL;
896    }
897
898    if ( NULL == pidChannel )
899    {
900        BDBG_ERR(("Unable to open pid 0x%x (%d)", pid, pid));
901        BSETTOP_ERROR(berr_external_error);
902    }
903
904    return pidChannel;
905}
906
907void bstream_p_close_pid(bstream_t stream, NEXUS_PidChannelHandle pidChannel)
908{
909    BDBG_OBJECT_ASSERT(stream, bstream);
910    BDBG_ASSERT(NULL != pidChannel);
911
912    if ( stream->producer.band )
913    {
914        NEXUS_PidChannel_Close(pidChannel);
915    }
916    else if ( stream->producer.playpump )
917    {
918        NEXUS_Playpump_ClosePidChannel(stream->producer.playpump->nPlaypump, pidChannel);
919    }
920#if NEXUS_HAS_PLAYBACK
921    else if (stream->producer.playback)
922    {
923        /* the index pid is closed with the stream */
924        if (pidChannel != stream->nIndexPid) {
925            NEXUS_Playback_ClosePidChannel(stream->producer.playback->nPlayback, pidChannel);
926        }
927    }
928#endif
929    else
930    {
931        BDBG_ERR(("Invalid stream configuration.  Stream must have a producer while pid channels are open."));
932        BDBG_ASSERT(false);
933    }
934}
935
936void bstream_p_stop_consumers(bstream_t stream)
937{
938    bmessage_stream_t msg;
939
940    BDBG_OBJECT_ASSERT(stream, bstream);
941
942    BDBG_MSG(("Stopping all consumers"));
943
944    if (stream->consumers.decode)
945    {
946        bdecode_stop(stream->consumers.decode);
947        BDBG_ASSERT(stream->consumers.decode == NULL);
948    }
949    if ( stream->consumers.still )
950    {
951        bdecode_stop(stream->consumers.still);
952        BDBG_ASSERT(stream->consumers.still == NULL);
953    }
954    if ( stream->consumers.recpump )
955    {
956        brecpump_stop(stream->consumers.recpump);
957        BDBG_ASSERT(stream->consumers.recpump == NULL);
958    }
959    if ( stream->consumers.record )
960    {
961        brecord_stop(stream->consumers.record);
962        BDBG_ASSERT(stream->consumers.record == NULL);
963    }
964    while ( (msg=BLST_Q_FIRST(&stream->consumers.messageList)) )
965    {
966        bmessage_stop(msg);
967    }
968}
969
Note: See TracBrowser for help on using the repository browser.