annotate h264_parser.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents cabcd751b1e5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
1 /*
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
2 * H.26L/H.264/AVC/JVT/14496-10/... parser
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
4 *
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
5 * This file is part of FFmpeg.
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
6 *
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
11 *
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
15 * Lesser General Public License for more details.
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
16 *
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
20 */
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
21
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
22 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 11047
diff changeset
23 * @file
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
24 * H.264 / AVC / MPEG4 part10 parser.
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
25 * @author Michael Niedermayer <michaelni@gmx.at>
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
26 */
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
27
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
28 #include "parser.h"
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
29 #include "h264_parser.h"
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
30 #include "h264data.h"
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
31 #include "golomb.h"
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
32
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
33 #include <assert.h>
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
34
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
35
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
36 int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
37 {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
38 int i;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
39 uint32_t state;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
40 ParseContext *pc = &(h->s.parse_context);
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
41 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
42 // mb_addr= pc->mb_addr - 1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
43 state= pc->state;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
44 if(state>13)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
45 state= 7;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
46
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
47 for(i=0; i<buf_size; i++){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
48 if(state==7){
8590
7a463923ecd1 Change semantic of CONFIG_*, HAVE_* and ARCH_*.
aurel
parents: 8522
diff changeset
49 #if HAVE_FAST_UNALIGNED
8503
7c82ed8d4824 Explain the lack of +3/7
michael
parents: 8442
diff changeset
50 /* we check i<buf_size instead of i+3/7 because its simpler
7c82ed8d4824 Explain the lack of +3/7
michael
parents: 8442
diff changeset
51 * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end
7c82ed8d4824 Explain the lack of +3/7
michael
parents: 8442
diff changeset
52 */
8590
7a463923ecd1 Change semantic of CONFIG_*, HAVE_* and ARCH_*.
aurel
parents: 8522
diff changeset
53 # if HAVE_FAST_64BIT
8763
8551f8149146 Fix a const related warning
superdump
parents: 8718
diff changeset
54 while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
8442
60be1c7d8345 Make h264 parser 50% faster.
michael
parents: 7991
diff changeset
55 i+=8;
60be1c7d8345 Make h264 parser 50% faster.
michael
parents: 7991
diff changeset
56 # else
8763
8551f8149146 Fix a const related warning
superdump
parents: 8718
diff changeset
57 while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
8442
60be1c7d8345 Make h264 parser 50% faster.
michael
parents: 7991
diff changeset
58 i+=4;
60be1c7d8345 Make h264 parser 50% faster.
michael
parents: 7991
diff changeset
59 # endif
60be1c7d8345 Make h264 parser 50% faster.
michael
parents: 7991
diff changeset
60 #endif
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
61 for(; i<buf_size; i++){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
62 if(!buf[i]){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
63 state=2;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
64 break;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
65 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
66 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
67 }else if(state<=2){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
68 if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
69 else if(buf[i]) state = 7;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
70 else state>>=1; //2->1, 1->0, 0->0
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
71 }else if(state<=5){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
72 int v= buf[i] & 0x1F;
9180
6fdc4c276ef1 Fix SEIs when splitting H264 input.
cehoyos
parents: 9057
diff changeset
73 if(v==6 || v==7 || v==8 || v==9){
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
74 if(pc->frame_start_found){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
75 i++;
7986
38d577c3cb60 fix warning reported by Intel C compiler:
gpoirier
parents: 5215
diff changeset
76 goto found;
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
77 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
78 }else if(v==1 || v==2 || v==5){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
79 if(pc->frame_start_found){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
80 state+=8;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
81 continue;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
82 }else
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
83 pc->frame_start_found = 1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
84 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
85 state= 7;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
86 }else{
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
87 if(buf[i] & 0x80)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
88 goto found;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
89 state= 7;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
90 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
91 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
92 pc->state= state;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
93 return END_NOT_FOUND;
7986
38d577c3cb60 fix warning reported by Intel C compiler:
gpoirier
parents: 5215
diff changeset
94
38d577c3cb60 fix warning reported by Intel C compiler:
gpoirier
parents: 5215
diff changeset
95 found:
38d577c3cb60 fix warning reported by Intel C compiler:
gpoirier
parents: 5215
diff changeset
96 pc->state=7;
38d577c3cb60 fix warning reported by Intel C compiler:
gpoirier
parents: 5215
diff changeset
97 pc->frame_start_found= 0;
38d577c3cb60 fix warning reported by Intel C compiler:
gpoirier
parents: 5215
diff changeset
98 return i-(state&5);
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
99 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
100
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
101 /*!
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
102 * Parse NAL units of found picture and decode some basic information.
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
103 *
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
104 * @param s parser context.
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
105 * @param avctx codec context.
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
106 * @param buf buffer with field/frame data.
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
107 * @param buf_size size of the buffer.
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
108 */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
109 static inline int parse_nal_units(AVCodecParserContext *s,
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
110 AVCodecContext *avctx,
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
111 const uint8_t *buf, int buf_size)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
112 {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
113 H264Context *h = s->priv_data;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
114 const uint8_t *buf_end = buf + buf_size;
8999
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
115 unsigned int pps_id;
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
116 unsigned int slice_type;
9424
cb73e3273191 Init state to -1 in h264 parser.
bcoudurier
parents: 9380
diff changeset
117 int state = -1;
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
118 const uint8_t *ptr;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
119
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
120 /* set some sane default values */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
121 s->pict_type = FF_I_TYPE;
8998
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
122 s->key_frame = 0;
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
123
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
124 h->s.avctx= avctx;
8998
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
125 h->sei_recovery_frame_cnt = -1;
9039
d4002371b3d2 Export timestamp parameter from H.264.
cehoyos
parents: 9035
diff changeset
126 h->sei_dpb_output_delay = 0;
d4002371b3d2 Export timestamp parameter from H.264.
cehoyos
parents: 9035
diff changeset
127 h->sei_cpb_removal_delay = -1;
d4002371b3d2 Export timestamp parameter from H.264.
cehoyos
parents: 9035
diff changeset
128 h->sei_buffering_period_present = 0;
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
129
12236
cabcd751b1e5 In h264 parser, return immediately if buf_size is 0, avoid printing
bcoudurier
parents: 11791
diff changeset
130 if (!buf_size)
cabcd751b1e5 In h264 parser, return immediately if buf_size is 0, avoid printing
bcoudurier
parents: 11791
diff changeset
131 return 0;
cabcd751b1e5 In h264 parser, return immediately if buf_size is 0, avoid printing
bcoudurier
parents: 11791
diff changeset
132
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
133 for(;;) {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
134 int src_length, dst_length, consumed;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
135 buf = ff_find_start_code(buf, buf_end, &state);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
136 if(buf >= buf_end)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
137 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
138 --buf;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
139 src_length = buf_end - buf;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
140 switch (state & 0x1f) {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
141 case NAL_SLICE:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
142 case NAL_IDR_SLICE:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
143 // Do not walk the whole buffer just to decode slice header
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
144 if (src_length > 20)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
145 src_length = 20;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
146 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
147 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
148 ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
149 if (ptr==NULL || dst_length < 0)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
150 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
151
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
152 init_get_bits(&h->s.gb, ptr, 8*dst_length);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
153 switch(h->nal_unit_type) {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
154 case NAL_SPS:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
155 ff_h264_decode_seq_parameter_set(h);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
156 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
157 case NAL_PPS:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
158 ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
159 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
160 case NAL_SEI:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
161 ff_h264_decode_sei(h);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
162 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
163 case NAL_IDR_SLICE:
8998
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
164 s->key_frame = 1;
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
165 /* fall through */
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
166 case NAL_SLICE:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
167 get_ue_golomb(&h->s.gb); // skip first_mb_in_slice
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
168 slice_type = get_ue_golomb_31(&h->s.gb);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
169 s->pict_type = golomb_to_pict_type[slice_type % 5];
8998
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
170 if (h->sei_recovery_frame_cnt >= 0) {
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
171 /* key frame, since recovery_frame_cnt is set */
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
172 s->key_frame = 1;
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
173 }
8999
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
174 pps_id= get_ue_golomb(&h->s.gb);
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
175 if(pps_id>=MAX_PPS_COUNT) {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
176 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
177 return -1;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
178 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
179 if(!h->pps_buffers[pps_id]) {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
180 av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
181 return -1;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
182 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
183 h->pps= *h->pps_buffers[pps_id];
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
184 if(!h->sps_buffers[h->pps.sps_id]) {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
185 av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
186 return -1;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
187 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
188 h->sps = *h->sps_buffers[h->pps.sps_id];
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
189 h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num);
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
190
11047
ec682347e19e Export H264 profile and level in AVCodecContext.
cehoyos
parents: 11043
diff changeset
191 avctx->profile = h->sps.profile_idc;
ec682347e19e Export H264 profile and level in AVCodecContext.
cehoyos
parents: 11043
diff changeset
192 avctx->level = h->sps.level_idc;
ec682347e19e Export H264 profile and level in AVCodecContext.
cehoyos
parents: 11043
diff changeset
193
8999
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
194 if(h->sps.frame_mbs_only_flag){
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
195 h->s.picture_structure= PICT_FRAME;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
196 }else{
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
197 if(get_bits1(&h->s.gb)) { //field_pic_flag
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
198 h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
199 } else {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
200 h->s.picture_structure= PICT_FRAME;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
201 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
202 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
203
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
204 if(h->sps.pic_struct_present_flag) {
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
205 switch (h->sei_pic_struct) {
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
206 case SEI_PIC_STRUCT_TOP_FIELD:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
207 case SEI_PIC_STRUCT_BOTTOM_FIELD:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
208 s->repeat_pict = 0;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
209 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
210 case SEI_PIC_STRUCT_FRAME:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
211 case SEI_PIC_STRUCT_TOP_BOTTOM:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
212 case SEI_PIC_STRUCT_BOTTOM_TOP:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
213 s->repeat_pict = 1;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
214 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
215 case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
216 case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
217 s->repeat_pict = 2;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
218 break;
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
219 case SEI_PIC_STRUCT_FRAME_DOUBLING:
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
220 s->repeat_pict = 3;
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
221 break;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
222 case SEI_PIC_STRUCT_FRAME_TRIPLING:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
223 s->repeat_pict = 5;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
224 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
225 default:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
226 s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
227 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
228 }
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
229 } else {
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
230 s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
231 }
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
232
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
233 return 0; /* no need to evaluate the rest */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
234 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
235 buf += consumed;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
236 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
237 /* didn't find a picture! */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
238 av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
239 return -1;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
240 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
241
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
242 static int h264_parse(AVCodecParserContext *s,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
243 AVCodecContext *avctx,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
244 const uint8_t **poutbuf, int *poutbuf_size,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
245 const uint8_t *buf, int buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
246 {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
247 H264Context *h = s->priv_data;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
248 ParseContext *pc = &h->s.parse_context;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
249 int next;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
250
11791
51abd780bda6 Cleanup prev commit, flag variable should start with 0
hyc
parents: 11790
diff changeset
251 if (!h->got_first) {
51abd780bda6 Cleanup prev commit, flag variable should start with 0
hyc
parents: 11790
diff changeset
252 h->got_first = 1;
11790
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
253 if (avctx->extradata_size) {
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
254 h->s.avctx = avctx;
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
255 ff_h264_decode_extradata(h);
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
256 }
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
257 }
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
258
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
259 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
260 next= buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
261 }else{
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
262 next= ff_h264_find_frame_end(h, buf, buf_size);
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
263
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
264 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
265 *poutbuf = NULL;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
266 *poutbuf_size = 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
267 return buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
268 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
269
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
270 if(next<0 && next != END_NOT_FOUND){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
271 assert(pc->last_index + next >= 0 );
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
272 ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
273 }
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
274
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
275 parse_nal_units(s, avctx, buf, buf_size);
9039
d4002371b3d2 Export timestamp parameter from H.264.
cehoyos
parents: 9035
diff changeset
276
9056
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
277 if (h->sei_cpb_removal_delay >= 0) {
9057
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
278 s->dts_sync_point = h->sei_buffering_period_present;
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
279 s->dts_ref_dts_delta = h->sei_cpb_removal_delay;
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
280 s->pts_dts_delta = h->sei_dpb_output_delay;
9056
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
281 } else {
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
282 s->dts_sync_point = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
283 s->dts_ref_dts_delta = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
284 s->pts_dts_delta = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
285 }
11770
6d58a4f5e455 Add an AVSTREAM_PARSE_FULL_ONCE parsing mode to parse headers and combine packets once and only once.
alexc
parents: 11644
diff changeset
286 if (s->flags & PARSER_FLAG_ONCE) {
6d58a4f5e455 Add an AVSTREAM_PARSE_FULL_ONCE parsing mode to parse headers and combine packets once and only once.
alexc
parents: 11644
diff changeset
287 s->flags &= PARSER_FLAG_COMPLETE_FRAMES;
6d58a4f5e455 Add an AVSTREAM_PARSE_FULL_ONCE parsing mode to parse headers and combine packets once and only once.
alexc
parents: 11644
diff changeset
288 }
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
289 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
290
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
291 *poutbuf = buf;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
292 *poutbuf_size = buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
293 return next;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
294 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
295
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
296 static int h264_split(AVCodecContext *avctx,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
297 const uint8_t *buf, int buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
298 {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
299 int i;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
300 uint32_t state = -1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
301 int has_sps= 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
302
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
303 for(i=0; i<=buf_size; i++){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
304 if((state&0xFFFFFF1F) == 0x107)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
305 has_sps=1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
306 /* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
307 }*/
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
308 if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
309 if(has_sps){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
310 while(i>4 && buf[i-5]==0) i--;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
311 return i-4;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
312 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
313 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
314 if (i<buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
315 state= (state<<8) | buf[i];
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
316 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
317 return 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
318 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
319
7991
a38b31a2ac52 100l forgot return type.
michael
parents: 7989
diff changeset
320 static void close(AVCodecParserContext *s)
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
321 {
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
322 H264Context *h = s->priv_data;
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
323 ParseContext *pc = &h->s.parse_context;
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
324
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
325 av_free(pc->buffer);
9380
54e650136c87 Add a ff_h264_free_context function and call it from the H.264 parser.
reimar
parents: 9180
diff changeset
326 ff_h264_free_context(h);
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
327 }
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
328
11043
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
329 static int init(AVCodecParserContext *s)
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
330 {
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
331 H264Context *h = s->priv_data;
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
332 h->thread_context[0] = h;
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
333 return 0;
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
334 }
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
335
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
336 AVCodecParser h264_parser = {
8610
2ca51be7dad8 Remove CODEC_ID_H264_VDPAU.
cehoyos
parents: 8590
diff changeset
337 { CODEC_ID_H264 },
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
338 sizeof(H264Context),
11043
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
339 init,
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
340 h264_parse,
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
341 close,
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
342 h264_split,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
343 };