Unexported vlc_thread_set_priority().
[vlc/vlc-skelet.git] / modules / codec / crystalhd.c
blobff60509d521041485685d71742e014cc7e390414
1 /*****************************************************************************
2 * Copyright © 2010-2011 VideoLAN
4 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
5 * Narendra Sankar <nsankar@broadcom.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20 *****************************************************************************/
22 /*****************************************************************************
23 * Preamble
24 *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 /* TODO
31 * - pts = 0?
32 * - mpeg4-asp
33 * - win32 testing
36 /* VLC includes */
37 #include <vlc_common.h>
38 #include <vlc_plugin.h>
39 #include <vlc_codec.h>
41 /* Workaround for some versions of libcrystalHD */
42 #if !defined(_WIN32) && !defined(__APPLE__)
43 # define __LINUX_USER__
44 #endif
46 /* CrystalHD */
47 #include <libcrystalhd/bc_dts_defs.h>
48 #include <libcrystalhd/bc_dts_types.h>
50 #if defined(HAVE_LIBCRYSTALHD_BC_DRV_IF_H) /* Win32 */
51 # include <libcrystalhd/bc_drv_if.h>
52 #elif defined(_WIN32)
53 # define USE_DL_OPENING 1
54 #else
55 # include <libcrystalhd/libcrystalhd_if.h>
56 #endif
58 /* On a normal Win32 build, well aren't going to ship the BCM dll
59 And forcing users to install the right dll at the right place will not work
60 Therefore, we need to dl_open and resolve the symbols */
61 #ifdef USE_DL_OPENING
62 # warning DLL opening mode
63 # define BC_FUNC( a ) Our ## a
64 # define BC_FUNC_PSYS( a ) p_sys->Our ## a
65 #else
66 # define BC_FUNC( a ) a
67 # define BC_FUNC_PSYS( a ) a
68 #endif
70 #include <assert.h>
72 /* BC pts are multiple of 100ns */
73 #define TO_BC_PTS( a ) ( a * 10 + 1 )
74 #define FROM_BC_PTS( a ) ((a - 1) /10)
76 //#define DEBUG_CRYSTALHD 1
78 /*****************************************************************************
79 * Module descriptor
80 *****************************************************************************/
81 static int OpenDecoder ( vlc_object_t * );
82 static void CloseDecoder ( vlc_object_t * );
84 vlc_module_begin ()
85 set_category( CAT_INPUT )
86 set_subcategory( SUBCAT_INPUT_VCODEC )
87 set_description( N_("Crystal HD hardware video decoder") )
88 set_capability( "decoder", 0 )
89 set_callbacks( OpenDecoder, CloseDecoder )
90 add_shortcut( "crystalhd" )
91 vlc_module_end ()
93 /*****************************************************************************
94 * Local prototypes
95 *****************************************************************************/
96 static picture_t *DecodeBlock ( decoder_t *p_dec, block_t **pp_block );
97 // static void crystal_CopyPicture ( picture_t *, BC_DTS_PROC_OUT* );
98 static int crystal_insert_sps_pps(decoder_t *, uint8_t *, uint32_t);
100 /*****************************************************************************
101 * decoder_sys_t : CrysalHD decoder structure
102 *****************************************************************************/
103 struct decoder_sys_t
105 HANDLE bcm_handle; /* Device Handle */
107 uint8_t *p_sps_pps_buf; /* SPS/PPS buffer */
108 uint32_t i_sps_pps_size; /* SPS/PPS size */
110 uint32_t i_nal_size; /* NAL header size */
112 /* Callback */
113 picture_t *p_pic;
114 BC_DTS_PROC_OUT *proc_out;
116 #ifdef USE_DL_OPENING
117 HINSTANCE p_bcm_dll;
118 BC_STATUS (WINAPI *OurDtsCloseDecoder)( HANDLE hDevice );
119 BC_STATUS (WINAPI *OurDtsDeviceClose)( HANDLE hDevice );
120 BC_STATUS (WINAPI *OurDtsFlushInput)( HANDLE hDevice, U32 Mode );
121 BC_STATUS (WINAPI *OurDtsStopDecoder)( HANDLE hDevice );
122 BC_STATUS (WINAPI *OurDtsGetDriverStatus)( HANDLE hDevice,
123 BC_DTS_STATUS *pStatus );
124 BC_STATUS (WINAPI *OurDtsProcInput)( HANDLE hDevice, U8 *pUserData,
125 U32 ulSizeInBytes, U64 timeStamp, BOOL encrypted );
126 BC_STATUS (WINAPI *OurDtsProcOutput)( HANDLE hDevice, U32 milliSecWait,
127 BC_DTS_PROC_OUT *pOut );
128 BC_STATUS (WINAPI *OurDtsIsEndOfStream)( HANDLE hDevice, U8* bEOS );
129 #endif
132 /*****************************************************************************
133 * OpenDecoder: probe the decoder and return score
134 *****************************************************************************/
135 static int OpenDecoder( vlc_object_t *p_this )
137 decoder_t *p_dec = (decoder_t*)p_this;
138 decoder_sys_t *p_sys;
140 /* Codec specifics */
141 uint32_t i_bcm_codec_subtype = 0;
142 switch ( p_dec->fmt_in.i_codec )
144 case VLC_CODEC_H264:
145 if( p_dec->fmt_in.i_original_fourcc == VLC_FOURCC( 'a', 'v', 'c', '1' ) )
146 i_bcm_codec_subtype = BC_MSUBTYPE_AVC1;
147 else
148 i_bcm_codec_subtype = BC_MSUBTYPE_H264;
149 break;
150 case VLC_CODEC_VC1:
151 i_bcm_codec_subtype = BC_MSUBTYPE_VC1;
152 break;
153 case VLC_CODEC_WMV3:
154 i_bcm_codec_subtype = BC_MSUBTYPE_WMV3;
155 break;
156 case VLC_CODEC_WMVA:
157 i_bcm_codec_subtype = BC_MSUBTYPE_WMVA;
158 break;
159 case VLC_CODEC_MPGV:
160 i_bcm_codec_subtype = BC_MSUBTYPE_MPEG2VIDEO;
161 break;
162 /* Not ready for production yet
163 case VLC_CODEC_MP4V:
164 i_bcm_codec_subtype = BC_MSUBTYPE_DIVX;
165 break;
166 case VLC_CODEC_DIV3:
167 i_bcm_codec_subtype = BC_MSUBTYPE_DIVX311;
168 break; */
169 default:
170 return VLC_EGENERIC;
173 /* Allocate the memory needed to store the decoder's structure */
174 p_sys = malloc( sizeof(*p_sys) );
175 if( !p_sys )
176 return VLC_ENOMEM;
178 /* Fill decoder_sys_t */
179 p_dec->p_sys = p_sys;
180 p_sys->i_nal_size = 4; // assume 4 byte start codes
181 p_sys->i_sps_pps_size = 0;
182 p_sys->p_sps_pps_buf = NULL;
183 p_dec->p_sys->p_pic = NULL;
184 p_dec->p_sys->proc_out = NULL;
186 /* Win32 code *
187 * We cannot link and ship BCM dll, even with LGPL license (too big)
188 * and if we don't ship it, the plugin would not work depending on the
189 * installation order => DLopen */
190 #ifdef USE_DL_OPENING
191 # define DLL_NAME "bcmDIL.dll"
192 # define PATHS_NB 3
193 static const char *psz_paths[PATHS_NB] = {
194 DLL_NAME,
195 "C:\\Program Files\\Broadcom\\Broadcom CrystalHD Decoder\\" DLL_NAME,
196 "C:\\Program Files (x86)\\Broadcom\\Broadcom CrystalHD Decoder\\" DLL_NAME,
198 for( int i = 0; i < PATHS_NB; i++ )
200 HINSTANCE p_bcm_dll = LoadLibrary( psz_paths[i] );
201 if( p_bcm_dll )
203 p_sys->p_bcm_dll = p_bcm_dll;
204 break;
207 if( !p_sys->p_bcm_dll )
209 msg_Dbg( p_dec, "Couldn't load the CrystalHD dll");
210 return VLC_EGENERIC;
213 #define LOAD_SYM( a ) \
214 BC_FUNC( a ) = (void *)GetProcAddress( p_sys->p_bcm_dll, TEXT( #a ) ); \
215 if( !BC_FUNC( a ) ) { \
216 msg_Err( p_dec, "missing symbol " # a ); return VLC_EGENERIC; }
218 #define LOAD_SYM_PSYS( a ) \
219 p_sys->BC_FUNC( a ) = (void *)GetProcAddress( p_sys->p_bcm_dll, #a ); \
220 if( !p_sys->BC_FUNC( a ) ) { \
221 msg_Err( p_dec, "missing symbol " # a ); return VLC_EGENERIC; }
223 BC_STATUS (WINAPI *OurDtsDeviceOpen)( HANDLE *hDevice, U32 mode );
224 LOAD_SYM( DtsDeviceOpen );
225 BC_STATUS (WINAPI *OurDtsCrystalHDVersion)( HANDLE hDevice, PBC_INFO_CRYSTAL bCrystalInfo );
226 LOAD_SYM( DtsCrystalHDVersion );
227 BC_STATUS (WINAPI *OurDtsSetColorSpace)( HANDLE hDevice, BC_OUTPUT_FORMAT Mode422 );
228 LOAD_SYM( DtsSetColorSpace );
229 BC_STATUS (WINAPI *OurDtsSetInputFormat)( HANDLE hDevice, BC_INPUT_FORMAT *pInputFormat );
230 LOAD_SYM( DtsSetInputFormat );
231 BC_STATUS (WINAPI *OurDtsOpenDecoder)( HANDLE hDevice, U32 StreamType );
232 LOAD_SYM( DtsOpenDecoder );
233 BC_STATUS (WINAPI *OurDtsStartDecoder)( HANDLE hDevice );
234 LOAD_SYM( DtsStartDecoder );
235 BC_STATUS (WINAPI *OurDtsStartCapture)( HANDLE hDevice );
236 LOAD_SYM( DtsStartCapture );
237 LOAD_SYM_PSYS( DtsCloseDecoder );
238 LOAD_SYM_PSYS( DtsDeviceClose );
239 LOAD_SYM_PSYS( DtsFlushInput );
240 LOAD_SYM_PSYS( DtsStopDecoder );
241 LOAD_SYM_PSYS( DtsGetDriverStatus );
242 LOAD_SYM_PSYS( DtsProcInput );
243 LOAD_SYM_PSYS( DtsProcOutput );
244 LOAD_SYM_PSYS( DtsIsEndOfStream );
245 #undef LOAD_SYM
246 #undef LOAD_SYM_PSYS
247 #endif /* USE_DL_OPENING */
249 #ifdef DEBUG_CRYSTALHD
250 msg_Dbg( p_dec, "Trying to open CrystalHD HW");
251 #endif
253 /* Get the handle for the device */
254 if( BC_FUNC(DtsDeviceOpen)( &p_sys->bcm_handle,
255 (DTS_PLAYBACK_MODE | DTS_LOAD_FILE_PLAY_FW | DTS_SKIP_TX_CHK_CPB) )
256 // | DTS_DFLT_RESOLUTION(vdecRESOLUTION_720p29_97) ) )
257 != BC_STS_SUCCESS )
259 msg_Err( p_dec, "Couldn't find and open the BCM CrystalHD device" );
260 free( p_sys );
261 return VLC_EGENERIC;
264 #ifdef DEBUG_CRYSTALHD
265 BC_INFO_CRYSTAL info;
266 if( BC_FUNC(DtsCrystalHDVersion)( p_sys->bcm_handle, &info ) == BC_STS_SUCCESS )
268 msg_Dbg( p_dec, "Using CrystalHD Driver version: %i.%i.%i, "
269 "Library version: %i.%i.%i, Firmware version: %i.%i.%i",
270 info.drvVersion.drvRelease, info.drvVersion.drvMajor,
271 info.drvVersion.drvMinor,
272 info.dilVersion.dilRelease, info.dilVersion.dilMajor,
273 info.dilVersion.dilMinor,
274 info.fwVersion.fwRelease, info.fwVersion.fwMajor,
275 info.fwVersion.fwMinor );
277 #endif
279 /* Special case for AVC1 */
280 if( i_bcm_codec_subtype == BC_MSUBTYPE_AVC1 )
282 if( p_dec->fmt_in.i_extra > 0 )
284 msg_Dbg( p_dec, "Parsing extra infos for avc1" );
285 if( crystal_insert_sps_pps( p_dec, (uint8_t*)p_dec->fmt_in.p_extra,
286 p_dec->fmt_in.i_extra ) != VLC_SUCCESS )
287 goto error;
289 else
291 msg_Err( p_dec, "Missing extra infos for avc1" );
292 goto error;
296 /* Always use YUY2 color */
297 if( BC_FUNC(DtsSetColorSpace)( p_sys->bcm_handle, OUTPUT_MODE422_YUY2 )
298 != BC_STS_SUCCESS )
300 msg_Err( p_dec, "Couldn't set the color space. Please report this!" );
301 goto error;
304 /* Prepare Input for the device */
305 BC_INPUT_FORMAT p_in;
306 memset( &p_in, 0, sizeof(BC_INPUT_FORMAT) );
307 p_in.OptFlags = 0x51; /* 0b 0 1 01 0001 */
308 p_in.mSubtype = i_bcm_codec_subtype;
309 p_in.startCodeSz = p_sys->i_nal_size;
310 p_in.pMetaData = p_sys->p_sps_pps_buf;
311 p_in.metaDataSz = p_sys->i_sps_pps_size;
312 p_in.width = p_dec->fmt_in.video.i_width;
313 p_in.height = p_dec->fmt_in.video.i_height;
314 p_in.Progressive = true;
316 if( BC_FUNC(DtsSetInputFormat)( p_sys->bcm_handle, &p_in ) != BC_STS_SUCCESS )
318 msg_Err( p_dec, "Couldn't set the color space. Please report this!" );
319 goto error;
322 /* Open a decoder */
323 if( BC_FUNC(DtsOpenDecoder)( p_sys->bcm_handle, BC_STREAM_TYPE_ES )
324 != BC_STS_SUCCESS )
326 msg_Err( p_dec, "Couldn't open the CrystalHD decoder" );
327 goto error;
330 /* Start it */
331 if( BC_FUNC(DtsStartDecoder)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
333 msg_Err( p_dec, "Couldn't start the decoder" );
334 goto error;
337 if( BC_FUNC(DtsStartCapture)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
339 msg_Err( p_dec, "Couldn't start the capture" );
340 goto error_complete;
343 /* Set output properties */
344 p_dec->fmt_out.i_cat = VIDEO_ES;
345 p_dec->fmt_out.i_codec = VLC_CODEC_YUYV;
346 p_dec->fmt_out.video.i_width = p_dec->fmt_in.video.i_width;
347 p_dec->fmt_out.video.i_height = p_dec->fmt_in.video.i_height;
348 p_dec->b_need_packetized = true;
350 /* Set callbacks */
351 p_dec->pf_decode_video = DecodeBlock;
353 msg_Info( p_dec, "Opened CrystalHD hardware with success" );
354 return VLC_SUCCESS;
356 error_complete:
357 BC_FUNC_PSYS(DtsCloseDecoder)( p_sys->bcm_handle );
358 error:
359 BC_FUNC_PSYS(DtsDeviceClose)( p_sys->bcm_handle );
360 free( p_sys );
361 return VLC_EGENERIC;
364 /*****************************************************************************
365 * CloseDecoder: decoder destruction
366 *****************************************************************************/
367 static void CloseDecoder( vlc_object_t *p_this )
369 decoder_t *p_dec = (decoder_t *)p_this;
370 decoder_sys_t *p_sys = p_dec->p_sys;
372 if( BC_FUNC_PSYS(DtsFlushInput)( p_sys->bcm_handle, 2 ) != BC_STS_SUCCESS )
373 goto error;
374 if( BC_FUNC_PSYS(DtsStopDecoder)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
375 goto error;
376 if( BC_FUNC_PSYS(DtsCloseDecoder)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
377 goto error;
378 if( BC_FUNC_PSYS(DtsDeviceClose)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
379 goto error;
381 error:
382 free( p_sys->p_sps_pps_buf );
383 #ifdef DEBUG_CRYSTALHD
384 msg_Dbg( p_dec, "done cleaning up CrystalHD" );
385 #endif
386 free( p_sys );
389 static BC_STATUS ourCallback(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut)
391 VLC_UNUSED(width); VLC_UNUSED(height); VLC_UNUSED(stride);
393 decoder_t *p_dec = (decoder_t *)shnd;
394 BC_DTS_PROC_OUT *proc_out = p_dec->p_sys->proc_out;
395 BC_DTS_PROC_OUT *proc_in = (BC_DTS_PROC_OUT*)pOut;
397 /* Direct Rendering */
398 /* Do not allocate for the second-field in the pair, in interlaced */
399 if( !(proc_in->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) ||
400 !(proc_in->PicInfo.flags & VDEC_FLAG_FIELDPAIR) )
401 p_dec->p_sys->p_pic = decoder_NewPicture( p_dec );
403 /* */
404 picture_t *p_pic = p_dec->p_sys->p_pic;
405 if( !p_pic )
406 return BC_STS_ERROR;
408 /* Interlacing */
409 p_pic->b_progressive = !(proc_in->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC);
410 p_pic->b_top_field_first = !(proc_in->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
411 p_pic->i_nb_fields = p_pic->b_progressive? 1: 2;
413 /* Filling out the struct */
414 proc_out->Ybuff = !(proc_in->PicInfo.flags & VDEC_FLAG_FIELDPAIR) ?
415 &p_pic->p[0].p_pixels[0] :
416 &p_pic->p[0].p_pixels[p_pic->p[0].i_pitch];
417 proc_out->YbuffSz = 2 * p_pic->p[0].i_pitch;
418 proc_out->StrideSz = (proc_in->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC)?
419 2 * (p_pic->p[0].i_pitch/2) - p_dec->fmt_out.video.i_width:
420 p_pic->p[0].i_pitch/2 - p_dec->fmt_out.video.i_width;
421 proc_out->PoutFlags |= BC_POUT_FLAGS_STRIDE; /* Trust Stride info */
423 return BC_STS_SUCCESS;
426 /****************************************************************************
427 * DecodeBlock: the whole thing
428 ****************************************************************************/
429 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
431 decoder_sys_t *p_sys = p_dec->p_sys;
432 block_t *p_block;
434 BC_DTS_PROC_OUT proc_out;
435 BC_DTS_STATUS driver_stat;
437 /* First check the status of the decode to produce pictures */
438 if( BC_FUNC_PSYS(DtsGetDriverStatus)( p_sys->bcm_handle, &driver_stat ) != BC_STS_SUCCESS )
439 return NULL;
441 p_block = *pp_block;
442 if( p_block )
444 if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) == 0 )
446 /* Valid input block, so we can send to HW to decode */
448 BC_STATUS status = BC_FUNC_PSYS(DtsProcInput)( p_sys->bcm_handle,
449 p_block->p_buffer,
450 p_block->i_buffer,
451 p_block->i_pts >= VLC_TS_INVALID ? TO_BC_PTS(p_block->i_pts) : 0, false );
453 block_Release( p_block );
454 *pp_block = NULL;
456 if( status != BC_STS_SUCCESS )
457 return NULL;
460 #ifdef DEBUG_CRYSTALHD
461 else
463 if( driver_stat.ReadyListCount != 0 )
464 msg_Err( p_dec, " Input NULL but have pictures %u", driver_stat.ReadyListCount );
466 #endif
468 if( driver_stat.ReadyListCount == 0 )
469 return NULL;
471 /* Prepare the Output structure */
472 /* We always expect and use YUY2 */
473 memset( &proc_out, 0, sizeof(BC_DTS_PROC_OUT) );
474 proc_out.PicInfo.width = p_dec->fmt_out.video.i_width;
475 proc_out.PicInfo.height = p_dec->fmt_out.video.i_height;
476 proc_out.PoutFlags = BC_POUT_FLAGS_SIZE;
477 proc_out.AppCallBack = ourCallback;
478 proc_out.hnd = p_dec;
479 p_sys->proc_out = &proc_out;
481 /* */
482 BC_STATUS sts = BC_FUNC_PSYS(DtsProcOutput)( p_sys->bcm_handle, 128, &proc_out );
483 #ifdef DEBUG_CRYSTALHD
484 if( sts != BC_STS_SUCCESS )
485 msg_Err( p_dec, "DtsProcOutput returned %i", sts );
486 #endif
488 uint8_t b_eos;
489 picture_t *p_pic = p_sys->p_pic;
490 switch( sts )
492 case BC_STS_SUCCESS:
493 if( !(proc_out.PoutFlags & BC_POUT_FLAGS_PIB_VALID) )
495 msg_Dbg( p_dec, "Invalid PIB" );
496 break;
499 if( !p_pic )
500 break;
502 /* In interlaced mode, do not push the first field in the pipeline */
503 if( (proc_out.PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
504 !(proc_out.PicInfo.flags & VDEC_FLAG_FIELDPAIR) )
505 return NULL;
507 // crystal_CopyPicture( p_pic, &proc_out );
508 p_pic->date = proc_out.PicInfo.timeStamp > 0 ?
509 FROM_BC_PTS(proc_out.PicInfo.timeStamp) : VLC_TS_INVALID;
510 //p_pic->date += 100 * 1000;
511 #ifdef DEBUG_CRYSTALHD
512 msg_Dbg( p_dec, "TS Output is %"PRIu64, p_pic->date);
513 #endif
514 return p_pic;
516 case BC_STS_DEC_NOT_OPEN:
517 case BC_STS_DEC_NOT_STARTED:
518 msg_Err( p_dec, "Decoder not opened or started" );
519 break;
521 case BC_STS_INV_ARG:
522 msg_Warn( p_dec, "Invalid arguments. Please report" );
523 break;
525 case BC_STS_FMT_CHANGE: /* Format change */
526 /* if( !(proc_out.PoutFlags & BC_POUT_FLAGS_PIB_VALID) )
527 break; */
528 p_dec->fmt_out.video.i_width = proc_out.PicInfo.width;
529 p_dec->fmt_out.video.i_height = proc_out.PicInfo.height;
530 if( proc_out.PicInfo.height == 1088 )
531 p_dec->fmt_out.video.i_height = 1080;
532 #define setAR( a, b, c ) case a: p_dec->fmt_out.video.i_sar_num = b; \
533 p_dec->fmt_out.video.i_sar_den = c; break;
534 switch( proc_out.PicInfo.aspect_ratio )
536 setAR( vdecAspectRatioSquare, 1, 1 )
537 setAR( vdecAspectRatio12_11, 12, 11 )
538 setAR( vdecAspectRatio10_11, 10, 11 )
539 setAR( vdecAspectRatio16_11, 16, 11 )
540 setAR( vdecAspectRatio40_33, 40, 33 )
541 setAR( vdecAspectRatio24_11, 24, 11 )
542 setAR( vdecAspectRatio20_11, 20, 11 )
543 setAR( vdecAspectRatio32_11, 32, 11 )
544 setAR( vdecAspectRatio80_33, 80, 33 )
545 setAR( vdecAspectRatio18_11, 18, 11 )
546 setAR( vdecAspectRatio15_11, 15, 11 )
547 setAR( vdecAspectRatio64_33, 64, 33 )
548 setAR( vdecAspectRatio160_99, 160, 99 )
549 setAR( vdecAspectRatio4_3, 4, 3 )
550 setAR( vdecAspectRatio16_9, 16, 9 )
551 setAR( vdecAspectRatio221_1, 221, 1 )
552 default: break;
554 #undef setAR
555 msg_Dbg( p_dec, "Format Change Detected [%i, %i], AR: %i/%i",
556 proc_out.PicInfo.width, proc_out.PicInfo.height,
557 p_dec->fmt_out.video.i_sar_num,
558 p_dec->fmt_out.video.i_sar_den );
559 break;
561 /* Nothing is documented here... */
562 case BC_STS_NO_DATA:
563 if( BC_FUNC_PSYS(DtsIsEndOfStream)( p_sys->bcm_handle, &b_eos )
564 == BC_STS_SUCCESS )
565 if( b_eos )
566 msg_Dbg( p_dec, "End of Stream" );
567 break;
568 case BC_STS_TIMEOUT: /* Timeout */
569 msg_Err( p_dec, "ProcOutput timeout" );
570 break;
571 case BC_STS_IO_XFR_ERROR:
572 case BC_STS_IO_USER_ABORT:
573 case BC_STS_IO_ERROR:
574 msg_Err( p_dec, "ProcOutput return mode not implemented. Please report" );
575 break;
576 default:
577 msg_Err( p_dec, "Unknown return status. Please report %i", sts );
578 break;
580 if( p_pic )
581 decoder_DeletePicture( p_dec, p_pic );
582 return NULL;
585 #if 0
586 /* Copy the data
587 * FIXME: this should not exist */
588 static void crystal_CopyPicture ( picture_t *p_pic, BC_DTS_PROC_OUT* p_out )
590 int i_dst_stride;
591 uint8_t *p_dst, *p_dst_end;
592 uint8_t *p_src = p_out->Ybuff;
594 p_dst = p_pic->p[0].p_pixels;
595 i_dst_stride = p_pic->p[0].i_pitch;
596 p_dst_end = p_dst + (i_dst_stride * p_out->PicInfo.height);
598 for( ; p_dst < p_dst_end; p_dst += i_dst_stride, p_src += (p_out->PicInfo.width * 2))
599 vlc_memcpy( p_dst, p_src, p_out->PicInfo.width * 2); // Copy in bytes
601 #endif
603 /* Parse the SPS/PPS Metadata to feed the decoder for avc1 */
604 static int crystal_insert_sps_pps( decoder_t *p_dec,
605 uint8_t *p_buf,
606 uint32_t i_buf_size)
608 decoder_sys_t *p_sys = p_dec->p_sys;
609 int i_profile;
610 uint32_t i_data_size = i_buf_size, i_nal_size;
611 unsigned int i_loop_end;
613 p_sys->i_sps_pps_size = 0;
615 p_sys->p_sps_pps_buf = malloc( p_dec->fmt_in.i_extra * 2 );
616 if( !p_sys->p_sps_pps_buf )
617 return VLC_ENOMEM;
619 /* */
620 if( i_data_size < 7 )
622 msg_Err( p_dec, "Input Metadata too small" );
623 goto error;
626 /* Read infos in first 6 bytes */
627 i_profile = (p_buf[1] << 16) | (p_buf[2] << 8) | p_buf[3];
628 p_sys->i_nal_size = (p_buf[4] & 0x03) + 1;
629 p_buf += 5;
630 i_data_size -= 5;
632 for ( unsigned int j = 0; j < 2; j++ )
634 /* First time is SPS, Second is PPS */
635 if( i_data_size < 1 )
637 msg_Err( p_dec, "PPS too small after processing SPS/PPS %u",
638 i_data_size );
639 goto error;
641 i_loop_end = p_buf[0] & (j == 0 ? 0x1f : 0xff);
642 p_buf++; i_data_size--;
644 for ( unsigned int i = 0; i < i_loop_end; i++)
646 if( i_data_size < 2 )
648 msg_Err( p_dec, "SPS is too small %u", i_data_size );
649 goto error;
652 i_nal_size = (p_buf[0] << 8) | p_buf[1];
653 p_buf += 2;
654 i_data_size -= 2;
656 if( i_data_size < i_nal_size )
658 msg_Err( p_dec, "SPS size does not match NAL specified size %u",
659 i_data_size );
660 goto error;
663 p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 0;
664 p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 0;
665 p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 0;
666 p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 1;
668 memcpy( p_sys->p_sps_pps_buf + p_sys->i_sps_pps_size, p_buf, i_nal_size );
669 p_sys->i_sps_pps_size += i_nal_size;
671 p_buf += i_nal_size;
672 i_data_size -= i_nal_size;
676 return VLC_SUCCESS;
678 error:
679 free( p_sys->p_sps_pps_buf );
680 p_sys->p_sps_pps_buf = NULL;
681 return VLC_ENOMEM;