[omxplayer] fixed playback of h264 streams with 00 00 00 01 starcodes
authorgimli <ebsi4711@gmail.com>
Thu, 18 Oct 2012 15:38:07 +0000 (17:38 +0200)
committergimli <ebsi4711@gmail.com>
Thu, 18 Oct 2012 15:38:07 +0000 (17:38 +0200)
xbmc/cores/omxplayer/OMXVideo.cpp
xbmc/cores/omxplayer/OMXVideo.h

index 1be51b6..7889964 100644 (file)
@@ -128,6 +128,21 @@ bool COMXVideo::SendDecoderConfig()
   return true;
 }
 
+bool COMXVideo::NaluFormatStartCodes(enum CodecID codec, uint8_t *in_extradata, int in_extrasize)
+{
+  switch(codec)
+  {
+    case CODEC_ID_H264:
+      if (in_extrasize < 7 || in_extradata == NULL)
+        return true;
+      // valid avcC atom data always starts with the value 1 (version), otherwise annexb
+      else if ( *in_extradata != 1 )
+        return true;
+    default: break;
+  }
+  return false;    
+}
+
 bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, bool hdmi_clock_sync)
 {
   if(m_is_open)
@@ -147,28 +162,16 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b
   if(!m_decoded_width || !m_decoded_height)
     return false;
 
-  m_converter     = new CBitstreamConverter();
-  m_video_convert = m_converter->Open(hints.codec, (uint8_t *)hints.extradata, hints.extrasize, false);
-
-  if(m_video_convert)
-  {
-    if(m_converter->GetExtraData() != NULL && m_converter->GetExtraSize() > 0)
-    {
-      m_extrasize = m_converter->GetExtraSize();
-      m_extradata = (uint8_t *)malloc(m_extrasize);
-      memcpy(m_extradata, m_converter->GetExtraData(), m_converter->GetExtraSize());
-    }
-  }
-  else
+  if(hints.extrasize > 0 && hints.extradata != NULL)
   {
-    if(hints.extrasize > 0 && hints.extradata != NULL)
-    {
-      m_extrasize = hints.extrasize;
-      m_extradata = (uint8_t *)malloc(m_extrasize);
-      memcpy(m_extradata, hints.extradata, hints.extrasize);
-    }
+    m_extrasize = hints.extrasize;
+    m_extradata = (uint8_t *)malloc(m_extrasize);
+    memcpy(m_extradata, hints.extradata, hints.extrasize);
   }
 
+  m_converter     = new CBitstreamConverter();
+  m_video_convert = m_converter->Open(hints.codec, (uint8_t *)hints.extradata, hints.extrasize, false);
+
   switch (hints.codec)
   {
     case CODEC_ID_H264:
@@ -209,11 +212,10 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b
       }
 
       /* check interlaced */
-      uint8_t *extradata = (uint8_t *)hints.extradata;
-      if(hints.extrasize > 9 && extradata[0] == 1)
+      if(m_extrasize > 9 && m_extradata[0] == 1)
       {
         int32_t  max_ref_frames = 0;
-        uint8_t  *spc = extradata + 6;
+        uint8_t  *spc = m_extradata + 6;
         uint32_t sps_size = BS_RB16(spc);
         bool     interlaced = true;
         if (sps_size)
@@ -418,6 +420,21 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b
     return false;
   }
 
+  if(NaluFormatStartCodes(hints.codec, m_extradata, m_extrasize))
+  {
+    OMX_NALSTREAMFORMATTYPE nalStreamFormat;
+    OMX_INIT_STRUCTURE(nalStreamFormat);
+    nalStreamFormat.nPortIndex = m_omx_decoder.GetInputPort();
+    nalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodes;
+
+    omx_err = m_omx_decoder.SetParameter((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, &nalStreamFormat);
+    if (omx_err != OMX_ErrorNone)
+    {
+      CLog::Log(LOGERROR, "COMXVideo::Open OMX_IndexParamNalStreamFormatSelect error (0%08x)\n", omx_err);
+      return false;
+    }
+  }
+
   if(m_hdmi_clock_sync)
   {
     OMX_CONFIG_LATENCYTARGETTYPE latencyTarget;
index b2d4b5f..87efc36 100644 (file)
@@ -92,6 +92,8 @@ protected:
   bool              m_deinterlace;
   bool              m_hdmi_clock_sync;
   bool              m_first_frame;
+
+  bool NaluFormatStartCodes(enum CodecID codec, uint8_t *in_extradata, int in_extrasize);
 };
 
 #endif