sync to current internal FFMpeg code
authordavilla <davilla@4pi.com>
Sat, 5 Oct 2013 14:57:05 +0000 (10:57 -0400)
committerdavilla <davilla@4pi.com>
Sun, 6 Oct 2013 21:49:26 +0000 (17:49 -0400)
xbmc/utils/BitstreamConverter.cpp

index 5365caf..8b5f691 100644 (file)
@@ -582,43 +582,63 @@ bool CBitstreamConverter::BitstreamConvertInit(void *in_extradata, int in_extras
 
   uint16_t unit_size;
   uint32_t total_size = 0;
-  uint8_t *out = NULL, unit_nb, sps_done = 0;
+  uint8_t *out = NULL, unit_nb, sps_done = 0, sps_seen = 0, pps_seen = 0;
   const uint8_t *extradata = (uint8_t*)in_extradata + 4;
   static const uint8_t nalu_header[4] = {0, 0, 0, 1};
 
   // retrieve length coded size
   m_sps_pps_context.length_size = (*extradata++ & 0x3) + 1;
-  if (m_sps_pps_context.length_size == 3)
-    return false;
 
   // retrieve sps and pps unit(s)
   unit_nb = *extradata++ & 0x1f;  // number of sps unit(s)
   if (!unit_nb)
   {
-    unit_nb = *extradata++;       // number of pps unit(s)
-    sps_done++;
+    goto pps;
   }
+  else
+  {
+    sps_seen = 1;
+  }
+
   while (unit_nb--)
   {
+    void *tmp;
+
     unit_size = extradata[0] << 8 | extradata[1];
     total_size += unit_size + 4;
-    if ( (extradata + 2 + unit_size) > ((uint8_t*)in_extradata + in_extrasize) )
-    {
+
+    if (total_size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE ||
+      (extradata + 2 + unit_size) > ((uint8_t*)in_extradata + in_extrasize)) {
       m_dllAvUtil->av_free(out);
       return false;
     }
-    out = (uint8_t*)m_dllAvUtil->av_realloc(out, total_size);
-    if (!out)
-      return false;
-
+    tmp = m_dllAvUtil->av_realloc(out, total_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!tmp) {
+        m_dllAvUtil->av_free(out);
+        return false;
+    }
+    out = (uint8_t*)tmp;
     memcpy(out + total_size - unit_size - 4, nalu_header, 4);
     memcpy(out + total_size - unit_size, extradata + 2, unit_size);
     extradata += 2 + unit_size;
 
+pps:
     if (!unit_nb && !sps_done++)
-      unit_nb = *extradata++;     // number of pps unit(s)
+    {
+      unit_nb = *extradata++;   // number of pps unit(s)
+      if (unit_nb)
+        pps_seen = 1;
+    }
   }
 
+  if (out)
+    memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+  if (!sps_seen)
+      CLog::Log(LOGDEBUG, "SPS NALU missing or invalid. The resulting stream may not play");
+  if (!pps_seen)
+      CLog::Log(LOGDEBUG, "PPS NALU missing or invalid. The resulting stream may not play");
+
   m_sps_pps_context.sps_pps_data = out;
   m_sps_pps_context.size = total_size;
   m_sps_pps_context.first_idr = 1;
@@ -632,7 +652,7 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
   // which is Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr>
   // and Licensed GPL 2.1 or greater
 
-
+  int i;
   uint8_t *buf = pData;
   uint32_t buf_size = iSize;
   uint8_t  unit_type;
@@ -645,12 +665,8 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
     if (buf + m_sps_pps_context.length_size > buf_end)
       goto fail;
 
-    if (m_sps_pps_context.length_size == 1)
-      nal_size = buf[0];
-    else if (m_sps_pps_context.length_size == 2)
-      nal_size = buf[0] << 8 | buf[1];
-    else
-      nal_size = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
+    for (nal_size = 0, i = 0; i < m_sps_pps_context.length_size; i++)
+      nal_size = (nal_size << 8) | buf[i];
 
     buf += m_sps_pps_context.length_size;
     unit_type = *buf & 0x1f;
@@ -691,24 +707,22 @@ void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf
   // which is Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr>
   // and Licensed GPL 2.1 or greater
 
-  #define CHD_WB32(p, d) { \
-    ((uint8_t*)(p))[3] = (d); \
-    ((uint8_t*)(p))[2] = (d) >> 8; \
-    ((uint8_t*)(p))[1] = (d) >> 16; \
-    ((uint8_t*)(p))[0] = (d) >> 24; }
-
   uint32_t offset = *poutbuf_size;
   uint8_t nal_header_size = offset ? 3 : 4;
+  void *tmp;
 
   *poutbuf_size += sps_pps_size + in_size + nal_header_size;
-  *poutbuf = (uint8_t*)m_dllAvUtil->av_realloc(*poutbuf, *poutbuf_size);
+  tmp = m_dllAvUtil->av_realloc(*poutbuf, *poutbuf_size);
+  if (!tmp)
+    return;
+  *poutbuf = (uint8_t*)tmp;
   if (sps_pps)
     memcpy(*poutbuf + offset, sps_pps, sps_pps_size);
 
   memcpy(*poutbuf + sps_pps_size + nal_header_size + offset, in, in_size);
   if (!offset)
   {
-    CHD_WB32(*poutbuf + sps_pps_size, 1);
+    BS_WB32(*poutbuf + sps_pps_size, 1);
   }
   else
   {