Merge commit '7e350379f87e7f74420b4813170fe808e2313911'

* commit '7e350379f87e7f74420b4813170fe808e2313911':
  lavfi: switch to AVFrame.

Conflicts:
	doc/filters.texi
	libavfilter/af_ashowinfo.c
	libavfilter/audio.c
	libavfilter/avfilter.c
	libavfilter/avfilter.h
	libavfilter/buffersink.c
	libavfilter/buffersrc.c
	libavfilter/buffersrc.h
	libavfilter/f_select.c
	libavfilter/f_setpts.c
	libavfilter/fifo.c
	libavfilter/split.c
	libavfilter/src_movie.c
	libavfilter/version.h
	libavfilter/vf_aspect.c
	libavfilter/vf_bbox.c
	libavfilter/vf_blackframe.c
	libavfilter/vf_delogo.c
	libavfilter/vf_drawbox.c
	libavfilter/vf_drawtext.c
	libavfilter/vf_fade.c
	libavfilter/vf_fieldorder.c
	libavfilter/vf_fps.c
	libavfilter/vf_frei0r.c
	libavfilter/vf_gradfun.c
	libavfilter/vf_hqdn3d.c
	libavfilter/vf_lut.c
	libavfilter/vf_overlay.c
	libavfilter/vf_pad.c
	libavfilter/vf_scale.c
	libavfilter/vf_showinfo.c
	libavfilter/vf_transpose.c
	libavfilter/vf_vflip.c
	libavfilter/vf_yadif.c
	libavfilter/video.c
	libavfilter/vsrc_testsrc.c
	libavfilter/yadif.h

Following are notes about the merge authorship and various technical details.

Michael Niedermayer:
  * Main merge operation, notably avfilter.c and video.c
  * Switch to AVFrame:
    - afade
    - anullsrc
    - apad
    - aresample
    - blackframe
    - deshake
    - idet
    - il
    - mandelbrot
    - mptestsrc
    - noise
    - setfield
    - smartblur
    - tinterlace
  * various merge changes and fixes in:
    - ashowinfo
    - blackdetect
    - field
    - fps
    - select
    - testsrc
    - yadif

Nicolas George:
  * Switch to AVFrame:
    - make rawdec work with refcounted frames. Adapted from commit
      759001c534 by Anton Khirnov.
      Also, fix the use of || instead of | in a flags check.
    - make buffer sink and src, audio and video work all together

Clément Bœsch:
  * Switch to AVFrame:
    - aevalsrc
    - alphaextract
    - blend
    - cellauto
    - colormatrix
    - concat
    - earwax
    - ebur128
    - edgedetect
    - geq
    - histeq
    - histogram
    - hue
    - kerndeint
    - life
    - movie
    - mp (with the help of Michael)
    - overlay
    - pad
    - pan
    - pp
    - pp
    - removelogo
    - sendcmd
    - showspectrum
    - showwaves
    - silencedetect
    - stereo3d
    - subtitles
    - super2xsai
    - swapuv
    - thumbnail
    - tile

Hendrik Leppkes:
  * Switch to AVFrame:
    - aconvert
    - amerge
    - asetnsamples
    - atempo
    - biquads

Matthieu Bouron:
  * Switch to AVFrame
    - alphamerge
    - decimate
    - volumedetect

Stefano Sabatini:
  * Switch to AVFrame:
    - astreamsync
    - flite
    - framestep

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Nicolas George <nicolas.george@normalesup.org>
Signed-off-by: Clément Bœsch <ubitux@gmail.com>
Signed-off-by: Hendrik Leppkes <h.leppkes@gmail.com>
Signed-off-by: Matthieu Bouron <matthieu.bouron@gmail.com>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2013-03-10 01:30:30 +01:00
commit a05a44e205
124 changed files with 1827 additions and 1933 deletions

View File

@ -2086,9 +2086,6 @@ pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
@item n
the number of input frame, starting from 0
@item pos
the position in the file of the input frame, NAN if unknown
@item t
timestamp expressed in seconds, NAN if the input timestamp is unknown

View File

@ -1627,8 +1627,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
(AVRational){1, ist->st->codec->sample_rate}, decoded_frame->nb_samples, &ist->filter_in_rescale_delta_last,
(AVRational){1, ist->st->codec->sample_rate});
for (i = 0; i < ist->nb_filters; i++)
av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame,
AV_BUFFERSRC_FLAG_PUSH);
av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame);
/* TODO re-add AV_BUFFERSRC_FLAG_PUSH */
decoded_frame->pts = AV_NOPTS_VALUE;
@ -1737,7 +1737,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
AV_BUFFERSRC_FLAG_NO_COPY |
AV_BUFFERSRC_FLAG_PUSH);
} else
if(av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, AV_BUFFERSRC_FLAG_PUSH)<0) {
if(av_buffersrc_add_frame_flags(ist->filters[i]->filter, decoded_frame, AV_BUFFERSRC_FLAG_PUSH)<0) {
av_log(NULL, AV_LOG_FATAL, "Failed to inject frame into filter network\n");
exit(1);
}

View File

@ -33,7 +33,6 @@ OBJS = allfilters.o \
avfilter.o \
avfiltergraph.o \
buffer.o \
buffersink.o \
buffersrc.o \
drawutils.o \
fifo.o \
@ -41,7 +40,6 @@ OBJS = allfilters.o \
graphdump.o \
graphparser.o \
sink_buffer.o \
src_buffer.o \
transform.o \
video.o \

View File

@ -135,23 +135,23 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref)
{
AConvertContext *aconvert = inlink->dst->priv;
const int n = insamplesref->audio->nb_samples;
const int n = insamplesref->nb_samples;
AVFilterLink *const outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
AVFrame *outsamplesref = ff_get_audio_buffer(outlink, n);
int ret;
swr_convert(aconvert->swr, outsamplesref->data, n,
(void *)insamplesref->data, n);
swr_convert(aconvert->swr, outsamplesref->extended_data, n,
(void *)insamplesref->extended_data, n);
avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
outsamplesref->audio->channels = outlink->channels;
outsamplesref->audio->channel_layout = outlink->channel_layout;
av_frame_copy_props(outsamplesref, insamplesref);
outsamplesref->channels = outlink->channels;
outsamplesref->channel_layout = outlink->channel_layout;
ret = ff_filter_frame(outlink, outsamplesref);
avfilter_unref_buffer(insamplesref);
av_frame_free(&insamplesref);
return ret;
}
@ -160,7 +160,6 @@ static const AVFilterPad aconvert_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -232,22 +232,22 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AudioFadeContext *afade = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
int nb_samples = buf->audio->nb_samples;
AVFilterBufferRef *out_buf;
int nb_samples = buf->nb_samples;
AVFrame *out_buf;
int64_t cur_sample = av_rescale_q(buf->pts, (AVRational){1, outlink->sample_rate}, outlink->time_base);
if ((!afade->type && (afade->start_sample + afade->nb_samples < cur_sample)) ||
( afade->type && (cur_sample + afade->nb_samples < afade->start_sample)))
return ff_filter_frame(outlink, buf);
if (buf->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(buf)) {
out_buf = buf;
} else {
out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
out_buf = ff_get_audio_buffer(inlink, nb_samples);
if (!out_buf)
return AVERROR(ENOMEM);
out_buf->pts = buf->pts;
@ -256,7 +256,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
if ((!afade->type && (cur_sample + nb_samples < afade->start_sample)) ||
( afade->type && (afade->start_sample + afade->nb_samples < cur_sample))) {
av_samples_set_silence(out_buf->extended_data, 0, nb_samples,
out_buf->audio->channels, out_buf->format);
out_buf->channels, out_buf->format);
} else {
int64_t start;
@ -266,13 +266,13 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
start = afade->start_sample + afade->nb_samples - cur_sample;
afade->fade_samples(out_buf->extended_data, buf->extended_data,
nb_samples, buf->audio->channels,
nb_samples, buf->channels,
afade->type ? -1 : 1, start,
afade->nb_samples, afade->curve);
}
if (buf != out_buf)
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ff_filter_frame(outlink, out_buf);
}

View File

@ -219,14 +219,14 @@ static inline void copy_samples(int nb_inputs, struct amerge_input in[],
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterContext *ctx = inlink->dst;
AMergeContext *am = ctx->priv;
AVFilterLink *const outlink = ctx->outputs[0];
int input_number;
int nb_samples, ns, i;
AVFilterBufferRef *outbuf, *inbuf[SWR_CH_MAX];
AVFrame *outbuf, *inbuf[SWR_CH_MAX];
uint8_t *ins[SWR_CH_MAX], *outs;
for (input_number = 0; input_number < am->nb_inputs; input_number++)
@ -235,39 +235,40 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
av_assert1(input_number < am->nb_inputs);
if (ff_bufqueue_is_full(&am->in[input_number].queue)) {
av_log(ctx, AV_LOG_ERROR, "Buffer queue overflow\n");
avfilter_unref_buffer(insamples);
av_frame_free(&insamples);
return AVERROR(ENOMEM);
}
ff_bufqueue_add(ctx, &am->in[input_number].queue, insamples);
am->in[input_number].nb_samples += insamples->audio->nb_samples;
ff_bufqueue_add(ctx, &am->in[input_number].queue, av_frame_clone(insamples));
am->in[input_number].nb_samples += insamples->nb_samples;
av_frame_free(&insamples);
nb_samples = am->in[0].nb_samples;
for (i = 1; i < am->nb_inputs; i++)
nb_samples = FFMIN(nb_samples, am->in[i].nb_samples);
if (!nb_samples)
return 0;
outbuf = ff_get_audio_buffer(ctx->outputs[0], AV_PERM_WRITE, nb_samples);
outbuf = ff_get_audio_buffer(ctx->outputs[0], nb_samples);
outs = outbuf->data[0];
for (i = 0; i < am->nb_inputs; i++) {
inbuf[i] = ff_bufqueue_peek(&am->in[i].queue, 0);
ins[i] = inbuf[i]->data[0] +
am->in[i].pos * am->in[i].nb_ch * am->bps;
}
avfilter_copy_buffer_ref_props(outbuf, inbuf[0]);
av_frame_copy_props(outbuf, inbuf[0]);
outbuf->pts = inbuf[0]->pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
inbuf[0]->pts +
av_rescale_q(am->in[0].pos,
(AVRational){ 1, ctx->inputs[0]->sample_rate },
ctx->outputs[0]->time_base);
outbuf->audio->nb_samples = nb_samples;
outbuf->audio->channel_layout = outlink->channel_layout;
outbuf->audio->channels = outlink->channels;
outbuf->nb_samples = nb_samples;
outbuf->channel_layout = outlink->channel_layout;
outbuf->channels = outlink->channels;
while (nb_samples) {
ns = nb_samples;
for (i = 0; i < am->nb_inputs; i++)
ns = FFMIN(ns, inbuf[i]->audio->nb_samples - am->in[i].pos);
ns = FFMIN(ns, inbuf[i]->nb_samples - am->in[i].pos);
/* Unroll the most common sample formats: speed +~350% for the loop,
+~13% overall (including two common decoders) */
switch (am->bps) {
@ -289,9 +290,9 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
for (i = 0; i < am->nb_inputs; i++) {
am->in[i].nb_samples -= ns;
am->in[i].pos += ns;
if (am->in[i].pos == inbuf[i]->audio->nb_samples) {
if (am->in[i].pos == inbuf[i]->nb_samples) {
am->in[i].pos = 0;
avfilter_unref_buffer(inbuf[i]);
av_frame_free(&inbuf[i]);
ff_bufqueue_get(&am->in[i].queue);
inbuf[i] = ff_bufqueue_peek(&am->in[i].queue, 0);
ins[i] = inbuf[i] ? inbuf[i]->data[0] : NULL;
@ -322,7 +323,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
.name = name,
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
};
if (!name)
return AVERROR(ENOMEM);

View File

@ -270,18 +270,18 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
{
AVFilterContext *ctx = outlink->src;
MixContext *s = ctx->priv;
AVFilterBufferRef *out_buf, *in_buf;
AVFrame *out_buf, *in_buf;
int i;
calculate_scales(s, nb_samples);
out_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
out_buf = ff_get_audio_buffer(outlink, nb_samples);
if (!out_buf)
return AVERROR(ENOMEM);
in_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
in_buf = ff_get_audio_buffer(outlink, nb_samples);
if (!in_buf) {
avfilter_unref_buffer(out_buf);
av_frame_free(&out_buf);
return AVERROR(ENOMEM);
}
@ -303,7 +303,7 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
}
}
}
avfilter_unref_buffer(in_buf);
av_frame_free(&in_buf);
out_buf->pts = s->next_pts;
if (s->next_pts != AV_NOPTS_VALUE)
@ -450,7 +450,7 @@ static int request_frame(AVFilterLink *outlink)
return output_frame(outlink, available_samples);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
MixContext *s = ctx->priv;
@ -469,16 +469,16 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
if (i == 0) {
int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
outlink->time_base);
ret = frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts);
if (ret < 0)
goto fail;
}
ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
buf->audio->nb_samples);
buf->nb_samples);
fail:
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ret;
}

View File

@ -77,15 +77,15 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
APadContext *apad = ctx->priv;
if (apad->whole_len)
apad->whole_len -= frame->audio->nb_samples;
apad->whole_len -= frame->nb_samples;
apad->next_pts = frame->pts + av_rescale_q(frame->audio->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
apad->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
return ff_filter_frame(ctx->outputs[0], frame);
}
@ -99,7 +99,7 @@ static int request_frame(AVFilterLink *outlink)
if (ret == AVERROR_EOF) {
int n_out = apad->packet_size;
AVFilterBufferRef *outsamplesref;
AVFrame *outsamplesref;
if (apad->whole_len > 0) {
apad->pad_len = apad->whole_len;
@ -113,16 +113,16 @@ static int request_frame(AVFilterLink *outlink)
if(!n_out)
return AVERROR_EOF;
outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
outsamplesref = ff_get_audio_buffer(outlink, n_out);
if (!outsamplesref)
return AVERROR(ENOMEM);
av_assert0(outsamplesref->audio->sample_rate == outlink->sample_rate);
av_assert0(outsamplesref->audio->nb_samples == n_out);
av_assert0(outsamplesref->sample_rate == outlink->sample_rate);
av_assert0(outsamplesref->nb_samples == n_out);
av_samples_set_silence(outsamplesref->extended_data, 0,
n_out,
outsamplesref->audio->channels,
outsamplesref->channels,
outsamplesref->format);
outsamplesref->pts = apad->next_pts;

View File

@ -174,23 +174,23 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref)
{
AResampleContext *aresample = inlink->dst->priv;
const int n_in = insamplesref->audio->nb_samples;
const int n_in = insamplesref->nb_samples;
int n_out = n_in * aresample->ratio * 2 + 256;
AVFilterLink *const outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
AVFrame *outsamplesref = ff_get_audio_buffer(outlink, n_out);
int ret;
if(!outsamplesref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
av_frame_copy_props(outsamplesref, insamplesref);
outsamplesref->format = outlink->format;
outsamplesref->audio->channels = outlink->channels;
outsamplesref->audio->channel_layout = outlink->channel_layout;
outsamplesref->audio->sample_rate = outlink->sample_rate;
outsamplesref->channels = outlink->channels;
outsamplesref->channel_layout = outlink->channel_layout;
outsamplesref->sample_rate = outlink->sample_rate;
if(insamplesref->pts != AV_NOPTS_VALUE) {
int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den);
@ -203,16 +203,16 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out,
(void *)insamplesref->extended_data, n_in);
if (n_out <= 0) {
avfilter_unref_buffer(outsamplesref);
avfilter_unref_buffer(insamplesref);
av_frame_free(&outsamplesref);
av_frame_free(&insamplesref);
return 0;
}
outsamplesref->audio->nb_samples = n_out;
outsamplesref->nb_samples = n_out;
ret = ff_filter_frame(outlink, outsamplesref);
aresample->req_fullfilled= 1;
avfilter_unref_buffer(insamplesref);
av_frame_free(&insamplesref);
return ret;
}
@ -229,20 +229,20 @@ static int request_frame(AVFilterLink *outlink)
}while(!aresample->req_fullfilled && ret>=0);
if (ret == AVERROR_EOF) {
AVFilterBufferRef *outsamplesref;
AVFrame *outsamplesref;
int n_out = 4096;
outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
outsamplesref = ff_get_audio_buffer(outlink, n_out);
if (!outsamplesref)
return AVERROR(ENOMEM);
n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, 0, 0);
if (n_out <= 0) {
avfilter_unref_buffer(outsamplesref);
av_frame_free(&outsamplesref);
return (n_out == 0) ? AVERROR_EOF : n_out;
}
outsamplesref->audio->sample_rate = outlink->sample_rate;
outsamplesref->audio->nb_samples = n_out;
outsamplesref->sample_rate = outlink->sample_rate;
outsamplesref->nb_samples = n_out;
#if 0
outsamplesref->pts = aresample->next_pts;
if(aresample->next_pts != AV_NOPTS_VALUE)
@ -263,7 +263,6 @@ static const AVFilterPad aresample_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL },
};

View File

@ -93,7 +93,7 @@ static int config_props_output(AVFilterLink *outlink)
static int push_samples(AVFilterLink *outlink)
{
ASNSContext *asns = outlink->src->priv;
AVFilterBufferRef *outsamples = NULL;
AVFrame *outsamples = NULL;
int nb_out_samples, nb_pad_samples;
if (asns->pad) {
@ -107,7 +107,7 @@ static int push_samples(AVFilterLink *outlink)
if (!nb_out_samples)
return 0;
outsamples = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_out_samples);
outsamples = ff_get_audio_buffer(outlink, nb_out_samples);
av_assert0(outsamples);
av_audio_fifo_read(asns->fifo,
@ -117,9 +117,9 @@ static int push_samples(AVFilterLink *outlink)
av_samples_set_silence(outsamples->extended_data, nb_out_samples - nb_pad_samples,
nb_pad_samples, av_get_channel_layout_nb_channels(outlink->channel_layout),
outlink->format);
outsamples->audio->nb_samples = nb_out_samples;
outsamples->audio->channel_layout = outlink->channel_layout;
outsamples->audio->sample_rate = outlink->sample_rate;
outsamples->nb_samples = nb_out_samples;
outsamples->channel_layout = outlink->channel_layout;
outsamples->sample_rate = outlink->sample_rate;
outsamples->pts = asns->next_out_pts;
if (asns->next_out_pts != AV_NOPTS_VALUE)
@ -130,13 +130,13 @@ static int push_samples(AVFilterLink *outlink)
return nb_out_samples;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterContext *ctx = inlink->dst;
ASNSContext *asns = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
int ret;
int nb_samples = insamples->audio->nb_samples;
int nb_samples = insamples->nb_samples;
if (av_audio_fifo_space(asns->fifo) < nb_samples) {
av_log(ctx, AV_LOG_DEBUG, "No space for %d samples, stretching audio fifo\n", nb_samples);
@ -150,7 +150,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
av_audio_fifo_write(asns->fifo, (void **)insamples->extended_data, nb_samples);
if (asns->next_out_pts == AV_NOPTS_VALUE)
asns->next_out_pts = insamples->pts;
avfilter_unref_buffer(insamples);
av_frame_free(&insamples);
while (av_audio_fifo_size(asns->fifo) >= asns->nb_out_samples)
push_samples(outlink);
@ -177,10 +177,10 @@ static int request_frame(AVFilterLink *outlink)
static const AVFilterPad asetnsamples_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_WRITE,
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.needs_writable = 1,
},
{ NULL }
};

View File

@ -55,16 +55,16 @@ static void uninit(AVFilterContext *ctx)
av_freep(&s->plane_checksums);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
AShowInfoContext *s = ctx->priv;
char chlayout_str[128];
uint32_t checksum = 0;
int channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
int channels = av_get_channel_layout_nb_channels(buf->channel_layout);
int planar = av_sample_fmt_is_planar(buf->format);
int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels);
int data_size = buf->audio->nb_samples * block_align;
int data_size = buf->nb_samples * block_align;
int planes = planar ? channels : 1;
int i;
void *tmp_ptr = av_realloc(s->plane_checksums, channels * sizeof(*s->plane_checksums));
@ -82,7 +82,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
}
av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1,
buf->audio->channel_layout);
buf->channel_layout);
av_log(ctx, AV_LOG_INFO,
"n:%"PRIu64" pts:%s pts_time:%s pos:%"PRId64" "
@ -90,9 +90,9 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
"checksum:%08X ",
s->frame,
av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base),
buf->pos,
av_get_sample_fmt_name(buf->format), buf->audio->channels, chlayout_str,
buf->audio->sample_rate, buf->audio->nb_samples,
av_frame_get_pkt_pos(buf),
av_get_sample_fmt_name(buf->format), av_frame_get_channels(buf), chlayout_str,
buf->sample_rate, buf->nb_samples,
checksum);
av_log(ctx, AV_LOG_INFO, "plane_checksums: [ ");
@ -110,7 +110,6 @@ static const AVFilterPad inputs[] = {
.type = AVMEDIA_TYPE_AUDIO,
.get_audio_buffer = ff_null_get_audio_buffer,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL },
};

View File

@ -48,7 +48,7 @@ typedef struct {
AVExpr *expr;
double var_values[VAR_NB];
struct buf_queue {
AVFilterBufferRef *buf[QUEUE_SIZE];
AVFrame *buf[QUEUE_SIZE];
unsigned tail, nb;
/* buf[tail] is the oldest,
buf[(tail + nb) % QUEUE_SIZE] is where the next is added */
@ -111,16 +111,16 @@ static int send_out(AVFilterContext *ctx, int out_id)
{
AStreamSyncContext *as = ctx->priv;
struct buf_queue *queue = &as->queue[out_id];
AVFilterBufferRef *buf = queue->buf[queue->tail];
AVFrame *buf = queue->buf[queue->tail];
int ret;
queue->buf[queue->tail] = NULL;
as->var_values[VAR_B1 + out_id]++;
as->var_values[VAR_S1 + out_id] += buf->audio->nb_samples;
as->var_values[VAR_S1 + out_id] += buf->nb_samples;
if (buf->pts != AV_NOPTS_VALUE)
as->var_values[VAR_T1 + out_id] =
av_q2d(ctx->outputs[out_id]->time_base) * buf->pts;
as->var_values[VAR_T1 + out_id] += buf->audio->nb_samples /
as->var_values[VAR_T1 + out_id] += buf->nb_samples /
(double)ctx->inputs[out_id]->sample_rate;
ret = ff_filter_frame(ctx->outputs[out_id], buf);
queue->nb--;
@ -167,7 +167,7 @@ static int request_frame(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterContext *ctx = inlink->dst;
AStreamSyncContext *as = ctx->priv;
@ -185,12 +185,10 @@ static const AVFilterPad astreamsync_inputs[] = {
.name = "in1",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
},{
.name = "in2",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
},
{ NULL }
};

View File

@ -152,14 +152,13 @@ static int request_frame(AVFilterLink *link)
handle_trimming(ctx);
if (nb_samples = get_delay(s)) {
AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
nb_samples);
AVFrame *buf = ff_get_audio_buffer(link, nb_samples);
if (!buf)
return AVERROR(ENOMEM);
ret = avresample_convert(s->avr, buf->extended_data,
buf->linesize[0], nb_samples, NULL, 0, 0);
if (ret <= 0) {
avfilter_unref_bufferp(&buf);
av_frame_free(&buf);
return (ret < 0) ? ret : AVERROR_EOF;
}
@ -171,20 +170,20 @@ static int request_frame(AVFilterLink *link)
return ret;
}
static int write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
static int write_to_fifo(ASyncContext *s, AVFrame *buf)
{
int ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data,
buf->linesize[0], buf->audio->nb_samples);
avfilter_unref_buffer(buf);
buf->linesize[0], buf->nb_samples);
av_frame_free(&buf);
return ret;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
ASyncContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
int nb_channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
int nb_channels = av_get_channel_layout_nb_channels(buf->channel_layout);
int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts :
av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
int out_size, ret;
@ -223,8 +222,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
}
if (out_size > 0) {
AVFilterBufferRef *buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
out_size);
AVFrame *buf_out = ff_get_audio_buffer(outlink, out_size);
if (!buf_out) {
ret = AVERROR(ENOMEM);
goto fail;
@ -266,11 +264,11 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
s->pts = pts - avresample_get_delay(s->avr);
ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data,
buf->linesize[0], buf->audio->nb_samples);
buf->linesize[0], buf->nb_samples);
s->first_frame = 0;
fail:
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ret;
}

View File

@ -140,7 +140,7 @@ typedef struct {
// for managing AVFilterPad.request_frame and AVFilterPad.filter_frame
int request_fulfilled;
AVFilterBufferRef *dst_buffer;
AVFrame *dst_buffer;
uint8_t *dst;
uint8_t *dst_end;
uint64_t nsamples_in;
@ -177,7 +177,7 @@ static void yae_clear(ATempoContext *atempo)
atempo->frag[0].position[0] = -(int64_t)(atempo->window / 2);
atempo->frag[0].position[1] = -(int64_t)(atempo->window / 2);
avfilter_unref_bufferp(&atempo->dst_buffer);
av_frame_free(&atempo->dst_buffer);
atempo->dst = NULL;
atempo->dst_end = NULL;
@ -1024,8 +1024,8 @@ static void push_samples(ATempoContext *atempo,
AVFilterLink *outlink,
int n_out)
{
atempo->dst_buffer->audio->sample_rate = outlink->sample_rate;
atempo->dst_buffer->audio->nb_samples = n_out;
atempo->dst_buffer->sample_rate = outlink->sample_rate;
atempo->dst_buffer->nb_samples = n_out;
// adjust the PTS:
atempo->dst_buffer->pts =
@ -1041,14 +1041,13 @@ static void push_samples(ATempoContext *atempo,
atempo->nsamples_out += n_out;
}
static int filter_frame(AVFilterLink *inlink,
AVFilterBufferRef *src_buffer)
static int filter_frame(AVFilterLink *inlink, AVFrame *src_buffer)
{
AVFilterContext *ctx = inlink->dst;
ATempoContext *atempo = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
int n_in = src_buffer->audio->nb_samples;
int n_in = src_buffer->nb_samples;
int n_out = (int)(0.5 + ((double)n_in) / atempo->tempo);
const uint8_t *src = src_buffer->data[0];
@ -1056,10 +1055,8 @@ static int filter_frame(AVFilterLink *inlink,
while (src < src_end) {
if (!atempo->dst_buffer) {
atempo->dst_buffer = ff_get_audio_buffer(outlink,
AV_PERM_WRITE,
n_out);
avfilter_copy_buffer_ref_props(atempo->dst_buffer, src_buffer);
atempo->dst_buffer = ff_get_audio_buffer(outlink, n_out);
av_frame_copy_props(atempo->dst_buffer, src_buffer);
atempo->dst = atempo->dst_buffer->data[0];
atempo->dst_end = atempo->dst + n_out * atempo->stride;
@ -1074,7 +1071,7 @@ static int filter_frame(AVFilterLink *inlink,
}
atempo->nsamples_in += n_in;
avfilter_unref_bufferp(&src_buffer);
av_frame_free(&src_buffer);
return 0;
}
@ -1098,9 +1095,7 @@ static int request_frame(AVFilterLink *outlink)
while (err == AVERROR(EAGAIN)) {
if (!atempo->dst_buffer) {
atempo->dst_buffer = ff_get_audio_buffer(outlink,
AV_PERM_WRITE,
n_max);
atempo->dst_buffer = ff_get_audio_buffer(outlink, n_max);
atempo->dst = atempo->dst_buffer->data[0];
atempo->dst_end = atempo->dst + n_max * atempo->stride;
@ -1116,7 +1111,7 @@ static int request_frame(AVFilterLink *outlink)
}
}
avfilter_unref_bufferp(&atempo->dst_buffer);
av_frame_free(&atempo->dst_buffer);
atempo->dst = NULL;
atempo->dst_end = NULL;
@ -1142,7 +1137,6 @@ static const AVFilterPad atempo_inputs[] = {
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.config_props = config_props,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -392,24 +392,24 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
BiquadsContext *p = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out_buf;
int nb_samples = buf->audio->nb_samples;
AVFrame *out_buf;
int nb_samples = buf->nb_samples;
int ch;
if (buf->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(buf)) {
out_buf = buf;
} else {
out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
out_buf = ff_get_audio_buffer(inlink, nb_samples);
if (!out_buf)
return AVERROR(ENOMEM);
out_buf->pts = buf->pts;
}
for (ch = 0; ch < buf->audio->channels; ch++)
for (ch = 0; ch < buf->channels; ch++)
p->filter(buf->extended_data[ch],
out_buf->extended_data[ch], nb_samples,
&p->cache[ch].i1, &p->cache[ch].i2,
@ -417,7 +417,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
p->b0, p->b1, p->b2, p->a1, p->a2);
if (buf != out_buf)
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ff_filter_frame(outlink, out_buf);
}

View File

@ -312,7 +312,7 @@ static int channelmap_query_formats(AVFilterContext *ctx)
return 0;
}
static int channelmap_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
@ -330,7 +330,7 @@ static int channelmap_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
uint8_t **new_extended_data =
av_mallocz(nch_out * sizeof(*buf->extended_data));
if (!new_extended_data) {
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return AVERROR(ENOMEM);
}
if (buf->extended_data == buf->data) {

View File

@ -105,13 +105,13 @@ static int query_formats(AVFilterContext *ctx)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
int i, ret = 0;
for (i = 0; i < ctx->nb_outputs; i++) {
AVFilterBufferRef *buf_out = avfilter_ref_buffer(buf, ~AV_PERM_WRITE);
AVFrame *buf_out = av_frame_clone(buf);
if (!buf_out) {
ret = AVERROR(ENOMEM);
@ -119,14 +119,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
}
buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i];
buf_out->audio->channel_layout =
av_channel_layout_extract_channel(buf->audio->channel_layout, i);
buf_out->channel_layout =
av_channel_layout_extract_channel(buf->channel_layout, i);
ret = ff_filter_frame(ctx->outputs[i], buf_out);
if (ret < 0)
break;
}
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ret;
}

View File

@ -109,18 +109,18 @@ static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, in
return out;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
int16_t *taps, *endin, *in, *out;
AVFilterBufferRef *outsamples =
ff_get_audio_buffer(inlink, AV_PERM_WRITE,
insamples->audio->nb_samples);
AVFrame *outsamples = ff_get_audio_buffer(inlink, insamples->nb_samples);
int ret;
if (!outsamples)
if (!outsamples) {
av_frame_free(&insamples);
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outsamples, insamples);
}
av_frame_copy_props(outsamples, insamples);
taps = ((EarwaxContext *)inlink->dst->priv)->taps;
out = (int16_t *)outsamples->data[0];
@ -131,14 +131,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
out = scalarproduct(taps, taps + NUMTAPS, out);
// process current input
endin = in + insamples->audio->nb_samples * 2 - NUMTAPS;
endin = in + insamples->nb_samples * 2 - NUMTAPS;
scalarproduct(in, endin, out);
// save part of input for next round
memcpy(taps, endin, NUMTAPS * sizeof(*taps));
ret = ff_filter_frame(outlink, outsamples);
avfilter_unref_buffer(insamples);
av_frame_free(&insamples);
return ret;
}
@ -147,7 +147,6 @@ static const AVFilterPad earwax_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -56,24 +56,14 @@ typedef struct JoinContext {
/**
* Temporary storage for input frames, until we get one on each input.
*/
AVFilterBufferRef **input_frames;
AVFrame **input_frames;
/**
* Temporary storage for data pointers, for assembling the output buffer.
* Temporary storage for buffer references, for assembling the output frame.
*/
uint8_t **data;
AVBufferRef **buffers;
} JoinContext;
/**
* To avoid copying the data from input buffers, this filter creates
* a custom output buffer that stores references to all inputs and
* unrefs them on free.
*/
typedef struct JoinBufferPriv {
AVFilterBufferRef **in_buffers;
int nb_in_buffers;
} JoinBufferPriv;
#define OFFSET(x) offsetof(JoinContext, x)
#define A AV_OPT_FLAG_AUDIO_PARAM
#define F AV_OPT_FLAG_FILTERING_PARAM
@ -94,7 +84,7 @@ static const AVClass join_class = {
.version = LIBAVUTIL_VERSION_INT,
};
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *link, AVFrame *frame)
{
AVFilterContext *ctx = link->dst;
JoinContext *s = ctx->priv;
@ -105,7 +95,7 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
break;
av_assert0(i < ctx->nb_inputs);
av_assert0(!s->input_frames[i]);
s->input_frames[i] = buf;
s->input_frames[i] = frame;
return 0;
}
@ -207,9 +197,9 @@ static int join_init(AVFilterContext *ctx, const char *args)
s->nb_channels = av_get_channel_layout_nb_channels(s->channel_layout);
s->channels = av_mallocz(sizeof(*s->channels) * s->nb_channels);
s->data = av_mallocz(sizeof(*s->data) * s->nb_channels);
s->buffers = av_mallocz(sizeof(*s->buffers) * s->nb_channels);
s->input_frames = av_mallocz(sizeof(*s->input_frames) * s->inputs);
if (!s->channels || !s->data || !s->input_frames) {
if (!s->channels || !s->buffers|| !s->input_frames) {
ret = AVERROR(ENOMEM);
goto fail;
}
@ -248,11 +238,11 @@ static void join_uninit(AVFilterContext *ctx)
for (i = 0; i < ctx->nb_inputs; i++) {
av_freep(&ctx->input_pads[i].name);
avfilter_unref_bufferp(&s->input_frames[i]);
av_frame_free(&s->input_frames[i]);
}
av_freep(&s->channels);
av_freep(&s->data);
av_freep(&s->buffers);
av_freep(&s->input_frames);
}
@ -394,34 +384,14 @@ fail:
return ret;
}
static void join_free_buffer(AVFilterBuffer *buf)
{
JoinBufferPriv *priv = buf->priv;
if (priv) {
int i;
for (i = 0; i < priv->nb_in_buffers; i++)
avfilter_unref_bufferp(&priv->in_buffers[i]);
av_freep(&priv->in_buffers);
av_freep(&buf->priv);
}
if (buf->extended_data != buf->data)
av_freep(&buf->extended_data);
av_freep(&buf);
}
static int join_request_frame(AVFilterLink *outlink)
{
AVFilterContext *ctx = outlink->src;
JoinContext *s = ctx->priv;
AVFilterBufferRef *buf;
JoinBufferPriv *priv;
AVFrame *frame;
int linesize = INT_MAX;
int perms = ~0;
int nb_samples = 0;
int nb_buffers = 0;
int i, j, ret;
/* get a frame on each input */
@ -434,54 +404,95 @@ static int join_request_frame(AVFilterLink *outlink)
/* request the same number of samples on all inputs */
if (i == 0) {
nb_samples = s->input_frames[0]->audio->nb_samples;
nb_samples = s->input_frames[0]->nb_samples;
for (j = 1; !i && j < ctx->nb_inputs; j++)
ctx->inputs[j]->request_samples = nb_samples;
}
}
for (i = 0; i < s->nb_channels; i++) {
ChannelMap *ch = &s->channels[i];
AVFilterBufferRef *cur_buf = s->input_frames[ch->input];
s->data[i] = cur_buf->extended_data[ch->in_channel_idx];
linesize = FFMIN(linesize, cur_buf->linesize[0]);
perms &= cur_buf->perms;
/* setup the output frame */
frame = av_frame_alloc();
if (!frame)
return AVERROR(ENOMEM);
if (s->nb_channels > FF_ARRAY_ELEMS(frame->data)) {
frame->extended_data = av_mallocz(s->nb_channels *
sizeof(*frame->extended_data));
if (!frame->extended_data) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
av_assert0(nb_samples > 0);
buf = avfilter_get_audio_buffer_ref_from_arrays(s->data, linesize, perms,
nb_samples, outlink->format,
outlink->channel_layout);
if (!buf)
return AVERROR(ENOMEM);
/* copy the data pointers */
for (i = 0; i < s->nb_channels; i++) {
ChannelMap *ch = &s->channels[i];
AVFrame *cur = s->input_frames[ch->input];
AVBufferRef *buf;
buf->buf->free = join_free_buffer;
buf->pts = s->input_frames[0]->pts;
frame->extended_data[i] = cur->extended_data[ch->in_channel_idx];
linesize = FFMIN(linesize, cur->linesize[0]);
if (!(priv = av_mallocz(sizeof(*priv))))
goto fail;
if (!(priv->in_buffers = av_mallocz(sizeof(*priv->in_buffers) * ctx->nb_inputs)))
goto fail;
/* add the buffer where this plan is stored to the list if it's
* not already there */
buf = av_frame_get_plane_buffer(cur, ch->in_channel_idx);
if (!buf) {
ret = AVERROR(EINVAL);
goto fail;
}
for (j = 0; j < nb_buffers; j++)
if (s->buffers[j]->buffer == buf->buffer)
break;
if (j == i)
s->buffers[nb_buffers++] = buf;
}
for (i = 0; i < ctx->nb_inputs; i++)
priv->in_buffers[i] = s->input_frames[i];
priv->nb_in_buffers = ctx->nb_inputs;
buf->buf->priv = priv;
/* create references to the buffers we copied to output */
if (nb_buffers > FF_ARRAY_ELEMS(frame->buf)) {
frame->nb_extended_buf = nb_buffers - FF_ARRAY_ELEMS(frame->buf);
frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) *
frame->nb_extended_buf);
if (!frame->extended_buf) {
frame->nb_extended_buf = 0;
ret = AVERROR(ENOMEM);
goto fail;
}
}
for (i = 0; i < FFMIN(FF_ARRAY_ELEMS(frame->buf), nb_buffers); i++) {
frame->buf[i] = av_buffer_ref(s->buffers[i]);
if (!frame->buf[i]) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
for (i = 0; i < frame->nb_extended_buf; i++) {
frame->extended_buf[i] = av_buffer_ref(s->buffers[i +
FF_ARRAY_ELEMS(frame->buf)]);
if (!frame->extended_buf[i]) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
ret = ff_filter_frame(outlink, buf);
frame->nb_samples = nb_samples;
frame->channel_layout = outlink->channel_layout;
frame->sample_rate = outlink->sample_rate;
frame->pts = s->input_frames[0]->pts;
frame->linesize[0] = linesize;
if (frame->data != frame->extended_data) {
memcpy(frame->data, frame->extended_data, sizeof(*frame->data) *
FFMIN(FF_ARRAY_ELEMS(frame->data), s->nb_channels));
}
ret = ff_filter_frame(outlink, frame);
memset(s->input_frames, 0, sizeof(*s->input_frames) * ctx->nb_inputs);
return ret;
fail:
avfilter_unref_buffer(buf);
if (priv)
av_freep(&priv->in_buffers);
av_freep(&priv);
return AVERROR(ENOMEM);
av_frame_free(&frame);
return ret;
}
static const AVFilterPad avfilter_af_join_outputs[] = {

View File

@ -353,21 +353,21 @@ static int config_props(AVFilterLink *link)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
int ret;
int n = insamples->audio->nb_samples;
int n = insamples->nb_samples;
AVFilterLink *const outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outsamples = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
AVFrame *outsamples = ff_get_audio_buffer(outlink, n);
PanContext *pan = inlink->dst->priv;
swr_convert(pan->swr, outsamples->data, n, (void *)insamples->data, n);
avfilter_copy_buffer_ref_props(outsamples, insamples);
outsamples->audio->channel_layout = outlink->channel_layout;
outsamples->audio->channels = outlink->channels;
av_frame_copy_props(outsamples, insamples);
outsamples->channel_layout = outlink->channel_layout;
outsamples->channels = outlink->channels;
ret = ff_filter_frame(outlink, outsamples);
avfilter_unref_buffer(insamples);
av_frame_free(&insamples);
return ret;
}
@ -383,7 +383,6 @@ static const AVFilterPad pan_inputs[] = {
.type = AVMEDIA_TYPE_AUDIO,
.config_props = config_props,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -174,7 +174,7 @@ static int request_frame(AVFilterLink *outlink)
/* flush the lavr delay buffer */
if (ret == AVERROR_EOF && s->avr) {
AVFilterBufferRef *buf;
AVFrame *frame;
int nb_samples = av_rescale_rnd(avresample_get_delay(s->avr),
outlink->sample_rate,
ctx->inputs[0]->sample_rate,
@ -183,25 +183,25 @@ static int request_frame(AVFilterLink *outlink)
if (!nb_samples)
return ret;
buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
if (!buf)
frame = ff_get_audio_buffer(outlink, nb_samples);
if (!frame)
return AVERROR(ENOMEM);
ret = avresample_convert(s->avr, buf->extended_data,
buf->linesize[0], nb_samples,
ret = avresample_convert(s->avr, frame->extended_data,
frame->linesize[0], nb_samples,
NULL, 0, 0);
if (ret <= 0) {
avfilter_unref_buffer(buf);
av_frame_free(&frame);
return (ret == 0) ? AVERROR_EOF : ret;
}
buf->pts = s->next_pts;
return ff_filter_frame(outlink, buf);
frame->pts = s->next_pts;
return ff_filter_frame(outlink, frame);
}
return ret;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
ResampleContext *s = ctx->priv;
@ -209,27 +209,26 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
int ret;
if (s->avr) {
AVFilterBufferRef *buf_out;
AVFrame *out;
int delay, nb_samples;
/* maximum possible samples lavr can output */
delay = avresample_get_delay(s->avr);
nb_samples = av_rescale_rnd(buf->audio->nb_samples + delay,
nb_samples = av_rescale_rnd(in->nb_samples + delay,
outlink->sample_rate, inlink->sample_rate,
AV_ROUND_UP);
buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
if (!buf_out) {
out = ff_get_audio_buffer(outlink, nb_samples);
if (!out) {
ret = AVERROR(ENOMEM);
goto fail;
}
ret = avresample_convert(s->avr, buf_out->extended_data,
buf_out->linesize[0], nb_samples,
buf->extended_data, buf->linesize[0],
buf->audio->nb_samples);
ret = avresample_convert(s->avr, out->extended_data, out->linesize[0],
nb_samples, in->extended_data, in->linesize[0],
in->nb_samples);
if (ret <= 0) {
avfilter_unref_buffer(buf_out);
av_frame_free(&out);
if (ret < 0)
goto fail;
}
@ -237,36 +236,36 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
av_assert0(!avresample_available(s->avr));
if (s->next_pts == AV_NOPTS_VALUE) {
if (buf->pts == AV_NOPTS_VALUE) {
if (in->pts == AV_NOPTS_VALUE) {
av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
"assuming 0.\n");
s->next_pts = 0;
} else
s->next_pts = av_rescale_q(buf->pts, inlink->time_base,
s->next_pts = av_rescale_q(in->pts, inlink->time_base,
outlink->time_base);
}
if (ret > 0) {
buf_out->audio->nb_samples = ret;
if (buf->pts != AV_NOPTS_VALUE) {
buf_out->pts = av_rescale_q(buf->pts, inlink->time_base,
out->nb_samples = ret;
if (in->pts != AV_NOPTS_VALUE) {
out->pts = av_rescale_q(in->pts, inlink->time_base,
outlink->time_base) -
av_rescale(delay, outlink->sample_rate,
inlink->sample_rate);
} else
buf_out->pts = s->next_pts;
out->pts = s->next_pts;
s->next_pts = buf_out->pts + buf_out->audio->nb_samples;
s->next_pts = out->pts + out->nb_samples;
ret = ff_filter_frame(outlink, buf_out);
ret = ff_filter_frame(outlink, out);
s->got_output = 1;
}
fail:
avfilter_unref_buffer(buf);
av_frame_free(&in);
} else {
buf->format = outlink->format;
ret = ff_filter_frame(outlink, buf);
in->format = outlink->format;
ret = ff_filter_frame(outlink, in);
s->got_output = 1;
}
@ -278,7 +277,6 @@ static const AVFilterPad avfilter_af_resample_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ
},
{ NULL }
};

View File

@ -70,20 +70,20 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0;
}
static char *get_metadata_val(AVFilterBufferRef *insamples, const char *key)
static char *get_metadata_val(AVFrame *insamples, const char *key)
{
AVDictionaryEntry *e = av_dict_get(insamples->metadata, key, NULL, 0);
return e && e->value ? e->value : NULL;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
int i;
SilenceDetectContext *silence = inlink->dst->priv;
const int nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout);
const int srate = inlink->sample_rate;
const int nb_samples = insamples->audio->nb_samples * nb_channels;
const int64_t nb_samples_notify = srate * silence->duration * nb_channels;
const int nb_samples = insamples->nb_samples * nb_channels;
const int64_t nb_samples_notify = srate * silence->duration * nb_channels;
// scale number of null samples to the new sample rate
if (silence->last_sample_rate && silence->last_sample_rate != srate)

View File

@ -226,21 +226,21 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
VolumeContext *vol = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
int nb_samples = buf->audio->nb_samples;
AVFilterBufferRef *out_buf;
int nb_samples = buf->nb_samples;
AVFrame *out_buf;
if (vol->volume == 1.0 || vol->volume_i == 256)
return ff_filter_frame(outlink, buf);
/* do volume scaling in-place if input buffer is writable */
if (buf->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(buf)) {
out_buf = buf;
} else {
out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
out_buf = ff_get_audio_buffer(inlink, nb_samples);
if (!out_buf)
return AVERROR(ENOMEM);
out_buf->pts = buf->pts;
@ -276,7 +276,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
}
if (buf != out_buf)
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ff_filter_frame(outlink, out_buf);
}

View File

@ -49,12 +49,12 @@ static int query_formats(AVFilterContext *ctx)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *samples)
static int filter_frame(AVFilterLink *inlink, AVFrame *samples)
{
AVFilterContext *ctx = inlink->dst;
VolDetectContext *vd = ctx->priv;
int64_t layout = samples->audio->channel_layout;
int nb_samples = samples->audio->nb_samples;
int64_t layout = samples->channel_layout;
int nb_samples = samples->nb_samples;
int nb_channels = av_get_channel_layout_nb_channels(layout);
int nb_planes = nb_channels;
int plane, i;
@ -137,7 +137,6 @@ static const AVFilterPad volumedetect_inputs[] = {
.type = AVMEDIA_TYPE_AUDIO,
.get_audio_buffer = ff_null_get_audio_buffer,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -193,8 +193,8 @@ void avfilter_register_all(void)
* unconditionally */
REGISTER_FILTER_UNCONDITIONAL(asrc_abuffer);
REGISTER_FILTER_UNCONDITIONAL(vsrc_buffer);
REGISTER_FILTER_UNCONDITIONAL(asink_abuffer);
REGISTER_FILTER_UNCONDITIONAL(vsink_buffer);
//REGISTER_FILTER_UNCONDITIONAL(asink_abuffer);
//REGISTER_FILTER_UNCONDITIONAL(vsink_buffer);
REGISTER_FILTER_UNCONDITIONAL(af_afifo);
REGISTER_FILTER_UNCONDITIONAL(vf_fifo);
}

View File

@ -22,9 +22,9 @@
#include "avfilter.h"
#include "internal.h"
static int null_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
static int null_filter_frame(AVFilterLink *link, AVFrame *frame)
{
avfilter_unref_bufferp(&samplesref);
av_frame_free(&frame);
return 0;
}

View File

@ -212,14 +212,14 @@ static int query_formats(AVFilterContext *ctx)
static int request_frame(AVFilterLink *outlink)
{
EvalContext *eval = outlink->src->priv;
AVFilterBufferRef *samplesref;
AVFrame *samplesref;
int i, j;
double t = eval->n * (double)1/eval->sample_rate;
if (eval->duration >= 0 && t >= eval->duration)
return AVERROR_EOF;
samplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, eval->nb_samples);
samplesref = ff_get_audio_buffer(outlink, eval->nb_samples);
/* evaluate expression for each single sample and for each channel */
for (i = 0; i < eval->nb_samples; i++, eval->n++) {
@ -233,8 +233,7 @@ static int request_frame(AVFilterLink *outlink)
}
samplesref->pts = eval->pts;
samplesref->pos = -1;
samplesref->audio->sample_rate = eval->sample_rate;
samplesref->sample_rate = eval->sample_rate;
eval->pts += eval->nb_samples;
ff_filter_frame(outlink, samplesref);

View File

@ -102,17 +102,15 @@ static int config_props(AVFilterLink *outlink)
static int request_frame(AVFilterLink *outlink)
{
ANullContext *null = outlink->src->priv;
AVFilterBufferRef *samplesref;
AVFrame *samplesref;
samplesref =
ff_get_audio_buffer(outlink, AV_PERM_WRITE, null->nb_samples);
samplesref = ff_get_audio_buffer(outlink, null->nb_samples);
samplesref->pts = null->pts;
samplesref->pos = -1;
samplesref->audio->channel_layout = null->channel_layout;
samplesref->audio->sample_rate = outlink->sample_rate;
samplesref->channel_layout = null->channel_layout;
samplesref->sample_rate = outlink->sample_rate;
ff_filter_frame(outlink, avfilter_ref_buffer(samplesref, ~0));
avfilter_unref_buffer(samplesref);
ff_filter_frame(outlink, av_frame_clone(samplesref));
av_frame_free(&samplesref);
null->pts += null->nb_samples;
return 0;

View File

@ -245,22 +245,22 @@ static int config_props(AVFilterLink *outlink)
static int request_frame(AVFilterLink *outlink)
{
AVFilterBufferRef *samplesref;
AVFrame *samplesref;
FliteContext *flite = outlink->src->priv;
int nb_samples = FFMIN(flite->wave_nb_samples, flite->frame_nb_samples);
if (!nb_samples)
return AVERROR_EOF;
samplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
samplesref = ff_get_audio_buffer(outlink, nb_samples);
if (!samplesref)
return AVERROR(ENOMEM);
memcpy(samplesref->data[0], flite->wave_samples,
nb_samples * flite->wave->num_channels * 2);
samplesref->pts = flite->pts;
samplesref->pos = -1;
samplesref->audio->sample_rate = flite->wave->sample_rate;
av_frame_set_pkt_pos(samplesref, -1);
av_frame_set_sample_rate(samplesref, flite->wave->sample_rate);
flite->pts += nb_samples;
flite->wave_samples += nb_samples * flite->wave->num_channels;
flite->wave_nb_samples -= nb_samples;

View File

@ -22,6 +22,7 @@
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavcodec/avcodec.h"
#include "audio.h"
#include "avfilter.h"
@ -32,69 +33,70 @@ int avfilter_ref_get_channels(AVFilterBufferRef *ref)
return ref->audio ? ref->audio->channels : 0;
}
AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples)
AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples)
{
return ff_get_audio_buffer(link->dst->outputs[0], perms, nb_samples);
return ff_get_audio_buffer(link->dst->outputs[0], nb_samples);
}
AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples)
AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples)
{
AVFilterBufferRef *samplesref = NULL;
uint8_t **data;
int planar = av_sample_fmt_is_planar(link->format);
int nb_channels = link->channels;
int planes = planar ? nb_channels : 1;
int linesize;
int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE |
AV_PERM_REUSE | AV_PERM_REUSE2 | AV_PERM_ALIGN;
AVFrame *frame = av_frame_alloc();
int channels = link->channels;
int buf_size, ret;
av_assert1(!(perms & ~(full_perms | AV_PERM_NEG_LINESIZES)));
av_assert0(channels == av_get_channel_layout_nb_channels(link->channel_layout) || !av_get_channel_layout_nb_channels(link->channel_layout));
if (!(data = av_mallocz(sizeof(*data) * planes)))
if (!frame)
return NULL;
buf_size = av_samples_get_buffer_size(NULL, channels, nb_samples,
link->format, 0);
if (buf_size < 0)
goto fail;
if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
frame->buf[0] = av_buffer_alloc(buf_size);
if (!frame->buf[0])
goto fail;
samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels(
data, linesize, full_perms, nb_samples, link->format,
link->channels, link->channel_layout);
if (!samplesref)
frame->nb_samples = nb_samples;
ret = avcodec_fill_audio_frame(frame, channels, link->format,
frame->buf[0]->data, buf_size, 0);
if (ret < 0)
goto fail;
samplesref->audio->sample_rate = link->sample_rate;
av_samples_set_silence(frame->extended_data, 0, nb_samples, channels,
link->format);
av_freep(&data);
frame->nb_samples = nb_samples;
frame->format = link->format;
frame->channels = link->channels;
frame->channel_layout = link->channel_layout;
frame->sample_rate = link->sample_rate;
return frame;
fail:
if (data)
av_freep(&data[0]);
av_freep(&data);
return samplesref;
av_buffer_unref(&frame->buf[0]);
av_frame_free(&frame);
return NULL;
}
AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples)
AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
{
AVFilterBufferRef *ret = NULL;
AVFrame *ret = NULL;
if (link->dstpad->get_audio_buffer)
ret = link->dstpad->get_audio_buffer(link, perms, nb_samples);
ret = link->dstpad->get_audio_buffer(link, nb_samples);
if (!ret)
ret = ff_default_get_audio_buffer(link, perms, nb_samples);
if (ret)
ret->type = AVMEDIA_TYPE_AUDIO;
ret = ff_default_get_audio_buffer(link, nb_samples);
return ret;
}
#if FF_API_AVFILTERBUFFER
AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
int linesize,
int perms,
int linesize,int perms,
int nb_samples,
enum AVSampleFormat sample_fmt,
int channels,
@ -179,3 +181,4 @@ AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
nb_samples, sample_fmt,
channels, channel_layout);
}
#endif

View File

@ -44,25 +44,21 @@ static const enum AVSampleFormat ff_planar_sample_fmts_array[] = {
};
/** default handler for get_audio_buffer() for audio inputs */
AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples);
AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples);
/** get_audio_buffer() handler for filters which simply pass audio along */
AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples);
AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples);
/**
* Request an audio samples buffer with a specific set of permissions.
*
* @param link the output link to the filter from which the buffer will
* be requested
* @param perms the required access permissions
* @param nb_samples the number of samples per channel
* @return A reference to the samples. This must be unreferenced with
* avfilter_unref_buffer when you are finished with it.
*/
AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples);
AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples);
/**
* Send a buffer of audio samples to the next filter.

View File

@ -27,52 +27,6 @@
#include "libavutil/avassert.h"
#include "libavutil/opt.h"
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
{
dst->pts = src->pts;
dst->pos = av_frame_get_pkt_pos(src);
dst->format = src->format;
av_dict_free(&dst->metadata);
av_dict_copy(&dst->metadata, av_frame_get_metadata(src), 0);
switch (dst->type) {
case AVMEDIA_TYPE_VIDEO:
dst->video->w = src->width;
dst->video->h = src->height;
dst->video->sample_aspect_ratio = src->sample_aspect_ratio;
dst->video->interlaced = src->interlaced_frame;
dst->video->top_field_first = src->top_field_first;
dst->video->key_frame = src->key_frame;
dst->video->pict_type = src->pict_type;
av_freep(&dst->video->qp_table);
dst->video->qp_table_linesize = 0;
if (src->qscale_table) {
int qsize = src->qstride ? src->qstride * ((src->height+15)/16) : (src->width+15)/16;
dst->video->qp_table = av_malloc(qsize);
if (!dst->video->qp_table)
return AVERROR(ENOMEM);
dst->video->qp_table_linesize = src->qstride;
dst->video->qp_table_size = qsize;
memcpy(dst->video->qp_table, src->qscale_table, qsize);
}
break;
case AVMEDIA_TYPE_AUDIO:
dst->audio->sample_rate = src->sample_rate;
dst->audio->channel_layout = src->channel_layout;
dst->audio->channels = src->channels;
if(src->channels < av_get_channel_layout_nb_channels(src->channel_layout)) {
av_log(NULL, AV_LOG_ERROR, "libavfilter does not support this channel layout\n");
return AVERROR(EINVAL);
}
break;
default:
return AVERROR(EINVAL);
}
return 0;
}
AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame,
int perms)
{

View File

@ -31,22 +31,6 @@
#include "libavcodec/avcodec.h" // AVFrame
#include "avfilter.h"
/**
* Copy the frame properties of src to dst, without copying the actual
* image data.
*
* @return 0 on success, a negative number on error.
*/
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
/**
* Copy the frame properties and data pointers of src to dst, without copying
* the actual data.
*
* @return 0 on success, a negative number on error.
*/
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
/**
* Create and return a picref reference from the data and properties
* contained in frame.
@ -116,16 +100,4 @@ int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
const AVFilterBufferRef *ref);
#endif
/**
* Add frame data to buffer_src.
*
* @param buffer_src pointer to a buffer source context
* @param frame a frame, or NULL to mark EOF
* @param flags a combination of AV_BUFFERSRC_FLAG_*
* @return >= 0 in case of success, a negative AVERROR code
* in case of failure
*/
int av_buffersrc_add_frame(AVFilterContext *buffer_src,
const AVFrame *frame, int flags);
#endif /* AVFILTER_AVCODEC_H */

View File

@ -157,7 +157,7 @@ static int config_output(AVFilterLink *outlink)
}
static void push_frame(AVFilterContext *ctx, unsigned in_no,
AVFilterBufferRef *buf)
AVFrame *buf)
{
ConcatContext *cat = ctx->priv;
unsigned out_no = in_no % ctx->nb_outputs;
@ -171,7 +171,7 @@ static void push_frame(AVFilterContext *ctx, unsigned in_no,
/* add duration to input PTS */
if (inlink->sample_rate)
/* use number of audio samples */
in->pts += av_rescale_q(buf->audio->nb_samples,
in->pts += av_rescale_q(buf->nb_samples,
(AVRational){ 1, inlink->sample_rate },
outlink->time_base);
else if (in->nb_frames >= 2)
@ -182,7 +182,7 @@ static void push_frame(AVFilterContext *ctx, unsigned in_no,
ff_filter_frame(outlink, buf);
}
static void process_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static void process_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
ConcatContext *cat = ctx->priv;
@ -191,7 +191,7 @@ static void process_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
if (in_no < cat->cur_idx) {
av_log(ctx, AV_LOG_ERROR, "Frame after EOF on input %s\n",
ctx->input_pads[in_no].name);
avfilter_unref_buffer(buf);
av_frame_free(&buf);
} else if (in_no >= cat->cur_idx + ctx->nb_outputs) {
ff_bufqueue_add(ctx, &cat->in[in_no].queue, buf);
} else {
@ -199,27 +199,25 @@ static void process_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
}
}
static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms,
int w, int h)
static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
{
AVFilterContext *ctx = inlink->dst;
unsigned in_no = FF_INLINK_IDX(inlink);
AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs];
return ff_get_video_buffer(outlink, perms, w, h);
return ff_get_video_buffer(outlink, w, h);
}
static AVFilterBufferRef *get_audio_buffer(AVFilterLink *inlink, int perms,
int nb_samples)
static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples)
{
AVFilterContext *ctx = inlink->dst;
unsigned in_no = FF_INLINK_IDX(inlink);
AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs];
return ff_get_audio_buffer(outlink, perms, nb_samples);
return ff_get_audio_buffer(outlink, nb_samples);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
process_frame(inlink, buf);
return 0; /* enhancement: handle error return */
@ -256,7 +254,7 @@ static void send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no)
int64_t nb_samples, sent = 0;
int frame_nb_samples;
AVRational rate_tb = { 1, ctx->inputs[in_no]->sample_rate };
AVFilterBufferRef *buf;
AVFrame *buf;
int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
if (!rate_tb.den)
@ -266,7 +264,7 @@ static void send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no)
frame_nb_samples = FFMAX(9600, rate_tb.den / 5); /* arbitrary */
while (nb_samples) {
frame_nb_samples = FFMIN(frame_nb_samples, nb_samples);
buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, frame_nb_samples);
buf = ff_get_audio_buffer(outlink, frame_nb_samples);
if (!buf)
return;
av_samples_set_silence(buf->extended_data, 0, frame_nb_samples,
@ -360,7 +358,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
for (str = 0; str < cat->nb_streams[type]; str++) {
AVFilterPad pad = {
.type = type,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
.get_video_buffer = get_video_buffer,
.get_audio_buffer = get_audio_buffer,
.filter_frame = filter_frame,

View File

@ -41,7 +41,7 @@ enum ColorMode { CHANNEL, INTENSITY, NB_CLMODES };
typedef struct {
const AVClass *class;
int w, h;
AVFilterBufferRef *outpicref;
AVFrame *outpicref;
int req_fullfilled;
int nb_display_channels;
int channel_height;
@ -122,7 +122,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep(&showspectrum->rdft_data[i]);
av_freep(&showspectrum->rdft_data);
av_freep(&showspectrum->window_func_lut);
avfilter_unref_bufferp(&showspectrum->outpicref);
av_frame_free(&showspectrum->outpicref);
}
static int query_formats(AVFilterContext *ctx)
@ -179,7 +179,7 @@ static int config_output(AVFilterLink *outlink)
/* (re-)configuration if the video output changed (or first init) */
if (rdft_bits != showspectrum->rdft_bits) {
size_t rdft_size, rdft_listsize;
AVFilterBufferRef *outpicref;
AVFrame *outpicref;
av_rdft_end(showspectrum->rdft);
showspectrum->rdft = av_rdft_init(rdft_bits, DFT_R2C);
@ -219,10 +219,9 @@ static int config_output(AVFilterLink *outlink)
showspectrum->window_func_lut[i] = .5f * (1 - cos(2*M_PI*i / (win_size-1)));
/* prepare the initial picref buffer (black frame) */
avfilter_unref_bufferp(&showspectrum->outpicref);
av_frame_free(&showspectrum->outpicref);
showspectrum->outpicref = outpicref =
ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE2,
outlink->w, outlink->h);
ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
outlink->sample_aspect_ratio = (AVRational){1,1};
@ -253,7 +252,7 @@ inline static void push_frame(AVFilterLink *outlink)
showspectrum->filled = 0;
showspectrum->req_fullfilled = 1;
ff_filter_frame(outlink, avfilter_ref_buffer(showspectrum->outpicref, ~AV_PERM_WRITE));
ff_filter_frame(outlink, av_frame_clone(showspectrum->outpicref));
}
static int request_frame(AVFilterLink *outlink)
@ -272,12 +271,12 @@ static int request_frame(AVFilterLink *outlink)
return ret;
}
static int plot_spectrum_column(AVFilterLink *inlink, AVFilterBufferRef *insamples, int nb_samples)
static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples, int nb_samples)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
ShowSpectrumContext *showspectrum = ctx->priv;
AVFilterBufferRef *outpicref = showspectrum->outpicref;
AVFrame *outpicref = showspectrum->outpicref;
/* nb_freq contains the power of two superior or equal to the output image
* height (or half the RDFT window size) */
@ -462,11 +461,11 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFilterBufferRef *insampl
return add_samples;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterContext *ctx = inlink->dst;
ShowSpectrumContext *showspectrum = ctx->priv;
int left_samples = insamples->audio->nb_samples;
int left_samples = insamples->nb_samples;
showspectrum->consumed = 0;
while (left_samples) {
@ -475,7 +474,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
left_samples -= added_samples;
}
avfilter_unref_buffer(insamples);
av_frame_free(&insamples);
return 0;
}
@ -484,7 +483,6 @@ static const AVFilterPad showspectrum_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -44,7 +44,7 @@ typedef struct {
char *rate_str;
AVRational rate;
int buf_idx;
AVFilterBufferRef *outpicref;
AVFrame *outpicref;
int req_fullfilled;
int n;
int sample_count_mod;
@ -89,7 +89,7 @@ static av_cold void uninit(AVFilterContext *ctx)
ShowWavesContext *showwaves = ctx->priv;
av_freep(&showwaves->rate_str);
avfilter_unref_bufferp(&showwaves->outpicref);
av_frame_free(&showwaves->outpicref);
}
static int query_formats(AVFilterContext *ctx)
@ -190,16 +190,16 @@ static int request_frame(AVFilterLink *outlink)
#define MAX_INT16 ((1<<15) -1)
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
ShowWavesContext *showwaves = ctx->priv;
const int nb_samples = insamples->audio->nb_samples;
AVFilterBufferRef *outpicref = showwaves->outpicref;
const int nb_samples = insamples->nb_samples;
AVFrame *outpicref = showwaves->outpicref;
int linesize = outpicref ? outpicref->linesize[0] : 0;
int16_t *p = (int16_t *)insamples->data[0];
int nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
int nb_channels = av_get_channel_layout_nb_channels(insamples->channel_layout);
int i, j, k, h, ret = 0;
const int n = showwaves->n;
const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */
@ -208,12 +208,11 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
for (i = 0; i < nb_samples; i++) {
if (!showwaves->outpicref) {
showwaves->outpicref = outpicref =
ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN,
outlink->w, outlink->h);
ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
outpicref->width = outlink->w;
outpicref->height = outlink->h;
outpicref->pts = insamples->pts +
av_rescale_q((p - (int16_t *)insamples->data[0]) / nb_channels,
(AVRational){ 1, inlink->sample_rate },
@ -251,7 +250,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
outpicref = showwaves->outpicref;
}
avfilter_unref_buffer(insamples);
av_frame_free(&insamples);
return ret;
}
@ -260,7 +259,6 @@ static const AVFilterPad showwaves_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -34,43 +34,31 @@
#include "internal.h"
#include "audio.h"
static int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *frame);
static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame);
char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
{
snprintf(buf, buf_size, "%s%s%s%s%s%s",
perms & AV_PERM_READ ? "r" : "",
perms & AV_PERM_WRITE ? "w" : "",
perms & AV_PERM_PRESERVE ? "p" : "",
perms & AV_PERM_REUSE ? "u" : "",
perms & AV_PERM_REUSE2 ? "U" : "",
perms & AV_PERM_NEG_LINESIZES ? "n" : "");
return buf;
}
void ff_tlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
void ff_tlog_ref(void *ctx, AVFrame *ref, int end)
{
av_unused char buf[16];
ff_tlog(ctx,
"ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
"ref[%p buf:%p data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
ref, ref->buf, ref->data[0],
ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
ref->pts, ref->pos);
ref->pts, av_frame_get_pkt_pos(ref));
if (ref->video) {
if (ref->width) {
ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
ref->video->sample_aspect_ratio.num, ref->video->sample_aspect_ratio.den,
ref->video->w, ref->video->h,
!ref->video->interlaced ? 'P' : /* Progressive */
ref->video->top_field_first ? 'T' : 'B', /* Top / Bottom */
ref->video->key_frame,
av_get_picture_type_char(ref->video->pict_type));
ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den,
ref->width, ref->height,
!ref->interlaced_frame ? 'P' : /* Progressive */
ref->top_field_first ? 'T' : 'B', /* Top / Bottom */
ref->key_frame,
av_get_picture_type_char(ref->pict_type));
}
if (ref->audio) {
if (ref->nb_samples) {
ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
ref->audio->channel_layout,
ref->audio->nb_samples,
ref->audio->sample_rate);
ref->channel_layout,
ref->nb_samples,
ref->sample_rate);
}
ff_tlog(ctx, "]%s", end ? "\n" : "");
@ -158,10 +146,7 @@ void avfilter_link_free(AVFilterLink **link)
if (!*link)
return;
if ((*link)->pool)
ff_free_pool((*link)->pool);
avfilter_unref_bufferp(&(*link)->partial_buf);
av_frame_free(&(*link)->partial_buf);
av_freep(link);
}
@ -342,7 +327,7 @@ int ff_request_frame(AVFilterLink *link)
else if (link->src->inputs[0])
ret = ff_request_frame(link->src->inputs[0]);
if (ret == AVERROR_EOF && link->partial_buf) {
AVFilterBufferRef *pbuf = link->partial_buf;
AVFrame *pbuf = link->partial_buf;
link->partial_buf = NULL;
ff_filter_frame_framed(link, pbuf);
return 0;
@ -633,76 +618,64 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
return pads[pad_idx].type;
}
static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
{
return ff_filter_frame(link->dst->outputs[0], frame);
}
static int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *frame)
static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
{
int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
int (*filter_frame)(AVFilterLink *, AVFrame *);
AVFilterPad *src = link->srcpad;
AVFilterPad *dst = link->dstpad;
AVFilterBufferRef *out;
int perms, ret;
AVFrame *out;
int ret;
AVFilterCommand *cmd= link->dst->command_queue;
int64_t pts;
if (link->closed) {
avfilter_unref_buffer(frame);
av_frame_free(&frame);
return AVERROR_EOF;
}
if (!(filter_frame = dst->filter_frame))
filter_frame = default_filter_frame;
av_assert1((frame->perms & src->min_perms) == src->min_perms);
frame->perms &= ~ src->rej_perms;
perms = frame->perms;
if (frame->linesize[0] < 0)
perms |= AV_PERM_NEG_LINESIZES;
/* prepare to copy the frame if the buffer has insufficient permissions */
if ((dst->min_perms & perms) != dst->min_perms ||
dst->rej_perms & perms) {
av_log(link->dst, AV_LOG_DEBUG,
"Copying data in avfilter (have perms %x, need %x, reject %x)\n",
perms, link->dstpad->min_perms, link->dstpad->rej_perms);
/* copy the frame if needed */
if (dst->needs_writable && !av_frame_is_writable(frame)) {
av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
/* Maybe use ff_copy_buffer_ref instead? */
switch (link->type) {
case AVMEDIA_TYPE_VIDEO:
out = ff_get_video_buffer(link, dst->min_perms,
link->w, link->h);
out = ff_get_video_buffer(link, link->w, link->h);
break;
case AVMEDIA_TYPE_AUDIO:
out = ff_get_audio_buffer(link, dst->min_perms,
frame->audio->nb_samples);
out = ff_get_audio_buffer(link, frame->nb_samples);
break;
default: return AVERROR(EINVAL);
}
if (!out) {
avfilter_unref_buffer(frame);
av_frame_free(&frame);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, frame);
av_frame_copy_props(out, frame);
switch (link->type) {
case AVMEDIA_TYPE_VIDEO:
av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
frame->format, frame->video->w, frame->video->h);
frame->format, frame->width, frame->height);
break;
case AVMEDIA_TYPE_AUDIO:
av_samples_copy(out->extended_data, frame->extended_data,
0, 0, frame->audio->nb_samples,
av_get_channel_layout_nb_channels(frame->audio->channel_layout),
0, 0, frame->nb_samples,
av_get_channel_layout_nb_channels(frame->channel_layout),
frame->format);
break;
default: return AVERROR(EINVAL);
}
avfilter_unref_buffer(frame);
av_frame_free(&frame);
} else
out = frame;
@ -721,48 +694,47 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *frame)
return ret;
}
static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFilterBufferRef *frame)
static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame)
{
int insamples = frame->audio->nb_samples, inpos = 0, nb_samples;
AVFilterBufferRef *pbuf = link->partial_buf;
int nb_channels = frame->audio->channels;
int insamples = frame->nb_samples, inpos = 0, nb_samples;
AVFrame *pbuf = link->partial_buf;
int nb_channels = frame->channels;
int ret = 0;
/* Handle framing (min_samples, max_samples) */
while (insamples) {
if (!pbuf) {
AVRational samples_tb = { 1, link->sample_rate };
int perms = link->dstpad->min_perms | AV_PERM_WRITE;
pbuf = ff_get_audio_buffer(link, perms, link->partial_buf_size);
pbuf = ff_get_audio_buffer(link, link->partial_buf_size);
if (!pbuf) {
av_log(link->dst, AV_LOG_WARNING,
"Samples dropped due to memory allocation failure.\n");
return 0;
}
avfilter_copy_buffer_ref_props(pbuf, frame);
av_frame_copy_props(pbuf, frame);
pbuf->pts = frame->pts +
av_rescale_q(inpos, samples_tb, link->time_base);
pbuf->audio->nb_samples = 0;
pbuf->nb_samples = 0;
}
nb_samples = FFMIN(insamples,
link->partial_buf_size - pbuf->audio->nb_samples);
link->partial_buf_size - pbuf->nb_samples);
av_samples_copy(pbuf->extended_data, frame->extended_data,
pbuf->audio->nb_samples, inpos,
pbuf->nb_samples, inpos,
nb_samples, nb_channels, link->format);
inpos += nb_samples;
insamples -= nb_samples;
pbuf->audio->nb_samples += nb_samples;
if (pbuf->audio->nb_samples >= link->min_samples) {
pbuf->nb_samples += nb_samples;
if (pbuf->nb_samples >= link->min_samples) {
ret = ff_filter_frame_framed(link, pbuf);
pbuf = NULL;
}
}
avfilter_unref_buffer(frame);
av_frame_free(&frame);
link->partial_buf = pbuf;
return ret;
}
int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
{
FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1);
@ -770,22 +742,22 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
if (link->type == AVMEDIA_TYPE_VIDEO) {
if (strcmp(link->dst->filter->name, "scale")) {
av_assert1(frame->format == link->format);
av_assert1(frame->video->w == link->w);
av_assert1(frame->video->h == link->h);
av_assert1(frame->width == link->w);
av_assert1(frame->height == link->h);
}
} else {
av_assert1(frame->format == link->format);
av_assert1(frame->audio->channels == link->channels);
av_assert1(frame->audio->channel_layout == link->channel_layout);
av_assert1(frame->audio->sample_rate == link->sample_rate);
av_assert1(frame->channels == link->channels);
av_assert1(frame->channel_layout == link->channel_layout);
av_assert1(frame->sample_rate == link->sample_rate);
}
/* Go directly to actual filtering if possible */
if (link->type == AVMEDIA_TYPE_AUDIO &&
link->min_samples &&
(link->partial_buf ||
frame->audio->nb_samples < link->min_samples ||
frame->audio->nb_samples > link->max_samples)) {
frame->nb_samples < link->min_samples ||
frame->nb_samples > link->max_samples)) {
return ff_filter_frame_needs_framing(link, frame);
} else {
return ff_filter_frame_framed(link, frame);

View File

@ -37,6 +37,7 @@
#include "libavutil/avutil.h"
#include "libavutil/dict.h"
#include "libavutil/frame.h"
#include "libavutil/log.h"
#include "libavutil/samplefmt.h"
#include "libavutil/pixfmt.h"
@ -69,6 +70,7 @@ typedef struct AVFilterLink AVFilterLink;
typedef struct AVFilterPad AVFilterPad;
typedef struct AVFilterFormats AVFilterFormats;
#if FF_API_AVFILTERBUFFER
/**
* A reference-counted buffer data type used by the filter system. Filters
* should not store pointers to this structure directly, but instead use the
@ -200,6 +202,7 @@ typedef struct AVFilterBufferRef {
/**
* Copy properties of src to dst, without copying the actual data
*/
attribute_deprecated
void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src);
/**
@ -211,6 +214,7 @@ void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *s
* @return a new reference to the buffer with the same properties as the
* old, excluding any permissions denied by pmask
*/
attribute_deprecated
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
/**
@ -222,6 +226,7 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
* @note it is recommended to use avfilter_unref_bufferp() instead of this
* function
*/
attribute_deprecated
void avfilter_unref_buffer(AVFilterBufferRef *ref);
/**
@ -231,11 +236,14 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref);
*
* @param ref pointer to the buffer reference
*/
attribute_deprecated
void avfilter_unref_bufferp(AVFilterBufferRef **ref);
#endif
/**
* Get the number of channels of a buffer reference.
*/
attribute_deprecated
int avfilter_ref_get_channels(AVFilterBufferRef *ref);
#if FF_API_AVFILTERPAD_PUBLIC
@ -273,7 +281,7 @@ struct AVFilterPad {
* link must have at least these permissions; this fact is checked by
* asserts. It can be used to optimize buffer allocation.
*/
int min_perms;
attribute_deprecated int min_perms;
/**
* Input pads:
@ -287,7 +295,7 @@ struct AVFilterPad {
* Permissions which are automatically removed on outgoing buffers. It
* can be used to optimize buffer allocation.
*/
int rej_perms;
attribute_deprecated int rej_perms;
/**
* @deprecated unused
@ -300,7 +308,7 @@ struct AVFilterPad {
*
* Input video pads only.
*/
AVFilterBufferRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h);
AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);
/**
* Callback function to get an audio buffer. If NULL, the filter system will
@ -308,8 +316,7 @@ struct AVFilterPad {
*
* Input audio pads only.
*/
AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
int nb_samples);
AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);
/**
* @deprecated unused
@ -331,7 +338,7 @@ struct AVFilterPad {
* must ensure that frame is properly unreferenced on error if it
* hasn't been passed on to another filter.
*/
int (*filter_frame)(AVFilterLink *link, AVFilterBufferRef *frame);
int (*filter_frame)(AVFilterLink *link, AVFrame *frame);
/**
* Frame poll callback. This returns the number of immediately available
@ -381,6 +388,8 @@ struct AVFilterPad {
* input pads only.
*/
int needs_fifo;
int needs_writable;
};
#endif
@ -616,7 +625,7 @@ struct AVFilterLink {
/**
* Buffer partially filled with samples to achieve a fixed/minimum size.
*/
AVFilterBufferRef *partial_buf;
AVFrame *partial_buf;
/**
* Size of the partial buffer to allocate.
@ -701,6 +710,7 @@ void avfilter_link_set_closed(AVFilterLink *link, int closed);
*/
int avfilter_config_links(AVFilterContext *filter);
#if FF_API_AVFILTERBUFFER
/**
* Create a buffer reference wrapped around an already allocated image
* buffer.
@ -712,6 +722,7 @@ int avfilter_config_links(AVFilterContext *filter);
* @param h the height of the image specified by the data and linesize arrays
* @param format the pixel format of the image specified by the data and linesize arrays
*/
attribute_deprecated
AVFilterBufferRef *
avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
int w, int h, enum AVPixelFormat format);
@ -730,6 +741,7 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int lin
* @param sample_fmt the format of each sample in the buffer to allocate
* @param channel_layout the channel layout of the buffer
*/
attribute_deprecated
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
int linesize,
int perms,
@ -749,6 +761,7 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
* @param channel_layout the channel layout of the buffer,
* must be either 0 or consistent with channels
*/
attribute_deprecated
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
int linesize,
int perms,
@ -757,6 +770,7 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **
int channels,
uint64_t channel_layout);
#endif
#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically
@ -845,6 +859,26 @@ void avfilter_free(AVFilterContext *filter);
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
unsigned filt_srcpad_idx, unsigned filt_dstpad_idx);
#if FF_API_AVFILTERBUFFER
/**
* Copy the frame properties of src to dst, without copying the actual
* image data.
*
* @return 0 on success, a negative number on error.
*/
attribute_deprecated
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
/**
* Copy the frame properties and data pointers of src to dst, without copying
* the actual data.
*
* @return 0 on success, a negative number on error.
*/
attribute_deprecated
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
#endif
/**
* @}
*/

View File

@ -92,84 +92,13 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
return ret;
}
void ff_free_pool(AVFilterPool *pool)
{
int i;
av_assert0(pool->refcount > 0);
for (i = 0; i < POOL_SIZE; i++) {
if (pool->pic[i]) {
AVFilterBufferRef *picref = pool->pic[i];
/* free buffer: picrefs stored in the pool are not
* supposed to contain a free callback */
av_assert0(!picref->buf->refcount);
av_freep(&picref->buf->data[0]);
av_freep(&picref->buf);
av_freep(&picref->audio);
av_assert0(!picref->video || !picref->video->qp_table);
av_freep(&picref->video);
av_freep(&pool->pic[i]);
pool->count--;
}
}
pool->draining = 1;
if (!--pool->refcount) {
av_assert0(!pool->count);
av_free(pool);
}
}
static void store_in_pool(AVFilterBufferRef *ref)
{
int i;
AVFilterPool *pool= ref->buf->priv;
av_assert0(ref->buf->data[0]);
av_assert0(pool->refcount>0);
if (ref->video)
av_freep(&ref->video->qp_table);
if (pool->count == POOL_SIZE) {
AVFilterBufferRef *ref1 = pool->pic[0];
av_freep(&ref1->video);
av_freep(&ref1->audio);
av_freep(&ref1->buf->data[0]);
av_freep(&ref1->buf);
av_free(ref1);
memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
pool->count--;
pool->pic[POOL_SIZE-1] = NULL;
}
for (i = 0; i < POOL_SIZE; i++) {
if (!pool->pic[i]) {
pool->pic[i] = ref;
pool->count++;
break;
}
}
if (pool->draining) {
ff_free_pool(pool);
} else
--pool->refcount;
}
void avfilter_unref_buffer(AVFilterBufferRef *ref)
{
if (!ref)
return;
av_assert0(ref->buf->refcount > 0);
if (!(--ref->buf->refcount)) {
if (!ref->buf->free) {
store_in_pool(ref);
return;
}
if (!(--ref->buf->refcount))
ref->buf->free(ref->buf);
}
if (ref->extended_data != ref->data)
av_freep(&ref->extended_data);
if (ref->video)
@ -186,6 +115,36 @@ void avfilter_unref_bufferp(AVFilterBufferRef **ref)
*ref = NULL;
}
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
{
dst->pts = src->pts;
dst->pos = av_frame_get_pkt_pos(src);
dst->format = src->format;
av_dict_free(&dst->metadata);
av_dict_copy(&dst->metadata, av_frame_get_metadata(src), 0);
switch (dst->type) {
case AVMEDIA_TYPE_VIDEO:
dst->video->w = src->width;
dst->video->h = src->height;
dst->video->sample_aspect_ratio = src->sample_aspect_ratio;
dst->video->interlaced = src->interlaced_frame;
dst->video->top_field_first = src->top_field_first;
dst->video->key_frame = src->key_frame;
dst->video->pict_type = src->pict_type;
break;
case AVMEDIA_TYPE_AUDIO:
dst->audio->sample_rate = src->sample_rate;
dst->audio->channel_layout = src->channel_layout;
break;
default:
return AVERROR(EINVAL);
}
return 0;
}
void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
{
// copy common properties
@ -206,40 +165,3 @@ void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *s
av_dict_free(&dst->metadata);
av_dict_copy(&dst->metadata, src->metadata, 0);
}
AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink,
AVFilterBufferRef *ref)
{
AVFilterBufferRef *buf;
int channels;
switch (outlink->type) {
case AVMEDIA_TYPE_VIDEO:
buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
ref->video->w, ref->video->h);
if(!buf)
return NULL;
av_image_copy(buf->data, buf->linesize,
(void*)ref->data, ref->linesize,
ref->format, ref->video->w, ref->video->h);
break;
case AVMEDIA_TYPE_AUDIO:
buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
ref->audio->nb_samples);
if(!buf)
return NULL;
channels = ref->audio->channels;
av_samples_copy(buf->extended_data, ref->buf->extended_data,
0, 0, ref->audio->nb_samples,
channels,
ref->format);
break;
default:
return NULL;
}
avfilter_copy_buffer_ref_props(buf, ref);
return buf;
}

View File

@ -23,7 +23,7 @@
#define AVFILTER_BUFFERQUEUE_H
/**
* FFBufQueue: simple AVFilterBufferRef queue API
* FFBufQueue: simple AVFrame queue API
*
* Note: this API is not thread-safe. Concurrent access to the same queue
* must be protected by a mutex or any synchronization mechanism.
@ -47,7 +47,7 @@
* Structure holding the queue
*/
struct FFBufQueue {
AVFilterBufferRef *queue[FF_BUFQUEUE_SIZE];
AVFrame *queue[FF_BUFQUEUE_SIZE];
unsigned short head;
unsigned short available; /**< number of available buffers */
};
@ -69,11 +69,11 @@ static inline int ff_bufqueue_is_full(struct FFBufQueue *queue)
* (and unrefed) with a warning before adding the new buffer.
*/
static inline void ff_bufqueue_add(void *log, struct FFBufQueue *queue,
AVFilterBufferRef *buf)
AVFrame *buf)
{
if (ff_bufqueue_is_full(queue)) {
av_log(log, AV_LOG_WARNING, "Buffer queue overflow, dropping.\n");
avfilter_unref_buffer(BUCKET(--queue->available));
av_frame_free(&BUCKET(--queue->available));
}
BUCKET(queue->available++) = buf;
}
@ -84,8 +84,8 @@ static inline void ff_bufqueue_add(void *log, struct FFBufQueue *queue,
* Buffer with index 0 is the first buffer in the queue.
* Return NULL if the queue has not enough buffers.
*/
static inline AVFilterBufferRef *ff_bufqueue_peek(struct FFBufQueue *queue,
unsigned index)
static inline AVFrame *ff_bufqueue_peek(struct FFBufQueue *queue,
unsigned index)
{
return index < queue->available ? BUCKET(index) : NULL;
}
@ -95,9 +95,9 @@ static inline AVFilterBufferRef *ff_bufqueue_peek(struct FFBufQueue *queue,
*
* Do not use on an empty queue.
*/
static inline AVFilterBufferRef *ff_bufqueue_get(struct FFBufQueue *queue)
static inline AVFrame *ff_bufqueue_get(struct FFBufQueue *queue)
{
AVFilterBufferRef *ret = queue->queue[queue->head];
AVFrame *ret = queue->queue[queue->head];
av_assert0(queue->available);
queue->available--;
queue->queue[queue->head] = NULL;
@ -110,8 +110,10 @@ static inline AVFilterBufferRef *ff_bufqueue_get(struct FFBufQueue *queue)
*/
static inline void ff_bufqueue_discard_all(struct FFBufQueue *queue)
{
while (queue->available)
avfilter_unref_buffer(ff_bufqueue_get(queue));
while (queue->available) {
AVFrame *buf = ff_bufqueue_get(queue);
av_frame_free(&buf);
}
}
#undef BUCKET

View File

@ -35,7 +35,7 @@
#include "internal.h"
typedef struct {
AVFilterBufferRef *cur_buf; ///< last buffer delivered on the sink
AVFrame *cur_frame; ///< last frame delivered on the sink
AVAudioFifo *audio_fifo; ///< FIFO for audio samples
int64_t next_pts; ///< interpolating audio pts
} BufferSinkContext;
@ -48,59 +48,71 @@ static av_cold void uninit(AVFilterContext *ctx)
av_audio_fifo_free(sink->audio_fifo);
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *link, AVFrame *frame)
{
BufferSinkContext *s = link->dst->priv;
// av_assert0(!s->cur_buf);
s->cur_buf = buf;
// av_assert0(!s->cur_frame);
s->cur_frame = frame;
return 0;
}
<<<<<<< HEAD
int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf)
||||||| merged common ancestors
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
=======
int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
>>>>>>> 7e350379f87e7f74420b4813170fe808e2313911
{
BufferSinkContext *s = ctx->priv;
AVFilterLink *link = ctx->inputs[0];
int ret;
if (!buf)
return ff_poll_frame(ctx->inputs[0]);
if ((ret = ff_request_frame(link)) < 0)
return ret;
if (!s->cur_buf)
if (!s->cur_frame)
return AVERROR(EINVAL);
*buf = s->cur_buf;
s->cur_buf = NULL;
av_frame_move_ref(frame, s->cur_frame);
av_frame_free(&s->cur_frame);
return 0;
}
static int read_from_fifo(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
static int read_from_fifo(AVFilterContext *ctx, AVFrame *frame,
int nb_samples)
{
BufferSinkContext *s = ctx->priv;
AVFilterLink *link = ctx->inputs[0];
AVFilterBufferRef *buf;
AVFrame *tmp;
if (!(buf = ff_get_audio_buffer(link, AV_PERM_WRITE, nb_samples)))
if (!(tmp = ff_get_audio_buffer(link, nb_samples)))
return AVERROR(ENOMEM);
av_audio_fifo_read(s->audio_fifo, (void**)buf->extended_data, nb_samples);
av_audio_fifo_read(s->audio_fifo, (void**)tmp->extended_data, nb_samples);
buf->pts = s->next_pts;
tmp->pts = s->next_pts;
s->next_pts += av_rescale_q(nb_samples, (AVRational){1, link->sample_rate},
link->time_base);
*pbuf = buf;
av_frame_move_ref(frame, tmp);
av_frame_free(&tmp);
return 0;
}
<<<<<<< HEAD
int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
int nb_samples)
||||||| merged common ancestors
int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
int nb_samples)
=======
int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples)
>>>>>>> 7e350379f87e7f74420b4813170fe808e2313911
{
BufferSinkContext *s = ctx->priv;
AVFilterLink *link = ctx->inputs[0];
@ -113,38 +125,107 @@ int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **
}
while (ret >= 0) {
AVFilterBufferRef *buf;
if (av_audio_fifo_size(s->audio_fifo) >= nb_samples)
return read_from_fifo(ctx, pbuf, nb_samples);
return read_from_fifo(ctx, frame, nb_samples);
ret = av_buffersink_read(ctx, &buf);
ret = ff_request_frame(link);
if (ret == AVERROR_EOF && av_audio_fifo_size(s->audio_fifo))
return read_from_fifo(ctx, pbuf, av_audio_fifo_size(s->audio_fifo));
return read_from_fifo(ctx, frame, av_audio_fifo_size(s->audio_fifo));
else if (ret < 0)
return ret;
if (buf->pts != AV_NOPTS_VALUE) {
s->next_pts = buf->pts -
if (s->cur_frame->pts != AV_NOPTS_VALUE) {
s->next_pts = s->cur_frame->pts -
av_rescale_q(av_audio_fifo_size(s->audio_fifo),
(AVRational){ 1, link->sample_rate },
link->time_base);
}
ret = av_audio_fifo_write(s->audio_fifo, (void**)buf->extended_data,
buf->audio->nb_samples);
avfilter_unref_buffer(buf);
ret = av_audio_fifo_write(s->audio_fifo, (void**)s->cur_frame->extended_data,
s->cur_frame->nb_samples);
av_frame_free(&s->cur_frame);
}
return ret;
}
#if FF_API_AVFILTERBUFFER
static void compat_free_buffer(AVFilterBuffer *buf)
{
AVFrame *frame = buf->priv;
av_frame_free(&frame);
av_free(buf);
}
static int compat_read(AVFilterContext *ctx, AVFilterBufferRef **pbuf, int nb_samples)
{
AVFilterBufferRef *buf;
AVFrame *frame;
int ret;
if (!pbuf)
return ff_poll_frame(ctx->inputs[0]);
frame = av_frame_alloc();
if (!frame)
return AVERROR(ENOMEM);
if (!nb_samples)
ret = av_buffersink_get_frame(ctx, frame);
else
ret = av_buffersink_get_samples(ctx, frame, nb_samples);
if (ret < 0)
goto fail;
if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) {
buf = avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize,
AV_PERM_READ,
frame->width, frame->height,
frame->format);
} else {
buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data,
frame->linesize[0], AV_PERM_READ,
frame->nb_samples,
frame->format,
frame->channel_layout);
}
if (!buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
avfilter_copy_frame_props(buf, frame);
buf->buf->priv = frame;
buf->buf->free = compat_free_buffer;
*pbuf = buf;
return 0;
fail:
av_frame_free(&frame);
return ret;
}
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
{
return compat_read(ctx, buf, 0);
}
int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
int nb_samples)
{
return compat_read(ctx, buf, nb_samples);
}
#endif
static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
.needs_fifo = 1
},
{ NULL }
@ -169,7 +250,6 @@ static const AVFilterPad avfilter_asink_abuffer_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
.needs_fifo = 1
},
{ NULL }

View File

@ -26,6 +26,7 @@
#include "avfilter.h"
#if FF_API_AVFILTERBUFFER
/**
* Struct to use for initializing a buffersink context.
*/
@ -94,6 +95,8 @@ void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size);
int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink,
AVFilterBufferRef **bufref, int flags);
/* TODO */
int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags);
/**
* Get the number of immediately available frames.
@ -122,6 +125,7 @@ AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx);
* @return >= 0 in case of success, a negative AVERROR code in case of
* failure.
*/
attribute_deprecated
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf);
/**
@ -140,8 +144,38 @@ int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf);
* @warning do not mix this function with av_buffersink_read(). Use only one or
* the other with a single sink, not both.
*/
attribute_deprecated
int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
int nb_samples);
#endif
/**
* Get a frame with filtered data from sink and put it in frame.
*
* @param ctx pointer to a context of a buffersink or abuffersink AVFilter.
* @param frame pointer to an allocated frame that will be filled with data.
* The data must be freed using av_frame_unref() / av_frame_free()
*
* @return >= 0 in case of success, a negative AVERROR code in case of
* failure.
*/
int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame);
/**
* Same as av_buffersink_get_frame(), but with the ability to specify the number
* of samples read. This function is less efficient than
* av_buffersink_get_frame(), because it copies the data around.
*
* @param ctx pointer to a context of the abuffersink AVFilter.
* @param frame pointer to an allocated frame that will be filled with data.
* The data must be freed using av_frame_unref() / av_frame_free()
* frame will contain exactly nb_samples audio samples, except at
* the end of stream, when it can contain less than nb_samples.
*
* @warning do not mix this function with av_buffersink_get_frame(). Use only one or
* the other with a single sink, not both.
*/
int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples);
/**
* @}

View File

@ -26,6 +26,7 @@
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/fifo.h"
#include "libavutil/frame.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/samplefmt.h"
@ -74,100 +75,194 @@ typedef struct {
return AVERROR(EINVAL);\
}
int av_buffersrc_add_frame(AVFilterContext *buffer_src,
const AVFrame *frame, int flags)
int av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
{
AVFilterBufferRef *picref;
int ret;
return av_buffersrc_add_frame(ctx, frame);
}
if (!frame) /* NULL for EOF */
return av_buffersrc_add_ref(buffer_src, NULL, flags);
int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
{
AVFrame *copy;
int ret = 0;
int64_t layout = frame->channel_layout;
picref = avfilter_get_buffer_ref_from_frame(buffer_src->outputs[0]->type,
frame, AV_PERM_WRITE);
if (!picref)
if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) {
av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
return AVERROR(EINVAL);
}
if (!(copy = av_frame_alloc()))
return AVERROR(ENOMEM);
ret = av_buffersrc_add_ref(buffer_src, picref, flags);
picref->buf->data[0] = NULL;
avfilter_unref_buffer(picref);
ret = av_frame_ref(copy, frame);
if (ret >= 0)
ret = av_buffersrc_add_frame(ctx, copy);
av_frame_free(&copy);
return ret;
}
int av_buffersrc_write_frame(AVFilterContext *buffer_filter, const AVFrame *frame)
int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
{
return av_buffersrc_add_frame(buffer_filter, frame, 0);
}
int av_buffersrc_add_ref(AVFilterContext *s, AVFilterBufferRef *buf, int flags)
{
BufferSourceContext *c = s->priv;
AVFilterBufferRef *to_free = NULL;
BufferSourceContext *s = ctx->priv;
AVFrame *copy;
int ret;
int64_t layout;
if (!buf) {
c->eof = 1;
if (!frame) {
s->eof = 1;
return 0;
} else if (c->eof)
} else if (s->eof)
return AVERROR(EINVAL);
if (!av_fifo_space(c->fifo) &&
(ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
sizeof(buf))) < 0)
return ret;
switch (ctx->outputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
frame->format);
break;
case AVMEDIA_TYPE_AUDIO:
CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
frame->format);
if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) {
switch (s->outputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
break;
case AVMEDIA_TYPE_AUDIO:
if (!buf->audio->channel_layout)
buf->audio->channel_layout = c->channel_layout;
CHECK_AUDIO_PARAM_CHANGE(s, c, buf->audio->sample_rate, buf->audio->channel_layout,
buf->format);
break;
default:
layout = frame->channel_layout;
if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) {
av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
return AVERROR(EINVAL);
}
break;
default:
return AVERROR(EINVAL);
}
if (!(flags & AV_BUFFERSRC_FLAG_NO_COPY))
to_free = buf = ff_copy_buffer_ref(s->outputs[0], buf);
if(!buf)
return -1;
if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
avfilter_unref_buffer(to_free);
if (!av_fifo_space(s->fifo) &&
(ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
sizeof(copy))) < 0)
return ret;
if (!(copy = av_frame_alloc()))
return AVERROR(ENOMEM);
av_frame_move_ref(copy, frame);
if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
av_frame_move_ref(frame, copy);
av_frame_free(&copy);
return ret;
}
c->nb_failed_requests = 0;
if (c->warning_limit &&
av_fifo_size(c->fifo) / sizeof(buf) >= c->warning_limit) {
av_log(s, AV_LOG_WARNING,
"%d buffers queued in %s, something may be wrong.\n",
c->warning_limit,
(char *)av_x_if_null(s->name, s->filter->name));
c->warning_limit *= 10;
}
if ((flags & AV_BUFFERSRC_FLAG_PUSH))
if ((ret = s->output_pads[0].request_frame(s->outputs[0])) < 0)
return ret;
return 0;
}
#ifdef FF_API_BUFFERSRC_BUFFER
int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
#if FF_API_AVFILTERBUFFER
static void compat_free_buffer(void *opaque, uint8_t *data)
{
return av_buffersrc_add_ref(s, buf, AV_BUFFERSRC_FLAG_NO_COPY);
AVFilterBufferRef *buf = opaque;
avfilter_unref_buffer(buf);
}
static void compat_unref_buffer(void *opaque, uint8_t *data)
{
AVBufferRef *buf = opaque;
av_buffer_unref(&buf);
}
int av_buffersrc_add_ref(AVFilterContext *ctx, AVFilterBufferRef *buf,
int flags)
{
BufferSourceContext *s = ctx->priv;
AVFrame *frame = NULL;
AVBufferRef *dummy_buf = NULL;
int ret = 0, planes, i;
if (!buf) {
s->eof = 1;
return 0;
} else if (s->eof)
return AVERROR(EINVAL);
frame = av_frame_alloc();
if (!frame)
return AVERROR(ENOMEM);
dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, buf,
(buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY);
if (!dummy_buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
if ((ret = avfilter_copy_buf_props(frame, buf)) < 0)
goto fail;
#define WRAP_PLANE(ref_out, data, data_size) \
do { \
AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf); \
if (!dummy_ref) { \
ret = AVERROR(ENOMEM); \
goto fail; \
} \
ref_out = av_buffer_create(data, data_size, compat_unref_buffer, \
dummy_ref, (buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY); \
if (!ref_out) { \
av_frame_unref(frame); \
ret = AVERROR(ENOMEM); \
goto fail; \
} \
} while (0)
if (ctx->outputs[0]->type == AVMEDIA_TYPE_VIDEO) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
if (!desc) {
ret = AVERROR(EINVAL);
goto fail;
}
planes = (desc->flags & PIX_FMT_PLANAR) ? desc->nb_components : 1;
for (i = 0; i < planes; i++) {
int h_shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
int plane_size = (frame->width >> h_shift) * frame->linesize[i];
WRAP_PLANE(frame->buf[i], frame->data[i], plane_size);
}
} else {
int planar = av_sample_fmt_is_planar(frame->format);
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
planes = planar ? channels : 1;
if (planes > FF_ARRAY_ELEMS(frame->buf)) {
frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf);
frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) *
frame->nb_extended_buf);
if (!frame->extended_buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
for (i = 0; i < planes - FF_ARRAY_ELEMS(frame->buf); i++)
WRAP_PLANE(frame->extended_buf[i],
frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)],
frame->linesize[0]);
}
ret = av_buffersrc_add_frame_flags(ctx, frame, flags);
fail:
av_buffer_unref(&dummy_buf);
av_frame_free(&frame);
return ret;
}
int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf)
{
return av_buffersrc_add_ref(ctx, buf, 0);
}
#endif
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
{
return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
}
#define OFFSET(x) offsetof(BufferSourceContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static const AVOption buffer_options[] = {
@ -186,7 +281,7 @@ AVFILTER_DEFINE_CLASS(buffer);
static av_cold int init_video(AVFilterContext *ctx, const char *args)
{
BufferSourceContext *c = ctx->priv;
char pix_fmt_str[128], sws_param[256] = "", *colon, *equal;
char pix_fmt_str[128], *colon, *equal;
int ret, n = 0;
c->class = &buffer_class;
@ -195,6 +290,7 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args)
av_log(ctx, AV_LOG_ERROR, "Arguments required\n");
return AVERROR(EINVAL);
}
colon = strchr(args, ':');
equal = strchr(args, '=');
if (equal && (!colon || equal < colon)) {
@ -203,28 +299,25 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args)
if (ret < 0)
goto fail;
} else {
if ((n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d:%255c", &c->w, &c->h, pix_fmt_str,
if (!args ||
(n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
&c->time_base.num, &c->time_base.den,
&c->pixel_aspect.num, &c->pixel_aspect.den, sws_param)) < 7) {
av_log(ctx, AV_LOG_ERROR, "Expected at least 7 arguments, but only %d found in '%s'\n", n, args);
ret = AVERROR(EINVAL);
goto fail;
&c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args);
return AVERROR(EINVAL);
}
av_log(ctx, AV_LOG_WARNING, "Flat options syntax is deprecated, use key=value pairs\n");
if ((ret = ff_parse_pixel_format(&c->pix_fmt, pix_fmt_str, ctx)) < 0)
goto fail;
c->sws_param = av_strdup(sws_param);
if (!c->sws_param) {
ret = AVERROR(ENOMEM);
goto fail;
if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == AV_PIX_FMT_NONE) {
char *tail;
c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
if (*tail || c->pix_fmt < 0 || c->pix_fmt >= AV_PIX_FMT_NB) {
av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str);
return AVERROR(EINVAL);
}
}
}
if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
ret = AVERROR(ENOMEM);
goto fail;
}
if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*))))
return AVERROR(ENOMEM);
av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n",
c->w, c->h, av_get_pix_fmt_name(c->pix_fmt),
@ -238,6 +331,11 @@ fail:
return ret;
}
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
{
return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
}
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
static const AVOption abuffer_options[] = {
{ "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS },
@ -298,7 +396,7 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args)
goto fail;
}
if (!(s->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*)))) {
ret = AVERROR(ENOMEM);
goto fail;
}
@ -321,9 +419,9 @@ static av_cold void uninit(AVFilterContext *ctx)
{
BufferSourceContext *s = ctx->priv;
while (s->fifo && av_fifo_size(s->fifo)) {
AVFilterBufferRef *buf;
av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
avfilter_unref_buffer(buf);
AVFrame *frame;
av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL);
av_frame_free(&frame);
}
av_fifo_free(s->fifo);
s->fifo = NULL;
@ -387,7 +485,8 @@ static int config_props(AVFilterLink *link)
static int request_frame(AVFilterLink *link)
{
BufferSourceContext *c = link->src->priv;
AVFilterBufferRef *buf;
AVFrame *frame;
int ret = 0;
if (!av_fifo_size(c->fifo)) {
if (c->eof)
@ -395,9 +494,12 @@ static int request_frame(AVFilterLink *link)
c->nb_failed_requests++;
return AVERROR(EAGAIN);
}
av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
av_fifo_generic_read(c->fifo, &frame, sizeof(frame), NULL);
return ff_filter_frame(link, buf);
/* CIG TODO do not ignore error */
ff_filter_frame(link, frame);
return ret;
}
static int poll_frame(AVFilterLink *link)
@ -406,7 +508,7 @@ static int poll_frame(AVFilterLink *link)
int size = av_fifo_size(c->fifo);
if (!size && c->eof)
return AVERROR_EOF;
return size/sizeof(AVFilterBufferRef*);
return size/sizeof(AVFrame*);
}
static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {

View File

@ -68,14 +68,15 @@ int av_buffersrc_add_ref(AVFilterContext *buffer_src,
*/
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src);
#ifdef FF_API_BUFFERSRC_BUFFER
#if FF_API_AVFILTERBUFFER
/**
* Add a buffer to the filtergraph s.
*
* @param buf buffer containing frame data to be passed down the filtergraph.
* This function will take ownership of buf, the user must not free it.
* A NULL buf signals EOF -- i.e. no more frames will be sent to this filter.
* @deprecated Use av_buffersrc_add_ref(s, picref, AV_BUFFERSRC_FLAG_NO_COPY) instead.
*
* @deprecated use av_buffersrc_write_frame() or av_buffersrc_add_frame()
*/
attribute_deprecated
int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
@ -85,11 +86,42 @@ int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
* Add a frame to the buffer source.
*
* @param s an instance of the buffersrc filter.
* @param frame frame to be added.
* @param frame frame to be added. If the frame is reference counted, this
* function will make a new reference to it. Otherwise the frame data will be
* copied.
*
* @warning frame data will be memcpy()ed, which may be a big performance
* hit. Use av_buffersrc_buffer() to avoid copying the data.
* @return 0 on success, a negative AVERROR on error
*/
int av_buffersrc_write_frame(AVFilterContext *s, const AVFrame *frame);
/**
* Add a frame to the buffer source.
*
* @param s an instance of the buffersrc filter.
* @param frame frame to be added. If the frame is reference counted, this
* function will take ownership of the reference(s) and reset the frame.
* Otherwise the frame data will be copied. If this function returns an error,
* the input frame is not touched.
*
* @return 0 on success, a negative AVERROR on error.
*
* @note the difference between this function and av_buffersrc_write_frame() is
* that av_buffersrc_write_frame() creates a new reference to the input frame,
* while this function takes ownership of the reference passed to it.
*/
int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame);
/**
* Add frame data to buffer_src. XXX
*
* @param buffer_src pointer to a buffer source context
* @param frame a frame, or NULL to mark EOF
* @param flags a combination of AV_BUFFERSRC_FLAG_*
* @return >= 0 in case of success, a negative AVERROR code
* in case of failure
*/
int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src,
AVFrame *frame, int flags);
#endif /* AVFILTER_BUFFERSRC_H */

View File

@ -97,7 +97,7 @@ typedef struct {
struct rect text; ///< rectangle for the LU legend on the left
struct rect graph; ///< rectangle for the main graph in the center
struct rect gauge; ///< rectangle for the gauge on the right
AVFilterBufferRef *outpicref; ///< output picture reference, updated regularly
AVFrame *outpicref; ///< output picture reference, updated regularly
int meter; ///< select a EBU mode between +9 and +18
int scale_range; ///< the range of LU values according to the meter
int y_zero_lu; ///< the y value (pixel position) for 0 LU
@ -174,7 +174,7 @@ static const uint8_t font_colors[] = {
0x00, 0x96, 0x96,
};
static void drawtext(AVFilterBufferRef *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt, ...)
static void drawtext(AVFrame *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt, ...)
{
int i;
char buf[128] = {0};
@ -207,7 +207,7 @@ static void drawtext(AVFilterBufferRef *pic, int x, int y, int ftid, const uint8
}
}
static void drawline(AVFilterBufferRef *pic, int x, int y, int len, int step)
static void drawline(AVFrame *pic, int x, int y, int len, int step)
{
int i;
uint8_t *p = pic->data[0] + y*pic->linesize[0] + x*3;
@ -224,7 +224,7 @@ static int config_video_output(AVFilterLink *outlink)
uint8_t *p;
AVFilterContext *ctx = outlink->src;
EBUR128Context *ebur128 = ctx->priv;
AVFilterBufferRef *outpicref;
AVFrame *outpicref;
/* check if there is enough space to represent everything decently */
if (ebur128->w < 640 || ebur128->h < 480) {
@ -259,10 +259,9 @@ static int config_video_output(AVFilterLink *outlink)
av_assert0(ebur128->graph.h == ebur128->gauge.h);
/* prepare the initial picref buffer */
avfilter_unref_bufferp(&ebur128->outpicref);
av_frame_free(&ebur128->outpicref);
ebur128->outpicref = outpicref =
ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE2,
outlink->w, outlink->h);
ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
outlink->sample_aspect_ratio = (AVRational){1,1};
@ -450,15 +449,15 @@ static int gate_update(struct integrator *integ, double power,
return gate_hist_pos;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{
int i, ch, idx_insample;
AVFilterContext *ctx = inlink->dst;
EBUR128Context *ebur128 = ctx->priv;
const int nb_channels = ebur128->nb_channels;
const int nb_samples = insamples->audio->nb_samples;
const int nb_samples = insamples->nb_samples;
const double *samples = (double *)insamples->data[0];
AVFilterBufferRef *pic = ebur128->outpicref;
AVFrame *pic = ebur128->outpicref;
for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) {
const int bin_id_400 = ebur128->i400.cache_pos;
@ -639,7 +638,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
/* set pts and push frame */
pic->pts = pts;
ret = ff_filter_frame(outlink, avfilter_ref_buffer(pic, ~AV_PERM_WRITE));
ret = ff_filter_frame(outlink, av_frame_clone(pic));
if (ret < 0)
return ret;
}
@ -738,7 +737,7 @@ static av_cold void uninit(AVFilterContext *ctx)
}
for (i = 0; i < ctx->nb_outputs; i++)
av_freep(&ctx->output_pads[i].name);
avfilter_unref_bufferp(&ebur128->outpicref);
av_frame_free(&ebur128->outpicref);
}
static const AVFilterPad ebur128_inputs[] = {

View File

@ -134,7 +134,7 @@ typedef struct {
DSPContext c; ///< context providing optimized SAD methods (scene detect only)
double prev_mafd; ///< previous MAFD (scene detect only)
#endif
AVFilterBufferRef *prev_picref; ///< previous frame (scene detect only)
AVFrame *prev_picref; ///< previous frame (scene detect only)
double select;
} SelectContext;
@ -219,25 +219,25 @@ static int config_input(AVFilterLink *inlink)
}
#if CONFIG_AVCODEC
static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref)
static double get_scene_score(AVFilterContext *ctx, AVFrame *frame)
{
double ret = 0;
SelectContext *select = ctx->priv;
AVFilterBufferRef *prev_picref = select->prev_picref;
AVFrame *prev_picref = select->prev_picref;
if (prev_picref &&
picref->video->h == prev_picref->video->h &&
picref->video->w == prev_picref->video->w &&
picref->linesize[0] == prev_picref->linesize[0]) {
frame->height == prev_picref->height &&
frame->width == prev_picref->width &&
frame->linesize[0] == prev_picref->linesize[0]) {
int x, y, nb_sad = 0;
int64_t sad = 0;
double mafd, diff;
uint8_t *p1 = picref->data[0];
uint8_t *p1 = frame->data[0];
uint8_t *p2 = prev_picref->data[0];
const int linesize = picref->linesize[0];
const int linesize = frame->linesize[0];
for (y = 0; y < picref->video->h - 8; y += 8) {
for (x = 0; x < picref->video->w*3 - 8; x += 8) {
for (y = 0; y < frame->height - 8; y += 8) {
for (x = 0; x < frame->width*3 - 8; x += 8) {
sad += select->c.sad[1](select, p1 + x, p2 + x,
linesize, 8);
nb_sad += 8 * 8;
@ -250,9 +250,9 @@ static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref)
diff = fabs(mafd - select->prev_mafd);
ret = av_clipf(FFMIN(mafd, diff) / 100., 0, 1);
select->prev_mafd = mafd;
avfilter_unref_buffer(prev_picref);
av_frame_free(&prev_picref);
}
select->prev_picref = avfilter_ref_buffer(picref, ~0);
select->prev_picref = av_frame_clone(frame);
return ret;
}
#endif
@ -260,38 +260,38 @@ static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref)
#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *ref)
static int select_frame(AVFilterContext *ctx, AVFrame *frame)
{
SelectContext *select = ctx->priv;
AVFilterLink *inlink = ctx->inputs[0];
double res;
if (isnan(select->var_values[VAR_START_PTS]))
select->var_values[VAR_START_PTS] = TS2D(ref->pts);
select->var_values[VAR_START_PTS] = TS2D(frame->pts);
if (isnan(select->var_values[VAR_START_T]))
select->var_values[VAR_START_T] = TS2D(ref->pts) * av_q2d(inlink->time_base);
select->var_values[VAR_START_T] = TS2D(frame->pts) * av_q2d(inlink->time_base);
select->var_values[VAR_PTS] = TS2D(ref->pts);
select->var_values[VAR_T ] = TS2D(ref->pts) * av_q2d(inlink->time_base);
select->var_values[VAR_POS] = ref->pos == -1 ? NAN : ref->pos;
select->var_values[VAR_PTS] = TS2D(frame->pts);
select->var_values[VAR_T ] = TS2D(frame->pts) * av_q2d(inlink->time_base);
select->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ? NAN : av_frame_get_pkt_pos(frame);
switch (inlink->type) {
case AVMEDIA_TYPE_AUDIO:
select->var_values[VAR_SAMPLES_N] = ref->audio->nb_samples;
select->var_values[VAR_SAMPLES_N] = frame->nb_samples;
break;
case AVMEDIA_TYPE_VIDEO:
select->var_values[VAR_INTERLACE_TYPE] =
!ref->video->interlaced ? INTERLACE_TYPE_P :
ref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
select->var_values[VAR_PICT_TYPE] = ref->video->pict_type;
!frame->interlaced_frame ? INTERLACE_TYPE_P :
frame->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
select->var_values[VAR_PICT_TYPE] = frame->pict_type;
#if CONFIG_AVCODEC
if (select->do_scene_detect) {
char buf[32];
select->var_values[VAR_SCENE] = get_scene_score(ctx, ref);
select->var_values[VAR_SCENE] = get_scene_score(ctx, frame);
// TODO: document metadata
snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]);
av_dict_set(&ref->metadata, "lavfi.scene_score", buf, 0);
av_dict_set(&frame->metadata, "lavfi.scene_score", buf, 0);
}
#endif
break;
@ -299,11 +299,10 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *ref)
res = av_expr_eval(select->expr, select->var_values, NULL);
av_log(inlink->dst, AV_LOG_DEBUG,
"n:%f pts:%f t:%f pos:%f key:%d",
"n:%f pts:%f t:%f key:%d",
select->var_values[VAR_N],
select->var_values[VAR_PTS],
select->var_values[VAR_T],
select->var_values[VAR_POS],
(int)select->var_values[VAR_KEY]);
switch (inlink->type) {
@ -330,7 +329,7 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *ref)
select->var_values[VAR_PREV_SELECTED_T] = select->var_values[VAR_T];
select->var_values[VAR_SELECTED_N] += 1.0;
if (inlink->type == AVMEDIA_TYPE_AUDIO)
select->var_values[VAR_CONSUMED_SAMPLES_N] += ref->audio->nb_samples;
select->var_values[VAR_CONSUMED_SAMPLES_N] += frame->nb_samples;
}
select->var_values[VAR_N] += 1.0;
@ -340,7 +339,7 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *ref)
return res;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
SelectContext *select = inlink->dst->priv;
@ -348,7 +347,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
if (select->select)
return ff_filter_frame(inlink->dst->outputs[0], frame);
avfilter_unref_bufferp(&frame);
av_frame_free(&frame);
return 0;
}
@ -378,7 +377,7 @@ static av_cold void uninit(AVFilterContext *ctx)
#if CONFIG_AVCODEC
if (select->do_scene_detect) {
avfilter_unref_bufferp(&select->prev_picref);
av_frame_free(&select->prev_picref);
if (select->avctx) {
avcodec_close(select->avctx);
av_freep(&select->avctx);

View File

@ -448,7 +448,7 @@ static void av_cold uninit(AVFilterContext *ctx)
av_freep(&sendcmd->intervals);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
{
AVFilterContext *ctx = inlink->dst;
SendCmdContext *sendcmd = ctx->priv;

View File

@ -138,7 +138,7 @@ static inline char *double2int64str(char *buf, double v)
#define d2istr(v) double2int64str((char[BUF_SIZE]){0}, v)
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
SetPTSContext *setpts = inlink->dst->priv;
int64_t in_pts = frame->pts;
@ -150,16 +150,16 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
}
setpts->var_values[VAR_PTS ] = TS2D(frame->pts);
setpts->var_values[VAR_T ] = TS2T(frame->pts, inlink->time_base);
setpts->var_values[VAR_POS ] = frame->pos == -1 ? NAN : frame->pos;
setpts->var_values[VAR_POS ] = av_frame_get_pkt_pos(frame) == -1 ? NAN : av_frame_get_pkt_pos(frame);
setpts->var_values[VAR_RTCTIME ] = av_gettime();
switch (inlink->type) {
case AVMEDIA_TYPE_VIDEO:
setpts->var_values[VAR_INTERLACED] = frame->video->interlaced;
setpts->var_values[VAR_INTERLACED] = frame->interlaced_frame;
break;
case AVMEDIA_TYPE_AUDIO:
setpts->var_values[VAR_NB_SAMPLES] = frame->audio->nb_samples;
setpts->var_values[VAR_NB_SAMPLES] = frame->nb_samples;
break;
}
@ -192,7 +192,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
setpts->var_values[VAR_PREV_OUTT] = TS2T(frame->pts, inlink->time_base);
setpts->var_values[VAR_N] += 1.0;
if (setpts->type == AVMEDIA_TYPE_AUDIO) {
setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += frame->audio->nb_samples;
setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += frame->nb_samples;
}
return ff_filter_frame(inlink->dst->outputs[0], frame);
}

View File

@ -103,7 +103,7 @@ static int config_output_props(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];

View File

@ -35,7 +35,7 @@
#include "video.h"
typedef struct Buf {
AVFilterBufferRef *buf;
AVFrame *frame;
struct Buf *next;
} Buf;
@ -47,8 +47,8 @@ typedef struct {
* When a specific number of output samples is requested, the partial
* buffer is stored here
*/
AVFilterBufferRef *buf_out;
int allocated_samples; ///< number of samples buf_out was allocated for
AVFrame *out;
int allocated_samples; ///< number of samples out was allocated for
} FifoContext;
static av_cold int init(AVFilterContext *ctx, const char *args)
@ -66,25 +66,25 @@ static av_cold void uninit(AVFilterContext *ctx)
for (buf = fifo->root.next; buf; buf = tmp) {
tmp = buf->next;
avfilter_unref_bufferp(&buf->buf);
av_frame_free(&buf->frame);
av_free(buf);
}
avfilter_unref_bufferp(&fifo->buf_out);
av_frame_free(&fifo->out);
}
static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int add_to_queue(AVFilterLink *inlink, AVFrame *frame)
{
FifoContext *fifo = inlink->dst->priv;
fifo->last->next = av_mallocz(sizeof(Buf));
if (!fifo->last->next) {
avfilter_unref_buffer(buf);
av_frame_free(&frame);
return AVERROR(ENOMEM);
}
fifo->last = fifo->last->next;
fifo->last->buf = buf;
fifo->last->frame = frame;
return 0;
}
@ -101,7 +101,7 @@ static void queue_pop(FifoContext *s)
/**
* Move data pointers and pts offset samples forward.
*/
static void buffer_offset(AVFilterLink *link, AVFilterBufferRef *buf,
static void buffer_offset(AVFilterLink *link, AVFrame *frame,
int offset)
{
int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
@ -110,32 +110,32 @@ static void buffer_offset(AVFilterLink *link, AVFilterBufferRef *buf,
int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels);
int i;
av_assert0(buf->audio->nb_samples > offset);
av_assert0(frame->nb_samples > offset);
for (i = 0; i < planes; i++)
buf->extended_data[i] += block_align*offset;
if (buf->data != buf->extended_data)
memcpy(buf->data, buf->extended_data,
FFMIN(planes, FF_ARRAY_ELEMS(buf->data)) * sizeof(*buf->data));
buf->linesize[0] -= block_align*offset;
buf->audio->nb_samples -= offset;
frame->extended_data[i] += block_align * offset;
if (frame->data != frame->extended_data)
memcpy(frame->data, frame->extended_data,
FFMIN(planes, FF_ARRAY_ELEMS(frame->data)) * sizeof(*frame->data));
frame->linesize[0] -= block_align*offset;
frame->nb_samples -= offset;
if (buf->pts != AV_NOPTS_VALUE) {
buf->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate},
link->time_base);
if (frame->pts != AV_NOPTS_VALUE) {
frame->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate},
link->time_base);
}
}
static int calc_ptr_alignment(AVFilterBufferRef *buf)
static int calc_ptr_alignment(AVFrame *frame)
{
int planes = av_sample_fmt_is_planar(buf->format) ?
av_get_channel_layout_nb_channels(buf->audio->channel_layout) : 1;
int planes = av_sample_fmt_is_planar(frame->format) ?
av_get_channel_layout_nb_channels(frame->channel_layout) : 1;
int min_align = 128;
int p;
for (p = 0; p < planes; p++) {
int cur_align = 128;
while ((intptr_t)buf->extended_data[p] % cur_align)
while ((intptr_t)frame->extended_data[p] % cur_align)
cur_align >>= 1;
if (cur_align < min_align)
min_align = cur_align;
@ -147,35 +147,34 @@ static int return_audio_frame(AVFilterContext *ctx)
{
AVFilterLink *link = ctx->outputs[0];
FifoContext *s = ctx->priv;
AVFilterBufferRef *head = s->root.next->buf;
AVFilterBufferRef *buf_out;
AVFrame *head = s->root.next->frame;
AVFrame *out;
int ret;
if (!s->buf_out &&
head->audio->nb_samples >= link->request_samples &&
if (!s->out &&
head->nb_samples >= link->request_samples &&
calc_ptr_alignment(head) >= 32) {
if (head->audio->nb_samples == link->request_samples) {
buf_out = head;
if (head->nb_samples == link->request_samples) {
out = head;
queue_pop(s);
} else {
buf_out = avfilter_ref_buffer(head, AV_PERM_READ);
if (!buf_out)
out = av_frame_clone(head);
if (!out)
return AVERROR(ENOMEM);
buf_out->audio->nb_samples = link->request_samples;
out->nb_samples = link->request_samples;
buffer_offset(link, head, link->request_samples);
}
} else {
int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
if (!s->buf_out) {
s->buf_out = ff_get_audio_buffer(link, AV_PERM_WRITE,
link->request_samples);
if (!s->buf_out)
if (!s->out) {
s->out = ff_get_audio_buffer(link, link->request_samples);
if (!s->out)
return AVERROR(ENOMEM);
s->buf_out->audio->nb_samples = 0;
s->buf_out->pts = head->pts;
s->out->nb_samples = 0;
s->out->pts = head->pts;
s->allocated_samples = link->request_samples;
} else if (link->request_samples != s->allocated_samples) {
av_log(ctx, AV_LOG_ERROR, "request_samples changed before the "
@ -183,41 +182,41 @@ static int return_audio_frame(AVFilterContext *ctx)
return AVERROR(EINVAL);
}
while (s->buf_out->audio->nb_samples < s->allocated_samples) {
int len = FFMIN(s->allocated_samples - s->buf_out->audio->nb_samples,
head->audio->nb_samples);
while (s->out->nb_samples < s->allocated_samples) {
int len = FFMIN(s->allocated_samples - s->out->nb_samples,
head->nb_samples);
av_samples_copy(s->buf_out->extended_data, head->extended_data,
s->buf_out->audio->nb_samples, 0, len, nb_channels,
av_samples_copy(s->out->extended_data, head->extended_data,
s->out->nb_samples, 0, len, nb_channels,
link->format);
s->buf_out->audio->nb_samples += len;
s->out->nb_samples += len;
if (len == head->audio->nb_samples) {
avfilter_unref_buffer(head);
if (len == head->nb_samples) {
av_frame_free(&head);
queue_pop(s);
if (!s->root.next &&
(ret = ff_request_frame(ctx->inputs[0])) < 0) {
if (ret == AVERROR_EOF) {
av_samples_set_silence(s->buf_out->extended_data,
s->buf_out->audio->nb_samples,
av_samples_set_silence(s->out->extended_data,
s->out->nb_samples,
s->allocated_samples -
s->buf_out->audio->nb_samples,
s->out->nb_samples,
nb_channels, link->format);
s->buf_out->audio->nb_samples = s->allocated_samples;
s->out->nb_samples = s->allocated_samples;
break;
}
return ret;
}
head = s->root.next->buf;
head = s->root.next->frame;
} else {
buffer_offset(link, head, len);
}
}
buf_out = s->buf_out;
s->buf_out = NULL;
out = s->out;
s->out = NULL;
}
return ff_filter_frame(link, buf_out);
return ff_filter_frame(link, out);
}
static int request_frame(AVFilterLink *outlink)
@ -234,7 +233,7 @@ static int request_frame(AVFilterLink *outlink)
if (outlink->request_samples) {
return return_audio_frame(outlink->src);
} else {
ret = ff_filter_frame(outlink, fifo->root.next->buf);
ret = ff_filter_frame(outlink, fifo->root.next->frame);
queue_pop(fifo);
}
@ -247,7 +246,6 @@ static const AVFilterPad avfilter_vf_fifo_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = ff_null_get_video_buffer,
.filter_frame = add_to_queue,
.min_perms = AV_PERM_PRESERVE,
},
{ NULL }
};
@ -280,7 +278,6 @@ static const AVFilterPad avfilter_af_afifo_inputs[] = {
.type = AVMEDIA_TYPE_AUDIO,
.get_audio_buffer = ff_null_get_audio_buffer,
.filter_frame = add_to_queue,
.min_perms = AV_PERM_PRESERVE,
},
{ NULL }
};

View File

@ -67,33 +67,13 @@ struct AVFilterPad {
*/
enum AVMediaType type;
/**
* Minimum required permissions on incoming buffers. Any buffer with
* insufficient permissions will be automatically copied by the filter
* system to a new buffer which provides the needed access permissions.
*
* Input pads only.
*/
int min_perms;
/**
* Permissions which are not accepted on incoming buffers. Any buffer
* which has any of these permissions set will be automatically copied
* by the filter system to a new buffer which does not have those
* permissions. This can be used to easily disallow buffers with
* AV_PERM_REUSE.
*
* Input pads only.
*/
int rej_perms;
/**
* Callback function to get a video buffer. If NULL, the filter system will
* use ff_default_get_video_buffer().
*
* Input video pads only.
*/
AVFilterBufferRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h);
AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);
/**
* Callback function to get an audio buffer. If NULL, the filter system will
@ -101,8 +81,7 @@ struct AVFilterPad {
*
* Input audio pads only.
*/
AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
int nb_samples);
AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);
/**
* Filtering callback. This is where a filter receives a frame with
@ -114,7 +93,7 @@ struct AVFilterPad {
* must ensure that samplesref is properly unreferenced on error if it
* hasn't been passed on to another filter.
*/
int (*filter_frame)(AVFilterLink *link, AVFilterBufferRef *frame);
int (*filter_frame)(AVFilterLink *link, AVFrame *frame);
/**
* Frame poll callback. This returns the number of immediately available
@ -234,8 +213,6 @@ int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx);
void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);
void ff_free_pool(AVFilterPool *pool);
void ff_command_queue_pop(AVFilterContext *filter);
/* misc trace functions */
@ -252,7 +229,7 @@ void ff_command_queue_pop(AVFilterContext *filter);
char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms);
void ff_tlog_ref(void *ctx, AVFilterBufferRef *ref, int end);
void ff_tlog_ref(void *ctx, AVFrame *ref, int end);
void ff_tlog_link(void *ctx, AVFilterLink *link, int end);
@ -346,6 +323,6 @@ int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **
* @return >= 0 on success, a negative AVERROR on error. The receiving filter
* is responsible for unreferencing frame in case of error.
*/
int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame);
int ff_filter_frame(AVFilterLink *link, AVFrame *frame);
#endif /* AVFILTER_INTERNAL_H */

View File

@ -31,6 +31,8 @@
#include "audio.h"
#include "internal.h"
#include "libavutil/audio_fifo.h"
AVBufferSinkParams *av_buffersink_params_alloc(void)
{
static const int pixel_fmts[] = { AV_PIX_FMT_NONE };
@ -88,14 +90,14 @@ static av_cold void common_uninit(AVFilterContext *ctx)
if (buf->fifo) {
while (av_fifo_size(buf->fifo) >= sizeof(AVFilterBufferRef *)) {
av_fifo_generic_read(buf->fifo, &picref, sizeof(picref), NULL);
avfilter_unref_buffer(picref);
av_frame_unref(picref);
}
av_fifo_free(buf->fifo);
buf->fifo = NULL;
}
}
static int add_buffer_ref(AVFilterContext *ctx, AVFilterBufferRef *ref)
static int add_buffer_ref(AVFilterContext *ctx, AVFrame *ref)
{
BufferSinkContext *buf = ctx->priv;
@ -114,7 +116,7 @@ static int add_buffer_ref(AVFilterContext *ctx, AVFilterBufferRef *ref)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
{
AVFilterContext *ctx = inlink->dst;
BufferSinkContext *buf = inlink->dst->priv;
@ -141,6 +143,116 @@ void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)
inlink->partial_buf_size = frame_size;
}
int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
{
BufferSinkContext *buf = ctx->priv;
AVFilterLink *inlink = ctx->inputs[0];
int ret;
AVFrame *cur_frame;
/* no picref available, fetch it from the filterchain */
if (!av_fifo_size(buf->fifo)) {
if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
return AVERROR(EAGAIN);
if ((ret = ff_request_frame(inlink)) < 0)
return ret;
}
if (!av_fifo_size(buf->fifo))
return AVERROR(EINVAL);
if (flags & AV_BUFFERSINK_FLAG_PEEK) {
cur_frame = *((AVFrame **)av_fifo_peek2(buf->fifo, 0));
av_frame_ref(frame, cur_frame); /* TODO check failure */
} else {
av_fifo_generic_read(buf->fifo, &cur_frame, sizeof(cur_frame), NULL);
av_frame_move_ref(frame, cur_frame);
av_frame_free(&cur_frame);
}
return 0;
}
int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
{
return av_buffersink_get_frame_flags(ctx, frame, 0);
}
int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples)
{
av_assert0(!"TODO");
}
#if FF_API_AVFILTERBUFFER
static void compat_free_buffer(AVFilterBuffer *buf)
{
AVFrame *frame = buf->priv;
av_frame_free(&frame);
av_free(buf);
}
static int compat_read(AVFilterContext *ctx, AVFilterBufferRef **pbuf, int nb_samples, int flags)
{
AVFilterBufferRef *buf;
AVFrame *frame;
int ret;
if (!pbuf)
return ff_poll_frame(ctx->inputs[0]);
frame = av_frame_alloc();
if (!frame)
return AVERROR(ENOMEM);
if (!nb_samples)
ret = av_buffersink_get_frame_flags(ctx, frame, flags);
else
ret = av_buffersink_get_samples(ctx, frame, nb_samples);
if (ret < 0)
goto fail;
if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) {
buf = avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize,
AV_PERM_READ,
frame->width, frame->height,
frame->format);
} else {
buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data,
frame->linesize[0], AV_PERM_READ,
frame->nb_samples,
frame->format,
frame->channel_layout);
}
if (!buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
avfilter_copy_frame_props(buf, frame);
buf->buf->priv = frame;
buf->buf->free = compat_free_buffer;
*pbuf = buf;
return 0;
fail:
av_frame_free(&frame);
return ret;
}
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
{
return compat_read(ctx, buf, 0, 0);
}
int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
int nb_samples)
{
return compat_read(ctx, buf, nb_samples, 0);
}
int av_buffersink_get_buffer_ref(AVFilterContext *ctx,
AVFilterBufferRef **bufref, int flags)
{
@ -154,24 +266,9 @@ int av_buffersink_get_buffer_ref(AVFilterContext *ctx,
|| !strcmp(ctx->filter->name, "ffbuffersink")
|| !strcmp(ctx->filter->name, "ffabuffersink"));
/* no picref available, fetch it from the filterchain */
if (!av_fifo_size(buf->fifo)) {
if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
return AVERROR(EAGAIN);
if ((ret = ff_request_frame(inlink)) < 0)
return ret;
}
if (!av_fifo_size(buf->fifo))
return AVERROR(EINVAL);
if (flags & AV_BUFFERSINK_FLAG_PEEK)
*bufref = *((AVFilterBufferRef **)av_fifo_peek2(buf->fifo, 0));
else
av_fifo_generic_read(buf->fifo, bufref, sizeof(*bufref), NULL);
return 0;
return compat_read(ctx, bufref, 0, flags);
}
#endif
AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx)
{
@ -406,94 +503,3 @@ AVFilter avfilter_asink_abuffersink = {
.inputs = abuffersink_inputs,
.outputs = NULL,
};
/* Libav compatibility API */
extern AVFilter avfilter_vsink_buffer;
extern AVFilter avfilter_asink_abuffer;
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
{
AVFilterBufferRef *tbuf;
int ret;
if (ctx->filter-> inputs[0].start_frame ==
avfilter_vsink_buffer. inputs[0].start_frame ||
ctx->filter-> inputs[0].filter_frame ==
avfilter_asink_abuffer.inputs[0].filter_frame)
return ff_buffersink_read_compat(ctx, buf);
av_assert0(ctx->filter-> inputs[0].end_frame ==
avfilter_vsink_ffbuffersink. inputs[0].end_frame ||
ctx->filter-> inputs[0].filter_frame ==
avfilter_asink_ffabuffersink.inputs[0].filter_frame);
ret = av_buffersink_get_buffer_ref(ctx, &tbuf,
buf ? 0 : AV_BUFFERSINK_FLAG_PEEK);
if (!buf)
return ret >= 0;
if (ret < 0)
return ret;
*buf = tbuf;
return 0;
}
int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
int nb_samples)
{
BufferSinkContext *sink = ctx->priv;
int ret = 0, have_samples = 0, need_samples;
AVFilterBufferRef *tbuf, *in_buf;
AVFilterLink *link = ctx->inputs[0];
int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
if (ctx->filter-> inputs[0].filter_frame ==
avfilter_asink_abuffer.inputs[0].filter_frame)
return ff_buffersink_read_samples_compat(ctx, buf, nb_samples);
av_assert0(ctx->filter-> inputs[0].filter_frame ==
avfilter_asink_ffabuffersink.inputs[0].filter_frame);
tbuf = ff_get_audio_buffer(link, AV_PERM_WRITE, nb_samples);
if (!tbuf)
return AVERROR(ENOMEM);
while (have_samples < nb_samples) {
ret = av_buffersink_get_buffer_ref(ctx, &in_buf,
AV_BUFFERSINK_FLAG_PEEK);
if (ret < 0) {
if (ret == AVERROR_EOF && have_samples) {
nb_samples = have_samples;
ret = 0;
}
break;
}
need_samples = FFMIN(in_buf->audio->nb_samples,
nb_samples - have_samples);
av_samples_copy(tbuf->extended_data, in_buf->extended_data,
have_samples, 0, need_samples,
nb_channels, in_buf->format);
have_samples += need_samples;
if (need_samples < in_buf->audio->nb_samples) {
in_buf->audio->nb_samples -= need_samples;
av_samples_copy(in_buf->extended_data, in_buf->extended_data,
0, need_samples, in_buf->audio->nb_samples,
nb_channels, in_buf->format);
} else {
av_buffersink_get_buffer_ref(ctx, &in_buf, 0);
avfilter_unref_buffer(in_buf);
}
}
tbuf->audio->nb_samples = have_samples;
if (ret < 0) {
av_assert0(!av_fifo_size(sink->fifo));
if (have_samples)
add_buffer_ref(ctx, tbuf);
else
avfilter_unref_buffer(tbuf);
return ret;
}
*buf = tbuf;
return 0;
}

View File

@ -68,17 +68,17 @@ static void split_uninit(AVFilterContext *ctx)
av_freep(&ctx->output_pads[i].name);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
int i, ret = AVERROR_EOF;
for (i = 0; i < ctx->nb_outputs; i++) {
AVFilterBufferRef *buf_out;
AVFrame *buf_out;
if (ctx->outputs[i]->closed)
continue;
buf_out = avfilter_ref_buffer(frame, ~AV_PERM_WRITE);
buf_out = av_frame_clone(frame);
if (!buf_out) {
ret = AVERROR(ENOMEM);
break;
@ -88,7 +88,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
if (ret < 0)
break;
}
avfilter_unref_bufferp(&frame);
av_frame_free(&frame);
return ret;
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2008 Vitor Sessak
* Copyright (c) 2010 S.N. Hemanth Meenakshisundaram
* Copyright (c) 2011 Mina Nagy Zaki
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* memory buffer source filter
*/
#include "avfilter.h"
#include "internal.h"
#include "audio.h"
#include "avcodec.h"
#include "buffersrc.h"
#include "asrc_abuffer.h"
#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
#include "libavutil/fifo.h"
#include "libavutil/imgutils.h"
typedef struct {
AVFifoBuffer *fifo;
AVRational time_base; ///< time_base to set in the output link
int eof;
unsigned nb_failed_requests;
/* Video only */
AVFilterContext *scale;
int h, w;
enum AVPixelFormat pix_fmt;
AVRational sample_aspect_ratio;
char sws_param[256];
/* Audio only */
// Audio format of incoming buffers
int sample_rate;
unsigned int sample_format;
int64_t channel_layout;
// Normalization filters
AVFilterContext *aconvert;
AVFilterContext *aresample;
} BufferSourceContext;
static void buf_free(AVFilterBuffer *ptr)
{
av_free(ptr);
return;
}
int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx,
AVFilterBufferRef *samplesref,
int av_unused flags)
{
return av_buffersrc_add_ref(ctx, samplesref, AV_BUFFERSRC_FLAG_NO_COPY);
}
int av_asrc_buffer_add_samples(AVFilterContext *ctx,
uint8_t *data[8], int linesize[8],
int nb_samples, int sample_rate,
int sample_fmt, int64_t channel_layout, int planar,
int64_t pts, int av_unused flags)
{
AVFilterBufferRef *samplesref;
if (!channel_layout)
return AVERROR(EINVAL);
samplesref = avfilter_get_audio_buffer_ref_from_arrays(
data, linesize[0], AV_PERM_WRITE,
nb_samples,
sample_fmt, channel_layout);
if (!samplesref)
return AVERROR(ENOMEM);
samplesref->buf->free = buf_free;
samplesref->pts = pts;
samplesref->audio->sample_rate = sample_rate;
AV_NOWARN_DEPRECATED(
return av_asrc_buffer_add_audio_buffer_ref(ctx, samplesref, 0);
)
}
int av_asrc_buffer_add_buffer(AVFilterContext *ctx,
uint8_t *buf, int buf_size, int sample_rate,
int sample_fmt, int64_t channel_layout, int planar,
int64_t pts, int av_unused flags)
{
uint8_t *data[8] = {0};
int linesize[8];
int nb_channels = av_get_channel_layout_nb_channels(channel_layout),
nb_samples = buf_size / nb_channels / av_get_bytes_per_sample(sample_fmt);
av_samples_fill_arrays(data, linesize,
buf, nb_channels, nb_samples,
sample_fmt, 16);
AV_NOWARN_DEPRECATED(
return av_asrc_buffer_add_samples(ctx,
data, linesize, nb_samples,
sample_rate,
sample_fmt, channel_layout, planar,
pts, flags);
)
}

View File

@ -313,11 +313,6 @@ static av_cold int movie_common_init(AVFilterContext *ctx, const char *args, con
}
}
if (!(movie->frame = avcodec_alloc_frame()) ) {
av_log(log, AV_LOG_ERROR, "Failed to alloc frame\n");
return AVERROR(ENOMEM);
}
av_log(ctx, AV_LOG_VERBOSE, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n",
movie->seek_point, movie->format_name, movie->file_name,
movie->stream_index);
@ -339,7 +334,7 @@ static av_cold void movie_uninit(AVFilterContext *ctx)
av_freep(&movie->file_name);
av_freep(&movie->st);
av_freep(&movie->out_index);
avcodec_free_frame(&movie->frame);
av_frame_free(&movie->frame);
if (movie->format_ctx)
avformat_close_input(&movie->format_ctx);
}
@ -399,54 +394,34 @@ static int movie_config_output_props(AVFilterLink *outlink)
return 0;
}
static AVFilterBufferRef *frame_to_buf(enum AVMediaType type, AVFrame *frame,
AVFilterLink *outlink)
{
AVFilterBufferRef *buf, *copy;
buf = avfilter_get_buffer_ref_from_frame(type, frame,
AV_PERM_WRITE |
AV_PERM_PRESERVE |
AV_PERM_REUSE2);
if (!buf)
return NULL;
buf->pts = av_frame_get_best_effort_timestamp(frame);
copy = ff_copy_buffer_ref(outlink, buf);
if (!copy)
return NULL;
buf->buf->data[0] = NULL; /* it belongs to the frame */
avfilter_unref_buffer(buf);
return copy;
}
static char *describe_bufref_to_str(char *dst, size_t dst_size,
AVFilterBufferRef *buf,
static char *describe_frame_to_str(char *dst, size_t dst_size,
AVFrame *frame,
AVFilterLink *link)
{
switch (buf->type) {
switch (frame->type) {
case AVMEDIA_TYPE_VIDEO:
snprintf(dst, dst_size,
"video pts:%s time:%s pos:%"PRId64" size:%dx%d aspect:%d/%d",
av_ts2str(buf->pts), av_ts2timestr(buf->pts, &link->time_base),
buf->pos, buf->video->w, buf->video->h,
buf->video->sample_aspect_ratio.num,
buf->video->sample_aspect_ratio.den);
"video pts:%s time:%s size:%dx%d aspect:%d/%d",
av_ts2str(frame->pts), av_ts2timestr(frame->pts, &link->time_base),
frame->width, frame->height,
frame->sample_aspect_ratio.num,
frame->sample_aspect_ratio.den);
break;
case AVMEDIA_TYPE_AUDIO:
snprintf(dst, dst_size,
"audio pts:%s time:%s pos:%"PRId64" samples:%d",
av_ts2str(buf->pts), av_ts2timestr(buf->pts, &link->time_base),
buf->pos, buf->audio->nb_samples);
"audio pts:%s time:%s samples:%d",
av_ts2str(frame->pts), av_ts2timestr(frame->pts, &link->time_base),
frame->nb_samples);
break;
default:
snprintf(dst, dst_size, "%s BUG", av_get_media_type_string(buf->type));
snprintf(dst, dst_size, "%s BUG", av_get_media_type_string(frame->type));
break;
}
return dst;
}
#define describe_bufref(buf, link) \
describe_bufref_to_str((char[1024]){0}, 1024, buf, link)
#define describe_frameref(f, link) \
describe_frame_to_str((char[1024]){0}, 1024, f, link)
static int rewind_file(AVFilterContext *ctx)
{
@ -489,7 +464,6 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id)
MovieStream *st;
int ret, got_frame = 0, pkt_out_id;
AVFilterLink *outlink;
AVFilterBufferRef *buf;
if (!pkt->size) {
if (movie->eof) {
@ -532,6 +506,10 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id)
st = &movie->st[pkt_out_id];
outlink = ctx->outputs[pkt_out_id];
movie->frame = av_frame_alloc();
if (!movie->frame)
return AVERROR(ENOMEM);
switch (st->st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
ret = avcodec_decode_video2(st->st->codec, movie->frame, &got_frame, pkt);
@ -545,6 +523,7 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id)
}
if (ret < 0) {
av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret));
av_frame_free(&movie->frame);
return 0;
}
if (!ret)
@ -560,23 +539,16 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id)
if (!got_frame) {
if (!ret)
st->done = 1;
av_frame_free(&movie->frame);
return 0;
}
buf = frame_to_buf(st->st->codec->codec_type, movie->frame, outlink);
if (!buf)
return AVERROR(ENOMEM);
av_dlog(ctx, "movie_push_frame(): file:'%s' %s\n", movie->file_name,
describe_bufref(buf, outlink));
switch (st->st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
if (!movie->frame->sample_aspect_ratio.num)
buf->video->sample_aspect_ratio = st->st->sample_aspect_ratio;
/* Fall through */
case AVMEDIA_TYPE_AUDIO:
ff_filter_frame(outlink, buf);
break;
}
describe_frameref(movie->frame, outlink));
movie->frame->pts = av_frame_get_best_effort_timestamp(movie->frame);
ff_filter_frame(outlink, movie->frame); // FIXME: raise error properly
movie->frame = NULL;
return pkt_out_id == out_id;
}

View File

@ -60,5 +60,8 @@
#ifndef FF_API_BUFFERSRC_BUFFER
#define FF_API_BUFFERSRC_BUFFER (LIBAVFILTER_VERSION_MAJOR < 4)
#endif
#ifndef FF_API_AVFILTERBUFFER
#define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 4)
#endif
#endif /* AVFILTER_VERSION_H */

View File

@ -60,19 +60,18 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *cur_buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *cur_buf)
{
AlphaExtractContext *extract = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out_buf =
ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
AVFrame *out_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h);
int ret;
if (!out_buf) {
ret = AVERROR(ENOMEM);
goto end;
}
avfilter_copy_buffer_ref_props(out_buf, cur_buf);
av_frame_copy_props(out_buf, cur_buf);
if (extract->is_packed_rgb) {
int x, y;
@ -99,7 +98,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *cur_buf)
ret = ff_filter_frame(outlink, out_buf);
end:
avfilter_unref_buffer(cur_buf);
av_frame_unref(cur_buf);
return ret;
}
@ -109,7 +108,6 @@ static const AVFilterPad alphaextract_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -96,11 +96,11 @@ static int config_output(AVFilterLink *outlink)
}
static void draw_frame(AVFilterContext *ctx,
AVFilterBufferRef *main_buf,
AVFilterBufferRef *alpha_buf)
AVFrame *main_buf,
AVFrame *alpha_buf)
{
AlphaMergeContext *merge = ctx->priv;
int h = main_buf->video->h;
int h = main_buf->height;
if (merge->is_packed_rgb) {
int x, y;
@ -108,7 +108,7 @@ static void draw_frame(AVFilterContext *ctx,
for (y = 0; y < h; y++) {
pin = alpha_buf->data[0] + y * alpha_buf->linesize[0];
pout = main_buf->data[0] + y * main_buf->linesize[0] + merge->rgba_map[A];
for (x = 0; x < main_buf->video->w; x++) {
for (x = 0; x < main_buf->width; x++) {
*pout = *pin;
pin += 1;
pout += 4;
@ -118,7 +118,7 @@ static void draw_frame(AVFilterContext *ctx,
int y;
const int main_linesize = main_buf->linesize[A];
const int alpha_linesize = alpha_buf->linesize[Y];
for (y = 0; y < h && y < alpha_buf->video->h; y++) {
for (y = 0; y < h && y < alpha_buf->height; y++) {
memcpy(main_buf->data[A] + y * main_linesize,
alpha_buf->data[Y] + y * alpha_linesize,
FFMIN(main_linesize, alpha_linesize));
@ -126,7 +126,7 @@ static void draw_frame(AVFilterContext *ctx,
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
AlphaMergeContext *merge = ctx->priv;
@ -137,7 +137,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
ff_bufqueue_add(ctx, queue, buf);
while (1) {
AVFilterBufferRef *main_buf, *alpha_buf;
AVFrame *main_buf, *alpha_buf;
if (!ff_bufqueue_peek(&merge->queue_main, 0) ||
!ff_bufqueue_peek(&merge->queue_alpha, 0)) break;
@ -148,7 +148,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
merge->frame_requested = 0;
draw_frame(ctx, main_buf, alpha_buf);
ff_filter_frame(ctx->outputs[0], main_buf);
avfilter_unref_buffer(alpha_buf);
av_frame_free(&alpha_buf);
}
return 0;
}

View File

@ -80,11 +80,11 @@ static av_cold int init(AVFilterContext *ctx, const char *args, const AVClass *c
return 0;
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *link, AVFrame *frame)
{
AspectContext *aspect = link->dst->priv;
frame->video->sample_aspect_ratio = aspect->ratio;
frame->sample_aspect_ratio = aspect->ratio;
return ff_filter_frame(link->dst->outputs[0], frame);
}

View File

@ -56,7 +56,7 @@ static int query_formats(AVFilterContext *ctx)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
BBoxContext *bbox = ctx->priv;
@ -65,14 +65,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
has_bbox =
ff_calculate_bounding_box(&box,
picref->data[0], picref->linesize[0],
frame->data[0], frame->linesize[0],
inlink->w, inlink->h, 16);
w = box.x2 - box.x1 + 1;
h = box.y2 - box.y1 + 1;
av_log(ctx, AV_LOG_INFO,
"n:%d pts:%s pts_time:%s", bbox->frame,
av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base));
av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base));
if (has_bbox) {
av_log(ctx, AV_LOG_INFO,
@ -85,7 +85,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
av_log(ctx, AV_LOG_INFO, "\n");
bbox->frame++;
return ff_filter_frame(inlink->dst->outputs[0], picref);
return ff_filter_frame(inlink->dst->outputs[0], frame);
}
static const AVFilterPad bbox_inputs[] = {

View File

@ -146,7 +146,7 @@ static int request_frame(AVFilterLink *outlink)
return ret;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
{
AVFilterContext *ctx = inlink->dst;
BlackDetectContext *blackdetect = ctx->priv;
@ -163,10 +163,10 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
picture_black_ratio = (double)blackdetect->nb_black_pixels / (inlink->w * inlink->h);
av_log(ctx, AV_LOG_DEBUG,
"frame:%u picture_black_ratio:%f pos:%"PRId64" pts:%s t:%s type:%c\n",
"frame:%u picture_black_ratio:%f pts:%s t:%s type:%c\n",
blackdetect->frame_count, picture_black_ratio,
picref->pos, av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base),
av_get_picture_type_char(picref->video->pict_type));
av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base),
av_get_picture_type_char(picref->pict_type));
if (picture_black_ratio >= blackdetect->picture_black_ratio_th) {
if (!blackdetect->black_started) {

View File

@ -81,7 +81,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
BlackFrameContext *blackframe = ctx->priv;
@ -89,22 +89,22 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
int pblack = 0;
uint8_t *p = frame->data[0];
for (i = 0; i < frame->video->h; i++) {
for (i = 0; i < frame->height; i++) {
for (x = 0; x < inlink->w; x++)
blackframe->nblack += p[x] < blackframe->bthresh;
p += frame->linesize[0];
}
if (frame->video->key_frame)
if (frame->key_frame)
blackframe->last_keyframe = blackframe->frame;
pblack = blackframe->nblack * 100 / (inlink->w * inlink->h);
if (pblack >= blackframe->bamount)
av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pos:%"PRId64" pts:%"PRId64" t:%f "
av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pts:%"PRId64" t:%f "
"type:%c last_keyframe:%d\n",
blackframe->frame, pblack, frame->pos, frame->pts,
blackframe->frame, pblack, frame->pts,
frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
av_get_picture_type_char(frame->video->pict_type), blackframe->last_keyframe);
av_get_picture_type_char(frame->pict_type), blackframe->last_keyframe);
blackframe->frame++;
blackframe->nblack = 0;

View File

@ -368,9 +368,9 @@ static int request_frame(AVFilterLink *outlink)
}
static void blend_frame(AVFilterContext *ctx,
AVFilterBufferRef *top_buf,
AVFilterBufferRef *bottom_buf,
AVFilterBufferRef *dst_buf)
AVFrame *top_buf,
AVFrame *bottom_buf,
AVFrame *dst_buf)
{
BlendContext *b = ctx->priv;
AVFilterLink *inlink = ctx->inputs[0];
@ -380,8 +380,8 @@ static void blend_frame(AVFilterContext *ctx,
for (plane = 0; dst_buf->data[plane]; plane++) {
int hsub = plane == 1 || plane == 2 ? b->hsub : 0;
int vsub = plane == 1 || plane == 2 ? b->vsub : 0;
int outw = dst_buf->video->w >> hsub;
int outh = dst_buf->video->h >> vsub;
int outw = dst_buf->width >> hsub;
int outh = dst_buf->height >> vsub;
uint8_t *dst = dst_buf->data[plane];
uint8_t *top = top_buf->data[plane];
uint8_t *bottom = bottom_buf->data[plane];
@ -390,15 +390,15 @@ static void blend_frame(AVFilterContext *ctx,
param->values[VAR_T] = dst_buf->pts == AV_NOPTS_VALUE ? NAN : dst_buf->pts * av_q2d(inlink->time_base);
param->values[VAR_W] = outw;
param->values[VAR_H] = outh;
param->values[VAR_SW] = outw / dst_buf->video->w;
param->values[VAR_SH] = outh / dst_buf->video->h;
param->values[VAR_SW] = outw / dst_buf->width;
param->values[VAR_SH] = outh / dst_buf->height;
param->blend(top, top_buf->linesize[plane],
bottom, bottom_buf->linesize[plane],
dst, dst_buf->linesize[plane], outw, outh, param);
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
@ -411,7 +411,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
ff_bufqueue_add(ctx, queue, buf);
while (1) {
AVFilterBufferRef *top_buf, *bottom_buf, *out_buf;
AVFrame *top_buf, *bottom_buf, *out_buf;
if (!ff_bufqueue_peek(&b->queue_top, TOP) ||
!ff_bufqueue_peek(&b->queue_bottom, BOTTOM)) break;
@ -419,18 +419,17 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
top_buf = ff_bufqueue_get(&b->queue_top);
bottom_buf = ff_bufqueue_get(&b->queue_bottom);
out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h);
out_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out_buf) {
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out_buf, top_buf);
av_frame_copy_props(out_buf, top_buf);
b->frame_requested = 0;
blend_frame(ctx, top_buf, bottom_buf, out_buf);
ret = ff_filter_frame(ctx->outputs[0], out_buf);
avfilter_unref_buffer(top_buf);
avfilter_unref_buffer(bottom_buf);
av_frame_free(&top_buf);
av_frame_free(&bottom_buf);
}
return ret;
}
@ -441,12 +440,10 @@ static const AVFilterPad blend_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input_top,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
},{
.name = "bottom",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
},
{ NULL }
};

View File

@ -328,23 +328,23 @@ static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_li
h, radius, power, temp);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
BoxBlurContext *boxblur = ctx->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
int plane;
int cw = inlink->w >> boxblur->hsub, ch = in->video->h >> boxblur->vsub;
int cw = inlink->w >> boxblur->hsub, ch = in->height >> boxblur->vsub;
int w[4] = { inlink->w, cw, cw, inlink->w };
int h[4] = { in->video->h, ch, ch, in->video->h };
int h[4] = { in->height, ch, ch, in->height };
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
for (plane = 0; in->data[plane] && plane < 4; plane++)
hblur(out->data[plane], out->linesize[plane],
@ -358,7 +358,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
boxblur->temp);
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -369,7 +369,6 @@ static const AVFilterPad avfilter_vf_boxblur_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ
},
{ NULL }
};

View File

@ -183,12 +183,12 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
}
static void process_frame_uyvy422(ColorMatrixContext *color,
AVFilterBufferRef *dst, AVFilterBufferRef *src)
AVFrame *dst, AVFrame *src)
{
const unsigned char *srcp = src->data[0];
const int src_pitch = src->linesize[0];
const int height = src->video->h;
const int width = src->video->w*2;
const int height = src->height;
const int width = src->width*2;
unsigned char *dstp = dst->data[0];
const int dst_pitch = dst->linesize[0];
const int c2 = color->yuv_convert[color->mode][0][1];
@ -215,15 +215,15 @@ static void process_frame_uyvy422(ColorMatrixContext *color,
}
static void process_frame_yuv422p(ColorMatrixContext *color,
AVFilterBufferRef *dst, AVFilterBufferRef *src)
AVFrame *dst, AVFrame *src)
{
const unsigned char *srcpU = src->data[1];
const unsigned char *srcpV = src->data[2];
const unsigned char *srcpY = src->data[0];
const int src_pitchY = src->linesize[0];
const int src_pitchUV = src->linesize[1];
const int height = src->video->h;
const int width = src->video->w;
const int height = src->height;
const int width = src->width;
unsigned char *dstpU = dst->data[1];
unsigned char *dstpV = dst->data[2];
unsigned char *dstpY = dst->data[0];
@ -257,7 +257,7 @@ static void process_frame_yuv422p(ColorMatrixContext *color,
}
static void process_frame_yuv420p(ColorMatrixContext *color,
AVFilterBufferRef *dst, AVFilterBufferRef *src)
AVFrame *dst, AVFrame *src)
{
const unsigned char *srcpU = src->data[1];
const unsigned char *srcpV = src->data[2];
@ -265,8 +265,8 @@ static void process_frame_yuv420p(ColorMatrixContext *color,
const unsigned char *srcpN = src->data[0] + src->linesize[0];
const int src_pitchY = src->linesize[0];
const int src_pitchUV = src->linesize[1];
const int height = src->video->h;
const int width = src->video->w;
const int height = src->height;
const int width = src->width;
unsigned char *dstpU = dst->data[1];
unsigned char *dstpV = dst->data[2];
unsigned char *dstpY = dst->data[0];
@ -332,19 +332,19 @@ static int query_formats(AVFilterContext *ctx)
return 0;
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *link, AVFrame *in)
{
AVFilterContext *ctx = link->dst;
ColorMatrixContext *color = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
if (in->format == AV_PIX_FMT_YUV422P)
process_frame_yuv422p(color, out, in);
@ -353,7 +353,7 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
else
process_frame_uyvy422(color, out, in);
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -362,7 +362,6 @@ static const AVFilterPad colormatrix_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.min_perms = AV_PERM_READ,
.filter_frame = filter_frame,
},
{ NULL }

View File

@ -21,17 +21,35 @@
* copy video filter
*/
#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "avfilter.h"
#include "internal.h"
#include "video.h"
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height);
if (!out) {
av_frame_free(&in);
return AVERROR(ENOMEM);
}
av_frame_copy_props(out, in);
av_image_copy(out->data, out->linesize, in->data, in->linesize,
in->format, in->width, in->height);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
static const AVFilterPad avfilter_vf_copy_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = ff_null_get_video_buffer,
.rej_perms = ~0
.filter_frame = filter_frame,
},
{ NULL }
};

View File

@ -70,7 +70,6 @@ enum var_name {
VAR_X,
VAR_Y,
VAR_N,
VAR_POS,
VAR_T,
VAR_VARS_NB
};
@ -198,7 +197,6 @@ static int config_input(AVFilterLink *link)
crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = NAN;
crop->var_values[VAR_N] = 0;
crop->var_values[VAR_T] = NAN;
crop->var_values[VAR_POS] = NAN;
av_image_fill_max_pixsteps(crop->max_step, NULL, pix_desc);
crop->hsub = pix_desc->log2_chroma_w;
@ -277,19 +275,18 @@ static int config_output(AVFilterLink *link)
return 0;
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *link, AVFrame *frame)
{
AVFilterContext *ctx = link->dst;
CropContext *crop = ctx->priv;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
int i;
frame->video->w = crop->w;
frame->video->h = crop->h;
frame->width = crop->w;
frame->height = crop->h;
crop->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
NAN : frame->pts * av_q2d(link->time_base);
crop->var_values[VAR_POS] = frame->pos == -1 ? NAN : frame->pos;
crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);
crop->var_values[VAR_Y] = av_expr_eval(crop->y_pexpr, crop->var_values, NULL);
crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);

View File

@ -117,7 +117,7 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
CropDetectContext *cd = ctx->priv;
@ -128,36 +128,36 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
if (++cd->frame_nb > 0) {
// Reset the crop area every reset_count frames, if reset_count is > 0
if (cd->reset_count > 0 && cd->frame_nb > cd->reset_count) {
cd->x1 = frame->video->w-1;
cd->y1 = frame->video->h-1;
cd->x1 = frame->width - 1;
cd->y1 = frame->height - 1;
cd->x2 = 0;
cd->y2 = 0;
cd->frame_nb = 1;
}
for (y = 0; y < cd->y1; y++) {
if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->video->w, bpp) > cd->limit) {
if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > cd->limit) {
cd->y1 = y;
break;
}
}
for (y = frame->video->h-1; y > cd->y2; y--) {
if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->video->w, bpp) > cd->limit) {
for (y = frame->height - 1; y > cd->y2; y--) {
if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > cd->limit) {
cd->y2 = y;
break;
}
}
for (y = 0; y < cd->x1; y++) {
if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->video->h, bpp) > cd->limit) {
if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > cd->limit) {
cd->x1 = y;
break;
}
}
for (y = frame->video->w-1; y > cd->x2; y--) {
if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->video->h, bpp) > cd->limit) {
for (y = frame->width - 1; y > cd->x2; y--) {
if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > cd->limit) {
cd->x2 = y;
break;
}
@ -187,8 +187,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
y += (shrink_by/2 + 1) & ~1;
av_log(ctx, AV_LOG_INFO,
"x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pos:%"PRId64" pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n",
cd->x1, cd->x2, cd->y1, cd->y2, w, h, x, y, frame->pos, frame->pts,
"x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n",
cd->x1, cd->x2, cd->y1, cd->y2, w, h, x, y, frame->pts,
frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
w, h, x, y);
}

View File

@ -47,7 +47,7 @@ typedef struct {
///< if negative: number of sequential frames which were not dropped
int hsub, vsub; ///< chroma subsampling values
AVFilterBufferRef *ref; ///< reference picture
AVFrame *ref; ///< reference picture
DSPContext dspctx; ///< context providing optimized diff routines
AVCodecContext *avctx; ///< codec context required for the DSPContext
} DecimateContext;
@ -105,7 +105,7 @@ static int diff_planes(AVFilterContext *ctx,
* different with respect to the reference frame ref.
*/
static int decimate_frame(AVFilterContext *ctx,
AVFilterBufferRef *cur, AVFilterBufferRef *ref)
AVFrame *cur, AVFrame *ref)
{
DecimateContext *decimate = ctx->priv;
int plane;
@ -122,7 +122,7 @@ static int decimate_frame(AVFilterContext *ctx,
int hsub = plane == 1 || plane == 2 ? decimate->hsub : 0;
if (diff_planes(ctx,
cur->data[plane], ref->data[plane], ref->linesize[plane],
ref->video->w>>hsub, ref->video->h>>vsub))
ref->width>>hsub, ref->height>>vsub))
return 0;
}
@ -155,7 +155,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
static av_cold void uninit(AVFilterContext *ctx)
{
DecimateContext *decimate = ctx->priv;
avfilter_unref_bufferp(&decimate->ref);
av_frame_free(&decimate->ref);
avcodec_close(decimate->avctx);
av_opt_free(decimate);
av_freep(&decimate->avctx);
@ -189,7 +189,7 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *cur)
static int filter_frame(AVFilterLink *inlink, AVFrame *cur)
{
DecimateContext *decimate = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
@ -198,11 +198,11 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *cur)
if (decimate->ref && decimate_frame(inlink->dst, cur, decimate->ref)) {
decimate->drop_count = FFMAX(1, decimate->drop_count+1);
} else {
avfilter_unref_buffer(decimate->ref);
av_frame_free(&decimate->ref);
decimate->ref = cur;
decimate->drop_count = FFMIN(-1, decimate->drop_count-1);
if (ret = ff_filter_frame(outlink, avfilter_ref_buffer(cur, ~AV_PERM_WRITE)) < 0)
if (ret = ff_filter_frame(outlink, av_frame_clone(cur)) < 0)
return ret;
}
@ -213,7 +213,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *cur)
decimate->drop_count);
if (decimate->drop_count > 0)
avfilter_unref_buffer(cur);
av_frame_free(&cur);
return 0;
}
@ -238,7 +238,6 @@ static const AVFilterPad decimate_inputs[] = {
.get_video_buffer = ff_null_get_video_buffer,
.config_props = config_input,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
},
{ NULL }
};

View File

@ -209,27 +209,28 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
DelogoContext *delogo = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
AVFilterBufferRef *out;
AVFrame *out;
int hsub0 = desc->log2_chroma_w;
int vsub0 = desc->log2_chroma_h;
int direct = 0;
int plane;
if (in->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(in)) {
direct = 1;
out = in;
} else {
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
}
for (plane = 0; plane < 4 && in->data[plane]; plane++) {
@ -246,7 +247,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
if (!direct)
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -257,7 +258,6 @@ static const AVFilterPad avfilter_vf_delogo_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = ff_null_get_video_buffer,
.filter_frame = filter_frame,
.min_perms = AV_PERM_WRITE | AV_PERM_READ,
},
{ NULL }
};

View File

@ -88,7 +88,7 @@ typedef struct {
typedef struct {
const AVClass *class;
AVFilterBufferRef *ref; ///< Previous frame
AVFrame *ref; ///< Previous frame
int rx; ///< Maximum horizontal shift
int ry; ///< Maximum vertical shift
int edge; ///< Edge fill method
@ -434,7 +434,7 @@ static av_cold void uninit(AVFilterContext *ctx)
{
DeshakeContext *deshake = ctx->priv;
avfilter_unref_buffer(deshake->ref);
av_frame_free(&deshake->ref);
if (deshake->fp)
fclose(deshake->fp);
if (deshake->avctx)
@ -443,22 +443,22 @@ static av_cold void uninit(AVFilterContext *ctx)
av_opt_free(deshake);
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *link, AVFrame *in)
{
DeshakeContext *deshake = link->dst->priv;
AVFilterLink *outlink = link->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
Transform t = {{0},0}, orig = {{0},0};
float matrix[9];
float alpha = 2.0 / deshake->refcount;
char tmp[256];
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
if (deshake->cx < 0 || deshake->cy < 0 || deshake->cw < 0 || deshake->ch < 0) {
// Find the most likely global motion for the current frame
@ -545,7 +545,7 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
avfilter_transform(in->data[2], out->data[2], in->linesize[2], out->linesize[2], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), matrix, INTERPOLATE_BILINEAR, deshake->edge);
// Cleanup the old reference frame
avfilter_unref_buffer(deshake->ref);
av_frame_free(&deshake->ref);
// Store the current frame as the reference frame for calculating the
// motion of the next frame

View File

@ -130,13 +130,13 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
DrawBoxContext *drawbox = inlink->dst->priv;
int plane, x, y, xb = drawbox->x, yb = drawbox->y;
unsigned char *row[4];
for (y = FFMAX(yb, 0); y < frame->video->h && y < (yb + drawbox->h); y++) {
for (y = FFMAX(yb, 0); y < frame->height && y < (yb + drawbox->h); y++) {
row[0] = frame->data[0] + y * frame->linesize[0];
for (plane = 1; plane < 3; plane++)
@ -144,12 +144,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
frame->linesize[plane] * (y >> drawbox->vsub);
if (drawbox->invert_color) {
for (x = FFMAX(xb, 0); x < xb + drawbox->w && x < frame->video->w; x++)
for (x = FFMAX(xb, 0); x < xb + drawbox->w && x < frame->width; x++)
if ((y - yb < drawbox->thickness-1) || (yb + drawbox->h - y < drawbox->thickness) ||
(x - xb < drawbox->thickness-1) || (xb + drawbox->w - x < drawbox->thickness))
row[0][x] = 0xff - row[0][x];
} else {
for (x = FFMAX(xb, 0); x < xb + drawbox->w && x < frame->video->w; x++) {
for (x = FFMAX(xb, 0); x < xb + drawbox->w && x < frame->width; x++) {
double alpha = (double)drawbox->yuv_color[A] / 255;
if ((y - yb < drawbox->thickness-1) || (yb + drawbox->h - y < drawbox->thickness) ||
@ -172,7 +172,7 @@ static const AVFilterPad avfilter_vf_drawbox_inputs[] = {
.config_props = config_input,
.get_video_buffer = ff_null_get_video_buffer,
.filter_frame = filter_frame,
.min_perms = AV_PERM_WRITE | AV_PERM_READ,
.needs_writable = 1,
},
{ NULL }
};

View File

@ -784,7 +784,7 @@ static int expand_text(AVFilterContext *ctx)
return 0;
}
static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
static int draw_glyphs(DrawTextContext *dtext, AVFrame *frame,
int width, int height, const uint8_t rgbcolor[4], FFDrawColor *color, int x, int y)
{
char *text = dtext->expanded_text.str;
@ -812,7 +812,7 @@ static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
y1 = dtext->positions[i].y+dtext->y+y;
ff_blend_mask(&dtext->dc, color,
picref->data, picref->linesize, width, height,
frame->data, frame->linesize, width, height,
glyph->bitmap.buffer, glyph->bitmap.pitch,
glyph->bitmap.width, glyph->bitmap.rows,
glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO ? 0 : 3,
@ -822,7 +822,7 @@ static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
return 0;
}
static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
static int draw_text(AVFilterContext *ctx, AVFrame *frame,
int width, int height)
{
DrawTextContext *dtext = ctx->priv;
@ -845,7 +845,7 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
av_bprint_clear(bp);
if(dtext->basetime != AV_NOPTS_VALUE)
now= picref->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
now= frame->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
switch (dtext->exp_mode) {
case EXP_NONE:
@ -962,23 +962,23 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
/* draw box */
if (dtext->draw_box)
ff_blend_rectangle(&dtext->dc, &dtext->boxcolor,
picref->data, picref->linesize, width, height,
frame->data, frame->linesize, width, height,
dtext->x, dtext->y, box_w, box_h);
if (dtext->shadowx || dtext->shadowy) {
if ((ret = draw_glyphs(dtext, picref, width, height, dtext->shadowcolor.rgba,
if ((ret = draw_glyphs(dtext, frame, width, height, dtext->shadowcolor.rgba,
&dtext->shadowcolor, dtext->shadowx, dtext->shadowy)) < 0)
return ret;
}
if ((ret = draw_glyphs(dtext, picref, width, height, dtext->fontcolor.rgba,
if ((ret = draw_glyphs(dtext, frame, width, height, dtext->fontcolor.rgba,
&dtext->fontcolor, 0, 0)) < 0)
return ret;
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
@ -992,7 +992,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
dtext->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
NAN : frame->pts * av_q2d(inlink->time_base);
draw_text(ctx, frame, frame->video->w, frame->video->h);
draw_text(ctx, frame, frame->width, frame->height);
av_log(ctx, AV_LOG_DEBUG, "n:%d t:%f text_w:%d text_h:%d x:%d y:%d\n",
(int)dtext->var_values[VAR_N], dtext->var_values[VAR_T],
@ -1011,8 +1011,7 @@ static const AVFilterPad avfilter_vf_drawtext_inputs[] = {
.get_video_buffer = ff_null_get_video_buffer,
.filter_frame = filter_frame,
.config_props = config_input,
.min_perms = AV_PERM_WRITE |
AV_PERM_READ,
.needs_writable = 1,
},
{ NULL }
};

View File

@ -249,21 +249,21 @@ static void double_threshold(AVFilterContext *ctx, int w, int h,
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
EdgeDetectContext *edgedetect = ctx->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
uint8_t *tmpbuf = edgedetect->tmpbuf;
uint16_t *gradients = edgedetect->gradients;
AVFilterBufferRef *out;
AVFrame *out;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
/* gaussian filter to reduce noise */
gaussian_blur(ctx, inlink->w, inlink->h,
@ -287,7 +287,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
out->data[0], out->linesize[0],
tmpbuf, inlink->w);
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -305,7 +305,6 @@ static const AVFilterPad edgedetect_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_props,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -178,7 +178,7 @@ static void fade_plane(int y, int h, int w,
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
FadeContext *fade = inlink->dst->priv;
uint8_t *p;
@ -189,21 +189,21 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
// alpha only
plane = fade->is_packed_rgb ? 0 : A; // alpha is on plane 0 for packed formats
// or plane 3 for planar formats
fade_plane(0, frame->video->h, inlink->w,
fade_plane(0, frame->height, inlink->w,
fade->factor, fade->black_level, fade->black_level_scaled,
fade->is_packed_rgb ? fade->rgba_map[A] : 0, // alpha offset for packed formats
fade->is_packed_rgb ? 4 : 1, // pixstep for 8 bit packed formats
1, frame->data[plane], frame->linesize[plane]);
} else {
/* luma or rgb plane */
fade_plane(0, frame->video->h, inlink->w,
fade_plane(0, frame->height, inlink->w,
fade->factor, fade->black_level, fade->black_level_scaled,
0, 1, // offset & pixstep for Y plane or RGB packed format
fade->bpp, frame->data[0], frame->linesize[0]);
if (frame->data[1] && frame->data[2]) {
/* chroma planes */
for (plane = 1; plane < 3; plane++) {
for (i = 0; i < frame->video->h; i++) {
for (i = 0; i < frame->height; i++) {
p = frame->data[plane] + (i >> fade->vsub) * frame->linesize[plane];
for (j = 0; j < inlink->w >> fade->hsub; j++) {
/* 8421367 = ((128 << 1) + 1) << 15. It is an integer
@ -234,7 +234,7 @@ static const AVFilterPad avfilter_vf_fade_inputs[] = {
.config_props = config_props,
.get_video_buffer = ff_null_get_video_buffer,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_WRITE,
.needs_writable = 1,
},
{ NULL }
};

View File

@ -82,14 +82,14 @@ static int config_props_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
{
FieldContext *field = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
int i;
inpicref->video->h = outlink->h;
inpicref->video->interlaced = 0;
inpicref->height = outlink->h;
inpicref->interlaced_frame = 0;
for (i = 0; i < field->nb_planes; i++) {
if (field->type == FIELD_TYPE_BOTTOM)

View File

@ -113,15 +113,15 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
return ff_get_video_buffer(outlink, perms, w, h);
return ff_get_video_buffer(outlink, w, h);
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
AVFilterContext *ctx = inlink->dst;
FieldOrderContext *s = ctx->priv;
@ -129,14 +129,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
int h, plane, line_step, line_size, line;
uint8_t *data;
if (!frame->video->interlaced ||
frame->video->top_field_first == s->dst_tff)
if (!frame->interlaced_frame ||
frame->top_field_first == s->dst_tff)
return ff_filter_frame(outlink, frame);
av_dlog(ctx,
"picture will move %s one line\n",
s->dst_tff ? "up" : "down");
h = frame->video->h;
h = frame->height;
for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
line_step = frame->linesize[plane];
line_size = s->line_size[plane];
@ -148,7 +148,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
* The new last line is created as a copy of the
* penultimate line from that field. */
for (line = 0; line < h; line++) {
if (1 + line < frame->video->h) {
if (1 + line < frame->height) {
memcpy(data, data + line_step, line_size);
} else {
memcpy(data, data - line_step - line_step, line_size);
@ -172,7 +172,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
}
}
}
frame->video->top_field_first = s->dst_tff;
frame->top_field_first = s->dst_tff;
return ff_filter_frame(outlink, frame);
}
@ -184,7 +184,7 @@ static const AVFilterPad avfilter_vf_fieldorder_inputs[] = {
.config_props = config_input,
.get_video_buffer = get_video_buffer,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ | AV_PERM_WRITE,
.needs_writable = 1,
},
{ NULL }
};

View File

@ -89,7 +89,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
}
av_opt_free(s);
if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFilterBufferRef*))))
if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*))))
return AVERROR(ENOMEM);
av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den);
@ -99,9 +99,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
static void flush_fifo(AVFifoBuffer *fifo)
{
while (av_fifo_size(fifo)) {
AVFilterBufferRef *tmp;
AVFrame *tmp;
av_fifo_generic_read(fifo, &tmp, sizeof(tmp), NULL);
avfilter_unref_buffer(tmp);
av_frame_free(&tmp);
}
}
@ -109,7 +109,7 @@ static av_cold void uninit(AVFilterContext *ctx)
{
FPSContext *s = ctx->priv;
if (s->fifo) {
s->drop += av_fifo_size(s->fifo) / sizeof(AVFilterBufferRef*);
s->drop += av_fifo_size(s->fifo) / sizeof(AVFrame*);
flush_fifo(s->fifo);
av_fifo_free(s->fifo);
}
@ -145,7 +145,7 @@ static int request_frame(AVFilterLink *outlink)
if (ret == AVERROR_EOF && av_fifo_size(s->fifo)) {
int i;
for (i = 0; av_fifo_size(s->fifo); i++) {
AVFilterBufferRef *buf;
AVFrame *buf;
av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base,
@ -162,13 +162,13 @@ static int request_frame(AVFilterLink *outlink)
return ret;
}
static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
static int write_to_fifo(AVFifoBuffer *fifo, AVFrame *buf)
{
int ret;
if (!av_fifo_space(fifo) &&
(ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
avfilter_unref_bufferp(&buf);
av_frame_free(&buf);
return ret;
}
@ -176,7 +176,7 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
FPSContext *s = ctx->priv;
@ -196,7 +196,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
} else {
av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
"timestamp.\n");
avfilter_unref_buffer(buf);
av_frame_free(&buf);
s->drop++;
}
return 0;
@ -213,8 +213,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
if (delta < 1) {
/* drop the frame and everything buffered except the first */
AVFilterBufferRef *tmp;
int drop = av_fifo_size(s->fifo)/sizeof(AVFilterBufferRef*);
AVFrame *tmp;
int drop = av_fifo_size(s->fifo)/sizeof(AVFrame*);
av_log(ctx, AV_LOG_DEBUG, "Dropping %d frame(s).\n", drop);
s->drop += drop;
@ -223,18 +223,18 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
flush_fifo(s->fifo);
ret = write_to_fifo(s->fifo, tmp);
avfilter_unref_buffer(buf);
av_frame_free(&buf);
return ret;
}
/* can output >= 1 frames */
for (i = 0; i < delta; i++) {
AVFilterBufferRef *buf_out;
AVFrame *buf_out;
av_fifo_generic_read(s->fifo, &buf_out, sizeof(buf_out), NULL);
/* duplicate the frame if needed */
if (!av_fifo_size(s->fifo) && i < delta - 1) {
AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, ~0);
AVFrame *dup = av_frame_clone(buf_out);
av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n");
if (dup)
@ -243,8 +243,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&buf_out);
avfilter_unref_bufferp(&buf);
av_frame_free(&buf_out);
av_frame_free(&buf);
return ret;
}
@ -255,7 +255,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
outlink->time_base) + s->frames_out;
if ((ret = ff_filter_frame(outlink, buf_out)) < 0) {
avfilter_unref_bufferp(&buf);
av_frame_free(&buf);
return ret;
}

View File

@ -66,7 +66,7 @@ static int config_output_props(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
{
FrameStepContext *framestep = inlink->dst->priv;
@ -75,7 +75,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
return ff_filter_frame(inlink->dst->outputs[0], ref);
} else {
framestep->frame_selected = 0;
avfilter_unref_buffer(ref);
av_frame_free(&ref);
return 0;
}
}

View File

@ -379,24 +379,24 @@ static int query_formats(AVFilterContext *ctx)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
Frei0rContext *frei0r = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
frei0r->update(frei0r->instance, in->pts * av_q2d(inlink->time_base) * 1000,
(const uint32_t *)in->data[0],
(uint32_t *)out->data[0]);
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -407,7 +407,6 @@ static const AVFilterPad avfilter_vf_frei0r_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input_props,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ
},
{ NULL }
};
@ -487,19 +486,18 @@ static int source_config_props(AVFilterLink *outlink)
static int source_request_frame(AVFilterLink *outlink)
{
Frei0rContext *frei0r = outlink->src->priv;
AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!picref)
if (!frame)
return AVERROR(ENOMEM);
picref->video->sample_aspect_ratio = (AVRational) {1, 1};
picref->pts = frei0r->pts++;
picref->pos = -1;
frame->sample_aspect_ratio = (AVRational) {1, 1};
frame->pts = frei0r->pts++;
frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}),
NULL, (uint32_t *)picref->data[0]);
frei0r->update(frei0r->instance, av_rescale_q(frame->pts, frei0r->time_base, (AVRational){1,1000}),
NULL, (uint32_t *)frame->data[0]);
return ff_filter_frame(outlink, picref);
return ff_filter_frame(outlink, frame);
}
static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = {

View File

@ -37,7 +37,7 @@ typedef struct {
AVExpr *e[4]; ///< expressions for each plane
char *expr_str[4]; ///< expression strings for each plane
int framenum; ///< frame counter
AVFilterBufferRef *picref; ///< current input buffer
AVFrame *picref; ///< current input buffer
int hsub, vsub; ///< chroma subsampling
int planes; ///< number of planes
} GEQContext;
@ -59,11 +59,11 @@ static inline double getpix(void *priv, double x, double y, int plane)
{
int xi, yi;
GEQContext *geq = priv;
AVFilterBufferRef *picref = geq->picref;
AVFrame *picref = geq->picref;
const uint8_t *src = picref->data[plane];
const int linesize = picref->linesize[plane];
const int w = picref->video->w >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
const int h = picref->video->h >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
const int w = picref->width >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
const int h = picref->height >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
if (!src)
return 0;
@ -163,24 +163,24 @@ static int geq_config_props(AVFilterLink *inlink)
return 0;
}
static int geq_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in)
{
int plane;
GEQContext *geq = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
double values[VAR_VARS_NB] = {
[VAR_N] = geq->framenum++,
[VAR_T] = in->pts == AV_NOPTS_VALUE ? NAN : in->pts * av_q2d(inlink->time_base),
};
geq->picref = in;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
for (plane = 0; plane < geq->planes && out->data[plane]; plane++) {
int x, y;
@ -204,7 +204,7 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
}
avfilter_unref_bufferp(&geq->picref);
av_frame_free(&geq->picref);
return ff_filter_frame(outlink, out);
}
@ -224,7 +224,6 @@ static const AVFilterPad geq_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = geq_config_props,
.filter_frame = geq_filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -197,23 +197,23 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
GradFunContext *gf = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
int p, direct = 0;
if (in->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(in)) {
direct = 1;
out = in;
} else {
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
}
for (p = 0; p < 4 && in->data[p]; p++) {
@ -233,7 +233,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
if (!direct)
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -244,7 +244,6 @@ static const AVFilterPad avfilter_vf_gradfun_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -70,21 +70,21 @@ static int config_props(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
FlipContext *flip = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
uint8_t *inrow, *outrow;
int i, j, plane, step, hsub, vsub;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
/* copy palette if required */
if (av_pix_fmt_desc_get(inlink->format)->flags & PIX_FMT_PAL)
@ -97,7 +97,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
outrow = out->data[plane];
inrow = in ->data[plane] + ((inlink->w >> hsub) - 1) * step;
for (i = 0; i < in->video->h >> vsub; i++) {
for (i = 0; i < in->height >> vsub; i++) {
switch (step) {
case 1:
for (j = 0; j < (inlink->w >> hsub); j++)
@ -143,7 +143,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
}
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -153,7 +153,6 @@ static const AVFilterPad avfilter_vf_hflip_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_props,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -142,7 +142,7 @@ static int config_input(AVFilterLink *inlink)
b = src[x + map[B]]; \
} while (0)
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
{
AVFilterContext *ctx = inlink->dst;
HisteqContext *histeq = ctx->priv;
@ -150,16 +150,16 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
int strength = histeq->strength * 1000;
int intensity = histeq->intensity * 1000;
int x, y, i, luthi, lutlo, lut, luma, oluma, m;
AVFilterBufferRef *outpic;
AVFrame *outpic;
unsigned int r, g, b, jran;
uint8_t *src, *dst;
outpic = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpic) {
avfilter_unref_bufferp(&inpic);
av_frame_free(&inpic);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(outpic, inpic);
av_frame_copy_props(outpic, inpic);
/* Seed random generator for antibanding. */
jran = LCG_SEED;
@ -261,7 +261,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
av_dlog(ctx, "out[%d]: %u\n", x, histeq->out_histogram[x]);
#endif
avfilter_unref_bufferp(&inpic);
av_frame_free(&inpic);
return ff_filter_frame(outlink, outpic);
}
@ -271,7 +271,6 @@ static const AVFilterPad histeq_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -174,24 +174,23 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
HistogramContext *h = inlink->dst->priv;
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
const uint8_t *src;
uint8_t *dst;
int i, j, k, l, ret;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
out->pts = in->pts;
out->pos = in->pos;
for (k = 0; k < h->ncomp; k++)
for (i = 0; i < outlink->h; i++)
@ -202,9 +201,9 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
for (k = 0; k < h->ncomp; k++) {
int start = k * (h->level_height + h->scale_height) * h->display_mode;
for (i = 0; i < in->video->h; i++) {
for (i = 0; i < in->height; i++) {
src = in->data[k] + i * in->linesize[k];
for (j = 0; j < in->video->w; j++)
for (j = 0; j < in->width; j++)
h->histogram[src[j]]++;
}
@ -301,7 +300,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
ret = ff_filter_frame(outlink, out);
avfilter_unref_bufferp(&in);
av_frame_free(&in);
if (ret < 0)
return ret;
return 0;
@ -320,7 +319,6 @@ static const AVFilterPad inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_input,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -304,37 +304,38 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
HQDN3DContext *hqdn3d = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
int direct = 0, c;
if (in->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(in)) {
direct = 1;
out = in;
} else {
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
}
for (c = 0; c < 3; c++) {
denoise(hqdn3d, in->data[c], out->data[c],
hqdn3d->line, &hqdn3d->frame_prev[c],
in->video->w >> (!!c * hqdn3d->hsub),
in->video->h >> (!!c * hqdn3d->vsub),
in->width >> (!!c * hqdn3d->hsub),
in->height >> (!!c * hqdn3d->vsub),
in->linesize[c], out->linesize[c],
hqdn3d->coefs[c?2:0], hqdn3d->coefs[c?3:1]);
}
if (!direct)
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}

View File

@ -276,18 +276,18 @@ static void process_chrominance(uint8_t *udst, uint8_t *vdst, const int dst_line
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb))
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
{
HueContext *hue = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpic;
AVFrame *outpic;
outpic = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpic) {
avfilter_unref_bufferp(&inpic);
av_frame_free(&inpic);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(outpic, inpic);
av_frame_copy_props(outpic, inpic);
if (!hue->flat_syntax) {
hue->var_values[VAR_T] = TS2T(inpic->pts, inlink->time_base);
@ -330,7 +330,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
inlink->w >> hue->hsub, inlink->h >> hue->vsub,
hue->hue_cos, hue->hue_sin);
avfilter_unref_bufferp(&inpic);
av_frame_free(&inpic);
return ff_filter_frame(outlink, outpic);
}
@ -349,7 +349,6 @@ static const AVFilterPad hue_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_props,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -47,9 +47,9 @@ typedef struct {
uint8_t history[HIST_SIZE];
AVFilterBufferRef *cur;
AVFilterBufferRef *next;
AVFilterBufferRef *prev;
AVFrame *cur;
AVFrame *next;
AVFrame *prev;
int (*filter_line)(const uint8_t *prev, const uint8_t *cur, const uint8_t *next, int w);
const AVPixFmtDescriptor *csp;
@ -113,8 +113,8 @@ static void filter(AVFilterContext *ctx)
int match = 0;
for (i = 0; i < idet->csp->nb_components; i++) {
int w = idet->cur->video->w;
int h = idet->cur->video->h;
int w = idet->cur->width;
int h = idet->cur->height;
int refs = idet->cur->linesize[i];
if (i && i<3) {
@ -165,13 +165,13 @@ static void filter(AVFilterContext *ctx)
}
if (idet->last_type == TFF){
idet->cur->video->top_field_first = 1;
idet->cur->video->interlaced = 1;
idet->cur->top_field_first = 1;
idet->cur->interlaced_frame = 1;
}else if(idet->last_type == BFF){
idet->cur->video->top_field_first = 0;
idet->cur->video->interlaced = 1;
idet->cur->top_field_first = 0;
idet->cur->interlaced_frame = 1;
}else if(idet->last_type == PROGRSSIVE){
idet->cur->video->interlaced = 0;
idet->cur->interlaced_frame = 0;
}
idet->prestat [ type] ++;
@ -179,13 +179,13 @@ static void filter(AVFilterContext *ctx)
av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type));
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)
static int filter_frame(AVFilterLink *link, AVFrame *picref)
{
AVFilterContext *ctx = link->dst;
IDETContext *idet = ctx->priv;
if (idet->prev)
avfilter_unref_buffer(idet->prev);
av_frame_free(&idet->prev);
idet->prev = idet->cur;
idet->cur = idet->next;
idet->next = picref;
@ -194,7 +194,7 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)
return 0;
if (!idet->prev)
idet->prev = avfilter_ref_buffer(idet->cur, ~0);
idet->prev = av_frame_clone(idet->cur);
if (!idet->csp)
idet->csp = av_pix_fmt_desc_get(link->format);
@ -203,7 +203,7 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)
filter(ctx);
return ff_filter_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, ~0));
return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
}
static int request_frame(AVFilterLink *link)
@ -238,9 +238,9 @@ static av_cold void uninit(AVFilterContext *ctx)
idet->poststat[UNDETERMINED]
);
avfilter_unref_bufferp(&idet->prev);
avfilter_unref_bufferp(&idet->cur );
avfilter_unref_bufferp(&idet->next);
av_frame_free(&idet->prev);
av_frame_free(&idet->cur );
av_frame_free(&idet->next);
}
static int query_formats(AVFilterContext *ctx)

View File

@ -160,19 +160,19 @@ static void interleave(uint8_t *dst, uint8_t *src, int w, int h,
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
{
IlContext *il = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
int ret, comp;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&inpicref);
av_frame_free(&inpicref);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, inpicref);
av_frame_copy_props(out, inpicref);
interleave(out->data[0], inpicref->data[0],
il->linesize[0], inlink->h,
@ -195,7 +195,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
}
ret = ff_filter_frame(outlink, out);
avfilter_unref_bufferp(&inpicref);
av_frame_free(&inpicref);
return ret;
}

View File

@ -116,11 +116,11 @@ static int config_props(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
{
KerndeintContext *kerndeint = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpic;
AVFrame *outpic;
const uint8_t *prvp; ///< Previous field's pixel line number n
const uint8_t *prvpp; ///< Previous field's pixel line number (n - 1)
const uint8_t *prvpn; ///< Previous field's pixel line number (n + 1)
@ -154,13 +154,13 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
const int is_packed_rgb = kerndeint->is_packed_rgb;
outpic = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpic) {
avfilter_unref_bufferp(&inpic);
av_frame_free(&inpic);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(outpic, inpic);
outpic->video->interlaced = 0;
av_frame_copy_props(outpic, inpic);
outpic->interlaced_frame = 0;
for (plane = 0; inpic->data[plane] && plane < 4; plane++) {
h = plane == 0 ? inlink->h : inlink->h >> kerndeint->vsub;
@ -295,7 +295,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
av_image_copy_plane(dstp, psrc_linesize, srcp, src_linesize, bwidth, h);
}
avfilter_unref_buffer(inpic);
av_frame_free(&inpic);
return ff_filter_frame(outlink, outpic);
}
@ -305,7 +305,6 @@ static const AVFilterPad kerndeint_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_props,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -35,7 +35,7 @@
#include "internal.h"
#include "video.h"
static void fill_iplimage_from_picref(IplImage *img, const AVFilterBufferRef *picref, enum AVPixelFormat pixfmt)
static void fill_iplimage_from_frame(IplImage *img, const AVFrame *frame, enum AVPixelFormat pixfmt)
{
IplImage *tmpimg;
int depth, channels_nb;
@ -45,18 +45,18 @@ static void fill_iplimage_from_picref(IplImage *img, const AVFilterBufferRef *pi
else if (pixfmt == AV_PIX_FMT_BGR24) { depth = IPL_DEPTH_8U; channels_nb = 3; }
else return;
tmpimg = cvCreateImageHeader((CvSize){picref->video->w, picref->video->h}, depth, channels_nb);
tmpimg = cvCreateImageHeader((CvSize){frame->width, frame->height}, depth, channels_nb);
*img = *tmpimg;
img->imageData = img->imageDataOrigin = picref->data[0];
img->imageData = img->imageDataOrigin = frame->data[0];
img->dataOrder = IPL_DATA_ORDER_PIXEL;
img->origin = IPL_ORIGIN_TL;
img->widthStep = picref->linesize[0];
img->widthStep = frame->linesize[0];
}
static void fill_picref_from_iplimage(AVFilterBufferRef *picref, const IplImage *img, enum AVPixelFormat pixfmt)
static void fill_frame_from_iplimage(AVFrame *frame, const IplImage *img, enum AVPixelFormat pixfmt)
{
picref->linesize[0] = img->widthStep;
picref->data[0] = img->imageData;
frame->linesize[0] = img->widthStep;
frame->data[0] = img->imageData;
}
static int query_formats(AVFilterContext *ctx)
@ -351,27 +351,27 @@ static av_cold void uninit(AVFilterContext *ctx)
memset(ocv, 0, sizeof(*ocv));
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
OCVContext *ocv = ctx->priv;
AVFilterLink *outlink= inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
IplImage inimg, outimg;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
fill_iplimage_from_picref(&inimg , in , inlink->format);
fill_iplimage_from_picref(&outimg, out, inlink->format);
fill_iplimage_from_frame(&inimg , in , inlink->format);
fill_iplimage_from_frame(&outimg, out, inlink->format);
ocv->end_frame_filter(ctx, &inimg, &outimg);
fill_picref_from_iplimage(out, &outimg, inlink->format);
fill_frame_from_iplimage(out, &outimg, inlink->format);
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -381,7 +381,6 @@ static const AVFilterPad avfilter_vf_ocv_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ
},
{ NULL }
};

View File

@ -253,28 +253,28 @@ static int config_props(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
LutContext *lut = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
uint8_t *inrow, *outrow, *inrow0, *outrow0;
int i, j, plane;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
if (lut->is_rgb) {
/* packed */
inrow0 = in ->data[0];
outrow0 = out->data[0];
for (i = 0; i < in->video->h; i ++) {
for (i = 0; i < in->height; i ++) {
int w = inlink->w;
const uint8_t (*tab)[256] = (const uint8_t (*)[256])lut->lut;
inrow = inrow0;
@ -305,7 +305,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
inrow = in ->data[plane];
outrow = out->data[plane];
for (i = 0; i < (in->video->h + (1<<vsub) - 1)>>vsub; i ++) {
for (i = 0; i < (in->height + (1<<vsub) - 1)>>vsub; i ++) {
const uint8_t *tab = lut->lut[plane];
int w = (inlink->w + (1<<hsub) - 1)>>hsub;
for (j = 0; j < w; j++)
@ -316,7 +316,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
}
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -325,7 +325,7 @@ static const AVFilterPad inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_props,
.min_perms = AV_PERM_READ, },
},
{ .name = NULL}
};
static const AVFilterPad outputs[] = {

View File

@ -536,45 +536,38 @@ mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgty
return mpi;
}
static void dummy_free(void *opaque, uint8_t *data){}
int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
MPContext *m= (void*)vf;
AVFilterLink *outlink = m->avfctx->outputs[0];
AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));
AVFrame *picref = av_frame_alloc();
int i;
av_assert0(vf->next);
av_log(m->avfctx, AV_LOG_DEBUG, "ff_vf_next_put_image\n");
if (!pic || !picref)
if (!picref)
goto fail;
picref->buf = pic;
picref->buf->free= (void*)av_free;
if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
goto fail;
picref->width = mpi->w;
picref->height = mpi->h;
pic->w = picref->video->w = mpi->w;
pic->h = picref->video->h = mpi->h;
/* make sure the buffer gets read permission or it's useless for output */
picref->perms = AV_PERM_READ | AV_PERM_REUSE2;
// av_assert0(mpi->flags&MP_IMGFLAG_READABLE);
if(!(mpi->flags&MP_IMGFLAG_PRESERVE))
picref->perms |= AV_PERM_WRITE;
pic->refcount = 1;
picref->type = AVMEDIA_TYPE_VIDEO;
for(i=0; conversion_map[i].fmt && mpi->imgfmt != conversion_map[i].fmt; i++);
pic->format = picref->format = conversion_map[i].pix_fmt;
picref->format = conversion_map[i].pix_fmt;
memcpy(pic->data, mpi->planes, FFMIN(sizeof(pic->data) , sizeof(mpi->planes)));
memcpy(pic->linesize, mpi->stride, FFMIN(sizeof(pic->linesize), sizeof(mpi->stride)));
memcpy(picref->data, pic->data, sizeof(picref->data));
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
memcpy(picref->linesize, mpi->stride, FFMIN(sizeof(picref->linesize), sizeof(mpi->stride)));
for(i=0; i<4 && mpi->stride[i]; i++){
picref->buf[i] = av_buffer_create(mpi->planes[i], mpi->stride[i], dummy_free, NULL,
(mpi->flags & MP_IMGFLAG_PRESERVE) ? AV_BUFFER_FLAG_READONLY : 0);
if (!picref->buf[i])
goto fail;
picref->data[i] = picref->buf[i]->data;
}
if(pts != MP_NOPTS_VALUE)
picref->pts= pts * av_q2d(outlink->time_base);
@ -584,10 +577,7 @@ int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
return 1;
fail:
if (picref && picref->video)
av_free(picref->video);
av_free(picref);
av_free(pic);
av_frame_free(&picref);
return 0;
}
@ -793,12 +783,12 @@ static int request_frame(AVFilterLink *outlink)
return ret;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
{
MPContext *m = inlink->dst->priv;
int i;
double pts= MP_NOPTS_VALUE;
mp_image_t* mpi = ff_new_mp_image(inpic->video->w, inpic->video->h);
mp_image_t* mpi = ff_new_mp_image(inpic->width, inpic->height);
if(inpic->pts != AV_NOPTS_VALUE)
pts= inpic->pts / av_q2d(inlink->time_base);
@ -813,12 +803,12 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
// mpi->flags|=MP_IMGFLAG_ALLOCATED; ?
mpi->flags |= MP_IMGFLAG_READABLE;
if(!(inpic->perms & AV_PERM_WRITE))
if(!av_frame_is_writable(inpic))
mpi->flags |= MP_IMGFLAG_PRESERVE;
if(m->vf.put_image(&m->vf, mpi, pts) == 0){
av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n");
}else{
avfilter_unref_buffer(inpic);
av_frame_free(&inpic);
}
ff_free_mp_image(mpi);
return 0;
@ -830,7 +820,6 @@ static const AVFilterPad mp_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_inprops,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -298,22 +298,22 @@ static void noise(uint8_t *dst, const uint8_t *src,
n->param[comp].shiftptr = 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
{
NoiseContext *n = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
int ret, i;
if (inpicref->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(inpicref)) {
out = inpicref;
} else {
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&inpicref);
av_frame_free(&inpicref);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, inpicref);
av_frame_copy_props(out, inpicref);
}
for (i = 0; i < n->nb_planes; i++)
@ -322,7 +322,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
ret = ff_filter_frame(outlink, out);
if (inpicref != out)
avfilter_unref_buffer(inpicref);
av_frame_free(&inpicref);
return ret;
}

View File

@ -85,7 +85,7 @@ typedef struct {
uint8_t overlay_has_alpha;
enum OverlayFormat { OVERLAY_FORMAT_YUV420, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_NB} format;
AVFilterBufferRef *overpicref;
AVFrame *overpicref;
struct FFBufQueue queue_main;
struct FFBufQueue queue_over;
@ -143,7 +143,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_opt_free(over);
avfilter_unref_bufferp(&over->overpicref);
av_frame_free(&over->overpicref);
ff_bufqueue_discard_all(&over->queue_main);
ff_bufqueue_discard_all(&over->queue_over);
}
@ -316,15 +316,15 @@ static int config_output(AVFilterLink *outlink)
* Blend image in src to destination buffer dst at position (x, y).
*/
static void blend_image(AVFilterContext *ctx,
AVFilterBufferRef *dst, AVFilterBufferRef *src,
AVFrame *dst, AVFrame *src,
int x, int y)
{
OverlayContext *over = ctx->priv;
int i, imax, j, jmax, k, kmax;
const int src_w = src->video->w;
const int src_h = src->video->h;
const int dst_w = dst->video->w;
const int dst_h = dst->video->h;
const int src_w = src->width;
const int src_h = src->height;
const int dst_w = dst->width;
const int dst_h = dst->height;
if (x >= dst_w || x+dst_w < 0 ||
y >= dst_h || y+dst_h < 0)
@ -503,11 +503,11 @@ static void blend_image(AVFilterContext *ctx,
}
}
static int try_filter_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
static int try_filter_frame(AVFilterContext *ctx, AVFrame *mainpic)
{
OverlayContext *over = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *next_overpic;
AVFrame *next_overpic;
int ret;
/* Discard obsolete overlay frames: if there is a next overlay frame with pts
@ -518,7 +518,7 @@ static int try_filter_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
mainpic->pts , ctx->inputs[MAIN]->time_base) > 0)
break;
ff_bufqueue_get(&over->queue_over);
avfilter_unref_buffer(over->overpicref);
av_frame_free(&over->overpicref);
over->overpicref = next_overpic;
}
@ -549,7 +549,7 @@ static int try_filter_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
static int try_filter_next_frame(AVFilterContext *ctx)
{
OverlayContext *over = ctx->priv;
AVFilterBufferRef *next_mainpic = ff_bufqueue_peek(&over->queue_main, 0);
AVFrame *next_mainpic = ff_bufqueue_peek(&over->queue_main, 0);
int ret;
if (!next_mainpic)
@ -568,7 +568,7 @@ static int flush_frames(AVFilterContext *ctx)
return ret == AVERROR(EAGAIN) ? 0 : ret;
}
static int filter_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
static int filter_frame_main(AVFilterLink *inlink, AVFrame *inpicref)
{
AVFilterContext *ctx = inlink->dst;
OverlayContext *over = ctx->priv;
@ -589,7 +589,7 @@ static int filter_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
return 0;
}
static int filter_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
static int filter_frame_over(AVFilterLink *inlink, AVFrame *inpicref)
{
AVFilterContext *ctx = inlink->dst;
OverlayContext *over = ctx->priv;
@ -639,14 +639,13 @@ static const AVFilterPad avfilter_vf_overlay_inputs[] = {
.get_video_buffer = ff_null_get_video_buffer,
.config_props = config_input_main,
.filter_frame = filter_frame_main,
.min_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE,
.needs_writable = 1,
},
{
.name = "overlay",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input_overlay,
.filter_frame = filter_frame_over,
.min_perms = AV_PERM_READ | AV_PERM_PRESERVE,
},
{ NULL }
};

View File

@ -238,98 +238,126 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
{
PadContext *pad = inlink->dst->priv;
int align = (perms&AV_PERM_ALIGN) ? AVFILTER_ALIGN : 1;
AVFilterBufferRef *picref = ff_get_video_buffer(inlink->dst->outputs[0], perms,
w + (pad->w - pad->in_w) + 4*align,
h + (pad->h - pad->in_h));
AVFrame *frame = ff_get_video_buffer(inlink->dst->outputs[0],
w + (pad->w - pad->in_w),
h + (pad->h - pad->in_h));
int plane;
if (!picref)
if (!frame)
return NULL;
picref->video->w = w;
picref->video->h = h;
frame->width = w;
frame->height = h;
for (plane = 0; plane < 4 && picref->data[plane]; plane++)
picref->data[plane] += FFALIGN(pad->x >> pad->draw.hsub[plane], align) * pad->draw.pixelstep[plane] +
(pad->y >> pad->draw.vsub[plane]) * picref->linesize[plane];
for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
int hsub = pad->draw.hsub[plane];
int vsub = pad->draw.vsub[plane];
frame->data[plane] += (pad->x >> hsub) * pad->draw.pixelstep[plane] +
(pad->y >> vsub) * frame->linesize[plane];
}
return picref;
return frame;
}
static int does_clip(PadContext *pad, AVFilterBufferRef *outpicref, int plane, int hsub, int vsub, int x, int y)
/* check whether each plane in this buffer can be padded without copying */
static int buffer_needs_copy(PadContext *s, AVFrame *frame, AVBufferRef *buf)
{
int64_t x_in_buf, y_in_buf;
int planes[4] = { -1, -1, -1, -1}, *p = planes;
int i, j;
x_in_buf = outpicref->data[plane] - outpicref->buf->data[plane]
+ (x >> hsub) * pad->draw.pixelstep[plane]
+ (y >> vsub) * outpicref->linesize[plane];
/* get all planes in this buffer */
for (i = 0; i < FF_ARRAY_ELEMS(planes) && frame->data[i]; i++) {
if (av_frame_get_plane_buffer(frame, i) == buf)
*p++ = i;
}
if(x_in_buf < 0 || x_in_buf % pad->draw.pixelstep[plane])
return 1;
x_in_buf /= pad->draw.pixelstep[plane];
/* for each plane in this buffer, check that it can be padded without
* going over buffer bounds or other planes */
for (i = 0; i < FF_ARRAY_ELEMS(planes) && planes[i] >= 0; i++) {
int hsub = s->draw.hsub[planes[i]];
int vsub = s->draw.vsub[planes[i]];
av_assert0(outpicref->buf->linesize[plane]>0); //while reference can use negative linesize the main buffer should not
uint8_t *start = frame->data[planes[i]];
uint8_t *end = start + (frame->height >> hsub) *
frame->linesize[planes[i]];
y_in_buf = x_in_buf / outpicref->buf->linesize[plane];
x_in_buf %= outpicref->buf->linesize[plane];
/* amount of free space needed before the start and after the end
* of the plane */
ptrdiff_t req_start = (s->x >> hsub) * s->draw.pixelstep[planes[i]] +
(s->y >> vsub) * frame->linesize[planes[i]];
ptrdiff_t req_end = ((s->w - s->x - frame->width) >> hsub) *
s->draw.pixelstep[planes[i]] +
(s->y >> vsub) * frame->linesize[planes[i]];
if (frame->linesize[planes[i]] < (s->w >> hsub) * s->draw.pixelstep[planes[i]])
return 1;
if (start - buf->data < req_start ||
(buf->data + buf->size) - end < req_end)
return 1;
#define SIGN(x) ((x) > 0 ? 1 : -1)
for (j = 0; j < FF_ARRAY_ELEMS(planes) & planes[j] >= 0; j++) {
int hsub1 = s->draw.hsub[planes[j]];
uint8_t *start1 = frame->data[planes[j]];
uint8_t *end1 = start1 + (frame->height >> hsub1) *
frame->linesize[planes[j]];
if (i == j)
continue;
if (SIGN(start - end1) != SIGN(start - end1 - req_start) ||
SIGN(end - start1) != SIGN(end - start1 + req_end))
return 1;
}
}
if( y_in_buf<<vsub >= outpicref->buf->h
|| x_in_buf<<hsub >= outpicref->buf->w)
return 1;
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int frame_needs_copy(PadContext *s, AVFrame *frame)
{
int i;
if (!av_frame_is_writable(frame))
return 1;
for (i = 0; i < 4 && frame->buf[i]; i++)
if (buffer_needs_copy(s, frame, frame->buf[i]))
return 1;
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
PadContext *pad = inlink->dst->priv;
AVFilterBufferRef *out = avfilter_ref_buffer(in, ~0);
int plane, needs_copy;
AVFrame *out;
int needs_copy = frame_needs_copy(pad, in);
if (!out) {
avfilter_unref_bufferp(&in);
return AVERROR(ENOMEM);
}
for (plane = 0; plane < 4 && out->data[plane] && pad->draw.pixelstep[plane]; plane++) {
int hsub = pad->draw.hsub[plane];
int vsub = pad->draw.vsub[plane];
av_assert0(out->buf->w > 0 && out->buf->h > 0);
if (out->format != out->buf->format) //unsupported currently
break;
out->data[plane] -= (pad->x >> hsub) * pad->draw.pixelstep[plane] +
(pad->y >> vsub) * out->linesize[plane];
if (does_clip(pad, out, plane, hsub, vsub, 0, 0) ||
does_clip(pad, out, plane, hsub, vsub, 0, pad->h - 1) ||
does_clip(pad, out, plane, hsub, vsub, pad->w - 1, 0) ||
does_clip(pad, out, plane, hsub, vsub, pad->w - 1, pad->h - 1))
break;
}
needs_copy = plane < 4 && out->data[plane] || !(out->perms & AV_PERM_WRITE);
if (needs_copy) {
av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
avfilter_unref_buffer(out);
out = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
out = ff_get_video_buffer(inlink->dst->outputs[0],
FFMAX(inlink->w, pad->w),
FFMAX(inlink->h, pad->h));
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
}
av_frame_copy_props(out, in);
} else {
int i;
out->video->w = pad->w;
out->video->h = pad->h;
out = in;
for (i = 0; i < 4 && out->data[i]; i++) {
int hsub = pad->draw.hsub[i];
int vsub = pad->draw.vsub[i];
out->data[i] -= (pad->x >> hsub) * pad->draw.pixelstep[i] +
(pad->y >> vsub) * out->linesize[i];
}
}
/* top bar */
if (pad->y) {
@ -347,20 +375,24 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
/* left border */
ff_fill_rectangle(&pad->draw, &pad->color, out->data, out->linesize,
0, pad->y, pad->x, in->video->h);
0, pad->y, pad->x, in->height);
if (needs_copy) {
ff_copy_rectangle2(&pad->draw,
out->data, out->linesize, in->data, in->linesize,
pad->x, pad->y, 0, 0, in->video->w, in->video->h);
pad->x, pad->y, 0, 0, in->width, in->height);
}
/* right border */
ff_fill_rectangle(&pad->draw, &pad->color, out->data, out->linesize,
pad->x + pad->in_w, pad->y, pad->w - pad->x - pad->in_w,
in->video->h);
in->height);
avfilter_unref_bufferp(&in);
out->width = pad->w;
out->height = pad->h;
if (in != out)
av_frame_free(&in);
return ff_filter_frame(inlink->dst->outputs[0], out);
}

View File

@ -52,21 +52,20 @@ static int config_props(AVFilterLink *inlink)
return 0;
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
PixdescTestContext *priv = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
int i, c, w = inlink->w, h = inlink->h;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
av_frame_copy_props(out, in);
for (i = 0; i < 4; i++) {
int h = outlink->h;
@ -102,7 +101,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
}
}
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -112,7 +111,6 @@ static const AVFilterPad avfilter_vf_pixdesctest_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_props,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -100,32 +100,32 @@ static int pp_config_props(AVFilterLink *inlink)
return 0;
}
static int pp_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inbuf)
static int pp_filter_frame(AVFilterLink *inlink, AVFrame *inbuf)
{
AVFilterContext *ctx = inlink->dst;
PPFilterContext *pp = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
const int aligned_w = FFALIGN(outlink->w, 8);
const int aligned_h = FFALIGN(outlink->h, 8);
AVFilterBufferRef *outbuf;
AVFrame *outbuf;
outbuf = ff_get_video_buffer(outlink, AV_PERM_WRITE, aligned_w, aligned_h);
outbuf = ff_get_video_buffer(outlink, aligned_w, aligned_h);
if (!outbuf) {
avfilter_unref_buffer(inbuf);
av_frame_free(&inbuf);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(outbuf, inbuf);
av_frame_copy_props(outbuf, inbuf);
pp_postprocess((const uint8_t **)inbuf->data, inbuf->linesize,
outbuf->data, outbuf->linesize,
aligned_w, outlink->h,
outbuf->video->qp_table,
outbuf->video->qp_table_linesize,
outbuf->qscale_table,
outbuf->qstride,
pp->modes[pp->mode_id],
pp->pp_ctx,
outbuf->video->pict_type);
outbuf->pict_type);
avfilter_unref_buffer(inbuf);
av_frame_free(&inbuf);
return ff_filter_frame(outlink, outbuf);
}
@ -146,7 +146,6 @@ static const AVFilterPad pp_inputs[] = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = pp_config_props,
.filter_frame = pp_filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -473,23 +473,23 @@ static void blur_image(int ***mask,
}
}
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
{
RemovelogoContext *removelogo = inlink->dst->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref;
AVFrame *outpicref;
int direct = 0;
if (inpicref->perms & AV_PERM_WRITE) {
if (av_frame_is_writable(inpicref)) {
direct = 1;
outpicref = inpicref;
} else {
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!outpicref) {
avfilter_unref_bufferp(&inpicref);
av_frame_free(&inpicref);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(outpicref, inpicref);
av_frame_copy_props(outpicref, inpicref);
}
blur_image(removelogo->mask,
@ -509,7 +509,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
inlink->w/2, inlink->h/2, direct, &removelogo->half_mask_bbox);
if (!direct)
avfilter_unref_bufferp(&inpicref);
av_frame_free(&inpicref);
return ff_filter_frame(outlink, outpicref);
}
@ -543,7 +543,6 @@ static const AVFilterPad removelogo_inputs[] = {
.get_video_buffer = ff_null_get_video_buffer,
.config_props = config_props_input,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

View File

@ -329,7 +329,7 @@ fail:
return ret;
}
static int scale_slice(AVFilterLink *link, AVFilterBufferRef *out_buf, AVFilterBufferRef *cur_pic, struct SwsContext *sws, int y, int h, int mul, int field)
static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, struct SwsContext *sws, int y, int h, int mul, int field)
{
ScaleContext *scale = link->dst->priv;
const uint8_t *in[4];
@ -353,17 +353,17 @@ static int scale_slice(AVFilterLink *link, AVFilterBufferRef *out_buf, AVFilterB
out,out_stride);
}
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
static int filter_frame(AVFilterLink *link, AVFrame *in)
{
ScaleContext *scale = link->dst->priv;
AVFilterLink *outlink = link->dst->outputs[0];
AVFilterBufferRef *out;
AVFrame *out;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
char buf[32];
if( in->video->w != link->w
|| in->video->h != link->h
|| in->format != link->format) {
if( in->width != link->w
|| in->height != link->h
|| in->format != link->format) {
int ret;
snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
av_opt_set(scale, "w", buf, 0);
@ -371,8 +371,8 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
av_opt_set(scale, "h", buf, 0);
link->dst->inputs[0]->format = in->format;
link->dst->inputs[0]->w = in->video->w;
link->dst->inputs[0]->h = in->video->h;
link->dst->inputs[0]->w = in->width;
link->dst->inputs[0]->h = in->height;
if ((ret = config_props(outlink)) < 0)
return ret;
@ -384,32 +384,32 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
scale->hsub = desc->log2_chroma_w;
scale->vsub = desc->log2_chroma_h;
out = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return AVERROR(ENOMEM);
}
avfilter_copy_buffer_ref_props(out, in);
out->video->w = outlink->w;
out->video->h = outlink->h;
av_frame_copy_props(out, in);
out->width = outlink->w;
out->height = outlink->h;
if(scale->output_is_pal)
avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
av_reduce(&out->video->sample_aspect_ratio.num, &out->video->sample_aspect_ratio.den,
(int64_t)in->video->sample_aspect_ratio.num * outlink->h * link->w,
(int64_t)in->video->sample_aspect_ratio.den * outlink->w * link->h,
av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
(int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
(int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
INT_MAX);
if(scale->interlaced>0 || (scale->interlaced<0 && in->video->interlaced)){
if(scale->interlaced>0 || (scale->interlaced<0 && in->interlaced_frame)){
scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0);
scale_slice(link, out, in, scale->isws[1], 0, link->h /2, 2, 1);
}else{
scale_slice(link, out, in, scale->sws, 0, link->h, 1, 0);
}
avfilter_unref_bufferp(&in);
av_frame_free(&in);
return ff_filter_frame(outlink, out);
}
@ -418,7 +418,6 @@ static const AVFilterPad avfilter_vf_scale_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.min_perms = AV_PERM_READ,
},
{ NULL }
};

Some files were not shown because too many files have changed in this diff Show More