* qatar/master: rtmp: Add a new option 'rtmp_buffer', for setting the client buffer time rtmp: Set the client buffer time to 3s instead of 0.26s rtmp: Handle server bandwidth packets rtmp: Display a verbose message when an unknown packet type is received lavfi/audio: use av_samples_copy() instead of custom code. configure: add all filters hardcoded into avconv to avconv_deps avfiltergraph: remove a redundant call to avfilter_get_by_name(). lavfi: allow building without swscale. build: Do not delete tests/vsynth2 directory, which is no longer created. lavfi: replace AVFilterContext.input/output_count with nb_inputs/outputs lavfi: make AVFilterPad opaque after two major bumps. lavfi: add avfilter_pad_get_type() and avfilter_pad_get_name(). lavfi: make avfilter_get_video_buffer() private on next bump. jack: update to new latency range API as the old one has been deprecated rtmp: Tokenize the AMF connection parameters manually instead of using strtok_r ppc: Rename H.264 optimization template file for consistency. lavfi: add channelsplit audio filter. golomb: check remaining bits during unary decoding in get_ur_golomb_jpegls() sws: fix planar RGB input conversions for 9/10/16 bpp. Conflicts: Changelog configure doc/APIchanges ffmpeg.c libavcodec/golomb.h libavcodec/v210dec.h libavfilter/Makefile libavfilter/allfilters.c libavfilter/asrc_anullsrc.c libavfilter/audio.c libavfilter/avfilter.c libavfilter/avfilter.h libavfilter/avfiltergraph.c libavfilter/buffersrc.c libavfilter/formats.c libavfilter/version.h libavfilter/vf_frei0r.c libavfilter/vf_pad.c libavfilter/vf_scale.c libavfilter/video.h libavfilter/vsrc_color.c libavformat/rtmpproto.c libswscale/input.c tests/Makefile
Unified · Split
| @@ -50,7 +50,6 @@ tests/rotozoom · 49 unmodified lines | ||
| 50 | 50 | tests/tiny_psnr |
| 51 | 51 | tests/videogen |
| 52 | 52 | tests/vsynth1 |
| 53 | −tests/vsynth2 | |
| 54 | 53 | tools/aviocat |
| 55 | 54 | tools/cws2fws |
| 56 | 55 | tools/ffeval |
| @@ -5,6 +5,7 @@ version next: · 4 unmodified lines | ||
| 5 | 5 | - INI and flat output in ffprobe |
| 6 | 6 | - Scene detection in libavfilter |
| 7 | 7 | - Indeo Audio decoder |
| 8 | +- channelsplit audio filter | |
| 8 | 9 | |
| 9 | 10 | |
| 10 | 11 | version 0.11: |
| @@ -1210,6 +1210,7 @@ HAVE_LIST=" · 1209 unmodified lines | ||
| 1210 | 1210 | inet_aton |
| 1211 | 1211 | inline_asm |
| 1212 | 1212 | isatty |
| 1213 | + jack_port_get_latency_range | |
| 1213 | 1214 | kbhit |
| 1214 | 1215 | ldbrx |
| 1215 | 1216 | libdc1394_1 |
| @@ -1730,7 +1731,6 @@ yadif_filter_deps="gpl" · 514 unmodified lines | ||
| 1730 | 1731 | |
| 1731 | 1732 | # libraries |
| 1732 | 1733 | avdevice_deps="avcodec avformat" |
| 1733 | −avfilter_deps="swscale" | |
| 1734 | 1734 | avformat_deps="avcodec" |
| 1735 | 1735 | postproc_deps="gpl" |
| 1736 | 1736 | |
| @@ -3354,7 +3354,8 @@ check_header soundcard.h · 1617 unmodified lines | ||
| 3354 | 3354 | |
| 3355 | 3355 | enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound |
| 3356 | 3356 | |
| 3357 | −enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack && check_func sem_timedwait | |
| 3357 | +enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack && check_func sem_timedwait && | |
| 3358 | + check_func jack_port_get_latency_range -ljack | |
| 3358 | 3359 | |
| 3359 | 3360 | enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio |
| 3360 | 3361 | |
| @@ -38,6 +38,15 @@ API changes, most recent first: · 37 unmodified lines | ||
| 38 | 38 | 2012-03-26 - a67d9cf - lavfi 2.66.100 |
| 39 | 39 | Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions. |
| 40 | 40 | |
| 41 | +2012-xx-xx - xxxxxxx - lavfi 2.23.0 - avfilter.h | |
| 42 | + Add AVFilterContext.nb_inputs/outputs. Deprecate | |
| 43 | + AVFilterContext.input/output_count. | |
| 44 | + | |
| 45 | +2012-xx-xx - xxxxxxx - lavfi 2.22.0 - avfilter.h | |
| 46 | + Add avfilter_pad_get_type() and avfilter_pad_get_name(). Those | |
| 47 | + should now be used instead of accessing AVFilterPad members | |
| 48 | + directly. | |
| 49 | + | |
| 41 | 50 | 2012-xx-xx - xxxxxxx - lavu 51.32.0 - audioconvert.h |
| 42 | 51 | Add av_get_channel_layout_channel_index(), av_get_channel_name() |
| 43 | 52 | and av_channel_layout_extract_channel(). |
| @@ -576,6 +576,31 @@ Maximum compensation in samples per second. · 575 unmodified lines | ||
| 576 | 576 | |
| 577 | 577 | @end table |
| 578 | 578 | |
| 579 | +@section channelsplit | |
| 580 | +Split each channel in input audio stream into a separate output stream. | |
| 581 | + | |
| 582 | +This filter accepts the following named parameters: | |
| 583 | +@table @option | |
| 584 | +@item channel_layout | |
| 585 | +Channel layout of the input stream. Default is "stereo". | |
| 586 | +@end table | |
| 587 | + | |
| 588 | +For example, assuming a stereo input MP3 file | |
| 589 | +@example | |
| 590 | +ffmpeg -i in.mp3 -filter_complex channelsplit out.mkv | |
| 591 | +@end example | |
| 592 | +will create an output Matroska file with two audio streams, one containing only | |
| 593 | +the left channel and the other the right channel. | |
| 594 | + | |
| 595 | +To split a 5.1 WAV file into per-channel files | |
| 596 | +@example | |
| 597 | +ffmpeg -i in.wav -filter_complex | |
| 598 | +'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]' | |
| 599 | +-map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]' | |
| 600 | +front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]' | |
| 601 | +side_right.wav | |
| 602 | +@end example | |
| 603 | + | |
| 579 | 604 | @section resample |
| 580 | 605 | Convert the audio sample format, sample rate and channel layout. This filter is |
| 581 | 606 | not meant to be used directly. |
| @@ -228,6 +228,9 @@ Additionally, the following parameters can be set via command line options · 227 unmodified lines | ||
| 228 | 228 | Name of application to connect on the RTMP server. This option |
| 229 | 229 | overrides the parameter specified in the URI. |
| 230 | 230 | |
| 231 | +@item rtmp_buffer | |
| 232 | +Set the client buffer time in milliseconds. The default is 3000. | |
| 233 | + | |
| 231 | 234 | @item rtmp_conn |
| 232 | 235 | Extra arbitrary AMF connection parameters, parsed from a string, |
| 233 | 236 | e.g. like @code{B:1 S:authMe O:1 NN:code:1.23 NS:flag:ok O:0}. |
| @@ -708,7 +708,7 @@ static FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost) · 707 unmodified lines | ||
| 708 | 708 | static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) |
| 709 | 709 | { |
| 710 | 710 | InputStream *ist = NULL; |
| 711 | − enum AVMediaType type = in->filter_ctx->input_pads[in->pad_idx].type; | |
| 711 | + enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx); | |
| 712 | 712 | int i; |
| 713 | 713 | |
| 714 | 714 | // TODO: support other filter types |
| @@ -978,7 +978,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, · 263 unmodified lines | ||
| 978 | 978 | \ |
| 979 | 979 | avio_printf(pb, "%s", ctx->filter->name); \ |
| 980 | 980 | if (nb_pads > 1) \ |
| 981 | − avio_printf(pb, ":%s", pads[inout->pad_idx].name); \ | |
| 981 | + avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\ | |
| 982 | 982 | avio_w8(pb, 0); \ |
| 983 | 983 | avio_close_dyn_buf(pb, &f->name); \ |
| 984 | 984 | } |
| @@ -988,7 +988,7 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFil · 3 unmodified lines | ||
| 988 | 988 | av_freep(&ofilter->name); |
| 989 | 989 | DESCRIBE_FILTER_LINK(ofilter, out, 0); |
| 990 | 990 | |
| 991 | − switch (out->filter_ctx->output_pads[out->pad_idx].type) { | |
| 991 | + switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) { | |
| 992 | 992 | case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out); |
| 993 | 993 | case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out); |
| 994 | 994 | default: av_assert0(0); |
| @@ -1132,7 +1132,7 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, · 137 unmodified lines | ||
| 1132 | 1132 | av_freep(&ifilter->name); |
| 1133 | 1133 | DESCRIBE_FILTER_LINK(ifilter, in, 1); |
| 1134 | 1134 | |
| 1135 | − switch (in->filter_ctx->input_pads[in->pad_idx].type) { | |
| 1135 | + switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) { | |
| 1136 | 1136 | case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in); |
| 1137 | 1137 | case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in); |
| 1138 | 1138 | default: av_assert0(0); |
| @@ -4899,7 +4899,8 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o, · 3760 unmodified lines | ||
| 4899 | 4899 | { |
| 4900 | 4900 | OutputStream *ost; |
| 4901 | 4901 | |
| 4902 | − switch (ofilter->out_tmp->filter_ctx->output_pads[ofilter->out_tmp->pad_idx].type) { | |
| 4902 | + switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads, | |
| 4903 | + ofilter->out_tmp->pad_idx)) { | |
| 4903 | 4904 | case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break; |
| 4904 | 4905 | case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break; |
| 4905 | 4906 | default: |
| @@ -4961,7 +4962,8 @@ static void opt_output_file(void *optctx, const char *filename) · 55 unmodified lines | ||
| 4961 | 4962 | if (!ofilter->out_tmp || ofilter->out_tmp->name) |
| 4962 | 4963 | continue; |
| 4963 | 4964 | |
| 4964 | − switch (ofilter->out_tmp->filter_ctx->output_pads[ofilter->out_tmp->pad_idx].type) { | |
| 4965 | + switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads, | |
| 4966 | + ofilter->out_tmp->pad_idx)) { | |
| 4965 | 4967 | case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break; |
| 4966 | 4968 | case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break; |
| 4967 | 4969 | case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break; |
| @@ -39,7 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #define PREFIX_h264_qpel16_v_lowpass_num altivec_put_h264_qpel16_v_lowpass_num |
| 40 | 40 | #define PREFIX_h264_qpel16_hv_lowpass_altivec put_h264_qpel16_hv_lowpass_altivec |
| 41 | 41 | #define PREFIX_h264_qpel16_hv_lowpass_num altivec_put_h264_qpel16_hv_lowpass_num |
| 42 | −#include "h264_template_altivec.c" | |
| 42 | +#include "h264_altivec_template.c" | |
| 43 | 43 | #undef OP_U8_ALTIVEC |
| 44 | 44 | #undef PREFIX_h264_chroma_mc8_altivec |
| 45 | 45 | #undef PREFIX_h264_chroma_mc8_num |
| @@ -59,7 +59,7 @@ · 13 unmodified lines | ||
| 59 | 59 | #define PREFIX_h264_qpel16_v_lowpass_num altivec_avg_h264_qpel16_v_lowpass_num |
| 60 | 60 | #define PREFIX_h264_qpel16_hv_lowpass_altivec avg_h264_qpel16_hv_lowpass_altivec |
| 61 | 61 | #define PREFIX_h264_qpel16_hv_lowpass_num altivec_avg_h264_qpel16_hv_lowpass_num |
| 62 | −#include "h264_template_altivec.c" | |
| 62 | +#include "h264_altivec_template.c" | |
| 63 | 63 | #undef OP_U8_ALTIVEC |
| 64 | 64 | #undef PREFIX_h264_chroma_mc8_altivec |
| 65 | 65 | #undef PREFIX_h264_chroma_mc8_num |
File renamed without changes.
| @@ -325,13 +325,13 @@ static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block) · 324 unmodified lines | ||
| 325 | 325 | |
| 326 | 326 | #define OP_U8_ALTIVEC PUT_OP_U8_ALTIVEC |
| 327 | 327 | #define PREFIX_no_rnd_vc1_chroma_mc8_altivec put_no_rnd_vc1_chroma_mc8_altivec |
| 328 | −#include "h264_template_altivec.c" | |
| 328 | +#include "h264_altivec_template.c" | |
| 329 | 329 | #undef OP_U8_ALTIVEC |
| 330 | 330 | #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec |
| 331 | 331 | |
| 332 | 332 | #define OP_U8_ALTIVEC AVG_OP_U8_ALTIVEC |
| 333 | 333 | #define PREFIX_no_rnd_vc1_chroma_mc8_altivec avg_no_rnd_vc1_chroma_mc8_altivec |
| 334 | −#include "h264_template_altivec.c" | |
| 334 | +#include "h264_altivec_template.c" | |
| 335 | 335 | #undef OP_U8_ALTIVEC |
| 336 | 336 | #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec |
| 337 | 337 | |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include "libavutil/log.h" |
| 23 | 23 | #include "libavutil/opt.h" |
| 24 | 24 | |
| 25 | + | |
| 25 | 26 | typedef struct { |
| 26 | 27 | AVClass *av_class; |
| 27 | 28 | int custom_stride; |
| @@ -92,7 +92,13 @@ static int process_callback(jack_nframes_t nframes, void *arg) · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | /* Copy and interleave audio data from the JACK buffer into the packet */ |
| 94 | 94 | for (i = 0; i < self->nports; i++) { |
| 95 | + #if HAVE_JACK_PORT_GET_LATENCY_RANGE | |
| 96 | + jack_latency_range_t range; | |
| 97 | + jack_port_get_latency_range(self->ports[i], JackCaptureLatency, &range); | |
| 98 | + latency += range.max; | |
| 99 | + #else | |
| 95 | 100 | latency += jack_port_get_total_latency(self->client, self->ports[i]); |
| 101 | + #endif | |
| 96 | 102 | buffer = jack_port_get_buffer(self->ports[i], self->buffer_size); |
| 97 | 103 | for (j = 0; j < self->buffer_size; j++) |
| 98 | 104 | pkt_data[j * self->nports + i] = buffer[j]; |
| @@ -1,9 +1,10 @@ | ||
| 1 | 1 | include $(SUBDIR)../config.mak |
| 2 | 2 | |
| 3 | 3 | NAME = avfilter |
| 4 | −FFLIBS = avutil swscale | |
| 4 | +FFLIBS = avutil | |
| 5 | 5 | FFLIBS-$(CONFIG_ASYNCTS_FILTER) += avresample |
| 6 | 6 | FFLIBS-$(CONFIG_RESAMPLE_FILTER) += avresample |
| 7 | +FFLIBS-$(CONFIG_SCALE_FILTER) += swscale | |
| 7 | 8 | |
| 8 | 9 | FFLIBS-$(CONFIG_ACONVERT_FILTER) += swresample |
| 9 | 10 | FFLIBS-$(CONFIG_AMOVIE_FILTER) += avformat avcodec |
| @@ -54,6 +55,7 @@ OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o · 44 unmodified lines | ||
| 54 | 55 | OBJS-$(CONFIG_ASPLIT_FILTER) += split.o |
| 55 | 56 | OBJS-$(CONFIG_ASTREAMSYNC_FILTER) += af_astreamsync.o |
| 56 | 57 | OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o |
| 58 | +OBJS-$(CONFIG_CHANNELSPLIT_FILTER) += af_channelsplit.o | |
| 57 | 59 | OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o |
| 58 | 60 | OBJS-$(CONFIG_PAN_FILTER) += af_pan.o |
| 59 | 61 | OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o |
| @@ -102,6 +104,7 @@ OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o · 42 unmodified lines | ||
| 102 | 104 | OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o |
| 103 | 105 | OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o |
| 104 | 106 | OBJS-$(CONFIG_REMOVELOGO_FILTER) += bbox.o lswsutils.o lavfutils.o vf_removelogo.o |
| 107 | +OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o | |
| 105 | 108 | OBJS-$(CONFIG_SELECT_FILTER) += vf_select.o |
| 106 | 109 | OBJS-$(CONFIG_SETDAR_FILTER) += vf_aspect.o |
| 107 | 110 | OBJS-$(CONFIG_SETFIELD_FILTER) += vf_setfield.o |
| @@ -118,7 +118,7 @@ static int query_formats(AVFilterContext *ctx) · 117 unmodified lines | ||
| 118 | 118 | if ((inlayout[i] >> c) & 1) |
| 119 | 119 | *(route[i]++) = out_ch_number++; |
| 120 | 120 | } |
| 121 | − formats = avfilter_make_format_list(ff_packed_sample_fmts); | |
| 121 | + formats = avfilter_make_format_list(ff_packed_sample_fmts_array); | |
| 122 | 122 | avfilter_set_common_sample_formats(ctx, formats); |
| 123 | 123 | for (i = 0; i < am->nb_inputs; i++) { |
| 124 | 124 | layouts = NULL; |
| @@ -454,10 +454,10 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) · 453 unmodified lines | ||
| 454 | 454 | AVFilterLink *outlink = ctx->outputs[0]; |
| 455 | 455 | int i; |
| 456 | 456 | |
| 457 | − for (i = 0; i < ctx->input_count; i++) | |
| 457 | + for (i = 0; i < ctx->nb_inputs; i++) | |
| 458 | 458 | if (ctx->inputs[i] == inlink) |
| 459 | 459 | break; |
| 460 | − if (i >= ctx->input_count) { | |
| 460 | + if (i >= ctx->nb_inputs) { | |
| 461 | 461 | av_log(ctx, AV_LOG_ERROR, "unknown input link\n"); |
| 462 | 462 | return; |
| 463 | 463 | } |
| @@ -518,7 +518,7 @@ static void uninit(AVFilterContext *ctx) · 54 unmodified lines | ||
| 518 | 518 | av_freep(&s->input_state); |
| 519 | 519 | av_freep(&s->input_scale); |
| 520 | 520 | |
| 521 | − for (i = 0; i < ctx->input_count; i++) | |
| 521 | + for (i = 0; i < ctx->nb_inputs; i++) | |
| 522 | 522 | av_freep(&ctx->input_pads[i].name); |
| 523 | 523 | } |
| 524 | 524 | |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include "audio.h" |
| 26 | 26 | #include "avfilter.h" |
| 27 | +#include "internal.h" | |
| 27 | 28 | |
| 28 | 29 | AVFilter avfilter_af_anull = { |
| 29 | 30 | .name = "anull", |
| @@ -0,0 +1,146 @@ | ||
| 1 | +/* | |
| 2 | + * This file is part of Libav. | |
| 3 | + * | |
| 4 | + * Libav is free software; you can redistribute it and/or | |
| 5 | + * modify it under the terms of the GNU Lesser General Public | |
| 6 | + * License as published by the Free Software Foundation; either | |
| 7 | + * version 2.1 of the License, or (at your option) any later version. | |
| 8 | + * | |
| 9 | + * Libav is distributed in the hope that it will be useful, | |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 | + * Lesser General Public License for more details. | |
| 13 | + * | |
| 14 | + * You should have received a copy of the GNU Lesser General Public | |
| 15 | + * License along with Libav; if not, write to the Free Software | |
| 16 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 17 | + */ | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * @file | |
| 21 | + * Channel split filter | |
| 22 | + * | |
| 23 | + * Split an audio stream into per-channel streams. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#include "libavutil/audioconvert.h" | |
| 27 | +#include "libavutil/opt.h" | |
| 28 | + | |
| 29 | +#include "audio.h" | |
| 30 | +#include "avfilter.h" | |
| 31 | +#include "formats.h" | |
| 32 | +#include "internal.h" | |
| 33 | + | |
| 34 | +typedef struct ChannelSplitContext { | |
| 35 | + const AVClass *class; | |
| 36 | + | |
| 37 | + uint64_t channel_layout; | |
| 38 | + char *channel_layout_str; | |
| 39 | +} ChannelSplitContext; | |
| 40 | + | |
| 41 | +#define OFFSET(x) offsetof(ChannelSplitContext, x) | |
| 42 | +#define A AV_OPT_FLAG_AUDIO_PARAM | |
| 43 | +static const AVOption options[] = { | |
| 44 | + { "channel_layout", "Input channel layout.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, { .str = "stereo" }, .flags = A }, | |
| 45 | + { NULL }, | |
| 46 | +}; | |
| 47 | + | |
| 48 | +static const AVClass channelsplit_class = { | |
| 49 | + .class_name = "channelsplit filter", | |
| 50 | + .item_name = av_default_item_name, | |
| 51 | + .option = options, | |
| 52 | + .version = LIBAVUTIL_VERSION_INT, | |
| 53 | +}; | |
| 54 | + | |
| 55 | +static int init(AVFilterContext *ctx, const char *arg, void *opaque) | |
| 56 | +{ | |
| 57 | + ChannelSplitContext *s = ctx->priv; | |
| 58 | + int nb_channels; | |
| 59 | + int ret = 0, i; | |
| 60 | + | |
| 61 | + s->class = &channelsplit_class; | |
| 62 | + av_opt_set_defaults(s); | |
| 63 | + if ((ret = av_set_options_string(s, arg, "=", ":")) < 0) { | |
| 64 | + av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", arg); | |
| 65 | + return ret; | |
| 66 | + } | |
| 67 | + if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) { | |
| 68 | + av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n", | |
| 69 | + s->channel_layout_str); | |
| 70 | + ret = AVERROR(EINVAL); | |
| 71 | + goto fail; | |
| 72 | + } | |
| 73 | + | |
| 74 | + nb_channels = av_get_channel_layout_nb_channels(s->channel_layout); | |
| 75 | + for (i = 0; i < nb_channels; i++) { | |
| 76 | + uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, i); | |
| 77 | + AVFilterPad pad = { 0 }; | |
| 78 | + | |
| 79 | + pad.type = AVMEDIA_TYPE_AUDIO; | |
| 80 | + pad.name = av_get_channel_name(channel); | |
| 81 | + | |
| 82 | + ff_insert_outpad(ctx, i, &pad); | |
| 83 | + } | |
| 84 | + | |
| 85 | +fail: | |
| 86 | + av_opt_free(s); | |
| 87 | + return ret; | |
| 88 | +} | |
| 89 | + | |
| 90 | +static int query_formats(AVFilterContext *ctx) | |
| 91 | +{ | |
| 92 | + ChannelSplitContext *s = ctx->priv; | |
| 93 | + AVFilterChannelLayouts *in_layouts = NULL; | |
| 94 | + int i; | |
| 95 | + | |
| 96 | + ff_set_common_formats (ctx, ff_planar_sample_fmts()); | |
| 97 | + ff_set_common_samplerates(ctx, ff_all_samplerates()); | |
| 98 | + | |
| 99 | + ff_add_channel_layout(&in_layouts, s->channel_layout); | |
| 100 | + ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->out_channel_layouts); | |
| 101 | + | |
| 102 | + for (i = 0; i < ctx->nb_outputs; i++) { | |
| 103 | + AVFilterChannelLayouts *out_layouts = NULL; | |
| 104 | + uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, i); | |
| 105 | + | |
| 106 | + ff_add_channel_layout(&out_layouts, channel); | |
| 107 | + ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->in_channel_layouts); | |
| 108 | + } | |
| 109 | + | |
| 110 | + return 0; | |
| 111 | +} | |
| 112 | + | |
| 113 | +static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) | |
| 114 | +{ | |
| 115 | + AVFilterContext *ctx = inlink->dst; | |
| 116 | + int i; | |
| 117 | + | |
| 118 | + for (i = 0; i < ctx->nb_outputs; i++) { | |
| 119 | + AVFilterBufferRef *buf_out = avfilter_ref_buffer(buf, ~AV_PERM_WRITE); | |
| 120 | + | |
| 121 | + if (!buf_out) | |
| 122 | + return; | |
| 123 | + | |
| 124 | + buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i]; | |
| 125 | + buf_out->audio->channel_layout = | |
| 126 | + av_channel_layout_extract_channel(buf->audio->channel_layout, i); | |
| 127 | + | |
| 128 | + ff_filter_samples(ctx->outputs[i], buf_out); | |
| 129 | + } | |
| 130 | + avfilter_unref_buffer(buf); | |
| 131 | +} | |
| 132 | + | |
| 133 | +AVFilter avfilter_af_channelsplit = { | |
| 134 | + .name = "channelsplit", | |
| 135 | + .description = NULL_IF_CONFIG_SMALL("Split audio into per-channel streams"), | |
| 136 | + .priv_size = sizeof(ChannelSplitContext), | |
| 137 | + | |
| 138 | + .init = init, | |
| 139 | + .query_formats = query_formats, | |
| 140 | + | |
| 141 | + .inputs = (const AVFilterPad[]){{ .name = "default", | |
| 142 | + .type = AVMEDIA_TYPE_AUDIO, | |
| 143 | + .filter_samples = filter_samples, }, | |
| 144 | + { NULL }}, | |
| 145 | + .outputs = (const AVFilterPad[]){{ NULL }}, | |
| 146 | +}; | |
| @@ -44,6 +44,7 @@ void avfilter_register_all(void) · 43 unmodified lines | ||
| 44 | 44 | REGISTER_FILTER (ASPLIT, asplit, af); |
| 45 | 45 | REGISTER_FILTER (ASTREAMSYNC, astreamsync, af); |
| 46 | 46 | REGISTER_FILTER (ASYNCTS, asyncts, af); |
| 47 | + REGISTER_FILTER (CHANNELSPLIT,channelsplit,af); | |
| 47 | 48 | REGISTER_FILTER (EARWAX, earwax, af); |
| 48 | 49 | REGISTER_FILTER (PAN, pan, af); |
| 49 | 50 | REGISTER_FILTER (SILENCEDETECT, silencedetect, af); |
| @@ -92,6 +93,7 @@ void avfilter_register_all(void) · 42 unmodified lines | ||
| 92 | 93 | REGISTER_FILTER (PAD, pad, vf); |
| 93 | 94 | REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf); |
| 94 | 95 | REGISTER_FILTER (REMOVELOGO, removelogo, vf); |
| 96 | + REGISTER_FILTER (SCALE, scale, vf); | |
| 95 | 97 | REGISTER_FILTER (SELECT, select, vf); |
| 96 | 98 | REGISTER_FILTER (SETDAR, setdar, vf); |
| 97 | 99 | REGISTER_FILTER (SETFIELD, setfield, vf); |
| @@ -143,8 +145,4 @@ void avfilter_register_all(void) · 45 unmodified lines | ||
| 143 | 145 | extern AVFilter avfilter_asink_abuffer; |
| 144 | 146 | avfilter_register(&avfilter_asink_abuffer); |
| 145 | 147 | } |
| 146 | − { | |
| 147 | − extern AVFilter avfilter_vf_scale; | |
| 148 | − avfilter_register(&avfilter_vf_scale); | |
| 149 | − } | |
| 150 | 148 | } |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | 21 | #include "avfilter.h" |
| 22 | +#include "internal.h" | |
| 22 | 23 | |
| 23 | 24 | static void null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { } |
| 24 | 25 | |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | * null audio source |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | +#include "internal.h" | |
| 27 | 28 | #include "libavutil/audioconvert.h" |
| 28 | 29 | #include "libavutil/opt.h" |
| 29 | 30 | |
| @@ -160,7 +160,7 @@ void ff_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesr · 159 unmodified lines | ||
| 160 | 160 | { |
| 161 | 161 | AVFilterLink *outlink = NULL; |
| 162 | 162 | |
| 163 | − if (inlink->dst->output_count) | |
| 163 | + if (inlink->dst->nb_outputs) | |
| 164 | 164 | outlink = inlink->dst->outputs[0]; |
| 165 | 165 | |
| 166 | 166 | if (outlink) { |
| @@ -190,10 +190,7 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) · 23 unmodified lines | ||
| 190 | 190 | /* prepare to copy the samples if the buffer has insufficient permissions */ |
| 191 | 191 | if ((dst->min_perms & samplesref->perms) != dst->min_perms || |
| 192 | 192 | dst->rej_perms & samplesref->perms) { |
| 193 | − int i, size, planar = av_sample_fmt_is_planar(samplesref->format); | |
| 194 | − int planes = !planar ? 1: | |
| 195 | − av_get_channel_layout_nb_channels(samplesref->audio->channel_layout); | |
| 196 | − | |
| 193 | + int size; | |
| 197 | 194 | av_log(link->dst, AV_LOG_DEBUG, |
| 198 | 195 | "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n", |
| 199 | 196 | samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms); |
| @@ -204,13 +201,10 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) · 4 unmodified lines | ||
| 204 | 201 | link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate; |
| 205 | 202 | |
| 206 | 203 | /* Copy actual data into new samples buffer */ |
| 207 | − /* src can be larger than dst if it was allocated larger than necessary. | |
| 208 | − dst can be slightly larger due to extra alignment padding. */ | |
| 209 | − size = FFMIN(samplesref->linesize[0], link->cur_buf->linesize[0]); | |
| 210 | − for (i = 0; samplesref->data[i] && i < 8; i++) | |
| 211 | − memcpy(link->cur_buf->data[i], samplesref->data[i], size); | |
| 212 | − for (i = 0; i < planes; i++) | |
| 213 | − memcpy(link->cur_buf->extended_data[i], samplesref->extended_data[i], size); | |
| 204 | + av_samples_copy(link->cur_buf->extended_data, samplesref->extended_data, | |
| 205 | + 0, 0, samplesref->audio->nb_samples, | |
| 206 | + av_get_channel_layout_nb_channels(link->channel_layout), | |
| 207 | + link->format); | |
| 214 | 208 | |
| 215 | 209 | avfilter_unref_buffer(samplesref); |
| 216 | 210 | } else |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include "avfilter.h" |
| 26 | 26 | |
| 27 | −static const enum AVSampleFormat ff_packed_sample_fmts[] = { | |
| 27 | +static const enum AVSampleFormat ff_packed_sample_fmts_array[] = { | |
| 28 | 28 | AV_SAMPLE_FMT_U8, |
| 29 | 29 | AV_SAMPLE_FMT_S16, |
| 30 | 30 | AV_SAMPLE_FMT_S32, |
| @@ -33,7 +33,7 @@ static const enum AVSampleFormat ff_packed_sample_fmts[] = { · 2 unmodified lines | ||
| 33 | 33 | AV_SAMPLE_FMT_NONE |
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | −static const enum AVSampleFormat ff_planar_sample_fmts[] = { | |
| 36 | +static const enum AVSampleFormat ff_planar_sample_fmts_array[] = { | |
| 37 | 37 | AV_SAMPLE_FMT_U8P, |
| 38 | 38 | AV_SAMPLE_FMT_S16P, |
| 39 | 39 | AV_SAMPLE_FMT_S32P, |
| @@ -120,8 +120,8 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad, · 119 unmodified lines | ||
| 120 | 120 | { |
| 121 | 121 | AVFilterLink *link; |
| 122 | 122 | |
| 123 | − if (src->output_count <= srcpad || dst->input_count <= dstpad || | |
| 124 | − src->outputs[srcpad] || dst->inputs[dstpad]) | |
| 123 | + if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad || | |
| 124 | + src->outputs[srcpad] || dst->inputs[dstpad]) | |
| 125 | 125 | return -1; |
| 126 | 126 | |
| 127 | 127 | if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) { |
| @@ -200,9 +200,9 @@ int avfilter_config_links(AVFilterContext *filter) · 72 unmodified lines | ||
| 200 | 200 | unsigned i; |
| 201 | 201 | int ret; |
| 202 | 202 | |
| 203 | − for (i = 0; i < filter->input_count; i ++) { | |
| 203 | + for (i = 0; i < filter->nb_inputs; i ++) { | |
| 204 | 204 | AVFilterLink *link = filter->inputs[i]; |
| 205 | − AVFilterLink *inlink = link->src->input_count ? | |
| 205 | + AVFilterLink *inlink = link->src->nb_inputs ? | |
| 206 | 206 | link->src->inputs[0] : NULL; |
| 207 | 207 | |
| 208 | 208 | if (!link) continue; |
| @@ -222,7 +222,7 @@ int avfilter_config_links(AVFilterContext *filter) · 13 unmodified lines | ||
| 222 | 222 | return ret; |
| 223 | 223 | |
| 224 | 224 | if (!(config_link = link->srcpad->config_props)) { |
| 225 | − if (link->src->input_count != 1) { | |
| 225 | + if (link->src->nb_inputs != 1) { | |
| 226 | 226 | av_log(link->src, AV_LOG_ERROR, "Source filters and filters " |
| 227 | 227 | "with more than one input " |
| 228 | 228 | "must set config_props() " |
| @@ -335,7 +335,7 @@ int ff_poll_frame(AVFilterLink *link) · 106 unmodified lines | ||
| 335 | 335 | if (link->srcpad->poll_frame) |
| 336 | 336 | return link->srcpad->poll_frame(link); |
| 337 | 337 | |
| 338 | − for (i = 0; i < link->src->input_count; i++) { | |
| 338 | + for (i = 0; i < link->src->nb_inputs; i++) { | |
| 339 | 339 | int val; |
| 340 | 340 | if (!link->src->inputs[i]) |
| 341 | 341 | return -1; |
| @@ -450,27 +450,31 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in · 108 unmodified lines | ||
| 450 | 450 | goto err; |
| 451 | 451 | } |
| 452 | 452 | |
| 453 | − ret->input_count = pad_count(filter->inputs); | |
| 454 | − if (ret->input_count) { | |
| 455 | − ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->input_count); | |
| 453 | + ret->nb_inputs = pad_count(filter->inputs); | |
| 454 | + if (ret->nb_inputs ) { | |
| 455 | + ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs); | |
| 456 | 456 | if (!ret->input_pads) |
| 457 | 457 | goto err; |
| 458 | − memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count); | |
| 459 | − ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->input_count); | |
| 458 | + memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->nb_inputs); | |
| 459 | + ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_inputs); | |
| 460 | 460 | if (!ret->inputs) |
| 461 | 461 | goto err; |
| 462 | 462 | } |
| 463 | 463 | |
| 464 | − ret->output_count = pad_count(filter->outputs); | |
| 465 | − if (ret->output_count) { | |
| 466 | − ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->output_count); | |
| 464 | + ret->nb_outputs = pad_count(filter->outputs); | |
| 465 | + if (ret->nb_outputs) { | |
| 466 | + ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs); | |
| 467 | 467 | if (!ret->output_pads) |
| 468 | 468 | goto err; |
| 469 | − memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count); | |
| 470 | − ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->output_count); | |
| 469 | + memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->nb_outputs); | |
| 470 | + ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_outputs); | |
| 471 | 471 | if (!ret->outputs) |
| 472 | 472 | goto err; |
| 473 | 473 | } |
| 474 | +#if FF_API_FOO_COUNT | |
| 475 | + ret->output_count = ret->nb_outputs; | |
| 476 | + ret->input_count = ret->nb_inputs; | |
| 477 | +#endif | |
| 474 | 478 | |
| 475 | 479 | *filter_ctx = ret; |
| 476 | 480 | return 0; |
| @@ -478,10 +482,10 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in · 1 unmodified line | ||
| 478 | 482 | err: |
| 479 | 483 | av_freep(&ret->inputs); |
| 480 | 484 | av_freep(&ret->input_pads); |
| 481 | − ret->input_count = 0; | |
| 485 | + ret->nb_inputs = 0; | |
| 482 | 486 | av_freep(&ret->outputs); |
| 483 | 487 | av_freep(&ret->output_pads); |
| 484 | − ret->output_count = 0; | |
| 488 | + ret->nb_outputs = 0; | |
| 485 | 489 | av_freep(&ret->priv); |
| 486 | 490 | av_free(ret); |
| 487 | 491 | return AVERROR(ENOMEM); |
| @@ -498,7 +502,7 @@ void avfilter_free(AVFilterContext *filter) · 10 unmodified lines | ||
| 498 | 502 | if (filter->filter->uninit) |
| 499 | 503 | filter->filter->uninit(filter); |
| 500 | 504 | |
| 501 | − for (i = 0; i < filter->input_count; i++) { | |
| 505 | + for (i = 0; i < filter->nb_inputs; i++) { | |
| 502 | 506 | if ((link = filter->inputs[i])) { |
| 503 | 507 | if (link->src) |
| 504 | 508 | link->src->outputs[link->srcpad - link->src->output_pads] = NULL; |
| @@ -511,7 +515,7 @@ void avfilter_free(AVFilterContext *filter) · 6 unmodified lines | ||
| 511 | 515 | } |
| 512 | 516 | avfilter_link_free(&link); |
| 513 | 517 | } |
| 514 | − for (i = 0; i < filter->output_count; i++) { | |
| 518 | + for (i = 0; i < filter->nb_outputs; i++) { | |
| 515 | 519 | if ((link = filter->outputs[i])) { |
| 516 | 520 | if (link->dst) |
| 517 | 521 | link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL; |
| @@ -546,6 +550,16 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque · 28 unmodified lines | ||
| 546 | 550 | return ret; |
| 547 | 551 | } |
| 548 | 552 | |
| 553 | +const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx) | |
| 554 | +{ | |
| 555 | + return pads[pad_idx].name; | |
| 556 | +} | |
| 557 | + | |
| 558 | +enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx) | |
| 559 | +{ | |
| 560 | + return pads[pad_idx].type; | |
| 561 | +} | |
| 562 | + | |
| 549 | 563 | #if FF_API_DEFAULT_CONFIG_OUTPUT_LINK |
| 550 | 564 | void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, |
| 551 | 565 | AVFilterPad **pads, AVFilterLink ***links, |
| @@ -556,14 +570,20 @@ void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, · 4 unmodified lines | ||
| 556 | 570 | void avfilter_insert_inpad(AVFilterContext *f, unsigned index, |
| 557 | 571 | AVFilterPad *p) |
| 558 | 572 | { |
| 559 | − ff_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), | |
| 573 | + ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad), | |
| 560 | 574 | &f->input_pads, &f->inputs, p); |
| 575 | +#if FF_API_FOO_COUNT | |
| 576 | + f->input_count = f->nb_inputs; | |
| 577 | +#endif | |
| 561 | 578 | } |
| 562 | 579 | void avfilter_insert_outpad(AVFilterContext *f, unsigned index, |
| 563 | 580 | AVFilterPad *p) |
| 564 | 581 | { |
| 565 | − ff_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), | |
| 582 | + ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad), | |
| 566 | 583 | &f->output_pads, &f->outputs, p); |
| 584 | +#if FF_API_FOO_COUNT | |
| 585 | + f->output_count = f->nb_outputs; | |
| 586 | +#endif | |
| 567 | 587 | } |
| 568 | 588 | int avfilter_poll_frame(AVFilterLink *link) |
| 569 | 589 | { |
| @@ -369,10 +369,16 @@ void avfilter_set_common_packing_formats(AVFilterContext *ctx, AVFilterFormats * · 368 unmodified lines | ||
| 369 | 369 | */ |
| 370 | 370 | #endif |
| 371 | 371 | |
| 372 | +#if FF_API_AVFILTERPAD_PUBLIC | |
| 372 | 373 | /** |
| 373 | 374 | * A filter pad used for either input or output. |
| 374 | 375 | * |
| 375 | 376 | * See doc/filter_design.txt for details on how to implement the methods. |
| 377 | + * | |
| 378 | + * @warning this struct might be removed from public API. | |
| 379 | + * users should call avfilter_pad_get_name() and avfilter_pad_get_type() | |
| 380 | + * to access the name and type fields; there should be no need to access | |
| 381 | + * any other fields from outside of libavfilter. | |
| 376 | 382 | */ |
| 377 | 383 | struct AVFilterPad { |
| 378 | 384 | /** |
| @@ -499,6 +505,29 @@ struct AVFilterPad { · 120 unmodified lines | ||
| 499 | 505 | */ |
| 500 | 506 | int (*config_props)(AVFilterLink *link); |
| 501 | 507 | }; |
| 508 | +#endif | |
| 509 | + | |
| 510 | +/** | |
| 511 | + * Get the name of an AVFilterPad. | |
| 512 | + * | |
| 513 | + * @param pads an array of AVFilterPads | |
| 514 | + * @param pad_idx index of the pad in the array it; is the caller's | |
| 515 | + * responsibility to ensure the index is valid | |
| 516 | + * | |
| 517 | + * @return name of the pad_idx'th pad in pads | |
| 518 | + */ | |
| 519 | +const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx); | |
| 520 | + | |
| 521 | +/** | |
| 522 | + * Get the type of an AVFilterPad. | |
| 523 | + * | |
| 524 | + * @param pads an array of AVFilterPads | |
| 525 | + * @param pad_idx index of the pad in the array; it is the caller's | |
| 526 | + * responsibility to ensure the index is valid | |
| 527 | + * | |
| 528 | + * @return type of the pad_idx'th pad in pads | |
| 529 | + */ | |
| 530 | +enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx); | |
| 502 | 531 | |
| 503 | 532 | #if FF_API_FILTERS_PUBLIC |
| 504 | 533 | /** default handler for start_frame() for video inputs */ |
| @@ -608,16 +637,23 @@ struct AVFilterContext { · 103 unmodified lines | ||
| 608 | 637 | |
| 609 | 638 | char *name; ///< name of this filter instance |
| 610 | 639 | |
| 611 | − unsigned input_count; ///< number of input pads | |
| 640 | +#if FF_API_FOO_COUNT | |
| 641 | + unsigned input_count; ///< @deprecated use nb_inputs | |
| 642 | +#endif | |
| 612 | 643 | AVFilterPad *input_pads; ///< array of input pads |
| 613 | 644 | AVFilterLink **inputs; ///< array of pointers to input links |
| 614 | 645 | |
| 615 | − unsigned output_count; ///< number of output pads | |
| 646 | +#if FF_API_FOO_COUNT | |
| 647 | + unsigned output_count; ///< @deprecated use nb_outputs | |
| 648 | +#endif | |
| 616 | 649 | AVFilterPad *output_pads; ///< array of output pads |
| 617 | 650 | AVFilterLink **outputs; ///< array of pointers to output links |
| 618 | 651 | |
| 619 | 652 | void *priv; ///< private data for use by the filter |
| 620 | 653 | |
| 654 | + unsigned nb_inputs; ///< number of input pads | |
| 655 | + unsigned nb_outputs; ///< number of output pads | |
| 656 | + | |
| 621 | 657 | struct AVFilterCommand *command_queue; |
| 622 | 658 | }; |
| 623 | 659 | |
| @@ -777,19 +813,11 @@ void avfilter_link_free(AVFilterLink **link); · 153 unmodified lines | ||
| 777 | 813 | */ |
| 778 | 814 | int avfilter_config_links(AVFilterContext *filter); |
| 779 | 815 | |
| 780 | −/** | |
| 781 | − * Request a picture buffer with a specific set of permissions. | |
| 782 | − * | |
| 783 | − * @param link the output link to the filter from which the buffer will | |
| 784 | − * be requested | |
| 785 | − * @param perms the required access permissions | |
| 786 | − * @param w the minimum width of the buffer to allocate | |
| 787 | − * @param h the minimum height of the buffer to allocate | |
| 788 | − * @return A reference to the buffer. This must be unreferenced with | |
| 789 | − * avfilter_unref_buffer when you are finished with it. | |
| 790 | − */ | |
| 816 | +#if FF_API_FILTERS_PUBLIC | |
| 817 | +attribute_deprecated | |
| 791 | 818 | AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, |
| 792 | 819 | int w, int h); |
| 820 | +#endif | |
| 793 | 821 | |
| 794 | 822 | /** |
| 795 | 823 | * Create a buffer reference wrapped around an already allocated image |
| @@ -118,7 +118,7 @@ static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx) · 117 unmodified lines | ||
| 118 | 118 | for (i = 0; i < graph->filter_count; i++) { |
| 119 | 119 | filt = graph->filters[i]; |
| 120 | 120 | |
| 121 | − for (j = 0; j < filt->input_count; j++) { | |
| 121 | + for (j = 0; j < filt->nb_inputs; j++) { | |
| 122 | 122 | if (!filt->inputs[j] || !filt->inputs[j]->src) { |
| 123 | 123 | av_log(log_ctx, AV_LOG_ERROR, |
| 124 | 124 | "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n", |
| @@ -127,7 +127,7 @@ static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx) · 2 unmodified lines | ||
| 127 | 127 | } |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | − for (j = 0; j < filt->output_count; j++) { | |
| 130 | + for (j = 0; j < filt->nb_outputs; j++) { | |
| 131 | 131 | if (!filt->outputs[j] || !filt->outputs[j]->dst) { |
| 132 | 132 | av_log(log_ctx, AV_LOG_ERROR, |
| 133 | 133 | "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n", |
| @@ -153,7 +153,7 @@ static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx) · 19 unmodified lines | ||
| 153 | 153 | for (i=0; i < graph->filter_count; i++) { |
| 154 | 154 | filt = graph->filters[i]; |
| 155 | 155 | |
| 156 | − if (!filt->output_count) { | |
| 156 | + if (!filt->nb_outputs) { | |
| 157 | 157 | if ((ret = avfilter_config_links(filt))) |
| 158 | 158 | return ret; |
| 159 | 159 | } |
| @@ -271,7 +271,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 111 unmodified lines | ||
| 271 | 271 | /* Call query_formats on sources first. |
| 272 | 272 | This is a temporary workaround for amerge, |
| 273 | 273 | until format renegociation is implemented. */ |
| 274 | − if (!graph->filters[i]->input_count == j) | |
| 274 | + if (!graph->filters[i]->nb_inputs == j) | |
| 275 | 275 | continue; |
| 276 | 276 | if (graph->filters[i]->filter->query_formats) |
| 277 | 277 | ret = filter_query_formats(graph->filters[i]); |
| @@ -286,7 +286,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 8 unmodified lines | ||
| 286 | 286 | for (i = 0; i < graph->filter_count; i++) { |
| 287 | 287 | AVFilterContext *filter = graph->filters[i]; |
| 288 | 288 | |
| 289 | − for (j = 0; j < filter->input_count; j++) { | |
| 289 | + for (j = 0; j < filter->nb_inputs; j++) { | |
| 290 | 290 | AVFilterLink *link = filter->inputs[j]; |
| 291 | 291 | #if 0 |
| 292 | 292 | if (!link) continue; |
| @@ -348,11 +348,16 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 55 unmodified lines | ||
| 348 | 348 | /* couldn't merge format lists. auto-insert conversion filter */ |
| 349 | 349 | switch (link->type) { |
| 350 | 350 | case AVMEDIA_TYPE_VIDEO: |
| 351 | + if (!(filter = avfilter_get_by_name("scale"))) { | |
| 352 | + av_log(log_ctx, AV_LOG_ERROR, "'scale' filter " | |
| 353 | + "not present, cannot convert pixel formats.\n"); | |
| 354 | + return AVERROR(EINVAL); | |
| 355 | + } | |
| 356 | + | |
| 351 | 357 | snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d", |
| 352 | 358 | scaler_count++); |
| 353 | 359 | snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts); |
| 354 | − if ((ret = avfilter_graph_create_filter(&convert, | |
| 355 | − avfilter_get_by_name("scale"), | |
| 360 | + if ((ret = avfilter_graph_create_filter(&convert, filter, | |
| 356 | 361 | inst_name, scale_args, NULL, |
| 357 | 362 | graph)) < 0) |
| 358 | 363 | return ret; |
| @@ -366,8 +371,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 7 unmodified lines | ||
| 366 | 371 | |
| 367 | 372 | snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d", |
| 368 | 373 | resampler_count++); |
| 369 | − if ((ret = avfilter_graph_create_filter(&convert, | |
| 370 | − avfilter_get_by_name("aresample"), | |
| 374 | + if ((ret = avfilter_graph_create_filter(&convert, filter, | |
| 371 | 375 | inst_name, NULL, NULL, graph)) < 0) |
| 372 | 376 | return ret; |
| 373 | 377 | break; |
| @@ -464,7 +468,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 90 unmodified lines | ||
| 464 | 468 | |
| 465 | 469 | #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \ |
| 466 | 470 | do { \ |
| 467 | − for (i = 0; i < filter->input_count; i++) { \ | |
| 471 | + for (i = 0; i < filter->nb_inputs; i++) { \ | |
| 468 | 472 | AVFilterLink *link = filter->inputs[i]; \ |
| 469 | 473 | fmt_type fmt; \ |
| 470 | 474 | \ |
| @@ -472,7 +476,7 @@ do { \ · 1 unmodified line | ||
| 472 | 476 | continue; \ |
| 473 | 477 | fmt = link->out_ ## list->var[0]; \ |
| 474 | 478 | \ |
| 475 | − for (j = 0; j < filter->output_count; j++) { \ | |
| 479 | + for (j = 0; j < filter->nb_outputs; j++) { \ | |
| 476 | 480 | AVFilterLink *out_link = filter->outputs[j]; \ |
| 477 | 481 | list_type *fmts; \ |
| 478 | 482 | \ |
| @@ -529,19 +533,19 @@ static void swap_samplerates_on_filter(AVFilterContext *filter) · 50 unmodified lines | ||
| 529 | 533 | int sample_rate; |
| 530 | 534 | int i, j; |
| 531 | 535 | |
| 532 | − for (i = 0; i < filter->input_count; i++) { | |
| 536 | + for (i = 0; i < filter->nb_inputs; i++) { | |
| 533 | 537 | link = filter->inputs[i]; |
| 534 | 538 | |
| 535 | 539 | if (link->type == AVMEDIA_TYPE_AUDIO && |
| 536 | 540 | link->out_samplerates->format_count == 1) |
| 537 | 541 | break; |
| 538 | 542 | } |
| 539 | − if (i == filter->input_count) | |
| 543 | + if (i == filter->nb_inputs) | |
| 540 | 544 | return; |
| 541 | 545 | |
| 542 | 546 | sample_rate = link->out_samplerates->formats[0]; |
| 543 | 547 | |
| 544 | − for (i = 0; i < filter->output_count; i++) { | |
| 548 | + for (i = 0; i < filter->nb_outputs; i++) { | |
| 545 | 549 | AVFilterLink *outlink = filter->outputs[i]; |
| 546 | 550 | int best_idx, best_diff = INT_MAX; |
| 547 | 551 | |
| @@ -576,19 +580,19 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) · 28 unmodified lines | ||
| 576 | 580 | uint64_t chlayout; |
| 577 | 581 | int i, j; |
| 578 | 582 | |
| 579 | − for (i = 0; i < filter->input_count; i++) { | |
| 583 | + for (i = 0; i < filter->nb_inputs; i++) { | |
| 580 | 584 | link = filter->inputs[i]; |
| 581 | 585 | |
| 582 | 586 | if (link->type == AVMEDIA_TYPE_AUDIO && |
| 583 | 587 | link->out_channel_layouts->nb_channel_layouts == 1) |
| 584 | 588 | break; |
| 585 | 589 | } |
| 586 | − if (i == filter->input_count) | |
| 590 | + if (i == filter->nb_inputs) | |
| 587 | 591 | return; |
| 588 | 592 | |
| 589 | 593 | chlayout = link->out_channel_layouts->channel_layouts[0]; |
| 590 | 594 | |
| 591 | − for (i = 0; i < filter->output_count; i++) { | |
| 595 | + for (i = 0; i < filter->nb_outputs; i++) { | |
| 592 | 596 | AVFilterLink *outlink = filter->outputs[i]; |
| 593 | 597 | int best_idx, best_score = INT_MIN; |
| 594 | 598 | |
| @@ -629,20 +633,20 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter) · 34 unmodified lines | ||
| 629 | 633 | int format, bps; |
| 630 | 634 | int i, j; |
| 631 | 635 | |
| 632 | − for (i = 0; i < filter->input_count; i++) { | |
| 636 | + for (i = 0; i < filter->nb_inputs; i++) { | |
| 633 | 637 | link = filter->inputs[i]; |
| 634 | 638 | |
| 635 | 639 | if (link->type == AVMEDIA_TYPE_AUDIO && |
| 636 | 640 | link->out_formats->format_count == 1) |
| 637 | 641 | break; |
| 638 | 642 | } |
| 639 | − if (i == filter->input_count) | |
| 643 | + if (i == filter->nb_inputs) | |
| 640 | 644 | return; |
| 641 | 645 | |
| 642 | 646 | format = link->out_formats->formats[0]; |
| 643 | 647 | bps = av_get_bytes_per_sample(format); |
| 644 | 648 | |
| 645 | − for (i = 0; i < filter->output_count; i++) { | |
| 649 | + for (i = 0; i < filter->nb_outputs; i++) { | |
| 646 | 650 | AVFilterLink *outlink = filter->outputs[i]; |
| 647 | 651 | int best_idx, best_score = INT_MIN; |
| 648 | 652 | |
| @@ -700,24 +704,24 @@ static int pick_formats(AVFilterGraph *graph) · 51 unmodified lines | ||
| 700 | 704 | change = 0; |
| 701 | 705 | for (i = 0; i < graph->filter_count; i++) { |
| 702 | 706 | AVFilterContext *filter = graph->filters[i]; |
| 703 | − if (filter->input_count){ | |
| 704 | − for (j = 0; j < filter->input_count; j++){ | |
| 707 | + if (filter->nb_inputs){ | |
| 708 | + for (j = 0; j < filter->nb_inputs; j++){ | |
| 705 | 709 | if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) { |
| 706 | 710 | pick_format(filter->inputs[j], NULL); |
| 707 | 711 | change = 1; |
| 708 | 712 | } |
| 709 | 713 | } |
| 710 | 714 | } |
| 711 | − if (filter->output_count){ | |
| 712 | − for (j = 0; j < filter->output_count; j++){ | |
| 715 | + if (filter->nb_outputs){ | |
| 716 | + for (j = 0; j < filter->nb_outputs; j++){ | |
| 713 | 717 | if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) { |
| 714 | 718 | pick_format(filter->outputs[j], NULL); |
| 715 | 719 | change = 1; |
| 716 | 720 | } |
| 717 | 721 | } |
| 718 | 722 | } |
| 719 | − if (filter->input_count && filter->output_count && filter->inputs[0]->format>=0) { | |
| 720 | − for (j = 0; j < filter->output_count; j++) { | |
| 723 | + if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) { | |
| 724 | + for (j = 0; j < filter->nb_outputs; j++) { | |
| 721 | 725 | if(filter->outputs[j]->format<0) { |
| 722 | 726 | pick_format(filter->outputs[j], filter->inputs[0]); |
| 723 | 727 | change = 1; |
| @@ -730,10 +734,10 @@ static int pick_formats(AVFilterGraph *graph) · 6 unmodified lines | ||
| 730 | 734 | for (i = 0; i < graph->filter_count; i++) { |
| 731 | 735 | AVFilterContext *filter = graph->filters[i]; |
| 732 | 736 | |
| 733 | − for (j = 0; j < filter->input_count; j++) | |
| 737 | + for (j = 0; j < filter->nb_inputs; j++) | |
| 734 | 738 | if ((ret = pick_format(filter->inputs[j], NULL)) < 0) |
| 735 | 739 | return ret; |
| 736 | − for (j = 0; j < filter->output_count; j++) | |
| 740 | + for (j = 0; j < filter->nb_outputs; j++) | |
| 737 | 741 | if ((ret = pick_format(filter->outputs[j], NULL)) < 0) |
| 738 | 742 | return ret; |
| 739 | 743 | } |
| @@ -778,18 +782,18 @@ static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph, · 38 unmodified lines | ||
| 778 | 782 | |
| 779 | 783 | for (i = 0; i < graph->filter_count; i++) { |
| 780 | 784 | f = graph->filters[i]; |
| 781 | − for (j = 0; j < f->input_count; j++) { | |
| 785 | + for (j = 0; j < f->nb_inputs; j++) { | |
| 782 | 786 | f->inputs[j]->graph = graph; |
| 783 | 787 | f->inputs[j]->age_index = -1; |
| 784 | 788 | } |
| 785 | − for (j = 0; j < f->output_count; j++) { | |
| 789 | + for (j = 0; j < f->nb_outputs; j++) { | |
| 786 | 790 | f->outputs[j]->graph = graph; |
| 787 | 791 | f->outputs[j]->age_index= -1; |
| 788 | 792 | } |
| 789 | − if (!f->output_count) { | |
| 790 | − if (f->input_count > INT_MAX - sink_links_count) | |
| 793 | + if (!f->nb_outputs) { | |
| 794 | + if (f->nb_inputs > INT_MAX - sink_links_count) | |
| 791 | 795 | return AVERROR(EINVAL); |
| 792 | − sink_links_count += f->input_count; | |
| 796 | + sink_links_count += f->nb_inputs; | |
| 793 | 797 | } |
| 794 | 798 | } |
| 795 | 799 | sinks = av_calloc(sink_links_count, sizeof(*sinks)); |
| @@ -797,8 +801,8 @@ static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph, · 1 unmodified line | ||
| 797 | 801 | return AVERROR(ENOMEM); |
| 798 | 802 | for (i = 0; i < graph->filter_count; i++) { |
| 799 | 803 | f = graph->filters[i]; |
| 800 | − if (!f->output_count) { | |
| 801 | − for (j = 0; j < f->input_count; j++) { | |
| 804 | + if (!f->nb_outputs) { | |
| 805 | + for (j = 0; j < f->nb_inputs; j++) { | |
| 802 | 806 | sinks[n] = f->inputs[j]; |
| 803 | 807 | f->inputs[j]->age_index = n++; |
| 804 | 808 | } |
| @@ -84,7 +84,7 @@ static AVFilterBufferRef *copy_buffer_ref(AVFilterContext *ctx, · 83 unmodified lines | ||
| 84 | 84 | switch (outlink->type) { |
| 85 | 85 | |
| 86 | 86 | case AVMEDIA_TYPE_VIDEO: |
| 87 | − buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 87 | + buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 88 | 88 | ref->video->w, ref->video->h); |
| 89 | 89 | if(!buf) |
| 90 | 90 | return NULL; |
| @@ -303,6 +303,18 @@ AVFilterFormats *avfilter_make_all_packing_formats(void) · 302 unmodified lines | ||
| 303 | 303 | } |
| 304 | 304 | #endif |
| 305 | 305 | |
| 306 | +AVFilterFormats *ff_planar_sample_fmts(void) | |
| 307 | +{ | |
| 308 | + AVFilterFormats *ret = NULL; | |
| 309 | + int fmt; | |
| 310 | + | |
| 311 | + for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++) | |
| 312 | + if (av_sample_fmt_is_planar(fmt)) | |
| 313 | + ff_add_format(&ret, fmt); | |
| 314 | + | |
| 315 | + return ret; | |
| 316 | +} | |
| 317 | + | |
| 306 | 318 | AVFilterFormats *ff_all_samplerates(void) |
| 307 | 319 | { |
| 308 | 320 | AVFilterFormats *ret = av_mallocz(sizeof(*ret)); |
| @@ -401,13 +413,13 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) · 92 unmodified lines | ||
| 401 | 413 | { \ |
| 402 | 414 | int count = 0, i; \ |
| 403 | 415 | \ |
| 404 | − for (i = 0; i < ctx->input_count; i++) { \ | |
| 416 | + for (i = 0; i < ctx->nb_inputs; i++) { \ | |
| 405 | 417 | if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \ |
| 406 | 418 | ref(fmts, &ctx->inputs[i]->out_fmts); \ |
| 407 | 419 | count++; \ |
| 408 | 420 | } \ |
| 409 | 421 | } \ |
| 410 | − for (i = 0; i < ctx->output_count; i++) { \ | |
| 422 | + for (i = 0; i < ctx->nb_outputs; i++) { \ | |
| 411 | 423 | if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \ |
| 412 | 424 | ref(fmts, &ctx->outputs[i]->in_fmts); \ |
| 413 | 425 | count++; \ |
| @@ -162,6 +162,11 @@ int ff_add_format(AVFilterFormats **avff, int64_t fmt); · 161 unmodified lines | ||
| 162 | 162 | */ |
| 163 | 163 | AVFilterFormats *ff_all_formats(enum AVMediaType type); |
| 164 | 164 | |
| 165 | +/** | |
| 166 | + * Construct a formats list containing all planar sample formats. | |
| 167 | + */ | |
| 168 | +AVFilterFormats *ff_planar_sample_fmts(void); | |
| 169 | + | |
| 165 | 170 | /** |
| 166 | 171 | * Return a format list which contains the intersection of the formats of |
| 167 | 172 | * a and b. Also, all the references of a, all the references of b, and |
| @@ -226,7 +226,7 @@ static int link_filter_inouts(AVFilterContext *filt_ctx, · 225 unmodified lines | ||
| 226 | 226 | { |
| 227 | 227 | int pad, ret; |
| 228 | 228 | |
| 229 | − for (pad = 0; pad < filt_ctx->input_count; pad++) { | |
| 229 | + for (pad = 0; pad < filt_ctx->nb_inputs; pad++) { | |
| 230 | 230 | AVFilterInOut *p = *curr_inputs; |
| 231 | 231 | |
| 232 | 232 | if (p) { |
| @@ -254,7 +254,7 @@ static int link_filter_inouts(AVFilterContext *filt_ctx, · 21 unmodified lines | ||
| 254 | 254 | return AVERROR(EINVAL); |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | − pad = filt_ctx->output_count; | |
| 257 | + pad = filt_ctx->nb_outputs; | |
| 258 | 258 | while (pad--) { |
| 259 | 259 | AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut)); |
| 260 | 260 | if (!currlinkn) |
| @@ -50,6 +50,132 @@ typedef struct AVFilterCommand { · 49 unmodified lines | ||
| 50 | 50 | */ |
| 51 | 51 | void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link); |
| 52 | 52 | |
| 53 | +#if !FF_API_AVFILTERPAD_PUBLIC | |
| 54 | +/** | |
| 55 | + * A filter pad used for either input or output. | |
| 56 | + */ | |
| 57 | +struct AVFilterPad { | |
| 58 | + /** | |
| 59 | + * Pad name. The name is unique among inputs and among outputs, but an | |
| 60 | + * input may have the same name as an output. This may be NULL if this | |
| 61 | + * pad has no need to ever be referenced by name. | |
| 62 | + */ | |
| 63 | + const char *name; | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * AVFilterPad type. | |
| 67 | + */ | |
| 68 | + enum AVMediaType type; | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Minimum required permissions on incoming buffers. Any buffer with | |
| 72 | + * insufficient permissions will be automatically copied by the filter | |
| 73 | + * system to a new buffer which provides the needed access permissions. | |
| 74 | + * | |
| 75 | + * Input pads only. | |
| 76 | + */ | |
| 77 | + int min_perms; | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * Permissions which are not accepted on incoming buffers. Any buffer | |
| 81 | + * which has any of these permissions set will be automatically copied | |
| 82 | + * by the filter system to a new buffer which does not have those | |
| 83 | + * permissions. This can be used to easily disallow buffers with | |
| 84 | + * AV_PERM_REUSE. | |
| 85 | + * | |
| 86 | + * Input pads only. | |
| 87 | + */ | |
| 88 | + int rej_perms; | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * Callback called before passing the first slice of a new frame. If | |
| 92 | + * NULL, the filter layer will default to storing a reference to the | |
| 93 | + * picture inside the link structure. | |
| 94 | + * | |
| 95 | + * Input video pads only. | |
| 96 | + */ | |
| 97 | + void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Callback function to get a video buffer. If NULL, the filter system will | |
| 101 | + * use avfilter_default_get_video_buffer(). | |
| 102 | + * | |
| 103 | + * Input video pads only. | |
| 104 | + */ | |
| 105 | + AVFilterBufferRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h); | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Callback function to get an audio buffer. If NULL, the filter system will | |
| 109 | + * use avfilter_default_get_audio_buffer(). | |
| 110 | + * | |
| 111 | + * Input audio pads only. | |
| 112 | + */ | |
| 113 | + AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms, | |
| 114 | + int nb_samples); | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * Callback called after the slices of a frame are completely sent. If | |
| 118 | + * NULL, the filter layer will default to releasing the reference stored | |
| 119 | + * in the link structure during start_frame(). | |
| 120 | + * | |
| 121 | + * Input video pads only. | |
| 122 | + */ | |
| 123 | + void (*end_frame)(AVFilterLink *link); | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Slice drawing callback. This is where a filter receives video data | |
| 127 | + * and should do its processing. | |
| 128 | + * | |
| 129 | + * Input video pads only. | |
| 130 | + */ | |
| 131 | + void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * Samples filtering callback. This is where a filter receives audio data | |
| 135 | + * and should do its processing. | |
| 136 | + * | |
| 137 | + * Input audio pads only. | |
| 138 | + */ | |
| 139 | + void (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref); | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Frame poll callback. This returns the number of immediately available | |
| 143 | + * samples. It should return a positive value if the next request_frame() | |
| 144 | + * is guaranteed to return one frame (with no delay). | |
| 145 | + * | |
| 146 | + * Defaults to just calling the source poll_frame() method. | |
| 147 | + * | |
| 148 | + * Output pads only. | |
| 149 | + */ | |
| 150 | + int (*poll_frame)(AVFilterLink *link); | |
| 151 | + | |
| 152 | + /** | |
| 153 | + * Frame request callback. A call to this should result in at least one | |
| 154 | + * frame being output over the given link. This should return zero on | |
| 155 | + * success, and another value on error. | |
| 156 | + * | |
| 157 | + * Output pads only. | |
| 158 | + */ | |
| 159 | + int (*request_frame)(AVFilterLink *link); | |
| 160 | + | |
| 161 | + /** | |
| 162 | + * Link configuration callback. | |
| 163 | + * | |
| 164 | + * For output pads, this should set the link properties such as | |
| 165 | + * width/height. This should NOT set the format property - that is | |
| 166 | + * negotiated between filters by the filter system using the | |
| 167 | + * query_formats() callback before this function is called. | |
| 168 | + * | |
| 169 | + * For input pads, this should check the properties of the link, and update | |
| 170 | + * the filter's internal state as necessary. | |
| 171 | + * | |
| 172 | + * For both input and output filters, this should return zero on success, | |
| 173 | + * and another value on error. | |
| 174 | + */ | |
| 175 | + int (*config_props)(AVFilterLink *link); | |
| 176 | +}; | |
| 177 | +#endif | |
| 178 | + | |
| 53 | 179 | /** default handler for freeing audio/video buffer when there are no references left */ |
| 54 | 180 | void ff_avfilter_default_free_buffer(AVFilterBuffer *buf); |
| 55 | 181 | |
| @@ -165,16 +291,22 @@ void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, · 109 unmodified lines | ||
| 165 | 291 | static inline void ff_insert_inpad(AVFilterContext *f, unsigned index, |
| 166 | 292 | AVFilterPad *p) |
| 167 | 293 | { |
| 168 | − ff_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), | |
| 294 | + ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad), | |
| 169 | 295 | &f->input_pads, &f->inputs, p); |
| 296 | +#if FF_API_FOO_COUNT | |
| 297 | + f->input_count = f->nb_inputs; | |
| 298 | +#endif | |
| 170 | 299 | } |
| 171 | 300 | |
| 172 | 301 | /** Insert a new output pad for the filter. */ |
| 173 | 302 | static inline void ff_insert_outpad(AVFilterContext *f, unsigned index, |
| 174 | 303 | AVFilterPad *p) |
| 175 | 304 | { |
| 176 | − ff_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), | |
| 305 | + ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad), | |
| 177 | 306 | &f->output_pads, &f->outputs, p); |
| 307 | +#if FF_API_FOO_COUNT | |
| 308 | + f->output_count = f->nb_outputs; | |
| 309 | +#endif | |
| 178 | 310 | } |
| 179 | 311 | |
| 180 | 312 | /** |
| @@ -59,7 +59,7 @@ static void split_uninit(AVFilterContext *ctx) · 58 unmodified lines | ||
| 59 | 59 | { |
| 60 | 60 | int i; |
| 61 | 61 | |
| 62 | − for (i = 0; i < ctx->output_count; i++) | |
| 62 | + for (i = 0; i < ctx->nb_outputs; i++) | |
| 63 | 63 | av_freep(&ctx->output_pads[i].name); |
| 64 | 64 | } |
| 65 | 65 | |
| @@ -68,7 +68,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) · 2 unmodified lines | ||
| 68 | 68 | AVFilterContext *ctx = inlink->dst; |
| 69 | 69 | int i; |
| 70 | 70 | |
| 71 | − for (i = 0; i < ctx->output_count; i++) | |
| 71 | + for (i = 0; i < ctx->nb_outputs; i++) | |
| 72 | 72 | ff_start_frame(ctx->outputs[i], |
| 73 | 73 | avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); |
| 74 | 74 | } |
| @@ -78,7 +78,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) · 3 unmodified lines | ||
| 78 | 78 | AVFilterContext *ctx = inlink->dst; |
| 79 | 79 | int i; |
| 80 | 80 | |
| 81 | − for (i = 0; i < ctx->output_count; i++) | |
| 81 | + for (i = 0; i < ctx->nb_outputs; i++) | |
| 82 | 82 | ff_draw_slice(ctx->outputs[i], y, h, slice_dir); |
| 83 | 83 | } |
| 84 | 84 | |
| @@ -87,7 +87,7 @@ static void end_frame(AVFilterLink *inlink) · 2 unmodified lines | ||
| 87 | 87 | AVFilterContext *ctx = inlink->dst; |
| 88 | 88 | int i; |
| 89 | 89 | |
| 90 | − for (i = 0; i < ctx->output_count; i++) | |
| 90 | + for (i = 0; i < ctx->nb_outputs; i++) | |
| 91 | 91 | ff_end_frame(ctx->outputs[i]); |
| 92 | 92 | |
| 93 | 93 | avfilter_unref_buffer(inlink->cur_buf); |
| @@ -115,7 +115,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref) · 21 unmodified lines | ||
| 115 | 115 | AVFilterContext *ctx = inlink->dst; |
| 116 | 116 | int i; |
| 117 | 117 | |
| 118 | − for (i = 0; i < ctx->output_count; i++) | |
| 118 | + for (i = 0; i < ctx->nb_outputs; i++) | |
| 119 | 119 | ff_filter_samples(inlink->dst->outputs[i], |
| 120 | 120 | avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE)); |
| 121 | 121 | } |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #include "avcodec.h" |
| 40 | 40 | #include "avfilter.h" |
| 41 | 41 | #include "formats.h" |
| 42 | +#include "internal.h" | |
| 42 | 43 | #include "video.h" |
| 43 | 44 | |
| 44 | 45 | typedef struct { |
| @@ -272,8 +273,8 @@ static int movie_get_frame(AVFilterLink *outlink) · 227 unmodified lines | ||
| 272 | 273 | |
| 273 | 274 | if (frame_decoded) { |
| 274 | 275 | /* FIXME: avoid the memcpy */ |
| 275 | − movie->picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE | AV_PERM_PRESERVE | | |
| 276 | − AV_PERM_REUSE2, outlink->w, outlink->h); | |
| 276 | + movie->picref = ff_get_video_buffer(outlink, AV_PERM_WRITE | AV_PERM_PRESERVE | | |
| 277 | + AV_PERM_REUSE2, outlink->w, outlink->h); | |
| 277 | 278 | av_image_copy(movie->picref->data, movie->picref->linesize, |
| 278 | 279 | (void*)movie->frame->data, movie->frame->linesize, |
| 279 | 280 | movie->picref->format, outlink->w, outlink->h); |
| @@ -29,8 +29,8 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "libavutil/avutil.h" |
| 30 | 30 | |
| 31 | 31 | #define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 | −#define LIBAVFILTER_VERSION_MINOR 78 | |
| 33 | −#define LIBAVFILTER_VERSION_MICRO 101 | |
| 32 | +#define LIBAVFILTER_VERSION_MINOR 79 | |
| 33 | +#define LIBAVFILTER_VERSION_MICRO 100 | |
| 34 | 34 | |
| 35 | 35 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| 36 | 36 | LIBAVFILTER_VERSION_MINOR, \ |
| @@ -62,5 +62,11 @@ · 25 unmodified lines | ||
| 62 | 62 | #ifndef FF_API_FILTERS_PUBLIC |
| 63 | 63 | #define FF_API_FILTERS_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 3) |
| 64 | 64 | #endif |
| 65 | +#ifndef FF_API_AVFILTERPAD_PUBLIC | |
| 66 | +#define FF_API_AVFILTERPAD_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 4) | |
| 67 | +#endif | |
| 68 | +#ifndef FF_API_FOO_COUNT | |
| 69 | +#define FF_API_FOO_COUNT (LIBAVFILTER_VERSION_MAJOR < 4) | |
| 70 | +#endif | |
| 65 | 71 | |
| 66 | 72 | #endif // AVFILTER_VERSION_H |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include "libavutil/mathematics.h" |
| 27 | 27 | #include "libavutil/parseutils.h" |
| 28 | 28 | #include "avfilter.h" |
| 29 | +#include "internal.h" | |
| 29 | 30 | #include "video.h" |
| 30 | 31 | |
| 31 | 32 | typedef struct { |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "avfilter.h" |
| 31 | 31 | #include "internal.h" |
| 32 | 32 | #include "formats.h" |
| 33 | +#include "internal.h" | |
| 33 | 34 | #include "video.h" |
| 34 | 35 | |
| 35 | 36 | typedef struct { |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "libavutil/pixdesc.h" |
| 31 | 31 | #include "avfilter.h" |
| 32 | 32 | #include "formats.h" |
| 33 | +#include "internal.h" | |
| 33 | 34 | #include "video.h" |
| 34 | 35 | |
| 35 | 36 | static const char *const var_names[] = { |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | */ |
| 23 | 23 | |
| 24 | 24 | #include "avfilter.h" |
| 25 | +#include "internal.h" | |
| 25 | 26 | #include "video.h" |
| 26 | 27 | |
| 27 | 28 | AVFilter avfilter_vf_copy = { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #include "avfilter.h" |
| 29 | 29 | #include "formats.h" |
| 30 | +#include "internal.h" | |
| 30 | 31 | #include "video.h" |
| 31 | 32 | #include "libavutil/eval.h" |
| 32 | 33 | #include "libavutil/avstring.h" |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include "libavutil/imgutils.h" |
| 27 | 27 | #include "avfilter.h" |
| 28 | 28 | #include "formats.h" |
| 29 | +#include "internal.h" | |
| 29 | 30 | #include "video.h" |
| 30 | 31 | |
| 31 | 32 | typedef struct { |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "libavutil/pixdesc.h" |
| 31 | 31 | #include "avfilter.h" |
| 32 | 32 | #include "formats.h" |
| 33 | +#include "internal.h" | |
| 33 | 34 | #include "video.h" |
| 34 | 35 | |
| 35 | 36 | /** |
| @@ -218,8 +219,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) · 182 unmodified lines | ||
| 218 | 219 | AVFilterBufferRef *outpicref; |
| 219 | 220 | |
| 220 | 221 | if (inpicref->perms & AV_PERM_PRESERVE) { |
| 221 | − outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 222 | − outlink->w, outlink->h); | |
| 222 | + outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 223 | + outlink->w, outlink->h); | |
| 223 | 224 | avfilter_copy_buffer_ref_props(outpicref, inpicref); |
| 224 | 225 | outpicref->video->w = outlink->w; |
| 225 | 226 | outpicref->video->h = outlink->h; |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "libavutil/parseutils.h" |
| 30 | 30 | #include "avfilter.h" |
| 31 | 31 | #include "formats.h" |
| 32 | +#include "internal.h" | |
| 32 | 33 | #include "video.h" |
| 33 | 34 | |
| 34 | 35 | enum { Y, U, V, A }; |
| @@ -42,6 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #include "avfilter.h" |
| 43 | 43 | #include "drawutils.h" |
| 44 | 44 | #include "formats.h" |
| 45 | +#include "internal.h" | |
| 45 | 46 | #include "video.h" |
| 46 | 47 | |
| 47 | 48 | #undef time |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #include "drawutils.h" |
| 34 | 34 | #include "internal.h" |
| 35 | 35 | #include "formats.h" |
| 36 | +#include "internal.h" | |
| 36 | 37 | #include "video.h" |
| 37 | 38 | |
| 38 | 39 | #define R 0 |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "libavutil/pixdesc.h" |
| 30 | 30 | #include "avfilter.h" |
| 31 | 31 | #include "formats.h" |
| 32 | +#include "internal.h" | |
| 32 | 33 | #include "video.h" |
| 33 | 34 | |
| 34 | 35 | typedef struct |
| @@ -112,7 +113,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int · 77 unmodified lines | ||
| 112 | 113 | AVFilterContext *ctx = inlink->dst; |
| 113 | 114 | AVFilterLink *outlink = ctx->outputs[0]; |
| 114 | 115 | |
| 115 | − return avfilter_get_video_buffer(outlink, perms, w, h); | |
| 116 | + return ff_get_video_buffer(outlink, perms, w, h); | |
| 116 | 117 | } |
| 117 | 118 | |
| 118 | 119 | static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include "avfilter.h" |
| 28 | 28 | #include "internal.h" |
| 29 | 29 | #include "formats.h" |
| 30 | +#include "internal.h" | |
| 30 | 31 | #include "video.h" |
| 31 | 32 | |
| 32 | 33 | typedef struct { |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "libavutil/parseutils.h" |
| 33 | 33 | #include "avfilter.h" |
| 34 | 34 | #include "formats.h" |
| 35 | +#include "internal.h" | |
| 35 | 36 | #include "video.h" |
| 36 | 37 | |
| 37 | 38 | typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height); |
| @@ -433,7 +434,7 @@ static int source_config_props(AVFilterLink *outlink) · 395 unmodified lines | ||
| 433 | 434 | static int source_request_frame(AVFilterLink *outlink) |
| 434 | 435 | { |
| 435 | 436 | Frei0rContext *frei0r = outlink->src->priv; |
| 436 | − AVFilterBufferRef *picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |
| 437 | + AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |
| 437 | 438 | picref->video->sample_aspect_ratio = (AVRational) {1, 1}; |
| 438 | 439 | picref->pts = frei0r->pts++; |
| 439 | 440 | picref->pos = -1; |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | #include "avfilter.h" |
| 39 | 39 | #include "formats.h" |
| 40 | 40 | #include "gradfun.h" |
| 41 | +#include "internal.h" | |
| 41 | 42 | #include "video.h" |
| 42 | 43 | |
| 43 | 44 | DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = { |
| @@ -190,7 +191,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) · 146 unmodified lines | ||
| 190 | 191 | AVFilterBufferRef *outpicref; |
| 191 | 192 | |
| 192 | 193 | if (inpicref->perms & AV_PERM_PRESERVE) { |
| 193 | − outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |
| 194 | + outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |
| 194 | 195 | avfilter_copy_buffer_ref_props(outpicref, inpicref); |
| 195 | 196 | outpicref->video->w = outlink->w; |
| 196 | 197 | outpicref->video->h = outlink->h; |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #include "avfilter.h" |
| 28 | 28 | #include "formats.h" |
| 29 | +#include "internal.h" | |
| 29 | 30 | #include "video.h" |
| 30 | 31 | #include "libavutil/pixdesc.h" |
| 31 | 32 | #include "libavutil/intreadwrite.h" |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "libavutil/pixdesc.h" |
| 29 | 29 | #include "avfilter.h" |
| 30 | 30 | #include "formats.h" |
| 31 | +#include "internal.h" | |
| 31 | 32 | #include "video.h" |
| 32 | 33 | |
| 33 | 34 | typedef struct { |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | */ |
| 23 | 23 | |
| 24 | 24 | #include "avfilter.h" |
| 25 | +#include "internal.h" | |
| 25 | 26 | #include "video.h" |
| 26 | 27 | |
| 27 | 28 | AVFilter avfilter_vf_null = { |
| @@ -303,7 +303,7 @@ static int config_output(AVFilterLink *outlink) · 302 unmodified lines | ||
| 303 | 303 | |
| 304 | 304 | static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w, int h) |
| 305 | 305 | { |
| 306 | − return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 306 | + return ff_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 307 | 307 | } |
| 308 | 308 | |
| 309 | 309 | // divide by 255 and round to nearest |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #include "avfilter.h" |
| 28 | 28 | #include "formats.h" |
| 29 | +#include "internal.h" | |
| 29 | 30 | #include "video.h" |
| 30 | 31 | #include "libavutil/avstring.h" |
| 31 | 32 | #include "libavutil/eval.h" |
| @@ -220,9 +221,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int · 188 unmodified lines | ||
| 220 | 221 | PadContext *pad = inlink->dst->priv; |
| 221 | 222 | int align = (perms&AV_PERM_ALIGN) ? AVFILTER_ALIGN : 1; |
| 222 | 223 | |
| 223 | − AVFilterBufferRef *picref = avfilter_get_video_buffer(inlink->dst->outputs[0], perms, | |
| 224 | − w + (pad->w - pad->in_w) + 4*align, | |
| 225 | − h + (pad->h - pad->in_h)); | |
| 224 | + AVFilterBufferRef *picref = ff_get_video_buffer(inlink->dst->outputs[0], perms, | |
| 225 | + w + (pad->w - pad->in_w) + 4*align, | |
| 226 | + h + (pad->h - pad->in_h)); | |
| 226 | 227 | int plane; |
| 227 | 228 | |
| 228 | 229 | picref->video->w = w; |
| @@ -287,9 +288,9 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) · 58 unmodified lines | ||
| 287 | 288 | if(pad->needs_copy){ |
| 288 | 289 | av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n"); |
| 289 | 290 | avfilter_unref_buffer(outpicref); |
| 290 | − outpicref = avfilter_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES, | |
| 291 | − FFMAX(inlink->w, pad->w), | |
| 292 | − FFMAX(inlink->h, pad->h)); | |
| 291 | + outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES, | |
| 292 | + FFMAX(inlink->w, pad->w), | |
| 293 | + FFMAX(inlink->h, pad->h)); | |
| 293 | 294 | avfilter_copy_buffer_ref_props(outpicref, inpicref); |
| 294 | 295 | } |
| 295 | 296 | |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "libavutil/pixdesc.h" |
| 27 | 27 | #include "avfilter.h" |
| 28 | +#include "internal.h" | |
| 28 | 29 | #include "video.h" |
| 29 | 30 | |
| 30 | 31 | typedef struct { |
| @@ -57,8 +58,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) · 26 unmodified lines | ||
| 57 | 58 | AVFilterBufferRef *outpicref; |
| 58 | 59 | int i; |
| 59 | 60 | |
| 60 | − outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 61 | − outlink->w, outlink->h); | |
| 61 | + outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 62 | + outlink->w, outlink->h); | |
| 62 | 63 | outpicref = outlink->out_buf; |
| 63 | 64 | avfilter_copy_buffer_ref_props(outpicref, picref); |
| 64 | 65 | |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "avfilter.h" |
| 27 | 27 | #include "formats.h" |
| 28 | +#include "internal.h" | |
| 28 | 29 | #include "video.h" |
| 29 | 30 | #include "libavutil/avstring.h" |
| 30 | 31 | #include "libavutil/eval.h" |
| @@ -302,7 +303,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) · 271 unmodified lines | ||
| 302 | 303 | scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; |
| 303 | 304 | scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; |
| 304 | 305 | |
| 305 | − outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h); | |
| 306 | + outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h); | |
| 306 | 307 | avfilter_copy_buffer_ref_props(outpicref, picref); |
| 307 | 308 | outpicref->video->w = outlink->w; |
| 308 | 309 | outpicref->video->h = outlink->h; |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "libavutil/eval.h" |
| 30 | 30 | #include "libavutil/mathematics.h" |
| 31 | 31 | #include "avfilter.h" |
| 32 | +#include "internal.h" | |
| 32 | 33 | #include "video.h" |
| 33 | 34 | |
| 34 | 35 | static const char *const var_names[] = { |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | */ |
| 25 | 25 | |
| 26 | 26 | #include "avfilter.h" |
| 27 | +#include "internal.h" | |
| 27 | 28 | #include "video.h" |
| 28 | 29 | #include "libavutil/pixdesc.h" |
| 29 | 30 | |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "libavutil/imgutils.h" |
| 31 | 31 | #include "avfilter.h" |
| 32 | 32 | #include "formats.h" |
| 33 | +#include "internal.h" | |
| 33 | 34 | #include "video.h" |
| 34 | 35 | |
| 35 | 36 | typedef struct { |
| @@ -117,8 +118,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) · 81 unmodified lines | ||
| 117 | 118 | { |
| 118 | 119 | AVFilterLink *outlink = inlink->dst->outputs[0]; |
| 119 | 120 | |
| 120 | − outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 121 | − outlink->w, outlink->h); | |
| 121 | + outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 122 | + outlink->w, outlink->h); | |
| 122 | 123 | outlink->out_buf->pts = picref->pts; |
| 123 | 124 | |
| 124 | 125 | if (picref->video->sample_aspect_ratio.num == 0) { |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | #include "avfilter.h" |
| 40 | 40 | #include "formats.h" |
| 41 | +#include "internal.h" | |
| 41 | 42 | #include "video.h" |
| 42 | 43 | #include "libavutil/common.h" |
| 43 | 44 | #include "libavutil/mem.h" |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "libavutil/pixdesc.h" |
| 27 | 27 | #include "avfilter.h" |
| 28 | +#include "internal.h" | |
| 28 | 29 | #include "video.h" |
| 29 | 30 | |
| 30 | 31 | typedef struct { |
| @@ -50,7 +51,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, · 19 unmodified lines | ||
| 50 | 51 | if (!(perms & AV_PERM_NEG_LINESIZES)) |
| 51 | 52 | return ff_default_get_video_buffer(link, perms, w, h); |
| 52 | 53 | |
| 53 | − picref = avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 54 | + picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 54 | 55 | for (i = 0; i < 4; i ++) { |
| 55 | 56 | int vsub = i == 1 || i == 2 ? flip->vsub : 0; |
| 56 | 57 | |
| @@ -207,8 +207,8 @@ static void return_frame(AVFilterContext *ctx, int is_second) · 206 unmodified lines | ||
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | if (is_second) { |
| 210 | − yadif->out = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE | | |
| 211 | − AV_PERM_REUSE, link->w, link->h); | |
| 210 | + yadif->out = ff_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE | | |
| 211 | + AV_PERM_REUSE, link->w, link->h); | |
| 212 | 212 | avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); |
| 213 | 213 | yadif->out->video->interlaced = 0; |
| 214 | 214 | } |
| @@ -269,8 +269,8 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) · 54 unmodified lines | ||
| 269 | 269 | if (!yadif->prev) |
| 270 | 270 | yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); |
| 271 | 271 | |
| 272 | − yadif->out = avfilter_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE | | |
| 273 | − AV_PERM_REUSE, link->w, link->h); | |
| 272 | + yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE | | |
| 273 | + AV_PERM_REUSE, link->w, link->h); | |
| 274 | 274 | |
| 275 | 275 | avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); |
| 276 | 276 | yadif->out->video->interlaced = 0; |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h) |
| 30 | 30 | { |
| 31 | − return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 31 | + return ff_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | AVFilterBufferRef *ff_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h) |
| @@ -127,7 +127,7 @@ fail: · 92 unmodified lines | ||
| 127 | 127 | return NULL; |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | −AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) | |
| 130 | +AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h) | |
| 131 | 131 | { |
| 132 | 132 | AVFilterBufferRef *ret = NULL; |
| 133 | 133 | |
| @@ -158,11 +158,11 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) · 24 unmodified lines | ||
| 158 | 158 | { |
| 159 | 159 | AVFilterLink *outlink = NULL; |
| 160 | 160 | |
| 161 | − if (inlink->dst->output_count) | |
| 161 | + if (inlink->dst->nb_outputs) | |
| 162 | 162 | outlink = inlink->dst->outputs[0]; |
| 163 | 163 | |
| 164 | 164 | if (outlink) { |
| 165 | − outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |
| 165 | + outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); | |
| 166 | 166 | avfilter_copy_buffer_ref_props(outlink->out_buf, picref); |
| 167 | 167 | ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); |
| 168 | 168 | } |
| @@ -191,7 +191,7 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) · 22 unmodified lines | ||
| 191 | 191 | picref->perms, |
| 192 | 192 | link->dstpad->min_perms, link->dstpad->rej_perms); |
| 193 | 193 | |
| 194 | − link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h); | |
| 194 | + link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h); | |
| 195 | 195 | link->src_buf = picref; |
| 196 | 196 | avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf); |
| 197 | 197 | |
| @@ -230,7 +230,7 @@ static void default_end_frame(AVFilterLink *inlink) · 32 unmodified lines | ||
| 230 | 230 | { |
| 231 | 231 | AVFilterLink *outlink = NULL; |
| 232 | 232 | |
| 233 | − if (inlink->dst->output_count) | |
| 233 | + if (inlink->dst->nb_outputs) | |
| 234 | 234 | outlink = inlink->dst->outputs[0]; |
| 235 | 235 | |
| 236 | 236 | avfilter_unref_buffer(inlink->cur_buf); |
| @@ -271,7 +271,7 @@ static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir · 34 unmodified lines | ||
| 271 | 271 | { |
| 272 | 272 | AVFilterLink *outlink = NULL; |
| 273 | 273 | |
| 274 | − if (inlink->dst->output_count) | |
| 274 | + if (inlink->dst->nb_outputs) | |
| 275 | 275 | outlink = inlink->dst->outputs[0]; |
| 276 | 276 | |
| 277 | 277 | if (outlink) |
| @@ -364,4 +364,8 @@ void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) · 86 unmodified lines | ||
| 364 | 364 | { |
| 365 | 365 | ff_draw_slice(link, y, h, slice_dir); |
| 366 | 366 | } |
| 367 | +AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) | |
| 368 | +{ | |
| 369 | + return ff_get_video_buffer(link, perms, w, h); | |
| 370 | +} | |
| 367 | 371 | #endif |
| @@ -28,6 +28,19 @@ AVFilterBufferRef *ff_default_get_video_buffer(AVFilterLink *link, · 27 unmodified lines | ||
| 28 | 28 | int perms, int w, int h); |
| 29 | 29 | AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h); |
| 30 | 30 | |
| 31 | +/** | |
| 32 | + * Request a picture buffer with a specific set of permissions. | |
| 33 | + * | |
| 34 | + * @param link the output link to the filter from which the buffer will | |
| 35 | + * be requested | |
| 36 | + * @param perms the required access permissions | |
| 37 | + * @param w the minimum width of the buffer to allocate | |
| 38 | + * @param h the minimum height of the buffer to allocate | |
| 39 | + * @return A reference to the buffer. This must be unreferenced with | |
| 40 | + * avfilter_unref_buffer when you are finished with it. | |
| 41 | + */ | |
| 42 | +AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, | |
| 43 | + int w, int h); | |
| 31 | 44 | |
| 32 | 45 | void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); |
| 33 | 46 | void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | #include "avfilter.h" |
| 20 | +#include "internal.h" | |
| 20 | 21 | |
| 21 | 22 | static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
| 22 | 23 | { |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "avfilter.h" |
| 27 | 27 | #include "formats.h" |
| 28 | +#include "internal.h" | |
| 28 | 29 | #include "video.h" |
| 29 | 30 | #include "libavutil/pixdesc.h" |
| 30 | 31 | #include "libavutil/colorspace.h" |
| @@ -105,7 +106,7 @@ static int color_config_props(AVFilterLink *inlink) · 74 unmodified lines | ||
| 105 | 106 | static int color_request_frame(AVFilterLink *link) |
| 106 | 107 | { |
| 107 | 108 | ColorContext *color = link->src->priv; |
| 108 | − AVFilterBufferRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); | |
| 109 | + AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); | |
| 109 | 110 | picref->video->sample_aspect_ratio = (AVRational) {1, 1}; |
| 110 | 111 | picref->pts = color->pts++; |
| 111 | 112 | picref->pos = -1; |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include "libavutil/parseutils.h" |
| 38 | 38 | #include "avfilter.h" |
| 39 | 39 | #include "formats.h" |
| 40 | +#include "internal.h" | |
| 40 | 41 | #include "video.h" |
| 41 | 42 | |
| 42 | 43 | typedef struct { |
| @@ -137,8 +138,7 @@ static int request_frame(AVFilterLink *outlink) · 94 unmodified lines | ||
| 137 | 138 | |
| 138 | 139 | if (test->max_pts >= 0 && test->pts >= test->max_pts) |
| 139 | 140 | return AVERROR_EOF; |
| 140 | − picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, | |
| 141 | − test->w, test->h); | |
| 141 | + picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h); | |
| 142 | 142 | picref->pts = test->pts++; |
| 143 | 143 | picref->pos = -1; |
| 144 | 144 | picref->video->key_frame = 1; |
| @@ -88,6 +88,8 @@ typedef struct RTMPContext { · 87 unmodified lines | ||
| 88 | 88 | char* tcurl; ///< url of the target stream |
| 89 | 89 | char* flashver; ///< version of the flash plugin |
| 90 | 90 | char* swfurl; ///< url of the swf player |
| 91 | + int server_bw; ///< server bandwidth | |
| 92 | + int client_buffer_time; ///< client buffer time in ms | |
| 91 | 93 | } RTMPContext; |
| 92 | 94 | |
| 93 | 95 | #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing |
| @@ -115,7 +117,7 @@ static const uint8_t rtmp_server_key[] = { · 21 unmodified lines | ||
| 115 | 117 | |
| 116 | 118 | static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p) |
| 117 | 119 | { |
| 118 | − char *field, *value, *saveptr; | |
| 120 | + char *field, *value; | |
| 119 | 121 | char type; |
| 120 | 122 | |
| 121 | 123 | /* The type must be B for Boolean, N for number, S for string, O for |
| @@ -130,8 +132,12 @@ static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p) · 8 unmodified lines | ||
| 130 | 132 | value = param + 2; |
| 131 | 133 | } else if (param[0] == 'N' && param[1] && param[2] == ':') { |
| 132 | 134 | type = param[1]; |
| 133 | − field = av_strtok(param + 3, ":", &saveptr); | |
| 134 | − value = av_strtok(NULL, ":", &saveptr); | |
| 135 | + field = param + 3; | |
| 136 | + value = strchr(field, ':'); | |
| 137 | + if (!value) | |
| 138 | + goto fail; | |
| 139 | + *value = '\0'; | |
| 140 | + value++; | |
| 135 | 141 | |
| 136 | 142 | if (!field || !value) |
| 137 | 143 | goto fail; |
| @@ -226,18 +232,27 @@ static int gen_connect(URLContext *s, RTMPContext *rt) · 88 unmodified lines | ||
| 226 | 232 | ff_amf_write_object_end(&p); |
| 227 | 233 | |
| 228 | 234 | if (rt->conn) { |
| 229 | − char *param, *saveptr; | |
| 235 | + char *param = rt->conn; | |
| 230 | 236 | |
| 231 | 237 | // Write arbitrary AMF data to the Connect message. |
| 232 | − param = av_strtok(rt->conn, " ", &saveptr); | |
| 233 | 238 | while (param != NULL) { |
| 239 | + char *sep; | |
| 240 | + param += strspn(param, " "); | |
| 241 | + if (!*param) | |
| 242 | + break; | |
| 243 | + sep = strchr(param, ' '); | |
| 244 | + if (sep) | |
| 245 | + *sep = '\0'; | |
| 234 | 246 | if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) { |
| 235 | 247 | // Invalid AMF parameter. |
| 236 | 248 | ff_rtmp_packet_destroy(&pkt); |
| 237 | 249 | return ret; |
| 238 | 250 | } |
| 239 | 251 | |
| 240 | − param = av_strtok(NULL, " ", &saveptr); | |
| 252 | + if (sep) | |
| 253 | + param = sep + 1; | |
| 254 | + else | |
| 255 | + break; | |
| 241 | 256 | } |
| 242 | 257 | } |
| 243 | 258 | |
| @@ -393,6 +408,31 @@ static int gen_delete_stream(URLContext *s, RTMPContext *rt) · 149 unmodified lines | ||
| 393 | 408 | return ret; |
| 394 | 409 | } |
| 395 | 410 | |
| 411 | +/** | |
| 412 | + * Generate client buffer time and send it to the server. | |
| 413 | + */ | |
| 414 | +static int gen_buffer_time(URLContext *s, RTMPContext *rt) | |
| 415 | +{ | |
| 416 | + RTMPPacket pkt; | |
| 417 | + uint8_t *p; | |
| 418 | + int ret; | |
| 419 | + | |
| 420 | + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, | |
| 421 | + 1, 10)) < 0) | |
| 422 | + return ret; | |
| 423 | + | |
| 424 | + p = pkt.data; | |
| 425 | + bytestream_put_be16(&p, 3); | |
| 426 | + bytestream_put_be32(&p, rt->main_channel_id); | |
| 427 | + bytestream_put_be32(&p, rt->client_buffer_time); | |
| 428 | + | |
| 429 | + ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, | |
| 430 | + rt->prev_pkt[1]); | |
| 431 | + ff_rtmp_packet_destroy(&pkt); | |
| 432 | + | |
| 433 | + return ret; | |
| 434 | +} | |
| 435 | + | |
| 396 | 436 | /** |
| 397 | 437 | * Generate 'play' call and send it to the server, then ping the server |
| 398 | 438 | * to start actual playing. |
| @@ -422,23 +462,6 @@ static int gen_play(URLContext *s, RTMPContext *rt) · 23 unmodified lines | ||
| 422 | 462 | rt->prev_pkt[1]); |
| 423 | 463 | ff_rtmp_packet_destroy(&pkt); |
| 424 | 464 | |
| 425 | − if (ret < 0) | |
| 426 | − return ret; | |
| 427 | − | |
| 428 | − // set client buffer time disguised in ping packet | |
| 429 | − if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, | |
| 430 | − 1, 10)) < 0) | |
| 431 | − return ret; | |
| 432 | − | |
| 433 | − p = pkt.data; | |
| 434 | − bytestream_put_be16(&p, 3); | |
| 435 | − bytestream_put_be32(&p, 1); | |
| 436 | − bytestream_put_be32(&p, 256); //TODO: what is a good value here? | |
| 437 | − | |
| 438 | − ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, | |
| 439 | − rt->prev_pkt[1]); | |
| 440 | − ff_rtmp_packet_destroy(&pkt); | |
| 441 | − | |
| 442 | 465 | return ret; |
| 443 | 466 | } |
| 444 | 467 | |
| @@ -510,7 +533,7 @@ static int gen_server_bw(URLContext *s, RTMPContext *rt) · 65 unmodified lines | ||
| 510 | 533 | return ret; |
| 511 | 534 | |
| 512 | 535 | p = pkt.data; |
| 513 | − bytestream_put_be32(&p, 2500000); | |
| 536 | + bytestream_put_be32(&p, rt->server_bw); | |
| 514 | 537 | ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, |
| 515 | 538 | rt->prev_pkt[1]); |
| 516 | 539 | ff_rtmp_packet_destroy(&pkt); |
| @@ -838,6 +861,14 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) · 321 unmodified lines | ||
| 838 | 861 | av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data)); |
| 839 | 862 | rt->client_report_size = AV_RB32(pkt->data) >> 1; |
| 840 | 863 | break; |
| 864 | + case RTMP_PT_SERVER_BW: | |
| 865 | + rt->server_bw = AV_RB32(pkt->data); | |
| 866 | + if (rt->server_bw <= 0) { | |
| 867 | + av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n", rt->server_bw); | |
| 868 | + return AVERROR(EINVAL); | |
| 869 | + } | |
| 870 | + av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw); | |
| 871 | + break; | |
| 841 | 872 | case RTMP_PT_INVOKE: |
| 842 | 873 | //TODO: check for the messages sent for wrong state? |
| 843 | 874 | if (!memcmp(pkt->data, "\002\000\006_error", 9)) { |
| @@ -888,6 +919,8 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) · 44 unmodified lines | ||
| 888 | 919 | if (rt->is_input) { |
| 889 | 920 | if ((ret = gen_play(s, rt)) < 0) |
| 890 | 921 | return ret; |
| 922 | + if ((ret = gen_buffer_time(s, rt)) < 0) | |
| 923 | + return ret; | |
| 891 | 924 | } else { |
| 892 | 925 | if ((ret = gen_publish(s, rt)) < 0) |
| 893 | 926 | return ret; |
| @@ -924,6 +957,9 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) · 30 unmodified lines | ||
| 924 | 957 | return ret; |
| 925 | 958 | } |
| 926 | 959 | break; |
| 960 | + default: | |
| 961 | + av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type); | |
| 962 | + break; | |
| 927 | 963 | } |
| 928 | 964 | return 0; |
| 929 | 965 | } |
| @@ -1182,6 +1218,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) · 252 unmodified lines | ||
| 1182 | 1218 | rt->client_report_size = 1048576; |
| 1183 | 1219 | rt->bytes_read = 0; |
| 1184 | 1220 | rt->last_bytes_read = 0; |
| 1221 | + rt->server_bw = 2500000; | |
| 1185 | 1222 | |
| 1186 | 1223 | av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", |
| 1187 | 1224 | proto, path, rt->app, rt->playpath); |
| @@ -1328,6 +1365,7 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) · 140 unmodified lines | ||
| 1328 | 1365 | |
| 1329 | 1366 | static const AVOption rtmp_options[] = { |
| 1330 | 1367 | {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, |
| 1368 | + {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC}, | |
| 1331 | 1369 | {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, |
| 1332 | 1370 | {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, |
| 1333 | 1371 | {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"}, |
| @@ -677,80 +677,120 @@ static void planar_rgb_to_y(uint16_t *dst, const uint8_t *src[4], int width) · 676 unmodified lines | ||
| 677 | 677 | } |
| 678 | 678 | } |
| 679 | 679 | |
| 680 | −static void planar_rgb16le_to_y(uint8_t *_dst, const uint8_t *_src[4], int width) | |
| 680 | +static void planar_rgb_to_uv(uint16_t *dstU, uint16_t *dstV, const uint8_t *src[4], int width) | |
| 681 | 681 | { |
| 682 | 682 | int i; |
| 683 | − const uint16_t **src = (const uint16_t **)_src; | |
| 684 | − uint16_t *dst = (uint16_t *)_dst; | |
| 685 | 683 | for (i = 0; i < width; i++) { |
| 686 | − int g = AV_RL16(src[0] + i); | |
| 687 | − int b = AV_RL16(src[1] + i); | |
| 688 | − int r = AV_RL16(src[2] + i); | |
| 684 | + int g = src[0][i]; | |
| 685 | + int b = src[1][i]; | |
| 686 | + int r = src[2][i]; | |
| 689 | 687 | |
| 690 | − dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT); | |
| 688 | + dstU[i] = (RU*r + GU*g + BU*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); | |
| 689 | + dstV[i] = (RV*r + GV*g + BV*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); | |
| 691 | 690 | } |
| 692 | 691 | } |
| 693 | 692 | |
| 694 | −static void planar_rgb16be_to_y(uint8_t *_dst, const uint8_t *_src[4], int width) | |
| 693 | +#define rdpx(src) \ | |
| 694 | + is_be ? AV_RB16(src) : AV_RL16(src) | |
| 695 | +static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_src[4], | |
| 696 | + int width, int bpc, int is_be) | |
| 695 | 697 | { |
| 696 | 698 | int i; |
| 697 | 699 | const uint16_t **src = (const uint16_t **)_src; |
| 698 | 700 | uint16_t *dst = (uint16_t *)_dst; |
| 699 | 701 | for (i = 0; i < width; i++) { |
| 700 | − int g = AV_RB16(src[0] + i); | |
| 701 | − int b = AV_RB16(src[1] + i); | |
| 702 | − int r = AV_RB16(src[2] + i); | |
| 702 | + int g = rdpx(src[0] + i); | |
| 703 | + int b = rdpx(src[1] + i); | |
| 704 | + int r = rdpx(src[2] + i); | |
| 703 | 705 | |
| 704 | − dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT); | |
| 706 | + dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT); | |
| 705 | 707 | } |
| 706 | 708 | } |
| 707 | 709 | |
| 708 | −static void planar_rgb_to_uv(uint16_t *dstU, uint16_t *dstV, const uint8_t *src[4], int width) | |
| 710 | +static void planar_rgb9le_to_y(uint8_t *dst, const uint8_t *src[4], int w) | |
| 709 | 711 | { |
| 710 | − int i; | |
| 711 | − for (i = 0; i < width; i++) { | |
| 712 | − int g = src[0][i]; | |
| 713 | − int b = src[1][i]; | |
| 714 | − int r = src[2][i]; | |
| 712 | + planar_rgb16_to_y(dst, src, w, 9, 0); | |
| 713 | +} | |
| 715 | 714 | |
| 716 | − dstU[i] = (RU*r + GU*g + BU*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); | |
| 717 | − dstV[i] = (RV*r + GV*g + BV*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); | |
| 718 | − } | |
| 715 | +static void planar_rgb9be_to_y(uint8_t *dst, const uint8_t *src[4], int w) | |
| 716 | +{ | |
| 717 | + planar_rgb16_to_y(dst, src, w, 9, 1); | |
| 719 | 718 | } |
| 720 | 719 | |
| 721 | −static void planar_rgb16le_to_uv(uint8_t *_dstU, uint8_t *_dstV, | |
| 722 | − const uint8_t *_src[4], int width) | |
| 720 | +static void planar_rgb10le_to_y(uint8_t *dst, const uint8_t *src[4], int w) | |
| 723 | 721 | { |
| 724 | − int i; | |
| 725 | − const uint16_t **src = (const uint16_t **)_src; | |
| 726 | − uint16_t *dstU = (uint16_t *)_dstU; | |
| 727 | − uint16_t *dstV = (uint16_t *)_dstV; | |
| 728 | − for (i = 0; i < width; i++) { | |
| 729 | − int g = AV_RL16(src[0] + i); | |
| 730 | − int b = AV_RL16(src[1] + i); | |
| 731 | − int r = AV_RL16(src[2] + i); | |
| 722 | + planar_rgb16_to_y(dst, src, w, 10, 0); | |
| 723 | +} | |
| 732 | 724 | |
| 733 | − dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); | |
| 734 | − dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); | |
| 735 | − } | |
| 725 | +static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w) | |
| 726 | +{ | |
| 727 | + planar_rgb16_to_y(dst, src, w, 10, 1); | |
| 728 | +} | |
| 729 | + | |
| 730 | +static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w) | |
| 731 | +{ | |
| 732 | + planar_rgb16_to_y(dst, src, w, 16, 0); | |
| 736 | 733 | } |
| 737 | 734 | |
| 738 | −static void planar_rgb16be_to_uv(uint8_t *_dstU, uint8_t *_dstV, | |
| 739 | − const uint8_t *_src[4], int width) | |
| 735 | +static void planar_rgb16be_to_y(uint8_t *dst, const uint8_t *src[4], int w) | |
| 736 | +{ | |
| 737 | + planar_rgb16_to_y(dst, src, w, 16, 1); | |
| 738 | +} | |
| 739 | + | |
| 740 | +static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV, | |
| 741 | + const uint8_t *_src[4], int width, | |
| 742 | + int bpc, int is_be) | |
| 740 | 743 | { |
| 741 | 744 | int i; |
| 742 | 745 | const uint16_t **src = (const uint16_t **)_src; |
| 743 | 746 | uint16_t *dstU = (uint16_t *)_dstU; |
| 744 | 747 | uint16_t *dstV = (uint16_t *)_dstV; |
| 745 | 748 | for (i = 0; i < width; i++) { |
| 746 | − int g = AV_RB16(src[0] + i); | |
| 747 | − int b = AV_RB16(src[1] + i); | |
| 748 | − int r = AV_RB16(src[2] + i); | |
| 749 | + int g = rdpx(src[0] + i); | |
| 750 | + int b = rdpx(src[1] + i); | |
| 751 | + int r = rdpx(src[2] + i); | |
| 749 | 752 | |
| 750 | − dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); | |
| 751 | − dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); | |
| 753 | + dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT; | |
| 754 | + dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT; | |
| 752 | 755 | } |
| 753 | 756 | } |
| 757 | +#undef rdpx | |
| 758 | + | |
| 759 | +static void planar_rgb9le_to_uv(uint8_t *dstU, uint8_t *dstV, | |
| 760 | + const uint8_t *src[4], int w) | |
| 761 | +{ | |
| 762 | + planar_rgb16_to_uv(dstU, dstV, src, w, 9, 0); | |
| 763 | +} | |
| 764 | + | |
| 765 | +static void planar_rgb9be_to_uv(uint8_t *dstU, uint8_t *dstV, | |
| 766 | + const uint8_t *src[4], int w) | |
| 767 | +{ | |
| 768 | + planar_rgb16_to_uv(dstU, dstV, src, w, 9, 1); | |
| 769 | +} | |
| 770 | + | |
| 771 | +static void planar_rgb10le_to_uv(uint8_t *dstU, uint8_t *dstV, | |
| 772 | + const uint8_t *src[4], int w) | |
| 773 | +{ | |
| 774 | + planar_rgb16_to_uv(dstU, dstV, src, w, 10, 0); | |
| 775 | +} | |
| 776 | + | |
| 777 | +static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV, | |
| 778 | + const uint8_t *src[4], int w) | |
| 779 | +{ | |
| 780 | + planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1); | |
| 781 | +} | |
| 782 | + | |
| 783 | +static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV, | |
| 784 | + const uint8_t *src[4], int w) | |
| 785 | +{ | |
| 786 | + planar_rgb16_to_uv(dstU, dstV, src, w, 16, 0); | |
| 787 | +} | |
| 788 | + | |
| 789 | +static void planar_rgb16be_to_uv(uint8_t *dstU, uint8_t *dstV, | |
| 790 | + const uint8_t *src[4], int w) | |
| 791 | +{ | |
| 792 | + planar_rgb16_to_uv(dstU, dstV, src, w, 16, 1); | |
| 793 | +} | |
| 754 | 794 | |
| 755 | 795 | av_cold void ff_sws_init_input_funcs(SwsContext *c) |
| 756 | 796 | { |
| @@ -778,12 +818,20 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) · 21 unmodified lines | ||
| 778 | 818 | c->chrToYV12 = palToUV_c; |
| 779 | 819 | break; |
| 780 | 820 | case PIX_FMT_GBRP9LE: |
| 821 | + c->readChrPlanar = planar_rgb9le_to_uv; | |
| 822 | + break; | |
| 781 | 823 | case PIX_FMT_GBRP10LE: |
| 824 | + c->readChrPlanar = planar_rgb10le_to_uv; | |
| 825 | + break; | |
| 782 | 826 | case PIX_FMT_GBRP16LE: |
| 783 | 827 | c->readChrPlanar = planar_rgb16le_to_uv; |
| 784 | 828 | break; |
| 785 | 829 | case PIX_FMT_GBRP9BE: |
| 830 | + c->readChrPlanar = planar_rgb9be_to_uv; | |
| 831 | + break; | |
| 786 | 832 | case PIX_FMT_GBRP10BE: |
| 833 | + c->readChrPlanar = planar_rgb10be_to_uv; | |
| 834 | + break; | |
| 787 | 835 | case PIX_FMT_GBRP16BE: |
| 788 | 836 | c->readChrPlanar = planar_rgb16be_to_uv; |
| 789 | 837 | break; |
| @@ -975,12 +1023,20 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) · 185 unmodified lines | ||
| 975 | 1023 | c->alpToYV12 = NULL; |
| 976 | 1024 | switch (srcFormat) { |
| 977 | 1025 | case PIX_FMT_GBRP9LE: |
| 1026 | + c->readLumPlanar = planar_rgb9le_to_y; | |
| 1027 | + break; | |
| 978 | 1028 | case PIX_FMT_GBRP10LE: |
| 1029 | + c->readLumPlanar = planar_rgb10le_to_y; | |
| 1030 | + break; | |
| 979 | 1031 | case PIX_FMT_GBRP16LE: |
| 980 | 1032 | c->readLumPlanar = planar_rgb16le_to_y; |
| 981 | 1033 | break; |
| 982 | 1034 | case PIX_FMT_GBRP9BE: |
| 1035 | + c->readLumPlanar = planar_rgb9be_to_y; | |
| 1036 | + break; | |
| 983 | 1037 | case PIX_FMT_GBRP10BE: |
| 1038 | + c->readLumPlanar = planar_rgb10be_to_y; | |
| 1039 | + break; | |
| 984 | 1040 | case PIX_FMT_GBRP16BE: |
| 985 | 1041 | c->readLumPlanar = planar_rgb16be_to_y; |
| 986 | 1042 | break; |
| @@ -148,7 +148,7 @@ fate-list: · 147 unmodified lines | ||
| 148 | 148 | clean:: testclean |
| 149 | 149 | |
| 150 | 150 | testclean: |
| 151 | − $(RM) -r tests/vsynth1 tests/vsynth2 tests/data tools/lavfi-showfiltfmts$(EXESUF) | |
| 151 | + $(RM) -r tests/vsynth1 tests/data tools/lavfi-showfiltfmts$(EXESUF) | |
| 152 | 152 | $(RM) $(CLEANSUFFIXES:%=tests/%) |
| 153 | 153 | $(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF)) |
| 154 | 154 | |