summaryrefslogtreecommitdiff
path: root/libavcodec/h264_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/h264_parser.c')
-rw-r--r--libavcodec/h264_parser.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 9f82a370de..cd37d31fbd 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -45,6 +45,7 @@
typedef struct H264ParseContext {
H264Context h;
ParseContext pc;
+ H264ParamSets ps;
int got_first;
} H264ParseContext;
@@ -115,13 +116,13 @@ static int scan_mmco_reset(AVCodecParserContext *s, GetBitContext *gb)
int list_count, ref_count[2];
- if (h->pps.redundant_pic_cnt_present)
+ if (p->ps.pps->redundant_pic_cnt_present)
get_ue_golomb(gb); // redundant_pic_count
if (slice_type_nos == AV_PICTURE_TYPE_B)
get_bits1(gb); // direct_spatial_mv_pred
- if (ff_h264_parse_ref_count(&list_count, ref_count, gb, &h->pps,
+ if (ff_h264_parse_ref_count(&list_count, ref_count, gb, p->ps.pps,
slice_type_nos, h->picture_structure) < 0)
return AVERROR_INVALIDDATA;
@@ -153,9 +154,9 @@ static int scan_mmco_reset(AVCodecParserContext *s, GetBitContext *gb)
}
}
- if ((h->pps.weighted_pred && slice_type_nos == AV_PICTURE_TYPE_P) ||
- (h->pps.weighted_bipred_idc == 1 && slice_type_nos == AV_PICTURE_TYPE_B))
- ff_h264_pred_weight_table(gb, &h->sps, ref_count, slice_type_nos,
+ if ((p->ps.pps->weighted_pred && slice_type_nos == AV_PICTURE_TYPE_P) ||
+ (p->ps.pps->weighted_bipred_idc == 1 && slice_type_nos == AV_PICTURE_TYPE_B))
+ ff_h264_pred_weight_table(gb, p->ps.sps, ref_count, slice_type_nos,
&pwt);
if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag
@@ -220,6 +221,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
return 0;
for (;;) {
+ const SPS *sps;
int src_length, consumed;
buf = avpriv_find_start_code(buf, buf_end, &state);
if (buf >= buf_end)
@@ -260,10 +262,11 @@ static inline int parse_nal_units(AVCodecParserContext *s,
switch (h->nal_unit_type) {
case NAL_SPS:
- ff_h264_decode_seq_parameter_set(h);
+ ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps);
break;
case NAL_PPS:
- ff_h264_decode_picture_parameter_set(h, h->gb.size_in_bits);
+ ff_h264_decode_picture_parameter_set(&nal.gb, avctx, &p->ps,
+ nal.size_bits);
break;
case NAL_SEI:
ff_h264_decode_sei(h);
@@ -290,30 +293,35 @@ static inline int parse_nal_units(AVCodecParserContext *s,
"pps_id %u out of range\n", pps_id);
goto fail;
}
- if (!h->pps_buffers[pps_id]) {
+ if (!p->ps.pps_list[pps_id]) {
av_log(h->avctx, AV_LOG_ERROR,
"non-existing PPS %u referenced\n", pps_id);
goto fail;
}
- h->pps = *h->pps_buffers[pps_id];
- if (!h->sps_buffers[h->pps.sps_id]) {
+ p->ps.pps = (const PPS*)p->ps.pps_list[pps_id]->data;
+ if (!p->ps.sps_list[p->ps.pps->sps_id]) {
av_log(h->avctx, AV_LOG_ERROR,
- "non-existing SPS %u referenced\n", h->pps.sps_id);
+ "non-existing SPS %u referenced\n", p->ps.pps->sps_id);
goto fail;
}
- h->sps = *h->sps_buffers[h->pps.sps_id];
- h->frame_num = get_bits(&nal.gb, h->sps.log2_max_frame_num);
+ p->ps.sps = (SPS*)p->ps.sps_list[p->ps.pps->sps_id]->data;
- s->coded_width = 16 * h->sps.mb_width;
- s->coded_height = 16 * h->sps.mb_height;
- s->width = s->coded_width - (h->sps.crop_right + h->sps.crop_left);
- s->height = s->coded_height - (h->sps.crop_top + h->sps.crop_bottom);
+ h->ps.sps = p->ps.sps;
+ h->ps.pps = p->ps.pps;
+ sps = p->ps.sps;
+
+ h->frame_num = get_bits(&nal.gb, sps->log2_max_frame_num);
+
+ s->coded_width = 16 * sps->mb_width;
+ s->coded_height = 16 * sps->mb_height;
+ s->width = s->coded_width - (sps->crop_right + sps->crop_left);
+ s->height = s->coded_height - (sps->crop_top + sps->crop_bottom);
if (s->width <= 0 || s->height <= 0) {
s->width = s->coded_width;
s->height = s->coded_height;
}
- switch (h->sps.bit_depth_luma) {
+ switch (sps->bit_depth_luma) {
case 9:
if (CHROMA444(h)) s->format = AV_PIX_FMT_YUV444P9;
else if (CHROMA422(h)) s->format = AV_PIX_FMT_YUV422P9;
@@ -333,10 +341,10 @@ static inline int parse_nal_units(AVCodecParserContext *s,
s->format = AV_PIX_FMT_NONE;
}
- avctx->profile = ff_h264_get_profile(&h->sps);
- avctx->level = h->sps.level_idc;
+ avctx->profile = ff_h264_get_profile(sps);
+ avctx->level = sps->level_idc;
- if (h->sps.frame_mbs_only_flag) {
+ if (sps->frame_mbs_only_flag) {
h->picture_structure = PICT_FRAME;
} else {
if (get_bits1(&nal.gb)) { // field_pic_flag
@@ -348,19 +356,19 @@ static inline int parse_nal_units(AVCodecParserContext *s,
if (h->nal_unit_type == NAL_IDR_SLICE)
get_ue_golomb(&nal.gb); /* idr_pic_id */
- if (h->sps.poc_type == 0) {
- h->poc_lsb = get_bits(&nal.gb, h->sps.log2_max_poc_lsb);
+ if (sps->poc_type == 0) {
+ h->poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb);
- if (h->pps.pic_order_present == 1 &&
+ if (p->ps.pps->pic_order_present == 1 &&
h->picture_structure == PICT_FRAME)
h->delta_poc_bottom = get_se_golomb(&nal.gb);
}
- if (h->sps.poc_type == 1 &&
- !h->sps.delta_pic_order_always_zero_flag) {
+ if (sps->poc_type == 1 &&
+ !sps->delta_pic_order_always_zero_flag) {
h->delta_poc[0] = get_se_golomb(&nal.gb);
- if (h->pps.pic_order_present == 1 &&
+ if (p->ps.pps->pic_order_present == 1 &&
h->picture_structure == PICT_FRAME)
h->delta_poc[1] = get_se_golomb(&nal.gb);
}
@@ -394,7 +402,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
}
}
- if (h->sps.pic_struct_present_flag) {
+ if (sps->pic_struct_present_flag) {
switch (h->sei_pic_struct) {
case SEI_PIC_STRUCT_TOP_FIELD:
case SEI_PIC_STRUCT_BOTTOM_FIELD:
@@ -425,7 +433,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
if (h->picture_structure == PICT_FRAME) {
s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
- if (h->sps.pic_struct_present_flag) {
+ if (sps->pic_struct_present_flag) {
switch (h->sei_pic_struct) {
case SEI_PIC_STRUCT_TOP_BOTTOM:
case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
@@ -566,9 +574,16 @@ static void h264_close(AVCodecParserContext *s)
H264ParseContext *p = s->priv_data;
H264Context *h = &p->h;
ParseContext *pc = &p->pc;
+ int i;
av_free(pc->buffer);
ff_h264_free_context(h);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(p->ps.sps_list); i++)
+ av_buffer_unref(&p->ps.sps_list[i]);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(p->ps.pps_list); i++)
+ av_buffer_unref(&p->ps.pps_list[i]);
}
static av_cold int init(AVCodecParserContext *s)