summaryrefslogtreecommitdiff
path: root/ffmpeg1/tools
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-08-26 15:10:18 +0100
committerTim Redfern <tim@eclectronics.org>2013-08-26 15:10:18 +0100
commit150c9823e71a161e97003849cf8b2f55b21520bd (patch)
tree3559c840cf403d1386708b2591d58f928c7b160d /ffmpeg1/tools
parentb4b1e2630c95d5e6014463f7608d59dc2322a3b8 (diff)
adding ffmpeg specific version
Diffstat (limited to 'ffmpeg1/tools')
-rw-r--r--ffmpeg1/tools/aviocat.c96
-rwxr-xr-xffmpeg1/tools/bisect-create46
-rw-r--r--ffmpeg1/tools/bookmarklets.html55
-rw-r--r--ffmpeg1/tools/build_libstagefright58
-rwxr-xr-xffmpeg1/tools/clean-diff11
-rw-r--r--ffmpeg1/tools/cws2fws.c145
-rw-r--r--ffmpeg1/tools/enum_options.c143
-rw-r--r--ffmpeg1/tools/ffescape.c180
-rw-r--r--ffmpeg1/tools/ffeval.c142
-rw-r--r--ffmpeg1/tools/fourcc2pixfmt.c123
-rw-r--r--ffmpeg1/tools/graph2dot.c193
-rw-r--r--ffmpeg1/tools/ismindex.c567
-rwxr-xr-xffmpeg1/tools/make_chlayout_test114
-rwxr-xr-xffmpeg1/tools/missing_codec_desc37
-rwxr-xr-xffmpeg1/tools/patcheck180
-rw-r--r--ffmpeg1/tools/pktdumper.c137
-rwxr-xr-xffmpeg1/tools/plotframes164
-rw-r--r--ffmpeg1/tools/probetest.c145
-rw-r--r--ffmpeg1/tools/qt-faststart.c356
-rw-r--r--ffmpeg1/tools/seek_print.c107
-rw-r--r--ffmpeg1/tools/trasher.c81
-rwxr-xr-xffmpeg1/tools/unwrap-diff2
-rw-r--r--ffmpeg1/tools/yuvcmp.c182
23 files changed, 3264 insertions, 0 deletions
diff --git a/ffmpeg1/tools/aviocat.c b/ffmpeg1/tools/aviocat.c
new file mode 100644
index 0000000..52a96bd
--- /dev/null
+++ b/ffmpeg1/tools/aviocat.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libavutil/time.h"
+#include "libavformat/avformat.h"
+
+static int usage(const char *argv0, int ret)
+{
+ fprintf(stderr, "%s [-b bytespersec] input_url output_url\n", argv0);
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
+ int bps = 0, ret, i;
+ const char *input_url = NULL, *output_url = NULL;
+ int64_t stream_pos = 0;
+ int64_t start_time;
+ char errbuf[50];
+ AVIOContext *input, *output;
+
+ av_register_all();
+ avformat_network_init();
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-b")) {
+ bps = atoi(argv[i + 1]);
+ i++;
+ } else if (!input_url) {
+ input_url = argv[i];
+ } else if (!output_url) {
+ output_url = argv[i];
+ } else {
+ return usage(argv[0], 1);
+ }
+ }
+ if (!output_url)
+ return usage(argv[0], 1);
+
+ ret = avio_open2(&input, input_url, AVIO_FLAG_READ, NULL, NULL);
+ if (ret) {
+ av_strerror(ret, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Unable to open %s: %s\n", input_url, errbuf);
+ return 1;
+ }
+ ret = avio_open2(&output, output_url, AVIO_FLAG_WRITE, NULL, NULL);
+ if (ret) {
+ av_strerror(ret, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Unable to open %s: %s\n", output_url, errbuf);
+ goto fail;
+ }
+
+ start_time = av_gettime();
+ while (1) {
+ uint8_t buf[1024];
+ int n;
+ n = avio_read(input, buf, sizeof(buf));
+ if (n <= 0)
+ break;
+ avio_write(output, buf, n);
+ stream_pos += n;
+ if (bps) {
+ avio_flush(output);
+ while ((av_gettime() - start_time) * bps / AV_TIME_BASE < stream_pos)
+ av_usleep(50 * 1000);
+ }
+ }
+
+ avio_flush(output);
+ avio_close(output);
+
+fail:
+ avio_close(input);
+ avformat_network_deinit();
+ return ret ? 1 : 0;
+}
diff --git a/ffmpeg1/tools/bisect-create b/ffmpeg1/tools/bisect-create
new file mode 100755
index 0000000..fc60e86
--- /dev/null
+++ b/ffmpeg1/tools/bisect-create
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+set -e
+
+if test "bisect-create" = "`basename $0`" ; then
+ echo tools/ffbisect created
+ git show master:tools/bisect-create > tools/ffbisect
+ chmod u+x tools/ffbisect
+ exit 1
+fi
+
+if ! git show master:tools/bisect-create | diff - tools/ffbisect > /dev/null ; then
+ echo updating tools/ffbisect script to HEAD.
+ git show master:tools/bisect-create > tools/ffbisect
+ chmod u+x tools/ffbisect
+ tools/ffbisect $*
+ exit 0
+fi
+
+case "$1" in
+ need)
+ case $2 in
+ ffmpeg|ffplay|ffprobe|ffserver)
+ echo $2.c >> tools/bisect.need
+ ;;
+ esac
+ ;;
+ start|reset)
+ echo . > tools/bisect.need
+ git bisect $*
+ ;;
+ skip)
+ git bisect $*
+ ;;
+ good|bad)
+ git bisect $*
+
+ until ls `cat tools/bisect.need` > /dev/null 2> /dev/null; do
+ git bisect skip || break
+ done
+ ;;
+ run)
+ shift # remove "run" from arguments
+ git bisect run sh -c "ls \`cat tools/bisect.need\` > /dev/null 2> /dev/null || exit 125; \"\$@\"" sh "$@"
+ ;;
+esac
diff --git a/ffmpeg1/tools/bookmarklets.html b/ffmpeg1/tools/bookmarklets.html
new file mode 100644
index 0000000..9800ab5
--- /dev/null
+++ b/ffmpeg1/tools/bookmarklets.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!--
+ This file is part of FFmpeg.
+
+ All scripts contained in this file can be considered public domain.
+ -->
+<title>FFmpeg bookmarklets</title>
+<meta charset="UTF-8">
+<script type="text/javascript">
+function convert(js) {
+ js = js.replace(/\/\*.*?\*\//g, ""); /* comments */
+ js = js.replace(/\s+/g, " ");
+ js = js.replace(/\s+\z/, "");
+ js = "(function(){" + js + "})();void 0";
+ return "javascript:" + escape(js);
+}
+function init() {
+ var pre = document.getElementsByTagName("pre");
+ for (var i = 0; pre.length > i; i++) {
+ document.getElementById(pre[i].id + "-link").href = convert(pre[i].textContent);
+ }
+}
+</script>
+<style type="text/css">
+pre { border: solid black 1px; padding: 0.2ex; font-size: 80% }
+</style>
+</head>
+<body onload="init()">
+
+<h1>Introduction</h1>
+
+The scripts in this page are
+<a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklets</a>: store
+their link version in a bookmark, and later activate the bookmark on a page
+to run the script.
+
+<h1>TED Talks captions</h1>
+
+<p><a id="ted_talks_captions-link" href="#">Get links to the captions</a></p>
+
+<pre id="ted_talks_captions">
+d = window.open("", "sub", "width=256,height=512,resizable=yes,scrollbars=yes").document;
+l = document.getElementById("languageCode").getElementsByTagName("option");
+for (i = 1; i &lt; l.length ; i++) {
+ d.body.appendChild(p = d.createElement("p"));
+ p.appendChild(a = d.createElement("a"));
+ a.appendChild(d.createTextNode(l[i].textContent));
+ a.href="http://www.ted.com/talks/subtitles/id/" + talkID+"/lang/" + l[i].value;
+}
+</pre>
+
+</body>
+</html>
diff --git a/ffmpeg1/tools/build_libstagefright b/ffmpeg1/tools/build_libstagefright
new file mode 100644
index 0000000..8b3a093
--- /dev/null
+++ b/ffmpeg1/tools/build_libstagefright
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+if [ "$NDK" = "" ]; then
+ echo NDK variable not set, assuming ${HOME}/android-ndk
+ export NDK=${HOME}/android-ndk
+fi
+
+echo "Fetching Android system headers"
+git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_frameworks_base.git ../android-source/frameworks/base
+git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_system_core.git ../android-source/system/core
+
+echo "Fetching Android libraries for linking"
+# Libraries from any froyo/gingerbread device/emulator should work
+# fine, since the symbols used should be available on most of them.
+if [ ! -d "../android-libs" ]; then
+ if [ ! -f "../update-cm-7.0.3-N1-signed.zip" ]; then
+ wget http://download.cyanogenmod.com/get/update-cm-7.0.3-N1-signed.zip -P../
+ fi
+ unzip ../update-cm-7.0.3-N1-signed.zip system/lib/* -d../
+ mv ../system/lib ../android-libs
+ rmdir ../system
+fi
+
+
+SYSROOT=$NDK/platforms/android-9/arch-arm
+# Expand the prebuilt/* path into the correct one
+TOOLCHAIN=`echo $NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/*-x86`
+export PATH=$TOOLCHAIN/bin:$PATH
+ANDROID_SOURCE=../android-source
+ANDROID_LIBS=../android-libs
+ABI="armeabi-v7a"
+
+rm -rf ../build/stagefright
+mkdir -p ../build/stagefright
+
+DEST=../build/stagefright
+FLAGS="--target-os=linux --cross-prefix=arm-linux-androideabi- --arch=arm --cpu=armv7-a"
+FLAGS="$FLAGS --sysroot=$SYSROOT"
+FLAGS="$FLAGS --disable-avdevice --disable-decoder=h264 --disable-decoder=h264_vdpau --enable-libstagefright-h264"
+
+EXTRA_CFLAGS="-I$ANDROID_SOURCE/frameworks/base/include -I$ANDROID_SOURCE/system/core/include"
+EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/media/libstagefright"
+EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/include/media/stagefright/openmax"
+EXTRA_CFLAGS="$EXTRA_CFLAGS -I$NDK/sources/cxx-stl/gnu-libstdc++/include -I$NDK/sources/cxx-stl/gnu-libstdc++/libs/$ABI/include"
+
+EXTRA_CFLAGS="$EXTRA_CFLAGS -march=armv7-a -mfloat-abi=softfp -mfpu=neon"
+EXTRA_LDFLAGS="-Wl,--fix-cortex-a8 -L$ANDROID_LIBS -Wl,-rpath-link,$ANDROID_LIBS -L$NDK/sources/cxx-stl/gnu-libstdc++/libs/$ABI"
+EXTRA_CXXFLAGS="-Wno-multichar -fno-exceptions -fno-rtti"
+DEST="$DEST/$ABI"
+FLAGS="$FLAGS --prefix=$DEST"
+
+mkdir -p $DEST
+
+echo $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" > $DEST/info.txt
+./configure $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" | tee $DEST/configuration.txt
+[ $PIPESTATUS == 0 ] || exit 1
+make clean
+make -j4 || exit 1
diff --git a/ffmpeg1/tools/clean-diff b/ffmpeg1/tools/clean-diff
new file mode 100755
index 0000000..4600702
--- /dev/null
+++ b/ffmpeg1/tools/clean-diff
@@ -0,0 +1,11 @@
+#!/bin/sh
+sed '/^+[^+]/!s/ /TaBBaT/g' |\
+ expand -t $(seq -s , 9 8 200) |\
+ sed 's/TaBBaT/ /g' |\
+ sed '/^+[^+]/s/ * $//' |\
+ tr -d '\015' |\
+ tr '\n' '°' |\
+ sed 's/\(@@[^@]*@@°[^@]*\)/\n\1/g' |\
+ egrep -v '@@[^@]*@@°(( [^°]*°)|([+-][[:space:]]*°)|(-[[:space:]]*([^°]*)°\+[[:space:]]*\5°))*$' |\
+ tr -d '\n' |\
+ tr '°' '\n'
diff --git a/ffmpeg1/tools/cws2fws.c b/ffmpeg1/tools/cws2fws.c
new file mode 100644
index 0000000..84feda9
--- /dev/null
+++ b/ffmpeg1/tools/cws2fws.c
@@ -0,0 +1,145 @@
+/*
+ * cws2fws by Alex Beregszaszi
+ * This file is placed in the public domain.
+ * Use the program however you see fit.
+ *
+ * This utility converts compressed Macromedia Flash files to uncompressed ones.
+ */
+
+#include "config.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#include <zlib.h>
+
+#ifdef DEBUG
+#define dbgprintf printf
+#else
+#define dbgprintf(...)
+#endif
+
+int main(int argc, char *argv[])
+{
+ int fd_in, fd_out, comp_len, uncomp_len, i, last_out;
+ char buf_in[1024], buf_out[65536];
+ z_stream zstream;
+ struct stat statbuf;
+
+ if (argc < 3) {
+ printf("Usage: %s <infile.swf> <outfile.swf>\n", argv[0]);
+ return 1;
+ }
+
+ fd_in = open(argv[1], O_RDONLY);
+ if (fd_in < 0) {
+ perror("Error opening input file");
+ return 1;
+ }
+
+ fd_out = open(argv[2], O_WRONLY | O_CREAT, 00644);
+ if (fd_out < 0) {
+ perror("Error opening output file");
+ close(fd_in);
+ return 1;
+ }
+
+ if (read(fd_in, &buf_in, 8) != 8) {
+ printf("Header error\n");
+ close(fd_in);
+ close(fd_out);
+ return 1;
+ }
+
+ if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S') {
+ printf("Not a compressed flash file\n");
+ return 1;
+ }
+
+ if (fstat(fd_in, &statbuf) < 0) {
+ perror("fstat failed");
+ return 1;
+ }
+ comp_len = statbuf.st_size;
+ uncomp_len = buf_in[4] | (buf_in[5] << 8) | (buf_in[6] << 16) | (buf_in[7] << 24);
+
+ printf("Compressed size: %d Uncompressed size: %d\n",
+ comp_len - 4, uncomp_len - 4);
+
+ // write out modified header
+ buf_in[0] = 'F';
+ if (write(fd_out, &buf_in, 8) < 8) {
+ perror("Error writing output file");
+ return 1;
+ }
+
+ zstream.zalloc = NULL;
+ zstream.zfree = NULL;
+ zstream.opaque = NULL;
+ if (inflateInit(&zstream) != Z_OK) {
+ fprintf(stderr, "inflateInit failed\n");
+ return 1;
+ }
+
+ for (i = 0; i < comp_len - 8;) {
+ int ret, len = read(fd_in, &buf_in, 1024);
+
+ dbgprintf("read %d bytes\n", len);
+
+ last_out = zstream.total_out;
+
+ zstream.next_in = &buf_in[0];
+ zstream.avail_in = len;
+ zstream.next_out = &buf_out[0];
+ zstream.avail_out = 65536;
+
+ ret = inflate(&zstream, Z_SYNC_FLUSH);
+ if (ret != Z_STREAM_END && ret != Z_OK) {
+ printf("Error while decompressing: %d\n", ret);
+ inflateEnd(&zstream);
+ return 1;
+ }
+
+ dbgprintf("a_in: %d t_in: %lu a_out: %d t_out: %lu -- %lu out\n",
+ zstream.avail_in, zstream.total_in, zstream.avail_out,
+ zstream.total_out, zstream.total_out - last_out);
+
+ if (write(fd_out, &buf_out, zstream.total_out - last_out) <
+ zstream.total_out - last_out) {
+ perror("Error writing output file");
+ return 1;
+ }
+
+ i += len;
+
+ if (ret == Z_STREAM_END || ret == Z_BUF_ERROR)
+ break;
+ }
+
+ if (zstream.total_out != uncomp_len - 8) {
+ printf("Size mismatch (%lu != %d), updating header...\n",
+ zstream.total_out, uncomp_len - 8);
+
+ buf_in[0] = (zstream.total_out + 8) & 0xff;
+ buf_in[1] = ((zstream.total_out + 8) >> 8) & 0xff;
+ buf_in[2] = ((zstream.total_out + 8) >> 16) & 0xff;
+ buf_in[3] = ((zstream.total_out + 8) >> 24) & 0xff;
+
+ if ( lseek(fd_out, 4, SEEK_SET) < 0
+ || write(fd_out, &buf_in, 4) < 4) {
+ perror("Error writing output file");
+ return 1;
+ }
+ }
+
+ inflateEnd(&zstream);
+ close(fd_in);
+ close(fd_out);
+ return 0;
+}
diff --git a/ffmpeg1/tools/enum_options.c b/ffmpeg1/tools/enum_options.c
new file mode 100644
index 0000000..45ac727
--- /dev/null
+++ b/ffmpeg1/tools/enum_options.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011 Anton Khirnov
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * enumerate avoptions and format them in texinfo format
+ */
+
+#include <string.h>
+
+#include "libavformat/avformat.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
+static void print_usage(void)
+{
+ fprintf(stderr, "Usage: enum_options type\n"
+ "type: format codec\n");
+ exit(1);
+}
+
+static void print_option(const AVClass *class, const AVOption *o)
+{
+ printf("@item -%s @var{", o->name);
+ switch (o->type) {
+ case FF_OPT_TYPE_BINARY: printf("hexadecimal string"); break;
+ case FF_OPT_TYPE_STRING: printf("string"); break;
+ case FF_OPT_TYPE_INT:
+ case FF_OPT_TYPE_INT64: printf("integer"); break;
+ case FF_OPT_TYPE_FLOAT:
+ case FF_OPT_TYPE_DOUBLE: printf("float"); break;
+ case FF_OPT_TYPE_RATIONAL: printf("rational number"); break;
+ case FF_OPT_TYPE_FLAGS: printf("flags"); break;
+ default: printf("value"); break;
+ }
+ printf("} (@emph{");
+
+ if (o->flags & AV_OPT_FLAG_ENCODING_PARAM) {
+ printf("input");
+ if (o->flags & AV_OPT_FLAG_ENCODING_PARAM)
+ printf("/");
+ }
+ if (o->flags & AV_OPT_FLAG_ENCODING_PARAM)
+ printf("output");
+
+ printf("})\n");
+ if (o->help)
+ printf("%s\n", o->help);
+
+ if (o->unit) {
+ const AVOption *u = NULL;
+ printf("\nPossible values:\n@table @samp\n");
+
+ while ((u = av_next_option(&class, u)))
+ if (u->type == FF_OPT_TYPE_CONST && u->unit && !strcmp(u->unit, o->unit))
+ printf("@item %s\n%s\n", u->name, u->help ? u->help : "");
+ printf("@end table\n");
+ }
+}
+
+static void show_opts(const AVClass *class)
+{
+ const AVOption *o = NULL;
+
+ printf("@table @option\n");
+ while ((o = av_next_option(&class, o)))
+ if (o->type != FF_OPT_TYPE_CONST)
+ print_option(class, o);
+ printf("@end table\n");
+}
+
+static void show_format_opts(void)
+{
+ AVInputFormat *iformat = NULL;
+ AVOutputFormat *oformat = NULL;
+
+ printf("@section Generic format AVOptions\n");
+ show_opts(avformat_get_class());
+
+ printf("@section Format-specific AVOptions\n");
+ while ((iformat = av_iformat_next(iformat))) {
+ if (!iformat->priv_class)
+ continue;
+ printf("@subsection %s AVOptions\n", iformat->priv_class->class_name);
+ show_opts(iformat->priv_class);
+ }
+ while ((oformat = av_oformat_next(oformat))) {
+ if (!oformat->priv_class)
+ continue;
+ printf("@subsection %s AVOptions\n", oformat->priv_class->class_name);
+ show_opts(oformat->priv_class);
+ }
+}
+
+static void show_codec_opts(void)
+{
+ AVCodec *c = NULL;
+
+ printf("@section Generic codec AVOptions\n");
+ show_opts(avcodec_get_class());
+
+ printf("@section Codec-specific AVOptions\n");
+ while ((c = av_codec_next(c))) {
+ if (!c->priv_class)
+ continue;
+ printf("@subsection %s AVOptions\n", c->priv_class->class_name);
+ show_opts(c->priv_class);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 2)
+ print_usage();
+
+ av_register_all();
+
+ if (!strcmp(argv[1], "format"))
+ show_format_opts();
+ else if (!strcmp(argv[1], "codec"))
+ show_codec_opts();
+ else
+ print_usage();
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/ffescape.c b/ffmpeg1/tools/ffescape.c
new file mode 100644
index 0000000..0530d28
--- /dev/null
+++ b/ffmpeg1/tools/ffescape.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012 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"
+#if HAVE_UNISTD_H
+#include <unistd.h> /* getopt */
+#endif
+
+#include "libavutil/log.h"
+#include "libavutil/bprint.h"
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+/**
+ * @file
+ * escaping utility
+ */
+
+static void usage(void)
+{
+ printf("Escape an input string, adopting the av_get_token() escaping logic\n");
+ printf("usage: ffescape [OPTIONS]\n");
+ printf("\n"
+ "Options:\n"
+ "-e echo each input line on output\n"
+ "-f flag select an escape flag, can assume the values 'whitespace' and 'strict'\n"
+ "-h print this help\n"
+ "-i INFILE set INFILE as input file, stdin if omitted\n"
+ "-l LEVEL set the number of escaping levels, 1 if omitted\n"
+ "-m ESCAPE_MODE select escape mode between 'auto', 'backslash', 'quote'\n"
+ "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
+ "-p PROMPT set output prompt, is '=> ' by default\n"
+ "-s SPECIAL_CHARS set the list of special characters\n");
+}
+
+int main(int argc, char **argv)
+{
+ AVBPrint src;
+ char *src_buf, *dst_buf;
+ const char *outfilename = NULL, *infilename = NULL;
+ FILE *outfile = NULL, *infile = NULL;
+ const char *prompt = "=> ";
+ enum AVEscapeMode escape_mode = AV_ESCAPE_MODE_AUTO;
+ int escape_flags = 0;
+ int level = 1;
+ int echo = 0;
+ char *special_chars = NULL;
+ int c;
+
+ while ((c = getopt(argc, argv, "ef:hi:l:o:m:p:s:")) != -1) {
+ switch (c) {
+ case 'e':
+ echo = 1;
+ break;
+ case 'h':
+ usage();
+ return 0;
+ case 'i':
+ infilename = optarg;
+ break;
+ case 'f':
+ if (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
+ else if (!strcmp(optarg, "strict")) escape_flags |= AV_ESCAPE_FLAG_STRICT;
+ else {
+ av_log(NULL, AV_LOG_ERROR,
+ "Invalid value '%s' for option -f, "
+ "valid arguments are 'whitespace', and 'strict'\n", optarg);
+ return 1;
+ }
+ break;
+ case 'l':
+ {
+ char *tail;
+ long int li = strtol(optarg, &tail, 10);
+ if (*tail || li > INT_MAX || li < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Invalid value '%s' for option -l, argument must be a non negative integer\n",
+ optarg);
+ return 1;
+ }
+ level = li;
+ break;
+ }
+ case 'm':
+ if (!strcmp(optarg, "auto")) escape_mode = AV_ESCAPE_MODE_AUTO;
+ else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH;
+ else if (!strcmp(optarg, "quote")) escape_mode = AV_ESCAPE_MODE_QUOTE;
+ else {
+ av_log(NULL, AV_LOG_ERROR,
+ "Invalid value '%s' for option -m, "
+ "valid arguments are 'backslash', and 'quote'\n", optarg);
+ return 1;
+ }
+ break;
+ case 'o':
+ outfilename = optarg;
+ break;
+ case 'p':
+ prompt = optarg;
+ break;
+ case 's':
+ special_chars = optarg;
+ break;
+ case '?':
+ return 1;
+ }
+ }
+
+ if (!infilename || !strcmp(infilename, "-")) {
+ infilename = "stdin";
+ infile = stdin;
+ } else {
+ infile = fopen(infilename, "r");
+ }
+ if (!infile) {
+ av_log(NULL, AV_LOG_ERROR, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
+ return 1;
+ }
+
+ if (!outfilename || !strcmp(outfilename, "-")) {
+ outfilename = "stdout";
+ outfile = stdout;
+ } else {
+ outfile = fopen(outfilename, "w");
+ }
+ if (!outfile) {
+ av_log(NULL, AV_LOG_ERROR, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
+ return 1;
+ }
+
+ /* grab the input and store it in src */
+ av_bprint_init(&src, 1, AV_BPRINT_SIZE_UNLIMITED);
+ while ((c = fgetc(infile)) != EOF)
+ av_bprint_chars(&src, c, 1);
+ av_bprint_chars(&src, 0, 1);
+
+ if (!av_bprint_is_complete(&src)) {
+ av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
+ av_bprint_finalize(&src, NULL);
+ return 1;
+ }
+ av_bprint_finalize(&src, &src_buf);
+
+ if (echo)
+ fprintf(outfile, "%s", src_buf);
+
+ /* escape */
+ dst_buf = src_buf;
+ while (level--) {
+ if (av_escape(&dst_buf, src_buf, special_chars, escape_mode, escape_flags) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Could not escape string\n");
+ return 1;
+ }
+ av_free(src_buf);
+ src_buf = dst_buf;
+ }
+
+ fprintf(outfile, "%s%s", prompt, dst_buf);
+ av_free(dst_buf);
+ return 0;
+}
diff --git a/ffmpeg1/tools/ffeval.c b/ffmpeg1/tools/ffeval.c
new file mode 100644
index 0000000..0fab877
--- /dev/null
+++ b/ffmpeg1/tools/ffeval.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012 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"
+#if HAVE_UNISTD_H
+#include <unistd.h> /* getopt */
+#endif
+
+#include "libavutil/eval.h"
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+/**
+ * @file
+ * simple arithmetic expression evaluator
+ */
+
+static void usage(void)
+{
+ printf("Simple expression evalutor, please *don't* turn me to a feature-complete language interpreter\n");
+ printf("usage: ffeval [OPTIONS]\n");
+ printf("\n"
+ "Options:\n"
+ "-e echo each input line on output\n"
+ "-h print this help\n"
+ "-i INFILE set INFILE as input file, stdin if omitted\n"
+ "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
+ "-p PROMPT set output prompt\n");
+}
+
+#define MAX_BLOCK_SIZE SIZE_MAX
+
+int main(int argc, char **argv)
+{
+ size_t buf_size = 256;
+ char *buf = av_malloc(buf_size);
+ const char *outfilename = NULL, *infilename = NULL;
+ FILE *outfile = NULL, *infile = NULL;
+ const char *prompt = "=> ";
+ int count = 0, echo = 0;
+ int c;
+
+ av_max_alloc(MAX_BLOCK_SIZE);
+
+ while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
+ switch (c) {
+ case 'e':
+ echo = 1;
+ break;
+ case 'h':
+ usage();
+ return 0;
+ case 'i':
+ infilename = optarg;
+ break;
+ case 'o':
+ outfilename = optarg;
+ break;
+ case 'p':
+ prompt = optarg;
+ break;
+ case '?':
+ return 1;
+ }
+ }
+
+ if (!infilename || !strcmp(infilename, "-")) {
+ infilename = "stdin";
+ infile = stdin;
+ } else {
+ infile = fopen(infilename, "r");
+ }
+ if (!infile) {
+ fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
+ return 1;
+ }
+
+ if (!outfilename || !strcmp(outfilename, "-")) {
+ outfilename = "stdout";
+ outfile = stdout;
+ } else {
+ outfile = fopen(outfilename, "w");
+ }
+ if (!outfile) {
+ fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
+ return 1;
+ }
+
+ while ((c = fgetc(infile)) != EOF) {
+ if (c == '\n') {
+ double d;
+
+ buf[count] = 0;
+ if (buf[0] != '#') {
+ av_expr_parse_and_eval(&d, buf,
+ NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, 0, NULL);
+ if (echo)
+ fprintf(outfile, "%s ", buf);
+ fprintf(outfile, "%s%f\n", prompt, d);
+ }
+ count = 0;
+ } else {
+ if (count >= buf_size-1) {
+ if (buf_size == MAX_BLOCK_SIZE) {
+ av_log(NULL, AV_LOG_ERROR, "Memory allocation problem, "
+ "max block size '%zd' reached\n", MAX_BLOCK_SIZE);
+ return 1;
+ }
+ buf_size = FFMIN(buf_size, MAX_BLOCK_SIZE / 2) * 2;
+ buf = av_realloc_f((void *)buf, buf_size, 1);
+ if (!buf) {
+ av_log(NULL, AV_LOG_ERROR, "Memory allocation problem occurred\n");
+ return 1;
+ }
+ }
+ buf[count++] = c;
+ }
+ }
+
+ av_free(buf);
+ return 0;
+}
diff --git a/ffmpeg1/tools/fourcc2pixfmt.c b/ffmpeg1/tools/fourcc2pixfmt.c
new file mode 100644
index 0000000..77cb0b6
--- /dev/null
+++ b/ffmpeg1/tools/fourcc2pixfmt.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012 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"
+#if HAVE_UNISTD_H
+#include <unistd.h> /* getopt */
+#endif
+
+#include "libavutil/pixdesc.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/common.h"
+#include "libavcodec/raw.h"
+
+#undef printf
+#undef fprintf
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+static void usage(void)
+{
+ printf("Show the relationships between rawvideo pixel formats and FourCC tags.\n");
+ printf("usage: fourcc2pixfmt [OPTIONS]\n");
+ printf("\n"
+ "Options:\n"
+ "-l list the pixel format for each fourcc\n"
+ "-L list the fourccs for each pixel format\n"
+ "-p PIX_FMT given a pixel format, print the list of associated fourccs (one per line)\n"
+ "-h print this help\n");
+}
+
+static void print_pix_fmt_fourccs(enum AVPixelFormat pix_fmt, char sep)
+{
+ int i;
+
+ for (i = 0; ff_raw_pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
+ if (ff_raw_pix_fmt_tags[i].pix_fmt == pix_fmt) {
+ char buf[32];
+ av_get_codec_tag_string(buf, sizeof(buf), ff_raw_pix_fmt_tags[i].fourcc);
+ printf("%s%c", buf, sep);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int i, list_fourcc_pix_fmt = 0, list_pix_fmt_fourccs = 0;
+ const char *pix_fmt_name = NULL;
+ char c;
+
+ if (argc == 1) {
+ usage();
+ return 0;
+ }
+
+ while ((c = getopt(argc, argv, "hp:lL")) != -1) {
+ switch (c) {
+ case 'h':
+ usage();
+ return 0;
+ case 'l':
+ list_fourcc_pix_fmt = 1;
+ break;
+ case 'L':
+ list_pix_fmt_fourccs = 1;
+ break;
+ case 'p':
+ pix_fmt_name = optarg;
+ break;
+ case '?':
+ usage();
+ return 1;
+ }
+ }
+
+ if (list_fourcc_pix_fmt) {
+ for (i = 0; ff_raw_pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
+ char buf[32];
+ av_get_codec_tag_string(buf, sizeof(buf), ff_raw_pix_fmt_tags[i].fourcc);
+ printf("%s: %s\n", buf, av_get_pix_fmt_name(ff_raw_pix_fmt_tags[i].pix_fmt));
+ }
+ }
+
+ if (list_pix_fmt_fourccs) {
+ for (i = 0; i < AV_PIX_FMT_NB; i++) {
+ const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(i);
+ if (!pix_desc->name || pix_desc->flags & PIX_FMT_HWACCEL)
+ continue;
+ printf("%s: ", pix_desc->name);
+ print_pix_fmt_fourccs(i, ' ');
+ printf("\n");
+ }
+ }
+
+ if (pix_fmt_name) {
+ enum AVPixelFormat pix_fmt = av_get_pix_fmt(pix_fmt_name);
+ if (pix_fmt == AV_PIX_FMT_NONE) {
+ fprintf(stderr, "Invalid pixel format selected '%s'\n", pix_fmt_name);
+ return 1;
+ }
+ print_pix_fmt_fourccs(pix_fmt, '\n');
+ }
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/graph2dot.c b/ffmpeg1/tools/graph2dot.c
new file mode 100644
index 0000000..d53642f
--- /dev/null
+++ b/ffmpeg1/tools/graph2dot.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2008-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"
+#if HAVE_UNISTD_H
+#include <unistd.h> /* getopt */
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/mem.h"
+#include "libavutil/pixdesc.h"
+#include "libavfilter/avfiltergraph.h"
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+static void usage(void)
+{
+ printf("Convert a libavfilter graph to a dot file\n");
+ printf("Usage: graph2dot [OPTIONS]\n");
+ printf("\n"
+ "Options:\n"
+ "-i INFILE set INFILE as input file, stdin if omitted\n"
+ "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
+ "-h print this help\n");
+}
+
+struct line {
+ char data[256];
+ struct line *next;
+};
+
+static void print_digraph(FILE *outfile, AVFilterGraph *graph)
+{
+ int i, j;
+
+ fprintf(outfile, "digraph G {\n");
+ fprintf(outfile, "node [shape=box]\n");
+ fprintf(outfile, "rankdir=LR\n");
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ char filter_ctx_label[128];
+ const AVFilterContext *filter_ctx = graph->filters[i];
+
+ snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s\\n(%s)",
+ filter_ctx->name,
+ filter_ctx->filter->name);
+
+ for (j = 0; j < filter_ctx->output_count; j++) {
+ AVFilterLink *link = filter_ctx->outputs[j];
+ if (link) {
+ char dst_filter_ctx_label[128];
+ const AVFilterContext *dst_filter_ctx = link->dst;
+
+ snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label),
+ "%s\\n(%s)",
+ dst_filter_ctx->name,
+ dst_filter_ctx->filter->name);
+
+ fprintf(outfile, "\"%s\" -> \"%s\" [ label= \"inpad:%s -> outpad:%s\\n",
+ filter_ctx_label, dst_filter_ctx_label,
+ link->srcpad->name, link->dstpad->name);
+
+ if (link->type == AVMEDIA_TYPE_VIDEO) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
+ fprintf(outfile,
+ "fmt:%s w:%d h:%d tb:%d/%d",
+ desc->name,
+ link->w, link->h,
+ link->time_base.num, link->time_base.den);
+ } else if (link->type == AVMEDIA_TYPE_AUDIO) {
+ char buf[255];
+ av_get_channel_layout_string(buf, sizeof(buf), -1,
+ link->channel_layout);
+ fprintf(outfile,
+ "fmt:%s sr:%d cl:%s tb:%d/%d",
+ av_get_sample_fmt_name(link->format),
+ link->sample_rate, buf,
+ link->time_base.num, link->time_base.den);
+ }
+ fprintf(outfile, "\" ];\n");
+ }
+ }
+ }
+ fprintf(outfile, "}\n");
+}
+
+int main(int argc, char **argv)
+{
+ const char *outfilename = NULL;
+ const char *infilename = NULL;
+ FILE *outfile = NULL;
+ FILE *infile = NULL;
+ char *graph_string = NULL;
+ AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
+ char c;
+
+ av_log_set_level(AV_LOG_DEBUG);
+
+ while ((c = getopt(argc, argv, "hi:o:")) != -1) {
+ switch (c) {
+ case 'h':
+ usage();
+ return 0;
+ case 'i':
+ infilename = optarg;
+ break;
+ case 'o':
+ outfilename = optarg;
+ break;
+ case '?':
+ return 1;
+ }
+ }
+
+ if (!infilename || !strcmp(infilename, "-"))
+ infilename = "/dev/stdin";
+ infile = fopen(infilename, "r");
+ if (!infile) {
+ fprintf(stderr, "Impossible to open input file '%s': %s\n",
+ infilename, strerror(errno));
+ return 1;
+ }
+
+ if (!outfilename || !strcmp(outfilename, "-"))
+ outfilename = "/dev/stdout";
+ outfile = fopen(outfilename, "w");
+ if (!outfile) {
+ fprintf(stderr, "Impossible to open output file '%s': %s\n",
+ outfilename, strerror(errno));
+ return 1;
+ }
+
+ /* read from infile and put it in a buffer */
+ {
+ unsigned int count = 0;
+ struct line *line, *last_line, *first_line;
+ char *p;
+ last_line = first_line = av_malloc(sizeof(struct line));
+
+ while (fgets(last_line->data, sizeof(last_line->data), infile)) {
+ struct line *new_line = av_malloc(sizeof(struct line));
+ count += strlen(last_line->data);
+ last_line->next = new_line;
+ last_line = new_line;
+ }
+ last_line->next = NULL;
+
+ graph_string = av_malloc(count + 1);
+ p = graph_string;
+ for (line = first_line; line->next; line = line->next) {
+ unsigned int l = strlen(line->data);
+ memcpy(p, line->data, l);
+ p += l;
+ }
+ *p = '\0';
+ }
+
+ avfilter_register_all();
+
+ if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) {
+ fprintf(stderr, "Impossible to parse the graph description\n");
+ return 1;
+ }
+
+ if (avfilter_graph_config(graph, NULL) < 0)
+ return 1;
+
+ print_digraph(outfile, graph);
+ fflush(outfile);
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/ismindex.c b/ffmpeg1/tools/ismindex.c
new file mode 100644
index 0000000..502a7dc
--- /dev/null
+++ b/ffmpeg1/tools/ismindex.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * To create a simple file for smooth streaming:
+ * ffmpeg <normal input/transcoding options> -movflags frag_keyframe foo.ismv
+ * ismindex -n foo foo.ismv
+ * This step creates foo.ism and foo.ismc that is required by IIS for
+ * serving it.
+ *
+ * To pre-split files for serving as static files by a web server without
+ * any extra server support, create the ismv file as above, and split it:
+ * ismindex -split foo.ismv
+ * This step creates a file Manifest and directories QualityLevel(...),
+ * that can be read directly by a smooth streaming player.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#ifdef _WIN32
+#include <direct.h>
+#define mkdir(a, b) _mkdir(a)
+#endif
+
+#include "cmdutils.h"
+
+#include "libavformat/avformat.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+
+static int usage(const char *argv0, int ret)
+{
+ fprintf(stderr, "%s [-split] [-n basename] file1 [file2] ...\n", argv0);
+ return ret;
+}
+
+struct MoofOffset {
+ int64_t time;
+ int64_t offset;
+ int duration;
+};
+
+struct Track {
+ const char *name;
+ int64_t duration;
+ int bitrate;
+ int track_id;
+ int is_audio, is_video;
+ int width, height;
+ int chunks;
+ int sample_rate, channels;
+ uint8_t *codec_private;
+ int codec_private_size;
+ struct MoofOffset *offsets;
+ int timescale;
+ const char *fourcc;
+ int blocksize;
+ int tag;
+};
+
+struct Tracks {
+ int nb_tracks;
+ int64_t duration;
+ struct Track **tracks;
+ int video_track, audio_track;
+ int nb_video_tracks, nb_audio_tracks;
+};
+
+static int copy_tag(AVIOContext *in, AVIOContext *out, int32_t tag_name)
+{
+ int32_t size, tag;
+
+ size = avio_rb32(in);
+ tag = avio_rb32(in);
+ avio_wb32(out, size);
+ avio_wb32(out, tag);
+ if (tag != tag_name)
+ return -1;
+ size -= 8;
+ while (size > 0) {
+ char buf[1024];
+ int len = FFMIN(sizeof(buf), size);
+ if (avio_read(in, buf, len) != len)
+ break;
+ avio_write(out, buf, len);
+ size -= len;
+ }
+ return 0;
+}
+
+static int write_fragment(const char *filename, AVIOContext *in)
+{
+ AVIOContext *out = NULL;
+ int ret;
+
+ if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, NULL, NULL)) < 0)
+ return ret;
+ copy_tag(in, out, MKBETAG('m', 'o', 'o', 'f'));
+ copy_tag(in, out, MKBETAG('m', 'd', 'a', 't'));
+
+ avio_flush(out);
+ avio_close(out);
+
+ return ret;
+}
+
+static int write_fragments(struct Tracks *tracks, int start_index,
+ AVIOContext *in)
+{
+ char dirname[100], filename[500];
+ int i, j;
+
+ for (i = start_index; i < tracks->nb_tracks; i++) {
+ struct Track *track = tracks->tracks[i];
+ const char *type = track->is_video ? "video" : "audio";
+ snprintf(dirname, sizeof(dirname), "QualityLevels(%d)", track->bitrate);
+ mkdir(dirname, 0777);
+ for (j = 0; j < track->chunks; j++) {
+ snprintf(filename, sizeof(filename), "%s/Fragments(%s=%"PRId64")",
+ dirname, type, track->offsets[j].time);
+ avio_seek(in, track->offsets[j].offset, SEEK_SET);
+ write_fragment(filename, in);
+ }
+ }
+ return 0;
+}
+
+static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f)
+{
+ int ret = AVERROR_EOF, track_id;
+ int version, fieldlength, i, j;
+ int64_t pos = avio_tell(f);
+ uint32_t size = avio_rb32(f);
+ struct Track *track = NULL;
+
+ if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a'))
+ goto fail;
+ version = avio_r8(f);
+ avio_rb24(f);
+ track_id = avio_rb32(f); /* track id */
+ for (i = start_index; i < tracks->nb_tracks && !track; i++)
+ if (tracks->tracks[i]->track_id == track_id)
+ track = tracks->tracks[i];
+ if (!track) {
+ /* Ok, continue parsing the next atom */
+ ret = 0;
+ goto fail;
+ }
+ fieldlength = avio_rb32(f);
+ track->chunks = avio_rb32(f);
+ track->offsets = av_mallocz(sizeof(*track->offsets) * track->chunks);
+ if (!track->offsets) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ for (i = 0; i < track->chunks; i++) {
+ if (version == 1) {
+ track->offsets[i].time = avio_rb64(f);
+ track->offsets[i].offset = avio_rb64(f);
+ } else {
+ track->offsets[i].time = avio_rb32(f);
+ track->offsets[i].offset = avio_rb32(f);
+ }
+ for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
+ avio_r8(f);
+ for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
+ avio_r8(f);
+ for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
+ avio_r8(f);
+ if (i > 0)
+ track->offsets[i - 1].duration = track->offsets[i].time -
+ track->offsets[i - 1].time;
+ }
+ if (track->chunks > 0)
+ track->offsets[track->chunks - 1].duration = track->duration -
+ track->offsets[track->chunks - 1].time;
+ ret = 0;
+
+fail:
+ avio_seek(f, pos + size, SEEK_SET);
+ return ret;
+}
+
+static int read_mfra(struct Tracks *tracks, int start_index,
+ const char *file, int split)
+{
+ int err = 0;
+ AVIOContext *f = NULL;
+ int32_t mfra_size;
+
+ if ((err = avio_open2(&f, file, AVIO_FLAG_READ, NULL, NULL)) < 0)
+ goto fail;
+ avio_seek(f, avio_size(f) - 4, SEEK_SET);
+ mfra_size = avio_rb32(f);
+ avio_seek(f, -mfra_size, SEEK_CUR);
+ if (avio_rb32(f) != mfra_size) {
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ while (!read_tfra(tracks, start_index, f)) {
+ /* Empty */
+ }
+
+ if (split)
+ write_fragments(tracks, start_index, f);
+
+fail:
+ if (f)
+ avio_close(f);
+ if (err)
+ fprintf(stderr, "Unable to read the MFRA atom in %s\n", file);
+ return err;
+}
+
+static int get_private_data(struct Track *track, AVCodecContext *codec)
+{
+ track->codec_private_size = codec->extradata_size;
+ track->codec_private = av_mallocz(codec->extradata_size);
+ if (!track->codec_private)
+ return AVERROR(ENOMEM);
+ memcpy(track->codec_private, codec->extradata, codec->extradata_size);
+ return 0;
+}
+
+static int get_video_private_data(struct Track *track, AVCodecContext *codec)
+{
+ AVIOContext *io = NULL;
+ uint16_t sps_size, pps_size;
+ int err = AVERROR(EINVAL);
+
+ if (codec->codec_id == AV_CODEC_ID_VC1)
+ return get_private_data(track, codec);
+
+ if (avio_open_dyn_buf(&io) < 0) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if (codec->extradata_size < 11 || codec->extradata[0] != 1)
+ goto fail;
+ sps_size = AV_RB16(&codec->extradata[6]);
+ if (11 + sps_size > codec->extradata_size)
+ goto fail;
+ avio_wb32(io, 0x00000001);
+ avio_write(io, &codec->extradata[8], sps_size);
+ pps_size = AV_RB16(&codec->extradata[9 + sps_size]);
+ if (11 + sps_size + pps_size > codec->extradata_size)
+ goto fail;
+ avio_wb32(io, 0x00000001);
+ avio_write(io, &codec->extradata[11 + sps_size], pps_size);
+ err = 0;
+
+fail:
+ track->codec_private_size = avio_close_dyn_buf(io, &track->codec_private);
+ return err;
+}
+
+static int handle_file(struct Tracks *tracks, const char *file, int split)
+{
+ AVFormatContext *ctx = NULL;
+ int err = 0, i, orig_tracks = tracks->nb_tracks;
+ char errbuf[50], *ptr;
+ struct Track *track;
+
+ err = avformat_open_input(&ctx, file, NULL, NULL);
+ if (err < 0) {
+ av_strerror(err, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Unable to open %s: %s\n", file, errbuf);
+ return 1;
+ }
+
+ err = avformat_find_stream_info(ctx, NULL);
+ if (err < 0) {
+ av_strerror(err, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Unable to identify %s: %s\n", file, errbuf);
+ goto fail;
+ }
+
+ if (ctx->nb_streams < 1) {
+ fprintf(stderr, "No streams found in %s\n", file);
+ goto fail;
+ }
+ if (!tracks->duration)
+ tracks->duration = ctx->duration;
+
+ for (i = 0; i < ctx->nb_streams; i++) {
+ struct Track **temp;
+ AVStream *st = ctx->streams[i];
+ track = av_mallocz(sizeof(*track));
+ if (!track) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ temp = av_realloc(tracks->tracks,
+ sizeof(*tracks->tracks) * (tracks->nb_tracks + 1));
+ if (!temp) {
+ av_free(track);
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ tracks->tracks = temp;
+ tracks->tracks[tracks->nb_tracks] = track;
+
+ track->name = file;
+ if ((ptr = strrchr(file, '/')) != NULL)
+ track->name = ptr + 1;
+
+ track->bitrate = st->codec->bit_rate;
+ track->track_id = st->id;
+ track->timescale = st->time_base.den;
+ track->duration = av_rescale_rnd(ctx->duration, track->timescale,
+ AV_TIME_BASE, AV_ROUND_UP);
+ track->is_audio = st->codec->codec_type == AVMEDIA_TYPE_AUDIO;
+ track->is_video = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
+
+ if (!track->is_audio && !track->is_video) {
+ fprintf(stderr,
+ "Track %d in %s is neither video nor audio, skipping\n",
+ track->track_id, file);
+ av_freep(&tracks->tracks[tracks->nb_tracks]);
+ continue;
+ }
+
+ if (track->is_audio) {
+ if (tracks->audio_track < 0)
+ tracks->audio_track = tracks->nb_tracks;
+ tracks->nb_audio_tracks++;
+ track->channels = st->codec->channels;
+ track->sample_rate = st->codec->sample_rate;
+ if (st->codec->codec_id == AV_CODEC_ID_AAC) {
+ track->fourcc = "AACL";
+ track->tag = 255;
+ track->blocksize = 4;
+ } else if (st->codec->codec_id == AV_CODEC_ID_WMAPRO) {
+ track->fourcc = "WMAP";
+ track->tag = st->codec->codec_tag;
+ track->blocksize = st->codec->block_align;
+ }
+ get_private_data(track, st->codec);
+ }
+ if (track->is_video) {
+ if (tracks->video_track < 0)
+ tracks->video_track = tracks->nb_tracks;
+ tracks->nb_video_tracks++;
+ track->width = st->codec->width;
+ track->height = st->codec->height;
+ if (st->codec->codec_id == AV_CODEC_ID_H264)
+ track->fourcc = "H264";
+ else if (st->codec->codec_id == AV_CODEC_ID_VC1)
+ track->fourcc = "WVC1";
+ get_video_private_data(track, st->codec);
+ }
+
+ tracks->nb_tracks++;
+ }
+
+ avformat_close_input(&ctx);
+
+ err = read_mfra(tracks, orig_tracks, file, split);
+
+fail:
+ if (ctx)
+ avformat_close_input(&ctx);
+ return err;
+}
+
+static void output_server_manifest(struct Tracks *tracks,
+ const char *basename)
+{
+ char filename[1000];
+ FILE *out;
+ int i;
+
+ snprintf(filename, sizeof(filename), "%s.ism", basename);
+ out = fopen(filename, "w");
+ if (!out) {
+ perror(filename);
+ return;
+ }
+ fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ fprintf(out, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
+ fprintf(out, "\t<head>\n");
+ fprintf(out, "\t\t<meta name=\"clientManifestRelativePath\" "
+ "content=\"%s.ismc\" />\n", basename);
+ fprintf(out, "\t</head>\n");
+ fprintf(out, "\t<body>\n");
+ fprintf(out, "\t\t<switch>\n");
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ struct Track *track = tracks->tracks[i];
+ const char *type = track->is_video ? "video" : "audio";
+ fprintf(out, "\t\t\t<%s src=\"%s\" systemBitrate=\"%d\">\n",
+ type, track->name, track->bitrate);
+ fprintf(out, "\t\t\t\t<param name=\"trackID\" value=\"%d\" "
+ "valueType=\"data\" />\n", track->track_id);
+ fprintf(out, "\t\t\t</%s>\n", type);
+ }
+ fprintf(out, "\t\t</switch>\n");
+ fprintf(out, "\t</body>\n");
+ fprintf(out, "</smil>\n");
+ fclose(out);
+}
+
+static void print_track_chunks(FILE *out, struct Tracks *tracks, int main,
+ const char *type)
+{
+ int i, j;
+ struct Track *track = tracks->tracks[main];
+ for (i = 0; i < track->chunks; i++) {
+ for (j = main + 1; j < tracks->nb_tracks; j++) {
+ if (tracks->tracks[j]->is_audio == track->is_audio &&
+ track->offsets[i].duration != tracks->tracks[j]->offsets[i].duration)
+ fprintf(stderr, "Mismatched duration of %s chunk %d in %s and %s\n",
+ type, i, track->name, tracks->tracks[j]->name);
+ }
+ fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n",
+ i, track->offsets[i].duration);
+ }
+}
+
+static void output_client_manifest(struct Tracks *tracks,
+ const char *basename, int split)
+{
+ char filename[1000];
+ FILE *out;
+ int i, j;
+
+ if (split)
+ snprintf(filename, sizeof(filename), "Manifest");
+ else
+ snprintf(filename, sizeof(filename), "%s.ismc", basename);
+ out = fopen(filename, "w");
+ if (!out) {
+ perror(filename);
+ return;
+ }
+ fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ fprintf(out, "<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" "
+ "Duration=\"%"PRId64 "\">\n", tracks->duration * 10);
+ if (tracks->video_track >= 0) {
+ struct Track *track = tracks->tracks[tracks->video_track];
+ struct Track *first_track = track;
+ int index = 0;
+ fprintf(out,
+ "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
+ "Chunks=\"%d\" "
+ "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
+ tracks->nb_video_tracks, track->chunks);
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ track = tracks->tracks[i];
+ if (!track->is_video)
+ continue;
+ fprintf(out,
+ "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
+ "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" "
+ "CodecPrivateData=\"",
+ index, track->bitrate, track->fourcc, track->width, track->height);
+ for (j = 0; j < track->codec_private_size; j++)
+ fprintf(out, "%02X", track->codec_private[j]);
+ fprintf(out, "\" />\n");
+ index++;
+ if (track->chunks != first_track->chunks)
+ fprintf(stderr, "Mismatched number of video chunks in %s and %s\n",
+ track->name, first_track->name);
+ }
+ print_track_chunks(out, tracks, tracks->video_track, "video");
+ fprintf(out, "\t</StreamIndex>\n");
+ }
+ if (tracks->audio_track >= 0) {
+ struct Track *track = tracks->tracks[tracks->audio_track];
+ struct Track *first_track = track;
+ int index = 0;
+ fprintf(out,
+ "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
+ "Chunks=\"%d\" "
+ "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
+ tracks->nb_audio_tracks, track->chunks);
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ track = tracks->tracks[i];
+ if (!track->is_audio)
+ continue;
+ fprintf(out,
+ "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
+ "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" "
+ "BitsPerSample=\"16\" PacketSize=\"%d\" "
+ "AudioTag=\"%d\" CodecPrivateData=\"",
+ index, track->bitrate, track->fourcc, track->sample_rate,
+ track->channels, track->blocksize, track->tag);
+ for (j = 0; j < track->codec_private_size; j++)
+ fprintf(out, "%02X", track->codec_private[j]);
+ fprintf(out, "\" />\n");
+ index++;
+ if (track->chunks != first_track->chunks)
+ fprintf(stderr, "Mismatched number of audio chunks in %s and %s\n",
+ track->name, first_track->name);
+ }
+ print_track_chunks(out, tracks, tracks->audio_track, "audio");
+ fprintf(out, "\t</StreamIndex>\n");
+ }
+ fprintf(out, "</SmoothStreamingMedia>\n");
+ fclose(out);
+}
+
+static void clean_tracks(struct Tracks *tracks)
+{
+ int i;
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ av_freep(&tracks->tracks[i]->codec_private);
+ av_freep(&tracks->tracks[i]->offsets);
+ av_freep(&tracks->tracks[i]);
+ }
+ av_freep(&tracks->tracks);
+ tracks->nb_tracks = 0;
+}
+
+int main(int argc, char **argv)
+{
+ const char *basename = NULL;
+ int split = 0, i;
+ struct Tracks tracks = { 0, .video_track = -1, .audio_track = -1 };
+
+ av_register_all();
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-n")) {
+ basename = argv[i + 1];
+ i++;
+ } else if (!strcmp(argv[i], "-split")) {
+ split = 1;
+ } else if (argv[i][0] == '-') {
+ return usage(argv[0], 1);
+ } else {
+ if (handle_file(&tracks, argv[i], split))
+ return 1;
+ }
+ }
+ if (!tracks.nb_tracks || (!basename && !split))
+ return usage(argv[0], 1);
+
+ if (!split)
+ output_server_manifest(&tracks, basename);
+ output_client_manifest(&tracks, basename, split);
+
+ clean_tracks(&tracks);
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/make_chlayout_test b/ffmpeg1/tools/make_chlayout_test
new file mode 100755
index 0000000..fcdbda3
--- /dev/null
+++ b/ffmpeg1/tools/make_chlayout_test
@@ -0,0 +1,114 @@
+#!/usr/bin/env perl
+
+# Copyright (c) 2012 Nicolas George
+#
+# 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
+
+=head1 NAME
+
+make_chlayout_test - produce a multichannel test file with the channels
+clearly identified
+
+=head1 SYNOPSIS
+
+tools/make_chlayout_test I<channels> I<out_options>
+
+=head1 DESCRIPTION
+
+This script uses B<ffmpeg> and B<libflite> to produce a file with audio
+channels clearly identified by their name. The resulting file can be used to
+check that the layout and order of channels is correctly handled by a piece
+of software, either a part of B<FFmpeg> or not.
+
+I<channels> is a list of channels or channel layouts, separated by '+'.
+
+I<out_options> is a list of valid ffmpeg outout options, including the
+output file.
+
+Note that some output codecs or formats can not handle arbitrary channel
+layout.
+
+This script requires a B<ffmpeg> binary, either in the source tree or in the
+search path; it must have the flite audio source enabled.
+
+=head1 EXAMPLES
+
+Check that the speakers are correctly plugged:
+
+ tools/make_chlayout_test FL+FR -f alsa default
+
+Produce a 5.1 FLAC file:
+
+ tools/make_chlayout_test 5.1 surround.flac
+
+=cut
+
+use strict;
+use warnings;
+use Getopt::Long ":config" => "require_order";
+use Pod::Usage;
+
+GetOptions (
+ "help|usage|?|h" => sub { pod2usage({ -verbose => 1, -exitval => 0 }) },
+ "manpage|m" => sub { pod2usage({ -verbose => 2, -exitval => 0 }) },
+) and @ARGV >= 2 or pod2usage({ -verbose => 1, -exitval => 1 });
+
+my $channels = shift @ARGV;
+my @out_options = @ARGV;
+
+my $ffmpeg = exists $ENV{FFMPEG} ? $ENV{FFMPEG} :
+ $0 =~ /(.*)\// && -e "$1/../ffmpeg" ? "$1/../ffmpeg" :
+ "ffmpeg";
+
+my %channel_label_to_descr;
+my %layout_to_channels;
+
+{
+ open my $stderr, ">&STDERR";
+ open STDERR, ">", "/dev/null";
+ open my $f, "-|", $ffmpeg, "-layouts" or die "$ffmpeg: $!\n";
+ open STDERR, ">&", $stderr;
+ while (<$f>) {
+ chomp;
+ next if /^NAME/ or /:$/ or /^$/; # skip headings
+ my ($name, $descr) = split " ", $_, 2;
+ next unless $descr;
+ if ($descr =~ /^[[:upper:]]+(?:\+[[:upper:]]+)*$/) {
+ $layout_to_channels{$name} = [ split /\+/, $descr ];
+ } else {
+ $channel_label_to_descr{$name} = $descr;
+ }
+ }
+}
+
+my @channels = map { @{$layout_to_channels{$_} // [$_]} } split /\+/, $channels;
+
+my $layout = join "+", @channels;
+my $graph = "";
+my $concat_in = "";
+for my $i (0 .. $#channels) {
+ my $label = $channels[$i];
+ my $descr = $channel_label_to_descr{$label}
+ or die "Channel $label not found\n";
+ $graph .= "flite=text='${descr}', aformat=channel_layouts=mono, " .
+ "pan=${layout}:${label}=c0 [ch$i] ;\n";
+ $concat_in .= "[ch$i] ";
+}
+$graph .= "${concat_in}concat=v=0:a=1:n=" . scalar(@channels);
+
+exec $ffmpeg, "-f", "lavfi", "-i", $graph, @out_options
+ or die "$ffmpeg: $!\n";
diff --git a/ffmpeg1/tools/missing_codec_desc b/ffmpeg1/tools/missing_codec_desc
new file mode 100755
index 0000000..093d02e
--- /dev/null
+++ b/ffmpeg1/tools/missing_codec_desc
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+srcdir=${0%/*}/..
+
+while read -r field equal value; do
+ case "$field $equal" in
+ ".id =")
+ eval "known_${value%,}=1"
+ ;;
+ esac
+done < $srcdir/libavcodec/codec_desc.c
+
+known_AV_CODEC_ID_NONE=1
+known_AV_CODEC_ID_FIRST_AUDIO=1
+known_AV_CODEC_ID_FIRST_SUBTITLE=1
+known_AV_CODEC_ID_FIRST_UNKNOWN=1
+known_AV_CODEC_ID_TTF=1
+known_AV_CODEC_ID_PROBE=1
+known_AV_CODEC_ID_MPEG2TS=1
+known_AV_CODEC_ID_MPEG4SYSTEMS=1
+known_AV_CODEC_ID_FFMETADATA=1
+
+in=0
+while read -r line; do
+ case "$in-$line" in
+ 0-"enum AVCodecID"*) in=1;;
+ 1-*"};"*) in=0;;
+ 1-*AV_CODEC_ID_*,*)
+ cid="${line%%[, =]*}"
+ eval "known=\$known_$cid"
+ case "$known" in
+ 1) ;;
+ *) echo "$cid missing";;
+ esac
+ ;;
+ esac
+done < $srcdir/libavcodec/avcodec.h
diff --git a/ffmpeg1/tools/patcheck b/ffmpeg1/tools/patcheck
new file mode 100755
index 0000000..83db4c0
--- /dev/null
+++ b/ffmpeg1/tools/patcheck
@@ -0,0 +1,180 @@
+#!/bin/sh
+
+# if no argument provided, write stdin to a file and re-run the script
+if [ $# = 0 ]; then
+ cat > patcheck.stdout
+ $0 patcheck.stdout
+ rm -f patcheck.stdout
+ exit
+fi
+
+GREP=grep
+EGREP=egrep
+TMP=patcheck.tmp
+OPT="-nH"
+#FILES=$($GREP '^+++' $* | sed 's/+++ //g')
+
+echo patCHeck 1e10.0
+echo This tool is intended to help a human check/review patches. It is very far from
+echo being free of false positives and negatives, and its output are just hints of what
+echo may or may not be bad. When you use it and it misses something or detects
+echo something wrong, fix it and send a patch to the ffmpeg-devel mailing list.
+echo License: GPL, Author: Michael Niedermayer
+
+ERE_PRITYP='(unsigned *|)(char|short|long|int|long *int|short *int|void|float|double|(u|)int(8|16|32|64)_t)'
+ERE_TYPES='(const|static|av_cold|inline| *)*('$ERE_PRITYP'|[a-zA-Z][a-zA-Z0-9_]*)[* ]{1,}[a-zA-Z][a-zA-Z0-9_]*'
+ERE_FUNCS="$ERE_TYPES"' *\('
+
+hiegrep(){
+ arg="$1"
+ msg="$2"
+ shift 2
+ $GREP $OPT '^+' $* | $GREP -v ':+++'| $EGREP --color=always -- "$arg"> $TMP && printf "\n$msg\n"
+ cat $TMP
+}
+
+hiegrep2(){
+ arg="$1"
+ varg="$2"
+ msg="$3"
+ shift 3
+ $GREP $OPT '^+' $* | $GREP -v ':+++' | $EGREP -v -- "$varg" | $EGREP --color=always -- "$arg" > $TMP && printf "\n$msg\n"
+ cat $TMP
+}
+
+hiegrep '[[:space:]]$' 'trailing whitespace' $*
+hiegrep "$(echo x | tr 'x' '\t')" 'tabs' $*
+#hiegrep ':\+$' 'Empty lines' $*
+hiegrep ';;' 'double ;' $*
+hiegrep2 '\b_[a-zA-Z0-9_]{1,}' '__(asm|attribute)([^a-zA-Z0-9]|$)' 'reserved identifer' $*
+hiegrep '//[-/<\* ]*$' 'empty comment' $*
+hiegrep '/\*[-<\* ]*\*/' 'empty comment' $*
+hiegrep 'for *\( *'"$ERE_PRITYP"' ' 'not gcc 2.95 compatible' $*
+hiegrep '(static|inline|const) *\1' 'duplicate word' $*
+hiegrep 'INIT_VLC_USE_STATIC' 'forbidden ancient vlc type' $*
+hiegrep '=[-+\*\&] ' 'looks like compound assignment' $*
+hiegrep2 '/\*\* *[a-zA-Z0-9].*' '\*/' 'Inconsistently formatted doxygen comment' $*
+hiegrep '; */\*\*[^<]' 'Misformatted doxygen comment' $*
+hiegrep '//!|/\*!' 'inconsistent doxygen syntax' $*
+
+hiegrep2 '(int|unsigned|static|void)[a-zA-Z0-9 _]*(init|end)[a-zA-Z0-9 _]*\(.*[^;]$' '(av_cold|:\+[^a-zA-Z_])' 'These functions may need av_cold, please review the whole patch for similar functions needing av_cold' $*
+
+hiegrep '\+= *1 *;' 'can be simplified to ++' $*
+hiegrep '-= *1 *;' 'can be simplified to --' $*
+hiegrep '((!|=)= *(0|NULL)[^0-9a-z]|[^0-9a-z](0|NULL) *(!|=)=)' 'x==0 / x!=0 can be simplified to !x / x' $*
+
+$EGREP $OPT '^\+ *(const *|)static' $*| $EGREP --color=always '[^=]= *(0|NULL)[^0-9a-zA-Z]'> $TMP && printf '\nuseless 0 init\n'
+cat $TMP
+hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $*
+
+hiegrep '\b(awnser|cant|dont|wont|usefull|successfull|occured|teh|alot|wether|skiped|skiping|heigth|informations|colums|loosy|loosing|ouput|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention|acheive|funtions|overriden|outputing|seperation|initalize|compatibilty|bistream|knwon|unknwon)\b' 'common typos' $*
+
+hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
+hiegrep '[^sn]printf' 'Please use av_log' $*
+hiegrep '\bmalloc' 'Please use av_malloc' $*
+hiegrep '\) *av_malloc' 'useless casts' $*
+hiegrep ':\+ *'"$ERE_PRITYP"' *inline' 'non static inline or strangely ordered inline+static' $*
+hiegrep "$ERE_FUNCS"' *\)' 'missing void' $*
+hiegrep '(sprintf|strcat|strcpy)' 'Possible security issue, make sure this is safe or use snprintf/av_strl*' $*
+hiegrep '/ *(2|4|8|16|32|64|128|256|512|1024|2048|4096|8192|16384|32768|65536)[^0-9]' 'divide by 2^x could use >> maybe' $*
+hiegrep '#(el|)if *(0|1)' 'useless #if' $*
+hiegrep 'if *\( *(0|1) *\)' 'useless if()' $*
+hiegrep '& *[a-zA-Z0-9_]* *\[ *0 *\]' 'useless & [0]' $*
+hiegrep '(\( *[0-9] *(&&|\|\|)|(&&|\|\|) *[0-9] *\))' 'overriding condition' $*
+hiegrep '(:\+|,|;)( *|static|\*)*'"$ERE_PRITYP"' *\*( |\*)*(src|source|input|in[^a-z])' 'missing const?' $*
+hiegrep '(:\+|,|;)( *|static|\*)*'"$ERE_PRITYP"' *(src|source|input|in)([0-9A-Z_][0-9A-Za-z_]*){1,} *\[' 'missing const (test2)?' $*
+hiegrep ' *static *'"$ERE_FUNCS"'[^)]*\);' 'static prototype, maybe you should reorder your functions' $*
+hiegrep '@file: *[a-zA-Z0-9_]' 'doxy filetag with filename can in the future cause problems when forgotten during a rename' $*
+hiegrep '\bassert' 'Please use av_assert0, av_assert1 or av_assert2' $*
+
+hiegrep2 '\.long_name *=' 'NULL_IF_CONFIG_SMAL' 'missing NULL_IF_CONFIG_SMAL' $*
+hiegrep2 '\.pix_fmts *= *\(' 'const' 'missing const for pix_fmts array' $*
+hiegrep2 '\.sample_fmts *= *\(' 'const' 'missing const for sample_fmts array' $*
+hiegrep2 '\.supported_framerates *= *\(' 'const' 'missing const for supported_framerates array' $*
+hiegrep2 '\.channel_layouts *= *\(' 'const' 'missing const for channel_layouts array' $*
+
+#$EGREP $OPT '^\+.*const ' $*| $GREP -v 'static'> $TMP && printf '\nnon static const\n'
+#cat $TMP
+
+hiegrep2 "$ERE_TYPES" '(static|av_|ff_|typedef|:\+[^a-zA-Z_])' 'Non static with no ff_/av_ prefix' $*
+
+hiegrep ':\+[^}#]*else' 'missing } prior to else' $*
+hiegrep '(if|while|for)\(' 'missing whitespace between keyword and ( (feel free to ignore)' $*
+hiegrep '(else|do){' 'missing whitespace between keyword and { (feel free to ignore)' $*
+hiegrep '}(else|while)' 'missing whitespace between } and keyword (feel free to ignore)' $*
+
+#FIXME this should print the previous statement maybe
+hiegrep ':\+ *{ *$' '{ should be on the same line as the related previous statement' $*
+
+
+rm $TMP
+for i in $($GREP -H '^+.*@param' $*| sed 's/^\([^:]*\):.*@param\(\[.*\]\|\) *\([a-zA-Z0-9_]*\) .*$/\1:\3/') ; do
+ doxpar=$(echo $i | sed 's/^.*:\(.*\)$/\1/')
+ file=$(echo $i | sed 's/^\([^:]*\):.*$/\1/')
+ $GREP " *$doxpar *[),]" $file | $GREP -v '@param' >/dev/null || $GREP --color=always "@param *$doxpar" $file >>$TMP
+done
+if test -e $TMP ; then
+ printf '\nmismatching doxy params\n'
+ cat $TMP
+fi
+
+$EGREP -B2 $OPT '^(\+|) *('"$ERE_TYPES"'|# *define)' $* | $EGREP -A2 --color=always '(:|-)\+[^/]*/(\*([^*]|$)|/([^/]|$))' > $TMP && printf "\n Non doxy comments\n"
+cat $TMP
+
+rm $TMP
+for i in \
+ $($EGREP -H '^\+ *'"$ERE_TYPES" $* |\
+ $GREP -v '(' | $EGREP -v '\Wgoto\W' |\
+ xargs -d '\n' -n 1 |\
+ $GREP -o '[* ][* ]*[a-zA-Z][0-9a-zA-Z_]* *[,;=]' |\
+ sed 's/.[* ]*\([a-zA-Z][0-9a-zA-Z_]*\) *[,;=]/\1/') \
+ ; do
+ echo $i | $GREP '^NULL$' && continue
+ $EGREP $i' *(\+|-|\*|/|\||&|%|)=[^=]' $* >/dev/null || echo "possibly never written:"$i >> $TMP
+ $EGREP '(=|\(|return).*'$i'(==|[^=])*$' $* >/dev/null || echo "possibly never read :"$i >> $TMP
+ $EGREP -o $i' *((\+|-|\*|/|\||&|%|)=[^=]|\+\+|--) *(0x|)[0-9]*(;|)' $* |\
+ $EGREP -v $i' *= *(0x|)[0-9]{1,};'>/dev/null || echo "possibly constant :"$i >> $TMP
+done
+if test -e $TMP ; then
+ printf '\npossibly unused variables\n'
+ cat $TMP
+fi
+
+$GREP '^+++ .*Changelog' $* >/dev/null || printf "\nMissing changelog entry (ignore if minor change)\n"
+
+cat $* | tr '\n' '@' | $EGREP --color=always -o '(fprintf|av_log|printf)\([^)]*\)[+ ;@]*\1' >$TMP && printf "\nMergeable calls\n"
+cat $TMP | tr '@' '\n'
+
+cat $* | tr '\n' '@' | $EGREP --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *[<>]=? *[0-9]* *\) * \1 *= *[0-9]* *;[ @\\+]*else *if *\( *\1 *[<>]=? *[0-9]* *\) *\1 *= *[0-9]* *;' >$TMP && printf "\nav_clip / av_clip_uint8 / av_clip_int16 / ...\n"
+cat $TMP | tr '@' '\n'
+
+cat $* | tr '\n' '@' | $EGREP --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *[<>]=? *([A-Za-z0-9_]*) *\)[ @\\+]*(\1|\2) *= *(\1|\2) *;' >$TMP && printf "\nFFMIN/FFMAX\n"
+cat $TMP | tr '@' '\n'
+
+cat $* | tr '\n' '@' | $EGREP --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *\)[ @\\+]*av_free(p|) *\( *(&|) *\1[^-.]' >$TMP && printf "\nav_free(NULL) is safe\n"
+cat $TMP | tr '@' '\n'
+
+cat $* | tr '\n' '@' | $EGREP --color=always -o '[^a-zA-Z0-9_]([a-zA-Z0-9_]*) *= *av_malloc *\([^)]*\)[ @;\\+]*memset *\( *\1' >$TMP && printf "\nav_mallocz()\n"
+cat $TMP | tr '@' '\n'
+
+
+# does not work
+#cat $* | tr '\n' '@' | $EGREP -o '[^a-zA-Z_0-9]([a-zA-Z][a-zA-Z_0-9]*) *=[^=].*\1' | $EGREP -o '[^a-zA-Z_0-9]([a-zA-Z][a-zA-Z_0-9]*) *=[^=].*\1 *=[^=]' >$TMP && printf "\nPossibly written 2x before read\n"
+#cat $TMP | tr '@' '\n'
+
+exit
+
+TODO/idea list:
+
+for all demuxers & muxers
+ $EGREP for "avctx->priv_data"
+
+vertical align =
+/* and * align
+arrays fitting in smaller types
+variables written to twice with no interspaced read
+memset(block, 0, 6*64*sizeof(int16_t)); -> clear_blocks
+check existence of long_name in AVCodec
+check that the patch does not touch codec & (de)muxer layer at the same time ->split
+
+write a regression test containing at least a line that triggers each warning once
diff --git a/ffmpeg1/tools/pktdumper.c b/ffmpeg1/tools/pktdumper.c
new file mode 100644
index 0000000..920397b
--- /dev/null
+++ b/ffmpeg1/tools/pktdumper.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2005 Francois Revol
+ *
+ * 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 <limits.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+
+#define FILENAME_BUF_SIZE 4096
+
+#include "libavutil/avstring.h"
+#include "libavutil/time.h"
+#include "libavformat/avformat.h"
+
+#define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin"
+
+static int usage(int ret)
+{
+ fprintf(stderr, "dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n");
+ fprintf(stderr, "each packet is dumped in its own file named like `basename file.ext`_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n");
+ fprintf(stderr, "pktdumper [-nw] file [maxpkts]\n");
+ fprintf(stderr, "-n\twrite No file at all, only demux.\n");
+ fprintf(stderr, "-w\tWait at end of processing instead of quitting.\n");
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
+ char fntemplate[FILENAME_BUF_SIZE];
+ char pktfilename[FILENAME_BUF_SIZE];
+ AVFormatContext *fctx = NULL;
+ AVPacket pkt;
+ int64_t pktnum = 0;
+ int64_t maxpkts = 0;
+ int donotquit = 0;
+ int nowrite = 0;
+ int err;
+
+ if ((argc > 1) && !strncmp(argv[1], "-", 1)) {
+ if (strchr(argv[1], 'w'))
+ donotquit = 1;
+ if (strchr(argv[1], 'n'))
+ nowrite = 1;
+ argv++;
+ argc--;
+ }
+ if (argc < 2)
+ return usage(1);
+ if (argc > 2)
+ maxpkts = atoi(argv[2]);
+ av_strlcpy(fntemplate, argv[1], sizeof(fntemplate));
+ if (strrchr(argv[1], '/'))
+ av_strlcpy(fntemplate, strrchr(argv[1], '/') + 1, sizeof(fntemplate));
+ if (strrchr(fntemplate, '.'))
+ *strrchr(fntemplate, '.') = '\0';
+ if (strchr(fntemplate, '%')) {
+ fprintf(stderr, "can't use filenames containing '%%'\n");
+ return usage(1);
+ }
+ if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= sizeof(fntemplate) - 1) {
+ fprintf(stderr, "filename too long\n");
+ return usage(1);
+ }
+ strcat(fntemplate, PKTFILESUFF);
+ printf("FNTEMPLATE: '%s'\n", fntemplate);
+
+ // register all file formats
+ av_register_all();
+
+ err = avformat_open_input(&fctx, argv[1], NULL, NULL);
+ if (err < 0) {
+ fprintf(stderr, "cannot open input: error %d\n", err);
+ return 1;
+ }
+
+ err = avformat_find_stream_info(fctx, NULL);
+ if (err < 0) {
+ fprintf(stderr, "avformat_find_stream_info: error %d\n", err);
+ return 1;
+ }
+
+ av_init_packet(&pkt);
+
+ while ((err = av_read_frame(fctx, &pkt)) >= 0) {
+ int fd;
+ snprintf(pktfilename, sizeof(pktfilename), fntemplate, pktnum,
+ pkt.stream_index, pkt.pts, pkt.size,
+ (pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_');
+ printf(PKTFILESUFF "\n", pktnum, pkt.stream_index, pkt.pts, pkt.size,
+ (pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_');
+ if (!nowrite) {
+ fd = open(pktfilename, O_WRONLY | O_CREAT, 0644);
+ err = write(fd, pkt.data, pkt.size);
+ if (err < 0) {
+ fprintf(stderr, "write: error %d\n", err);
+ return 1;
+ }
+ close(fd);
+ }
+ av_free_packet(&pkt);
+ pktnum++;
+ if (maxpkts && (pktnum >= maxpkts))
+ break;
+ }
+
+ avformat_close_input(&fctx);
+
+ while (donotquit)
+ av_usleep(60 * 1000000);
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/plotframes b/ffmpeg1/tools/plotframes
new file mode 100755
index 0000000..f379723
--- /dev/null
+++ b/ffmpeg1/tools/plotframes
@@ -0,0 +1,164 @@
+#!/usr/bin/env perl
+
+# Copyright (c) 2007-2013 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
+
+=head1 NAME
+
+plotframes - Plot video frame sizes using ffprobe and gnuplot
+
+=head1 SYNOPSIS
+
+plotframes [I<options>] [I<input>]
+
+=head1 DESCRIPTION
+
+plotframes reads a multimedia files with ffprobe, and plots the
+collected video sizes with gnuplot.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--input|-i> I<infile>
+
+Specify multimedia file to read. This is the file passed to the
+ffprobe command. If not specified it is the first argument passed to
+the script.
+
+=item B<--help|--usage|-h|-?>
+
+Print a brief help message and exit.
+
+=item B<--manpage|-m>
+
+Print the man page.
+
+=item B<--output|-o> I<outfile>
+
+Set the name of the output used by gnuplot. If not specified no output
+is created. Must be used in conjunction with the B<terminal> option.
+
+=item B<--stream|--s> I<stream_specifier>
+
+Specify stream. The value must be a string containing a stream
+specifier. Default value is "v".
+
+=item B<--terminal|-t> I<terminal>
+
+Set the name of the terminal used by gnuplot. By default it is
+"x11". Must be used in conjunction with the B<output> option. Check
+the gnuplot manual for the valid values.
+
+=back
+
+=cut
+
+=head1 SEE ALSO
+
+ffprobe(1), gnuplot(1)
+
+=cut
+
+use warnings;
+use strict;
+
+use File::Temp;
+use JSON -support_by_pp;
+use Getopt::Long;
+use Pod::Usage;
+
+my $input = $ARGV[0];
+my $stream_specifier = "v";
+my $gnuplot_terminal = "x11";
+my $gnuplot_output;
+
+GetOptions (
+ 'input|i=s' => \$input,
+ 'help|usage|?|h' => sub { pod2usage ( { -verbose => 1, -exitval => 0 }) },
+ 'manpage|m' => sub { pod2usage ( { -verbose => 2, -exitval => 0 }) },
+ 'stream|s=s' => \$stream_specifier,
+ 'terminal|t=s' => \$gnuplot_terminal,
+ 'output|o=s' => \$gnuplot_output,
+ ) or pod2usage( { -message=> "Parsing error", -verbose => 1, -exitval => 1 });
+
+die "You must specify an input file\n" unless $input;
+
+# fetch data
+my @cmd = (qw{ffprobe -show_entries frame -select_streams}, $stream_specifier, "-of", "json", $input);
+print STDERR "Executing command: @cmd\n";
+my $json_struct;
+{
+ open(FH, "-|", @cmd) or die "ffprobe command failed: $!\n";
+ local $/;
+ my $json_text = <FH>;
+ close FH;
+ die "ffprobe command failed" if $?;
+ eval { $json_struct = decode_json($json_text); };
+ die "JSON parsing error: $@\n" if $@;
+}
+
+# collect and print frame statistics per pict_type
+my %stats;
+my $frames = $json_struct->{frames};
+my $frame_count = 0;
+foreach my $frame (@{$frames}) {
+ my $type = $frame->{pict_type};
+ $frame->{count} = $frame_count++;
+ if (not $stats{$type}) {
+ $stats{$type}->{tmpfile} = File::Temp->new(SUFFIX => '.dat');
+ my $fn = $stats{$type}->{tmpfile}->filename;
+ open($stats{$type}->{fh}, ">", $fn) or die "Can't open $fn";
+ }
+
+ print { $stats{$type}->{fh} }
+ "$frame->{count} ", $frame->{pkt_size} * 8 / 1000, "\n";
+}
+foreach (keys %stats) { close $stats{$_}->{fh}; }
+
+# write gnuplot script
+my %type_color_map = (
+ "I" => "red",
+ "P" => "green",
+ "B" => "blue"
+ );
+
+my $gnuplot_script_tmpfile = File::Temp->new(SUFFIX => '.gnuplot');
+my $fn = $gnuplot_script_tmpfile->filename;
+open(FH, ">", $fn) or die "Couldn't open $fn: $!";
+print FH << "EOF";
+set title "video frame sizes"
+set xlabel "frame time"
+set ylabel "frame size (Kbits)"
+set grid
+set terminal "$gnuplot_terminal"
+EOF
+
+print FH "set output \"$gnuplot_output\"\n" if $gnuplot_output;
+print FH "plot";
+my $sep = "";
+foreach my $type (keys %stats) {
+ my $fn = $stats{$type}->{tmpfile}->filename;
+ print FH "$sep\"$fn\" title \"$type frames\" with impulses";
+ print FH " linecolor rgb \"$type_color_map{$type}\"" if $type_color_map{$type};
+ $sep = ", ";
+}
+close FH;
+
+# launch gnuplot with the generated script
+system ("gnuplot", "--persist", $gnuplot_script_tmpfile->filename);
diff --git a/ffmpeg1/tools/probetest.c b/ffmpeg1/tools/probetest.c
new file mode 100644
index 0000000..b13c6f9
--- /dev/null
+++ b/ffmpeg1/tools/probetest.c
@@ -0,0 +1,145 @@
+/*
+ * copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 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 <stdlib.h>
+
+#include "libavformat/avformat.h"
+#include "libavcodec/put_bits.h"
+#include "libavutil/lfg.h"
+
+static int score_array[1000]; //this must be larger than the number of formats
+static int failures = 0;
+
+static void probe(AVProbeData *pd, int type, int p, int size)
+{
+ int i = 0;
+ AVInputFormat *fmt = NULL;
+
+ while ((fmt = av_iformat_next(fmt))) {
+ if (fmt->flags & AVFMT_NOFILE)
+ continue;
+ if (fmt->read_probe) {
+ int score = fmt->read_probe(pd);
+ if (score > score_array[i] && score > AVPROBE_SCORE_MAX / 4) {
+ score_array[i] = score;
+ fprintf(stderr,
+ "Failure of %s probing code with score=%d type=%d p=%X size=%d\n",
+ fmt->name, score, type, p, size);
+ failures++;
+ }
+ }
+ i++;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int p, i, type, size, retry;
+ AVProbeData pd;
+ AVLFG state;
+ PutBitContext pb;
+ int retry_count= 4097;
+ int max_size = 65537;
+
+ if(argc >= 2)
+ retry_count = atoi(argv[1]);
+ if(argc >= 3)
+ max_size = atoi(argv[2]);
+
+ if (max_size > 1000000000U/8) {
+ fprintf(stderr, "max_size out of bounds\n");
+ return 1;
+ }
+
+ if (retry_count > 1000000000U) {
+ fprintf(stderr, "retry_count out of bounds\n");
+ return 1;
+ }
+
+ avcodec_register_all();
+ av_register_all();
+
+ av_lfg_init(&state, 0xdeadbeef);
+
+ pd.buf = NULL;
+ for (size = 1; size < max_size; size *= 2) {
+ pd.buf_size = size;
+ pd.buf = av_realloc(pd.buf, size + AVPROBE_PADDING_SIZE);
+ pd.filename = "";
+
+ memset(pd.buf, 0, size + AVPROBE_PADDING_SIZE);
+
+ fprintf(stderr, "testing size=%d\n", size);
+
+ for (retry = 0; retry < retry_count; retry += FFMAX(size, 32)) {
+ for (type = 0; type < 4; type++) {
+ for (p = 0; p < 4096; p++) {
+ unsigned hist = 0;
+ init_put_bits(&pb, pd.buf, size);
+ switch (type) {
+ case 0:
+ for (i = 0; i < size * 8; i++)
+ put_bits(&pb, 1, (av_lfg_get(&state) & 0xFFFFFFFF) > p << 20);
+ break;
+ case 1:
+ for (i = 0; i < size * 8; i++) {
+ unsigned int p2 = hist ? p & 0x3F : (p >> 6);
+ unsigned int v = (av_lfg_get(&state) & 0xFFFFFFFF) > p2 << 26;
+ put_bits(&pb, 1, v);
+ hist = v;
+ }
+ break;
+ case 2:
+ for (i = 0; i < size * 8; i++) {
+ unsigned int p2 = (p >> (hist * 3)) & 7;
+ unsigned int v = (av_lfg_get(&state) & 0xFFFFFFFF) > p2 << 29;
+ put_bits(&pb, 1, v);
+ hist = (2 * hist + v) & 3;
+ }
+ break;
+ case 3:
+ for (i = 0; i < size; i++) {
+ int c = 0;
+ while (p & 63) {
+ c = (av_lfg_get(&state) & 0xFFFFFFFF) >> 24;
+ if (c >= 'a' && c <= 'z' && (p & 1))
+ break;
+ else if (c >= 'A' && c <= 'Z' && (p & 2))
+ break;
+ else if (c >= '0' && c <= '9' && (p & 4))
+ break;
+ else if (c == ' ' && (p & 8))
+ break;
+ else if (c == 0 && (p & 16))
+ break;
+ else if (c == 1 && (p & 32))
+ break;
+ }
+ pd.buf[i] = c;
+ }
+ }
+ flush_put_bits(&pb);
+ probe(&pd, type, p, size);
+ }
+ }
+ }
+ }
+ return failures;
+}
diff --git a/ffmpeg1/tools/qt-faststart.c b/ffmpeg1/tools/qt-faststart.c
new file mode 100644
index 0000000..c9aa6e8
--- /dev/null
+++ b/ffmpeg1/tools/qt-faststart.c
@@ -0,0 +1,356 @@
+/*
+ * qt-faststart.c, v0.2
+ * by Mike Melanson (melanson@pcisys.net)
+ * This file is placed in the public domain. Use the program however you
+ * see fit.
+ *
+ * This utility rearranges a Quicktime file such that the moov atom
+ * is in front of the data, thus facilitating network streaming.
+ *
+ * To compile this program, start from the base directory from which you
+ * are building FFmpeg and type:
+ * make tools/qt-faststart
+ * The qt-faststart program will be built in the tools/ directory. If you
+ * do not build the program in this manner, correct results are not
+ * guaranteed, particularly on 64-bit platforms.
+ * Invoke the program with:
+ * qt-faststart <infile.mov> <outfile.mov>
+ *
+ * Notes: Quicktime files can come in many configurations of top-level
+ * atoms. This utility stipulates that the very last atom in the file needs
+ * to be a moov atom. When given such a file, this utility will rearrange
+ * the top-level atoms by shifting the moov atom from the back of the file
+ * to the front, and patch the chunk offsets along the way. This utility
+ * presently only operates on uncompressed moov atoms.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+
+#ifdef __MINGW32__
+#define fseeko(x, y, z) fseeko64(x, y, z)
+#define ftello(x) ftello64(x)
+#elif defined(_WIN32)
+#define fseeko(x, y, z) _fseeki64(x, y, z)
+#define ftello(x) _ftelli64(x)
+#endif
+
+#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
+
+#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
+
+#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
+ (((uint8_t*)(x))[1] << 16) | \
+ (((uint8_t*)(x))[2] << 8) | \
+ ((uint8_t*)(x))[3])
+
+#define BE_64(x) (((uint64_t)(((uint8_t*)(x))[0]) << 56) | \
+ ((uint64_t)(((uint8_t*)(x))[1]) << 48) | \
+ ((uint64_t)(((uint8_t*)(x))[2]) << 40) | \
+ ((uint64_t)(((uint8_t*)(x))[3]) << 32) | \
+ ((uint64_t)(((uint8_t*)(x))[4]) << 24) | \
+ ((uint64_t)(((uint8_t*)(x))[5]) << 16) | \
+ ((uint64_t)(((uint8_t*)(x))[6]) << 8) | \
+ ((uint64_t)( (uint8_t*)(x))[7]))
+
+#define BE_FOURCC(ch0, ch1, ch2, ch3) \
+ ( (uint32_t)(unsigned char)(ch3) | \
+ ((uint32_t)(unsigned char)(ch2) << 8) | \
+ ((uint32_t)(unsigned char)(ch1) << 16) | \
+ ((uint32_t)(unsigned char)(ch0) << 24) )
+
+#define QT_ATOM BE_FOURCC
+/* top level atoms */
+#define FREE_ATOM QT_ATOM('f', 'r', 'e', 'e')
+#define JUNK_ATOM QT_ATOM('j', 'u', 'n', 'k')
+#define MDAT_ATOM QT_ATOM('m', 'd', 'a', 't')
+#define MOOV_ATOM QT_ATOM('m', 'o', 'o', 'v')
+#define PNOT_ATOM QT_ATOM('p', 'n', 'o', 't')
+#define SKIP_ATOM QT_ATOM('s', 'k', 'i', 'p')
+#define WIDE_ATOM QT_ATOM('w', 'i', 'd', 'e')
+#define PICT_ATOM QT_ATOM('P', 'I', 'C', 'T')
+#define FTYP_ATOM QT_ATOM('f', 't', 'y', 'p')
+#define UUID_ATOM QT_ATOM('u', 'u', 'i', 'd')
+
+#define CMOV_ATOM QT_ATOM('c', 'm', 'o', 'v')
+#define STCO_ATOM QT_ATOM('s', 't', 'c', 'o')
+#define CO64_ATOM QT_ATOM('c', 'o', '6', '4')
+
+#define ATOM_PREAMBLE_SIZE 8
+#define COPY_BUFFER_SIZE 33554432
+
+int main(int argc, char *argv[])
+{
+ FILE *infile = NULL;
+ FILE *outfile = NULL;
+ unsigned char atom_bytes[ATOM_PREAMBLE_SIZE];
+ uint32_t atom_type = 0;
+ uint64_t atom_size = 0;
+ uint64_t atom_offset = 0;
+ uint64_t last_offset;
+ unsigned char *moov_atom = NULL;
+ unsigned char *ftyp_atom = NULL;
+ uint64_t moov_atom_size;
+ uint64_t ftyp_atom_size = 0;
+ uint64_t i, j;
+ uint32_t offset_count;
+ uint64_t current_offset;
+ int64_t start_offset = 0;
+ unsigned char *copy_buffer = NULL;
+ int bytes_to_copy;
+
+ if (argc != 3) {
+ printf("Usage: qt-faststart <infile.mov> <outfile.mov>\n");
+ return 0;
+ }
+
+ if (!strcmp(argv[1], argv[2])) {
+ fprintf(stderr, "input and output files need to be different\n");
+ return 1;
+ }
+
+ infile = fopen(argv[1], "rb");
+ if (!infile) {
+ perror(argv[1]);
+ goto error_out;
+ }
+
+ /* traverse through the atoms in the file to make sure that 'moov' is
+ * at the end */
+ while (!feof(infile)) {
+ if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
+ break;
+ }
+ atom_size = (uint32_t) BE_32(&atom_bytes[0]);
+ atom_type = BE_32(&atom_bytes[4]);
+
+ /* keep ftyp atom */
+ if (atom_type == FTYP_ATOM) {
+ ftyp_atom_size = atom_size;
+ free(ftyp_atom);
+ ftyp_atom = malloc(ftyp_atom_size);
+ if (!ftyp_atom) {
+ printf("could not allocate %"PRIu64" bytes for ftyp atom\n",
+ atom_size);
+ goto error_out;
+ }
+ if ( fseeko(infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR)
+ || fread(ftyp_atom, atom_size, 1, infile) != 1
+ || (start_offset = ftello(infile))<0) {
+ perror(argv[1]);
+ goto error_out;
+ }
+ } else {
+ int ret;
+ /* 64-bit special case */
+ if (atom_size == 1) {
+ if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
+ break;
+ }
+ atom_size = BE_64(&atom_bytes[0]);
+ ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
+ } else {
+ ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
+ }
+ if(ret) {
+ perror(argv[1]);
+ goto error_out;
+ }
+ }
+ printf("%c%c%c%c %10"PRIu64" %"PRIu64"\n",
+ (atom_type >> 24) & 255,
+ (atom_type >> 16) & 255,
+ (atom_type >> 8) & 255,
+ (atom_type >> 0) & 255,
+ atom_offset,
+ atom_size);
+ if ((atom_type != FREE_ATOM) &&
+ (atom_type != JUNK_ATOM) &&
+ (atom_type != MDAT_ATOM) &&
+ (atom_type != MOOV_ATOM) &&
+ (atom_type != PNOT_ATOM) &&
+ (atom_type != SKIP_ATOM) &&
+ (atom_type != WIDE_ATOM) &&
+ (atom_type != PICT_ATOM) &&
+ (atom_type != UUID_ATOM) &&
+ (atom_type != FTYP_ATOM)) {
+ printf("encountered non-QT top-level atom (is this a QuickTime file?)\n");
+ break;
+ }
+ atom_offset += atom_size;
+
+ /* The atom header is 8 (or 16 bytes), if the atom size (which
+ * includes these 8 or 16 bytes) is less than that, we won't be
+ * able to continue scanning sensibly after this atom, so break. */
+ if (atom_size < 8)
+ break;
+ }
+
+ if (atom_type != MOOV_ATOM) {
+ printf("last atom in file was not a moov atom\n");
+ free(ftyp_atom);
+ fclose(infile);
+ return 0;
+ }
+
+ /* moov atom was, in fact, the last atom in the chunk; load the whole
+ * moov atom */
+ if (fseeko(infile, -atom_size, SEEK_END)) {
+ perror(argv[1]);
+ goto error_out;
+ }
+ last_offset = ftello(infile);
+ moov_atom_size = atom_size;
+ moov_atom = malloc(moov_atom_size);
+ if (!moov_atom) {
+ printf("could not allocate %"PRIu64" bytes for moov atom\n", atom_size);
+ goto error_out;
+ }
+ if (fread(moov_atom, atom_size, 1, infile) != 1) {
+ perror(argv[1]);
+ goto error_out;
+ }
+
+ /* this utility does not support compressed atoms yet, so disqualify
+ * files with compressed QT atoms */
+ if (BE_32(&moov_atom[12]) == CMOV_ATOM) {
+ printf("this utility does not support compressed moov atoms yet\n");
+ goto error_out;
+ }
+
+ /* close; will be re-opened later */
+ fclose(infile);
+ infile = NULL;
+
+ /* crawl through the moov chunk in search of stco or co64 atoms */
+ for (i = 4; i < moov_atom_size - 4; i++) {
+ atom_type = BE_32(&moov_atom[i]);
+ if (atom_type == STCO_ATOM) {
+ printf(" patching stco atom...\n");
+ atom_size = BE_32(&moov_atom[i - 4]);
+ if (i + atom_size - 4 > moov_atom_size) {
+ printf(" bad atom size\n");
+ goto error_out;
+ }
+ offset_count = BE_32(&moov_atom[i + 8]);
+ if (i + 12LL + offset_count * 4LL > moov_atom_size) {
+ printf(" bad atom size\n");
+ goto error_out;
+ }
+ for (j = 0; j < offset_count; j++) {
+ current_offset = BE_32(&moov_atom[i + 12 + j * 4]);
+ current_offset += moov_atom_size;
+ moov_atom[i + 12 + j * 4 + 0] = (current_offset >> 24) & 0xFF;
+ moov_atom[i + 12 + j * 4 + 1] = (current_offset >> 16) & 0xFF;
+ moov_atom[i + 12 + j * 4 + 2] = (current_offset >> 8) & 0xFF;
+ moov_atom[i + 12 + j * 4 + 3] = (current_offset >> 0) & 0xFF;
+ }
+ i += atom_size - 4;
+ } else if (atom_type == CO64_ATOM) {
+ printf(" patching co64 atom...\n");
+ atom_size = BE_32(&moov_atom[i - 4]);
+ if (i + atom_size - 4 > moov_atom_size) {
+ printf(" bad atom size\n");
+ goto error_out;
+ }
+ offset_count = BE_32(&moov_atom[i + 8]);
+ if (i + 12LL + offset_count * 8LL > moov_atom_size) {
+ printf(" bad atom size\n");
+ goto error_out;
+ }
+ for (j = 0; j < offset_count; j++) {
+ current_offset = BE_64(&moov_atom[i + 12 + j * 8]);
+ current_offset += moov_atom_size;
+ moov_atom[i + 12 + j * 8 + 0] = (current_offset >> 56) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 1] = (current_offset >> 48) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 2] = (current_offset >> 40) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 3] = (current_offset >> 32) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 4] = (current_offset >> 24) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 5] = (current_offset >> 16) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 6] = (current_offset >> 8) & 0xFF;
+ moov_atom[i + 12 + j * 8 + 7] = (current_offset >> 0) & 0xFF;
+ }
+ i += atom_size - 4;
+ }
+ }
+
+ /* re-open the input file and open the output file */
+ infile = fopen(argv[1], "rb");
+ if (!infile) {
+ perror(argv[1]);
+ goto error_out;
+ }
+
+ if (start_offset > 0) { /* seek after ftyp atom */
+ if (fseeko(infile, start_offset, SEEK_SET)) {
+ perror(argv[1]);
+ goto error_out;
+ }
+
+ last_offset -= start_offset;
+ }
+
+ outfile = fopen(argv[2], "wb");
+ if (!outfile) {
+ perror(argv[2]);
+ goto error_out;
+ }
+
+ /* dump the same ftyp atom */
+ if (ftyp_atom_size > 0) {
+ printf(" writing ftyp atom...\n");
+ if (fwrite(ftyp_atom, ftyp_atom_size, 1, outfile) != 1) {
+ perror(argv[2]);
+ goto error_out;
+ }
+ }
+
+ /* dump the new moov atom */
+ printf(" writing moov atom...\n");
+ if (fwrite(moov_atom, moov_atom_size, 1, outfile) != 1) {
+ perror(argv[2]);
+ goto error_out;
+ }
+
+ /* copy the remainder of the infile, from offset 0 -> last_offset - 1 */
+ bytes_to_copy = FFMIN(COPY_BUFFER_SIZE, last_offset);
+ copy_buffer = malloc(bytes_to_copy);
+ if (!copy_buffer) {
+ printf("could not allocate %d bytes for copy_buffer\n", bytes_to_copy);
+ goto error_out;
+ }
+ printf(" copying rest of file...\n");
+ while (last_offset) {
+ bytes_to_copy = FFMIN(bytes_to_copy, last_offset);
+
+ if (fread(copy_buffer, bytes_to_copy, 1, infile) != 1) {
+ perror(argv[1]);
+ goto error_out;
+ }
+ if (fwrite(copy_buffer, bytes_to_copy, 1, outfile) != 1) {
+ perror(argv[2]);
+ goto error_out;
+ }
+ last_offset -= bytes_to_copy;
+ }
+
+ fclose(infile);
+ fclose(outfile);
+ free(moov_atom);
+ free(ftyp_atom);
+ free(copy_buffer);
+
+ return 0;
+
+error_out:
+ if (infile)
+ fclose(infile);
+ if (outfile)
+ fclose(outfile);
+ free(moov_atom);
+ free(ftyp_atom);
+ free(copy_buffer);
+ return 1;
+}
diff --git a/ffmpeg1/tools/seek_print.c b/ffmpeg1/tools/seek_print.c
new file mode 100644
index 0000000..a99a0ad
--- /dev/null
+++ b/ffmpeg1/tools/seek_print.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013 Nicolas George
+ *
+ * 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 <unistd.h>
+
+#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h> /* getopt */
+#endif
+
+#include "libavformat/avformat.h"
+#include "libavutil/timestamp.h"
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+static void usage(int ret)
+{
+ fprintf(ret ? stderr : stdout,
+ "Usage: seek_print file [command ...]\n"
+ "Commands:\n"
+ " read\n"
+ " seek:stream:min_ts:ts:max_ts:flags\n"
+ );
+ exit(ret);
+}
+
+int main(int argc, char **argv)
+{
+ int opt, ret, stream, flags;
+ const char *filename;
+ AVFormatContext *avf = NULL;
+ int64_t min_ts, max_ts, ts;
+ AVPacket packet;
+
+ while ((opt = getopt(argc, argv, "h")) != -1) {
+ switch (opt) {
+ case 'h':
+ usage(0);
+ default:
+ usage(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (!argc)
+ usage(1);
+ filename = *argv;
+ argv++;
+ argc--;
+
+ av_register_all();
+ if ((ret = avformat_open_input(&avf, filename, NULL, NULL)) < 0) {
+ fprintf(stderr, "%s: %s\n", filename, av_err2str(ret));
+ return 1;
+ }
+ if ((ret = avformat_find_stream_info(avf, NULL)) < 0) {
+ fprintf(stderr, "%s: could not find codec parameters: %s\n", filename,
+ av_err2str(ret));
+ return 1;
+ }
+
+ for (; argc; argc--, argv++) {
+ if (!strcmp(*argv, "read")) {
+ ret = av_read_frame(avf, &packet);
+ if (ret < 0) {
+ printf("read: %d (%s)\n", ret, av_err2str(ret));
+ } else {
+ AVRational *tb = &avf->streams[packet.stream_index]->time_base;
+ printf("read: %d size=%d stream=%d dts=%s (%s) pts=%s (%s)\n",
+ ret, packet.size, packet.stream_index,
+ av_ts2str(packet.dts), av_ts2timestr(packet.dts, tb),
+ av_ts2str(packet.pts), av_ts2timestr(packet.pts, tb));
+ av_free_packet(&packet);
+ }
+ } else if (sscanf(*argv, "seek:%i:%"PRIi64":%"PRIi64":%"PRIi64":%i",
+ &stream, &min_ts, &ts, &max_ts, &flags) == 5) {
+ ret = avformat_seek_file(avf, stream, min_ts, ts, max_ts, flags);
+ printf("seek: %d (%s)\n", ret, av_err2str(ret));
+ } else {
+ fprintf(stderr, "'%s': unknown command\n", *argv);
+ return 1;
+ }
+ }
+
+ avformat_close_input(&avf);
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/trasher.c b/ffmpeg1/tools/trasher.c
new file mode 100644
index 0000000..aaa09f4
--- /dev/null
+++ b/ffmpeg1/tools/trasher.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007 Michael Niedermayer
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+
+static uint32_t state;
+static uint32_t ran(void)
+{
+ return state = state * 1664525 + 1013904223;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *f;
+ int count, maxburst, length;
+
+ if (argc < 5) {
+ printf("USAGE: trasher <filename> <count> <maxburst> <seed>\n");
+ return 1;
+ }
+
+ f = fopen(argv[1], "rb+");
+ if (!f) {
+ perror(argv[1]);
+ return 2;
+ }
+ count = atoi(argv[2]);
+ maxburst = atoi(argv[3]);
+ state = atoi(argv[4]);
+
+ fseek(f, 0, SEEK_END);
+ length = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ while (count--) {
+ int burst = 1 + ran() * (uint64_t) (abs(maxburst) - 1) / UINT32_MAX;
+ int pos = ran() * (uint64_t) length / UINT32_MAX;
+ if (fseek(f, pos, SEEK_SET) < 0) {
+ fprintf(stderr, "seek failed\n");
+ return 1;
+ }
+
+ if (maxburst < 0)
+ burst = -maxburst;
+
+ if (pos + burst > length)
+ continue;
+
+ while (burst--) {
+ int val = ran() * 256ULL / UINT32_MAX;
+
+ if (maxburst < 0)
+ val = 0;
+
+ fwrite(&val, 1, 1, f);
+ }
+ }
+
+ return 0;
+}
diff --git a/ffmpeg1/tools/unwrap-diff b/ffmpeg1/tools/unwrap-diff
new file mode 100755
index 0000000..ccea99b
--- /dev/null
+++ b/ffmpeg1/tools/unwrap-diff
@@ -0,0 +1,2 @@
+#!/bin/sh
+tr '\n' '\001' | sed 's/\x01\x01/\x01 \x01/g' | sed 's/\x01\([^-+ @]\)/ \1/g' | tr '\001' '\n'
diff --git a/ffmpeg1/tools/yuvcmp.c b/ffmpeg1/tools/yuvcmp.c
new file mode 100644
index 0000000..11585f9
--- /dev/null
+++ b/ffmpeg1/tools/yuvcmp.c
@@ -0,0 +1,182 @@
+/*
+ * originally by Andreas Ă–man (andoma)
+ * some changes by Alexander Strange
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+int
+main(int argc, char **argv)
+{
+ int fd[2];
+ int print_pixels = 0;
+ int dump_blocks = 0;
+
+ int width;
+ int height;
+ int to_skip = 0;
+
+ if (argc < 6) {
+ fprintf(stderr, "%s [YUV file 1] [YUV file 2] width height pixelcmp|blockdump (# to skip)\n", argv[0]);
+ return 1;
+ }
+
+ width = atoi(argv[3]);
+ height = atoi(argv[4]);
+ if (argc > 6)
+ to_skip = atoi(argv[6]);
+
+ uint8_t *Y[2], *C[2][2];
+ int i, v, c, p;
+ int lsiz = width * height;
+ int csiz = width * height / 4;
+ int x, y;
+ int cwidth = width / 2;
+ int fr = to_skip;
+ int mb;
+ char *mberrors;
+ int mb_x, mb_y;
+ uint8_t *a;
+ uint8_t *b;
+ int die = 0;
+
+ print_pixels = strstr(argv[5], "pixelcmp") ? 1 : 0;
+ dump_blocks = strstr(argv[5], "blockdump") ? 1 : 0;
+
+ for(i = 0; i < 2; i++) {
+ Y[i] = malloc(lsiz);
+ C[0][i] = malloc(csiz);
+ C[1][i] = malloc(csiz);
+
+ fd[i] = open(argv[1 + i], O_RDONLY);
+ if(fd[i] == -1) {
+ perror("open");
+ exit(1);
+ }
+ fcntl(fd[i], F_NOCACHE, 1);
+
+ if (to_skip)
+ lseek(fd[i], to_skip * (lsiz + 2*csiz), SEEK_SET);
+ }
+
+ mb_x = width / 16;
+ mb_y = height / 16;
+
+ mberrors = malloc(mb_x * mb_y);
+
+ while(!die) {
+ memset(mberrors, 0, mb_x * mb_y);
+
+ printf("Loading frame %d\n", ++fr);
+
+ for(i = 0; i < 2; i++) {
+ v = read(fd[i], Y[i], lsiz);
+ if(v != lsiz) {
+ fprintf(stderr, "Unable to read Y from file %d, exiting\n", i + 1);
+ return 1;
+ }
+ }
+
+
+ for(c = 0; c < lsiz; c++) {
+ if(Y[0][c] != Y[1][c]) {
+ x = c % width;
+ y = c / width;
+
+ mb = x / 16 + (y / 16) * mb_x;
+
+ if(print_pixels)
+ printf("Luma diff 0x%02x != 0x%02x at pixel (%4d,%-4d) mb(%d,%d) #%d\n",
+ Y[0][c],
+ Y[1][c],
+ x, y,
+ x / 16,
+ y / 16,
+ mb);
+
+ mberrors[mb] |= 1;
+ }
+ }
+
+ /* Chroma planes */
+
+ for(p = 0; p < 2; p++) {
+
+ for(i = 0; i < 2; i++) {
+ v = read(fd[i], C[p][i], csiz);
+ if(v != csiz) {
+ fprintf(stderr, "Unable to read %c from file %d, exiting\n",
+ "UV"[p], i + 1);
+ return 1;
+ }
+ }
+
+ for(c = 0; c < csiz; c++) {
+ if(C[p][0][c] != C[p][1][c]) {
+ x = c % cwidth;
+ y = c / cwidth;
+
+ mb = x / 8 + (y / 8) * mb_x;
+
+ mberrors[mb] |= 2 << p;
+
+ if(print_pixels)
+
+ printf("c%c diff 0x%02x != 0x%02x at pixel (%4d,%-4d) "
+ "mb(%3d,%-3d) #%d\n",
+ p ? 'r' : 'b',
+ C[p][0][c],
+ C[p][1][c],
+
+ x, y,
+ x / 8,
+ y / 8,
+ x / 8 + y / 8 * cwidth / 8);
+ }
+ }
+ }
+
+ for(i = 0; i < mb_x * mb_y; i++) {
+ x = i % mb_x;
+ y = i / mb_x;
+
+ if(mberrors[i]) {
+ die = 1;
+
+ printf("MB (%3d,%-3d) %4d %d %c%c%c damaged\n",
+ x, y, i, mberrors[i],
+ mberrors[i] & 1 ? 'Y' : ' ',
+ mberrors[i] & 2 ? 'U' : ' ',
+ mberrors[i] & 4 ? 'V' : ' ');
+
+ if(dump_blocks) {
+ a = Y[0] + x * 16 + y * 16 * width;
+ b = Y[1] + x * 16 + y * 16 * width;
+
+ for(y = 0; y < 16; y++) {
+ printf("%c ", "TB"[y&1]);
+ for(x = 0; x < 16; x++)
+ printf("%02x%c", a[x + y * width],
+ a[x + y * width] != b[x + y * width] ? '<' : ' ');
+
+ printf("| ");
+ for(x = 0; x < 16; x++)
+ printf("%02x%c", b[x + y * width],
+ a[x + y * width] != b[x + y * width] ? '<' : ' ');
+
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}