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;