ref: da5f38c9a8a977f6313088b129e7980608f7863c
parent: 5d38e358408e070e884de57b2fbadb2fd87d625c
author: xiaotianshi2 <[email protected]>
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) {