* qatar/master: (23 commits) build: cosmetics: Reorder some lists in a more logical fashion x86: pngdsp: Fix assembly for OS/2 fate: add test for RTjpeg in nuv with frameheader rtmp: send check_bw as notification g723_1: clip argument for 15-bit version of normalize_bits() g723_1: use all LPC vectors in formant postfilter id3v2: Support v2.2 PIC avplay: fix build with lavfi disabled. avconv: split configuring filter configuration to a separate file. avconv: split option parsing into a separate file. mpc8: do not leave padding after last frame in buffer for the next decode call mpegaudioenc: list supported channel layouts. mpegaudiodec: don't print an error on > 1 frame in a packet. api-example: update to new audio encoding API. configure: add --enable/disable-random option doc: cygwin: Update list of FATE package requirements build: Remove all installed headers and header directories on uninstall build: change checkheaders to use regular build rules rtmp: Add a new option 'rtmp_subscribe' rtmp: Add support for subscribing live streams ... Conflicts: Makefile common.mak configure doc/examples/decoding_encoding.c ffmpeg.c libavcodec/g723_1.c libavcodec/mpegaudiodec.c libavcodec/x86/pngdsp.asm libavformat/version.h library.mak tests/fate/video.mak Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.0
| @@ -4,7 +4,7 @@ | |||||
| *.def | *.def | ||||
| *.dll | *.dll | ||||
| *.exe | *.exe | ||||
| *.ho | |||||
| *.h.c | |||||
| *.lib | *.lib | ||||
| *.pc | *.pc | ||||
| *.so | *.so | ||||
| @@ -18,6 +18,7 @@ PROGS-$(CONFIG_FFSERVER) += ffserver | |||||
| PROGS := $(PROGS-yes:%=%$(EXESUF)) | PROGS := $(PROGS-yes:%=%$(EXESUF)) | ||||
| INSTPROGS = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF)) | INSTPROGS = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF)) | ||||
| OBJS = cmdutils.o | OBJS = cmdutils.o | ||||
| OBJS-ffmpeg = ffmpeg_opt.o ffmpeg_filter.o | |||||
| TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64 | TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64 | ||||
| HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options | HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options | ||||
| TOOLS = qt-faststart trasher | TOOLS = qt-faststart trasher | ||||
| @@ -68,8 +69,9 @@ config.h: .config | |||||
| SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \ | SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \ | ||||
| ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \ | ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \ | ||||
| ALTIVEC-OBJS ARMV5TE-OBJS ARMV6-OBJS ARMVFP-OBJS MMI-OBJS \ | |||||
| MMX-OBJS NEON-OBJS VIS-OBJS YASM-OBJS \ | |||||
| ARMV5TE-OBJS ARMV6-OBJS ARMVFP-OBJS NEON-OBJS \ | |||||
| MMI-OBJS ALTIVEC-OBJS VIS-OBJS \ | |||||
| MMX-OBJS YASM-OBJS \ | |||||
| MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS \ | MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS \ | ||||
| OBJS TESTOBJS | OBJS TESTOBJS | ||||
| @@ -10,8 +10,9 @@ ifndef SUBDIR | |||||
| ifndef V | ifndef V | ||||
| Q = @ | Q = @ | ||||
| ECHO = printf "$(1)\t%s\n" $(2) | ECHO = printf "$(1)\t%s\n" $(2) | ||||
| BRIEF = CC CXX AS YASM AR LD HOSTCC STRIP CP | |||||
| SILENT = DEPCC DEPAS DEPHOSTCC DEPYASM RM RANLIB | |||||
| BRIEF = CC CXX HOSTCC AS YASM AR LD STRIP CP | |||||
| SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM | |||||
| MSG = $@ | MSG = $@ | ||||
| M = @$(call ECHO,$(TAG),$@); | M = @$(call ECHO,$(TAG),$@); | ||||
| $(foreach VAR,$(BRIEF), \ | $(foreach VAR,$(BRIEF), \ | ||||
| @@ -98,8 +99,9 @@ DEP_LIBS := $(foreach NAME,$(FFLIBS),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME) | |||||
| ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h)) | ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h)) | ||||
| SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-) | SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-) | ||||
| SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%) | SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%) | ||||
| HEADEROBJS := $(filter-out $(SKIPHEADERS:.h=.ho),$(ALLHEADERS:.h=.ho)) | |||||
| checkheaders: $(HEADEROBJS) | |||||
| HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o)) | |||||
| checkheaders: $(HOBJS) | |||||
| .SECONDARY: $(HOBJS:.o=.c) | |||||
| alltools: $(TOOLS) | alltools: $(TOOLS) | ||||
| @@ -117,8 +119,8 @@ $(TOOLOBJS): | tools | |||||
| OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS) $(HEADEROBJS)) | OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS) $(HEADEROBJS)) | ||||
| CLEANSUFFIXES = *.d *.o *~ *.ho *.map *.ver *.gcno *.gcda | |||||
| CLEANSUFFIXES = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda | |||||
| DISTCLEANSUFFIXES = *.pc | DISTCLEANSUFFIXES = *.pc | ||||
| LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a | LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a | ||||
| -include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d)) | |||||
| -include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d)) | |||||
| @@ -1211,6 +1211,7 @@ HAVE_LIST=" | |||||
| alsa_asoundlib_h | alsa_asoundlib_h | ||||
| altivec_h | altivec_h | ||||
| arpa_inet_h | arpa_inet_h | ||||
| asm_mod_q | |||||
| asm_mod_y | asm_mod_y | ||||
| asm_types_h | asm_types_h | ||||
| attribute_may_alias | attribute_may_alias | ||||
| @@ -3119,6 +3120,7 @@ EOF | |||||
| enabled neon && check_asm neon '"vadd.i16 q0, q0, q0"' | enabled neon && check_asm neon '"vadd.i16 q0, q0, q0"' | ||||
| enabled vfpv3 && check_asm vfpv3 '"vmov.f32 s0, #1.0"' | enabled vfpv3 && check_asm vfpv3 '"vmov.f32 s0, #1.0"' | ||||
| check_asm asm_mod_q '"add r0, %Q0, %R0" :: "r"((long long)0)' | |||||
| check_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' | check_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' | ||||
| enabled_all armv6t2 shared !pic && enable_pic | enabled_all armv6t2 shared !pic && enable_pic | ||||
| @@ -34,6 +34,7 @@ | |||||
| #include <libavutil/imgutils.h> | #include <libavutil/imgutils.h> | ||||
| #include <libavutil/opt.h> | #include <libavutil/opt.h> | ||||
| #include <libavcodec/avcodec.h> | #include <libavcodec/avcodec.h> | ||||
| #include <libavutil/audioconvert.h> | |||||
| #include <libavutil/mathematics.h> | #include <libavutil/mathematics.h> | ||||
| #include <libavutil/samplefmt.h> | #include <libavutil/samplefmt.h> | ||||
| @@ -41,6 +42,59 @@ | |||||
| #define AUDIO_INBUF_SIZE 20480 | #define AUDIO_INBUF_SIZE 20480 | ||||
| #define AUDIO_REFILL_THRESH 4096 | #define AUDIO_REFILL_THRESH 4096 | ||||
| /* check that a given sample format is supported by the encoder */ | |||||
| static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) | |||||
| { | |||||
| const enum AVSampleFormat *p = codec->sample_fmts; | |||||
| while (*p != AV_SAMPLE_FMT_NONE) { | |||||
| if (*p == sample_fmt) | |||||
| return 1; | |||||
| p++; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| /* just pick the highest supported samplerate */ | |||||
| static int select_sample_rate(AVCodec *codec) | |||||
| { | |||||
| const int *p; | |||||
| int best_samplerate = 0; | |||||
| if (!codec->supported_samplerates) | |||||
| return 44100; | |||||
| p = codec->supported_samplerates; | |||||
| while (*p) { | |||||
| best_samplerate = FFMAX(*p, best_samplerate); | |||||
| p++; | |||||
| } | |||||
| return best_samplerate; | |||||
| } | |||||
| /* select layout with the highest channel count */ | |||||
| static int select_channel_layout(AVCodec *codec) | |||||
| { | |||||
| const uint64_t *p; | |||||
| uint64_t best_ch_layout = 0; | |||||
| int best_nb_channells = 0; | |||||
| if (!codec->channel_layouts) | |||||
| return AV_CH_LAYOUT_STEREO; | |||||
| p = codec->channel_layouts; | |||||
| while (*p) { | |||||
| int nb_channels = av_get_channel_layout_nb_channels(*p); | |||||
| if (nb_channels > best_nb_channells) { | |||||
| best_ch_layout = *p; | |||||
| best_nb_channells = nb_channels; | |||||
| } | |||||
| p++; | |||||
| } | |||||
| return best_ch_layout; | |||||
| } | |||||
| /* | /* | ||||
| * Audio encoding example | * Audio encoding example | ||||
| */ | */ | ||||
| @@ -48,11 +102,13 @@ static void audio_encode_example(const char *filename) | |||||
| { | { | ||||
| AVCodec *codec; | AVCodec *codec; | ||||
| AVCodecContext *c= NULL; | AVCodecContext *c= NULL; | ||||
| int frame_size, i, j, out_size, outbuf_size; | |||||
| AVFrame *frame; | |||||
| AVPacket pkt; | |||||
| int i, j, k, ret, got_output; | |||||
| int buffer_size; | |||||
| FILE *f; | FILE *f; | ||||
| short *samples; | |||||
| uint16_t *samples; | |||||
| float t, tincr; | float t, tincr; | ||||
| uint8_t *outbuf; | |||||
| printf("Encode audio file %s\n", filename); | printf("Encode audio file %s\n", filename); | ||||
| @@ -67,9 +123,19 @@ static void audio_encode_example(const char *filename) | |||||
| /* put sample parameters */ | /* put sample parameters */ | ||||
| c->bit_rate = 64000; | c->bit_rate = 64000; | ||||
| c->sample_rate = 44100; | |||||
| c->channels = 2; | |||||
| /* check that the encoder supports s16 pcm input */ | |||||
| c->sample_fmt = AV_SAMPLE_FMT_S16; | c->sample_fmt = AV_SAMPLE_FMT_S16; | ||||
| if (!check_sample_fmt(codec, c->sample_fmt)) { | |||||
| fprintf(stderr, "encoder does not support %s", | |||||
| av_get_sample_fmt_name(c->sample_fmt)); | |||||
| exit(1); | |||||
| } | |||||
| /* select other audio parameters supported by the encoder */ | |||||
| c->sample_rate = select_sample_rate(codec); | |||||
| c->channel_layout = select_channel_layout(codec); | |||||
| c->channels = av_get_channel_layout_nb_channels(c->channel_layout); | |||||
| /* open it */ | /* open it */ | ||||
| if (avcodec_open2(c, codec, NULL) < 0) { | if (avcodec_open2(c, codec, NULL) < 0) { | ||||
| @@ -77,35 +143,71 @@ static void audio_encode_example(const char *filename) | |||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| /* the codec gives us the frame size, in samples */ | |||||
| frame_size = c->frame_size; | |||||
| samples = malloc(frame_size * 2 * c->channels); | |||||
| outbuf_size = 10000; | |||||
| outbuf = malloc(outbuf_size); | |||||
| f = fopen(filename, "wb"); | f = fopen(filename, "wb"); | ||||
| if (!f) { | if (!f) { | ||||
| fprintf(stderr, "could not open %s\n", filename); | fprintf(stderr, "could not open %s\n", filename); | ||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| /* frame containing input raw audio */ | |||||
| frame = avcodec_alloc_frame(); | |||||
| if (!frame) { | |||||
| fprintf(stderr, "could not allocate audio frame\n"); | |||||
| exit(1); | |||||
| } | |||||
| frame->nb_samples = c->frame_size; | |||||
| frame->format = c->sample_fmt; | |||||
| frame->channel_layout = c->channel_layout; | |||||
| /* the codec gives us the frame size, in samples, | |||||
| * we calculate the size of the samples buffer in bytes */ | |||||
| buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, | |||||
| c->sample_fmt, 0); | |||||
| samples = av_malloc(buffer_size); | |||||
| if (!samples) { | |||||
| fprintf(stderr, "could not allocate %d bytes for samples buffer\n", | |||||
| buffer_size); | |||||
| exit(1); | |||||
| } | |||||
| /* setup the data pointers in the AVFrame */ | |||||
| ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, | |||||
| (const uint8_t*)samples, buffer_size, 0); | |||||
| if (ret < 0) { | |||||
| fprintf(stderr, "could not setup audio frame\n"); | |||||
| exit(1); | |||||
| } | |||||
| /* encode a single tone sound */ | /* encode a single tone sound */ | ||||
| t = 0; | t = 0; | ||||
| tincr = 2 * M_PI * 440.0 / c->sample_rate; | tincr = 2 * M_PI * 440.0 / c->sample_rate; | ||||
| for(i=0;i<200;i++) { | for(i=0;i<200;i++) { | ||||
| for(j=0;j<frame_size;j++) { | |||||
| av_init_packet(&pkt); | |||||
| pkt.data = NULL; // packet data will be allocated by the encoder | |||||
| pkt.size = 0; | |||||
| for (j = 0; j < c->frame_size; j++) { | |||||
| samples[2*j] = (int)(sin(t) * 10000); | samples[2*j] = (int)(sin(t) * 10000); | ||||
| samples[2*j+1] = samples[2*j]; | |||||
| for (k = 1; k < c->channels; k++) | |||||
| samples[2*j + k] = samples[2*j]; | |||||
| t += tincr; | t += tincr; | ||||
| } | } | ||||
| /* encode the samples */ | /* encode the samples */ | ||||
| out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples); | |||||
| fwrite(outbuf, 1, out_size, f); | |||||
| ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); | |||||
| if (ret < 0) { | |||||
| fprintf(stderr, "error encoding audio frame\n"); | |||||
| exit(1); | |||||
| } | |||||
| if (got_output) { | |||||
| fwrite(pkt.data, 1, pkt.size, f); | |||||
| av_free_packet(&pkt); | |||||
| } | |||||
| } | } | ||||
| fclose(f); | fclose(f); | ||||
| free(outbuf); | |||||
| free(samples); | |||||
| av_freep(&samples); | |||||
| av_freep(&frame); | |||||
| avcodec_close(c); | avcodec_close(c); | ||||
| av_free(c); | av_free(c); | ||||
| } | } | ||||
| @@ -318,9 +318,9 @@ following "Devel" ones: | |||||
| binutils, gcc4-core, make, git, mingw-runtime, texi2html | binutils, gcc4-core, make, git, mingw-runtime, texi2html | ||||
| @end example | @end example | ||||
| And the following "Utils" one: | |||||
| In order to run FATE you will also need the following "Utils" packages: | |||||
| @example | @example | ||||
| diffutils | |||||
| bc, diffutils | |||||
| @end example | @end example | ||||
| Then run | Then run | ||||
| @@ -267,6 +267,11 @@ value will be sent. | |||||
| Stream identifier to play or to publish. This option overrides the | Stream identifier to play or to publish. This option overrides the | ||||
| parameter specified in the URI. | parameter specified in the URI. | ||||
| @item rtmp_subscribe | |||||
| Name of live stream to subscribe to. By default no value will be sent. | |||||
| It is only sent if the option is specified or if rtmp_live | |||||
| is set to live. | |||||
| @item rtmp_swfurl | @item rtmp_swfurl | ||||
| URL of the SWF player for the media. By default no value will be sent. | URL of the SWF player for the media. By default no value will be sent. | ||||
| @@ -0,0 +1,391 @@ | |||||
| /* | |||||
| * This file is part of FFmpeg. | |||||
| * | |||||
| * FFmpeg is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * | |||||
| * FFmpeg is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with FFmpeg; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #ifndef FFMPEG_H | |||||
| #define FFMPEG_H | |||||
| #include "config.h" | |||||
| #include <stdint.h> | |||||
| #include <stdio.h> | |||||
| #include <signal.h> | |||||
| #if HAVE_PTHREADS | |||||
| #include <pthread.h> | |||||
| #endif | |||||
| #include "cmdutils.h" | |||||
| #include "libavformat/avformat.h" | |||||
| #include "libavformat/avio.h" | |||||
| #include "libavcodec/avcodec.h" | |||||
| #include "libavfilter/avfilter.h" | |||||
| #include "libavfilter/avfiltergraph.h" | |||||
| #include "libavutil/avutil.h" | |||||
| #include "libavutil/dict.h" | |||||
| #include "libavutil/fifo.h" | |||||
| #include "libavutil/pixfmt.h" | |||||
| #include "libavutil/rational.h" | |||||
| #include "libswresample/swresample.h" | |||||
| #define VSYNC_AUTO -1 | |||||
| #define VSYNC_PASSTHROUGH 0 | |||||
| #define VSYNC_CFR 1 | |||||
| #define VSYNC_VFR 2 | |||||
| #define VSYNC_DROP 0xff | |||||
| #define MAX_STREAMS 1024 /* arbitrary sanity check value */ | |||||
| /* select an input stream for an output stream */ | |||||
| typedef struct StreamMap { | |||||
| int disabled; /** 1 is this mapping is disabled by a negative map */ | |||||
| int file_index; | |||||
| int stream_index; | |||||
| int sync_file_index; | |||||
| int sync_stream_index; | |||||
| char *linklabel; /** name of an output link, for mapping lavfi outputs */ | |||||
| } StreamMap; | |||||
| typedef struct { | |||||
| int file_idx, stream_idx, channel_idx; // input | |||||
| int ofile_idx, ostream_idx; // output | |||||
| } AudioChannelMap; | |||||
| typedef struct OptionsContext { | |||||
| /* input/output options */ | |||||
| int64_t start_time; | |||||
| const char *format; | |||||
| SpecifierOpt *codec_names; | |||||
| int nb_codec_names; | |||||
| SpecifierOpt *audio_channels; | |||||
| int nb_audio_channels; | |||||
| SpecifierOpt *audio_sample_rate; | |||||
| int nb_audio_sample_rate; | |||||
| SpecifierOpt *frame_rates; | |||||
| int nb_frame_rates; | |||||
| SpecifierOpt *frame_sizes; | |||||
| int nb_frame_sizes; | |||||
| SpecifierOpt *frame_pix_fmts; | |||||
| int nb_frame_pix_fmts; | |||||
| /* input options */ | |||||
| int64_t input_ts_offset; | |||||
| int rate_emu; | |||||
| SpecifierOpt *ts_scale; | |||||
| int nb_ts_scale; | |||||
| SpecifierOpt *dump_attachment; | |||||
| int nb_dump_attachment; | |||||
| /* output options */ | |||||
| StreamMap *stream_maps; | |||||
| int nb_stream_maps; | |||||
| AudioChannelMap *audio_channel_maps; /* one info entry per -map_channel */ | |||||
| int nb_audio_channel_maps; /* number of (valid) -map_channel settings */ | |||||
| int metadata_global_manual; | |||||
| int metadata_streams_manual; | |||||
| int metadata_chapters_manual; | |||||
| const char **attachments; | |||||
| int nb_attachments; | |||||
| int chapters_input_file; | |||||
| int64_t recording_time; | |||||
| uint64_t limit_filesize; | |||||
| float mux_preload; | |||||
| float mux_max_delay; | |||||
| int video_disable; | |||||
| int audio_disable; | |||||
| int subtitle_disable; | |||||
| int data_disable; | |||||
| /* indexed by output file stream index */ | |||||
| int *streamid_map; | |||||
| int nb_streamid_map; | |||||
| SpecifierOpt *metadata; | |||||
| int nb_metadata; | |||||
| SpecifierOpt *max_frames; | |||||
| int nb_max_frames; | |||||
| SpecifierOpt *bitstream_filters; | |||||
| int nb_bitstream_filters; | |||||
| SpecifierOpt *codec_tags; | |||||
| int nb_codec_tags; | |||||
| SpecifierOpt *sample_fmts; | |||||
| int nb_sample_fmts; | |||||
| SpecifierOpt *qscale; | |||||
| int nb_qscale; | |||||
| SpecifierOpt *forced_key_frames; | |||||
| int nb_forced_key_frames; | |||||
| SpecifierOpt *force_fps; | |||||
| int nb_force_fps; | |||||
| SpecifierOpt *frame_aspect_ratios; | |||||
| int nb_frame_aspect_ratios; | |||||
| SpecifierOpt *rc_overrides; | |||||
| int nb_rc_overrides; | |||||
| SpecifierOpt *intra_matrices; | |||||
| int nb_intra_matrices; | |||||
| SpecifierOpt *inter_matrices; | |||||
| int nb_inter_matrices; | |||||
| SpecifierOpt *top_field_first; | |||||
| int nb_top_field_first; | |||||
| SpecifierOpt *metadata_map; | |||||
| int nb_metadata_map; | |||||
| SpecifierOpt *presets; | |||||
| int nb_presets; | |||||
| SpecifierOpt *copy_initial_nonkeyframes; | |||||
| int nb_copy_initial_nonkeyframes; | |||||
| SpecifierOpt *filters; | |||||
| int nb_filters; | |||||
| } OptionsContext; | |||||
| typedef struct InputFilter { | |||||
| AVFilterContext *filter; | |||||
| struct InputStream *ist; | |||||
| struct FilterGraph *graph; | |||||
| uint8_t *name; | |||||
| } InputFilter; | |||||
| typedef struct OutputFilter { | |||||
| AVFilterContext *filter; | |||||
| struct OutputStream *ost; | |||||
| struct FilterGraph *graph; | |||||
| uint8_t *name; | |||||
| /* temporary storage until stream maps are processed */ | |||||
| AVFilterInOut *out_tmp; | |||||
| } OutputFilter; | |||||
| typedef struct FilterGraph { | |||||
| int index; | |||||
| const char *graph_desc; | |||||
| AVFilterGraph *graph; | |||||
| InputFilter **inputs; | |||||
| int nb_inputs; | |||||
| OutputFilter **outputs; | |||||
| int nb_outputs; | |||||
| } FilterGraph; | |||||
| typedef struct InputStream { | |||||
| int file_index; | |||||
| AVStream *st; | |||||
| int discard; /* true if stream data should be discarded */ | |||||
| int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ | |||||
| AVCodec *dec; | |||||
| AVFrame *decoded_frame; | |||||
| int64_t start; /* time when read started */ | |||||
| /* predicted dts of the next packet read for this stream or (when there are | |||||
| * several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */ | |||||
| int64_t next_dts; | |||||
| int64_t dts; ///< dts of the last packet read for this stream (in AV_TIME_BASE units) | |||||
| int64_t next_pts; ///< synthetic pts for the next decode frame (in AV_TIME_BASE units) | |||||
| int64_t pts; ///< current pts of the decoded frame (in AV_TIME_BASE units) | |||||
| int wrap_correction_done; | |||||
| double ts_scale; | |||||
| int is_start; /* is 1 at the start and after a discontinuity */ | |||||
| int saw_first_ts; | |||||
| int showed_multi_packet_warning; | |||||
| AVDictionary *opts; | |||||
| AVRational framerate; /* framerate forced with -r */ | |||||
| int top_field_first; | |||||
| int resample_height; | |||||
| int resample_width; | |||||
| int resample_pix_fmt; | |||||
| int resample_sample_fmt; | |||||
| int resample_sample_rate; | |||||
| int resample_channels; | |||||
| uint64_t resample_channel_layout; | |||||
| struct sub2video { | |||||
| int64_t last_pts; | |||||
| AVFilterBufferRef *ref; | |||||
| int w, h; | |||||
| } sub2video; | |||||
| /* a pool of free buffers for decoded data */ | |||||
| FrameBuffer *buffer_pool; | |||||
| int dr1; | |||||
| /* decoded data from this stream goes into all those filters | |||||
| * currently video and audio only */ | |||||
| InputFilter **filters; | |||||
| int nb_filters; | |||||
| } InputStream; | |||||
| typedef struct InputFile { | |||||
| AVFormatContext *ctx; | |||||
| int eof_reached; /* true if eof reached */ | |||||
| int unavailable; /* true if the file is unavailable (possibly temporarily) */ | |||||
| int ist_index; /* index of first stream in input_streams */ | |||||
| int64_t ts_offset; | |||||
| int nb_streams; /* number of stream that ffmpeg is aware of; may be different | |||||
| from ctx.nb_streams if new streams appear during av_read_frame() */ | |||||
| int nb_streams_warn; /* number of streams that the user was warned of */ | |||||
| int rate_emu; | |||||
| #if HAVE_PTHREADS | |||||
| pthread_t thread; /* thread reading from this file */ | |||||
| int finished; /* the thread has exited */ | |||||
| int joined; /* the thread has been joined */ | |||||
| pthread_mutex_t fifo_lock; /* lock for access to fifo */ | |||||
| pthread_cond_t fifo_cond; /* the main thread will signal on this cond after reading from fifo */ | |||||
| AVFifoBuffer *fifo; /* demuxed packets are stored here; freed by the main thread */ | |||||
| #endif | |||||
| } InputFile; | |||||
| typedef struct OutputStream { | |||||
| int file_index; /* file index */ | |||||
| int index; /* stream index in the output file */ | |||||
| int source_index; /* InputStream index */ | |||||
| AVStream *st; /* stream in the output file */ | |||||
| int encoding_needed; /* true if encoding needed for this stream */ | |||||
| int frame_number; | |||||
| /* input pts and corresponding output pts | |||||
| for A/V sync */ | |||||
| struct InputStream *sync_ist; /* input stream to sync against */ | |||||
| int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number | |||||
| /* pts of the first frame encoded for this stream, used for limiting | |||||
| * recording time */ | |||||
| int64_t first_pts; | |||||
| AVBitStreamFilterContext *bitstream_filters; | |||||
| AVCodec *enc; | |||||
| int64_t max_frames; | |||||
| AVFrame *filtered_frame; | |||||
| /* video only */ | |||||
| AVRational frame_rate; | |||||
| int force_fps; | |||||
| int top_field_first; | |||||
| float frame_aspect_ratio; | |||||
| float last_quality; | |||||
| /* forced key frames */ | |||||
| int64_t *forced_kf_pts; | |||||
| int forced_kf_count; | |||||
| int forced_kf_index; | |||||
| char *forced_keyframes; | |||||
| /* audio only */ | |||||
| int audio_channels_map[SWR_CH_MAX]; /* list of the channels id to pick from the source stream */ | |||||
| int audio_channels_mapped; /* number of channels in audio_channels_map */ | |||||
| FILE *logfile; | |||||
| OutputFilter *filter; | |||||
| char *avfilter; | |||||
| int64_t sws_flags; | |||||
| int64_t swr_dither_method; | |||||
| double swr_dither_scale; | |||||
| AVDictionary *opts; | |||||
| int is_past_recording_time; | |||||
| int unavailable; /* true if the steram is unavailable (possibly temporarily) */ | |||||
| int stream_copy; | |||||
| const char *attachment_filename; | |||||
| int copy_initial_nonkeyframes; | |||||
| int keep_pix_fmt; | |||||
| } OutputStream; | |||||
| typedef struct OutputFile { | |||||
| AVFormatContext *ctx; | |||||
| AVDictionary *opts; | |||||
| int ost_index; /* index of the first stream in output_streams */ | |||||
| int64_t recording_time; ///< desired length of the resulting file in microseconds == AV_TIME_BASE units | |||||
| int64_t start_time; ///< start time in microseconds == AV_TIME_BASE units | |||||
| uint64_t limit_filesize; /* filesize limit expressed in bytes */ | |||||
| } OutputFile; | |||||
| extern InputStream **input_streams; | |||||
| extern int nb_input_streams; | |||||
| extern InputFile **input_files; | |||||
| extern int nb_input_files; | |||||
| extern OutputStream **output_streams; | |||||
| extern int nb_output_streams; | |||||
| extern OutputFile **output_files; | |||||
| extern int nb_output_files; | |||||
| extern FilterGraph **filtergraphs; | |||||
| extern int nb_filtergraphs; | |||||
| extern const char *pass_logfilename_prefix; | |||||
| extern char *vstats_filename; | |||||
| extern float audio_drift_threshold; | |||||
| extern float dts_delta_threshold; | |||||
| extern float dts_error_threshold; | |||||
| extern int audio_volume; | |||||
| extern int audio_sync_method; | |||||
| extern int video_sync_method; | |||||
| extern int do_benchmark; | |||||
| extern int do_benchmark_all; | |||||
| extern int do_deinterlace; | |||||
| extern int do_hex_dump; | |||||
| extern int do_pkt_dump; | |||||
| extern int copy_ts; | |||||
| extern int copy_tb; | |||||
| extern int debug_ts; | |||||
| extern int opt_shortest; | |||||
| extern int exit_on_error; | |||||
| extern int print_stats; | |||||
| extern int qp_hist; | |||||
| extern int same_quant; | |||||
| extern int stdin_interaction; | |||||
| extern int frame_bits_per_raw_sample; | |||||
| extern AVIOContext *progress_avio; | |||||
| extern const AVIOInterruptCB int_cb; | |||||
| extern const OptionDef options[]; | |||||
| void term_init(void); | |||||
| void term_exit(void); | |||||
| void reset_options(OptionsContext *o, int is_input); | |||||
| void show_usage(void); | |||||
| void opt_output_file(void *optctx, const char *filename); | |||||
| void assert_avoptions(AVDictionary *m); | |||||
| int guess_input_channel_layout(InputStream *ist); | |||||
| enum PixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum PixelFormat target); | |||||
| void choose_sample_fmt(AVStream *st, AVCodec *codec); | |||||
| int configure_filtergraph(FilterGraph *fg); | |||||
| int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out); | |||||
| int ist_in_filtergraph(FilterGraph *fg, InputStream *ist); | |||||
| FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost); | |||||
| #endif /* FFMPEG_H */ | |||||
| @@ -0,0 +1,789 @@ | |||||
| /* | |||||
| * ffmpeg filter configuration | |||||
| * | |||||
| * This file is part of FFmpeg. | |||||
| * | |||||
| * FFmpeg is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * | |||||
| * FFmpeg is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with FFmpeg; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #include "ffmpeg.h" | |||||
| #include "libavfilter/avfilter.h" | |||||
| #include "libavfilter/avfiltergraph.h" | |||||
| #include "libavfilter/buffersink.h" | |||||
| #include "libavutil/audioconvert.h" | |||||
| #include "libavutil/avassert.h" | |||||
| #include "libavutil/avstring.h" | |||||
| #include "libavutil/bprint.h" | |||||
| #include "libavutil/pixdesc.h" | |||||
| #include "libavutil/pixfmt.h" | |||||
| #include "libavutil/imgutils.h" | |||||
| #include "libavutil/samplefmt.h" | |||||
| enum PixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum PixelFormat target) | |||||
| { | |||||
| if (codec && codec->pix_fmts) { | |||||
| const enum PixelFormat *p = codec->pix_fmts; | |||||
| int has_alpha= av_pix_fmt_descriptors[target].nb_components % 2 == 0; | |||||
| enum PixelFormat best= PIX_FMT_NONE; | |||||
| if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { | |||||
| if (st->codec->codec_id == AV_CODEC_ID_MJPEG) { | |||||
| p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE }; | |||||
| } else if (st->codec->codec_id == AV_CODEC_ID_LJPEG) { | |||||
| p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P, | |||||
| PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE }; | |||||
| } | |||||
| } | |||||
| for (; *p != PIX_FMT_NONE; p++) { | |||||
| best= avcodec_find_best_pix_fmt2(best, *p, target, has_alpha, NULL); | |||||
| if (*p == target) | |||||
| break; | |||||
| } | |||||
| if (*p == PIX_FMT_NONE) { | |||||
| if (target != PIX_FMT_NONE) | |||||
| av_log(NULL, AV_LOG_WARNING, | |||||
| "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n", | |||||
| av_pix_fmt_descriptors[target].name, | |||||
| codec->name, | |||||
| av_pix_fmt_descriptors[best].name); | |||||
| return best; | |||||
| } | |||||
| } | |||||
| return target; | |||||
| } | |||||
| void choose_sample_fmt(AVStream *st, AVCodec *codec) | |||||
| { | |||||
| if (codec && codec->sample_fmts) { | |||||
| const enum AVSampleFormat *p = codec->sample_fmts; | |||||
| for (; *p != -1; p++) { | |||||
| if (*p == st->codec->sample_fmt) | |||||
| break; | |||||
| } | |||||
| if (*p == -1) { | |||||
| if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0])) | |||||
| av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n"); | |||||
| if(av_get_sample_fmt_name(st->codec->sample_fmt)) | |||||
| av_log(NULL, AV_LOG_WARNING, | |||||
| "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n", | |||||
| av_get_sample_fmt_name(st->codec->sample_fmt), | |||||
| codec->name, | |||||
| av_get_sample_fmt_name(codec->sample_fmts[0])); | |||||
| st->codec->sample_fmt = codec->sample_fmts[0]; | |||||
| } | |||||
| } | |||||
| } | |||||
| static char *choose_pix_fmts(OutputStream *ost) | |||||
| { | |||||
| if (ost->keep_pix_fmt) { | |||||
| if (ost->filter) | |||||
| avfilter_graph_set_auto_convert(ost->filter->graph->graph, | |||||
| AVFILTER_AUTO_CONVERT_NONE); | |||||
| if (ost->st->codec->pix_fmt == PIX_FMT_NONE) | |||||
| return NULL; | |||||
| return av_strdup(av_get_pix_fmt_name(ost->st->codec->pix_fmt)); | |||||
| } | |||||
| if (ost->st->codec->pix_fmt != PIX_FMT_NONE) { | |||||
| return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc, ost->st->codec->pix_fmt))); | |||||
| } else if (ost->enc && ost->enc->pix_fmts) { | |||||
| const enum PixelFormat *p; | |||||
| AVIOContext *s = NULL; | |||||
| uint8_t *ret; | |||||
| int len; | |||||
| if (avio_open_dyn_buf(&s) < 0) | |||||
| exit_program(1); | |||||
| p = ost->enc->pix_fmts; | |||||
| if (ost->st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { | |||||
| if (ost->st->codec->codec_id == AV_CODEC_ID_MJPEG) { | |||||
| p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE }; | |||||
| } else if (ost->st->codec->codec_id == AV_CODEC_ID_LJPEG) { | |||||
| p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P, | |||||
| PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE }; | |||||
| } | |||||
| } | |||||
| for (; *p != PIX_FMT_NONE; p++) { | |||||
| const char *name = av_get_pix_fmt_name(*p); | |||||
| avio_printf(s, "%s:", name); | |||||
| } | |||||
| len = avio_close_dyn_buf(s, &ret); | |||||
| ret[len - 1] = 0; | |||||
| return ret; | |||||
| } else | |||||
| return NULL; | |||||
| } | |||||
| /** | |||||
| * Define a function for building a string containing a list of | |||||
| * allowed formats, | |||||
| */ | |||||
| #define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name, separator)\ | |||||
| static char *choose_ ## var ## s(OutputStream *ost) \ | |||||
| { \ | |||||
| if (ost->st->codec->var != none) { \ | |||||
| get_name(ost->st->codec->var); \ | |||||
| return av_strdup(name); \ | |||||
| } else if (ost->enc->supported_list) { \ | |||||
| const type *p; \ | |||||
| AVIOContext *s = NULL; \ | |||||
| uint8_t *ret; \ | |||||
| int len; \ | |||||
| \ | |||||
| if (avio_open_dyn_buf(&s) < 0) \ | |||||
| exit_program(1); \ | |||||
| \ | |||||
| for (p = ost->enc->supported_list; *p != none; p++) { \ | |||||
| get_name(*p); \ | |||||
| avio_printf(s, "%s" separator, name); \ | |||||
| } \ | |||||
| len = avio_close_dyn_buf(s, &ret); \ | |||||
| ret[len - 1] = 0; \ | |||||
| return ret; \ | |||||
| } else \ | |||||
| return NULL; \ | |||||
| } | |||||
| #define GET_PIX_FMT_NAME(pix_fmt)\ | |||||
| const char *name = av_get_pix_fmt_name(pix_fmt); | |||||
| // DEF_CHOOSE_FORMAT(enum PixelFormat, pix_fmt, pix_fmts, PIX_FMT_NONE, | |||||
| // GET_PIX_FMT_NAME, ":") | |||||
| #define GET_SAMPLE_FMT_NAME(sample_fmt)\ | |||||
| const char *name = av_get_sample_fmt_name(sample_fmt) | |||||
| DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts, | |||||
| AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",") | |||||
| #define GET_SAMPLE_RATE_NAME(rate)\ | |||||
| char name[16];\ | |||||
| snprintf(name, sizeof(name), "%d", rate); | |||||
| DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0, | |||||
| GET_SAMPLE_RATE_NAME, ",") | |||||
| #define GET_CH_LAYOUT_NAME(ch_layout)\ | |||||
| char name[16];\ | |||||
| snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout); | |||||
| DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0, | |||||
| GET_CH_LAYOUT_NAME, ",") | |||||
| FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost) | |||||
| { | |||||
| FilterGraph *fg = av_mallocz(sizeof(*fg)); | |||||
| if (!fg) | |||||
| exit_program(1); | |||||
| fg->index = nb_filtergraphs; | |||||
| fg->outputs = grow_array(fg->outputs, sizeof(*fg->outputs), &fg->nb_outputs, | |||||
| fg->nb_outputs + 1); | |||||
| if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0])))) | |||||
| exit_program(1); | |||||
| fg->outputs[0]->ost = ost; | |||||
| fg->outputs[0]->graph = fg; | |||||
| ost->filter = fg->outputs[0]; | |||||
| fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs), &fg->nb_inputs, | |||||
| fg->nb_inputs + 1); | |||||
| if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0])))) | |||||
| exit_program(1); | |||||
| fg->inputs[0]->ist = ist; | |||||
| fg->inputs[0]->graph = fg; | |||||
| ist->filters = grow_array(ist->filters, sizeof(*ist->filters), | |||||
| &ist->nb_filters, ist->nb_filters + 1); | |||||
| ist->filters[ist->nb_filters - 1] = fg->inputs[0]; | |||||
| filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs), | |||||
| &nb_filtergraphs, nb_filtergraphs + 1); | |||||
| filtergraphs[nb_filtergraphs - 1] = fg; | |||||
| return fg; | |||||
| } | |||||
| static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) | |||||
| { | |||||
| InputStream *ist = NULL; | |||||
| enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx); | |||||
| int i; | |||||
| // TODO: support other filter types | |||||
| if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported " | |||||
| "currently.\n"); | |||||
| exit_program(1); | |||||
| } | |||||
| if (in->name) { | |||||
| AVFormatContext *s; | |||||
| AVStream *st = NULL; | |||||
| char *p; | |||||
| int file_idx = strtol(in->name, &p, 0); | |||||
| if (file_idx < 0 || file_idx >= nb_input_files) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n", | |||||
| file_idx, fg->graph_desc); | |||||
| exit_program(1); | |||||
| } | |||||
| s = input_files[file_idx]->ctx; | |||||
| for (i = 0; i < s->nb_streams; i++) { | |||||
| enum AVMediaType stream_type = s->streams[i]->codec->codec_type; | |||||
| if (stream_type != type && | |||||
| !(stream_type == AVMEDIA_TYPE_SUBTITLE && | |||||
| type == AVMEDIA_TYPE_VIDEO /* sub2video hack */)) | |||||
| continue; | |||||
| if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) { | |||||
| st = s->streams[i]; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (!st) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s " | |||||
| "matches no streams.\n", p, fg->graph_desc); | |||||
| exit_program(1); | |||||
| } | |||||
| ist = input_streams[input_files[file_idx]->ist_index + st->index]; | |||||
| } else { | |||||
| /* find the first unused stream of corresponding type */ | |||||
| for (i = 0; i < nb_input_streams; i++) { | |||||
| ist = input_streams[i]; | |||||
| if (ist->st->codec->codec_type == type && ist->discard) | |||||
| break; | |||||
| } | |||||
| if (i == nb_input_streams) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for " | |||||
| "unlabeled input pad %d on filter %s\n", in->pad_idx, | |||||
| in->filter_ctx->name); | |||||
| exit_program(1); | |||||
| } | |||||
| } | |||||
| av_assert0(ist); | |||||
| ist->discard = 0; | |||||
| ist->decoding_needed = 1; | |||||
| ist->st->discard = AVDISCARD_NONE; | |||||
| fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs), | |||||
| &fg->nb_inputs, fg->nb_inputs + 1); | |||||
| if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0])))) | |||||
| exit_program(1); | |||||
| fg->inputs[fg->nb_inputs - 1]->ist = ist; | |||||
| fg->inputs[fg->nb_inputs - 1]->graph = fg; | |||||
| ist->filters = grow_array(ist->filters, sizeof(*ist->filters), | |||||
| &ist->nb_filters, ist->nb_filters + 1); | |||||
| ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1]; | |||||
| } | |||||
| static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) | |||||
| { | |||||
| char *pix_fmts; | |||||
| OutputStream *ost = ofilter->ost; | |||||
| AVCodecContext *codec = ost->st->codec; | |||||
| AVFilterContext *last_filter = out->filter_ctx; | |||||
| int pad_idx = out->pad_idx; | |||||
| int ret; | |||||
| char name[255]; | |||||
| AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc(); | |||||
| snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index); | |||||
| ret = avfilter_graph_create_filter(&ofilter->filter, | |||||
| avfilter_get_by_name("buffersink"), | |||||
| name, NULL, NULL/*buffersink_params*/, fg->graph); | |||||
| av_freep(&buffersink_params); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| if (codec->width || codec->height) { | |||||
| char args[255]; | |||||
| AVFilterContext *filter; | |||||
| snprintf(args, sizeof(args), "%d:%d:flags=0x%X", | |||||
| codec->width, | |||||
| codec->height, | |||||
| (unsigned)ost->sws_flags); | |||||
| snprintf(name, sizeof(name), "scaler for output stream %d:%d", | |||||
| ost->file_index, ost->index); | |||||
| if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"), | |||||
| name, args, NULL, fg->graph)) < 0) | |||||
| return ret; | |||||
| if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0) | |||||
| return ret; | |||||
| last_filter = filter; | |||||
| pad_idx = 0; | |||||
| } | |||||
| if ((pix_fmts = choose_pix_fmts(ost))) { | |||||
| AVFilterContext *filter; | |||||
| snprintf(name, sizeof(name), "pixel format for output stream %d:%d", | |||||
| ost->file_index, ost->index); | |||||
| if ((ret = avfilter_graph_create_filter(&filter, | |||||
| avfilter_get_by_name("format"), | |||||
| "format", pix_fmts, NULL, | |||||
| fg->graph)) < 0) | |||||
| return ret; | |||||
| if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0) | |||||
| return ret; | |||||
| last_filter = filter; | |||||
| pad_idx = 0; | |||||
| av_freep(&pix_fmts); | |||||
| } | |||||
| if (ost->frame_rate.num && 0) { | |||||
| AVFilterContext *fps; | |||||
| char args[255]; | |||||
| snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num, | |||||
| ost->frame_rate.den); | |||||
| snprintf(name, sizeof(name), "fps for output stream %d:%d", | |||||
| ost->file_index, ost->index); | |||||
| ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"), | |||||
| name, args, NULL, fg->graph); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| ret = avfilter_link(last_filter, pad_idx, fps, 0); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| last_filter = fps; | |||||
| pad_idx = 0; | |||||
| } | |||||
| if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) | |||||
| return ret; | |||||
| return 0; | |||||
| } | |||||
| static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) | |||||
| { | |||||
| OutputStream *ost = ofilter->ost; | |||||
| AVCodecContext *codec = ost->st->codec; | |||||
| AVFilterContext *last_filter = out->filter_ctx; | |||||
| int pad_idx = out->pad_idx; | |||||
| char *sample_fmts, *sample_rates, *channel_layouts; | |||||
| char name[255]; | |||||
| int ret; | |||||
| snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index); | |||||
| ret = avfilter_graph_create_filter(&ofilter->filter, | |||||
| avfilter_get_by_name("abuffersink"), | |||||
| name, NULL, NULL, fg->graph); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \ | |||||
| AVFilterContext *filt_ctx; \ | |||||
| \ | |||||
| av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \ | |||||
| "similarly to -af " filter_name "=%s.\n", arg); \ | |||||
| \ | |||||
| ret = avfilter_graph_create_filter(&filt_ctx, \ | |||||
| avfilter_get_by_name(filter_name), \ | |||||
| filter_name, arg, NULL, fg->graph); \ | |||||
| if (ret < 0) \ | |||||
| return ret; \ | |||||
| \ | |||||
| ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \ | |||||
| if (ret < 0) \ | |||||
| return ret; \ | |||||
| \ | |||||
| last_filter = filt_ctx; \ | |||||
| pad_idx = 0; \ | |||||
| } while (0) | |||||
| if (ost->audio_channels_mapped) { | |||||
| int i; | |||||
| AVBPrint pan_buf; | |||||
| av_bprint_init(&pan_buf, 256, 8192); | |||||
| av_bprintf(&pan_buf, "0x%"PRIx64, | |||||
| av_get_default_channel_layout(ost->audio_channels_mapped)); | |||||
| for (i = 0; i < ost->audio_channels_mapped; i++) | |||||
| if (ost->audio_channels_map[i] != -1) | |||||
| av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]); | |||||
| AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str); | |||||
| av_bprint_finalize(&pan_buf, NULL); | |||||
| } | |||||
| if (codec->channels && !codec->channel_layout) | |||||
| codec->channel_layout = av_get_default_channel_layout(codec->channels); | |||||
| sample_fmts = choose_sample_fmts(ost); | |||||
| sample_rates = choose_sample_rates(ost); | |||||
| channel_layouts = choose_channel_layouts(ost); | |||||
| if (sample_fmts || sample_rates || channel_layouts) { | |||||
| AVFilterContext *format; | |||||
| char args[256]; | |||||
| int len = 0; | |||||
| if (sample_fmts) | |||||
| len += snprintf(args + len, sizeof(args) - len, "sample_fmts=%s:", | |||||
| sample_fmts); | |||||
| if (sample_rates) | |||||
| len += snprintf(args + len, sizeof(args) - len, "sample_rates=%s:", | |||||
| sample_rates); | |||||
| if (channel_layouts) | |||||
| len += snprintf(args + len, sizeof(args) - len, "channel_layouts=%s:", | |||||
| channel_layouts); | |||||
| args[len - 1] = 0; | |||||
| av_freep(&sample_fmts); | |||||
| av_freep(&sample_rates); | |||||
| av_freep(&channel_layouts); | |||||
| snprintf(name, sizeof(name), "audio format for output stream %d:%d", | |||||
| ost->file_index, ost->index); | |||||
| ret = avfilter_graph_create_filter(&format, | |||||
| avfilter_get_by_name("aformat"), | |||||
| name, args, NULL, fg->graph); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| ret = avfilter_link(last_filter, pad_idx, format, 0); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| last_filter = format; | |||||
| pad_idx = 0; | |||||
| } | |||||
| if (audio_volume != 256 && 0) { | |||||
| char args[256]; | |||||
| snprintf(args, sizeof(args), "%f", audio_volume / 256.); | |||||
| AUTO_INSERT_FILTER("-vol", "volume", args); | |||||
| } | |||||
| if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) | |||||
| return ret; | |||||
| return 0; | |||||
| } | |||||
| #define DESCRIBE_FILTER_LINK(f, inout, in) \ | |||||
| { \ | |||||
| AVFilterContext *ctx = inout->filter_ctx; \ | |||||
| AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; \ | |||||
| int nb_pads = in ? ctx->input_count : ctx->output_count; \ | |||||
| AVIOContext *pb; \ | |||||
| \ | |||||
| if (avio_open_dyn_buf(&pb) < 0) \ | |||||
| exit_program(1); \ | |||||
| \ | |||||
| avio_printf(pb, "%s", ctx->filter->name); \ | |||||
| if (nb_pads > 1) \ | |||||
| avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\ | |||||
| avio_w8(pb, 0); \ | |||||
| avio_close_dyn_buf(pb, &f->name); \ | |||||
| } | |||||
| int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) | |||||
| { | |||||
| av_freep(&ofilter->name); | |||||
| DESCRIBE_FILTER_LINK(ofilter, out, 0); | |||||
| switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) { | |||||
| case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out); | |||||
| case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out); | |||||
| default: av_assert0(0); | |||||
| } | |||||
| } | |||||
| static int sub2video_prepare(InputStream *ist) | |||||
| { | |||||
| AVFormatContext *avf = input_files[ist->file_index]->ctx; | |||||
| int i, ret, w, h; | |||||
| uint8_t *image[4]; | |||||
| int linesize[4]; | |||||
| /* Compute the size of the canvas for the subtitles stream. | |||||
| If the subtitles codec has set a size, use it. Otherwise use the | |||||
| maximum dimensions of the video streams in the same file. */ | |||||
| w = ist->st->codec->width; | |||||
| h = ist->st->codec->height; | |||||
| if (!(w && h)) { | |||||
| for (i = 0; i < avf->nb_streams; i++) { | |||||
| if (avf->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { | |||||
| w = FFMAX(w, avf->streams[i]->codec->width); | |||||
| h = FFMAX(h, avf->streams[i]->codec->height); | |||||
| } | |||||
| } | |||||
| if (!(w && h)) { | |||||
| w = FFMAX(w, 720); | |||||
| h = FFMAX(h, 576); | |||||
| } | |||||
| av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h); | |||||
| } | |||||
| ist->sub2video.w = ist->st->codec->width = w; | |||||
| ist->sub2video.h = ist->st->codec->height = h; | |||||
| /* rectangles are PIX_FMT_PAL8, but we have no guarantee that the | |||||
| palettes for all rectangles are identical or compatible */ | |||||
| ist->st->codec->pix_fmt = PIX_FMT_RGB32; | |||||
| ret = av_image_alloc(image, linesize, w, h, PIX_FMT_RGB32, 32); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| memset(image[0], 0, h * linesize[0]); | |||||
| ist->sub2video.ref = avfilter_get_video_buffer_ref_from_arrays( | |||||
| image, linesize, AV_PERM_READ | AV_PERM_PRESERVE, | |||||
| w, h, PIX_FMT_RGB32); | |||||
| if (!ist->sub2video.ref) { | |||||
| av_free(image[0]); | |||||
| return AVERROR(ENOMEM); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, | |||||
| AVFilterInOut *in) | |||||
| { | |||||
| AVFilterContext *first_filter = in->filter_ctx; | |||||
| AVFilter *filter = avfilter_get_by_name("buffer"); | |||||
| InputStream *ist = ifilter->ist; | |||||
| AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) : | |||||
| ist->st->time_base; | |||||
| AVRational fr = ist->framerate.num ? ist->framerate : | |||||
| ist->st->r_frame_rate; | |||||
| AVRational sar; | |||||
| AVBPrint args; | |||||
| char name[255]; | |||||
| int pad_idx = in->pad_idx; | |||||
| int ret; | |||||
| if (ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { | |||||
| ret = sub2video_prepare(ist); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| } | |||||
| sar = ist->st->sample_aspect_ratio.num ? | |||||
| ist->st->sample_aspect_ratio : | |||||
| ist->st->codec->sample_aspect_ratio; | |||||
| if(!sar.den) | |||||
| sar = (AVRational){0,1}; | |||||
| av_bprint_init(&args, 0, 1); | |||||
| av_bprintf(&args, | |||||
| "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:" | |||||
| "pixel_aspect=%d/%d:sws_param=flags=%d", ist->st->codec->width, | |||||
| ist->st->codec->height, ist->st->codec->pix_fmt, | |||||
| tb.num, tb.den, sar.num, sar.den, | |||||
| SWS_BILINEAR + ((ist->st->codec->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0)); | |||||
| if (fr.num && fr.den) | |||||
| av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den); | |||||
| snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, | |||||
| ist->file_index, ist->st->index); | |||||
| if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, name, | |||||
| args.str, NULL, fg->graph)) < 0) | |||||
| return ret; | |||||
| if (ist->framerate.num) { | |||||
| AVFilterContext *setpts; | |||||
| snprintf(name, sizeof(name), "force CFR for input from stream %d:%d", | |||||
| ist->file_index, ist->st->index); | |||||
| if ((ret = avfilter_graph_create_filter(&setpts, | |||||
| avfilter_get_by_name("setpts"), | |||||
| name, "N", NULL, | |||||
| fg->graph)) < 0) | |||||
| return ret; | |||||
| if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0) | |||||
| return ret; | |||||
| first_filter = setpts; | |||||
| pad_idx = 0; | |||||
| } | |||||
| if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0) | |||||
| return ret; | |||||
| return 0; | |||||
| } | |||||
| static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, | |||||
| AVFilterInOut *in) | |||||
| { | |||||
| AVFilterContext *first_filter = in->filter_ctx; | |||||
| AVFilter *filter = avfilter_get_by_name("abuffer"); | |||||
| InputStream *ist = ifilter->ist; | |||||
| int pad_idx = in->pad_idx; | |||||
| char args[255], name[255]; | |||||
| int ret; | |||||
| snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s" | |||||
| ":channel_layout=0x%"PRIx64, | |||||
| 1, ist->st->codec->sample_rate, | |||||
| ist->st->codec->sample_rate, | |||||
| av_get_sample_fmt_name(ist->st->codec->sample_fmt), | |||||
| ist->st->codec->channel_layout); | |||||
| snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, | |||||
| ist->file_index, ist->st->index); | |||||
| if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, | |||||
| name, args, NULL, | |||||
| fg->graph)) < 0) | |||||
| return ret; | |||||
| #define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do { \ | |||||
| AVFilterContext *filt_ctx; \ | |||||
| \ | |||||
| av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \ | |||||
| "similarly to -af " filter_name "=%s.\n", arg); \ | |||||
| \ | |||||
| snprintf(name, sizeof(name), "graph %d %s for input stream %d:%d", \ | |||||
| fg->index, filter_name, ist->file_index, ist->st->index); \ | |||||
| ret = avfilter_graph_create_filter(&filt_ctx, \ | |||||
| avfilter_get_by_name(filter_name), \ | |||||
| name, arg, NULL, fg->graph); \ | |||||
| if (ret < 0) \ | |||||
| return ret; \ | |||||
| \ | |||||
| ret = avfilter_link(filt_ctx, 0, first_filter, pad_idx); \ | |||||
| if (ret < 0) \ | |||||
| return ret; \ | |||||
| \ | |||||
| first_filter = filt_ctx; \ | |||||
| } while (0) | |||||
| if (audio_sync_method > 0) { | |||||
| char args[256] = {0}; | |||||
| av_strlcatf(args, sizeof(args), "min_comp=0.001:min_hard_comp=%f", audio_drift_threshold); | |||||
| if (audio_sync_method > 1) | |||||
| av_strlcatf(args, sizeof(args), ":max_soft_comp=%f", audio_sync_method/(double)ist->st->codec->sample_rate); | |||||
| AUTO_INSERT_FILTER_INPUT("-async", "aresample", args); | |||||
| } | |||||
| // if (ost->audio_channels_mapped) { | |||||
| // int i; | |||||
| // AVBPrint pan_buf; | |||||
| // av_bprint_init(&pan_buf, 256, 8192); | |||||
| // av_bprintf(&pan_buf, "0x%"PRIx64, | |||||
| // av_get_default_channel_layout(ost->audio_channels_mapped)); | |||||
| // for (i = 0; i < ost->audio_channels_mapped; i++) | |||||
| // if (ost->audio_channels_map[i] != -1) | |||||
| // av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]); | |||||
| // AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str); | |||||
| // av_bprint_finalize(&pan_buf, NULL); | |||||
| // } | |||||
| if (audio_volume != 256) { | |||||
| char args[256]; | |||||
| snprintf(args, sizeof(args), "%f", audio_volume / 256.); | |||||
| AUTO_INSERT_FILTER_INPUT("-vol", "volume", args); | |||||
| } | |||||
| if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0) | |||||
| return ret; | |||||
| return 0; | |||||
| } | |||||
| static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, | |||||
| AVFilterInOut *in) | |||||
| { | |||||
| av_freep(&ifilter->name); | |||||
| DESCRIBE_FILTER_LINK(ifilter, in, 1); | |||||
| switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) { | |||||
| case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in); | |||||
| case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in); | |||||
| default: av_assert0(0); | |||||
| } | |||||
| } | |||||
| int configure_filtergraph(FilterGraph *fg) | |||||
| { | |||||
| AVFilterInOut *inputs, *outputs, *cur; | |||||
| int ret, i, init = !fg->graph, simple = !fg->graph_desc; | |||||
| const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter : | |||||
| fg->graph_desc; | |||||
| avfilter_graph_free(&fg->graph); | |||||
| if (!(fg->graph = avfilter_graph_alloc())) | |||||
| return AVERROR(ENOMEM); | |||||
| if (simple) { | |||||
| OutputStream *ost = fg->outputs[0]->ost; | |||||
| char args[255]; | |||||
| snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags); | |||||
| fg->graph->scale_sws_opts = av_strdup(args); | |||||
| } | |||||
| if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0) | |||||
| return ret; | |||||
| if (simple && (!inputs || inputs->next || !outputs || outputs->next)) { | |||||
| av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have " | |||||
| "exactly one input and output.\n", graph_desc); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| for (cur = inputs; !simple && init && cur; cur = cur->next) | |||||
| init_input_filter(fg, cur); | |||||
| for (cur = inputs, i = 0; cur; cur = cur->next, i++) | |||||
| if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) | |||||
| return ret; | |||||
| avfilter_inout_free(&inputs); | |||||
| if (!init || simple) { | |||||
| /* we already know the mappings between lavfi outputs and output streams, | |||||
| * so we can finish the setup */ | |||||
| for (cur = outputs, i = 0; cur; cur = cur->next, i++) | |||||
| configure_output_filter(fg, fg->outputs[i], cur); | |||||
| avfilter_inout_free(&outputs); | |||||
| if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) | |||||
| return ret; | |||||
| } else { | |||||
| /* wait until output mappings are processed */ | |||||
| for (cur = outputs; cur;) { | |||||
| fg->outputs = grow_array(fg->outputs, sizeof(*fg->outputs), | |||||
| &fg->nb_outputs, fg->nb_outputs + 1); | |||||
| if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0])))) | |||||
| exit_program(1); | |||||
| fg->outputs[fg->nb_outputs - 1]->graph = fg; | |||||
| fg->outputs[fg->nb_outputs - 1]->out_tmp = cur; | |||||
| cur = cur->next; | |||||
| fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL; | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| int ist_in_filtergraph(FilterGraph *fg, InputStream *ist) | |||||
| { | |||||
| int i; | |||||
| for (i = 0; i < fg->nb_inputs; i++) | |||||
| if (fg->inputs[i]->ist == ist) | |||||
| return 1; | |||||
| return 0; | |||||
| } | |||||
| @@ -264,6 +264,7 @@ static int scale_vector(int16_t *vector, int length) | |||||
| for (i = 0; i < length; i++) | for (i = 0; i < length; i++) | ||||
| max = FFMAX(max, FFABS(vector[i])); | max = FFMAX(max, FFABS(vector[i])); | ||||
| max = FFMIN(max, 0x7FFF); | |||||
| bits = normalize_bits(max, 15); | bits = normalize_bits(max, 15); | ||||
| scale = shift_table[bits]; | scale = shift_table[bits]; | ||||
| @@ -913,6 +914,7 @@ static void formant_postfilter(G723_1_Context *p, int16_t *lpc, int16_t *buf) | |||||
| } | } | ||||
| iir_filter(filter_coef[0], filter_coef[1], buf + i, | iir_filter(filter_coef[0], filter_coef[1], buf + i, | ||||
| filter_signal + i, 1); | filter_signal + i, 1); | ||||
| lpc += LPC_ORDER; | |||||
| } | } | ||||
| memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t)); | memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t)); | ||||
| @@ -419,6 +419,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, | |||||
| c->cur_frame++; | c->cur_frame++; | ||||
| c->last_bits_used = get_bits_count(gb); | c->last_bits_used = get_bits_count(gb); | ||||
| if(get_bits_left(gb) < 8) // we have only padding left | |||||
| c->last_bits_used = buf_size << 3; | |||||
| if(c->cur_frame >= c->frames) | if(c->cur_frame >= c->frames) | ||||
| c->cur_frame = 0; | c->cur_frame = 0; | ||||
| @@ -1686,7 +1686,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, | |||||
| if (s->frame_size <= 0 || s->frame_size > buf_size) { | if (s->frame_size <= 0 || s->frame_size > buf_size) { | ||||
| av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); | av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); | ||||
| return AVERROR_INVALIDDATA; | return AVERROR_INVALIDDATA; | ||||
| }else if(s->frame_size < buf_size){ | |||||
| } else if (s->frame_size < buf_size) { | |||||
| av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n"); | av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n"); | ||||
| buf_size= s->frame_size; | buf_size= s->frame_size; | ||||
| } | } | ||||
| @@ -24,6 +24,8 @@ | |||||
| * The simplest mpeg audio layer 2 encoder. | * The simplest mpeg audio layer 2 encoder. | ||||
| */ | */ | ||||
| #include "libavutil/audioconvert.h" | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "put_bits.h" | #include "put_bits.h" | ||||
| @@ -792,6 +794,9 @@ AVCodec ff_mp2_encoder = { | |||||
| .supported_samplerates = (const int[]){ | .supported_samplerates = (const int[]){ | ||||
| 44100, 48000, 32000, 22050, 24000, 16000, 0 | 44100, 48000, 32000, 22050, 24000, 16000, 0 | ||||
| }, | }, | ||||
| .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, | |||||
| AV_CH_LAYOUT_STEREO, | |||||
| 0 }, | |||||
| .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), | .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), | ||||
| .defaults = mp2_defaults, | .defaults = mp2_defaults, | ||||
| }; | }; | ||||
| @@ -28,7 +28,7 @@ SECTION_RODATA | |||||
| cextern pw_255 | cextern pw_255 | ||||
| SECTION_TEXT 16 | |||||
| SECTION_TEXT | |||||
| ; %1 = nr. of xmm registers used | ; %1 = nr. of xmm registers used | ||||
| %macro ADD_BYTES_FN 1 | %macro ADD_BYTES_FN 1 | ||||
| @@ -131,6 +131,8 @@ const CodecMime ff_id3v2_mime_tags[] = { | |||||
| {"image/png" , AV_CODEC_ID_PNG}, | {"image/png" , AV_CODEC_ID_PNG}, | ||||
| {"image/tiff", AV_CODEC_ID_TIFF}, | {"image/tiff", AV_CODEC_ID_TIFF}, | ||||
| {"image/bmp", AV_CODEC_ID_BMP}, | {"image/bmp", AV_CODEC_ID_BMP}, | ||||
| {"JPG", AV_CODEC_ID_MJPEG}, /* ID3v2.2 */ | |||||
| {"PNG" , AV_CODEC_ID_PNG}, /* ID3v2.2 */ | |||||
| {"", AV_CODEC_ID_NONE}, | {"", AV_CODEC_ID_NONE}, | ||||
| }; | }; | ||||
| @@ -32,6 +32,15 @@ | |||||
| #define HMAC_IPAD_VAL 0x36 | #define HMAC_IPAD_VAL 0x36 | ||||
| #define HMAC_OPAD_VAL 0x5C | #define HMAC_OPAD_VAL 0x5C | ||||
| /** | |||||
| * A non-zero transaction id requires the server to send back | |||||
| * a _result or _error response. | |||||
| * Setting it to 0 marks the message as a notification not | |||||
| * requiring feedback. | |||||
| */ | |||||
| #define RTMP_NOTIFICATION 0 | |||||
| /** | /** | ||||
| * emulated Flash client version - 9.0.124.2 on Linux | * emulated Flash client version - 9.0.124.2 on Linux | ||||
| * @{ | * @{ | ||||
| @@ -91,6 +91,7 @@ typedef struct RTMPContext { | |||||
| char* flashver; ///< version of the flash plugin | char* flashver; ///< version of the flash plugin | ||||
| char* swfurl; ///< url of the swf player | char* swfurl; ///< url of the swf player | ||||
| char* pageurl; ///< url of the web page | char* pageurl; ///< url of the web page | ||||
| char* subscribe; ///< name of live stream to subscribe | |||||
| int server_bw; ///< server bandwidth | int server_bw; ///< server bandwidth | ||||
| int client_buffer_time; ///< client buffer time in ms | int client_buffer_time; ///< client buffer time in ms | ||||
| int flush_interval; ///< number of packets flushed in the same request (RTMPT only) | int flush_interval; ///< number of packets flushed in the same request (RTMPT only) | ||||
| @@ -572,7 +573,7 @@ static int gen_check_bw(URLContext *s, RTMPContext *rt) | |||||
| p = pkt.data; | p = pkt.data; | ||||
| ff_amf_write_string(&p, "_checkbw"); | ff_amf_write_string(&p, "_checkbw"); | ||||
| ff_amf_write_number(&p, ++rt->nb_invokes); | |||||
| ff_amf_write_number(&p, RTMP_NOTIFICATION); | |||||
| ff_amf_write_null(&p); | ff_amf_write_null(&p); | ||||
| ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, | ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, | ||||
| @@ -604,6 +605,30 @@ static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts) | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt, | |||||
| const char *subscribe) | |||||
| { | |||||
| RTMPPacket pkt; | |||||
| uint8_t *p; | |||||
| int ret; | |||||
| if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, | |||||
| 0, 27 + strlen(subscribe))) < 0) | |||||
| return ret; | |||||
| p = pkt.data; | |||||
| ff_amf_write_string(&p, "FCSubscribe"); | |||||
| ff_amf_write_number(&p, ++rt->nb_invokes); | |||||
| ff_amf_write_null(&p); | |||||
| ff_amf_write_string(&p, subscribe); | |||||
| ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, | |||||
| rt->prev_pkt[1]); | |||||
| ff_rtmp_packet_destroy(&pkt); | |||||
| return ret; | |||||
| } | |||||
| int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap, | int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap, | ||||
| const uint8_t *key, int keylen, uint8_t *dst) | const uint8_t *key, int keylen, uint8_t *dst) | ||||
| { | { | ||||
| @@ -1011,6 +1036,20 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt) | |||||
| } | } | ||||
| if ((ret = gen_create_stream(s, rt)) < 0) | if ((ret = gen_create_stream(s, rt)) < 0) | ||||
| return ret; | return ret; | ||||
| if (rt->is_input) { | |||||
| /* Send the FCSubscribe command when the name of live | |||||
| * stream is defined by the user or if it's a live stream. */ | |||||
| if (rt->subscribe) { | |||||
| if ((ret = gen_fcsubscribe_stream(s, rt, | |||||
| rt->subscribe)) < 0) | |||||
| return ret; | |||||
| } else if (rt->live == -1) { | |||||
| if ((ret = gen_fcsubscribe_stream(s, rt, | |||||
| rt->playpath)) < 0) | |||||
| return ret; | |||||
| } | |||||
| } | |||||
| break; | break; | ||||
| case STATE_FCPUBLISH: | case STATE_FCPUBLISH: | ||||
| rt->state = STATE_CONNECTING; | rt->state = STATE_CONNECTING; | ||||
| @@ -1593,115 +1632,35 @@ static const AVOption rtmp_options[] = { | |||||
| {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"}, | {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"}, | ||||
| {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC}, | {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC}, | ||||
| {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, | {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, | ||||
| {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC}, | |||||
| {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, | {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, | ||||
| {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, | {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, | ||||
| { NULL }, | { NULL }, | ||||
| }; | }; | ||||
| static const AVClass rtmp_class = { | |||||
| .class_name = "rtmp", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmp_protocol = { | |||||
| .name = "rtmp", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class= &rtmp_class, | |||||
| #define RTMP_PROTOCOL(flavor) \ | |||||
| static const AVClass flavor##_class = { \ | |||||
| .class_name = #flavor, \ | |||||
| .item_name = av_default_item_name, \ | |||||
| .option = rtmp_options, \ | |||||
| .version = LIBAVUTIL_VERSION_INT, \ | |||||
| }; \ | |||||
| \ | |||||
| URLProtocol ff_##flavor##_protocol = { \ | |||||
| .name = #flavor, \ | |||||
| .url_open = rtmp_open, \ | |||||
| .url_read = rtmp_read, \ | |||||
| .url_write = rtmp_write, \ | |||||
| .url_close = rtmp_close, \ | |||||
| .priv_data_size = sizeof(RTMPContext), \ | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, \ | |||||
| .priv_data_class= &flavor##_class, \ | |||||
| }; | }; | ||||
| static const AVClass rtmpe_class = { | |||||
| .class_name = "rtmpe", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmpe_protocol = { | |||||
| .name = "rtmpe", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class = &rtmpe_class, | |||||
| }; | |||||
| static const AVClass rtmps_class = { | |||||
| .class_name = "rtmps", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmps_protocol = { | |||||
| .name = "rtmps", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class = &rtmps_class, | |||||
| }; | |||||
| static const AVClass rtmpt_class = { | |||||
| .class_name = "rtmpt", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmpt_protocol = { | |||||
| .name = "rtmpt", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class = &rtmpt_class, | |||||
| }; | |||||
| static const AVClass rtmpte_class = { | |||||
| .class_name = "rtmpte", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmpte_protocol = { | |||||
| .name = "rtmpte", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class = &rtmpte_class, | |||||
| }; | |||||
| static const AVClass rtmpts_class = { | |||||
| .class_name = "rtmpts", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmpts_protocol = { | |||||
| .name = "rtmpts", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class = &rtmpts_class, | |||||
| }; | |||||
| RTMP_PROTOCOL(rtmp) | |||||
| RTMP_PROTOCOL(rtmpe) | |||||
| RTMP_PROTOCOL(rtmps) | |||||
| RTMP_PROTOCOL(rtmpt) | |||||
| RTMP_PROTOCOL(rtmpte) | |||||
| RTMP_PROTOCOL(rtmpts) | |||||
| @@ -31,7 +31,7 @@ | |||||
| #define LIBAVFORMAT_VERSION_MAJOR 54 | #define LIBAVFORMAT_VERSION_MAJOR 54 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 22 | #define LIBAVFORMAT_VERSION_MINOR 22 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 102 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 103 | |||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| LIBAVFORMAT_VERSION_MINOR, \ | LIBAVFORMAT_VERSION_MINOR, \ | ||||
| @@ -97,6 +97,8 @@ static av_always_inline av_const int FASTDIV(int a, int b) | |||||
| #endif /* HAVE_ARMV6 */ | #endif /* HAVE_ARMV6 */ | ||||
| #if HAVE_ASM_MOD_Q | |||||
| #define av_clipl_int32 av_clipl_int32_arm | #define av_clipl_int32 av_clipl_int32_arm | ||||
| static av_always_inline av_const int32_t av_clipl_int32_arm(int64_t a) | static av_always_inline av_const int32_t av_clipl_int32_arm(int64_t a) | ||||
| { | { | ||||
| @@ -110,6 +112,8 @@ static av_always_inline av_const int32_t av_clipl_int32_arm(int64_t a) | |||||
| return x; | return x; | ||||
| } | } | ||||
| #endif /* HAVE_ASM_MOD_Q */ | |||||
| #endif /* HAVE_INLINE_ASM */ | #endif /* HAVE_INLINE_ASM */ | ||||
| #endif /* AVUTIL_ARM_INTMATH_H */ | #endif /* AVUTIL_ARM_INTMATH_H */ | ||||
| @@ -61,6 +61,8 @@ static av_always_inline void AV_WN32(void *p, uint32_t v) | |||||
| __asm__ ("str %1, %0" : "=m"(*(uint32_t *)p) : "r"(v)); | __asm__ ("str %1, %0" : "=m"(*(uint32_t *)p) : "r"(v)); | ||||
| } | } | ||||
| #if HAVE_ASM_MOD_Q | |||||
| #define AV_RN64 AV_RN64 | #define AV_RN64 AV_RN64 | ||||
| static av_always_inline uint64_t AV_RN64(const void *p) | static av_always_inline uint64_t AV_RN64(const void *p) | ||||
| { | { | ||||
| @@ -82,6 +84,8 @@ static av_always_inline void AV_WN64(void *p, uint64_t v) | |||||
| : "r"(v)); | : "r"(v)); | ||||
| } | } | ||||
| #endif /* HAVE_ASM_MOD_Q */ | |||||
| #endif /* HAVE_INLINE_ASM */ | #endif /* HAVE_INLINE_ASM */ | ||||
| #endif /* AVUTIL_ARM_INTREADWRITE_H */ | #endif /* AVUTIL_ARM_INTREADWRITE_H */ | ||||
| @@ -20,7 +20,7 @@ $(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm | |||||
| $(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d) | $(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d) | ||||
| $(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $< | $(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $< | ||||
| $(OBJS) $(OBJS:.o=.s) $(SUBDIR)%.ho $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H | |||||
| $(OBJS) $(OBJS:.o=.s) $(SUBDIR)%.h.o $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H | |||||
| $(TESTOBJS): CPPFLAGS += -DTEST | $(TESTOBJS): CPPFLAGS += -DTEST | ||||
| $(SUBDIR)$(LIBNAME): $(OBJS) | $(SUBDIR)$(LIBNAME): $(OBJS) | ||||
| @@ -87,7 +87,7 @@ uninstall-libs:: | |||||
| -$(RM) "$(LIBDIR)/$(LIBNAME)" | -$(RM) "$(LIBDIR)/$(LIBNAME)" | ||||
| uninstall-headers:: | uninstall-headers:: | ||||
| $(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS)) $(addprefix "$(INCINSTDIR)/",$(BUILT_HEADERS)) | |||||
| $(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS) $(BUILT_HEADERS)) | |||||
| $(RM) "$(LIBDIR)/pkgconfig/lib$(NAME).pc" | $(RM) "$(LIBDIR)/pkgconfig/lib$(NAME).pc" | ||||
| -rmdir "$(INCINSTDIR)" | -rmdir "$(INCINSTDIR)" | ||||
| endef | endef | ||||
| @@ -167,8 +167,14 @@ FATE_VIDEO += fate-mpeg2-field-enc | |||||
| fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an | fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an | ||||
| # FIXME dropped frames in this test because of coarse timebase | # FIXME dropped frames in this test because of coarse timebase | ||||
| FATE_VIDEO += fate-nuv | |||||
| fate-nuv: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv -an | |||||
| FATE_NUV += fate-nuv-rtjpeg | |||||
| fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv -an | |||||
| FATE_NUV += fate-nuv-rtjpeg-fh | |||||
| fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/rtjpeg_frameheader.nuv -an | |||||
| FATE_VIDEO += $(FATE_NUV) | |||||
| fate-nuv: $(FATE_NUV) | |||||
| FATE_VIDEO += fate-paf-video | FATE_VIDEO += fate-paf-video | ||||
| fate-paf-video: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an | fate-paf-video: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an | ||||
| @@ -1,4 +1,4 @@ | |||||
| dec0deb2425e908d232d2471acff04a3 *tests/data/fate/acodec-g723_1.g723_1 | dec0deb2425e908d232d2471acff04a3 *tests/data/fate/acodec-g723_1.g723_1 | ||||
| 4800 tests/data/fate/acodec-g723_1.g723_1 | 4800 tests/data/fate/acodec-g723_1.g723_1 | ||||
| 87fd529c9e41914f73a865d147cc9516 *tests/data/fate/acodec-g723_1.out.wav | |||||
| stddev: 8425.98 PSNR: 17.82 MAXDIFF:53268 bytes: 95992/ 96000 | |||||
| d70776846d77c652bceed281fcca9cc8 *tests/data/fate/acodec-g723_1.out.wav | |||||
| stddev: 8423.47 PSNR: 17.82 MAXDIFF:53292 bytes: 95992/ 96000 | |||||
| @@ -0,0 +1,51 @@ | |||||
| #tb 0: 1/50 | |||||
| 0, 0, 0, 1, 221184, 0xf48c94f6 | |||||
| 0, 2, 2, 1, 221184, 0x89b625b2 | |||||
| 0, 3, 3, 1, 221184, 0x37e04714 | |||||
| 0, 4, 4, 1, 221184, 0x4f4c5224 | |||||
| 0, 5, 5, 1, 221184, 0x9193c9f1 | |||||
| 0, 6, 6, 1, 221184, 0x5d1a6197 | |||||
| 0, 7, 7, 1, 221184, 0x40cd51e7 | |||||
| 0, 8, 8, 1, 221184, 0xb2c1a729 | |||||
| 0, 10, 10, 1, 221184, 0x998d6144 | |||||
| 0, 11, 11, 1, 221184, 0xf5d52311 | |||||
| 0, 12, 12, 1, 221184, 0xea9dd6bf | |||||
| 0, 13, 13, 1, 221184, 0x0e2ed854 | |||||
| 0, 14, 14, 1, 221184, 0xe295ba58 | |||||
| 0, 15, 15, 1, 221184, 0x8aedbb69 | |||||
| 0, 16, 16, 1, 221184, 0x253c9aaa | |||||
| 0, 17, 17, 1, 221184, 0x5eaf9fb1 | |||||
| 0, 18, 18, 1, 221184, 0xcdb5a0cb | |||||
| 0, 19, 19, 1, 221184, 0xcdb5a0cb | |||||
| 0, 20, 20, 1, 221184, 0x23f89994 | |||||
| 0, 21, 21, 1, 221184, 0x23f89994 | |||||
| 0, 22, 22, 1, 221184, 0x10dc98d6 | |||||
| 0, 23, 23, 1, 221184, 0x799b9d98 | |||||
| 0, 24, 24, 1, 221184, 0xb226996c | |||||
| 0, 25, 25, 1, 221184, 0x0ac59a42 | |||||
| 0, 26, 26, 1, 221184, 0x87c2a654 | |||||
| 0, 27, 27, 1, 221184, 0xf4c1a711 | |||||
| 0, 28, 28, 1, 221184, 0xf60fa72e | |||||
| 0, 29, 29, 1, 221184, 0xc8f8b6fc | |||||
| 0, 30, 30, 1, 221184, 0xd709b813 | |||||
| 0, 31, 31, 1, 221184, 0x5fdfb76b | |||||
| 0, 32, 32, 1, 221184, 0x5798b0aa | |||||
| 0, 33, 33, 1, 221184, 0xf572b1c3 | |||||
| 0, 34, 34, 1, 221184, 0x14b0afdf | |||||
| 0, 35, 35, 1, 221184, 0x0a66b5b8 | |||||
| 0, 36, 36, 1, 221184, 0xe316c620 | |||||
| 0, 37, 37, 1, 221184, 0xbc76c5c2 | |||||
| 0, 38, 38, 1, 221184, 0x77c7c5e5 | |||||
| 0, 39, 39, 1, 221184, 0xfc7ac63e | |||||
| 0, 40, 40, 1, 221184, 0x05a29ffe | |||||
| 0, 41, 41, 1, 221184, 0x9bffbf6c | |||||
| 0, 42, 42, 1, 221184, 0x3c55be40 | |||||
| 0, 43, 43, 1, 221184, 0x6f46c14e | |||||
| 0, 44, 44, 1, 221184, 0x9cf4ae70 | |||||
| 0, 45, 45, 1, 221184, 0xf205b2f8 | |||||
| 0, 46, 46, 1, 221184, 0x7180aff8 | |||||
| 0, 47, 47, 1, 221184, 0x125eaffe | |||||
| 0, 48, 48, 1, 221184, 0x6970a32d | |||||
| 0, 49, 49, 1, 221184, 0xaea79f62 | |||||
| 0, 50, 50, 1, 221184, 0x48d2a093 | |||||
| 0, 51, 51, 1, 221184, 0x10a59eb5 | |||||