ffmpeg / libavcodec / h264_parser.c @ 2912e87a
History | View | Annotate | Download (10.6 KB)
1 | 26b4fe82 | Aurelien Jacobs | /*
|
---|---|---|---|
2 | * H.26L/H.264/AVC/JVT/14496-10/... parser
|
||
3 | * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||
4 | *
|
||
5 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
6 | 26b4fe82 | Aurelien Jacobs | *
|
7 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
8 | 26b4fe82 | Aurelien Jacobs | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | * version 2.1 of the License, or (at your option) any later version.
|
||
11 | *
|
||
12 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
13 | 26b4fe82 | Aurelien Jacobs | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
15 | * Lesser General Public License for more details.
|
||
16 | *
|
||
17 | * You should have received a copy of the GNU Lesser General Public
|
||
18 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
19 | 26b4fe82 | Aurelien Jacobs | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | */
|
||
21 | |||
22 | /**
|
||
23 | ba87f080 | Diego Biurrun | * @file
|
24 | 26b4fe82 | Aurelien Jacobs | * H.264 / AVC / MPEG4 part10 parser.
|
25 | * @author Michael Niedermayer <michaelni@gmx.at>
|
||
26 | */
|
||
27 | |||
28 | #include "parser.h" |
||
29 | ff6474dd | Ivan Schreter | #include "h264data.h" |
30 | #include "golomb.h" |
||
31 | 26b4fe82 | Aurelien Jacobs | |
32 | #include <assert.h> |
||
33 | |||
34 | |||
35 | 13eb6b90 | Diego Elio Pettenò | static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size) |
36 | 26b4fe82 | Aurelien Jacobs | { |
37 | int i;
|
||
38 | uint32_t state; |
||
39 | ParseContext *pc = &(h->s.parse_context); |
||
40 | //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
|
||
41 | // mb_addr= pc->mb_addr - 1;
|
||
42 | state= pc->state; |
||
43 | if(state>13) |
||
44 | state= 7;
|
||
45 | |||
46 | for(i=0; i<buf_size; i++){ |
||
47 | if(state==7){ |
||
48 | b250f9c6 | Aurelien Jacobs | #if HAVE_FAST_UNALIGNED
|
49 | e4f1ec3a | Michael Niedermayer | /* we check i<buf_size instead of i+3/7 because its simpler
|
50 | * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end
|
||
51 | */
|
||
52 | b250f9c6 | Aurelien Jacobs | # if HAVE_FAST_64BIT
|
53 | 4d8eb2e8 | Ivan Schreter | while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL)) |
54 | 5cb5023c | Michael Niedermayer | i+=8;
|
55 | # else
|
||
56 | 4d8eb2e8 | Ivan Schreter | while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U)) |
57 | 5cb5023c | Michael Niedermayer | i+=4;
|
58 | # endif
|
||
59 | #endif
|
||
60 | 26b4fe82 | Aurelien Jacobs | for(; i<buf_size; i++){
|
61 | if(!buf[i]){
|
||
62 | state=2;
|
||
63 | break;
|
||
64 | } |
||
65 | } |
||
66 | }else if(state<=2){ |
||
67 | if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5 |
||
68 | else if(buf[i]) state = 7; |
||
69 | else state>>=1; //2->1, 1->0, 0->0 |
||
70 | }else if(state<=5){ |
||
71 | int v= buf[i] & 0x1F; |
||
72 | 9e85f9c5 | John Cox | if(v==6 || v==7 || v==8 || v==9){ |
73 | 26b4fe82 | Aurelien Jacobs | if(pc->frame_start_found){
|
74 | i++; |
||
75 | 9aa1cfec | Diego Pettenò | goto found;
|
76 | 26b4fe82 | Aurelien Jacobs | } |
77 | }else if(v==1 || v==2 || v==5){ |
||
78 | if(pc->frame_start_found){
|
||
79 | state+=8;
|
||
80 | continue;
|
||
81 | }else
|
||
82 | pc->frame_start_found = 1;
|
||
83 | } |
||
84 | state= 7;
|
||
85 | }else{
|
||
86 | if(buf[i] & 0x80) |
||
87 | goto found;
|
||
88 | state= 7;
|
||
89 | } |
||
90 | } |
||
91 | pc->state= state; |
||
92 | return END_NOT_FOUND;
|
||
93 | 9aa1cfec | Diego Pettenò | |
94 | found:
|
||
95 | pc->state=7;
|
||
96 | pc->frame_start_found= 0;
|
||
97 | return i-(state&5); |
||
98 | 26b4fe82 | Aurelien Jacobs | } |
99 | |||
100 | ff6474dd | Ivan Schreter | /*!
|
101 | * Parse NAL units of found picture and decode some basic information.
|
||
102 | *
|
||
103 | * @param s parser context.
|
||
104 | * @param avctx codec context.
|
||
105 | * @param buf buffer with field/frame data.
|
||
106 | * @param buf_size size of the buffer.
|
||
107 | */
|
||
108 | static inline int parse_nal_units(AVCodecParserContext *s, |
||
109 | AVCodecContext *avctx, |
||
110 | const uint8_t *buf, int buf_size) |
||
111 | { |
||
112 | H264Context *h = s->priv_data; |
||
113 | const uint8_t *buf_end = buf + buf_size;
|
||
114 | 96c3da93 | Ivan Schreter | unsigned int pps_id; |
115 | ff6474dd | Ivan Schreter | unsigned int slice_type; |
116 | 8fa0ae06 | Baptiste Coudurier | int state = -1; |
117 | ff6474dd | Ivan Schreter | const uint8_t *ptr;
|
118 | |||
119 | /* set some sane default values */
|
||
120 | s->pict_type = FF_I_TYPE; |
||
121 | 0ed260c7 | Ivan Schreter | s->key_frame = 0;
|
122 | ff6474dd | Ivan Schreter | |
123 | h->s.avctx= avctx; |
||
124 | 0ed260c7 | Ivan Schreter | h->sei_recovery_frame_cnt = -1;
|
125 | c733922e | Ivan Schreter | h->sei_dpb_output_delay = 0;
|
126 | h->sei_cpb_removal_delay = -1;
|
||
127 | h->sei_buffering_period_present = 0;
|
||
128 | ff6474dd | Ivan Schreter | |
129 | 9479415e | Baptiste Coudurier | if (!buf_size)
|
130 | return 0; |
||
131 | |||
132 | ff6474dd | Ivan Schreter | for(;;) {
|
133 | int src_length, dst_length, consumed;
|
||
134 | buf = ff_find_start_code(buf, buf_end, &state); |
||
135 | if(buf >= buf_end)
|
||
136 | break;
|
||
137 | --buf; |
||
138 | src_length = buf_end - buf; |
||
139 | switch (state & 0x1f) { |
||
140 | case NAL_SLICE:
|
||
141 | case NAL_IDR_SLICE:
|
||
142 | // Do not walk the whole buffer just to decode slice header
|
||
143 | if (src_length > 20) |
||
144 | src_length = 20;
|
||
145 | break;
|
||
146 | } |
||
147 | ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); |
||
148 | if (ptr==NULL || dst_length < 0) |
||
149 | break;
|
||
150 | |||
151 | init_get_bits(&h->s.gb, ptr, 8*dst_length);
|
||
152 | switch(h->nal_unit_type) {
|
||
153 | case NAL_SPS:
|
||
154 | ff_h264_decode_seq_parameter_set(h); |
||
155 | break;
|
||
156 | case NAL_PPS:
|
||
157 | ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits); |
||
158 | break;
|
||
159 | case NAL_SEI:
|
||
160 | ff_h264_decode_sei(h); |
||
161 | break;
|
||
162 | case NAL_IDR_SLICE:
|
||
163 | 0ed260c7 | Ivan Schreter | s->key_frame = 1;
|
164 | /* fall through */
|
||
165 | ff6474dd | Ivan Schreter | case NAL_SLICE:
|
166 | get_ue_golomb(&h->s.gb); // skip first_mb_in_slice
|
||
167 | slice_type = get_ue_golomb_31(&h->s.gb); |
||
168 | s->pict_type = golomb_to_pict_type[slice_type % 5];
|
||
169 | 0ed260c7 | Ivan Schreter | if (h->sei_recovery_frame_cnt >= 0) { |
170 | /* key frame, since recovery_frame_cnt is set */
|
||
171 | s->key_frame = 1;
|
||
172 | } |
||
173 | 96c3da93 | Ivan Schreter | pps_id= get_ue_golomb(&h->s.gb); |
174 | if(pps_id>=MAX_PPS_COUNT) {
|
||
175 | av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
|
||
176 | return -1; |
||
177 | } |
||
178 | if(!h->pps_buffers[pps_id]) {
|
||
179 | av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
|
||
180 | return -1; |
||
181 | } |
||
182 | h->pps= *h->pps_buffers[pps_id]; |
||
183 | if(!h->sps_buffers[h->pps.sps_id]) {
|
||
184 | av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
|
||
185 | return -1; |
||
186 | } |
||
187 | h->sps = *h->sps_buffers[h->pps.sps_id]; |
||
188 | h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num); |
||
189 | |||
190 | fe9a3fbe | Janne Grunau | avctx->profile = ff_h264_get_profile(&h->sps); |
191 | dd0cd3d2 | Rafaël Carré | avctx->level = h->sps.level_idc; |
192 | |||
193 | 96c3da93 | Ivan Schreter | if(h->sps.frame_mbs_only_flag){
|
194 | h->s.picture_structure= PICT_FRAME; |
||
195 | }else{
|
||
196 | if(get_bits1(&h->s.gb)) { //field_pic_flag |
||
197 | h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag
|
||
198 | } else {
|
||
199 | h->s.picture_structure= PICT_FRAME; |
||
200 | } |
||
201 | } |
||
202 | |||
203 | 346db3ef | Ivan Schreter | if(h->sps.pic_struct_present_flag) {
|
204 | switch (h->sei_pic_struct) {
|
||
205 | case SEI_PIC_STRUCT_TOP_FIELD:
|
||
206 | case SEI_PIC_STRUCT_BOTTOM_FIELD:
|
||
207 | fc9fe428 | Ivan Schreter | s->repeat_pict = 0;
|
208 | 346db3ef | Ivan Schreter | break;
|
209 | case SEI_PIC_STRUCT_FRAME:
|
||
210 | case SEI_PIC_STRUCT_TOP_BOTTOM:
|
||
211 | case SEI_PIC_STRUCT_BOTTOM_TOP:
|
||
212 | fc9fe428 | Ivan Schreter | s->repeat_pict = 1;
|
213 | 346db3ef | Ivan Schreter | break;
|
214 | case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
|
||
215 | case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
|
||
216 | fc9fe428 | Ivan Schreter | s->repeat_pict = 2;
|
217 | 346db3ef | Ivan Schreter | break;
|
218 | case SEI_PIC_STRUCT_FRAME_DOUBLING:
|
||
219 | fc9fe428 | Ivan Schreter | s->repeat_pict = 3;
|
220 | 346db3ef | Ivan Schreter | break;
|
221 | case SEI_PIC_STRUCT_FRAME_TRIPLING:
|
||
222 | fc9fe428 | Ivan Schreter | s->repeat_pict = 5;
|
223 | 346db3ef | Ivan Schreter | break;
|
224 | default:
|
||
225 | fc9fe428 | Ivan Schreter | s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; |
226 | 346db3ef | Ivan Schreter | break;
|
227 | } |
||
228 | } else {
|
||
229 | fc9fe428 | Ivan Schreter | s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; |
230 | 346db3ef | Ivan Schreter | } |
231 | |||
232 | ff6474dd | Ivan Schreter | return 0; /* no need to evaluate the rest */ |
233 | } |
||
234 | buf += consumed; |
||
235 | } |
||
236 | /* didn't find a picture! */
|
||
237 | av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
|
||
238 | return -1; |
||
239 | } |
||
240 | |||
241 | 26b4fe82 | Aurelien Jacobs | static int h264_parse(AVCodecParserContext *s, |
242 | AVCodecContext *avctx, |
||
243 | const uint8_t **poutbuf, int *poutbuf_size, |
||
244 | const uint8_t *buf, int buf_size) |
||
245 | { |
||
246 | H264Context *h = s->priv_data; |
||
247 | ParseContext *pc = &h->s.parse_context; |
||
248 | int next;
|
||
249 | |||
250 | 82f1ffc7 | Howard Chu | if (!h->got_first) {
|
251 | h->got_first = 1;
|
||
252 | 23584bec | Howard Chu | if (avctx->extradata_size) {
|
253 | h->s.avctx = avctx; |
||
254 | ff_h264_decode_extradata(h); |
||
255 | } |
||
256 | } |
||
257 | |||
258 | 26b4fe82 | Aurelien Jacobs | if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
|
259 | next= buf_size; |
||
260 | }else{
|
||
261 | next= ff_h264_find_frame_end(h, buf, buf_size); |
||
262 | |||
263 | if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { |
||
264 | *poutbuf = NULL;
|
||
265 | *poutbuf_size = 0;
|
||
266 | return buf_size;
|
||
267 | } |
||
268 | |||
269 | if(next<0 && next != END_NOT_FOUND){ |
||
270 | assert(pc->last_index + next >= 0 );
|
||
271 | ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
|
||
272 | } |
||
273 | ff6474dd | Ivan Schreter | |
274 | parse_nal_units(s, avctx, buf, buf_size); |
||
275 | c733922e | Ivan Schreter | |
276 | 2c0c5e12 | Ivan Schreter | if (h->sei_cpb_removal_delay >= 0) { |
277 | 26aedb4a | Carl Eugen Hoyos | s->dts_sync_point = h->sei_buffering_period_present; |
278 | s->dts_ref_dts_delta = h->sei_cpb_removal_delay; |
||
279 | s->pts_dts_delta = h->sei_dpb_output_delay; |
||
280 | 2c0c5e12 | Ivan Schreter | } else {
|
281 | s->dts_sync_point = INT_MIN; |
||
282 | s->dts_ref_dts_delta = INT_MIN; |
||
283 | s->pts_dts_delta = INT_MIN; |
||
284 | } |
||
285 | 74a6df59 | Alex Converse | if (s->flags & PARSER_FLAG_ONCE) {
|
286 | s->flags &= PARSER_FLAG_COMPLETE_FRAMES; |
||
287 | } |
||
288 | 26b4fe82 | Aurelien Jacobs | } |
289 | |||
290 | *poutbuf = buf; |
||
291 | *poutbuf_size = buf_size; |
||
292 | return next;
|
||
293 | } |
||
294 | |||
295 | static int h264_split(AVCodecContext *avctx, |
||
296 | const uint8_t *buf, int buf_size) |
||
297 | { |
||
298 | int i;
|
||
299 | uint32_t state = -1;
|
||
300 | int has_sps= 0; |
||
301 | |||
302 | for(i=0; i<=buf_size; i++){ |
||
303 | if((state&0xFFFFFF1F) == 0x107) |
||
304 | has_sps=1;
|
||
305 | /* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
|
||
306 | }*/
|
||
307 | if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){ |
||
308 | if(has_sps){
|
||
309 | while(i>4 && buf[i-5]==0) i--; |
||
310 | return i-4; |
||
311 | } |
||
312 | } |
||
313 | if (i<buf_size)
|
||
314 | state= (state<<8) | buf[i];
|
||
315 | } |
||
316 | return 0; |
||
317 | } |
||
318 | |||
319 | dd990075 | Michael Niedermayer | static void close(AVCodecParserContext *s) |
320 | 3ee4f5e4 | Michael Niedermayer | { |
321 | H264Context *h = s->priv_data; |
||
322 | ParseContext *pc = &h->s.parse_context; |
||
323 | |||
324 | av_free(pc->buffer); |
||
325 | 15861962 | Reimar Döffinger | ff_h264_free_context(h); |
326 | 3ee4f5e4 | Michael Niedermayer | } |
327 | |||
328 | e9ca315d | Rafaël Carré | static int init(AVCodecParserContext *s) |
329 | { |
||
330 | H264Context *h = s->priv_data; |
||
331 | h->thread_context[0] = h;
|
||
332 | return 0; |
||
333 | } |
||
334 | 26b4fe82 | Aurelien Jacobs | |
335 | d36beb3f | Diego Elio Pettenò | AVCodecParser ff_h264_parser = { |
336 | 0d3d172f | Carl Eugen Hoyos | { CODEC_ID_H264 }, |
337 | 26b4fe82 | Aurelien Jacobs | sizeof(H264Context),
|
338 | e9ca315d | Rafaël Carré | init, |
339 | 26b4fe82 | Aurelien Jacobs | h264_parse, |
340 | 3ee4f5e4 | Michael Niedermayer | close, |
341 | 26b4fe82 | Aurelien Jacobs | h264_split, |
342 | }; |