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