annotate h264_parser.c @ 11816:7c2369ec6faa libavcodec

ARM: check struct offsets only when they are used The offsets differ depending on configuration, so only check them when they will actually be used. Presently, this is when NEON is enabled.
author mru
date Wed, 02 Jun 2010 22:05:25 +0000
parents 51abd780bda6
children cabcd751b1e5
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
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
130 for(;;) {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
131 int src_length, dst_length, consumed;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
132 buf = ff_find_start_code(buf, buf_end, &state);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
133 if(buf >= buf_end)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
134 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
135 --buf;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
136 src_length = buf_end - buf;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
137 switch (state & 0x1f) {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
138 case NAL_SLICE:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
139 case NAL_IDR_SLICE:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
140 // Do not walk the whole buffer just to decode slice header
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
141 if (src_length > 20)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
142 src_length = 20;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
143 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
144 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
145 ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
146 if (ptr==NULL || dst_length < 0)
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
147 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
148
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
149 init_get_bits(&h->s.gb, ptr, 8*dst_length);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
150 switch(h->nal_unit_type) {
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
151 case NAL_SPS:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
152 ff_h264_decode_seq_parameter_set(h);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
153 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
154 case NAL_PPS:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
155 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
156 break;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
157 case NAL_SEI:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
158 ff_h264_decode_sei(h);
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_IDR_SLICE:
8998
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
161 s->key_frame = 1;
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
162 /* fall through */
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
163 case NAL_SLICE:
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
164 get_ue_golomb(&h->s.gb); // skip first_mb_in_slice
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
165 slice_type = get_ue_golomb_31(&h->s.gb);
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
166 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
167 if (h->sei_recovery_frame_cnt >= 0) {
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
168 /* key frame, since recovery_frame_cnt is set */
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
169 s->key_frame = 1;
9339bf262eb5 Set context variable key_frame in H264 parser.
cehoyos
parents: 8997
diff changeset
170 }
8999
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
171 pps_id= get_ue_golomb(&h->s.gb);
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
172 if(pps_id>=MAX_PPS_COUNT) {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
173 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
174 return -1;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
175 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
176 if(!h->pps_buffers[pps_id]) {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
177 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
178 return -1;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
179 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
180 h->pps= *h->pps_buffers[pps_id];
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
181 if(!h->sps_buffers[h->pps.sps_id]) {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
182 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
183 return -1;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
184 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
185 h->sps = *h->sps_buffers[h->pps.sps_id];
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
186 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
187
11047
ec682347e19e Export H264 profile and level in AVCodecContext.
cehoyos
parents: 11043
diff changeset
188 avctx->profile = h->sps.profile_idc;
ec682347e19e Export H264 profile and level in AVCodecContext.
cehoyos
parents: 11043
diff changeset
189 avctx->level = h->sps.level_idc;
ec682347e19e Export H264 profile and level in AVCodecContext.
cehoyos
parents: 11043
diff changeset
190
8999
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
191 if(h->sps.frame_mbs_only_flag){
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
192 h->s.picture_structure= PICT_FRAME;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
193 }else{
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
194 if(get_bits1(&h->s.gb)) { //field_pic_flag
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
195 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
196 } else {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
197 h->s.picture_structure= PICT_FRAME;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
198 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
199 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
200
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
201 if(h->sps.pic_struct_present_flag) {
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
202 switch (h->sei_pic_struct) {
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
203 case SEI_PIC_STRUCT_TOP_FIELD:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
204 case SEI_PIC_STRUCT_BOTTOM_FIELD:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
205 s->repeat_pict = 0;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
206 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
207 case SEI_PIC_STRUCT_FRAME:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
208 case SEI_PIC_STRUCT_TOP_BOTTOM:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
209 case SEI_PIC_STRUCT_BOTTOM_TOP:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
210 s->repeat_pict = 1;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
211 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
212 case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
213 case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
214 s->repeat_pict = 2;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
215 break;
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
216 case SEI_PIC_STRUCT_FRAME_DOUBLING:
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
217 s->repeat_pict = 3;
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
218 break;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
219 case SEI_PIC_STRUCT_FRAME_TRIPLING:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
220 s->repeat_pict = 5;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
221 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
222 default:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
223 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
224 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
225 }
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
226 } else {
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
227 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
228 }
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
229
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
230 return 0; /* no need to evaluate the rest */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
231 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
232 buf += consumed;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
233 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
234 /* didn't find a picture! */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
235 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
236 return -1;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
237 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
238
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
239 static int h264_parse(AVCodecParserContext *s,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
240 AVCodecContext *avctx,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
241 const uint8_t **poutbuf, int *poutbuf_size,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
242 const uint8_t *buf, int buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
243 {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
244 H264Context *h = s->priv_data;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
245 ParseContext *pc = &h->s.parse_context;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
246 int next;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
247
11791
51abd780bda6 Cleanup prev commit, flag variable should start with 0
hyc
parents: 11790
diff changeset
248 if (!h->got_first) {
51abd780bda6 Cleanup prev commit, flag variable should start with 0
hyc
parents: 11790
diff changeset
249 h->got_first = 1;
11790
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
250 if (avctx->extradata_size) {
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
251 h->s.avctx = avctx;
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
252 ff_h264_decode_extradata(h);
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
253 }
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
254 }
f918fb753b31 Parse avctx->extradata if available.
hyc
parents: 11770
diff changeset
255
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
256 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
257 next= buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
258 }else{
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
259 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
260
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
261 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
262 *poutbuf = NULL;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
263 *poutbuf_size = 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
264 return buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
265 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
266
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
267 if(next<0 && next != END_NOT_FOUND){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
268 assert(pc->last_index + next >= 0 );
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
269 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
270 }
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
271
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
272 parse_nal_units(s, avctx, buf, buf_size);
9039
d4002371b3d2 Export timestamp parameter from H.264.
cehoyos
parents: 9035
diff changeset
273
9056
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
274 if (h->sei_cpb_removal_delay >= 0) {
9057
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
275 s->dts_sync_point = h->sei_buffering_period_present;
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
276 s->dts_ref_dts_delta = h->sei_cpb_removal_delay;
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
277 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
278 } else {
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
279 s->dts_sync_point = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
280 s->dts_ref_dts_delta = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
281 s->pts_dts_delta = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
282 }
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
283 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
284 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
285 }
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
286 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
287
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
288 *poutbuf = buf;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
289 *poutbuf_size = buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
290 return next;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
291 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
292
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
293 static int h264_split(AVCodecContext *avctx,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
294 const uint8_t *buf, int buf_size)
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 int i;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
297 uint32_t state = -1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
298 int has_sps= 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
299
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
300 for(i=0; i<=buf_size; i++){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
301 if((state&0xFFFFFF1F) == 0x107)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
302 has_sps=1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
303 /* 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
304 }*/
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
305 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
306 if(has_sps){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
307 while(i>4 && buf[i-5]==0) i--;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
308 return i-4;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
309 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
310 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
311 if (i<buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
312 state= (state<<8) | buf[i];
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 return 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
315 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
316
7991
a38b31a2ac52 100l forgot return type.
michael
parents: 7989
diff changeset
317 static void close(AVCodecParserContext *s)
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
318 {
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
319 H264Context *h = s->priv_data;
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
320 ParseContext *pc = &h->s.parse_context;
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 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
323 ff_h264_free_context(h);
7989
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
11043
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
326 static int init(AVCodecParserContext *s)
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
327 {
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
328 H264Context *h = s->priv_data;
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
329 h->thread_context[0] = h;
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
330 return 0;
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
331 }
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
332
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
333 AVCodecParser h264_parser = {
8610
2ca51be7dad8 Remove CODEC_ID_H264_VDPAU.
cehoyos
parents: 8590
diff changeset
334 { CODEC_ID_H264 },
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
335 sizeof(H264Context),
11043
916df4ea4e64 Initialize thread_context[0] with h264 parser context.
benoit
parents: 9424
diff changeset
336 init,
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
337 h264_parse,
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
338 close,
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
339 h264_split,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
340 };