source: svn/newcon3bcm2_21bu/nexus/lib/playback_ip/apps/ip_client_fcc.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: 29.8 KB
Line 
1/******************************************************************************
2 *    (c)2011-2012 Broadcom Corporation
3 *
4 * This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 * and may only be used, duplicated, modified or distributed pursuant to the terms and
6 * conditions of a separate, written license agreement executed between you and Broadcom
7 * (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 * no license (express or implied), right to use, or waiver of any kind with respect to the
9 * Software, and Broadcom expressly reserves all rights in and to the Software and all
10 * intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 * Except as expressly set forth in the Authorized License,
15 *
16 * 1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 * and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 * THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 * USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 * ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: ip_client_fcc.c $
39 * $brcm_Revision: 17 $
40 * $brcm_Date: 1/12/12 6:01p $
41 *
42 * Module Description: client example code to show fast channel change over IP
43 *
44 * $brcm_Log: /nexus/lib/playback_ip/apps/ip_client_fcc.c $
45 *
46 * 17   1/12/12 6:01p ssood
47 * SW7231-332: coverity fix
48 *
49 * 16   11/30/11 4:40p mward
50 * SW7429-1:  Allow build with NEXUS_NUM_AUDIO_DACS 0
51 *
52 * 15   11/18/11 12:37p mananp
53 * SW7425-1123: Coverity fix for UNINIT ipSessionList
54 *
55 * 14   11/16/11 3:33p mananp
56 * SW7425-1123: Coverity fix for assigning value to maxPrimers and
57 *  checking its bou
58 * ndaies
59 *
60 * 13   11/11/11 11:37a mward
61 * SW7125-1150: Initialize maxPrimers to NUM_PRIMERS in case no program
62 *  args.
63 *
64 * 12   11/4/11 2:18p mananp
65 * SW7425-1123: Coverity fix
66 *
67 * 9   9/23/11 3:00p mananp
68 * SW7346-496:Coverity Defect ID:35206 TAINTED_SCALAR ip_client_fcc.c
69 *  Product=97346
70 *
71 * 8   8/25/11 8:06a jrubio
72 * SW7344-181: false coverity issue with argv[1]
73 *
74 * 7   8/23/11 4:49p jrubio
75 * SW7344-181: false coverity issues
76 *
77 * 6   8/22/11 5:34p qsong
78 * SWDTV-8319: Make it compile for DTV chip 35233
79 *
80 * 5   8/22/11 2:02p ssood
81 * SW7231-332: Coverity fixes
82 *
83 * 4   8/17/11 10:27a ssood
84 * SW7425-1040: enable decode mode to hold last picture until TSM passes
85 *  on the next channel
86 *
87 * 3   8/15/11 11:09a ssood
88 * SW7425-1040: changes to enable pts offset adjustments in primer for IP
89 *  sessions
90 *
91 * 2   8/10/11 5:15p randyjew
92 * SW7425-1040: Disable Component output ifs chip doesn't support
93 *  component
94 *
95 * 1   8/7/11 7:00p ssood
96 * SW7425-1040: more changes to support FCC over IP sessions
97 *
98******************************************************************************/
99
100#include <stdio.h>
101#include <stdlib.h>
102#include "nexus_platform.h"
103#include "nexus_pid_channel.h"
104#include "nexus_parser_band.h"
105#include "nexus_video_decoder.h"
106#include "nexus_video_decoder_primer.h"
107#include "nexus_video_decoder_extra.h"
108#include "nexus_stc_channel.h"
109#include "nexus_timebase.h"
110#include "nexus_display.h"
111#include "nexus_video_window.h"
112#include "nexus_ir_input.h"
113#include "nexus_composite_output.h"
114#include "nexus_component_output.h"
115#include "bstd.h"
116#include "bkni.h"
117#include "bdbg.h"
118#include "nexus_audio_dac.h"
119#include "nexus_audio_decoder.h"
120#include "nexus_audio_output.h"
121#include "nexus_audio_input.h"
122#include "b_os_lib.h"
123#include "b_playback_ip_lib.h"
124
125#if 0
126#undef NEXUS_HAS_SYNC_CHANNEL
127#endif
128#if NEXUS_HAS_SYNC_CHANNEL
129#include "nexus_sync_channel.h"
130#endif
131
132BDBG_MODULE(ip_client_fcc);
133
134#define NUM_PROGRAMS 5
135#define NUM_PRIMERS 5
136#if 1
137#define AUDIO
138#endif
139
140#define IP_NETWORK_JITTER       300
141typedef struct 
142{
143    char *ipAddr;
144    int port;
145    int protocol;
146    char *uri;
147} IpChannel;
148
149#if 0
150IpChannel ipChannelList[NUM_PROGRAMS] = {
151    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=111;SubChannel=1;StreamingEnabled=Yes"},
152    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=147;SubChannel=1;StreamingEnabled=Yes"},
153    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=549;SubChannel=1;StreamingEnabled=Yes"}
154#if 0
155    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=561;SubChannel=1;StreamingEnabled=Yes"}
156    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=111;SubChannel=5;StreamingEnabled=Yes"},
157    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=111;SubChannel=2;StreamingEnabled=Yes"}
158#endif
159};
160#else
161IpChannel ipChannelList[NUM_PROGRAMS] = {
162    {"192.168.1.102", 4321, B_PlaybackIpProtocol_eHttp, "/cds/ContentDir/?id=923"},
163    {"192.168.1.102", 4321, B_PlaybackIpProtocol_eHttp, "/cds/ContentDir/?id=924"},
164    {"192.168.1.102", 4321, B_PlaybackIpProtocol_eHttp, "/cds/ContentDir/?id=925"},
165    {"192.168.1.102", 4321, B_PlaybackIpProtocol_eHttp, "/cds/ContentDir/?id=926"},
166    {"192.168.1.102", 4321, B_PlaybackIpProtocol_eHttp, "/cds/ContentDir/?id=927"},
167#if 0
168    {"192.168.1.102", 4321, B_PlaybackIpProtocol_eHttp, "/cds/ContentDir/?id=926"}
169    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=111;SubChannel=5;StreamingEnabled=Yes"},
170    {"192.168.1.102", 5000, B_PlaybackIpProtocol_eHttp, "/LiveChannel;Type=QAM;QamMode=QAM256;Freq=111;SubChannel=2;StreamingEnabled=Yes"}
171#endif
172};
173#endif
174
175typedef struct _ipSession {
176    B_PlaybackIpHandle playbackIp;
177    NEXUS_PlaypumpHandle playpump;
178    NEXUS_PidChannelHandle videoPidChannel;
179    NEXUS_PidChannelHandle audioPidChannel;
180    NEXUS_PidChannelHandle pcrPidChannel;
181    NEXUS_VideoDecoderPrimerHandle primer;
182    NEXUS_VideoDecoderStartSettings videoProgram;
183    NEXUS_AudioDecoderStartSettings audioProgram;
184    NEXUS_StcChannelHandle stcChannel;
185    B_PlaybackIpPsiInfo psi;
186}IpSession;
187typedef struct _ipSession *IpSessionHandle; 
188
189typedef struct _decodeSession {
190    NEXUS_VideoDecoderHandle videoDecoder;
191    NEXUS_AudioDecoderHandle audioDecoder;
192    NEXUS_DisplayHandle display;
193    NEXUS_VideoWindowHandle window;
194    NEXUS_Timebase timebaseStc;
195    bool timebaseStcConfigured;
196#if NEXUS_HAS_SYNC_CHANNEL
197    NEXUS_SyncChannelHandle syncChannel;
198#endif
199}DecodeSession;
200typedef struct _decodeSession *DecodeSessionHandle; 
201
202IpSessionHandle
203IpPrimerSessionStart(int sessionIndex, IpChannel *ipChannel, DecodeSessionHandle decodeSession)
204{
205    NEXUS_Error rc;
206    NEXUS_PlaypumpOpenSettings playpumpOpenSettings;
207    NEXUS_PlaypumpOpenPidChannelSettings pidChannelSettings;
208    B_PlaybackIpSessionOpenSettings ipSessionOpenSettings;
209    B_PlaybackIpSessionOpenStatus ipSessionOpenStatus;
210    B_PlaybackIpSessionSetupSettings ipSessionSetupSettings;
211    B_PlaybackIpSessionSetupStatus ipSessionSetupStatus;
212    B_PlaybackIpSettings playbackIpSettings;
213    NEXUS_PlaypumpSettings playpumpSettings;
214    B_PlaybackIpSessionStartSettings ipSessionStartSettings;
215    B_PlaybackIpSessionStartStatus ipSessionStartStatus;
216    NEXUS_VideoDecoderPrimerSettings primerSettings;
217    NEXUS_TimebaseSettings timebaseSettings;
218    IpSessionHandle ipSession;
219    NEXUS_StcChannelSettings stcSettings;
220
221    ipSession = BKNI_Malloc(sizeof(IpSession));
222    BDBG_ASSERT(ipSession);
223    BKNI_Memset(ipSession, 0, sizeof(IpSession));
224
225    /* open playpump */
226    NEXUS_Playpump_GetDefaultOpenSettings(&playpumpOpenSettings);
227    playpumpOpenSettings.fifoSize *= 2;
228    playpumpOpenSettings.numDescriptors = 200;
229    ipSession->playpump = NEXUS_Playpump_Open(sessionIndex, &playpumpOpenSettings);
230    BDBG_ASSERT(ipSession->playpump);
231    BDBG_WRN(("Playpump Idx %d", sessionIndex));
232
233    /* Open IP Session */
234    ipSession->playbackIp = B_PlaybackIp_Open(NULL);
235    BDBG_ASSERT(ipSession->playbackIp);
236
237    BKNI_Memset(&ipSessionOpenSettings, 0, sizeof(ipSessionOpenSettings));
238    BKNI_Memset(&ipSessionOpenStatus, 0, sizeof(ipSessionOpenStatus));
239    strncpy(ipSessionOpenSettings.socketOpenSettings.ipAddr, ipChannel->ipAddr, sizeof(ipSessionOpenSettings.socketOpenSettings.ipAddr)-1);
240    ipSessionOpenSettings.socketOpenSettings.port = ipChannel->port;
241    ipSessionOpenSettings.socketOpenSettings.protocol = ipChannel->protocol;
242    ipSessionOpenSettings.socketOpenSettings.url = ipChannel->uri;
243    ipSessionOpenSettings.ipMode = B_PlaybackIpClockRecoveryMode_ePushWithPcrSyncSlip;
244    ipSessionOpenSettings.maxNetworkJitter = 300;
245    ipSessionOpenSettings.networkTimeout = 1;  /* timeout in 1 sec during network outage events */
246    rc = B_PlaybackIp_SessionOpen(ipSession->playbackIp, &ipSessionOpenSettings, &ipSessionOpenStatus);
247    BDBG_ASSERT(!rc);
248   
249    /* do IP Session Setup so that PIDs are known */
250    memset(&ipSessionSetupSettings, 0, sizeof(ipSessionSetupSettings));
251    rc = B_PlaybackIp_SessionSetup(ipSession->playbackIp, &ipSessionSetupSettings, &ipSessionSetupStatus);
252    BDBG_ASSERT(!rc);
253    ipSession->psi = ipSessionSetupStatus.u.http.psi;
254    BDBG_WRN(("vpid %d, vcodec %d, apid %d, acodec %d, psiPid %d", ipSession->psi.videoPid, ipSession->psi.videoCodec, ipSession->psi.audioPid, ipSession->psi.audioCodec, ipSession->psi.pcrPid));
255
256    NEXUS_Playpump_GetSettings(ipSession->playpump, &playpumpSettings);
257    playpumpSettings.transportType = ipSession->psi.mpegType;
258    rc = NEXUS_Playpump_SetSettings(ipSession->playpump, &playpumpSettings);
259    BDBG_ASSERT(!rc);
260
261    /* open AV pid channels */
262    NEXUS_Playpump_GetDefaultOpenPidChannelSettings(&pidChannelSettings);
263    pidChannelSettings.pidType = NEXUS_PidType_eVideo;
264    ipSession->videoPidChannel = NEXUS_Playpump_OpenPidChannel(ipSession->playpump, ipSession->psi.videoPid, &pidChannelSettings);
265    BDBG_ASSERT(ipSession->videoPidChannel != NULL);
266
267    NEXUS_Playpump_GetDefaultOpenPidChannelSettings(&pidChannelSettings);
268    pidChannelSettings.pidType = NEXUS_PidType_eAudio;
269    pidChannelSettings.pidTypeSettings.audio.codec = ipSession->psi.audioCodec;
270    ipSession->audioPidChannel = NEXUS_Playpump_OpenPidChannel(ipSession->playpump, ipSession->psi.audioPid, &pidChannelSettings);
271    BDBG_ASSERT(ipSession->audioPidChannel != NULL);
272
273    if (ipSession->psi.pcrPid == ipSession->psi.videoPid)
274        ipSession->pcrPidChannel = ipSession->videoPidChannel;
275    else if (ipSession->psi.pcrPid == ipSession->psi.audioPid)
276        ipSession->pcrPidChannel = ipSession->audioPidChannel;
277    else {
278        NEXUS_Playpump_GetDefaultOpenPidChannelSettings(&pidChannelSettings);
279        pidChannelSettings.pidType = NEXUS_PidType_eOther;
280        ipSession->pcrPidChannel = NEXUS_Playpump_OpenPidChannel(ipSession->playpump, ipSession->psi.pcrPid, &pidChannelSettings);
281        BDBG_ASSERT(ipSession->pcrPidChannel != NULL);
282    }
283
284    /* configured the timebase */
285    /* note: same timebase is used for all priming and the main decoding session */
286    /* we configure it once here for the 1st priming session */
287    /* later when the decode is started using this priming session, timebase is configured */
288    /* again to include the pidChannel of the main decoding session */
289    if (decodeSession->timebaseStcConfigured == false) {
290        NEXUS_Timebase_GetSettings(decodeSession->timebaseStc, &timebaseSettings);
291        timebaseSettings.sourceType = NEXUS_TimebaseSourceType_ePcr;
292        timebaseSettings.freeze = false;
293        timebaseSettings.sourceSettings.pcr.maxPcrError = IP_NETWORK_JITTER * 183/2;    /* in milliseconds: based on 90Khz clock */
294        timebaseSettings.sourceSettings.pcr.trackRange = NEXUS_TimebaseTrackRange_e244ppm;
295        timebaseSettings.sourceSettings.pcr.pidChannel = ipSession->pcrPidChannel;
296        rc = NEXUS_Timebase_SetSettings(decodeSession->timebaseStc, &timebaseSettings);
297        BDBG_ASSERT(!rc);
298        decodeSession->timebaseStcConfigured = true;
299    }
300
301    /* configure STC channel: each priming session needs its own STC channel */
302    /* all STC use the same Timebase */
303    NEXUS_StcChannel_GetDefaultSettings(sessionIndex, &stcSettings);
304    stcSettings.timebase = decodeSession->timebaseStc;
305    stcSettings.mode = NEXUS_StcChannelMode_ePcr;
306    stcSettings.autoConfigTimebase = false;
307    stcSettings.modeSettings.pcr.offsetThreshold = IP_NETWORK_JITTER * 183; 
308    stcSettings.modeSettings.pcr.maxPcrError = IP_NETWORK_JITTER * 183;    /* in milliseconds: based on 90Khz clock */
309    stcSettings.modeSettings.pcr.disableJitterAdjustment = true;
310    stcSettings.modeSettings.pcr.disableTimestampCorrection = true;
311    stcSettings.modeSettings.pcr.pidChannel = ipSession->pcrPidChannel;
312    stcSettings.stcIndex = 0;
313    ipSession->stcChannel = NEXUS_StcChannel_Open(sessionIndex, &stcSettings);
314    BDBG_WRN(("stc ch %d, ptr %p", sessionIndex, (void *)ipSession->stcChannel)); 
315    BDBG_ASSERT(ipSession->stcChannel != NULL);
316
317    /* setup the AV decoder start settings */
318    NEXUS_VideoDecoder_GetDefaultStartSettings(&ipSession->videoProgram);
319    ipSession->videoProgram.codec = ipSession->psi.videoCodec;
320    ipSession->videoProgram.pidChannel = ipSession->videoPidChannel;
321    ipSession->videoProgram.stcChannel = ipSession->stcChannel;
322
323#ifdef AUDIO
324    NEXUS_AudioDecoder_GetDefaultStartSettings(&ipSession->audioProgram);
325    ipSession->audioProgram.codec = ipSession->psi.audioCodec;
326    ipSession->audioProgram.pidChannel = ipSession->audioPidChannel;
327    ipSession->audioProgram.stcChannel = ipSession->stcChannel;
328#endif
329
330    /* Start playpump */
331    rc = NEXUS_Playpump_Start(ipSession->playpump);
332    BDBG_ASSERT(!rc);
333
334    ipSession->primer = NEXUS_VideoDecoder_OpenPrimer(decodeSession->videoDecoder);
335    BDBG_ASSERT(ipSession->primer != NULL);
336    NEXUS_VideoDecoder_GetPrimerSettings(ipSession->primer, &primerSettings);
337    primerSettings.pastTolerance = 1500; /* amount of time willing to race */
338    primerSettings.futureTolerance = 0;
339    primerSettings.ptsStcDiffCorrectionEnabled = true;
340    rc = NEXUS_VideoDecoder_SetPrimerSettings(ipSession->primer, &primerSettings);
341    BDBG_ASSERT(!rc);
342    /* start priming */
343    rc = NEXUS_VideoDecoder_StartPrimer(decodeSession->videoDecoder, ipSession->primer, &ipSession->videoProgram);
344    BDBG_ASSERT(!rc);
345    BDBG_WRN(("############## primer %p started: pastTolerance=%d, futureTolerance=%d\n", ipSession->primer, primerSettings.pastTolerance, primerSettings.futureTolerance));
346
347    /* start IP session: all other modules (playpump, decoder, primer) must be started before this */
348    /* update IP Session Settings */
349    B_PlaybackIp_GetSettings(ipSession->playbackIp, &playbackIpSettings);
350    playbackIpSettings.ipMode = B_PlaybackIpClockRecoveryMode_ePushWithPcrSyncSlip;
351    rc = B_PlaybackIp_SetSettings(ipSession->playbackIp, &playbackIpSettings);
352    BDBG_ASSERT(!rc);
353
354    BKNI_Memset(&ipSessionStartSettings, 0, sizeof(ipSessionStartSettings));
355    ipSessionStartSettings.nexusHandles.playpump = ipSession->playpump;
356    ipSessionStartSettings.nexusHandles.videoDecoder = decodeSession->videoDecoder;
357    ipSessionStartSettings.nexusHandles.stcChannel = ipSession->stcChannel;
358    ipSessionStartSettings.nexusHandles.primaryAudioDecoder = decodeSession->audioDecoder;
359    ipSessionStartSettings.nexusHandlesValid = true;
360    rc = B_PlaybackIp_SessionStart(ipSession->playbackIp, &ipSessionStartSettings, &ipSessionStartStatus);
361    BDBG_ASSERT(!rc);
362
363    return ipSession;
364}
365
366void
367IpPrimerSessionStop(IpSessionHandle ipSession, DecodeSessionHandle decodeSession)
368{
369    NEXUS_Error rc;
370
371    rc = B_PlaybackIp_SessionStop(ipSession->playbackIp);
372    BDBG_ASSERT(!rc);
373
374    NEXUS_Playpump_Stop(ipSession->playpump);
375
376    NEXUS_VideoDecoder_StopPrimer(decodeSession->videoDecoder, ipSession->primer);
377
378    BDBG_WRN(("############## primer %p session stopped", ipSession->primer));
379    NEXUS_VideoDecoder_ClosePrimer(decodeSession->videoDecoder, ipSession->primer);
380
381    NEXUS_Playpump_CloseAllPidChannels(ipSession->playpump);
382    NEXUS_Playpump_Close(ipSession->playpump);
383
384    rc = B_PlaybackIp_SessionClose(ipSession->playbackIp);
385    BDBG_ASSERT(!rc);
386    B_PlaybackIp_Close(ipSession->playbackIp);
387
388    NEXUS_StcChannel_Close(ipSession->stcChannel);
389    BKNI_Free(ipSession);
390}
391
392int 
393IpSessionStartDecodeWithPrimer(IpSessionHandle ipSession, DecodeSessionHandle decodeSession)
394{
395    NEXUS_Error rc;
396    NEXUS_TimebaseSettings timebaseSettings;
397    /* update timebase to use the PCR from this decode session */
398    NEXUS_Timebase_GetSettings(decodeSession->timebaseStc, &timebaseSettings);
399    timebaseSettings.sourceType = NEXUS_TimebaseSourceType_ePcr;
400    timebaseSettings.freeze = false;
401    timebaseSettings.sourceSettings.pcr.maxPcrError = IP_NETWORK_JITTER * 183/2;    /* in milliseconds: based on 90Khz clock */
402    timebaseSettings.sourceSettings.pcr.trackRange = NEXUS_TimebaseTrackRange_e244ppm;
403    timebaseSettings.sourceSettings.pcr.pidChannel = ipSession->videoProgram.pidChannel;
404    rc = NEXUS_Timebase_SetSettings(decodeSession->timebaseStc, &timebaseSettings);
405    BDBG_ASSERT(!rc);
406
407    /* now start the decode with priming channel */
408    rc = NEXUS_VideoDecoder_StartDecodeWithPrimer(decodeSession->videoDecoder, ipSession->primer);
409    BDBG_ASSERT(!rc);
410
411#ifdef AUDIO
412    rc = NEXUS_AudioDecoder_Start(decodeSession->audioDecoder, &ipSession->audioProgram);
413    BDBG_ASSERT(!rc);
414#endif
415
416    BDBG_WRN((">>>>>>>>>>>>>>>>> starting program with primer: vpid 0x%x, apid 0x%x", ipSession->psi.videoPid, ipSession->psi.audioPid));
417    return 0;
418}
419
420void IpsClose(IpSessionHandle ips)
421{
422    /* TODO: should we have an IpsStop() ? */
423    if (ips->playbackIp) {
424        B_PlaybackIp_SessionStop(ips->playbackIp);
425        B_PlaybackIp_Close(ips->playbackIp);
426        ips->playbackIp = NULL;
427    }
428    NEXUS_Playpump_Stop(ips->playpump);
429    NEXUS_Playpump_ClosePidChannel(ips->playpump, ips->videoPidChannel);
430    NEXUS_Playpump_Close(ips->playpump);
431    BKNI_Free(ips);
432}
433
434static void 
435firstPtsCallback(void *context, int param)
436{
437    NEXUS_VideoDecoderHandle videoDecoder = (NEXUS_VideoDecoderHandle)context;
438    BSTD_UNUSED(param);
439    if (videoDecoder) {
440        NEXUS_VideoDecoderStatus status;
441        if (NEXUS_VideoDecoder_GetStatus(videoDecoder, &status) != NEXUS_SUCCESS) {
442            BDBG_ERR(("%s: Failed to get current vidoe currentPts\n", __FUNCTION__));
443            return;
444        }
445        BDBG_WRN(("%s: first decoded pts 0x%x, ptsStcDifference 0x%x, type %d, tsm %d", __FUNCTION__, status.pts, status.ptsStcDifference, status.ptsType, status.tsm));
446    }
447    else {
448        BDBG_WRN(("NOTHING >>>>>>>>>>>>>>>>>>>>"));
449    }
450}
451
452static void 
453firstPtsPassedCallback(void *context, int param)
454{
455    BSTD_UNUSED(param);
456    NEXUS_VideoDecoderHandle videoDecoder = (NEXUS_VideoDecoderHandle)context;
457    if (videoDecoder) {
458        NEXUS_VideoDecoderStatus status;
459        if (NEXUS_VideoDecoder_GetStatus(videoDecoder, &status) != NEXUS_SUCCESS) {
460            BDBG_ERR(("%s: Failed to get current vidoe currentPts\n", __FUNCTION__));
461            return;
462        }
463        BDBG_WRN(("%s: first passed pts 0x%x, ptsStcDifference 0x%x, type %d, tsm %d\n", __FUNCTION__, status.pts, status.ptsStcDifference, status.ptsType, status.tsm));
464    }
465    else
466        BDBG_WRN(("NOTHING >>>>>>>>>>>>>>>>>>>>"));
467}
468
469
470DecodeSessionHandle
471decodeSessionInit(void)
472{
473    DecodeSessionHandle decodeSession = NULL;
474    NEXUS_TimebaseSettings timebaseSettings;
475    NEXUS_PlatformConfiguration platformConfig;
476    NEXUS_VideoDecoderOpenSettings videoDecoderOpenSettings;
477    NEXUS_VideoDecoderSettings videoDecoderSettings;
478    NEXUS_Error rc;
479    NEXUS_DisplaySettings displaySettings;
480    NEXUS_AudioDecoderOpenSettings audioDecoderOpenSettings;
481    NEXUS_AudioDecoderSettings audioDecoderSettings;
482#if NEXUS_HAS_SYNC_CHANNEL
483    NEXUS_SyncChannelSettings syncChannelSettings;
484#endif
485    NEXUS_AudioOutputSettings audioOutputSettings;
486    NEXUS_AudioOutput audioOutput;
487    NEXUS_Timebase timebaseOutput;
488
489    NEXUS_Platform_GetConfiguration(&platformConfig);
490
491    decodeSession = BKNI_Malloc(sizeof(DecodeSession));
492    BDBG_ASSERT(decodeSession);
493    BKNI_Memset(decodeSession, 0, sizeof(DecodeSession));
494
495#if NEXUS_HAS_SYNC_CHANNEL
496    /* create a sync channel */
497    NEXUS_SyncChannel_GetDefaultSettings(&syncChannelSettings);
498    syncChannelSettings.enablePrecisionLipsync = true;
499    decodeSession->syncChannel = NEXUS_SyncChannel_Create(&syncChannelSettings);
500    if (decodeSession->syncChannel == NULL) {printf("NEXUS Error at %d, Exiting...\n", __LINE__); exit(1);}
501#endif
502
503#ifdef AUDIO
504    NEXUS_AudioDecoder_GetDefaultOpenSettings(&audioDecoderOpenSettings);
505    audioDecoderOpenSettings.fifoSize = 512 * 1024; /* increased CDB for dejitter buffer */
506    decodeSession->audioDecoder = NEXUS_AudioDecoder_Open(0, &audioDecoderOpenSettings);
507    BDBG_ASSERT(decodeSession->audioDecoder);
508    #if NEXUS_NUM_AUDIO_DACS
509    rc = NEXUS_AudioOutput_AddInput(
510        NEXUS_AudioDac_GetConnector(platformConfig.outputs.audioDacs[0]),
511        NEXUS_AudioDecoder_GetConnector(decodeSession->audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo));
512    BDBG_ASSERT(!rc);
513    #endif
514#if NEXUS_NUM_HDMI_OUTPUTS
515    rc = NEXUS_AudioOutput_AddInput(
516            NEXUS_HdmiOutput_GetAudioConnector(platformConfig.outputs.hdmi[0]),
517            NEXUS_AudioDecoder_GetConnector(decodeSession->audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo));
518    BDBG_ASSERT(!rc);
519#endif
520#endif
521
522    /* Bring up display */
523    NEXUS_Display_GetDefaultSettings(&displaySettings);
524    displaySettings.format = NEXUS_VideoFormat_e1080i;
525    displaySettings.format = NEXUS_VideoFormat_eNtsc;
526    decodeSession->display = NEXUS_Display_Open(0, &displaySettings);
527    BDBG_ASSERT(decodeSession->display);
528#if NEXUS_NUM_COMPONENT_OUTPUTS
529    rc = NEXUS_Display_AddOutput(decodeSession->display, NEXUS_ComponentOutput_GetConnector(platformConfig.outputs.component[0]));
530    BDBG_ASSERT(!rc);
531#endif
532#if NEXUS_NUM_HDMI_OUTPUTS
533    rc = NEXUS_Display_AddOutput(decodeSession->display, NEXUS_HdmiOutput_GetVideoConnector(platformConfig.outputs.hdmi[0]));
534    BDBG_ASSERT(!rc);
535#endif
536
537    decodeSession->window = NEXUS_VideoWindow_Open(decodeSession->display, 0);
538    BDBG_ASSERT(decodeSession->window);
539    /* Bring up decoder and connect to display */
540    NEXUS_VideoDecoder_GetDefaultOpenSettings(&videoDecoderOpenSettings);
541    /* Increase the CDB size as it is used as the dejitter buffer */ 
542    videoDecoderOpenSettings.fifoSize = 10 * 1024 * 1024;
543    decodeSession->videoDecoder = NEXUS_VideoDecoder_Open(0, &videoDecoderOpenSettings);
544    NEXUS_VideoWindow_AddInput(decodeSession->window, NEXUS_VideoDecoder_GetConnector(decodeSession->videoDecoder));
545
546    NEXUS_VideoDecoder_GetSettings(decodeSession->videoDecoder, &videoDecoderSettings);
547    videoDecoderSettings.firstPts.callback = firstPtsCallback;
548    videoDecoderSettings.firstPts.context = decodeSession->videoDecoder;
549    videoDecoderSettings.firstPtsPassed.callback = firstPtsPassedCallback;
550    videoDecoderSettings.firstPtsPassed.context = decodeSession->videoDecoder;
551    videoDecoderSettings.ptsOffset = IP_NETWORK_JITTER * 45; /* in 45Khz clock */
552    videoDecoderSettings.channelChangeMode = NEXUS_VideoDecoder_ChannelChangeMode_eHoldUntilTsmLock;
553    rc = NEXUS_VideoDecoder_SetSettings(decodeSession->videoDecoder, &videoDecoderSettings);
554    BDBG_ASSERT(!rc);
555
556#ifdef AUDIO
557    NEXUS_AudioDecoder_GetSettings(decodeSession->audioDecoder, &audioDecoderSettings);
558    audioDecoderSettings.ptsOffset = IP_NETWORK_JITTER * 45;
559    rc = NEXUS_AudioDecoder_SetSettings(decodeSession->audioDecoder, &audioDecoderSettings);
560    BDBG_ASSERT(!rc);
561#endif
562
563#if NEXUS_HAS_SYNC_CHANNEL
564    /* connect sync channel */
565    NEXUS_SyncChannel_GetSettings(decodeSession->syncChannel, &syncChannelSettings);
566    syncChannelSettings.videoInput = NEXUS_VideoDecoder_GetConnector(decodeSession->videoDecoder);
567    syncChannelSettings.audioInput[0] = NEXUS_AudioDecoder_GetConnector(decodeSession->audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo);
568    rc = NEXUS_SyncChannel_SetSettings(decodeSession->syncChannel, &syncChannelSettings);
569    BDBG_ASSERT(!rc);
570    BDBG_WRN(("SYNC Channel Settings are updated...."));
571#endif
572
573    /* one timebase (DPCR) block is shared for all priming & current decoding session */
574    decodeSession->timebaseStc = NEXUS_Timebase_e0;
575    timebaseOutput = NEXUS_Timebase_e1;
576
577    /* configure output timebase to freerun */
578    NEXUS_Timebase_GetSettings(timebaseOutput, &timebaseSettings);
579    timebaseSettings.freeze = true;
580    timebaseSettings.sourceSettings.pcr.trackRange = NEXUS_TimebaseTrackRange_e61ppm;
581    timebaseSettings.sourceType = NEXUS_TimebaseSourceType_eFreeRun;
582    rc = NEXUS_Timebase_SetSettings(timebaseOutput, &timebaseSettings);
583    BDBG_ASSERT(!rc);
584
585#ifdef AUDIO
586    /* decouple display and audio output from input timebase */
587    #if NEXUS_NUM_AUDIO_DACS
588    audioOutput = NEXUS_AudioDac_GetConnector(platformConfig.outputs.audioDacs[0]);
589    NEXUS_AudioOutput_GetSettings(audioOutput, &audioOutputSettings);
590    audioOutputSettings.timebase = timebaseOutput;
591    rc = NEXUS_AudioOutput_SetSettings(audioOutput, &audioOutputSettings);
592    BDBG_ASSERT(!rc);
593    #endif
594#if NEXUS_NUM_HDMI_OUTPUTS
595    audioOutput = NEXUS_HdmiOutput_GetAudioConnector(platformConfig.outputs.hdmi[0]);
596    NEXUS_AudioOutput_GetSettings(audioOutput, &audioOutputSettings);
597    audioOutputSettings.timebase = timebaseOutput;
598    rc = NEXUS_AudioOutput_SetSettings(audioOutput, &audioOutputSettings);
599    BDBG_ASSERT(!rc);
600#endif
601#endif
602
603    NEXUS_Display_GetSettings(decodeSession->display, &displaySettings);
604    displaySettings.timebase = timebaseOutput;
605    rc = NEXUS_Display_SetSettings(decodeSession->display, &displaySettings);
606    BDBG_ASSERT(!rc);
607
608    return decodeSession;
609}
610
611void 
612IpStopDecoders(DecodeSessionHandle decodeSession)
613{
614#ifdef AUDIO
615        NEXUS_AudioDecoder_Stop(decodeSession->audioDecoder);
616#endif
617        NEXUS_VideoDecoder_Stop(decodeSession->videoDecoder);
618}
619
620int main(int argc, char *argv[])
621{
622    unsigned nextProgramToDecode; /* next program that should be decoded */
623    unsigned nextPrimerToDecode; /* next priming session that should be decoded */
624    unsigned nextPrimerToUse; /* next primer index available for priming */
625    unsigned nextProgramToPrime; /* next program to prime */
626    NEXUS_Error rc;
627    IpSessionHandle ipSessionList[NUM_PRIMERS];
628    DecodeSessionHandle decodeSession = NULL;
629    unsigned maxPrimers = NUM_PRIMERS;
630
631    if (NEXUS_Platform_Init(NULL) != NEXUS_SUCCESS)
632        BDBG_ASSERT(NULL);
633
634    B_Os_Init();
635
636    decodeSession = decodeSessionInit();
637    BDBG_ASSERT(decodeSession);
638
639    if (!((argc > 1) && argv[1] && (maxPrimers = atoi(argv[1]))<=NUM_PRIMERS))
640    {
641        maxPrimers = NUM_PRIMERS;
642    }   
643
644    if((maxPrimers > 0) && (maxPrimers <= NUM_PRIMERS)) {
645        for ( nextProgramToPrime = 0, nextPrimerToUse=0; 
646              nextPrimerToUse < maxPrimers; 
647              nextProgramToPrime++, nextPrimerToUse++) 
648        {
649            ipSessionList[nextPrimerToUse] = IpPrimerSessionStart(nextPrimerToUse, &ipChannelList[nextProgramToPrime], decodeSession);
650        }
651    /* start decode on priming session 0 */
652    nextProgramToDecode = 0;
653    rc = IpSessionStartDecodeWithPrimer(ipSessionList[nextProgramToDecode], decodeSession);
654    BDBG_ASSERT(!rc);
655
656    /* since 1st priming session is now being decoded and all primers were being initially used, so next available primer is 0 */
657    nextPrimerToUse = 0;
658    nextPrimerToDecode = 1;
659    nextProgramToPrime = maxPrimers % NUM_PROGRAMS;
660    nextProgramToDecode = 1;
661   
662    while (1) 
663    {
664#if 0
665        BDBG_WRN(("Switching Channels every 4 sec\n"));
666        BKNI_Sleep(4000);
667#else
668        BDBG_WRN(("Press Enter to Channel Up............"));
669        getchar();
670#endif
671        BDBG_WRN((">>>>>>>>>>>>>>>>> starting program %d decode with primer id %d: video pid 0x%x, audio pid 0x%x", nextProgramToDecode, nextPrimerToDecode, ipSessionList[nextPrimerToDecode]->psi.videoPid, ipSessionList[nextPrimerToDecode]->psi.audioPid));
672        /* stop the current decoders */
673        IpStopDecoders(decodeSession);
674
675        /* start next decode session using next primer */
676        rc = IpSessionStartDecodeWithPrimer(ipSessionList[nextPrimerToDecode], decodeSession);
677        BDBG_ASSERT(!rc);
678        if (++nextPrimerToDecode == maxPrimers) nextPrimerToDecode = 0;
679
680        /* stop/close the unused primer before we can reuse it */
681        IpPrimerSessionStop(ipSessionList[nextPrimerToUse], decodeSession);
682
683#if 0
684        BDBG_WRN(("sleeping extra 50 msec"));
685        BKNI_Sleep(500);
686#endif
687        /* start priming next program on this primer now */
688        ipSessionList[nextPrimerToUse] = IpPrimerSessionStart(nextPrimerToUse, &ipChannelList[nextProgramToPrime], decodeSession);
689
690        if (++nextPrimerToUse == maxPrimers) nextPrimerToUse = 0;
691        if (++nextProgramToPrime == NUM_PROGRAMS) nextProgramToPrime = 0;
692        if (++nextProgramToDecode == NUM_PROGRAMS) nextProgramToDecode = 0;
693    }
694
695    IpsClose(ipSessionList[0]);
696    }
697    return 0;
698}
Note: See TracBrowser for help on using the repository browser.