Commit ff6474dd authored by Ivan Schreter's avatar Ivan Schreter Committed by Carl Eugen Hoyos

Parse NAL units in H264 parser.

Patch by Ivan Schreter, schreter gmx net

Originally committed as revision 17488 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 1790a5e9
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "parser.h" #include "parser.h"
#include "h264_parser.h" #include "h264_parser.h"
#include "h264data.h"
#include "golomb.h"
#include <assert.h> #include <assert.h>
...@@ -96,6 +98,73 @@ found: ...@@ -96,6 +98,73 @@ found:
return i-(state&5); return i-(state&5);
} }
/*!
* Parse NAL units of found picture and decode some basic information.
*
* @param s parser context.
* @param avctx codec context.
* @param buf buffer with field/frame data.
* @param buf_size size of the buffer.
*/
static inline int parse_nal_units(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
H264Context *h = s->priv_data;
const uint8_t *buf_end = buf + buf_size;
unsigned int slice_type;
int state;
const uint8_t *ptr;
/* set some sane default values */
s->pict_type = FF_I_TYPE;
h->s.avctx= avctx;
for(;;) {
int src_length, dst_length, consumed;
buf = ff_find_start_code(buf, buf_end, &state);
if(buf >= buf_end)
break;
--buf;
src_length = buf_end - buf;
switch (state & 0x1f) {
case NAL_SLICE:
case NAL_IDR_SLICE:
// Do not walk the whole buffer just to decode slice header
if (src_length > 20)
src_length = 20;
break;
}
ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
if (ptr==NULL || dst_length < 0)
break;
init_get_bits(&h->s.gb, ptr, 8*dst_length);
switch(h->nal_unit_type) {
case NAL_SPS:
ff_h264_decode_seq_parameter_set(h);
break;
case NAL_PPS:
ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits);
break;
case NAL_SEI:
ff_h264_decode_sei(h);
break;
case NAL_IDR_SLICE:
case NAL_SLICE:
get_ue_golomb(&h->s.gb); // skip first_mb_in_slice
slice_type = get_ue_golomb_31(&h->s.gb);
s->pict_type = golomb_to_pict_type[slice_type % 5];
return 0; /* no need to evaluate the rest */
}
buf += consumed;
}
/* didn't find a picture! */
av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
return -1;
}
static int h264_parse(AVCodecParserContext *s, static int h264_parse(AVCodecParserContext *s,
AVCodecContext *avctx, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size, const uint8_t **poutbuf, int *poutbuf_size,
...@@ -120,6 +189,8 @@ static int h264_parse(AVCodecParserContext *s, ...@@ -120,6 +189,8 @@ static int h264_parse(AVCodecParserContext *s,
assert(pc->last_index + next >= 0 ); assert(pc->last_index + next >= 0 );
ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
} }
parse_nal_units(s, avctx, buf, buf_size);
} }
*poutbuf = buf; *poutbuf = buf;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment