shithub: openh264

Download patch

ref: da5f38c9a8a977f6313088b129e7980608f7863c
parent: 5d38e358408e070e884de57b2fbadb2fd87d625c
author: xiaotianshi2 <xiaotianshimail2@gmail.com>
date: Tue Jul 14 18:19:20 EDT 2020

update readPicture to make it to read one complete frame at a time for the support of thread-decoding of multi-slice frame.

--- a/codec/console/dec/src/h264dec.cpp
+++ b/codec/console/dec/src/h264dec.cpp
@@ -68,6 +68,40 @@
 #endif
 //using namespace WelsDec;
 
+int32_t readBit (uint8_t* pBufPtr, int32_t& curBit) {
+  int nIndex = curBit / 8;
+  int nOffset = curBit % 8 + 1;
+
+  curBit++;
+  return (pBufPtr[nIndex] >> (8 - nOffset)) & 0x01;
+}
+
+int32_t readBits (uint8_t* pBufPtr, int32_t& n, int32_t& curBit) {
+  int r = 0;
+  int i;
+  for (i = 0; i < n; i++) {
+    r |= (readBit (pBufPtr, curBit) << (n - i - 1));
+  }
+  return r;
+}
+
+int32_t bsGetUe (uint8_t* pBufPtr, int32_t& curBit) {
+  int r = 0;
+  int i = 0;
+  while ((readBit (pBufPtr, curBit) == 0) && (i < 32)) {
+    i++;
+  }
+  r = readBits (pBufPtr, i, curBit);
+  r += (1 << i) - 1;
+  return r;
+}
+
+int32_t readFirstMbInSlice (uint8_t* pSliceNalPtr) {
+  int32_t curBit = 0;
+  int32_t firstMBInSlice = bsGetUe (pSliceNalPtr + 1, curBit);
+  return firstMBInSlice;
+}
+
 int32_t readPicture (uint8_t* pBuf, const int32_t& iFileSize, const int32_t& bufPos, uint8_t*& pSpsBuf,
                      int32_t& sps_byte_count) {
   int32_t bytes_available = iFileSize - bufPos;
@@ -89,19 +123,22 @@
       has3ByteStartCode = ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 1;
     }
     if (has4ByteStartCode || has3ByteStartCode) {
+      int32_t byteOffset = has4ByteStartCode ? 4 : 3;
       uint8_t nal_unit_type = has4ByteStartCode ? (ptr[4] & 0x1F) : (ptr[3] & 0x1F);
       if (nal_unit_type == 1) {
-        if (++non_idr_pict_count == 1 && idr_pict_count == 1) {
+        int32_t firstMBInSlice = readFirstMbInSlice (ptr + byteOffset);
+        if (++non_idr_pict_count >= 1 && idr_pict_count >= 1 && firstMBInSlice == 0) {
           return read_bytes;
         }
-        if (non_idr_pict_count == 2) {
+        if (non_idr_pict_count >= 2 && firstMBInSlice == 0) {
           return read_bytes;
         }
       } else if (nal_unit_type == 5) {
-        if (++idr_pict_count == 1 && non_idr_pict_count == 1) {
+        int32_t firstMBInSlice = readFirstMbInSlice (ptr + byteOffset);
+        if (++idr_pict_count >= 1 && non_idr_pict_count >= 1 && firstMBInSlice == 0) {
           return read_bytes;
         }
-        if (idr_pict_count == 2) {
+        if (idr_pict_count >= 2 && firstMBInSlice == 0) {
           return read_bytes;
         }
       } else if (nal_unit_type == 7) {