Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 12 Dec 2011 23:29:25 +0000 (00:29 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 12 Dec 2011 23:39:48 +0000 (00:39 +0100)
* qatar/master:
  doxygen: misc consistency, spelling and wording fixes
  vcr1: drop unnecessary emms_c() calls without MMX code
  Replace all uses of av_close_input_file() with avformat_close_input().
  lavf: add avformat_close_input().
  lavf: deprecate av_close_input_stream().
  lavf doxy: add some basic demuxing documentation.
  lavf doxy: add some general lavf information.
  lavf doxy: add misc utility functions to a group.
  lavf doxy: add av_guess_codec/format to the encoding group.
  lavf doxy: add core functions to a doxy group.
  Add basic libavdevice documentation.
  lavc: convert error_recognition to err_recognition.
  avconv: update -map option help text
  x86: Require 7 registers for the cabac asm
  x86: bswap: remove test for bswap instruction
  bswap: make generic implementation more compiler-friendly
  h264: remove useless cast
  proresdec: fix decode_slice() prototype

Conflicts:
configure
doc/APIchanges
ffprobe.c
libavcodec/avcodec.h
libavcodec/celp_math.h
libavcodec/h264.c
libavfilter/src_movie.c
libavformat/anm.c
libavformat/avformat.h
libavformat/version.h
libavutil/avstring.h
libavutil/bswap.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
77 files changed:
1  2 
avconv.c
configure
doc/APIchanges
ffmpeg.c
ffplay.c
ffprobe.c
ffserver.c
libavcodec/aacpsy.c
libavcodec/amrwbdec.c
libavcodec/avcodec.h
libavcodec/cavs_parser.c
libavcodec/celp_math.h
libavcodec/dca_parser.c
libavcodec/dsputil.c
libavcodec/error_resilience.c
libavcodec/get_bits.h
libavcodec/h261dec.c
libavcodec/h261enc.c
libavcodec/h263dec.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_mvpred.h
libavcodec/ituh263dec.c
libavcodec/ituh263enc.c
libavcodec/latm_parser.c
libavcodec/mjpeg_parser.c
libavcodec/mpeg12.c
libavcodec/mpeg4video.h
libavcodec/mpeg4video_parser.h
libavcodec/mpeg4videodec.c
libavcodec/mpeg4videoenc.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavcodec/mpegvideo_common.h
libavcodec/mpegvideo_enc.c
libavcodec/msmpeg4.c
libavcodec/parser.c
libavcodec/proresdec_lgpl.c
libavcodec/pthread.c
libavcodec/ratecontrol.c
libavcodec/resample2.c
libavcodec/thread.h
libavcodec/vc1_parser.c
libavcodec/vcr1.c
libavdevice/avdevice.h
libavfilter/src_movie.c
libavformat/applehttp.c
libavformat/avformat.h
libavformat/avidec.c
libavformat/mpegts.c
libavformat/rdt.c
libavformat/rtpdec_asf.c
libavformat/rtpdec_qdm2.c
libavformat/rtsp.c
libavformat/rtsp.h
libavformat/sapdec.c
libavformat/seek-test.c
libavformat/utils.c
libavformat/version.h
libavformat/vorbiscomment.h
libavutil/arm/bswap.h
libavutil/avstring.h
libavutil/avutil.h
libavutil/bswap.h
libavutil/internal.h
libavutil/parseutils.h
libavutil/x86/bswap.h
libpostproc/postprocess.h
libpostproc/postprocess_template.c
libswscale/swscale.h
libswscale/swscale_internal.h
tests/audiogen.c
tests/rotozoom.c
tests/videogen.c
tools/pktdumper.c

diff --cc avconv.c
Simple merge
diff --cc configure
+++ b/configure
@@@ -1139,8 -1053,6 +1139,7 @@@ HAVE_LIST=
      asm_mod_y
      attribute_may_alias
      attribute_packed
-     bswap
 +    cbrtf
      closesocket
      cmov
      dcbzl
diff --cc doc/APIchanges
@@@ -13,24 -13,10 +13,28 @@@ libavutil:   2011-04-1
  
  API changes, most recent first:
  
 +2011-12-08 - a502939 - lavfi 2.52.0
 +  Add av_buffersink_poll_frame() to buffersink.h.
 +
 +2011-12-08 - xxxxxxx - lavu 51.31.0
 +  Add av_log_format_line.
 +
 +2011-12-03 - xxxxxxx - lavu 51.30.0
 +  Add AVERROR_BUG.
 +
 +2011-xx-xx - xxxxxxx - lavu 51.28.1
 +  Add av_get_alt_sample_fmt() to samplefmt.h.
 +
 +2011-11-03 - 96949da - lavu 51.23.0
 +  Add av_strcasecmp() and av_strncasecmp() to avstring.h.
 +
 +2011-10-20 - b35e9e1 - lavu 51.22.0
 +  Add av_strtok() to avstring.h.
 +
+ 2011-xx-xx - xxxxxxx - lavf 53.17.0
+   Add avformat_open_input().
+   Deprecate av_close_input_file() and av_close_input_stream().
  2011-xx-xx - xxxxxxx - lavc 53.25.0
    Add nb_samples and extended_data fields to AVFrame.
    Deprecate AVCODEC_MAX_AUDIO_FRAME_SIZE.
diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -654,16 -456,17 +654,16 @@@ void av_noreturn exit_program(int ret
          if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
              avio_close(s->pb);
          avformat_free_context(s);
 -        av_free(output_streams_for_file[i]);
 -        av_dict_free(&output_opts[i]);
 +        av_dict_free(&output_files[i].opts);
      }
      for(i=0;i<nb_input_files;i++) {
--        av_close_input_file(input_files[i].ctx);
++        avformat_close_input(&input_files[i].ctx);
      }
 -    for (i = 0; i < nb_input_streams; i++)
 +    for (i = 0; i < nb_input_streams; i++) {
 +        av_freep(&input_streams[i].decoded_frame);
 +        av_freep(&input_streams[i].filtered_frame);
          av_dict_free(&input_streams[i].opts);
 -
 -    av_free(intra_matrix);
 -    av_free(inter_matrix);
 +    }
  
      if (vstats_file)
          fclose(vstats_file);
@@@ -3421,9 -3233,9 +3421,9 @@@ static int opt_input_file(OptionsContex
      /* If not enough info to get the stream parameters, we decode the
         first frames to get it. (used in mpeg case for example) */
      ret = avformat_find_stream_info(ic, opts);
 -    if (ret < 0 && verbose >= 0) {
 -        fprintf(stderr, "%s: could not find codec parameters\n", filename);
 -        av_close_input_file(ic);
 +    if (ret < 0) {
 +        av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
-         av_close_input_file(ic);
++        avformat_close_input(&ic);
          exit_program(1);
      }
  
@@@ -4660,28 -4222,23 +4660,28 @@@ static int opt_video_filters(OptionsCon
  static const OptionDef options[] = {
      /* main options */
  #include "cmdutils_common_opts.h"
 -    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
 -    { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
 +    { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" },
 +    { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" },
      { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
 -    { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
 -    { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile",
 +    { "n", OPT_BOOL, {(void*)&no_file_overwrite}, "do not overwrite output files" },
 +    { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
 +    { "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", "file.stream[:syncfile.syncstream]" },
++    { "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, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
 +    { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
        "outfile[,metadata]:infile[,metadata]" },
 -    { "map_chapters",  HAS_ARG | OPT_EXPERT, {(void*)opt_map_chapters},  "set chapters mapping", "outfile:infile" },
 -    { "t", HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" },
 -    { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, //
 -    { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
 -    { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
 -    { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" },
 -    { "timestamp", HAS_ARG, {(void*)opt_recording_timestamp}, "set the recording timestamp ('now' to set the current time)", "time" },
 -    { "metadata", HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" },
 -    { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" },
 +    { "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" },
 +    { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET, {.off = OFFSET(limit_filesize)}, "set the limit file size in bytes", "limit_size" }, //
 +    { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" },
 +    { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" },
 +    { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(ts_scale)}, "set the input ts scale", "scale" },
 +    { "timestamp", HAS_ARG | OPT_FUNC2, {(void*)opt_recording_timestamp}, "set the recording timestamp ('now' to set the current time)", "time" },
 +    { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata)}, "add metadata", "string=string" },
 +    { "dframes", HAS_ARG | OPT_FUNC2, {(void*)opt_data_frames}, "set the number of data frames to record", "number" },
      { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
        "add timings for benchmarking" },
      { "timelimit", HAS_ARG, {(void*)opt_timelimit}, "set max runtime in seconds", "limit" },
diff --cc ffplay.c
Simple merge
diff --cc ffprobe.c
index 6af7695,0000000..577fed3
mode 100644,000000..100644
--- /dev/null
+++ b/ffprobe.c
@@@ -1,1270 -1,0 +1,1270 @@@
-     av_close_input_file(fmt_ctx);
 +/*
 + * ffprobe : Simple Media Prober based on the FFmpeg libraries
 + * Copyright (c) 2007-2010 Stefano Sabatini
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include "config.h"
 +
 +#include "libavformat/avformat.h"
 +#include "libavcodec/avcodec.h"
 +#include "libavutil/avstring.h"
 +#include "libavutil/opt.h"
 +#include "libavutil/pixdesc.h"
 +#include "libavutil/dict.h"
 +#include "libavdevice/avdevice.h"
 +#include "cmdutils.h"
 +
 +const char program_name[] = "ffprobe";
 +const int program_birth_year = 2007;
 +
 +static int do_show_format  = 0;
 +static int do_show_packets = 0;
 +static int do_show_streams = 0;
 +
 +static int show_value_unit              = 0;
 +static int use_value_prefix             = 0;
 +static int use_byte_value_binary_prefix = 0;
 +static int use_value_sexagesimal_format = 0;
 +
 +static char *print_format;
 +
 +static const OptionDef options[];
 +
 +/* FFprobe context */
 +static const char *input_filename;
 +static AVInputFormat *iformat = NULL;
 +
 +static const char *binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
 +static const char *decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P"  };
 +
 +static const char *unit_second_str          = "s"    ;
 +static const char *unit_hertz_str           = "Hz"   ;
 +static const char *unit_byte_str            = "byte" ;
 +static const char *unit_bit_per_second_str  = "bit/s";
 +
 +void av_noreturn exit_program(int ret)
 +{
 +    exit(ret);
 +}
 +
 +struct unit_value {
 +    union { double d; int i; } val;
 +    const char *unit;
 +};
 +
 +static char *value_string(char *buf, int buf_size, struct unit_value uv)
 +{
 +    double vald;
 +    int show_float = 0;
 +
 +    if (uv.unit == unit_second_str) {
 +        vald = uv.val.d;
 +        show_float = 1;
 +    } else {
 +        vald = uv.val.i;
 +    }
 +
 +    if (uv.unit == unit_second_str && use_value_sexagesimal_format) {
 +        double secs;
 +        int hours, mins;
 +        secs  = vald;
 +        mins  = (int)secs / 60;
 +        secs  = secs - mins * 60;
 +        hours = mins / 60;
 +        mins %= 60;
 +        snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
 +    } else if (use_value_prefix) {
 +        const char *prefix_string;
 +        int index, l;
 +
 +        if (uv.unit == unit_byte_str && use_byte_value_binary_prefix) {
 +            index = (int) (log(vald)/log(2)) / 10;
 +            index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) -1);
 +            vald /= pow(2, index*10);
 +            prefix_string = binary_unit_prefixes[index];
 +        } else {
 +            index = (int) (log10(vald)) / 3;
 +            index = av_clip(index, 0, FF_ARRAY_ELEMS(decimal_unit_prefixes) -1);
 +            vald /= pow(10, index*3);
 +            prefix_string = decimal_unit_prefixes[index];
 +        }
 +
 +        if (show_float || vald != (int)vald) l = snprintf(buf, buf_size, "%.3f", vald);
 +        else                                 l = snprintf(buf, buf_size, "%d",   (int)vald);
 +        snprintf(buf+l, buf_size-l, "%s%s%s", prefix_string || show_value_unit ? " " : "",
 +                 prefix_string, show_value_unit ? uv.unit : "");
 +    } else {
 +        int l;
 +
 +        if (show_float) l = snprintf(buf, buf_size, "%.3f", vald);
 +        else            l = snprintf(buf, buf_size, "%d",   (int)vald);
 +        snprintf(buf+l, buf_size-l, "%s%s", show_value_unit ? " " : "",
 +                 show_value_unit ? uv.unit : "");
 +    }
 +
 +    return buf;
 +}
 +
 +/* WRITERS API */
 +
 +typedef struct WriterContext WriterContext;
 +
 +#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1
 +
 +typedef struct Writer {
 +    int priv_size;                  ///< private size for the writer context
 +    const char *name;
 +
 +    int  (*init)  (WriterContext *wctx, const char *args, void *opaque);
 +    void (*uninit)(WriterContext *wctx);
 +
 +    void (*print_header)(WriterContext *ctx);
 +    void (*print_footer)(WriterContext *ctx);
 +
 +    void (*print_chapter_header)(WriterContext *wctx, const char *);
 +    void (*print_chapter_footer)(WriterContext *wctx, const char *);
 +    void (*print_section_header)(WriterContext *wctx, const char *);
 +    void (*print_section_footer)(WriterContext *wctx, const char *);
 +    void (*print_integer)       (WriterContext *wctx, const char *, long long int);
 +    void (*print_string)        (WriterContext *wctx, const char *, const char *);
 +    void (*show_tags)           (WriterContext *wctx, AVDictionary *dict);
 +    int flags;                  ///< a combination or WRITER_FLAG_*
 +} Writer;
 +
 +struct WriterContext {
 +    const AVClass *class;           ///< class of the writer
 +    const Writer *writer;           ///< the Writer of which this is an instance
 +    char *name;                     ///< name of this writer instance
 +    void *priv;                     ///< private data for use by the filter
 +    unsigned int nb_item;           ///< number of the item printed in the given section, starting at 0
 +    unsigned int nb_section;        ///< number of the section printed in the given section sequence, starting at 0
 +    unsigned int nb_chapter;        ///< number of the chapter, starting at 0
 +};
 +
 +static const char *writer_get_name(void *p)
 +{
 +    WriterContext *wctx = p;
 +    return wctx->writer->name;
 +}
 +
 +static const AVClass writer_class = {
 +    "Writer",
 +    writer_get_name,
 +    NULL,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +static void writer_close(WriterContext **wctx)
 +{
 +    if (*wctx && (*wctx)->writer->uninit)
 +        (*wctx)->writer->uninit(*wctx);
 +
 +    av_freep(&((*wctx)->priv));
 +    av_freep(wctx);
 +}
 +
 +static int writer_open(WriterContext **wctx, const Writer *writer,
 +                       const char *args, void *opaque)
 +{
 +    int ret = 0;
 +
 +    if (!(*wctx = av_malloc(sizeof(WriterContext)))) {
 +        ret = AVERROR(ENOMEM);
 +        goto fail;
 +    }
 +
 +    if (!((*wctx)->priv = av_mallocz(writer->priv_size))) {
 +        ret = AVERROR(ENOMEM);
 +        goto fail;
 +    }
 +
 +    (*wctx)->class = &writer_class;
 +    (*wctx)->writer = writer;
 +    if ((*wctx)->writer->init)
 +        ret = (*wctx)->writer->init(*wctx, args, opaque);
 +    if (ret < 0)
 +        goto fail;
 +
 +    return 0;
 +
 +fail:
 +    writer_close(wctx);
 +    return ret;
 +}
 +
 +static inline void writer_print_header(WriterContext *wctx)
 +{
 +    if (wctx->writer->print_header)
 +        wctx->writer->print_header(wctx);
 +    wctx->nb_chapter = 0;
 +}
 +
 +static inline void writer_print_footer(WriterContext *wctx)
 +{
 +    if (wctx->writer->print_footer)
 +        wctx->writer->print_footer(wctx);
 +}
 +
 +static inline void writer_print_chapter_header(WriterContext *wctx,
 +                                               const char *header)
 +{
 +    if (wctx->writer->print_chapter_header)
 +        wctx->writer->print_chapter_header(wctx, header);
 +    wctx->nb_section = 0;
 +}
 +
 +static inline void writer_print_chapter_footer(WriterContext *wctx,
 +                                               const char *footer)
 +{
 +    if (wctx->writer->print_chapter_footer)
 +        wctx->writer->print_chapter_footer(wctx, footer);
 +    wctx->nb_chapter++;
 +}
 +
 +static inline void writer_print_section_header(WriterContext *wctx,
 +                                               const char *header)
 +{
 +    if (wctx->writer->print_section_header)
 +        wctx->writer->print_section_header(wctx, header);
 +    wctx->nb_item = 0;
 +}
 +
 +static inline void writer_print_section_footer(WriterContext *wctx,
 +                                               const char *footer)
 +{
 +    if (wctx->writer->print_section_footer)
 +        wctx->writer->print_section_footer(wctx, footer);
 +    wctx->nb_section++;
 +}
 +
 +static inline void writer_print_integer(WriterContext *wctx,
 +                                        const char *key, long long int val)
 +{
 +    wctx->writer->print_integer(wctx, key, val);
 +    wctx->nb_item++;
 +}
 +
 +static inline void writer_print_string(WriterContext *wctx,
 +                                       const char *key, const char *val, int opt)
 +{
 +    if (opt && !(wctx->writer->flags & WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS))
 +        return;
 +    wctx->writer->print_string(wctx, key, val);
 +    wctx->nb_item++;
 +}
 +
 +static void writer_print_time(WriterContext *wctx, const char *key,
 +                              int64_t ts, const AVRational *time_base)
 +{
 +    char buf[128];
 +
 +    if (ts == AV_NOPTS_VALUE) {
 +        writer_print_string(wctx, key, "N/A", 1);
 +    } else {
 +        double d = ts * av_q2d(*time_base);
 +        value_string(buf, sizeof(buf), (struct unit_value){.val.d=d, .unit=unit_second_str});
 +        writer_print_string(wctx, key, buf, 0);
 +    }
 +}
 +
 +static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts)
 +{
 +    if (ts == AV_NOPTS_VALUE) {
 +        writer_print_string(wctx, key, "N/A", 1);
 +    } else {
 +        writer_print_integer(wctx, key, ts);
 +    }
 +}
 +
 +static inline void writer_show_tags(WriterContext *wctx, AVDictionary *dict)
 +{
 +    wctx->writer->show_tags(wctx, dict);
 +}
 +
 +#define MAX_REGISTERED_WRITERS_NB 64
 +
 +static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1];
 +
 +static int writer_register(const Writer *writer)
 +{
 +    static int next_registered_writer_idx = 0;
 +
 +    if (next_registered_writer_idx == MAX_REGISTERED_WRITERS_NB)
 +        return AVERROR(ENOMEM);
 +
 +    registered_writers[next_registered_writer_idx++] = writer;
 +    return 0;
 +}
 +
 +static const Writer *writer_get_by_name(const char *name)
 +{
 +    int i;
 +
 +    for (i = 0; registered_writers[i]; i++)
 +        if (!strcmp(registered_writers[i]->name, name))
 +            return registered_writers[i];
 +
 +    return NULL;
 +}
 +
 +/* Print helpers */
 +
 +struct print_buf {
 +    char *s;
 +    int len;
 +};
 +
 +static char *fast_asprintf(struct print_buf *pbuf, const char *fmt, ...)
 +{
 +    va_list va;
 +    int len;
 +
 +    va_start(va, fmt);
 +    len = vsnprintf(NULL, 0, fmt, va);
 +    va_end(va);
 +    if (len < 0)
 +        goto fail;
 +
 +    if (pbuf->len < len) {
 +        char *p = av_realloc(pbuf->s, len + 1);
 +        if (!p)
 +            goto fail;
 +        pbuf->s   = p;
 +        pbuf->len = len;
 +    }
 +
 +    va_start(va, fmt);
 +    len = vsnprintf(pbuf->s, len + 1, fmt, va);
 +    va_end(va);
 +    if (len < 0)
 +        goto fail;
 +    return pbuf->s;
 +
 +fail:
 +    av_freep(&pbuf->s);
 +    pbuf->len = 0;
 +    return NULL;
 +}
 +
 +#define ESCAPE_INIT_BUF_SIZE 256
 +
 +#define ESCAPE_CHECK_SIZE(src, size, max_size)                          \
 +    if (size > max_size) {                                              \
 +        char buf[64];                                                   \
 +        snprintf(buf, sizeof(buf), "%s", src);                          \
 +        av_log(log_ctx, AV_LOG_WARNING,                                 \
 +               "String '%s...' with is too big\n", buf);                \
 +        return "FFPROBE_TOO_BIG_STRING";                                \
 +    }
 +
 +#define ESCAPE_REALLOC_BUF(dst_size_p, dst_p, src, size)                \
 +    if (*dst_size_p < size) {                                           \
 +        char *q = av_realloc(*dst_p, size);                             \
 +        if (!q) {                                                       \
 +            char buf[64];                                               \
 +            snprintf(buf, sizeof(buf), "%s", src);                      \
 +            av_log(log_ctx, AV_LOG_WARNING,                             \
 +                   "String '%s...' could not be escaped\n", buf);       \
 +            return "FFPROBE_THIS_STRING_COULD_NOT_BE_ESCAPED";          \
 +        }                                                               \
 +        *dst_size_p = size;                                             \
 +        *dst = q;                                                       \
 +    }
 +
 +/* WRITERS */
 +
 +/* Default output */
 +
 +static void default_print_footer(WriterContext *wctx)
 +{
 +    printf("\n");
 +}
 +
 +static void default_print_chapter_header(WriterContext *wctx, const char *chapter)
 +{
 +    if (wctx->nb_chapter)
 +        printf("\n");
 +}
 +
 +/* lame uppercasing routine, assumes the string is lower case ASCII */
 +static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
 +{
 +    int i;
 +    for (i = 0; src[i] && i < dst_size-1; i++)
 +        dst[i] = src[i]-32;
 +    dst[i] = 0;
 +    return dst;
 +}
 +
 +static void default_print_section_header(WriterContext *wctx, const char *section)
 +{
 +    char buf[32];
 +
 +    if (wctx->nb_section)
 +        printf("\n");
 +    printf("[%s]\n", upcase_string(buf, sizeof(buf), section));
 +}
 +
 +static void default_print_section_footer(WriterContext *wctx, const char *section)
 +{
 +    char buf[32];
 +
 +    printf("[/%s]", upcase_string(buf, sizeof(buf), section));
 +}
 +
 +static void default_print_str(WriterContext *wctx, const char *key, const char *value)
 +{
 +    printf("%s=%s\n", key, value);
 +}
 +
 +static void default_print_int(WriterContext *wctx, const char *key, long long int value)
 +{
 +    printf("%s=%lld\n", key, value);
 +}
 +
 +static void default_show_tags(WriterContext *wctx, AVDictionary *dict)
 +{
 +    AVDictionaryEntry *tag = NULL;
 +    while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) {
 +        printf("TAG:");
 +        writer_print_string(wctx, tag->key, tag->value, 0);
 +    }
 +}
 +
 +static const Writer default_writer = {
 +    .name                  = "default",
 +    .print_footer          = default_print_footer,
 +    .print_chapter_header  = default_print_chapter_header,
 +    .print_section_header  = default_print_section_header,
 +    .print_section_footer  = default_print_section_footer,
 +    .print_integer         = default_print_int,
 +    .print_string          = default_print_str,
 +    .show_tags             = default_show_tags,
 +    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
 +};
 +
 +/* Compact output */
 +
 +/**
 + * Escape \n, \r, \\ and sep characters contained in s, and print the
 + * resulting string.
 + */
 +static const char *c_escape_str(char **dst, size_t *dst_size,
 +                                const char *src, const char sep, void *log_ctx)
 +{
 +    const char *p;
 +    char *q;
 +    size_t size = 1;
 +
 +    /* precompute size */
 +    for (p = src; *p; p++, size++) {
 +        ESCAPE_CHECK_SIZE(src, size, SIZE_MAX-2);
 +        if (*p == '\n' || *p == '\r' || *p == '\\')
 +            size++;
 +    }
 +
 +    ESCAPE_REALLOC_BUF(dst_size, dst, src, size);
 +
 +    q = *dst;
 +    for (p = src; *p; p++) {
 +        switch (*src) {
 +        case '\n': *q++ = '\\'; *q++ = 'n';  break;
 +        case '\r': *q++ = '\\'; *q++ = 'r';  break;
 +        case '\\': *q++ = '\\'; *q++ = '\\'; break;
 +        default:
 +            if (*p == sep)
 +                *q++ = '\\';
 +            *q++ = *p;
 +        }
 +    }
 +    *q = 0;
 +    return *dst;
 +}
 +
 +/**
 + * Quote fields containing special characters, check RFC4180.
 + */
 +static const char *csv_escape_str(char **dst, size_t *dst_size,
 +                                  const char *src, const char sep, void *log_ctx)
 +{
 +    const char *p;
 +    char *q;
 +    size_t size = 1;
 +    int quote = 0;
 +
 +    /* precompute size */
 +    for (p = src; *p; p++, size++) {
 +        ESCAPE_CHECK_SIZE(src, size, SIZE_MAX-4);
 +        if (*p == '"' || *p == sep || *p == '\n' || *p == '\r')
 +            if (!quote) {
 +                quote = 1;
 +                size += 2;
 +            }
 +        if (*p == '"')
 +            size++;
 +    }
 +
 +    ESCAPE_REALLOC_BUF(dst_size, dst, src, size);
 +
 +    q = *dst;
 +    p = src;
 +    if (quote)
 +        *q++ = '\"';
 +    while (*p) {
 +        if (*p == '"')
 +            *q++ = '\"';
 +        *q++ = *p++;
 +    }
 +    if (quote)
 +        *q++ = '\"';
 +    *q = 0;
 +
 +    return *dst;
 +}
 +
 +static const char *none_escape_str(char **dst, size_t *dst_size,
 +                                   const char *src, const char sep, void *log_ctx)
 +{
 +    return src;
 +}
 +
 +typedef struct CompactContext {
 +    const AVClass *class;
 +    char *item_sep_str;
 +    char item_sep;
 +    int nokey;
 +    char  *buf;
 +    size_t buf_size;
 +    char *escape_mode_str;
 +    const char * (*escape_str)(char **dst, size_t *dst_size,
 +                               const char *src, const char sep, void *log_ctx);
 +} CompactContext;
 +
 +#define OFFSET(x) offsetof(CompactContext, x)
 +
 +static const AVOption compact_options[]= {
 +    {"item_sep", "set item separator",    OFFSET(item_sep_str),    AV_OPT_TYPE_STRING, {.str="|"},  CHAR_MIN, CHAR_MAX },
 +    {"s",        "set item separator",    OFFSET(item_sep_str),    AV_OPT_TYPE_STRING, {.str="|"},  CHAR_MIN, CHAR_MAX },
 +    {"nokey",    "force no key printing", OFFSET(nokey),           AV_OPT_TYPE_INT,    {.dbl=0},    0,        1        },
 +    {"nk",       "force no key printing", OFFSET(nokey),           AV_OPT_TYPE_INT,    {.dbl=0},    0,        1        },
 +    {"escape",   "set escape mode",       OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"},  CHAR_MIN, CHAR_MAX },
 +    {"e",        "set escape mode",       OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"},  CHAR_MIN, CHAR_MAX },
 +    {NULL},
 +};
 +
 +static const char *compact_get_name(void *ctx)
 +{
 +    return "compact";
 +}
 +
 +static const AVClass compact_class = {
 +    "CompactContext",
 +    compact_get_name,
 +    compact_options
 +};
 +
 +static av_cold int compact_init(WriterContext *wctx, const char *args, void *opaque)
 +{
 +    CompactContext *compact = wctx->priv;
 +    int err;
 +
 +    compact->class = &compact_class;
 +    av_opt_set_defaults(compact);
 +
 +    if (args &&
 +        (err = (av_set_options_string(compact, args, "=", ":"))) < 0) {
 +        av_log(wctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
 +        return err;
 +    }
 +    if (strlen(compact->item_sep_str) != 1) {
 +        av_log(wctx, AV_LOG_ERROR, "Item separator '%s' specified, but must contain a single character\n",
 +               compact->item_sep_str);
 +        return AVERROR(EINVAL);
 +    }
 +    compact->item_sep = compact->item_sep_str[0];
 +
 +    compact->buf_size = ESCAPE_INIT_BUF_SIZE;
 +    if (!(compact->buf = av_malloc(compact->buf_size)))
 +        return AVERROR(ENOMEM);
 +
 +    if      (!strcmp(compact->escape_mode_str, "none")) compact->escape_str = none_escape_str;
 +    else if (!strcmp(compact->escape_mode_str, "c"   )) compact->escape_str = c_escape_str;
 +    else if (!strcmp(compact->escape_mode_str, "csv" )) compact->escape_str = csv_escape_str;
 +    else {
 +        av_log(wctx, AV_LOG_ERROR, "Unknown escape mode '%s'\n", compact->escape_mode_str);
 +        return AVERROR(EINVAL);
 +    }
 +
 +    return 0;
 +}
 +
 +static av_cold void compact_uninit(WriterContext *wctx)
 +{
 +    CompactContext *compact = wctx->priv;
 +
 +    av_freep(&compact->item_sep_str);
 +    av_freep(&compact->buf);
 +    av_freep(&compact->escape_mode_str);
 +}
 +
 +static void compact_print_section_header(WriterContext *wctx, const char *section)
 +{
 +    CompactContext *compact = wctx->priv;
 +
 +    printf("%s%c", section, compact->item_sep);
 +}
 +
 +static void compact_print_section_footer(WriterContext *wctx, const char *section)
 +{
 +    printf("\n");
 +}
 +
 +static void compact_print_str(WriterContext *wctx, const char *key, const char *value)
 +{
 +    CompactContext *compact = wctx->priv;
 +
 +    if (wctx->nb_item) printf("%c", compact->item_sep);
 +    if (!compact->nokey)
 +        printf("%s=", key);
 +    printf("%s", compact->escape_str(&compact->buf, &compact->buf_size,
 +                                     value, compact->item_sep, wctx));
 +}
 +
 +static void compact_print_int(WriterContext *wctx, const char *key, long long int value)
 +{
 +    CompactContext *compact = wctx->priv;
 +
 +    if (wctx->nb_item) printf("%c", compact->item_sep);
 +    if (!compact->nokey)
 +        printf("%s=", key);
 +    printf("%lld", value);
 +}
 +
 +static void compact_show_tags(WriterContext *wctx, AVDictionary *dict)
 +{
 +    CompactContext *compact = wctx->priv;
 +    AVDictionaryEntry *tag = NULL;
 +
 +    while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) {
 +        if (wctx->nb_item) printf("%c", compact->item_sep);
 +        if (!compact->nokey)
 +            printf("tag:%s=", compact->escape_str(&compact->buf, &compact->buf_size,
 +                                                  tag->key, compact->item_sep, wctx));
 +        printf("%s", compact->escape_str(&compact->buf, &compact->buf_size,
 +                                         tag->value, compact->item_sep, wctx));
 +    }
 +}
 +
 +static const Writer compact_writer = {
 +    .name                 = "compact",
 +    .priv_size            = sizeof(CompactContext),
 +    .init                 = compact_init,
 +    .uninit               = compact_uninit,
 +    .print_section_header = compact_print_section_header,
 +    .print_section_footer = compact_print_section_footer,
 +    .print_integer        = compact_print_int,
 +    .print_string         = compact_print_str,
 +    .show_tags            = compact_show_tags,
 +    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
 +};
 +
 +/* CSV output */
 +
 +static av_cold int csv_init(WriterContext *wctx, const char *args, void *opaque)
 +{
 +    return compact_init(wctx, "item_sep=,:nokey=1:escape=csv", opaque);
 +}
 +
 +static const Writer csv_writer = {
 +    .name                 = "csv",
 +    .priv_size            = sizeof(CompactContext),
 +    .init                 = csv_init,
 +    .uninit               = compact_uninit,
 +    .print_section_header = compact_print_section_header,
 +    .print_section_footer = compact_print_section_footer,
 +    .print_integer        = compact_print_int,
 +    .print_string         = compact_print_str,
 +    .show_tags            = compact_show_tags,
 +    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
 +};
 +
 +/* JSON output */
 +
 +typedef struct {
 +    int multiple_entries; ///< tells if the given chapter requires multiple entries
 +    char *buf;
 +    size_t buf_size;
 +} JSONContext;
 +
 +static av_cold int json_init(WriterContext *wctx, const char *args, void *opaque)
 +{
 +    JSONContext *json = wctx->priv;
 +
 +    json->buf_size = ESCAPE_INIT_BUF_SIZE;
 +    if (!(json->buf = av_malloc(json->buf_size)))
 +        return AVERROR(ENOMEM);
 +
 +    return 0;
 +}
 +
 +static av_cold void json_uninit(WriterContext *wctx)
 +{
 +    JSONContext *json = wctx->priv;
 +    av_freep(&json->buf);
 +}
 +
 +static const char *json_escape_str(char **dst, size_t *dst_size, const char *src,
 +                                   void *log_ctx)
 +{
 +    static const char json_escape[] = {'"', '\\', '\b', '\f', '\n', '\r', '\t', 0};
 +    static const char json_subst[]  = {'"', '\\',  'b',  'f',  'n',  'r',  't', 0};
 +    const char *p;
 +    char *q;
 +    size_t size = 1;
 +
 +    // compute the length of the escaped string
 +    for (p = src; *p; p++) {
 +        ESCAPE_CHECK_SIZE(src, size, SIZE_MAX-6);
 +        if (strchr(json_escape, *p))     size += 2; // simple escape
 +        else if ((unsigned char)*p < 32) size += 6; // handle non-printable chars
 +        else                             size += 1; // char copy
 +    }
 +    ESCAPE_REALLOC_BUF(dst_size, dst, src, size);
 +
 +    q = *dst;
 +    for (p = src; *p; p++) {
 +        char *s = strchr(json_escape, *p);
 +        if (s) {
 +            *q++ = '\\';
 +            *q++ = json_subst[s - json_escape];
 +        } else if ((unsigned char)*p < 32) {
 +            snprintf(q, 7, "\\u00%02x", *p & 0xff);
 +            q += 6;
 +        } else {
 +            *q++ = *p;
 +        }
 +    }
 +    *q = 0;
 +    return *dst;
 +}
 +
 +static void json_print_header(WriterContext *wctx)
 +{
 +    printf("{");
 +}
 +
 +static void json_print_footer(WriterContext *wctx)
 +{
 +    printf("\n}\n");
 +}
 +
 +static void json_print_chapter_header(WriterContext *wctx, const char *chapter)
 +{
 +    JSONContext *json = wctx->priv;
 +
 +    if (wctx->nb_chapter)
 +        printf(",");
 +    json->multiple_entries = !strcmp(chapter, "packets") || !strcmp(chapter, "streams");
 +    printf("\n  \"%s\":%s", json_escape_str(&json->buf, &json->buf_size, chapter, wctx),
 +           json->multiple_entries ? " [" : " ");
 +}
 +
 +static void json_print_chapter_footer(WriterContext *wctx, const char *chapter)
 +{
 +    JSONContext *json = wctx->priv;
 +
 +    if (json->multiple_entries)
 +        printf("]");
 +}
 +
 +static void json_print_section_header(WriterContext *wctx, const char *section)
 +{
 +    if (wctx->nb_section) printf(",");
 +    printf("{\n");
 +}
 +
 +static void json_print_section_footer(WriterContext *wctx, const char *section)
 +{
 +    printf("\n  }");
 +}
 +
 +static inline void json_print_item_str(WriterContext *wctx,
 +                                       const char *key, const char *value,
 +                                       const char *indent)
 +{
 +    JSONContext *json = wctx->priv;
 +
 +    printf("%s\"%s\":", indent, json_escape_str(&json->buf, &json->buf_size, key,   wctx));
 +    printf(" \"%s\"",           json_escape_str(&json->buf, &json->buf_size, value, wctx));
 +}
 +
 +#define INDENT "    "
 +
 +static void json_print_str(WriterContext *wctx, const char *key, const char *value)
 +{
 +    if (wctx->nb_item) printf(",\n");
 +    json_print_item_str(wctx, key, value, INDENT);
 +}
 +
 +static void json_print_int(WriterContext *wctx, const char *key, long long int value)
 +{
 +    JSONContext *json = wctx->priv;
 +
 +    if (wctx->nb_item) printf(",\n");
 +    printf(INDENT "\"%s\": %lld",
 +           json_escape_str(&json->buf, &json->buf_size, key, wctx), value);
 +}
 +
 +static void json_show_tags(WriterContext *wctx, AVDictionary *dict)
 +{
 +    AVDictionaryEntry *tag = NULL;
 +    int is_first = 1;
 +    if (!dict)
 +        return;
 +    printf(",\n" INDENT "\"tags\": {\n");
 +    while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) {
 +        if (is_first) is_first = 0;
 +        else          printf(",\n");
 +        json_print_item_str(wctx, tag->key, tag->value, INDENT INDENT);
 +    }
 +    printf("\n    }");
 +}
 +
 +static const Writer json_writer = {
 +    .name                 = "json",
 +    .priv_size            = sizeof(JSONContext),
 +    .init                 = json_init,
 +    .uninit               = json_uninit,
 +    .print_header         = json_print_header,
 +    .print_footer         = json_print_footer,
 +    .print_chapter_header = json_print_chapter_header,
 +    .print_chapter_footer = json_print_chapter_footer,
 +    .print_section_header = json_print_section_header,
 +    .print_section_footer = json_print_section_footer,
 +    .print_integer        = json_print_int,
 +    .print_string         = json_print_str,
 +    .show_tags            = json_show_tags,
 +};
 +
 +static void writer_register_all(void)
 +{
 +    static int initialized;
 +
 +    if (initialized)
 +        return;
 +    initialized = 1;
 +
 +    writer_register(&default_writer);
 +    writer_register(&compact_writer);
 +    writer_register(&csv_writer);
 +    writer_register(&json_writer);
 +}
 +
 +#define print_fmt(k, f, ...) do {              \
 +    if (fast_asprintf(&pbuf, f, __VA_ARGS__))  \
 +        writer_print_string(w, k, pbuf.s, 0);  \
 +} while (0)
 +
 +#define print_fmt_opt(k, f, ...) do {          \
 +    if (fast_asprintf(&pbuf, f, __VA_ARGS__))  \
 +        writer_print_string(w, k, pbuf.s, 1);  \
 +} while (0)
 +
 +#define print_int(k, v)         writer_print_integer(w, k, v)
 +#define print_str(k, v)         writer_print_string(w, k, v, 0)
 +#define print_str_opt(k, v)     writer_print_string(w, k, v, 1)
 +#define print_time(k, v, tb)    writer_print_time(w, k, v, tb)
 +#define print_ts(k, v)          writer_print_ts(w, k, v)
 +#define print_val(k, v, u)      writer_print_string(w, k, \
 +    value_string(val_str, sizeof(val_str), (struct unit_value){.val.i = v, .unit=u}), 0)
 +#define print_section_header(s) writer_print_section_header(w, s)
 +#define print_section_footer(s) writer_print_section_footer(w, s)
 +#define show_tags(metadata)     writer_show_tags(w, metadata)
 +
 +static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx)
 +{
 +    char val_str[128];
 +    AVStream *st = fmt_ctx->streams[pkt->stream_index];
 +    struct print_buf pbuf = {.s = NULL};
 +    const char *s;
 +
 +    print_section_header("packet");
 +    s = av_get_media_type_string(st->codec->codec_type);
 +    if (s) print_str    ("codec_type", s);
 +    else   print_str_opt("codec_type", "unknown");
 +    print_int("stream_index",     pkt->stream_index);
 +    print_ts  ("pts",             pkt->pts);
 +    print_time("pts_time",        pkt->pts, &st->time_base);
 +    print_ts  ("dts",             pkt->dts);
 +    print_time("dts_time",        pkt->dts, &st->time_base);
 +    print_ts  ("duration",        pkt->duration);
 +    print_time("duration_time",   pkt->duration, &st->time_base);
 +    print_val("size",             pkt->size, unit_byte_str);
 +    if (pkt->pos != -1) print_fmt    ("pos", "%"PRId64, pkt->pos);
 +    else                print_str_opt("pos", "N/A");
 +    print_fmt("flags", "%c",      pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
 +    print_section_footer("packet");
 +
 +    av_free(pbuf.s);
 +    fflush(stdout);
 +}
 +
 +static void show_packets(WriterContext *w, AVFormatContext *fmt_ctx)
 +{
 +    AVPacket pkt;
 +    int i = 0;
 +
 +    av_init_packet(&pkt);
 +
 +    while (!av_read_frame(fmt_ctx, &pkt))
 +        show_packet(w, fmt_ctx, &pkt, i++);
 +}
 +
 +static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx)
 +{
 +    AVStream *stream = fmt_ctx->streams[stream_idx];
 +    AVCodecContext *dec_ctx;
 +    AVCodec *dec;
 +    char val_str[128];
 +    const char *s;
 +    AVRational display_aspect_ratio;
 +    struct print_buf pbuf = {.s = NULL};
 +
 +    print_section_header("stream");
 +
 +    print_int("index", stream->index);
 +
 +    if ((dec_ctx = stream->codec)) {
 +        if ((dec = dec_ctx->codec)) {
 +            print_str("codec_name",      dec->name);
 +            print_str("codec_long_name", dec->long_name);
 +        } else {
 +            print_str_opt("codec_name",      "unknown");
 +            print_str_opt("codec_long_name", "unknown");
 +        }
 +
 +        s = av_get_media_type_string(dec_ctx->codec_type);
 +        if (s) print_str    ("codec_type", s);
 +        else   print_str_opt("codec_type", "unknown");
 +        print_fmt("codec_time_base", "%d/%d", dec_ctx->time_base.num, dec_ctx->time_base.den);
 +
 +        /* print AVI/FourCC tag */
 +        av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
 +        print_str("codec_tag_string",    val_str);
 +        print_fmt("codec_tag", "0x%04x", dec_ctx->codec_tag);
 +
 +        switch (dec_ctx->codec_type) {
 +        case AVMEDIA_TYPE_VIDEO:
 +            print_int("width",        dec_ctx->width);
 +            print_int("height",       dec_ctx->height);
 +            print_int("has_b_frames", dec_ctx->has_b_frames);
 +            if (dec_ctx->sample_aspect_ratio.num) {
 +                print_fmt("sample_aspect_ratio", "%d:%d",
 +                          dec_ctx->sample_aspect_ratio.num,
 +                          dec_ctx->sample_aspect_ratio.den);
 +                av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
 +                          dec_ctx->width  * dec_ctx->sample_aspect_ratio.num,
 +                          dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
 +                          1024*1024);
 +                print_fmt("display_aspect_ratio", "%d:%d",
 +                          display_aspect_ratio.num,
 +                          display_aspect_ratio.den);
 +            } else {
 +                print_str_opt("sample_aspect_ratio", "N/A");
 +                print_str_opt("display_aspect_ratio", "N/A");
 +            }
 +            s = av_get_pix_fmt_name(dec_ctx->pix_fmt);
 +            if (s) print_str    ("pix_fmt", s);
 +            else   print_str_opt("pix_fmt", "unknown");
 +            print_int("level",   dec_ctx->level);
 +            if (dec_ctx->timecode_frame_start >= 0) {
 +                uint32_t tc = dec_ctx->timecode_frame_start;
 +                print_fmt("timecode", "%02d:%02d:%02d%c%02d",
 +                          tc>>19 & 0x1f,              // hours
 +                          tc>>13 & 0x3f,              // minutes
 +                          tc>>6  & 0x3f,              // seconds
 +                          tc     & 1<<24 ? ';' : ':', // drop
 +                          tc     & 0x3f);             // frames
 +            } else {
 +                print_str_opt("timecode", "N/A");
 +            }
 +            break;
 +
 +        case AVMEDIA_TYPE_AUDIO:
 +            s = av_get_sample_fmt_name(dec_ctx->sample_fmt);
 +            if (s) print_str    ("sample_fmt", s);
 +            else   print_str_opt("sample_fmt", "unknown");
 +            print_val("sample_rate",     dec_ctx->sample_rate, unit_hertz_str);
 +            print_int("channels",        dec_ctx->channels);
 +            print_int("bits_per_sample", av_get_bits_per_sample(dec_ctx->codec_id));
 +            break;
 +        }
 +    } else {
 +        print_str_opt("codec_type", "unknown");
 +    }
 +    if (dec_ctx->codec && dec_ctx->codec->priv_class) {
 +        const AVOption *opt = NULL;
 +        while (opt = av_opt_next(dec_ctx->priv_data,opt)) {
 +            uint8_t *str;
 +            if (opt->flags) continue;
 +            if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {
 +                print_str(opt->name, str);
 +                av_free(str);
 +            }
 +        }
 +    }
 +
 +    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt    ("id", "0x%x", stream->id);
 +    else                                          print_str_opt("id", "N/A");
 +    print_fmt("r_frame_rate",   "%d/%d", stream->r_frame_rate.num,   stream->r_frame_rate.den);
 +    print_fmt("avg_frame_rate", "%d/%d", stream->avg_frame_rate.num, stream->avg_frame_rate.den);
 +    print_fmt("time_base",      "%d/%d", stream->time_base.num,      stream->time_base.den);
 +    print_time("start_time",    stream->start_time, &stream->time_base);
 +    print_time("duration",      stream->duration,   &stream->time_base);
 +    if (stream->nb_frames) print_fmt    ("nb_frames", "%"PRId64, stream->nb_frames);
 +    else                   print_str_opt("nb_frames", "N/A");
 +    show_tags(stream->metadata);
 +
 +    print_section_footer("stream");
 +    av_free(pbuf.s);
 +    fflush(stdout);
 +}
 +
 +static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx)
 +{
 +    int i;
 +    for (i = 0; i < fmt_ctx->nb_streams; i++)
 +        show_stream(w, fmt_ctx, i);
 +}
 +
 +static void show_format(WriterContext *w, AVFormatContext *fmt_ctx)
 +{
 +    char val_str[128];
 +    int64_t size = avio_size(fmt_ctx->pb);
 +    struct print_buf pbuf = {.s = NULL};
 +
 +    print_section_header("format");
 +    print_str("filename",         fmt_ctx->filename);
 +    print_int("nb_streams",       fmt_ctx->nb_streams);
 +    print_str("format_name",      fmt_ctx->iformat->name);
 +    print_str("format_long_name", fmt_ctx->iformat->long_name);
 +    print_time("start_time",      fmt_ctx->start_time, &AV_TIME_BASE_Q);
 +    print_time("duration",        fmt_ctx->duration,   &AV_TIME_BASE_Q);
 +    if (size >= 0) print_val    ("size", size, unit_byte_str);
 +    else           print_str_opt("size", "N/A");
 +    if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
 +    else                       print_str_opt("bit_rate", "N/A");
 +    show_tags(fmt_ctx->metadata);
 +    print_section_footer("format");
 +    av_free(pbuf.s);
 +    fflush(stdout);
 +}
 +
 +static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
 +{
 +    int err, i;
 +    AVFormatContext *fmt_ctx = NULL;
 +    AVDictionaryEntry *t;
 +
 +    if ((err = avformat_open_input(&fmt_ctx, filename, iformat, &format_opts)) < 0) {
 +        print_error(filename, err);
 +        return err;
 +    }
 +    if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
 +        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
 +        return AVERROR_OPTION_NOT_FOUND;
 +    }
 +
 +
 +    /* fill the streams in the format context */
 +    if ((err = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
 +        print_error(filename, err);
 +        return err;
 +    }
 +
 +    av_dump_format(fmt_ctx, 0, filename, 0);
 +
 +    /* bind a decoder to each input stream */
 +    for (i = 0; i < fmt_ctx->nb_streams; i++) {
 +        AVStream *stream = fmt_ctx->streams[i];
 +        AVCodec *codec;
 +
 +        if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
 +            fprintf(stderr, "Unsupported codec with id %d for input stream %d\n",
 +                    stream->codec->codec_id, stream->index);
 +        } else if (avcodec_open2(stream->codec, codec, NULL) < 0) {
 +            fprintf(stderr, "Error while opening codec for input stream %d\n",
 +                    stream->index);
 +        }
 +    }
 +
 +    *fmt_ctx_ptr = fmt_ctx;
 +    return 0;
 +}
 +
 +#define PRINT_CHAPTER(name) do {                                        \
 +    if (do_show_ ## name) {                                             \
 +        writer_print_chapter_header(wctx, #name);                       \
 +        show_ ## name (wctx, fmt_ctx);                                  \
 +        writer_print_chapter_footer(wctx, #name);                       \
 +    }                                                                   \
 +} while (0)
 +
 +static int probe_file(const char *filename)
 +{
 +    AVFormatContext *fmt_ctx;
 +    int ret;
 +    const Writer *w;
 +    char *buf;
 +    char *w_name = NULL, *w_args = NULL;
 +    WriterContext *wctx;
 +
 +    writer_register_all();
 +
 +    if (!print_format)
 +        print_format = av_strdup("default");
 +    w_name = av_strtok(print_format, "=", &buf);
 +    w_args = buf;
 +
 +    w = writer_get_by_name(w_name);
 +    if (!w) {
 +        av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name);
 +        ret = AVERROR(EINVAL);
 +        goto end;
 +    }
 +
 +    if ((ret = writer_open(&wctx, w, w_args, NULL)) < 0)
 +        goto end;
 +    if ((ret = open_input_file(&fmt_ctx, filename)))
 +        goto end;
 +
 +    writer_print_header(wctx);
 +    PRINT_CHAPTER(packets);
 +    PRINT_CHAPTER(streams);
 +    PRINT_CHAPTER(format);
 +    writer_print_footer(wctx);
 +
++    avformat_close_input(&fmt_ctx);
 +    writer_close(&wctx);
 +
 +end:
 +    av_freep(&print_format);
 +
 +    return ret;
 +}
 +
 +static void show_usage(void)
 +{
 +    printf("Simple multimedia streams analyzer\n");
 +    printf("usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
 +    printf("\n");
 +}
 +
 +static int opt_format(const char *opt, const char *arg)
 +{
 +    iformat = av_find_input_format(arg);
 +    if (!iformat) {
 +        fprintf(stderr, "Unknown input format: %s\n", arg);
 +        return AVERROR(EINVAL);
 +    }
 +    return 0;
 +}
 +
 +static void opt_input_file(void *optctx, const char *arg)
 +{
 +    if (input_filename) {
 +        fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
 +                arg, input_filename);
 +        exit(1);
 +    }
 +    if (!strcmp(arg, "-"))
 +        arg = "pipe:";
 +    input_filename = arg;
 +}
 +
 +static int opt_help(const char *opt, const char *arg)
 +{
 +    av_log_set_callback(log_callback_help);
 +    show_usage();
 +    show_help_options(options, "Main options:\n", 0, 0);
 +    printf("\n");
 +
 +    show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
 +
 +    return 0;
 +}
 +
 +static int opt_pretty(const char *opt, const char *arg)
 +{
 +    show_value_unit              = 1;
 +    use_value_prefix             = 1;
 +    use_byte_value_binary_prefix = 1;
 +    use_value_sexagesimal_format = 1;
 +    return 0;
 +}
 +
 +static const OptionDef options[] = {
 +#include "cmdutils_common_opts.h"
 +    { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
 +    { "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" },
 +    { "prefix", OPT_BOOL, {(void*)&use_value_prefix}, "use SI prefixes for the displayed values" },
 +    { "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix},
 +      "use binary prefixes for byte units" },
 +    { "sexagesimal", OPT_BOOL,  {(void*)&use_value_sexagesimal_format},
 +      "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
 +    { "pretty", 0, {(void*)&opt_pretty},
 +      "prettify the format of displayed values, make it more human readable" },
 +    { "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format},
 +      "set the output printing format (available formats are: default, compact, csv, json)", "format" },
 +    { "show_format",  OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
 +    { "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" },
 +    { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" },
 +    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
 +    { "i", HAS_ARG, {(void *)opt_input_file}, "read specified file", "input_file"},
 +    { NULL, },
 +};
 +
 +int main(int argc, char **argv)
 +{
 +    int ret;
 +
 +    parse_loglevel(argc, argv, options);
 +    av_register_all();
 +    avformat_network_init();
 +    init_opts();
 +#if CONFIG_AVDEVICE
 +    avdevice_register_all();
 +#endif
 +
 +    show_banner();
 +    parse_options(NULL, argc, argv, options, opt_input_file);
 +
 +    if (!input_filename) {
 +        show_usage();
 +        fprintf(stderr, "You have to specify one input file.\n");
 +        fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
 +        exit(1);
 +    }
 +
 +    ret = probe_file(input_filename);
 +
 +    avformat_network_deinit();
 +
 +    return ret;
 +}
diff --cc ffserver.c
Simple merge
Simple merge
Simple merge
@@@ -4628,8 -4486,8 +4628,16 @@@ int av_picture_pad(AVPicture *dst, cons
  unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
  
  /**
++<<<<<<< HEAD
 + * Logs a generic warning message about a missing feature. This function is
 + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
++||||||| merged common ancestors
++ * Logs a generic warning message about a missing feature. This function is
++ * intended to be used internally by Libav (libavcodec, libavformat, etc.)
++=======
+  * Log a generic warning message about a missing feature. This function is
+  * intended to be used internally by Libav (libavcodec, libavformat, etc.)
++>>>>>>> qatar/master
   * only, and would normally not be used by applications.
   * @param[in] avc a pointer to an arbitrary struct of which the first field is
   * a pointer to an AVClass struct
Simple merge
@@@ -64,17 -64,7 +64,17 @@@ static inline int bidir_sal(int value, 
  }
  
  /**
-  * returns the dot product.
 + * returns the dot product of 2 int16_t vectors.
 + * @param a input data array
 + * @param b input data array
 + * @param length number of elements
 + *
 + * @return dot product = sum of elementwise products
 + */
 +int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length);
 +
 +/**
+  * Return the dot product.
   * @param a input data array
   * @param b input data array
   * @param length number of elements
@@@ -36,10 -36,10 +36,10 @@@ typedef struct DCAParseContext 
  #define IS_MARKER(state, i, buf, buf_size) \
   ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \
   || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \
 - || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE)
 + || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE || state == DCA_HD_MARKER)
  
  /**
-  * finds the end of the current frame in the bitstream.
+  * Find the end of the current frame in the bitstream.
   * @return the position of the first byte of the next frame, or -1
   */
  static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
Simple merge
@@@ -870,9 -857,9 +870,9 @@@ void ff_er_frame_end(MpegEncContext *s)
                  end_ok=0;
          }
      }
 -
 +#endif
      /* handle missing slices */
-     if(s->error_recognition>=4){
+     if(s->err_recognition&AV_EF_EXPLODE){
          int end_ok=1;
  
          for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -3743,12 -3706,11 +3744,12 @@@ static int execute_decode_slices(H264Co
      } else {
          for(i = 1; i < context_count; i++) {
              hx = h->thread_context[i];
-             hx->s.error_recognition = avctx->error_recognition;
+             hx->s.err_recognition = avctx->err_recognition;
              hx->s.error_count = 0;
 +            hx->x264_build= h->x264_build;
          }
  
-         avctx->execute(avctx, (void *)decode_slice,
+         avctx->execute(avctx, decode_slice,
                         h->thread_context, NULL, context_count, sizeof(void*));
  
          /* pull back stuff from slices to master context */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  
  #include "parser.h"
  
 +typedef struct MJPEGParserContext{
 +    ParseContext pc;
 +    int size;
 +}MJPEGParserContext;
  
  /**
-  * finds the end of the current frame in the bitstream.
+  * Find the end of the current frame in the bitstream.
   * @return the position of the first byte of the next frame, or -1
   */
 -static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
 +static int find_frame_end(MJPEGParserContext *m, const uint8_t *buf, int buf_size){
 +    ParseContext *pc= &m->pc;
      int vop_found, i;
 -    uint16_t state;
 +    uint32_t state;
  
      vop_found= pc->frame_start_found;
      state= pc->state;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  #ifndef AVDEVICE_AVDEVICE_H
  #define AVDEVICE_AVDEVICE_H
  
+ /**
+  * @file
+  * @ingroup lavd
+  * Main libavdevice API header
+  */
+ /**
+  * @defgroup lavd Special devices muxing/demuxing library
+  * @{
+  * Libavdevice is a complementary library to @ref libavf "libavformat". It
+  * provides various "special" platform-specific muxers and demuxers, e.g. for
+  * grabbing devices, audio capture and playback etc. As a consequence, the
+  * (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own
+  * I/O functions). The filename passed to avformat_open_input() often does not
+  * refer to an actually existing file, but has some special device-specific
+  * meaning - e.g. for the x11grab device it is the display name.
+  *
+  * To use libavdevice, simply call avdevice_register_all() to register all
+  * compiled muxers and demuxers. They all use standard libavformat API.
+  * @}
+  */
  #include "libavutil/avutil.h"
 +#include "libavformat/avformat.h"
  
  #define LIBAVDEVICE_VERSION_MAJOR 53
 -#define LIBAVDEVICE_VERSION_MINOR  2
 +#define LIBAVDEVICE_VERSION_MINOR  4
  #define LIBAVDEVICE_VERSION_MICRO  0
  
  #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
@@@ -188,37 -192,12 +188,37 @@@ static av_cold void movie_common_uninit
      if (movie->codec_ctx)
          avcodec_close(movie->codec_ctx);
      if (movie->format_ctx)
-         av_close_input_file(movie->format_ctx);
+         avformat_close_input(&movie->format_ctx);
 +
      avfilter_unref_buffer(movie->picref);
      av_freep(&movie->frame);
 +
 +    avfilter_unref_buffer(movie->samplesref);
 +    av_freep(&movie->samples_buf);
 +}
 +
 +#if CONFIG_MOVIE_FILTER
 +
 +static av_cold int movie_init(AVFilterContext *ctx, const char *args, void *opaque)
 +{
 +    MovieContext *movie = ctx->priv;
 +    int ret;
 +
 +    if ((ret = movie_common_init(ctx, args, opaque, AVMEDIA_TYPE_VIDEO)) < 0)
 +        return ret;
 +
 +    if (!(movie->frame = avcodec_alloc_frame()) ) {
 +        av_log(ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
 +        return AVERROR(ENOMEM);
 +    }
 +
 +    movie->w = movie->codec_ctx->width;
 +    movie->h = movie->codec_ctx->height;
 +
 +    return 0;
  }
  
 -static int query_formats(AVFilterContext *ctx)
 +static int movie_query_formats(AVFilterContext *ctx)
  {
      MovieContext *movie = ctx->priv;
      enum PixelFormat pix_fmts[] = { movie->codec_ctx->pix_fmt, PIX_FMT_NONE };
Simple merge
@@@ -1176,175 -1168,130 +1234,159 @@@ typedef struct AVPacketList 
      struct AVPacketList *next;
  } AVPacketList;
  
  /**
-  * If f is NULL, returns the first registered input format,
-  * if f is non-NULL, returns the next registered input format after f
-  * or NULL if f is the last one.
+  * @defgroup lavf_core Core functions
+  * @ingroup libavf
+  *
+  * Functions for querying libavformat capabilities, allocating core structures,
+  * etc.
+  * @{
   */
- AVInputFormat  *av_iformat_next(AVInputFormat  *f);
  
  /**
-  * If f is NULL, returns the first registered output format,
-  * if f is non-NULL, returns the next registered output format after f
-  * or NULL if f is the last one.
+  * Return the LIBAVFORMAT_VERSION_INT constant.
   */
- AVOutputFormat *av_oformat_next(AVOutputFormat *f);
- #if FF_API_GUESS_IMG2_CODEC
- attribute_deprecated enum CodecID av_guess_image2_codec(const char *filename);
- #endif
- /* XXX: Use automatic init with either ELF sections or C file parser */
- /* modules. */
- /* utils.c */
- void av_register_input_format(AVInputFormat *format);
- void av_register_output_format(AVOutputFormat *format);
+ unsigned avformat_version(void);
  
  /**
-  * Return the output format in the list of registered output formats
-  * which best matches the provided parameters, or return NULL if
-  * there is no match.
-  *
-  * @param short_name if non-NULL checks if short_name matches with the
-  * names of the registered formats
-  * @param filename if non-NULL checks if filename terminates with the
-  * extensions of the registered formats
-  * @param mime_type if non-NULL checks if mime_type matches with the
-  * MIME type of the registered formats
+  * Return the libavformat build-time configuration.
   */
- AVOutputFormat *av_guess_format(const char *short_name,
-                                 const char *filename,
-                                 const char *mime_type);
+ const char *avformat_configuration(void);
  
  /**
-  * Guess the codec ID based upon muxer and filename.
+  * Return the libavformat license.
   */
- enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
-                             const char *filename, const char *mime_type,
-                             enum AVMediaType type);
+ const char *avformat_license(void);
  
  /**
-  * Send a nice hexadecimal dump of a buffer to the specified file stream.
-  *
-  * @param f The file stream pointer where the dump should be sent to.
-  * @param buf buffer
-  * @param size buffer size
+  * Initialize libavformat and register all the muxers, demuxers and
+  * protocols. If you do not call this function, then you can select
+  * exactly which formats you want to support.
   *
-  * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2
+  * @see av_register_input_format()
+  * @see av_register_output_format()
+  * @see av_register_protocol()
   */
- void av_hex_dump(FILE *f, uint8_t *buf, int size);
+ void av_register_all(void);
+ void av_register_input_format(AVInputFormat *format);
+ void av_register_output_format(AVOutputFormat *format);
  
  /**
-  * Send a nice hexadecimal dump of a buffer to the log.
-  *
-  * @param avcl A pointer to an arbitrary struct of which the first field is a
-  * pointer to an AVClass struct.
-  * @param level The importance level of the message, lower values signifying
-  * higher importance.
-  * @param buf buffer
-  * @param size buffer size
+  * Do global initialization of network components. This is optional,
+  * but recommended, since it avoids the overhead of implicitly
+  * doing the setup for each session.
   *
-  * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2
+  * Calling this function will become mandatory if using network
+  * protocols at some major version bump.
   */
void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size);
int avformat_network_init(void);
  
  /**
-  * Send a nice dump of a packet to the specified file stream.
-  *
-  * @param f The file stream pointer where the dump should be sent to.
-  * @param pkt packet to dump
-  * @param dump_payload True if the payload must be displayed, too.
-  * @param st AVStream that the packet belongs to
+  * Undo the initialization done by avformat_network_init.
   */
void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st);
int avformat_network_deinit(void);
  
+ /**
+  * If f is NULL, returns the first registered input format,
+  * if f is non-NULL, returns the next registered input format after f
+  * or NULL if f is the last one.
+  */
+ AVInputFormat  *av_iformat_next(AVInputFormat  *f);
  
  /**
-  * Send a nice dump of a packet to the log.
-  *
-  * @param avcl A pointer to an arbitrary struct of which the first field is a
-  * pointer to an AVClass struct.
-  * @param level The importance level of the message, lower values signifying
-  * higher importance.
-  * @param pkt packet to dump
-  * @param dump_payload True if the payload must be displayed, too.
-  * @param st AVStream that the packet belongs to
+  * If f is NULL, returns the first registered output format,
+  * if f is non-NULL, returns the next registered output format after f
+  * or NULL if f is the last one.
   */
- void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
-                       AVStream *st);
+ AVOutputFormat *av_oformat_next(AVOutputFormat *f);
  
- #if FF_API_PKT_DUMP
- attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
- attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
-                                           int dump_payload);
- #endif
+ /**
+  * Allocate an AVFormatContext.
+  * avformat_free_context() can be used to free the context and everything
+  * allocated by the framework within it.
+  */
+ AVFormatContext *avformat_alloc_context(void);
  
  /**
-  * Initialize libavformat and register all the muxers, demuxers and
-  * protocols. If you do not call this function, then you can select
-  * exactly which formats you want to support.
-  *
-  * @see av_register_input_format()
-  * @see av_register_output_format()
-  * @see av_register_protocol()
+  * Free an AVFormatContext and all its streams.
+  * @param s context to free
   */
- void av_register_all(void);
+ void avformat_free_context(AVFormatContext *s);
  
  /**
-  * Get the CodecID for the given codec tag tag.
-  * If no codec id is found returns CODEC_ID_NONE.
+  * Get the AVClass for AVFormatContext. It can be used in combination with
+  * AV_OPT_SEARCH_FAKE_OBJ for examining options.
   *
-  * @param tags list of supported codec_id-codec_tag pairs, as stored
-  * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+  * @see av_opt_find().
   */
enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
const AVClass *avformat_get_class(void);
  
  /**
-  * Get the codec tag for the given codec id id.
-  * If no codec tag is found returns 0.
+  * Add a new stream to a media file.
   *
-  * @param tags list of supported codec_id-codec_tag pairs, as stored
-  * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+  * When demuxing, it is called by the demuxer in read_header(). If the
+  * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also
+  * be called in read_packet().
+  *
+  * When muxing, should be called by the user before avformat_write_header().
+  *
+  * @param c If non-NULL, the AVCodecContext corresponding to the new stream
+  * will be initialized to use this codec. This is needed for e.g. codec-specific
+  * defaults to be set, so codec should be provided if it is known.
+  *
+  * @return newly created stream or NULL on error.
   */
- unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id);
+ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c);
+ AVProgram *av_new_program(AVFormatContext *s, int id);
  
  /**
-  * Allocate an AVFormatContext.
-  * avformat_free_context() can be used to free the context and everything
-  * allocated by the framework within it.
+  * @}
   */
- AVFormatContext *avformat_alloc_context(void);
+ #if FF_API_GUESS_IMG2_CODEC
+ attribute_deprecated enum CodecID av_guess_image2_codec(const char *filename);
+ #endif
+ #if FF_API_PKT_DUMP
+ attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
+ attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
+                                           int dump_payload);
+ #endif
  
 +#if FF_API_ALLOC_OUTPUT_CONTEXT
 +/**
 + * @deprecated deprecated in favor of avformat_alloc_output_context2()
 + */
 +attribute_deprecated
 +AVFormatContext *avformat_alloc_output_context(const char *format,
 +                                               AVOutputFormat *oformat,
 +                                               const char *filename);
 +#endif
 +
 +/**
 + * Allocate an AVFormatContext for an output format.
 + * avformat_free_context() can be used to free the context and
 + * everything allocated by the framework within it.
 + *
 + * @param *ctx is set to the created format context, or to NULL in
 + * case of failure
 + * @param oformat format to use for allocating the context, if NULL
 + * format_name and filename are used instead
 + * @param format_name the name of output format to use for allocating the
 + * context, if NULL filename is used instead
 + * @param filename the name of the filename to use for allocating the
 + * context, may be NULL
 + * @return >= 0 in case of success, a negative AVERROR code in case of
 + * failure
 + */
 +int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat,
 +                                   const char *format_name, const char *filename);
 +
  /**
   * @addtogroup lavf_decoding
   * @{
@@@ -1869,32 -1736,161 +1854,183 @@@ int av_interleave_packet_per_dts(AVForm
   * @return 0 if OK, AVERROR_xxx on error
   */
  int av_write_trailer(AVFormatContext *s);
  /**
-  * @}
+  * Return the output format in the list of registered output formats
+  * which best matches the provided parameters, or return NULL if
+  * there is no match.
+  *
+  * @param short_name if non-NULL checks if short_name matches with the
+  * names of the registered formats
+  * @param filename if non-NULL checks if filename terminates with the
+  * extensions of the registered formats
+  * @param mime_type if non-NULL checks if mime_type matches with the
+  * MIME type of the registered formats
+  */
+ AVOutputFormat *av_guess_format(const char *short_name,
+                                 const char *filename,
+                                 const char *mime_type);
+ /**
+  * Guess the codec ID based upon muxer and filename.
   */
+ enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+                             const char *filename, const char *mime_type,
+                             enum AVMediaType type);
  
  /**
 + * Get timing information for the data currently output.
 + * The exact meaning of "currently output" depends on the format.
 + * It is mostly relevant for devices that have an internal buffer and/or
 + * work in real time.
 + * @param s          media file handle
 + * @param stream     stream in the media file
 + * @param dts[out]   DTS of the last packet output for the stream, in stream
 + *                   time_base units
 + * @param wall[out]  absolute time when that packet whas output,
 + *                   in microsecond
 + * @return  0 if OK, AVERROR(ENOSYS) if the format does not support it
 + * Note: some formats or devices may not allow to measure dts and wall
 + * atomically.
 + */
 +int av_get_output_timestamp(struct AVFormatContext *s, int stream,
 +                            int64_t *dts, int64_t *wall);
 +
++
++/**
+  * @}
+  */
+ /**
+  * @defgroup lavf_misc Utility functions
+  * @ingroup libavf
+  * @{
+  *
+  * Miscelaneous utility functions related to both muxing and demuxing
+  * (or neither).
+  */
+ /**
+  * Send a nice hexadecimal dump of a buffer to the specified file stream.
+  *
+  * @param f The file stream pointer where the dump should be sent to.
+  * @param buf buffer
+  * @param size buffer size
+  *
+  * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2
+  */
+ void av_hex_dump(FILE *f, uint8_t *buf, int size);
+ /**
+  * Send a nice hexadecimal dump of a buffer to the log.
+  *
+  * @param avcl A pointer to an arbitrary struct of which the first field is a
+  * pointer to an AVClass struct.
+  * @param level The importance level of the message, lower values signifying
+  * higher importance.
+  * @param buf buffer
+  * @param size buffer size
+  *
+  * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2
+  */
+ void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size);
+ /**
+  * Send a nice dump of a packet to the specified file stream.
+  *
+  * @param f The file stream pointer where the dump should be sent to.
+  * @param pkt packet to dump
+  * @param dump_payload True if the payload must be displayed, too.
+  * @param st AVStream that the packet belongs to
+  */
+ void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st);
+ /**
+  * Send a nice dump of a packet to the log.
+  *
+  * @param avcl A pointer to an arbitrary struct of which the first field is a
+  * pointer to an AVClass struct.
+  * @param level The importance level of the message, lower values signifying
+  * higher importance.
+  * @param pkt packet to dump
+  * @param dump_payload True if the payload must be displayed, too.
+  * @param st AVStream that the packet belongs to
+  */
+ void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
+                       AVStream *st);
+ /**
+  * Get the CodecID for the given codec tag tag.
+  * If no codec id is found returns CODEC_ID_NONE.
+  *
+  * @param tags list of supported codec_id-codec_tag pairs, as stored
+  * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+  */
+ enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
+ /**
+  * Get the codec tag for the given codec id id.
+  * If no codec tag is found returns 0.
+  *
+  * @param tags list of supported codec_id-codec_tag pairs, as stored
+  * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+  */
+ unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id);
+ int av_find_default_stream_index(AVFormatContext *s);
+ /**
+  * Get the index for a specific timestamp.
+  * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond
+  *                 to the timestamp which is <= the requested one, if backward
+  *                 is 0, then it will be >=
+  *              if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
+  * @return < 0 if no such timestamp could be found
+  */
+ int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
+ /**
+  * Add an index entry into a sorted list. Update the entry if the list
+  * already contains it.
+  *
+  * @param timestamp timestamp in the time base of the given stream
+  */
+ int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
+                        int size, int distance, int flags);
+ /**
+  * Split a URL string into components.
+  *
+  * The pointers to buffers for storing individual components may be null,
+  * in order to ignore that component. Buffers for components not found are
+  * set to empty strings. If the port is not found, it is set to a negative
+  * value.
+  *
+  * @param proto the buffer for the protocol
+  * @param proto_size the size of the proto buffer
+  * @param authorization the buffer for the authorization
+  * @param authorization_size the size of the authorization buffer
+  * @param hostname the buffer for the host name
+  * @param hostname_size the size of the hostname buffer
+  * @param port_ptr a pointer to store the port number in
+  * @param path the buffer for the path
+  * @param path_size the size of the path buffer
+  * @param url the URL to split
+  */
+ void av_url_split(char *proto,         int proto_size,
+                   char *authorization, int authorization_size,
+                   char *hostname,      int hostname_size,
+                   int *port_ptr,
+                   char *path,          int path_size,
+                   const char *url);
  #if FF_API_DUMP_FORMAT
 +/**
 + * @deprecated Deprecated in favor of av_dump_format().
 + */
  attribute_deprecated void dump_format(AVFormatContext *ic,
                                        int index,
                                        const char *url,
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -30,7 -30,7 +30,7 @@@
  #include "libavutil/avutil.h"
  
  #define LIBAVFORMAT_VERSION_MAJOR 53
- #define LIBAVFORMAT_VERSION_MINOR 24
 -#define LIBAVFORMAT_VERSION_MINOR 17
++#define LIBAVFORMAT_VERSION_MINOR 25
  #define LIBAVFORMAT_VERSION_MICRO  0
  
  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
Simple merge
Simple merge
@@@ -147,31 -137,7 +147,31 @@@ char *av_d2str(double d)
  char *av_get_token(const char **buf, const char *term);
  
  /**
-  * Locale independent conversion of ASCII characters to upper case.
 + * Split the string into several tokens which can be accessed by
 + * successive calls to av_strtok().
 + *
 + * A token is defined as a sequence of characters not belonging to the
 + * set specified in delim.
 + *
 + * On the first call to av_strtok(), s should point to the string to
 + * parse, and the value of saveptr is ignored. In subsequent calls, s
 + * should be NULL, and saveptr should be unchanged since the previous
 + * call.
 + *
 + * This function is similar to strtok_r() defined in POSIX.1.
 + *
 + * @param s the string to parse, may be NULL
 + * @param delim 0-terminated list of token delimiters, must be non-NULL
 + * @param saveptr user-provided pointer which points to stored
 + * information necessary for av_strtok() to continue scanning the same
 + * string. saveptr is updated to point to the next character after the
 + * first delimiter found, or to NULL if the string was terminated
 + * @return the found token, or NULL when no token is found
 + */
 +char *av_strtok(char *s, const char *delim, char **saveptr);
 +
 +/**
+  * Locale-independent conversion of ASCII characters to uppercase.
   */
  static inline int av_toupper(int c)
  {
@@@ -190,8 -156,8 +190,8 @@@ static inline int av_tolower(int c
      return c;
  }
  
 -/*
 +/**
-  * Locale independent case-insensitive compare.
+  * Locale-independent case-insensitive compare.
   * @note This means only ASCII-range characters are case-insensitive
   */
  int av_strcasecmp(const char *a, const char *b);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  #ifndef FF_API_SWS_CPU_CAPS
  #define FF_API_SWS_CPU_CAPS    (LIBSWSCALE_VERSION_MAJOR < 3)
  #endif
 +#ifndef FF_API_SWS_FORMAT_NAME
 +#define FF_API_SWS_FORMAT_NAME  (LIBSWSCALE_VERSION_MAJOR < 3)
 +#endif
  
  /**
-  * Returns the LIBSWSCALE_VERSION_INT constant.
+  * Return the LIBSWSCALE_VERSION_INT constant.
   */
  unsigned swscale_version(void);
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge