Commit 1c600888 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  x86: Only use optimizations with cmov if the CPU supports the instruction
  x86: Add CPU flag for the i686 cmov instruction
  x86: remove unused inline asm macros from dsputil_mmx.h
  x86: move some inline asm macros to the only places they are used
  lavfi: Add the af_channelmap audio channel mapping filter.
  lavfi: add join audio filter.
  lavfi: allow audio filters to request a given number of samples.
  lavfi: support automatically inserting the fifo filter when needed.
  lavfi/audio: eliminate ff_default_filter_samples().

Conflicts:
	Changelog
	libavcodec/x86/h264dsp_mmx.c
	libavfilter/Makefile
	libavfilter/allfilters.c
	libavfilter/avfilter.h
	libavfilter/avfiltergraph.c
	libavfilter/version.h
	libavutil/x86/cpu.c
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents da728d5d fe07c9c6
......@@ -12,6 +12,8 @@ version next:
- RTMPT protocol support
- iLBC encoding/decoding via libilbc
- Microsoft Screen 1 decoder
- join audio filter
- audio channel mapping filter
- showwaves filter
- LucasArts SMUSH playback support
......
......@@ -4,7 +4,7 @@ since the last major version increase.
The last version increases were:
libavcodec: 2012-01-27
libavdevice: 2011-04-18
libavfilter: 2011-04-18
libavfilter: 2012-06-22
libavformat: 2012-01-27
libavresample: 2012-04-24
libpostproc: 2011-04-18
......
......@@ -649,6 +649,76 @@ front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
side_right.wav
@end example
@section channelmap
Remap input channels to new locations.
This filter accepts the following named parameters:
@table @option
@item channel_layout
Channel layout of the output stream.
@item map
Map channels from input to output. The argument is a comma-separated list of
mappings, each in the @code{@var{in_channel}-@var{out_channel}} or
@var{in_channel} form. @var{in_channel} can be either the name of the input
channel (e.g. FL for front left) or its index in the input channel layout.
@var{out_channel} is the name of the output channel or its index in the output
channel layout. If @var{out_channel} is not given then it is implicitly an
index, starting with zero and increasing by one for each mapping.
@end table
If no mapping is present, the filter will implicitly map input channels to
output channels preserving index.
For example, assuming a 5.1+downmix input MOV file
@example
ffmpeg -i in.mov -filter 'channelmap=map=DL-FL\,DR-FR' out.wav
@end example
will create an output WAV file tagged as stereo from the downmix channels of
the input.
To fix a 5.1 WAV improperly encoded in AAC's native channel order
@example
ffmpeg -i in.wav -filter 'channelmap=1\,2\,0\,5\,3\,4:channel_layout=5.1' out.wav
@end example
@section join
Join multiple input streams into one multi-channel stream.
The filter accepts the following named parameters:
@table @option
@item inputs
Number of input streams. Defaults to 2.
@item channel_layout
Desired output channel layout. Defaults to stereo.
@item map
Map channels from inputs to output. The argument is a comma-separated list of
mappings, each in the @code{@var{input_idx}.@var{in_channel}-@var{out_channel}}
form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
can be either the name of the input channel (e.g. FR for front left) or its
index in the specified input stream. @var{out_channel} is the name of the output
channel.
@end table
The filter will attempt to guess the mappings when those are not specified
explicitly. It does so by first trying to find an unused matching input channel
and if that fails it picks the first unused input channel.
E.g. to join 3 inputs (with properly set channel layouts)
@example
ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
@end example
To build a 5.1 output from 6 single-channel streams:
@example
ffmpeg -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
'join=inputs=6:channel_layout=5.1:map=0.0-FL\,1.0-FR\,2.0-FC\,3.0-SL\,4.0-SR\,5.0-LFE'
out
@end example
@section resample
Convert the audio sample format, sample rate and channel layout. This filter is
not meant to be used directly.
......
......@@ -29,6 +29,12 @@
#include "libavcodec/cavsdsp.h"
#include "dsputil_mmx.h"
/* in/out: mma=mma+mmb, mmb=mmb-mma */
#define SUMSUB_BA( a, b ) \
"paddw "#b", "#a" \n\t"\
"paddw "#b", "#b" \n\t"\
"psubw "#a", "#b" \n\t"
/*****************************************************************************
*
* inverse transform
......
......@@ -631,6 +631,34 @@ static void add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
}
#endif
static inline void transpose4x4(uint8_t *dst, uint8_t *src, x86_reg dst_stride, x86_reg src_stride){
__asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ...
"movd (%1), %%mm0 \n\t"
"add %3, %1 \n\t"
"movd (%1), %%mm1 \n\t"
"movd (%1,%3,1), %%mm2 \n\t"
"movd (%1,%3,2), %%mm3 \n\t"
"punpcklbw %%mm1, %%mm0 \n\t"
"punpcklbw %%mm3, %%mm2 \n\t"
"movq %%mm0, %%mm1 \n\t"
"punpcklwd %%mm2, %%mm0 \n\t"
"punpckhwd %%mm2, %%mm1 \n\t"
"movd %%mm0, (%0) \n\t"
"add %2, %0 \n\t"
"punpckhdq %%mm0, %%mm0 \n\t"
"movd %%mm0, (%0) \n\t"
"movd %%mm1, (%0,%2,1) \n\t"
"punpckhdq %%mm1, %%mm1 \n\t"
"movd %%mm1, (%0,%2,2) \n\t"
: "+&r" (dst),
"+&r" (src)
: "r" (dst_stride),
"r" (src_stride)
: "memory"
);
}
#define H263_LOOP_FILTER \
"pxor %%mm7, %%mm7 \n\t" \
"movq %0, %%mm0 \n\t" \
......@@ -2902,7 +2930,8 @@ static void dsputil_init_3dnow(DSPContext *c, AVCodecContext *avctx,
c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;
#if HAVE_7REGS
c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
if (mm_flags & AV_CPU_FLAG_CMOV)
c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
#endif
}
......
......@@ -66,24 +66,6 @@ extern const xmm_reg ff_pb_FE;
extern const double ff_pd_1[2];
extern const double ff_pd_2[2];
#define LOAD4(stride,in,a,b,c,d)\
"movq 0*"#stride"+"#in", "#a"\n\t"\
"movq 1*"#stride"+"#in", "#b"\n\t"\
"movq 2*"#stride"+"#in", "#c"\n\t"\
"movq 3*"#stride"+"#in", "#d"\n\t"
#define STORE4(stride,out,a,b,c,d)\
"movq "#a", 0*"#stride"+"#out"\n\t"\
"movq "#b", 1*"#stride"+"#out"\n\t"\
"movq "#c", 2*"#stride"+"#out"\n\t"\
"movq "#d", 3*"#stride"+"#out"\n\t"
/* in/out: mma=mma+mmb, mmb=mmb-mma */
#define SUMSUB_BA( a, b ) \
"paddw "#b", "#a" \n\t"\
"paddw "#b", "#b" \n\t"\
"psubw "#a", "#b" \n\t"
#define SBUTTERFLY(a,b,t,n,m)\
"mov" #m " " #a ", " #t " \n\t" /* abcd */\
"punpckl" #n " " #b ", " #a " \n\t" /* aebf */\
......@@ -95,90 +77,6 @@ extern const double ff_pd_2[2];
SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\
SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */
static inline void transpose4x4(uint8_t *dst, uint8_t *src, x86_reg dst_stride, x86_reg src_stride){
__asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ...
"movd (%1), %%mm0 \n\t"
"add %3, %1 \n\t"
"movd (%1), %%mm1 \n\t"
"movd (%1,%3,1), %%mm2 \n\t"
"movd (%1,%3,2), %%mm3 \n\t"
"punpcklbw %%mm1, %%mm0 \n\t"
"punpcklbw %%mm3, %%mm2 \n\t"
"movq %%mm0, %%mm1 \n\t"
"punpcklwd %%mm2, %%mm0 \n\t"
"punpckhwd %%mm2, %%mm1 \n\t"
"movd %%mm0, (%0) \n\t"
"add %2, %0 \n\t"
"punpckhdq %%mm0, %%mm0 \n\t"
"movd %%mm0, (%0) \n\t"
"movd %%mm1, (%0,%2,1) \n\t"
"punpckhdq %%mm1, %%mm1 \n\t"
"movd %%mm1, (%0,%2,2) \n\t"
: "+&r" (dst),
"+&r" (src)
: "r" (dst_stride),
"r" (src_stride)
: "memory"
);
}
// e,f,g,h can be memory
// out: a,d,t,c
#define TRANSPOSE8x4(a,b,c,d,e,f,g,h,t)\
"punpcklbw " #e ", " #a " \n\t" /* a0 e0 a1 e1 a2 e2 a3 e3 */\
"punpcklbw " #f ", " #b " \n\t" /* b0 f0 b1 f1 b2 f2 b3 f3 */\
"punpcklbw " #g ", " #c " \n\t" /* c0 g0 c1 g1 c2 g2 d3 g3 */\
"punpcklbw " #h ", " #d " \n\t" /* d0 h0 d1 h1 d2 h2 d3 h3 */\
SBUTTERFLY(a, b, t, bw, q) /* a= a0 b0 e0 f0 a1 b1 e1 f1 */\
/* t= a2 b2 e2 f2 a3 b3 e3 f3 */\
SBUTTERFLY(c, d, b, bw, q) /* c= c0 d0 g0 h0 c1 d1 g1 h1 */\
/* b= c2 d2 g2 h2 c3 d3 g3 h3 */\
SBUTTERFLY(a, c, d, wd, q) /* a= a0 b0 c0 d0 e0 f0 g0 h0 */\
/* d= a1 b1 c1 d1 e1 f1 g1 h1 */\
SBUTTERFLY(t, b, c, wd, q) /* t= a2 b2 c2 d2 e2 f2 g2 h2 */\
/* c= a3 b3 c3 d3 e3 f3 g3 h3 */
#if ARCH_X86_64
// permutes 01234567 -> 05736421
#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\
SBUTTERFLY(a,b,%%xmm8,wd,dqa)\
SBUTTERFLY(c,d,b,wd,dqa)\
SBUTTERFLY(e,f,d,wd,dqa)\
SBUTTERFLY(g,h,f,wd,dqa)\
SBUTTERFLY(a,c,h,dq,dqa)\
SBUTTERFLY(%%xmm8,b,c,dq,dqa)\
SBUTTERFLY(e,g,b,dq,dqa)\
SBUTTERFLY(d,f,g,dq,dqa)\
SBUTTERFLY(a,e,f,qdq,dqa)\
SBUTTERFLY(%%xmm8,d,e,qdq,dqa)\
SBUTTERFLY(h,b,d,qdq,dqa)\
SBUTTERFLY(c,g,b,qdq,dqa)\
"movdqa %%xmm8, "#g" \n\t"
#else
#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\
"movdqa "#h", "#t" \n\t"\
SBUTTERFLY(a,b,h,wd,dqa)\
"movdqa "#h", 16"#t" \n\t"\
"movdqa "#t", "#h" \n\t"\
SBUTTERFLY(c,d,b,wd,dqa)\
SBUTTERFLY(e,f,d,wd,dqa)\
SBUTTERFLY(g,h,f,wd,dqa)\
SBUTTERFLY(a,c,h,dq,dqa)\
"movdqa "#h", "#t" \n\t"\
"movdqa 16"#t", "#h" \n\t"\
SBUTTERFLY(h,b,c,dq,dqa)\
SBUTTERFLY(e,g,b,dq,dqa)\
SBUTTERFLY(d,f,g,dq,dqa)\
SBUTTERFLY(a,e,f,qdq,dqa)\
SBUTTERFLY(h,d,e,qdq,dqa)\
"movdqa "#h", 16"#t" \n\t"\
"movdqa "#t", "#h" \n\t"\
SBUTTERFLY(h,b,d,qdq,dqa)\
SBUTTERFLY(c,g,b,qdq,dqa)\
"movdqa 16"#t", "#g" \n\t"
#endif
#define MOVQ_WONE(regd) \
__asm__ volatile ( \
"pcmpeqd %%" #regd ", %%" #regd " \n\t" \
......
......@@ -362,7 +362,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom
c->h264_idct_add8 = ff_h264_idct_add8_8_mmx;
c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx;
if (mm_flags & AV_CPU_FLAG_CMOV)
c->h264_luma_dc_dequant_idct= ff_h264_luma_dc_dequant_idct_mmx;
c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx;
if (mm_flags & AV_CPU_FLAG_MMX2) {
c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmx2;
......
......@@ -59,8 +59,10 @@ OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
OBJS-$(CONFIG_ASTREAMSYNC_FILTER) += af_astreamsync.o
OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o
OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o
OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o
OBJS-$(CONFIG_CHANNELSPLIT_FILTER) += af_channelsplit.o
OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o
OBJS-$(CONFIG_JOIN_FILTER) += af_join.o
OBJS-$(CONFIG_PAN_FILTER) += af_pan.o
OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o
OBJS-$(CONFIG_SILENCEDETECT_FILTER) += af_silencedetect.o
......
......@@ -75,14 +75,14 @@ static int query_formats(AVFilterContext *ctx)
AVFilterLink *outlink = ctx->outputs[0];
AVFilterChannelLayouts *layouts;
ff_formats_ref(avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO),
ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO),
&inlink->out_formats);
if (aconvert->out_sample_fmt != AV_SAMPLE_FMT_NONE) {
formats = NULL;
ff_add_format(&formats, aconvert->out_sample_fmt);
ff_formats_ref(formats, &outlink->in_formats);
} else
ff_formats_ref(avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO),
ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO),
&outlink->in_formats);
ff_channel_layouts_ref(ff_all_channel_layouts(),
......
......@@ -134,8 +134,7 @@ AVFilter avfilter_af_aformat = {
.priv_size = sizeof(AFormatContext),
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_samples = ff_null_filter_samples },
.type = AVMEDIA_TYPE_AUDIO, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO},
......
......@@ -169,7 +169,7 @@ static int request_frame(AVFilterLink *outlink)
for (i = 0; i < am->nb_inputs; i++)
if (!am->in[i].nb_samples)
if ((ret = avfilter_request_frame(ctx->inputs[i])) < 0)
if ((ret = ff_request_frame(ctx->inputs[i])) < 0)
return ret;
return 0;
}
......
......@@ -34,8 +34,7 @@ AVFilter avfilter_af_anull = {
.inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.get_audio_buffer = ff_null_get_audio_buffer,
.filter_samples = ff_null_filter_samples },
.get_audio_buffer = ff_null_get_audio_buffer, },
{ .name = NULL}},
.outputs = (const AVFilterPad[]) {{ .name = "default",
......
......@@ -112,7 +112,7 @@ static int query_formats(AVFilterContext *ctx)
if(out_format != AV_SAMPLE_FMT_NONE) {
out_formats = ff_make_format_list((int[]){ out_format, -1 });
} else
out_formats = avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO);
out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO);
ff_formats_ref(out_formats, &outlink->in_formats);
if(out_layout) {
......@@ -211,7 +211,7 @@ static int request_frame(AVFilterLink *outlink)
aresample->req_fullfilled = 0;
do{
ret = avfilter_request_frame(ctx->inputs[0]);
ret = ff_request_frame(ctx->inputs[0]);
}while(!aresample->req_fullfilled && ret>=0);
if (ret == AVERROR_EOF) {
......
......@@ -164,7 +164,7 @@ static int request_frame(AVFilterLink *outlink)
asns->req_fullfilled = 0;
do {
ret = avfilter_request_frame(inlink);
ret = ff_request_frame(inlink);
} while (!asns->req_fullfilled && ret >= 0);
if (ret == AVERROR_EOF)
......
......@@ -157,7 +157,7 @@ static int request_frame(AVFilterLink *outlink)
send_next(ctx);
} else {
as->eof |= 1 << as->next_out;
avfilter_request_frame(ctx->inputs[as->next_out]);
ff_request_frame(ctx->inputs[as->next_out]);
if (as->eof & (1 << as->next_out))
as->next_out = !as->next_out;
}
......
......@@ -1083,7 +1083,7 @@ static int request_frame(AVFilterLink *outlink)
atempo->request_fulfilled = 0;
do {
ret = avfilter_request_frame(ctx->inputs[0]);
ret = ff_request_frame(ctx->inputs[0]);
}
while (!atempo->request_fulfilled && ret >= 0);
......
This diff is collapsed.
This diff is collapsed.
......@@ -217,7 +217,7 @@ static int query_formats(AVFilterContext *ctx)
pan->pure_gains = are_gains_pure(pan);
/* libswr supports any sample and packing formats */
ff_set_common_formats(ctx, avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO));
ff_set_common_formats(ctx, ff_all_formats(AVMEDIA_TYPE_AUDIO));
formats = ff_all_samplerates();
if (!formats)
......
......@@ -47,8 +47,10 @@ void avfilter_register_all(void)
REGISTER_FILTER (ASTREAMSYNC, astreamsync, af);
REGISTER_FILTER (ASYNCTS, asyncts, af);
REGISTER_FILTER (ATEMPO, atempo, af);
REGISTER_FILTER (CHANNELMAP, channelmap, af);
REGISTER_FILTER (CHANNELSPLIT,channelsplit,af);
REGISTER_FILTER (EARWAX, earwax, af);
REGISTER_FILTER (JOIN, join, af);
REGISTER_FILTER (PAN, pan, af);
REGISTER_FILTER (SILENCEDETECT, silencedetect, af);
REGISTER_FILTER (VOLUME, volume, af);
......
......@@ -150,32 +150,12 @@ fail:
return NULL;
}
void ff_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
static void default_filter_samples(AVFilterLink *link,
AVFilterBufferRef *samplesref)
{
ff_filter_samples(link->dst->outputs[0], samplesref);
}
/* FIXME: samplesref is same as link->cur_buf. Need to consider removing the redundant parameter. */
void ff_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
{
AVFilterLink *outlink = NULL;
if (inlink->dst->nb_outputs)
outlink = inlink->dst->outputs[0];
if (outlink) {
outlink->out_buf = ff_default_get_audio_buffer(inlink, AV_PERM_WRITE,
samplesref->audio->nb_samples);
outlink->out_buf->pts = samplesref->pts;
outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate;
ff_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
avfilter_unref_buffer(outlink->out_buf);
outlink->out_buf = NULL;
}
avfilter_unref_buffer(samplesref);
inlink->cur_buf = NULL;
}
void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
{
void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
......@@ -186,7 +166,7 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
FF_TPRINTF_START(NULL, filter_samples); ff_tlog_link(NULL, link, 1);
if (!(filter_samples = dst->filter_samples))
filter_samples = ff_default_filter_samples;
filter_samples = default_filter_samples;
/* prepare to copy the samples if the buffer has insufficient permissions */
if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
......
......@@ -63,12 +63,6 @@ AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
int nb_samples);
/** default handler for filter_samples() for audio inputs */
void ff_default_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
/** filter_samples() handler for filters which simply pass audio along */
void ff_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
/**
* Send a buffer of audio samples to the next filter.
*
......
......@@ -170,7 +170,7 @@ static int request_frame(AVFilterLink *outlink)
showwaves->req_fullfilled = 0;
do {
ret = avfilter_request_frame(inlink);
ret = ff_request_frame(inlink);
} while (!showwaves->req_fullfilled && ret >= 0);
if (ret == AVERROR_EOF && showwaves->outpicref)
......
......@@ -211,7 +211,6 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
*/
void avfilter_unref_buffer(AVFilterBufferRef *ref);
#if FF_API_FILTERS_PUBLIC
/**
* Remove a reference to a buffer and set the pointer to NULL.
* If this is the last reference to the buffer, the buffer itself
......@@ -221,6 +220,7 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref);
*/
void avfilter_unref_bufferp(AVFilterBufferRef **ref);
#if FF_API_FILTERS_PUBLIC
/**
* A list of supported formats for one end of a filter link. This is used
* during the format negotiation process to try to pick the best format to
......@@ -291,7 +291,7 @@ AVFilterFormats *avfilter_make_format_list(const int *fmts);
*
* @return a non negative value in case of success, or a negative
* value corresponding to an AVERROR code in case of error
* @deprecated Use avfilter_make_all_formats() instead.
* @deprecated Use ff_all_formats() instead.
*/
attribute_deprecated
int avfilter_add_format(AVFilterFormats **avff, int64_t fmt);
......@@ -479,7 +479,7 @@ struct AVFilterPad {
* Frame request callback. A call to this should result in at least one
* frame being output over the given link. This should return zero on
* success, and another value on error.
* See avfilter_request_frame() for the error codes with a specific
* See ff_request_frame() for the error codes with a specific
* meaning.
*
* Output pads only.
......@@ -504,6 +504,14 @@ struct AVFilterPad {
* and another value on error.
*/
int (*config_props)(AVFilterLink *link);
/**
* The filter expects a fifo to be inserted on its input link,
* typically because it has a delay.
*
* input pads only.
*/
int needs_fifo;
};
#endif
......@@ -529,6 +537,10 @@ const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx);
*/
enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx);
/** default handler for end_frame() for video inputs */
attribute_deprecated
void avfilter_default_end_frame(AVFilterLink *link);
#if FF_API_FILTERS_PUBLIC
/** default handler for start_frame() for video inputs */
attribute_deprecated
......@@ -538,10 +550,6 @@ void avfilter_default_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
attribute_deprecated
void avfilter_default_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
/** default handler for end_frame() for video inputs */
attribute_deprecated
void avfilter_default_end_frame(AVFilterLink *link);
/** default handler for get_video_buffer() for video inputs */
attribute_deprecated
AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link,
......@@ -756,6 +764,15 @@ struct AVFilterLink {
struct AVFilterChannelLayouts *in_channel_layouts;
struct AVFilterChannelLayouts *out_channel_layouts;
/**
* Audio only, the destination filter sets this to a non-zero value to
* request that buffers with the given number of samples should be sent to
* it. AVFilterPad.needs_fifo must also be set on the corresponding input
* pad.
* Last buffer before EOF will be padded with silence.
*/
int request_samples;
struct AVFilterPool *pool;
/**
......@@ -785,7 +802,6 @@ struct AVFilterLink {
* It is similar to the r_frae_rate field in AVStream.
*/
AVRational frame_rate;
};
/**
......
......@@ -187,7 +187,7 @@ static int filter_query_formats(AVFilterContext *ctx)
if ((ret = ctx->filter->query_formats(ctx)) < 0)
return ret;
formats = avfilter_make_all_formats(type);
formats = ff_all_formats(type);
if (!formats)
return AVERROR(ENOMEM);
ff_set_common_formats(ctx, formats);
......@@ -815,12 +815,52 @@ static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph,
return 0;
}
static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
{
AVFilterContext *f;
int i, j, ret;
int fifo_count = 0;
for (i = 0; i < graph->filter_count; i++) {
f = graph->filters[i];
for (j = 0; j < f->nb_inputs; j++) {
AVFilterLink *link = f->inputs[j];
AVFilterContext *fifo_ctx;
AVFilter *fifo;
char name[32];
if (!link->dstpad->needs_fifo)
continue;
fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
avfilter_get_by_name("fifo") :
avfilter_get_by_name("afifo");
snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
NULL, graph);
if (ret < 0)
return ret;
ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
if (ret < 0)
return ret;
}
}
return 0;
}
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
{
int ret;
if ((ret = graph_check_validity(graphctx, log_ctx)))
return ret;
if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
return ret;
if ((ret = graph_config_formats(graphctx, log_ctx)))
return ret;
if ((ret = graph_config_links(graphctx, log_ctx)))
......@@ -939,7 +979,7 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph)
{
while (graph->sink_links_count) {
AVFilterLink *oldest = graph->sink_links[0];
int r = avfilter_request_frame(oldest);
int r = ff_request_frame(oldest);
if (r != AVERROR_EOF)
return r;
/* EOF: remove the link from the heap */
......
......@@ -257,7 +257,7 @@ char *avfilter_graph_dump(AVFilterGraph *graph, const char *options);
* of a filtergraph, only a convenience function to help drain a filtergraph
* in a balanced way under normal circumstances.
*
* @return the return value of avfilter_request_frame,
* @return the return value of ff_request_frame,
* or AVERROR_EOF of all links returned AVERROR_EOF.
*/
int avfilter_graph_request_oldest(AVFilterGraph *graph);
......
......@@ -25,7 +25,7 @@
#include "libavutil/audio_fifo.h"
#include "libavutil/audioconvert.h"
#include "libavutil/fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/mathematics.h"
#include "audio.h"
......@@ -34,86 +34,45 @@
#include "internal.h"
typedef struct {
AVFifoBuffer *fifo; ///< FIFO buffer of frame references
AVFilterBufferRef *cur_buf; ///< last buffer delivered on the sink
AVAudioFifo *audio_fifo; ///< FIFO for audio samples
int64_t next_pts; ///< interpolating audio pts
} BufferSinkContext;
#define FIFO_INIT_SIZE 8
static av_cold void uninit(AVFilterContext *ctx)
{
BufferSinkContext *sink = ctx->priv;
while (sink->fifo && av_fifo_size(sink->fifo)) {
AVFilterBufferRef *buf;
av_fifo_generic_read(sink->fifo, &buf, sizeof(buf), NULL);
avfilter_unref_buffer(buf);
}
av_fifo_free(sink->fifo);
if (sink->audio_fifo)
av_audio_fifo_free(sink->audio_fifo);
}
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
BufferSinkContext *sink = ctx->priv;
if (!(sink->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef*)))) {
av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n");
return AVERROR(ENOMEM);
}
return 0;
}
static void write_buf(AVFilterContext *ctx, AVFilterBufferRef *buf)
static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
{
BufferSinkContext *sink = ctx->priv;
if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
(av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
return;
}
BufferSinkContext *s = link->dst->priv;
av_fifo_generic_write(sink->fifo, &buf, sizeof(buf), NULL);
}
static void end_frame(AVFilterLink *link)
{
write_buf(link->dst, link->cur_buf);
// av_assert0(!s->cur_buf);
s->cur_buf = buf;
link->cur_buf = NULL;
}
static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
{
write_buf(link->dst, buf);
}
};
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
{
BufferSinkContext *sink = ctx->priv;
BufferSinkContext *s = ctx->priv;
AVFilterLink *link = ctx->inputs[0];
int ret;
if (!buf) {
if (av_fifo_size(sink->fifo))
return av_fifo_size(sink->fifo)/sizeof(*buf);
else
return ff_poll_frame(ctx->inputs[0]);
}
if (!buf)
return ff_poll_frame(ctx->inputs[0]);
if (!av_fifo_size(sink->fifo) &&
(ret = ff_request_frame(link)) < 0)
if ((ret = ff_request_frame(link)) < 0)
return ret;
if (!av_fifo_size(sink->fifo))
if (!s->cur_buf)
return AVERROR(EINVAL);
av_fifo_generic_read(sink->fifo, buf, sizeof(*buf), NULL);
*buf = s->cur_buf;
s->cur_buf = NULL;
return 0;
}
......@@ -182,13 +141,13 @@ AVFilter avfilter_vsink_buffer = {
.name = "buffersink_old",
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
.priv_size = sizeof(BufferSinkContext),
.init = init,
.uninit = uninit,
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.end_frame = end_frame,
.min_perms = AV_PERM_READ, },
.start_frame = start_frame,
.min_perms = AV_PERM_READ,
.needs_fifo = 1 },
{ .name = NULL }},
.outputs = (AVFilterPad[]) {{ .name = NULL }},
};
......@@ -197,13 +156,13 @@ AVFilter avfilter_asink_abuffer = {
.name = "abuffersink_old",
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
.priv_size = sizeof(BufferSinkContext),
.init = init,
.uninit = uninit,
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.filter_samples = filter_samples,
.min_perms = AV_PERM_READ, },
.filter_samples = start_frame,
.min_perms = AV_PERM_READ,
.needs_fifo = 1 },
{ .name = NULL }},
.outputs = (AVFilterPad[]) {{ .name = NULL }},
};
......@@ -47,27 +47,6 @@ static void set_common_formats(AVFilterContext *ctx, AVFilterFormats *fmts,
}
}
void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats)
{
set_common_formats(ctx, formats, AVMEDIA_TYPE_VIDEO,
offsetof(AVFilterLink, in_formats),
offsetof(AVFilterLink, out_formats));
}
void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats)
{
set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO,
offsetof(AVFilterLink, in_formats),
offsetof(AVFilterLink, out_formats));
}
void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats)
{
set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO,
offsetof(AVFilterLink, in_channel_layouts),
offsetof(AVFilterLink, out_channel_layouts));
}
#if FF_API_PACKING
void avfilter_set_common_packing_formats(AVFilterContext *ctx, AVFilterFormats *formats)
{
......
......@@ -23,6 +23,11 @@
* FIFO buffering filter
*/
#include "libavutil/avassert.h"
#include "libavutil/audioconvert.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
#include "audio.h"
#include "avfilter.h"
#include "internal.h"
......@@ -36,6 +41,13 @@ typedef struct Buf {
typedef struct {
Buf root;
Buf *last; ///< last buffered frame
/**
* 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
} FifoContext;
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
......@@ -57,6 +69,8 @@ static av_cold void uninit(AVFilterContext *ctx)
avfilter_unref_buffer(buf->buf);
av_free(buf);
}
avfilter_unref_buffer(fifo->buf_out);
}
static void add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
......@@ -68,14 +82,143 @@ static void add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
fifo->last->buf = buf;
}
static void queue_pop(FifoContext *s)
{
Buf *tmp = s->root.next->next;
if (s->last == s->root.next)
s->last = &s->root;
av_freep(&s->root.next);
s->root.next = tmp;
}
static void end_frame(AVFilterLink *inlink) { }
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { }
/**
* Move data pointers and pts offset samples forward.
*/
static void buffer_offset(AVFilterLink *link, AVFilterBufferRef *buf,
int offset)
{
int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
int planar = av_sample_fmt_is_planar(link->format);
int planes = planar ? nb_channels : 1;
int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels);
int i;
av_assert0(buf->audio->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;
if (buf->pts != AV_NOPTS_VALUE) {
buf->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate},
link->time_base);
}
}
static int calc_ptr_alignment(AVFilterBufferRef *buf)
{
int planes = av_sample_fmt_is_planar(buf->format) ?
av_get_channel_layout_nb_channels(buf->audio->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)
cur_align >>= 1;
if (cur_align < min_align)
min_align = cur_align;
}
return min_align;
}
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;
int ret;
if (!s->buf_out &&
head->audio->nb_samples >= link->request_samples &&
calc_ptr_alignment(head) >= 32) {
if (head->audio->nb_samples == link->request_samples) {
buf_out = head;
queue_pop(s);
} else {
buf_out = avfilter_ref_buffer(head, AV_PERM_READ);
buf_out->audio->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)
return AVERROR(ENOMEM);
s->buf_out->audio->nb_samples = 0;
s->buf_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 "
"buffer was returned.\n");
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);
av_samples_copy(s->buf_out->extended_data, head->extended_data,
s->buf_out->audio->nb_samples, 0, len, nb_channels,
link->format);
s->buf_out->audio->nb_samples += len;
if (len == head->audio->nb_samples) {
avfilter_unref_buffer(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,
s->allocated_samples -
s->buf_out->audio->nb_samples,
nb_channels, link->format);
s->buf_out->audio->nb_samples = s->allocated_samples;
break;
}
return ret;
}
head = s->root.next->buf;
} else {
buffer_offset(link, head, len);
}
}
buf_out = s->buf_out;
s->buf_out = NULL;
}
ff_filter_samples(link, buf_out);
return 0;
}
static int request_frame(AVFilterLink *outlink)
{
FifoContext *fifo = outlink->src->priv;
Buf *tmp;
int ret;
if (!fifo->root.next) {
......@@ -90,20 +233,20 @@ static int request_frame(AVFilterLink *outlink)
ff_start_frame(outlink, fifo->root.next->buf);
ff_draw_slice (outlink, 0, outlink->h, 1);
ff_end_frame (outlink);
queue_pop(fifo);
break;
case AVMEDIA_TYPE_AUDIO:
ff_filter_samples(outlink, fifo->root.next->buf);
if (outlink->request_samples) {
return return_audio_frame(outlink->src);
} else {
ff_filter_samples(outlink, fifo->root.next->buf);
queue_pop(fifo);
}
break;
default:
return AVERROR(EINVAL);
}
if (fifo->last == fifo->root.next)
fifo->last = &fifo->root;
tmp = fifo->root.next->next;
av_free(fifo->root.next);
fifo->root.next = tmp;
return 0;
}
......
......@@ -261,11 +261,6 @@ int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
}
AVFilterFormats *ff_all_formats(enum AVMediaType type)
{
return avfilter_make_all_formats(type);
}
AVFilterFormats *avfilter_make_all_formats(enum AVMediaType type)
{
AVFilterFormats *ret = NULL;
int fmt;
......
......@@ -173,6 +173,14 @@ struct AVFilterPad {
* and another value on error.
*/
int (*config_props)(AVFilterLink *link);
/**
* The filter expects a fifo to be inserted on its input link,
* typically because it has a delay.
*
* input pads only.
*/
int needs_fifo;
};
#endif
......
......@@ -94,7 +94,7 @@ static const uint8_t offset[511][2]= {
{ 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
{ 7, 5}, {15, 5}, { 7,13}, {15,13}, { 7, 7}, {15, 7}, { 7,15}, {15,15},
{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, { 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13}, { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9}, { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15}, { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11}, { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13}, { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9}, { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12}, { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8}, { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, { 1, 2}, { 9, 2}, { 1,10}, { 9,10}, { 5, 6}, {13, 6}, { 5,14}, {13,14}, { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10}, { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12}, { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8},
{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, { 3, 1}, {11,1}, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13}, { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9}, { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15}, { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11}, { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13}, { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9}, { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12}, { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8}, { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, { 1, 2}, { 9, 2}, { 1,10}, {9,10}, { 5, 6}, {13, 6}, { 5,14}, {13,14}, { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10}, { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12}, { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8},
};
struct vf_priv_s {
......
......@@ -127,7 +127,7 @@ int av_buffersink_get_buffer_ref(AVFilterContext *ctx,
if (!av_fifo_size(buf->fifo)) {
if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
return AVERROR(EAGAIN);
if ((ret = avfilter_request_frame(inlink)) < 0)
if ((ret = ff_request_frame(inlink)) < 0)
return ret;
}
......
......@@ -28,8 +28,8 @@
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 2
#define LIBAVFILTER_VERSION_MINOR 82
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 0
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
......
......@@ -136,7 +136,7 @@ static int request_frame(AVFilterLink *outlink)
AVFilterContext *ctx = outlink->src;
BlackDetectContext *blackdetect = ctx->priv;
AVFilterLink *inlink = ctx->inputs[0];
int ret = avfilter_request_frame(inlink);
int ret = ff_request_frame(inlink);
if (ret == AVERROR_EOF && blackdetect->black_started) {
// FIXME: black_end should be set to last_picref_pts + last_picref_duration
......
......@@ -216,7 +216,7 @@ static int request_frame(AVFilterLink *link)
do {
int ret;
if ((ret = avfilter_request_frame(link->src->inputs[0])))
if ((ret = ff_request_frame(link->src->inputs[0])))
return ret;
} while (!idet->cur);
......@@ -231,7 +231,7 @@ static int poll_frame(AVFilterLink *link)
val = ff_poll_frame(link->src->inputs[0]);
if (val >= 1 && !idet->next) { //FIXME change API to not requre this red tape
if ((ret = avfilter_request_frame(link->src->inputs[0])) < 0)
if ((ret = ff_request_frame(link->src->inputs[0])) < 0)
return ret;
val = ff_poll_frame(link->src->inputs[0]);
}
......
......@@ -25,6 +25,9 @@
*/
#include "avfilter.h"
#include "video.h"
#include "formats.h"
#include "internal.h"
#include "libavutil/avassert.h"
#include "libavutil/pixdesc.h"
#include "libavutil/intreadwrite.h"
......@@ -633,9 +636,9 @@ int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
if(pts != MP_NOPTS_VALUE)
picref->pts= pts * av_q2d(outlink->time_base);
avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
avfilter_draw_slice(outlink, 0, picref->video->h, 1);
avfilter_end_frame(outlink);
ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
ff_draw_slice(outlink, 0, picref->video->h, 1);
ff_end_frame(outlink);
avfilter_unref_buffer(picref);
m->frame_returned++;
......@@ -788,14 +791,14 @@ static int query_formats(AVFilterContext *ctx)
if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){
av_log(ctx, AV_LOG_DEBUG, "supported,adding\n");
if (conversion_map[i].pix_fmt != lastpixfmt) {
avfilter_add_format(&avfmts, conversion_map[i].pix_fmt);
ff_add_format(&avfmts, conversion_map[i].pix_fmt);
lastpixfmt = conversion_map[i].pix_fmt;
}
}
}
//We assume all allowed input formats are also allowed output formats
avfilter_set_common_pixel_formats(ctx, avfmts);
ff_set_common_formats(ctx, avfmts);
return 0;
}
......@@ -836,7 +839,7 @@ static int request_frame(AVFilterLink *outlink)
av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame\n");
for(m->frame_returned=0; !m->frame_returned;){
ret=avfilter_request_frame(outlink->src->inputs[0]);
ret=ff_request_frame(outlink->src->inputs[0]);
if(ret<0)
break;
}
......
......@@ -178,7 +178,7 @@ static int request_frame(AVFilterLink *link)
/* loop until a frame thumbnail is available (when a frame is queued,
* thumb->n is reset to zero) */
do {
int ret = avfilter_request_frame(link->src->inputs[0]);
int ret = ff_request_frame(link->src->inputs[0]);
if (ret < 0)
return ret;
} while (thumb->n);
......@@ -203,7 +203,7 @@ static int poll_frame(AVFilterLink *link)
/* we have some frame(s) available in the input link, but not yet enough to
* output a thumbnail, so we request more */
ret = avfilter_request_frame(inlink);
ret = ff_request_frame(inlink);
return ret < 0 ? ret : 0;
}
......
......@@ -28,6 +28,7 @@
#include "drawutils.h"
#include "formats.h"
#include "video.h"
#include "internal.h"
typedef struct {
unsigned w, h;
......@@ -170,7 +171,7 @@ static int request_frame(AVFilterLink *outlink)
int r;
while (1) {
r = avfilter_request_frame(inlink);
r = ff_request_frame(inlink);
if (r < 0) {
if (r == AVERROR_EOF && tile->current)
end_last_frame(ctx);
......
......@@ -334,7 +334,7 @@ static int poll_frame(AVFilterLink *outlink)
val = ff_poll_frame(inlink);
if (val == 1 && !tinterlace->next) {
if ((ret = avfilter_request_frame(inlink)) < 0)
if ((ret = ff_request_frame(inlink)) < 0)
return ret;
val = ff_poll_frame(inlink);
}
......@@ -351,7 +351,7 @@ static int request_frame(AVFilterLink *outlink)
do {
int ret;
if ((ret = avfilter_request_frame(inlink)) < 0)
if ((ret = ff_request_frame(inlink)) < 0)
return ret;
} while (!tinterlace->cur);
......
......@@ -321,6 +321,11 @@ void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
draw_slice(link, y, h, slice_dir);
}
void avfilter_default_end_frame(AVFilterLink *inlink)
{
default_end_frame(inlink);
}
#if FF_API_FILTERS_PUBLIC
AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
{
......@@ -330,10 +335,6 @@ void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picre
{
default_start_frame(inlink, picref);
}
void avfilter_default_end_frame(AVFilterLink *inlink)
{
default_end_frame(inlink);
}
void avfilter_default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{
default_draw_slice(inlink, y, h, slice_dir);
......
......@@ -49,7 +49,7 @@ void av_set_cpu_flags_mask(int mask)
int av_parse_cpu_flags(const char *s)
{
#define CPUFLAG_MMX2 (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMX2)
#define CPUFLAG_MMX2 (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_CMOV)
#define CPUFLAG_3DNOW (AV_CPU_FLAG_3DNOW | AV_CPU_FLAG_MMX)
#define CPUFLAG_3DNOWEXT (AV_CPU_FLAG_3DNOWEXT | CPUFLAG_3DNOW)
#define CPUFLAG_SSE (AV_CPU_FLAG_SSE | CPUFLAG_MMX2)
......@@ -84,6 +84,7 @@ int av_parse_cpu_flags(const char *s)
{ "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_FMA4 }, .unit = "flags" },
{ "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_3DNOW }, .unit = "flags" },
{ "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_3DNOWEXT }, .unit = "flags" },
{ "cmov", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_CMOV }, .unit = "flags" },
#elif ARCH_ARM
{ "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
{ "armv6", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
......@@ -188,6 +189,7 @@ static const struct {
{ AV_CPU_FLAG_FMA4, "fma4" },
{ AV_CPU_FLAG_3DNOW, "3dnow" },
{ AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
{ AV_CPU_FLAG_CMOV, "cmov" },
#endif
{ 0 }
};
......
......@@ -40,9 +40,14 @@
#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions
#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions
#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
#define AV_CPU_FLAG_CMOV 0x1000000 ///< supports cmov instruction
#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions
#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions
#if LIBAVUTIL_VERSION_MAJOR <52
#define AV_CPU_FLAG_CMOV 0x1001000 ///< supports cmov instruction
#else
#define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction
#endif
#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard
#define AV_CPU_FLAG_ARMV5TE (1 << 0)
......
......@@ -83,7 +83,7 @@ int ff_get_cpu_flags_x86(void)
cpuid(1, eax, ebx, ecx, std_caps);
family = ((eax>>8)&0xf) + ((eax>>20)&0xff);
model = ((eax>>4)&0xf) + ((eax>>12)&0xf0);
if (std_caps & (1<<15))
if (std_caps & (1 << 15))
rval |= AV_CPU_FLAG_CMOV;
if (std_caps & (1<<23))
rval |= AV_CPU_FLAG_MMX;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment