I've been trying to copy a AVFrame just like what was answered in ffmpeg: make a copy from a decoded frame (AVFrame). However but I can't seem to get it to get a positive return code from av_frame_copy().
Here is basically what I'm doing:
AVFrame *copyFrame = NULL;
copyFrame = av_frame_alloc();
int return_code = av_frame_copy(copyFrame, originalFrame);
if(return_code < 0){
fprintf(stderr, "av_frame_copy failed with return code %d\n", return_code);
return(1);
}
If it helps, the return code I get from av_frame_copy is -22.
If you read the documentation for av_frame_copy
, it says "This function does not allocate anything, dst must be already initialized and allocated with the same parameters as src."
av_frame_alloc
doesn't do anything other than allocate the AVFrame
struct and initialize it to some default values. Most importantly, it doesn't allocate buffers for the frame data or prepare the frame to be used. av_frame_copy
is failing because the destination frame doesn't have the correct pixel format set or buffers allocated.
If you want to clone a frame (by incrementing its reference counter, not creating a deep copy) you can use av_frame_clone
or av_frame_ref
.
If you want to move the frame you can use av_frame_move_ref
.
But you probably want to do a proper deep copy. In that case, you can look at the source code of the av_frame_make_writable
. This function makes a deep copy of the frame if it isn't writeable, so we can use the same logic to make a deep copy of the frame here:
AVFrame *copyFrame = av_frame_alloc();
copyFrame->format = frame->format;
copyFrame->width = frame->width;
copyFrame->height = frame->height;
copyFrame->channels = frame->channels;
copyFrame->channel_layout = frame->channel_layout;
copyFrame->nb_samples = frame->nb_samples;
av_frame_get_buffer(copyFrame, 32);
av_frame_copy(copyFrame, frame);
av_frame_copy_props(copyFrame, frame);
Note that I haven't checked for errors in the functions I've called. You should do that in your real code. I omitted it here for brevity.
I had AVFrame * on GPU. This worked for me:
int ret;
AVFrame *dst;
dst = av_frame_alloc();
memcpy(dst,src,sizeof(AVFrame));
dst->format = src->format;
dst->width = src->width;
dst->height = src->height;
dst->channels = src->channels;
dst->channel_layout = src->channel_layout;
dst->nb_samples = src->nb_samples;
dst->extended_data = src->extended_data;
memcpy(dst->data, src->data, sizeof(src->data));
ret = av_frame_copy_props(dst, src);
if (ret < 0) { av_frame_unref(dst);}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With