* qatar/master: (23 commits) x86inc: use sse versions of common macros instead of sse2 when applicable doc/APIchanges: add missing dates and hashes lavf: don't return from void av_update_cur_dts() Changelog: add more entries. Changelog: update ffmpeg/avconv incompatibility list. avconv: remove some redundant temporary variables. avconv: fix broken indentation avconv: move copy_initial_nonkeyframes to the options context. avconv: use file:stream instead of file.stream in log messages. doc/avconv: elaborate on basic functionality. doc/avconv: -sample_fmts, not -help sample_fmts prints the sample formats openssl: Only use CRYPTO_set_id_callback on OpenSSL < 1.0.0 Call avformat_network_init/deinit in the programs Remove leftover includes of strings.h avutil: Don't allow using strcasecmp/strncasecmp Replace all usage of strcasecmp/strncasecmp avstring: Add locale independent implementations of strcasecmp/strncasecmp avstring: Add locale independent implementations of toupper/tolower cosmetics: insert some spaces in explicit enum value assignments move 8SVX audio codecs to the audio codec list part on the next bump ... Conflicts: avprobe.c doc/APIchanges ffplay.c ffserver.c libavcodec/avcodec.h libavdevice/bktr.c libavdevice/v4l.c libavdevice/v4l2.c libavformat/matroskaenc.c libavformat/wtv.c libavutil/avstring.c libavutil/avstring.h libavutil/avutil.h libswscale/x86/swscale_template.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
| @@ -11,37 +11,72 @@ version next: | |||
| - added avconv, which is almost the same for now, except | |||
| for a few incompatible changes in the options, which will hopefully make them | |||
| easier to use. The changes are: | |||
| * -newvideo/-newaudio/-newsubtitle are gone, because they were redundant and | |||
| worked in a nonstandard way. -map is sufficient to add streams to output | |||
| files. | |||
| * -map now has slightly different and more powerful syntax. | |||
| + it's possible to specify stream type. E.g. -map 0:a:2 means 'third | |||
| audio stream'. | |||
| + omitting the stream index now maps all the streams of the given | |||
| type, not just the first. E.g. -map 0:s maps all the subtitle streams. | |||
| + colons (':') are used to separate file index/stream type/stream | |||
| index. Comma (',') is used to separate the sync stream. This is done | |||
| for consistency with other options. | |||
| + since -map can now match multiple streams, negative mappings were | |||
| * The options placement is now strictly enforced! While in theory the | |||
| options for ffmpeg should be given in [input options] -i INPUT [output | |||
| options] OUTPUT order, in practice it was possible to give output options | |||
| before the -i and it mostly worked. Except when it didn't - the behavior was | |||
| a bit inconsistent. In avconv, it is not possible to mix input and output | |||
| options. All non-global options are reset after an input or output filename. | |||
| * All per-file options are now truly per-file - they apply only to the next | |||
| input or output file and specifying different values for different files | |||
| will now work properly (notably -ss and -t options). | |||
| * All per-stream options are now truly per-stream - it is possible to | |||
| specify which stream(s) should a given option apply to. See the Stream | |||
| specifiers section in the avconv manual for details. | |||
| * In ffmpeg some options (like -newvideo/-newaudio/...) are irregular in the | |||
| sense that they're specified after the output filename instead of before, | |||
| like all other options. In avconv this irregularity is removed, all options | |||
| apply to the next input or output file. | |||
| * -newvideo/-newaudio/-newsubtitle options were removed. Not only were they | |||
| irregular and highly confusing, they were also redundant. In avconv the -map | |||
| option will create new streams in the output file and map input streams to | |||
| them. E.g. avconv -i INPUT -map 0 OUTPUT will create an output stream for | |||
| each stream in the first input file. | |||
| * The -map option now has slightly different and more powerful syntax: | |||
| + Colons (':') are used to separate file index/stream type/stream index | |||
| instead of dots. Comma (',') is used to separate the sync stream instead | |||
| of colon.. This is done for consistency with other options. | |||
| + It's possible to specify stream type. E.g. -map 0:a:2 creates an | |||
| output stream from the third input audio stream. | |||
| + Omitting the stream index now maps all the streams of the given type, | |||
| not just the first. E.g. -map 0:s creates output streams for all the | |||
| subtitle streams in the first input file. | |||
| + Since -map can now match multiple streams, negative mappings were | |||
| introduced. Negative mappings disable some streams from an already | |||
| defined map. E.g. '-map 0 -map -0:a:1' means 'map everything except | |||
| for the second audio stream'. | |||
| * -vcodec/-acodec/-scodec are replaced by -c (or -codec), which | |||
| allows to precisely specify target stream(s) consistently with other | |||
| options. E.g. '-c:v libx264' sets the codec for all video streams, | |||
| '-c:a:0 libvorbis' sets the codec for the first audio stream and '-c | |||
| copy' copies all the streams. | |||
| defined map. E.g. '-map 0 -map -0:a:1' means 'create output streams for | |||
| all the stream in the first input file, except for the second audio | |||
| stream'. | |||
| * There is a new option -c (or -codec) for choosing the decoder/encoder to | |||
| use, which allows to precisely specify target stream(s) consistently with | |||
| other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0 | |||
| libvorbis sets the codec for the first audio stream and -c copy copies all | |||
| the streams without reencoding. Old -vcodec/-acodec/-scodec options are now | |||
| aliases to -c:v/a/s | |||
| * It is now possible to precisely specify which stream should an AVOption | |||
| apply to. See the manual for detailed explanation. | |||
| apply to. E.g. -b:v:0 2M sets the bitrate for the first video stream, while | |||
| -b:a 128k sets the bitrate for all audio streams. Note that the old -ab 128k | |||
| syntax is deprecated and will stop working soon. | |||
| * -map_chapters now takes only an input file index and applies to the next | |||
| output file. This is consistent with how all the other options work. | |||
| * -map_metadata now takes only an input metadata specifier and applies to | |||
| the next output file. Output metadata specifier is now part of the option | |||
| name, similarly to the AVOptions/map/codec feature above. | |||
| * Presets in avconv are disabled, because only libx264 used them and | |||
| presets for libx264 can now be specified using a private option | |||
| '-preset <presetname>'. | |||
| * -intra option was removed, it's equivalent to -g 0. | |||
| * -metadata can now be used to set metadata on streams and chapters, e.g. | |||
| -metadata:s:1 language=eng sets the language of the first stream to 'eng'. | |||
| This made -vlang/-alang/-slang options redundant, so they were removed. | |||
| * -qscale option now uses stream specifiers and applies to all streams, not | |||
| just video. I.e. plain -qscale number would now apply to all streams. To get | |||
| the old behavior, use -qscale:v. Also there is now a shortcut -q for -qscale | |||
| and -aq is now an alias for -q:a. | |||
| * -vbsf/-absf/-sbsf options were removed and replaced by a -bsf option which | |||
| uses stream specifiers. Use -bsf:v/a/s instead of the old options. | |||
| * -itsscale option now uses stream specifiers, so its argument is only the | |||
| scale parameter. | |||
| * -intra option was removed, use -g 0 for the same effect. | |||
| * -psnr option was removed, use -flags +psnr for the same effect. | |||
| * -vf option is now an alias to the new -filter option, which uses stream specifiers. | |||
| * -vframes/-aframes/-dframes options are now aliases to the new -frames option. | |||
| * -vtag/-atag/-stag options are now aliases to the new -tag option. | |||
| - XMV demuxer | |||
| - LOAS demuxer | |||
| - ashowinfo filter added | |||
| @@ -68,6 +103,7 @@ easier to use. The changes are: | |||
| - Ut Video decoder | |||
| - Speex encoding via libspeex | |||
| - 4:2:2 H.264 decoding support | |||
| - 4:2:2 and 4:4:4 H.264 encoding with libx264 | |||
| - Pulseaudio input device | |||
| - Prores encoder | |||
| - Video Decoder Acceleration (VDA) HWAccel module. | |||
| @@ -77,6 +113,11 @@ easier to use. The changes are: | |||
| - earwax audio filter added | |||
| - libv4l2 support (--enable-libv4l2) | |||
| - TLS/SSL and HTTPS protocol support | |||
| - AVOptions API rewritten and documented | |||
| - most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in | |||
| AVCodecContext deprecated. Codec private options should be used instead. | |||
| - Properly working defaults in libx264 wrapper, support for native presets. | |||
| - Encrypted OMA files support | |||
| version 0.8: | |||
| @@ -132,7 +132,6 @@ static int copy_tb= 0; | |||
| static int opt_shortest = 0; | |||
| static char *vstats_filename; | |||
| static FILE *vstats_file; | |||
| static int copy_initial_nonkeyframes = 0; | |||
| static int audio_volume = 256; | |||
| @@ -240,11 +239,12 @@ typedef struct OutputStream { | |||
| AVFilterGraph *graph; | |||
| #endif | |||
| int64_t sws_flags; | |||
| AVDictionary *opts; | |||
| int is_past_recording_time; | |||
| int stream_copy; | |||
| const char *attachment_filename; | |||
| int64_t sws_flags; | |||
| AVDictionary *opts; | |||
| int is_past_recording_time; | |||
| int stream_copy; | |||
| const char *attachment_filename; | |||
| int copy_initial_nonkeyframes; | |||
| } OutputStream; | |||
| #if HAVE_TERMIOS_H | |||
| @@ -355,6 +355,8 @@ typedef struct OptionsContext { | |||
| int nb_top_field_first; | |||
| SpecifierOpt *presets; | |||
| int nb_presets; | |||
| SpecifierOpt *copy_initial_nonkeyframes; | |||
| int nb_copy_initial_nonkeyframes; | |||
| #if CONFIG_AVFILTER | |||
| SpecifierOpt *filters; | |||
| int nb_filters; | |||
| @@ -628,6 +630,7 @@ void exit_program(int ret) | |||
| #if CONFIG_AVFILTER | |||
| avfilter_uninit(); | |||
| #endif | |||
| avformat_network_deinit(); | |||
| if (received_sigterm) { | |||
| av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n", | |||
| @@ -822,7 +825,7 @@ need_realloc: | |||
| if ((ost->audio_resample && !ost->resample) || resample_changed) { | |||
| if (resample_changed) { | |||
| av_log(NULL, AV_LOG_INFO, "Input stream #%d.%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n", | |||
| av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n", | |||
| ist->file_index, ist->st->index, | |||
| ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels, | |||
| dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels); | |||
| @@ -1137,7 +1140,7 @@ static void do_video_resample(OutputStream *ost, | |||
| #if !CONFIG_AVFILTER | |||
| if (resample_changed) { | |||
| av_log(NULL, AV_LOG_INFO, | |||
| "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", | |||
| "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", | |||
| ist->file_index, ist->st->index, | |||
| ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt), | |||
| dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt)); | |||
| @@ -1886,7 +1889,8 @@ static int output_packet(InputStream *ist, int ist_index, | |||
| int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); | |||
| av_init_packet(&opkt); | |||
| if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes) | |||
| if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && | |||
| !ost->copy_initial_nonkeyframes) | |||
| #if !CONFIG_AVFILTER | |||
| continue; | |||
| #else | |||
| @@ -1994,13 +1998,13 @@ static int init_input_stream(int ist_index, OutputStream *output_streams, int nb | |||
| if (ist->decoding_needed) { | |||
| AVCodec *codec = ist->dec; | |||
| if (!codec) { | |||
| snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d.%d", | |||
| snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d", | |||
| ist->st->codec->codec_id, ist->file_index, ist->st->index); | |||
| return AVERROR(EINVAL); | |||
| } | |||
| if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) { | |||
| snprintf(error, error_len, "Error while opening decoder for input stream #%d.%d", | |||
| snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d", | |||
| ist->file_index, ist->st->index); | |||
| return AVERROR(EINVAL); | |||
| } | |||
| @@ -2280,7 +2284,7 @@ static int transcode_init(OutputFile *output_files, | |||
| AVCodec *codec = ost->enc; | |||
| AVCodecContext *dec = input_streams[ost->source_index].st->codec; | |||
| if (!codec) { | |||
| snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d", | |||
| snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d:%d", | |||
| ost->st->codec->codec_id, ost->file_index, ost->index); | |||
| ret = AVERROR(EINVAL); | |||
| goto dump_format; | |||
| @@ -2295,7 +2299,7 @@ static int transcode_init(OutputFile *output_files, | |||
| ost->st->codec->subtitle_header_size = dec->subtitle_header_size; | |||
| } | |||
| if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) { | |||
| snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height", | |||
| snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height", | |||
| ost->file_index, ost->index); | |||
| ret = AVERROR(EINVAL); | |||
| goto dump_format; | |||
| @@ -2365,13 +2369,13 @@ static int transcode_init(OutputFile *output_files, | |||
| ost->attachment_filename, ost->file_index, ost->index); | |||
| continue; | |||
| } | |||
| av_log(NULL, AV_LOG_INFO, " Stream #%d.%d -> #%d.%d", | |||
| av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d", | |||
| input_streams[ost->source_index].file_index, | |||
| input_streams[ost->source_index].st->index, | |||
| ost->file_index, | |||
| ost->index); | |||
| if (ost->sync_ist != &input_streams[ost->source_index]) | |||
| av_log(NULL, AV_LOG_INFO, " [sync #%d.%d]", | |||
| av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]", | |||
| ost->sync_ist->file_index, | |||
| ost->sync_ist->st->index); | |||
| if (ost->stream_copy) | |||
| @@ -2591,7 +2595,7 @@ static int transcode(OutputFile *output_files, | |||
| //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size); | |||
| if (output_packet(ist, ist_index, output_streams, nb_output_streams, &pkt) < 0) { | |||
| av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d.%d\n", | |||
| av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", | |||
| ist->file_index, ist->st->index); | |||
| if (exit_on_error) | |||
| exit_program(1); | |||
| @@ -2909,7 +2913,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) | |||
| AVStream *st = ic->streams[i]; | |||
| AVCodecContext *dec = st->codec; | |||
| InputStream *ist; | |||
| double scale = 1.0; | |||
| input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1); | |||
| ist = &input_streams[nb_input_streams - 1]; | |||
| @@ -2918,8 +2921,8 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) | |||
| ist->discard = 1; | |||
| ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st); | |||
| MATCH_PER_STREAM_OPT(ts_scale, dbl, scale, ic, st); | |||
| ist->ts_scale = scale; | |||
| ist->ts_scale = 1.0; | |||
| MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st); | |||
| ist->dec = choose_decoder(o, ic, st); | |||
| @@ -3231,7 +3234,6 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | |||
| OutputStream *ost; | |||
| AVStream *st = avformat_new_stream(oc, NULL); | |||
| int idx = oc->nb_streams - 1, ret = 0; | |||
| int64_t max_frames = INT64_MAX; | |||
| char *bsf = NULL, *next, *codec_tag = NULL; | |||
| AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | |||
| double qscale = -1; | |||
| @@ -3286,8 +3288,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | |||
| exit_program(1); | |||
| } | |||
| MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | |||
| ost->max_frames = max_frames; | |||
| ost->max_frames = INT64_MAX; | |||
| MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st); | |||
| MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st); | |||
| while (bsf) { | |||
| @@ -3359,7 +3361,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) | |||
| char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL; | |||
| char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL; | |||
| char *intra_matrix = NULL, *inter_matrix = NULL, *filters = NULL; | |||
| int i, force_fps = 0, top_field_first = -1; | |||
| int i; | |||
| MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st); | |||
| if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) { | |||
| @@ -3443,11 +3445,12 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) | |||
| if (forced_key_frames) | |||
| parse_forced_key_frames(forced_key_frames, ost, video_enc); | |||
| MATCH_PER_STREAM_OPT(force_fps, i, force_fps, oc, st); | |||
| ost->force_fps = force_fps; | |||
| MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st); | |||
| ost->top_field_first = -1; | |||
| MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st); | |||
| MATCH_PER_STREAM_OPT(top_field_first, i, top_field_first, oc, st); | |||
| ost->top_field_first = top_field_first; | |||
| MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st); | |||
| #if CONFIG_AVFILTER | |||
| MATCH_PER_STREAM_OPT(filters, str, filters, oc, st); | |||
| @@ -3711,7 +3714,7 @@ static void opt_output_file(void *optctx, const char *filename) | |||
| case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break; | |||
| case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break; | |||
| default: | |||
| av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d.%d - unsupported type.\n", | |||
| av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n", | |||
| map->file_index, map->stream_index); | |||
| exit_program(1); | |||
| } | |||
| @@ -4248,7 +4251,7 @@ static const OptionDef options[] = { | |||
| { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, // | |||
| { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" }, | |||
| { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" }, | |||
| { "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)©_initial_nonkeyframes}, "copy initial non-keyframes" }, | |||
| { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC, {.off = OFFSET(copy_initial_nonkeyframes)}, "copy initial non-keyframes" }, | |||
| { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC, {.off = OFFSET(max_frames)}, "set the number of frames to record", "number" }, | |||
| { "tag", OPT_STRING | HAS_ARG | OPT_SPEC, {.off = OFFSET(codec_tags)}, "force codec tag/fourcc", "fourcc/tag" }, | |||
| { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" }, | |||
| @@ -4349,6 +4352,7 @@ int main(int argc, char **argv) | |||
| avfilter_register_all(); | |||
| #endif | |||
| av_register_all(); | |||
| avformat_network_init(); | |||
| #if HAVE_ISATTY | |||
| if(isatty(STDIN_FILENO)) | |||
| @@ -19,7 +19,13 @@ API changes, most recent first: | |||
| 2011-10-20 - b35e9e1 - lavu 51.22.0 | |||
| Add av_strtok() to avstring.h. | |||
| 2011-11-xx - xxxxxxx - lavf 53.13.0 | |||
| 2011-11-06 - ba04ecf - lavu 51.14.0 | |||
| Add av_strcasecmp() and av_strncasecmp() to avstring.h. | |||
| 2011-11-06 - 07b172f - lavu 51.13.0 | |||
| Add av_toupper()/av_tolower() | |||
| 2011-11-05 - b6d08f4 - lavf 53.13.0 | |||
| Add avformat_network_init()/avformat_network_uninit() | |||
| 2011-10-27 - 512557b - lavc 53.15.0 | |||
| @@ -26,6 +26,23 @@ avconv is a very fast video and audio converter that can also grab from | |||
| a live audio/video source. It can also convert between arbitrary sample | |||
| rates and resize video on the fly with a high quality polyphase filter. | |||
| avconv reads from an arbitrary number of input "files" (which can be regular | |||
| files, pipes, network streams, grabbing devices, etc.), specified by the | |||
| @code{-i} option, and writes to an arbitrary number of output "files", which are | |||
| specified by a plain output filename. Anything found on the commandline which | |||
| cannot be interpreted as an option is considered to be an output filename. | |||
| Each input or output file can in principle contain any number of streams of | |||
| different types (video/audio/subtitle/attachment/data). Allowed number and/or | |||
| types of streams can be limited by the container format. Selecting, which | |||
| streams from which inputs go into output, is done either automatically or with | |||
| the @code{-map} option (see the Stream selection chapter). | |||
| To refer to input files in options, you must use their indices (0-based). E.g. | |||
| the first input file is @code{0}, the second is @code{1} etc. Similarly, streams | |||
| within a file are referred to by their indices. E.g. @code{2:3} refers to the | |||
| fourth stream in the third input file. See also the Stream specifiers chapter. | |||
| As a general rule, options are applied to the next specified | |||
| file. Therefore, order is important, and you can have the same | |||
| option on the command line multiple times. Each occurrence is | |||
| @@ -33,6 +50,10 @@ then applied to the next input or output file. | |||
| Exceptions from this rule are the global options (e.g. verbosity level), | |||
| which should be specified first. | |||
| Do not mix input and output files -- first specify all input files, then all | |||
| output files. Also do not mix options which belong to different files. All | |||
| options apply ONLY to the next input or output file and are reset between files. | |||
| @itemize | |||
| @item | |||
| To set the video bitrate of the output file to 64kbit/s: | |||
| @@ -525,6 +546,10 @@ frames after each specified time. | |||
| This option can be useful to ensure that a seek point is present at a | |||
| chapter mark or any other designated place in the output file. | |||
| The timestamps must be specified in ascending order. | |||
| @item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream}) | |||
| When doing stream copy, copy also non-key frames found at the | |||
| beginning. | |||
| @end table | |||
| @section Audio Options | |||
| @@ -549,7 +574,7 @@ Disable audio recording. | |||
| @item -acodec @var{codec} (@emph{input/output}) | |||
| Set the audio codec. This is an alias for @code{-codec:a}. | |||
| @item -sample_fmt[:@var{stream_specifier}] @var{sample_fmt} (@emph{output,per-stream}) | |||
| Set the audio sample format. Use @code{-help sample_fmts} to get a list | |||
| Set the audio sample format. Use @code{-sample_fmts} to get a list | |||
| of supported sample formats. | |||
| @end table | |||
| @@ -144,7 +144,6 @@ static int copy_tb= 0; | |||
| static int opt_shortest = 0; | |||
| static char *vstats_filename; | |||
| static FILE *vstats_file; | |||
| static int copy_initial_nonkeyframes = 0; | |||
| static int audio_volume = 256; | |||
| @@ -255,11 +254,12 @@ typedef struct OutputStream { | |||
| AVFilterGraph *graph; | |||
| #endif | |||
| int64_t sws_flags; | |||
| AVDictionary *opts; | |||
| int is_past_recording_time; | |||
| int stream_copy; | |||
| const char *attachment_filename; | |||
| int64_t sws_flags; | |||
| AVDictionary *opts; | |||
| int is_past_recording_time; | |||
| int stream_copy; | |||
| const char *attachment_filename; | |||
| int copy_initial_nonkeyframes; | |||
| } OutputStream; | |||
| @@ -375,6 +375,8 @@ typedef struct OptionsContext { | |||
| int nb_top_field_first; | |||
| SpecifierOpt *presets; | |||
| int nb_presets; | |||
| SpecifierOpt *copy_initial_nonkeyframes; | |||
| int nb_copy_initial_nonkeyframes; | |||
| #if CONFIG_AVFILTER | |||
| SpecifierOpt *filters; | |||
| int nb_filters; | |||
| @@ -569,6 +571,7 @@ static void term_init(void) | |||
| signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ | |||
| } | |||
| #endif | |||
| avformat_network_deinit(); | |||
| signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ | |||
| signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ | |||
| @@ -672,6 +675,7 @@ void exit_program(int ret) | |||
| #if CONFIG_AVFILTER | |||
| avfilter_uninit(); | |||
| #endif | |||
| avformat_network_deinit(); | |||
| av_freep(&input_tmp); | |||
| @@ -869,7 +873,7 @@ need_realloc: | |||
| if ((ost->audio_resample && !ost->swr) || resample_changed || ost->audio_channels_mapped) { | |||
| if (resample_changed) { | |||
| av_log(NULL, AV_LOG_INFO, "Input stream #%d.%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n", | |||
| av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n", | |||
| ist->file_index, ist->st->index, | |||
| ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels, | |||
| dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels); | |||
| @@ -1165,7 +1169,7 @@ static void do_video_resample(OutputStream *ost, | |||
| *out_picture = in_picture; | |||
| if (resample_changed) { | |||
| av_log(NULL, AV_LOG_INFO, | |||
| "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", | |||
| "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", | |||
| ist->file_index, ist->st->index, | |||
| ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt), | |||
| dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt)); | |||
| @@ -1918,7 +1922,8 @@ static int output_packet(InputStream *ist, int ist_index, | |||
| int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); | |||
| av_init_packet(&opkt); | |||
| if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes) | |||
| if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && | |||
| !ost->copy_initial_nonkeyframes) | |||
| #if !CONFIG_AVFILTER | |||
| continue; | |||
| #else | |||
| @@ -2024,12 +2029,12 @@ static int init_input_stream(int ist_index, OutputStream *output_streams, int nb | |||
| if (ist->decoding_needed) { | |||
| AVCodec *codec = ist->dec; | |||
| if (!codec) { | |||
| snprintf(error, error_len, "Decoder (codec %s) not found for input stream #%d.%d", | |||
| snprintf(error, error_len, "Decoder (codec %s) not found for input stream #%d:%d", | |||
| avcodec_get_name(ist->st->codec->codec_id), ist->file_index, ist->st->index); | |||
| return AVERROR(EINVAL); | |||
| } | |||
| if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) { | |||
| snprintf(error, error_len, "Error while opening decoder for input stream #%d.%d", | |||
| snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d", | |||
| ist->file_index, ist->st->index); | |||
| return AVERROR(EINVAL); | |||
| } | |||
| @@ -2330,7 +2335,7 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, | |||
| AVCodec *codec = ost->enc; | |||
| AVCodecContext *dec = input_streams[ost->source_index].st->codec; | |||
| if (!codec) { | |||
| snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d.%d", | |||
| snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d:%d", | |||
| avcodec_get_name(ost->st->codec->codec_id), ost->file_index, ost->index); | |||
| ret = AVERROR(EINVAL); | |||
| goto dump_format; | |||
| @@ -2345,7 +2350,7 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, | |||
| ost->st->codec->subtitle_header_size = dec->subtitle_header_size; | |||
| } | |||
| if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) { | |||
| snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height", | |||
| snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height", | |||
| ost->file_index, ost->index); | |||
| ret = AVERROR(EINVAL); | |||
| goto dump_format; | |||
| @@ -2415,7 +2420,7 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, | |||
| ost->attachment_filename, ost->file_index, ost->index); | |||
| continue; | |||
| } | |||
| av_log(NULL, AV_LOG_INFO, " Stream #%d.%d -> #%d.%d", | |||
| av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d", | |||
| input_streams[ost->source_index].file_index, | |||
| input_streams[ost->source_index].st->index, | |||
| ost->file_index, | |||
| @@ -2430,7 +2435,7 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, | |||
| av_log(NULL, AV_LOG_INFO, "]"); | |||
| } | |||
| if (ost->sync_ist != &input_streams[ost->source_index]) | |||
| av_log(NULL, AV_LOG_INFO, " [sync #%d.%d]", | |||
| av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]", | |||
| ost->sync_ist->file_index, | |||
| ost->sync_ist->st->index); | |||
| if (ost->stream_copy) | |||
| @@ -2691,7 +2696,7 @@ static int transcode(OutputFile *output_files, int nb_output_files, | |||
| //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size); | |||
| if (output_packet(ist, ist_index, output_streams, nb_output_streams, &pkt) < 0) { | |||
| av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d.%d\n", | |||
| av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", | |||
| ist->file_index, ist->st->index); | |||
| if (exit_on_error) | |||
| exit_program(1); | |||
| @@ -3114,7 +3119,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) | |||
| AVStream *st = ic->streams[i]; | |||
| AVCodecContext *dec = st->codec; | |||
| InputStream *ist; | |||
| double scale = 1.0; | |||
| input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1); | |||
| ist = &input_streams[nb_input_streams - 1]; | |||
| @@ -3123,8 +3127,8 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) | |||
| ist->discard = 1; | |||
| ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st); | |||
| MATCH_PER_STREAM_OPT(ts_scale, dbl, scale, ic, st); | |||
| ist->ts_scale = scale; | |||
| ist->ts_scale = 1.0; | |||
| MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st); | |||
| MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st); | |||
| if (codec_tag) { | |||
| @@ -3454,7 +3458,6 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | |||
| OutputStream *ost; | |||
| AVStream *st = avformat_new_stream(oc, NULL); | |||
| int idx = oc->nb_streams - 1, ret = 0; | |||
| int64_t max_frames = INT64_MAX; | |||
| char *bsf = NULL, *next, *codec_tag = NULL; | |||
| AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | |||
| double qscale = -1; | |||
| @@ -3509,8 +3512,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | |||
| exit_program(1); | |||
| } | |||
| MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | |||
| ost->max_frames = max_frames; | |||
| ost->max_frames = INT64_MAX; | |||
| MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st); | |||
| MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st); | |||
| while (bsf) { | |||
| @@ -3582,7 +3585,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) | |||
| char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL; | |||
| char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL; | |||
| char *intra_matrix = NULL, *inter_matrix = NULL, *filters = NULL; | |||
| int i, force_fps = 0, top_field_first = -1; | |||
| int i; | |||
| MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st); | |||
| if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) { | |||
| @@ -3671,11 +3674,12 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) | |||
| if (forced_key_frames) | |||
| parse_forced_key_frames(forced_key_frames, ost); | |||
| MATCH_PER_STREAM_OPT(force_fps, i, force_fps, oc, st); | |||
| ost->force_fps = force_fps; | |||
| MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st); | |||
| ost->top_field_first = -1; | |||
| MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st); | |||
| MATCH_PER_STREAM_OPT(top_field_first, i, top_field_first, oc, st); | |||
| ost->top_field_first = top_field_first; | |||
| MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st); | |||
| #if CONFIG_AVFILTER | |||
| MATCH_PER_STREAM_OPT(filters, str, filters, oc, st); | |||
| @@ -3980,7 +3984,7 @@ static void opt_output_file(void *optctx, const char *filename) | |||
| case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break; | |||
| case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break; | |||
| default: | |||
| av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d.%d - unsupported type.\n", | |||
| av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n", | |||
| map->file_index, map->stream_index); | |||
| exit_program(1); | |||
| } | |||
| @@ -4580,7 +4584,7 @@ static const OptionDef options[] = { | |||
| { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, // | |||
| { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" }, | |||
| { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" }, | |||
| { "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)©_initial_nonkeyframes}, "copy initial non-keyframes" }, | |||
| { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC, {.off = OFFSET(copy_initial_nonkeyframes)}, "copy initial non-keyframes" }, | |||
| { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC, {.off = OFFSET(max_frames)}, "set the number of frames to record", "number" }, | |||
| { "tag", OPT_STRING | HAS_ARG | OPT_SPEC, {.off = OFFSET(codec_tags)}, "force codec tag/fourcc", "fourcc/tag" }, | |||
| { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" }, | |||
| @@ -4702,6 +4706,7 @@ int main(int argc, char **argv) | |||
| avfilter_register_all(); | |||
| #endif | |||
| av_register_all(); | |||
| avformat_network_init(); | |||
| #if HAVE_ISATTY | |||
| if(isatty(STDIN_FILENO)) | |||
| @@ -914,6 +914,7 @@ static void do_exit(VideoState *is) | |||
| #if CONFIG_AVFILTER | |||
| avfilter_uninit(); | |||
| #endif | |||
| avformat_network_deinit(); | |||
| if (show_status) | |||
| printf("\n"); | |||
| SDL_Quit(); | |||
| @@ -3143,6 +3144,7 @@ int main(int argc, char **argv) | |||
| avfilter_register_all(); | |||
| #endif | |||
| av_register_all(); | |||
| avformat_network_init(); | |||
| init_opts(); | |||
| @@ -936,6 +936,7 @@ int main(int argc, char **argv) | |||
| parse_loglevel(argc, argv, options); | |||
| av_register_all(); | |||
| avformat_network_init(); | |||
| init_opts(); | |||
| #if CONFIG_AVDEVICE | |||
| avdevice_register_all(); | |||
| @@ -953,5 +954,7 @@ int main(int argc, char **argv) | |||
| ret = probe_file(input_filename); | |||
| avformat_network_deinit(); | |||
| return ret; | |||
| } | |||
| @@ -24,7 +24,6 @@ | |||
| #define closesocket close | |||
| #endif | |||
| #include <string.h> | |||
| #include <strings.h> | |||
| #include <stdlib.h> | |||
| #include "libavformat/avformat.h" | |||
| #include "libavformat/ffm.h" | |||
| @@ -1085,13 +1084,13 @@ static int extract_rates(char *rates, int ratelen, const char *request) | |||
| const char *p; | |||
| for (p = request; *p && *p != '\r' && *p != '\n'; ) { | |||
| if (strncasecmp(p, "Pragma:", 7) == 0) { | |||
| if (av_strncasecmp(p, "Pragma:", 7) == 0) { | |||
| const char *q = p + 7; | |||
| while (*q && *q != '\n' && isspace(*q)) | |||
| q++; | |||
| if (strncasecmp(q, "stream-switch-entry=", 20) == 0) { | |||
| if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) { | |||
| int stream_no; | |||
| int rate_no; | |||
| @@ -1271,9 +1270,9 @@ static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_ac | |||
| int errors = 0; | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (strcasecmp(arg, "allow") == 0) | |||
| if (av_strcasecmp(arg, "allow") == 0) | |||
| acl.action = IP_ALLOW; | |||
| else if (strcasecmp(arg, "deny") == 0) | |||
| else if (av_strcasecmp(arg, "deny") == 0) | |||
| acl.action = IP_DENY; | |||
| else { | |||
| fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n", | |||
| @@ -1358,7 +1357,7 @@ static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c) | |||
| continue; | |||
| get_arg(cmd, sizeof(cmd), &p); | |||
| if (!strcasecmp(cmd, "ACL")) | |||
| if (!av_strcasecmp(cmd, "ACL")) | |||
| parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num); | |||
| } | |||
| fclose(f); | |||
| @@ -1500,7 +1499,7 @@ static int http_parse_request(HTTPContext *c) | |||
| av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1); | |||
| for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { | |||
| if (strncasecmp(p, "User-Agent:", 11) == 0) { | |||
| if (av_strncasecmp(p, "User-Agent:", 11) == 0) { | |||
| useragent = p + 11; | |||
| if (*useragent && *useragent != '\n' && isspace(*useragent)) | |||
| useragent++; | |||
| @@ -1518,7 +1517,7 @@ static int http_parse_request(HTTPContext *c) | |||
| redir_type = REDIR_ASX; | |||
| filename[strlen(filename)-1] = 'f'; | |||
| } else if (av_match_ext(filename, "asf") && | |||
| (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) { | |||
| (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) { | |||
| /* if this isn't WMP or lookalike, return the redirector file */ | |||
| redir_type = REDIR_ASF; | |||
| } else if (av_match_ext(filename, "rpm,ram")) { | |||
| @@ -1613,7 +1612,7 @@ static int http_parse_request(HTTPContext *c) | |||
| char *hostinfo = 0; | |||
| for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { | |||
| if (strncasecmp(p, "Host:", 5) == 0) { | |||
| if (av_strncasecmp(p, "Host:", 5) == 0) { | |||
| hostinfo = p + 5; | |||
| break; | |||
| } | |||
| @@ -1742,11 +1741,11 @@ static int http_parse_request(HTTPContext *c) | |||
| int client_id = 0; | |||
| for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { | |||
| if (strncasecmp(p, "Pragma: log-line=", 17) == 0) { | |||
| if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) { | |||
| logline = p; | |||
| break; | |||
| } | |||
| if (strncasecmp(p, "Pragma: client-id=", 18) == 0) | |||
| if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0) | |||
| client_id = strtol(p + 18, 0, 10); | |||
| p = strchr(p, '\n'); | |||
| if (!p) | |||
| @@ -4059,40 +4058,40 @@ static int parse_ffconfig(const char *filename) | |||
| get_arg(cmd, sizeof(cmd), &p); | |||
| if (!strcasecmp(cmd, "Port")) { | |||
| if (!av_strcasecmp(cmd, "Port")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| val = atoi(arg); | |||
| if (val < 1 || val > 65536) { | |||
| ERROR("Invalid_port: %s\n", arg); | |||
| } | |||
| my_http_addr.sin_port = htons(val); | |||
| } else if (!strcasecmp(cmd, "BindAddress")) { | |||
| } else if (!av_strcasecmp(cmd, "BindAddress")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (resolve_host(&my_http_addr.sin_addr, arg) != 0) { | |||
| ERROR("%s:%d: Invalid host/IP address: %s\n", arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "NoDaemon")) { | |||
| } else if (!av_strcasecmp(cmd, "NoDaemon")) { | |||
| ffserver_daemon = 0; | |||
| } else if (!strcasecmp(cmd, "RTSPPort")) { | |||
| } else if (!av_strcasecmp(cmd, "RTSPPort")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| val = atoi(arg); | |||
| if (val < 1 || val > 65536) { | |||
| ERROR("%s:%d: Invalid port: %s\n", arg); | |||
| } | |||
| my_rtsp_addr.sin_port = htons(atoi(arg)); | |||
| } else if (!strcasecmp(cmd, "RTSPBindAddress")) { | |||
| } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) { | |||
| ERROR("Invalid host/IP address: %s\n", arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "MaxHTTPConnections")) { | |||
| } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| val = atoi(arg); | |||
| if (val < 1 || val > 65536) { | |||
| ERROR("Invalid MaxHTTPConnections: %s\n", arg); | |||
| } | |||
| nb_max_http_connections = val; | |||
| } else if (!strcasecmp(cmd, "MaxClients")) { | |||
| } else if (!av_strcasecmp(cmd, "MaxClients")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| val = atoi(arg); | |||
| if (val < 1 || val > nb_max_http_connections) { | |||
| @@ -4100,7 +4099,7 @@ static int parse_ffconfig(const char *filename) | |||
| } else { | |||
| nb_max_connections = val; | |||
| } | |||
| } else if (!strcasecmp(cmd, "MaxBandwidth")) { | |||
| } else if (!av_strcasecmp(cmd, "MaxBandwidth")) { | |||
| int64_t llval; | |||
| get_arg(arg, sizeof(arg), &p); | |||
| llval = atoll(arg); | |||
| @@ -4108,10 +4107,10 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("Invalid MaxBandwidth: %s\n", arg); | |||
| } else | |||
| max_bandwidth = llval; | |||
| } else if (!strcasecmp(cmd, "CustomLog")) { | |||
| } else if (!av_strcasecmp(cmd, "CustomLog")) { | |||
| if (!ffserver_debug) | |||
| get_arg(logfilename, sizeof(logfilename), &p); | |||
| } else if (!strcasecmp(cmd, "<Feed")) { | |||
| } else if (!av_strcasecmp(cmd, "<Feed")) { | |||
| /*********************************************/ | |||
| /* Feed related options */ | |||
| char *q; | |||
| @@ -4145,7 +4144,7 @@ static int parse_ffconfig(const char *filename) | |||
| *last_feed = feed; | |||
| last_feed = &feed->next_feed; | |||
| } | |||
| } else if (!strcasecmp(cmd, "Launch")) { | |||
| } else if (!av_strcasecmp(cmd, "Launch")) { | |||
| if (feed) { | |||
| int i; | |||
| @@ -4167,24 +4166,24 @@ static int parse_ffconfig(const char *filename) | |||
| inet_ntoa(my_http_addr.sin_addr), | |||
| ntohs(my_http_addr.sin_port), feed->filename); | |||
| } | |||
| } else if (!strcasecmp(cmd, "ReadOnlyFile")) { | |||
| } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) { | |||
| if (feed) { | |||
| get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); | |||
| feed->readonly = 1; | |||
| } else if (stream) { | |||
| get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); | |||
| } | |||
| } else if (!strcasecmp(cmd, "File")) { | |||
| } else if (!av_strcasecmp(cmd, "File")) { | |||
| if (feed) { | |||
| get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); | |||
| } else if (stream) | |||
| get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); | |||
| } else if (!strcasecmp(cmd, "Truncate")) { | |||
| } else if (!av_strcasecmp(cmd, "Truncate")) { | |||
| if (feed) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| feed->truncate = strtod(arg, NULL); | |||
| } | |||
| } else if (!strcasecmp(cmd, "FileMaxSize")) { | |||
| } else if (!av_strcasecmp(cmd, "FileMaxSize")) { | |||
| if (feed) { | |||
| char *p1; | |||
| double fsize; | |||
| @@ -4208,12 +4207,12 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "</Feed>")) { | |||
| } else if (!av_strcasecmp(cmd, "</Feed>")) { | |||
| if (!feed) { | |||
| ERROR("No corresponding <Feed> for </Feed>\n"); | |||
| } | |||
| feed = NULL; | |||
| } else if (!strcasecmp(cmd, "<Stream")) { | |||
| } else if (!av_strcasecmp(cmd, "<Stream")) { | |||
| /*********************************************/ | |||
| /* Stream related options */ | |||
| char *q; | |||
| @@ -4247,7 +4246,7 @@ static int parse_ffconfig(const char *filename) | |||
| *last_stream = stream; | |||
| last_stream = &stream->next; | |||
| } | |||
| } else if (!strcasecmp(cmd, "Feed")) { | |||
| } else if (!av_strcasecmp(cmd, "Feed")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| FFStream *sfeed; | |||
| @@ -4263,7 +4262,7 @@ static int parse_ffconfig(const char *filename) | |||
| else | |||
| stream->feed = sfeed; | |||
| } | |||
| } else if (!strcasecmp(cmd, "Format")) { | |||
| } else if (!av_strcasecmp(cmd, "Format")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| if (!strcmp(arg, "status")) { | |||
| @@ -4284,7 +4283,7 @@ static int parse_ffconfig(const char *filename) | |||
| video_id = stream->fmt->video_codec; | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "InputFormat")) { | |||
| } else if (!av_strcasecmp(cmd, "InputFormat")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| stream->ifmt = av_find_input_format(arg); | |||
| @@ -4292,65 +4291,65 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("Unknown input format: %s\n", arg); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "FaviconURL")) { | |||
| } else if (!av_strcasecmp(cmd, "FaviconURL")) { | |||
| if (stream && stream->stream_type == STREAM_TYPE_STATUS) { | |||
| get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); | |||
| } else { | |||
| ERROR("FaviconURL only permitted for status streams\n"); | |||
| } | |||
| } else if (!strcasecmp(cmd, "Author")) { | |||
| } else if (!av_strcasecmp(cmd, "Author")) { | |||
| if (stream) | |||
| get_arg(stream->author, sizeof(stream->author), &p); | |||
| } else if (!strcasecmp(cmd, "Comment")) { | |||
| } else if (!av_strcasecmp(cmd, "Comment")) { | |||
| if (stream) | |||
| get_arg(stream->comment, sizeof(stream->comment), &p); | |||
| } else if (!strcasecmp(cmd, "Copyright")) { | |||
| } else if (!av_strcasecmp(cmd, "Copyright")) { | |||
| if (stream) | |||
| get_arg(stream->copyright, sizeof(stream->copyright), &p); | |||
| } else if (!strcasecmp(cmd, "Title")) { | |||
| } else if (!av_strcasecmp(cmd, "Title")) { | |||
| if (stream) | |||
| get_arg(stream->title, sizeof(stream->title), &p); | |||
| } else if (!strcasecmp(cmd, "Preroll")) { | |||
| } else if (!av_strcasecmp(cmd, "Preroll")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| stream->prebuffer = atof(arg) * 1000; | |||
| } else if (!strcasecmp(cmd, "StartSendOnKey")) { | |||
| } else if (!av_strcasecmp(cmd, "StartSendOnKey")) { | |||
| if (stream) | |||
| stream->send_on_key = 1; | |||
| } else if (!strcasecmp(cmd, "AudioCodec")) { | |||
| } else if (!av_strcasecmp(cmd, "AudioCodec")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| audio_id = opt_audio_codec(arg); | |||
| if (audio_id == CODEC_ID_NONE) { | |||
| ERROR("Unknown AudioCodec: %s\n", arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoCodec")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoCodec")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| video_id = opt_video_codec(arg); | |||
| if (video_id == CODEC_ID_NONE) { | |||
| ERROR("Unknown VideoCodec: %s\n", arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "MaxTime")) { | |||
| } else if (!av_strcasecmp(cmd, "MaxTime")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| stream->max_time = atof(arg) * 1000; | |||
| } else if (!strcasecmp(cmd, "AudioBitRate")) { | |||
| } else if (!av_strcasecmp(cmd, "AudioBitRate")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| audio_enc.bit_rate = lrintf(atof(arg) * 1000); | |||
| } else if (!strcasecmp(cmd, "AudioChannels")) { | |||
| } else if (!av_strcasecmp(cmd, "AudioChannels")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| audio_enc.channels = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "AudioSampleRate")) { | |||
| } else if (!av_strcasecmp(cmd, "AudioSampleRate")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| audio_enc.sample_rate = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "AudioQuality")) { | |||
| } else if (!av_strcasecmp(cmd, "AudioQuality")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| // audio_enc.quality = atof(arg) * 1000; | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoBitRateRange")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) { | |||
| if (stream) { | |||
| int minrate, maxrate; | |||
| @@ -4363,32 +4362,32 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "Debug")) { | |||
| } else if (!av_strcasecmp(cmd, "Debug")) { | |||
| if (stream) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| video_enc.debug = strtol(arg,0,0); | |||
| } | |||
| } else if (!strcasecmp(cmd, "Strict")) { | |||
| } else if (!av_strcasecmp(cmd, "Strict")) { | |||
| if (stream) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| video_enc.strict_std_compliance = atoi(arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoBufferSize")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoBufferSize")) { | |||
| if (stream) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| video_enc.rc_buffer_size = atoi(arg) * 8*1024; | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoBitRateTolerance")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) { | |||
| if (stream) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| video_enc.bit_rate_tolerance = atoi(arg) * 1000; | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoBitRate")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoBitRate")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| video_enc.bit_rate = atoi(arg) * 1000; | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoSize")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoSize")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| av_parse_video_size(&video_enc.width, &video_enc.height, arg); | |||
| @@ -4397,7 +4396,7 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("Image size must be a multiple of 16\n"); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoFrameRate")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoFrameRate")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| AVRational frame_rate; | |||
| @@ -4408,29 +4407,29 @@ static int parse_ffconfig(const char *filename) | |||
| video_enc.time_base.den = frame_rate.num; | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoGopSize")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoGopSize")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| video_enc.gop_size = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "VideoIntraOnly")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) { | |||
| if (stream) | |||
| video_enc.gop_size = 1; | |||
| } else if (!strcasecmp(cmd, "VideoHighQuality")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoHighQuality")) { | |||
| if (stream) | |||
| video_enc.mb_decision = FF_MB_DECISION_BITS; | |||
| } else if (!strcasecmp(cmd, "Video4MotionVector")) { | |||
| } else if (!av_strcasecmp(cmd, "Video4MotionVector")) { | |||
| if (stream) { | |||
| video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove | |||
| video_enc.flags |= CODEC_FLAG_4MV; | |||
| } | |||
| } else if (!strcasecmp(cmd, "AVOptionVideo") || | |||
| !strcasecmp(cmd, "AVOptionAudio")) { | |||
| } else if (!av_strcasecmp(cmd, "AVOptionVideo") || | |||
| !av_strcasecmp(cmd, "AVOptionAudio")) { | |||
| char arg2[1024]; | |||
| AVCodecContext *avctx; | |||
| int type; | |||
| get_arg(arg, sizeof(arg), &p); | |||
| get_arg(arg2, sizeof(arg2), &p); | |||
| if (!strcasecmp(cmd, "AVOptionVideo")) { | |||
| if (!av_strcasecmp(cmd, "AVOptionVideo")) { | |||
| avctx = &video_enc; | |||
| type = AV_OPT_FLAG_VIDEO_PARAM; | |||
| } else { | |||
| @@ -4440,12 +4439,12 @@ static int parse_ffconfig(const char *filename) | |||
| if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) { | |||
| ERROR("AVOption error: %s %s\n", arg, arg2); | |||
| } | |||
| } else if (!strcasecmp(cmd, "AVPresetVideo") || | |||
| !strcasecmp(cmd, "AVPresetAudio")) { | |||
| } else if (!av_strcasecmp(cmd, "AVPresetVideo") || | |||
| !av_strcasecmp(cmd, "AVPresetAudio")) { | |||
| AVCodecContext *avctx; | |||
| int type; | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (!strcasecmp(cmd, "AVPresetVideo")) { | |||
| if (!av_strcasecmp(cmd, "AVPresetVideo")) { | |||
| avctx = &video_enc; | |||
| video_enc.codec_id = video_id; | |||
| type = AV_OPT_FLAG_VIDEO_PARAM; | |||
| @@ -4457,26 +4456,26 @@ static int parse_ffconfig(const char *filename) | |||
| if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) { | |||
| ERROR("AVPreset error: %s\n", arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoTag")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoTag")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if ((strlen(arg) == 4) && stream) | |||
| video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]); | |||
| } else if (!strcasecmp(cmd, "BitExact")) { | |||
| } else if (!av_strcasecmp(cmd, "BitExact")) { | |||
| if (stream) | |||
| video_enc.flags |= CODEC_FLAG_BITEXACT; | |||
| } else if (!strcasecmp(cmd, "DctFastint")) { | |||
| } else if (!av_strcasecmp(cmd, "DctFastint")) { | |||
| if (stream) | |||
| video_enc.dct_algo = FF_DCT_FASTINT; | |||
| } else if (!strcasecmp(cmd, "IdctSimple")) { | |||
| } else if (!av_strcasecmp(cmd, "IdctSimple")) { | |||
| if (stream) | |||
| video_enc.idct_algo = FF_IDCT_SIMPLE; | |||
| } else if (!strcasecmp(cmd, "Qscale")) { | |||
| } else if (!av_strcasecmp(cmd, "Qscale")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| video_enc.flags |= CODEC_FLAG_QSCALE; | |||
| video_enc.global_quality = FF_QP2LAMBDA * atoi(arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoQDiff")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoQDiff")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| video_enc.max_qdiff = atoi(arg); | |||
| @@ -4484,7 +4483,7 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("VideoQDiff out of range\n"); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoQMax")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoQMax")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| video_enc.qmax = atoi(arg); | |||
| @@ -4492,7 +4491,7 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("VideoQMax out of range\n"); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoQMin")) { | |||
| } else if (!av_strcasecmp(cmd, "VideoQMin")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| video_enc.qmin = atoi(arg); | |||
| @@ -4500,39 +4499,39 @@ static int parse_ffconfig(const char *filename) | |||
| ERROR("VideoQMin out of range\n"); | |||
| } | |||
| } | |||
| } else if (!strcasecmp(cmd, "LumaElim")) { | |||
| } else if (!av_strcasecmp(cmd, "LumaElim")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| video_enc.luma_elim_threshold = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "ChromaElim")) { | |||
| } else if (!av_strcasecmp(cmd, "ChromaElim")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| video_enc.chroma_elim_threshold = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "LumiMask")) { | |||
| } else if (!av_strcasecmp(cmd, "LumiMask")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| video_enc.lumi_masking = atof(arg); | |||
| } else if (!strcasecmp(cmd, "DarkMask")) { | |||
| } else if (!av_strcasecmp(cmd, "DarkMask")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| video_enc.dark_masking = atof(arg); | |||
| } else if (!strcasecmp(cmd, "NoVideo")) { | |||
| } else if (!av_strcasecmp(cmd, "NoVideo")) { | |||
| video_id = CODEC_ID_NONE; | |||
| } else if (!strcasecmp(cmd, "NoAudio")) { | |||
| } else if (!av_strcasecmp(cmd, "NoAudio")) { | |||
| audio_id = CODEC_ID_NONE; | |||
| } else if (!strcasecmp(cmd, "ACL")) { | |||
| } else if (!av_strcasecmp(cmd, "ACL")) { | |||
| parse_acl_row(stream, feed, NULL, p, filename, line_num); | |||
| } else if (!strcasecmp(cmd, "DynamicACL")) { | |||
| } else if (!av_strcasecmp(cmd, "DynamicACL")) { | |||
| if (stream) { | |||
| get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p); | |||
| } | |||
| } else if (!strcasecmp(cmd, "RTSPOption")) { | |||
| } else if (!av_strcasecmp(cmd, "RTSPOption")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| av_freep(&stream->rtsp_option); | |||
| stream->rtsp_option = av_strdup(arg); | |||
| } | |||
| } else if (!strcasecmp(cmd, "MulticastAddress")) { | |||
| } else if (!av_strcasecmp(cmd, "MulticastAddress")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| if (resolve_host(&stream->multicast_ip, arg) != 0) { | |||
| @@ -4541,18 +4540,18 @@ static int parse_ffconfig(const char *filename) | |||
| stream->is_multicast = 1; | |||
| stream->loop = 1; /* default is looping */ | |||
| } | |||
| } else if (!strcasecmp(cmd, "MulticastPort")) { | |||
| } else if (!av_strcasecmp(cmd, "MulticastPort")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| stream->multicast_port = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "MulticastTTL")) { | |||
| } else if (!av_strcasecmp(cmd, "MulticastTTL")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) | |||
| stream->multicast_ttl = atoi(arg); | |||
| } else if (!strcasecmp(cmd, "NoLoop")) { | |||
| } else if (!av_strcasecmp(cmd, "NoLoop")) { | |||
| if (stream) | |||
| stream->loop = 0; | |||
| } else if (!strcasecmp(cmd, "</Stream>")) { | |||
| } else if (!av_strcasecmp(cmd, "</Stream>")) { | |||
| if (!stream) { | |||
| ERROR("No corresponding <Stream> for </Stream>\n"); | |||
| } else { | |||
| @@ -4570,7 +4569,7 @@ static int parse_ffconfig(const char *filename) | |||
| } | |||
| stream = NULL; | |||
| } | |||
| } else if (!strcasecmp(cmd, "<Redirect")) { | |||
| } else if (!av_strcasecmp(cmd, "<Redirect")) { | |||
| /*********************************************/ | |||
| char *q; | |||
| if (stream || feed || redirect) { | |||
| @@ -4586,10 +4585,10 @@ static int parse_ffconfig(const char *filename) | |||
| *q = '\0'; | |||
| redirect->stream_type = STREAM_TYPE_REDIRECT; | |||
| } | |||
| } else if (!strcasecmp(cmd, "URL")) { | |||
| } else if (!av_strcasecmp(cmd, "URL")) { | |||
| if (redirect) | |||
| get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p); | |||
| } else if (!strcasecmp(cmd, "</Redirect>")) { | |||
| } else if (!av_strcasecmp(cmd, "</Redirect>")) { | |||
| if (!redirect) { | |||
| ERROR("No corresponding <Redirect> for </Redirect>\n"); | |||
| } else { | |||
| @@ -4598,7 +4597,7 @@ static int parse_ffconfig(const char *filename) | |||
| } | |||
| redirect = NULL; | |||
| } | |||
| } else if (!strcasecmp(cmd, "LoadModule")) { | |||
| } else if (!av_strcasecmp(cmd, "LoadModule")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| #if HAVE_DLOPEN | |||
| load_module(arg); | |||
| @@ -4673,6 +4672,7 @@ int main(int argc, char **argv) | |||
| parse_loglevel(argc, argv, options); | |||
| av_register_all(); | |||
| avformat_network_init(); | |||
| show_banner(); | |||
| @@ -153,7 +153,9 @@ enum CodecID { | |||
| CODEC_ID_TIERTEXSEQVIDEO, | |||
| CODEC_ID_TIFF, | |||
| CODEC_ID_GIF, | |||
| #if LIBAVCODEC_VERSION_MAJOR == 53 | |||
| CODEC_ID_FFH264, | |||
| #endif | |||
| CODEC_ID_DXA, | |||
| CODEC_ID_DNXHD, | |||
| CODEC_ID_THP, | |||
| @@ -171,8 +173,10 @@ enum CodecID { | |||
| CODEC_ID_INDEO5, | |||
| CODEC_ID_MIMIC, | |||
| CODEC_ID_RL2, | |||
| #if LIBAVCODEC_VERSION_MAJOR == 53 | |||
| CODEC_ID_8SVX_EXP, | |||
| CODEC_ID_8SVX_FIB, | |||
| #endif | |||
| CODEC_ID_ESCAPE124, | |||
| CODEC_ID_DIRAC, | |||
| CODEC_ID_BFI, | |||
| @@ -222,7 +226,7 @@ enum CodecID { | |||
| /* various PCM "codecs" */ | |||
| CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs | |||
| CODEC_ID_PCM_S16LE= 0x10000, | |||
| CODEC_ID_PCM_S16LE = 0x10000, | |||
| CODEC_ID_PCM_S16BE, | |||
| CODEC_ID_PCM_U16LE, | |||
| CODEC_ID_PCM_U16BE, | |||
| @@ -251,7 +255,7 @@ enum CodecID { | |||
| CODEC_ID_S302M, | |||
| /* various ADPCM codecs */ | |||
| CODEC_ID_ADPCM_IMA_QT= 0x11000, | |||
| CODEC_ID_ADPCM_IMA_QT = 0x11000, | |||
| CODEC_ID_ADPCM_IMA_WAV, | |||
| CODEC_ID_ADPCM_IMA_DK3, | |||
| CODEC_ID_ADPCM_IMA_DK4, | |||
| @@ -282,21 +286,21 @@ enum CodecID { | |||
| CODEC_ID_ADPCM_G722, | |||
| /* AMR */ | |||
| CODEC_ID_AMR_NB= 0x12000, | |||
| CODEC_ID_AMR_NB = 0x12000, | |||
| CODEC_ID_AMR_WB, | |||
| /* RealAudio codecs*/ | |||
| CODEC_ID_RA_144= 0x13000, | |||
| CODEC_ID_RA_144 = 0x13000, | |||
| CODEC_ID_RA_288, | |||
| /* various DPCM codecs */ | |||
| CODEC_ID_ROQ_DPCM= 0x14000, | |||
| CODEC_ID_ROQ_DPCM = 0x14000, | |||
| CODEC_ID_INTERPLAY_DPCM, | |||
| CODEC_ID_XAN_DPCM, | |||
| CODEC_ID_SOL_DPCM, | |||
| /* audio codecs */ | |||
| CODEC_ID_MP2= 0x15000, | |||
| CODEC_ID_MP2 = 0x15000, | |||
| CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 | |||
| CODEC_ID_AAC, | |||
| CODEC_ID_AC3, | |||
| @@ -308,8 +312,10 @@ enum CodecID { | |||
| CODEC_ID_MACE3, | |||
| CODEC_ID_MACE6, | |||
| CODEC_ID_VMDAUDIO, | |||
| #if LIBAVCODEC_VERSION_MAJOR == 53 | |||
| CODEC_ID_SONIC, | |||
| CODEC_ID_SONIC_LS, | |||
| #endif | |||
| CODEC_ID_FLAC, | |||
| CODEC_ID_MP3ADU, | |||
| CODEC_ID_MP3ON4, | |||
| @@ -354,6 +360,8 @@ enum CodecID { | |||
| #if LIBAVCODEC_VERSION_MAJOR > 53 | |||
| CODEC_ID_G723_1_DEPRECATED, | |||
| CODEC_ID_G729_DEPRECATED, | |||
| CODEC_ID_8SVX_EXP, | |||
| CODEC_ID_8SVX_FIB, | |||
| #endif | |||
| CODEC_ID_G729 = 0x15800, | |||
| CODEC_ID_G723_1= 0x15801, | |||
| @@ -361,7 +369,7 @@ enum CodecID { | |||
| /* subtitle codecs */ | |||
| CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. | |||
| CODEC_ID_DVD_SUBTITLE= 0x17000, | |||
| CODEC_ID_DVD_SUBTITLE = 0x17000, | |||
| CODEC_ID_DVB_SUBTITLE, | |||
| CODEC_ID_TEXT, ///< raw UTF-8 text | |||
| CODEC_ID_XSUB, | |||
| @@ -374,18 +382,18 @@ enum CodecID { | |||
| /* other specific kind of codecs (generally used for attachments) */ | |||
| CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. | |||
| CODEC_ID_TTF= 0x18000, | |||
| CODEC_ID_TTF = 0x18000, | |||
| CODEC_ID_BINTEXT = MKBETAG('B','T','X','T'), | |||
| CODEC_ID_XBIN = MKBETAG('X','B','I','N'), | |||
| CODEC_ID_IDF = MKBETAG( 0 ,'I','D','F'), | |||
| CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it | |||
| CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it | |||
| CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS | |||
| CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS | |||
| * stream (only used by libavformat) */ | |||
| CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems | |||
| * stream (only used by libavformat) */ | |||
| CODEC_ID_FFMETADATA=0x21000, ///< Dummy codec for streams containing only metadata information. | |||
| CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information. | |||
| }; | |||
| #if FF_API_OLD_SAMPLE_FMT | |||
| @@ -46,7 +46,6 @@ | |||
| #include <sys/time.h> | |||
| #include <signal.h> | |||
| #include <stdint.h> | |||
| #include <strings.h> | |||
| #include "avdevice.h" | |||
| typedef struct { | |||
| @@ -28,7 +28,6 @@ | |||
| #include <sys/mman.h> | |||
| #include <sys/time.h> | |||
| #include <time.h> | |||
| #include <strings.h> | |||
| #include "libavutil/log.h" | |||
| #include "libavutil/opt.h" | |||
| @@ -38,7 +38,6 @@ | |||
| #define _LINUX_TIME_H 1 | |||
| #include <linux/videodev.h> | |||
| #include <time.h> | |||
| #include <strings.h> | |||
| #include "avdevice.h" | |||
| typedef struct { | |||
| @@ -46,7 +46,7 @@ static void openssl_lock(int mode, int type, const char *file, int line) | |||
| else | |||
| pthread_mutex_unlock(&openssl_mutexes[type]); | |||
| } | |||
| #ifndef WIN32 | |||
| #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 | |||
| static unsigned long openssl_thread_id(void) | |||
| { | |||
| return (intptr_t) pthread_self(); | |||
| @@ -79,7 +79,7 @@ void ff_tls_init(void) | |||
| for (i = 0; i < CRYPTO_num_locks(); i++) | |||
| pthread_mutex_init(&openssl_mutexes[i], NULL); | |||
| CRYPTO_set_locking_callback(openssl_lock); | |||
| #ifndef WIN32 | |||
| #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 | |||
| CRYPTO_set_id_callback(openssl_thread_id); | |||
| #endif | |||
| } | |||
| @@ -71,7 +71,6 @@ int ff_win32_open(const char *filename_utf8, int oflag, int pmode) | |||
| #if !HAVE_INET_ATON | |||
| #include <stdlib.h> | |||
| #include <strings.h> | |||
| int ff_inet_aton (const char * str, struct in_addr * add) | |||
| { | |||
| @@ -23,7 +23,6 @@ | |||
| #include "internal.h" | |||
| #include "libavutil/avstring.h" | |||
| #include "libavcodec/get_bits.h" | |||
| #include <strings.h> | |||
| struct PayloadContext { | |||
| AVIOContext *dyn_buf; | |||
| @@ -1434,7 +1434,7 @@ void ff_read_frame_flush(AVFormatContext *s) | |||
| #if FF_API_SEEK_PUBLIC | |||
| void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp) | |||
| { | |||
| return ff_update_cur_dts(s, ref_st, timestamp); | |||
| ff_update_cur_dts(s, ref_st, timestamp); | |||
| } | |||
| #endif | |||
| @@ -189,16 +189,12 @@ char *av_strtok(char *s, const char *delim, char **saveptr) | |||
| return tok; | |||
| } | |||
| #define TOUPPER(c) do { if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; } while (0) | |||
| int av_strcasecmp(const char *a, const char *b) | |||
| { | |||
| uint8_t c1, c2; | |||
| do { | |||
| c1 = *a++; | |||
| c2 = *b++; | |||
| TOUPPER(c1); | |||
| TOUPPER(c2); | |||
| c1 = av_tolower(*a++); | |||
| c2 = av_tolower(*b++); | |||
| } while (c1 && c1 == c2); | |||
| return c1 - c2; | |||
| } | |||
| @@ -208,10 +204,8 @@ int av_strncasecmp(const char *a, const char *b, size_t n) | |||
| const char *end = a + n; | |||
| uint8_t c1, c2; | |||
| do { | |||
| c1 = *a++; | |||
| c2 = *b++; | |||
| TOUPPER(c1); | |||
| TOUPPER(c2); | |||
| c1 = av_tolower(*a++); | |||
| c2 = av_tolower(*b++); | |||
| } while (a < end && c1 && c1 == c2); | |||
| return c1 - c2; | |||
| } | |||
| @@ -165,6 +165,26 @@ char *av_get_token(const char **buf, const char *term); | |||
| */ | |||
| char *av_strtok(char *s, const char *delim, char **saveptr); | |||
| /** | |||
| * Locale independent conversion of ASCII characters to upper case. | |||
| */ | |||
| static inline int av_toupper(int c) | |||
| { | |||
| if (c >= 'a' && c <= 'z') | |||
| c ^= 0x20; | |||
| return c; | |||
| } | |||
| /** | |||
| * Locale independent conversion of ASCII characters to lower case. | |||
| */ | |||
| static inline int av_tolower(int c) | |||
| { | |||
| if (c >= 'A' && c <= 'Z') | |||
| c ^= 0x20; | |||
| return c; | |||
| } | |||
| /** | |||
| * Locale independent case-insensitive compare. | |||
| * Note: This means only ASCII-range characters are case-insensitive | |||
| @@ -40,7 +40,7 @@ | |||
| #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) | |||
| #define LIBAVUTIL_VERSION_MAJOR 51 | |||
| #define LIBAVUTIL_VERSION_MINOR 23 | |||
| #define LIBAVUTIL_VERSION_MINOR 24 | |||
| #define LIBAVUTIL_VERSION_MICRO 0 | |||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||
| @@ -18,7 +18,6 @@ | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include <strings.h> | |||
| #include "avstring.h" | |||
| #include "dict.h" | |||
| #include "internal.h" | |||
| @@ -1,5 +1,5 @@ | |||
| ;***************************************************************************** | |||
| ;* x86inc.asm | |||
| ;* x86inc.asm: x264asm abstraction layer | |||
| ;***************************************************************************** | |||
| ;* Copyright (C) 2005-2011 x264 project | |||
| ;* | |||
| @@ -112,7 +112,7 @@ | |||
| ; we need more flexible macro. | |||
| ; RET: | |||
| ; Pops anything that was pushed by PROLOGUE | |||
| ; Pops anything that was pushed by PROLOGUE, and returns. | |||
| ; REP_RET: | |||
| ; Same, but if it doesn't pop anything it becomes a 2-byte ret, for athlons | |||
| @@ -297,6 +297,9 @@ DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 56] | |||
| %macro WIN64_SPILL_XMM 1 | |||
| %assign xmm_regs_used %1 | |||
| %if mmsize == 8 | |||
| %assign xmm_regs_used 0 | |||
| %endif | |||
| ASSERT xmm_regs_used <= 16 | |||
| %if xmm_regs_used > 6 | |||
| sub rsp, (xmm_regs_used-6)*16+16 | |||
| @@ -459,10 +462,24 @@ DECLARE_REG 6, ebp, ebp, bp, null, [esp + stack_offset + 28] | |||
| %assign function_align 16 | |||
| ; Symbol prefix for C linkage | |||
| %macro cglobal 1-2+ | |||
| %xdefine %1 mangle(program_name %+ _ %+ %1) | |||
| %xdefine %1.skip_prologue %1 %+ .skip_prologue | |||
| ; Begin a function. | |||
| ; Applies any symbol mangling needed for C linkage, and sets up a define such that | |||
| ; subsequent uses of the function name automatically refer to the mangled version. | |||
| ; Appends cpuflags to the function name if cpuflags has been specified. | |||
| %macro cglobal 1-2+ ; name, [PROLOGUE args] | |||
| %if %0 == 1 | |||
| cglobal_internal %1 %+ SUFFIX | |||
| %else | |||
| cglobal_internal %1 %+ SUFFIX, %2 | |||
| %endif | |||
| %endmacro | |||
| %macro cglobal_internal 1-2+ | |||
| %ifndef cglobaled_%1 | |||
| %xdefine %1 mangle(program_name %+ _ %+ %1) | |||
| %xdefine %1.skip_prologue %1 %+ .skip_prologue | |||
| CAT_XDEFINE cglobaled_, %1, 1 | |||
| %endif | |||
| %xdefine current_function %1 | |||
| %ifidn __OUTPUT_FORMAT__,elf | |||
| global %1:function hidden | |||
| %else | |||
| @@ -479,12 +496,14 @@ DECLARE_REG 6, ebp, ebp, bp, null, [esp + stack_offset + 28] | |||
| %macro cextern 1 | |||
| %xdefine %1 mangle(program_name %+ _ %+ %1) | |||
| CAT_XDEFINE cglobaled_, %1, 1 | |||
| extern %1 | |||
| %endmacro | |||
| ;like cextern, but without the prefix | |||
| ; like cextern, but without the prefix | |||
| %macro cextern_naked 1 | |||
| %xdefine %1 mangle(%1) | |||
| CAT_XDEFINE cglobaled_, %1, 1 | |||
| extern %1 | |||
| %endmacro | |||
| @@ -500,6 +519,66 @@ DECLARE_REG 6, ebp, ebp, bp, null, [esp + stack_offset + 28] | |||
| SECTION .note.GNU-stack noalloc noexec nowrite progbits | |||
| %endif | |||
| ; cpuflags | |||
| %assign cpuflags_mmx (1<<0) | |||
| %assign cpuflags_mmx2 (1<<1) | cpuflags_mmx | |||
| %assign cpuflags_3dnow (1<<2) | cpuflags_mmx | |||
| %assign cpuflags_3dnow2 (1<<3) | cpuflags_3dnow | |||
| %assign cpuflags_sse (1<<4) | cpuflags_mmx2 | |||
| %assign cpuflags_sse2 (1<<5) | cpuflags_sse | |||
| %assign cpuflags_sse2slow (1<<6) | cpuflags_sse2 | |||
| %assign cpuflags_sse3 (1<<7) | cpuflags_sse2 | |||
| %assign cpuflags_ssse3 (1<<8) | cpuflags_sse3 | |||
| %assign cpuflags_sse4 (1<<9) | cpuflags_ssse3 | |||
| %assign cpuflags_sse42 (1<<10)| cpuflags_sse4 | |||
| %assign cpuflags_avx (1<<11)| cpuflags_sse42 | |||
| %assign cpuflags_xop (1<<12)| cpuflags_avx | |||
| %assign cpuflags_fma4 (1<<13)| cpuflags_avx | |||
| %assign cpuflags_cache32 (1<<16) | |||
| %assign cpuflags_cache64 (1<<17) | |||
| %assign cpuflags_slowctz (1<<18) | |||
| %assign cpuflags_lzcnt (1<<19) | |||
| %assign cpuflags_misalign (1<<20) | |||
| %assign cpuflags_aligned (1<<21) ; not a cpu feature, but a function variant | |||
| %assign cpuflags_atom (1<<22) | |||
| %define cpuflag(x) ((cpuflags & (cpuflags_ %+ x)) == (cpuflags_ %+ x)) | |||
| %define notcpuflag(x) ((cpuflags & (cpuflags_ %+ x)) != (cpuflags_ %+ x)) | |||
| ; Takes up to 2 cpuflags from the above list. | |||
| ; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu. | |||
| ; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co. | |||
| %macro INIT_CPUFLAGS 0-2 | |||
| %if %0 >= 1 | |||
| %xdefine cpuname %1 | |||
| %assign cpuflags cpuflags_%1 | |||
| %if %0 >= 2 | |||
| %xdefine cpuname %1_%2 | |||
| %assign cpuflags cpuflags | cpuflags_%2 | |||
| %endif | |||
| %xdefine SUFFIX _ %+ cpuname | |||
| %if cpuflag(avx) | |||
| %assign avx_enabled 1 | |||
| %endif | |||
| %if mmsize == 16 && notcpuflag(sse2) | |||
| %define mova movaps | |||
| %define movu movups | |||
| %define movnta movntps | |||
| %endif | |||
| %if cpuflag(aligned) | |||
| %define movu mova | |||
| %elifidn %1, sse3 | |||
| %define movu lddqu | |||
| %endif | |||
| %else | |||
| %xdefine SUFFIX | |||
| %undef cpuname | |||
| %undef cpuflags | |||
| %endif | |||
| %endmacro | |||
| ; merge mmx and sse* | |||
| %macro CAT_XDEFINE 3 | |||
| @@ -510,9 +589,9 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits | |||
| %undef %1%2 | |||
| %endmacro | |||
| %macro INIT_MMX 0 | |||
| %macro INIT_MMX 0-1+ | |||
| %assign avx_enabled 0 | |||
| %define RESET_MM_PERMUTATION INIT_MMX | |||
| %define RESET_MM_PERMUTATION INIT_MMX %1 | |||
| %define mmsize 8 | |||
| %define num_mmregs 8 | |||
| %define mova movq | |||
| @@ -530,11 +609,12 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits | |||
| CAT_UNDEF nmm, %%i | |||
| %assign %%i %%i+1 | |||
| %endrep | |||
| INIT_CPUFLAGS %1 | |||
| %endmacro | |||
| %macro INIT_XMM 0 | |||
| %macro INIT_XMM 0-1+ | |||
| %assign avx_enabled 0 | |||
| %define RESET_MM_PERMUTATION INIT_XMM | |||
| %define RESET_MM_PERMUTATION INIT_XMM %1 | |||
| %define mmsize 16 | |||
| %define num_mmregs 8 | |||
| %ifdef ARCH_X86_64 | |||
| @@ -550,8 +630,10 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits | |||
| CAT_XDEFINE nxmm, %%i, %%i | |||
| %assign %%i %%i+1 | |||
| %endrep | |||
| INIT_CPUFLAGS %1 | |||
| %endmacro | |||
| ; FIXME: INIT_AVX can be replaced by INIT_XMM avx | |||
| %macro INIT_AVX 0 | |||
| INIT_XMM | |||
| %assign avx_enabled 1 | |||
| @@ -559,9 +641,9 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits | |||
| %define RESET_MM_PERMUTATION INIT_AVX | |||
| %endmacro | |||
| %macro INIT_YMM 0 | |||
| %macro INIT_YMM 0-1+ | |||
| %assign avx_enabled 1 | |||
| %define RESET_MM_PERMUTATION INIT_YMM | |||
| %define RESET_MM_PERMUTATION INIT_YMM %1 | |||
| %define mmsize 32 | |||
| %define num_mmregs 8 | |||
| %ifdef ARCH_X86_64 | |||
| @@ -569,15 +651,18 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits | |||
| %endif | |||
| %define mova vmovaps | |||
| %define movu vmovups | |||
| %undef movh | |||
| %define movnta vmovntps | |||
| %assign %%i 0 | |||
| %rep num_mmregs | |||
| CAT_XDEFINE m, %%i, ymm %+ %%i | |||
| CAT_XDEFINE nymm, %%i, %%i | |||
| %assign %%i %%i+1 | |||
| %endrep | |||
| INIT_CPUFLAGS %1 | |||
| %endmacro | |||
| INIT_MMX | |||
| INIT_XMM | |||
| ; I often want to use macros that permute their arguments. e.g. there's no | |||
| ; efficient way to implement butterfly or transpose or dct without swapping some | |||
| @@ -633,31 +718,46 @@ INIT_MMX | |||
| %endrep | |||
| %endmacro | |||
| ; If SAVE_MM_PERMUTATION is placed at the end of a function and given the | |||
| ; function name, then any later calls to that function will automatically | |||
| ; load the permutation, so values can be returned in mmregs. | |||
| %macro SAVE_MM_PERMUTATION 1 ; name to save as | |||
| ; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later | |||
| ; calls to that function will automatically load the permutation, so values can | |||
| ; be returned in mmregs. | |||
| %macro SAVE_MM_PERMUTATION 0-1 | |||
| %if %0 | |||
| %xdefine %%f %1_m | |||
| %else | |||
| %xdefine %%f current_function %+ _m | |||
| %endif | |||
| %assign %%i 0 | |||
| %rep num_mmregs | |||
| CAT_XDEFINE %1_m, %%i, m %+ %%i | |||
| CAT_XDEFINE %%f, %%i, m %+ %%i | |||
| %assign %%i %%i+1 | |||
| %endrep | |||
| %endmacro | |||
| %macro LOAD_MM_PERMUTATION 1 ; name to load from | |||
| %assign %%i 0 | |||
| %rep num_mmregs | |||
| CAT_XDEFINE m, %%i, %1_m %+ %%i | |||
| CAT_XDEFINE n, m %+ %%i, %%i | |||
| %assign %%i %%i+1 | |||
| %endrep | |||
| %ifdef %1_m0 | |||
| %assign %%i 0 | |||
| %rep num_mmregs | |||
| CAT_XDEFINE m, %%i, %1_m %+ %%i | |||
| CAT_XDEFINE n, m %+ %%i, %%i | |||
| %assign %%i %%i+1 | |||
| %endrep | |||
| %endif | |||
| %endmacro | |||
| ; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't | |||
| %macro call 1 | |||
| call %1 | |||
| %ifdef %1_m0 | |||
| LOAD_MM_PERMUTATION %1 | |||
| call_internal %1, %1 %+ SUFFIX | |||
| %endmacro | |||
| %macro call_internal 2 | |||
| %xdefine %%i %1 | |||
| %ifndef cglobaled_%1 | |||
| %ifdef cglobaled_%2 | |||
| %xdefine %%i %2 | |||
| %endif | |||
| %endif | |||
| call %%i | |||
| LOAD_MM_PERMUTATION %%i | |||
| %endmacro | |||
| ; Substitutions that reduce instruction size but are functionally equivalent | |||
| @@ -702,14 +802,19 @@ INIT_MMX | |||
| ;%1 == instruction | |||
| ;%2 == 1 if float, 0 if int | |||
| ;%3 == 0 if 3-operand (xmm, xmm, xmm), 1 if 4-operand (xmm, xmm, xmm, imm) | |||
| ;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 3-operand (xmm, xmm, xmm) | |||
| ;%4 == number of operands given | |||
| ;%5+: operands | |||
| %macro RUN_AVX_INSTR 6-7+ | |||
| %if sizeof%5==32 | |||
| %ifid %5 | |||
| %define %%size sizeof%5 | |||
| %else | |||
| %define %%size mmsize | |||
| %endif | |||
| %if %%size==32 | |||
| v%1 %5, %6, %7 | |||
| %else | |||
| %if sizeof%5==8 | |||
| %if %%size==8 | |||
| %define %%regmov movq | |||
| %elif %2 | |||
| %define %%regmov movaps | |||
| @@ -736,15 +841,37 @@ INIT_MMX | |||
| %endif | |||
| %endmacro | |||
| ; 3arg AVX ops with a memory arg can only have it in src2, | |||
| ; whereas SSE emulation of 3arg prefers to have it in src1 (i.e. the mov). | |||
| ; So, if the op is symmetric and the wrong one is memory, swap them. | |||
| %macro RUN_AVX_INSTR1 8 | |||
| %assign %%swap 0 | |||
| %if avx_enabled | |||
| %ifnid %6 | |||
| %assign %%swap 1 | |||
| %endif | |||
| %elifnidn %5, %6 | |||
| %ifnid %7 | |||
| %assign %%swap 1 | |||
| %endif | |||
| %endif | |||
| %if %%swap && %3 == 0 && %8 == 1 | |||
| RUN_AVX_INSTR %1, %2, %3, %4, %5, %7, %6 | |||
| %else | |||
| RUN_AVX_INSTR %1, %2, %3, %4, %5, %6, %7 | |||
| %endif | |||
| %endmacro | |||
| ;%1 == instruction | |||
| ;%2 == 1 if float, 0 if int | |||
| ;%3 == 0 if 3-operand (xmm, xmm, xmm), 1 if 4-operand (xmm, xmm, xmm, imm) | |||
| %macro AVX_INSTR 3 | |||
| %macro %1 2-8 fnord, fnord, fnord, %1, %2, %3 | |||
| ;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 3-operand (xmm, xmm, xmm) | |||
| ;%4 == 1 if symmetric (i.e. doesn't matter which src arg is which), 0 if not | |||
| %macro AVX_INSTR 4 | |||
| %macro %1 2-9 fnord, fnord, fnord, %1, %2, %3, %4 | |||
| %ifidn %3, fnord | |||
| RUN_AVX_INSTR %6, %7, %8, 2, %1, %2 | |||
| %elifidn %4, fnord | |||
| RUN_AVX_INSTR %6, %7, %8, 3, %1, %2, %3 | |||
| RUN_AVX_INSTR1 %6, %7, %8, 3, %1, %2, %3, %9 | |||
| %elifidn %5, fnord | |||
| RUN_AVX_INSTR %6, %7, %8, 4, %1, %2, %3, %4 | |||
| %else | |||
| @@ -753,153 +880,188 @@ INIT_MMX | |||
| %endmacro | |||
| %endmacro | |||
| AVX_INSTR addpd, 1, 0 | |||
| AVX_INSTR addps, 1, 0 | |||
| AVX_INSTR addsd, 1, 0 | |||
| AVX_INSTR addss, 1, 0 | |||
| AVX_INSTR addsubpd, 1, 0 | |||
| AVX_INSTR addsubps, 1, 0 | |||
| AVX_INSTR andpd, 1, 0 | |||
| AVX_INSTR andps, 1, 0 | |||
| AVX_INSTR andnpd, 1, 0 | |||
| AVX_INSTR andnps, 1, 0 | |||
| AVX_INSTR blendpd, 1, 0 | |||
| AVX_INSTR blendps, 1, 0 | |||
| AVX_INSTR blendvpd, 1, 0 | |||
| AVX_INSTR blendvps, 1, 0 | |||
| AVX_INSTR cmppd, 1, 0 | |||
| AVX_INSTR cmpps, 1, 0 | |||
| AVX_INSTR cmpsd, 1, 0 | |||
| AVX_INSTR cmpss, 1, 0 | |||
| AVX_INSTR divpd, 1, 0 | |||
| AVX_INSTR divps, 1, 0 | |||
| AVX_INSTR divsd, 1, 0 | |||
| AVX_INSTR divss, 1, 0 | |||
| AVX_INSTR dppd, 1, 0 | |||
| AVX_INSTR dpps, 1, 0 | |||
| AVX_INSTR haddpd, 1, 0 | |||
| AVX_INSTR haddps, 1, 0 | |||
| AVX_INSTR hsubpd, 1, 0 | |||
| AVX_INSTR hsubps, 1, 0 | |||
| AVX_INSTR maxpd, 1, 0 | |||
| AVX_INSTR maxps, 1, 0 | |||
| AVX_INSTR maxsd, 1, 0 | |||
| AVX_INSTR maxss, 1, 0 | |||
| AVX_INSTR minpd, 1, 0 | |||
| AVX_INSTR minps, 1, 0 | |||
| AVX_INSTR minsd, 1, 0 | |||
| AVX_INSTR minss, 1, 0 | |||
| AVX_INSTR mpsadbw, 0, 1 | |||
| AVX_INSTR mulpd, 1, 0 | |||
| AVX_INSTR mulps, 1, 0 | |||
| AVX_INSTR mulsd, 1, 0 | |||
| AVX_INSTR mulss, 1, 0 | |||
| AVX_INSTR orpd, 1, 0 | |||
| AVX_INSTR orps, 1, 0 | |||
| AVX_INSTR packsswb, 0, 0 | |||
| AVX_INSTR packssdw, 0, 0 | |||
| AVX_INSTR packuswb, 0, 0 | |||
| AVX_INSTR packusdw, 0, 0 | |||
| AVX_INSTR paddb, 0, 0 | |||
| AVX_INSTR paddw, 0, 0 | |||
| AVX_INSTR paddd, 0, 0 | |||
| AVX_INSTR paddq, 0, 0 | |||
| AVX_INSTR paddsb, 0, 0 | |||
| AVX_INSTR paddsw, 0, 0 | |||
| AVX_INSTR paddusb, 0, 0 | |||
| AVX_INSTR paddusw, 0, 0 | |||
| AVX_INSTR palignr, 0, 1 | |||
| AVX_INSTR pand, 0, 0 | |||
| AVX_INSTR pandn, 0, 0 | |||
| AVX_INSTR pavgb, 0, 0 | |||
| AVX_INSTR pavgw, 0, 0 | |||
| AVX_INSTR pblendvb, 0, 0 | |||
| AVX_INSTR pblendw, 0, 1 | |||
| AVX_INSTR pcmpestri, 0, 0 | |||
| AVX_INSTR pcmpestrm, 0, 0 | |||
| AVX_INSTR pcmpistri, 0, 0 | |||
| AVX_INSTR pcmpistrm, 0, 0 | |||
| AVX_INSTR pcmpeqb, 0, 0 | |||
| AVX_INSTR pcmpeqw, 0, 0 | |||
| AVX_INSTR pcmpeqd, 0, 0 | |||
| AVX_INSTR pcmpeqq, 0, 0 | |||
| AVX_INSTR pcmpgtb, 0, 0 | |||
| AVX_INSTR pcmpgtw, 0, 0 | |||
| AVX_INSTR pcmpgtd, 0, 0 | |||
| AVX_INSTR pcmpgtq, 0, 0 | |||
| AVX_INSTR phaddw, 0, 0 | |||
| AVX_INSTR phaddd, 0, 0 | |||
| AVX_INSTR phaddsw, 0, 0 | |||
| AVX_INSTR phsubw, 0, 0 | |||
| AVX_INSTR phsubd, 0, 0 | |||
| AVX_INSTR phsubsw, 0, 0 | |||
| AVX_INSTR pmaddwd, 0, 0 | |||
| AVX_INSTR pmaddubsw, 0, 0 | |||
| AVX_INSTR pmaxsb, 0, 0 | |||
| AVX_INSTR pmaxsw, 0, 0 | |||
| AVX_INSTR pmaxsd, 0, 0 | |||
| AVX_INSTR pmaxub, 0, 0 | |||
| AVX_INSTR pmaxuw, 0, 0 | |||
| AVX_INSTR pmaxud, 0, 0 | |||
| AVX_INSTR pminsb, 0, 0 | |||
| AVX_INSTR pminsw, 0, 0 | |||
| AVX_INSTR pminsd, 0, 0 | |||
| AVX_INSTR pminub, 0, 0 | |||
| AVX_INSTR pminuw, 0, 0 | |||
| AVX_INSTR pminud, 0, 0 | |||
| AVX_INSTR pmulhuw, 0, 0 | |||
| AVX_INSTR pmulhrsw, 0, 0 | |||
| AVX_INSTR pmulhw, 0, 0 | |||
| AVX_INSTR pmullw, 0, 0 | |||
| AVX_INSTR pmulld, 0, 0 | |||
| AVX_INSTR pmuludq, 0, 0 | |||
| AVX_INSTR pmuldq, 0, 0 | |||
| AVX_INSTR por, 0, 0 | |||
| AVX_INSTR psadbw, 0, 0 | |||
| AVX_INSTR pshufb, 0, 0 | |||
| AVX_INSTR psignb, 0, 0 | |||
| AVX_INSTR psignw, 0, 0 | |||
| AVX_INSTR psignd, 0, 0 | |||
| AVX_INSTR psllw, 0, 0 | |||
| AVX_INSTR pslld, 0, 0 | |||
| AVX_INSTR psllq, 0, 0 | |||
| AVX_INSTR pslldq, 0, 0 | |||
| AVX_INSTR psraw, 0, 0 | |||
| AVX_INSTR psrad, 0, 0 | |||
| AVX_INSTR psrlw, 0, 0 | |||
| AVX_INSTR psrld, 0, 0 | |||
| AVX_INSTR psrlq, 0, 0 | |||
| AVX_INSTR psrldq, 0, 0 | |||
| AVX_INSTR psubb, 0, 0 | |||
| AVX_INSTR psubw, 0, 0 | |||
| AVX_INSTR psubd, 0, 0 | |||
| AVX_INSTR psubq, 0, 0 | |||
| AVX_INSTR psubsb, 0, 0 | |||
| AVX_INSTR psubsw, 0, 0 | |||
| AVX_INSTR psubusb, 0, 0 | |||
| AVX_INSTR psubusw, 0, 0 | |||
| AVX_INSTR punpckhbw, 0, 0 | |||
| AVX_INSTR punpckhwd, 0, 0 | |||
| AVX_INSTR punpckhdq, 0, 0 | |||
| AVX_INSTR punpckhqdq, 0, 0 | |||
| AVX_INSTR punpcklbw, 0, 0 | |||
| AVX_INSTR punpcklwd, 0, 0 | |||
| AVX_INSTR punpckldq, 0, 0 | |||
| AVX_INSTR punpcklqdq, 0, 0 | |||
| AVX_INSTR pxor, 0, 0 | |||
| AVX_INSTR shufps, 0, 1 | |||
| AVX_INSTR subpd, 1, 0 | |||
| AVX_INSTR subps, 1, 0 | |||
| AVX_INSTR subsd, 1, 0 | |||
| AVX_INSTR subss, 1, 0 | |||
| AVX_INSTR unpckhpd, 1, 0 | |||
| AVX_INSTR unpckhps, 1, 0 | |||
| AVX_INSTR unpcklpd, 1, 0 | |||
| AVX_INSTR unpcklps, 1, 0 | |||
| AVX_INSTR xorpd, 1, 0 | |||
| AVX_INSTR xorps, 1, 0 | |||
| AVX_INSTR addpd, 1, 0, 1 | |||
| AVX_INSTR addps, 1, 0, 1 | |||
| AVX_INSTR addsd, 1, 0, 1 | |||
| AVX_INSTR addss, 1, 0, 1 | |||
| AVX_INSTR addsubpd, 1, 0, 0 | |||
| AVX_INSTR addsubps, 1, 0, 0 | |||
| AVX_INSTR andpd, 1, 0, 1 | |||
| AVX_INSTR andps, 1, 0, 1 | |||
| AVX_INSTR andnpd, 1, 0, 0 | |||
| AVX_INSTR andnps, 1, 0, 0 | |||
| AVX_INSTR blendpd, 1, 0, 0 | |||
| AVX_INSTR blendps, 1, 0, 0 | |||
| AVX_INSTR blendvpd, 1, 0, 0 | |||
| AVX_INSTR blendvps, 1, 0, 0 | |||
| AVX_INSTR cmppd, 1, 0, 0 | |||
| AVX_INSTR cmpps, 1, 0, 0 | |||
| AVX_INSTR cmpsd, 1, 0, 0 | |||
| AVX_INSTR cmpss, 1, 0, 0 | |||
| AVX_INSTR divpd, 1, 0, 0 | |||
| AVX_INSTR divps, 1, 0, 0 | |||
| AVX_INSTR divsd, 1, 0, 0 | |||
| AVX_INSTR divss, 1, 0, 0 | |||
| AVX_INSTR dppd, 1, 1, 0 | |||
| AVX_INSTR dpps, 1, 1, 0 | |||
| AVX_INSTR haddpd, 1, 0, 0 | |||
| AVX_INSTR haddps, 1, 0, 0 | |||
| AVX_INSTR hsubpd, 1, 0, 0 | |||
| AVX_INSTR hsubps, 1, 0, 0 | |||
| AVX_INSTR maxpd, 1, 0, 1 | |||
| AVX_INSTR maxps, 1, 0, 1 | |||
| AVX_INSTR maxsd, 1, 0, 1 | |||
| AVX_INSTR maxss, 1, 0, 1 | |||
| AVX_INSTR minpd, 1, 0, 1 | |||
| AVX_INSTR minps, 1, 0, 1 | |||
| AVX_INSTR minsd, 1, 0, 1 | |||
| AVX_INSTR minss, 1, 0, 1 | |||
| AVX_INSTR movsd, 1, 0, 0 | |||
| AVX_INSTR movss, 1, 0, 0 | |||
| AVX_INSTR mpsadbw, 0, 1, 0 | |||
| AVX_INSTR mulpd, 1, 0, 1 | |||
| AVX_INSTR mulps, 1, 0, 1 | |||
| AVX_INSTR mulsd, 1, 0, 1 | |||
| AVX_INSTR mulss, 1, 0, 1 | |||
| AVX_INSTR orpd, 1, 0, 1 | |||
| AVX_INSTR orps, 1, 0, 1 | |||
| AVX_INSTR packsswb, 0, 0, 0 | |||
| AVX_INSTR packssdw, 0, 0, 0 | |||
| AVX_INSTR packuswb, 0, 0, 0 | |||
| AVX_INSTR packusdw, 0, 0, 0 | |||
| AVX_INSTR paddb, 0, 0, 1 | |||
| AVX_INSTR paddw, 0, 0, 1 | |||
| AVX_INSTR paddd, 0, 0, 1 | |||
| AVX_INSTR paddq, 0, 0, 1 | |||
| AVX_INSTR paddsb, 0, 0, 1 | |||
| AVX_INSTR paddsw, 0, 0, 1 | |||
| AVX_INSTR paddusb, 0, 0, 1 | |||
| AVX_INSTR paddusw, 0, 0, 1 | |||
| AVX_INSTR palignr, 0, 1, 0 | |||
| AVX_INSTR pand, 0, 0, 1 | |||
| AVX_INSTR pandn, 0, 0, 0 | |||
| AVX_INSTR pavgb, 0, 0, 1 | |||
| AVX_INSTR pavgw, 0, 0, 1 | |||
| AVX_INSTR pblendvb, 0, 0, 0 | |||
| AVX_INSTR pblendw, 0, 1, 0 | |||
| AVX_INSTR pcmpestri, 0, 0, 0 | |||
| AVX_INSTR pcmpestrm, 0, 0, 0 | |||
| AVX_INSTR pcmpistri, 0, 0, 0 | |||
| AVX_INSTR pcmpistrm, 0, 0, 0 | |||
| AVX_INSTR pcmpeqb, 0, 0, 1 | |||
| AVX_INSTR pcmpeqw, 0, 0, 1 | |||
| AVX_INSTR pcmpeqd, 0, 0, 1 | |||
| AVX_INSTR pcmpeqq, 0, 0, 1 | |||
| AVX_INSTR pcmpgtb, 0, 0, 0 | |||
| AVX_INSTR pcmpgtw, 0, 0, 0 | |||
| AVX_INSTR pcmpgtd, 0, 0, 0 | |||
| AVX_INSTR pcmpgtq, 0, 0, 0 | |||
| AVX_INSTR phaddw, 0, 0, 0 | |||
| AVX_INSTR phaddd, 0, 0, 0 | |||
| AVX_INSTR phaddsw, 0, 0, 0 | |||
| AVX_INSTR phsubw, 0, 0, 0 | |||
| AVX_INSTR phsubd, 0, 0, 0 | |||
| AVX_INSTR phsubsw, 0, 0, 0 | |||
| AVX_INSTR pmaddwd, 0, 0, 1 | |||
| AVX_INSTR pmaddubsw, 0, 0, 0 | |||
| AVX_INSTR pmaxsb, 0, 0, 1 | |||
| AVX_INSTR pmaxsw, 0, 0, 1 | |||
| AVX_INSTR pmaxsd, 0, 0, 1 | |||
| AVX_INSTR pmaxub, 0, 0, 1 | |||
| AVX_INSTR pmaxuw, 0, 0, 1 | |||
| AVX_INSTR pmaxud, 0, 0, 1 | |||
| AVX_INSTR pminsb, 0, 0, 1 | |||
| AVX_INSTR pminsw, 0, 0, 1 | |||
| AVX_INSTR pminsd, 0, 0, 1 | |||
| AVX_INSTR pminub, 0, 0, 1 | |||
| AVX_INSTR pminuw, 0, 0, 1 | |||
| AVX_INSTR pminud, 0, 0, 1 | |||
| AVX_INSTR pmulhuw, 0, 0, 1 | |||
| AVX_INSTR pmulhrsw, 0, 0, 1 | |||
| AVX_INSTR pmulhw, 0, 0, 1 | |||
| AVX_INSTR pmullw, 0, 0, 1 | |||
| AVX_INSTR pmulld, 0, 0, 1 | |||
| AVX_INSTR pmuludq, 0, 0, 1 | |||
| AVX_INSTR pmuldq, 0, 0, 1 | |||
| AVX_INSTR por, 0, 0, 1 | |||
| AVX_INSTR psadbw, 0, 0, 1 | |||
| AVX_INSTR pshufb, 0, 0, 0 | |||
| AVX_INSTR psignb, 0, 0, 0 | |||
| AVX_INSTR psignw, 0, 0, 0 | |||
| AVX_INSTR psignd, 0, 0, 0 | |||
| AVX_INSTR psllw, 0, 0, 0 | |||
| AVX_INSTR pslld, 0, 0, 0 | |||
| AVX_INSTR psllq, 0, 0, 0 | |||
| AVX_INSTR pslldq, 0, 0, 0 | |||
| AVX_INSTR psraw, 0, 0, 0 | |||
| AVX_INSTR psrad, 0, 0, 0 | |||
| AVX_INSTR psrlw, 0, 0, 0 | |||
| AVX_INSTR psrld, 0, 0, 0 | |||
| AVX_INSTR psrlq, 0, 0, 0 | |||
| AVX_INSTR psrldq, 0, 0, 0 | |||
| AVX_INSTR psubb, 0, 0, 0 | |||
| AVX_INSTR psubw, 0, 0, 0 | |||
| AVX_INSTR psubd, 0, 0, 0 | |||
| AVX_INSTR psubq, 0, 0, 0 | |||
| AVX_INSTR psubsb, 0, 0, 0 | |||
| AVX_INSTR psubsw, 0, 0, 0 | |||
| AVX_INSTR psubusb, 0, 0, 0 | |||
| AVX_INSTR psubusw, 0, 0, 0 | |||
| AVX_INSTR punpckhbw, 0, 0, 0 | |||
| AVX_INSTR punpckhwd, 0, 0, 0 | |||
| AVX_INSTR punpckhdq, 0, 0, 0 | |||
| AVX_INSTR punpckhqdq, 0, 0, 0 | |||
| AVX_INSTR punpcklbw, 0, 0, 0 | |||
| AVX_INSTR punpcklwd, 0, 0, 0 | |||
| AVX_INSTR punpckldq, 0, 0, 0 | |||
| AVX_INSTR punpcklqdq, 0, 0, 0 | |||
| AVX_INSTR pxor, 0, 0, 1 | |||
| AVX_INSTR shufps, 0, 1, 0 | |||
| AVX_INSTR subpd, 1, 0, 0 | |||
| AVX_INSTR subps, 1, 0, 0 | |||
| AVX_INSTR subsd, 1, 0, 0 | |||
| AVX_INSTR subss, 1, 0, 0 | |||
| AVX_INSTR unpckhpd, 1, 0, 0 | |||
| AVX_INSTR unpckhps, 1, 0, 0 | |||
| AVX_INSTR unpcklpd, 1, 0, 0 | |||
| AVX_INSTR unpcklps, 1, 0, 0 | |||
| AVX_INSTR xorpd, 1, 0, 1 | |||
| AVX_INSTR xorps, 1, 0, 1 | |||
| ; 3DNow instructions, for sharing code between AVX, SSE and 3DN | |||
| AVX_INSTR pfadd, 1, 0 | |||
| AVX_INSTR pfsub, 1, 0 | |||
| AVX_INSTR pfmul, 1, 0 | |||
| AVX_INSTR pfadd, 1, 0, 1 | |||
| AVX_INSTR pfsub, 1, 0, 0 | |||
| AVX_INSTR pfmul, 1, 0, 1 | |||
| ; base-4 constants for shuffles | |||
| %assign i 0 | |||
| %rep 256 | |||
| %assign j ((i>>6)&3)*1000 + ((i>>4)&3)*100 + ((i>>2)&3)*10 + (i&3) | |||
| %if j < 10 | |||
| CAT_XDEFINE q000, j, i | |||
| %elif j < 100 | |||
| CAT_XDEFINE q00, j, i | |||
| %elif j < 1000 | |||
| CAT_XDEFINE q0, j, i | |||
| %else | |||
| CAT_XDEFINE q, j, i | |||
| %endif | |||
| %assign i i+1 | |||
| %endrep | |||
| %undef i | |||
| %undef j | |||
| %macro FMA_INSTR 3 | |||
| %macro %1 4-7 %1, %2, %3 | |||
| %if cpuflag(xop) | |||
| v%5 %1, %2, %3, %4 | |||
| %else | |||
| %6 %1, %2, %3 | |||
| %7 %1, %4 | |||
| %endif | |||
| %endmacro | |||
| %endmacro | |||
| FMA_INSTR pmacsdd, pmulld, paddd | |||
| FMA_INSTR pmacsww, pmullw, paddw | |||
| FMA_INSTR pmadcswd, pmaddwd, paddd | |||
| @@ -34,6 +34,12 @@ yuv2yuvX_10_start: times 4 dd 0x10000 | |||
| yuv2yuvX_9_start: times 4 dd 0x20000 | |||
| yuv2yuvX_10_upper: times 8 dw 0x3ff | |||
| yuv2yuvX_9_upper: times 8 dw 0x1ff | |||
| pd_4: times 4 dd 4 | |||
| pd_4min0x40000:times 4 dd 4 - (0x40000) | |||
| pw_16: times 8 dw 16 | |||
| pw_32: times 8 dw 32 | |||
| pw_512: times 8 dw 512 | |||
| pw_1024: times 8 dw 1024 | |||
| SECTION .text | |||
| @@ -665,3 +671,139 @@ INIT_AVX | |||
| yuv2planeX_fn avx, 8, 10, 7 | |||
| yuv2planeX_fn avx, 9, 7, 5 | |||
| yuv2planeX_fn avx, 10, 7, 5 | |||
| ; %1=outout-bpc, %2=alignment (u/a) | |||
| %macro yuv2plane1_mainloop 2 | |||
| .loop_%2: | |||
| %if %1 == 8 | |||
| paddsw m0, m2, [r0+r2*2+mmsize*0] | |||
| paddsw m1, m3, [r0+r2*2+mmsize*1] | |||
| psraw m0, 7 | |||
| psraw m1, 7 | |||
| packuswb m0, m1 | |||
| mov%2 [r1+r2], m0 | |||
| %elif %1 == 16 | |||
| paddd m0, m4, [r0+r2*4+mmsize*0] | |||
| paddd m1, m4, [r0+r2*4+mmsize*1] | |||
| paddd m2, m4, [r0+r2*4+mmsize*2] | |||
| paddd m3, m4, [r0+r2*4+mmsize*3] | |||
| psrad m0, 3 | |||
| psrad m1, 3 | |||
| psrad m2, 3 | |||
| psrad m3, 3 | |||
| %if cpuflag(sse4) ; avx/sse4 | |||
| packusdw m0, m1 | |||
| packusdw m2, m3 | |||
| %else ; mmx/sse2 | |||
| packssdw m0, m1 | |||
| packssdw m2, m3 | |||
| paddw m0, m5 | |||
| paddw m2, m5 | |||
| %endif ; mmx/sse2/sse4/avx | |||
| mov%2 [r1+r2*2], m0 | |||
| mov%2 [r1+r2*2+mmsize], m2 | |||
| %else | |||
| paddsw m0, m2, [r0+r2*2+mmsize*0] | |||
| paddsw m1, m2, [r0+r2*2+mmsize*1] | |||
| psraw m0, 15 - %1 | |||
| psraw m1, 15 - %1 | |||
| pmaxsw m0, m4 | |||
| pmaxsw m1, m4 | |||
| pminsw m0, m3 | |||
| pminsw m1, m3 | |||
| mov%2 [r1+r2*2], m0 | |||
| mov%2 [r1+r2*2+mmsize], m1 | |||
| %endif | |||
| add r2, mmsize | |||
| jl .loop_%2 | |||
| %endmacro | |||
| %macro yuv2plane1_fn 3 | |||
| cglobal yuv2plane1_%1, %3, %3, %2 | |||
| %if %1 == 8 | |||
| add r1, r2 | |||
| %else ; %1 != 8 | |||
| lea r1, [r1+r2*2] | |||
| %endif ; %1 == 8 | |||
| %if %1 == 16 | |||
| lea r0, [r0+r2*4] | |||
| %else ; %1 != 16 | |||
| lea r0, [r0+r2*2] | |||
| %endif ; %1 == 16 | |||
| neg r2 | |||
| %if %1 == 8 | |||
| pxor m4, m4 ; zero | |||
| ; create registers holding dither | |||
| movq m3, [r3] ; dither | |||
| test r4d, r4d | |||
| jz .no_rot | |||
| %if mmsize == 16 | |||
| punpcklqdq m3, m3 | |||
| %endif ; mmsize == 16 | |||
| PALIGNR_MMX m3, m3, 3, m2 | |||
| .no_rot: | |||
| %if mmsize == 8 | |||
| mova m2, m3 | |||
| punpckhbw m3, m4 ; byte->word | |||
| punpcklbw m2, m4 ; byte->word | |||
| %else | |||
| punpcklbw m3, m4 | |||
| mova m2, m3 | |||
| %endif | |||
| %elif %1 == 9 | |||
| pxor m4, m4 | |||
| mova m3, [pw_512] | |||
| mova m2, [pw_32] | |||
| %elif %1 == 10 | |||
| pxor m4, m4 | |||
| mova m3, [pw_1024] | |||
| mova m2, [pw_16] | |||
| %else ; %1 == 16 | |||
| %if cpuflag(sse4) ; sse4/avx | |||
| mova m4, [pd_4] | |||
| %else ; mmx/sse2 | |||
| mova m4, [pd_4min0x40000] | |||
| mova m5, [minshort] | |||
| %endif ; mmx/sse2/sse4/avx | |||
| %endif ; %1 == .. | |||
| ; actual pixel scaling | |||
| %if mmsize == 8 | |||
| yuv2plane1_mainloop %1, a | |||
| %else ; mmsize == 16 | |||
| test r1, 15 | |||
| jnz .unaligned | |||
| yuv2plane1_mainloop %1, a | |||
| REP_RET | |||
| .unaligned: | |||
| yuv2plane1_mainloop %1, u | |||
| %endif ; mmsize == 8/16 | |||
| REP_RET | |||
| %endmacro | |||
| %ifdef ARCH_X86_32 | |||
| INIT_MMX mmx | |||
| yuv2plane1_fn 8, 0, 5 | |||
| yuv2plane1_fn 16, 0, 3 | |||
| INIT_MMX mmx2 | |||
| yuv2plane1_fn 9, 0, 3 | |||
| yuv2plane1_fn 10, 0, 3 | |||
| %endif | |||
| INIT_XMM sse2 | |||
| yuv2plane1_fn 8, 5, 5 | |||
| yuv2plane1_fn 9, 5, 3 | |||
| yuv2plane1_fn 10, 5, 3 | |||
| yuv2plane1_fn 16, 6, 3 | |||
| INIT_XMM sse4 | |||
| yuv2plane1_fn 16, 5, 3 | |||
| INIT_XMM avx | |||
| yuv2plane1_fn 8, 5, 5 | |||
| yuv2plane1_fn 9, 5, 3 | |||
| yuv2plane1_fn 10, 5, 3 | |||
| yuv2plane1_fn 16, 5, 3 | |||
| @@ -289,6 +289,22 @@ VSCALEX_FUNCS(sse4, sse4); | |||
| VSCALEX_FUNC(16, sse4); | |||
| VSCALEX_FUNCS(avx, avx); | |||
| #define VSCALE_FUNC(size, opt) \ | |||
| extern void ff_yuv2plane1_ ## size ## _ ## opt(const int16_t *src, uint8_t *dst, int dstW, \ | |||
| const uint8_t *dither, int offset) | |||
| #define VSCALE_FUNCS(opt1, opt2) \ | |||
| VSCALE_FUNC(8, opt1); \ | |||
| VSCALE_FUNC(9, opt2); \ | |||
| VSCALE_FUNC(10, opt2); \ | |||
| VSCALE_FUNC(16, opt1) | |||
| #if ARCH_X86_32 | |||
| VSCALE_FUNCS(mmx, mmx2); | |||
| #endif | |||
| VSCALE_FUNCS(sse2, sse2); | |||
| VSCALE_FUNC(16, sse4); | |||
| VSCALE_FUNCS(avx, avx); | |||
| void ff_sws_init_swScale_mmx(SwsContext *c) | |||
| { | |||
| int cpu_flags = av_get_cpu_flags(); | |||
| @@ -336,11 +352,19 @@ switch(c->dstBpc){ \ | |||
| case 9: if (!isBE(c->dstFormat) && opt2chk) /*vscalefn = ff_yuv2planeX_9_ ## opt2;*/ break; \ | |||
| default: /*vscalefn = ff_yuv2planeX_8_ ## opt1;*/ break; \ | |||
| } | |||
| #define ASSIGN_VSCALE_FUNC(vscalefn, opt1, opt2, opt2chk) \ | |||
| switch(c->dstBpc){ \ | |||
| case 16: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2plane1_16_ ## opt1; break; \ | |||
| case 10: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_10_ ## opt2; break; \ | |||
| case 9: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_9_ ## opt2; break; \ | |||
| default: vscalefn = ff_yuv2plane1_8_ ## opt1; break; \ | |||
| } | |||
| #if ARCH_X86_32 | |||
| if (cpu_flags & AV_CPU_FLAG_MMX) { | |||
| ASSIGN_MMX_SCALE_FUNC(c->hyScale, c->hLumFilterSize, mmx, mmx); | |||
| ASSIGN_MMX_SCALE_FUNC(c->hcScale, c->hChrFilterSize, mmx, mmx); | |||
| ASSIGN_VSCALEX_FUNC(c->yuv2planeX, mmx, mmx2, cpu_flags & AV_CPU_FLAG_MMX2,); | |||
| ASSIGN_VSCALE_FUNC(c->yuv2plane1, mmx, mmx2, cpu_flags & AV_CPU_FLAG_MMX2); | |||
| } | |||
| #endif | |||
| #define ASSIGN_SSE_SCALE_FUNC(hscalefn, filtersize, opt1, opt2) \ | |||
| @@ -355,6 +379,7 @@ switch(c->dstBpc){ \ | |||
| ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse2, sse2); | |||
| ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse2, sse2); | |||
| ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2, sse2, 1,); | |||
| ASSIGN_VSCALE_FUNC(c->yuv2plane1, sse2, sse2, 1); | |||
| } | |||
| if (cpu_flags & AV_CPU_FLAG_SSSE3) { | |||
| ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, ssse3, ssse3); | |||
| @@ -366,10 +391,13 @@ switch(c->dstBpc){ \ | |||
| ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse4, ssse3); | |||
| ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse4, sse4, 1, | |||
| if (!isBE(c->dstFormat)) c->yuv2planeX = ff_yuv2planeX_16_sse4); | |||
| if (c->dstBpc == 16 && !isBE(c->dstFormat)) | |||
| c->yuv2plane1 = ff_yuv2plane1_16_sse4; | |||
| } | |||
| if (cpu_flags & AV_CPU_FLAG_AVX) { | |||
| ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx, avx, 1,); | |||
| ASSIGN_VSCALE_FUNC(c->yuv2plane1, avx, avx, 1); | |||
| } | |||
| #endif | |||
| } | |||
| @@ -109,29 +109,6 @@ static void RENAME(yuv2yuvX)(const int16_t *filter, int filterSize, | |||
| ); | |||
| } | |||
| static void RENAME(yuv2yuv1_ar)(const int16_t *src, uint8_t *dst, int dstW, const uint8_t *dither, int offset) | |||
| { | |||
| dither_8to16(dither, offset); | |||
| __asm__ volatile( | |||
| "mov %2, %%"REG_a" \n\t" | |||
| ".p2align 4 \n\t" /* FIXME Unroll? */ | |||
| "1: \n\t" | |||
| "movq (%0, %%"REG_a", 2), %%mm0 \n\t" | |||
| "movq 8(%0, %%"REG_a", 2), %%mm1 \n\t" | |||
| "paddsw %%mm3, %%mm0 \n\t" | |||
| "paddsw %%mm4, %%mm1 \n\t" | |||
| "psraw $7, %%mm0 \n\t" | |||
| "psraw $7, %%mm1 \n\t" | |||
| "packuswb %%mm1, %%mm0 \n\t" | |||
| MOVNTQ(%%mm0, (%1, %%REGa)) | |||
| "add $8, %%"REG_a" \n\t" | |||
| "jnc 1b \n\t" | |||
| :: "r" (src + dstW), "r" (dst + dstW), | |||
| "g" ((x86_reg)-dstW) | |||
| : "%"REG_a | |||
| ); | |||
| } | |||
| #define YSCALEYUV2PACKEDX_UV \ | |||
| __asm__ volatile(\ | |||
| "xor %%"REG_a", %%"REG_a" \n\t"\ | |||
| @@ -1881,9 +1858,7 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c) | |||
| c->use_mmx_vfilter= 0; | |||
| if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) && dstFormat != PIX_FMT_NV12 | |||
| && dstFormat != PIX_FMT_NV21 && !(c->flags & SWS_BITEXACT)) { | |||
| c->yuv2plane1 = RENAME(yuv2yuv1_ar ); | |||
| if (c->flags & SWS_ACCURATE_RND) { | |||
| //c->yuv2yuv1 = RENAME(yuv2yuv1_ar ); | |||
| if (!(c->flags & SWS_FULL_CHR_H_INT)) { | |||
| switch (c->dstFormat) { | |||
| case PIX_FMT_RGB32: c->yuv2packedX = RENAME(yuv2rgb32_X_ar); break; | |||
| @@ -1896,7 +1871,6 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c) | |||
| } | |||
| } else { | |||
| int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat); | |||
| //c->yuv2plane1 = should_dither ? RENAME(yuv2yuv1_ar ) : RENAME(yuv2yuv1 ); | |||
| c->use_mmx_vfilter= 1; | |||
| c->yuv2planeX = RENAME(yuv2yuvX ); | |||
| if (!(c->flags & SWS_FULL_CHR_H_INT)) { | |||