mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 13:30:45 +00:00
Merge remote-tracking branch 'qatar/master'
* 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>
This commit is contained in:
commit
13b7781ec8
89
Changelog
89
Changelog
@ -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:
|
||||
|
62
avconv.c
62
avconv.c
@ -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);
|
||||
|
||||
MATCH_PER_STREAM_OPT(top_field_first, i, top_field_first, oc, st);
|
||||
ost->top_field_first = top_field_first;
|
||||
ost->top_field_first = -1;
|
||||
MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
|
||||
|
||||
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
|
||||
|
||||
|
63
ffmpeg.c
63
ffmpeg.c
@ -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);
|
||||
|
||||
MATCH_PER_STREAM_OPT(top_field_first, i, top_field_first, oc, st);
|
||||
ost->top_field_first = top_field_first;
|
||||
ost->top_field_first = -1;
|
||||
MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
|
||||
|
||||
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))
|
||||
|
2
ffplay.c
2
ffplay.c
@ -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;
|
||||
}
|
||||
|
178
ffserver.c
178
ffserver.c
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user