int ff_h264_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { H264Context *h = dst->priv_data, *h1 = src->priv_data; int inited = h->context_initialized, err = 0; int need_reinit = 0; int i, ret; if (dst == src || !h1->context_initialized) return 0; if (!h1->ps.sps) return AVERROR_INVALIDDATA; if (inited && (h->width != h1->width || h->height != h1->height || h->mb_width != h1->mb_width || h->mb_height != h1->mb_height || !h->ps.sps || h->ps.sps->bit_depth_luma != h1->ps.sps->bit_depth_luma || h->ps.sps->chroma_format_idc != h1->ps.sps->chroma_format_idc || h->ps.sps->colorspace != h1->ps.sps->colorspace)) { need_reinit = 1; } // SPS/PPS for (i = 0; i < FF_ARRAY_ELEMS(h->ps.sps_list); i++) { av_buffer_unref(&h->ps.sps_list[i]); if (h1->ps.sps_list[i]) { h->ps.sps_list[i] = av_buffer_ref(h1->ps.sps_list[i]); if (!h->ps.sps_list[i]) return AVERROR(ENOMEM); } } for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list); i++) { av_buffer_unref(&h->ps.pps_list[i]); if (h1->ps.pps_list[i]) { h->ps.pps_list[i] = av_buffer_ref(h1->ps.pps_list[i]); if (!h->ps.pps_list[i]) return AVERROR(ENOMEM); } } h->ps.sps = h1->ps.sps; if (need_reinit || !inited) { h->width = h1->width; h->height = h1->height; h->mb_height = h1->mb_height; h->mb_width = h1->mb_width; h->mb_num = h1->mb_num; h->mb_stride = h1->mb_stride; h->b_stride = h1->b_stride; if ((err = h264_slice_header_init(h)) < 0) { av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed"); return err; } /* copy block_offset since frame_start may not be called */ memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset)); } h->avctx->coded_height = h1->avctx->coded_height; h->avctx->coded_width = h1->avctx->coded_width; h->avctx->width = h1->avctx->width; h->avctx->height = h1->avctx->height; h->coded_picture_number = h1->coded_picture_number; h->first_field = h1->first_field; h->picture_structure = h1->picture_structure; h->droppable = h1->droppable; h->low_delay = h1->low_delay; for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) { ff_h264_unref_picture(h, &h->DPB[i]); if (h1->DPB[i].f->buf[0] && (ret = ff_h264_ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0) return ret; } h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1); ff_h264_unref_picture(h, &h->cur_pic); if (h1->cur_pic.f->buf[0]) { ret = ff_h264_ref_picture(h, &h->cur_pic, &h1->cur_pic); if (ret < 0) return ret; } h->enable_er = h1->enable_er; h->workaround_bugs = h1->workaround_bugs; h->low_delay = h1->low_delay; h->droppable = h1->droppable; // extradata/NAL handling h->is_avc = h1->is_avc; h->nal_length_size = h1->nal_length_size; // POC timing copy_fields(h, h1, poc_lsb, current_slice); copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1); copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1); copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT + 2, h, h1); if (!h->cur_pic_ptr) return 0; if (!h->droppable) { err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); h->prev_poc_msb = h->poc_msb; h->prev_poc_lsb = h->poc_lsb; } h->prev_frame_num_offset = h->frame_num_offset; h->prev_frame_num = h->frame_num; h->recovery_frame = h1->recovery_frame; h->frame_recovered = h1->frame_recovered; return err; }