int y, int height)
{
AVCodecContext *avctx = h->avctx;
- const AVFrame *src = &h->cur_pic.f;
+ const AVFrame *src = h->cur_pic.f;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
int vshift = desc->log2_chroma_h;
const int field_pic = h->picture_structure != PICT_FRAME;
return 0;
}
-void ff_h264_free_tables(H264Context *h, int free_rbsp)
+void ff_h264_free_tables(H264Context *h)
{
int i;
av_buffer_pool_uninit(&h->motion_val_pool);
av_buffer_pool_uninit(&h->ref_index_pool);
- if (free_rbsp && h->DPB) {
- for (i = 0; i < H264_MAX_PICTURE_COUNT; i++)
- ff_h264_unref_picture(h, &h->DPB[i]);
- av_freep(&h->DPB);
- }
-
- h->cur_pic_ptr = NULL;
-
for (i = 0; i < h->nb_slice_ctx; i++) {
H264SliceContext *sl = &h->slice_ctx[i];
sl->edge_emu_buffer_allocated = 0;
sl->top_borders_allocated[0] = 0;
sl->top_borders_allocated[1] = 0;
-
- if (free_rbsp) {
- av_freep(&sl->rbsp_buffer);
- sl->rbsp_buffer_size = 0;
- }
}
}
{
const int big_mb_num = h->mb_stride * (h->mb_height + 1);
const int row_mb_num = h->mb_stride * 2 * h->avctx->thread_count;
- int x, y, i;
+ int x, y;
FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
row_mb_num * 8 * sizeof(uint8_t), fail)
if (!h->dequant4_coeff[0])
h264_init_dequant_tables(h);
- if (!h->DPB) {
- h->DPB = av_mallocz_array(H264_MAX_PICTURE_COUNT, sizeof(*h->DPB));
- if (!h->DPB)
- goto fail;
- for (i = 0; i < H264_MAX_PICTURE_COUNT; i++)
- av_frame_unref(&h->DPB[i].f);
- av_frame_unref(&h->cur_pic.f);
- }
-
return 0;
fail:
- ff_h264_free_tables(h, 1);
+ ff_h264_free_tables(h);
return AVERROR(ENOMEM);
}
h->avctx = avctx;
h->dequant_coeff_pps = -1;
- h->cur_chroma_format_idc = -1;
h->picture_structure = PICT_FRAME;
h->slice_context_count = 1;
return AVERROR(ENOMEM);
}
+ for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {
+ h->DPB[i].f = av_frame_alloc();
+ if (!h->DPB[i].f)
+ return AVERROR(ENOMEM);
+ }
+
+ h->cur_pic.f = av_frame_alloc();
+ if (!h->cur_pic.f)
+ return AVERROR(ENOMEM);
+
for (i = 0; i < h->nb_slice_ctx; i++)
h->slice_ctx[i].h264 = h;
int i, pics, out_of_order, out_idx;
int invalid = 0, cnt = 0;
- h->cur_pic_ptr->f.pict_type = h->pict_type;
+ h->cur_pic_ptr->f->pict_type = h->pict_type;
if (h->next_output_pic)
return;
return;
}
- cur->f.interlaced_frame = 0;
- cur->f.repeat_pict = 0;
+ cur->f->interlaced_frame = 0;
+ cur->f->repeat_pict = 0;
/* Signal interlacing information externally. */
/* Prioritize picture timing SEI information over used
break;
case SEI_PIC_STRUCT_TOP_FIELD:
case SEI_PIC_STRUCT_BOTTOM_FIELD:
- cur->f.interlaced_frame = 1;
+ cur->f->interlaced_frame = 1;
break;
case SEI_PIC_STRUCT_TOP_BOTTOM:
case SEI_PIC_STRUCT_BOTTOM_TOP:
if (FIELD_OR_MBAFF_PICTURE(h))
- cur->f.interlaced_frame = 1;
+ cur->f->interlaced_frame = 1;
else
// try to flag soft telecine progressive
- cur->f.interlaced_frame = h->prev_interlaced_frame;
+ cur->f->interlaced_frame = h->prev_interlaced_frame;
break;
case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
/* Signal the possibility of telecined film externally
* (pic_struct 5,6). From these hints, let the applications
* decide if they apply deinterlacing. */
- cur->f.repeat_pict = 1;
+ cur->f->repeat_pict = 1;
break;
case SEI_PIC_STRUCT_FRAME_DOUBLING:
- cur->f.repeat_pict = 2;
+ cur->f->repeat_pict = 2;
break;
case SEI_PIC_STRUCT_FRAME_TRIPLING:
- cur->f.repeat_pict = 4;
+ cur->f->repeat_pict = 4;
break;
}
if ((h->sei_ct_type & 3) &&
h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)
- cur->f.interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0;
+ cur->f->interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0;
} else {
/* Derive interlacing flag from used decoding process. */
- cur->f.interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
+ cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
}
- h->prev_interlaced_frame = cur->f.interlaced_frame;
+ h->prev_interlaced_frame = cur->f->interlaced_frame;
if (cur->field_poc[0] != cur->field_poc[1]) {
/* Derive top_field_first from field pocs. */
- cur->f.top_field_first = cur->field_poc[0] < cur->field_poc[1];
+ cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];
} else {
- if (cur->f.interlaced_frame || h->sps.pic_struct_present_flag) {
+ if (cur->f->interlaced_frame || h->sps.pic_struct_present_flag) {
/* Use picture timing SEI information. Even if it is a
* information of a past frame, better than nothing. */
if (h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM ||
h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
- cur->f.top_field_first = 1;
+ cur->f->top_field_first = 1;
else
- cur->f.top_field_first = 0;
+ cur->f->top_field_first = 0;
} else {
/* Most likely progressive */
- cur->f.top_field_first = 0;
+ cur->f->top_field_first = 0;
}
}
h->frame_packing_arrangement_type <= 6 &&
h->content_interpretation_type > 0 &&
h->content_interpretation_type < 3) {
- AVStereo3D *stereo = av_stereo3d_create_side_data(&cur->f);
+ AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f);
if (!stereo)
return;
if (h->sei_display_orientation_present &&
(h->sei_anticlockwise_rotation || h->sei_hflip || h->sei_vflip)) {
double angle = h->sei_anticlockwise_rotation * 360 / (double) (1 << 16);
- AVFrameSideData *rotation = av_frame_new_side_data(&cur->f,
+ AVFrameSideData *rotation = av_frame_new_side_data(cur->f,
AV_FRAME_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 9);
if (!rotation)
h->sei_hflip, h->sei_vflip);
}
+ if (h->sei_reguserdata_afd_present) {
+ AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD,
+ sizeof(uint8_t));
+ if (!sd)
+ return;
+
+ *sd->data = h->active_format_description;
+ h->sei_reguserdata_afd_present = 0;
+ }
+
// FIXME do something with unavailable reference frames
/* Sort B-frames into display order */
cnt += out->poc < h->last_pocs[i];
invalid += out->poc == INT_MIN;
}
- if (!h->mmco_reset && !cur->f.key_frame &&
+ if (!h->mmco_reset && !cur->f->key_frame &&
cnt + invalid == MAX_DELAYED_PIC_COUNT && cnt > 0) {
h->mmco_reset = 2;
if (pics > 1)
h->delayed_pic[pics - 2]->mmco_reset = 2;
}
- if (h->mmco_reset || cur->f.key_frame) {
+ if (h->mmco_reset || cur->f->key_frame) {
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
h->last_pocs[i] = INT_MIN;
cnt = 0;
for (i = 1; i < MAX_DELAYED_PIC_COUNT &&
h->delayed_pic[i] &&
!h->delayed_pic[i - 1]->mmco_reset &&
- !h->delayed_pic[i]->f.key_frame;
+ !h->delayed_pic[i]->f->key_frame;
i++)
if (h->delayed_pic[i]->poc < out->poc) {
out = h->delayed_pic[i];
out_idx = i;
}
if (h->avctx->has_b_frames == 0 &&
- (h->delayed_pic[0]->f.key_frame || h->mmco_reset))
+ (h->delayed_pic[0]->f->key_frame || h->mmco_reset))
h->next_outputed_poc = INT_MIN;
- out_of_order = !out->f.key_frame && !h->mmco_reset &&
+ out_of_order = !out->f->key_frame && !h->mmco_reset &&
(out->poc < h->next_outputed_poc);
if (h->sps.bitstream_restriction_flag &&
} else if (h->low_delay &&
((h->next_outputed_poc != INT_MIN &&
out->poc > h->next_outputed_poc + 2) ||
- cur->f.pict_type == AV_PICTURE_TYPE_B)) {
+ cur->f->pict_type == AV_PICTURE_TYPE_B)) {
h->low_delay = 0;
h->avctx->has_b_frames++;
}
h->next_outputed_poc = INT_MIN;
}
} else {
- if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) {
+ if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f->key_frame) {
h->next_outputed_poc = INT_MIN;
} else {
h->next_outputed_poc = out->poc;
h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI);
}
- if (setup_finished && !h->avctx->hwaccel)
+ if (setup_finished && !h->avctx->hwaccel) {
ff_thread_finish_setup(h->avctx);
+
+ if (h->avctx->active_thread_type & FF_THREAD_FRAME)
+ h->setup_finished = 1;
+ }
}
int ff_pred_weight_table(H264Context *h, H264SliceContext *sl)
ff_h264_flush_change(h);
- if (h->DPB)
- for (i = 0; i < H264_MAX_PICTURE_COUNT; i++)
- ff_h264_unref_picture(h, &h->DPB[i]);
+ for (i = 0; i < H264_MAX_PICTURE_COUNT; i++)
+ ff_h264_unref_picture(h, &h->DPB[i]);
h->cur_pic_ptr = NULL;
ff_h264_unref_picture(h, &h->cur_pic);
h->mb_y = 0;
- ff_h264_free_tables(h, 1);
+ ff_h264_free_tables(h);
h->context_initialized = 0;
}
return profile;
}
-int ff_h264_set_parameter_from_sps(H264Context *h)
-{
- if (h->flags & CODEC_FLAG_LOW_DELAY ||
- (h->sps.bitstream_restriction_flag &&
- !h->sps.num_reorder_frames)) {
- if (h->avctx->has_b_frames > 1 || h->delayed_pic[0])
- av_log(h->avctx, AV_LOG_WARNING, "Delayed frames seen. "
- "Reenabling low delay requires a codec flush.\n");
- else
- h->low_delay = 1;
- }
-
- if (h->avctx->has_b_frames < 2)
- h->avctx->has_b_frames = !h->low_delay;
-
- if (h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
- h->cur_chroma_format_idc != h->sps.chroma_format_idc) {
- if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) {
- h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
- h->cur_chroma_format_idc = h->sps.chroma_format_idc;
- h->pixel_shift = h->sps.bit_depth_luma > 8;
-
- ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma,
- h->sps.chroma_format_idc);
- ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
- ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma);
- ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma,
- h->sps.chroma_format_idc);
- ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma);
- } else {
- av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth %d\n",
- h->sps.bit_depth_luma);
- return AVERROR_INVALIDDATA;
- }
- }
- return 0;
-}
-
int ff_set_ref_count(H264Context *h, H264SliceContext *sl)
{
int ref_count[2], list_count;
((1 << h->sps.log2_max_frame_num) - 1);
}
- h->cur_pic_ptr->f.key_frame |=
+ h->cur_pic_ptr->f->key_frame |=
(h->nal_unit_type == NAL_IDR_SLICE) ||
(h->sei_recovery_frame_cnt >= 0);
ff_h264_decode_seq_parameter_set(h);
}
- ret = ff_h264_set_parameter_from_sps(h);
- if (ret < 0)
- goto end;
-
break;
case NAL_PPS:
init_get_bits(&h->gb, ptr, bit_length);
int ret;
h->flags = avctx->flags;
+ h->setup_finished = 0;
/* end of stream, output what is still in the buffers */
out:
out_idx = 0;
for (i = 1;
h->delayed_pic[i] &&
- !h->delayed_pic[i]->f.key_frame &&
+ !h->delayed_pic[i]->f->key_frame &&
!h->delayed_pic[i]->mmco_reset;
i++)
if (h->delayed_pic[i]->poc < out->poc) {
h->delayed_pic[i] = h->delayed_pic[i + 1];
if (out) {
- ret = output_frame(h, pict, &out->f);
+ ret = output_frame(h, pict, out->f);
if (ret < 0)
return ret;
*got_frame = 1;
if (h->next_output_pic && ((avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT) ||
h->next_output_pic->recovered)) {
if (!h->next_output_pic->recovered)
- h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT;
+ h->next_output_pic->f->flags |= AV_FRAME_FLAG_CORRUPT;
- ret = output_frame(h, pict, &h->next_output_pic->f);
+ ret = output_frame(h, pict, h->next_output_pic->f);
if (ret < 0)
return ret;
*got_frame = 1;
{
int i;
- ff_h264_free_tables(h, 1); // FIXME cleanup init stuff perhaps
+ ff_h264_free_tables(h);
+ for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {
+ ff_h264_unref_picture(h, &h->DPB[i]);
+ av_frame_free(&h->DPB[i].f);
+ }
+
+ h->cur_pic_ptr = NULL;
+
+ for (i = 0; i < h->nb_slice_ctx; i++)
+ av_freep(&h->slice_ctx[i].rbsp_buffer);
av_freep(&h->slice_ctx);
h->nb_slice_ctx = 0;
ff_h264_free_context(h);
ff_h264_unref_picture(h, &h->cur_pic);
+ av_frame_free(&h->cur_pic.f);
return 0;
}