annotate h264_parser.c @ 9930:32e856bd5ded libavcodec

Check for CONFIG_LIBFOO_DECODER/CONFIG_LIBFOO_ENCODER instead of just CONFIG_LIBFOO in the external libraries section. This is more consistent with the rest of the Makefiles, it makes clearer what is actually implemented and should be advantageous if we implement an external library encoder where we previously just had the decoder and vice versa.
author diego
date Tue, 07 Jul 2009 09:33:08 +0000
parents cb73e3273191
children 916df4ea4e64
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 /**
8718
e9d9d946f213 Use full internal pathname in doxygen @file directives.
diego
parents: 8610
diff changeset
23 * @file libavcodec/h264_parser.c
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
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
188 if(h->sps.frame_mbs_only_flag){
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
189 h->s.picture_structure= PICT_FRAME;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
190 }else{
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
191 if(get_bits1(&h->s.gb)) { //field_pic_flag
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
192 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
193 } else {
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
194 h->s.picture_structure= PICT_FRAME;
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
195 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
196 }
f701dab6a62d Set context variable picture_structure in H264 parser.
cehoyos
parents: 8998
diff changeset
197
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
198 if(h->sps.pic_struct_present_flag) {
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
199 switch (h->sei_pic_struct) {
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
200 case SEI_PIC_STRUCT_TOP_FIELD:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
201 case SEI_PIC_STRUCT_BOTTOM_FIELD:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
202 s->repeat_pict = 0;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
203 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
204 case SEI_PIC_STRUCT_FRAME:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
205 case SEI_PIC_STRUCT_TOP_BOTTOM:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
206 case SEI_PIC_STRUCT_BOTTOM_TOP:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
207 s->repeat_pict = 1;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
208 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
209 case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
210 case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
211 s->repeat_pict = 2;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
212 break;
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
213 case SEI_PIC_STRUCT_FRAME_DOUBLING:
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
214 s->repeat_pict = 3;
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
215 break;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
216 case SEI_PIC_STRUCT_FRAME_TRIPLING:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
217 s->repeat_pict = 5;
9000
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
218 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
219 default:
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
220 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
221 break;
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
222 }
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
223 } else {
9035
d22ed7aad1b0 Correct time_base of H.264 and repeat_pict.
cehoyos
parents: 9000
diff changeset
224 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
225 }
78afc2990d00 Use context variable repeat_pict for frame duration computation and
cehoyos
parents: 8999
diff changeset
226
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
227 return 0; /* no need to evaluate the rest */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
228 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
229 buf += consumed;
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
230 }
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
231 /* didn't find a picture! */
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
232 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
233 return -1;
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
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
236 static int h264_parse(AVCodecParserContext *s,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
237 AVCodecContext *avctx,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
238 const uint8_t **poutbuf, int *poutbuf_size,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
239 const uint8_t *buf, int buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
240 {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
241 H264Context *h = s->priv_data;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
242 ParseContext *pc = &h->s.parse_context;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
243 int next;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
244
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
245 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
246 next= buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
247 }else{
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
248 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
249
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
250 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
251 *poutbuf = NULL;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
252 *poutbuf_size = 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
253 return buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
254 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
255
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
256 if(next<0 && next != END_NOT_FOUND){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
257 assert(pc->last_index + next >= 0 );
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
258 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
259 }
8997
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
260
1c69c50d78f1 Parse NAL units in H264 parser.
cehoyos
parents: 8763
diff changeset
261 parse_nal_units(s, avctx, buf, buf_size);
9039
d4002371b3d2 Export timestamp parameter from H.264.
cehoyos
parents: 9035
diff changeset
262
9056
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
263 if (h->sei_cpb_removal_delay >= 0) {
9057
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
264 s->dts_sync_point = h->sei_buffering_period_present;
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
265 s->dts_ref_dts_delta = h->sei_cpb_removal_delay;
0adefec7e2b4 Cosmetics: Fix indentation after last commit.
cehoyos
parents: 9056
diff changeset
266 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
267 } else {
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
268 s->dts_sync_point = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
269 s->dts_ref_dts_delta = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
270 s->pts_dts_delta = INT_MIN;
4180f20569c1 Initialize H264 parser context correctly if the optional SEI messages
cehoyos
parents: 9039
diff changeset
271 }
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
272 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
273
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
274 *poutbuf = buf;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
275 *poutbuf_size = buf_size;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
276 return next;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
277 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
278
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
279 static int h264_split(AVCodecContext *avctx,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
280 const uint8_t *buf, int buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
281 {
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
282 int i;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
283 uint32_t state = -1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
284 int has_sps= 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
285
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
286 for(i=0; i<=buf_size; i++){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
287 if((state&0xFFFFFF1F) == 0x107)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
288 has_sps=1;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
289 /* 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
290 }*/
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
291 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
292 if(has_sps){
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
293 while(i>4 && buf[i-5]==0) i--;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
294 return i-4;
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 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
297 if (i<buf_size)
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
298 state= (state<<8) | buf[i];
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 return 0;
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
301 }
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
302
7991
a38b31a2ac52 100l forgot return type.
michael
parents: 7989
diff changeset
303 static void close(AVCodecParserContext *s)
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
304 {
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
305 H264Context *h = s->priv_data;
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
306 ParseContext *pc = &h->s.parse_context;
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
307
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
308 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
309 ff_h264_free_context(h);
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
310 }
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
311
4975
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 AVCodecParser h264_parser = {
8610
2ca51be7dad8 Remove CODEC_ID_H264_VDPAU.
cehoyos
parents: 8590
diff changeset
314 { CODEC_ID_H264 },
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
315 sizeof(H264Context),
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
316 NULL,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
317 h264_parse,
7989
0607ff0877ff ff_parse_close() is not the correct function for H264Context.
michael
parents: 7986
diff changeset
318 close,
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
319 h264_split,
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents:
diff changeset
320 };