diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-12-17 01:36:59 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-12-17 02:18:16 +0100 |
commit | 552ec4c9fda480d61bff8447347b08f927f1fca3 (patch) | |
tree | 72da1c610adde49ba4bb08e310e7d8f6b18ec581 | |
parent | 6d8e6fe9dbc365f50521cf0c4a5ffee97c970cb5 (diff) | |
parent | a1e98f198e9db4e5ddfc2f777014179d3d7bc4d2 (diff) | |
download | ffmpeg-552ec4c9fda480d61bff8447347b08f927f1fca3.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
get_bits: remove A32 variant
avconv: support stream specifiers in -metadata and -map_metadata
wavpack: Fix 32-bit clipping
wavpack: Clip samples after shifting
h264: don't drop B-frames after next keyframe on POC reset.
get_bits: remove useless pointer casts
configure: refactor lists of tests and components into variables
rv40: NEON optimised weak loop filter
mpegts: replace some magic numbers with the existing define
swscale: add unscaled packed 16 bit per component endianess conversion
Conflicts:
libavcodec/get_bits.h
libavcodec/h264.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | avconv.c | 207 | ||||
-rwxr-xr-x | configure | 48 | ||||
-rw-r--r-- | doc/avconv.texi | 38 | ||||
-rw-r--r-- | doc/avtools-common-opts.texi | 1 | ||||
-rw-r--r-- | ffmpeg.c | 218 | ||||
-rw-r--r-- | libavcodec/arm/rv40dsp_init_neon.c | 9 | ||||
-rw-r--r-- | libavcodec/arm/rv40dsp_neon.S | 110 | ||||
-rw-r--r-- | libavcodec/dv.c | 2 | ||||
-rw-r--r-- | libavcodec/get_bits.h | 4 | ||||
-rw-r--r-- | libavcodec/imc.c | 1 | ||||
-rw-r--r-- | libavcodec/proresdec_lgpl.c | 2 | ||||
-rw-r--r-- | libavcodec/wavpack.c | 8 | ||||
-rw-r--r-- | libavformat/mpegts.c | 6 | ||||
-rw-r--r-- | libswscale/swscale_unscaled.c | 30 |
14 files changed, 449 insertions, 235 deletions
@@ -354,6 +354,8 @@ typedef struct OptionsContext { int nb_inter_matrices; SpecifierOpt *top_field_first; int nb_top_field_first; + SpecifierOpt *metadata_map; + int nb_metadata_map; SpecifierOpt *presets; int nb_presets; SpecifierOpt *copy_initial_nonkeyframes; @@ -2865,7 +2867,13 @@ static int opt_attach(OptionsContext *o, const char *opt, const char *arg) return 0; } -static void parse_meta_type(char *arg, char *type, int *index) +/** + * Parse a metadata specifier in arg. + * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram) + * @param index for type c/p, chapter/program index is written here + * @param stream_spec for type s, the stream specifier is written here + */ +static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec) { if (*arg) { *type = *arg; @@ -2873,6 +2881,12 @@ static void parse_meta_type(char *arg, char *type, int *index) case 'g': break; case 's': + if (*(++arg) && *arg != ':') { + av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg); + exit_program(1); + } + *stream_spec = *arg == ':' ? arg + 1 : ""; + break; case 'c': case 'p': if (*(++arg) == ':') @@ -2886,31 +2900,76 @@ static void parse_meta_type(char *arg, char *type, int *index) *type = 'g'; } -static int opt_map_metadata(OptionsContext *o, const char *opt, const char *arg) +static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o) { - MetadataMap *m, *m1; - char *p; - - o->meta_data_maps = grow_array(o->meta_data_maps, sizeof(*o->meta_data_maps), - &o->nb_meta_data_maps, o->nb_meta_data_maps + 1); - - m = &o->meta_data_maps[o->nb_meta_data_maps - 1][1]; - m->file = strtol(arg, &p, 0); - parse_meta_type(*p ? p + 1 : p, &m->type, &m->index); + AVDictionary **meta_in = NULL; + AVDictionary **meta_out; + int i, ret = 0; + char type_in, type_out; + const char *istream_spec = NULL, *ostream_spec = NULL; + int idx_in = 0, idx_out = 0; - m1 = &o->meta_data_maps[o->nb_meta_data_maps - 1][0]; - if (p = strchr(opt, ':')) - parse_meta_type(p + 1, &m1->type, &m1->index); - else - m1->type = 'g'; + parse_meta_type(inspec, &type_in, &idx_in, &istream_spec); + parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec); - if (m->type == 'g' || m1->type == 'g') + if (type_in == 'g' || type_out == 'g') o->metadata_global_manual = 1; - if (m->type == 's' || m1->type == 's') + if (type_in == 's' || type_out == 's') o->metadata_streams_manual = 1; - if (m->type == 'c' || m1->type == 'c') + if (type_in == 'c' || type_out == 'c') o->metadata_chapters_manual = 1; +#define METADATA_CHECK_INDEX(index, nb_elems, desc)\ + if ((index) < 0 || (index) >= (nb_elems)) {\ + av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\ + (desc), (index));\ + exit_program(1);\ + } + +#define SET_DICT(type, meta, context, index)\ + switch (type) {\ + case 'g':\ + meta = &context->metadata;\ + break;\ + case 'c':\ + METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\ + meta = &context->chapters[index]->metadata;\ + break;\ + case 'p':\ + METADATA_CHECK_INDEX(index, context->nb_programs, "program")\ + meta = &context->programs[index]->metadata;\ + break;\ + }\ + + SET_DICT(type_in, meta_in, ic, idx_in); + SET_DICT(type_out, meta_out, oc, idx_out); + + /* for input streams choose first matching stream */ + if (type_in == 's') { + for (i = 0; i < ic->nb_streams; i++) { + if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) { + meta_in = &ic->streams[i]->metadata; + break; + } else if (ret < 0) + exit_program(1); + } + if (!meta_in) { + av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec); + exit_program(1); + } + } + + if (type_out == 's') { + for (i = 0; i < oc->nb_streams; i++) { + if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) { + meta_out = &oc->streams[i]->metadata; + av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE); + } else if (ret < 0) + exit_program(1); + } + } else + av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE); + return 0; } @@ -3802,6 +3861,20 @@ static void opt_output_file(void *optctx, const char *filename) } oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE); + /* copy metadata */ + for (i = 0; i < o->nb_metadata_map; i++) { + char *p; + int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0); + + if (in_file_index < 0) + continue; + if (in_file_index >= nb_input_files) { + av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index); + exit_program(1); + } + copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, input_files[in_file_index].ctx, o); + } + /* copy chapters */ if (o->chapters_input_file >= nb_input_files) { if (o->chapters_input_file == INT_MAX) { @@ -3822,52 +3895,6 @@ static void opt_output_file(void *optctx, const char *filename) copy_chapters(&input_files[o->chapters_input_file], &output_files[nb_output_files - 1], !o->metadata_chapters_manual); - /* copy metadata */ - for (i = 0; i < o->nb_meta_data_maps; i++) { - AVFormatContext *files[2]; - AVDictionary **meta[2]; - int j; - -#define METADATA_CHECK_INDEX(index, nb_elems, desc)\ - if ((index) < 0 || (index) >= (nb_elems)) {\ - av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps\n",\ - (desc), (index));\ - exit_program(1);\ - } - - int in_file_index = o->meta_data_maps[i][1].file; - if (in_file_index < 0) - continue; - METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file") - - files[0] = oc; - files[1] = input_files[in_file_index].ctx; - - for (j = 0; j < 2; j++) { - MetadataMap *map = &o->meta_data_maps[i][j]; - - switch (map->type) { - case 'g': - meta[j] = &files[j]->metadata; - break; - case 's': - METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream") - meta[j] = &files[j]->streams[map->index]->metadata; - break; - case 'c': - METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter") - meta[j] = &files[j]->chapters[map->index]->metadata; - break; - case 'p': - METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program") - meta[j] = &files[j]->programs[map->index]->metadata; - break; - } - } - - av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE); - } - /* copy global metadata by default */ if (!o->metadata_global_manual && nb_input_files) av_dict_copy(&oc->metadata, input_files[0].ctx->metadata, @@ -3885,7 +3912,8 @@ static void opt_output_file(void *optctx, const char *filename) for (i = 0; i < o->nb_metadata; i++) { AVDictionary **m; char type, *val; - int index = 0; + const char *stream_spec; + int index = 0, j, ret; val = strchr(o->metadata[i].u.str, '='); if (!val) { @@ -3895,31 +3923,34 @@ static void opt_output_file(void *optctx, const char *filename) } *val++ = 0; - parse_meta_type(o->metadata[i].specifier, &type, &index); - switch (type) { - case 'g': - m = &oc->metadata; - break; - case 's': - if (index < 0 || index >= oc->nb_streams) { - av_log(NULL, AV_LOG_FATAL, "Invalid stream index %d in metadata specifier.\n", index); - exit_program(1); + parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec); + if (type == 's') { + for (j = 0; j < oc->nb_streams; j++) { + if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { + av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); + } else if (ret < 0) + exit_program(1); } - m = &oc->streams[index]->metadata; - break; - case 'c': - if (index < 0 || index >= oc->nb_chapters) { - av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + printf("ret %d, stream_spec %s\n", ret, stream_spec); + } + else { + switch (type) { + case 'g': + m = &oc->metadata; + break; + case 'c': + if (index < 0 || index >= oc->nb_chapters) { + av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + exit_program(1); + } + m = &oc->chapters[index]->metadata; + break; + default: + av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); exit_program(1); } - m = &oc->chapters[index]->metadata; - break; - default: - av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); - exit_program(1); + av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); } - - av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); } reset_options(o); @@ -4231,7 +4262,7 @@ static const OptionDef options[] = { { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" }, { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" }, - { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", + { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata_map)}, "set metadata information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(chapters_input_file)}, "set chapters mapping", "input_file_index" }, { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" }, @@ -1882,6 +1882,20 @@ INDEV_LIST=$(find_things indev _IN libavdevice/alldevices.c) PROTOCOL_LIST=$(find_things protocol PROTOCOL libavformat/allformats.c) FILTER_LIST=$(find_things filter FILTER libavfilter/allfilters.c) +ALL_COMPONENTS=" + $BSF_LIST + $DECODER_LIST + $DEMUXER_LIST + $ENCODER_LIST + $FILTER_LIST + $HWACCEL_LIST + $INDEV_LIST + $MUXER_LIST + $OUTDEV_LIST + $PARSER_LIST + $PROTOCOL_LIST +" + find_tests(){ map "echo ${2}\${v}_test" $(ls "$source_path"/tests/ref/$1 | grep -v '[^-a-z0-9_]') } @@ -1892,6 +1906,8 @@ LAVF_TESTS=$(find_tests lavf) LAVFI_TESTS=$(find_tests lavfi) SEEK_TESTS=$(find_tests seek seek_) +ALL_TESTS="$ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS" + pcm_test_deps=$(map 'echo ${v%_*}_decoder $v' $(filter pcm_* $ENCODER_LIST)) for n in $COMPONENT_LIST; do @@ -1900,7 +1916,7 @@ for n in $COMPONENT_LIST; do eval ${n}_if_any="\$$v" done -enable $ARCH_EXT_LIST $ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS +enable $ARCH_EXT_LIST $ALL_TESTS die_unknown(){ echo "Unknown option \"$1\"." @@ -3310,22 +3326,8 @@ enabled_any $THREADS_LIST && enable threads check_deps $CONFIG_LIST \ $CONFIG_EXTRA \ $HAVE_LIST \ - $DECODER_LIST \ - $ENCODER_LIST \ - $HWACCEL_LIST \ - $PARSER_LIST \ - $BSF_LIST \ - $DEMUXER_LIST \ - $MUXER_LIST \ - $FILTER_LIST \ - $INDEV_LIST \ - $OUTDEV_LIST \ - $PROTOCOL_LIST \ - $ACODEC_TESTS \ - $VCODEC_TESTS \ - $LAVF_TESTS \ - $LAVFI_TESTS \ - $SEEK_TESTS \ + $ALL_COMPONENTS \ + $ALL_TESTS \ enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } @@ -3606,17 +3608,7 @@ print_config ARCH_ "$config_files" $ARCH_LIST print_config HAVE_ "$config_files" $HAVE_LIST print_config CONFIG_ "$config_files" $CONFIG_LIST \ $CONFIG_EXTRA \ - $DECODER_LIST \ - $ENCODER_LIST \ - $HWACCEL_LIST \ - $PARSER_LIST \ - $BSF_LIST \ - $DEMUXER_LIST \ - $MUXER_LIST \ - $FILTER_LIST \ - $PROTOCOL_LIST \ - $INDEV_LIST \ - $OUTDEV_LIST \ + $ALL_COMPONENTS \ cat >>config.mak <<EOF ACODEC_TESTS=$(print_enabled -n _test $ACODEC_TESTS) diff --git a/doc/avconv.texi b/doc/avconv.texi index f83cf590b6..e6ebe71d9d 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -173,9 +173,9 @@ For example, for setting the title in the output file: avconv -i in.avi -metadata title="my title" out.flv @end example -To set the language of the second stream: +To set the language of the first audio stream: @example -avconv -i INPUT -metadata:s:1 language=eng OUTPUT +avconv -i INPUT -metadata:s:a:0 language=eng OUTPUT @end example @item -target @var{type} (@emph{output}) @@ -680,14 +680,28 @@ avconv -i INPUT -map 0 -map -0:a:1 OUTPUT Note that using this option disables the default mappings for this output file. -@item -map_metadata[:@var{metadata_type}][:@var{index}] @var{infile}[:@var{metadata_type}][:@var{index}] (@emph{output,per-metadata}) +@item -map_metadata[:@var{metadata_spec_out}] @var{infile}[:@var{metadata_spec_in}] (@emph{output,per-metadata}) Set metadata information of the next output file from @var{infile}. Note that those are file indices (zero-based), not filenames. -Optional @var{metadata_type} parameters specify, which metadata to copy - (g)lobal -(i.e. metadata that applies to the whole file), per-(s)tream, per-(c)hapter or -per-(p)rogram. All metadata specifiers other than global must be followed by the -stream/chapter/program index. If metadata specifier is omitted, it defaults to -global. +Optional @var{metadata_spec_in/out} parameters specify, which metadata to copy. +A metadata specifier can have the following forms: +@table @option +@item @var{g} +global metadata, i.e. metadata that applies to the whole file + +@item @var{s}[:@var{stream_spec}] +per-stream metadata. @var{stream_spec} is a stream specifier as described +in the @ref{Stream specifiers} chapter. In an input metadata specifier, the first +matching stream is copied from. In an output metadata specifier, all matching +streams are copied to. + +@item @var{c}:@var{chapter_index} +per-chapter metadata. @var{chapter_index} is the zero-based chapter index. + +@item @var{p}:@var{program_index} +per-program metadata. @var{program_index} is the zero-based program index. +@end table +If metadata specifier is omitted, it defaults to global. By default, global metadata is copied from the first input file, per-stream and per-chapter metadata is copied along with streams/chapters. These @@ -699,6 +713,14 @@ of the output file: @example avconv -i in.ogg -map_metadata 0:s:0 out.mp3 @end example + +To do the reverse, i.e. copy global metadata to all audio streams: +@example +avconv -i in.mkv -map_metadata:s:a 0:g out.mkv +@end example +Note that simple @code{0} would work as well in this example, since global +metadata is assumed by default. + @item -map_chapters @var{input_file_index} (@emph{output}) Copy chapters from input file with index @var{input_file_index} to the next output file. If no chapter mapping is specified, then chapters are copied from diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi index b97a3c8b2a..1a50d6e6b2 100644 --- a/doc/avtools-common-opts.texi +++ b/doc/avtools-common-opts.texi @@ -11,6 +11,7 @@ corresponding value to true. They can be set to false by prefixing with "no" the option name, for example using "-nofoo" in the command line will set to false the boolean option with name "foo". +@anchor{Stream specifiers} @section Stream specifiers Some options are applied per-stream, e.g. bitrate or codec. Stream specifiers are used to precisely specify which stream(s) does a given option belong to. @@ -376,6 +376,8 @@ typedef struct OptionsContext { int nb_inter_matrices; SpecifierOpt *top_field_first; int nb_top_field_first; + SpecifierOpt *metadata_map; + int nb_metadata_map; SpecifierOpt *presets; int nb_presets; SpecifierOpt *copy_initial_nonkeyframes; @@ -3110,7 +3112,13 @@ static int opt_map_channel(OptionsContext *o, const char *opt, const char *arg) return 0; } -static void parse_meta_type(char *arg, char *type, int *index) +/** + * Parse a metadata specifier in arg. + * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram) + * @param index for type c/p, chapter/program index is written here + * @param stream_spec for type s, the stream specifier is written here + */ +static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec) { if (*arg) { *type = *arg; @@ -3118,6 +3126,12 @@ static void parse_meta_type(char *arg, char *type, int *index) case 'g': break; case 's': + if (*(++arg) && *arg != ':') { + av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg); + exit_program(1); + } + *stream_spec = *arg == ':' ? arg + 1 : ""; + break; case 'c': case 'p': if (*(++arg) == ':') @@ -3131,39 +3145,77 @@ static void parse_meta_type(char *arg, char *type, int *index) *type = 'g'; } -static int opt_map_metadata(OptionsContext *o, const char *opt, const char *arg) +static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o) { - MetadataMap *m, *m1; - char *p; - - o->meta_data_maps = grow_array(o->meta_data_maps, sizeof(*o->meta_data_maps), - &o->nb_meta_data_maps, o->nb_meta_data_maps + 1); - - m = &o->meta_data_maps[o->nb_meta_data_maps - 1][1]; - m->file = strtol(arg, &p, 0); - parse_meta_type(*p ? p + 1 : p, &m->type, &m->index); + AVDictionary **meta_in = NULL; + AVDictionary **meta_out; + int i, ret = 0; + char type_in, type_out; + const char *istream_spec = NULL, *ostream_spec = NULL; + int idx_in = 0, idx_out = 0; - m1 = &o->meta_data_maps[o->nb_meta_data_maps - 1][0]; - if (p = strchr(opt, ':')) - parse_meta_type(p + 1, &m1->type, &m1->index); - else - m1->type = 'g'; + parse_meta_type(inspec, &type_in, &idx_in, &istream_spec); + parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec); - if (m->type == 'g' || m1->type == 'g') + if (type_in == 'g' || type_out == 'g') o->metadata_global_manual = 1; - if (m->type == 's' || m1->type == 's') + if (type_in == 's' || type_out == 's') o->metadata_streams_manual = 1; - if (m->type == 'c' || m1->type == 'c') + if (type_in == 'c' || type_out == 'c') o->metadata_chapters_manual = 1; - return 0; -} +#define METADATA_CHECK_INDEX(index, nb_elems, desc)\ + if ((index) < 0 || (index) >= (nb_elems)) {\ + av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\ + (desc), (index));\ + exit_program(1);\ + } + +#define SET_DICT(type, meta, context, index)\ + switch (type) {\ + case 'g':\ + meta = &context->metadata;\ + break;\ + case 'c':\ + METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\ + meta = &context->chapters[index]->metadata;\ + break;\ + case 'p':\ + METADATA_CHECK_INDEX(index, context->nb_programs, "program")\ + meta = &context->programs[index]->metadata;\ + break;\ + }\ + + SET_DICT(type_in, meta_in, ic, idx_in); + SET_DICT(type_out, meta_out, oc, idx_out); + + /* for input streams choose first matching stream */ + if (type_in == 's') { + for (i = 0; i < ic->nb_streams; i++) { + if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) { + meta_in = &ic->streams[i]->metadata; + break; + } else if (ret < 0) + exit_program(1); + } + if (!meta_in) { + av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec); + exit_program(1); + } + } -static int opt_map_meta_data(OptionsContext *o, const char *opt, const char *arg) -{ - av_log(NULL, AV_LOG_WARNING, "-map_meta_data is deprecated and will be removed soon. " - "Use -map_metadata instead.\n"); - return opt_map_metadata(o, opt, arg); + if (type_out == 's') { + for (i = 0; i < oc->nb_streams; i++) { + if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) { + meta_out = &oc->streams[i]->metadata; + av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE); + } else if (ret < 0) + exit_program(1); + } + } else + av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE); + + return 0; } static int opt_recording_timestamp(OptionsContext *o, const char *opt, const char *arg) @@ -4197,6 +4249,20 @@ static void opt_output_file(void *optctx, const char *filename) oc->loop_output = loop_output; } + /* copy metadata */ + for (i = 0; i < o->nb_metadata_map; i++) { + char *p; + int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0); + + if (in_file_index < 0) + continue; + if (in_file_index >= nb_input_files) { + av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index); + exit_program(1); + } + copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, input_files[in_file_index].ctx, o); + } + /* copy chapters */ if (o->chapters_input_file >= nb_input_files) { if (o->chapters_input_file == INT_MAX) { @@ -4217,54 +4283,6 @@ static void opt_output_file(void *optctx, const char *filename) copy_chapters(&input_files[o->chapters_input_file], &output_files[nb_output_files - 1], !o->metadata_chapters_manual); - /* copy metadata */ - for (i = 0; i < o->nb_meta_data_maps; i++) { - AVFormatContext *files[2]; - AVDictionary **meta[2]; - int j; - -#define METADATA_CHECK_INDEX(index, nb_elems, desc)\ - if ((index) < 0 || (index) >= (nb_elems)) {\ - av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps\n",\ - (desc), (index));\ - exit_program(1);\ - } - - int in_file_index = o->meta_data_maps[i][1].file; - if (in_file_index < 0) - continue; - METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file") - - files[0] = oc; - files[1] = input_files[in_file_index].ctx; - - for (j = 0; j < 2; j++) { - MetadataMap *map = &o->meta_data_maps[i][j]; - - switch (map->type) { - case 'g': - meta[j] = &files[j]->metadata; - break; - case 's': - METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream") - meta[j] = &files[j]->streams[map->index]->metadata; - break; - case 'c': - METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter") - meta[j] = &files[j]->chapters[map->index]->metadata; - break; - case 'p': - METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program") - meta[j] = &files[j]->programs[map->index]->metadata; - break; - default: - abort(); - } - } - - av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE); - } - /* copy global metadata by default */ if (!o->metadata_global_manual && nb_input_files){ av_dict_copy(&oc->metadata, input_files[0].ctx->metadata, @@ -4285,7 +4303,8 @@ static void opt_output_file(void *optctx, const char *filename) for (i = 0; i < o->nb_metadata; i++) { AVDictionary **m; char type, *val; - int index = 0; + const char *stream_spec; + int index = 0, j, ret; val = strchr(o->metadata[i].u.str, '='); if (!val) { @@ -4295,31 +4314,34 @@ static void opt_output_file(void *optctx, const char *filename) } *val++ = 0; - parse_meta_type(o->metadata[i].specifier, &type, &index); - switch (type) { - case 'g': - m = &oc->metadata; - break; - case 's': - if (index < 0 || index >= oc->nb_streams) { - av_log(NULL, AV_LOG_FATAL, "Invalid stream index %d in metadata specifier.\n", index); - exit_program(1); + parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec); + if (type == 's') { + for (j = 0; j < oc->nb_streams; j++) { + if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { + av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); + } else if (ret < 0) + exit_program(1); } - m = &oc->streams[index]->metadata; - break; - case 'c': - if (index < 0 || index >= oc->nb_chapters) { - av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + printf("ret %d, stream_spec %s\n", ret, stream_spec); + } + else { + switch (type) { + case 'g': + m = &oc->metadata; + break; + case 'c': + if (index < 0 || index >= oc->nb_chapters) { + av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + exit_program(1); + } + m = &oc->chapters[index]->metadata; + break; + default: + av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); exit_program(1); } - m = &oc->chapters[index]->metadata; - break; - default: - av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); - exit_program(1); + av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); } - - av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); } reset_options(o, 0); @@ -4679,9 +4701,7 @@ static const OptionDef options[] = { { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" }, { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" }, { "map_channel", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_channel}, "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" }, - { "map_meta_data", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile", - "outfile[,metadata]:infile[,metadata]" }, - { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", + { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata_map)}, "set metadata information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(chapters_input_file)}, "set chapters mapping", "input_file_index" }, { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" }, diff --git a/libavcodec/arm/rv40dsp_init_neon.c b/libavcodec/arm/rv40dsp_init_neon.c index 59dddb6605..898b841344 100644 --- a/libavcodec/arm/rv40dsp_init_neon.c +++ b/libavcodec/arm/rv40dsp_init_neon.c @@ -61,6 +61,13 @@ int ff_rv40_v_loop_filter_strength_neon(uint8_t *src, int stride, int beta, int beta2, int edge, int *p1, int *q1); +void ff_rv40_h_weak_loop_filter_neon(uint8_t *src, int stride, int filter_p1, + int filter_q1, int alpha, int beta, + int lim_p0q0, int lim_q1, int lim_p1); +void ff_rv40_v_weak_loop_filter_neon(uint8_t *src, int stride, int filter_p1, + int filter_q1, int alpha, int beta, + int lim_p0q0, int lim_q1, int lim_p1); + void ff_rv40dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) { c->put_pixels_tab[0][ 1] = ff_put_rv40_qpel16_mc10_neon; @@ -126,4 +133,6 @@ void ff_rv40dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) c->rv40_loop_filter_strength[0] = ff_rv40_h_loop_filter_strength_neon; c->rv40_loop_filter_strength[1] = ff_rv40_v_loop_filter_strength_neon; + c->rv40_weak_loop_filter[0] = ff_rv40_h_weak_loop_filter_neon; + c->rv40_weak_loop_filter[1] = ff_rv40_v_weak_loop_filter_neon; } diff --git a/libavcodec/arm/rv40dsp_neon.S b/libavcodec/arm/rv40dsp_neon.S index d9e1b7c959..f68f38234a 100644 --- a/libavcodec/arm/rv40dsp_neon.S +++ b/libavcodec/arm/rv40dsp_neon.S @@ -808,3 +808,113 @@ function ff_rv40_v_loop_filter_strength_neon, export=1 vmov.u16 r0, d0[0] bx lr endfunc + +.macro rv40_weak_loop_filter + vdup.16 d30, r2 @ filter_p1 + vdup.16 d31, r3 @ filter_q1 + ldrd r2, r3, [sp] + vdup.16 d28, r2 @ alpha + vdup.16 d29, r3 @ beta + ldr r12, [sp, #8] + vdup.16 d25, r12 @ lim_p0q0 + ldrd r2, r3, [sp, #12] + vsubl.u8 q9, d5, d4 @ x, t + vabdl.u8 q8, d5, d4 @ x, abs(t) + vneg.s16 q15, q15 + vceq.i16 d16, d19, #0 @ !t + vshl.s16 d19, d19, #2 @ t << 2 + vmul.u16 d18, d17, d28 @ alpha * abs(t) + vand d24, d30, d31 @ filter_p1 & filter_q1 + vsubl.u8 q1, d0, d4 @ p1p2, p1p0 + vsubl.u8 q3, d1, d5 @ q1q2, q1q0 + vmov.i16 d22, #3 + vshr.u16 d18, d18, #7 + vadd.i16 d22, d22, d24 @ 3 - (filter_p1 & filter_q1) + vsubl.u8 q10, d0, d1 @ src[-2] - src[1] + vcle.u16 d18, d18, d22 + vand d20, d20, d24 + vneg.s16 d23, d25 @ -lim_p0q0 + vadd.s16 d19, d19, d20 + vbic d16, d18, d16 @ t && u <= 3 - (fp1 & fq1) + vtrn.32 d4, d5 @ -3, 2, -1, 0 + vrshr.s16 d19, d19, #3 + vmov d28, d29 @ beta + vswp d3, d6 @ q1q2, p1p0 + vmin.s16 d19, d19, d25 + vand d30, d30, d16 + vand d31, d31, d16 + vadd.s16 q10, q1, q3 @ p1p2 + p1p0, q1q2 + q1q0 + vmax.s16 d19, d19, d23 @ diff + vabs.s16 q1, q1 @ abs(p1p2), abs(q1q2) + vand d18, d19, d16 @ diff + vcle.u16 q1, q1, q14 + vneg.s16 d19, d18 @ -diff + vdup.16 d26, r3 @ lim_p1 + vaddw.u8 q2, q9, d5 @ src[-1]+diff, src[0]-diff + vhsub.s16 q11, q10, q9 + vand q1, q1, q15 + vqmovun.s16 d4, q2 @ -1, 0 + vand q9, q11, q1 + vdup.16 d27, r2 @ lim_q1 + vneg.s16 q9, q9 + vneg.s16 q14, q13 + vmin.s16 q9, q9, q13 + vtrn.32 d0, d1 @ -2, 1, -2, 1 + vmax.s16 q9, q9, q14 + vaddw.u8 q3, q9, d0 + vqmovun.s16 d5, q3 @ -2, 1 +.endm + +function ff_rv40_h_weak_loop_filter_neon, export=1 + sub r0, r0, r1, lsl #1 + sub r0, r0, r1 + + vld1.32 {d4[]}, [r0,:32], r1 + vld1.32 {d0[]}, [r0,:32], r1 + vld1.32 {d4[1]}, [r0,:32], r1 + vld1.32 {d5[]}, [r0,:32], r1 + vld1.32 {d1[]}, [r0,:32], r1 + vld1.32 {d5[0]}, [r0,:32] + + sub r0, r0, r1, lsl #2 + + rv40_weak_loop_filter + + vst1.32 {d5[0]}, [r0,:32], r1 + vst1.32 {d4[0]}, [r0,:32], r1 + vst1.32 {d4[1]}, [r0,:32], r1 + vst1.32 {d5[1]}, [r0,:32], r1 + + bx lr +endfunc + +function ff_rv40_v_weak_loop_filter_neon, export=1 + sub r12, r0, #3 + sub r0, r0, #2 + + vld1.8 {d4}, [r12], r1 + vld1.8 {d5}, [r12], r1 + vld1.8 {d2}, [r12], r1 + vld1.8 {d3}, [r12], r1 + + vtrn.16 q2, q1 + vtrn.8 d4, d5 + vtrn.8 d2, d3 + + vrev64.32 d5, d5 + vtrn.32 q2, q1 + vdup.32 d0, d3[0] + vdup.32 d1, d2[0] + + rv40_weak_loop_filter + + vtrn.32 q2, q3 + vswp d4, d5 + + vst4.8 {d4[0],d5[0],d6[0],d7[0]}, [r0], r1 + vst4.8 {d4[1],d5[1],d6[1],d7[1]}, [r0], r1 + vst4.8 {d4[2],d5[2],d6[2],d7[2]}, [r0], r1 + vst4.8 {d4[3],d5[3],d6[3],d7[3]}, [r0], r1 + + bx lr +endfunc diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 787bd6511e..a05928801d 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -37,7 +37,7 @@ * @file * DV codec. */ -#define ALT_BITSTREAM_READER + #include "libavutil/pixdesc.h" #include "avcodec.h" #include "dsputil.h" diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index d4d81375b1..46620410e3 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -133,12 +133,12 @@ for examples see get_bits, show_bits, skip_bits, get_vlc # ifdef ALT_BITSTREAM_READER_LE # define UPDATE_CACHE(name, gb) \ - name##_cache = AV_RL32(((const uint8_t *)(gb)->buffer)+(name##_index>>3)) >> (name##_index&0x07) + name##_cache = AV_RL32((gb)->buffer+(name##_index>>3)) >> (name##_index&0x07) # define SKIP_CACHE(name, gb, num) name##_cache >>= (num) # else # define UPDATE_CACHE(name, gb) \ - name##_cache = AV_RB32(((const uint8_t *)(gb)->buffer)+(name##_index>>3)) << (name##_index&0x07) + name##_cache = AV_RB32((gb)->buffer+(name##_index>>3)) << (name##_index&0x07) # define SKIP_CACHE(name, gb, num) name##_cache <<= (num) # endif diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 3919797038..d3b8bf5a12 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -35,7 +35,6 @@ #include <stddef.h> #include <stdio.h> -#define ALT_BITSTREAM_READER #include "avcodec.h" #include "get_bits.h" #include "dsputil.h" diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c index 1e9b962790..5fe47755c2 100644 --- a/libavcodec/proresdec_lgpl.c +++ b/libavcodec/proresdec_lgpl.c @@ -28,7 +28,7 @@ * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes */ -#define A32_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once +#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once #include <stdint.h> diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 1a8c25943f..8d9b804852 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -405,12 +405,12 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in } bit = (S & s->and) | s->or; - bit = (((S + bit) << s->shift) - bit); + bit = (((S + bit) << s->shift) - bit) << s->post_shift; if(s->hybrid) - bit = av_clip(bit, -s->hybrid_maxclip, s->hybrid_maxclip - 1); + bit = av_clip(bit, -s->hybrid_maxclip - 1, s->hybrid_maxclip); - return bit << s->post_shift; + return bit; } static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) @@ -798,7 +798,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->joint = s->frame_flags & WV_JOINT_STEREO; s->hybrid = s->frame_flags & WV_HYBRID_MODE; s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; - s->hybrid_maxclip = 1 << ((((s->frame_flags & 0x03) + 1) << 3) - 1); + s->hybrid_maxclip = (1LL << ((((s->frame_flags & 0x03) + 1) << 3) - 1)) - 1; s->post_shift = 8 * (bpp-1-(s->frame_flags&0x03)) + ((s->frame_flags >> 13) & 0x1f); s->CRC = AV_RL32(buf); buf += 4; if(wc->mkv_mode) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 846c587cca..0fa472d0a2 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -665,7 +665,7 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) pkt->size = pes->data_index; if(pes->total_size != MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index != pes->total_size + 6) { + pes->pes_header_size + pes->data_index != pes->total_size + PES_START_SIZE) { av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n"); pes->flags |= AV_PKT_FLAG_CORRUPT; } @@ -948,9 +948,9 @@ static int mpegts_push_data(MpegTSFilter *filter, * decreases demuxer delay for infrequent packets like subtitles from * a couple of seconds to milliseconds for properly muxed files. * total_size is the number of bytes following pes_packet_length - * in the pes header, i.e. not counting the first 6 bytes */ + * in the pes header, i.e. not counting the first PES_START_SIZE bytes */ if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index == pes->total_size + 6) { + pes->pes_header_size + pes->data_index == pes->total_size + PES_START_SIZE) { ts->stop_parse = 1; new_pes_packet(pes, ts->pkt); } diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 80ae5fc287..1065d79fc9 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -210,6 +210,27 @@ static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, c } } +static int packed_16bpc_bswap(SwsContext *c, const uint8_t* src[], + int srcStride[], int srcSliceY, int srcSliceH, + uint8_t* dst[], int dstStride[]) +{ + int i, j; + int srcstr = srcStride[0] >> 1; + int dststr = dstStride[0] >> 1; + uint16_t *dstPtr = (uint16_t *)dst[0]; + const uint16_t *srcPtr = (const uint16_t *)src[0]; + + for (i = 0; i < srcSliceH; i++) { + for (j = 0; j < srcstr; j++) { + dstPtr[j] = av_bswap16(srcPtr[j]); + } + srcPtr += srcstr; + dstPtr += dststr; + } + + return srcSliceH; +} + static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) { @@ -676,6 +697,15 @@ void ff_get_unscaled_swscale(SwsContext *c) if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND)) c->swScale= bgr24ToYv12Wrapper; + /* bswap 16 bits per component packed formats */ + if ((srcFormat == PIX_FMT_RGB48LE && dstFormat == PIX_FMT_RGB48BE) || + (srcFormat == PIX_FMT_RGB48BE && dstFormat == PIX_FMT_RGB48LE) || + (srcFormat == PIX_FMT_BGR48LE && dstFormat == PIX_FMT_BGR48BE) || + (srcFormat == PIX_FMT_BGR48BE && dstFormat == PIX_FMT_BGR48LE) || + (srcFormat == PIX_FMT_GRAY16LE && dstFormat == PIX_FMT_GRAY16BE) || + (srcFormat == PIX_FMT_GRAY16BE && dstFormat == PIX_FMT_GRAY16LE)) + c->swScale = packed_16bpc_bswap; + /* RGB/BGR -> RGB/BGR (no dither needed forms) */ if ( isAnyRGB(srcFormat) && isAnyRGB(dstFormat) |