]> git.sesse.net Git - vlc/blobdiff - modules/codec/crystalhd.c
avcodec: move debug message to correct place
[vlc] / modules / codec / crystalhd.c
index 632c044db9101fd262ad3848d264a0b2e8dfdb5f..3c838c4959840d678dc5369d4d9ad5d4c6abd7b8 100644 (file)
@@ -1,22 +1,24 @@
 /*****************************************************************************
- * Copyright © 2010 VideoLAN
+ * crystalhd.c: CrystalHD decoder
+ *****************************************************************************
+ * Copyright © 2010-2011 VideoLAN
  *
  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
  *          Narendra Sankar <nsankar@broadcom.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
  * the Free Software Foundation; either version 2.1 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
 # include "config.h"
 #endif
 
+/* TODO
+ * - pts = 0?
+ * - mpeg4-asp
+ * - win32 testing
+ */
+
 /* VLC includes */
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_codec.h>
+#include "h264_nal.h"
 
+/* Workaround for some versions of libcrystalHD */
 #if !defined(_WIN32) && !defined(__APPLE__)
-   #define __LINUX_USER__
+#  define __LINUX_USER__
 #endif
 
 /* CrystalHD */
 #include <libcrystalhd/bc_dts_defs.h>
 #include <libcrystalhd/bc_dts_types.h>
-#if HAVE_LIBCRYSTALHD_BC_DRV_IF_H
-  #include <libcrystalhd/bc_drv_if.h>
+
+#if defined(HAVE_LIBCRYSTALHD_BC_DRV_IF_H) /* Win32 */
+#  include <libcrystalhd/bc_drv_if.h>
+#elif defined(_WIN32)
+#  define USE_DL_OPENING 1
+#else
+#  include <libcrystalhd/libcrystalhd_if.h>
+#endif
+
+/* On a normal Win32 build, well aren't going to ship the BCM dll
+   And forcing users to install the right dll at the right place will not work
+   Therefore, we need to dl_open and resolve the symbols */
+#ifdef USE_DL_OPENING
+#  warning DLL opening mode
+#  define BC_FUNC( a ) Our ## a
+#  define BC_FUNC_PSYS( a ) p_sys->Our ## a
 #else
-  #include <libcrystalhd/libcrystalhd_if.h>
+#  define BC_FUNC( a ) a
+#  define BC_FUNC_PSYS( a ) a
 #endif
 
 #include <assert.h>
@@ -72,7 +97,7 @@ vlc_module_end ()
  * Local prototypes
  *****************************************************************************/
 static picture_t *DecodeBlock   ( decoder_t *p_dec, block_t **pp_block );
-static void crystal_CopyPicture ( picture_t *, BC_DTS_PROC_OUT* );
+// static void crystal_CopyPicture ( picture_t *, BC_DTS_PROC_OUT* );
 static int crystal_insert_sps_pps(decoder_t *, uint8_t *, uint32_t);
 
 /*****************************************************************************
@@ -86,11 +111,30 @@ struct decoder_sys_t
     uint32_t i_sps_pps_size; /* SPS/PPS size */
 
     uint32_t i_nal_size;     /* NAL header size */
+
+    /* Callback */
+    picture_t       *p_pic;
+    BC_DTS_PROC_OUT *proc_out;
+
+#ifdef USE_DL_OPENING
+    HINSTANCE p_bcm_dll;
+    BC_STATUS (WINAPI *OurDtsCloseDecoder)( HANDLE hDevice );
+    BC_STATUS (WINAPI *OurDtsDeviceClose)( HANDLE hDevice );
+    BC_STATUS (WINAPI *OurDtsFlushInput)( HANDLE hDevice, U32 Mode );
+    BC_STATUS (WINAPI *OurDtsStopDecoder)( HANDLE hDevice );
+    BC_STATUS (WINAPI *OurDtsGetDriverStatus)( HANDLE hDevice,
+                            BC_DTS_STATUS *pStatus );
+    BC_STATUS (WINAPI *OurDtsProcInput)( HANDLE hDevice, U8 *pUserData,
+                            U32 ulSizeInBytes, U64 timeStamp, BOOL encrypted );
+    BC_STATUS (WINAPI *OurDtsProcOutput)( HANDLE hDevice, U32 milliSecWait,
+                            BC_DTS_PROC_OUT *pOut );
+    BC_STATUS (WINAPI *OurDtsIsEndOfStream)( HANDLE hDevice, U8* bEOS );
+#endif
 };
 
 /*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************/
+* OpenDecoder: probe the decoder and return score
+*****************************************************************************/
 static int OpenDecoder( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
@@ -121,43 +165,99 @@ static int OpenDecoder( vlc_object_t *p_this )
 /* Not ready for production yet
     case VLC_CODEC_MP4V:
         i_bcm_codec_subtype = BC_MSUBTYPE_DIVX;
+        break;
+    case VLC_CODEC_DIV3:
+        i_bcm_codec_subtype = BC_MSUBTYPE_DIVX311;
         break; */
     default:
         return VLC_EGENERIC;
     }
 
-#ifdef _WIN32
-    HINSTANCE p_bcm_dll = LoadLibrary( "bcmDIL.dll" );
-    if( !p_bcm_dll )
-    {
-        #ifdef DEBUG_CRYSTALHD
-        msg_Dbg( p_dec, "Couldn't load the CrystalHD dll");
-        #endif
-        return VLC_EGENERIC
-    }
-#endif
-
     /* Allocate the memory needed to store the decoder's structure */
     p_sys = malloc( sizeof(*p_sys) );
     if( !p_sys )
         return VLC_ENOMEM;
 
     /* Fill decoder_sys_t */
-    p_dec->p_sys          = p_sys;
-    p_sys->i_nal_size     = 4; // assume 4 byte start codes
-    p_sys->i_sps_pps_size = 0;
-    p_sys->p_sps_pps_buf  = NULL;
+    p_dec->p_sys            = p_sys;
+    p_sys->i_nal_size       = 4; // assume 4 byte start codes
+    p_sys->i_sps_pps_size   = 0;
+    p_sys->p_sps_pps_buf    = NULL;
+    p_dec->p_sys->p_pic     = NULL;
+    p_dec->p_sys->proc_out  = NULL;
+
+    /* Win32 code *
+     * We cannot link and ship BCM dll, even with LGPL license (too big)
+     * and if we don't ship it, the plugin would not work depending on the
+     * installation order => DLopen */
+#ifdef USE_DL_OPENING
+#  define DLL_NAME "bcmDIL.dll"
+#  define PATHS_NB 3
+    static const char *psz_paths[PATHS_NB] = {
+    DLL_NAME,
+    "C:\\Program Files\\Broadcom\\Broadcom CrystalHD Decoder\\" DLL_NAME,
+    "C:\\Program Files (x86)\\Broadcom\\Broadcom CrystalHD Decoder\\" DLL_NAME,
+    };
+    for( int i = 0; i < PATHS_NB; i++ )
+    {
+        HINSTANCE p_bcm_dll = LoadLibraryA( psz_paths[i] );
+        if( p_bcm_dll )
+        {
+            p_sys->p_bcm_dll = p_bcm_dll;
+            break;
+        }
+    }
+    if( !p_sys->p_bcm_dll )
+    {
+        msg_Dbg( p_dec, "Couldn't load the CrystalHD dll");
+        return VLC_EGENERIC;
+    }
 
+#define LOAD_SYM( a ) \
+    BC_FUNC( a )  = (void *)GetProcAddress( p_sys->p_bcm_dll, ( #a ) ); \
+    if( !BC_FUNC( a ) ) { \
+        msg_Err( p_dec, "missing symbol " # a ); return VLC_EGENERIC; }
+
+#define LOAD_SYM_PSYS( a ) \
+    p_sys->BC_FUNC( a )  = (void *)GetProcAddress( p_sys->p_bcm_dll, #a ); \
+    if( !p_sys->BC_FUNC( a ) ) { \
+        msg_Err( p_dec, "missing symbol " # a ); return VLC_EGENERIC; }
+
+    BC_STATUS (WINAPI *OurDtsDeviceOpen)( HANDLE *hDevice, U32 mode );
+    LOAD_SYM( DtsDeviceOpen );
+    BC_STATUS (WINAPI *OurDtsCrystalHDVersion)( HANDLE  hDevice, PBC_INFO_CRYSTAL bCrystalInfo );
+    LOAD_SYM( DtsCrystalHDVersion );
+    BC_STATUS (WINAPI *OurDtsSetColorSpace)( HANDLE hDevice, BC_OUTPUT_FORMAT Mode422 );
+    LOAD_SYM( DtsSetColorSpace );
+    BC_STATUS (WINAPI *OurDtsSetInputFormat)( HANDLE hDevice, BC_INPUT_FORMAT *pInputFormat );
+    LOAD_SYM( DtsSetInputFormat );
+    BC_STATUS (WINAPI *OurDtsOpenDecoder)( HANDLE hDevice, U32 StreamType );
+    LOAD_SYM( DtsOpenDecoder );
+    BC_STATUS (WINAPI *OurDtsStartDecoder)( HANDLE hDevice );
+    LOAD_SYM( DtsStartDecoder );
+    BC_STATUS (WINAPI *OurDtsStartCapture)( HANDLE hDevice );
+    LOAD_SYM( DtsStartCapture );
+    LOAD_SYM_PSYS( DtsCloseDecoder );
+    LOAD_SYM_PSYS( DtsDeviceClose );
+    LOAD_SYM_PSYS( DtsFlushInput );
+    LOAD_SYM_PSYS( DtsStopDecoder );
+    LOAD_SYM_PSYS( DtsGetDriverStatus );
+    LOAD_SYM_PSYS( DtsProcInput );
+    LOAD_SYM_PSYS( DtsProcOutput );
+    LOAD_SYM_PSYS( DtsIsEndOfStream );
+#undef LOAD_SYM
+#undef LOAD_SYM_PSYS
+#endif /* USE_DL_OPENING */
 
 #ifdef DEBUG_CRYSTALHD
     msg_Dbg( p_dec, "Trying to open CrystalHD HW");
 #endif
 
     /* Get the handle for the device */
-    if( DtsDeviceOpen( &p_sys->bcm_handle,
-                      (DTS_PLAYBACK_MODE | DTS_LOAD_FILE_PLAY_FW | DTS_SKIP_TX_CHK_CPB ) )
-                      // | DTS_DFLT_RESOLUTION(vdecRESOLUTION_720p29_97) ) )
-                     != BC_STS_SUCCESS )
+    if( BC_FUNC(DtsDeviceOpen)( &p_sys->bcm_handle,
+             (DTS_PLAYBACK_MODE | DTS_LOAD_FILE_PLAY_FW | DTS_SKIP_TX_CHK_CPB) )
+             // | DTS_DFLT_RESOLUTION(vdecRESOLUTION_720p29_97) ) )
+             != BC_STS_SUCCESS )
     {
         msg_Err( p_dec, "Couldn't find and open the BCM CrystalHD device" );
         free( p_sys );
@@ -166,14 +266,16 @@ static int OpenDecoder( vlc_object_t *p_this )
 
 #ifdef DEBUG_CRYSTALHD
     BC_INFO_CRYSTAL info;
-    if( DtsCrystalHDVersion( p_sys->bcm_handle, &info ) == BC_STS_SUCCESS )
+    if( BC_FUNC(DtsCrystalHDVersion)( p_sys->bcm_handle, &info ) == BC_STS_SUCCESS )
     {
         msg_Dbg( p_dec, "Using CrystalHD Driver version: %i.%i.%i, "
-            "Library version: %i.%i.%i, "
-            "Firmware version: %i.%i.%i",
-            info.drvVersion.drvRelease, info.drvVersion.drvMajor, info.drvVersion.drvMinor,
-            info.dilVersion.dilRelease, info.dilVersion.dilMajor, info.dilVersion.dilMinor,
-            info.fwVersion.fwRelease, info.fwVersion.fwMajor, info.fwVersion.fwMinor );
+            "Library version: %i.%i.%i, Firmware version: %i.%i.%i",
+            info.drvVersion.drvRelease, info.drvVersion.drvMajor,
+            info.drvVersion.drvMinor,
+            info.dilVersion.dilRelease, info.dilVersion.dilMajor,
+            info.dilVersion.dilMinor,
+            info.fwVersion.fwRelease,   info.fwVersion.fwMajor,
+            info.fwVersion.fwMinor );
     }
 #endif
 
@@ -194,8 +296,9 @@ static int OpenDecoder( vlc_object_t *p_this )
         }
     }
 
-    /* Always YUY2 color */
-    if( DtsSetColorSpace( p_sys->bcm_handle, OUTPUT_MODE422_YUY2 ) != BC_STS_SUCCESS )
+    /* Always use YUY2 color */
+    if( BC_FUNC(DtsSetColorSpace)( p_sys->bcm_handle, OUTPUT_MODE422_YUY2 )
+            != BC_STS_SUCCESS )
     {
         msg_Err( p_dec, "Couldn't set the color space. Please report this!" );
         goto error;
@@ -213,27 +316,28 @@ static int OpenDecoder( vlc_object_t *p_this )
     p_in.height      = p_dec->fmt_in.video.i_height;
     p_in.Progressive = true;
 
-    if( DtsSetInputFormat( p_sys->bcm_handle, &p_in ) != BC_STS_SUCCESS )
+    if( BC_FUNC(DtsSetInputFormat)( p_sys->bcm_handle, &p_in ) != BC_STS_SUCCESS )
     {
         msg_Err( p_dec, "Couldn't set the color space. Please report this!" );
         goto error;
     }
 
     /* Open a decoder */
-    if( DtsOpenDecoder( p_sys->bcm_handle, BC_STREAM_TYPE_ES ) != BC_STS_SUCCESS )
+    if( BC_FUNC(DtsOpenDecoder)( p_sys->bcm_handle, BC_STREAM_TYPE_ES )
+            != BC_STS_SUCCESS )
     {
         msg_Err( p_dec, "Couldn't open the CrystalHD decoder" );
         goto error;
     }
 
     /* Start it */
-    if( DtsStartDecoder( p_sys->bcm_handle ) != BC_STS_SUCCESS )
+    if( BC_FUNC(DtsStartDecoder)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
     {
         msg_Err( p_dec, "Couldn't start the decoder" );
         goto error;
     }
 
-    if( DtsStartCapture( p_sys->bcm_handle ) != BC_STS_SUCCESS )
+    if( BC_FUNC(DtsStartCapture)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
     {
         msg_Err( p_dec, "Couldn't start the capture" );
         goto error_complete;
@@ -253,9 +357,9 @@ static int OpenDecoder( vlc_object_t *p_this )
     return VLC_SUCCESS;
 
 error_complete:
-    DtsCloseDecoder( p_sys->bcm_handle );
+    BC_FUNC_PSYS(DtsCloseDecoder)( p_sys->bcm_handle );
 error:
-    DtsDeviceClose( p_sys->bcm_handle );
+    BC_FUNC_PSYS(DtsDeviceClose)( p_sys->bcm_handle );
     free( p_sys );
     return VLC_EGENERIC;
 }
@@ -268,13 +372,13 @@ static void CloseDecoder( vlc_object_t *p_this )
     decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( DtsFlushInput( p_sys->bcm_handle, 2 ) != BC_STS_SUCCESS )
+    if( BC_FUNC_PSYS(DtsFlushInput)( p_sys->bcm_handle, 2 ) != BC_STS_SUCCESS )
         goto error;
-    if( DtsStopDecoder( p_sys->bcm_handle ) != BC_STS_SUCCESS )
+    if( BC_FUNC_PSYS(DtsStopDecoder)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
         goto error;
-    if( DtsCloseDecoder( p_sys->bcm_handle ) != BC_STS_SUCCESS )
+    if( BC_FUNC_PSYS(DtsCloseDecoder)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
         goto error;
-    if( DtsDeviceClose( p_sys->bcm_handle ) != BC_STS_SUCCESS )
+    if( BC_FUNC_PSYS(DtsDeviceClose)( p_sys->bcm_handle ) != BC_STS_SUCCESS )
         goto error;
 
 error:
@@ -285,6 +389,43 @@ error:
     free( p_sys );
 }
 
+static BC_STATUS ourCallback(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut)
+{
+    VLC_UNUSED(width); VLC_UNUSED(height); VLC_UNUSED(stride);
+
+    decoder_t *p_dec          = (decoder_t *)shnd;
+    BC_DTS_PROC_OUT *proc_out = p_dec->p_sys->proc_out;
+    BC_DTS_PROC_OUT *proc_in  = (BC_DTS_PROC_OUT*)pOut;
+
+    /* Direct Rendering */
+    /* Do not allocate for the second-field in the pair, in interlaced */
+    if( !(proc_in->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) ||
+        !(proc_in->PicInfo.flags & VDEC_FLAG_FIELDPAIR) )
+        p_dec->p_sys->p_pic = decoder_NewPicture( p_dec );
+
+    /* */
+    picture_t *p_pic = p_dec->p_sys->p_pic;
+    if( !p_pic )
+        return BC_STS_ERROR;
+
+    /* Interlacing */
+    p_pic->b_progressive     = !(proc_in->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC);
+    p_pic->b_top_field_first = !(proc_in->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
+    p_pic->i_nb_fields       = p_pic->b_progressive? 1: 2;
+
+    /* Filling out the struct */
+    proc_out->Ybuff      = !(proc_in->PicInfo.flags & VDEC_FLAG_FIELDPAIR) ?
+                             &p_pic->p[0].p_pixels[0] :
+                             &p_pic->p[0].p_pixels[p_pic->p[0].i_pitch];
+    proc_out->YbuffSz    = 2 * p_pic->p[0].i_pitch;
+    proc_out->StrideSz   = (proc_in->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC)?
+                            2 * (p_pic->p[0].i_pitch/2) - p_dec->fmt_out.video.i_width:
+                            p_pic->p[0].i_pitch/2 - p_dec->fmt_out.video.i_width;
+    proc_out->PoutFlags |= BC_POUT_FLAGS_STRIDE;              /* Trust Stride info */
+
+    return BC_STS_SUCCESS;
+}
+
 /****************************************************************************
  * DecodeBlock: the whole thing
  ****************************************************************************/
@@ -296,10 +437,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
     BC_DTS_PROC_OUT proc_out;
     BC_DTS_STATUS driver_stat;
 
-    picture_t *p_pic;
-
     /* First check the status of the decode to produce pictures */
-    if( DtsGetDriverStatus( p_sys->bcm_handle, &driver_stat ) != BC_STS_SUCCESS )
+    if( BC_FUNC_PSYS(DtsGetDriverStatus)( p_sys->bcm_handle, &driver_stat ) != BC_STS_SUCCESS )
         return NULL;
 
     p_block = *pp_block;
@@ -309,10 +448,10 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         {
             /* Valid input block, so we can send to HW to decode */
 
-            BC_STATUS status = DtsProcInput( p_sys->bcm_handle,
-                                             p_block->p_buffer,
-                                             p_block->i_buffer,
-                                             p_block->i_pts >= VLC_TS_INVALID ? TO_BC_PTS(p_block->i_pts) : 0, false );
+            BC_STATUS status = BC_FUNC_PSYS(DtsProcInput)( p_sys->bcm_handle,
+                                            p_block->p_buffer,
+                                            p_block->i_buffer,
+                                            p_block->i_pts >= VLC_TS_INVALID ? TO_BC_PTS(p_block->i_pts) : 0, false );
 
             block_Release( p_block );
             *pp_block = NULL;
@@ -337,23 +476,20 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
     memset( &proc_out, 0, sizeof(BC_DTS_PROC_OUT) );
     proc_out.PicInfo.width  = p_dec->fmt_out.video.i_width;
     proc_out.PicInfo.height = p_dec->fmt_out.video.i_height;
-    proc_out.YbuffSz        = p_dec->fmt_out.video.i_width * p_dec->fmt_out.video.i_height  / 2;
-    proc_out.Ybuff          = malloc( proc_out.YbuffSz  * 4);               // Allocate in bytes
-    proc_out.PoutFlags      = BC_POUT_FLAGS_SIZE;                           //FIXME why?
+    proc_out.PoutFlags      = BC_POUT_FLAGS_SIZE;
+    proc_out.AppCallBack    = ourCallback;
+    proc_out.hnd            = p_dec;
+    p_sys->proc_out         = &proc_out;
 
-#ifdef DEBUG_CRYSTALHD
-    msg_Dbg( p_dec, "%i, %i",  p_dec->fmt_out.video.i_width, p_dec->fmt_out.video.i_height );
-#endif
-    if( !proc_out.Ybuff )
-        return NULL;
-
-    BC_STATUS sts = DtsProcOutput( p_sys->bcm_handle, 128, &proc_out );
+    /* */
+    BC_STATUS sts = BC_FUNC_PSYS(DtsProcOutput)( p_sys->bcm_handle, 128, &proc_out );
 #ifdef DEBUG_CRYSTALHD
     if( sts != BC_STS_SUCCESS )
         msg_Err( p_dec, "DtsProcOutput returned %i", sts );
 #endif
 
     uint8_t b_eos;
+    picture_t *p_pic = p_sys->p_pic;
     switch( sts )
     {
         case BC_STS_SUCCESS:
@@ -363,17 +499,21 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
                 break;
             }
 
-            p_pic = decoder_NewPicture( p_dec );
             if( !p_pic )
                 break;
 
-            crystal_CopyPicture( p_pic, &proc_out );
-            p_pic->date = proc_out.PicInfo.timeStamp > 0 ? FROM_BC_PTS(proc_out.PicInfo.timeStamp) : VLC_TS_INVALID;
+            /* In interlaced mode, do not push the first field in the pipeline */
+            if( (proc_out.PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
+               !(proc_out.PicInfo.flags & VDEC_FLAG_FIELDPAIR) )
+                return NULL;
+
+            //  crystal_CopyPicture( p_pic, &proc_out );
+            p_pic->date = proc_out.PicInfo.timeStamp > 0 ?
+                          FROM_BC_PTS(proc_out.PicInfo.timeStamp) : VLC_TS_INVALID;
             //p_pic->date += 100 * 1000;
 #ifdef DEBUG_CRYSTALHD
             msg_Dbg( p_dec, "TS Output is %"PRIu64, p_pic->date);
 #endif
-            free( proc_out.Ybuff );
             return p_pic;
 
         case BC_STS_DEC_NOT_OPEN:
@@ -390,7 +530,10 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
                 break; */
             p_dec->fmt_out.video.i_width  = proc_out.PicInfo.width;
             p_dec->fmt_out.video.i_height = proc_out.PicInfo.height;
-#define setAR( a, b, c ) case a: p_dec->fmt_out.video.i_sar_num = b; p_dec->fmt_out.video.i_sar_den = c; break;
+            if( proc_out.PicInfo.height == 1088 )
+                p_dec->fmt_out.video.i_height = 1080;
+#define setAR( a, b, c ) case a: p_dec->fmt_out.video.i_sar_num = b; \
+                                 p_dec->fmt_out.video.i_sar_den = c; break;
             switch( proc_out.PicInfo.aspect_ratio )
             {
                 setAR( vdecAspectRatioSquare, 1, 1 )
@@ -414,12 +557,14 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 #undef setAR
             msg_Dbg( p_dec, "Format Change Detected [%i, %i], AR: %i/%i",
                     proc_out.PicInfo.width, proc_out.PicInfo.height,
-                    p_dec->fmt_out.video.i_sar_num, p_dec->fmt_out.video.i_sar_den );
+                    p_dec->fmt_out.video.i_sar_num,
+                    p_dec->fmt_out.video.i_sar_den );
             break;
 
         /* Nothing is documented here... */
         case BC_STS_NO_DATA:
-            if( DtsIsEndOfStream( p_sys->bcm_handle, &b_eos ) == BC_STS_SUCCESS )
+            if( BC_FUNC_PSYS(DtsIsEndOfStream)( p_sys->bcm_handle, &b_eos )
+                    == BC_STS_SUCCESS )
                 if( b_eos )
                     msg_Dbg( p_dec, "End of Stream" );
             break;
@@ -435,10 +580,12 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
             msg_Err( p_dec, "Unknown return status. Please report %i", sts );
             break;
     }
-    free( proc_out.Ybuff );
+    if( p_pic )
+        decoder_DeletePicture( p_dec, p_pic );
     return NULL;
 }
 
+#if 0
 /* Copy the data
  * FIXME: this should not exist */
 static void crystal_CopyPicture ( picture_t *p_pic, BC_DTS_PROC_OUT* p_out )
@@ -452,16 +599,17 @@ static void crystal_CopyPicture ( picture_t *p_pic, BC_DTS_PROC_OUT* p_out )
     p_dst_end     = p_dst  + (i_dst_stride * p_out->PicInfo.height);
 
     for( ; p_dst < p_dst_end; p_dst += i_dst_stride, p_src += (p_out->PicInfo.width * 2))
-        vlc_memcpy( p_dst, p_src, p_out->PicInfo.width * 2); // Copy in bytes
+        memcpy( p_dst, p_src, p_out->PicInfo.width * 2); // Copy in bytes
 }
+#endif
 
 /* Parse the SPS/PPS Metadata to feed the decoder for avc1 */
-static int crystal_insert_sps_pps(decoder_t *p_dec, uint8_t *p_buf, uint32_t i_buf_size)
+static int crystal_insert_sps_pps( decoder_t *p_dec,
+                                   uint8_t *p_buf,
+                                   uint32_t i_buf_size)
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    int i_profile;
-    uint32_t i_data_size = i_buf_size, i_nal_size;
-    unsigned int i_loop_end;
+    int ret;
 
     p_sys->i_sps_pps_size = 0;
 
@@ -469,63 +617,14 @@ static int crystal_insert_sps_pps(decoder_t *p_dec, uint8_t *p_buf, uint32_t i_b
     if( !p_sys->p_sps_pps_buf )
         return VLC_ENOMEM;
 
-    /* */
-    if( i_data_size < 7 )
-    {
-        msg_Err( p_dec, "Input Metadata too small" );
-        goto error;
-    }
-
-    /* Read infos in first 6 bytes */
-    i_profile         = (p_buf[1] << 16) | (p_buf[2] << 8) | p_buf[3];
-    p_sys->i_nal_size = (p_buf[4] & 0x03) + 1;
-    p_buf += 5;
-    i_data_size -= 5;
-
-    for ( unsigned int j = 0; j < 2; j++ )
-    {
-        /* First time is SPS, Second is PPS */
-        if (i_data_size < 1) {
-            msg_Err( p_dec, "PPS too small after processing SPS/PPS %u", i_data_size );
-            goto error;
-        }
-        i_loop_end = p_buf[0] & (j == 0 ? 0x1f : 0xff);
-        p_buf++; i_data_size--;
-
-        for ( unsigned int i = 0; i < i_loop_end; i++)
-        {
-            if (i_data_size < 2 ) {
-                msg_Err( p_dec, "SPS is too small %u", i_data_size );
-                goto error;
-            }
-
-            i_nal_size = (p_buf[0] << 8) | p_buf[1];
-            p_buf += 2;
-            i_data_size -= 2;
-
-            if (i_data_size < i_nal_size ) {
-                msg_Err( p_dec, "SPS size does not match NAL specified size %u", i_data_size );
-                goto error;
-            }
-
-            p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 0;
-            p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 0;
-            p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 0;
-            p_sys->p_sps_pps_buf[p_sys->i_sps_pps_size++] = 1;
-
-            memcpy(p_sys->p_sps_pps_buf + p_sys->i_sps_pps_size, p_buf, i_nal_size);
-            p_sys->i_sps_pps_size += i_nal_size;
-
-            p_buf += i_nal_size;
-            i_data_size -= i_nal_size;
-        }
-    }
-
-    return VLC_SUCCESS;
+    ret = convert_sps_pps( p_dec, p_buf, i_buf_size, p_sys->p_sps_pps_buf,
+                           p_dec->fmt_in.i_extra * 2, &p_sys->i_sps_pps_size,
+                           &p_sys->i_nal_size );
+    if( !ret )
+        return ret;
 
-error:
     free( p_sys->p_sps_pps_buf );
     p_sys->p_sps_pps_buf = NULL;
-    return VLC_ENOMEM;
+    return ret;
 }