avfilter/lavfutils: Avoid copying frame in ff_load_image()
Return the data in an AVFrame instead. This is what several users
({find,cover}_rect*) want anyway. This also avoids accessing
AVFrame.format (an int) via an enum AVPixelFormat*.
*: This commit actually avoids two frame copies For find_rect:
av_frame_clone() contained an implicit alloc+copy.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
+13
-15
@@ -404,33 +404,31 @@ static int init_axis_empty(ShowCQTContext *s)
|
||||
|
||||
static int init_axis_from_file(ShowCQTContext *s)
|
||||
{
|
||||
uint8_t *tmp_data[4] = { NULL };
|
||||
int tmp_linesize[4];
|
||||
enum AVPixelFormat tmp_format;
|
||||
int tmp_w, tmp_h, ret;
|
||||
|
||||
if ((ret = ff_load_image(tmp_data, tmp_linesize, &tmp_w, &tmp_h, &tmp_format,
|
||||
s->axisfile, s->ctx)) < 0)
|
||||
goto error;
|
||||
AVFrame *tmp_frame;
|
||||
int ret = ff_load_image(&tmp_frame, s->axisfile, s->ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = AVERROR(ENOMEM);
|
||||
if (!(s->axis_frame = av_frame_alloc()))
|
||||
goto error;
|
||||
|
||||
if ((ret = ff_scale_image(s->axis_frame->data, s->axis_frame->linesize, s->width, s->axis_h,
|
||||
convert_axis_pixel_format(s->format), tmp_data, tmp_linesize, tmp_w, tmp_h,
|
||||
tmp_format, s->ctx)) < 0)
|
||||
ret = ff_scale_image(s->axis_frame->data, s->axis_frame->linesize, s->width, s->axis_h,
|
||||
convert_axis_pixel_format(s->format),
|
||||
tmp_frame->data, tmp_frame->linesize, tmp_frame->width, tmp_frame->height,
|
||||
tmp_frame->format, s->ctx);
|
||||
if (ret < 0) {
|
||||
av_frame_free(&s->axis_frame);
|
||||
goto error;
|
||||
}
|
||||
|
||||
s->axis_frame->width = s->width;
|
||||
s->axis_frame->height = s->axis_h;
|
||||
s->axis_frame->format = convert_axis_pixel_format(s->format);
|
||||
av_freep(tmp_data);
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
error:
|
||||
av_frame_free(&s->axis_frame);
|
||||
av_freep(tmp_data);
|
||||
av_frame_free(&tmp_frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+13
-23
@@ -21,9 +21,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
@@ -31,8 +30,7 @@
|
||||
|
||||
#include "lavfutils.h"
|
||||
|
||||
int ff_load_image(uint8_t *data[4], int linesize[4],
|
||||
int *w, int *h, enum AVPixelFormat *pix_fmt,
|
||||
int ff_load_image(struct AVFrame **outframe,
|
||||
const char *filename, void *log_ctx)
|
||||
{
|
||||
const AVInputFormat *iformat = NULL;
|
||||
@@ -45,6 +43,8 @@ int ff_load_image(uint8_t *data[4], int linesize[4],
|
||||
AVPacket pkt;
|
||||
AVDictionary *opt=NULL;
|
||||
|
||||
*outframe = NULL;
|
||||
|
||||
iformat = av_find_input_format("image2pipe");
|
||||
if ((ret = avformat_open_input(&format_ctx, filename, iformat, NULL)) < 0) {
|
||||
av_log(log_ctx, AV_LOG_ERROR,
|
||||
@@ -84,12 +84,6 @@ int ff_load_image(uint8_t *data[4], int linesize[4],
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(frame = av_frame_alloc()) ) {
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_read_frame(format_ctx, &pkt);
|
||||
if (ret < 0) {
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Failed to read frame from file\n");
|
||||
@@ -103,27 +97,23 @@ int ff_load_image(uint8_t *data[4], int linesize[4],
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(codec_ctx, frame);
|
||||
if (ret < 0) {
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from file\n");
|
||||
if (!(frame = av_frame_alloc()) ) {
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*w = frame->width;
|
||||
*h = frame->height;
|
||||
*pix_fmt = frame->format;
|
||||
|
||||
if ((ret = av_image_alloc(data, linesize, *w, *h, *pix_fmt, 16)) < 0)
|
||||
ret = avcodec_receive_frame(codec_ctx, frame);
|
||||
if (ret < 0) {
|
||||
av_frame_free(&frame);
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from file\n");
|
||||
goto end;
|
||||
ret = 0;
|
||||
|
||||
av_image_copy2(data, linesize, frame->data, frame->linesize,
|
||||
*pix_fmt, *w, *h);
|
||||
}
|
||||
*outframe = frame;
|
||||
|
||||
end:
|
||||
avcodec_free_context(&codec_ctx);
|
||||
avformat_close_input(&format_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_dict_free(&opt);
|
||||
|
||||
if (ret < 0)
|
||||
|
||||
@@ -24,21 +24,18 @@
|
||||
#ifndef AVFILTER_LAVFUTILS_H
|
||||
#define AVFILTER_LAVFUTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libavutil/pixfmt.h"
|
||||
struct AVFrame;
|
||||
|
||||
/**
|
||||
* Load image from filename and put the resulting image in data.
|
||||
* Load image from filename and put the resulting image in an AVFrame.
|
||||
*
|
||||
* @param w pointer to the width of the loaded image
|
||||
* @param h pointer to the height of the loaded image
|
||||
* @param pix_fmt pointer to the pixel format of the loaded image
|
||||
* @param outframe pointer to a pointer to an AVFrame; *outframe will
|
||||
* point to a new allocated AVFrame on success
|
||||
* @param filename the name of the image file to load
|
||||
* @param log_ctx log context
|
||||
* @return >= 0 in case of success, a negative error code otherwise.
|
||||
*/
|
||||
int ff_load_image(uint8_t *data[4], int linesize[4],
|
||||
int *w, int *h, enum AVPixelFormat *pix_fmt,
|
||||
int ff_load_image(struct AVFrame **outframe,
|
||||
const char *filename, void *log_ctx);
|
||||
|
||||
#endif /* AVFILTER_LAVFUTILS_H */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* @todo switch to dualinput
|
||||
*/
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "filters.h"
|
||||
#include "video.h"
|
||||
@@ -189,8 +188,6 @@ static av_cold void uninit(AVFilterContext *ctx)
|
||||
{
|
||||
CoverContext *cover = ctx->priv;
|
||||
|
||||
if (cover->cover_frame)
|
||||
av_freep(&cover->cover_frame->data[0]);
|
||||
av_frame_free(&cover->cover_frame);
|
||||
}
|
||||
|
||||
@@ -205,13 +202,8 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
cover->cover_frame = av_frame_alloc();
|
||||
if (!cover->cover_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if ((ret = ff_load_image(cover->cover_frame->data, cover->cover_frame->linesize,
|
||||
&cover->cover_frame->width, &cover->cover_frame->height,
|
||||
&cover->cover_frame->format, cover->cover_filename, ctx)) < 0)
|
||||
ret = ff_load_image(&cover->cover_frame, cover->cover_filename, ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (cover->cover_frame->format != AV_PIX_FMT_YUV420P && cover->cover_frame->format != AV_PIX_FMT_YUVJ420P) {
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* @todo switch to dualinput
|
||||
*/
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include "filters.h"
|
||||
@@ -250,8 +249,6 @@ static av_cold void uninit(AVFilterContext *ctx)
|
||||
av_frame_free(&foc->haystack_frame[i]);
|
||||
}
|
||||
|
||||
if (foc->obj_frame)
|
||||
av_freep(&foc->obj_frame->data[0]);
|
||||
av_frame_free(&foc->obj_frame);
|
||||
}
|
||||
|
||||
@@ -265,13 +262,8 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
foc->obj_frame = av_frame_alloc();
|
||||
if (!foc->obj_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if ((ret = ff_load_image(foc->obj_frame->data, foc->obj_frame->linesize,
|
||||
&foc->obj_frame->width, &foc->obj_frame->height,
|
||||
&foc->obj_frame->format, foc->obj_filename, ctx)) < 0)
|
||||
ret = ff_load_image(&foc->obj_frame, foc->obj_filename, ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (foc->obj_frame->format != AV_PIX_FMT_GRAY8) {
|
||||
|
||||
@@ -207,18 +207,22 @@ static int load_mask(uint8_t **mask, int *w, int *h,
|
||||
const char *filename, void *log_ctx)
|
||||
{
|
||||
int ret;
|
||||
enum AVPixelFormat pix_fmt;
|
||||
uint8_t *src_data[4], *gray_data[4];
|
||||
int src_linesize[4], gray_linesize[4];
|
||||
uint8_t *gray_data[4];
|
||||
AVFrame *src_frame;
|
||||
int gray_linesize[4];
|
||||
|
||||
/* load image from file */
|
||||
if ((ret = ff_load_image(src_data, src_linesize, w, h, &pix_fmt, filename, log_ctx)) < 0)
|
||||
ret = ff_load_image(&src_frame, filename, log_ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*w = src_frame->width;
|
||||
*h = src_frame->height;
|
||||
|
||||
/* convert the image to GRAY8 */
|
||||
if ((ret = ff_scale_image(gray_data, gray_linesize, *w, *h, AV_PIX_FMT_GRAY8,
|
||||
src_data, src_linesize, *w, *h, pix_fmt,
|
||||
log_ctx)) < 0)
|
||||
ret = ff_scale_image(gray_data, gray_linesize, *w, *h, AV_PIX_FMT_GRAY8,
|
||||
src_frame->data, src_frame->linesize, *w, *h,
|
||||
src_frame->format, log_ctx);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
/* copy mask to a newly allocated array */
|
||||
@@ -230,8 +234,8 @@ static int load_mask(uint8_t **mask, int *w, int *h,
|
||||
av_image_copy_plane(*mask, *w, gray_data[0], gray_linesize[0], *w, *h);
|
||||
|
||||
end:
|
||||
av_freep(&src_data[0]);
|
||||
av_freep(&gray_data[0]);
|
||||
av_frame_free(&src_frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user