vdr-plugin-softhddevice-drm-gles 1.4.0
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 "buf2rgb.h"
33
34/*****************************************************************************
35 * cH264Parser class
36 ****************************************************************************/
37
44{
45 m_pAvpkt = avpkt;
46}
47
52{
53}
54
61void cH264Parser::GetDimensions(int *width, int *height)
62{
63 m_pStart = NULL;
64 int i;
65
66 for (i = 0; i < m_pAvpkt->size; i++) {
67 if (!m_pAvpkt->data[i] && !m_pAvpkt->data[i + 1] && m_pAvpkt->data[i + 2] == 0x01 &&
68 (m_pAvpkt->data[i + 3] == 0x67 || m_pAvpkt->data[i + 3] == 0x27)) {
69
70 m_pStart = &m_pAvpkt->data[i + 4];
71 m_nLength = m_pAvpkt->size - i - 4;
72 break;
73 }
74 }
75 if (!m_pStart) {
76 LOGERROR("H264Parser: %s: No m_pStart %p Pkt %p i %d", __FUNCTION__, m_pStart, m_pAvpkt, i);
77// PrintStreamData(m_pAvpkt->data, m_pAvpkt->size);
78 return;
79 }
80
81 m_nCurrentBit = 0;
82 int frameCropLeftOffset = 0;
83 int frameCropRightOffset = 0;
84 int frameCropTopOffset = 0;
85 int frameCropBottomOffset = 0;
86 int chromaFormatIdc = 0;
87 int separateColorPlaneFlag = 0;
88
89 int profileIdc = ReadBits(8);
90 ReadBits(16);
92
93 if (profileIdc == 100 || profileIdc == 110 ||
94 profileIdc == 122 || profileIdc == 244 ||
95 profileIdc == 44 || profileIdc == 83 ||
96 profileIdc == 86 || profileIdc == 118) {
97
98 chromaFormatIdc = ReadExponentialGolombCode();
99 if (chromaFormatIdc == 3)
100 separateColorPlaneFlag = ReadBit();
103 ReadBit();
104 int seqScalingMatrixPresentFlag = ReadBit();
105 if (seqScalingMatrixPresentFlag) {
106 for (int i = 0; i < 8; i++) {
107 int seqScalingListPresentFlag = ReadBit();
108 if (seqScalingListPresentFlag) {
109 int sizeOfScalingList = (i < 6) ? 16 : 64;
110 int lastScale = 8;
111 int nextScale = 8;
112 for (int j = 0; j < sizeOfScalingList; j++) {
113 if (nextScale != 0) {
114 int delta_scale = ReadSE();
115 nextScale = (lastScale + delta_scale + 256) % 256;
116 }
117 lastScale = (nextScale == 0) ? lastScale : nextScale;
118 }
119 }
120 }
121 }
122 }
124 int picOrderCntType = ReadExponentialGolombCode();
125 if (picOrderCntType == 0) {
127 } else if (picOrderCntType == 1) {
128 ReadBit();
129 ReadSE();
130 ReadSE();
131 int numRefFramesInPicOrderCntCycle = ReadExponentialGolombCode();
132 for (int i = 0; i < numRefFramesInPicOrderCntCycle; i++ ) {
133 ReadSE();
134 }
135 }
137 ReadBit();
138 int picWidthInMbsMinusOne = ReadExponentialGolombCode();
139 int picHeightInMapUnitsMinusOne = ReadExponentialGolombCode();
140 int frameMbsOnlyFlag = ReadBit();
141 if (!frameMbsOnlyFlag) {
142 ReadBit();
143 }
144 ReadBit();
145 int frameCroppingFlag = ReadBit();
146 if (frameCroppingFlag) {
147 frameCropLeftOffset = ReadExponentialGolombCode();
148 frameCropRightOffset = ReadExponentialGolombCode();
149 frameCropTopOffset = ReadExponentialGolombCode();
150 frameCropBottomOffset = ReadExponentialGolombCode();
151 }
152
153 int subWidthC = 0;
154 int subHeightC = 0;
155
156 if (chromaFormatIdc == 0 && separateColorPlaneFlag == 0) { //monochrome
157 subWidthC = subHeightC = 2;
158 } else if (chromaFormatIdc == 1 && separateColorPlaneFlag == 0) { //4:2:0
159 subWidthC = subHeightC = 2;
160 } else if (chromaFormatIdc == 2 && separateColorPlaneFlag == 0) { //4:2:2
161 subWidthC = 2;
162 subHeightC = 1;
163 } else if (chromaFormatIdc == 3) { //4:4:4
164 if (separateColorPlaneFlag == 0) {
165 subWidthC = subHeightC = 1;
166 } else if (separateColorPlaneFlag == 1) {
167 subWidthC = subHeightC = 0;
168 }
169 }
170
171 *width = ((picWidthInMbsMinusOne + 1) * 16) -
172 subWidthC * (frameCropRightOffset + frameCropLeftOffset);
173
174 *height = ((2 - frameMbsOnlyFlag)* (picHeightInMapUnitsMinusOne +1) * 16) -
175 subHeightC * ((frameCropBottomOffset * 2) + (frameCropTopOffset * 2));
176}
177
178/*
179 * helper functions to parse resolution from stream
180 */
182{
183 assert(m_nCurrentBit <= m_nLength * 8);
184 int nIndex = m_nCurrentBit / 8;
185 int nOffset = m_nCurrentBit % 8 + 1;
186
188 return (m_pStart[nIndex] >> (8-nOffset)) & 0x01;
189}
190
191unsigned int cH264Parser::ReadBits(int n)
192{
193 int r = 0;
194
195 for (int i = 0; i < n; i++) {
196 r |= ( ReadBit() << ( n - i - 1 ) );
197 }
198 return r;
199}
200
202{
203 int r = 0;
204 int i = 0;
205
206 while((ReadBit() == 0) && (i < 32)) {
207 i++;
208 }
209
210 r = ReadBits(i);
211 r += (1 << i) - 1;
212 return r;
213}
214
216{
218
219 if (r & 0x01) {
220 r = (r+1)/2;
221 } else {
222 r = -(r/2);
223 }
224 return r;
225}
Some helper functions header file.
unsigned int ReadSE(void)
Definition: h264parser.cpp:215
unsigned int ReadBit(void)
Definition: h264parser.cpp:181
unsigned int ReadBits(int)
Definition: h264parser.cpp:191
unsigned short m_nLength
Definition: h264parser.h:39
virtual ~cH264Parser(void)
cH264Parser destructor
Definition: h264parser.cpp:51
const unsigned char * m_pStart
Definition: h264parser.h:38
void GetDimensions(int *, int *)
Get width and height from stream.
Definition: h264parser.cpp:61
int m_nCurrentBit
Definition: h264parser.h:40
AVPacket * m_pAvpkt
Definition: h264parser.h:37
unsigned int ReadExponentialGolombCode(void)
Definition: h264parser.cpp:201
cH264Parser(AVPacket *)
cH264Parser constructor
Definition: h264parser.cpp:43
H264 parser header file.
Logger class header file.
#define LOGERROR
Definition: logger.h:46