/*************************************************************************** * Copyright (c) 2012, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * * $brcm_Log: $ * ***************************************************************************/ #include "bsettop_stream_n_priv.h" BDBG_MODULE(bstream); #define INVALID_PID 0xFFFF /* * Summary: * Private stream data structure to associate rave and context info with the stream. */ struct bstream { bool in_use; /* flag indicating the context is in use */ int pid_ch; /* Main pid channel index */ bband_t band; /* Band with possibly playback flag */ bstream_mpeg mpeg; /* mpeg program pids */ bstream_info_t stream_info; /* private stream parameters */ }; static bstream_t bstream_p_find_stream(void); static struct bstream s_streams[BSETTOP_MAX_STREAMS]; static bstream_mpeg s_def_stream_mpeg = { {{INVALID_PID,0}}, {{INVALID_PID,0}}, INVALID_PID}; static bool s_bstream_init = false; /* * Summary * Module initialization function */ void bstream_init(NEXUS_VideoDecoderHandle videoDecodeHandle) { int i; if (s_bstream_init) return; for (i=0; iband = band; stream->mpeg = *mpeg; stream->stream_info.pcrPidChannel = NULL; if (stream->mpeg.video[0].pid != 0) { stream->stream_info.videoPidChannel = NEXUS_PidChannel_Open(stream->band, stream->mpeg.video[0].pid, NULL); if (!stream->stream_info.videoPidChannel) { BDBG_WRN(("NEXUS_PidChannel_Open video pid = 0x%04x", stream->mpeg.video[0].pid)); goto ExitError; } if (stream->mpeg.pcr_pid == stream->mpeg.video[0].pid) { stream->stream_info.pcrPidChannel = stream->stream_info.videoPidChannel; } } if (stream->mpeg.audio[0].pid != 0) { stream->stream_info.audioPidChannel = NEXUS_PidChannel_Open(stream->band, stream->mpeg.audio[0].pid, NULL); if (!stream->stream_info.audioPidChannel) { BDBG_WRN(("NEXUS_PidChannel_Open audio pid = 0x%04x", stream->mpeg.audio[0].pid)); goto ExitError; } if (stream->mpeg.pcr_pid == stream->mpeg.audio[0].pid) { stream->stream_info.pcrPidChannel = stream->stream_info.audioPidChannel; } } if ((stream->mpeg.pcr_pid != 0) && (stream->stream_info.pcrPidChannel == NULL)) { stream->stream_info.pcrPidChannel = NEXUS_PidChannel_Open(stream->band, stream->mpeg.pcr_pid, NULL); if (!stream->stream_info.pcrPidChannel) { BDBG_WRN(("NEXUS_PidChannel_Open pcr pid = 0x%04x", stream->mpeg.pcr_pid)); goto ExitError; } } if (!stream->stream_info.pcrPidChannel) stream->stream_info.pcrPidChannel = stream->stream_info.videoPidChannel; NEXUS_StcChannel_GetDefaultSettings(0, &stcSettings); stcSettings.autoConfigTimebase = false; stcSettings.timebase = NEXUS_Timebase_e0; stcSettings.mode = NEXUS_StcChannelMode_ePcr; stcSettings.modeSettings.pcr.pidChannel = stream->stream_info.pcrPidChannel; stcSettings.modeSettings.pcr.offsetThreshold = 0; stcSettings.stcIndex = 0; stcSettings.modeSettings.Auto.behavior = NEXUS_StcChannelAutoModeBehavior_eFirstAvailable; stcSettings.modeSettings.Auto.transportType = NEXUS_TransportType_eTs; stream->stream_info.stcChannel = NEXUS_StcChannel_Open(stream->pid_ch, &stcSettings); if (!stream->stream_info.stcChannel) { BDBG_WRN(("NEXUS_StcChannel_Open failed (%d)", stream->pid_ch)); goto ExitError; } if (stream->mpeg.video[0].pid) { NEXUS_VideoDecoder_GetDefaultStartSettings(&(stream->stream_info.decodeSettings)); stream->stream_info.decodeSettings.codec = stream->mpeg.video[0].format; stream->stream_info.decodeSettings.pidChannel = stream->stream_info.videoPidChannel; stream->stream_info.decodeSettings.stcChannel = stream->stream_info.stcChannel; stream->stream_info.decodeSettings.prerollRate = 1; stream->stream_info.primerHandle = NEXUS_VideoDecoder_OpenPrimer(stream->stream_info.videoDecoder); if (!stream->stream_info.primerHandle) { BDBG_WRN(("NEXUS_VideoDecoder_OpenPrimer failed %d", stream->pid_ch)); goto ExitError; } BDBG_ASSERT(stream->stream_info.decodeSettings.stcChannel); BDBG_ERR(("NEXUS_VideoDecoder_StartPrimer (0x%08x)", stream->mpeg.video[0].pid)); NEXUS_VideoDecoder_StartPrimer(stream->stream_info.videoDecoder, stream->stream_info.primerHandle, &(stream->stream_info.decodeSettings)); } stream->in_use = true; return stream; ExitError: if (stream) bstream_close(stream); return NULL; } void bstream_close(bstream_t stream) { BDBG_ASSERT(stream); BDBG_ASSERT(stream->stream_info.videoDecoder); if (stream->stream_info.primerHandle) { NEXUS_VideoDecoder_StopPrimer(stream->stream_info.videoDecoder, stream->stream_info.primerHandle); NEXUS_VideoDecoder_ClosePrimer(stream->stream_info.videoDecoder, stream->stream_info.primerHandle); stream->stream_info.primerHandle = NULL; } if (stream->stream_info.stcChannel) { NEXUS_StcChannel_Close(stream->stream_info.stcChannel); stream->stream_info.stcChannel = NULL; } if ((stream->stream_info.pcrPidChannel) && (stream->stream_info.pcrPidChannel != stream->stream_info.videoPidChannel) && (stream->stream_info.pcrPidChannel != stream->stream_info.audioPidChannel)) { NEXUS_PidChannel_Close(stream->stream_info.pcrPidChannel); stream->stream_info.pcrPidChannel = NULL; } if (stream->stream_info.videoPidChannel) { NEXUS_PidChannel_Close(stream->stream_info.videoPidChannel); stream->stream_info.videoPidChannel = NULL; } if (stream->stream_info.audioPidChannel) { NEXUS_PidChannel_Close(stream->stream_info.audioPidChannel); stream->stream_info.audioPidChannel = NULL; } stream->in_use = false; } bresult bstream_get_status(bstream_t stream, bstream_status *status) { BDBG_ASSERT(stream); BDBG_ASSERT(status); BKNI_Memset(status, 0, sizeof(bstream_status)); status->mpeg = stream->mpeg; status->band = stream->band; return b_ok; } bstream_info_t *bstream_get_info(bstream_t stream) { return &(stream->stream_info); } /* * Summary: * Find available stream. */ static bstream_t bstream_p_find_stream(void) { int i; for (i=0; impeg = *mpeg; }