Mercurial > libavcodec.hg
comparison h264_parser.c @ 8997:1c69c50d78f1 libavcodec
Parse NAL units in H264 parser.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Sat, 21 Feb 2009 19:56:50 +0000 |
parents | 8551f8149146 |
children | 9339bf262eb5 |
comparison
equal
deleted
inserted
replaced
8996:e65778184ded | 8997:1c69c50d78f1 |
---|---|
25 * @author Michael Niedermayer <michaelni@gmx.at> | 25 * @author Michael Niedermayer <michaelni@gmx.at> |
26 */ | 26 */ |
27 | 27 |
28 #include "parser.h" | 28 #include "parser.h" |
29 #include "h264_parser.h" | 29 #include "h264_parser.h" |
30 #include "h264data.h" | |
31 #include "golomb.h" | |
30 | 32 |
31 #include <assert.h> | 33 #include <assert.h> |
32 | 34 |
33 | 35 |
34 int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size) | 36 int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size) |
94 pc->state=7; | 96 pc->state=7; |
95 pc->frame_start_found= 0; | 97 pc->frame_start_found= 0; |
96 return i-(state&5); | 98 return i-(state&5); |
97 } | 99 } |
98 | 100 |
101 /*! | |
102 * Parse NAL units of found picture and decode some basic information. | |
103 * | |
104 * @param s parser context. | |
105 * @param avctx codec context. | |
106 * @param buf buffer with field/frame data. | |
107 * @param buf_size size of the buffer. | |
108 */ | |
109 static inline int parse_nal_units(AVCodecParserContext *s, | |
110 AVCodecContext *avctx, | |
111 const uint8_t *buf, int buf_size) | |
112 { | |
113 H264Context *h = s->priv_data; | |
114 const uint8_t *buf_end = buf + buf_size; | |
115 unsigned int slice_type; | |
116 int state; | |
117 const uint8_t *ptr; | |
118 | |
119 /* set some sane default values */ | |
120 s->pict_type = FF_I_TYPE; | |
121 | |
122 h->s.avctx= avctx; | |
123 | |
124 for(;;) { | |
125 int src_length, dst_length, consumed; | |
126 buf = ff_find_start_code(buf, buf_end, &state); | |
127 if(buf >= buf_end) | |
128 break; | |
129 --buf; | |
130 src_length = buf_end - buf; | |
131 switch (state & 0x1f) { | |
132 case NAL_SLICE: | |
133 case NAL_IDR_SLICE: | |
134 // Do not walk the whole buffer just to decode slice header | |
135 if (src_length > 20) | |
136 src_length = 20; | |
137 break; | |
138 } | |
139 ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); | |
140 if (ptr==NULL || dst_length < 0) | |
141 break; | |
142 | |
143 init_get_bits(&h->s.gb, ptr, 8*dst_length); | |
144 switch(h->nal_unit_type) { | |
145 case NAL_SPS: | |
146 ff_h264_decode_seq_parameter_set(h); | |
147 break; | |
148 case NAL_PPS: | |
149 ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits); | |
150 break; | |
151 case NAL_SEI: | |
152 ff_h264_decode_sei(h); | |
153 break; | |
154 case NAL_IDR_SLICE: | |
155 case NAL_SLICE: | |
156 get_ue_golomb(&h->s.gb); // skip first_mb_in_slice | |
157 slice_type = get_ue_golomb_31(&h->s.gb); | |
158 s->pict_type = golomb_to_pict_type[slice_type % 5]; | |
159 return 0; /* no need to evaluate the rest */ | |
160 } | |
161 buf += consumed; | |
162 } | |
163 /* didn't find a picture! */ | |
164 av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n"); | |
165 return -1; | |
166 } | |
167 | |
99 static int h264_parse(AVCodecParserContext *s, | 168 static int h264_parse(AVCodecParserContext *s, |
100 AVCodecContext *avctx, | 169 AVCodecContext *avctx, |
101 const uint8_t **poutbuf, int *poutbuf_size, | 170 const uint8_t **poutbuf, int *poutbuf_size, |
102 const uint8_t *buf, int buf_size) | 171 const uint8_t *buf, int buf_size) |
103 { | 172 { |
118 | 187 |
119 if(next<0 && next != END_NOT_FOUND){ | 188 if(next<0 && next != END_NOT_FOUND){ |
120 assert(pc->last_index + next >= 0 ); | 189 assert(pc->last_index + next >= 0 ); |
121 ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state | 190 ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state |
122 } | 191 } |
192 | |
193 parse_nal_units(s, avctx, buf, buf_size); | |
123 } | 194 } |
124 | 195 |
125 *poutbuf = buf; | 196 *poutbuf = buf; |
126 *poutbuf_size = buf_size; | 197 *poutbuf_size = buf_size; |
127 return next; | 198 return next; |