forked from FFmpeg/FFmpeg
lavd/lavfi: upgrade to AVFrame.
Fix a memory leak because the compat implementation of AV_BUFFERSINK_FLAG_PEEK is not identical to the previous one.
This commit is contained in:
parent
a9b424879f
commit
b90912be68
1 changed files with 28 additions and 21 deletions
|
@ -51,6 +51,7 @@ typedef struct {
|
|||
int *sink_stream_map;
|
||||
int *sink_eof;
|
||||
int *stream_sink_map;
|
||||
AVFrame *decoded_frame;
|
||||
} LavfiContext;
|
||||
|
||||
static int *create_all_formats(int n)
|
||||
|
@ -83,6 +84,7 @@ av_cold static int lavfi_read_close(AVFormatContext *avctx)
|
|||
av_freep(&lavfi->stream_sink_map);
|
||||
av_freep(&lavfi->sinks);
|
||||
avfilter_graph_free(&lavfi->graph);
|
||||
av_frame_free(&lavfi->decoded_frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -300,6 +302,9 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx)
|
|||
}
|
||||
}
|
||||
|
||||
if (!(lavfi->decoded_frame = av_frame_alloc()))
|
||||
FAIL(AVERROR(ENOMEM));
|
||||
|
||||
end:
|
||||
av_free(pix_fmts);
|
||||
avfilter_inout_free(&input_links);
|
||||
|
@ -314,8 +319,9 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
|||
LavfiContext *lavfi = avctx->priv_data;
|
||||
double min_pts = DBL_MAX;
|
||||
int stream_idx, min_pts_sink_idx = 0;
|
||||
AVFilterBufferRef *ref;
|
||||
AVFrame *frame = lavfi->decoded_frame;
|
||||
AVPicture pict;
|
||||
AVDictionary *frame_metadata;
|
||||
int ret, i;
|
||||
int size = 0;
|
||||
|
||||
|
@ -329,16 +335,17 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
|||
if (lavfi->sink_eof[i])
|
||||
continue;
|
||||
|
||||
ret = av_buffersink_get_buffer_ref(lavfi->sinks[i],
|
||||
&ref, AV_BUFFERSINK_FLAG_PEEK);
|
||||
ret = av_buffersink_get_frame_flags(lavfi->sinks[i], frame,
|
||||
AV_BUFFERSINK_FLAG_PEEK);
|
||||
if (ret == AVERROR_EOF) {
|
||||
av_dlog(avctx, "EOF sink_idx:%d\n", i);
|
||||
lavfi->sink_eof[i] = 1;
|
||||
continue;
|
||||
} else if (ret < 0)
|
||||
return ret;
|
||||
d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q);
|
||||
d = av_rescale_q(frame->pts, tb, AV_TIME_BASE_Q);
|
||||
av_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
|
||||
av_frame_unref(frame);
|
||||
|
||||
if (d < min_pts) {
|
||||
min_pts = d;
|
||||
|
@ -350,35 +357,35 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
|||
|
||||
av_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx);
|
||||
|
||||
av_buffersink_get_buffer_ref(lavfi->sinks[min_pts_sink_idx], &ref, 0);
|
||||
av_buffersink_get_frame_flags(lavfi->sinks[min_pts_sink_idx], frame, 0);
|
||||
stream_idx = lavfi->sink_stream_map[min_pts_sink_idx];
|
||||
|
||||
if (ref->video) {
|
||||
size = avpicture_get_size(ref->format, ref->video->w, ref->video->h);
|
||||
if (frame->width /* FIXME best way of testing a video */) {
|
||||
size = avpicture_get_size(frame->format, frame->width, frame->height);
|
||||
if ((ret = av_new_packet(pkt, size)) < 0)
|
||||
return ret;
|
||||
|
||||
memcpy(pict.data, ref->data, 4*sizeof(ref->data[0]));
|
||||
memcpy(pict.linesize, ref->linesize, 4*sizeof(ref->linesize[0]));
|
||||
memcpy(pict.data, frame->data, 4*sizeof(frame->data[0]));
|
||||
memcpy(pict.linesize, frame->linesize, 4*sizeof(frame->linesize[0]));
|
||||
|
||||
avpicture_layout(&pict, ref->format, ref->video->w,
|
||||
ref->video->h, pkt->data, size);
|
||||
} else if (ref->audio) {
|
||||
size = ref->audio->nb_samples *
|
||||
av_get_bytes_per_sample(ref->format) *
|
||||
av_get_channel_layout_nb_channels(ref->audio->channel_layout);
|
||||
avpicture_layout(&pict, frame->format, frame->width, frame->height,
|
||||
pkt->data, size);
|
||||
} else if (av_frame_get_channels(frame) /* FIXME test audio */) {
|
||||
size = frame->nb_samples * av_get_bytes_per_sample(frame->format) *
|
||||
av_frame_get_channels(frame);
|
||||
if ((ret = av_new_packet(pkt, size)) < 0)
|
||||
return ret;
|
||||
memcpy(pkt->data, ref->data[0], size);
|
||||
memcpy(pkt->data, frame->data[0], size);
|
||||
}
|
||||
|
||||
if (ref->metadata) {
|
||||
frame_metadata = av_frame_get_metadata(frame);
|
||||
if (frame_metadata) {
|
||||
uint8_t *metadata;
|
||||
AVDictionaryEntry *e = NULL;
|
||||
AVBPrint meta_buf;
|
||||
|
||||
av_bprint_init(&meta_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
while ((e = av_dict_get(ref->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
|
||||
while ((e = av_dict_get(frame_metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_bprintf(&meta_buf, "%s", e->key);
|
||||
av_bprint_chars(&meta_buf, '\0', 1);
|
||||
av_bprintf(&meta_buf, "%s", e->value);
|
||||
|
@ -395,10 +402,10 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
|||
}
|
||||
|
||||
pkt->stream_index = stream_idx;
|
||||
pkt->pts = ref->pts;
|
||||
pkt->pos = ref->pos;
|
||||
pkt->pts = frame->pts;
|
||||
pkt->pos = av_frame_get_pkt_pos(frame);
|
||||
pkt->size = size;
|
||||
avfilter_unref_buffer(ref);
|
||||
av_frame_unref(frame);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue