AVFrameSideData *ffmpeg_garbage(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf) { AVFrameSideData *sd = av_frame_new_side_data(frame, type, buf->size); if (sd) memcpy(sd->data, buf->data, buf->size); av_buffer_unref(&buf); return sd; }
AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame) { AVFrameSideData *side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_STEREO3D, sizeof(AVStereo3D)); if (!side_data) return NULL; return (AVStereo3D *)side_data->data; }
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AVPacket *pkt = avctx->internal->last_pkt_props; int i; struct { enum AVPacketSideDataType packet; enum AVFrameSideDataType frame; } sd[] = { { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, { AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL }, { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, }; frame->color_primaries = avctx->color_primaries; frame->color_trc = avctx->color_trc; frame->colorspace = avctx->colorspace; frame->color_range = avctx->color_range; frame->chroma_location = avctx->chroma_sample_location; frame->reordered_opaque = avctx->reordered_opaque; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS frame->pkt_pts = pkt->pts; FF_ENABLE_DEPRECATION_WARNINGS #endif frame->pts = pkt->pts; for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { int size; uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); if (packet_sd) { AVFrameSideData *frame_sd = av_frame_new_side_data(frame, sd[i].frame, size); if (!frame_sd) return AVERROR(ENOMEM); memcpy(frame_sd->data, packet_sd, size); } } return 0; }
int av_frame_copy_props(AVFrame *dst, const AVFrame *src) { int i; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; dst->sample_aspect_ratio = src->sample_aspect_ratio; dst->pts = src->pts; dst->repeat_pict = src->repeat_pict; dst->interlaced_frame = src->interlaced_frame; dst->top_field_first = src->top_field_first; dst->palette_has_changed = src->palette_has_changed; dst->sample_rate = src->sample_rate; dst->opaque = src->opaque; dst->pkt_pts = src->pkt_pts; dst->pkt_dts = src->pkt_dts; dst->reordered_opaque = src->reordered_opaque; dst->quality = src->quality; dst->coded_picture_number = src->coded_picture_number; dst->display_picture_number = src->display_picture_number; dst->flags = src->flags; memcpy(dst->error, src->error, sizeof(dst->error)); for (i = 0; i < src->nb_side_data; i++) { const AVFrameSideData *sd_src = src->side_data[i]; AVFrameSideData *sd_dst = av_frame_new_side_data(dst, sd_src->type, sd_src->size); if (!sd_dst) { for (i = 0; i < dst->nb_side_data; i++) { av_freep(&dst->side_data[i]->data); av_freep(&dst->side_data[i]); av_dict_free(&dst->side_data[i]->metadata); } av_freep(&dst->side_data); return AVERROR(ENOMEM); } memcpy(sd_dst->data, sd_src->data, sd_src->size); av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); } return 0; }
int av_frame_copy_props(AVFrame *dst, const AVFrame *src) { int i; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; dst->sample_aspect_ratio = src->sample_aspect_ratio; dst->pts = src->pts; dst->repeat_pict = src->repeat_pict; dst->interlaced_frame = src->interlaced_frame; dst->top_field_first = src->top_field_first; dst->palette_has_changed = src->palette_has_changed; dst->sample_rate = src->sample_rate; dst->opaque = src->opaque; #if FF_API_AVFRAME_LAVC dst->type = src->type; #endif dst->pkt_pts = src->pkt_pts; dst->pkt_dts = src->pkt_dts; dst->pkt_pos = src->pkt_pos; dst->pkt_size = src->pkt_size; dst->pkt_duration = src->pkt_duration; dst->reordered_opaque = src->reordered_opaque; dst->quality = src->quality; dst->best_effort_timestamp = src->best_effort_timestamp; dst->coded_picture_number = src->coded_picture_number; dst->display_picture_number = src->display_picture_number; dst->flags = src->flags; dst->decode_error_flags = src->decode_error_flags; dst->colorspace = src->colorspace; dst->color_range = src->color_range; av_dict_copy(&dst->metadata, src->metadata, 0); memcpy(dst->error, src->error, sizeof(dst->error)); for (i = 0; i < src->nb_side_data; i++) { const AVFrameSideData *sd_src = src->side_data[i]; AVFrameSideData *sd_dst = av_frame_new_side_data(dst, sd_src->type, sd_src->size); if (!sd_dst) { for (i = 0; i < dst->nb_side_data; i++) { av_freep(&dst->side_data[i]->data); av_freep(&dst->side_data[i]); av_dict_free(&dst->side_data[i]->metadata); } av_freep(&dst->side_data); return AVERROR(ENOMEM); } memcpy(sd_dst->data, sd_src->data, sd_src->size); av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); } dst->qscale_table = NULL; dst->qstride = 0; dst->qscale_type = 0; if (src->qp_table_buf) { dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); if (dst->qp_table_buf) { dst->qscale_table = dst->qp_table_buf->data; dst->qstride = src->qstride; dst->qscale_type = src->qscale_type; } } return 0; }
static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) { int i; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; dst->sample_aspect_ratio = src->sample_aspect_ratio; dst->pts = src->pts; dst->repeat_pict = src->repeat_pict; dst->interlaced_frame = src->interlaced_frame; dst->top_field_first = src->top_field_first; dst->palette_has_changed = src->palette_has_changed; dst->sample_rate = src->sample_rate; dst->opaque = src->opaque; dst->pkt_pts = src->pkt_pts; dst->pkt_dts = src->pkt_dts; dst->pkt_pos = src->pkt_pos; dst->pkt_size = src->pkt_size; dst->pkt_duration = src->pkt_duration; dst->reordered_opaque = src->reordered_opaque; dst->quality = src->quality; dst->best_effort_timestamp = src->best_effort_timestamp; dst->coded_picture_number = src->coded_picture_number; dst->display_picture_number = src->display_picture_number; dst->flags = src->flags; dst->decode_error_flags = src->decode_error_flags; dst->color_primaries = src->color_primaries; dst->color_trc = src->color_trc; dst->colorspace = src->colorspace; dst->color_range = src->color_range; dst->chroma_location = src->chroma_location; av_dict_copy(&dst->metadata, src->metadata, 0); #if FF_API_ERROR_FRAME FF_DISABLE_DEPRECATION_WARNINGS memcpy(dst->error, src->error, sizeof(dst->error)); FF_ENABLE_DEPRECATION_WARNINGS #endif for (i = 0; i < src->nb_side_data; i++) { const AVFrameSideData *sd_src = src->side_data[i]; AVFrameSideData *sd_dst; if ( sd_src->type == AV_FRAME_DATA_PANSCAN && (src->width != dst->width || src->height != dst->height)) continue; if (force_copy) { sd_dst = av_frame_new_side_data(dst, sd_src->type, sd_src->size); if (!sd_dst) { wipe_side_data(dst); return AVERROR(ENOMEM); } memcpy(sd_dst->data, sd_src->data, sd_src->size); } else { sd_dst = av_frame_new_side_data(dst, sd_src->type, 0); if (!sd_dst) { wipe_side_data(dst); return AVERROR(ENOMEM); } sd_dst->buf = av_buffer_ref(sd_src->buf); if (!sd_dst->buf) { wipe_side_data(dst); return AVERROR(ENOMEM); } sd_dst->data = sd_dst->buf->data; sd_dst->size = sd_dst->buf->size; } av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); } #if FF_API_FRAME_QP FF_DISABLE_DEPRECATION_WARNINGS dst->qscale_table = NULL; dst->qstride = 0; dst->qscale_type = 0; av_buffer_unref(&dst->qp_table_buf); if (src->qp_table_buf) { dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); if (dst->qp_table_buf) { dst->qscale_table = dst->qp_table_buf->data; dst->qstride = src->qstride; dst->qscale_type = src->qscale_type; } } FF_ENABLE_DEPRECATION_WARNINGS #endif return 0; }
static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; MEContext *s = ctx->priv; AVMotionEstContext *me_ctx = &s->me_ctx; AVFrameSideData *sd; AVFrame *out; int mb_x, mb_y, dir; int32_t mv_count = 0; int ret; if (frame->pts == AV_NOPTS_VALUE) { ret = ff_filter_frame(ctx->outputs[0], frame); return ret; } av_frame_free(&s->prev); s->prev = s->cur; s->cur = s->next; s->next = frame; s->mv_table[2] = memcpy(s->mv_table[2], s->mv_table[1], sizeof(*s->mv_table[1]) * s->b_count); s->mv_table[1] = memcpy(s->mv_table[1], s->mv_table[0], sizeof(*s->mv_table[0]) * s->b_count); if (!s->cur) { s->cur = av_frame_clone(frame); if (!s->cur) return AVERROR(ENOMEM); } if (!s->prev) return 0; out = av_frame_clone(s->cur); if (!out) return AVERROR(ENOMEM); sd = av_frame_new_side_data(out, AV_FRAME_DATA_MOTION_VECTORS, 2 * s->b_count * sizeof(AVMotionVector)); if (!sd) { av_frame_free(&out); return AVERROR(ENOMEM); } me_ctx->data_cur = s->cur->data[0]; me_ctx->linesize = s->cur->linesize[0]; for (dir = 0; dir < 2; dir++) { me_ctx->data_ref = (dir ? s->next : s->prev)->data[0]; if (s->method == AV_ME_METHOD_DS) SEARCH_MV(ds); else if (s->method == AV_ME_METHOD_ESA) SEARCH_MV(esa); else if (s->method == AV_ME_METHOD_FSS) SEARCH_MV(fss); else if (s->method == AV_ME_METHOD_NTSS) SEARCH_MV(ntss); else if (s->method == AV_ME_METHOD_TDLS) SEARCH_MV(tdls); else if (s->method == AV_ME_METHOD_TSS) SEARCH_MV(tss); else if (s->method == AV_ME_METHOD_HEXBS) SEARCH_MV(hexbs); else if (s->method == AV_ME_METHOD_UMH) { for (mb_y = 0; mb_y < s->b_height; mb_y++) for (mb_x = 0; mb_x < s->b_width; mb_x++) { const int mb_i = mb_x + mb_y * s->b_width; const int x_mb = mb_x << s->log2_mb_size; const int y_mb = mb_y << s->log2_mb_size; int mv[2] = {x_mb, y_mb}; AVMotionEstPredictor *preds = me_ctx->preds; preds[0].nb = 0; ADD_PRED(preds[0], 0, 0); //left mb in current frame if (mb_x > 0) ADD_PRED(preds[0], s->mv_table[0][mb_i - 1][dir][0], s->mv_table[0][mb_i - 1][dir][1]); if (mb_y > 0) { //top mb in current frame ADD_PRED(preds[0], s->mv_table[0][mb_i - s->b_width][dir][0], s->mv_table[0][mb_i - s->b_width][dir][1]); //top-right mb in current frame if (mb_x + 1 < s->b_width) ADD_PRED(preds[0], s->mv_table[0][mb_i - s->b_width + 1][dir][0], s->mv_table[0][mb_i - s->b_width + 1][dir][1]); //top-left mb in current frame else if (mb_x > 0) ADD_PRED(preds[0], s->mv_table[0][mb_i - s->b_width - 1][dir][0], s->mv_table[0][mb_i - s->b_width - 1][dir][1]); } //median predictor if (preds[0].nb == 4) { me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]); me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]); } else if (preds[0].nb == 3) { me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]); me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]); } else if (preds[0].nb == 2) { me_ctx->pred_x = preds[0].mvs[1][0]; me_ctx->pred_y = preds[0].mvs[1][1]; } else { me_ctx->pred_x = 0; me_ctx->pred_y = 0; } ff_me_search_umh(me_ctx, x_mb, y_mb, mv); s->mv_table[0][mb_i][dir][0] = mv[0] - x_mb; s->mv_table[0][mb_i][dir][1] = mv[1] - y_mb; add_mv_data(((AVMotionVector *) sd->data) + mv_count++, me_ctx->mb_size, x_mb, y_mb, mv[0], mv[1], dir); } } else if (s->method == AV_ME_METHOD_EPZS) { for (mb_y = 0; mb_y < s->b_height; mb_y++) for (mb_x = 0; mb_x < s->b_width; mb_x++) { const int mb_i = mb_x + mb_y * s->b_width; const int x_mb = mb_x << s->log2_mb_size; const int y_mb = mb_y << s->log2_mb_size; int mv[2] = {x_mb, y_mb}; AVMotionEstPredictor *preds = me_ctx->preds; preds[0].nb = 0; preds[1].nb = 0; ADD_PRED(preds[0], 0, 0); //left mb in current frame if (mb_x > 0) ADD_PRED(preds[0], s->mv_table[0][mb_i - 1][dir][0], s->mv_table[0][mb_i - 1][dir][1]); //top mb in current frame if (mb_y > 0) ADD_PRED(preds[0], s->mv_table[0][mb_i - s->b_width][dir][0], s->mv_table[0][mb_i - s->b_width][dir][1]); //top-right mb in current frame if (mb_y > 0 && mb_x + 1 < s->b_width) ADD_PRED(preds[0], s->mv_table[0][mb_i - s->b_width + 1][dir][0], s->mv_table[0][mb_i - s->b_width + 1][dir][1]); //median predictor if (preds[0].nb == 4) { me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]); me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]); } else if (preds[0].nb == 3) { me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]); me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]); } else if (preds[0].nb == 2) { me_ctx->pred_x = preds[0].mvs[1][0]; me_ctx->pred_y = preds[0].mvs[1][1]; } else { me_ctx->pred_x = 0; me_ctx->pred_y = 0; } //collocated mb in prev frame ADD_PRED(preds[0], s->mv_table[1][mb_i][dir][0], s->mv_table[1][mb_i][dir][1]); //accelerator motion vector of collocated block in prev frame ADD_PRED(preds[1], s->mv_table[1][mb_i][dir][0] + (s->mv_table[1][mb_i][dir][0] - s->mv_table[2][mb_i][dir][0]), s->mv_table[1][mb_i][dir][1] + (s->mv_table[1][mb_i][dir][1] - s->mv_table[2][mb_i][dir][1])); //left mb in prev frame if (mb_x > 0) ADD_PRED(preds[1], s->mv_table[1][mb_i - 1][dir][0], s->mv_table[1][mb_i - 1][dir][1]); //top mb in prev frame if (mb_y > 0) ADD_PRED(preds[1], s->mv_table[1][mb_i - s->b_width][dir][0], s->mv_table[1][mb_i - s->b_width][dir][1]); //right mb in prev frame if (mb_x + 1 < s->b_width) ADD_PRED(preds[1], s->mv_table[1][mb_i + 1][dir][0], s->mv_table[1][mb_i + 1][dir][1]); //bottom mb in prev frame if (mb_y + 1 < s->b_height) ADD_PRED(preds[1], s->mv_table[1][mb_i + s->b_width][dir][0], s->mv_table[1][mb_i + s->b_width][dir][1]); ff_me_search_epzs(me_ctx, x_mb, y_mb, mv); s->mv_table[0][mb_i][dir][0] = mv[0] - x_mb; s->mv_table[0][mb_i][dir][1] = mv[1] - y_mb; add_mv_data(((AVMotionVector *) sd->data) + mv_count++, s->mb_size, x_mb, y_mb, mv[0], mv[1], dir); } } } return ff_filter_frame(ctx->outputs[0], out); }