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 /*****************************************************************************
24 *****************************************************************************/
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__
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>
53 # define USE_DL_OPENING 1
55 # include <libcrystalhd/libcrystalhd_if.h>
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 */
62 # warning DLL opening mode
63 # define BC_FUNC( a ) Our ## a
64 # define BC_FUNC_PSYS( a ) p_sys->Our ## a
66 # define BC_FUNC( a ) a
67 # define BC_FUNC_PSYS( a ) a
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 /*****************************************************************************
80 *****************************************************************************/
81 static int OpenDecoder ( vlc_object_t
* );
82 static void CloseDecoder ( vlc_object_t
* );
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" )
93 /*****************************************************************************
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 *****************************************************************************/
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 */
114 BC_DTS_PROC_OUT
*proc_out
;
116 #ifdef USE_DL_OPENING
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
);
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
)
145 if( p_dec
->fmt_in
.i_original_fourcc
== VLC_FOURCC( 'a', 'v', 'c', '1' ) )
146 i_bcm_codec_subtype
= BC_MSUBTYPE_AVC1
;
148 i_bcm_codec_subtype
= BC_MSUBTYPE_H264
;
151 i_bcm_codec_subtype
= BC_MSUBTYPE_VC1
;
154 i_bcm_codec_subtype
= BC_MSUBTYPE_WMV3
;
157 i_bcm_codec_subtype
= BC_MSUBTYPE_WMVA
;
160 i_bcm_codec_subtype
= BC_MSUBTYPE_MPEG2VIDEO
;
162 /* Not ready for production yet
164 i_bcm_codec_subtype = BC_MSUBTYPE_DIVX;
167 i_bcm_codec_subtype = BC_MSUBTYPE_DIVX311;
173 /* Allocate the memory needed to store the decoder's structure */
174 p_sys
= malloc( sizeof(*p_sys
) );
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
;
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"
193 static const char *psz_paths
[PATHS_NB
] = {
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
] );
203 p_sys
->p_bcm_dll
= p_bcm_dll
;
207 if( !p_sys
->p_bcm_dll
)
209 msg_Dbg( p_dec
, "Couldn't load the CrystalHD dll");
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
);
247 #endif /* USE_DL_OPENING */
249 #ifdef DEBUG_CRYSTALHD
250 msg_Dbg( p_dec
, "Trying to open CrystalHD HW");
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) ) )
259 msg_Err( p_dec
, "Couldn't find and open the BCM CrystalHD device" );
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
);
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
)
291 msg_Err( p_dec
, "Missing extra infos for avc1" );
296 /* Always use YUY2 color */
297 if( BC_FUNC(DtsSetColorSpace
)( p_sys
->bcm_handle
, OUTPUT_MODE422_YUY2
)
300 msg_Err( p_dec
, "Couldn't set the color space. Please report this!" );
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!" );
323 if( BC_FUNC(DtsOpenDecoder
)( p_sys
->bcm_handle
, BC_STREAM_TYPE_ES
)
326 msg_Err( p_dec
, "Couldn't open the CrystalHD decoder" );
331 if( BC_FUNC(DtsStartDecoder
)( p_sys
->bcm_handle
) != BC_STS_SUCCESS
)
333 msg_Err( p_dec
, "Couldn't start the decoder" );
337 if( BC_FUNC(DtsStartCapture
)( p_sys
->bcm_handle
) != BC_STS_SUCCESS
)
339 msg_Err( p_dec
, "Couldn't start the capture" );
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;
351 p_dec
->pf_decode_video
= DecodeBlock
;
353 msg_Info( p_dec
, "Opened CrystalHD hardware with success" );
357 BC_FUNC_PSYS(DtsCloseDecoder
)( p_sys
->bcm_handle
);
359 BC_FUNC_PSYS(DtsDeviceClose
)( p_sys
->bcm_handle
);
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
)
374 if( BC_FUNC_PSYS(DtsStopDecoder
)( p_sys
->bcm_handle
) != BC_STS_SUCCESS
)
376 if( BC_FUNC_PSYS(DtsCloseDecoder
)( p_sys
->bcm_handle
) != BC_STS_SUCCESS
)
378 if( BC_FUNC_PSYS(DtsDeviceClose
)( p_sys
->bcm_handle
) != BC_STS_SUCCESS
)
382 free( p_sys
->p_sps_pps_buf
);
383 #ifdef DEBUG_CRYSTALHD
384 msg_Dbg( p_dec
, "done cleaning up CrystalHD" );
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
);
404 picture_t
*p_pic
= p_dec
->p_sys
->p_pic
;
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
;
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
)
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
,
451 p_block
->i_pts
>= VLC_TS_INVALID
? TO_BC_PTS(p_block
->i_pts
) : 0, false );
453 block_Release( p_block
);
456 if( status
!= BC_STS_SUCCESS
)
460 #ifdef DEBUG_CRYSTALHD
463 if( driver_stat
.ReadyListCount
!= 0 )
464 msg_Err( p_dec
, " Input NULL but have pictures %u", driver_stat
.ReadyListCount
);
468 if( driver_stat
.ReadyListCount
== 0 )
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
;
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
);
489 picture_t
*p_pic
= p_sys
->p_pic
;
493 if( !(proc_out
.PoutFlags
& BC_POUT_FLAGS_PIB_VALID
) )
495 msg_Dbg( p_dec
, "Invalid PIB" );
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
) )
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
);
516 case BC_STS_DEC_NOT_OPEN
:
517 case BC_STS_DEC_NOT_STARTED
:
518 msg_Err( p_dec
, "Decoder not opened or started" );
522 msg_Warn( p_dec
, "Invalid arguments. Please report" );
525 case BC_STS_FMT_CHANGE
: /* Format change */
526 /* if( !(proc_out.PoutFlags & BC_POUT_FLAGS_PIB_VALID) )
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 )
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
);
561 /* Nothing is documented here... */
563 if( BC_FUNC_PSYS(DtsIsEndOfStream
)( p_sys
->bcm_handle
, &b_eos
)
566 msg_Dbg( p_dec
, "End of Stream" );
568 case BC_STS_TIMEOUT
: /* Timeout */
569 msg_Err( p_dec
, "ProcOutput timeout" );
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" );
577 msg_Err( p_dec
, "Unknown return status. Please report %i", sts
);
581 decoder_DeletePicture( p_dec
, p_pic
);
587 * FIXME: this should not exist */
588 static void crystal_CopyPicture ( picture_t
*p_pic
, BC_DTS_PROC_OUT
* p_out
)
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
603 /* Parse the SPS/PPS Metadata to feed the decoder for avc1 */
604 static int crystal_insert_sps_pps( decoder_t
*p_dec
,
608 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
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
)
620 if( i_data_size
< 7 )
622 msg_Err( p_dec
, "Input Metadata too small" );
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;
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",
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
);
652 i_nal_size
= (p_buf
[0] << 8) | p_buf
[1];
656 if( i_data_size
< i_nal_size
)
658 msg_Err( p_dec
, "SPS size does not match NAL specified size %u",
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
;
672 i_data_size
-= i_nal_size
;
679 free( p_sys
->p_sps_pps_buf
);
680 p_sys
->p_sps_pps_buf
= NULL
;