| 1 | /****************************************************************************** |
|---|
| 2 | * (c)2008-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: playback.c $ |
|---|
| 39 | * $brcm_Revision: 82 $ |
|---|
| 40 | * $brcm_Date: 2/22/12 1:52p $ |
|---|
| 41 | * |
|---|
| 42 | * Module Description: |
|---|
| 43 | * |
|---|
| 44 | * Revision History: |
|---|
| 45 | * |
|---|
| 46 | * $brcm_Log: /nexus/utils/playback.c $ |
|---|
| 47 | * |
|---|
| 48 | * 82 2/22/12 1:52p vsilyaev |
|---|
| 49 | * SW7425-2258: Improved handling of MJPEG decoders |
|---|
| 50 | * |
|---|
| 51 | * 81 2/21/12 12:21p erickson |
|---|
| 52 | * SW7208-183: can't call cmdline_probe until after NEXUS_Platform_Init |
|---|
| 53 | * because it calls thunked core module functions |
|---|
| 54 | * |
|---|
| 55 | * 80 2/14/12 12:32p erickson |
|---|
| 56 | * SW7425-2282: seek now fails if out of bounds |
|---|
| 57 | * |
|---|
| 58 | * 79 1/31/12 5:07p rjlewis |
|---|
| 59 | * SW7425-1136: Added HDMI support (and some cleanup). |
|---|
| 60 | * |
|---|
| 61 | * 78 1/26/12 1:32p erickson |
|---|
| 62 | * SW7425-2250: print hex PTS/STC values, add audio/video queue depth to |
|---|
| 63 | * status |
|---|
| 64 | * |
|---|
| 65 | * 77 1/19/12 11:52a erickson |
|---|
| 66 | * SW7346-629: add -cmp_crc and -avd_crc options |
|---|
| 67 | * |
|---|
| 68 | * 76 1/11/12 6:13p vsilyaev |
|---|
| 69 | * SW7425-2112: Added option to limit playback rate |
|---|
| 70 | * |
|---|
| 71 | * 75 1/10/12 11:11a jgarrett |
|---|
| 72 | * SW7231-524: Fixing multichannel audio playback |
|---|
| 73 | * |
|---|
| 74 | * 74 11/9/11 5:10p erickson |
|---|
| 75 | * SW7405-5317: add host(bcm,X) |
|---|
| 76 | * |
|---|
| 77 | * 73 11/9/11 2:14p erickson |
|---|
| 78 | * SW7335-1368: avoid round to zero, clarify 3rd param of host() is |
|---|
| 79 | * slowmotion rate, not overall rate |
|---|
| 80 | * |
|---|
| 81 | * 72 10/19/11 3:52p erickson |
|---|
| 82 | * SW7335-1368: don't allow non-zero rate to round down to zero (pause) |
|---|
| 83 | * |
|---|
| 84 | * 71 10/12/11 11:44a erickson |
|---|
| 85 | * SW7425-1264: don't abs rate |
|---|
| 86 | * |
|---|
| 87 | * 70 8/29/11 10:32a erickson |
|---|
| 88 | * SW7425-1205: add host(gop,X) option |
|---|
| 89 | * |
|---|
| 90 | * 69 7/13/11 8:39p vsilyaev |
|---|
| 91 | * SWDTV-7897: Added code to wrap PCM file with the WAV header |
|---|
| 92 | * |
|---|
| 93 | * 68 7/7/11 5:53p jtna |
|---|
| 94 | * SW7425-869: added runtime option to override |
|---|
| 95 | * NEXUS_VideoDecoderSourceOrientation |
|---|
| 96 | * |
|---|
| 97 | * 67 5/13/11 12:17p erickson |
|---|
| 98 | * SW7420-1873: remove shutdown attribute |
|---|
| 99 | * |
|---|
| 100 | * 66 5/11/11 12:49p erickson |
|---|
| 101 | * SW7405-5317: add host trick mode command |
|---|
| 102 | * |
|---|
| 103 | * 65 4/22/11 5:49p vsilyaev |
|---|
| 104 | * SW7425-416: Added option to override display orientation |
|---|
| 105 | * |
|---|
| 106 | * 64 3/23/11 5:41p vsilyaev |
|---|
| 107 | * SW7422-406: Unified parsing of command line parameters |
|---|
| 108 | * |
|---|
| 109 | * 63 3/23/11 2:48p vsilyaev |
|---|
| 110 | * SW7422-14: Added status for the enhanced layer FIFO |
|---|
| 111 | * |
|---|
| 112 | * 62 3/15/11 2:15p erickson |
|---|
| 113 | * SW7346-101: fix dss playback |
|---|
| 114 | * |
|---|
| 115 | * 61 3/11/11 3:35p vsilyaev |
|---|
| 116 | * SW7422-14: Added support for decoding SVC/MVC streams |
|---|
| 117 | * |
|---|
| 118 | * 60 3/4/11 3:18p jgarrett |
|---|
| 119 | * SW7422-146: Adding multichannel audio support |
|---|
| 120 | * |
|---|
| 121 | * 59 1/7/11 3:31p jtna |
|---|
| 122 | * SW7422-165: use NEXUS_VideoDecoderStatus.ptsStcDifference to calculate |
|---|
| 123 | * PTS - STC difference |
|---|
| 124 | * |
|---|
| 125 | * 58 11/23/10 8:39p vsilyaev |
|---|
| 126 | * SW35230-2195: Added compile time option to capture and restore stream |
|---|
| 127 | * data with relative timing |
|---|
| 128 | * |
|---|
| 129 | * 57 11/17/10 3:58p jgarrett |
|---|
| 130 | * SW7408-137: Adding HDMI output |
|---|
| 131 | * |
|---|
| 132 | * 56 10/27/10 3:26p erickson |
|---|
| 133 | * SW7422-69: fix dtv |
|---|
| 134 | * |
|---|
| 135 | * 55 10/22/10 12:17p vsilyaev |
|---|
| 136 | * SW3548-3106: Added option to start playback in a paused state |
|---|
| 137 | * |
|---|
| 138 | * 54 10/5/10 10:41a erickson |
|---|
| 139 | * SW7422-65: add index |
|---|
| 140 | * |
|---|
| 141 | * 53 9/8/10 12:06p vsilyaev |
|---|
| 142 | * SW7468-129: Added video decoder on ZSP |
|---|
| 143 | * |
|---|
| 144 | * 52 8/31/10 2:44p erickson |
|---|
| 145 | * SWGIGGSVIZIO-57: add -fixed_bitrate option to set |
|---|
| 146 | * NEXUS_PlaybackMode_eFixedBitrate |
|---|
| 147 | * |
|---|
| 148 | * 51 8/9/10 6:48a erickson |
|---|
| 149 | * SW7420-933: don't assert for fast or reverse trick modes |
|---|
| 150 | * |
|---|
| 151 | * 50 7/14/10 6:12p vsilyaev |
|---|
| 152 | * SW3556-1131: Added basic support for CDXA format |
|---|
| 153 | * |
|---|
| 154 | * 49 6/18/10 4:38p vsilyaev |
|---|
| 155 | * SW3548-2988: Don't open pidChannel if pid is 0 |
|---|
| 156 | * |
|---|
| 157 | * 48 6/1/10 3:56p erickson |
|---|
| 158 | * SW3548-2962: add runtime bvn_usage(ID) command |
|---|
| 159 | * |
|---|
| 160 | * 47 5/10/10 12:59p vsilyaev |
|---|
| 161 | * SW3548-2920: Added printout for End Of Stream |
|---|
| 162 | * |
|---|
| 163 | * 46 5/5/10 10:43a vsilyaev |
|---|
| 164 | * SW7405-1260: Added settings for size of the audio decoder buffer |
|---|
| 165 | * |
|---|
| 166 | * 45 2/23/10 4:50p vsilyaev |
|---|
| 167 | * SW3556-913: Added code that monitors state of the playback file and |
|---|
| 168 | * restarts playback (from last good position) in case of error |
|---|
| 169 | * |
|---|
| 170 | * 44 2/22/10 5:33p vsilyaev |
|---|
| 171 | * SW3556-913: Added option to plug Custom File I/O routines to inject |
|---|
| 172 | * errors |
|---|
| 173 | * |
|---|
| 174 | * 43 2/18/10 6:00p vsilyaev |
|---|
| 175 | * SW3556-913: Added command to restart playback |
|---|
| 176 | * |
|---|
| 177 | * 42 2/12/10 5:56p jtna |
|---|
| 178 | * SW3556-1051: added option to control playback timestamp reordering |
|---|
| 179 | * |
|---|
| 180 | * 41 12/30/09 3:19p vsilyaev |
|---|
| 181 | * SW7408-17: Added options to select PCM and compressed audio outputs |
|---|
| 182 | * |
|---|
| 183 | * 40 12/30/09 2:13p erickson |
|---|
| 184 | * SW7550-128: add closed caption feature (-cc on) |
|---|
| 185 | * |
|---|
| 186 | * 39 11/25/09 5:24p katrep |
|---|
| 187 | * SW7405-2740: Add support for WMA pro drc |
|---|
| 188 | * |
|---|
| 189 | * 38 11/20/09 3:54p erickson |
|---|
| 190 | * SW7405-3260: remove unused #include nexus_astm.h |
|---|
| 191 | * |
|---|
| 192 | * 37 10/20/09 4:32p erickson |
|---|
| 193 | * SW7405-3260: allow trick modes on streams where video/audio pid == 0. |
|---|
| 194 | * this is normal for AVI/ASF stream ids. |
|---|
| 195 | * |
|---|
| 196 | * 36 10/19/09 11:24a gmohile |
|---|
| 197 | * SW7405-3209 : Add support for streams where pcr pid is different from |
|---|
| 198 | * video pid |
|---|
| 199 | * |
|---|
| 200 | * 35 8/18/09 4:36p vsilyaev |
|---|
| 201 | * PR 56809: Added option to control handling of video errors |
|---|
| 202 | * |
|---|
| 203 | * 34 7/21/09 5:57p vsilyaev |
|---|
| 204 | * PR 56977: Nexus playback always control audio and video decoder. |
|---|
| 205 | * Provided way for the user to control the decoder slowmotion factor |
|---|
| 206 | * using the playback trick API. |
|---|
| 207 | * |
|---|
| 208 | * 33 7/15/09 7:27p vsilyaev |
|---|
| 209 | * PR 55653: Added WAV format |
|---|
| 210 | * |
|---|
| 211 | * 32 6/22/09 5:26p jtna |
|---|
| 212 | * PR55571: vdecoder trick modes require adecoder to be stopped |
|---|
| 213 | * |
|---|
| 214 | * 31 6/19/09 5:20p vsilyaev |
|---|
| 215 | * PR 56169: Added option to set max decode rate |
|---|
| 216 | * |
|---|
| 217 | * 30 6/8/09 7:06a erickson |
|---|
| 218 | * PR55617: add user-specific aspectRatio |
|---|
| 219 | * |
|---|
| 220 | * 29 5/22/09 6:28p vsilyaev |
|---|
| 221 | * PR 55376 PR 52344: Use custom heap configuration when enabled |
|---|
| 222 | * AVC(H.264) Level 5.1 decoding |
|---|
| 223 | * |
|---|
| 224 | * 28 5/22/09 5:21p vsilyaev |
|---|
| 225 | * PR 55376 PR 52344: Added option to enable processing of AVC(H.264) |
|---|
| 226 | * Level 5.1 video |
|---|
| 227 | * |
|---|
| 228 | * 27 5/15/09 1:23p vsilyaev |
|---|
| 229 | * PR 55193: Updated way on how we report status |
|---|
| 230 | * |
|---|
| 231 | * 26 5/15/09 12:48p vsilyaev |
|---|
| 232 | * PR 55193: Added function to return last parsed PTS by the media library |
|---|
| 233 | * |
|---|
| 234 | * 25 3/27/09 12:51p vsilyaev |
|---|
| 235 | * PR 50311: Return readPosition in the Nexus playback status. In |
|---|
| 236 | * combination with the position it could be used to measure depth of |
|---|
| 237 | * decoder and playback buffers in units of time. |
|---|
| 238 | * |
|---|
| 239 | * 24 3/18/09 10:26a erickson |
|---|
| 240 | * PR52350: add wxga/fha support with 50/60 hz option |
|---|
| 241 | * |
|---|
| 242 | * 23 3/6/09 3:38p vsilyaev |
|---|
| 243 | * PR 52831: Added shutdown code |
|---|
| 244 | * |
|---|
| 245 | * 22 3/6/09 9:33a erickson |
|---|
| 246 | * PR51743: added -ar and -graphics options, default DTV apps to panel |
|---|
| 247 | * output |
|---|
| 248 | * |
|---|
| 249 | * 21 2/27/09 5:05p vsilyaev |
|---|
| 250 | * PR 52634: Added code to handle MPEG-2 TS streams with timesampts (e.g. |
|---|
| 251 | * 192 byte packets) |
|---|
| 252 | * |
|---|
| 253 | * 20 2/20/09 2:06p vsilyaev |
|---|
| 254 | * PR 51467: Added option to set size of the video decoder buffer |
|---|
| 255 | * |
|---|
| 256 | * 19 2/5/09 2:12p erickson |
|---|
| 257 | * PR51151: update |
|---|
| 258 | * |
|---|
| 259 | * 18 1/26/09 1:15p vsilyaev |
|---|
| 260 | * PR 51351: Added option to seek using minutes and seconds |
|---|
| 261 | * |
|---|
| 262 | * 17 1/26/09 11:26a vsilyaev |
|---|
| 263 | * PR 51579: Added stream_processing and auto_bitrate options |
|---|
| 264 | * |
|---|
| 265 | * 16 1/23/09 5:12p erickson |
|---|
| 266 | * PR48944: update |
|---|
| 267 | * |
|---|
| 268 | * 15 1/22/09 7:48p vsilyaev |
|---|
| 269 | * PR 50848: Don't use globals for the command line options |
|---|
| 270 | * |
|---|
| 271 | * 14 1/20/09 4:28p erickson |
|---|
| 272 | * PR48944: add -mad and -display_format options |
|---|
| 273 | * |
|---|
| 274 | * 13 1/8/09 10:48p erickson |
|---|
| 275 | * PR50861: added avdStatusBlock |
|---|
| 276 | * |
|---|
| 277 | * 12 1/8/09 10:34p erickson |
|---|
| 278 | * PR48944: add more options |
|---|
| 279 | * |
|---|
| 280 | * 11 1/8/09 9:36p erickson |
|---|
| 281 | * PR50757: added NEXUS_VideoFrameRate support, both as a start setting |
|---|
| 282 | * and status |
|---|
| 283 | * |
|---|
| 284 | * 10 1/7/09 9:50p erickson |
|---|
| 285 | * PR50763: fix segfault |
|---|
| 286 | * |
|---|
| 287 | * 9 1/6/09 1:11a erickson |
|---|
| 288 | * PR50763: added sleep and ; delimiter |
|---|
| 289 | * |
|---|
| 290 | * 8 1/6/09 12:45a erickson |
|---|
| 291 | * PR50763: added -bof, -eof options. added playback position to status. |
|---|
| 292 | * fix mkv, mp4. |
|---|
| 293 | * |
|---|
| 294 | * 7 1/5/09 12:49p erickson |
|---|
| 295 | * PR50763: update for mkv testing |
|---|
| 296 | * |
|---|
| 297 | * 6 12/11/08 3:25p erickson |
|---|
| 298 | * PR48944: fix playback index support |
|---|
| 299 | * |
|---|
| 300 | * 5 12/3/08 3:55p erickson |
|---|
| 301 | * PR48944: update |
|---|
| 302 | * |
|---|
| 303 | * 4 11/26/08 8:52a erickson |
|---|
| 304 | * PR48944: more status |
|---|
| 305 | * |
|---|
| 306 | * 3 11/19/08 1:30p erickson |
|---|
| 307 | * PR48944: update |
|---|
| 308 | * |
|---|
| 309 | * 2 11/17/08 2:19p erickson |
|---|
| 310 | * PR48944: update |
|---|
| 311 | * |
|---|
| 312 | * 1 11/17/08 12:34p erickson |
|---|
| 313 | * PR48944: add utils |
|---|
| 314 | * |
|---|
| 315 | *****************************************************************************/ |
|---|
| 316 | |
|---|
| 317 | #include "nexus_platform.h" |
|---|
| 318 | #include "nexus_core_utils.h" |
|---|
| 319 | #include "nexus_video_decoder.h" |
|---|
| 320 | #include "nexus_video_decoder_trick.h" |
|---|
| 321 | #include "nexus_video_decoder_extra.h" |
|---|
| 322 | #include "nexus_video_adj.h" |
|---|
| 323 | #include "nexus_stc_channel.h" |
|---|
| 324 | #include "nexus_display.h" |
|---|
| 325 | #include "nexus_display_vbi.h" |
|---|
| 326 | #include "nexus_video_window.h" |
|---|
| 327 | #include "nexus_video_input.h" |
|---|
| 328 | #include "nexus_audio_dac.h" |
|---|
| 329 | #include "nexus_audio_decoder.h" |
|---|
| 330 | #include "nexus_audio_decoder_trick.h" |
|---|
| 331 | #include "nexus_audio_output.h" |
|---|
| 332 | #include "nexus_audio_input.h" |
|---|
| 333 | #include "nexus_audio_playback.h" |
|---|
| 334 | #include "nexus_spdif_output.h" |
|---|
| 335 | #include "nexus_composite_output.h" |
|---|
| 336 | #include "nexus_component_output.h" |
|---|
| 337 | #if NEXUS_HAS_HDMI_OUTPUT |
|---|
| 338 | #include "nexus_hdmi_output.h" |
|---|
| 339 | #endif |
|---|
| 340 | #include "nexus_surface.h" |
|---|
| 341 | #if NEXUS_HAS_PLAYBACK |
|---|
| 342 | #include "nexus_playback.h" |
|---|
| 343 | #include "nexus_file.h" |
|---|
| 344 | #endif |
|---|
| 345 | #include "cmdline_args.h" |
|---|
| 346 | |
|---|
| 347 | #include <stdio.h> |
|---|
| 348 | #include <string.h> |
|---|
| 349 | #include <assert.h> |
|---|
| 350 | #include <stdlib.h> |
|---|
| 351 | #include "bstd.h" |
|---|
| 352 | #include "bkni.h" |
|---|
| 353 | #include "fileio_custom.h" |
|---|
| 354 | #include "bmedia_cdxa.h" |
|---|
| 355 | #include "nexus_file_pvr.h" |
|---|
| 356 | |
|---|
| 357 | BDBG_MODULE(playback); |
|---|
| 358 | |
|---|
| 359 | #if !NEXUS_HAS_PLAYBACK |
|---|
| 360 | int main(void) |
|---|
| 361 | { |
|---|
| 362 | printf("This application is not supported on this platform (needs Playback)!\n"); |
|---|
| 363 | return 0; |
|---|
| 364 | } |
|---|
| 365 | #else |
|---|
| 366 | |
|---|
| 367 | static void print_cmp_crc(NEXUS_DisplayHandle display); |
|---|
| 368 | static void print_avd_crc(NEXUS_VideoDecoderHandle videoDecoder); |
|---|
| 369 | |
|---|
| 370 | /* this should be enabled with conjunction of enabling READ_TIMED_DATA in BSEAV/lib/utils/bsink_playback.c */ |
|---|
| 371 | /* #define READ_TIMED_DATA 1 */ |
|---|
| 372 | |
|---|
| 373 | #if READ_TIMED_DATA |
|---|
| 374 | #include "nexus_memory.h" |
|---|
| 375 | #include "barena.h" |
|---|
| 376 | static void *b_nexus_alloc(balloc_iface_t alloc, size_t size) |
|---|
| 377 | { |
|---|
| 378 | NEXUS_Error rc; |
|---|
| 379 | void *b; |
|---|
| 380 | BSTD_UNUSED(alloc); |
|---|
| 381 | rc = NEXUS_Memory_Allocate(size, NULL, &b); |
|---|
| 382 | if(rc==NEXUS_SUCCESS) {return b;} |
|---|
| 383 | else {return NULL;} |
|---|
| 384 | } |
|---|
| 385 | |
|---|
| 386 | static void b_nexus_free(balloc_iface_t alloc, void *ptr) |
|---|
| 387 | { |
|---|
| 388 | BSTD_UNUSED(alloc); |
|---|
| 389 | NEXUS_Memory_Free(ptr); |
|---|
| 390 | } |
|---|
| 391 | |
|---|
| 392 | static const struct balloc_iface b_nexus_alloc_iface = { |
|---|
| 393 | b_nexus_alloc, b_nexus_free |
|---|
| 394 | }; |
|---|
| 395 | |
|---|
| 396 | extern balloc_iface_t bsink_dump_reader_allocator; |
|---|
| 397 | #endif /* READ_TIMED_DATA */ |
|---|
| 398 | |
|---|
| 399 | |
|---|
| 400 | static void start_video(const struct util_opts_t *opts, NEXUS_VideoDecoderHandle videoDecoder, const NEXUS_VideoDecoderStartSettings *videoProgram) |
|---|
| 401 | { |
|---|
| 402 | NEXUS_Error rc; |
|---|
| 403 | if (opts->common.videoPid) { |
|---|
| 404 | rc = NEXUS_VideoDecoder_Start(videoDecoder, videoProgram); |
|---|
| 405 | if(rc!=NEXUS_SUCCESS) { |
|---|
| 406 | bool supported=true; |
|---|
| 407 | NEXUS_VideoDecoder_IsCodecSupported(videoDecoder, videoProgram->codec, &supported); |
|---|
| 408 | if(!supported) { |
|---|
| 409 | unsigned i; |
|---|
| 410 | bool found_supported=false; |
|---|
| 411 | unsigned num_decoders = NEXUS_NUM_VIDEO_DECODERS; |
|---|
| 412 | |
|---|
| 413 | BDBG_LOG(("VideoDecoder:%u doesn't support codec %u", opts->common.videoDecoder, videoProgram->codec)); |
|---|
| 414 | #if NEXUS_NUM_DSP_VIDEO_DECODERS |
|---|
| 415 | num_decoders += NEXUS_NUM_DSP_VIDEO_DECODERS; |
|---|
| 416 | #endif |
|---|
| 417 | |
|---|
| 418 | #if NEXUS_NUM_SID_VIDEO_DECODERS |
|---|
| 419 | num_decoders += NEXUS_NUM_SID_VIDEO_DECODERS; |
|---|
| 420 | #endif |
|---|
| 421 | |
|---|
| 422 | for(i=0;i<num_decoders;i++) { |
|---|
| 423 | NEXUS_VideoDecoderHandle decoder; |
|---|
| 424 | if(i==opts->common.videoDecoder) { |
|---|
| 425 | continue; |
|---|
| 426 | } |
|---|
| 427 | decoder = NEXUS_VideoDecoder_Open(i, NULL); |
|---|
| 428 | if(decoder) { |
|---|
| 429 | NEXUS_VideoDecoder_IsCodecSupported(decoder, videoProgram->codec, &supported); |
|---|
| 430 | if(supported) { |
|---|
| 431 | if(!found_supported) { |
|---|
| 432 | found_supported = true; |
|---|
| 433 | BDBG_LOG(("try to run with the '-video_decoder n' option, where 'n' is the index of the video decoder that supports codec %u", videoProgram->codec)); |
|---|
| 434 | } |
|---|
| 435 | BDBG_LOG(("VideoDecoder:%u supports codec %u", i, videoProgram->codec)); |
|---|
| 436 | } |
|---|
| 437 | NEXUS_VideoDecoder_Close(decoder); |
|---|
| 438 | } |
|---|
| 439 | } |
|---|
| 440 | } |
|---|
| 441 | BDBG_ASSERT(false); |
|---|
| 442 | } |
|---|
| 443 | } |
|---|
| 444 | return; |
|---|
| 445 | } |
|---|
| 446 | static void stop_video(const struct util_opts_t *opts, NEXUS_VideoDecoderHandle videoDecoder) |
|---|
| 447 | { |
|---|
| 448 | if (opts->common.videoPid) { |
|---|
| 449 | NEXUS_VideoDecoder_Stop(videoDecoder); |
|---|
| 450 | } |
|---|
| 451 | return; |
|---|
| 452 | } |
|---|
| 453 | |
|---|
| 454 | static void start_audio(const struct util_opts_t *opts, NEXUS_AudioDecoderHandle audioDecoder, NEXUS_AudioDecoderHandle compressedDecoder, const NEXUS_AudioDecoderStartSettings *audioProgram) |
|---|
| 455 | { |
|---|
| 456 | NEXUS_Error rc; |
|---|
| 457 | if (opts->common.audioPid) { |
|---|
| 458 | #if B_HAS_ASF |
|---|
| 459 | /* if DRC for WMA pro is available apply now */ |
|---|
| 460 | if(audioProgram->codec == NEXUS_AudioCodec_eWmaPro && opts->common.dynamicRangeControlValid ){ |
|---|
| 461 | |
|---|
| 462 | NEXUS_AudioDecoderCodecSettings codecSettings; |
|---|
| 463 | |
|---|
| 464 | BDBG_WRN(("wma-pro drc enabled,ref peak %d,ref target %d,ave peak %d, ave target %d", |
|---|
| 465 | opts->common.dynamicRangeControl.peakReference,opts->common.dynamicRangeControl.peakTarget, |
|---|
| 466 | opts->common.dynamicRangeControl.averageReference,opts->common.dynamicRangeControl.averageTarget)); |
|---|
| 467 | NEXUS_AudioDecoder_GetCodecSettings(audioDecoder, audioProgram->codec, &codecSettings); |
|---|
| 468 | codecSettings.codec = audioProgram->codec; |
|---|
| 469 | codecSettings.codecSettings.wmaPro.dynamicRangeControlValid = true; |
|---|
| 470 | codecSettings.codecSettings.wmaPro.dynamicRangeControl.peakReference = opts->common.dynamicRangeControl.peakReference; |
|---|
| 471 | codecSettings.codecSettings.wmaPro.dynamicRangeControl.peakTarget = opts->common.dynamicRangeControl.peakTarget; |
|---|
| 472 | codecSettings.codecSettings.wmaPro.dynamicRangeControl.averageReference = opts->common.dynamicRangeControl.averageReference; |
|---|
| 473 | codecSettings.codecSettings.wmaPro.dynamicRangeControl.averageTarget = opts->common.dynamicRangeControl.averageTarget; |
|---|
| 474 | NEXUS_AudioDecoder_SetCodecSettings(audioDecoder,&codecSettings); |
|---|
| 475 | } |
|---|
| 476 | #endif |
|---|
| 477 | |
|---|
| 478 | if(opts->common.decodedAudio) { |
|---|
| 479 | rc = NEXUS_AudioDecoder_Start(audioDecoder, audioProgram); |
|---|
| 480 | BDBG_ASSERT(!rc); |
|---|
| 481 | } |
|---|
| 482 | if(compressedDecoder) { |
|---|
| 483 | rc = NEXUS_AudioDecoder_Start(compressedDecoder, audioProgram); |
|---|
| 484 | /* This may fail in some cases because we haven't atached any outputs. Don't assert. */ |
|---|
| 485 | /*BDBG_ASSERT(!rc);*/ |
|---|
| 486 | } |
|---|
| 487 | } |
|---|
| 488 | return; |
|---|
| 489 | } |
|---|
| 490 | |
|---|
| 491 | static void stop_audio(const struct util_opts_t *opts, NEXUS_AudioDecoderHandle audioDecoder, NEXUS_AudioDecoderHandle compressedDecoder) |
|---|
| 492 | { |
|---|
| 493 | if (opts->common.audioPid) { |
|---|
| 494 | if(opts->common.decodedAudio) { |
|---|
| 495 | NEXUS_AudioDecoder_Stop(audioDecoder); |
|---|
| 496 | } |
|---|
| 497 | if(compressedDecoder) { |
|---|
| 498 | NEXUS_AudioDecoder_Stop(compressedDecoder); |
|---|
| 499 | } |
|---|
| 500 | } |
|---|
| 501 | return; |
|---|
| 502 | } |
|---|
| 503 | |
|---|
| 504 | #define B_HAS_PLAYBACK_MONITOR 0 |
|---|
| 505 | #if B_HAS_PLAYBACK_MONITOR |
|---|
| 506 | #include <pthread.h> |
|---|
| 507 | #include "bkni_multi.h" |
|---|
| 508 | |
|---|
| 509 | typedef struct PlaybackMonitorState { |
|---|
| 510 | bool terminate; |
|---|
| 511 | pthread_t thread; |
|---|
| 512 | BKNI_MutexHandle lock; |
|---|
| 513 | const struct util_opts_t *opts; |
|---|
| 514 | NEXUS_PlaybackHandle playback; |
|---|
| 515 | NEXUS_VideoDecoderHandle videoDecoder; |
|---|
| 516 | const NEXUS_VideoDecoderStartSettings *videoProgram; |
|---|
| 517 | NEXUS_AudioDecoderHandle audioDecoder; |
|---|
| 518 | NEXUS_AudioDecoderHandle compressedDecoder; |
|---|
| 519 | const NEXUS_AudioDecoderStartSettings *audioProgram; |
|---|
| 520 | NEXUS_FilePlayHandle file; |
|---|
| 521 | NEXUS_FilePlayHandle customFile; |
|---|
| 522 | NEXUS_FilePlayHandle stickyFile; |
|---|
| 523 | const NEXUS_PlaybackStartSettings *playbackStartSettings; |
|---|
| 524 | } PlaybackMonitorState; |
|---|
| 525 | |
|---|
| 526 | static void * |
|---|
| 527 | monitor_thread(void *state_) |
|---|
| 528 | { |
|---|
| 529 | const PlaybackMonitorState *state=state_; |
|---|
| 530 | while(!state->terminate) { |
|---|
| 531 | NEXUS_PlaybackStatus status; |
|---|
| 532 | NEXUS_PlaybackSettings playbackSettings; |
|---|
| 533 | NEXUS_VideoDecoderSettings videoDecoderSettings; |
|---|
| 534 | BERR_Code rc; |
|---|
| 535 | bool failed; |
|---|
| 536 | |
|---|
| 537 | rc = NEXUS_Playback_GetStatus(state->playback, &status); |
|---|
| 538 | BDBG_ASSERT(!rc); |
|---|
| 539 | BKNI_Sleep(1000); |
|---|
| 540 | FileIoSticky_GetFailBit(state->stickyFile, &failed); |
|---|
| 541 | if(!failed) { |
|---|
| 542 | continue; |
|---|
| 543 | } |
|---|
| 544 | |
|---|
| 545 | BDBG_WRN(("restarting from %u", status.position)); |
|---|
| 546 | BKNI_AcquireMutex(state->lock); |
|---|
| 547 | NEXUS_Playback_Stop(state->playback); |
|---|
| 548 | FileIoSticky_ClearFailBit(state->stickyFile); |
|---|
| 549 | if(state->customFile) { |
|---|
| 550 | FileIoCustomProbabilities probabilities; |
|---|
| 551 | FileIoCustom_GetProbabilities(state->customFile, NULL, &probabilities); |
|---|
| 552 | probabilities.error = 0; |
|---|
| 553 | probabilities.nodata = 0; |
|---|
| 554 | probabilities.partial_read = 0; |
|---|
| 555 | FileIoCustom_SetProbabilities(state->customFile, &probabilities, &probabilities); |
|---|
| 556 | } |
|---|
| 557 | |
|---|
| 558 | if (state->opts->videoPid) { |
|---|
| 559 | /* don't show black frame */ |
|---|
| 560 | NEXUS_VideoDecoder_GetSettings(state->videoDecoder, &videoDecoderSettings); |
|---|
| 561 | videoDecoderSettings.channelChangeMode = NEXUS_VideoDecoder_ChannelChangeMode_eHoldUntilTsmLock; |
|---|
| 562 | rc=NEXUS_VideoDecoder_SetSettings(state->videoDecoder, &videoDecoderSettings); |
|---|
| 563 | BDBG_ASSERT(!rc); |
|---|
| 564 | } |
|---|
| 565 | /* stop decoder */ |
|---|
| 566 | stop_video(state->opts, state->videoDecoder); |
|---|
| 567 | stop_audio(state->opts, state->audioDecoder, state->compressedDecoder); |
|---|
| 568 | |
|---|
| 569 | NEXUS_Playback_GetSettings(state->playback, &playbackSettings); |
|---|
| 570 | playbackSettings.startPaused = true; |
|---|
| 571 | rc = NEXUS_Playback_SetSettings(state->playback, &playbackSettings); |
|---|
| 572 | BDBG_ASSERT(!rc); |
|---|
| 573 | |
|---|
| 574 | /* Start decoders */ |
|---|
| 575 | start_video(state->opts, state->videoDecoder, state->videoProgram); |
|---|
| 576 | start_audio(state->opts, state->audioDecoder, state->compressedDecoder, state->audioProgram); |
|---|
| 577 | |
|---|
| 578 | /* start playback */ |
|---|
| 579 | rc = NEXUS_Playback_Start(state->playback, state->file, state->playbackStartSettings); |
|---|
| 580 | BDBG_ASSERT(!rc); |
|---|
| 581 | |
|---|
| 582 | /* seek into desired location */ |
|---|
| 583 | rc = NEXUS_Playback_Seek(state->playback, status.position); |
|---|
| 584 | BDBG_ASSERT(!rc); |
|---|
| 585 | |
|---|
| 586 | /* start playing */ |
|---|
| 587 | rc = NEXUS_Playback_Play(state->playback); |
|---|
| 588 | BDBG_ASSERT(!rc); |
|---|
| 589 | BKNI_ReleaseMutex(state->lock); |
|---|
| 590 | } |
|---|
| 591 | return NULL; |
|---|
| 592 | } |
|---|
| 593 | |
|---|
| 594 | static void |
|---|
| 595 | monitor_thread_start(PlaybackMonitorState *state) |
|---|
| 596 | { |
|---|
| 597 | int rc; |
|---|
| 598 | BKNI_CreateMutex(&state->lock); |
|---|
| 599 | state->terminate = false; |
|---|
| 600 | rc = pthread_create(&state->thread, NULL, monitor_thread, state); |
|---|
| 601 | BDBG_ASSERT(rc==0); |
|---|
| 602 | return; |
|---|
| 603 | } |
|---|
| 604 | |
|---|
| 605 | static void |
|---|
| 606 | monitor_thread_stop(PlaybackMonitorState *state) |
|---|
| 607 | { |
|---|
| 608 | state->terminate = true; |
|---|
| 609 | pthread_join(state->thread, NULL); |
|---|
| 610 | } |
|---|
| 611 | #endif /* B_HAS_PLAYBACK_MONITOR */ |
|---|
| 612 | |
|---|
| 613 | static void play_endOfStreamCallback(void *context, int param) |
|---|
| 614 | { |
|---|
| 615 | BSTD_UNUSED(param); |
|---|
| 616 | BSTD_UNUSED(context); |
|---|
| 617 | |
|---|
| 618 | printf("endOfStream\n"); |
|---|
| 619 | return; |
|---|
| 620 | } |
|---|
| 621 | |
|---|
| 622 | struct CdxaFile { |
|---|
| 623 | struct NEXUS_FilePlay interface; /* must be the first member */ |
|---|
| 624 | bcdxa_file_t data; |
|---|
| 625 | bcdxa_file_t index; |
|---|
| 626 | NEXUS_FilePlayHandle parent; |
|---|
| 627 | }; |
|---|
| 628 | |
|---|
| 629 | static void Cdxa_File_Close(struct NEXUS_FilePlay *file_) |
|---|
| 630 | { |
|---|
| 631 | struct CdxaFile *file = (void *)file_; |
|---|
| 632 | bcdxa_file_destroy(file->data); |
|---|
| 633 | if(file->index) { |
|---|
| 634 | bcdxa_file_destroy(file->index); |
|---|
| 635 | } |
|---|
| 636 | file->parent->file.close(file->parent); |
|---|
| 637 | BKNI_Free(file); |
|---|
| 638 | return; |
|---|
| 639 | } |
|---|
| 640 | |
|---|
| 641 | static NEXUS_FilePlayHandle Cdxa_File_Attach(NEXUS_FilePlayHandle parent) |
|---|
| 642 | { |
|---|
| 643 | struct CdxaFile *file; |
|---|
| 644 | file = BKNI_Malloc(sizeof(*file)); |
|---|
| 645 | BDBG_ASSERT(file); |
|---|
| 646 | file->parent = parent; |
|---|
| 647 | file->data = bcdxa_file_create(parent->file.data); |
|---|
| 648 | file->interface.file.close = Cdxa_File_Close; |
|---|
| 649 | BDBG_ASSERT(file->data); |
|---|
| 650 | file->interface.file.data = bcdxa_file_get_file_interface(file->data); |
|---|
| 651 | file->interface.file.index = NULL; |
|---|
| 652 | file->index = NULL; |
|---|
| 653 | if(parent->file.index) { |
|---|
| 654 | file->index = bcdxa_file_create(parent->file.index); |
|---|
| 655 | BDBG_ASSERT(file->index); |
|---|
| 656 | file->interface.file.index = bcdxa_file_get_file_interface(file->index); |
|---|
| 657 | } |
|---|
| 658 | return &file->interface; |
|---|
| 659 | } |
|---|
| 660 | |
|---|
| 661 | struct PcmFile { |
|---|
| 662 | struct NEXUS_FilePlay interface; /* must be the first member */ |
|---|
| 663 | bpcm_file_t data; |
|---|
| 664 | bpcm_file_t index; |
|---|
| 665 | NEXUS_FilePlayHandle parent; |
|---|
| 666 | }; |
|---|
| 667 | |
|---|
| 668 | static void Pcm_File_Close(struct NEXUS_FilePlay *file_) |
|---|
| 669 | { |
|---|
| 670 | struct PcmFile *file = (void *)file_; |
|---|
| 671 | bpcm_file_destroy(file->data); |
|---|
| 672 | if(file->index) { |
|---|
| 673 | bpcm_file_destroy(file->index); |
|---|
| 674 | } |
|---|
| 675 | file->parent->file.close(file->parent); |
|---|
| 676 | BKNI_Free(file); |
|---|
| 677 | return; |
|---|
| 678 | } |
|---|
| 679 | |
|---|
| 680 | static NEXUS_FilePlayHandle Pcm_File_Attach(NEXUS_FilePlayHandle parent, const bpcm_file_config *pcm_config) |
|---|
| 681 | { |
|---|
| 682 | struct PcmFile *file; |
|---|
| 683 | file = BKNI_Malloc(sizeof(*file)); |
|---|
| 684 | BDBG_ASSERT(file); |
|---|
| 685 | file->parent = parent; |
|---|
| 686 | file->data = bpcm_file_create(parent->file.data, pcm_config); |
|---|
| 687 | BDBG_ASSERT(file->data); |
|---|
| 688 | file->interface.file.data = bpcm_file_get_file_interface(file->data); |
|---|
| 689 | if(parent->file.index) { |
|---|
| 690 | file->index = bpcm_file_create(parent->file.index, pcm_config); |
|---|
| 691 | BDBG_ASSERT(file->index); |
|---|
| 692 | file->interface.file.index= bpcm_file_get_file_interface(file->index); |
|---|
| 693 | } else { |
|---|
| 694 | file->interface.file.index = NULL; |
|---|
| 695 | file->index = NULL; |
|---|
| 696 | } |
|---|
| 697 | file->interface.file.close = Pcm_File_Close; |
|---|
| 698 | return &file->interface; |
|---|
| 699 | } |
|---|
| 700 | |
|---|
| 701 | #if NEXUS_NUM_HDMI_OUTPUTS |
|---|
| 702 | /* registered HDMI hotplug handler -- changes the format (to monitor's default) if monitor doesn't support current format */ |
|---|
| 703 | static void hotplug_callback(void *pParam, int iParam) |
|---|
| 704 | { |
|---|
| 705 | NEXUS_HdmiOutputStatus hdmiStatus; |
|---|
| 706 | NEXUS_HdmiOutputHandle hdmi = pParam; |
|---|
| 707 | NEXUS_DisplayHandle display = (NEXUS_DisplayHandle)iParam; |
|---|
| 708 | NEXUS_Error rc; |
|---|
| 709 | |
|---|
| 710 | rc = NEXUS_HdmiOutput_GetStatus(hdmi, &hdmiStatus); |
|---|
| 711 | /*fprintf(stderr, "HDMI event: %s\n", hdmiStatus.connected?"connected":"not connected");*/ |
|---|
| 712 | |
|---|
| 713 | /* the app can choose to switch to the preferred format, but it's not required. */ |
|---|
| 714 | if ( !rc && hdmiStatus.connected ) |
|---|
| 715 | { |
|---|
| 716 | NEXUS_DisplaySettings displaySettings; |
|---|
| 717 | NEXUS_Display_GetSettings(display, &displaySettings); |
|---|
| 718 | if ( !hdmiStatus.videoFormatSupported[displaySettings.format] ) |
|---|
| 719 | { |
|---|
| 720 | fprintf(stderr, "Current format not supported by attached monitor -- switching to preferred format (%d)\n", hdmiStatus.preferredVideoFormat); |
|---|
| 721 | if (hdmiStatus.preferredVideoFormat >= NEXUS_VideoFormat_e480p) |
|---|
| 722 | fprintf(stderr, "Warning: This format may disable composite output!\n"); |
|---|
| 723 | displaySettings.format = hdmiStatus.preferredVideoFormat; |
|---|
| 724 | NEXUS_Display_SetSettings(display, &displaySettings); |
|---|
| 725 | } |
|---|
| 726 | } |
|---|
| 727 | } |
|---|
| 728 | #endif |
|---|
| 729 | |
|---|
| 730 | int main(int argc, const char *argv[]) |
|---|
| 731 | { |
|---|
| 732 | NEXUS_PlatformSettings platformSettings; |
|---|
| 733 | NEXUS_PlatformConfiguration platformConfig; |
|---|
| 734 | NEXUS_StcChannelHandle stcChannel; |
|---|
| 735 | NEXUS_StcChannelSettings stcSettings; |
|---|
| 736 | NEXUS_PidChannelHandle videoPidChannel = NULL, audioPidChannel = NULL, pcrPidChannel, videoExtPidChannel=NULL; |
|---|
| 737 | NEXUS_DisplayHandle display; |
|---|
| 738 | NEXUS_DisplaySettings displaySettings; |
|---|
| 739 | NEXUS_DisplayVbiSettings displayVbiSettings; |
|---|
| 740 | NEXUS_VideoWindowHandle window; |
|---|
| 741 | NEXUS_VideoWindowSettings windowSettings; |
|---|
| 742 | NEXUS_VideoDecoderHandle videoDecoder; |
|---|
| 743 | NEXUS_VideoDecoderSettings videoDecoderSettings; |
|---|
| 744 | NEXUS_VideoDecoderStartSettings videoProgram; |
|---|
| 745 | NEXUS_AudioDecoderHandle audioDecoder, compressedDecoder=NULL; |
|---|
| 746 | NEXUS_AudioDecoderStartSettings audioProgram; |
|---|
| 747 | NEXUS_FilePlayHandle file,customFile=NULL, stickyFile=NULL, cdxaFile=NULL, pcmFile=NULL; |
|---|
| 748 | NEXUS_PlaypumpHandle playpump; |
|---|
| 749 | NEXUS_PlaybackHandle playback; |
|---|
| 750 | NEXUS_PlaybackSettings playbackSettings; |
|---|
| 751 | NEXUS_PlaybackPidChannelSettings playbackPidSettings; |
|---|
| 752 | NEXUS_PlaybackStartSettings playbackStartSettings; |
|---|
| 753 | NEXUS_VideoDecoderOpenSettings openSettings; |
|---|
| 754 | NEXUS_Error rc; |
|---|
| 755 | bool exit; |
|---|
| 756 | NEXUS_SurfaceHandle framebuffer = NULL; |
|---|
| 757 | NEXUS_AudioDecoderOpenSettings audioDecoderOpenSettings; |
|---|
| 758 | struct util_opts_t opts; |
|---|
| 759 | |
|---|
| 760 | if (cmdline_parse(argc, argv, &opts)) { |
|---|
| 761 | return 0; |
|---|
| 762 | } |
|---|
| 763 | /* They MUST include a file to play */ |
|---|
| 764 | if (!opts.filename) { |
|---|
| 765 | BDBG_ERR(("Missing playback file; See usage.")); |
|---|
| 766 | print_usage(argv[0]); |
|---|
| 767 | return 0; |
|---|
| 768 | } |
|---|
| 769 | |
|---|
| 770 | /* Bring up all modules for a platform in a default configuraiton for this platform */ |
|---|
| 771 | NEXUS_Platform_GetDefaultSettings(&platformSettings); |
|---|
| 772 | platformSettings.openFrontend = false; |
|---|
| 773 | if(opts.avc51) { |
|---|
| 774 | platformSettings.videoDecoderModuleSettings.heapSize[0].general = (84*1024*1024); |
|---|
| 775 | platformSettings.videoDecoderModuleSettings.numDecodes = 1; |
|---|
| 776 | } |
|---|
| 777 | |
|---|
| 778 | rc = NEXUS_Platform_Init(&platformSettings); |
|---|
| 779 | BDBG_ASSERT(!rc); |
|---|
| 780 | NEXUS_Platform_GetConfiguration(&platformConfig); |
|---|
| 781 | |
|---|
| 782 | if (cmdline_probe(&opts.common, opts.filename, &opts.indexname)) { |
|---|
| 783 | return 1; |
|---|
| 784 | } |
|---|
| 785 | |
|---|
| 786 | playpump = NEXUS_Playpump_Open(0, NULL); |
|---|
| 787 | BDBG_ASSERT(playpump); |
|---|
| 788 | playback = NEXUS_Playback_Create(); |
|---|
| 789 | BDBG_ASSERT(playback); |
|---|
| 790 | |
|---|
| 791 | if ((opts.indexname && !strcmp(opts.indexname, "same")) || |
|---|
| 792 | opts.common.transportType == NEXUS_TransportType_eMkv || |
|---|
| 793 | opts.common.transportType == NEXUS_TransportType_eMp4 |
|---|
| 794 | ) |
|---|
| 795 | { |
|---|
| 796 | opts.indexname = opts.filename; |
|---|
| 797 | } |
|---|
| 798 | |
|---|
| 799 | file = NEXUS_FilePlay_OpenPosix(opts.filename, opts.indexname); |
|---|
| 800 | if (!file) { |
|---|
| 801 | fprintf(stderr, "can't open files: '%s' '%s'\n", opts.filename, opts.indexname); |
|---|
| 802 | return -1; |
|---|
| 803 | } |
|---|
| 804 | if(opts.customFileIo) { |
|---|
| 805 | customFile = file = FileIoCustom_Attach(file); |
|---|
| 806 | BDBG_ASSERT(file); |
|---|
| 807 | } |
|---|
| 808 | if(opts.common.cdxaFile) { |
|---|
| 809 | cdxaFile = file = Cdxa_File_Attach(file); |
|---|
| 810 | } |
|---|
| 811 | if(opts.common.pcm) { |
|---|
| 812 | pcmFile = file = Pcm_File_Attach(file, &opts.common.pcm_config); |
|---|
| 813 | } |
|---|
| 814 | if(opts.playbackMonitor) { |
|---|
| 815 | stickyFile = file = FileIoSticky_Attach(file); |
|---|
| 816 | BDBG_ASSERT(file); |
|---|
| 817 | } |
|---|
| 818 | |
|---|
| 819 | NEXUS_StcChannel_GetDefaultSettings(0, &stcSettings); |
|---|
| 820 | stcSettings.timebase = NEXUS_Timebase_e0; |
|---|
| 821 | stcSettings.mode = NEXUS_StcChannelMode_eAuto; |
|---|
| 822 | stcSettings.modeSettings.Auto.behavior = opts.stcChannelMaster; |
|---|
| 823 | stcSettings.modeSettings.Auto.transportType = opts.common.transportType; |
|---|
| 824 | stcChannel = NEXUS_StcChannel_Open(0, &stcSettings); |
|---|
| 825 | |
|---|
| 826 | NEXUS_Playback_GetSettings(playback, &playbackSettings); |
|---|
| 827 | playbackSettings.playpump = playpump; |
|---|
| 828 | playbackSettings.playpumpSettings.transportType = opts.common.transportType; |
|---|
| 829 | playbackSettings.playpumpSettings.timestamp.pacing = false; |
|---|
| 830 | playbackSettings.playpumpSettings.timestamp.type = opts.common.tsTimestampType; |
|---|
| 831 | if(opts.maxPlaybackDataRate) { |
|---|
| 832 | playbackSettings.playpumpSettings.maxDataRate = opts.maxPlaybackDataRate; |
|---|
| 833 | } |
|---|
| 834 | playbackSettings.startPaused = opts.startPaused; |
|---|
| 835 | playbackSettings.stcChannel = stcChannel; |
|---|
| 836 | playbackSettings.stcTrick = opts.stcTrick; |
|---|
| 837 | playbackSettings.beginningOfStreamAction = opts.beginningOfStreamAction; |
|---|
| 838 | playbackSettings.endOfStreamAction = opts.endOfStreamAction; |
|---|
| 839 | playbackSettings.endOfStreamCallback.callback = play_endOfStreamCallback; |
|---|
| 840 | playbackSettings.enableStreamProcessing = opts.streamProcessing; |
|---|
| 841 | rc = NEXUS_Playback_SetSettings(playback, &playbackSettings); |
|---|
| 842 | BDBG_ASSERT(!rc); |
|---|
| 843 | |
|---|
| 844 | NEXUS_AudioDecoder_GetDefaultOpenSettings(&audioDecoderOpenSettings); |
|---|
| 845 | if(opts.common.audioCdb) { |
|---|
| 846 | audioDecoderOpenSettings.fifoSize = opts.common.audioCdb*1024; |
|---|
| 847 | } |
|---|
| 848 | if (opts.common.multichannelAudio) { |
|---|
| 849 | audioDecoderOpenSettings.multichannelFormat = NEXUS_AudioMultichannelFormat_e5_1; |
|---|
| 850 | } |
|---|
| 851 | /* Bring up audio decoders and outputs */ |
|---|
| 852 | audioDecoder = NEXUS_AudioDecoder_Open(0, &audioDecoderOpenSettings); |
|---|
| 853 | BDBG_ASSERT(audioDecoder); |
|---|
| 854 | |
|---|
| 855 | if (opts.common.audioPid) { |
|---|
| 856 | rc = NEXUS_AudioOutput_AddInput( |
|---|
| 857 | NEXUS_AudioDac_GetConnector(platformConfig.outputs.audioDacs[0]), |
|---|
| 858 | NEXUS_AudioDecoder_GetConnector(audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo)); |
|---|
| 859 | BDBG_ASSERT(!rc); |
|---|
| 860 | } |
|---|
| 861 | if (opts.common.compressedAudio) { |
|---|
| 862 | audioDecoderOpenSettings.multichannelFormat = NEXUS_AudioMultichannelFormat_eNone; |
|---|
| 863 | compressedDecoder = NEXUS_AudioDecoder_Open(1, &audioDecoderOpenSettings); |
|---|
| 864 | BDBG_ASSERT(compressedDecoder); |
|---|
| 865 | if ( opts.common.audioCodec == NEXUS_AudioCodec_eAc3Plus || opts.common.audioCodec == NEXUS_AudioCodec_eWmaPro ) |
|---|
| 866 | { |
|---|
| 867 | /* These codecs pasthrough as part of decode (ac3+ is transcoded to ac3, wma pro is not transcoded) */ |
|---|
| 868 | rc = NEXUS_AudioOutput_AddInput( |
|---|
| 869 | NEXUS_SpdifOutput_GetConnector(platformConfig.outputs.spdif[0]), |
|---|
| 870 | NEXUS_AudioDecoder_GetConnector(audioDecoder, NEXUS_AudioDecoderConnectorType_eCompressed)); |
|---|
| 871 | } |
|---|
| 872 | else |
|---|
| 873 | { |
|---|
| 874 | rc = NEXUS_AudioOutput_AddInput( |
|---|
| 875 | NEXUS_SpdifOutput_GetConnector(platformConfig.outputs.spdif[0]), |
|---|
| 876 | NEXUS_AudioDecoder_GetConnector(compressedDecoder, NEXUS_AudioDecoderConnectorType_eCompressed)); |
|---|
| 877 | } |
|---|
| 878 | BDBG_ASSERT(!rc); |
|---|
| 879 | } |
|---|
| 880 | else |
|---|
| 881 | { |
|---|
| 882 | rc = NEXUS_AudioOutput_AddInput( |
|---|
| 883 | NEXUS_SpdifOutput_GetConnector(platformConfig.outputs.spdif[0]), |
|---|
| 884 | NEXUS_AudioDecoder_GetConnector(audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo)); |
|---|
| 885 | BDBG_ASSERT(!rc); |
|---|
| 886 | } |
|---|
| 887 | #if NEXUS_NUM_HDMI_OUTPUTS |
|---|
| 888 | if (opts.common.useHdmiOutput) |
|---|
| 889 | { |
|---|
| 890 | NEXUS_HdmiOutputStatus hdmiStatus; |
|---|
| 891 | NEXUS_AudioDecoderHandle hdmiDecoder = audioDecoder; |
|---|
| 892 | NEXUS_AudioDecoderConnectorType connectorType = NEXUS_AudioDecoderConnectorType_eStereo; |
|---|
| 893 | |
|---|
| 894 | NEXUS_HdmiOutput_GetStatus(platformConfig.outputs.hdmi[0], &hdmiStatus); |
|---|
| 895 | if ( opts.common.multichannelAudio && hdmiStatus.maxAudioPcmChannels > 2 ) |
|---|
| 896 | { |
|---|
| 897 | connectorType = NEXUS_AudioDecoderConnectorType_eMultichannel; |
|---|
| 898 | } |
|---|
| 899 | else if ( opts.common.compressedAudio ) |
|---|
| 900 | { |
|---|
| 901 | if ( hdmiStatus.audioCodecSupported[opts.common.audioCodec] ) |
|---|
| 902 | { |
|---|
| 903 | /* Codec is directly supported */ |
|---|
| 904 | hdmiDecoder = (opts.common.audioCodec == NEXUS_AudioCodec_eWmaPro) ? audioDecoder:compressedDecoder; |
|---|
| 905 | connectorType = NEXUS_AudioDecoderConnectorType_eCompressed; |
|---|
| 906 | } |
|---|
| 907 | else if ( opts.common.audioCodec == NEXUS_AudioCodec_eAc3Plus && hdmiStatus.audioCodecSupported[NEXUS_AudioCodec_eAc3] ) |
|---|
| 908 | { |
|---|
| 909 | /* AC3 is supported, convert ac3+ to ac3. */ |
|---|
| 910 | connectorType = NEXUS_AudioDecoderConnectorType_eCompressed; |
|---|
| 911 | } |
|---|
| 912 | } |
|---|
| 913 | |
|---|
| 914 | rc = NEXUS_AudioOutput_AddInput( |
|---|
| 915 | NEXUS_HdmiOutput_GetAudioConnector(platformConfig.outputs.hdmi[0]), |
|---|
| 916 | NEXUS_AudioDecoder_GetConnector(hdmiDecoder, connectorType)); |
|---|
| 917 | BDBG_ASSERT(!rc); |
|---|
| 918 | } |
|---|
| 919 | #endif /*NEXUS_NUM_HDMI_OUTPUTS*/ |
|---|
| 920 | |
|---|
| 921 | NEXUS_Display_GetDefaultSettings(&displaySettings); |
|---|
| 922 | displaySettings.displayType = opts.common.displayType; |
|---|
| 923 | displaySettings.format = opts.common.displayFormat; |
|---|
| 924 | if(opts.common.displayOrientation != NEXUS_VideoOrientation_e2D) { |
|---|
| 925 | displaySettings.display3DSettings.overrideOrientation = true; |
|---|
| 926 | displaySettings.display3DSettings.orientation = opts.common.displayOrientation; |
|---|
| 927 | } |
|---|
| 928 | if (opts.cmp_crc) { |
|---|
| 929 | displaySettings.crcQueueSize = 60; /* This enables the CRC capture */ |
|---|
| 930 | } |
|---|
| 931 | display = NEXUS_Display_Open(0, &displaySettings); |
|---|
| 932 | if (opts.common.useCompositeOutput) { |
|---|
| 933 | rc = NEXUS_Display_AddOutput(display, NEXUS_CompositeOutput_GetConnector(platformConfig.outputs.composite[0])); |
|---|
| 934 | BDBG_ASSERT(!rc); |
|---|
| 935 | } |
|---|
| 936 | #if NEXUS_NUM_COMPONENT_OUTPUTS |
|---|
| 937 | if (opts.common.useComponentOutput) { |
|---|
| 938 | rc = NEXUS_Display_AddOutput(display, NEXUS_ComponentOutput_GetConnector(platformConfig.outputs.component[0])); |
|---|
| 939 | BDBG_ASSERT(!rc); |
|---|
| 940 | } |
|---|
| 941 | #endif |
|---|
| 942 | #if NEXUS_NUM_PANEL_OUTPUTS |
|---|
| 943 | if (opts.common.usePanelOutput) { |
|---|
| 944 | rc = NEXUS_Display_AddOutput(display, NEXUS_PanelOutput_GetConnector(platformConfig.outputs.panel[0])); |
|---|
| 945 | BDBG_ASSERT(!rc); |
|---|
| 946 | NEXUS_BoardCfg_ConfigurePanel(true, true, true); |
|---|
| 947 | } |
|---|
| 948 | #endif |
|---|
| 949 | #if NEXUS_NUM_SCART_INPUTS |
|---|
| 950 | if (opts.common.useScart1CompositeOutput) { |
|---|
| 951 | printf("Turning on: scart 1 composite output\n"); |
|---|
| 952 | rc = NEXUS_Display_AddOutput(display, NEXUS_ScartInput_GetVideoOutputConnector(platformConfig.inputs.scart[1])); |
|---|
| 953 | BDBG_ASSERT(!rc); |
|---|
| 954 | } |
|---|
| 955 | #endif |
|---|
| 956 | #if NEXUS_NUM_HDMI_OUTPUTS |
|---|
| 957 | if (opts.common.useHdmiOutput) { |
|---|
| 958 | NEXUS_HdmiOutputSettings hdmiSettings; |
|---|
| 959 | |
|---|
| 960 | rc = NEXUS_Display_AddOutput(display, NEXUS_HdmiOutput_GetVideoConnector(platformConfig.outputs.hdmi[0])); |
|---|
| 961 | BDBG_ASSERT(!rc); |
|---|
| 962 | |
|---|
| 963 | /* Install hotplug callback -- video only for now */ |
|---|
| 964 | NEXUS_HdmiOutput_GetSettings(platformConfig.outputs.hdmi[0], &hdmiSettings); |
|---|
| 965 | hdmiSettings.hotplugCallback.callback = hotplug_callback; |
|---|
| 966 | hdmiSettings.hotplugCallback.context = platformConfig.outputs.hdmi[0]; |
|---|
| 967 | hdmiSettings.hotplugCallback.param = (int)display; |
|---|
| 968 | NEXUS_HdmiOutput_SetSettings(platformConfig.outputs.hdmi[0], &hdmiSettings); |
|---|
| 969 | |
|---|
| 970 | /* Force a hotplug to switch to preferred format */ |
|---|
| 971 | hotplug_callback(platformConfig.outputs.hdmi[0], (int)display); |
|---|
| 972 | } |
|---|
| 973 | #endif |
|---|
| 974 | |
|---|
| 975 | if (opts.graphics) { |
|---|
| 976 | NEXUS_SurfaceCreateSettings surfaceCreateSettings; |
|---|
| 977 | NEXUS_SurfaceMemory mem; |
|---|
| 978 | NEXUS_GraphicsSettings graphicsSettings; |
|---|
| 979 | NEXUS_VideoFormatInfo videoFormatInfo; |
|---|
| 980 | unsigned i,j; |
|---|
| 981 | |
|---|
| 982 | NEXUS_VideoFormat_GetInfo(displaySettings.format, &videoFormatInfo); |
|---|
| 983 | |
|---|
| 984 | NEXUS_Surface_GetDefaultCreateSettings(&surfaceCreateSettings); |
|---|
| 985 | surfaceCreateSettings.width = 720; |
|---|
| 986 | surfaceCreateSettings.height = videoFormatInfo.height; |
|---|
| 987 | framebuffer = NEXUS_Surface_Create(&surfaceCreateSettings); |
|---|
| 988 | NEXUS_Surface_GetMemory(framebuffer, &mem); |
|---|
| 989 | for (i=0;i<surfaceCreateSettings.height;i++) { |
|---|
| 990 | for (j=0;j<surfaceCreateSettings.width;j++) { |
|---|
| 991 | /* create checker board */ |
|---|
| 992 | ((uint32_t*)((uint8_t*)mem.buffer + i*mem.pitch))[j] = (((i/50)%2) ^ ((j/50)%2)) ? 0x00000000 : 0xFFFFFFFF; |
|---|
| 993 | } |
|---|
| 994 | } |
|---|
| 995 | NEXUS_Surface_Flush(framebuffer); |
|---|
| 996 | |
|---|
| 997 | NEXUS_Display_GetGraphicsSettings(display, &graphicsSettings); |
|---|
| 998 | graphicsSettings.enabled = true; |
|---|
| 999 | graphicsSettings.clip.width = surfaceCreateSettings.width; |
|---|
| 1000 | graphicsSettings.clip.height = surfaceCreateSettings.height; |
|---|
| 1001 | rc = NEXUS_Display_SetGraphicsSettings(display, &graphicsSettings); |
|---|
| 1002 | BDBG_ASSERT(!rc); |
|---|
| 1003 | rc = NEXUS_Display_SetGraphicsFramebuffer(display, framebuffer); |
|---|
| 1004 | BDBG_ASSERT(!rc); |
|---|
| 1005 | } |
|---|
| 1006 | |
|---|
| 1007 | window = NEXUS_VideoWindow_Open(display, 0); |
|---|
| 1008 | |
|---|
| 1009 | NEXUS_VideoWindow_GetSettings(window, &windowSettings); |
|---|
| 1010 | windowSettings.contentMode = opts.common.contentMode; |
|---|
| 1011 | rc = NEXUS_VideoWindow_SetSettings(window, &windowSettings); |
|---|
| 1012 | BDBG_ASSERT(!rc); |
|---|
| 1013 | |
|---|
| 1014 | if (opts.common.mad) { |
|---|
| 1015 | NEXUS_VideoWindowMadSettings madSettings; |
|---|
| 1016 | NEXUS_VideoWindow_GetMadSettings(window, &madSettings); |
|---|
| 1017 | madSettings.deinterlace = true; |
|---|
| 1018 | rc = NEXUS_VideoWindow_SetMadSettings(window, &madSettings); |
|---|
| 1019 | BDBG_ASSERT(!rc); |
|---|
| 1020 | } |
|---|
| 1021 | |
|---|
| 1022 | NEXUS_VideoDecoder_GetDefaultOpenSettings(&openSettings); |
|---|
| 1023 | if(opts.common.videoCdb) { |
|---|
| 1024 | openSettings.fifoSize = opts.common.videoCdb*1024; |
|---|
| 1025 | } |
|---|
| 1026 | if(opts.avc51) { |
|---|
| 1027 | openSettings.avc51Enabled = opts.avc51; |
|---|
| 1028 | } |
|---|
| 1029 | /* bring up decoder and connect to display */ |
|---|
| 1030 | videoDecoder = NEXUS_VideoDecoder_Open(opts.common.videoDecoder, &openSettings); |
|---|
| 1031 | NEXUS_VideoDecoder_GetSettings(videoDecoder, &videoDecoderSettings); |
|---|
| 1032 | if (opts.common.sourceOrientation != NEXUS_VideoDecoderSourceOrientation_e2D) { |
|---|
| 1033 | videoDecoderSettings.customSourceOrientation = true; |
|---|
| 1034 | videoDecoderSettings.sourceOrientation = opts.common.sourceOrientation; |
|---|
| 1035 | } |
|---|
| 1036 | rc = NEXUS_VideoDecoder_SetSettings(videoDecoder, &videoDecoderSettings); |
|---|
| 1037 | BDBG_ASSERT(!rc); |
|---|
| 1038 | if (opts.avd_crc) { |
|---|
| 1039 | NEXUS_VideoDecoderExtendedSettings settings; |
|---|
| 1040 | NEXUS_VideoDecoder_GetExtendedSettings(videoDecoder, &settings); |
|---|
| 1041 | settings.crcFifoSize = 30; |
|---|
| 1042 | rc = NEXUS_VideoDecoder_SetExtendedSettings(videoDecoder, &settings); |
|---|
| 1043 | BDBG_ASSERT(!rc); |
|---|
| 1044 | } |
|---|
| 1045 | rc = NEXUS_VideoWindow_AddInput(window, NEXUS_VideoDecoder_GetConnector(videoDecoder)); |
|---|
| 1046 | BDBG_ASSERT(!rc); |
|---|
| 1047 | |
|---|
| 1048 | NEXUS_Display_GetVbiSettings(display, &displayVbiSettings); |
|---|
| 1049 | displayVbiSettings.vbiSource = NEXUS_VideoDecoder_GetConnector(videoDecoder); |
|---|
| 1050 | displayVbiSettings.closedCaptionEnabled = opts.closedCaptionEnabled; |
|---|
| 1051 | displayVbiSettings.closedCaptionRouting = opts.closedCaptionEnabled; |
|---|
| 1052 | rc = NEXUS_Display_SetVbiSettings(display, &displayVbiSettings); |
|---|
| 1053 | BDBG_ASSERT(!rc); |
|---|
| 1054 | |
|---|
| 1055 | /* Open the audio and video pid channels */ |
|---|
| 1056 | if (opts.common.videoCodec != NEXUS_VideoCodec_eNone && opts.common.videoPid!=0) { |
|---|
| 1057 | NEXUS_Playback_GetDefaultPidChannelSettings(&playbackPidSettings); |
|---|
| 1058 | playbackPidSettings.pidSettings.pidType = NEXUS_PidType_eVideo; |
|---|
| 1059 | playbackPidSettings.pidSettings.allowTimestampReordering = opts.common.playpumpTimestampReordering; |
|---|
| 1060 | playbackPidSettings.pidTypeSettings.video.decoder = videoDecoder; |
|---|
| 1061 | playbackPidSettings.pidTypeSettings.video.index = true; |
|---|
| 1062 | playbackPidSettings.pidTypeSettings.video.codec = opts.common.videoCodec; |
|---|
| 1063 | videoPidChannel = NEXUS_Playback_OpenPidChannel(playback, opts.common.videoPid, &playbackPidSettings); |
|---|
| 1064 | } |
|---|
| 1065 | |
|---|
| 1066 | if (opts.common.extVideoCodec != NEXUS_VideoCodec_eNone && opts.common.extVideoPid!=0) { |
|---|
| 1067 | NEXUS_Playback_GetDefaultPidChannelSettings(&playbackPidSettings); |
|---|
| 1068 | playbackPidSettings.pidSettings.pidType = NEXUS_PidType_eVideo; |
|---|
| 1069 | playbackPidSettings.pidTypeSettings.video.index = true; |
|---|
| 1070 | playbackPidSettings.pidSettings.allowTimestampReordering = opts.common.playpumpTimestampReordering; |
|---|
| 1071 | playbackPidSettings.pidTypeSettings.video.decoder = videoDecoder; |
|---|
| 1072 | playbackPidSettings.pidTypeSettings.video.codec = opts.common.extVideoCodec; |
|---|
| 1073 | videoExtPidChannel = NEXUS_Playback_OpenPidChannel(playback, opts.common.extVideoPid, &playbackPidSettings); |
|---|
| 1074 | } |
|---|
| 1075 | |
|---|
| 1076 | if (opts.common.audioCodec != NEXUS_AudioCodec_eUnknown && opts.common.audioPid!=0) { |
|---|
| 1077 | NEXUS_Playback_GetDefaultPidChannelSettings(&playbackPidSettings); |
|---|
| 1078 | playbackPidSettings.pidSettings.pidType = NEXUS_PidType_eAudio; |
|---|
| 1079 | playbackPidSettings.pidTypeSettings.audio.primary = audioDecoder; |
|---|
| 1080 | playbackPidSettings.pidSettings.pidTypeSettings.audio.codec = opts.common.audioCodec; |
|---|
| 1081 | audioPidChannel = NEXUS_Playback_OpenPidChannel(playback, opts.common.audioPid, &playbackPidSettings); |
|---|
| 1082 | } |
|---|
| 1083 | |
|---|
| 1084 | if (opts.common.pcrPid && opts.common.pcrPid!=opts.common.videoPid && opts.common.pcrPid!=opts.common.audioPid) { |
|---|
| 1085 | NEXUS_Playback_GetDefaultPidChannelSettings(&playbackPidSettings); |
|---|
| 1086 | playbackPidSettings.pidSettings.pidType = NEXUS_PidType_eOther; |
|---|
| 1087 | pcrPidChannel = NEXUS_Playback_OpenPidChannel(playback, opts.common.pcrPid, &playbackPidSettings); |
|---|
| 1088 | } |
|---|
| 1089 | |
|---|
| 1090 | /* Set up decoder Start structures now. We need to know the audio codec to properly set up the audio outputs. */ |
|---|
| 1091 | NEXUS_VideoDecoder_GetDefaultStartSettings(&videoProgram); |
|---|
| 1092 | videoProgram.codec = opts.common.videoCodec; |
|---|
| 1093 | videoProgram.pidChannel = videoPidChannel; |
|---|
| 1094 | videoProgram.stcChannel = stcChannel; |
|---|
| 1095 | videoProgram.frameRate = opts.common.videoFrameRate; |
|---|
| 1096 | videoProgram.aspectRatio = opts.common.aspectRatio; |
|---|
| 1097 | videoProgram.sampleAspectRatio.x = opts.common.sampleAspectRatio.x; |
|---|
| 1098 | videoProgram.sampleAspectRatio.y = opts.common.sampleAspectRatio.y; |
|---|
| 1099 | videoProgram.errorHandling = opts.videoErrorHandling; |
|---|
| 1100 | videoProgram.timestampMode = opts.common.decoderTimestampMode; |
|---|
| 1101 | if(videoExtPidChannel) { |
|---|
| 1102 | videoProgram.enhancementPidChannel = videoExtPidChannel; |
|---|
| 1103 | videoProgram.codec = opts.common.extVideoCodec; |
|---|
| 1104 | } |
|---|
| 1105 | NEXUS_AudioDecoder_GetDefaultStartSettings(&audioProgram); |
|---|
| 1106 | audioProgram.codec = opts.common.audioCodec; |
|---|
| 1107 | audioProgram.pidChannel = audioPidChannel; |
|---|
| 1108 | audioProgram.stcChannel = stcChannel; |
|---|
| 1109 | |
|---|
| 1110 | /* Start decoders */ |
|---|
| 1111 | start_video(&opts, videoDecoder, &videoProgram); |
|---|
| 1112 | start_audio(&opts, audioDecoder, compressedDecoder, &audioProgram); |
|---|
| 1113 | |
|---|
| 1114 | /* Start playback */ |
|---|
| 1115 | NEXUS_Playback_GetDefaultStartSettings(&playbackStartSettings); |
|---|
| 1116 | if (opts.fixedBitrate) { |
|---|
| 1117 | playbackStartSettings.mode = NEXUS_PlaybackMode_eFixedBitrate; |
|---|
| 1118 | playbackStartSettings.bitrate = opts.fixedBitrate; |
|---|
| 1119 | } |
|---|
| 1120 | else if (opts.autoBitrate) { |
|---|
| 1121 | playbackStartSettings.mode = NEXUS_PlaybackMode_eAutoBitrate; |
|---|
| 1122 | } |
|---|
| 1123 | #if READ_TIMED_DATA |
|---|
| 1124 | { |
|---|
| 1125 | barena_t arena; |
|---|
| 1126 | |
|---|
| 1127 | arena = barena_create(&b_nexus_alloc_iface, 2*1024*1024); |
|---|
| 1128 | BDBG_ASSERT(arena); |
|---|
| 1129 | bsink_dump_reader_allocator = barena_alloc_iface(arena); |
|---|
| 1130 | } |
|---|
| 1131 | #endif |
|---|
| 1132 | rc = NEXUS_Playback_Start(playback, file, &playbackStartSettings); |
|---|
| 1133 | BDBG_ASSERT(!rc); |
|---|
| 1134 | |
|---|
| 1135 | #if B_HAS_PLAYBACK_MONITOR |
|---|
| 1136 | { |
|---|
| 1137 | PlaybackMonitorState monitorState; |
|---|
| 1138 | BKNI_Memset(&monitorState, 0, sizeof(monitorState)); |
|---|
| 1139 | monitorState.opts = &opts; |
|---|
| 1140 | monitorState.playback = playback; |
|---|
| 1141 | monitorState.videoDecoder = videoDecoder; |
|---|
| 1142 | monitorState.videoProgram = &videoProgram; |
|---|
| 1143 | monitorState.audioDecoder = audioDecoder; |
|---|
| 1144 | monitorState.compressedDecoder = compressedDecoder; |
|---|
| 1145 | monitorState.audioProgram = &audioProgram; |
|---|
| 1146 | monitorState.file = file; |
|---|
| 1147 | monitorState.stickyFile = stickyFile; |
|---|
| 1148 | monitorState.customFile = customFile; |
|---|
| 1149 | monitorState.playbackStartSettings = &playbackStartSettings; |
|---|
| 1150 | if(stickyFile) { |
|---|
| 1151 | monitor_thread_start(&monitorState); |
|---|
| 1152 | } |
|---|
| 1153 | #endif |
|---|
| 1154 | |
|---|
| 1155 | if (opts.avd_crc) { |
|---|
| 1156 | print_avd_crc(videoDecoder); |
|---|
| 1157 | } |
|---|
| 1158 | if (opts.cmp_crc) { |
|---|
| 1159 | print_cmp_crc(display); |
|---|
| 1160 | } |
|---|
| 1161 | |
|---|
| 1162 | for (exit=false;!exit;) |
|---|
| 1163 | { |
|---|
| 1164 | char buffer[256]; |
|---|
| 1165 | char *buf; |
|---|
| 1166 | |
|---|
| 1167 | printf("playback>"); fflush(stdout); |
|---|
| 1168 | fgets(buffer, 256, stdin); |
|---|
| 1169 | if (feof(stdin)) break; |
|---|
| 1170 | buffer[strlen(buffer)-1] = 0; /* chop off \n */ |
|---|
| 1171 | |
|---|
| 1172 | buf = strtok(buffer, ";"); |
|---|
| 1173 | if (!buf) continue; |
|---|
| 1174 | |
|---|
| 1175 | #if B_HAS_PLAYBACK_MONITOR |
|---|
| 1176 | if(stickyFile) { |
|---|
| 1177 | BKNI_AcquireMutex(monitorState.lock); |
|---|
| 1178 | } |
|---|
| 1179 | #endif |
|---|
| 1180 | do { |
|---|
| 1181 | if (!strcmp(buf, "?") || !strcmp(buf, "help")) { |
|---|
| 1182 | printf( |
|---|
| 1183 | "Commands:\n" |
|---|
| 1184 | " play - resume normal playback\n" |
|---|
| 1185 | " pause - pause playback\n" |
|---|
| 1186 | " i - decode only I frames\n" |
|---|
| 1187 | " ip - decode only I & P frames\n" |
|---|
| 1188 | " all - decode all frames\n" |
|---|
| 1189 | ); |
|---|
| 1190 | printf( |
|---|
| 1191 | " fa - frame advance\n" |
|---|
| 1192 | " fr - frame reverse\n" |
|---|
| 1193 | " rate(rate) - set trick rate (floating point number, 1.0 is normal play)\n" |
|---|
| 1194 | " host(type[,modifier,slowrate]) - set host trick mode\n" |
|---|
| 1195 | " type=i,ip,all; modifier=1,-1 for forward,reverse(i only); slowrate=decoder repeat rate (1=1x,2=2x)\n" |
|---|
| 1196 | ); |
|---|
| 1197 | printf( |
|---|
| 1198 | " seek(pos) - jump to position (in milliseconds)\n" |
|---|
| 1199 | " sleep(msec) - sleep for given number of milli-seconds\n" |
|---|
| 1200 | " st - print status\n" |
|---|
| 1201 | " af - audio flush\n" |
|---|
| 1202 | " restart - stop playback and restart play from the current position\n" |
|---|
| 1203 | ); |
|---|
| 1204 | /*TODO* figure out what these do and add appropriate explanation*/ |
|---|
| 1205 | #if 0 |
|---|
| 1206 | if (customFile) printf( |
|---|
| 1207 | " error_index(error,nodata,partial_read) - get \n" |
|---|
| 1208 | " error_data(error,nodata,partial_read) - set \n" |
|---|
| 1209 | ); |
|---|
| 1210 | #endif |
|---|
| 1211 | printf( |
|---|
| 1212 | /*TODO* figure out what this does and add appropriate explanation*/ |
|---|
| 1213 | /*" bvn_usage(id) - \n"*/ |
|---|
| 1214 | " q - quit\n" |
|---|
| 1215 | ); |
|---|
| 1216 | } |
|---|
| 1217 | else if (!strcmp(buf, "q") || !strcmp(buf, "quit")) { |
|---|
| 1218 | exit = true; |
|---|
| 1219 | break; |
|---|
| 1220 | } |
|---|
| 1221 | else if (!strcmp(buf, "play")) { |
|---|
| 1222 | rc = NEXUS_Playback_Play(playback); |
|---|
| 1223 | BDBG_ASSERT(!rc); |
|---|
| 1224 | } |
|---|
| 1225 | else if (!strcmp(buf, "fa")) { |
|---|
| 1226 | rc = NEXUS_Playback_FrameAdvance(playback, true); |
|---|
| 1227 | BDBG_ASSERT(!rc); |
|---|
| 1228 | } |
|---|
| 1229 | else if (!strcmp(buf, "fr")) { |
|---|
| 1230 | rc = NEXUS_Playback_FrameAdvance(playback, false); |
|---|
| 1231 | BDBG_ASSERT(!rc); |
|---|
| 1232 | } |
|---|
| 1233 | else if (!strcmp(buf, "pause")) { |
|---|
| 1234 | rc = NEXUS_Playback_Pause(playback); |
|---|
| 1235 | BDBG_ASSERT(!rc); |
|---|
| 1236 | } |
|---|
| 1237 | else if (!strcmp(buf, "i")) { |
|---|
| 1238 | NEXUS_PlaybackTrickModeSettings trickSettings; |
|---|
| 1239 | NEXUS_Playback_GetDefaultTrickModeSettings(&trickSettings); |
|---|
| 1240 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_ePlayI; |
|---|
| 1241 | trickSettings.skipControl = NEXUS_PlaybackSkipControl_eDecoder; |
|---|
| 1242 | trickSettings.rateControl = NEXUS_PlaybackRateControl_eDecoder; |
|---|
| 1243 | rc = NEXUS_Playback_TrickMode(playback, &trickSettings); |
|---|
| 1244 | BDBG_ASSERT(!rc); |
|---|
| 1245 | } |
|---|
| 1246 | else if (!strcmp(buf, "ip")) { |
|---|
| 1247 | NEXUS_PlaybackTrickModeSettings trickSettings; |
|---|
| 1248 | NEXUS_Playback_GetDefaultTrickModeSettings(&trickSettings); |
|---|
| 1249 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_ePlayIP; |
|---|
| 1250 | trickSettings.skipControl = NEXUS_PlaybackSkipControl_eDecoder; |
|---|
| 1251 | trickSettings.rateControl = NEXUS_PlaybackRateControl_eDecoder; |
|---|
| 1252 | rc = NEXUS_Playback_TrickMode(playback, &trickSettings); |
|---|
| 1253 | BDBG_ASSERT(!rc); |
|---|
| 1254 | } |
|---|
| 1255 | else if (!strcmp(buf, "all")) { |
|---|
| 1256 | NEXUS_PlaybackTrickModeSettings trickSettings; |
|---|
| 1257 | NEXUS_Playback_GetDefaultTrickModeSettings(&trickSettings); |
|---|
| 1258 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_eNormal; |
|---|
| 1259 | trickSettings.skipControl = NEXUS_PlaybackSkipControl_eDecoder; |
|---|
| 1260 | trickSettings.rateControl = NEXUS_PlaybackRateControl_eDecoder; |
|---|
| 1261 | rc = NEXUS_Playback_TrickMode(playback, &trickSettings); |
|---|
| 1262 | BDBG_ASSERT(!rc); |
|---|
| 1263 | } |
|---|
| 1264 | else if (strstr(buf, "sleep(") == buf) { |
|---|
| 1265 | unsigned msec; |
|---|
| 1266 | sscanf(buf+6, "%u", &msec); |
|---|
| 1267 | BKNI_Sleep(msec); |
|---|
| 1268 | } |
|---|
| 1269 | else if (strstr(buf, "rate(") == buf) { |
|---|
| 1270 | NEXUS_PlaybackTrickModeSettings trickSettings; |
|---|
| 1271 | float rate; |
|---|
| 1272 | |
|---|
| 1273 | sscanf(buf+5, "%f", &rate); |
|---|
| 1274 | NEXUS_Playback_GetDefaultTrickModeSettings(&trickSettings); |
|---|
| 1275 | trickSettings.rate = NEXUS_NORMAL_DECODE_RATE * rate; |
|---|
| 1276 | if (!trickSettings.rate && rate) { |
|---|
| 1277 | trickSettings.rate = rate>0?1:-1; |
|---|
| 1278 | } |
|---|
| 1279 | if(opts.maxDecoderRate) { |
|---|
| 1280 | trickSettings.maxDecoderRate = opts.maxDecoderRate; |
|---|
| 1281 | } |
|---|
| 1282 | rc = NEXUS_Playback_TrickMode(playback, &trickSettings); |
|---|
| 1283 | /* don't assert for fast or reverse trick modes */ |
|---|
| 1284 | if (trickSettings.rate >=0 && trickSettings.rate <= NEXUS_NORMAL_DECODE_RATE) { |
|---|
| 1285 | BDBG_ASSERT(!rc); |
|---|
| 1286 | } |
|---|
| 1287 | } |
|---|
| 1288 | else if (strstr(buf, "host(") == buf) { |
|---|
| 1289 | char *s; |
|---|
| 1290 | char trick[64]; |
|---|
| 1291 | int n, modifier, decoder_slowrate; |
|---|
| 1292 | NEXUS_PlaybackTrickModeSettings trickSettings; |
|---|
| 1293 | |
|---|
| 1294 | /* convert , and ) into spaces for sscanf */ |
|---|
| 1295 | while ((s = strpbrk(buf, ",)"))) { |
|---|
| 1296 | *s = ' '; |
|---|
| 1297 | } |
|---|
| 1298 | |
|---|
| 1299 | n = sscanf(buf+5, "%s %d %d", trick, &modifier, &decoder_slowrate); |
|---|
| 1300 | if (n < 2 || modifier == 0) modifier = 1; |
|---|
| 1301 | if (n < 3 || decoder_slowrate == 0) decoder_slowrate = 1; |
|---|
| 1302 | |
|---|
| 1303 | BDBG_MSG(("host(%s,%d,%d)", trick, modifier, decoder_slowrate)); |
|---|
| 1304 | |
|---|
| 1305 | NEXUS_Playback_GetDefaultTrickModeSettings(&trickSettings); |
|---|
| 1306 | trickSettings.skipControl = NEXUS_PlaybackSkipControl_eHost; |
|---|
| 1307 | trickSettings.rateControl = NEXUS_PlaybackRateControl_eDecoder; |
|---|
| 1308 | trickSettings.mode_modifier = modifier; |
|---|
| 1309 | if (!strcasecmp(trick, "ip")) { |
|---|
| 1310 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_ePlayIP; |
|---|
| 1311 | } |
|---|
| 1312 | else if (!strcasecmp(trick, "i")) { |
|---|
| 1313 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_ePlayI; |
|---|
| 1314 | } |
|---|
| 1315 | else if (!strcasecmp(trick, "all")) { |
|---|
| 1316 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_eNormal; |
|---|
| 1317 | } |
|---|
| 1318 | else if (!strcasecmp(trick, "gop")) { |
|---|
| 1319 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_ePlayGop; |
|---|
| 1320 | } |
|---|
| 1321 | else if (!strcasecmp(trick, "bcm")) { |
|---|
| 1322 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_ePlayBrcm; |
|---|
| 1323 | } |
|---|
| 1324 | else { |
|---|
| 1325 | BDBG_WRN(("unknown trick mode: %s", trick)); |
|---|
| 1326 | trickSettings.mode = NEXUS_PlaybackHostTrickMode_eNone; |
|---|
| 1327 | } |
|---|
| 1328 | trickSettings.rate = NEXUS_NORMAL_DECODE_RATE / decoder_slowrate; |
|---|
| 1329 | if (decoder_slowrate && !trickSettings.rate) { |
|---|
| 1330 | trickSettings.rate = 1; |
|---|
| 1331 | } |
|---|
| 1332 | NEXUS_Playback_TrickMode(playback, &trickSettings); |
|---|
| 1333 | } |
|---|
| 1334 | else if (strstr(buf, "seek(") == buf) { |
|---|
| 1335 | unsigned pos; |
|---|
| 1336 | unsigned min,sec,msec; |
|---|
| 1337 | |
|---|
| 1338 | if(sscanf(buf+5,"%u:%u.%u", &min, &sec, &msec)==3) { |
|---|
| 1339 | pos = (min*60+sec)*1000+msec; |
|---|
| 1340 | } if(sscanf(buf+5,"%u:%u", &min, &sec)==2) { |
|---|
| 1341 | pos = (min*60+sec)*1000; |
|---|
| 1342 | } else { |
|---|
| 1343 | sscanf(buf+5, "%u", &pos); |
|---|
| 1344 | } |
|---|
| 1345 | NEXUS_Playback_Seek(playback, pos); |
|---|
| 1346 | /* failure is normal if location doesn't exist */ |
|---|
| 1347 | } |
|---|
| 1348 | else if (!strcmp(buf, "st")) { |
|---|
| 1349 | NEXUS_VideoDecoderStatus vstatus; |
|---|
| 1350 | NEXUS_AudioDecoderStatus astatus; |
|---|
| 1351 | NEXUS_AudioDecoderStatus acstatus; |
|---|
| 1352 | NEXUS_PlaybackStatus pstatus; |
|---|
| 1353 | NEXUS_PlaypumpStatus pumpstatus; |
|---|
| 1354 | uint32_t stc; |
|---|
| 1355 | |
|---|
| 1356 | rc = NEXUS_VideoDecoder_GetStatus(videoDecoder, &vstatus); |
|---|
| 1357 | BDBG_ASSERT(!rc); |
|---|
| 1358 | if(opts.common.decodedAudio) { |
|---|
| 1359 | rc = NEXUS_AudioDecoder_GetStatus(audioDecoder, &astatus); |
|---|
| 1360 | BDBG_ASSERT(!rc); |
|---|
| 1361 | } |
|---|
| 1362 | if(compressedDecoder) { |
|---|
| 1363 | rc = NEXUS_AudioDecoder_GetStatus(compressedDecoder, &acstatus); |
|---|
| 1364 | BDBG_ASSERT(!rc); |
|---|
| 1365 | } |
|---|
| 1366 | |
|---|
| 1367 | rc = NEXUS_Playback_GetStatus(playback, &pstatus); |
|---|
| 1368 | BDBG_ASSERT(!rc); |
|---|
| 1369 | rc = NEXUS_Playpump_GetStatus(playpump, &pumpstatus); |
|---|
| 1370 | NEXUS_StcChannel_GetStc(stcChannel, &stc); |
|---|
| 1371 | |
|---|
| 1372 | if (opts.common.videoPid) { |
|---|
| 1373 | char enhancementInfo[64]; |
|---|
| 1374 | *enhancementInfo='\0'; |
|---|
| 1375 | if(vstatus.enhancementFifoSize) { |
|---|
| 1376 | snprintf(enhancementInfo, sizeof(enhancementInfo), " [%u/%u (%u%%)]", |
|---|
| 1377 | vstatus.enhancementFifoDepth, vstatus.enhancementFifoSize, |
|---|
| 1378 | vstatus.enhancementFifoDepth * 100 / vstatus.enhancementFifoSize); |
|---|
| 1379 | } |
|---|
| 1380 | |
|---|
| 1381 | printf("video %u/%u (%u%%)%s pts=%#x, stc=%#x (diff %d) fps=%sHz, queueDepth=%d\n", vstatus.fifoDepth, vstatus.fifoSize, |
|---|
| 1382 | vstatus.fifoSize ? vstatus.fifoDepth * 100 / vstatus.fifoSize : 0, |
|---|
| 1383 | enhancementInfo, |
|---|
| 1384 | vstatus.pts, stc, vstatus.ptsStcDifference, |
|---|
| 1385 | g_videoFrameRateStrs[vstatus.frameRate].name, |
|---|
| 1386 | vstatus.queueDepth); |
|---|
| 1387 | if (vstatus.avdStatusBlock) { |
|---|
| 1388 | printf(" avdStatusBlock=%#x\n", vstatus.avdStatusBlock); |
|---|
| 1389 | } |
|---|
| 1390 | } |
|---|
| 1391 | if (opts.common.audioPid) { |
|---|
| 1392 | if(opts.common.decodedAudio) { |
|---|
| 1393 | printf("audio %u/%u (%u%%) pts=%#x, stc=%#x (diff %d), queuedFrames=%d\n", astatus.fifoDepth, astatus.fifoSize, |
|---|
| 1394 | astatus.fifoSize ? astatus.fifoDepth * 100 / astatus.fifoSize : 0, |
|---|
| 1395 | astatus.pts, stc, astatus.ptsStcDifference, |
|---|
| 1396 | astatus.queuedFrames); |
|---|
| 1397 | } |
|---|
| 1398 | if(compressedDecoder) { |
|---|
| 1399 | printf("compressed %u/%u (%u%%) pts=%#x, stc=%#x (diff %d), queuedFrames=%d\n", acstatus.fifoDepth, acstatus.fifoSize, |
|---|
| 1400 | acstatus.fifoSize ? acstatus.fifoDepth * 100 / acstatus.fifoSize : 0, |
|---|
| 1401 | acstatus.pts, stc, acstatus.ptsStcDifference, |
|---|
| 1402 | astatus.queuedFrames); |
|---|
| 1403 | } |
|---|
| 1404 | } |
|---|
| 1405 | printf("playback %u/%u (%u%%) pos=%u:%02u.%03u(%d:%d) last=%u:%02u.%03u\n", pstatus.fifoDepth, pstatus.fifoSize, |
|---|
| 1406 | pstatus.fifoSize ? pstatus.fifoDepth * 100 / pstatus.fifoSize : 0, |
|---|
| 1407 | (unsigned)pstatus.position/60000, |
|---|
| 1408 | (unsigned)(pstatus.position%60000)/1000, |
|---|
| 1409 | (unsigned)pstatus.position%1000, |
|---|
| 1410 | (int)(pstatus.readPosition - pstatus.position), |
|---|
| 1411 | (int)(pumpstatus.mediaPts - (opts.common.videoPid?vstatus.pts:astatus.pts))/45, |
|---|
| 1412 | (unsigned)pstatus.last/60000, |
|---|
| 1413 | (unsigned)(pstatus.last%60000)/1000, |
|---|
| 1414 | (unsigned)pstatus.last%1000 |
|---|
| 1415 | ); |
|---|
| 1416 | } |
|---|
| 1417 | else if (!strcmp(buf, "af")) { |
|---|
| 1418 | NEXUS_AudioDecoder_Flush(audioDecoder); |
|---|
| 1419 | if(compressedDecoder) { |
|---|
| 1420 | NEXUS_AudioDecoder_Flush(compressedDecoder); |
|---|
| 1421 | } |
|---|
| 1422 | } |
|---|
| 1423 | else if (!strcmp(buf, "restart")) { |
|---|
| 1424 | NEXUS_PlaybackStatus status; |
|---|
| 1425 | NEXUS_VideoDecoderSettings videoDecoderSettings; |
|---|
| 1426 | |
|---|
| 1427 | /* get current playback position */ |
|---|
| 1428 | rc = NEXUS_Playback_GetStatus(playback, &status); |
|---|
| 1429 | BDBG_ASSERT(!rc); |
|---|
| 1430 | NEXUS_Playback_Stop(playback); |
|---|
| 1431 | |
|---|
| 1432 | if (opts.common.videoPid) { |
|---|
| 1433 | /* don't show black frame */ |
|---|
| 1434 | NEXUS_VideoDecoder_GetSettings(videoDecoder, &videoDecoderSettings); |
|---|
| 1435 | videoDecoderSettings.channelChangeMode = NEXUS_VideoDecoder_ChannelChangeMode_eHoldUntilTsmLock; |
|---|
| 1436 | rc=NEXUS_VideoDecoder_SetSettings(videoDecoder, &videoDecoderSettings); |
|---|
| 1437 | BDBG_ASSERT(!rc); |
|---|
| 1438 | } |
|---|
| 1439 | /* stop decoder */ |
|---|
| 1440 | stop_video(&opts, videoDecoder); |
|---|
| 1441 | stop_audio(&opts, audioDecoder, compressedDecoder); |
|---|
| 1442 | |
|---|
| 1443 | NEXUS_Playback_GetSettings(playback, &playbackSettings); |
|---|
| 1444 | playbackSettings.startPaused = true; |
|---|
| 1445 | rc = NEXUS_Playback_SetSettings(playback, &playbackSettings); |
|---|
| 1446 | BDBG_ASSERT(!rc); |
|---|
| 1447 | |
|---|
| 1448 | /* Start decoders */ |
|---|
| 1449 | start_video(&opts, videoDecoder, &videoProgram); |
|---|
| 1450 | start_audio(&opts, audioDecoder, compressedDecoder, &audioProgram); |
|---|
| 1451 | |
|---|
| 1452 | |
|---|
| 1453 | /* start playback */ |
|---|
| 1454 | rc = NEXUS_Playback_Start(playback, file, &playbackStartSettings); |
|---|
| 1455 | BDBG_ASSERT(!rc); |
|---|
| 1456 | |
|---|
| 1457 | /* seek into desired location */ |
|---|
| 1458 | rc = NEXUS_Playback_Seek(playback, status.position); |
|---|
| 1459 | BDBG_ASSERT(!rc); |
|---|
| 1460 | |
|---|
| 1461 | /* start playing */ |
|---|
| 1462 | rc = NEXUS_Playback_Play(playback); |
|---|
| 1463 | BDBG_ASSERT(!rc); |
|---|
| 1464 | } |
|---|
| 1465 | else if (customFile && strstr(buf, "error_index(")==buf) { |
|---|
| 1466 | FileIoCustomProbabilities probabilities; |
|---|
| 1467 | FileIoCustom_GetProbabilities(customFile, NULL, &probabilities); |
|---|
| 1468 | sscanf(buf+strlen("error_index("),"%u,%u,%u", &probabilities.error, &probabilities.nodata, &probabilities.partial_read); |
|---|
| 1469 | FileIoCustom_SetProbabilities(customFile, NULL, &probabilities); |
|---|
| 1470 | } |
|---|
| 1471 | else if (customFile && strstr(buf, "error_data(")==buf) { |
|---|
| 1472 | FileIoCustomProbabilities probabilities; |
|---|
| 1473 | FileIoCustom_GetProbabilities(customFile , &probabilities, NULL); |
|---|
| 1474 | sscanf(buf+strlen("error_data("),"%u,%u,%u", &probabilities.error, &probabilities.nodata, &probabilities.partial_read); |
|---|
| 1475 | FileIoCustom_SetProbabilities(customFile, &probabilities, NULL); |
|---|
| 1476 | } |
|---|
| 1477 | else if (strstr(buf, "bvn_usage(") == buf) { |
|---|
| 1478 | unsigned id; |
|---|
| 1479 | |
|---|
| 1480 | if (sscanf(buf+10,"%u", &id)==1) { |
|---|
| 1481 | NEXUS_DisplayModule_SetConfigurationId(id); |
|---|
| 1482 | /* allow failure */ |
|---|
| 1483 | } |
|---|
| 1484 | } |
|---|
| 1485 | else if (!*buf) { |
|---|
| 1486 | /* allow blank line */ |
|---|
| 1487 | } |
|---|
| 1488 | else { |
|---|
| 1489 | printf("unknown command: '%s' (use '?' for list)\n", buf); |
|---|
| 1490 | } |
|---|
| 1491 | } |
|---|
| 1492 | while ((buf = strtok(NULL, ";"))); |
|---|
| 1493 | |
|---|
| 1494 | #if B_HAS_PLAYBACK_MONITOR |
|---|
| 1495 | if(stickyFile) { |
|---|
| 1496 | BKNI_ReleaseMutex(monitorState.lock); |
|---|
| 1497 | } |
|---|
| 1498 | #endif |
|---|
| 1499 | } |
|---|
| 1500 | |
|---|
| 1501 | #if B_HAS_PLAYBACK_MONITOR |
|---|
| 1502 | if(stickyFile) { |
|---|
| 1503 | monitor_thread_stop(&monitorState); |
|---|
| 1504 | } |
|---|
| 1505 | } |
|---|
| 1506 | #endif |
|---|
| 1507 | NEXUS_Playback_Stop(playback); |
|---|
| 1508 | stop_video(&opts, videoDecoder); |
|---|
| 1509 | stop_audio(&opts, audioDecoder, compressedDecoder); |
|---|
| 1510 | |
|---|
| 1511 | NEXUS_Playback_CloseAllPidChannels(playback); |
|---|
| 1512 | NEXUS_FilePlay_Close(file); |
|---|
| 1513 | NEXUS_Playback_Destroy(playback); |
|---|
| 1514 | NEXUS_Playpump_Close(playpump); |
|---|
| 1515 | |
|---|
| 1516 | NEXUS_VideoWindow_Close(window); |
|---|
| 1517 | NEXUS_Display_Close(display); /* must precede NEXUS_VideoDecoder_Close to auto-shutdown of inputs */ |
|---|
| 1518 | NEXUS_VideoDecoder_Close(videoDecoder); |
|---|
| 1519 | if (framebuffer) { |
|---|
| 1520 | NEXUS_Surface_Destroy(framebuffer); |
|---|
| 1521 | } |
|---|
| 1522 | NEXUS_AudioDecoder_Close(audioDecoder); |
|---|
| 1523 | if(compressedDecoder) { |
|---|
| 1524 | NEXUS_AudioDecoder_Close(compressedDecoder); |
|---|
| 1525 | } |
|---|
| 1526 | NEXUS_Platform_Uninit(); |
|---|
| 1527 | |
|---|
| 1528 | return 0; |
|---|
| 1529 | } |
|---|
| 1530 | |
|---|
| 1531 | static void print_cmp_crc(NEXUS_DisplayHandle display) |
|---|
| 1532 | { |
|---|
| 1533 | /* loop forever printing CMP CRC's */ |
|---|
| 1534 | for (;;) { |
|---|
| 1535 | NEXUS_DisplayCrcData data[16]; |
|---|
| 1536 | unsigned num, i; |
|---|
| 1537 | int rc; |
|---|
| 1538 | |
|---|
| 1539 | rc = NEXUS_Display_GetCrcData(display, data, 16, &num); |
|---|
| 1540 | BDBG_ASSERT(!rc); |
|---|
| 1541 | if (!num) { |
|---|
| 1542 | BKNI_Sleep(10); |
|---|
| 1543 | continue; |
|---|
| 1544 | } |
|---|
| 1545 | |
|---|
| 1546 | for (i=0;i<num;i++) { |
|---|
| 1547 | printf("CMP CRC %x %x %x\n", data[i].cmp.luma, data[i].cmp.cb, data[i].cmp.cr); |
|---|
| 1548 | } |
|---|
| 1549 | } |
|---|
| 1550 | } |
|---|
| 1551 | |
|---|
| 1552 | static void print_avd_crc(NEXUS_VideoDecoderHandle videoDecoder) |
|---|
| 1553 | { |
|---|
| 1554 | /* loop forever printing AVD CRC's */ |
|---|
| 1555 | for (;;) { |
|---|
| 1556 | NEXUS_VideoDecoderCrc data[16]; |
|---|
| 1557 | unsigned num, i; |
|---|
| 1558 | int rc; |
|---|
| 1559 | |
|---|
| 1560 | rc = NEXUS_VideoDecoder_GetCrcData(videoDecoder, data, 16, &num); |
|---|
| 1561 | BDBG_ASSERT(!rc); |
|---|
| 1562 | if (!num) { |
|---|
| 1563 | BKNI_Sleep(10); |
|---|
| 1564 | continue; |
|---|
| 1565 | } |
|---|
| 1566 | |
|---|
| 1567 | for (i=0;i<num;i++) { |
|---|
| 1568 | printf("AVD CRC %x %x %x; %x %x %x\n", data[i].top.luma, data[i].top.cr, data[i].top.cb, data[i].bottom.luma, data[i].bottom.cr, data[i].bottom.cb); |
|---|
| 1569 | } |
|---|
| 1570 | } |
|---|
| 1571 | } |
|---|
| 1572 | |
|---|
| 1573 | #endif /*!NEXUS_HAS_PLAYBACK*/ |
|---|
| 1574 | |
|---|
| 1575 | /* |
|---|
| 1576 | ************************************************ |
|---|
| 1577 | |
|---|
| 1578 | examples / test cases |
|---|
| 1579 | |
|---|
| 1580 | # basic decode of streamer input |
|---|
| 1581 | nexus playback -video 0x31 -audio 0x34 -video_type mpeg -audio_type ac3 /mnt/hd/italyriviera_spiderman2_cc_q64.mpg |
|---|
| 1582 | |
|---|
| 1583 | ************************************************ |
|---|
| 1584 | */ |
|---|
| 1585 | |
|---|