vdr-plugin-softhddevice-drm-gles 1.5.9-20e15de
h264parser.cpp
Go to the documentation of this file.
1
24#include <cassert>
25
26extern "C" {
27#include <libavcodec/avcodec.h>
28}
29
30#include "h264parser.h"
31#include "logger.h"
32#include "misc.h"
33
34/*****************************************************************************
35 * cH264Parser class
36 ****************************************************************************/
37
44static void PrintStreamData(const uint8_t *data, int size)
45{
46 LOGDEBUG("Stream: %02x %02x %02x %02x %02x %02x %02x %02x %02x "
47 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
48 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x size %d",
49 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8],
50 data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17],
51 data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26],
52 data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], size);
53}
54
59bool isValidStartCode(const uint8_t *data, int offset)
60{
61 return ReadBytes(&data[offset], 3) == 0x000001;
62}
63
67static int NalUnitType(const uint8_t *data, int i)
68{
69 return data[i + 3] & 0x1F;
70}
71
78 : m_pAvpkt(avpkt)
79{
80 int i;
81
82 // part 1: collect the nalu types in the packet
83 for (i = 0; i < m_pAvpkt->size - 3; i++) {
84 if (!isValidStartCode(m_pAvpkt->data, i))
85 continue;
86
87 switch (NalUnitType(m_pAvpkt->data, i)) {
88 case 1:
90 break;
91 case 5:
93 break;
94 case 6:
96 break;
97 case 7:
99 break;
100 case 8:
102 break;
103 case 9:
105 break;
106 default:
107 break;
108 }
109 }
110
111 // part 2: parse h264 SPS and get width and height
112 m_pStart = NULL;
113 for (i = 0; i < m_pAvpkt->size - 4; i++) {
114 if (!isValidStartCode(m_pAvpkt->data, i))
115 continue;
116
117 if (NalUnitType(m_pAvpkt->data, i) == 7) {
118 m_pStart = &m_pAvpkt->data[i + 4];
119 m_nLength = m_pAvpkt->size - i - 4;
120 break;
121 }
122 }
123
124 // no SPS available
125 if (!m_pStart) {
126 LOGERROR("H264Parser: %s: No m_pStart %p Pkt %p i %d", __FUNCTION__, m_pStart, m_pAvpkt, i);
127 PrintStreamData(m_pAvpkt->data, m_pAvpkt->size);
128 return;
129 }
130
131 m_nCurrentBit = 0;
132 int frameCropLeftOffset = 0;
133 int frameCropRightOffset = 0;
134 int frameCropTopOffset = 0;
135 int frameCropBottomOffset = 0;
136 int chromaFormatIdc = 0;
137 int separateColorPlaneFlag = 0;
138
139 int profileIdc = ReadBits(8);
140 ReadBits(16);
142
143 if (profileIdc == 100 || profileIdc == 110 ||
144 profileIdc == 122 || profileIdc == 244 ||
145 profileIdc == 44 || profileIdc == 83 ||
146 profileIdc == 86 || profileIdc == 118) {
147
148 chromaFormatIdc = ReadExponentialGolombCode();
149 if (chromaFormatIdc == 3)
150 separateColorPlaneFlag = ReadBit();
153 ReadBit();
154 int seqScalingMatrixPresentFlag = ReadBit();
155 if (seqScalingMatrixPresentFlag) {
156 for (int i = 0; i < 8; i++) {
157 int seqScalingListPresentFlag = ReadBit();
158 if (seqScalingListPresentFlag) {
159 int sizeOfScalingList = (i < 6) ? 16 : 64;
160 int lastScale = 8;
161 int nextScale = 8;
162 for (int j = 0; j < sizeOfScalingList; j++) {
163 if (nextScale != 0) {
164 int delta_scale = ReadSE();
165 nextScale = (lastScale + delta_scale + 256) % 256;
166 }
167 lastScale = (nextScale == 0) ? lastScale : nextScale;
168 }
169 }
170 }
171 }
172 }
174 int picOrderCntType = ReadExponentialGolombCode();
175 if (picOrderCntType == 0) {
177 } else if (picOrderCntType == 1) {
178 ReadBit();
179 ReadSE();
180 ReadSE();
181 int numRefFramesInPicOrderCntCycle = ReadExponentialGolombCode();
182 for (int i = 0; i < numRefFramesInPicOrderCntCycle; i++ ) {
183 ReadSE();
184 }
185 }
187 ReadBit();
188 int picWidthInMbsMinusOne = ReadExponentialGolombCode();
189 int picHeightInMapUnitsMinusOne = ReadExponentialGolombCode();
190 int frameMbsOnlyFlag = ReadBit();
191 if (!frameMbsOnlyFlag) {
192 m_mbaff = ReadBit();
193 }
194
195 ReadBit();
196 int frameCroppingFlag = ReadBit();
197 if (frameCroppingFlag) {
198 frameCropLeftOffset = ReadExponentialGolombCode();
199 frameCropRightOffset = ReadExponentialGolombCode();
200 frameCropTopOffset = ReadExponentialGolombCode();
201 frameCropBottomOffset = ReadExponentialGolombCode();
202 }
203
204 int subWidthC = 0;
205 int subHeightC = 0;
206
207 if (chromaFormatIdc == 0 && separateColorPlaneFlag == 0) { // monochrome
208 subWidthC = subHeightC = 2;
209 } else if (chromaFormatIdc == 1 && separateColorPlaneFlag == 0) { // 4:2:0
210 subWidthC = subHeightC = 2;
211 } else if (chromaFormatIdc == 2 && separateColorPlaneFlag == 0) { // 4:2:2
212 subWidthC = 2;
213 subHeightC = 1;
214 } else if (chromaFormatIdc == 3) { // 4:4:4
215 if (separateColorPlaneFlag == 0) {
216 subWidthC = subHeightC = 1;
217 } else if (separateColorPlaneFlag == 1) {
218 subWidthC = subHeightC = 0;
219 }
220 }
221
222 m_width = ((picWidthInMbsMinusOne + 1) * 16) -
223 subWidthC * (frameCropRightOffset + frameCropLeftOffset);
224
225 m_height = ((2 - frameMbsOnlyFlag)* (picHeightInMapUnitsMinusOne +1) * 16) -
226 subHeightC * ((frameCropBottomOffset * 2) + (frameCropTopOffset * 2));
227
228 LOGDEBUG2(L_CODEC, "H264Parser: %s %s%s%s%s%s%s width %d height %d", __FUNCTION__,
229 m_nalutype & NALU_TYPE_AUD ? "AUD " : "",
230 m_nalutype & NALU_TYPE_SPS ? "SPS " : "",
231 m_nalutype & NALU_TYPE_PPS ? "PPS " : "",
232 m_nalutype & NALU_TYPE_SEI ? "SEI " : "",
233 m_nalutype & NALU_TYPE_IDR ? "IDR " : "",
234 m_nalutype & NALU_TYPE_NON_IDR ? "NON-IDR " : "",
236}
237
238/*
239 * Does the parser frame include an I-Frame?
240 */
246
247/*
248 * helper functions to parse resolution from stream
249 */
251{
252 assert(m_nCurrentBit <= m_nLength * 8);
253 int nIndex = m_nCurrentBit / 8;
254 int nOffset = m_nCurrentBit % 8 + 1;
255
257 return (m_pStart[nIndex] >> (8-nOffset)) & 0x01;
258}
259
260unsigned int cH264Parser::ReadBits(int n)
261{
262 int r = 0;
263
264 for (int i = 0; i < n; i++) {
265 r |= ( ReadBit() << ( n - i - 1 ) );
266 }
267 return r;
268}
269
271{
272 int r = 0;
273 int i = 0;
274
275 while((ReadBit() == 0) && (i < 32)) {
276 i++;
277 }
278
279 r = ReadBits(i);
280 r += (1 << i) - 1;
281 return r;
282}
283
285{
287
288 if (r & 0x01) {
289 r = (r+1)/2;
290 } else {
291 r = -(r/2);
292 }
293 return r;
294}
unsigned int ReadSE(void)
unsigned int ReadBit(void)
unsigned int ReadBits(int)
bool IsIFrame(void)
unsigned short m_nLength
Definition h264parser.h:51
const unsigned char * m_pStart
Definition h264parser.h:50
int m_nCurrentBit
Definition h264parser.h:52
AVPacket * m_pAvpkt
Definition h264parser.h:49
unsigned int ReadExponentialGolombCode(void)
cH264Parser(AVPacket *)
Init the h264 parser and detect the nalu types.
static void PrintStreamData(const uint8_t *data, int size)
Print raw stream data.
bool isValidStartCode(const uint8_t *data, int offset)
Returns true, if we have a 0x000001 start code in data at the offset position.
static int NalUnitType(const uint8_t *data, int i)
Return the nal unit type.
H264 parser header file.
@ NALU_TYPE_NON_IDR
Definition h264parser.h:28
@ NALU_TYPE_AUD
Definition h264parser.h:33
@ NALU_TYPE_SEI
Definition h264parser.h:30
@ NALU_TYPE_PPS
Definition h264parser.h:32
@ NALU_TYPE_SPS
Definition h264parser.h:31
@ NALU_TYPE_IDR
Definition h264parser.h:29
Logger class header file.
#define LOGDEBUG2
Definition logger.h:45
#define LOGDEBUG
Definition logger.h:44
#define LOGERROR
Definition logger.h:41
#define L_CODEC
Definition logger.h:58
Misc function header file.
static uint32_t ReadBytes(const uint8_t *data, int count)
Return count amount of bytes from data.
Definition misc.h:141