summaryrefslogtreecommitdiff
path: root/chromium/third_party/ffmpeg/libavformat
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-10-13 13:24:50 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-10-14 10:57:25 +0000
commitaf3d4809763ef308f08ced947a73b624729ac7ea (patch)
tree4402b911e30383f6c6dace1e8cf3b8e85355db3a /chromium/third_party/ffmpeg/libavformat
parent0e8ff63a407fe323e215bb1a2c423c09a4747c8a (diff)
downloadqtwebengine-chromium-af3d4809763ef308f08ced947a73b624729ac7ea.tar.gz
BASELINE: Update Chromium to 47.0.2526.14
Also adding in sources needed for spellchecking. Change-Id: Idd44170fa1616f26315188970a8d5ba7d472b18a Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat')
-rw-r--r--chromium/third_party/ffmpeg/libavformat/4xm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/Makefile12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aadec.c314
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ac3dec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/act.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aiffenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/allformats.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/anm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apetag.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apngdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apngenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aqtitledec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asf.h40
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfdec_f.c (renamed from chromium/third_party/ffmpeg/libavformat/asfdec.c)215
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfdec_o.c1755
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfenc.c32
-rw-r--r--chromium/third_party/ffmpeg/libavformat/assdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/async.c560
-rw-r--r--chromium/third_party/ffmpeg/libavformat/autorename_libavformat_flacdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/autorename_libavformat_options.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/autorename_libavformat_utils.c137
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avformat.h20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avidec.c33
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avienc.c28
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avio.c61
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avio.h50
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aviobuf.c21
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avisynth.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/brstm.c253
-rw-r--r--chromium/third_party/ffmpeg/libavformat/caf.c12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/cafdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/cafenc.c15
-rw-r--r--chromium/third_party/ffmpeg/libavformat/concatdec.c110
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dnxhddec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dtsdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dump.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dv.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dxa.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/electronicarts.c137
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ffmdec.c13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ffmenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/file.c161
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flac_picture.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flvdec.c22
-rw-r--r--chromium/third_party/ffmpeg/libavformat/format.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ftp.c358
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gifdec.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hevc.c10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hls.c111
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsenc.c271
-rw-r--r--chromium/third_party/ffmpeg/libavformat/http.c229
-rw-r--r--chromium/third_party/ffmpeg/libavformat/id3v2.c20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/iff.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2.h7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2dec.c50
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2enc.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/internal.h20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ipmovie.c56
-rw-r--r--chromium/third_party/ffmpeg/libavformat/isom.c18
-rw-r--r--chromium/third_party/ffmpeg/libavformat/isom.h8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ivfenc.c30
-rw-r--r--chromium/third_party/ffmpeg/libavformat/jacosubdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/jvdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/latmenc.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libsmbclient.c63
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libssh.c196
-rw-r--r--chromium/third_party/ffmpeg/libavformat/lrcdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskadec.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskaenc.c185
-rw-r--r--chromium/third_party/ffmpeg/libavformat/md5enc.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/microdvddec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mlvdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mov.c261
-rw-r--r--chromium/third_party/ffmpeg/libavformat/movenc.c70
-rw-r--r--chromium/third_party/ffmpeg/libavformat/movenc.h8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mp3dec.c141
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpc8.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpeg.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegenc.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegts.c70
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegtsenc.c56
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpjpeg.c18
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpjpegdec.c55
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpl2dec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpsubdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/msnwc_tcp.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mux.c58
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxf.c15
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxf.h1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxfdec.c57
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxfenc.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxg.c14
-rw-r--r--chromium/third_party/ffmpeg/libavformat/network.c27
-rw-r--r--chromium/third_party/ffmpeg/libavformat/network.h20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nutdec.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nutenc.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggdec.c22
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggenc.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparsedirac.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparseogm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparsetheora.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/options.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/options_table.h8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/os_support.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/pjsdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/psxstr.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/qcp.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rawdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rawenc.c20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rdt.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/realtextdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/redspark.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.h7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riffdec.c37
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riffenc.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rmdec.c84
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmp.h3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmppkt.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmpproto.c43
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_hevc.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_latm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_qt.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpenc_jpeg.c43
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtsp.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/samidec.c10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sdp.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segment.c19
-rw-r--r--chromium/third_party/ffmpeg/libavformat/spdifenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/srtdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/stldec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subtitles.c31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subtitles.h5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subviewer1dec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subviewerdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/swfdec.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/takdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tcp.c31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tee.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tls_gnutls.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/url.h27
-rw-r--r--chromium/third_party/ffmpeg/libavformat/utils.c137
-rw-r--r--chromium/third_party/ffmpeg/libavformat/version.h20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vplayerdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wavdec.c29
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wavenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webmdashenc.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webvttdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webvttenc.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wtvdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/xwma.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/yop.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/yuv4mpeg.h1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/yuv4mpegdec.c31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/yuv4mpegenc.c4
163 files changed, 6390 insertions, 1073 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/4xm.c b/chromium/third_party/ffmpeg/libavformat/4xm.c
index 8fdad185f47..260e080962d 100644
--- a/chromium/third_party/ffmpeg/libavformat/4xm.c
+++ b/chromium/third_party/ffmpeg/libavformat/4xm.c
@@ -111,7 +111,7 @@ static int parse_vtrk(AVFormatContext *s,
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = AV_CODEC_ID_4XM;
- st->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_mallocz(4 + AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
st->codec->extradata_size = 4;
diff --git a/chromium/third_party/ffmpeg/libavformat/Makefile b/chromium/third_party/ffmpeg/libavformat/Makefile
index 993ec09837d..466da516ada 100644
--- a/chromium/third_party/ffmpeg/libavformat/Makefile
+++ b/chromium/third_party/ffmpeg/libavformat/Makefile
@@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED) += log2_tab.o golomb_tab.o
# muxers/demuxers
OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o
+OBJS-$(CONFIG_AA_DEMUXER) += aadec.o
OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o
OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o
OBJS-$(CONFIG_AC3_MUXER) += rawenc.o
@@ -82,7 +83,9 @@ OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o img2.o
OBJS-$(CONFIG_APNG_DEMUXER) += apngdec.o
OBJS-$(CONFIG_APNG_MUXER) += apngenc.o
OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o
-OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \
+OBJS-$(CONFIG_ASF_DEMUXER) += asfdec_f.o asf.o asfcrypt.o \
+ avlanguage.o
+OBJS-$(CONFIG_ASF_O_DEMUXER) += asfdec_o.o asf.o asfcrypt.o \
avlanguage.o
OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o
OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o subtitles.o
@@ -200,6 +203,7 @@ OBJS-$(CONFIG_IMAGE2PIPE_MUXER) += img2enc.o img2.o
OBJS-$(CONFIG_IMAGE2_ALIAS_PIX_DEMUXER) += img2_alias_pix.o
OBJS-$(CONFIG_IMAGE2_BRENDER_PIX_DEMUXER) += img2_brender_pix.o
OBJS-$(CONFIG_IMAGE_BMP_PIPE_DEMUXER) += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_DDS_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_DPX_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_EXR_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_J2K_PIPE_DEMUXER) += img2dec.o img2.o
@@ -468,7 +472,7 @@ OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o
OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o
OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o
-OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv_common.o asfdec.o asf.o asfcrypt.o \
+OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv_common.o asfdec_f.o asf.o asfcrypt.o \
avlanguage.o mpegts.o isom.o
OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv_common.o \
mpegtsenc.o asf.o
@@ -493,6 +497,7 @@ OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o
OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o
# protocols I/O
+OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
OBJS-$(CONFIG_CACHE_PROTOCOL) += cache.o
@@ -542,7 +547,8 @@ SLIBOBJS-$(HAVE_GNU_WINDRES) += avformatres.o
SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h
-TESTPROGS = seek \
+TESTPROGS = async \
+ seek \
srtp \
url \
diff --git a/chromium/third_party/ffmpeg/libavformat/aadec.c b/chromium/third_party/ffmpeg/libavformat/aadec.c
new file mode 100644
index 00000000000..266a8e85acd
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/aadec.c
@@ -0,0 +1,314 @@
+/*
+ * Audible AA demuxer
+ * Copyright (c) 2015 Vesselin Bontchev
+ *
+ * Header parsing is borrowed from https://github.com/jteeuwen/audible project.
+ * Copyright (c) 2001-2014, Jim Teeuwen
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/tea.h"
+#include "libavutil/opt.h"
+
+#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */
+#define MAX_CODEC_SECOND_SIZE 3982
+#define MAX_TOC_ENTRIES 16
+#define MAX_DICTIONARY_ENTRIES 128
+#define TEA_BLOCK_SIZE 8
+
+typedef struct AADemuxContext {
+ AVClass *class;
+ uint8_t *aa_fixed_key;
+ int aa_fixed_key_len;
+ int codec_second_size;
+ int current_codec_second_size;
+ int chapter_idx;
+ struct AVTEA *tea_ctx;
+ uint8_t file_key[16];
+ int64_t current_chapter_size;
+} AADemuxContext;
+
+static int get_second_size(char *codec_name)
+{
+ int result = -1;
+
+ if (!strcmp(codec_name, "mp332")) {
+ result = 3982;
+ } else if (!strcmp(codec_name, "acelp16")) {
+ result = 2000;
+ } else if (!strcmp(codec_name, "acelp85")) {
+ result = 1045;
+ }
+
+ return result;
+}
+
+static int aa_read_header(AVFormatContext *s)
+{
+ int i, j, idx, largest_idx = -1;
+ uint32_t nkey, nval, toc_size, npairs, header_seed = 0, start;
+ char key[128], val[128], codec_name[64] = {0};
+ uint8_t output[24], dst[8], src[8];
+ int64_t largest_size = -1, current_size = -1;
+ struct toc_entry {
+ uint32_t offset;
+ uint32_t size;
+ } TOC[MAX_TOC_ENTRIES];
+ uint32_t header_key_part[4];
+ uint8_t header_key[16] = {0};
+ AADemuxContext *c = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVStream *st;
+
+ /* parse .aa header */
+ avio_skip(pb, 4); // file size
+ avio_skip(pb, 4); // magic string
+ toc_size = avio_rb32(pb); // TOC size
+ avio_skip(pb, 4); // unidentified integer
+ if (toc_size > MAX_TOC_ENTRIES)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < toc_size; i++) { // read TOC
+ avio_skip(pb, 4); // TOC entry index
+ TOC[i].offset = avio_rb32(pb); // block offset
+ TOC[i].size = avio_rb32(pb); // block size
+ }
+ avio_skip(pb, 24); // header termination block (ignored)
+ npairs = avio_rb32(pb); // read dictionary entries
+ if (npairs > MAX_DICTIONARY_ENTRIES)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < npairs; i++) {
+ memset(val, 0, sizeof(val));
+ memset(key, 0, sizeof(key));
+ avio_skip(pb, 1); // unidentified integer
+ nkey = avio_rb32(pb); // key string length
+ nval = avio_rb32(pb); // value string length
+ if (nkey > sizeof(key)) {
+ avio_skip(pb, nkey);
+ } else {
+ avio_read(pb, key, nkey); // key string
+ }
+ if (nval > sizeof(val)) {
+ avio_skip(pb, nval);
+ } else {
+ avio_read(pb, val, nval); // value string
+ }
+ if (!strcmp(key, "codec")) {
+ av_log(s, AV_LOG_DEBUG, "Codec is <%s>\n", val);
+ strncpy(codec_name, val, sizeof(codec_name) - 1);
+ }
+ if (!strcmp(key, "HeaderSeed")) {
+ av_log(s, AV_LOG_DEBUG, "HeaderSeed is <%s>\n", val);
+ header_seed = atoi(val);
+ }
+ if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890"
+ av_log(s, AV_LOG_DEBUG, "HeaderKey is <%s>\n", val);
+ sscanf(val, "%u%u%u%u", &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]);
+ for (idx = 0; idx < 4; idx++) {
+ AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE!
+ }
+ av_log(s, AV_LOG_DEBUG, "Processed HeaderKey is ");
+ for (i = 0; i < 16; i++)
+ av_log(s, AV_LOG_DEBUG, "%02x", header_key[i]);
+ av_log(s, AV_LOG_DEBUG, "\n");
+ }
+ }
+
+ /* verify fixed key */
+ if (c->aa_fixed_key_len != 16) {
+ av_log(s, AV_LOG_ERROR, "aa_fixed_key value needs to be 16 bytes!\n");
+ return AVERROR(EINVAL);
+ }
+
+ /* verify codec */
+ if ((c->codec_second_size = get_second_size(codec_name)) == -1) {
+ av_log(s, AV_LOG_ERROR, "unknown codec <%s>!\n", codec_name);
+ return AVERROR(EINVAL);
+ }
+
+ /* decryption key derivation */
+ c->tea_ctx = av_tea_alloc();
+ if (!c->tea_ctx)
+ return AVERROR(ENOMEM);
+ av_tea_init(c->tea_ctx, c->aa_fixed_key, 16);
+ output[0] = output[1] = 0; // purely for padding purposes
+ memcpy(output + 2, header_key, 16);
+ idx = 0;
+ for (i = 0; i < 3; i++) { // TEA CBC with weird mixed endianness
+ AV_WB32(src, header_seed);
+ AV_WB32(src + 4, header_seed + 1);
+ header_seed += 2;
+ av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 0); // TEA ECB encrypt
+ for (j = 0; j < TEA_BLOCK_SIZE && idx < 18; j+=1, idx+=1) {
+ output[idx] = output[idx] ^ dst[j];
+ }
+ }
+ memcpy(c->file_key, output + 2, 16); // skip first 2 bytes of output
+ av_log(s, AV_LOG_DEBUG, "File key is ");
+ for (i = 0; i < 16; i++)
+ av_log(s, AV_LOG_DEBUG, "%02x", c->file_key[i]);
+ av_log(s, AV_LOG_DEBUG, "\n");
+
+ /* decoder setup */
+ st = avformat_new_stream(s, NULL);
+ if (!st) {
+ av_freep(&c->tea_ctx);
+ return AVERROR(ENOMEM);
+ }
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ if (!strcmp(codec_name, "mp332")) {
+ st->codec->codec_id = AV_CODEC_ID_MP3;
+ st->codec->sample_rate = 22050;
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+ st->start_time = 0;
+ } else if (!strcmp(codec_name, "acelp85")) {
+ st->codec->codec_id = AV_CODEC_ID_SIPR;
+ st->codec->block_align = 19;
+ st->codec->channels = 1;
+ st->codec->sample_rate = 8500;
+ } else if (!strcmp(codec_name, "acelp16")) {
+ st->codec->codec_id = AV_CODEC_ID_SIPR;
+ st->codec->block_align = 20;
+ st->codec->channels = 1;
+ st->codec->sample_rate = 16000;
+ }
+
+ /* determine, and jump to audio start offset */
+ for (i = 1; i < toc_size; i++) { // skip the first entry!
+ current_size = TOC[i].size;
+ if (current_size > largest_size) {
+ largest_idx = i;
+ largest_size = current_size;
+ }
+ }
+ start = TOC[largest_idx].offset;
+ avio_seek(pb, start, SEEK_SET);
+ c->current_chapter_size = 0;
+
+ return 0;
+}
+
+static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ uint8_t dst[TEA_BLOCK_SIZE];
+ uint8_t src[TEA_BLOCK_SIZE];
+ int i;
+ int trailing_bytes;
+ int blocks;
+ uint8_t buf[MAX_CODEC_SECOND_SIZE * 2];
+ int written = 0;
+ int ret;
+ AADemuxContext *c = s->priv_data;
+
+ // are we at the start of a chapter?
+ if (c->current_chapter_size == 0) {
+ c->current_chapter_size = avio_rb32(s->pb);
+ if (c->current_chapter_size == 0) {
+ return AVERROR_EOF;
+ }
+ av_log(s, AV_LOG_DEBUG, "Chapter %d (%" PRId64 " bytes)\n", c->chapter_idx, c->current_chapter_size);
+ c->chapter_idx = c->chapter_idx + 1;
+ avio_skip(s->pb, 4); // data start offset
+ c->current_codec_second_size = c->codec_second_size;
+ }
+
+ // is this the last block in this chapter?
+ if (c->current_chapter_size / c->current_codec_second_size == 0) {
+ c->current_codec_second_size = c->current_chapter_size % c->current_codec_second_size;
+ }
+
+ // decrypt c->current_codec_second_size bytes
+ blocks = c->current_codec_second_size / TEA_BLOCK_SIZE;
+ for (i = 0; i < blocks; i++) {
+ avio_read(s->pb, src, TEA_BLOCK_SIZE);
+ av_tea_init(c->tea_ctx, c->file_key, 16);
+ av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1);
+ memcpy(buf + written, dst, TEA_BLOCK_SIZE);
+ written = written + TEA_BLOCK_SIZE;
+ }
+ trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE;
+ if (trailing_bytes != 0) { // trailing bytes are left unencrypted!
+ avio_read(s->pb, src, trailing_bytes);
+ memcpy(buf + written, src, trailing_bytes);
+ written = written + trailing_bytes;
+ }
+
+ // update state
+ c->current_chapter_size = c->current_chapter_size - c->current_codec_second_size;
+ if (c->current_chapter_size <= 0)
+ c->current_chapter_size = 0;
+
+ ret = av_new_packet(pkt, written);
+ if (ret < 0)
+ return ret;
+ memcpy(pkt->data, buf, written);
+
+ return 0;
+}
+
+static int aa_probe(AVProbeData *p)
+{
+ uint8_t *buf = p->buf;
+
+ // first 4 bytes are file size, next 4 bytes are the magic
+ if (AV_RB32(buf+4) != AA_MAGIC)
+ return 0;
+
+ return AVPROBE_SCORE_MAX / 2;
+}
+
+static int aa_read_close(AVFormatContext *s)
+{
+ AADemuxContext *c = s->priv_data;
+
+ av_freep(&c->tea_ctx);
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(AADemuxContext, x)
+static const AVOption aa_options[] = {
+ { "aa_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
+ "Fixed key used for handling Audible AA files", OFFSET(aa_fixed_key),
+ AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd2a51d673"},
+ .flags = AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass aa_class = {
+ .class_name = "aa",
+ .item_name = av_default_item_name,
+ .option = aa_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_aa_demuxer = {
+ .name = "aa",
+ .long_name = NULL_IF_CONFIG_SMALL("Audible AA format files"),
+ .priv_class = &aa_class,
+ .priv_data_size = sizeof(AADemuxContext),
+ .extensions = "aa",
+ .read_probe = aa_probe,
+ .read_header = aa_read_header,
+ .read_packet = aa_read_packet,
+ .read_close = aa_read_close,
+ .flags = AVFMT_GENERIC_INDEX,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/ac3dec.c b/chromium/third_party/ffmpeg/libavformat/ac3dec.c
index 58ef44d45a7..bef55cb6586 100644
--- a/chromium/third_party/ffmpeg/libavformat/ac3dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/ac3dec.c
@@ -80,7 +80,7 @@ static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)
if(codec_id != expected_codec_id) return 0;
// keep this in sync with mp3 probe, both need to avoid
// issues with MPEG-files!
- if (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1;
+ if (first_frames>=7) return AVPROBE_SCORE_EXTENSION + 1;
else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION/2;
else if(max_frames>=1) return 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/act.c b/chromium/third_party/ffmpeg/libavformat/act.c
index 7b6b8406fc0..35aacbc4595 100644
--- a/chromium/third_party/ffmpeg/libavformat/act.c
+++ b/chromium/third_party/ffmpeg/libavformat/act.c
@@ -75,7 +75,7 @@ static int read_header(AVFormatContext *s)
avio_skip(pb, 16);
size=avio_rl32(pb);
- ff_get_wav_header(pb, st->codec, size, 0);
+ ff_get_wav_header(s, pb, st->codec, size, 0);
/*
8000Hz (Fine-rec) file format has 10 bytes long
diff --git a/chromium/third_party/ffmpeg/libavformat/aiffenc.c b/chromium/third_party/ffmpeg/libavformat/aiffenc.c
index e2828e7508b..3abd2840f25 100644
--- a/chromium/third_party/ffmpeg/libavformat/aiffenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/aiffenc.c
@@ -112,7 +112,7 @@ static int aiff_write_header(AVFormatContext *s)
if (aiff->audio_stream_idx < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
aiff->audio_stream_idx = i;
} else if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) {
- av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in AIFF.\n");
+ av_log(s, AV_LOG_ERROR, "AIFF allows only one audio stream and a picture.\n");
return AVERROR(EINVAL);
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/allformats.c b/chromium/third_party/ffmpeg/libavformat/allformats.c
index 306e0c9876d..0a24ac718b2 100644
--- a/chromium/third_party/ffmpeg/libavformat/allformats.c
+++ b/chromium/third_party/ffmpeg/libavformat/allformats.c
@@ -60,6 +60,7 @@ void av_register_all(void)
/* (de)muxers */
REGISTER_MUXER (A64, a64);
+ REGISTER_DEMUXER (AA, aa);
REGISTER_DEMUXER (AAC, aac);
REGISTER_MUXDEMUX(AC3, ac3);
REGISTER_DEMUXER (ACT, act);
@@ -77,6 +78,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX(APNG, apng);
REGISTER_DEMUXER (AQTITLE, aqtitle);
REGISTER_MUXDEMUX(ASF, asf);
+ REGISTER_DEMUXER (ASF_O, asf_o);
REGISTER_MUXDEMUX(ASS, ass);
REGISTER_MUXDEMUX(AST, ast);
REGISTER_MUXER (ASF_STREAM, asf_stream);
@@ -334,6 +336,7 @@ void av_register_all(void)
/* image demuxers */
REGISTER_DEMUXER (IMAGE_BMP_PIPE, image_bmp_pipe);
+ REGISTER_DEMUXER (IMAGE_DDS_PIPE, image_dds_pipe);
REGISTER_DEMUXER (IMAGE_DPX_PIPE, image_dpx_pipe);
REGISTER_DEMUXER (IMAGE_EXR_PIPE, image_exr_pipe);
REGISTER_DEMUXER (IMAGE_J2K_PIPE, image_j2k_pipe);
@@ -349,6 +352,7 @@ void av_register_all(void)
/* protocols */
+ REGISTER_PROTOCOL(ASYNC, async);
REGISTER_PROTOCOL(BLURAY, bluray);
REGISTER_PROTOCOL(CACHE, cache);
REGISTER_PROTOCOL(CONCAT, concat);
diff --git a/chromium/third_party/ffmpeg/libavformat/anm.c b/chromium/third_party/ffmpeg/libavformat/anm.c
index f7187973109..23200474bd2 100644
--- a/chromium/third_party/ffmpeg/libavformat/anm.c
+++ b/chromium/third_party/ffmpeg/libavformat/anm.c
@@ -133,7 +133,7 @@ static int read_header(AVFormatContext *s)
/* color cycling and palette data */
st->codec->extradata_size = 16*8 + 4*256;
- st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_mallocz(st->codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata) {
return AVERROR(ENOMEM);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/apetag.c b/chromium/third_party/ffmpeg/libavformat/apetag.c
index 26359205f83..2ee277f8642 100644
--- a/chromium/third_party/ffmpeg/libavformat/apetag.c
+++ b/chromium/third_party/ffmpeg/libavformat/apetag.c
@@ -55,7 +55,7 @@ static int ape_tag_read_field(AVFormatContext *s)
av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key);
return -1;
}
- if (size > INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+ if (size > INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
av_log(s, AV_LOG_ERROR, "APE tag size too large.\n");
return AVERROR_INVALIDDATA;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/apngdec.c b/chromium/third_party/ffmpeg/libavformat/apngdec.c
index 6deff3b66ba..84298aecfdd 100644
--- a/chromium/third_party/ffmpeg/libavformat/apngdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/apngdec.c
@@ -132,7 +132,7 @@ static int append_extradata(AVCodecContext *s, AVIOContext *pb, int len)
return AVERROR_INVALIDDATA;
new_size = previous_size + len;
- new_extradata = av_realloc(s->extradata, new_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ new_extradata = av_realloc(s->extradata, new_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!new_extradata)
return AVERROR(ENOMEM);
s->extradata = new_extradata;
@@ -178,7 +178,7 @@ static int apng_read_header(AVFormatContext *s)
return ret;
/* extradata will contain every chunk up to the first fcTL (excluded) */
- st->codec->extradata = av_malloc(len + 12 + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
st->codec->extradata_size = len + 12;
diff --git a/chromium/third_party/ffmpeg/libavformat/apngenc.c b/chromium/third_party/ffmpeg/libavformat/apngenc.c
index dcf6b906e18..9b2c634b954 100644
--- a/chromium/third_party/ffmpeg/libavformat/apngenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/apngenc.c
@@ -173,7 +173,7 @@ static void flush_packet(AVFormatContext *format_context, AVPacket *packet)
"Frame rate is too high or specified too precisely. Unable to copy losslessly.\n");
apng->framerate_warned = 1;
}
- } else if (apng->last_delay.den > 0) {
+ } else if (apng->last_delay.num > 0) {
delay = apng->last_delay;
} else {
delay = apng->prev_delay;
diff --git a/chromium/third_party/ffmpeg/libavformat/aqtitledec.c b/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
index 95087665aa1..7c864c8e10f 100644
--- a/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
@@ -95,7 +95,7 @@ static int aqt_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&aqt->q);
+ ff_subtitles_queue_finalize(s, &aqt->q);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/asf.h b/chromium/third_party/ffmpeg/libavformat/asf.h
index 0c9598a8d8f..f98fc46edcb 100644
--- a/chromium/third_party/ffmpeg/libavformat/asf.h
+++ b/chromium/third_party/ffmpeg/libavformat/asf.h
@@ -28,37 +28,15 @@
#define PACKET_SIZE 3200
-typedef struct ASFPayload {
- uint8_t type;
- uint16_t size;
-} ASFPayload;
-
-typedef struct ASFStream {
- int num;
- unsigned char seq;
- /* use for reading */
- AVPacket pkt;
- int frag_offset;
- int packet_obj_size;
- int timestamp;
- int64_t duration;
- int skip_to_key;
- int pkt_clean;
-
- int ds_span; /* descrambling */
- int ds_packet_size;
- int ds_chunk_size;
-
- int64_t packet_pos;
-
- uint16_t stream_language_index;
-
- int palette_changed;
- uint32_t palette[256];
-
- int payload_ext_ct;
- ASFPayload payload[8];
-} ASFStream;
+typedef enum ASFDataType {
+ ASF_UNICODE = 0,
+ ASF_BYTE_ARRAY = 1,
+ ASF_BOOL = 2,
+ ASF_DWORD = 3,
+ ASF_QWORD = 4,
+ ASF_WORD = 5,
+ ASF_GUID = 6,
+}ASFDataType;
typedef struct ASFMainHeader {
ff_asf_guid guid; ///< generated by client computer
diff --git a/chromium/third_party/ffmpeg/libavformat/asfdec.c b/chromium/third_party/ffmpeg/libavformat/asfdec_f.c
index 92784348cba..7c31cfaee47 100644
--- a/chromium/third_party/ffmpeg/libavformat/asfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/asfdec_f.c
@@ -39,6 +39,38 @@
#include "asf.h"
#include "asfcrypt.h"
+typedef struct ASFPayload {
+ uint8_t type;
+ uint16_t size;
+} ASFPayload;
+
+typedef struct ASFStream {
+ int num;
+ unsigned char seq;
+ /* use for reading */
+ AVPacket pkt;
+ int frag_offset;
+ int packet_obj_size;
+ int timestamp;
+ int64_t duration;
+ int skip_to_key;
+ int pkt_clean;
+
+ int ds_span; /* descrambling */
+ int ds_packet_size;
+ int ds_chunk_size;
+
+ int64_t packet_pos;
+
+ uint16_t stream_language_index;
+
+ int palette_changed;
+ uint32_t palette[256];
+
+ int payload_ext_ct;
+ ASFPayload payload[8];
+} ASFStream;
+
typedef struct ASFContext {
const AVClass *class;
int asfid2avid[128]; ///< conversion table from asf ID 2 AVStream ID
@@ -81,6 +113,8 @@ typedef struct ASFContext {
int no_resync_search;
int export_xmp;
+
+ int uses_std_ecc;
} ASFContext;
static const AVOption options[] = {
@@ -100,8 +134,9 @@ static const AVClass asf_class = {
#include <assert.h>
#define ASF_MAX_STREAMS 127
-#define FRAME_HEADER_SIZE 16
-// Fix Me! FRAME_HEADER_SIZE may be different. (17 is known to be too large)
+#define FRAME_HEADER_SIZE 6
+// Fix Me! FRAME_HEADER_SIZE may be different.
+// (7 is known to be too large for GipsyGuitar.wmv)
#ifdef DEBUG
static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */
@@ -294,12 +329,15 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len, int
if (!value)
goto finish;
- if (type == 0) { // UTF16-LE
+ switch (type) {
+ case ASF_UNICODE:
avio_get_str16le(s->pb, len, value, 2 * len + 1);
- } else if (type == -1) { // ASCII
+ break;
+ case -1: // ASCI
avio_read(s->pb, value, len);
value[len]=0;
- } else if (type == 1) { // byte array
+ break;
+ case ASF_BYTE_ARRAY:
if (!strcmp(key, "WM/Picture")) { // handle cover art
asf_read_picture(s, len);
} else if (!strcmp(key, "ID3")) { // handle ID3 tag
@@ -308,13 +346,18 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len, int
av_log(s, AV_LOG_VERBOSE, "Unsupported byte array in tag %s.\n", key);
}
goto finish;
- } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD
+ case ASF_BOOL:
+ case ASF_DWORD:
+ case ASF_QWORD:
+ case ASF_WORD: {
uint64_t num = get_value(s->pb, type, type2_size);
snprintf(value, LEN, "%"PRIu64, num);
- } else if (type == 6) { // (don't) handle GUID
+ break;
+ }
+ case ASF_GUID:
av_log(s, AV_LOG_DEBUG, "Unsupported GUID value in tag %s.\n", key);
goto finish;
- } else {
+ default:
av_log(s, AV_LOG_DEBUG,
"Unsupported value type %d in tag %s.\n", type, key);
goto finish;
@@ -429,7 +472,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
st->codec->codec_type = type;
if (type == AVMEDIA_TYPE_AUDIO) {
- int ret = ff_get_wav_header(pb, st->codec, type_specific_size, 0);
+ int ret = ff_get_wav_header(s, pb, st->codec, type_specific_size, 0);
if (ret < 0)
return ret;
if (is_dvr_ms_audio) {
@@ -474,7 +517,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
if (sizeX > 40) {
st->codec->extradata_size = ffio_limit(pb, sizeX - 40);
st->codec->extradata = av_mallocz(st->codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
avio_read(pb, st->codec->extradata, st->codec->extradata_size);
@@ -653,24 +696,29 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
{
AVIOContext *pb = s->pb;
ASFContext *asf = s->priv_data;
- int n, stream_num, name_len, value_len;
+ int n, stream_num, name_len_utf16, name_len_utf8, value_len;
int ret, i;
n = avio_rl16(pb);
for (i = 0; i < n; i++) {
- char name[1024];
+ uint8_t *name;
int value_type;
avio_rl16(pb); // lang_list_index
stream_num = avio_rl16(pb);
- name_len = avio_rl16(pb);
+ name_len_utf16 = avio_rl16(pb);
value_type = avio_rl16(pb); /* value_type */
value_len = avio_rl32(pb);
- if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
- avio_skip(pb, name_len - ret);
+ name_len_utf8 = 2*name_len_utf16 + 1;
+ name = av_malloc(name_len_utf8);
+ if (!name)
+ return AVERROR(ENOMEM);
+
+ if ((ret = avio_get_str16le(pb, name_len_utf16, name, name_len_utf8)) < name_len_utf16)
+ avio_skip(pb, name_len_utf16 - ret);
av_log(s, AV_LOG_TRACE, "%d stream %d name_len %2d type %d len %4d <%s>\n",
- i, stream_num, name_len, value_type, value_len, name);
+ i, stream_num, name_len_utf16, value_type, value_len, name);
if (!strcmp(name, "AspectRatioX")){
int aspect_x = get_value(s->pb, value_type, 16);
@@ -683,6 +731,7 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
} else {
get_tag(s, name, value_type, value_len, 16);
}
+ av_freep(&name);
}
return 0;
@@ -746,6 +795,7 @@ static int asf_read_header(AVFormatContext *s)
for (;;) {
uint64_t gpos = avio_tell(pb);
+ int ret = 0;
ff_get_guid(pb, &g);
gsize = avio_rl64(pb);
print_guid(&g);
@@ -762,13 +812,9 @@ static int asf_read_header(AVFormatContext *s)
if (gsize < 24)
return AVERROR_INVALIDDATA;
if (!ff_guidcmp(&g, &ff_asf_file_header)) {
- int ret = asf_read_file_properties(s, gsize);
- if (ret < 0)
- return ret;
+ ret = asf_read_file_properties(s, gsize);
} else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {
- int ret = asf_read_stream_properties(s, gsize);
- if (ret < 0)
- return ret;
+ ret = asf_read_stream_properties(s, gsize);
} else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {
asf_read_content_desc(s, gsize);
} else if (!ff_guidcmp(&g, &ff_asf_language_guid)) {
@@ -797,7 +843,6 @@ static int asf_read_header(AVFormatContext *s)
if (!s->keylen) {
if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {
unsigned int len;
- int ret;
AVPacket pkt;
av_log(s, AV_LOG_WARNING,
"DRM protected stream detected, decoding will likely fail!\n");
@@ -823,6 +868,9 @@ static int asf_read_header(AVFormatContext *s)
}
}
}
+ if (ret < 0)
+ return ret;
+
if (avio_tell(pb) != gpos + gsize)
av_log(s, AV_LOG_DEBUG,
"gpos mismatch our pos=%"PRIu64", end=%"PRId64"\n",
@@ -910,44 +958,67 @@ static int asf_get_packet(AVFormatContext *s, AVIOContext *pb)
int rsize = 8;
int c, d, e, off;
- // if we do not know packet size, allow skipping up to 32 kB
- off = 32768;
- if (asf->no_resync_search)
- off = 3;
- else if (s->packet_size > 0)
- off = (avio_tell(pb) - s->internal->data_offset) % s->packet_size + 3;
-
- c = d = e = -1;
- while (off-- > 0) {
- c = d;
- d = e;
- e = avio_r8(pb);
- if (c == 0x82 && !d && !e)
- break;
- }
+ if (asf->uses_std_ecc > 0) {
+ // if we do not know packet size, allow skipping up to 32 kB
+ off = 32768;
+ if (asf->no_resync_search)
+ off = 3;
+// else if (s->packet_size > 0 && !asf->uses_std_ecc)
+// off = (avio_tell(pb) - s->internal->data_offset) % s->packet_size + 3;
+
+ c = d = e = -1;
+ while (off-- > 0) {
+ c = d;
+ d = e;
+ e = avio_r8(pb);
+ if (c == 0x82 && !d && !e)
+ break;
+ }
- if (c != 0x82) {
- /* This code allows handling of -EAGAIN at packet boundaries (i.e.
- * if the packet sync code above triggers -EAGAIN). This does not
- * imply complete -EAGAIN handling support at random positions in
- * the stream. */
- if (pb->error == AVERROR(EAGAIN))
- return AVERROR(EAGAIN);
- if (!avio_feof(pb))
- av_log(s, AV_LOG_ERROR,
- "ff asf bad header %x at:%"PRId64"\n", c, avio_tell(pb));
- }
- if ((c & 0x8f) == 0x82) {
- if (d || e) {
+ if (c != 0x82) {
+ /* This code allows handling of -EAGAIN at packet boundaries (i.e.
+ * if the packet sync code above triggers -EAGAIN). This does not
+ * imply complete -EAGAIN handling support at random positions in
+ * the stream. */
+ if (pb->error == AVERROR(EAGAIN))
+ return AVERROR(EAGAIN);
if (!avio_feof(pb))
- av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
- return AVERROR_INVALIDDATA;
+ av_log(s, AV_LOG_ERROR,
+ "ff asf bad header %x at:%"PRId64"\n", c, avio_tell(pb));
+ }
+ if ((c & 0x8f) == 0x82) {
+ if (d || e) {
+ if (!avio_feof(pb))
+ av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c = avio_r8(pb);
+ d = avio_r8(pb);
+ rsize += 3;
+ } else if(!avio_feof(pb)) {
+ avio_seek(pb, -1, SEEK_CUR); // FIXME
}
- c = avio_r8(pb);
- d = avio_r8(pb);
- rsize += 3;
- } else if(!avio_feof(pb)) {
- avio_seek(pb, -1, SEEK_CUR); // FIXME
+ } else {
+ c = avio_r8(pb);
+ if (c & 0x80) {
+ rsize ++;
+ if (!(c & 0x60)) {
+ d = avio_r8(pb);
+ e = avio_r8(pb);
+ avio_seek(pb, (c & 0xF) - 2, SEEK_CUR);
+ rsize += c & 0xF;
+ }
+
+ if (c != 0x82)
+ avpriv_request_sample(s, "Invalid ECC byte\n");
+
+ if (!asf->uses_std_ecc)
+ asf->uses_std_ecc = (c == 0x82 && !d && !e) ? 1 : -1;
+
+ c = avio_r8(pb);
+ } else
+ asf->uses_std_ecc = -1;
+ d = avio_r8(pb);
}
asf->packet_flags = c;
@@ -1019,9 +1090,9 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
- av_log(asf, AV_LOG_TRACE, "key:%d stream:%d seq:%d offset:%d replic_size:%d\n",
+ av_log(asf, AV_LOG_TRACE, "key:%d stream:%d seq:%d offset:%d replic_size:%d num:%X packet_property %X\n",
asf->packet_key_frame, asf->stream_index, asf->packet_seq,
- asf->packet_frag_offset, asf->packet_replic_size);
+ asf->packet_frag_offset, asf->packet_replic_size, num, asf->packet_property);
if (rsize+(int64_t)asf->packet_replic_size > asf->packet_size_left) {
av_log(s, AV_LOG_ERROR, "packet_replic_size %d is invalid\n", asf->packet_replic_size);
return AVERROR_INVALIDDATA;
@@ -1030,8 +1101,8 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
int64_t end = avio_tell(pb) + asf->packet_replic_size;
AVRational aspect;
asfst->packet_obj_size = avio_rl32(pb);
- if (asfst->packet_obj_size >= (1 << 24) || asfst->packet_obj_size <= 0) {
- av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
+ if (asfst->packet_obj_size >= (1 << 24) || asfst->packet_obj_size < 0) {
+ av_log(s, AV_LOG_ERROR, "packet_obj_size %d invalid\n", asfst->packet_obj_size);
asfst->packet_obj_size = 0;
return AVERROR_INVALIDDATA;
}
@@ -1100,8 +1171,8 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
return AVERROR_INVALIDDATA;
} else if (asf->packet_frag_size > asf->packet_size_left - rsize) {
if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) {
- av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n",
- asf->packet_size_left, rsize);
+ av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d>%d-%d+%d)\n",
+ asf->packet_frag_size, asf->packet_size_left, rsize, asf->packet_padsize);
return AVERROR_INVALIDDATA;
} else {
int diff = asf->packet_frag_size - (asf->packet_size_left - rsize);
@@ -1143,6 +1214,9 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
asf->packet_segments < 1 && asf->packet_time_start == 0) {
int ret = asf->packet_size_left + asf->packet_padsize;
+ if (asf->packet_size_left && asf->packet_size_left < FRAME_HEADER_SIZE)
+ av_log(s, AV_LOG_WARNING, "Skip due to FRAME_HEADER_SIZE\n");
+
assert(ret >= 0);
/* fail safe */
avio_skip(pb, ret);
@@ -1172,7 +1246,8 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
continue;
}
asf->asf_st = &asf->streams[s->streams[asf->stream_index]->id];
- asf->asf_st->skip_to_key = 0;
+ if (!asf->packet_frag_offset)
+ asf->asf_st->skip_to_key = 0;
}
asf_st = asf->asf_st;
av_assert0(asf_st);
@@ -1319,12 +1394,12 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
} else {
/* packet descrambling */
AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (buf) {
uint8_t *newdata = buf->data;
int offset = 0;
memset(newdata + asf_st->pkt.size, 0,
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
while (offset < asf_st->pkt.size) {
int off = offset / asf_st->ds_chunk_size;
int row = off / asf_st->ds_span;
@@ -1345,11 +1420,6 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
}
asf_st->frag_offset = 0;
*pkt = asf_st->pkt;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- asf_st->pkt.destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
asf_st->pkt.buf = 0;
asf_st->pkt.size = 0;
asf_st->pkt.data = 0;
@@ -1476,6 +1546,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
// assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
pos = asf_st->packet_pos;
+ av_assert1(pkt->pos == asf_st->packet_pos);
av_add_index_entry(s->streams[i], pos, pts, pkt->size,
pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
diff --git a/chromium/third_party/ffmpeg/libavformat/asfdec_o.c b/chromium/third_party/ffmpeg/libavformat/asfdec_o.c
new file mode 100644
index 00000000000..cf2a01e6dbf
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/asfdec_o.c
@@ -0,0 +1,1755 @@
+/*
+ * Microsoft Advanced Streaming Format demuxer
+ * Copyright (c) 2014 Alexandra HĂ¡jkovĂ¡
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bswap.h"
+#include "libavutil/common.h"
+#include "libavutil/dict.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/time_internal.h"
+
+#include "avformat.h"
+#include "avio_internal.h"
+#include "avlanguage.h"
+#include "id3v2.h"
+#include "internal.h"
+#include "riff.h"
+#include "asf.h"
+#include "asfcrypt.h"
+
+#define ASF_BOOL 0x2
+#define ASF_WORD 0x5
+#define ASF_GUID 0x6
+#define ASF_DWORD 0x3
+#define ASF_QWORD 0x4
+#define ASF_UNICODE 0x0
+#define ASF_FLAG_BROADCAST 0x1
+#define ASF_BYTE_ARRAY 0x1
+#define ASF_TYPE_AUDIO 0x2
+#define ASF_TYPE_VIDEO 0x1
+#define ASF_STREAM_NUM 0x7F
+#define ASF_MAX_STREAMS 128
+#define BMP_HEADER_SIZE 40
+#define ASF_NUM_OF_PAYLOADS 0x3F
+#define ASF_ERROR_CORRECTION_LENGTH_TYPE 0x60
+#define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
+
+typedef struct GUIDParseTable {
+ const char *name;
+ ff_asf_guid guid;
+ int (*read_object)(AVFormatContext *, const struct GUIDParseTable *);
+ int is_subobject;
+} GUIDParseTable;
+
+typedef struct ASFPacket {
+ AVPacket avpkt;
+ int64_t dts;
+ uint32_t frame_num; // ASF payloads with the same number are parts of the same frame
+ int flags;
+ int data_size;
+ int duration;
+ int size_left;
+ uint8_t stream_index;
+} ASFPacket;
+
+typedef struct ASFStream {
+ uint8_t stream_index; // from packet header
+ int index; // stream index in AVFormatContext, set in asf_read_stream_properties
+ int type;
+ int indexed; // added index entries from the Simple Index Object or not
+ int8_t span; // for deinterleaving
+ uint16_t virtual_pkt_len;
+ uint16_t virtual_chunk_len;
+ int16_t lang_idx;
+ ASFPacket pkt;
+} ASFStream;
+
+typedef struct ASFStreamData{
+ char langs[32];
+ AVDictionary *asf_met; // for storing per-stream metadata
+ AVRational aspect_ratio;
+} ASFStreamData;
+
+typedef struct ASFContext {
+ int data_reached;
+ int is_simple_index; // is simple index present or not 1/0
+ int is_header;
+
+ uint64_t preroll;
+ uint64_t nb_packets; // ASF packets
+ uint32_t packet_size;
+ int64_t send_time;
+ int duration;
+
+ uint32_t b_flags; // flags with broadcast flag
+ uint32_t prop_flags; // file properties object flags
+
+ uint64_t data_size; // data object size
+ uint64_t unknown_size; // size of the unknown object
+
+ int64_t offset; // offset of the current object
+
+ int64_t data_offset;
+ int64_t first_packet_offset; // packet offset
+ int64_t unknown_offset; // for top level header objects or subobjects without specified behavior
+
+ // ASF file must not contain more than 128 streams according to the specification
+ ASFStream *asf_st[ASF_MAX_STREAMS];
+ ASFStreamData asf_sd[ASF_MAX_STREAMS];
+ int nb_streams;
+
+ int stream_index; // from packet header, for the subpayload case
+
+ // packet parameteres
+ uint64_t sub_header_offset; // offset of subplayload header
+ int64_t sub_dts;
+ uint8_t dts_delta; // for subpayloads
+ uint32_t packet_size_internal; // packet size stored inside ASFPacket, can be 0
+ int64_t packet_offset; // offset of the current packet inside Data Object
+ uint32_t pad_len; // padding after payload
+ uint32_t rep_data_len;
+
+ // packet state
+ uint64_t sub_left; // subpayloads left or not
+ unsigned int nb_sub; // number of subpayloads read so far from the current ASF packet
+ uint16_t mult_sub_len; // total length of subpayloads array inside multiple payload
+ uint64_t nb_mult_left; // multiple payloads left
+ int return_subpayload;
+ enum {
+ PARSE_PACKET_HEADER,
+ READ_SINGLE,
+ READ_MULTI,
+ READ_MULTI_SUB
+ } state;
+} ASFContext;
+
+static int detect_unknown_subobject(AVFormatContext *s, int64_t offset, int64_t size);
+static const GUIDParseTable *find_guid(ff_asf_guid guid);
+
+static int asf_probe(AVProbeData *pd)
+{
+ /* check file header */
+ if (!ff_guidcmp(pd->buf, &ff_asf_header))
+ return AVPROBE_SCORE_MAX/2;
+ else
+ return 0;
+}
+
+static void swap_guid(ff_asf_guid guid)
+{
+ FFSWAP(unsigned char, guid[0], guid[3]);
+ FFSWAP(unsigned char, guid[1], guid[2]);
+ FFSWAP(unsigned char, guid[4], guid[5]);
+ FFSWAP(unsigned char, guid[6], guid[7]);
+}
+
+static void align_position(AVIOContext *pb, int64_t offset, uint64_t size)
+{
+ if (avio_tell(pb) != offset + size)
+ avio_seek(pb, offset + size, SEEK_SET);
+}
+
+static int asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size = avio_rl64(pb);
+ int ret;
+
+ if (asf->is_header)
+ asf->unknown_size = size;
+ asf->is_header = 0;
+ if (!g->is_subobject) {
+ if (!(ret = strcmp(g->name, "Header Extension")))
+ avio_skip(pb, 22); // skip reserved fields and Data Size
+ if ((ret = detect_unknown_subobject(s, asf->unknown_offset,
+ asf->unknown_size)) < 0)
+ return ret;
+ } else
+ avio_skip(pb, size - 24);
+
+ return 0;
+}
+
+static int get_asf_string(AVIOContext *pb, int maxlen, char *buf, int buflen)
+{
+ char *q = buf;
+ int ret = 0;
+ if (buflen <= 0)
+ return AVERROR(EINVAL);
+ while (ret + 1 < maxlen) {
+ uint8_t tmp;
+ uint32_t ch;
+ GET_UTF16(ch, (ret += 2) <= maxlen ? avio_rl16(pb) : 0, break;);
+ PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)
+ }
+ *q = 0;
+
+ return ret;
+}
+
+static int asf_read_marker(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size = avio_rl64(pb);
+ int i, nb_markers, ret;
+ size_t len;
+ char name[1024];
+
+ avio_skip(pb, 8);
+ avio_skip(pb, 8); // skip reserved GUID
+ nb_markers = avio_rl32(pb);
+ avio_skip(pb, 2); // skip reserved field
+ len = avio_rl16(pb);
+ for (i = 0; i < len; i++)
+ avio_skip(pb, 1);
+
+ for (i = 0; i < nb_markers; i++) {
+ int64_t pts;
+
+ avio_skip(pb, 8);
+ pts = avio_rl64(pb);
+ pts -= asf->preroll * 10000;
+ avio_skip(pb, 2); // entry length
+ avio_skip(pb, 4); // send time
+ avio_skip(pb, 4); // flags
+ len = avio_rl32(pb);
+
+ if ((ret = avio_get_str16le(pb, len, name,
+ sizeof(name))) < len)
+ avio_skip(pb, len - ret);
+ avpriv_new_chapter(s, i, (AVRational) { 1, 10000000 }, pts,
+ AV_NOPTS_VALUE, name);
+ }
+ align_position(pb, asf->offset, size);
+
+ return 0;
+}
+
+static int asf_read_metadata(AVFormatContext *s, const char *title, uint16_t len,
+ unsigned char *ch, uint16_t buflen)
+{
+ AVIOContext *pb = s->pb;
+
+ avio_get_str16le(pb, len, ch, buflen);
+ if (ch[0]) {
+ if (av_dict_set(&s->metadata, title, ch, 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+ }
+
+ return 0;
+}
+
+static int asf_read_value(AVFormatContext *s, const uint8_t *name, uint16_t name_len,
+ uint16_t val_len, int type, AVDictionary **met)
+{
+ int ret;
+ uint8_t *value;
+ uint16_t buflen = 2 * val_len + 1;
+ AVIOContext *pb = s->pb;
+
+ value = av_malloc(buflen);
+ if (!value)
+ return AVERROR(ENOMEM);
+ if (type == ASF_UNICODE) {
+ // get_asf_string reads UTF-16 and converts it to UTF-8 which needs longer buffer
+ if ((ret = get_asf_string(pb, val_len, value, buflen)) < 0)
+ goto failed;
+ if (av_dict_set(met, name, value, 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+ } else {
+ char buf[256];
+ if (val_len > sizeof(buf)) {
+ ret = AVERROR_INVALIDDATA;
+ goto failed;
+ }
+ if ((ret = avio_read(pb, value, val_len)) < 0)
+ goto failed;
+ if (ret < 2 * val_len)
+ value[ret] = '\0';
+ else
+ value[2 * val_len - 1] = '\0';
+ snprintf(buf, sizeof(buf), "%s", value);
+ if (av_dict_set(met, name, buf, 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+ }
+ av_freep(&value);
+
+ return 0;
+
+failed:
+ av_freep(&value);
+ return ret;
+}
+static int asf_read_generic_value(AVIOContext *pb, int type, uint64_t *value)
+{
+
+ switch (type) {
+ case ASF_BOOL:
+ *value = avio_rl16(pb);
+ break;
+ case ASF_DWORD:
+ *value = avio_rl32(pb);
+ break;
+ case ASF_QWORD:
+ *value = avio_rl64(pb);
+ break;
+ case ASF_WORD:
+ *value = avio_rl16(pb);
+ break;
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+static int asf_set_metadata(AVFormatContext *s, const uint8_t *name,
+ uint16_t name_len, int type, AVDictionary **met)
+{
+ AVIOContext *pb = s->pb;
+ uint64_t value;
+ char buf[32];
+ int ret;
+
+ ret = asf_read_generic_value(pb, type, &value);
+ if (ret < 0)
+ return ret;
+
+ snprintf(buf, sizeof(buf), "%"PRIu64, value);
+ if (av_dict_set(met, name, buf, 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+
+ return 0;
+}
+
+/* MSDN claims that this should be "compatible with the ID3 frame, APIC",
+ * but in reality this is only loosely similar */
+static int asf_read_picture(AVFormatContext *s, int len)
+{
+ ASFContext *asf = s->priv_data;
+ AVPacket pkt = { 0 };
+ const CodecMime *mime = ff_id3v2_mime_tags;
+ enum AVCodecID id = AV_CODEC_ID_NONE;
+ char mimetype[64];
+ uint8_t *desc = NULL;
+ AVStream *st = NULL;
+ int ret, type, picsize, desc_len;
+ ASFStream *asf_st;
+
+ /* type + picsize + mime + desc */
+ if (len < 1 + 4 + 2 + 2) {
+ av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* picture type */
+ type = avio_r8(s->pb);
+ len--;
+ if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+ av_log(s, AV_LOG_WARNING, "Unknown attached picture type: %d.\n", type);
+ type = 0;
+ }
+
+ /* picture data size */
+ picsize = avio_rl32(s->pb);
+ len -= 4;
+
+ /* picture MIME type */
+ len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype));
+ while (mime->id != AV_CODEC_ID_NONE) {
+ if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
+ id = mime->id;
+ break;
+ }
+ mime++;
+ }
+ if (id == AV_CODEC_ID_NONE) {
+ av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
+ mimetype);
+ return 0;
+ }
+
+ if (picsize >= len) {
+ av_log(s, AV_LOG_ERROR, "Invalid attached picture data size: %d >= %d.\n",
+ picsize, len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* picture description */
+ desc_len = (len - picsize) * 2 + 1;
+ desc = av_malloc(desc_len);
+ if (!desc)
+ return AVERROR(ENOMEM);
+ len -= avio_get_str16le(s->pb, len - picsize, desc, desc_len);
+
+ ret = av_get_packet(s->pb, &pkt, picsize);
+ if (ret < 0)
+ goto fail;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ asf->asf_st[asf->nb_streams] = av_mallocz(sizeof(*asf_st));
+ asf_st = asf->asf_st[asf->nb_streams];
+ if (!asf_st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+ st->codec->codec_type = asf_st->type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = id;
+ st->attached_pic = pkt;
+ st->attached_pic.stream_index = asf_st->index = st->index;
+ st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+
+ asf->nb_streams++;
+
+ if (*desc) {
+ if (av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+ } else
+ av_freep(&desc);
+
+ if (av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+
+ return 0;
+
+fail:
+ av_freep(&desc);
+ av_free_packet(&pkt);
+ return ret;
+}
+
+static void get_id3_tag(AVFormatContext *s, int len)
+{
+ ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+
+ ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len);
+ if (id3v2_extra_meta)
+ ff_id3v2_parse_apic(s, &id3v2_extra_meta);
+ ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+}
+
+static int process_metadata(AVFormatContext *s, const uint8_t *name, uint16_t name_len,
+ uint16_t val_len, uint16_t type, AVDictionary **met)
+{
+ int ret;
+ ff_asf_guid guid;
+
+ if (val_len) {
+ switch (type) {
+ case ASF_UNICODE:
+ asf_read_value(s, name, name_len, val_len, type, met);
+ break;
+ case ASF_BYTE_ARRAY:
+ if (!strcmp(name, "WM/Picture")) // handle cover art
+ asf_read_picture(s, val_len);
+ else if (!strcmp(name, "ID3")) // handle ID3 tag
+ get_id3_tag(s, val_len);
+ else
+ asf_read_value(s, name, name_len, val_len, type, met);
+ break;
+ case ASF_GUID:
+ ff_get_guid(s->pb, &guid);
+ break;
+ default:
+ if ((ret = asf_set_metadata(s, name, name_len, type, met)) < 0)
+ return ret;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int asf_read_ext_content(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size = avio_rl64(pb);
+ uint16_t nb_desc = avio_rl16(pb);
+ int i, ret;
+
+ for (i = 0; i < nb_desc; i++) {
+ uint16_t name_len, type, val_len;
+ uint8_t *name = NULL;
+
+ name_len = avio_rl16(pb);
+ if (!name_len)
+ return AVERROR_INVALIDDATA;
+ name = av_malloc(name_len);
+ if (!name)
+ return AVERROR(ENOMEM);
+ avio_get_str16le(pb, name_len, name,
+ name_len);
+ type = avio_rl16(pb);
+ // BOOL values are 16 bits long in the Metadata Object
+ // but 32 bits long in the Extended Content Description Object
+ if (type == ASF_BOOL)
+ type = ASF_DWORD;
+ val_len = avio_rl16(pb);
+
+ ret = process_metadata(s, name, name_len, val_len, type, &s->metadata);
+ av_freep(&name);
+ if (ret < 0)
+ return ret;
+ }
+
+ align_position(pb, asf->offset, size);
+ return 0;
+}
+
+static AVStream *find_stream(AVFormatContext *s, uint16_t st_num)
+{
+ AVStream *st = NULL;
+ ASFContext *asf = s->priv_data;
+ int i;
+
+ for (i = 0; i < asf->nb_streams; i++) {
+ if (asf->asf_st[i]->stream_index == st_num) {
+ st = s->streams[asf->asf_st[i]->index];
+ break;
+ }
+ }
+
+ return st;
+}
+
+static int asf_store_aspect_ratio(AVFormatContext *s, uint8_t st_num, uint8_t *name, int type)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t value = 0;
+ int ret;
+
+ ret = asf_read_generic_value(pb, type, &value);
+ if (ret < 0)
+ return ret;
+
+ if (st_num < ASF_MAX_STREAMS) {
+ if (!strcmp(name, "AspectRatioX"))
+ asf->asf_sd[st_num].aspect_ratio.num = value;
+ else
+ asf->asf_sd[st_num].aspect_ratio.den = value;
+ }
+ return 0;
+}
+
+static int asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size = avio_rl64(pb);
+ uint16_t nb_recs = avio_rl16(pb); // number of records in the Description Records list
+ int i, ret;
+
+ for (i = 0; i < nb_recs; i++) {
+ uint16_t name_len, buflen, type, val_len, st_num;
+ uint8_t *name = NULL;
+
+ avio_skip(pb, 2); // skip reserved field
+ st_num = avio_rl16(pb);
+ name_len = avio_rl16(pb);
+ buflen = 2 * name_len + 1;
+ if (!name_len)
+ break;
+ type = avio_rl16(pb);
+ val_len = avio_rl32(pb);
+ name = av_malloc(buflen);
+ if (!name)
+ return AVERROR(ENOMEM);
+ avio_get_str16le(pb, name_len, name,
+ buflen);
+ if (!strcmp(name, "AspectRatioX") || !strcmp(name, "AspectRatioY")) {
+ ret = asf_store_aspect_ratio(s, st_num, name, type);
+ if (ret < 0) {
+ av_freep(&name);
+ break;
+ }
+ } else {
+ if (st_num < ASF_MAX_STREAMS) {
+ if ((ret = process_metadata(s, name, name_len, val_len, type,
+ &asf->asf_sd[st_num].asf_met)) < 0) {
+ av_freep(&name);
+ break;
+ }
+ }
+ }
+ av_freep(&name);
+ }
+
+ align_position(pb, asf->offset, size);
+ return 0;
+}
+
+static int asf_read_content_desc(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int i;
+ static const char *const titles[] =
+ { "Title", "Author", "Copyright", "Description", "Rate" };
+ uint16_t len[5], buflen[5] = { 0 };
+ uint8_t *ch;
+ uint64_t size = avio_rl64(pb);
+
+ for (i = 0; i < 5; i++) {
+ len[i] = avio_rl16(pb);
+ // utf8 string should be <= 2 * utf16 string, extra byte for the terminator
+ buflen[i] = 2 * len[i] + 1;
+ }
+
+ for (i = 0; i < 5; i++) {
+ ch = av_malloc(buflen[i]);
+ if (!ch)
+ return(AVERROR(ENOMEM));
+ asf_read_metadata(s, titles[i], len[i], ch, buflen[i]);
+ av_freep(&ch);
+ }
+ align_position(pb, asf->offset, size);
+
+ return 0;
+}
+
+static int asf_read_properties(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ time_t creation_time;
+
+ avio_rl64(pb); // read object size
+ avio_skip(pb, 16); // skip File ID
+ avio_skip(pb, 8); // skip File size
+ creation_time = avio_rl64(pb);
+ if (!(asf->b_flags & ASF_FLAG_BROADCAST)) {
+ struct tm tmbuf;
+ struct tm *tm;
+ char buf[64];
+
+ // creation date is in 100 ns units from 1 Jan 1601, conversion to s
+ creation_time /= 10000000;
+ // there are 11644473600 seconds between 1 Jan 1601 and 1 Jan 1970
+ creation_time -= 11644473600;
+ tm = gmtime_r(&creation_time, &tmbuf);
+ if (tm) {
+ if (!strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm))
+ buf[0] = '\0';
+ } else
+ buf[0] = '\0';
+ if (buf[0]) {
+ if (av_dict_set(&s->metadata, "creation_time", buf, 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+ }
+ }
+ asf->nb_packets = avio_rl64(pb);
+ asf->duration = avio_rl64(pb) / 10000; // stream duration
+ avio_skip(pb, 8); // skip send duration
+ asf->preroll = avio_rl64(pb);
+ asf->duration -= asf->preroll;
+ asf->b_flags = avio_rl32(pb);
+ avio_skip(pb, 4); // skip minimal packet size
+ asf->packet_size = avio_rl32(pb);
+ avio_skip(pb, 4); // skip max_bitrate
+
+ return 0;
+}
+
+static int parse_video_info(AVIOContext *pb, AVStream *st)
+{
+ uint16_t size;
+ unsigned int tag;
+
+ st->codec->width = avio_rl32(pb);
+ st->codec->height = avio_rl32(pb);
+ avio_skip(pb, 1); // skip reserved flags
+ size = avio_rl16(pb); // size of the Format Data
+ tag = ff_get_bmp_header(pb, st, NULL);
+ st->codec->codec_tag = tag;
+ st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag);
+
+ if (size > BMP_HEADER_SIZE) {
+ int ret;
+ st->codec->extradata_size = size - BMP_HEADER_SIZE;
+ if (!(st->codec->extradata = av_malloc(st->codec->extradata_size +
+ AV_INPUT_BUFFER_PADDING_SIZE))) {
+ st->codec->extradata_size = 0;
+ return AVERROR(ENOMEM);
+ }
+ memset(st->codec->extradata + st->codec->extradata_size , 0,
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ if ((ret = avio_read(pb, st->codec->extradata,
+ st->codec->extradata_size)) < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int asf_read_stream_properties(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size;
+ uint32_t err_data_len, ts_data_len; // type specific data length
+ uint16_t flags;
+ ff_asf_guid stream_type;
+ enum AVMediaType type;
+ int i, ret;
+ uint8_t stream_index;
+ AVStream *st;
+ ASFStream *asf_st;
+
+ // ASF file must not contain more than 128 streams according to the specification
+ if (asf->nb_streams >= ASF_MAX_STREAMS)
+ return AVERROR_INVALIDDATA;
+
+ size = avio_rl64(pb);
+ ff_get_guid(pb, &stream_type);
+ if (!ff_guidcmp(&stream_type, &ff_asf_audio_stream))
+ type = AVMEDIA_TYPE_AUDIO;
+ else if (!ff_guidcmp(&stream_type, &ff_asf_video_stream))
+ type = AVMEDIA_TYPE_VIDEO;
+ else if (!ff_guidcmp(&stream_type, &ff_asf_jfif_media))
+ type = AVMEDIA_TYPE_VIDEO;
+ else if (!ff_guidcmp(&stream_type, &ff_asf_command_stream))
+ type = AVMEDIA_TYPE_DATA;
+ else if (!ff_guidcmp(&stream_type,
+ &ff_asf_ext_stream_embed_stream_header))
+ type = AVMEDIA_TYPE_UNKNOWN;
+ else
+ return AVERROR_INVALIDDATA;
+
+ ff_get_guid(pb, &stream_type); // error correction type
+ avio_skip(pb, 8); // skip the time offset
+ ts_data_len = avio_rl32(pb);
+ err_data_len = avio_rl32(pb);
+ flags = avio_rl16(pb); // bit 15 - Encrypted Content
+
+ stream_index = flags & ASF_STREAM_NUM;
+ for (i = 0; i < asf->nb_streams; i++)
+ if (stream_index == asf->asf_st[i]->stream_index) {
+ av_log(s, AV_LOG_WARNING,
+ "Duplicate stream found, this stream will be ignored.\n");
+ align_position(pb, asf->offset, size);
+ return 0;
+ }
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ avpriv_set_pts_info(st, 32, 1, 1000); // pts should be dword, in milliseconds
+ st->codec->codec_type = type;
+ asf->asf_st[asf->nb_streams] = av_mallocz(sizeof(*asf_st));
+ if (!asf->asf_st[asf->nb_streams])
+ return AVERROR(ENOMEM);
+ asf_st = asf->asf_st[asf->nb_streams];
+ asf->nb_streams++;
+ asf_st->stream_index = stream_index;
+ asf_st->index = st->index;
+ asf_st->indexed = 0;
+ st->id = flags & ASF_STREAM_NUM;
+ av_init_packet(&asf_st->pkt.avpkt);
+ asf_st->pkt.data_size = 0;
+ avio_skip(pb, 4); // skip reserved field
+
+ switch (type) {
+ case AVMEDIA_TYPE_AUDIO:
+ asf_st->type = AVMEDIA_TYPE_AUDIO;
+ if ((ret = ff_get_wav_header(s, pb, st->codec, ts_data_len, 0)) < 0)
+ return ret;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ asf_st->type = AVMEDIA_TYPE_VIDEO;
+ if ((ret = parse_video_info(pb, st)) < 0)
+ return ret;
+ break;
+ default:
+ avio_skip(pb, ts_data_len);
+ break;
+ }
+
+ if (err_data_len) {
+ if (type == AVMEDIA_TYPE_AUDIO) {
+ uint8_t span = avio_r8(pb);
+ if (span > 1) {
+ asf_st->span = span;
+ asf_st->virtual_pkt_len = avio_rl16(pb);
+ asf_st->virtual_chunk_len = avio_rl16(pb);
+ if (!asf_st->virtual_chunk_len || !asf_st->virtual_pkt_len)
+ return AVERROR_INVALIDDATA;
+ avio_skip(pb, err_data_len - 5);
+ } else
+ avio_skip(pb, err_data_len - 1);
+ } else
+ avio_skip(pb, err_data_len);
+ }
+
+ align_position(pb, asf->offset, size);
+
+ return 0;
+}
+
+static void set_language(AVFormatContext *s, const char *rfc1766, AVDictionary **met)
+{
+ // language abbr should contain at least 2 chars
+ if (rfc1766 && strlen(rfc1766) > 1) {
+ const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any
+ const char *iso6392 = av_convert_lang_to(primary_tag,
+ AV_LANG_ISO639_2_BIBL);
+ if (iso6392)
+ if (av_dict_set(met, "language", iso6392, 0) < 0)
+ av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
+ }
+}
+
+static int asf_read_ext_stream_properties(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVStream *st = NULL;
+ ff_asf_guid guid;
+ uint16_t nb_st_name, nb_pay_exts, st_num, lang_idx;
+ int i, ret;
+ uint32_t bitrate;
+ uint64_t start_time, end_time, time_per_frame;
+ uint64_t size = avio_rl64(pb);
+
+ start_time = avio_rl64(pb);
+ end_time = avio_rl64(pb);
+ bitrate = avio_rl32(pb);
+ avio_skip(pb, 28); // skip some unused values
+ st_num = avio_rl16(pb);
+ st_num &= ASF_STREAM_NUM;
+ lang_idx = avio_rl16(pb); // Stream Language ID Index
+ for (i = 0; i < asf->nb_streams; i++) {
+ if (st_num == asf->asf_st[i]->stream_index) {
+ st = s->streams[asf->asf_st[i]->index];
+ asf->asf_st[i]->lang_idx = lang_idx;
+ break;
+ }
+ }
+ time_per_frame = avio_rl64(pb); // average time per frame
+ if (st) {
+ st->start_time = start_time;
+ st->duration = end_time - start_time;
+ st->codec->bit_rate = bitrate;
+ st->avg_frame_rate.num = 10000000;
+ st->avg_frame_rate.den = time_per_frame;
+ }
+ nb_st_name = avio_rl16(pb);
+ nb_pay_exts = avio_rl16(pb);
+ for (i = 0; i < nb_st_name; i++) {
+ uint16_t len;
+
+ avio_rl16(pb); // Language ID Index
+ len = avio_rl16(pb);
+ avio_skip(pb, len);
+ }
+
+ for (i = 0; i < nb_pay_exts; i++) {
+ uint32_t len;
+ avio_skip(pb, 16); // Extension System ID
+ avio_skip(pb, 2); // Extension Data Size
+ len = avio_rl32(pb);
+ avio_skip(pb, len);
+ }
+
+ if ((ret = ff_get_guid(pb, &guid)) < 0) {
+ align_position(pb, asf->offset, size);
+
+ return 0;
+ }
+
+ g = find_guid(guid);
+ if (g && !(strcmp(g->name, "Stream Properties"))) {
+ if ((ret = g->read_object(s, g)) < 0)
+ return ret;
+ }
+
+ align_position(pb, asf->offset, size);
+ return 0;
+}
+
+static int asf_read_language_list(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int i, ret;
+ uint64_t size = avio_rl64(pb);
+ uint16_t nb_langs = avio_rl16(pb);
+
+ if (nb_langs < ASF_MAX_STREAMS) {
+ for (i = 0; i < nb_langs; i++) {
+ size_t len;
+ len = avio_r8(pb);
+ if (!len)
+ len = 6;
+ if ((ret = get_asf_string(pb, len, asf->asf_sd[i].langs,
+ sizeof(asf->asf_sd[i].langs))) < 0) {
+ return ret;
+ }
+ }
+ }
+
+ align_position(pb, asf->offset, size);
+ return 0;
+}
+
+// returns data object offset when reading this object for the first time
+static int asf_read_data(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size = asf->data_size = avio_rl64(pb);
+ int i;
+
+ if (!asf->data_reached) {
+ asf->data_reached = 1;
+ asf->data_offset = asf->offset;
+ }
+
+ for (i = 0; i < asf->nb_streams; i++) {
+ if (!(asf->b_flags & ASF_FLAG_BROADCAST))
+ s->streams[i]->duration = asf->duration;
+ }
+ asf->nb_mult_left = 0;
+ asf->sub_left = 0;
+ asf->state = PARSE_PACKET_HEADER;
+ asf->return_subpayload = 0;
+ asf->packet_size_internal = 0;
+ avio_skip(pb, 16); // skip File ID
+ size = avio_rl64(pb); // Total Data Packets
+ if (size != asf->nb_packets)
+ av_log(s, AV_LOG_WARNING,
+ "Number of Packets from File Properties Object is not equal to Total"
+ "Datapackets value! num of packets %"PRIu64" total num %"PRIu64".\n",
+ size, asf->nb_packets);
+ avio_skip(pb, 2); // skip reserved field
+ asf->first_packet_offset = avio_tell(pb);
+ if (pb->seekable && !(asf->b_flags & ASF_FLAG_BROADCAST))
+ align_position(pb, asf->offset, asf->data_size);
+
+ return 0;
+}
+
+static int asf_read_simple_index(AVFormatContext *s, const GUIDParseTable *g)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVStream *st = NULL;
+ uint64_t interval; // index entry time interval in 100 ns units, usually it's 1s
+ uint32_t pkt_num, nb_entries;
+ int32_t prev_pkt_num = -1;
+ int i;
+ uint64_t size = avio_rl64(pb);
+
+ // simple index objects should be ordered by stream number, this loop tries to find
+ // the first not indexed video stream
+ for (i = 0; i < asf->nb_streams; i++) {
+ if ((asf->asf_st[i]->type == AVMEDIA_TYPE_VIDEO) && !asf->asf_st[i]->indexed) {
+ asf->asf_st[i]->indexed = 1;
+ st = s->streams[asf->asf_st[i]->index];
+ break;
+ }
+ }
+ if (!st) {
+ avio_skip(pb, size - 24); // if there's no video stream, skip index object
+ return 0;
+ }
+ avio_skip(pb, 16); // skip File ID
+ interval = avio_rl64(pb);
+ avio_skip(pb, 4);
+ nb_entries = avio_rl32(pb);
+ for (i = 0; i < nb_entries; i++) {
+ pkt_num = avio_rl32(pb);
+ avio_skip(pb, 2);
+ if (prev_pkt_num != pkt_num) {
+ av_add_index_entry(st, asf->first_packet_offset + asf->packet_size *
+ pkt_num, av_rescale(interval, i, 10000),
+ asf->packet_size, 0, AVINDEX_KEYFRAME);
+ prev_pkt_num = pkt_num;
+ }
+ }
+ asf->is_simple_index = 1;
+ align_position(pb, asf->offset, size);
+
+ return 0;
+}
+
+static const GUIDParseTable gdef[] = {
+ { "Data", { 0x75, 0xB2, 0x26, 0x36, 0x66, 0x8E, 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, asf_read_data, 1 },
+ { "Simple Index", { 0x33, 0x00, 0x08, 0x90, 0xE5, 0xB1, 0x11, 0xCF, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB }, asf_read_simple_index, 1 },
+ { "Content Description", { 0x75, 0xB2, 0x26, 0x33, 0x66 ,0x8E, 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, asf_read_content_desc, 1 },
+ { "Extended Content Description", { 0xD2, 0xD0, 0xA4, 0x40, 0xE3, 0x07, 0x11, 0xD2, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5e, 0xA8, 0x50 }, asf_read_ext_content, 1 },
+ { "Stream Bitrate Properties", { 0x7B, 0xF8, 0x75, 0xCE, 0x46, 0x8D, 0x11, 0xD1, 0x8D, 0x82, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xB2 }, asf_read_unknown, 1 },
+ { "File Properties", { 0x8C, 0xAB, 0xDC, 0xA1, 0xA9, 0x47, 0x11, 0xCF, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_properties, 1 },
+ { "Header Extension", { 0x5F, 0xBF, 0x03, 0xB5, 0xA9, 0x2E, 0x11, 0xCF, 0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_unknown, 0 },
+ { "Stream Properties", { 0xB7, 0xDC, 0x07, 0x91, 0xA9, 0xB7, 0x11, 0xCF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_stream_properties, 1 },
+ { "Codec List", { 0x86, 0xD1, 0x52, 0x40, 0x31, 0x1D, 0x11, 0xD0, 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }, asf_read_unknown, 1 },
+ { "Marker", { 0xF4, 0x87, 0xCD, 0x01, 0xA9, 0x51, 0x11, 0xCF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_marker, 1 },
+ { "Script Command", { 0x1E, 0xFB, 0x1A, 0x30, 0x0B, 0x62, 0x11, 0xD0, 0xA3, 0x9B, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }, asf_read_unknown, 1 },
+ { "Language List", { 0x7C, 0x43, 0x46, 0xa9, 0xef, 0xe0, 0x4B, 0xFC, 0xB2, 0x29, 0x39, 0x3e, 0xde, 0x41, 0x5c, 0x85 }, asf_read_language_list, 1},
+ { "Padding", { 0x18, 0x06, 0xD4, 0x74, 0xCA, 0xDF, 0x45, 0x09, 0xA4, 0xBA, 0x9A, 0xAB, 0xCB, 0x96, 0xAA, 0xE8 }, asf_read_unknown, 1 },
+ { "DRMv1 Header", { 0x22, 0x11, 0xB3, 0xFB, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
+ { "DRMv2 Header", { 0x29, 0x8A, 0xE6, 0x14, 0x26, 0x22, 0x4C, 0x17, 0xB9, 0x35, 0xDA, 0xE0, 0x7E, 0xE9, 0x28, 0x9c }, asf_read_unknown, 1 },
+ { "Index", { 0xD6, 0xE2, 0x29, 0xD3, 0x35, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
+ { "Media Object Index", { 0xFE, 0xB1, 0x03, 0xF8, 0x12, 0xAD, 0x4C, 0x64, 0x84, 0x0F, 0x2A, 0x1D, 0x2F, 0x7A, 0xD4, 0x8C }, asf_read_unknown, 1 },
+ { "Timecode Index", { 0x3C, 0xB7, 0x3F, 0xD0, 0x0C, 0x4A, 0x48, 0x03, 0x95, 0x3D, 0xED, 0xF7, 0xB6, 0x22, 0x8F, 0x0C }, asf_read_unknown, 0 },
+ { "Bitrate_Mutual_Exclusion", { 0xD6, 0xE2, 0x29, 0xDC, 0x35, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
+ { "Error Correction", { 0x75, 0xB2, 0x26, 0x35, 0x66, 0x8E, 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, asf_read_unknown, 1 },
+ { "Content Branding", { 0x22, 0x11, 0xB3, 0xFA, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
+ { "Content Encryption", { 0x22, 0x11, 0xB3, 0xFB, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
+ { "Extended Content Encryption", { 0x29, 0x8A, 0xE6, 0x14, 0x26, 0x22, 0x4C, 0x17, 0xB9, 0x35, 0xDA, 0xE0, 0x7E, 0xE9, 0x28, 0x9C }, asf_read_unknown, 1 },
+ { "Digital Signature", { 0x22, 0x11, 0xB3, 0xFC, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
+ { "Extended Stream Properties", { 0x14, 0xE6, 0xA5, 0xCB, 0xC6, 0x72, 0x43, 0x32, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A }, asf_read_ext_stream_properties, 1 },
+ { "Advanced Mutual Exclusion", { 0xA0, 0x86, 0x49, 0xCF, 0x47, 0x75, 0x46, 0x70, 0x8A, 0x16, 0x6E, 0x35, 0x35, 0x75, 0x66, 0xCD }, asf_read_unknown, 1 },
+ { "Group Mutual Exclusion", { 0xD1, 0x46, 0x5A, 0x40, 0x5A, 0x79, 0x43, 0x38, 0xB7, 0x1B, 0xE3, 0x6B, 0x8F, 0xD6, 0xC2, 0x49 }, asf_read_unknown, 1},
+ { "Stream Prioritization", { 0xD4, 0xFE, 0xD1, 0x5B, 0x88, 0xD3, 0x45, 0x4F, 0x81, 0xF0, 0xED, 0x5C, 0x45, 0x99, 0x9E, 0x24 }, asf_read_unknown, 1 },
+ { "Bandwidth Sharing Object", { 0xA6, 0x96, 0x09, 0xE6, 0x51, 0x7B, 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9 }, asf_read_unknown, 1 },
+ { "Metadata", { 0xC5, 0xF8, 0xCB, 0xEA, 0x5B, 0xAF, 0x48, 0x77, 0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA }, asf_read_metadata_obj, 1 },
+ { "Metadata Library", { 0x44, 0x23, 0x1C, 0x94, 0x94, 0x98, 0x49, 0xD1, 0xA1, 0x41, 0x1D, 0x13, 0x4E, 0x45, 0x70, 0x54 }, asf_read_metadata_obj, 1 },
+ { "Audio Spread", { 0xBF, 0xC3, 0xCD, 0x50, 0x61, 0x8F, 0x11, 0xCF, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20 }, asf_read_unknown, 1 },
+ { "Index Parameters", { 0xD6, 0xE2, 0x29, 0xDF, 0x35, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
+ { "Content Encryption System Windows Media DRM Network Devices",
+ { 0x7A, 0x07, 0x9B, 0xB6, 0xDA, 0XA4, 0x4e, 0x12, 0xA5, 0xCA, 0x91, 0xD3, 0x8D, 0xC1, 0x1A, 0x8D }, asf_read_unknown, 1 },
+ { "Mutex Language", { 0xD6, 0xE2, 0x2A, 0x00, 0x25, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
+ { "Mutex Bitrate", { 0xD6, 0xE2, 0x2A, 0x01, 0x25, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
+ { "Mutex Unknown", { 0xD6, 0xE2, 0x2A, 0x02, 0x25, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
+ { "Bandwith Sharing Exclusive", { 0xAF, 0x60, 0x60, 0xAA, 0x51, 0x97, 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9 }, asf_read_unknown, 1 },
+ { "Bandwith Sharing Partial", { 0xAF, 0x60, 0x60, 0xAB, 0x51, 0x97, 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9 }, asf_read_unknown, 1 },
+ { "Payload Extension System Timecode", { 0x39, 0x95, 0x95, 0xEC, 0x86, 0x67, 0x4E, 0x2D, 0x8F, 0xDB, 0x98, 0x81, 0x4C, 0xE7, 0x6C, 0x1E }, asf_read_unknown, 1 },
+ { "Payload Extension System File Name", { 0xE1, 0x65, 0xEC, 0x0E, 0x19, 0xED, 0x45, 0xD7, 0xB4, 0xA7, 0x25, 0xCB, 0xD1, 0xE2, 0x8E, 0x9B }, asf_read_unknown, 1 },
+ { "Payload Extension System Content Type", { 0xD5, 0x90, 0xDC, 0x20, 0x07, 0xBC, 0x43, 0x6C, 0x9C, 0xF7, 0xF3, 0xBB, 0xFB, 0xF1, 0xA4, 0xDC }, asf_read_unknown, 1 },
+ { "Payload Extension System Pixel Aspect Ratio", { 0x1, 0x1E, 0xE5, 0x54, 0xF9, 0xEA, 0x4B, 0xC8, 0x82, 0x1A, 0x37, 0x6B, 0x74, 0xE4, 0xC4, 0xB8 }, asf_read_unknown, 1 },
+ { "Payload Extension System Sample Duration", { 0xC6, 0xBD, 0x94, 0x50, 0x86, 0x7F, 0x49, 0x07, 0x83, 0xA3, 0xC7, 0x79, 0x21, 0xB7, 0x33, 0xAD }, asf_read_unknown, 1 },
+ { "Payload Extension System Encryption Sample ID", { 0x66, 0x98, 0xB8, 0x4E, 0x0A, 0xFA, 0x43, 0x30, 0xAE, 0xB2, 0x1C, 0x0A, 0x98, 0xD7, 0xA4, 0x4D }, asf_read_unknown, 1 },
+ { "Payload Extension System Degradable JPEG", { 0x00, 0xE1, 0xAF, 0x06, 0x7B, 0xEC, 0x11, 0xD1, 0xA5, 0x82, 0x00, 0xC0, 0x4F, 0xC2, 0x9C, 0xFB }, asf_read_unknown, 1 },
+};
+
+#define READ_LEN(flag, name, len) \
+ do { \
+ if ((flag) == name ## IS_BYTE) \
+ len = avio_r8(pb); \
+ else if ((flag) == name ## IS_WORD) \
+ len = avio_rl16(pb); \
+ else if ((flag) == name ## IS_DWORD) \
+ len = avio_rl32(pb); \
+ else \
+ len = 0; \
+ } while(0)
+
+static int asf_read_subpayload(AVFormatContext *s, AVPacket *pkt, int is_header)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint8_t sub_len;
+ int ret, i;
+
+ if (is_header) {
+ asf->dts_delta = avio_r8(pb);
+ if (asf->nb_mult_left) {
+ asf->mult_sub_len = avio_rl16(pb); // total
+ }
+ asf->sub_header_offset = avio_tell(pb);
+ asf->nb_sub = 0;
+ asf->sub_left = 1;
+ }
+ sub_len = avio_r8(pb);
+ if ((ret = av_get_packet(pb, pkt, sub_len)) < 0) // each subpayload is entire frame
+ return ret;
+ for (i = 0; i < asf->nb_streams; i++) {
+ if (asf->stream_index == asf->asf_st[i]->stream_index) {
+ pkt->stream_index = asf->asf_st[i]->index;
+ break;
+ }
+ }
+ asf->return_subpayload = 1;
+ if (!sub_len)
+ asf->return_subpayload = 0;
+
+ if (sub_len)
+ asf->nb_sub++;
+ pkt->dts = asf->sub_dts + (asf->nb_sub - 1) * asf->dts_delta - asf->preroll;
+ if (asf->nb_mult_left && (avio_tell(pb) >=
+ (asf->sub_header_offset + asf->mult_sub_len))) {
+ asf->sub_left = 0;
+ asf->nb_mult_left--;
+ }
+ if (avio_tell(pb) >= asf->packet_offset + asf->packet_size - asf->pad_len) {
+ asf->sub_left = 0;
+ if (!asf->nb_mult_left) {
+ avio_skip(pb, asf->pad_len);
+ if (avio_tell(pb) != asf->packet_offset + asf->packet_size) {
+ if (!asf->packet_size)
+ return AVERROR_INVALIDDATA;
+ av_log(s, AV_LOG_WARNING,
+ "Position %"PRId64" wrong, should be %"PRId64"\n",
+ avio_tell(pb), asf->packet_offset + asf->packet_size);
+ avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void reset_packet(ASFPacket *asf_pkt)
+{
+ asf_pkt->size_left = 0;
+ asf_pkt->data_size = 0;
+ asf_pkt->duration = 0;
+ asf_pkt->flags = 0;
+ asf_pkt->dts = 0;
+ asf_pkt->duration = 0;
+ av_free_packet(&asf_pkt->avpkt);
+ av_init_packet(&asf_pkt->avpkt);
+}
+
+static int asf_read_replicated_data(AVFormatContext *s, ASFPacket *asf_pkt)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int ret;
+
+ if (!asf_pkt->data_size) {
+ asf_pkt->data_size = asf_pkt->size_left = avio_rl32(pb); // read media object size
+ if (asf_pkt->data_size <= 0)
+ return AVERROR_INVALIDDATA;
+ if ((ret = av_new_packet(&asf_pkt->avpkt, asf_pkt->data_size)) < 0)
+ return ret;
+ } else
+ avio_skip(pb, 4); // reading of media object size is already done
+ asf_pkt->dts = avio_rl32(pb); // read presentation time
+ if (asf->rep_data_len && (asf->rep_data_len >= 8))
+ avio_skip(pb, asf->rep_data_len - 8); // skip replicated data
+
+ return 0;
+}
+
+static int asf_read_multiple_payload(AVFormatContext *s, AVPacket *pkt,
+ ASFPacket *asf_pkt)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint16_t pay_len;
+ unsigned char *p;
+ int ret;
+ int skip = 0;
+
+ // if replicated lenght is 1, subpayloads are present
+ if (asf->rep_data_len == 1) {
+ asf->sub_left = 1;
+ asf->state = READ_MULTI_SUB;
+ pkt->flags = asf_pkt->flags;
+ if ((ret = asf_read_subpayload(s, pkt, 1)) < 0)
+ return ret;
+ } else {
+ if (asf->rep_data_len)
+ if ((ret = asf_read_replicated_data(s, asf_pkt)) < 0)
+ return ret;
+ pay_len = avio_rl16(pb); // payload length should be WORD
+ if (pay_len > asf->packet_size) {
+ av_log(s, AV_LOG_ERROR,
+ "Error: invalid data packet size, pay_len %"PRIu16", "
+ "asf->packet_size %"PRIu32", offset %"PRId64".\n",
+ pay_len, asf->packet_size, avio_tell(pb));
+ return AVERROR_INVALIDDATA;
+ }
+ p = asf_pkt->avpkt.data + asf_pkt->data_size - asf_pkt->size_left;
+ if (pay_len > asf_pkt->size_left) {
+ av_log(s, AV_LOG_ERROR,
+ "Error: invalid buffer size, pay_len %d, data size left %d.\n",
+ pay_len, asf_pkt->size_left);
+ skip = pay_len - asf_pkt->size_left;
+ pay_len = asf_pkt->size_left;
+ }
+ if (asf_pkt->size_left <= 0)
+ return AVERROR_INVALIDDATA;
+ if ((ret = avio_read(pb, p, pay_len)) < 0)
+ return ret;
+ if (s->key && s->keylen == 20)
+ ff_asfcrypt_dec(s->key, p, ret);
+ avio_skip(pb, skip);
+ asf_pkt->size_left -= pay_len;
+ asf->nb_mult_left--;
+ }
+
+ return 0;
+}
+
+static int asf_read_single_payload(AVFormatContext *s, AVPacket *pkt,
+ ASFPacket *asf_pkt)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int64_t offset;
+ uint64_t size;
+ unsigned char *p;
+ int ret;
+
+ if (!asf_pkt->data_size) {
+ asf_pkt->data_size = asf_pkt->size_left = avio_rl32(pb); // read media object size
+ if (asf_pkt->data_size <= 0)
+ return AVERROR_EOF;
+ if ((ret = av_new_packet(&asf_pkt->avpkt, asf_pkt->data_size)) < 0)
+ return ret;
+ } else
+ avio_skip(pb, 4); // skip media object size
+ asf_pkt->dts = avio_rl32(pb); // read presentation time
+ if (asf->rep_data_len >= 8)
+ avio_skip(pb, asf->rep_data_len - 8); // skip replicated data
+ offset = avio_tell(pb);
+
+ // size of the payload - size of the packet without header and padding
+ if (asf->packet_size_internal)
+ size = asf->packet_size_internal - offset + asf->packet_offset - asf->pad_len;
+ else
+ size = asf->packet_size - offset + asf->packet_offset - asf->pad_len;
+ if (size > asf->packet_size) {
+ av_log(s, AV_LOG_ERROR,
+ "Error: invalid data packet size, offset %"PRId64".\n",
+ avio_tell(pb));
+ return AVERROR_INVALIDDATA;
+ }
+ p = asf_pkt->avpkt.data + asf_pkt->data_size - asf_pkt->size_left;
+ if (size > asf_pkt->size_left || asf_pkt->size_left <= 0)
+ return AVERROR_INVALIDDATA;
+ if (asf_pkt->size_left > size)
+ asf_pkt->size_left -= size;
+ else
+ asf_pkt->size_left = 0;
+ if ((ret = avio_read(pb, p, size)) < 0)
+ return ret;
+ if (s->key && s->keylen == 20)
+ ff_asfcrypt_dec(s->key, p, ret);
+ if (asf->packet_size_internal)
+ avio_skip(pb, asf->packet_size - asf->packet_size_internal);
+ avio_skip(pb, asf->pad_len); // skip padding
+
+ return 0;
+}
+
+static int asf_read_payload(AVFormatContext *s, AVPacket *pkt)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int ret, i;
+ ASFPacket *asf_pkt = NULL;
+
+ if (!asf->sub_left) {
+ uint32_t off_len, media_len;
+ uint8_t stream_num;
+
+ stream_num = avio_r8(pb);
+ asf->stream_index = stream_num & ASF_STREAM_NUM;
+ for (i = 0; i < asf->nb_streams; i++) {
+ if (asf->stream_index == asf->asf_st[i]->stream_index) {
+ asf_pkt = &asf->asf_st[i]->pkt;
+ asf_pkt->stream_index = asf->asf_st[i]->index;
+ break;
+ }
+ }
+ if (!asf_pkt)
+ return AVERROR_INVALIDDATA;
+ if (stream_num >> 7)
+ asf_pkt->flags |= AV_PKT_FLAG_KEY;
+ READ_LEN(asf->prop_flags & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE,
+ ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_, media_len);
+ READ_LEN(asf->prop_flags & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE,
+ ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_, off_len);
+ READ_LEN(asf->prop_flags & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE,
+ ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_, asf->rep_data_len);
+ if (asf_pkt->size_left && (asf_pkt->frame_num != media_len)) {
+ av_log(s, AV_LOG_WARNING, "Unfinished frame will be ignored\n");
+ reset_packet(asf_pkt);
+ }
+ asf_pkt->frame_num = media_len;
+ asf->sub_dts = off_len;
+ if (asf->nb_mult_left) {
+ if ((ret = asf_read_multiple_payload(s, pkt, asf_pkt)) < 0)
+ return ret;
+ } else if (asf->rep_data_len == 1) {
+ asf->sub_left = 1;
+ asf->state = READ_SINGLE;
+ pkt->flags = asf_pkt->flags;
+ if ((ret = asf_read_subpayload(s, pkt, 1)) < 0)
+ return ret;
+ } else {
+ if ((ret = asf_read_single_payload(s, pkt, asf_pkt)) < 0)
+ return ret;
+ }
+ } else {
+ for (i = 0; i <= asf->nb_streams; i++) {
+ if (asf->stream_index == asf->asf_st[i]->stream_index) {
+ asf_pkt = &asf->asf_st[i]->pkt;
+ break;
+ }
+ }
+ if (!asf_pkt)
+ return AVERROR_INVALIDDATA;
+ pkt->flags = asf_pkt->flags;
+ pkt->dts = asf_pkt->dts;
+ pkt->stream_index = asf->asf_st[i]->index;
+ if ((ret = asf_read_subpayload(s, pkt, 0)) < 0) // read subpayload without its header
+ return ret;
+ }
+
+ return 0;
+}
+
+static int asf_read_packet_header(AVFormatContext *s)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint64_t size;
+ uint32_t av_unused seq;
+ unsigned char error_flags, len_flags, pay_flags;
+
+ asf->packet_offset = avio_tell(pb);
+ error_flags = avio_r8(pb); // read Error Correction Flags
+ if (error_flags & ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT) {
+ if (!(error_flags & ASF_ERROR_CORRECTION_LENGTH_TYPE)) {
+ size = error_flags & ASF_PACKET_ERROR_CORRECTION_DATA_SIZE;
+ avio_skip(pb, size);
+ }
+ len_flags = avio_r8(pb);
+ } else
+ len_flags = error_flags;
+ asf->prop_flags = avio_r8(pb);
+ READ_LEN(len_flags & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE,
+ ASF_PPI_FLAG_PACKET_LENGTH_FIELD_, asf->packet_size_internal);
+ READ_LEN(len_flags & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE,
+ ASF_PPI_FLAG_SEQUENCE_FIELD_, seq);
+ READ_LEN(len_flags & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE,
+ ASF_PPI_FLAG_PADDING_LENGTH_FIELD_, asf->pad_len );
+ asf->send_time = avio_rl32(pb); // send time
+ avio_skip(pb, 2); // skip duration
+ if (len_flags & ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT) { // Multiple Payloads present
+ pay_flags = avio_r8(pb);
+ asf->nb_mult_left = (pay_flags & ASF_NUM_OF_PAYLOADS);
+ }
+
+ return 0;
+}
+
+static int asf_deinterleave(AVFormatContext *s, ASFPacket *asf_pkt, int st_num)
+{
+ ASFContext *asf = s->priv_data;
+ ASFStream *asf_st = asf->asf_st[st_num];
+ unsigned char *p = asf_pkt->avpkt.data;
+ uint16_t pkt_len = asf->asf_st[st_num]->virtual_pkt_len;
+ uint16_t chunk_len = asf->asf_st[st_num]->virtual_chunk_len;
+ int nchunks = pkt_len / chunk_len;
+ AVPacket pkt;
+ int pos = 0, j, l, ret;
+
+
+ if ((ret = av_new_packet(&pkt, asf_pkt->data_size)) < 0)
+ return ret;
+
+ while (asf_pkt->data_size >= asf_st->span * pkt_len + pos) {
+ if (pos >= asf_pkt->data_size) {
+ break;
+ }
+ for (l = 0; l < pkt_len; l++) {
+ if (pos >= asf_pkt->data_size) {
+ break;
+ }
+ for (j = 0; j < asf_st->span; j++) {
+ if ((pos + chunk_len) >= asf_pkt->data_size)
+ break;
+ memcpy(pkt.data + pos,
+ p + (j * nchunks + l) * chunk_len,
+ chunk_len);
+ pos += chunk_len;
+ }
+ }
+ p += asf_st->span * pkt_len;
+ if (p > asf_pkt->avpkt.data + asf_pkt->data_size)
+ break;
+ }
+ av_free_packet(&asf_pkt->avpkt);
+ asf_pkt->avpkt = pkt;
+
+ return 0;
+}
+
+static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int ret, i;
+
+ if ((avio_tell(pb) >= asf->data_offset + asf->data_size) &&
+ !(asf->b_flags & ASF_FLAG_BROADCAST))
+ return AVERROR_EOF;
+ while (!pb->eof_reached) {
+ if (asf->state == PARSE_PACKET_HEADER) {
+ asf_read_packet_header(s);
+ if (!asf->nb_mult_left)
+ asf->state = READ_SINGLE;
+ else
+ asf->state = READ_MULTI;
+ }
+ if ((ret = asf_read_payload(s, pkt)) < 0)
+ return ret;
+ switch (asf->state) {
+ case READ_SINGLE:
+ if (!asf->sub_left)
+ asf->state = PARSE_PACKET_HEADER;
+ break;
+ case READ_MULTI_SUB:
+ if (!asf->sub_left && !asf->nb_mult_left) {
+ asf->state = PARSE_PACKET_HEADER;
+ if (!asf->return_subpayload)
+ avio_skip(pb, asf->pad_len); // skip padding
+ if (asf->packet_offset + asf->packet_size > avio_tell(pb))
+ avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
+ } else if (!asf->sub_left)
+ asf->state = READ_MULTI;
+ break;
+ case READ_MULTI:
+ if (!asf->nb_mult_left) {
+ asf->state = PARSE_PACKET_HEADER;
+ if (!asf->return_subpayload) {
+ avio_skip(pb, asf->pad_len); // skip padding
+ }
+ if (asf->packet_offset + asf->packet_size > avio_tell(pb))
+ avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
+ }
+ break;
+ }
+ if (asf->return_subpayload) {
+ asf->return_subpayload = 0;
+ return 0;
+ }
+ for (i = 0; i < s->nb_streams; i++) {
+ ASFPacket *asf_pkt = &asf->asf_st[i]->pkt;
+ if (asf_pkt && !asf_pkt->size_left && asf_pkt->data_size) {
+ if (asf->asf_st[i]->span > 1 &&
+ asf->asf_st[i]->type == AVMEDIA_TYPE_AUDIO)
+ if ((ret = asf_deinterleave(s, asf_pkt, i)) < 0)
+ return ret;
+ av_packet_move_ref(pkt, &asf_pkt->avpkt);
+ pkt->stream_index = asf->asf_st[i]->index;
+ pkt->flags = asf_pkt->flags;
+ pkt->dts = asf_pkt->dts - asf->preroll;
+ asf_pkt->data_size = 0;
+ asf_pkt->frame_num = 0;
+ return 0;
+ }
+ }
+ }
+
+ if (pb->eof_reached)
+ return AVERROR_EOF;
+
+ return 0;
+}
+
+static int asf_read_close(AVFormatContext *s)
+{
+ ASFContext *asf = s->priv_data;
+ int i;
+
+ for (i = 0; i < ASF_MAX_STREAMS; i++) {
+ av_dict_free(&asf->asf_sd[i].asf_met);
+ if (i < asf->nb_streams) {
+ av_free_packet(&asf->asf_st[i]->pkt.avpkt);
+ av_freep(&asf->asf_st[i]);
+ }
+ }
+
+ asf->nb_streams = 0;
+ return 0;
+}
+
+static void reset_packet_state(AVFormatContext *s)
+{
+ ASFContext *asf = s->priv_data;
+ int i;
+
+ asf->state = PARSE_PACKET_HEADER;
+ asf->offset = 0;
+ asf->return_subpayload = 0;
+ asf->sub_left = 0;
+ asf->sub_header_offset = 0;
+ asf->packet_offset = asf->first_packet_offset;
+ asf->pad_len = 0;
+ asf->rep_data_len = 0;
+ asf->dts_delta = 0;
+ asf->mult_sub_len = 0;
+ asf->nb_mult_left = 0;
+ asf->nb_sub = 0;
+ asf->prop_flags = 0;
+ asf->sub_dts = 0;
+ for (i = 0; i < asf->nb_streams; i++) {
+ ASFPacket *pkt = &asf->asf_st[i]->pkt;
+ pkt->size_left = 0;
+ pkt->data_size = 0;
+ pkt->duration = 0;
+ pkt->flags = 0;
+ pkt->dts = 0;
+ pkt->duration = 0;
+ av_free_packet(&pkt->avpkt);
+ av_init_packet(&pkt->avpkt);
+ }
+}
+
+/*
+ * Find a timestamp for the requested position within the payload
+ * where the pos (position) is the offset inside the Data Object.
+ * When position is not on the packet boundary, asf_read_timestamp tries
+ * to find the closest packet offset after this position. If this packet
+ * is a key frame, this packet timestamp is read and an index entry is created
+ * for the packet. If this packet belongs to the requested stream,
+ * asf_read_timestamp upgrades pos to the packet beginning offset and
+ * returns this packet's dts. So returned dts is the dts of the first key frame with
+ * matching stream number after given position.
+ */
+static int64_t asf_read_timestamp(AVFormatContext *s, int stream_index,
+ int64_t *pos, int64_t pos_limit)
+{
+ ASFContext *asf = s->priv_data;
+ int64_t pkt_pos = *pos, pkt_offset, dts = AV_NOPTS_VALUE, data_end;
+ AVPacket pkt;
+ int n;
+
+ data_end = asf->data_offset + asf->data_size;
+
+ n = (pkt_pos - asf->first_packet_offset + asf->packet_size - 1) /
+ asf->packet_size;
+ n = av_clip(n, 0, ((data_end - asf->first_packet_offset) / asf->packet_size - 1));
+ pkt_pos = asf->first_packet_offset + n * asf->packet_size;
+
+ avio_seek(s->pb, pkt_pos, SEEK_SET);
+ pkt_offset = pkt_pos;
+
+ reset_packet_state(s);
+ while (avio_tell(s->pb) < data_end) {
+
+ int i, ret, st_found;
+
+ av_init_packet(&pkt);
+ pkt_offset = avio_tell(s->pb);
+ if ((ret = asf_read_packet(s, &pkt)) < 0) {
+ dts = AV_NOPTS_VALUE;
+ return ret;
+ }
+ // ASFPacket may contain fragments of packets belonging to different streams,
+ // pkt_offset is the offset of the first fragment within it.
+ if ((pkt_offset >= (pkt_pos + asf->packet_size)))
+ pkt_pos += asf->packet_size;
+ for (i = 0; i < asf->nb_streams; i++) {
+ ASFStream *st = asf->asf_st[i];
+
+ st_found = 0;
+ if (pkt.flags & AV_PKT_FLAG_KEY) {
+ dts = pkt.dts;
+ if (dts) {
+ av_add_index_entry(s->streams[pkt.stream_index], pkt_pos,
+ dts, pkt.size, 0, AVINDEX_KEYFRAME);
+ if (stream_index == st->index) {
+ st_found = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (st_found)
+ break;
+ av_free_packet(&pkt);
+ }
+ *pos = pkt_pos;
+
+ av_free_packet(&pkt);
+ return dts;
+}
+
+static int asf_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ ASFContext *asf = s->priv_data;
+ int idx, ret;
+
+ if (s->streams[stream_index]->nb_index_entries && asf->is_simple_index) {
+ idx = av_index_search_timestamp(s->streams[stream_index], timestamp, flags);
+ if (idx < 0 || idx >= s->streams[stream_index]->nb_index_entries)
+ return AVERROR_INVALIDDATA;
+ avio_seek(s->pb, s->streams[stream_index]->index_entries[idx].pos, SEEK_SET);
+ } else {
+ if ((ret = ff_seek_frame_binary(s, stream_index, timestamp, flags)) < 0)
+ return ret;
+ }
+
+ reset_packet_state(s);
+
+ return 0;
+}
+
+static const GUIDParseTable *find_guid(ff_asf_guid guid)
+{
+ int j, ret;
+ const GUIDParseTable *g;
+
+ swap_guid(guid);
+ g = gdef;
+ for (j = 0; j < FF_ARRAY_ELEMS(gdef); j++) {
+ if (!(ret = memcmp(guid, g->guid, sizeof(g->guid))))
+ return g;
+ g++;
+ }
+
+ return NULL;
+}
+
+static int detect_unknown_subobject(AVFormatContext *s, int64_t offset, int64_t size)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ const GUIDParseTable *g = NULL;
+ ff_asf_guid guid;
+ int ret;
+
+ while (avio_tell(pb) <= offset + size) {
+ if (avio_tell(pb) == asf->offset)
+ break;
+ asf->offset = avio_tell(pb);
+ if ((ret = ff_get_guid(pb, &guid)) < 0)
+ return ret;
+ g = find_guid(guid);
+ if (g) {
+ if ((ret = g->read_object(s, g)) < 0)
+ return ret;
+ } else {
+ GUIDParseTable g2;
+
+ g2.name = "Unknown";
+ g2.is_subobject = 1;
+ asf_read_unknown(s, &g2);
+ }
+ }
+
+ return 0;
+}
+
+static int asf_read_header(AVFormatContext *s)
+{
+ ASFContext *asf = s->priv_data;
+ AVIOContext *pb = s->pb;
+ const GUIDParseTable *g = NULL;
+ ff_asf_guid guid;
+ int i, ret;
+ uint64_t size;
+
+ asf->preroll = 0;
+ asf->is_simple_index = 0;
+ ff_get_guid(pb, &guid);
+ if (ff_guidcmp(&guid, &ff_asf_header))
+ return AVERROR_INVALIDDATA;
+ avio_skip(pb, 8); // skip header object size
+ avio_skip(pb, 6); // skip number of header objects and 2 reserved bytes
+ asf->data_reached = 0;
+
+ /* 1 is here instead of pb->eof_reached because (when not streaming), Data are skipped
+ * for the first time,
+ * Index object is processed and got eof and then seeking back to the Data is performed.
+ */
+ while (1) {
+ // for the cases when object size is invalid
+ if (avio_tell(pb) == asf->offset)
+ break;
+ asf->offset = avio_tell(pb);
+ if ((ret = ff_get_guid(pb, &guid)) < 0) {
+ if (ret == AVERROR_EOF && asf->data_reached)
+ break;
+ else
+ goto failed;
+ }
+ g = find_guid(guid);
+ if (g) {
+ asf->unknown_offset = asf->offset;
+ asf->is_header = 1;
+ if ((ret = g->read_object(s, g)) < 0)
+ goto failed;
+ } else {
+ size = avio_rl64(pb);
+ align_position(pb, asf->offset, size);
+ }
+ if (asf->data_reached && (!pb->seekable || (asf->b_flags & ASF_FLAG_BROADCAST)))
+ break;
+ }
+
+ if (!asf->data_reached) {
+ av_log(s, AV_LOG_ERROR, "Data Object was not found.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto failed;
+ }
+ if (pb->seekable)
+ avio_seek(pb, asf->first_packet_offset, SEEK_SET);
+
+ for (i = 0; i < asf->nb_streams; i++) {
+ const char *rfc1766 = asf->asf_sd[asf->asf_st[i]->lang_idx].langs;
+ AVStream *st = s->streams[asf->asf_st[i]->index];
+ set_language(s, rfc1766, &st->metadata);
+ }
+
+ for (i = 0; i < ASF_MAX_STREAMS; i++) {
+ AVStream *st = NULL;
+
+ st = find_stream(s, i);
+ if (st) {
+ av_dict_copy(&st->metadata, asf->asf_sd[i].asf_met, AV_DICT_IGNORE_SUFFIX);
+ if (asf->asf_sd[i].aspect_ratio.num > 0 && asf->asf_sd[i].aspect_ratio.den > 0) {
+ st->sample_aspect_ratio.num = asf->asf_sd[i].aspect_ratio.num;
+ st->sample_aspect_ratio.den = asf->asf_sd[i].aspect_ratio.den;
+ }
+ }
+ }
+
+ return 0;
+
+failed:
+ asf_read_close(s);
+ return ret;
+}
+
+AVInputFormat ff_asf_o_demuxer = {
+ .name = "asf_o",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
+ .priv_data_size = sizeof(ASFContext),
+ .read_probe = asf_probe,
+ .read_header = asf_read_header,
+ .read_packet = asf_read_packet,
+ .read_close = asf_read_close,
+ .read_timestamp = asf_read_timestamp,
+ .read_seek = asf_read_seek,
+ .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/asfenc.c b/chromium/third_party/ffmpeg/libavformat/asfenc.c
index 015c731cec8..32b726bb293 100644
--- a/chromium/third_party/ffmpeg/libavformat/asfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/asfenc.c
@@ -183,6 +183,38 @@
#define DATA_HEADER_SIZE 50
+typedef struct ASFPayload {
+ uint8_t type;
+ uint16_t size;
+} ASFPayload;
+
+typedef struct ASFStream {
+ int num;
+ unsigned char seq;
+ /* use for reading */
+ AVPacket pkt;
+ int frag_offset;
+ int packet_obj_size;
+ int timestamp;
+ int64_t duration;
+ int skip_to_key;
+ int pkt_clean;
+
+ int ds_span; /* descrambling */
+ int ds_packet_size;
+ int ds_chunk_size;
+
+ int64_t packet_pos;
+
+ uint16_t stream_language_index;
+
+ int palette_changed;
+ uint32_t palette[256];
+
+ int payload_ext_ct;
+ ASFPayload payload[8];
+} ASFStream;
+
typedef struct ASFContext {
uint32_t seqno;
int is_streamed;
diff --git a/chromium/third_party/ffmpeg/libavformat/assdec.c b/chromium/third_party/ffmpeg/libavformat/assdec.c
index c62e76f0ddb..5423c03f146 100644
--- a/chromium/third_party/ffmpeg/libavformat/assdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/assdec.c
@@ -152,7 +152,7 @@ static int ass_read_header(AVFormatContext *s)
if (res < 0)
goto end;
- ff_subtitles_queue_finalize(&ass->q);
+ ff_subtitles_queue_finalize(s, &ass->q);
end:
av_bprint_finalize(&header, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/async.c b/chromium/third_party/ffmpeg/libavformat/async.c
new file mode 100644
index 00000000000..003212d5b6c
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/async.c
@@ -0,0 +1,560 @@
+/*
+ * Input async protocol.
+ * Copyright (c) 2015 Zhang Rui <bbcallen@gmail.com>
+ *
+ * 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
+ *
+ * Based on libavformat/cache.c by Michael Niedermayer
+ */
+
+ /**
+ * @TODO
+ * support timeout
+ * support backward short seek
+ * support work with concatdec, hls
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/error.h"
+#include "libavutil/fifo.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "url.h"
+#include <stdint.h>
+#include <pthread.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#define BUFFER_CAPACITY (4 * 1024 * 1024)
+#define SHORT_SEEK_THRESHOLD (256 * 1024)
+
+typedef struct Context {
+ AVClass *class;
+ URLContext *inner;
+
+ int seek_request;
+ int64_t seek_pos;
+ int seek_whence;
+ int seek_completed;
+ int64_t seek_ret;
+
+ int io_error;
+ int io_eof_reached;
+
+ int64_t logical_pos;
+ int64_t logical_size;
+ AVFifoBuffer *fifo;
+
+ pthread_cond_t cond_wakeup_main;
+ pthread_cond_t cond_wakeup_background;
+ pthread_mutex_t mutex;
+ pthread_t async_buffer_thread;
+
+ int abort_request;
+ AVIOInterruptCB interrupt_callback;
+} Context;
+
+static int async_check_interrupt(void *arg)
+{
+ URLContext *h = arg;
+ Context *c = h->priv_data;
+
+ if (c->abort_request)
+ return 1;
+
+ if (ff_check_interrupt(&c->interrupt_callback))
+ c->abort_request = 1;
+
+ return c->abort_request;
+}
+
+static void *async_buffer_task(void *arg)
+{
+ URLContext *h = arg;
+ Context *c = h->priv_data;
+ AVFifoBuffer *fifo = c->fifo;
+ int ret = 0;
+ int64_t seek_ret;
+
+ while (1) {
+ int fifo_space, to_copy;
+
+ pthread_mutex_lock(&c->mutex);
+ if (async_check_interrupt(h)) {
+ c->io_eof_reached = 1;
+ c->io_error = AVERROR_EXIT;
+ pthread_cond_signal(&c->cond_wakeup_main);
+ pthread_mutex_unlock(&c->mutex);
+ break;
+ }
+
+ if (c->seek_request) {
+ seek_ret = ffurl_seek(c->inner, c->seek_pos, c->seek_whence);
+ if (seek_ret < 0) {
+ c->io_eof_reached = 1;
+ c->io_error = (int)seek_ret;
+ } else {
+ c->io_eof_reached = 0;
+ c->io_error = 0;
+ }
+
+ c->seek_completed = 1;
+ c->seek_ret = seek_ret;
+ c->seek_request = 0;
+
+ av_fifo_reset(fifo);
+
+ pthread_cond_signal(&c->cond_wakeup_main);
+ pthread_mutex_unlock(&c->mutex);
+ continue;
+ }
+
+ fifo_space = av_fifo_space(fifo);
+ if (c->io_eof_reached || fifo_space <= 0) {
+ pthread_cond_signal(&c->cond_wakeup_main);
+ pthread_cond_wait(&c->cond_wakeup_background, &c->mutex);
+ pthread_mutex_unlock(&c->mutex);
+ continue;
+ }
+ pthread_mutex_unlock(&c->mutex);
+
+ to_copy = FFMIN(4096, fifo_space);
+ ret = av_fifo_generic_write(fifo, c->inner, to_copy, (void *)ffurl_read);
+
+ pthread_mutex_lock(&c->mutex);
+ if (ret <= 0) {
+ c->io_eof_reached = 1;
+ if (ret < 0) {
+ c->io_error = ret;
+ }
+ }
+
+ pthread_cond_signal(&c->cond_wakeup_main);
+ pthread_mutex_unlock(&c->mutex);
+ }
+
+ return NULL;
+}
+
+static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
+{
+ Context *c = h->priv_data;
+ int ret;
+ AVIOInterruptCB interrupt_callback = {.callback = async_check_interrupt, .opaque = h};
+
+ av_strstart(arg, "async:", &arg);
+
+ c->fifo = av_fifo_alloc(BUFFER_CAPACITY);
+ if (!c->fifo) {
+ ret = AVERROR(ENOMEM);
+ goto fifo_fail;
+ }
+
+ /* wrap interrupt callback */
+ c->interrupt_callback = h->interrupt_callback;
+ ret = ffurl_open(&c->inner, arg, flags, &interrupt_callback, options);
+ if (ret != 0) {
+ av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg);
+ goto url_fail;
+ }
+
+ c->logical_size = ffurl_size(c->inner);
+ h->is_streamed = c->inner->is_streamed;
+
+ ret = pthread_mutex_init(&c->mutex, NULL);
+ if (ret != 0) {
+ av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", av_err2str(ret));
+ goto mutex_fail;
+ }
+
+ ret = pthread_cond_init(&c->cond_wakeup_main, NULL);
+ if (ret != 0) {
+ av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret));
+ goto cond_wakeup_main_fail;
+ }
+
+ ret = pthread_cond_init(&c->cond_wakeup_background, NULL);
+ if (ret != 0) {
+ av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret));
+ goto cond_wakeup_background_fail;
+ }
+
+ ret = pthread_create(&c->async_buffer_thread, NULL, async_buffer_task, h);
+ if (ret) {
+ av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", av_err2str(ret));
+ goto thread_fail;
+ }
+
+ return 0;
+
+thread_fail:
+ pthread_cond_destroy(&c->cond_wakeup_background);
+cond_wakeup_background_fail:
+ pthread_cond_destroy(&c->cond_wakeup_main);
+cond_wakeup_main_fail:
+ pthread_mutex_destroy(&c->mutex);
+mutex_fail:
+ ffurl_close(c->inner);
+url_fail:
+ av_fifo_freep(&c->fifo);
+fifo_fail:
+ return ret;
+}
+
+static int async_close(URLContext *h)
+{
+ Context *c = h->priv_data;
+ int ret;
+
+ pthread_mutex_lock(&c->mutex);
+ c->abort_request = 1;
+ pthread_cond_signal(&c->cond_wakeup_background);
+ pthread_mutex_unlock(&c->mutex);
+
+ ret = pthread_join(c->async_buffer_thread, NULL);
+ if (ret != 0)
+ av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", av_err2str(ret));
+
+ pthread_cond_destroy(&c->cond_wakeup_background);
+ pthread_cond_destroy(&c->cond_wakeup_main);
+ pthread_mutex_destroy(&c->mutex);
+ ffurl_close(c->inner);
+ av_fifo_freep(&c->fifo);
+
+ return 0;
+}
+
+static int async_read_internal(URLContext *h, void *dest, int size, int read_complete,
+ void (*func)(void*, void*, int))
+{
+ Context *c = h->priv_data;
+ AVFifoBuffer *fifo = c->fifo;
+ int to_read = size;
+ int ret = 0;
+
+ pthread_mutex_lock(&c->mutex);
+
+ while (to_read > 0) {
+ int fifo_size, to_copy;
+ if (async_check_interrupt(h)) {
+ ret = AVERROR_EXIT;
+ break;
+ }
+ fifo_size = av_fifo_size(fifo);
+ to_copy = FFMIN(to_read, fifo_size);
+ if (to_copy > 0) {
+ av_fifo_generic_read(fifo, dest, to_copy, func);
+ if (!func)
+ dest = (uint8_t *)dest + to_copy;
+ c->logical_pos += to_copy;
+ to_read -= to_copy;
+ ret = size - to_read;
+
+ if (to_read <= 0 || !read_complete)
+ break;
+ } else if (c->io_eof_reached) {
+ if (ret <= 0)
+ ret = AVERROR_EOF;
+ break;
+ }
+ pthread_cond_signal(&c->cond_wakeup_background);
+ pthread_cond_wait(&c->cond_wakeup_main, &c->mutex);
+ }
+
+ pthread_cond_signal(&c->cond_wakeup_background);
+ pthread_mutex_unlock(&c->mutex);
+
+ return ret;
+}
+
+static int async_read(URLContext *h, unsigned char *buf, int size)
+{
+ return async_read_internal(h, buf, size, 0, NULL);
+}
+
+static void fifo_do_not_copy_func(void* dest, void* src, int size) {
+ // do not copy
+}
+
+static int64_t async_seek(URLContext *h, int64_t pos, int whence)
+{
+ Context *c = h->priv_data;
+ AVFifoBuffer *fifo = c->fifo;
+ int64_t ret;
+ int64_t new_logical_pos;
+ int fifo_size;
+
+ if (whence == AVSEEK_SIZE) {
+ av_log(h, AV_LOG_TRACE, "async_seek: AVSEEK_SIZE: %"PRId64"\n", (int64_t)c->logical_size);
+ return c->logical_size;
+ } else if (whence == SEEK_CUR) {
+ av_log(h, AV_LOG_TRACE, "async_seek: %"PRId64"\n", pos);
+ new_logical_pos = pos + c->logical_pos;
+ } else if (whence == SEEK_SET){
+ av_log(h, AV_LOG_TRACE, "async_seek: %"PRId64"\n", pos);
+ new_logical_pos = pos;
+ } else {
+ return AVERROR(EINVAL);
+ }
+ if (new_logical_pos < 0)
+ return AVERROR(EINVAL);
+
+ fifo_size = av_fifo_size(fifo);
+ if (new_logical_pos == c->logical_pos) {
+ /* current position */
+ return c->logical_pos;
+ } else if ((new_logical_pos > c->logical_pos) &&
+ (new_logical_pos < (c->logical_pos + fifo_size + SHORT_SEEK_THRESHOLD))) {
+ /* fast seek */
+ av_log(h, AV_LOG_TRACE, "async_seek: fask_seek %"PRId64" from %d dist:%d/%d\n",
+ new_logical_pos, (int)c->logical_pos,
+ (int)(new_logical_pos - c->logical_pos), fifo_size);
+ async_read_internal(h, NULL, (int)(new_logical_pos - c->logical_pos), 1, fifo_do_not_copy_func);
+ return c->logical_pos;
+ } else if (c->logical_size <= 0) {
+ /* can not seek */
+ return AVERROR(EINVAL);
+ } else if (new_logical_pos > c->logical_size) {
+ /* beyond end */
+ return AVERROR(EINVAL);
+ }
+
+ pthread_mutex_lock(&c->mutex);
+
+ c->seek_request = 1;
+ c->seek_pos = new_logical_pos;
+ c->seek_whence = SEEK_SET;
+ c->seek_completed = 0;
+ c->seek_ret = 0;
+
+ while (1) {
+ if (async_check_interrupt(h)) {
+ ret = AVERROR_EXIT;
+ break;
+ }
+ if (c->seek_completed) {
+ if (c->seek_ret >= 0)
+ c->logical_pos = c->seek_ret;
+ ret = c->seek_ret;
+ break;
+ }
+ pthread_cond_signal(&c->cond_wakeup_background);
+ pthread_cond_wait(&c->cond_wakeup_main, &c->mutex);
+ }
+
+ pthread_mutex_unlock(&c->mutex);
+
+ return ret;
+}
+
+#define OFFSET(x) offsetof(Context, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+ {NULL},
+};
+
+static const AVClass async_context_class = {
+ .class_name = "Async",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+URLProtocol ff_async_protocol = {
+ .name = "async",
+ .url_open2 = async_open,
+ .url_read = async_read,
+ .url_seek = async_seek,
+ .url_close = async_close,
+ .priv_data_size = sizeof(Context),
+ .priv_data_class = &async_context_class,
+};
+
+#ifdef TEST
+
+#define TEST_SEEK_POS (1536)
+#define TEST_STREAM_SIZE (2048)
+
+typedef struct TestContext {
+ AVClass *class;
+ int64_t logical_pos;
+ int64_t logical_size;
+} TestContext;
+
+static int async_test_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
+{
+ TestContext *c = h->priv_data;
+ c->logical_pos = 0;
+ c->logical_size = TEST_STREAM_SIZE;
+ return 0;
+}
+
+static int async_test_close(URLContext *h)
+{
+ return 0;
+}
+
+static int async_test_read(URLContext *h, unsigned char *buf, int size)
+{
+ TestContext *c = h->priv_data;
+ int i;
+ int read_len = 0;
+
+ if (c->logical_pos >= c->logical_size)
+ return AVERROR_EOF;
+
+ for (i = 0; i < size; ++i) {
+ buf[i] = c->logical_pos & 0xFF;
+
+ c->logical_pos++;
+ read_len++;
+
+ if (c->logical_pos >= c->logical_size)
+ break;
+ }
+
+ return read_len;
+}
+
+static int64_t async_test_seek(URLContext *h, int64_t pos, int whence)
+{
+ TestContext *c = h->priv_data;
+ int64_t new_logical_pos;
+
+ if (whence == AVSEEK_SIZE) {
+ return c->logical_size;
+ } else if (whence == SEEK_CUR) {
+ new_logical_pos = pos + c->logical_pos;
+ } else if (whence == SEEK_SET){
+ new_logical_pos = pos;
+ } else {
+ return AVERROR(EINVAL);
+ }
+ if (new_logical_pos < 0)
+ return AVERROR(EINVAL);
+
+ c->logical_pos = new_logical_pos;
+ return new_logical_pos;
+}
+
+static const AVClass async_test_context_class = {
+ .class_name = "Async-Test",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+URLProtocol ff_async_test_protocol = {
+ .name = "async-test",
+ .url_open2 = async_test_open,
+ .url_read = async_test_read,
+ .url_seek = async_test_seek,
+ .url_close = async_test_close,
+ .priv_data_size = sizeof(TestContext),
+ .priv_data_class = &async_test_context_class,
+};
+
+int main(void)
+{
+ URLContext *h = NULL;
+ int i;
+ int ret;
+ int64_t size;
+ int64_t pos;
+ int64_t read_len;
+ unsigned char buf[4096];
+
+ ffurl_register_protocol(&ff_async_protocol);
+ ffurl_register_protocol(&ff_async_test_protocol);
+
+ ret = ffurl_open(&h, "async:async-test:", AVIO_FLAG_READ, NULL, NULL);
+ printf("open: %d\n", ret);
+
+ size = ffurl_size(h);
+ printf("size: %"PRId64"\n", size);
+
+ pos = ffurl_seek(h, 0, SEEK_CUR);
+ read_len = 0;
+ while (1) {
+ ret = ffurl_read(h, buf, sizeof(buf));
+ if (ret == AVERROR_EOF) {
+ printf("read-error: AVERROR_EOF at %"PRId64"\n", ffurl_seek(h, 0, SEEK_CUR));
+ break;
+ }
+ else if (ret == 0)
+ break;
+ else if (ret < 0) {
+ printf("read-error: %d at %"PRId64"\n", ret, ffurl_seek(h, 0, SEEK_CUR));
+ goto fail;
+ } else {
+ for (i = 0; i < ret; ++i) {
+ if (buf[i] != (pos & 0xFF)) {
+ printf("read-mismatch: actual %d, expecting %d, at %"PRId64"\n",
+ (int)buf[i], (int)(pos & 0xFF), pos);
+ break;
+ }
+ pos++;
+ }
+ }
+
+ read_len += ret;
+ }
+ printf("read: %"PRId64"\n", read_len);
+
+ ret = ffurl_read(h, buf, 1);
+ printf("read: %d\n", ret);
+
+ pos = ffurl_seek(h, TEST_SEEK_POS, SEEK_SET);
+ printf("seek: %"PRId64"\n", pos);
+
+ read_len = 0;
+ while (1) {
+ ret = ffurl_read(h, buf, sizeof(buf));
+ if (ret == AVERROR_EOF)
+ break;
+ else if (ret == 0)
+ break;
+ else if (ret < 0) {
+ printf("read-error: %d at %"PRId64"\n", ret, ffurl_seek(h, 0, SEEK_CUR));
+ goto fail;
+ } else {
+ for (i = 0; i < ret; ++i) {
+ if (buf[i] != (pos & 0xFF)) {
+ printf("read-mismatch: actual %d, expecting %d, at %"PRId64"\n",
+ (int)buf[i], (int)(pos & 0xFF), pos);
+ break;
+ }
+ pos++;
+ }
+ }
+
+ read_len += ret;
+ }
+ printf("read: %"PRId64"\n", read_len);
+
+ ret = ffurl_read(h, buf, 1);
+ printf("read: %d\n", ret);
+
+fail:
+ ffurl_close(h);
+ return 0;
+}
+
+#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_flacdec.c b/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_flacdec.c
index 4207fd2bf6c..4c1f9435810 100644
--- a/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_flacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_flacdec.c
@@ -58,7 +58,7 @@ static int flac_read_header(AVFormatContext *s)
case FLAC_METADATA_TYPE_CUESHEET:
case FLAC_METADATA_TYPE_PICTURE:
case FLAC_METADATA_TYPE_VORBIS_COMMENT:
- buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ buffer = av_mallocz(metadata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!buffer) {
return AVERROR(ENOMEM);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_options.c b/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_options.c
index d238dd5ab70..9918349703a 100644
--- a/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_options.c
+++ b/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_options.c
@@ -20,6 +20,8 @@
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+
+#include "libavutil/internal.h"
#include "libavutil/opt.h"
/**
@@ -27,7 +29,9 @@
* Options definition for AVFormatContext.
*/
+FF_DISABLE_DEPRECATION_WARNINGS
#include "options_table.h"
+FF_ENABLE_DEPRECATION_WARNINGS
static const char* format_to_name(void* ptr)
{
diff --git a/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_utils.c b/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_utils.c
index caa15abbaed..24eacf39675 100644
--- a/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_utils.c
+++ b/chromium/third_party/ffmpeg/libavformat/autorename_libavformat_utils.c
@@ -116,7 +116,10 @@ MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb)
int64_t av_stream_get_end_pts(const AVStream *st)
{
- return st->pts.val;
+ if (st->priv_pts) {
+ return st->priv_pts->val;
+ } else
+ return AV_NOPTS_VALUE;
}
struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
@@ -1262,12 +1265,6 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
out_pkt.buf = pkt->buf;
pkt->buf = NULL;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- out_pkt.destruct = pkt->destruct;
- pkt->destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
}
if ((ret = av_dup_packet(&out_pkt)) < 0)
goto fail;
@@ -1585,26 +1582,26 @@ int av_find_default_stream_index(AVFormatContext *s)
int i;
AVStream *st;
int best_stream = 0;
- int best_score = -1;
+ int best_score = INT_MIN;
if (s->nb_streams <= 0)
return -1;
for (i = 0; i < s->nb_streams; i++) {
int score = 0;
st = s->streams[i];
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
- !(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
- if (!st->codec->width && !st->codec->height && !st->codec_info_nb_frames)
- score += 25;
- else
- score += 100;
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
+ score -= 400;
+ if (st->codec->width && st->codec->height)
+ score += 50;
+ score+= 25;
}
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (!st->codec->sample_rate && !st->codec_info_nb_frames)
- score += 12;
- else
+ if (st->codec->sample_rate)
score += 50;
}
+ if (st->codec_info_nb_frames)
+ score += 12;
if (st->discard != AVDISCARD_ALL)
score += 200;
@@ -1781,6 +1778,63 @@ int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries,
return m;
}
+void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
+{
+ int ist1, ist2;
+ int64_t pos_delta = 0;
+ int64_t skip = 0;
+ //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
+ const char *proto = avio_find_protocol_name(s->filename);
+
+ if (!proto) {
+ av_log(s, AV_LOG_INFO,
+ "Protocol name not provided, cannot determine if input is local or "
+ "a network protocol, buffers and access patterns cannot be configured "
+ "optimally without knowing the protocol\n");
+ }
+
+ if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache")))
+ return;
+
+ for (ist1 = 0; ist1 < s->nb_streams; ist1++) {
+ AVStream *st1 = s->streams[ist1];
+ for (ist2 = 0; ist2 < s->nb_streams; ist2++) {
+ AVStream *st2 = s->streams[ist2];
+ int i1, i2;
+
+ if (ist1 == ist2)
+ continue;
+
+ for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
+ AVIndexEntry *e1 = &st1->index_entries[i1];
+ int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
+
+ skip = FFMAX(skip, e1->size);
+ for (; i2 < st2->nb_index_entries; i2++) {
+ AVIndexEntry *e2 = &st2->index_entries[i2];
+ int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
+ if (e2_pts - e1_pts < time_tolerance)
+ continue;
+ pos_delta = FFMAX(pos_delta, e1->pos - e2->pos);
+ break;
+ }
+ }
+ }
+ }
+
+ pos_delta *= 2;
+ /* XXX This could be adjusted depending on protocol*/
+ if (s->pb->buffer_size < pos_delta && pos_delta < (1<<24)) {
+ av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta);
+ ffio_set_buf_size(s->pb, pos_delta);
+ s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2);
+ }
+
+ if (skip < (1<<23)) {
+ s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, skip);
+ }
+}
+
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
{
return ff_index_search_timestamp(st->index_entries, st->nb_index_entries,
@@ -2665,7 +2719,7 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
ret >= 0 &&
(!has_codec_parameters(st, NULL) || !has_decode_delay_been_guessed(st) ||
(!st->codec_info_nb_frames &&
- st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
+ (st->codec->codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)))) {
got_picture = 0;
switch (st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
@@ -2865,14 +2919,14 @@ int ff_alloc_extradata(AVCodecContext *avctx, int size)
{
int ret;
- if (size < 0 || size >= INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+ if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
avctx->extradata = NULL;
avctx->extradata_size = 0;
return AVERROR(EINVAL);
}
- avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ avctx->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
if (avctx->extradata) {
- memset(avctx->extradata + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(avctx->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
avctx->extradata_size = size;
ret = 0;
} else {
@@ -3031,9 +3085,18 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
// new streams might appear, no options for those
int orig_nb_streams = ic->nb_streams;
int flush_codecs;
+#if FF_API_PROBESIZE_32
int64_t max_analyze_duration = ic->max_analyze_duration2;
+#else
+ int64_t max_analyze_duration = ic->max_analyze_duration;
+#endif
int64_t max_stream_analyze_duration;
+ int64_t max_subtitle_analyze_duration;
+#if FF_API_PROBESIZE_32
int64_t probesize = ic->probesize2;
+#else
+ int64_t probesize = ic->probesize;
+#endif
if (!max_analyze_duration)
max_analyze_duration = ic->max_analyze_duration;
@@ -3044,11 +3107,13 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
max_stream_analyze_duration = max_analyze_duration;
+ max_subtitle_analyze_duration = max_analyze_duration;
if (!max_analyze_duration) {
max_stream_analyze_duration =
max_analyze_duration = 5*AV_TIME_BASE;
+ max_subtitle_analyze_duration = 30*AV_TIME_BASE;
if (!strcmp(ic->iformat->name, "flv"))
- max_stream_analyze_duration = 30*AV_TIME_BASE;
+ max_stream_analyze_duration = 90*AV_TIME_BASE;
}
if (ic->pb)
@@ -3264,6 +3329,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
}
if (st->codec_info_nb_frames>1) {
int64_t t = 0;
+ int64_t limit;
if (st->time_base.den > 0)
t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q);
@@ -3276,10 +3342,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
&& st->info->fps_last_dts != AV_NOPTS_VALUE)
t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
- if (t >= (analyzed_all_streams ? max_analyze_duration : max_stream_analyze_duration)) {
- av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds\n",
- max_analyze_duration,
- t);
+ if (analyzed_all_streams) limit = max_analyze_duration;
+ else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration;
+ else limit = max_stream_analyze_duration;
+
+ if (t >= limit) {
+ av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds st:%d\n",
+ limit,
+ t, pkt->stream_index);
if (ic->flags & AVFMT_FLAG_NOBUFFER)
av_packet_unref(pkt);
break;
@@ -3308,7 +3378,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
* it takes longer and uses more memory. For MPEG-4, we need to
* decompress for QuickTime.
*
- * If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
+ * If AV_CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
* least one frame of codec data, this makes sure the codec initializes
* the channel configuration and does not only trust the values from
* the container. */
@@ -3603,6 +3673,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st) {
av_freep(&st->info->duration_error);
av_freep(&st->info);
av_freep(&st->recommended_encoder_configuration);
+ av_freep(&st->priv_pts);
av_freep(&s->streams[ --s->nb_streams ]);
}
@@ -4235,8 +4306,9 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
if (*spec <= '9' && *spec >= '0') /* opt:index */
return strtol(spec, NULL, 0) == st->index;
else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
- *spec == 't') { /* opt:[vasdt] */
+ *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
enum AVMediaType type;
+ int nopic = 0;
switch (*spec++) {
case 'v': type = AVMEDIA_TYPE_VIDEO; break;
@@ -4244,15 +4316,20 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
case 'd': type = AVMEDIA_TYPE_DATA; break;
case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+ case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
default: av_assert0(0);
}
if (type != st->codec->codec_type)
return 0;
+ if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ return 0;
if (*spec++ == ':') { /* possibly followed by :index */
int i, index = strtol(spec, NULL, 0);
for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->codec->codec_type == type && index-- == 0)
- return i == st->index;
+ if (s->streams[i]->codec->codec_type == type &&
+ !(nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC)) &&
+ index-- == 0)
+ return i == st->index;
return 0;
}
return 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/avc.c b/chromium/third_party/ffmpeg/libavformat/avc.c
index 9d843e0ca4b..f7b8f38a00a 100644
--- a/chromium/third_party/ffmpeg/libavformat/avc.c
+++ b/chromium/third_party/ffmpeg/libavformat/avc.c
@@ -180,7 +180,7 @@ int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
if (11 + sps_size + pps_size > *size)
return AVERROR_INVALIDDATA;
out_size = 8 + sps_size + pps_size;
- out = av_mallocz(out_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ out = av_mallocz(out_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!out)
return AVERROR(ENOMEM);
AV_WB32(&out[0], 0x00000001);
diff --git a/chromium/third_party/ffmpeg/libavformat/avformat.h b/chromium/third_party/ffmpeg/libavformat/avformat.h
index fb69852f458..b7f18c16143 100644
--- a/chromium/third_party/ffmpeg/libavformat/avformat.h
+++ b/chromium/third_party/ffmpeg/libavformat/avformat.h
@@ -478,12 +478,7 @@ typedef struct AVProbeData {
#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fall back on generic search */
#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
#define AVFMT_ALLOW_FLUSH 0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
-#if LIBAVFORMAT_VERSION_MAJOR <= 54
-#define AVFMT_TS_NONSTRICT 0x8020000 //we try to be compatible to the ABIs of ffmpeg and major forks
-#else
-#define AVFMT_TS_NONSTRICT 0x20000
-#endif
- /**< Format does not require strictly
+#define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly
increasing timestamps, but they must
still be monotonic */
#define AVFMT_TS_NEGATIVE 0x40000 /**< Format allows muxing negative
@@ -1015,7 +1010,6 @@ typedef struct AVStream {
/**
* Number of packets to buffer for codec probing
*/
-#define MAX_PROBE_PACKETS 2500
int probe_packets;
/**
@@ -1171,6 +1165,8 @@ typedef struct AVStream {
* - decoding: Set by libavformat to calculate sample_aspect_ratio internally
*/
AVRational display_aspect_ratio;
+
+ struct FFFrac *priv_pts;
} AVStream;
AVRational av_stream_get_r_frame_rate(const AVStream *s);
@@ -1395,6 +1391,7 @@ typedef struct AVFormatContext {
#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate.
#define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats
+#if FF_API_PROBESIZE_32
/**
* @deprecated deprecated in favor of probesize2
*/
@@ -1405,6 +1402,7 @@ typedef struct AVFormatContext {
*/
attribute_deprecated
int max_analyze_duration;
+#endif
const uint8_t *key;
int keylen;
@@ -1757,7 +1755,11 @@ typedef struct AVFormatContext {
* via AVOptions (NO direct access).
* Can be set to 0 to let avformat choose using a heuristic.
*/
+#if FF_API_PROBESIZE_32
int64_t max_analyze_duration2;
+#else
+ int64_t max_analyze_duration;
+#endif
/**
* Maximum size of the data read from input for determining
@@ -1765,7 +1767,11 @@ typedef struct AVFormatContext {
* Demuxing only, set by the caller before avformat_open_input()
* via AVOptions (NO direct access).
*/
+#if FF_API_PROBESIZE_32
int64_t probesize2;
+#else
+ int64_t probesize;
+#endif
/**
* dump format separator.
diff --git a/chromium/third_party/ffmpeg/libavformat/avidec.c b/chromium/third_party/ffmpeg/libavformat/avidec.c
index 5348b44b741..30b949770e6 100644
--- a/chromium/third_party/ffmpeg/libavformat/avidec.c
+++ b/chromium/third_party/ffmpeg/libavformat/avidec.c
@@ -823,7 +823,7 @@ static int avi_read_header(AVFormatContext *s)
st->codec->extradata_size += 9;
if ((ret = av_reallocp(&st->codec->extradata,
st->codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+ AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
st->codec->extradata_size = 0;
return ret;
} else
@@ -835,7 +835,7 @@ static int avi_read_header(AVFormatContext *s)
// avio_skip(pb, size - 5 * 4);
break;
case AVMEDIA_TYPE_AUDIO:
- ret = ff_get_wav_header(pb, st->codec, size, 0);
+ ret = ff_get_wav_header(s, pb, st->codec, size, 0);
if (ret < 0)
return ret;
ast->dshow_block_align = st->codec->block_align;
@@ -861,6 +861,9 @@ static int avi_read_header(AVFormatContext *s)
if (st->codec->codec_id == AV_CODEC_ID_AAC &&
st->codec->extradata_size)
st->need_parsing = AVSTREAM_PARSE_NONE;
+ // The flac parser does not work with AVSTREAM_PARSE_TIMESTAMPS
+ if (st->codec->codec_id == AV_CODEC_ID_FLAC)
+ st->need_parsing = AVSTREAM_PARSE_NONE;
/* AVI files with Xan DPCM audio (wrongly) declare PCM
* audio in the header but have Axan as stream_code_tag. */
if (ast->handler == AV_RL32("Axan")) {
@@ -872,8 +875,9 @@ static int avi_read_header(AVFormatContext *s)
st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV;
ast->dshow_block_align = 0;
}
- if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align ||
- st->codec->codec_id == AV_CODEC_ID_MP2 && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
+ if ((st->codec->codec_id == AV_CODEC_ID_AAC ||
+ st->codec->codec_id == AV_CODEC_ID_FLAC ||
+ st->codec->codec_id == AV_CODEC_ID_MP2 ) && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
ast->dshow_block_align = 0;
}
@@ -1304,9 +1308,6 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
int err;
-#if FF_API_DESTRUCT_PACKET
- void *dstr;
-#endif
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
@@ -1423,18 +1424,8 @@ resync:
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
AVBufferRef *avbuf = pkt->buf;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- dstr = pkt->destruct;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
pkt->data, pkt->size, pkt->pos);
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dstr;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
pkt->buf = avbuf;
pkt->flags |= AV_PKT_FLAG_KEY;
if (size < 0)
@@ -1681,9 +1672,13 @@ static int guess_ni_flag(AVFormatContext *s)
if (n >= 2) {
int64_t pos = st->index_entries[0].pos;
- avio_seek(s->pb, pos + 4, SEEK_SET);
+ unsigned tag[2];
+ avio_seek(s->pb, pos, SEEK_SET);
+ tag[0] = avio_r8(s->pb);
+ tag[1] = avio_r8(s->pb);
+ avio_rl16(s->pb);
size = avio_rl32(s->pb);
- if (pos + size > st->index_entries[1].pos)
+ if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos)
last_start = INT64_MAX;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/avienc.c b/chromium/third_party/ffmpeg/libavformat/avienc.c
index e5609d998c3..649961d11cf 100644
--- a/chromium/third_party/ffmpeg/libavformat/avienc.c
+++ b/chromium/third_party/ffmpeg/libavformat/avienc.c
@@ -29,10 +29,12 @@
#include "mpegts.h"
#include "libavformat/avlanguage.h"
#include "libavutil/avstring.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/avassert.h"
#include "libavutil/timestamp.h"
+#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavcodec/raw.h"
@@ -57,9 +59,11 @@ typedef struct AVIIndex {
} AVIIndex;
typedef struct AVIContext {
+ const AVClass *class;
int64_t riff_start, movi_list, odml_list;
int64_t frames_hdr_all;
int riff_id;
+ int write_channel_mask;
} AVIContext;
typedef struct AVIStream {
@@ -338,7 +342,7 @@ static int avi_write_header(AVFormatContext *s)
ff_end_tag(pb, strh);
if (enc->codec_type != AVMEDIA_TYPE_DATA) {
- int ret;
+ int ret, flags;
enum AVPixelFormat pix_fmt;
strf = ff_start_tag(pb, "strf");
@@ -366,7 +370,8 @@ static int avi_write_header(AVFormatContext *s)
av_get_pix_fmt_name(enc->pix_fmt));
break;
case AVMEDIA_TYPE_AUDIO:
- if ((ret = ff_put_wav_header(pb, enc, 0)) < 0)
+ flags = (avi->write_channel_mask == 0) ? FF_PUT_WAV_HEADER_SKIP_CHANNELMASK : 0;
+ if ((ret = ff_put_wav_header(pb, enc, flags)) < 0)
return ret;
break;
default:
@@ -618,7 +623,7 @@ static int write_skip_frames(AVFormatContext *s, int stream_index, int64_t dts)
AVIStream *avist = s->streams[stream_index]->priv_data;
AVCodecContext *enc = s->streams[stream_index]->codec;
- av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(dts), avist->packet_count, stream_index);
+ ff_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(dts), avist->packet_count, stream_index);
while (enc->block_align == 0 && dts != AV_NOPTS_VALUE &&
dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count) {
AVPacket empty_packet;
@@ -633,7 +638,7 @@ static int write_skip_frames(AVFormatContext *s, int stream_index, int64_t dts)
empty_packet.data = NULL;
empty_packet.stream_index = stream_index;
avi_write_packet(s, &empty_packet);
- av_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(dts), avist->packet_count);
+ ff_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(dts), avist->packet_count);
}
return 0;
@@ -781,6 +786,20 @@ static int avi_write_trailer(AVFormatContext *s)
return res;
}
+#define OFFSET(x) offsetof(AVIContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "write_channel_mask", "write channel mask into wave format header", OFFSET(write_channel_mask), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
+ { NULL },
+};
+
+static const AVClass avi_muxer_class = {
+ .class_name = "AVI muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_avi_muxer = {
.name = "avi",
.long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
@@ -795,4 +814,5 @@ AVOutputFormat ff_avi_muxer = {
.codec_tag = (const AVCodecTag * const []) {
ff_codec_bmp_tags, ff_codec_wav_tags, 0
},
+ .priv_class = &avi_muxer_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/avio.c b/chromium/third_party/ffmpeg/libavformat/avio.c
index deeb87f9ecb..21713d9d5e6 100644
--- a/chromium/third_party/ffmpeg/libavformat/avio.c
+++ b/chromium/third_party/ffmpeg/libavformat/avio.c
@@ -211,6 +211,26 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
return 0;
}
+int ffurl_accept(URLContext *s, URLContext **c)
+{
+ av_assert0(!*c);
+ if (s->prot->url_accept)
+ return s->prot->url_accept(s, c);
+ return AVERROR(EBADF);
+}
+
+int ffurl_handshake(URLContext *c)
+{
+ int ret;
+ if (c->prot->url_handshake) {
+ ret = c->prot->url_handshake(c);
+ if (ret)
+ return ret;
+ }
+ c->is_connected = 1;
+ return 0;
+}
+
#define URL_SCHEME_CHARS \
"abcdefghijklmnopqrstuvwxyz" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
@@ -263,7 +283,7 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags,
*puc = NULL;
if (av_strstart(filename, "https:", NULL))
- av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile with "
+ av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile FFmpeg with "
"openssl, gnutls,\n"
"or securetransport enabled.\n");
return AVERROR_PROTOCOL_NOT_FOUND;
@@ -421,6 +441,44 @@ int avio_check(const char *url, int flags)
return ret;
}
+int avpriv_io_move(const char *url_src, const char *url_dst)
+{
+ URLContext *h_src, *h_dst;
+ int ret = ffurl_alloc(&h_src, url_src, AVIO_FLAG_READ_WRITE, NULL);
+ if (ret < 0)
+ return ret;
+ ret = ffurl_alloc(&h_dst, url_dst, AVIO_FLAG_WRITE, NULL);
+ if (ret < 0) {
+ ffurl_close(h_src);
+ return ret;
+ }
+
+ if (h_src->prot == h_dst->prot && h_src->prot->url_move)
+ ret = h_src->prot->url_move(h_src, h_dst);
+ else
+ ret = AVERROR(ENOSYS);
+
+ ffurl_close(h_src);
+ ffurl_close(h_dst);
+ return ret;
+}
+
+int avpriv_io_delete(const char *url)
+{
+ URLContext *h;
+ int ret = ffurl_alloc(&h, url, AVIO_FLAG_WRITE, NULL);
+ if (ret < 0)
+ return ret;
+
+ if (h->prot->url_delete)
+ ret = h->prot->url_delete(h);
+ else
+ ret = AVERROR(ENOSYS);
+
+ ffurl_close(h);
+ return ret;
+}
+
int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options)
{
URLContext *h = NULL;
@@ -447,6 +505,7 @@ int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options)
if (ret < 0)
goto fail;
+ h->is_connected = 1;
ctx->url_context = h;
*s = ctx;
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/avio.h b/chromium/third_party/ffmpeg/libavformat/avio.h
index 9f3a992307e..06dd7f5ef8e 100644
--- a/chromium/third_party/ffmpeg/libavformat/avio.h
+++ b/chromium/third_party/ffmpeg/libavformat/avio.h
@@ -230,6 +230,25 @@ const char *avio_find_protocol_name(const char *url);
int avio_check(const char *url, int flags);
/**
+ * Move or rename a resource.
+ *
+ * @note url_src and url_dst should share the same protocol and authority.
+ *
+ * @param url_src url to resource to be moved
+ * @param url_dst new url to resource if the operation succeeded
+ * @return >=0 on success or negative on error.
+ */
+int avpriv_io_move(const char *url_src, const char *url_dst);
+
+/**
+ * Delete a resource.
+ *
+ * @param url resource to be deleted.
+ * @return >=0 on success or negative on error.
+ */
+int avpriv_io_delete(const char *url);
+
+/**
* Open directory for reading.
*
* @param s directory read context. Pointer to a NULL pointer must be passed.
@@ -566,7 +585,7 @@ int avio_open_dyn_buf(AVIOContext **s);
/**
* Return the written size and a pointer to the buffer. The buffer
* must be freed with av_free().
- * Padding of FF_INPUT_BUFFER_PADDING_SIZE is added to the buffer.
+ * Padding of AV_INPUT_BUFFER_PADDING_SIZE is added to the buffer.
*
* @param s IO context
* @param pbuffer pointer to a byte buffer
@@ -629,4 +648,33 @@ struct AVBPrint;
*/
int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size);
+/**
+ * Accept and allocate a client context on a server context.
+ * @param s the server context
+ * @param c the client context, must be unallocated
+ * @return >= 0 on success or a negative value corresponding
+ * to an AVERROR on failure
+ */
+int avio_accept(AVIOContext *s, AVIOContext **c);
+
+/**
+ * Perform one step of the protocol handshake to accept a new client.
+ * This function must be called on a client returned by avio_accept() before
+ * using it as a read/write context.
+ * It is separate from avio_accept() because it may block.
+ * A step of the handshake is defined by places where the application may
+ * decide to change the proceedings.
+ * For example, on a protocol with a request header and a reply header, each
+ * one can constitute a step because the application may use the parameters
+ * from the request to change parameters in the reply; or each individual
+ * chunk of the request can constitute a step.
+ * If the handshake is already finished, avio_handshake() does nothing and
+ * returns 0 immediately.
+ *
+ * @param c the client context to perform the handshake on
+ * @return 0 on a complete and successful handshake
+ * > 0 if the handshake progressed, but is not complete
+ * < 0 for an AVERROR code
+ */
+int avio_handshake(AVIOContext *c);
#endif /* AVFORMAT_AVIO_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/aviobuf.c b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
index ff850813e67..1b3d5f5b80c 100644
--- a/chromium/third_party/ffmpeg/libavformat/aviobuf.c
+++ b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
@@ -1021,6 +1021,23 @@ int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
return 0;
}
+int avio_accept(AVIOContext *s, AVIOContext **c)
+{
+ int ret;
+ URLContext *sc = s->opaque;
+ URLContext *cc = NULL;
+ ret = ffurl_accept(sc, &cc);
+ if (ret < 0)
+ return ret;
+ return ffio_fdopen(c, cc);
+}
+
+int avio_handshake(AVIOContext *c)
+{
+ URLContext *cc = c->opaque;
+ return ffurl_handshake(cc);
+}
+
/* output in a dynamic buffer */
typedef struct DynBuffer {
@@ -1130,7 +1147,7 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
{
DynBuffer *d;
int size;
- static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
+ static const char padbuf[AV_INPUT_BUFFER_PADDING_SIZE] = {0};
int padding = 0;
if (!s) {
@@ -1141,7 +1158,7 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
/* don't attempt to pad fixed-size packet buffers */
if (!s->max_packet_size) {
avio_write(s, padbuf, sizeof(padbuf));
- padding = FF_INPUT_BUFFER_PADDING_SIZE;
+ padding = AV_INPUT_BUFFER_PADDING_SIZE;
}
avio_flush(s);
diff --git a/chromium/third_party/ffmpeg/libavformat/avisynth.c b/chromium/third_party/ffmpeg/libavformat/avisynth.c
index 7dc5ee7df62..45641c0fc1d 100644
--- a/chromium/third_party/ffmpeg/libavformat/avisynth.c
+++ b/chromium/third_party/ffmpeg/libavformat/avisynth.c
@@ -237,13 +237,12 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
st->codec->width = avs->vi->width;
st->codec->height = avs->vi->height;
- st->time_base = (AVRational) { avs->vi->fps_denominator,
- avs->vi->fps_numerator };
st->avg_frame_rate = (AVRational) { avs->vi->fps_numerator,
avs->vi->fps_denominator };
st->start_time = 0;
st->duration = avs->vi->num_frames;
st->nb_frames = avs->vi->num_frames;
+ avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator);
switch (avs->vi->pixel_type) {
#ifdef USING_AVISYNTH
@@ -311,9 +310,8 @@ static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st)
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->sample_rate = avs->vi->audio_samples_per_second;
st->codec->channels = avs->vi->nchannels;
- st->time_base = (AVRational) { 1,
- avs->vi->audio_samples_per_second };
st->duration = avs->vi->num_audio_samples;
+ avpriv_set_pts_info(st, 64, 1, avs->vi->audio_samples_per_second);
switch (avs->vi->sample_type) {
case AVS_SAMPLE_INT8:
diff --git a/chromium/third_party/ffmpeg/libavformat/brstm.c b/chromium/third_party/ffmpeg/libavformat/brstm.c
index 1eba943e51c..f2bc0388402 100644
--- a/chromium/third_party/ffmpeg/libavformat/brstm.c
+++ b/chromium/third_party/ffmpeg/libavformat/brstm.c
@@ -30,9 +30,12 @@ typedef struct BRSTMDemuxContext {
uint32_t current_block;
uint32_t samples_per_block;
uint32_t last_block_used_bytes;
+ uint32_t last_block_size;
+ uint32_t last_block_samples;
+ uint32_t data_start;
uint8_t *table;
uint8_t *adpc;
- int bfstm;
+ int little_endian;
} BRSTMDemuxContext;
static int probe(AVProbeData *p)
@@ -46,7 +49,8 @@ static int probe(AVProbeData *p)
static int probe_bfstm(AVProbeData *p)
{
- if (AV_RL32(p->buf) == MKTAG('F','S','T','M') &&
+ if ((AV_RL32(p->buf) == MKTAG('F','S','T','M') ||
+ AV_RL32(p->buf) == MKTAG('C','S','T','M')) &&
(AV_RL16(p->buf + 4) == 0xFFFE ||
AV_RL16(p->buf + 4) == 0xFEFF))
return AVPROBE_SCORE_MAX / 3 * 2;
@@ -63,16 +67,34 @@ static int read_close(AVFormatContext *s)
return 0;
}
+static av_always_inline unsigned int read16(AVFormatContext *s)
+{
+ BRSTMDemuxContext *b = s->priv_data;
+ if (b->little_endian)
+ return avio_rl16(s->pb);
+ else
+ return avio_rb16(s->pb);
+}
+
+static av_always_inline unsigned int read32(AVFormatContext *s)
+{
+ BRSTMDemuxContext *b = s->priv_data;
+ if (b->little_endian)
+ return avio_rl32(s->pb);
+ else
+ return avio_rb32(s->pb);
+}
+
static int read_header(AVFormatContext *s)
{
BRSTMDemuxContext *b = s->priv_data;
int bom, major, minor, codec, chunk;
- int64_t h1offset, pos, toffset, data_offset = 0;
- uint32_t size, start, asize;
+ int64_t h1offset, pos, toffset;
+ uint32_t size, asize, start = 0;
AVStream *st;
int ret = AVERROR_EOF;
-
- b->bfstm = !strcmp("bfstm", s->iformat->name);
+ int loop = 0;
+ int bfstm = !strcmp("bfstm", s->iformat->name);
st = avformat_new_stream(s, NULL);
if (!st)
@@ -86,16 +108,15 @@ static int read_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom);
return AVERROR_INVALIDDATA;
}
- if (bom == 0xFFFE) {
- avpriv_request_sample(s, "little endian byte order");
- return AVERROR_PATCHWELCOME;
- }
- if (!b->bfstm) {
+ if (bom == 0xFFFE)
+ b->little_endian = 1;
+
+ if (!bfstm) {
major = avio_r8(s->pb);
minor = avio_r8(s->pb);
avio_skip(s->pb, 4); // size of file
- size = avio_rb16(s->pb);
+ size = read16(s);
if (size < 14)
return AVERROR_INVALIDDATA;
@@ -104,59 +125,58 @@ static int read_header(AVFormatContext *s)
if (avio_rl32(s->pb) != MKTAG('H','E','A','D'))
return AVERROR_INVALIDDATA;
} else {
- uint32_t info_offset = 0, info_size;
+ uint32_t info_offset = 0;
uint16_t section_count, header_size, i;
- header_size = avio_rb16(s->pb); // 6
+ header_size = read16(s); // 6
avio_skip(s->pb, 4); // Unknown constant 0x00030000
avio_skip(s->pb, 4); // size of file
- section_count = avio_rb16(s->pb);
+ section_count = read16(s);
avio_skip(s->pb, 2); // padding
for (i = 0; avio_tell(s->pb) < header_size
- && !(data_offset && info_offset)
+ && !(start && info_offset)
&& i < section_count; i++) {
- uint32_t flag = avio_rb32(s->pb);
+ uint16_t flag = read16(s);
+ avio_skip(s->pb, 2);
switch (flag) {
- case 0x40000000:
- info_offset = avio_rb32(s->pb);
- info_size = avio_rb32(s->pb);
+ case 0x4000:
+ info_offset = read32(s);
+ /*info_size =*/ read32(s);
break;
- case 0x40010000:
+ case 0x4001:
avio_skip(s->pb, 4); // seek offset
avio_skip(s->pb, 4); // seek size
break;
- case 0x40020000:
- data_offset = avio_rb32(s->pb);
- avio_skip(s->pb, 4); //data_size = avio_rb32(s->pb);
+ case 0x4002:
+ start = read32(s) + 8;
+ avio_skip(s->pb, 4); //data_size = read32(s);
break;
- case 0x40030000:
+ case 0x4003:
avio_skip(s->pb, 4); // REGN offset
avio_skip(s->pb, 4); // REGN size
break;
}
}
- if (!info_offset || !data_offset)
+ if (!info_offset || !start)
return AVERROR_INVALIDDATA;
- start = data_offset + 8;
-
avio_skip(s->pb, info_offset - avio_tell(s->pb));
pos = avio_tell(s->pb);
if (avio_rl32(s->pb) != MKTAG('I','N','F','O'))
return AVERROR_INVALIDDATA;
}
- size = avio_rb32(s->pb);
+ size = read32(s);
if (size < 192)
return AVERROR_INVALIDDATA;
avio_skip(s->pb, 4); // unknown
- h1offset = avio_rb32(s->pb);
+ h1offset = read32(s);
if (h1offset > size)
return AVERROR_INVALIDDATA;
avio_skip(s->pb, 12);
- toffset = avio_rb32(s->pb) + 16LL;
+ toffset = read32(s) + 16LL;
if (toffset > size)
return AVERROR_INVALIDDATA;
@@ -165,65 +185,77 @@ static int read_header(AVFormatContext *s)
switch (codec) {
case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR; break;
- case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break;
- case 2: codec = AV_CODEC_ID_ADPCM_THP; break;
+ case 1: codec = b->little_endian ?
+ AV_CODEC_ID_PCM_S16LE_PLANAR :
+ AV_CODEC_ID_PCM_S16BE_PLANAR; break;
+ case 2: codec = b->little_endian ?
+ AV_CODEC_ID_ADPCM_THP_LE :
+ AV_CODEC_ID_ADPCM_THP; break;
default:
avpriv_request_sample(s, "codec %d", codec);
return AVERROR_PATCHWELCOME;
}
- avio_skip(s->pb, 1); // loop flag
+ loop = avio_r8(s->pb); // loop flag
st->codec->codec_id = codec;
st->codec->channels = avio_r8(s->pb);
if (!st->codec->channels)
return AVERROR_INVALIDDATA;
avio_skip(s->pb, 1); // padding
- if (b->bfstm)
- avio_skip(s->pb, 2); // padding
- st->codec->sample_rate = avio_rb16(s->pb);
+ st->codec->sample_rate = bfstm ? read32(s) : read16(s);
if (!st->codec->sample_rate)
return AVERROR_INVALIDDATA;
- if (!b->bfstm)
+ if (!bfstm)
avio_skip(s->pb, 2); // padding
- avio_skip(s->pb, 4); // loop start sample
+
+ if (loop) {
+ if (av_dict_set_int(&s->metadata, "loop_start",
+ av_rescale(read32(s), AV_TIME_BASE,
+ st->codec->sample_rate),
+ 0) < 0)
+ return AVERROR(ENOMEM);
+ } else {
+ avio_skip(s->pb, 4);
+ }
+
st->start_time = 0;
- st->duration = avio_rb32(s->pb);
+ st->duration = read32(s);
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
- if (!b->bfstm)
- start = avio_rb32(s->pb);
+ if (!bfstm)
+ start = read32(s);
b->current_block = 0;
- b->block_count = avio_rb32(s->pb);
+ b->block_count = read32(s);
if (b->block_count > UINT16_MAX) {
av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count);
return AVERROR_INVALIDDATA;
}
- b->block_size = avio_rb32(s->pb);
- if (b->block_size > UINT16_MAX / st->codec->channels)
+ b->block_size = read32(s);
+ if (b->block_size > UINT32_MAX / st->codec->channels)
return AVERROR_INVALIDDATA;
- b->block_size *= st->codec->channels;
- b->samples_per_block = avio_rb32(s->pb);
- b->last_block_used_bytes = avio_rb32(s->pb);
- if (b->last_block_used_bytes > UINT16_MAX / st->codec->channels)
+ b->samples_per_block = read32(s);
+ b->last_block_used_bytes = read32(s);
+ b->last_block_samples = read32(s);
+ b->last_block_size = read32(s);
+ if (b->last_block_size > UINT32_MAX / st->codec->channels)
+ return AVERROR_INVALIDDATA;
+ if (b->last_block_used_bytes > b->last_block_size)
return AVERROR_INVALIDDATA;
- b->last_block_used_bytes *= st->codec->channels;
- avio_skip(s->pb, 4); // last block samples
- avio_skip(s->pb, 4); // last block size
- if (codec == AV_CODEC_ID_ADPCM_THP) {
+ if (codec == AV_CODEC_ID_ADPCM_THP || codec == AV_CODEC_ID_ADPCM_THP_LE) {
int ch;
avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
- if (!b->bfstm)
- toffset = avio_rb32(s->pb) + 16LL;
+ if (!bfstm)
+ toffset = read32(s) + 16LL;
else
- toffset = toffset + avio_rb32(s->pb) + st->codec->channels * 8 - 8;
+ toffset = toffset + read32(s) + st->codec->channels * 8 - 8;
if (toffset > size)
return AVERROR_INVALIDDATA;
@@ -237,15 +269,7 @@ static int read_header(AVFormatContext *s)
ret = AVERROR_INVALIDDATA;
goto fail;
}
- avio_skip(s->pb, b->bfstm ? 14 : 24);
- }
-
- if (b->bfstm) {
- st->codec->extradata_size = 32 * st->codec->channels;
- st->codec->extradata = av_malloc(st->codec->extradata_size);
- if (!st->codec->extradata)
- return AVERROR(ENOMEM);
- memcpy(st->codec->extradata, b->table, st->codec->extradata_size);
+ avio_skip(s->pb, bfstm ? 14 : 24);
}
}
@@ -254,22 +278,21 @@ static int read_header(AVFormatContext *s)
goto fail;
}
- if (!b->bfstm)
- avio_skip(s->pb, size - (avio_tell(s->pb) - pos));
- else
- avio_skip(s->pb, data_offset - avio_tell(s->pb));
+ avio_skip(s->pb, size - (avio_tell(s->pb) - pos));
while (!avio_feof(s->pb)) {
chunk = avio_rl32(s->pb);
- size = avio_rb32(s->pb);
+ size = read32(s);
if (size < 8) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
size -= 8;
switch (chunk) {
+ case MKTAG('S','E','E','K'):
case MKTAG('A','D','P','C'):
- if (codec != AV_CODEC_ID_ADPCM_THP)
+ if (codec != AV_CODEC_ID_ADPCM_THP &&
+ codec != AV_CODEC_ID_ADPCM_THP_LE)
goto skip;
asize = b->block_count * st->codec->channels * 4;
@@ -286,19 +309,36 @@ static int read_header(AVFormatContext *s)
ret = AVERROR(ENOMEM);
goto fail;
}
- avio_read(s->pb, b->adpc, asize);
+ if (bfstm && codec != AV_CODEC_ID_ADPCM_THP_LE) {
+ // Big-endian BFSTMs have little-endian SEEK tables
+ // for some strange reason.
+ int i;
+ for (i = 0; i < asize; i += 2) {
+ b->adpc[i+1] = avio_r8(s->pb);
+ b->adpc[i] = avio_r8(s->pb);
+ }
+ } else {
+ avio_read(s->pb, b->adpc, asize);
+ }
avio_skip(s->pb, size - asize);
}
break;
case MKTAG('D','A','T','A'):
if ((start < avio_tell(s->pb)) ||
- (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP && !b->bfstm)) {
+ (!b->adpc && (codec == AV_CODEC_ID_ADPCM_THP ||
+ codec == AV_CODEC_ID_ADPCM_THP_LE))) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
avio_skip(s->pb, start - avio_tell(s->pb));
- if ((major != 1 || minor) && !b->bfstm)
+ if (bfstm && (codec == AV_CODEC_ID_ADPCM_THP ||
+ codec == AV_CODEC_ID_ADPCM_THP_LE))
+ avio_skip(s->pb, 24);
+
+ b->data_start = avio_tell(s->pb);
+
+ if (!bfstm && (major != 1 || minor))
avpriv_request_sample(s, "Version %d.%d", major, minor);
return 0;
@@ -319,15 +359,25 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
AVCodecContext *codec = s->streams[0]->codec;
BRSTMDemuxContext *b = s->priv_data;
- uint32_t samples, size;
- int ret;
+ uint32_t samples, size, skip = 0;
+ int ret, i;
if (avio_feof(s->pb))
return AVERROR_EOF;
b->current_block++;
if (b->current_block == b->block_count) {
size = b->last_block_used_bytes;
- samples = size / (8 * codec->channels) * 14;
+ samples = b->last_block_samples;
+ skip = b->last_block_size - b->last_block_used_bytes;
+
+ if (samples < size * 14 / 8) {
+ uint32_t adjusted_size = samples / 14 * 8;
+ if (samples % 14)
+ adjusted_size += (samples % 14 + 1) / 2 + 1;
+
+ skip += size - adjusted_size;
+ size = adjusted_size;
+ }
} else if (b->current_block < b->block_count) {
size = b->block_size;
samples = b->samples_per_block;
@@ -335,23 +385,36 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR_EOF;
}
- if (codec->codec_id == AV_CODEC_ID_ADPCM_THP && !codec->extradata) {
+ if (codec->codec_id == AV_CODEC_ID_ADPCM_THP ||
+ codec->codec_id == AV_CODEC_ID_ADPCM_THP_LE) {
uint8_t *dst;
- if (av_new_packet(pkt, 8 + (32 + 4) * codec->channels + size) < 0)
+ if (av_new_packet(pkt, 8 + (32 + 4 + size) * codec->channels) < 0)
return AVERROR(ENOMEM);
dst = pkt->data;
- bytestream_put_be32(&dst, size);
- bytestream_put_be32(&dst, samples);
+ if (codec->codec_id == AV_CODEC_ID_ADPCM_THP_LE) {
+ bytestream_put_le32(&dst, size * codec->channels);
+ bytestream_put_le32(&dst, samples);
+ } else {
+ bytestream_put_be32(&dst, size * codec->channels);
+ bytestream_put_be32(&dst, samples);
+ }
bytestream_put_buffer(&dst, b->table, 32 * codec->channels);
bytestream_put_buffer(&dst, b->adpc + 4 * codec->channels *
(b->current_block - 1), 4 * codec->channels);
- ret = avio_read(s->pb, dst, size);
- if (ret != size)
- av_free_packet(pkt);
+ for (i = 0; i < codec->channels; i++) {
+ ret = avio_read(s->pb, dst, size);
+ dst += size;
+ avio_skip(s->pb, skip);
+ if (ret != size) {
+ av_free_packet(pkt);
+ break;
+ }
+ }
pkt->duration = samples;
} else {
+ size *= codec->channels;
ret = av_get_packet(s->pb, pkt, size);
}
@@ -363,6 +426,24 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
+static int read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ AVStream *st = s->streams[stream_index];
+ BRSTMDemuxContext *b = s->priv_data;
+ int64_t ret = 0;
+
+ timestamp /= b->samples_per_block;
+ ret = avio_seek(s->pb, b->data_start + timestamp * b->block_size *
+ st->codec->channels, SEEK_SET);
+ if (ret < 0)
+ return ret;
+
+ b->current_block = timestamp;
+ ff_update_cur_dts(s, st, timestamp * b->samples_per_block);
+ return 0;
+}
+
AVInputFormat ff_brstm_demuxer = {
.name = "brstm",
.long_name = NULL_IF_CONFIG_SMALL("BRSTM (Binary Revolution Stream)"),
@@ -371,6 +452,7 @@ AVInputFormat ff_brstm_demuxer = {
.read_header = read_header,
.read_packet = read_packet,
.read_close = read_close,
+ .read_seek = read_seek,
.extensions = "brstm",
};
@@ -382,5 +464,6 @@ AVInputFormat ff_bfstm_demuxer = {
.read_header = read_header,
.read_packet = read_packet,
.read_close = read_close,
- .extensions = "bfstm",
+ .read_seek = read_seek,
+ .extensions = "bfstm,bcstm",
};
diff --git a/chromium/third_party/ffmpeg/libavformat/caf.c b/chromium/third_party/ffmpeg/libavformat/caf.c
index c1ecc94425e..00854615ca3 100644
--- a/chromium/third_party/ffmpeg/libavformat/caf.c
+++ b/chromium/third_party/ffmpeg/libavformat/caf.c
@@ -61,6 +61,18 @@ const AVCodecTag ff_codec_caf_tags[] = {
/*{ MPEG4CELP MKTAG('c','e','l','p') },*/
/*{ MPEG4HVXC MKTAG('h','v','x','c') },*/
/*{ MPEG4TwinVQ MKTAG('t','w','v','q') },*/
+
+ { AV_CODEC_ID_PCM_S8, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_S16LE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_S16BE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_S24LE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_S24BE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_S32LE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_S32BE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_F32LE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_F32BE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_F64LE, MKTAG('l','p','c','m') },
+ { AV_CODEC_ID_PCM_F64BE, MKTAG('l','p','c','m') },
{ AV_CODEC_ID_NONE, 0 },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/cafdec.c b/chromium/third_party/ffmpeg/libavformat/cafdec.c
index cc6ed0ce9f6..bfbbb02627a 100644
--- a/chromium/third_party/ffmpeg/libavformat/cafdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/cafdec.c
@@ -101,7 +101,7 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size)
AVIOContext *pb = s->pb;
AVStream *st = s->streams[0];
- if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
+ if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
return -1;
if (st->codec->codec_id == AV_CODEC_ID_AAC) {
diff --git a/chromium/third_party/ffmpeg/libavformat/cafenc.c b/chromium/third_party/ffmpeg/libavformat/cafenc.c
index 1708275e11f..544bc4a114f 100644
--- a/chromium/third_party/ffmpeg/libavformat/cafenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/cafenc.c
@@ -120,21 +120,6 @@ static int caf_write_header(AVFormatContext *s)
return AVERROR_PATCHWELCOME;
}
- switch (enc->codec_id) {
- case AV_CODEC_ID_PCM_S8:
- case AV_CODEC_ID_PCM_S16LE:
- case AV_CODEC_ID_PCM_S16BE:
- case AV_CODEC_ID_PCM_S24LE:
- case AV_CODEC_ID_PCM_S24BE:
- case AV_CODEC_ID_PCM_S32LE:
- case AV_CODEC_ID_PCM_S32BE:
- case AV_CODEC_ID_PCM_F32LE:
- case AV_CODEC_ID_PCM_F32BE:
- case AV_CODEC_ID_PCM_F64LE:
- case AV_CODEC_ID_PCM_F64BE:
- codec_tag = MKTAG('l','p','c','m');
- }
-
if (!codec_tag) {
av_log(s, AV_LOG_ERROR, "unsupported codec\n");
return AVERROR_INVALIDDATA;
diff --git a/chromium/third_party/ffmpeg/libavformat/concatdec.c b/chromium/third_party/ffmpeg/libavformat/concatdec.c
index 07db9f96a39..88b6dbe6a44 100644
--- a/chromium/third_party/ffmpeg/libavformat/concatdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/concatdec.c
@@ -41,8 +41,13 @@ typedef struct ConcatStream {
typedef struct {
char *url;
int64_t start_time;
+ int64_t file_start_time;
+ int64_t file_inpoint;
int64_t duration;
ConcatStream *streams;
+ int64_t inpoint;
+ int64_t outpoint;
+ AVDictionary *metadata;
int nb_streams;
} ConcatFile;
@@ -54,6 +59,7 @@ typedef struct {
AVFormatContext *avf;
int safe;
int seekable;
+ int eof;
ConcatMatchMode stream_match_mode;
unsigned auto_convert;
} ConcatContext;
@@ -142,6 +148,8 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
file->url = url;
file->start_time = AV_NOPTS_VALUE;
file->duration = AV_NOPTS_VALUE;
+ file->inpoint = AV_NOPTS_VALUE;
+ file->outpoint = AV_NOPTS_VALUE;
return 0;
@@ -172,6 +180,8 @@ static int copy_stream_props(AVStream *st, AVStream *source_st)
st->avg_frame_rate = source_st->avg_frame_rate;
st->time_base = source_st->time_base;
st->sample_aspect_ratio = source_st->sample_aspect_ratio;
+
+ av_dict_copy(&st->metadata, source_st->metadata, 0);
return 0;
}
@@ -304,8 +314,14 @@ static int open_file(AVFormatContext *avf, unsigned fileno)
file->start_time = !fileno ? 0 :
cat->files[fileno - 1].start_time +
cat->files[fileno - 1].duration;
+ file->file_start_time = (avf->start_time == AV_NOPTS_VALUE) ? 0 : avf->start_time;
+ file->file_inpoint = (file->inpoint == AV_NOPTS_VALUE) ? file->file_start_time : file->inpoint;
if ((ret = match_streams(avf)) < 0)
return ret;
+ if (file->inpoint != AV_NOPTS_VALUE) {
+ if ((ret = avformat_seek_file(cat->avf, -1, INT64_MIN, file->inpoint, file->inpoint, 0)) < 0)
+ return ret;
+ }
return 0;
}
@@ -319,6 +335,7 @@ static int concat_read_close(AVFormatContext *avf)
for (i = 0; i < cat->nb_files; i++) {
av_freep(&cat->files[i].url);
av_freep(&cat->files[i].streams);
+ av_dict_free(&cat->files[i].metadata);
}
av_freep(&cat->files);
return 0;
@@ -351,20 +368,43 @@ static int concat_read_header(AVFormatContext *avf)
}
if ((ret = add_file(avf, filename, &file, &nb_files_alloc)) < 0)
goto fail;
- } else if (!strcmp(keyword, "duration")) {
+ } else if (!strcmp(keyword, "duration") || !strcmp(keyword, "inpoint") || !strcmp(keyword, "outpoint")) {
char *dur_str = get_keyword(&cursor);
int64_t dur;
if (!file) {
- av_log(avf, AV_LOG_ERROR, "Line %d: duration without file\n",
- line);
+ av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n",
+ line, keyword);
FAIL(AVERROR_INVALIDDATA);
}
if ((ret = av_parse_time(&dur, dur_str, 1)) < 0) {
- av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n",
- line, dur_str);
+ av_log(avf, AV_LOG_ERROR, "Line %d: invalid %s '%s'\n",
+ line, keyword, dur_str);
goto fail;
}
- file->duration = dur;
+ if (!strcmp(keyword, "duration"))
+ file->duration = dur;
+ else if (!strcmp(keyword, "inpoint"))
+ file->inpoint = dur;
+ else if (!strcmp(keyword, "outpoint"))
+ file->outpoint = dur;
+ } else if (!strcmp(keyword, "file_packet_metadata")) {
+ char *metadata;
+ metadata = av_get_token((const char **)&cursor, SPACE_CHARS);
+ if (!metadata) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: packet metadata required\n", line);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if (!file) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n",
+ line, keyword);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if ((ret = av_dict_parse_string(&file->metadata, metadata, "=", "", 0)) < 0) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
+ av_freep(&metadata);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ av_freep(&metadata);
} else if (!strcmp(keyword, "stream")) {
if (!avformat_new_stream(avf, NULL))
FAIL(AVERROR(ENOMEM));
@@ -401,8 +441,11 @@ static int concat_read_header(AVFormatContext *avf)
cat->files[i].start_time = time;
else
time = cat->files[i].start_time;
- if (cat->files[i].duration == AV_NOPTS_VALUE)
- break;
+ if (cat->files[i].duration == AV_NOPTS_VALUE) {
+ if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE)
+ break;
+ cat->files[i].duration = cat->files[i].outpoint - cat->files[i].inpoint;
+ }
time += cat->files[i].duration;
}
if (i == cat->nb_files) {
@@ -426,11 +469,18 @@ static int open_next_file(AVFormatContext *avf)
ConcatContext *cat = avf->priv_data;
unsigned fileno = cat->cur_file - cat->files;
- if (cat->cur_file->duration == AV_NOPTS_VALUE)
+ if (cat->cur_file->duration == AV_NOPTS_VALUE) {
cat->cur_file->duration = cat->avf->duration;
+ if (cat->cur_file->inpoint != AV_NOPTS_VALUE)
+ cat->cur_file->duration -= (cat->cur_file->inpoint - cat->cur_file->file_start_time);
+ if (cat->cur_file->outpoint != AV_NOPTS_VALUE)
+ cat->cur_file->duration -= cat->avf->duration - (cat->cur_file->outpoint - cat->cur_file->file_start_time);
+ }
- if (++fileno >= cat->nb_files)
+ if (++fileno >= cat->nb_files) {
+ cat->eof = 1;
return AVERROR_EOF;
+ }
return open_file(avf, fileno);
}
@@ -474,20 +524,35 @@ static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
return 0;
}
+/* Returns true if the packet dts is greater or equal to the specified outpoint. */
+static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt)
+{
+ if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE) {
+ return av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
+ cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0;
+ }
+ return 0;
+}
+
static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
{
ConcatContext *cat = avf->priv_data;
int ret;
- int64_t file_start_time, delta;
+ int64_t delta;
ConcatStream *cs;
AVStream *st;
+ if (cat->eof)
+ return AVERROR_EOF;
+
if (!cat->avf)
return AVERROR(EIO);
while (1) {
ret = av_read_frame(cat->avf, pkt);
- if (ret == AVERROR_EOF) {
+ if (ret == AVERROR_EOF || packet_after_outpoint(cat, pkt)) {
+ if (ret == 0)
+ av_packet_unref(pkt);
if ((ret = open_next_file(avf)) < 0)
return ret;
continue;
@@ -515,10 +580,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
- file_start_time = cat->avf->start_time;
- if (file_start_time == AV_NOPTS_VALUE)
- file_start_time = 0;
- delta = av_rescale_q(cat->cur_file->start_time - file_start_time,
+ delta = av_rescale_q(cat->cur_file->start_time - cat->cur_file->file_inpoint,
AV_TIME_BASE_Q,
cat->avf->streams[pkt->stream_index]->time_base);
if (pkt->pts != AV_NOPTS_VALUE)
@@ -528,6 +590,19 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
+ if (cat->cur_file->metadata) {
+ uint8_t* metadata;
+ int metadata_len;
+ char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
+ if (!packed_metadata)
+ return AVERROR(ENOMEM);
+ if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) {
+ av_freep(&packed_metadata);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(metadata, packed_metadata, metadata_len);
+ av_freep(&packed_metadata);
+ }
return ret;
}
@@ -545,7 +620,7 @@ static int try_seek(AVFormatContext *avf, int stream,
int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
ConcatContext *cat = avf->priv_data;
- int64_t t0 = cat->cur_file->start_time - cat->avf->start_time;
+ int64_t t0 = cat->cur_file->start_time - cat->cur_file->file_inpoint;
ts -= t0;
min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0;
@@ -616,6 +691,7 @@ static int concat_seek(AVFormatContext *avf, int stream,
cat->cur_file = cur_file_saved;
} else {
avformat_close_input(&cur_avf_saved);
+ cat->eof = 0;
}
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/dnxhddec.c b/chromium/third_party/ffmpeg/libavformat/dnxhddec.c
index 910e6b6684e..37e52d54c27 100644
--- a/chromium/third_party/ffmpeg/libavformat/dnxhddec.c
+++ b/chromium/third_party/ffmpeg/libavformat/dnxhddec.c
@@ -37,7 +37,7 @@ static int dnxhd_probe(AVProbeData *p)
if (!w || !h)
return 0;
compression_id = AV_RB32(p->buf + 0x28);
- if (compression_id < 1235 || compression_id > 1258)
+ if (compression_id < 1235 || compression_id > 1260)
return 0;
return AVPROBE_SCORE_MAX;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/dtsdec.c b/chromium/third_party/ffmpeg/libavformat/dtsdec.c
index da0fb61a60a..ef283916e79 100644
--- a/chromium/third_party/ffmpeg/libavformat/dtsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/dtsdec.c
@@ -34,7 +34,7 @@ static int dts_probe(AVProbeData *p)
int markers[4*16] = {0};
int sum, max, i;
int64_t diff = 0;
- uint8_t hdr[12 + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
+ uint8_t hdr[12 + AV_INPUT_BUFFER_PADDING_SIZE] = { 0 };
buf = p->buf + FFMIN(4096, p->buf_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/dump.c b/chromium/third_party/ffmpeg/libavformat/dump.c
index 6355b99f416..705da821489 100644
--- a/chromium/third_party/ffmpeg/libavformat/dump.c
+++ b/chromium/third_party/ffmpeg/libavformat/dump.c
@@ -377,6 +377,9 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
av_log(ctx, AV_LOG_INFO, "audio service type: ");
dump_audioservicetype(ctx, &sd);
break;
+ case AV_PKT_DATA_QUALITY_STATS:
+ av_log(ctx, AV_LOG_INFO, "quality factor: %d, pict_type: %c", AV_RL32(sd.data), av_get_picture_type_char(sd.data[4]));
+ break;
default:
av_log(ctx, AV_LOG_WARNING,
"unknown side data type %d (%d bytes)", sd.type, sd.size);
@@ -420,8 +423,8 @@ static void dump_stream_format(AVFormatContext *ic, int i,
av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) {
AVRational display_aspect_ratio;
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
- st->codec->width * st->sample_aspect_ratio.num,
- st->codec->height * st->sample_aspect_ratio.den,
+ st->codec->width * (int64_t)st->sample_aspect_ratio.num,
+ st->codec->height * (int64_t)st->sample_aspect_ratio.den,
1024 * 1024);
av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d",
st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
@@ -509,7 +512,7 @@ void av_dump_format(AVFormatContext *ic, int index,
int secs, us;
av_log(NULL, AV_LOG_INFO, ", start: ");
secs = ic->start_time / AV_TIME_BASE;
- us = abs(ic->start_time % AV_TIME_BASE);
+ us = llabs(ic->start_time % AV_TIME_BASE);
av_log(NULL, AV_LOG_INFO, "%d.%06d",
secs, (int) av_rescale(us, 1000000, AV_TIME_BASE));
}
diff --git a/chromium/third_party/ffmpeg/libavformat/dv.c b/chromium/third_party/ffmpeg/libavformat/dv.c
index 85002289640..84c306114b6 100644
--- a/chromium/third_party/ffmpeg/libavformat/dv.c
+++ b/chromium/third_party/ffmpeg/libavformat/dv.c
@@ -553,12 +553,17 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
size = avpriv_dv_get_packet(c->dv_demux, pkt);
if (size < 0) {
+ int ret;
int64_t pos = avio_tell(s->pb);
if (!c->dv_demux->sys)
return AVERROR(EIO);
size = c->dv_demux->sys->frame_size;
- if (avio_read(s->pb, c->buf, size) <= 0)
+ ret = avio_read(s->pb, c->buf, size);
+ if (ret < 0) {
+ return ret;
+ } else if (ret == 0) {
return AVERROR(EIO);
+ }
size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/dxa.c b/chromium/third_party/ffmpeg/libavformat/dxa.c
index 44033563f8a..228e6fdca1a 100644
--- a/chromium/third_party/ffmpeg/libavformat/dxa.c
+++ b/chromium/third_party/ffmpeg/libavformat/dxa.c
@@ -106,7 +106,7 @@ static int dxa_read_header(AVFormatContext *s)
ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
- ret = ff_get_wav_header(pb, ast->codec, fsize, 0);
+ ret = ff_get_wav_header(s, pb, ast->codec, fsize, 0);
if (ret < 0)
return ret;
if (ast->codec->sample_rate > 0)
diff --git a/chromium/third_party/ffmpeg/libavformat/electronicarts.c b/chromium/third_party/ffmpeg/libavformat/electronicarts.c
index d6a396b1ef5..5d21d49c455 100644
--- a/chromium/third_party/ffmpeg/libavformat/electronicarts.c
+++ b/chromium/third_party/ffmpeg/libavformat/electronicarts.c
@@ -59,17 +59,25 @@
#define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
#define MV0K_TAG MKTAG('M', 'V', '0', 'K')
#define MV0F_TAG MKTAG('M', 'V', '0', 'F')
+#define AVhd_TAG MKTAG('A', 'V', 'h', 'd')
+#define AV0K_TAG MKTAG('A', 'V', '0', 'K')
+#define AV0F_TAG MKTAG('A', 'V', '0', 'F')
#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */
#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV I-frame */
+#define AVP6_TAG MKTAG('A', 'V', 'P', '6')
-typedef struct EaDemuxContext {
- int big_endian;
-
- enum AVCodecID video_codec;
+typedef struct VideoProperties {
+ enum AVCodecID codec;
AVRational time_base;
int width, height;
int nb_frames;
- int video_stream_index;
+ int stream_index;
+} VideoProperties;
+
+typedef struct EaDemuxContext {
+ int big_endian;
+
+ VideoProperties video, alpha;
enum AVCodecID audio_codec;
int audio_stream_index;
@@ -301,46 +309,43 @@ static void process_audio_header_sead(AVFormatContext *s)
ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
}
-static void process_video_header_mdec(AVFormatContext *s)
+static void process_video_header_mdec(AVFormatContext *s, VideoProperties *video)
{
- EaDemuxContext *ea = s->priv_data;
AVIOContext *pb = s->pb;
avio_skip(pb, 4);
- ea->width = avio_rl16(pb);
- ea->height = avio_rl16(pb);
- ea->time_base = (AVRational) { 1, 15 };
- ea->video_codec = AV_CODEC_ID_MDEC;
+ video->width = avio_rl16(pb);
+ video->height = avio_rl16(pb);
+ video->time_base = (AVRational) { 1, 15 };
+ video->codec = AV_CODEC_ID_MDEC;
}
-static int process_video_header_vp6(AVFormatContext *s)
+static int process_video_header_vp6(AVFormatContext *s, VideoProperties *video)
{
- EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
avio_skip(pb, 8);
- ea->nb_frames = avio_rl32(pb);
+ video->nb_frames = avio_rl32(pb);
avio_skip(pb, 4);
- ea->time_base.den = avio_rl32(pb);
- ea->time_base.num = avio_rl32(pb);
- if (ea->time_base.den <= 0 || ea->time_base.num <= 0) {
+ video->time_base.den = avio_rl32(pb);
+ video->time_base.num = avio_rl32(pb);
+ if (video->time_base.den <= 0 || video->time_base.num <= 0) {
av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
return AVERROR_INVALIDDATA;
}
- ea->video_codec = AV_CODEC_ID_VP6;
+ video->codec = AV_CODEC_ID_VP6;
return 1;
}
-static void process_video_header_cmv(AVFormatContext *s)
+static void process_video_header_cmv(AVFormatContext *s, VideoProperties *video)
{
- EaDemuxContext *ea = s->priv_data;
int fps;
avio_skip(s->pb, 10);
fps = avio_rl16(s->pb);
if (fps)
- ea->time_base = (AVRational) { 1, fps };
- ea->video_codec = AV_CODEC_ID_CMV;
+ video->time_base = (AVRational) { 1, fps };
+ video->codec = AV_CODEC_ID_CMV;
}
/* Process EA file header.
@@ -352,7 +357,7 @@ static int process_ea_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
int i;
- for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
+ for (i = 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) {
uint64_t startpos = avio_tell(pb);
int err = 0;
@@ -394,40 +399,44 @@ static int process_ea_header(AVFormatContext *s)
break;
case MVIh_TAG:
- process_video_header_cmv(s);
+ process_video_header_cmv(s, &ea->video);
break;
case kVGT_TAG:
- ea->video_codec = AV_CODEC_ID_TGV;
+ ea->video.codec = AV_CODEC_ID_TGV;
break;
case mTCD_TAG:
- process_video_header_mdec(s);
+ process_video_header_mdec(s, &ea->video);
break;
case MPCh_TAG:
- ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
+ ea->video.codec = AV_CODEC_ID_MPEG2VIDEO;
break;
case pQGT_TAG:
case TGQs_TAG:
- ea->video_codec = AV_CODEC_ID_TGQ;
- ea->time_base = (AVRational) { 1, 15 };
+ ea->video.codec = AV_CODEC_ID_TGQ;
+ ea->video.time_base = (AVRational) { 1, 15 };
break;
case pIQT_TAG:
- ea->video_codec = AV_CODEC_ID_TQI;
- ea->time_base = (AVRational) { 1, 15 };
+ ea->video.codec = AV_CODEC_ID_TQI;
+ ea->video.time_base = (AVRational) { 1, 15 };
break;
case MADk_TAG:
- ea->video_codec = AV_CODEC_ID_MAD;
+ ea->video.codec = AV_CODEC_ID_MAD;
avio_skip(pb, 6);
- ea->time_base = (AVRational) { avio_rl16(pb), 1000 };
+ ea->video.time_base = (AVRational) { avio_rl16(pb), 1000 };
break;
case MVhd_TAG:
- err = process_video_header_vp6(s);
+ err = process_video_header_vp6(s, &ea->video);
+ break;
+
+ case AVhd_TAG:
+ err = process_video_header_vp6(s, &ea->alpha);
break;
}
@@ -458,6 +467,7 @@ static int ea_probe(AVProbeData *p)
case MPCh_TAG:
case MVhd_TAG:
case MVIh_TAG:
+ case AVP6_TAG:
break;
default:
return 0;
@@ -472,6 +482,34 @@ static int ea_probe(AVProbeData *p)
return AVPROBE_SCORE_MAX;
}
+static int init_video_stream(AVFormatContext *s, VideoProperties *video)
+{
+ AVStream *st;
+
+ if (!video->codec)
+ return 0;
+
+ /* initialize the video decoder stream */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ video->stream_index = st->index;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = video->codec;
+ // parsing is necessary to make FFmpeg generate correct timestamps
+ if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
+ st->codec->codec_tag = 0; /* no fourcc */
+ st->codec->width = video->width;
+ st->codec->height = video->height;
+ st->duration = st->nb_frames = video->nb_frames;
+ if (video->time_base.num)
+ avpriv_set_pts_info(st, 64, video->time_base.num, video->time_base.den);
+ st->r_frame_rate =
+ st->avg_frame_rate = av_inv_q(video->time_base);
+ return 0;
+}
+
static int ea_read_header(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
@@ -480,26 +518,8 @@ static int ea_read_header(AVFormatContext *s)
if (process_ea_header(s)<=0)
return AVERROR(EIO);
- if (ea->video_codec) {
- /* initialize the video decoder stream */
- st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
- ea->video_stream_index = st->index;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = ea->video_codec;
- // parsing is necessary to make FFmpeg generate correct timestamps
- if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
- st->need_parsing = AVSTREAM_PARSE_HEADERS;
- st->codec->codec_tag = 0; /* no fourcc */
- st->codec->width = ea->width;
- st->codec->height = ea->height;
- st->duration = st->nb_frames = ea->nb_frames;
- if (ea->time_base.num)
- avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
- st->r_frame_rate =
- st->avg_frame_rate = av_inv_q(ea->time_base);
- }
+ if (init_video_stream(s, &ea->video) || init_video_stream(s, &ea->alpha))
+ return AVERROR(ENOMEM);
if (ea->audio_codec) {
if (ea->num_channels <= 0 || ea->num_channels > 2) {
@@ -659,10 +679,12 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
goto get_video_packet;
case MV0K_TAG:
+ case AV0K_TAG:
case MPCh_TAG:
case pIQT_TAG:
key = AV_PKT_FLAG_KEY;
case MV0F_TAG:
+ case AV0F_TAG:
get_video_packet:
if (!chunk_size)
continue;
@@ -676,7 +698,10 @@ get_video_packet:
break;
}
partial_packet = chunk_type == MVIh_TAG;
- pkt->stream_index = ea->video_stream_index;
+ if (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG)
+ pkt->stream_index = ea->alpha.stream_index;
+ else
+ pkt->stream_index = ea->video.stream_index;
pkt->flags |= key;
packet_read = 1;
break;
diff --git a/chromium/third_party/ffmpeg/libavformat/ffmdec.c b/chromium/third_party/ffmpeg/libavformat/ffmdec.c
index 9b50c9f5a6f..110d31540f1 100644
--- a/chromium/third_party/ffmpeg/libavformat/ffmdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/ffmdec.c
@@ -21,6 +21,7 @@
#include <stdint.h>
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/opt.h"
@@ -160,7 +161,7 @@ static int64_t ffm_seek1(AVFormatContext *s, int64_t pos1)
pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE);
pos = FFMAX(pos, FFM_PACKET_SIZE);
- av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
+ ff_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
return avio_seek(pb, pos, SEEK_SET);
}
@@ -172,7 +173,7 @@ static int64_t get_dts(AVFormatContext *s, int64_t pos)
ffm_seek1(s, pos);
avio_skip(pb, 4);
dts = avio_rb64(pb);
- av_dlog(s, "dts=%0.6f\n", dts / 1000000.0);
+ ff_dlog(s, "dts=%0.6f\n", dts / 1000000.0);
return dts;
}
@@ -326,7 +327,7 @@ static int ffm2_read_header(AVFormatContext *s)
codec->flags = avio_rb32(pb);
codec->flags2 = avio_rb32(pb);
codec->debug = avio_rb32(pb);
- if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
+ if (codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
return AVERROR(ENOMEM);
}
@@ -573,7 +574,7 @@ static int ffm_read_header(AVFormatContext *s)
default:
goto fail;
}
- if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
+ if (codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
return AVERROR(ENOMEM);
}
@@ -608,7 +609,7 @@ static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt)
if ((ret = ffm_is_avail_data(s, FRAME_HEADER_SIZE+4)) < 0)
return ret;
- av_dlog(s, "pos=%08"PRIx64" spos=%"PRIx64", write_index=%"PRIx64" size=%"PRIx64"\n",
+ ff_dlog(s, "pos=%08"PRIx64" spos=%"PRIx64", write_index=%"PRIx64" size=%"PRIx64"\n",
avio_tell(s->pb), s->pb->pos, ffm->write_index, ffm->file_size);
if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) !=
FRAME_HEADER_SIZE)
@@ -666,7 +667,7 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in
int64_t pts_min, pts_max, pts;
double pos1;
- av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
+ ff_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
/* find the position using linear interpolation (better than
dichotomy in typical cases) */
if (ffm->write_index && ffm->write_index < ffm->file_size) {
diff --git a/chromium/third_party/ffmpeg/libavformat/ffmenc.c b/chromium/third_party/ffmpeg/libavformat/ffmenc.c
index 3abbfdd08f4..f0b5743ea46 100644
--- a/chromium/third_party/ffmpeg/libavformat/ffmenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/ffmenc.c
@@ -268,7 +268,7 @@ static int ffm_write_header(AVFormatContext *s)
avio_wb32(pb, codec->flags);
avio_wb32(pb, codec->flags2);
avio_wb32(pb, codec->debug);
- if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
+ if (codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
avio_wb32(pb, codec->extradata_size);
avio_write(pb, codec->extradata, codec->extradata_size);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/file.c b/chromium/third_party/ffmpeg/libavformat/file.c
index 6511328de7d..d59aa42b50b 100644
--- a/chromium/third_party/ffmpeg/libavformat/file.c
+++ b/chromium/third_party/ffmpeg/libavformat/file.c
@@ -23,6 +23,9 @@
#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "avformat.h"
+#if HAVE_DIRENT_H
+#include <dirent.h>
+#endif
#include <fcntl.h>
#if HAVE_IO_H
#include <io.h>
@@ -44,6 +47,24 @@
# endif
#endif
+/* Not available in POSIX.1-1996 */
+#ifndef S_ISLNK
+# ifdef S_IFLNK
+# define S_ISLNK(m) (((m) & S_IFLNK) == S_IFLNK)
+# else
+# define S_ISLNK(m) 0
+# endif
+#endif
+
+/* Not available in POSIX.1-1996 */
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+#endif
+
/* standard file protocol */
typedef struct FileContext {
@@ -51,6 +72,9 @@ typedef struct FileContext {
int fd;
int trunc;
int blocksize;
+#if HAVE_DIRENT_H
+ DIR *dir;
+#endif
} FileContext;
static const AVOption file_options[] = {
@@ -81,19 +105,19 @@ static const AVClass pipe_class = {
static int file_read(URLContext *h, unsigned char *buf, int size)
{
FileContext *c = h->priv_data;
- int r;
+ int ret;
size = FFMIN(size, c->blocksize);
- r = read(c->fd, buf, size);
- return (-1 == r)?AVERROR(errno):r;
+ ret = read(c->fd, buf, size);
+ return (ret == -1) ? AVERROR(errno) : ret;
}
static int file_write(URLContext *h, const unsigned char *buf, int size)
{
FileContext *c = h->priv_data;
- int r;
+ int ret;
size = FFMIN(size, c->blocksize);
- r = write(c->fd, buf, size);
- return (-1 == r)?AVERROR(errno):r;
+ ret = write(c->fd, buf, size);
+ return (ret == -1) ? AVERROR(errno) : ret;
}
static int file_get_handle(URLContext *h)
@@ -131,6 +155,42 @@ static int file_check(URLContext *h, int mask)
return ret;
}
+static int file_delete(URLContext *h)
+{
+#if HAVE_UNISTD_H
+ int ret;
+ const char *filename = h->filename;
+ av_strstart(filename, "file:", &filename);
+
+ ret = rmdir(filename);
+ if (ret < 0 && errno == ENOTDIR)
+ ret = unlink(filename);
+ if (ret < 0)
+ return AVERROR(errno);
+
+ return ret;
+#else
+ return AVERROR(ENOSYS);
+#endif /* HAVE_UNISTD_H */
+}
+
+static int file_move(URLContext *h_src, URLContext *h_dst)
+{
+#if HAVE_UNISTD_H
+ const char *filename_src = h_src->filename;
+ const char *filename_dst = h_dst->filename;
+ av_strstart(filename_src, "file:", &filename_src);
+ av_strstart(filename_dst, "file:", &filename_dst);
+
+ if (rename(filename_src, filename_dst) < 0)
+ return AVERROR(errno);
+
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif /* HAVE_UNISTD_H */
+}
+
#if CONFIG_FILE_PROTOCOL
static int file_open(URLContext *h, const char *filename, int flags)
@@ -189,6 +249,90 @@ static int file_close(URLContext *h)
return close(c->fd);
}
+static int file_open_dir(URLContext *h)
+{
+#if HAVE_LSTAT
+ FileContext *c = h->priv_data;
+
+ c->dir = opendir(h->filename);
+ if (!c->dir)
+ return AVERROR(errno);
+
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif /* HAVE_LSTAT */
+}
+
+static int file_read_dir(URLContext *h, AVIODirEntry **next)
+{
+#if HAVE_LSTAT
+ FileContext *c = h->priv_data;
+ struct dirent *dir;
+ char *fullpath = NULL;
+
+ *next = ff_alloc_dir_entry();
+ if (!*next)
+ return AVERROR(ENOMEM);
+ do {
+ errno = 0;
+ dir = readdir(c->dir);
+ if (!dir) {
+ av_freep(next);
+ return AVERROR(errno);
+ }
+ } while (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."));
+
+ fullpath = av_append_path_component(h->filename, dir->d_name);
+ if (fullpath) {
+ struct stat st;
+ if (!lstat(fullpath, &st)) {
+ if (S_ISDIR(st.st_mode))
+ (*next)->type = AVIO_ENTRY_DIRECTORY;
+ else if (S_ISFIFO(st.st_mode))
+ (*next)->type = AVIO_ENTRY_NAMED_PIPE;
+ else if (S_ISCHR(st.st_mode))
+ (*next)->type = AVIO_ENTRY_CHARACTER_DEVICE;
+ else if (S_ISBLK(st.st_mode))
+ (*next)->type = AVIO_ENTRY_BLOCK_DEVICE;
+ else if (S_ISLNK(st.st_mode))
+ (*next)->type = AVIO_ENTRY_SYMBOLIC_LINK;
+ else if (S_ISSOCK(st.st_mode))
+ (*next)->type = AVIO_ENTRY_SOCKET;
+ else if (S_ISREG(st.st_mode))
+ (*next)->type = AVIO_ENTRY_FILE;
+ else
+ (*next)->type = AVIO_ENTRY_UNKNOWN;
+
+ (*next)->group_id = st.st_gid;
+ (*next)->user_id = st.st_uid;
+ (*next)->size = st.st_size;
+ (*next)->filemode = st.st_mode & 0777;
+ (*next)->modification_timestamp = INT64_C(1000000) * st.st_mtime;
+ (*next)->access_timestamp = INT64_C(1000000) * st.st_atime;
+ (*next)->status_change_timestamp = INT64_C(1000000) * st.st_ctime;
+ }
+ av_free(fullpath);
+ }
+
+ (*next)->name = av_strdup(dir->d_name);
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif /* HAVE_LSTAT */
+}
+
+static int file_close_dir(URLContext *h)
+{
+#if HAVE_LSTAT
+ FileContext *c = h->priv_data;
+ closedir(c->dir);
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif /* HAVE_LSTAT */
+}
+
URLProtocol ff_file_protocol = {
.name = "file",
.url_open = file_open,
@@ -198,8 +342,13 @@ URLProtocol ff_file_protocol = {
.url_close = file_close,
.url_get_file_handle = file_get_handle,
.url_check = file_check,
+ .url_delete = file_delete,
+ .url_move = file_move,
.priv_data_size = sizeof(FileContext),
.priv_data_class = &file_class,
+ .url_open_dir = file_open_dir,
+ .url_read_dir = file_read_dir,
+ .url_close_dir = file_close_dir,
};
#endif /* CONFIG_FILE_PROTOCOL */
diff --git a/chromium/third_party/ffmpeg/libavformat/flac_picture.c b/chromium/third_party/ffmpeg/libavformat/flac_picture.c
index 669fd2e7825..7bd98258e4f 100644
--- a/chromium/third_party/ffmpeg/libavformat/flac_picture.c
+++ b/chromium/third_party/ffmpeg/libavformat/flac_picture.c
@@ -108,10 +108,10 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
ret = AVERROR_INVALIDDATA;
goto fail;
}
- if (!(data = av_buffer_alloc(len + FF_INPUT_BUFFER_PADDING_SIZE))) {
+ if (!(data = av_buffer_alloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
RETURN_ERROR(AVERROR(ENOMEM));
}
- memset(data->data + len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(data->data + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
if (avio_read(pb, data->data, len) != len) {
av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
if (s->error_recognition & AV_EF_EXPLODE)
diff --git a/chromium/third_party/ffmpeg/libavformat/flacdec.c b/chromium/third_party/ffmpeg/libavformat/flacdec.c
index 4207fd2bf6c..4c1f9435810 100644
--- a/chromium/third_party/ffmpeg/libavformat/flacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flacdec.c
@@ -58,7 +58,7 @@ static int flac_read_header(AVFormatContext *s)
case FLAC_METADATA_TYPE_CUESHEET:
case FLAC_METADATA_TYPE_PICTURE:
case FLAC_METADATA_TYPE_VORBIS_COMMENT:
- buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ buffer = av_mallocz(metadata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!buffer) {
return AVERROR(ENOMEM);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/flvdec.c b/chromium/third_party/ffmpeg/libavformat/flvdec.c
index 345be1ea7d2..826e0d7ea20 100644
--- a/chromium/third_party/ffmpeg/libavformat/flvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flvdec.c
@@ -433,6 +433,8 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream,
case AMF_DATA_TYPE_UNSUPPORTED:
break; // these take up no additional space
case AMF_DATA_TYPE_MIXEDARRAY:
+ {
+ unsigned v;
avio_skip(ioc, 4); // skip 32-bit max array index
while (avio_tell(ioc) < max_pos - 2 &&
amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
@@ -441,11 +443,13 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream,
if (amf_parse_object(s, astream, vstream, str_val, max_pos,
depth + 1) < 0)
return -1;
- if (avio_r8(ioc) != AMF_END_OF_OBJECT) {
- av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_MIXEDARRAY\n");
+ v = avio_r8(ioc);
+ if (v != AMF_END_OF_OBJECT) {
+ av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_MIXEDARRAY, found %d\n", v);
return -1;
}
break;
+ }
case AMF_DATA_TYPE_ARRAY:
{
unsigned int arraylen, i;
@@ -654,7 +658,7 @@ static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
{
av_free(flv->new_extradata[stream]);
flv->new_extradata[stream] = av_mallocz(size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!flv->new_extradata[stream])
return AVERROR(ENOMEM);
flv->new_extradata_size[stream] = size;
@@ -797,15 +801,16 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
int av_uninit(channels);
int av_uninit(sample_rate);
AVStream *st = NULL;
+ int last = -1;
/* pkt size is repeated at end. skip it */
- for (;; avio_skip(s->pb, 4)) {
+ for (;; last = avio_rb32(s->pb)) {
pos = avio_tell(s->pb);
type = (avio_r8(s->pb) & 0x1F);
size = avio_rb24(s->pb);
dts = avio_rb24(s->pb);
dts |= avio_r8(s->pb) << 24;
- av_log(s, AV_LOG_TRACE, "type:%d, size:%d, dts:%"PRId64" pos:%"PRId64"\n", type, size, dts, avio_tell(s->pb));
+ av_log(s, AV_LOG_TRACE, "type:%d, size:%d, last:%d, dts:%"PRId64" pos:%"PRId64"\n", type, size, last, dts, avio_tell(s->pb));
if (avio_feof(s->pb))
return AVERROR_EOF;
avio_skip(s->pb, 3); /* stream id, always 0 */
@@ -849,6 +854,13 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
meta_pos = avio_tell(s->pb);
type = flv_read_metabody(s, next);
if (type == 0 && dts == 0 || type < 0 || type == TYPE_UNKNOWN) {
+ if (type < 0 && flv->validate_count &&
+ flv->validate_index[0].pos > next &&
+ flv->validate_index[0].pos - 4 < next
+ ) {
+ av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n");
+ next = flv->validate_index[0].pos - 4;
+ }
goto skip;
} else if (type == TYPE_ONTEXTDATA) {
avpriv_request_sample(s, "OnTextData packet");
diff --git a/chromium/third_party/ffmpeg/libavformat/format.c b/chromium/third_party/ffmpeg/libavformat/format.c
index 7df06b70fc0..fd81d7a132a 100644
--- a/chromium/third_party/ffmpeg/libavformat/format.c
+++ b/chromium/third_party/ffmpeg/libavformat/format.c
@@ -261,8 +261,13 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt,
if (pb->av_class) {
uint8_t *mime_type_opt = NULL;
+ char *semi;
av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type_opt);
pd.mime_type = (const char *)mime_type_opt;
+ semi = pd.mime_type ? strchr(pd.mime_type, ';') : NULL;
+ if (semi) {
+ *semi = '\0';
+ }
}
#if 0
if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) {
diff --git a/chromium/third_party/ffmpeg/libavformat/ftp.c b/chromium/third_party/ffmpeg/libavformat/ftp.c
index 27a172e8ad7..dcb588dac29 100644
--- a/chromium/third_party/ffmpeg/libavformat/ftp.c
+++ b/chromium/third_party/ffmpeg/libavformat/ftp.c
@@ -19,6 +19,8 @@
*/
#include "libavutil/avstring.h"
+#include "libavutil/internal.h"
+#include "libavutil/parseutils.h"
#include "avformat.h"
#include "internal.h"
#include "url.h"
@@ -26,15 +28,23 @@
#include "libavutil/bprint.h"
#define CONTROL_BUFFER_SIZE 1024
+#define DIR_BUFFER_SIZE 4096
typedef enum {
UNKNOWN,
READY,
DOWNLOADING,
UPLOADING,
+ LISTING_DIR,
DISCONNECTED
} FTPState;
+typedef enum {
+ UNKNOWN_METHOD,
+ NLST,
+ MLSD
+} FTPListingMethod;
+
typedef struct {
const AVClass *class;
URLContext *conn_control; /**< Control connection */
@@ -53,6 +63,12 @@ typedef struct {
const char *anonymous_password; /**< Password to be used for anonymous user. An email should be used. */
int write_seekable; /**< Control seekability, 0 = disable, 1 = enable. */
FTPState state; /**< State of data connection */
+ FTPListingMethod listing_method; /**< Called listing method */
+ char *features; /**< List of server's features represented as raw response */
+ char *dir_buffer;
+ size_t dir_buffer_size;
+ size_t dir_buffer_offset;
+ int utf8;
} FTPContext;
#define OFFSET(x) offsetof(FTPContext, x)
@@ -185,6 +201,8 @@ static int ftp_send_command(FTPContext *s, const char *command,
{
int err;
+ ff_dlog(s, "%s", command);
+
if (response)
*response = NULL;
@@ -266,7 +284,7 @@ static int ftp_passive_mode_epsv(FTPContext *s)
end[-1] = '\0';
s->server_data_port = atoi(start);
- av_dlog(s, "Server data port: %d\n", s->server_data_port);
+ ff_dlog(s, "Server data port: %d\n", s->server_data_port);
av_free(res);
return 0;
@@ -312,7 +330,7 @@ static int ftp_passive_mode(FTPContext *s)
start = av_strtok(end, ",", &end);
if (!start) goto fail;
s->server_data_port += atoi(start);
- av_dlog(s, "Server data port: %d\n", s->server_data_port);
+ ff_dlog(s, "Server data port: %d\n", s->server_data_port);
av_free(res);
return 0;
@@ -347,10 +365,7 @@ static int ftp_current_dir(FTPContext *s)
if (!end)
goto fail;
- if (end > res && end[-1] == '/') {
- end[-1] = '\0';
- } else
- *end = '\0';
+ *end = '\0';
s->path = av_strdup(start);
av_free(res);
@@ -434,19 +449,76 @@ static int ftp_restart(FTPContext *s, int64_t pos)
return 0;
}
+static int ftp_set_dir(FTPContext *s)
+{
+ static const int cwd_codes[] = {250, 550, 0}; /* 550 is incorrect code */
+ char command[MAX_URL_SIZE];
+
+ snprintf(command, sizeof(command), "CWD %s\r\n", s->path);
+ if (ftp_send_command(s, command, cwd_codes, NULL) != 250)
+ return AVERROR(EIO);
+ return 0;
+}
+
+static int ftp_list_mlsd(FTPContext *s)
+{
+ static const char *command = "MLSD\r\n";
+ static const int mlsd_codes[] = {150, 500, 0}; /* 500 is incorrect code */
+
+ if (ftp_send_command(s, command, mlsd_codes, NULL) != 150)
+ return AVERROR(ENOSYS);
+ s->listing_method = MLSD;
+ return 0;
+}
+
+static int ftp_list_nlst(FTPContext *s)
+{
+ static const char *command = "NLST\r\n";
+ static const int nlst_codes[] = {226, 425, 426, 451, 450, 550, 0};
+
+ if (ftp_send_command(s, command, nlst_codes, NULL) != 226)
+ return AVERROR(ENOSYS);
+ s->listing_method = NLST;
+ return 0;
+}
+
+static int ftp_has_feature(FTPContext *s, const char *feature_name);
+
+static int ftp_list(FTPContext *s)
+{
+ int ret;
+ s->state = LISTING_DIR;
+
+ if ((ret = ftp_list_mlsd(s)) < 0)
+ ret = ftp_list_nlst(s);
+
+ return ret;
+}
+
+static int ftp_has_feature(FTPContext *s, const char *feature_name)
+{
+ if (!s->features)
+ return 0;
+
+ return av_stristr(s->features, feature_name) != NULL;
+}
+
static int ftp_features(FTPContext *s)
{
static const char *feat_command = "FEAT\r\n";
static const char *enable_utf8_command = "OPTS UTF8 ON\r\n";
static const int feat_codes[] = {211, 0};
- static const int opts_codes[] = {200, 451};
- char *feat = NULL;
+ static const int opts_codes[] = {200, 451, 0};
- if (ftp_send_command(s, feat_command, feat_codes, &feat) == 211) {
- if (av_stristr(feat, "UTF8"))
- ftp_send_command(s, enable_utf8_command, opts_codes, NULL);
+ av_freep(&s->features);
+ if (ftp_send_command(s, feat_command, feat_codes, &s->features) != 211) {
+ av_freep(&s->features);
+ }
+
+ if (ftp_has_feature(s, "UTF8")) {
+ if (ftp_send_command(s, enable_utf8_command, opts_codes, NULL) == 200)
+ s->utf8 = 1;
}
- av_freep(&feat);
return 0;
}
@@ -570,20 +642,19 @@ static int ftp_abort(URLContext *h)
return 0;
}
-static int ftp_open(URLContext *h, const char *url, int flags)
+static int ftp_connect(URLContext *h, const char *url)
{
char proto[10], path[MAX_URL_SIZE], credencials[MAX_URL_SIZE], hostname[MAX_URL_SIZE];
const char *tok_user = NULL, *tok_pass = NULL;
- char *end = NULL;
+ char *end = NULL, *newpath = NULL;
int err;
- size_t pathlen;
FTPContext *s = h->priv_data;
- av_dlog(h, "ftp protocol open\n");
-
s->state = DISCONNECTED;
+ s->listing_method = UNKNOWN_METHOD;
s->filesize = -1;
s->position = 0;
+ s->features = NULL;
av_url_split(proto, sizeof(proto),
credencials, sizeof(credencials),
@@ -602,22 +673,36 @@ static int ftp_open(URLContext *h, const char *url, int flags)
s->password = av_strdup(tok_pass);
s->hostname = av_strdup(hostname);
if (!s->hostname || !s->user || (tok_pass && !s->password)) {
- err = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
if (s->server_control_port < 0 || s->server_control_port > 65535)
s->server_control_port = 21;
if ((err = ftp_connect_control_connection(h)) < 0)
- goto fail;
+ return err;
if ((err = ftp_current_dir(s)) < 0)
+ return err;
+
+ newpath = av_append_path_component(s->path, path);
+ if (!newpath)
+ return AVERROR(ENOMEM);
+ av_free(s->path);
+ s->path = newpath;
+
+ return 0;
+}
+
+static int ftp_open(URLContext *h, const char *url, int flags)
+{
+ FTPContext *s = h->priv_data;
+ int err;
+
+ ff_dlog(h, "ftp protocol open\n");
+
+ if ((err = ftp_connect(h, url)) < 0)
goto fail;
- pathlen = strlen(s->path) + strlen(path) + 1;
- if ((err = av_reallocp(&s->path, pathlen)) < 0)
- goto fail;
- av_strlcat(s->path + strlen(s->path), path, pathlen);
if (ftp_restart(s, 0) < 0) {
h->is_streamed = 1;
@@ -642,7 +727,7 @@ static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
int err;
int64_t new_pos, fake_pos;
- av_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);
+ ff_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);
switch(whence) {
case AVSEEK_SIZE:
@@ -684,7 +769,7 @@ static int ftp_read(URLContext *h, unsigned char *buf, int size)
FTPContext *s = h->priv_data;
int read, err, retry_done = 0;
- av_dlog(h, "ftp protocol read %d bytes\n", size);
+ ff_dlog(h, "ftp protocol read %d bytes\n", size);
retry:
if (s->state == DISCONNECTED) {
/* optimization */
@@ -742,7 +827,7 @@ static int ftp_write(URLContext *h, const unsigned char *buf, int size)
FTPContext *s = h->priv_data;
int written;
- av_dlog(h, "ftp protocol write %d bytes\n", size);
+ ff_dlog(h, "ftp protocol write %d bytes\n", size);
if (s->state == DISCONNECTED) {
if ((err = ftp_connect_data_connection(h)) < 0)
@@ -769,13 +854,14 @@ static int ftp_close(URLContext *h)
{
FTPContext *s = h->priv_data;
- av_dlog(h, "ftp protocol close\n");
+ ff_dlog(h, "ftp protocol close\n");
ftp_close_both_connections(s);
av_freep(&s->user);
av_freep(&s->password);
av_freep(&s->hostname);
av_freep(&s->path);
+ av_freep(&s->features);
return 0;
}
@@ -784,7 +870,7 @@ static int ftp_get_file_handle(URLContext *h)
{
FTPContext *s = h->priv_data;
- av_dlog(h, "ftp protocol get_file_handle\n");
+ ff_dlog(h, "ftp protocol get_file_handle\n");
if (s->conn_data)
return ffurl_get_file_handle(s->conn_data);
@@ -796,7 +882,7 @@ static int ftp_shutdown(URLContext *h, int flags)
{
FTPContext *s = h->priv_data;
- av_dlog(h, "ftp protocol shutdown\n");
+ ff_dlog(h, "ftp protocol shutdown\n");
if (s->conn_data)
return ffurl_shutdown(s->conn_data, flags);
@@ -804,6 +890,213 @@ static int ftp_shutdown(URLContext *h, int flags)
return AVERROR(EIO);
}
+static int ftp_open_dir(URLContext *h)
+{
+ FTPContext *s = h->priv_data;
+ int ret;
+
+ if ((ret = ftp_connect(h, h->filename)) < 0)
+ goto fail;
+ if ((ret = ftp_set_dir(s)) < 0)
+ goto fail;
+ if ((ret = ftp_connect_data_connection(h)) < 0)
+ goto fail;
+ if ((ret = ftp_list(s)) < 0)
+ goto fail;
+ s->dir_buffer = av_malloc(DIR_BUFFER_SIZE);
+ if (!s->dir_buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ s->dir_buffer[0] = 0;
+ if (s->conn_data && s->state == LISTING_DIR)
+ return 0;
+ fail:
+ ffurl_closep(&s->conn_control);
+ ffurl_closep(&s->conn_data);
+ return ret;
+}
+
+static int64_t ftp_parse_date(const char *date)
+{
+ struct tm tv;
+ memset(&tv, 0, sizeof(struct tm));
+ av_small_strptime(date, "%Y%m%d%H%M%S", &tv);
+ return INT64_C(1000000) * av_timegm(&tv);
+}
+
+static int ftp_parse_entry_nlst(char *line, AVIODirEntry *next)
+{
+ next->name = av_strdup(line);
+ return 0;
+}
+
+static int ftp_parse_entry_mlsd(char *mlsd, AVIODirEntry *next)
+{
+ char *fact, *value;
+ ff_dlog(NULL, "%s\n", mlsd);
+ while(fact = av_strtok(mlsd, ";", &mlsd)) {
+ if (fact[0] == ' ') {
+ next->name = av_strdup(&fact[1]);
+ continue;
+ }
+ fact = av_strtok(fact, "=", &value);
+ if (!av_strcasecmp(fact, "type")) {
+ if (!av_strcasecmp(value, "cdir") || !av_strcasecmp(value, "pdir"))
+ return 1;
+ if (!av_strcasecmp(value, "dir"))
+ next->type = AVIO_ENTRY_DIRECTORY;
+ else if (!av_strcasecmp(value, "file"))
+ next->type = AVIO_ENTRY_FILE;
+ else if (!av_strcasecmp(value, "OS.unix=slink:"))
+ next->type = AVIO_ENTRY_SYMBOLIC_LINK;
+ } else if (!av_strcasecmp(fact, "modify")) {
+ next->modification_timestamp = ftp_parse_date(value);
+ } else if (!av_strcasecmp(fact, "UNIX.mode")) {
+ next->filemode = strtoumax(value, NULL, 8);
+ } else if (!av_strcasecmp(fact, "UNIX.uid") || !av_strcasecmp(fact, "UNIX.owner"))
+ next->user_id = strtoumax(value, NULL, 10);
+ else if (!av_strcasecmp(fact, "UNIX.gid") || !av_strcasecmp(fact, "UNIX.group"))
+ next->group_id = strtoumax(value, NULL, 10);
+ else if (!av_strcasecmp(fact, "size") || !av_strcasecmp(fact, "sizd"))
+ next->size = strtoll(value, NULL, 10);
+ }
+ return 0;
+}
+
+/**
+ * @return 0 on success, negative on error, positive on entry to discard.
+ */
+static int ftp_parse_entry(URLContext *h, char *line, AVIODirEntry *next)
+{
+ FTPContext *s = h->priv_data;
+
+ switch (s->listing_method) {
+ case MLSD:
+ return ftp_parse_entry_mlsd(line, next);
+ case NLST:
+ return ftp_parse_entry_nlst(line, next);
+ case UNKNOWN_METHOD:
+ default:
+ return -1;
+ }
+}
+
+static int ftp_read_dir(URLContext *h, AVIODirEntry **next)
+{
+ FTPContext *s = h->priv_data;
+ char *start, *found;
+ int ret, retried;
+
+ do {
+ retried = 0;
+ start = s->dir_buffer + s->dir_buffer_offset;
+ while (!(found = strstr(start, "\n"))) {
+ if (retried)
+ return AVERROR(EIO);
+ s->dir_buffer_size -= s->dir_buffer_offset;
+ s->dir_buffer_offset = 0;
+ if (s->dir_buffer_size)
+ memmove(s->dir_buffer, start, s->dir_buffer_size);
+ ret = ffurl_read(s->conn_data, s->dir_buffer + s->dir_buffer_size, DIR_BUFFER_SIZE - (s->dir_buffer_size + 1));
+ if (ret < 0)
+ return ret;
+ if (!ret) {
+ *next = NULL;
+ return 0;
+ }
+ s->dir_buffer_size += ret;
+ s->dir_buffer[s->dir_buffer_size] = 0;
+ start = s->dir_buffer;
+ retried = 1;
+ }
+ s->dir_buffer_offset += (found + 1 - start);
+ found[0] = 0;
+ if (found > start && found[-1] == '\r')
+ found[-1] = 0;
+
+ *next = ff_alloc_dir_entry();
+ if (!*next)
+ return AVERROR(ENOMEM);
+ (*next)->utf8 = s->utf8;
+ ret = ftp_parse_entry(h, start, *next);
+ if (ret) {
+ avio_free_directory_entry(next);
+ if (ret < 0)
+ return ret;
+ }
+ } while (ret > 0);
+ return 0;
+}
+
+static int ftp_close_dir(URLContext *h)
+{
+ FTPContext *s = h->priv_data;
+ av_freep(&s->dir_buffer);
+ ffurl_closep(&s->conn_control);
+ ffurl_closep(&s->conn_data);
+ return 0;
+}
+
+static int ftp_delete(URLContext *h)
+{
+ FTPContext *s = h->priv_data;
+ char command[MAX_URL_SIZE];
+ static const int del_codes[] = {250, 421, 450, 500, 501, 502, 530, 550, 0};
+ static const int rmd_codes[] = {250, 421, 500, 501, 502, 530, 550, 0};
+ int ret;
+
+ if ((ret = ftp_connect(h, h->filename)) < 0)
+ goto cleanup;
+
+ snprintf(command, sizeof(command), "DELE %s\r\n", s->path);
+ if (ftp_send_command(s, command, del_codes, NULL) == 250) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ snprintf(command, sizeof(command), "RMD %s\r\n", s->path);
+ if (ftp_send_command(s, command, rmd_codes, NULL) == 250)
+ ret = 0;
+ else
+ ret = AVERROR(EIO);
+
+cleanup:
+ ftp_close(h);
+ return ret;
+}
+
+static int ftp_move(URLContext *h_src, URLContext *h_dst)
+{
+ FTPContext *s = h_src->priv_data;
+ char command[MAX_URL_SIZE], path[MAX_URL_SIZE];
+ static const int rnfr_codes[] = {350, 421, 450, 500, 501, 502, 503, 530, 0};
+ static const int rnto_codes[] = {250, 421, 500, 501, 502, 503, 530, 532, 553, 0};
+ int ret;
+
+ if ((ret = ftp_connect(h_src, h_src->filename)) < 0)
+ goto cleanup;
+
+ snprintf(command, sizeof(command), "RNFR %s\r\n", s->path);
+ if (ftp_send_command(s, command, rnfr_codes, NULL) != 350) {
+ ret = AVERROR(EIO);
+ goto cleanup;
+ }
+
+ av_url_split(0, 0, 0, 0, 0, 0, 0,
+ path, sizeof(path),
+ h_dst->filename);
+ snprintf(command, sizeof(command), "RNTO %s\r\n", path);
+ if (ftp_send_command(s, command, rnto_codes, NULL) == 250)
+ ret = 0;
+ else
+ ret = AVERROR(EIO);
+
+cleanup:
+ ftp_close(h_src);
+ return ret;
+}
+
URLProtocol ff_ftp_protocol = {
.name = "ftp",
.url_open = ftp_open,
@@ -815,5 +1108,10 @@ URLProtocol ff_ftp_protocol = {
.url_shutdown = ftp_shutdown,
.priv_data_size = sizeof(FTPContext),
.priv_data_class = &ftp_context_class,
+ .url_open_dir = ftp_open_dir,
+ .url_read_dir = ftp_read_dir,
+ .url_close_dir = ftp_close_dir,
+ .url_delete = ftp_delete,
+ .url_move = ftp_move,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/gifdec.c b/chromium/third_party/ffmpeg/libavformat/gifdec.c
index bb4c6ec6e64..1ac47fee504 100644
--- a/chromium/third_party/ffmpeg/libavformat/gifdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/gifdec.c
@@ -52,6 +52,9 @@ typedef struct GIFDemuxContext {
int total_iter;
int iter_count;
int ignore_loop;
+
+ int nb_frames;
+ int last_duration;
} GIFDemuxContext;
/**
@@ -279,6 +282,9 @@ parse_keyframe:
pkt->stream_index = 0;
pkt->duration = gdc->delay;
+ gdc->nb_frames ++;
+ gdc->last_duration = pkt->duration;
+
/* Graphic Control Extension's scope is single frame.
* Remove its influence. */
gdc->delay = gdc->default_delay;
@@ -299,6 +305,9 @@ resync:
}
if ((ret >= 0 && !frame_parsed) || ret == AVERROR_EOF) {
+ if (gdc->nb_frames == 1) {
+ s->streams[0]->r_frame_rate = (AVRational) {100, gdc->last_duration};
+ }
/* This might happen when there is no image block
* between extension blocks and GIF_TRAILER or EOF */
if (!gdc->ignore_loop && (block_label == GIF_TRAILER || avio_feof(pb))
diff --git a/chromium/third_party/ffmpeg/libavformat/hevc.c b/chromium/third_party/ffmpeg/libavformat/hevc.c
index 643b71596ad..7c294ef8a24 100644
--- a/chromium/third_party/ffmpeg/libavformat/hevc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hevc.c
@@ -565,7 +565,10 @@ static int hvcc_parse_sps(GetBitContext *gb,
}
if (get_bits1(gb)) { // long_term_ref_pics_present_flag
- for (i = 0; i < get_ue_golomb_long(gb); i++) { // num_long_term_ref_pics_sps
+ unsigned num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
+ if (num_long_term_ref_pics_sps > 31U)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < num_long_term_ref_pics_sps; i++) { // num_long_term_ref_pics_sps
int len = FFMIN(log2_max_pic_order_cnt_lsb_minus4 + 4, 16);
skip_bits (gb, len); // lt_ref_pic_poc_lsb_sps[i]
skip_bits1(gb); // used_by_curr_pic_lt_sps_flag[i]
@@ -616,11 +619,12 @@ static int hvcc_parse_pps(GetBitContext *gb,
get_se_golomb_long(gb); // pps_cr_qp_offset
/*
+ * pps_slice_chroma_qp_offsets_present_flag u(1)
* weighted_pred_flag u(1)
* weighted_bipred_flag u(1)
* transquant_bypass_enabled_flag u(1)
*/
- skip_bits(gb, 3);
+ skip_bits(gb, 4);
tiles_enabled_flag = get_bits1(gb);
entropy_coding_sync_enabled_flag = get_bits1(gb);
@@ -644,7 +648,7 @@ static uint8_t *nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len,
uint8_t *dst;
uint32_t i, len;
- dst = av_malloc(src_len);
+ dst = av_malloc(src_len + AV_INPUT_BUFFER_PADDING_SIZE);
if (!dst)
return NULL;
diff --git a/chromium/third_party/ffmpeg/libavformat/hls.c b/chromium/third_party/ffmpeg/libavformat/hls.c
index 3f1d97eb6f2..c16c7708f42 100644
--- a/chromium/third_party/ffmpeg/libavformat/hls.c
+++ b/chromium/third_party/ffmpeg/libavformat/hls.c
@@ -182,6 +182,7 @@ typedef struct HLSContext {
char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
+ AVDictionary *avio_opts;
} HLSContext;
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -481,7 +482,9 @@ static void handle_rendition_args(struct rendition_info *info, const char *key,
/* used by parse_playlist to allocate a new variant+playlist when the
* playlist is detected to be a Media Playlist (not Master Playlist)
* and we have no parent Master Playlist (parsing of which would have
- * allocated the variant and playlist already) */
+ * allocated the variant and playlist already)
+ * *pls == NULL => Master Playlist or parentless Media Playlist
+ * *pls != NULL => parented Media Playlist, playlist+variant allocated */
static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
{
if (*pls)
@@ -492,8 +495,55 @@ static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url
return 0;
}
-/* pls = NULL => Master Playlist or parentless Media Playlist
- * pls = !NULL => parented Media Playlist, playlist+variant allocated */
+static int open_in(HLSContext *c, AVIOContext **in, const char *url)
+{
+ AVDictionary *tmp = NULL;
+ int ret;
+
+ av_dict_copy(&tmp, c->avio_opts, 0);
+
+ ret = avio_open2(in, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
+
+ av_dict_free(&tmp);
+ return ret;
+}
+
+static int url_connect(struct playlist *pls, AVDictionary *opts, AVDictionary *opts2)
+{
+ AVDictionary *tmp = NULL;
+ int ret;
+
+ av_dict_copy(&tmp, opts, 0);
+ av_dict_copy(&tmp, opts2, 0);
+
+ if ((ret = av_opt_set_dict(pls->input, &tmp)) < 0)
+ goto fail;
+
+ if ((ret = ffurl_connect(pls->input, NULL)) < 0) {
+ ffurl_close(pls->input);
+ pls->input = NULL;
+ }
+
+fail:
+ av_dict_free(&tmp);
+ return ret;
+}
+
+static int open_url(HLSContext *c, URLContext **uc, const char *url, AVDictionary *opts)
+{
+ AVDictionary *tmp = NULL;
+ int ret;
+
+ av_dict_copy(&tmp, c->avio_opts, 0);
+ av_dict_copy(&tmp, opts, 0);
+
+ ret = ffurl_open(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
+
+ av_dict_free(&tmp);
+
+ return ret;
+}
+
static int parse_playlist(HLSContext *c, const char *url,
struct playlist *pls, AVIOContext *in)
{
@@ -513,6 +563,7 @@ static int parse_playlist(HLSContext *c, const char *url,
char tmp_str[MAX_URL_SIZE];
if (!in) {
+#if 1
AVDictionary *opts = NULL;
close_in = 1;
/* Some HLS servers don't like being sent the range header */
@@ -528,6 +579,12 @@ static int parse_playlist(HLSContext *c, const char *url,
av_dict_free(&opts);
if (ret < 0)
return ret;
+#else
+ ret = open_in(c, &in, url);
+ if (ret < 0)
+ return ret;
+ close_in = 1;
+#endif
}
if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
@@ -752,7 +809,7 @@ static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata,
if (apic) {
int size = pls->ctx->streams[1]->attached_pic.size;
- if (size != apic->buf->size - FF_INPUT_BUFFER_PADDING_SIZE)
+ if (size != apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE)
return 1;
if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
@@ -940,15 +997,13 @@ static int open_input(HLSContext *c, struct playlist *pls)
seg->url, seg->url_offset, pls->index);
if (seg->key_type == KEY_NONE) {
- ret = ffurl_open(&pls->input, seg->url, AVIO_FLAG_READ,
- &pls->parent->interrupt_callback, &opts);
-
+ ret = open_url(pls->parent->priv_data, &pls->input, seg->url, opts);
} else if (seg->key_type == KEY_AES_128) {
+// HLSContext *c = var->parent->priv_data;
char iv[33], key[33], url[MAX_URL_SIZE];
if (strcmp(seg->key, pls->key_url)) {
URLContext *uc;
- if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
- &pls->parent->interrupt_callback, &opts2) == 0) {
+ if (open_url(pls->parent->priv_data, &uc, seg->key, opts2) == 0) {
if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))
!= sizeof(pls->key)) {
av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
@@ -970,15 +1025,14 @@ static int open_input(HLSContext *c, struct playlist *pls)
snprintf(url, sizeof(url), "crypto+%s", seg->url);
else
snprintf(url, sizeof(url), "crypto:%s", seg->url);
+
if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,
&pls->parent->interrupt_callback)) < 0)
goto cleanup;
av_opt_set(pls->input->priv_data, "key", key, 0);
av_opt_set(pls->input->priv_data, "iv", iv, 0);
- if ((ret = ffurl_connect(pls->input, &opts)) < 0) {
- ffurl_close(pls->input);
- pls->input = NULL;
+ if ((ret = url_connect(pls, c->avio_opts, opts)) < 0) {
goto cleanup;
}
ret = 0;
@@ -1085,6 +1139,8 @@ reload:
ret = open_input(c, v);
if (ret < 0) {
+ if (ff_check_interrupt(c->interrupt_callback))
+ return AVERROR_EXIT;
av_log(v->parent, AV_LOG_WARNING, "Failed to open segment of playlist %d\n",
v->index);
v->cur_seq_no += 1;
@@ -1252,6 +1308,26 @@ static int select_cur_seq_no(HLSContext *c, struct playlist *pls)
return pls->start_seq_no;
}
+static int save_avio_options(AVFormatContext *s)
+{
+ HLSContext *c = s->priv_data;
+ const char *opts[] = { "headers", "user_agent", "user-agent", "cookies", NULL }, **opt = opts;
+ uint8_t *buf;
+ int ret = 0;
+
+ while (*opt) {
+ if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
+ ret = av_dict_set(&c->avio_opts, *opt, buf,
+ AV_DICT_DONT_STRDUP_VAL);
+ if (ret < 0)
+ return ret;
+ }
+ opt++;
+ }
+
+ return ret;
+}
+
static int hls_read_header(AVFormatContext *s)
{
URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
@@ -1279,6 +1355,12 @@ static int hls_read_header(AVFormatContext *s)
if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
goto fail;
+ if ((ret = save_avio_options(s)) < 0)
+ goto fail;
+
+ /* Some HLS servers don't like being sent the range header */
+ av_dict_set(&c->avio_opts, "seekable", "0", 0);
+
if (c->n_variants == 0) {
av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
ret = AVERROR_EOF;
@@ -1629,6 +1711,9 @@ static int hls_close(AVFormatContext *s)
free_playlist_list(c);
free_variant_list(c);
free_rendition_list(c);
+
+ av_dict_free(&c->avio_opts);
+
return 0;
}
@@ -1729,7 +1814,7 @@ static int hls_probe(AVProbeData *p)
#define FLAGS AV_OPT_FLAG_DECODING_PARAM
static const AVOption hls_options[] = {
{"live_start_index", "segment index to start live streams at (negative values are from the end)",
- OFFSET(live_start_index), FF_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
+ OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
{NULL}
};
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsenc.c b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
index cf29f4f737f..473ca3a7223 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
@@ -32,6 +32,7 @@
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "libavutil/log.h"
+#include "libavutil/time_internal.h"
#include "avformat.h"
#include "internal.h"
@@ -42,6 +43,7 @@
typedef struct HLSSegment {
char filename[1024];
+ char sub_filename[1024];
double duration; /* in seconds */
int64_t pos;
int64_t size;
@@ -67,8 +69,10 @@ typedef struct HLSContext {
int64_t sequence;
int64_t start_sequence;
AVOutputFormat *oformat;
+ AVOutputFormat *vtt_oformat;
AVFormatContext *avf;
+ AVFormatContext *vtt_avf;
float time; // Set by a private option.
int max_nb_segments; // Set by a private option.
@@ -76,9 +80,11 @@ typedef struct HLSContext {
uint32_t flags; // enum HLSFlags
char *segment_filename;
+ int use_localtime; ///< flag to expand filename with localtime
int allowcache;
int64_t recording_time;
int has_video;
+ int has_subtitle;
int64_t start_pts;
int64_t end_pts;
double duration; // last segment duration computed so far, in seconds
@@ -92,8 +98,12 @@ typedef struct HLSContext {
HLSSegment *old_segments;
char *basename;
+ char *vtt_basename;
+ char *vtt_m3u8_name;
char *baseurl;
char *format_options_str;
+ char *vtt_format_options_str;
+ char *subtitle_filename;
AVDictionary *format_options;
char *key_info_file;
@@ -101,14 +111,19 @@ typedef struct HLSContext {
char key_uri[LINE_BUFFER_SIZE + 1];
char key_string[KEYSIZE*2 + 1];
char iv_string[KEYSIZE*2 + 1];
+ AVDictionary *vtt_format_options;
+
+ char *method;
+
} HLSContext;
static int hls_delete_old_segments(HLSContext *hls) {
HLSSegment *segment, *previous_segment = NULL;
float playlist_duration = 0.0f;
- int ret = 0, path_size;
- char *dirname = NULL, *p, *path;
+ int ret = 0, path_size, sub_path_size;
+ char *dirname = NULL, *p, *sub_path;
+ char *path = NULL;
segment = hls->segments;
while (segment) {
@@ -150,19 +165,35 @@ static int hls_delete_old_segments(HLSContext *hls) {
ret = AVERROR(ENOMEM);
goto fail;
}
+ sub_path_size = strlen(dirname) + strlen(segment->sub_filename) + 1;
+ sub_path = av_malloc(sub_path_size);
+ if (!sub_path) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
av_strlcpy(path, dirname, path_size);
av_strlcat(path, segment->filename, path_size);
if (unlink(path) < 0) {
av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
path, strerror(errno));
}
- av_free(path);
+
+ av_strlcpy(sub_path, dirname, sub_path_size);
+ av_strlcat(sub_path, segment->sub_filename, sub_path_size);
+ if (unlink(sub_path) < 0) {
+ av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
+ sub_path, strerror(errno));
+ }
+ av_freep(&path);
+ av_free(sub_path);
previous_segment = segment;
segment = previous_segment->next;
av_free(previous_segment);
}
fail:
+ av_free(path);
av_free(dirname);
return ret;
@@ -226,6 +257,7 @@ static int hls_mux_init(AVFormatContext *s)
{
HLSContext *hls = s->priv_data;
AVFormatContext *oc;
+ AVFormatContext *vtt_oc = NULL;
int i, ret;
ret = avformat_alloc_output_context2(&hls->avf, hls->oformat, NULL, NULL);
@@ -238,9 +270,24 @@ static int hls_mux_init(AVFormatContext *s)
oc->max_delay = s->max_delay;
av_dict_copy(&oc->metadata, s->metadata, 0);
+ if(hls->vtt_oformat) {
+ ret = avformat_alloc_output_context2(&hls->vtt_avf, hls->vtt_oformat, NULL, NULL);
+ if (ret < 0)
+ return ret;
+ vtt_oc = hls->vtt_avf;
+ vtt_oc->oformat = hls->vtt_oformat;
+ av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
+ }
+
for (i = 0; i < s->nb_streams; i++) {
AVStream *st;
- if (!(st = avformat_new_stream(oc, NULL)))
+ AVFormatContext *loc;
+ if (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+ loc = vtt_oc;
+ else
+ loc = oc;
+
+ if (!(st = avformat_new_stream(loc, NULL)))
return AVERROR(ENOMEM);
avcodec_copy_context(st->codec, s->streams[i]->codec);
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
@@ -263,6 +310,9 @@ static int hls_append_segment(HLSContext *hls, double duration, int64_t pos,
av_strlcpy(en->filename, av_basename(hls->avf->filename), sizeof(en->filename));
+ if(hls->has_subtitle)
+ av_strlcpy(en->sub_filename, av_basename(hls->vtt_avf->filename), sizeof(en->sub_filename));
+
en->duration = duration;
en->pos = pos;
en->size = size;
@@ -310,6 +360,12 @@ static void hls_free_segments(HLSSegment *p)
}
}
+static void set_http_options(AVDictionary **options, HLSContext *c)
+{
+ if (c->method)
+ av_dict_set(options, "method", c->method, 0);
+}
+
static int hls_window(AVFormatContext *s, int last)
{
HLSContext *hls = s->priv_data;
@@ -317,6 +373,7 @@ static int hls_window(AVFormatContext *s, int last)
int target_duration = 0;
int ret = 0;
AVIOContext *out = NULL;
+ AVIOContext *sub_out = NULL;
char temp_filename[1024];
int64_t sequence = FFMAX(hls->start_sequence, hls->sequence - hls->nb_entries);
int version = hls->flags & HLS_SINGLE_FILE ? 4 : 3;
@@ -325,13 +382,15 @@ static int hls_window(AVFormatContext *s, int last)
static unsigned warned_non_file;
char *key_uri = NULL;
char *iv_string = NULL;
+ AVDictionary *options = NULL;
if (!use_rename && !warned_non_file++)
av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporarly partial files\n");
+ set_http_options(&options, hls);
snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename);
if ((ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
+ &s->interrupt_callback, &options)) < 0)
goto fail;
for (en = hls->segments; en; en = en->next) {
@@ -380,8 +439,40 @@ static int hls_window(AVFormatContext *s, int last)
if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
avio_printf(out, "#EXT-X-ENDLIST\n");
+ if( hls->vtt_m3u8_name ) {
+ if ((ret = avio_open2(&sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, &options)) < 0)
+ goto fail;
+ avio_printf(sub_out, "#EXTM3U\n");
+ avio_printf(sub_out, "#EXT-X-VERSION:%d\n", version);
+ if (hls->allowcache == 0 || hls->allowcache == 1) {
+ avio_printf(sub_out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? "NO" : "YES");
+ }
+ avio_printf(sub_out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
+ avio_printf(sub_out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
+
+ av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n",
+ sequence);
+
+ for (en = hls->segments; en; en = en->next) {
+ avio_printf(sub_out, "#EXTINF:%f,\n", en->duration);
+ if (hls->flags & HLS_SINGLE_FILE)
+ avio_printf(sub_out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n",
+ en->size, en->pos);
+ if (hls->baseurl)
+ avio_printf(sub_out, "%s", hls->baseurl);
+ avio_printf(sub_out, "%s\n", en->sub_filename);
+ }
+
+ if (last)
+ avio_printf(sub_out, "#EXT-X-ENDLIST\n");
+
+ }
+
fail:
+ av_dict_free(&options);
avio_closep(&out);
+ avio_closep(&sub_out);
if (ret >= 0 && use_rename)
ff_rename(temp_filename, s->filename, s);
return ret;
@@ -391,37 +482,60 @@ static int hls_start(AVFormatContext *s)
{
HLSContext *c = s->priv_data;
AVFormatContext *oc = c->avf;
+ AVFormatContext *vtt_oc = c->vtt_avf;
AVDictionary *options = NULL;
char *filename, iv_string[KEYSIZE*2 + 1];
int err = 0;
- if (c->flags & HLS_SINGLE_FILE)
+ if (c->flags & HLS_SINGLE_FILE) {
av_strlcpy(oc->filename, c->basename,
sizeof(oc->filename));
- else
- if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
+ if (c->vtt_basename)
+ av_strlcpy(vtt_oc->filename, c->vtt_basename,
+ sizeof(vtt_oc->filename));
+ } else {
+ if (c->use_localtime) {
+ time_t now0;
+ struct tm *tm, tmpbuf;
+ time(&now0);
+ tm = localtime_r(&now0, &tmpbuf);
+ if (!strftime(oc->filename, sizeof(oc->filename), c->basename, tm)) {
+ av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n");
+ return AVERROR(EINVAL);
+ }
+ } else if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
c->basename, c->wrap ? c->sequence % c->wrap : c->sequence) < 0) {
- av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename);
+ av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try use -use_localtime 1 with it\n", c->basename);
return AVERROR(EINVAL);
}
+ if( c->vtt_basename) {
+ if (av_get_frame_filename(vtt_oc->filename, sizeof(vtt_oc->filename),
+ c->vtt_basename, c->wrap ? c->sequence % c->wrap : c->sequence) < 0) {
+ av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->vtt_basename);
+ return AVERROR(EINVAL);
+ }
+ }
+ }
c->number++;
+ set_http_options(&options, c);
+
if (c->key_info_file) {
if ((err = hls_encryption_start(s)) < 0)
- return err;
+ goto fail;
if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0))
< 0)
- return err;
+ goto fail;
err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
if (!err)
snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, c->sequence);
if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0)
- return err;
+ goto fail;
filename = av_asprintf("crypto:%s", oc->filename);
if (!filename) {
- av_dict_free(&options);
- return AVERROR(ENOMEM);
+ err = AVERROR(ENOMEM);
+ goto fail;
}
err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
&s->interrupt_callback, &options);
@@ -431,13 +545,27 @@ static int hls_start(AVFormatContext *s)
return err;
} else
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
- return err;
+ &s->interrupt_callback, &options)) < 0)
+ goto fail;
+ if (c->vtt_basename) {
+ set_http_options(&options, c);
+ if ((err = avio_open2(&vtt_oc->pb, vtt_oc->filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, &options)) < 0)
+ goto fail;
+ }
+ av_dict_free(&options);
if (oc->oformat->priv_class && oc->priv_data)
av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
+ if (c->vtt_basename)
+ avformat_write_header(vtt_oc,NULL);
+
return 0;
+fail:
+ av_dict_free(&options);
+
+ return err;
}
static int hls_write_header(AVFormatContext *s)
@@ -446,8 +574,11 @@ static int hls_write_header(AVFormatContext *s)
int ret, i;
char *p;
const char *pattern = "%d.ts";
+ const char *pattern_localtime_fmt = "-%s.ts";
+ const char *vtt_pattern = "%d.vtt";
AVDictionary *options = NULL;
int basename_size;
+ int vtt_basename_size;
hls->sequence = hls->start_sequence;
hls->recording_time = hls->time * AV_TIME_BASE;
@@ -461,9 +592,12 @@ static int hls_write_header(AVFormatContext *s)
}
}
- for (i = 0; i < s->nb_streams; i++)
+ for (i = 0; i < s->nb_streams; i++) {
hls->has_video +=
s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO;
+ hls->has_subtitle +=
+ s->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE;
+ }
if (hls->has_video > 1)
av_log(s, AV_LOG_WARNING,
@@ -477,6 +611,14 @@ static int hls_write_header(AVFormatContext *s)
goto fail;
}
+ if(hls->has_subtitle) {
+ hls->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
+ if (!hls->oformat) {
+ ret = AVERROR_MUXER_NOT_FOUND;
+ goto fail;
+ }
+ }
+
if (hls->segment_filename) {
hls->basename = av_strdup(hls->segment_filename);
if (!hls->basename) {
@@ -487,7 +629,11 @@ static int hls_write_header(AVFormatContext *s)
if (hls->flags & HLS_SINGLE_FILE)
pattern = ".ts";
- basename_size = strlen(s->filename) + strlen(pattern) + 1;
+ if (hls->use_localtime) {
+ basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1;
+ } else {
+ basename_size = strlen(s->filename) + strlen(pattern) + 1;
+ }
hls->basename = av_malloc(basename_size);
if (!hls->basename) {
ret = AVERROR(ENOMEM);
@@ -499,7 +645,40 @@ static int hls_write_header(AVFormatContext *s)
p = strrchr(hls->basename, '.');
if (p)
*p = '\0';
- av_strlcat(hls->basename, pattern, basename_size);
+ if (hls->use_localtime) {
+ av_strlcat(hls->basename, pattern_localtime_fmt, basename_size);
+ } else {
+ av_strlcat(hls->basename, pattern, basename_size);
+ }
+ }
+
+ if(hls->has_subtitle) {
+
+ if (hls->flags & HLS_SINGLE_FILE)
+ vtt_pattern = ".vtt";
+ vtt_basename_size = strlen(s->filename) + strlen(vtt_pattern) + 1;
+ hls->vtt_basename = av_malloc(vtt_basename_size);
+ if (!hls->vtt_basename) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ hls->vtt_m3u8_name = av_malloc(vtt_basename_size);
+ if (!hls->vtt_m3u8_name ) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ av_strlcpy(hls->vtt_basename, s->filename, vtt_basename_size);
+ p = strrchr(hls->vtt_basename, '.');
+ if (p)
+ *p = '\0';
+
+ if( hls->subtitle_filename ) {
+ strcpy(hls->vtt_m3u8_name, hls->subtitle_filename);
+ } else {
+ strcpy(hls->vtt_m3u8_name, hls->vtt_basename);
+ av_strlcat(hls->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
+ }
+ av_strlcat(hls->vtt_basename, vtt_pattern, vtt_basename_size);
}
if ((ret = hls_mux_init(s)) < 0)
@@ -515,10 +694,19 @@ static int hls_write_header(AVFormatContext *s)
ret = AVERROR(EINVAL);
goto fail;
}
- av_assert0(s->nb_streams == hls->avf->nb_streams);
+ //av_assert0(s->nb_streams == hls->avf->nb_streams);
for (i = 0; i < s->nb_streams; i++) {
- AVStream *inner_st = hls->avf->streams[i];
+ AVStream *inner_st;
AVStream *outer_st = s->streams[i];
+ if (outer_st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
+ inner_st = hls->avf->streams[i];
+ else if (hls->vtt_avf)
+ inner_st = hls->vtt_avf->streams[0];
+ else {
+ /* We have a subtitle stream, when the user does not want one */
+ inner_st = NULL;
+ continue;
+ }
avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
}
fail:
@@ -526,8 +714,12 @@ fail:
av_dict_free(&options);
if (ret < 0) {
av_freep(&hls->basename);
+ av_freep(&hls->vtt_basename);
if (hls->avf)
avformat_free_context(hls->avf);
+ if (hls->vtt_avf)
+ avformat_free_context(hls->vtt_avf);
+
}
return ret;
}
@@ -535,12 +727,20 @@ fail:
static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
{
HLSContext *hls = s->priv_data;
- AVFormatContext *oc = hls->avf;
+ AVFormatContext *oc = NULL;
AVStream *st = s->streams[pkt->stream_index];
int64_t end_pts = hls->recording_time * hls->number;
int is_ref_pkt = 1;
int ret, can_split = 1;
+ int stream_index = 0;
+ if( st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
+ oc = hls->vtt_avf;
+ stream_index = 0;
+ } else {
+ oc = hls->avf;
+ stream_index = pkt->stream_index;
+ }
if (hls->start_pts == AV_NOPTS_VALUE) {
hls->start_pts = pkt->pts;
hls->end_pts = pkt->pts;
@@ -579,6 +779,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
hls->number++;
} else {
avio_closep(&oc->pb);
+ if (hls->vtt_avf)
+ avio_close(hls->vtt_avf->pb);
ret = hls_start(s);
}
@@ -586,13 +788,16 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
if (ret < 0)
return ret;
+ if( st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE )
+ oc = hls->vtt_avf;
+ else
oc = hls->avf;
if ((ret = hls_window(s, 0)) < 0)
return ret;
}
- ret = ff_write_chained(oc, pkt->stream_index, pkt, s, 0);
+ ret = ff_write_chained(oc, stream_index, pkt, s, 0);
return ret;
}
@@ -601,6 +806,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
{
HLSContext *hls = s->priv_data;
AVFormatContext *oc = hls->avf;
+ AVFormatContext *vtt_oc = hls->vtt_avf;
av_write_trailer(oc);
if (oc->pb) {
@@ -608,8 +814,22 @@ static int hls_write_trailer(struct AVFormatContext *s)
avio_closep(&oc->pb);
hls_append_segment(hls, hls->duration, hls->start_pos, hls->size);
}
+
+ if (vtt_oc) {
+ if (vtt_oc->pb)
+ av_write_trailer(vtt_oc);
+ hls->size = avio_tell(hls->vtt_avf->pb) - hls->start_pos;
+ avio_closep(&vtt_oc->pb);
+ }
av_freep(&hls->basename);
avformat_free_context(oc);
+
+ if (vtt_oc) {
+ av_freep(&hls->vtt_basename);
+ av_freep(&hls->vtt_m3u8_name);
+ avformat_free_context(vtt_oc);
+ }
+
hls->avf = NULL;
hls_window(s, 1);
@@ -625,17 +845,21 @@ static const AVOption options[] = {
{"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E},
{"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E},
{"hls_ts_options","set hls mpegts list of options for the container format used for hls", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
+ {"hls_vtt_options","set hls vtt list of options for the container format used for hls", OFFSET(vtt_format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{"hls_wrap", "set number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
{"hls_allow_cache", "explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments", OFFSET(allowcache), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, E},
{"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{"hls_segment_filename", "filename template for segment files", OFFSET(segment_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{"hls_key_info_file", "file with key URI and key file path", OFFSET(key_info_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
+ {"hls_subtitle_path", "set path of hls subtitles", OFFSET(subtitle_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{"hls_flags", "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, "flags"},
{"single_file", "generate a single media file indexed with byte ranges", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SINGLE_FILE }, 0, UINT_MAX, E, "flags"},
{"delete_segments", "delete segment files that are no longer part of the playlist", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DELETE_SEGMENTS }, 0, UINT_MAX, E, "flags"},
{"round_durations", "round durations in m3u8 to whole numbers", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_ROUND_DURATIONS }, 0, UINT_MAX, E, "flags"},
{"discont_start", "start the playlist with a discontinuity tag", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX, E, "flags"},
{"omit_endlist", "Do not append an endlist when ending stream", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX, E, "flags"},
+ { "use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, E },
+ {"method", "set the HTTP method", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{ NULL },
};
@@ -655,6 +879,7 @@ AVOutputFormat ff_hls_muxer = {
.priv_data_size = sizeof(HLSContext),
.audio_codec = AV_CODEC_ID_AAC,
.video_codec = AV_CODEC_ID_H264,
+ .subtitle_codec = AV_CODEC_ID_WEBVTT,
.flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
.write_header = hls_write_header,
.write_packet = hls_write_packet,
diff --git a/chromium/third_party/ffmpeg/libavformat/http.c b/chromium/third_party/ffmpeg/libavformat/http.c
index 676bfd5c5a8..075dda77b85 100644
--- a/chromium/third_party/ffmpeg/libavformat/http.c
+++ b/chromium/third_party/ffmpeg/libavformat/http.c
@@ -25,8 +25,10 @@
#include <zlib.h>
#endif /* CONFIG_ZLIB */
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
+#include "libavutil/time.h"
#include "avformat.h"
#include "http.h"
@@ -44,6 +46,14 @@
* path names). */
#define BUFFER_SIZE MAX_URL_SIZE
#define MAX_REDIRECTS 8
+#define HTTP_SINGLE 1
+#define HTTP_MUTLI 2
+typedef enum {
+ LOWER_PROTO,
+ READ_HEADERS,
+ WRITE_REPLY_HEADERS,
+ FINISH
+}HandshakeState;
typedef struct HTTPContext {
const AVClass *class;
@@ -96,7 +106,16 @@ typedef struct HTTPContext {
int send_expect_100;
char *method;
int reconnect;
+ int reconnect_at_eof;
+ int reconnect_streamed;
+ int reconnect_delay;
+ int reconnect_delay_max;
int listen;
+ char *resource;
+ int reply_code;
+ int is_multi_client;
+ HandshakeState handshake_step;
+ int is_connected_server;
} HTTPContext;
#define OFFSET(x) offsetof(HTTPContext, x)
@@ -128,7 +147,12 @@ static const AVOption options[] = {
{ "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D },
{ "method", "Override the HTTP method or set the expected HTTP method from a client", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D | E },
{ "reconnect", "auto reconnect after disconnect before EOF", OFFSET(reconnect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
- { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D | E },
+ { "reconnect_at_eof", "auto reconnect at EOF", OFFSET(reconnect_at_eof), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
+ { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
+ { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D },
+ { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E },
+ { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+ { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E},
{ NULL }
};
@@ -299,51 +323,143 @@ int ff_http_averror(int status_code, int default_averror)
return default_averror;
}
-static void handle_http_errors(URLContext *h, int error)
+static int http_write_reply(URLContext* h, int status_code)
{
- static const char bad_request[] = "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\n\r\n400 Bad Request\r\n";
- static const char internal_server_error[] = "HTTP/1.1 500 Internal server error\r\nContent-Type: text/plain\r\n\r\n500 Internal server error\r\n";
+ int ret, body = 0, reply_code, message_len;
+ const char *reply_text, *content_type;
HTTPContext *s = h->priv_data;
- if (h->is_connected) {
- switch(error) {
- case AVERROR_HTTP_BAD_REQUEST:
- ffurl_write(s->hd, bad_request, strlen(bad_request));
- break;
- default:
- av_log(h, AV_LOG_ERROR, "Unhandled HTTP error.\n");
- ffurl_write(s->hd, internal_server_error, strlen(internal_server_error));
+ char message[BUFFER_SIZE];
+ content_type = "text/plain";
+
+ if (status_code < 0)
+ body = 1;
+ switch (status_code) {
+ case AVERROR_HTTP_BAD_REQUEST:
+ case 400:
+ reply_code = 400;
+ reply_text = "Bad Request";
+ break;
+ case AVERROR_HTTP_FORBIDDEN:
+ case 403:
+ reply_code = 403;
+ reply_text = "Forbidden";
+ break;
+ case AVERROR_HTTP_NOT_FOUND:
+ case 404:
+ reply_code = 404;
+ reply_text = "Not Found";
+ break;
+ case 200:
+ reply_code = 200;
+ reply_text = "OK";
+ content_type = "application/octet-stream";
+ break;
+ case AVERROR_HTTP_SERVER_ERROR:
+ case 500:
+ reply_code = 500;
+ reply_text = "Internal server error";
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+ if (body) {
+ s->chunked_post = 0;
+ message_len = snprintf(message, sizeof(message),
+ "HTTP/1.1 %03d %s\r\n"
+ "Content-Type: %s\r\n"
+ "Content-Length: %zu\r\n"
+ "\r\n"
+ "%03d %s\r\n",
+ reply_code,
+ reply_text,
+ content_type,
+ strlen(reply_text) + 6, // 3 digit status code + space + \r\n
+ reply_code,
+ reply_text);
+ } else {
+ s->chunked_post = 1;
+ message_len = snprintf(message, sizeof(message),
+ "HTTP/1.1 %03d %s\r\n"
+ "Content-Type: %s\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n",
+ reply_code,
+ reply_text,
+ content_type);
+ }
+ av_log(h, AV_LOG_TRACE, "HTTP reply header: \n%s----\n", message);
+ if ((ret = ffurl_write(s->hd, message, message_len)) < 0)
+ return ret;
+ return 0;
+}
+
+static void handle_http_errors(URLContext *h, int error)
+{
+ av_assert0(error < 0);
+ http_write_reply(h, error);
+}
+
+static int http_handshake(URLContext *c)
+{
+ int ret, err, new_location;
+ HTTPContext *ch = c->priv_data;
+ URLContext *cl = ch->hd;
+ switch (ch->handshake_step) {
+ case LOWER_PROTO:
+ av_log(c, AV_LOG_TRACE, "Lower protocol\n");
+ if ((ret = ffurl_handshake(cl)) > 0)
+ return 2 + ret;
+ if (ret < 0)
+ return ret;
+ ch->handshake_step = READ_HEADERS;
+ ch->is_connected_server = 1;
+ return 2;
+ case READ_HEADERS:
+ av_log(c, AV_LOG_TRACE, "Read headers\n");
+ if ((err = http_read_header(c, &new_location)) < 0) {
+ handle_http_errors(c, err);
+ return err;
}
+ ch->handshake_step = WRITE_REPLY_HEADERS;
+ return 1;
+ case WRITE_REPLY_HEADERS:
+ av_log(c, AV_LOG_TRACE, "Reply code: %d\n", ch->reply_code);
+ if ((err = http_write_reply(c, ch->reply_code)) < 0)
+ return err;
+ ch->handshake_step = FINISH;
+ return 1;
+ case FINISH:
+ return 0;
}
+ // this should never be reached.
+ return AVERROR(EINVAL);
}
static int http_listen(URLContext *h, const char *uri, int flags,
AVDictionary **options) {
HTTPContext *s = h->priv_data;
int ret;
- static const char header[] = "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n";
char hostname[1024], proto[10];
char lower_url[100];
const char *lower_proto = "tcp";
- int port, new_location;
- s->chunked_post = 1;
+ int port;
av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
NULL, 0, uri);
if (!strcmp(proto, "https"))
lower_proto = "tls";
ff_url_join(lower_url, sizeof(lower_url), lower_proto, NULL, hostname, port,
NULL);
- av_dict_set(options, "listen", "1", 0);
+ if ((ret = av_dict_set_int(options, "listen", s->listen, 0)) < 0)
+ goto fail;
if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
&h->interrupt_callback, options)) < 0)
goto fail;
- if ((ret = http_read_header(h, &new_location)) < 0)
- goto fail;
- if ((ret = ffurl_write(s->hd, header, strlen(header))) < 0)
- goto fail;
- return 0;
-
+ s->handshake_step = LOWER_PROTO;
+ if (s->listen == HTTP_SINGLE) { /* single client */
+ s->reply_code = 200;
+ while ((ret = http_handshake(h)) > 0);
+ }
fail:
- handle_http_errors(h, ret);
av_dict_free(&s->chained_options);
return ret;
}
@@ -368,9 +484,16 @@ static int http_open(URLContext *h, const char *uri, int flags,
if (s->headers) {
int len = strlen(s->headers);
- if (len < 2 || strcmp("\r\n", s->headers + len - 2))
+ if (len < 2 || strcmp("\r\n", s->headers + len - 2)) {
av_log(h, AV_LOG_WARNING,
"No trailing CRLF found in HTTP header.\n");
+ ret = av_reallocp(&s->headers, len + 3);
+ if (ret < 0)
+ return ret;
+ s->headers[len] = '\r';
+ s->headers[len + 1] = '\n';
+ s->headers[len + 2] = '\0';
+ }
}
if (s->listen) {
@@ -382,6 +505,26 @@ static int http_open(URLContext *h, const char *uri, int flags,
return ret;
}
+static int http_accept(URLContext *s, URLContext **c)
+{
+ int ret;
+ HTTPContext *sc = s->priv_data;
+ HTTPContext *cc;
+ URLContext *sl = sc->hd;
+ URLContext *cl = NULL;
+
+ av_assert0(sc->listen);
+ if ((ret = ffurl_alloc(c, s->filename, s->flags, &sl->interrupt_callback)) < 0)
+ goto fail;
+ cc = (*c)->priv_data;
+ if ((ret = ffurl_accept(sl, &cl)) < 0)
+ goto fail;
+ cc->hd = cl;
+ cc->is_multi_client = 1;
+fail:
+ return ret;
+}
+
static int http_getc(HTTPContext *s)
{
int len;
@@ -576,10 +719,10 @@ static int process_line(URLContext *h, char *line, int line_count,
p = line;
if (line_count == 0) {
- if (s->listen) {
+ if (s->is_connected_server) {
// HTTP method
method = p;
- while (!av_isspace(*p))
+ while (*p && !av_isspace(*p))
p++;
*(p++) = '\0';
av_log(h, AV_LOG_TRACE, "Received method: %s\n", method);
@@ -597,6 +740,8 @@ static int process_line(URLContext *h, char *line, int line_count,
"(%s autodetected %s received)\n", auto_method, method);
return ff_http_averror(400, AVERROR(EIO));
}
+ if (!(s->method = av_strdup(method)))
+ return AVERROR(ENOMEM);
}
// HTTP resource
@@ -607,12 +752,14 @@ static int process_line(URLContext *h, char *line, int line_count,
p++;
*(p++) = '\0';
av_log(h, AV_LOG_TRACE, "Requested resource: %s\n", resource);
+ if (!(s->resource = av_strdup(resource)))
+ return AVERROR(ENOMEM);
// HTTP version
while (av_isspace(*p))
p++;
version = p;
- while (!av_isspace(*p))
+ while (*p && !av_isspace(*p))
p++;
*p = '\0';
if (av_strncasecmp(version, "HTTP/", 5)) {
@@ -1102,16 +1249,25 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
return http_buf_read_compressed(h, buf, size);
#endif /* CONFIG_ZLIB */
read_ret = http_buf_read(h, buf, size);
- if (read_ret < 0 && s->reconnect && !h->is_streamed && s->filesize > 0 && s->off < s->filesize) {
- av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64".\n", s->off);
- seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1);
- if (seek_ret != s->off) {
- av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", s->off);
+ if ( (read_ret < 0 && s->reconnect && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize)
+ || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) {
+ int64_t target = h->is_streamed ? 0 : s->off;
+
+ if (s->reconnect_delay > s->reconnect_delay_max)
+ return AVERROR(EIO);
+
+ av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64" error=%s.\n", s->off, av_err2str(read_ret));
+ av_usleep(1000U*1000*s->reconnect_delay);
+ s->reconnect_delay = 1 + 2*s->reconnect_delay;
+ seek_ret = http_seek_internal(h, target, SEEK_SET, 1);
+ if (seek_ret != target) {
+ av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", target);
return read_ret;
}
read_ret = http_buf_read(h, buf, size);
- }
+ } else
+ s->reconnect_delay = 0;
return read_ret;
}
@@ -1288,7 +1444,7 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo
((whence == SEEK_CUR && off == 0) ||
(whence == SEEK_SET && off == s->off)))
return s->off;
- else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed)
+ else if ((s->filesize == -1 && whence == SEEK_END))
return AVERROR(ENOSYS);
if (whence == SEEK_CUR)
@@ -1301,6 +1457,9 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo
return AVERROR(EINVAL);
s->off = off;
+ if (s->off && h->is_streamed)
+ return AVERROR(ENOSYS);
+
/* we save the old context in case the seek fails */
old_buf_size = s->buf_end - s->buf_ptr;
memcpy(old_buf, s->buf_ptr, old_buf_size);
@@ -1346,6 +1505,8 @@ HTTP_CLASS(http);
URLProtocol ff_http_protocol = {
.name = "http",
.url_open2 = http_open,
+ .url_accept = http_accept,
+ .url_handshake = http_handshake,
.url_read = http_read,
.url_write = http_write,
.url_seek = http_seek,
diff --git a/chromium/third_party/ffmpeg/libavformat/id3v2.c b/chromium/third_party/ffmpeg/libavformat/id3v2.c
index 2289bfc15a7..addf937afd2 100644
--- a/chromium/third_party/ffmpeg/libavformat/id3v2.c
+++ b/chromium/third_party/ffmpeg/libavformat/id3v2.c
@@ -535,6 +535,13 @@ static void free_apic(void *obj)
av_freep(&apic);
}
+static void rstrip_spaces(char *buf)
+{
+ size_t len = strlen(buf);
+ while (len > 0 && buf[len - 1] == ' ')
+ buf[--len] = 0;
+}
+
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
const char *tag, ID3v2ExtraMeta **extra_meta,
int isv34)
@@ -598,16 +605,20 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
goto fail;
}
- apic->buf = av_buffer_alloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE);
+ apic->buf = av_buffer_alloc(taglen + AV_INPUT_BUFFER_PADDING_SIZE);
if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen)
goto fail;
- memset(apic->buf->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(apic->buf->data + taglen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
new_extra->tag = "APIC";
new_extra->data = apic;
new_extra->next = *extra_meta;
*extra_meta = new_extra;
+ // The description must be unique, and some ID3v2 tag writers add spaces
+ // to write several APIC entries with the same description.
+ rstrip_spaces(apic->description);
+
return;
fail:
@@ -1083,6 +1094,9 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = apic->id;
+ if (AV_RB64(apic->buf->data) == 0x89504e470d0a1a0a)
+ st->codec->codec_id = AV_CODEC_ID_PNG;
+
if (apic->description[0])
av_dict_set(&st->metadata, "title", apic->description, 0);
@@ -1091,7 +1105,7 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
av_init_packet(&st->attached_pic);
st->attached_pic.buf = apic->buf;
st->attached_pic.data = apic->buf->data;
- st->attached_pic.size = apic->buf->size - FF_INPUT_BUFFER_PADDING_SIZE;
+ st->attached_pic.size = apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE;
st->attached_pic.stream_index = st->index;
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
diff --git a/chromium/third_party/ffmpeg/libavformat/iff.c b/chromium/third_party/ffmpeg/libavformat/iff.c
index 7235bc1c9c1..8ea3b38ac62 100644
--- a/chromium/third_party/ffmpeg/libavformat/iff.c
+++ b/chromium/third_party/ffmpeg/libavformat/iff.c
@@ -455,7 +455,7 @@ static int iff_read_header(AVFormatContext *s)
return AVERROR_INVALIDDATA;
}
st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;
- st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)
@@ -682,7 +682,7 @@ static int iff_read_header(AVFormatContext *s)
if (!st->codec->extradata) {
st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;
- st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/img2.c b/chromium/third_party/ffmpeg/libavformat/img2.c
index cf8a47856f7..50352b53b20 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2.c
@@ -22,13 +22,9 @@
#include "libavutil/avstring.h"
#include "internal.h"
+#include "img2.h"
-typedef struct IdStrMap {
- enum AVCodecID id;
- const char *str;
-} IdStrMap;
-
-static const IdStrMap img_tags[] = {
+const IdStrMap ff_img_tags[] = {
{ AV_CODEC_ID_MJPEG, "jpeg" },
{ AV_CODEC_ID_MJPEG, "jpg" },
{ AV_CODEC_ID_MJPEG, "jps" },
@@ -45,6 +41,7 @@ static const IdStrMap img_tags[] = {
{ AV_CODEC_ID_PBM, "pbm" },
{ AV_CODEC_ID_PAM, "pam" },
{ AV_CODEC_ID_ALIAS_PIX, "pix" },
+ { AV_CODEC_ID_DDS, "dds" },
{ AV_CODEC_ID_MPEG1VIDEO, "mpg1-img" },
{ AV_CODEC_ID_MPEG2VIDEO, "mpg2-img" },
{ AV_CODEC_ID_MPEG4, "mpg4-img" },
@@ -102,5 +99,5 @@ static enum AVCodecID av_str2id(const IdStrMap *tags, const char *str)
enum AVCodecID ff_guess_image2_codec(const char *filename)
{
- return av_str2id(img_tags, filename);
+ return av_str2id(ff_img_tags, filename);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/img2.h b/chromium/third_party/ffmpeg/libavformat/img2.h
index f6b9dd92205..deebcc34a76 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2.h
+++ b/chromium/third_party/ffmpeg/libavformat/img2.h
@@ -62,6 +62,13 @@ typedef struct VideoDemuxData {
int ts_from_file;
} VideoDemuxData;
+typedef struct IdStrMap {
+ enum AVCodecID id;
+ const char *str;
+} IdStrMap;
+
+extern const IdStrMap ff_img_tags[];
+
extern const AVOption ff_img_options[];
int ff_img_read_header(AVFormatContext *s1);
diff --git a/chromium/third_party/ffmpeg/libavformat/img2dec.c b/chromium/third_party/ffmpeg/libavformat/img2dec.c
index 0830f0073c7..70f0b09f180 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2dec.c
@@ -609,6 +609,17 @@ static int bmp_probe(AVProbeData *p)
return AVPROBE_SCORE_EXTENSION / 4;
}
+static int dds_probe(AVProbeData *p)
+{
+ const uint8_t *b = p->buf;
+
+ if ( AV_RB64(b) == 0x444453207c000000
+ && AV_RL32(b + 8)
+ && AV_RL32(b + 12))
+ return AVPROBE_SCORE_MAX - 1;
+ return 0;
+}
+
static int dpx_probe(AVProbeData *p)
{
const uint8_t *b = p->buf;
@@ -649,18 +660,14 @@ static int j2k_probe(AVProbeData *p)
static int jpeg_probe(AVProbeData *p)
{
const uint8_t *b = p->buf;
- int i, state = 0xD8, exif_size = 0;
+ int i, state = 0xD8;
if (AV_RB16(b) != 0xFFD8 ||
AV_RB32(b) == 0xFFD8FFF7)
return 0;
b += 2;
- if (AV_RB16(b) == 0xFFE1 && AV_RB32(b + 4) == AV_RB32("Exif")) {
- exif_size = AV_RB16(b + 2) + 2;
- b += exif_size;
- }
- for (i = 0; i + exif_size < p->buf_size - 2; i++) {
+ for (i = 0; i < p->buf_size - 3; i++) {
int c;
if (b[i] != 0xFF)
continue;
@@ -689,6 +696,24 @@ static int jpeg_probe(AVProbeData *p)
return 0;
state = 0xD9;
break;
+ case 0xE0:
+ case 0xE1:
+ case 0xE2:
+ case 0xE3:
+ case 0xE4:
+ case 0xE5:
+ case 0xE6:
+ case 0xE7:
+ case 0xE8:
+ case 0xE9:
+ case 0xEA:
+ case 0xEB:
+ case 0xEC:
+ case 0xED:
+ case 0xEE:
+ case 0xEF:
+ i += AV_RB16(&b[i + 2]) + 1;
+ break;
default:
if ( (c >= 0x02 && c <= 0xBF)
|| c == 0xC8)
@@ -714,9 +739,15 @@ static int qdraw_probe(AVProbeData *p)
{
const uint8_t *b = p->buf;
- if (!b[10] && AV_RB32(b+11) == 0x1102ff0c && !b[15] ||
- p->buf_size >= 528 && !b[522] && AV_RB32(b+523) == 0x1102ff0c && !b[527])
- return AVPROBE_SCORE_EXTENSION + 1;
+ if ( p->buf_size >= 528
+ && (AV_RB64(b + 520) & 0xFFFFFFFFFFFF) == 0x001102ff0c00
+ && AV_RB16(b + 520)
+ && AV_RB16(b + 518))
+ return AVPROBE_SCORE_MAX * 3 / 4;
+ if ( (AV_RB64(b + 8) & 0xFFFFFFFFFFFF) == 0x001102ff0c00
+ && AV_RB16(b + 8)
+ && AV_RB16(b + 6))
+ return AVPROBE_SCORE_EXTENSION / 4;
return 0;
}
@@ -799,6 +830,7 @@ AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
};
IMAGEAUTO_DEMUXER(bmp, AV_CODEC_ID_BMP)
+IMAGEAUTO_DEMUXER(dds, AV_CODEC_ID_DDS)
IMAGEAUTO_DEMUXER(dpx, AV_CODEC_ID_DPX)
IMAGEAUTO_DEMUXER(exr, AV_CODEC_ID_EXR)
IMAGEAUTO_DEMUXER(j2k, AV_CODEC_ID_JPEG2000)
diff --git a/chromium/third_party/ffmpeg/libavformat/img2enc.c b/chromium/third_party/ffmpeg/libavformat/img2enc.c
index f56c39e6d36..48454fe1d20 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2enc.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2enc.c
@@ -30,6 +30,7 @@
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+#include "img2.h"
typedef struct VideoMuxData {
const AVClass *class; /**< Class for private options. */
@@ -116,7 +117,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
if (img->split_planes) {
int ysize = codec->width * codec->height;
int usize = FF_CEIL_RSHIFT(codec->width, desc->log2_chroma_w) * FF_CEIL_RSHIFT(codec->height, desc->log2_chroma_h);
- if (desc->comp[0].depth_minus1 >= 8) {
+ if (desc->comp[0].depth >= 9) {
ysize *= 2;
usize *= 2;
}
@@ -172,6 +173,17 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
+static int query_codec(enum AVCodecID id, int std_compliance)
+{
+ int i;
+ for (i = 0; ff_img_tags[i].id != AV_CODEC_ID_NONE; i++)
+ if (ff_img_tags[i].id == id)
+ return 1;
+
+ // Anything really can be stored in img2
+ return std_compliance < FF_COMPLIANCE_NORMAL;
+}
+
#define OFFSET(x) offsetof(VideoMuxData, x)
#define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption muxoptions[] = {
@@ -200,6 +212,7 @@ AVOutputFormat ff_image2_muxer = {
.video_codec = AV_CODEC_ID_MJPEG,
.write_header = write_header,
.write_packet = write_packet,
+ .query_codec = query_codec,
.flags = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE,
.priv_class = &img2mux_class,
};
@@ -212,6 +225,7 @@ AVOutputFormat ff_image2pipe_muxer = {
.video_codec = AV_CODEC_ID_MJPEG,
.write_header = write_header,
.write_packet = write_packet,
+ .query_codec = query_codec,
.flags = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS
};
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/internal.h b/chromium/third_party/ffmpeg/libavformat/internal.h
index f90df902421..bd8a0bcf8a9 100644
--- a/chromium/third_party/ffmpeg/libavformat/internal.h
+++ b/chromium/third_party/ffmpeg/libavformat/internal.h
@@ -31,6 +31,8 @@
#define PROBE_BUF_MIN 2048
#define PROBE_BUF_MAX (1 << 20)
+#define MAX_PROBE_PACKETS 2500
+
#ifdef DEBUG
# define hex_dump_debug(class, buf, size) av_hex_dump_log(class, AV_LOG_DEBUG, buf, size)
#else
@@ -47,6 +49,18 @@ typedef struct CodecMime{
enum AVCodecID id;
} CodecMime;
+/*************************************************/
+/* fractional numbers for exact pts handling */
+
+/**
+ * The exact value of the fractional number is: 'val + num / den'.
+ * num is assumed to be 0 <= num < den.
+ */
+typedef struct FFFrac {
+ int64_t val, num, den;
+} FFFrac;
+
+
struct AVFormatInternal {
/**
* Number of streams relevant for interleaving.
@@ -254,6 +268,8 @@ int ff_add_index_entry(AVIndexEntry **index_entries,
unsigned int *index_entries_allocated_size,
int64_t pos, int64_t timestamp, int size, int distance, int flags);
+void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance);
+
/**
* Add a new chapter.
*
@@ -447,7 +463,7 @@ uint8_t *ff_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type,
int size);
/**
- * Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end
+ * Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end
* which is always set to 0.
*
* @param size size of extradata
@@ -456,7 +472,7 @@ uint8_t *ff_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type,
int ff_alloc_extradata(AVCodecContext *avctx, int size);
/**
- * Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end
+ * Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end
* which is always set to 0 and fill it from pb.
*
* @param size size of extradata
diff --git a/chromium/third_party/ffmpeg/libavformat/ipmovie.c b/chromium/third_party/ffmpeg/libavformat/ipmovie.c
index af518b59d3d..51aed323a24 100644
--- a/chromium/third_party/ffmpeg/libavformat/ipmovie.c
+++ b/chromium/third_party/ffmpeg/libavformat/ipmovie.c
@@ -78,7 +78,7 @@
#define PALETTE_COUNT 256
typedef struct IPMVEContext {
-
+ AVFormatContext *avf;
unsigned char *buf;
int buf_size;
@@ -212,6 +212,31 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
return chunk_type;
}
+static int init_audio(AVFormatContext *s)
+{
+ IPMVEContext *ipmovie = s->priv_data;
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
+ ipmovie->audio_stream_index = st->index;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = ipmovie->audio_type;
+ st->codec->codec_tag = 0; /* no tag */
+ st->codec->channels = ipmovie->audio_channels;
+ st->codec->channel_layout = st->codec->channels == 1 ? AV_CH_LAYOUT_MONO :
+ AV_CH_LAYOUT_STEREO;
+ st->codec->sample_rate = ipmovie->audio_sample_rate;
+ st->codec->bits_per_coded_sample = ipmovie->audio_bits;
+ st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
+ st->codec->bits_per_coded_sample;
+ if (st->codec->codec_id == AV_CODEC_ID_INTERPLAY_DPCM)
+ st->codec->bit_rate /= 2;
+ st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
+
+ return 0;
+}
+
/* This function loads and processes a single chunk in an IP movie file.
* It returns the type of chunk that was processed. */
static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
@@ -516,6 +541,9 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
}
}
+ if (s->avf->nb_streams == 1 && s->audio_type)
+ init_audio(s->avf);
+
/* make a note of where the stream is sitting */
s->next_chunk_offset = avio_tell(pb);
@@ -551,6 +579,8 @@ static int ipmovie_read_header(AVFormatContext *s)
int chunk_type, i;
uint8_t signature_buffer[sizeof(signature)];
+ ipmovie->avf = s;
+
avio_read(pb, signature_buffer, sizeof(signature_buffer));
while (memcmp(signature_buffer, signature, sizeof(signature))) {
memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
@@ -600,25 +630,9 @@ static int ipmovie_read_header(AVFormatContext *s)
st->codec->bits_per_coded_sample = ipmovie->video_bpp;
if (ipmovie->audio_type) {
- st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
- avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
- ipmovie->audio_stream_index = st->index;
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = ipmovie->audio_type;
- st->codec->codec_tag = 0; /* no tag */
- st->codec->channels = ipmovie->audio_channels;
- st->codec->channel_layout = st->codec->channels == 1 ? AV_CH_LAYOUT_MONO :
- AV_CH_LAYOUT_STEREO;
- st->codec->sample_rate = ipmovie->audio_sample_rate;
- st->codec->bits_per_coded_sample = ipmovie->audio_bits;
- st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
- st->codec->bits_per_coded_sample;
- if (st->codec->codec_id == AV_CODEC_ID_INTERPLAY_DPCM)
- st->codec->bit_rate /= 2;
- st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
- }
+ return init_audio(s);
+ } else
+ s->ctx_flags |= AVFMTCTX_NOHEADER;
return 0;
}
@@ -643,7 +657,7 @@ static int ipmovie_read_packet(AVFormatContext *s,
else if (ret == CHUNK_INIT_VIDEO || ret == CHUNK_INIT_AUDIO)
continue;
else
- ret = -1;
+ continue;
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/isom.c b/chromium/third_party/ffmpeg/libavformat/isom.c
index c99f2dc5db1..eff04ff8a22 100644
--- a/chromium/third_party/ffmpeg/libavformat/isom.c
+++ b/chromium/third_party/ffmpeg/libavformat/isom.c
@@ -110,7 +110,7 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
{ AV_CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
- { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
+ { AV_CODEC_ID_AVRN , MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
/* { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */
{ AV_CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, /* Motion JPEG OpenDML */
{ AV_CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
@@ -258,6 +258,13 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_AIC, MKTAG('i', 'c', 'o', 'd') },
+ { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '1') },
+ { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '5') },
+ { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'Y') },
+
+ { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', '3') },
+ { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', 'I') },
+
{ AV_CODEC_ID_NONE, 0 },
};
@@ -447,19 +454,24 @@ static const AVCodecTag mp4_audio_types[] = {
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb)
{
enum AVCodecID codec_id;
+ unsigned v;
int len, tag;
int ret;
int object_type_id = avio_r8(pb);
avio_r8(pb); /* stream type */
avio_rb24(pb); /* buffer size db */
- avio_rb32(pb); /* max bitrate */
- avio_rb32(pb); /* avg bitrate */
if(avcodec_is_open(st->codec)) {
av_log(fc, AV_LOG_DEBUG, "codec open in read_dec_config_descr\n");
return -1;
}
+ v = avio_rb32(pb);
+ if (v < INT32_MAX)
+ st->codec->rc_max_rate = v;
+
+ st->codec->bit_rate = avio_rb32(pb); /* avg bitrate */
+
codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
if (codec_id)
st->codec->codec_id= codec_id;
diff --git a/chromium/third_party/ffmpeg/libavformat/isom.h b/chromium/third_party/ffmpeg/libavformat/isom.h
index 5d48989fd90..aee9d6e8c79 100644
--- a/chromium/third_party/ffmpeg/libavformat/isom.h
+++ b/chromium/third_party/ffmpeg/libavformat/isom.h
@@ -198,6 +198,14 @@ typedef struct MOVContext {
MOVFragmentIndex** fragment_index_data;
unsigned fragment_index_count;
int atom_depth;
+ unsigned int aax_mode; ///< 'aax' file has been detected
+ uint8_t file_key[20];
+ uint8_t file_iv[20];
+ void *activation_bytes;
+ int activation_bytes_size;
+ void *audible_fixed_key;
+ int audible_fixed_key_size;
+ struct AVAES *aes_decrypt;
} MOVContext;
int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/chromium/third_party/ffmpeg/libavformat/ivfenc.c b/chromium/third_party/ffmpeg/libavformat/ivfenc.c
index 1d76c5c7cb7..2053c509f9f 100644
--- a/chromium/third_party/ffmpeg/libavformat/ivfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/ivfenc.c
@@ -20,6 +20,11 @@
#include "avformat.h"
#include "libavutil/intreadwrite.h"
+typedef struct IVFEncContext {
+ unsigned frame_cnt;
+ uint64_t last_pts, sum_delta_pts;
+} IVFEncContext;
+
static int ivf_write_header(AVFormatContext *s)
{
AVCodecContext *ctx;
@@ -43,7 +48,7 @@ static int ivf_write_header(AVFormatContext *s)
avio_wl16(pb, ctx->height);
avio_wl32(pb, s->streams[0]->time_base.den);
avio_wl32(pb, s->streams[0]->time_base.num);
- avio_wl64(pb, s->streams[0]->duration); // TODO: duration or number of frames?!?
+ avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL);
return 0;
}
@@ -51,14 +56,36 @@ static int ivf_write_header(AVFormatContext *s)
static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt)
{
AVIOContext *pb = s->pb;
+ IVFEncContext *ctx = s->priv_data;
+
avio_wl32(pb, pkt->size);
avio_wl64(pb, pkt->pts);
avio_write(pb, pkt->data, pkt->size);
+ if (ctx->frame_cnt)
+ ctx->sum_delta_pts += pkt->pts - ctx->last_pts;
+ ctx->frame_cnt++;
+ ctx->last_pts = pkt->pts;
+
+ return 0;
+}
+
+static int ivf_write_trailer(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ if (pb->seekable) {
+ IVFEncContext *ctx = s->priv_data;
+ size_t end = avio_tell(pb);
+
+ avio_seek(pb, 24, SEEK_SET);
+ avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1));
+ avio_seek(pb, end, SEEK_SET);
+ }
return 0;
}
AVOutputFormat ff_ivf_muxer = {
+ .priv_data_size = sizeof(IVFEncContext),
.name = "ivf",
.long_name = NULL_IF_CONFIG_SMALL("On2 IVF"),
.extensions = "ivf",
@@ -66,4 +93,5 @@ AVOutputFormat ff_ivf_muxer = {
.video_codec = AV_CODEC_ID_VP8,
.write_header = ivf_write_header,
.write_packet = ivf_write_packet,
+ .write_trailer = ivf_write_trailer,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/jacosubdec.c b/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
index 1ca00558774..5e543634fd3 100644
--- a/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
@@ -172,7 +172,7 @@ static int jacosub_read_header(AVFormatContext *s)
jacosub->timeres = 30;
- av_bprint_init(&header, 1024+FF_INPUT_BUFFER_PADDING_SIZE, 4096);
+ av_bprint_init(&header, 1024+AV_INPUT_BUFFER_PADDING_SIZE, 4096);
while (!avio_feof(pb)) {
int cmd_len;
@@ -240,7 +240,7 @@ static int jacosub_read_header(AVFormatContext *s)
AVPacket *sub = &jacosub->q.subs[i];
read_ts(jacosub, sub->data, &sub->pts, &sub->duration);
}
- ff_subtitles_queue_finalize(&jacosub->q);
+ ff_subtitles_queue_finalize(s, &jacosub->q);
return 0;
fail:
diff --git a/chromium/third_party/ffmpeg/libavformat/jvdec.c b/chromium/third_party/ffmpeg/libavformat/jvdec.c
index 64d31e0ee69..4d4f0c78c53 100644
--- a/chromium/third_party/ffmpeg/libavformat/jvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/jvdec.c
@@ -196,7 +196,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
if (ret < size) {
memset(pkt->data + JV_PREAMBLE_SIZE + ret, 0,
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
pkt->flags |= AV_PKT_FLAG_CORRUPT;
}
pkt->size = ret + JV_PREAMBLE_SIZE;
diff --git a/chromium/third_party/ffmpeg/libavformat/latmenc.c b/chromium/third_party/ffmpeg/libavformat/latmenc.c
index 17dbf33b721..db6977e5853 100644
--- a/chromium/third_party/ffmpeg/libavformat/latmenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/latmenc.c
@@ -124,7 +124,8 @@ static void latm_write_frame_header(AVFormatContext *s, PutBitContext *bs)
if (!ctx->channel_conf) {
GetBitContext gb;
- init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
+ int ret = init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
+ av_assert0(ret >= 0); // extradata size has been checked already, so this should not fail
skip_bits_long(&gb, ctx->off + 3);
avpriv_copy_pce_data(bs, &gb);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/libsmbclient.c b/chromium/third_party/ffmpeg/libavformat/libsmbclient.c
index 1af8163674c..84fef7f1620 100644
--- a/chromium/third_party/ffmpeg/libavformat/libsmbclient.c
+++ b/chromium/third_party/ffmpeg/libavformat/libsmbclient.c
@@ -287,6 +287,67 @@ static int libsmbc_close_dir(URLContext *h)
return 0;
}
+static int libsmbc_delete(URLContext *h)
+{
+ LIBSMBContext *libsmbc = h->priv_data;
+ int ret;
+ struct stat st;
+
+ if ((ret = libsmbc_connect(h)) < 0)
+ goto cleanup;
+
+ if ((libsmbc->fd = smbc_open(h->filename, O_WRONLY, 0666)) < 0) {
+ ret = AVERROR(errno);
+ goto cleanup;
+ }
+
+ if (smbc_fstat(libsmbc->fd, &st) < 0) {
+ ret = AVERROR(errno);
+ goto cleanup;
+ }
+
+ smbc_close(libsmbc->fd);
+ libsmbc->fd = -1;
+
+ if (S_ISDIR(st.st_mode)) {
+ if (smbc_rmdir(h->filename) < 0) {
+ ret = AVERROR(errno);
+ goto cleanup;
+ }
+ } else {
+ if (smbc_unlink(h->filename) < 0) {
+ ret = AVERROR(errno);
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ libsmbc_close(h);
+ return ret;
+}
+
+static int libsmbc_move(URLContext *h_src, URLContext *h_dst)
+{
+ LIBSMBContext *libsmbc = h_src->priv_data;
+ int ret;
+
+ if ((ret = libsmbc_connect(h_src)) < 0)
+ goto cleanup;
+
+ if ((libsmbc->dh = smbc_rename(h_src->filename, h_dst->filename)) < 0) {
+ ret = AVERROR(errno);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ libsmbc_close(h_src);
+ return ret;
+}
+
#define OFFSET(x) offsetof(LIBSMBContext, x)
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
@@ -311,6 +372,8 @@ URLProtocol ff_libsmbclient_protocol = {
.url_write = libsmbc_write,
.url_seek = libsmbc_seek,
.url_close = libsmbc_close,
+ .url_delete = libsmbc_delete,
+ .url_move = libsmbc_move,
.url_open_dir = libsmbc_open_dir,
.url_read_dir = libsmbc_read_dir,
.url_close_dir = libsmbc_close_dir,
diff --git a/chromium/third_party/ffmpeg/libavformat/libssh.c b/chromium/third_party/ffmpeg/libavformat/libssh.c
index fac6114210c..3c056f874ad 100644
--- a/chromium/third_party/ffmpeg/libavformat/libssh.c
+++ b/chromium/third_party/ffmpeg/libavformat/libssh.c
@@ -24,6 +24,7 @@
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "libavutil/attributes.h"
+#include "libavformat/avio.h"
#include "avformat.h"
#include "internal.h"
#include "url.h"
@@ -33,6 +34,7 @@ typedef struct {
ssh_session session;
sftp_session sftp;
sftp_file file;
+ sftp_dir dir;
int64_t filesize;
int rw_timeout;
int trunc;
@@ -187,11 +189,11 @@ static av_cold int libssh_close(URLContext *h)
return 0;
}
-static av_cold int libssh_open(URLContext *h, const char *url, int flags)
+static av_cold int libssh_connect(URLContext *h, const char *url, char *path, size_t path_size)
{
LIBSSHContext *libssh = h->priv_data;
- char proto[10], path[MAX_URL_SIZE], hostname[1024], credencials[1024];
- int port, ret;
+ char proto[10], hostname[1024], credencials[1024];
+ int port = 22, ret;
const char *user = NULL, *pass = NULL;
char *end = NULL;
@@ -199,23 +201,38 @@ static av_cold int libssh_open(URLContext *h, const char *url, int flags)
credencials, sizeof(credencials),
hostname, sizeof(hostname),
&port,
- path, sizeof(path),
+ path, path_size,
url);
+ if (!(*path))
+ av_strlcpy(path, "/", path_size);
+
// a port of 0 will use a port from ~/.ssh/config or the default value 22
if (port < 0 || port > 65535)
port = 0;
if ((ret = libssh_create_ssh_session(libssh, hostname, port)) < 0)
- goto fail;
+ return ret;
user = av_strtok(credencials, ":", &end);
pass = av_strtok(end, ":", &end);
if ((ret = libssh_authentication(libssh, user, pass)) < 0)
- goto fail;
+ return ret;
if ((ret = libssh_create_sftp_session(libssh)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static av_cold int libssh_open(URLContext *h, const char *url, int flags)
+{
+ int ret;
+ LIBSSHContext *libssh = h->priv_data;
+ char path[MAX_URL_SIZE];
+
+ if ((ret = libssh_connect(h, url, path, sizeof(path))) < 0)
goto fail;
if ((ret = libssh_open_file(libssh, flags, path)) < 0)
@@ -293,6 +310,168 @@ static int libssh_write(URLContext *h, const unsigned char *buf, int size)
return bytes_written;
}
+static int libssh_open_dir(URLContext *h)
+{
+ LIBSSHContext *libssh = h->priv_data;
+ int ret;
+ char path[MAX_URL_SIZE];
+
+ if ((ret = libssh_connect(h, h->filename, path, sizeof(path))) < 0)
+ goto fail;
+
+ if (!(libssh->dir = sftp_opendir(libssh->sftp, path))) {
+ av_log(libssh, AV_LOG_ERROR, "Error opening sftp dir: %s\n", ssh_get_error(libssh->session));
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+
+ return 0;
+
+ fail:
+ libssh_close(h);
+ return ret;
+}
+
+static int libssh_read_dir(URLContext *h, AVIODirEntry **next)
+{
+ LIBSSHContext *libssh = h->priv_data;
+ sftp_attributes attr = NULL;
+ AVIODirEntry *entry;
+
+ *next = entry = ff_alloc_dir_entry();
+ if (!entry)
+ return AVERROR(ENOMEM);
+
+ do {
+ if (attr)
+ sftp_attributes_free(attr);
+ attr = sftp_readdir(libssh->sftp, libssh->dir);
+ if (!attr) {
+ av_freep(next);
+ if (sftp_dir_eof(libssh->dir))
+ return 0;
+ return AVERROR(EIO);
+ }
+ } while (!strcmp(attr->name, ".") || !strcmp(attr->name, ".."));
+
+ entry->name = av_strdup(attr->name);
+ entry->group_id = attr->gid;
+ entry->user_id = attr->uid;
+ entry->size = attr->size;
+ entry->access_timestamp = INT64_C(1000000) * attr->atime;
+ entry->modification_timestamp = INT64_C(1000000) * attr->mtime;
+ entry->filemode = attr->permissions & 0777;
+ switch(attr->type) {
+ case SSH_FILEXFER_TYPE_REGULAR:
+ entry->type = AVIO_ENTRY_FILE;
+ break;
+ case SSH_FILEXFER_TYPE_DIRECTORY:
+ entry->type = AVIO_ENTRY_DIRECTORY;
+ break;
+ case SSH_FILEXFER_TYPE_SYMLINK:
+ entry->type = AVIO_ENTRY_SYMBOLIC_LINK;
+ break;
+ case SSH_FILEXFER_TYPE_SPECIAL:
+ /* Special type includes: sockets, char devices, block devices and pipes.
+ It is probably better to return unknown type, to not confuse anybody. */
+ case SSH_FILEXFER_TYPE_UNKNOWN:
+ default:
+ entry->type = AVIO_ENTRY_UNKNOWN;
+ }
+ sftp_attributes_free(attr);
+ return 0;
+}
+
+static int libssh_close_dir(URLContext *h)
+{
+ LIBSSHContext *libssh = h->priv_data;
+ if (libssh->dir)
+ sftp_closedir(libssh->dir);
+ libssh->dir = NULL;
+ libssh_close(h);
+ return 0;
+}
+
+static int libssh_delete(URLContext *h)
+{
+ int ret;
+ LIBSSHContext *libssh = h->priv_data;
+ sftp_attributes attr = NULL;
+ char path[MAX_URL_SIZE];
+
+ if ((ret = libssh_connect(h, h->filename, path, sizeof(path))) < 0)
+ goto cleanup;
+
+ if (!(attr = sftp_stat(libssh->sftp, path))) {
+ ret = AVERROR(sftp_get_error(libssh->sftp));
+ goto cleanup;
+ }
+
+ if (attr->type == SSH_FILEXFER_TYPE_DIRECTORY) {
+ if (sftp_rmdir(libssh->sftp, path) < 0) {
+ ret = AVERROR(sftp_get_error(libssh->sftp));
+ goto cleanup;
+ }
+ } else {
+ if (sftp_unlink(libssh->sftp, path) < 0) {
+ ret = AVERROR(sftp_get_error(libssh->sftp));
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ if (attr)
+ sftp_attributes_free(attr);
+ libssh_close(h);
+ return ret;
+}
+
+static int libssh_move(URLContext *h_src, URLContext *h_dst)
+{
+ int ret;
+ LIBSSHContext *libssh = h_src->priv_data;
+ char path_src[MAX_URL_SIZE], path_dst[MAX_URL_SIZE];
+ char hostname_src[1024], hostname_dst[1024];
+ char credentials_src[1024], credentials_dst[1024];
+ int port_src = 22, port_dst = 22;
+
+ av_url_split(NULL, 0,
+ credentials_src, sizeof(credentials_src),
+ hostname_src, sizeof(hostname_src),
+ &port_src,
+ path_src, sizeof(path_src),
+ h_src->filename);
+
+ av_url_split(NULL, 0,
+ credentials_dst, sizeof(credentials_dst),
+ hostname_dst, sizeof(hostname_dst),
+ &port_dst,
+ path_dst, sizeof(path_dst),
+ h_dst->filename);
+
+ if (strcmp(credentials_src, credentials_dst) ||
+ strcmp(hostname_src, hostname_dst) ||
+ port_src != port_dst) {
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = libssh_connect(h_src, h_src->filename, path_src, sizeof(path_src))) < 0)
+ goto cleanup;
+
+ if (sftp_rename(libssh->sftp, path_src, path_dst) < 0) {
+ ret = AVERROR(sftp_get_error(libssh->sftp));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ libssh_close(h_src);
+ return ret;
+}
+
#define OFFSET(x) offsetof(LIBSSHContext, x)
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
@@ -317,6 +496,11 @@ URLProtocol ff_libssh_protocol = {
.url_write = libssh_write,
.url_seek = libssh_seek,
.url_close = libssh_close,
+ .url_delete = libssh_delete,
+ .url_move = libssh_move,
+ .url_open_dir = libssh_open_dir,
+ .url_read_dir = libssh_read_dir,
+ .url_close_dir = libssh_close_dir,
.priv_data_size = sizeof(LIBSSHContext),
.priv_data_class = &libssh_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
diff --git a/chromium/third_party/ffmpeg/libavformat/lrcdec.c b/chromium/third_party/ffmpeg/libavformat/lrcdec.c
index df61853d2b2..d3655fccd50 100644
--- a/chromium/third_party/ffmpeg/libavformat/lrcdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/lrcdec.c
@@ -210,7 +210,7 @@ static int lrc_read_header(AVFormatContext *s)
}
}
}
- ff_subtitles_queue_finalize(&lrc->q);
+ ff_subtitles_queue_finalize(s, &lrc->q);
ff_metadata_conv_ctx(s, NULL, ff_lrc_metadata_conv);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskadec.c b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
index 3edde1ec34d..756e49c2b9b 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
@@ -812,7 +812,7 @@ static int ebml_read_sint(AVIOContext *pb, int size, int64_t *num)
/* big-endian ordering; build up number */
while (n++ < size)
- *num = (*num << 8) | avio_r8(pb);
+ *num = ((uint64_t)*num << 8) | avio_r8(pb);
}
return 0;
@@ -1798,7 +1798,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
ffio_init_context(&b, track->codec_priv.data,
track->codec_priv.size,
0, NULL, NULL, NULL, NULL);
- ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size, 0);
+ ret = ff_get_wav_header(s, &b, st->codec, track->codec_priv.size, 0);
if (ret < 0)
return ret;
codec_id = st->codec->codec_id;
@@ -1859,7 +1859,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
} else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) {
int profile = matroska_aac_profile(track->codec_id);
int sri = matroska_aac_sri(track->audio.samplerate);
- extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE);
+ extradata = av_mallocz(5 + AV_INPUT_BUFFER_PADDING_SIZE);
if (!extradata)
return AVERROR(ENOMEM);
extradata[0] = (profile << 3) | ((sri & 0x0E) >> 1);
@@ -1872,13 +1872,13 @@ static int matroska_parse_tracks(AVFormatContext *s)
extradata_size = 5;
} else
extradata_size = 2;
- } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - FF_INPUT_BUFFER_PADDING_SIZE) {
+ } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - AV_INPUT_BUFFER_PADDING_SIZE) {
/* Only ALAC's magic cookie is stored in Matroska's track headers.
* Create the "atom size", "tag", and "tag version" fields the
* decoder expects manually. */
extradata_size = 12 + track->codec_priv.size;
extradata = av_mallocz(extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!extradata)
return AVERROR(ENOMEM);
AV_WB32(extradata, extradata_size);
@@ -1888,7 +1888,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
track->codec_priv.size);
} else if (codec_id == AV_CODEC_ID_TTA) {
extradata_size = 30;
- extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!extradata)
return AVERROR(ENOMEM);
ffio_init_context(&b, extradata, extradata_size, 1,
@@ -2077,7 +2077,9 @@ static int matroska_parse_tracks(AVFormatContext *s)
st->codec->channels = track->audio.channels;
if (!st->codec->bits_per_coded_sample)
st->codec->bits_per_coded_sample = track->audio.bitdepth;
- if (st->codec->codec_id != AV_CODEC_ID_AAC)
+ if (st->codec->codec_id == AV_CODEC_ID_MP3)
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ else if (st->codec->codec_id != AV_CODEC_ID_AAC)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
if (track->codec_delay > 0) {
st->codec->delay = av_rescale_q(track->codec_delay,
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
index 3b525ad4d4d..2b2d034e00c 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
@@ -44,6 +44,7 @@
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/random_seed.h"
+#include "libavutil/rational.h"
#include "libavutil/samplefmt.h"
#include "libavutil/sha.h"
#include "libavutil/stereo3d.h"
@@ -131,6 +132,9 @@ typedef struct MatroskaMuxContext {
int64_t last_track_timestamp[MAX_TRACKS];
+ int64_t* stream_durations;
+ int64_t* stream_duration_offsets;
+
int allow_raw_vfw;
} MatroskaMuxContext;
@@ -305,6 +309,23 @@ static void put_xiph_size(AVIOContext *pb, int size)
}
/**
+ * Free the members allocated in the mux context.
+ */
+static void mkv_free(MatroskaMuxContext *mkv) {
+ if (mkv->main_seekhead) {
+ av_freep(&mkv->main_seekhead->entries);
+ av_freep(&mkv->main_seekhead);
+ }
+ if (mkv->cues) {
+ av_freep(&mkv->cues->entries);
+ av_freep(&mkv->cues);
+ }
+ av_freep(&mkv->tracks);
+ av_freep(&mkv->stream_durations);
+ av_freep(&mkv->stream_duration_offsets);
+}
+
+/**
* Initialize a mkv_seekhead element to be ready to index level 1 Matroska
* elements. If a maximum number of elements is specified, enough space
* will be reserved at the current file location to write a seek head of
@@ -364,8 +385,9 @@ static int mkv_add_seekhead_entry(mkv_seekhead *seekhead, unsigned int elementid
* @return The file offset where the seekhead was written,
* -1 if an error occurred.
*/
-static int64_t mkv_write_seekhead(AVIOContext *pb, mkv_seekhead *seekhead)
+static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
{
+ mkv_seekhead *seekhead = mkv->main_seekhead;
ebml_master metaseek, seekentry;
int64_t currentpos;
int i;
@@ -402,8 +424,8 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, mkv_seekhead *seekhead)
currentpos = seekhead->filepos;
}
fail:
- av_freep(&seekhead->entries);
- av_free(seekhead);
+ av_freep(&mkv->main_seekhead->entries);
+ av_freep(&mkv->main_seekhead);
return currentpos;
}
@@ -1151,12 +1173,12 @@ static int mkv_write_simpletag(AVIOContext *pb, AVDictionaryEntry *t)
return 0;
}
-static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int elementid,
- unsigned int uid, ebml_master *tags)
+static int mkv_write_tag_targets(AVFormatContext *s,
+ unsigned int elementid, unsigned int uid,
+ ebml_master *tags, ebml_master* tag)
{
MatroskaMuxContext *mkv = s->priv_data;
- ebml_master tag, targets;
- AVDictionaryEntry *t = NULL;
+ ebml_master targets;
int ret;
if (!tags->pos) {
@@ -1166,11 +1188,24 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme
*tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0);
}
- tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0);
+ *tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0);
targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0);
if (elementid)
put_ebml_uint(s->pb, elementid, uid);
end_ebml_master(s->pb, targets);
+ return 0;
+}
+
+static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int elementid,
+ unsigned int uid, ebml_master *tags)
+{
+ ebml_master tag;
+ int ret;
+ AVDictionaryEntry *t = NULL;
+
+ ret = mkv_write_tag_targets(s, elementid, uid, tags, &tag);
+ if (ret < 0)
+ return ret;
while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
if (av_strcasecmp(t->key, "title") &&
@@ -1220,6 +1255,25 @@ static int mkv_write_tags(AVFormatContext *s)
if (ret < 0) return ret;
}
+ if (!mkv->is_live) {
+ for (i = 0; i < s->nb_streams; i++) {
+ ebml_master tag_target;
+ ebml_master tag;
+
+ mkv_write_tag_targets(s, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags, &tag_target);
+
+ tag = start_ebml_master(s->pb, MATROSKA_ID_SIMPLETAG, 0);
+ put_ebml_string(s->pb, MATROSKA_ID_TAGNAME, "DURATION");
+ mkv->stream_duration_offsets[i] = avio_tell(s->pb);
+
+ // Reserve space to write duration as a 20-byte string.
+ // 2 (ebml id) + 1 (data size) + 20 (data)
+ put_ebml_void(s->pb, 23);
+ end_ebml_master(s->pb, tag);
+ end_ebml_master(s->pb, tag_target);
+ }
+ }
+
for (i = 0; i < s->nb_chapters; i++) {
AVChapter *ch = s->chapters[i];
@@ -1361,9 +1415,10 @@ static int mkv_write_header(AVFormatContext *s)
}
mkv->tracks = av_mallocz_array(s->nb_streams, sizeof(*mkv->tracks));
- if (!mkv->tracks)
- return AVERROR(ENOMEM);
-
+ if (!mkv->tracks) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0);
put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1);
put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1);
@@ -1383,11 +1438,13 @@ static int mkv_write_header(AVFormatContext *s)
// isn't more than 10 elements if we only write one of each other
// currently defined level 1 element
mkv->main_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 10);
- if (!mkv->main_seekhead)
- return AVERROR(ENOMEM);
+ if (!mkv->main_seekhead) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, avio_tell(pb));
- if (ret < 0) return ret;
+ if (ret < 0) goto fail;
segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0);
put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
@@ -1430,9 +1487,13 @@ static int mkv_write_header(AVFormatContext *s)
}
end_ebml_master(pb, segment_info);
+ // initialize stream_duration fields
+ mkv->stream_durations = av_mallocz(s->nb_streams * sizeof(int64_t));
+ mkv->stream_duration_offsets = av_mallocz(s->nb_streams * sizeof(int64_t));
+
ret = mkv_write_tracks(s);
if (ret < 0)
- return ret;
+ goto fail;
for (i = 0; i < s->nb_chapters; i++)
mkv->chapter_id_offset = FFMAX(mkv->chapter_id_offset, 1LL - s->chapters[i]->id);
@@ -1440,24 +1501,25 @@ static int mkv_write_header(AVFormatContext *s)
if (mkv->mode != MODE_WEBM) {
ret = mkv_write_chapters(s);
if (ret < 0)
- return ret;
+ goto fail;
ret = mkv_write_tags(s);
if (ret < 0)
- return ret;
+ goto fail;
ret = mkv_write_attachments(s);
if (ret < 0)
- return ret;
+ goto fail;
}
if (!s->pb->seekable && !mkv->is_live)
- mkv_write_seekhead(pb, mkv->main_seekhead);
+ mkv_write_seekhead(pb, mkv);
mkv->cues = mkv_start_cues(mkv->segment_offset);
- if (!mkv->cues)
- return AVERROR(ENOMEM);
-
+ if (!mkv->cues) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
if (pb->seekable && mkv->reserve_cues_space) {
mkv->cues_pos = avio_tell(pb);
put_ebml_void(pb, mkv->reserve_cues_space);
@@ -1484,6 +1546,9 @@ static int mkv_write_header(AVFormatContext *s)
}
return 0;
+fail:
+ mkv_free(mkv);
+ return ret;
}
static int mkv_blockgroup_size(int pkt_size)
@@ -1772,33 +1837,40 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe);
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe || add_cue) {
+ if (s->pb->seekable && (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe || add_cue)) {
ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, dash_tracknum, ts, mkv->cluster_pos, relative_packet_pos, -1);
if (ret < 0) return ret;
}
} else {
- if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
- duration = mkv_write_vtt_blocks(s, pb, pkt);
- } else {
- ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
- mkv_blockgroup_size(pkt->size));
- /* For backward compatibility, prefer convergence_duration. */
- if (pkt->convergence_duration > 0) {
- duration = pkt->convergence_duration;
+ if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
+ duration = mkv_write_vtt_blocks(s, pb, pkt);
+ } else {
+ ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
+ mkv_blockgroup_size(pkt->size));
+ /* For backward compatibility, prefer convergence_duration. */
+ if (pkt->convergence_duration > 0) {
+ duration = pkt->convergence_duration;
+ }
+ /* All subtitle blocks are considered to be keyframes. */
+ mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 1);
+ put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
+ end_ebml_master(pb, blockgroup);
}
- /* All subtitle blocks are considered to be keyframes. */
- mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 1);
- put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
- end_ebml_master(pb, blockgroup);
- }
- ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, dash_tracknum, ts,
- mkv->cluster_pos, relative_packet_pos, duration);
- if (ret < 0)
- return ret;
+ if (s->pb->seekable) {
+ ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, dash_tracknum, ts,
+ mkv->cluster_pos, relative_packet_pos, duration);
+ if (ret < 0)
+ return ret;
+ }
}
mkv->duration = FFMAX(mkv->duration, ts + duration);
+
+ if (mkv->stream_durations)
+ mkv->stream_durations[pkt->stream_index] =
+ FFMAX(mkv->stream_durations[pkt->stream_index], ts + duration);
+
return 0;
}
@@ -1968,7 +2040,7 @@ static int mkv_write_trailer(AVFormatContext *s)
return ret;
}
- mkv_write_seekhead(pb, mkv->main_seekhead);
+ mkv_write_seekhead(pb, mkv);
// update the duration
av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
@@ -1976,16 +2048,37 @@ static int mkv_write_trailer(AVFormatContext *s)
avio_seek(pb, mkv->duration_offset, SEEK_SET);
put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);
+ // update stream durations
+ if (mkv->stream_durations) {
+ int i;
+ for (i = 0; i < s->nb_streams; ++i) {
+ AVStream *st = s->streams[i];
+ double duration_sec = mkv->stream_durations[i] * av_q2d(st->time_base);
+ char duration_string[20] = "";
+
+ av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i,
+ mkv->stream_durations[i]);
+
+ if (!mkv->is_live && mkv->stream_duration_offsets[i] > 0) {
+ avio_seek(pb, mkv->stream_duration_offsets[i], SEEK_SET);
+
+ snprintf(duration_string, 20, "%02d:%02d:%012.9f",
+ (int) duration_sec / 3600, ((int) duration_sec / 60) % 60,
+ fmod(duration_sec, 60));
+
+ put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20);
+ }
+ }
+ }
+
avio_seek(pb, currentpos, SEEK_SET);
}
if (!mkv->is_live) {
end_ebml_master(pb, mkv->segment);
}
- av_freep(&mkv->tracks);
- av_freep(&mkv->cues->entries);
- av_freep(&mkv->cues);
+ mkv_free(mkv);
return 0;
}
@@ -2097,8 +2190,8 @@ AVOutputFormat ff_webm_muxer = {
.mime_type = "video/webm",
.extensions = "webm",
.priv_data_size = sizeof(MatroskaMuxContext),
- .audio_codec = AV_CODEC_ID_VORBIS,
- .video_codec = AV_CODEC_ID_VP8,
+ .audio_codec = CONFIG_LIBOPUS_ENCODER ? AV_CODEC_ID_OPUS : AV_CODEC_ID_VORBIS,
+ .video_codec = CONFIG_LIBVPX_VP9_ENCODER? AV_CODEC_ID_VP9 : AV_CODEC_ID_VP8,
.subtitle_codec = AV_CODEC_ID_WEBVTT,
.write_header = mkv_write_header,
.write_packet = mkv_write_flush_packet,
diff --git a/chromium/third_party/ffmpeg/libavformat/md5enc.c b/chromium/third_party/ffmpeg/libavformat/md5enc.c
index 8e87f095c99..e1a53684b6f 100644
--- a/chromium/third_party/ffmpeg/libavformat/md5enc.c
+++ b/chromium/third_party/ffmpeg/libavformat/md5enc.c
@@ -107,7 +107,8 @@ AVOutputFormat ff_md5_muxer = {
.write_header = write_header,
.write_packet = write_packet,
.write_trailer = write_trailer,
- .flags = AVFMT_NOTIMESTAMPS,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+ AVFMT_TS_NEGATIVE,
.priv_class = &md5enc_class,
};
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/microdvddec.c b/chromium/third_party/ffmpeg/libavformat/microdvddec.c
index a3839051a45..727ff947e7e 100644
--- a/chromium/third_party/ffmpeg/libavformat/microdvddec.c
+++ b/chromium/third_party/ffmpeg/libavformat/microdvddec.c
@@ -141,7 +141,7 @@ static int microdvd_read_header(AVFormatContext *s)
sub->pts = get_pts(line);
sub->duration = get_duration(line);
}
- ff_subtitles_queue_finalize(&microdvd->q);
+ ff_subtitles_queue_finalize(s, &microdvd->q);
if (has_real_fps) {
/* export the FPS info only if set in the file */
microdvd->frame_rate = pts_info;
diff --git a/chromium/third_party/ffmpeg/libavformat/mlvdec.c b/chromium/third_party/ffmpeg/libavformat/mlvdec.c
index aa1ba60d37e..48a429eb23a 100644
--- a/chromium/third_party/ffmpeg/libavformat/mlvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mlvdec.c
@@ -143,7 +143,7 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f
vst->codec->codec_tag = MKTAG('B', 'I', 'T', 16);
size -= 164;
} else if (ast && type == MKTAG('W', 'A', 'V', 'I') && size >= 16) {
- ret = ff_get_wav_header(pb, ast->codec, 16, 0);
+ ret = ff_get_wav_header(avctx, pb, ast->codec, 16, 0);
if (ret < 0)
return ret;
size -= 16;
diff --git a/chromium/third_party/ffmpeg/libavformat/mov.c b/chromium/third_party/ffmpeg/libavformat/mov.c
index 5ea69328011..c57aaeb178d 100644
--- a/chromium/third_party/ffmpeg/libavformat/mov.c
+++ b/chromium/third_party/ffmpeg/libavformat/mov.c
@@ -29,6 +29,7 @@
#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/mathematics.h"
@@ -37,6 +38,8 @@
#include "libavutil/dict.h"
#include "libavutil/display.h"
#include "libavutil/opt.h"
+#include "libavutil/aes.h"
+#include "libavutil/sha.h"
#include "libavutil/timecode.h"
#include "libavcodec/ac3tab.h"
#include "avformat.h"
@@ -769,7 +772,7 @@ static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if ((ret = ff_get_wav_header(pb, st->codec, atom.size, 0)) < 0)
+ if ((ret = ff_get_wav_header(c->fc, pb, st->codec, atom.size, 0)) < 0)
av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
return ret;
@@ -807,6 +810,120 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0; /* now go for moov */
}
+#define DRM_BLOB_SIZE 56
+
+static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ uint8_t intermediate_key[20];
+ uint8_t intermediate_iv[20];
+ uint8_t input[64];
+ uint8_t output[64];
+ uint8_t file_checksum[20];
+ uint8_t calculated_checksum[20];
+ struct AVSHA *sha;
+ int i;
+ int ret = 0;
+ uint8_t *activation_bytes = c->activation_bytes;
+ uint8_t *fixed_key = c->audible_fixed_key;
+
+ c->aax_mode = 1;
+
+ sha = av_sha_alloc();
+ if (!sha)
+ return AVERROR(ENOMEM);
+ c->aes_decrypt = av_aes_alloc();
+ if (!c->aes_decrypt) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ /* drm blob processing */
+ avio_read(pb, output, 8); // go to offset 8, absolute postion 0x251
+ avio_read(pb, input, DRM_BLOB_SIZE);
+ avio_read(pb, output, 4); // go to offset 4, absolute postion 0x28d
+ avio_read(pb, file_checksum, 20);
+
+ av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
+ for (i = 0; i < 20; i++)
+ av_log(sha, AV_LOG_INFO, "%02x", file_checksum[i]);
+ av_log(c->fc, AV_LOG_INFO, "\n");
+
+ /* verify activation data */
+ if (!activation_bytes) {
+ av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
+ ret = 0; /* allow ffprobe to continue working on .aax files */
+ goto fail;
+ }
+ if (c->activation_bytes_size != 4) {
+ av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ /* verify fixed key */
+ if (c->audible_fixed_key_size != 16) {
+ av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ /* AAX (and AAX+) key derivation */
+ av_sha_init(sha, 160);
+ av_sha_update(sha, fixed_key, 16);
+ av_sha_update(sha, activation_bytes, 4);
+ av_sha_final(sha, intermediate_key);
+ av_sha_init(sha, 160);
+ av_sha_update(sha, fixed_key, 16);
+ av_sha_update(sha, intermediate_key, 20);
+ av_sha_update(sha, activation_bytes, 4);
+ av_sha_final(sha, intermediate_iv);
+ av_sha_init(sha, 160);
+ av_sha_update(sha, intermediate_key, 16);
+ av_sha_update(sha, intermediate_iv, 16);
+ av_sha_final(sha, calculated_checksum);
+ if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
+ av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
+ av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
+ for (i = 0; i < 4; i++) {
+ // file data (in output) is stored in big-endian mode
+ if (activation_bytes[i] != output[3 - i]) { // critical error
+ av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ }
+ memcpy(c->file_key, output + 8, 16);
+ memcpy(input, output + 26, 16);
+ av_sha_init(sha, 160);
+ av_sha_update(sha, input, 16);
+ av_sha_update(sha, c->file_key, 16);
+ av_sha_update(sha, fixed_key, 16);
+ av_sha_final(sha, c->file_iv);
+
+fail:
+ av_free(sha);
+
+ return ret;
+}
+
+// Audible AAX (and AAX+) bytestream decryption
+static int aax_filter(uint8_t *input, int size, MOVContext *c)
+{
+ int blocks = 0;
+ unsigned char iv[16];
+
+ memcpy(iv, c->file_iv, 16); // iv is overwritten
+ blocks = size >> 4; // trailing bytes are not encrypted!
+ av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
+ av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
+
+ return 0;
+}
+
/* read major brand, minor version and compatible brands and store them as metadata */
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
@@ -1024,7 +1141,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
char color_parameter_type[5] = { 0 };
- int color_primaries, color_trc, color_matrix;
+ uint16_t color_primaries, color_trc, color_matrix;
int ret;
if (c->fc->nb_streams < 1)
@@ -1130,14 +1247,14 @@ static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_realloc_extradata(AVCodecContext *codec, MOVAtom atom)
{
int err = 0;
- uint64_t size = (uint64_t)codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
+ uint64_t size = (uint64_t)codec->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
return AVERROR_INVALIDDATA;
if ((err = av_reallocp(&codec->extradata, size)) < 0) {
codec->extradata_size = 0;
return err;
}
- codec->extradata_size = size - FF_INPUT_BUFFER_PADDING_SIZE;
+ codec->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
return 0;
}
@@ -1159,7 +1276,7 @@ static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVA
codec->extradata_size -= atom.size - err;
result = err;
}
- memset(buf + 8 + err, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
return result;
}
@@ -1277,7 +1394,7 @@ static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
break;
}
- av_dlog(c, "color_range: %d\n", codec->color_range);
+ ff_dlog(c, "color_range: %d\n", codec->color_range);
} else {
/* For some reason the whole atom was not added to the extradata */
av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
@@ -1319,6 +1436,32 @@ static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (ret < 0)
return ret;
} else if (atom.size > 8) { /* to read frma, esds atoms */
+ if (st->codec->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
+ uint64_t buffer;
+ ret = ffio_ensure_seekback(pb, 8);
+ if (ret < 0)
+ return ret;
+ buffer = avio_rb64(pb);
+ atom.size -= 8;
+ if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
+ && buffer >> 32 <= atom.size
+ && buffer >> 32 >= 8) {
+ avio_skip(pb, -8);
+ atom.size += 8;
+ } else if (!st->codec->extradata_size) {
+#define ALAC_EXTRADATA_SIZE 36
+ st->codec->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata_size = ALAC_EXTRADATA_SIZE;
+ AV_WB32(st->codec->extradata , ALAC_EXTRADATA_SIZE);
+ AV_WB32(st->codec->extradata + 4, MKTAG('a','l','a','c'));
+ AV_WB64(st->codec->extradata + 12, buffer);
+ avio_read(pb, st->codec->extradata + 20, 16);
+ avio_skip(pb, atom.size - 24);
+ return 0;
+ }
+ }
if ((ret = mov_read_default(c, pb, atom)) < 0)
return ret;
} else
@@ -1567,7 +1710,7 @@ static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) {
/* for palette traversal */
unsigned int color_start, color_count, color_end;
- unsigned char a, r, g, b;
+ unsigned int a, r, g, b;
if (color_greyscale) {
int color_index, color_dec;
@@ -1669,6 +1812,15 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample,
flags);
}
+ if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
+ /* can't correctly handle variable sized packet as audio unit */
+ switch (st->codec->codec_id) {
+ case AV_CODEC_ID_MP2:
+ case AV_CODEC_ID_MP3:
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ break;
+ }
+ }
}
switch (st->codec->codec_id) {
@@ -1774,7 +1926,7 @@ static int mov_rewrite_dvd_sub_extradata(AVStream *st)
av_freep(&st->codec->extradata);
st->codec->extradata_size = 0;
- st->codec->extradata = av_mallocz(strlen(buf) + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_mallocz(strlen(buf) + AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
st->codec->extradata_size = strlen(buf);
@@ -1802,7 +1954,7 @@ static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
val = AV_RB32(st->codec->extradata + 4);
tmcd_ctx->tmcd_flags = val;
if (val & 1)
- st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
+ st->codec->flags2 |= AV_CODEC_FLAG2_DROP_FRAME_TIMECODE;
st->codec->time_base.den = st->codec->extradata[16]; /* number of frame */
st->codec->time_base.num = 1;
/* adjust for per frame dur in counter mode */
@@ -1889,7 +2041,6 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
case AV_CODEC_ID_MP3:
/* force type after stsd for m1a hdlr */
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->need_parsing = AVSTREAM_PARSE_FULL;
break;
case AV_CODEC_ID_GSM:
case AV_CODEC_ID_ADPCM_MS:
@@ -1985,9 +2136,10 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
id = mov_codec_id(st, format);
- av_log(c->fc, AV_LOG_TRACE, "size=%"PRId64" 4CC= %c%c%c%c codec_type=%d\n", size,
+ av_log(c->fc, AV_LOG_TRACE,
+ "size=%"PRId64" 4CC= %c%c%c%c/0x%08x codec_type=%d\n", size,
(format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
- (format >> 24) & 0xff, st->codec->codec_type);
+ (format >> 24) & 0xff, format, st->codec->codec_type);
if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
st->codec->codec_id = id;
@@ -2211,7 +2363,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
num_bytes = (entries*field_size+4)>>3;
- buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
+ buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
if (!buf) {
av_freep(&sc->sample_sizes);
return AVERROR(ENOMEM);
@@ -2354,7 +2506,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
count, duration);
- if (FFABS(duration) > (1<<28) && i+2<entries) {
+ if (FFNABS(duration) < -(1<<28) && i+2<entries) {
av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
av_freep(&sc->ctts_data);
sc->ctts_count = 0;
@@ -2689,6 +2841,35 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
}
+static int test_same_origin(const char *src, const char *ref) {
+ char src_proto[64];
+ char ref_proto[64];
+ char src_auth[256];
+ char ref_auth[256];
+ char src_host[256];
+ char ref_host[256];
+ int src_port=-1;
+ int ref_port=-1;
+
+ av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
+ av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
+
+ if (strlen(src) == 0) {
+ return -1;
+ } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
+ strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
+ strlen(src_host) + 1 >= sizeof(src_host) ||
+ strlen(ref_host) + 1 >= sizeof(ref_host)) {
+ return 0;
+ } else if (strcmp(src_proto, ref_proto) ||
+ strcmp(src_auth, ref_auth) ||
+ strcmp(src_host, ref_host) ||
+ src_port != ref_port) {
+ return 0;
+ } else
+ return 1;
+}
+
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref,
AVIOInterruptCB *int_cb)
{
@@ -2699,7 +2880,7 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr
/* try relative path, we do not try the absolute because it can leak information about our
system to an attacker */
- if (ref->nlvl_to > 0 && ref->nlvl_from > 0 && ref->path[0] != '/') {
+ if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
char filename[1025];
const char *src_path;
int i, l;
@@ -2729,9 +2910,23 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr
av_strlcat(filename, "../", sizeof(filename));
av_strlcat(filename, ref->path + l + 1, sizeof(filename));
- if (!c->use_absolute_path && !c->fc->open_cb)
- if(strstr(ref->path + l + 1, "..") || ref->nlvl_from > 1)
+ if (!c->use_absolute_path && !c->fc->open_cb) {
+ int same_origin = test_same_origin(src, filename);
+
+ if (!same_origin) {
+ av_log(c->fc, AV_LOG_ERROR,
+ "Reference with mismatching origin, %s not tried for security reasons, "
+ "set demuxer option use_absolute_path to allow it anyway\n",
+ ref->path);
+ return AVERROR(ENOENT);
+ }
+
+ if(strstr(ref->path + l + 1, "..") ||
+ strstr(ref->path + l + 1, ":") ||
+ (ref->nlvl_from > 1 && same_origin < 0) ||
+ (filename[0] == '/' && src_path == src))
return AVERROR(ENOENT);
+ }
if (strlen(filename) + 1 == sizeof(filename))
return AVERROR(ENOENT);
@@ -3233,7 +3428,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
int64_t dts;
int data_offset = 0;
unsigned entries, first_sample_flags = frag->flags;
- int flags, distance, i, found_keyframe = 0, err;
+ int flags, distance, i, err;
for (i = 0; i < c->fc->nb_streams; i++) {
if (c->fc->streams[i]->id == frag->track_id) {
@@ -3320,8 +3515,8 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->ctts_count++;
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
keyframe = 1;
- else if (!found_keyframe)
- keyframe = found_keyframe =
+ else
+ keyframe =
!(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
if (keyframe)
@@ -3585,6 +3780,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('e','l','s','t'), mov_read_elst },
{ MKTAG('e','n','d','a'), mov_read_enda },
{ MKTAG('f','i','e','l'), mov_read_fiel },
+{ MKTAG('a','d','r','m'), mov_read_adrm },
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
@@ -3964,6 +4160,9 @@ static int mov_read_close(AVFormatContext *s)
AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
+ if (!sc)
+ continue;
+
av_freep(&sc->ctts_data);
for (j = 0; j < sc->drefs_count; j++) {
av_freep(&sc->drefs[j].path);
@@ -4003,6 +4202,8 @@ static int mov_read_close(AVFormatContext *s)
}
av_freep(&mov->fragment_index_data);
+ av_freep(&mov->aes_decrypt);
+
return 0;
}
@@ -4290,6 +4491,7 @@ static int mov_read_header(AVFormatContext *s)
break;
}
}
+ ff_configure_buffers_for_index(s, AV_TIME_BASE);
return 0;
}
@@ -4421,6 +4623,9 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
pkt->pos = sample->pos;
+ if (mov->aax_mode)
+ aax_filter(pkt->data, pkt->size, mov);
+
return 0;
}
@@ -4511,17 +4716,17 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
static const AVOption mov_options[] = {
{"use_absolute_path",
"allow using absolute path when opening alias, this is a possible security issue",
- OFFSET(use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0},
+ OFFSET(use_absolute_path), AV_OPT_TYPE_INT, {.i64 = 0},
0, 1, FLAGS},
{"seek_streams_individually",
"Seek each stream individually to the to the closest point",
OFFSET(seek_individually), AV_OPT_TYPE_INT, { .i64 = 1 },
0, 1, FLAGS},
- {"ignore_editlist", "", OFFSET(ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0},
+ {"ignore_editlist", "", OFFSET(ignore_editlist), AV_OPT_TYPE_INT, {.i64 = 0},
0, 1, FLAGS},
{"use_mfra_for",
"use mfra for fragment timestamps",
- OFFSET(use_mfra_for), FF_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
+ OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
-1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
"use_mfra_for"},
{"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
@@ -4531,9 +4736,15 @@ static const AVOption mov_options[] = {
{"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
FLAGS, "use_mfra_for" },
{ "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
{ "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
+ { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
+ AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
+ { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
+ "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
+ AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
+ .flags = AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/movenc.c b/chromium/third_party/ffmpeg/libavformat/movenc.c
index adde4b2c230..08d0c2a7720 100644
--- a/chromium/third_party/ffmpeg/libavformat/movenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/movenc.c
@@ -66,6 +66,7 @@ static const AVOption options[] = {
{ "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "write_colr", "Write colr atom (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
@@ -733,7 +734,7 @@ static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
"dvc1 atom. Set the delay_moov flag to fix this.\n");
}
- unescaped = av_mallocz(track->vos_len + FF_INPUT_BUFFER_PADDING_SIZE);
+ unescaped = av_mallocz(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
if (!unescaped)
return AVERROR(ENOMEM);
start = find_next_marker(track->vos_data, end);
@@ -2573,7 +2574,7 @@ static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
int ret, size;
uint8_t *buf;
- if (!st || mov->fc->flags & AVFMT_FLAG_BITEXACT)
+ if (!st)
return 0;
ret = avio_open_dyn_buf(&pb_buf);
@@ -2919,9 +2920,10 @@ static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
mov_write_string_metadata(s, pb, "\251day", "date" , 1);
- if (!mov->exact &&
- !mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1))
- mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
+ if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
+ if (!(s->flags & AVFMT_FLAG_BITEXACT))
+ mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
+ }
mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1);
@@ -3115,7 +3117,6 @@ static void mov_write_psp_udta_tag(AVIOContext *pb,
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
{
- MOVMuxContext *mov = s->priv_data;
AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
int64_t pos, pos2;
@@ -3140,7 +3141,7 @@ static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
avio_wb16(pb, 0x0); /* ? */
avio_wb16(pb, 0x021C); /* data */
- if (!mov->exact)
+ if (!(s->flags & AVFMT_FLAG_BITEXACT))
mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
@@ -3275,7 +3276,7 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
avio_printf(pb, "<head>\n");
- if (!mov->exact)
+ if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
LIBAVFORMAT_IDENT);
avio_printf(pb, "</head>\n");
@@ -3680,6 +3681,8 @@ static int mov_write_sidx_tag(AVIOContext *pb,
}
} else {
entries = track->nb_frag_info;
+ if (entries <= 0)
+ return 0;
presentation_time = track->frag_info[0].time;
}
@@ -3763,7 +3766,7 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
moof_size = ffio_close_null_buf(avio_buf);
- if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_FASTSTART))
+ if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX))
mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
@@ -3903,7 +3906,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
else if (mov->mode == MODE_MP4)
ffio_wfourcc(pb, "mp41");
- if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_FASTSTART)
+ if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
ffio_wfourcc(pb, "dash");
return update_size(pb, pos);
@@ -4165,8 +4168,8 @@ static int mov_flush_fragment(AVFormatContext *s)
return ret;
if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
- if (mov->flags & FF_MOV_FLAG_FASTSTART)
- mov->reserved_moov_pos = avio_tell(s->pb);
+ if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
+ mov->reserved_header_pos = avio_tell(s->pb);
avio_flush(s->pb);
mov->moov_written = 1;
return 0;
@@ -4179,6 +4182,9 @@ static int mov_flush_fragment(AVFormatContext *s)
avio_write(s->pb, buf, buf_size);
av_free(buf);
+ if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
+ mov->reserved_header_pos = avio_tell(s->pb);
+
mov->moov_written = 1;
mov->mdat_size = 0;
for (i = 0; i < mov->nb_streams; i++) {
@@ -4455,7 +4461,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
* in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
* the next fragment. This means the cts of the first sample must
* be the same in all fragments. */
- if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_FASTSTART)) ||
+ if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)) ||
mov->mode == MODE_ISM)
pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
} else {
@@ -4960,9 +4966,6 @@ static int mov_write_header(AVFormatContext *s)
else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
}
- if (s->flags & AVFMT_FLAG_BITEXACT)
- mov->exact = 1;
-
if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
@@ -5230,7 +5233,7 @@ static int mov_write_header(AVFormatContext *s)
if (mov->reserved_moov_size){
- mov->reserved_moov_pos= avio_tell(pb);
+ mov->reserved_header_pos = avio_tell(pb);
if (mov->reserved_moov_size > 0)
avio_skip(pb, mov->reserved_moov_size);
}
@@ -5243,12 +5246,17 @@ static int mov_write_header(AVFormatContext *s)
mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
} else {
if (mov->flags & FF_MOV_FLAG_FASTSTART)
- mov->reserved_moov_pos = avio_tell(pb);
+ mov->reserved_header_pos = avio_tell(pb);
mov_write_mdat_tag(pb, mov);
}
- if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
mov->time = ff_iso8601_to_unix_time(t->value);
+ if (mov->time < 0) {
+ av_log(s, AV_LOG_WARNING, "Failed to parse creation_time %s\n", t->value);
+ mov->time = 0;
+ }
+ }
if (mov->time)
mov->time += 0x7C25B080; // 1970 based -> 1904 based
@@ -5297,8 +5305,8 @@ static int mov_write_header(AVFormatContext *s)
if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
return ret;
mov->moov_written = 1;
- if (mov->flags & FF_MOV_FLAG_FASTSTART)
- mov->reserved_moov_pos = avio_tell(pb);
+ if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
+ mov->reserved_header_pos = avio_tell(pb);
}
return 0;
@@ -5415,10 +5423,10 @@ static int shift_data(AVFormatContext *s)
/* mark the end of the shift to up to the last data we wrote, and get ready
* for writing */
pos_end = avio_tell(s->pb);
- avio_seek(s->pb, mov->reserved_moov_pos + moov_size, SEEK_SET);
+ avio_seek(s->pb, mov->reserved_header_pos + moov_size, SEEK_SET);
/* start reading at where the new moov will be placed */
- avio_seek(read_pb, mov->reserved_moov_pos, SEEK_SET);
+ avio_seek(read_pb, mov->reserved_header_pos, SEEK_SET);
pos = avio_tell(read_pb);
#define READ_BLOCK do { \
@@ -5492,13 +5500,13 @@ static int mov_write_trailer(AVFormatContext *s)
ffio_wfourcc(pb, "mdat");
avio_wb64(pb, mov->mdat_size + 16);
}
- avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
+ avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
if (mov->flags & FF_MOV_FLAG_FASTSTART) {
av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
res = shift_data(s);
if (res == 0) {
- avio_seek(pb, mov->reserved_moov_pos, SEEK_SET);
+ avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
goto error;
}
@@ -5506,7 +5514,7 @@ static int mov_write_trailer(AVFormatContext *s)
int64_t size;
if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
goto error;
- size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
+ size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
if (size < 8){
av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
res = AVERROR(EINVAL);
@@ -5525,12 +5533,12 @@ static int mov_write_trailer(AVFormatContext *s)
mov_auto_flush_fragment(s);
for (i = 0; i < mov->nb_streams; i++)
mov->tracks[i].data_offset = 0;
- if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+ if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
res = shift_data(s);
if (res == 0) {
int64_t end = avio_tell(pb);
- avio_seek(pb, mov->reserved_moov_pos, SEEK_SET);
+ avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
mov_write_sidx_tags(pb, mov, -1, 0);
avio_seek(pb, end, SEEK_SET);
mov_write_mfra_tag(pb, mov);
@@ -5588,7 +5596,7 @@ MOV_CLASS(mp4)
AVOutputFormat ff_mp4_muxer = {
.name = "mp4",
.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
- .mime_type = "application/mp4",
+ .mime_type = "video/mp4",
.extensions = "mp4",
.priv_data_size = sizeof(MOVMuxContext),
.audio_codec = AV_CODEC_ID_AAC,
@@ -5642,7 +5650,7 @@ MOV_CLASS(ipod)
AVOutputFormat ff_ipod_muxer = {
.name = "ipod",
.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
- .mime_type = "application/mp4",
+ .mime_type = "video/mp4",
.extensions = "m4v,m4a",
.priv_data_size = sizeof(MOVMuxContext),
.audio_codec = AV_CODEC_ID_AAC,
@@ -5660,7 +5668,7 @@ MOV_CLASS(ismv)
AVOutputFormat ff_ismv_muxer = {
.name = "ismv",
.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
- .mime_type = "application/mp4",
+ .mime_type = "video/mp4",
.extensions = "ismv,isma",
.priv_data_size = sizeof(MOVMuxContext),
.audio_codec = AV_CODEC_ID_AAC,
diff --git a/chromium/third_party/ffmpeg/libavformat/movenc.h b/chromium/third_party/ffmpeg/libavformat/movenc.h
index 744d14e5b2d..06adf2b1217 100644
--- a/chromium/third_party/ffmpeg/libavformat/movenc.h
+++ b/chromium/third_party/ffmpeg/libavformat/movenc.h
@@ -164,7 +164,6 @@ typedef struct MOVMuxContext {
int flags;
int rtp_flags;
- int exact;
int iods_skip;
int iods_video_profile;
@@ -182,7 +181,7 @@ typedef struct MOVMuxContext {
int video_track_timescale;
int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
- int64_t reserved_moov_pos;
+ int64_t reserved_header_pos;
char *major_brand;
@@ -210,8 +209,9 @@ typedef struct MOVMuxContext {
#define FF_MOV_FLAG_DASH (1 << 11)
#define FF_MOV_FLAG_FRAG_DISCONT (1 << 12)
#define FF_MOV_FLAG_DELAY_MOOV (1 << 13)
-#define FF_MOV_FLAG_WRITE_COLR (1 << 14)
-#define FF_MOV_FLAG_WRITE_GAMA (1 << 15)
+#define FF_MOV_FLAG_GLOBAL_SIDX (1 << 14)
+#define FF_MOV_FLAG_WRITE_COLR (1 << 15)
+#define FF_MOV_FLAG_WRITE_GAMA (1 << 16)
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
diff --git a/chromium/third_party/ffmpeg/libavformat/mp3dec.c b/chromium/third_party/ffmpeg/libavformat/mp3dec.c
index 4023c8223e6..7354c2841bb 100644
--- a/chromium/third_party/ffmpeg/libavformat/mp3dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mp3dec.c
@@ -54,7 +54,7 @@ typedef struct {
int is_cbr;
} MP3DecContext;
-static int check(AVFormatContext *s, int64_t pos);
+static int check(AVIOContext *pb, int64_t pos);
/* mp3 read */
@@ -98,7 +98,7 @@ static int mp3_read_probe(AVProbeData *p)
avcodec_free_context(&avctx);
// keep this in sync with ac3 probe, both need to avoid
// issues with MPEG-files!
- if (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1;
+ if (first_frames>=7) return AVPROBE_SCORE_EXTENSION + 1;
else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
else if(max_frames>=4 && max_frames >= p->buf_size/10000) return AVPROBE_SCORE_EXTENSION / 2;
else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size)
@@ -148,6 +148,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
MP3DecContext *mp3 = s->priv_data;
static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
+ uint64_t fsize = avio_size(s->pb);
+ fsize = fsize >= avio_tell(s->pb) ? fsize - avio_tell(s->pb) : 0;
/* Check for Xing / Info tag */
avio_skip(s->pb, xing_offtbl[c->lsf == 1][c->nb_channels == 1]);
@@ -161,6 +163,19 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
mp3->frames = avio_rb32(s->pb);
if (v & XING_FLAG_SIZE)
mp3->header_filesize = avio_rb32(s->pb);
+ if (fsize && mp3->header_filesize) {
+ uint64_t min, delta;
+ min = FFMIN(fsize, mp3->header_filesize);
+ delta = FFMAX(fsize, mp3->header_filesize) - min;
+ if (fsize > mp3->header_filesize && delta > min >> 4) {
+ mp3->frames = 0;
+ av_log(s, AV_LOG_WARNING,
+ "invalid concatenated file detected - using bitrate for duration\n");
+ } else if (delta > min >> 4) {
+ av_log(s, AV_LOG_WARNING,
+ "filesize and duration do not match (growing file?)\n");
+ }
+ }
if (v & XING_FLAG_TOC)
read_xing_toc(s, mp3->header_filesize, av_rescale_q(mp3->frames,
(AVRational){spf, c->sample_rate},
@@ -223,6 +238,14 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
st->last_discard_sample = mp3->frames * (int64_t)spf;
}
+ // TODO(dalecurtis): Chrome expects to handle this start time change
+ // itself, instead of ffmpeg magically moving the start time into
+ // the future.
+ //
+ // if (!st->start_time)
+ // st->start_time = av_rescale_q(st->start_skip_samples,
+ // (AVRational){1, c->sample_rate},
+ // st->time_base);
av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad);
}
@@ -323,7 +346,7 @@ static int mp3_read_header(AVFormatContext *s)
int i;
if (mp3->usetoc < 0)
- mp3->usetoc = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 0 : 2;
+ mp3->usetoc = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 1 : 2;
st = avformat_new_stream(s, NULL);
if (!st)
@@ -357,7 +380,7 @@ static int mp3_read_header(AVFormatContext *s)
for (i = 0; i < 64 * 1024; i++) {
if (!(i&1023))
ffio_ensure_seekback(s->pb, i + 1024 + 4);
- if (check(s, off + i) >= 0) {
+ if (check(s->pb, off + i) >= 0) {
av_log(s, AV_LOG_INFO, "Skipping %d bytes of junk at %"PRId64".\n", i, off);
avio_seek(s->pb, off + i, SEEK_SET);
break;
@@ -396,73 +419,45 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
pkt->stream_index = 0;
- if (ret >= ID3v1_TAG_SIZE &&
- memcmp(&pkt->data[ret - ID3v1_TAG_SIZE], "TAG", 3) == 0)
- ret -= ID3v1_TAG_SIZE;
-
- /* note: we need to modify the packet size here to handle the last
- packet */
- pkt->size = ret;
return ret;
}
-static int check(AVFormatContext *s, int64_t pos)
+#define SEEK_WINDOW 4096
+
+static int check(AVIOContext *pb, int64_t pos)
{
- int64_t ret = avio_seek(s->pb, pos, SEEK_SET);
+ int64_t ret = avio_seek(pb, pos, SEEK_SET);
unsigned header;
MPADecodeHeader sd;
if (ret < 0)
return ret;
- header = avio_rb32(s->pb);
+
+ header = avio_rb32(pb);
if (ff_mpa_check_header(header) < 0)
return -1;
if (avpriv_mpegaudio_decode_header(&sd, header) == 1)
return -1;
+
return sd.frame_size;
}
-static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
- int flags)
+static int64_t mp3_sync(AVFormatContext *s, int64_t target_pos, int flags)
{
- MP3DecContext *mp3 = s->priv_data;
- AVIndexEntry *ie, ie1;
- AVStream *st = s->streams[0];
- int64_t ret = av_index_search_timestamp(st, timestamp, flags);
- int i, j;
int dir = (flags&AVSEEK_FLAG_BACKWARD) ? -1 : 1;
int64_t best_pos;
- int best_score;
+ int best_score, i, j;
+ int64_t ret;
- if (mp3->usetoc == 2)
- return -1; // generic index code
-
- if ( mp3->is_cbr
- && (mp3->usetoc == 0 || !mp3->xing_toc)
- && st->duration > 0
- && mp3->header_filesize > s->internal->data_offset) {
- ie = &ie1;
- timestamp = av_clip64(timestamp, 0, st->duration);
- ie->timestamp = timestamp;
- ie->pos = av_rescale(timestamp, mp3->header_filesize, st->duration) + s->internal->data_offset;
- } else if (mp3->xing_toc) {
- if (ret < 0)
- return ret;
-
- ie = &st->index_entries[ret];
- } else {
- return -1;
- }
-
- avio_seek(s->pb, FFMAX(ie->pos - 4096, 0), SEEK_SET);
- ret = avio_seek(s->pb, ie->pos, SEEK_SET);
+ avio_seek(s->pb, FFMAX(target_pos - SEEK_WINDOW, 0), SEEK_SET);
+ ret = avio_seek(s->pb, target_pos, SEEK_SET);
if (ret < 0)
return ret;
#define MIN_VALID 3
- best_pos = ie->pos;
+ best_pos = target_pos;
best_score = 999;
- for(i=0; i<4096; i++) {
- int64_t pos = ie->pos + (dir > 0 ? i - 1024 : -i);
+ for(i=0; i<SEEK_WINDOW; i++) {
+ int64_t pos = target_pos + (dir > 0 ? i - SEEK_WINDOW/4 : -i);
int64_t candidate = -1;
int score = 999;
@@ -470,10 +465,10 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
continue;
for(j=0; j<MIN_VALID; j++) {
- ret = check(s, pos);
+ ret = check(s->pb, pos);
if(ret < 0)
break;
- if ((ie->pos - pos)*dir <= 0 && abs(MIN_VALID/2-j) < score) {
+ if ((target_pos - pos)*dir <= 0 && abs(MIN_VALID/2-j) < score) {
candidate = pos;
score = abs(MIN_VALID/2-j);
}
@@ -487,11 +482,51 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
}
}
- ret = avio_seek(s->pb, best_pos, SEEK_SET);
- if (ret < 0)
- return ret;
+ return avio_seek(s->pb, best_pos, SEEK_SET);
+}
+
+static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
+ int flags)
+{
+ MP3DecContext *mp3 = s->priv_data;
+ AVIndexEntry *ie, ie1;
+ AVStream *st = s->streams[0];
+ int64_t ret = av_index_search_timestamp(st, timestamp, flags);
+ int64_t best_pos;
+ int fast_seek = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 1 : 0;
+ int64_t filesize = mp3->header_filesize;
+
+ if (mp3->usetoc == 2)
+ return -1; // generic index code
+
+ if (filesize <= 0) {
+ int64_t size = avio_size(s->pb);
+ if (size > 0 && size > s->internal->data_offset)
+ filesize = size - s->internal->data_offset;
+ }
+
+ if ( (mp3->is_cbr || fast_seek)
+ && (mp3->usetoc == 0 || !mp3->xing_toc)
+ && st->duration > 0
+ && filesize > 0) {
+ ie = &ie1;
+ timestamp = av_clip64(timestamp, 0, st->duration);
+ ie->timestamp = timestamp;
+ ie->pos = av_rescale(timestamp, filesize, st->duration) + s->internal->data_offset;
+ } else if (mp3->xing_toc) {
+ if (ret < 0)
+ return ret;
+
+ ie = &st->index_entries[ret];
+ } else {
+ return -1;
+ }
+
+ best_pos = mp3_sync(s, ie->pos, flags);
+ if (best_pos < 0)
+ return best_pos;
- if (mp3->is_cbr && ie == &ie1) {
+ if (mp3->is_cbr && ie == &ie1 && mp3->frames) {
int frame_duration = av_rescale(st->duration, 1, mp3->frames);
ie1.timestamp = frame_duration * av_rescale(best_pos - s->internal->data_offset, mp3->frames, mp3->header_filesize);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mpc8.c b/chromium/third_party/ffmpeg/libavformat/mpc8.c
index 0cef65ff7d0..bf597b88a58 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpc8.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpc8.c
@@ -154,7 +154,7 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off)
av_log(s, AV_LOG_ERROR, "Bad seek table size\n");
return;
}
- if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE)))
+ if(!(buf = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE)))
return;
ret = avio_read(s->pb, buf, size);
if (ret != size) {
@@ -162,7 +162,7 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off)
av_free(buf);
return;
}
- memset(buf+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(buf+size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
init_get_bits(&gb, buf, size * 8);
size = gb_get_v(&gb);
diff --git a/chromium/third_party/ffmpeg/libavformat/mpeg.c b/chromium/third_party/ffmpeg/libavformat/mpeg.c
index edb134f7405..223b6906d68 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpeg.c
@@ -612,7 +612,7 @@ found:
if (st->discard >= AVDISCARD_ALL)
goto skip;
if (startcode >= 0xa0 && startcode <= 0xaf) {
- if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) {
+ if (st->codec->codec_id == AV_CODEC_ID_MLP) {
if (len < 6)
goto skip;
avio_skip(s->pb, 6);
@@ -857,7 +857,7 @@ static int vobsub_read_header(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
vobsub->q[i].sort = SUB_SORT_POS_TS;
- ff_subtitles_queue_finalize(&vobsub->q[i]);
+ ff_subtitles_queue_finalize(s, &vobsub->q[i]);
}
if (!av_bprint_is_complete(&header)) {
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegenc.c b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
index 2520f49db19..b3ee2a09b9d 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
@@ -410,7 +410,9 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
stream->max_buffer_size = 16 * 1024;
break;
default:
- return -1;
+ av_log(ctx, AV_LOG_ERROR, "Invalid media type %s for output stream #%d\n",
+ av_get_media_type_string(st->codec->codec_type), i);
+ return AVERROR(EINVAL);
}
stream->fifo = av_fifo_alloc(16);
if (!stream->fifo)
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegts.c b/chromium/third_party/ffmpeg/libavformat/mpegts.c
index 84946e3cfd5..ed0a86b337d 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegts.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegts.c
@@ -21,6 +21,7 @@
#include "libavutil/buffer.h"
#include "libavutil/crc.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/dict.h"
@@ -161,19 +162,19 @@ struct MpegTSContext {
};
#define MPEGTS_OPTIONS \
- { "resync_size", "Size limit for looking up a new synchronization.", offsetof(MpegTSContext, resync_size), AV_OPT_TYPE_INT, { .i64 = MAX_RESYNC_SIZE}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }
+ { "resync_size", "set size limit for looking up a new synchronization", offsetof(MpegTSContext, resync_size), AV_OPT_TYPE_INT, { .i64 = MAX_RESYNC_SIZE}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }
static const AVOption options[] = {
MPEGTS_OPTIONS,
- {"fix_teletext_pts", "Try to fix pts values of dvb teletext streams.", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT,
+ {"fix_teletext_pts", "try to fix pts values of dvb teletext streams", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT,
{.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
- {"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
+ {"ts_packetsize", "output option carrying the raw packet size", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
- {"scan_all_pmts", "Scan and combine all PMTs", offsetof(MpegTSContext, scan_all_pmts), AV_OPT_TYPE_INT,
+ {"scan_all_pmts", "scan and combine all PMTs", offsetof(MpegTSContext, scan_all_pmts), AV_OPT_TYPE_INT,
{ .i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM },
- {"skip_changes", "Skip changing / adding streams / programs.", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_INT,
+ {"skip_changes", "skip changing / adding streams / programs", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 1, 0 },
- {"skip_clear", "Skip clearing programs.", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_INT,
+ {"skip_clear", "skip clearing programs", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 1, 0 },
{ NULL },
};
@@ -187,10 +188,10 @@ static const AVClass mpegts_class = {
static const AVOption raw_options[] = {
MPEGTS_OPTIONS,
- { "compute_pcr", "Compute exact PCR for each transport stream packet.",
+ { "compute_pcr", "compute exact PCR for each transport stream packet",
offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
{ .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
- { "ts_packetsize", "Output option carrying the raw packet size.",
+ { "ts_packetsize", "output option carrying the raw packet size",
offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
{ .i64 = 0 }, 0, 0,
AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
@@ -698,6 +699,7 @@ static const StreamType ISO_types[] = {
#endif
{ 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 },
{ 0x20, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 },
+ { 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 },
{ 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC },
{ 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS },
{ 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
@@ -716,6 +718,7 @@ static const StreamType HDMV_types[] = {
{ 0xa1, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, /* E-AC3 Secondary Audio */
{ 0xa2, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS Express Secondary Audio */
{ 0x90, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_PGS_SUBTITLE },
+ { 0x92, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_TEXT_SUBTITLE },
{ 0 },
};
@@ -838,7 +841,7 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
if ((st->codec->codec_id == AV_CODEC_ID_NONE ||
(st->request_probe > 0 && st->request_probe < AVPROBE_SCORE_STREAM_RETRY / 5)) &&
!avcodec_is_open(st->codec) &&
- stream_type == 6) {
+ stream_type == STREAM_TYPE_PRIVATE_DATA) {
st->codec->codec_type = AVMEDIA_TYPE_DATA;
st->codec->codec_id = AV_CODEC_ID_BIN_DATA;
st->request_probe = AVPROBE_SCORE_STREAM_RETRY / 5;
@@ -870,7 +873,7 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n");
pes->flags |= AV_PKT_FLAG_CORRUPT;
}
- memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
// Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID
if (pes->sub_st && pes->stream_type == 0x83 && pes->extended_stream_id == 0x76)
@@ -902,8 +905,8 @@ static int read_sl_header(PESContext *pes, SLConfigDescr *sl,
int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0;
int dts_flag = -1, cts_flag = -1;
int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE;
- uint8_t buf_padded[128 + FF_INPUT_BUFFER_PADDING_SIZE];
- int buf_padded_size = FFMIN(buf_size, sizeof(buf_padded) - FF_INPUT_BUFFER_PADDING_SIZE);
+ uint8_t buf_padded[128 + AV_INPUT_BUFFER_PADDING_SIZE];
+ int buf_padded_size = FFMIN(buf_size, sizeof(buf_padded) - AV_INPUT_BUFFER_PADDING_SIZE);
memcpy(buf_padded, buf, buf_padded_size);
@@ -1035,7 +1038,7 @@ static int mpegts_push_data(MpegTSFilter *filter,
/* allocate pes buffer */
pes->buffer = av_buffer_alloc(pes->total_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!pes->buffer)
return AVERROR(ENOMEM);
@@ -1052,6 +1055,7 @@ static int mpegts_push_data(MpegTSFilter *filter,
pes->st->request_probe = 1;
}
} else {
+ pes->pes_header_size = 6;
pes->state = MPEGTS_PAYLOAD;
pes->data_index = 0;
}
@@ -1139,7 +1143,10 @@ skip:
p += 5;
buf_size -= 5;
}
- if (pes->ts->fix_teletext_pts && pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+ if ( pes->ts->fix_teletext_pts
+ && ( pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT
+ || pes->st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
+ ) {
AVProgram *p = NULL;
while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) {
if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) {
@@ -1168,7 +1175,11 @@ skip:
pes->st->pts_wrap_behavior = st->pts_wrap_behavior;
if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) {
pes->pts = pes->dts = pcr;
- } else if (pes->dts > pcr + 3654 + 9000) {
+ } else if (pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT &&
+ pes->dts > pcr + 3654 + 9000) {
+ pes->pts = pes->dts = pcr + 3654 + 9000;
+ } else if (pes->st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE &&
+ pes->dts > pcr + 10*90000) { //10sec
pes->pts = pes->dts = pcr + 3654 + 9000;
}
break;
@@ -1186,7 +1197,7 @@ skip:
new_pes_packet(pes, ts->pkt);
pes->total_size = MAX_PES_PAYLOAD;
pes->buffer = av_buffer_alloc(pes->total_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!pes->buffer)
return AVERROR(ENOMEM);
ts->stop_parse = 1;
@@ -1643,9 +1654,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
if (language_count > 0) {
/* 4 bytes per language code (3 bytes) with comma or NUL byte should fit language buffer */
- if (language_count > sizeof(language) / 4) {
- language_count = sizeof(language) / 4;
- }
+ av_assert0(language_count <= sizeof(language) / 4);
if (st->codec->extradata == NULL) {
if (ff_alloc_extradata(st->codec, language_count * 2)) {
@@ -1695,9 +1704,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
uint8_t *extradata;
/* 4 bytes per language code (3 bytes) with comma or NUL byte should fit language buffer */
- if (language_count > sizeof(language) / 4) {
- language_count = sizeof(language) / 4;
- }
+ av_assert0(language_count <= sizeof(language) / 4);
if (st->codec->extradata == NULL) {
if (ff_alloc_extradata(st->codec, language_count * 5)) {
@@ -1789,7 +1796,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
ext_desc_tag == 0x80) { /* User defined (provisional Opus) */
if (!st->codec->extradata) {
st->codec->extradata = av_mallocz(sizeof(opus_default_extradata) +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
@@ -2378,7 +2385,7 @@ static void finished_reading_packet(AVFormatContext *s, int raw_packet_size)
static int handle_packets(MpegTSContext *ts, int64_t nb_packets)
{
AVFormatContext *s = ts->stream;
- uint8_t packet[TS_PACKET_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
+ uint8_t packet[TS_PACKET_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
const uint8_t *data;
int64_t packet_num;
int ret = 0;
@@ -2405,7 +2412,7 @@ static int handle_packets(MpegTSContext *ts, int64_t nb_packets)
ts->stop_parse = 0;
packet_num = 0;
- memset(packet + TS_PACKET_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(packet + TS_PACKET_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
for (;;) {
packet_num++;
if (nb_packets != 0 && packet_num >= nb_packets ||
@@ -2439,7 +2446,7 @@ static int mpegts_probe(AVProbeData *p)
#define CHECK_BLOCK 100
if (check_count < CHECK_COUNT)
- return AVERROR_INVALIDDATA;
+ return 0;
for (i = 0; i<check_count; i+=CHECK_BLOCK) {
int left = FFMIN(check_count - i, CHECK_BLOCK);
@@ -2454,12 +2461,12 @@ static int mpegts_probe(AVProbeData *p)
sumscore = sumscore * CHECK_COUNT / check_count;
maxscore = maxscore * CHECK_COUNT / CHECK_BLOCK;
- av_dlog(0, "TS score: %d %d\n", sumscore, maxscore);
+ ff_dlog(0, "TS score: %d %d\n", sumscore, maxscore);
if (sumscore > 6) return AVPROBE_SCORE_MAX + sumscore - CHECK_COUNT;
else if (maxscore > 6) return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;
else
- return AVERROR_INVALIDDATA;
+ return 0;
}
/* return the 90kHz PCR and the extension for the 27MHz PCR. return
@@ -2505,7 +2512,12 @@ static int mpegts_read_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
uint8_t buf[8 * 1024] = {0};
int len;
- int64_t pos, probesize = s->probesize ? s->probesize : s->probesize2;
+ int64_t pos, probesize =
+#if FF_API_PROBESIZE_32
+ s->probesize ? s->probesize : s->probesize2;
+#else
+ s->probesize;
+#endif
if (ffio_ensure_seekback(pb, probesize) < 0)
av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
index 9efa9fc3624..45bab1ce01a 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
@@ -98,9 +98,14 @@ typedef struct MpegTSWrite {
int pcr_period;
#define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01
#define MPEGTS_FLAG_AAC_LATM 0x02
+#define MPEGTS_FLAG_PAT_PMT_AT_FRAMES 0x04
int flags;
int copyts;
int tables_version;
+ float pat_period;
+ float sdt_period;
+ int64_t last_pat_ts;
+ int64_t last_sdt_ts;
int omit_video_pes_length;
} MpegTSWrite;
@@ -783,6 +788,16 @@ static int mpegts_write_header(AVFormatContext *s)
service->pcr_packet_period = 1;
}
+ ts->last_pat_ts = AV_NOPTS_VALUE;
+ ts->last_sdt_ts = AV_NOPTS_VALUE;
+ // The user specified a period, use only it
+ if (ts->pat_period < INT_MAX/2) {
+ ts->pat_packet_period = INT_MAX;
+ }
+ if (ts->sdt_period < INT_MAX/2) {
+ ts->sdt_packet_period = INT_MAX;
+ }
+
// output a PCR as soon as possible
service->pcr_packet_count = service->pcr_packet_period;
ts->pat_packet_count = ts->pat_packet_period - 1;
@@ -833,17 +848,27 @@ fail:
}
/* send SDT, PAT and PMT tables regulary */
-static void retransmit_si_info(AVFormatContext *s, int force_pat)
+static void retransmit_si_info(AVFormatContext *s, int force_pat, int64_t dts)
{
MpegTSWrite *ts = s->priv_data;
int i;
- if (++ts->sdt_packet_count == ts->sdt_packet_period) {
+ if (++ts->sdt_packet_count == ts->sdt_packet_period ||
+ (dts != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
+ (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0)
+ ) {
ts->sdt_packet_count = 0;
+ if (dts != AV_NOPTS_VALUE)
+ ts->last_sdt_ts = FFMAX(dts, ts->last_sdt_ts);
mpegts_write_sdt(s);
}
- if (++ts->pat_packet_count == ts->pat_packet_period || force_pat) {
+ if (++ts->pat_packet_count == ts->pat_packet_period ||
+ (dts != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
+ (dts != AV_NOPTS_VALUE && dts - ts->last_pat_ts >= ts->pat_period*90000.0) ||
+ force_pat) {
ts->pat_packet_count = 0;
+ if (dts != AV_NOPTS_VALUE)
+ ts->last_pat_ts = FFMAX(dts, ts->last_pat_ts);
mpegts_write_pat(s);
for (i = 0; i < ts->nb_services; i++)
mpegts_write_pmt(s, ts->services[i]);
@@ -971,9 +996,14 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
int force_pat = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
+ av_assert0(ts_st->payload != buf || st->codec->codec_type != AVMEDIA_TYPE_VIDEO);
+ if (ts->flags & MPEGTS_FLAG_PAT_PMT_AT_FRAMES && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ force_pat = 1;
+ }
+
is_start = 1;
while (payload_size > 0) {
- retransmit_si_info(s, force_pat);
+ retransmit_si_info(s, force_pat, dts);
force_pat = 0;
write_pcr = 0;
@@ -1313,9 +1343,9 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
if (!ts_st->amux) {
av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format "
"and extradata missing\n");
- return AVERROR_INVALIDDATA;
- }
-
+ if (!st->nb_frames)
+ return AVERROR_INVALIDDATA;
+ } else {
av_init_packet(&pkt2);
pkt2.data = pkt->data;
pkt2.size = pkt->size;
@@ -1334,6 +1364,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
size = avio_close_dyn_buf(ts_st->amux->pb, &data);
ts_st->amux->pb = NULL;
buf = data;
+ }
}
} else if (st->codec->codec_id == AV_CODEC_ID_HEVC) {
int ret = check_hevc_startcode(s, st, pkt);
@@ -1504,6 +1535,9 @@ static const AVOption options[] = {
{ "latm", "Use LATM packetization for AAC",
0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_AAC_LATM }, 0, INT_MAX,
AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
+ { "pat_pmt_at_frames", "Reemit PAT and PMT at each video frame",
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_PAT_PMT_AT_FRAMES}, 0, INT_MAX,
+ AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
// backward compatibility
{ "resend_headers", "Reemit PAT/PMT before writing the next packet",
offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT,
@@ -1520,6 +1554,12 @@ static const AVOption options[] = {
{ "pcr_period", "PCR retransmission time",
offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT,
{ .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { "pat_period", "PAT/PMT retransmission time limit in seconds",
+ offsetof(MpegTSWrite, pat_period), AV_OPT_TYPE_FLOAT,
+ { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { "sdt_period", "SDT retransmission time limit in seconds",
+ offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_FLOAT,
+ { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -1541,6 +1581,6 @@ AVOutputFormat ff_mpegts_muxer = {
.write_header = mpegts_write_header,
.write_packet = mpegts_write_packet,
.write_trailer = mpegts_write_end,
- .flags = AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_ALLOW_FLUSH | AVFMT_VARIABLE_FPS,
.priv_class = &mpegts_muxer_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/mpjpeg.c b/chromium/third_party/ffmpeg/libavformat/mpjpeg.c
index 7b975e28d6c..3904ccb2b43 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpjpeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpjpeg.c
@@ -33,10 +33,7 @@ typedef struct MPJPEGContext {
static int mpjpeg_write_header(AVFormatContext *s)
{
MPJPEGContext *mpj = s->priv_data;
- uint8_t buf1[256];
-
- snprintf(buf1, sizeof(buf1), "--%s\r\n", mpj->boundary_tag);
- avio_write(s->pb, buf1, strlen(buf1));
+ avio_printf(s->pb, "--%s\r\n", mpj->boundary_tag);
avio_flush(s->pb);
return 0;
}
@@ -44,17 +41,12 @@ static int mpjpeg_write_header(AVFormatContext *s)
static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
{
MPJPEGContext *mpj = s->priv_data;
- uint8_t buf1[256];
-
- snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\r\n");
- avio_write(s->pb, buf1, strlen(buf1));
-
- snprintf(buf1, sizeof(buf1), "Content-length: %d\r\n\r\n", pkt->size);
- avio_write(s->pb, buf1, strlen(buf1));
+ avio_printf(s->pb, "Content-type: image/jpeg\r\n");
+ avio_printf(s->pb, "Content-length: %d\r\n\r\n",
+ pkt->size);
avio_write(s->pb, pkt->data, pkt->size);
- snprintf(buf1, sizeof(buf1), "\r\n--%s\r\n", mpj->boundary_tag);
- avio_write(s->pb, buf1, strlen(buf1));
+ avio_printf(s->pb, "\r\n--%s\r\n", mpj->boundary_tag);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mpjpegdec.c b/chromium/third_party/ffmpeg/libavformat/mpjpegdec.c
index 845e95cb744..d9553040e85 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpjpegdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpjpegdec.c
@@ -40,6 +40,19 @@ static int get_line(AVIOContext *pb, char *line, int line_size)
return 0;
}
+
+static void trim_right(char* p)
+{
+ char *end;
+ if (!p || !*p)
+ return;
+ end = p + strlen(p) - 1;
+ while (end != p && av_isspace(*end)) {
+ *end = '\0';
+ end--;
+ }
+}
+
static int split_tag_value(char **tag, char **value, char *line)
{
char *p = line;
@@ -51,6 +64,7 @@ static int split_tag_value(char **tag, char **value, char *line)
*p = '\0';
*tag = line;
+ trim_right(*tag);
p++;
@@ -58,6 +72,7 @@ static int split_tag_value(char **tag, char **value, char *line)
p++;
*value = p;
+ trim_right(*value);
return 0;
}
@@ -77,6 +92,8 @@ static int check_content_type(char *line)
return 0;
}
+static int parse_multipart_header(AVIOContext *pb, void *log_ctx);
+
static int mpjpeg_read_probe(AVProbeData *p)
{
AVIOContext *pb;
@@ -90,17 +107,7 @@ static int mpjpeg_read_probe(AVProbeData *p)
if (!pb)
return AVERROR(ENOMEM);
- while (!pb->eof_reached) {
- ret = get_line(pb, line, sizeof(line));
- if (ret < 0)
- break;
-
- ret = check_content_type(line);
- if (!ret) {
- ret = AVPROBE_SCORE_MAX;
- break;
- }
- }
+ ret = (parse_multipart_header(pb, NULL)>0)?AVPROBE_SCORE_MAX:0;
av_free(pb);
@@ -123,6 +130,8 @@ static int mpjpeg_read_header(AVFormatContext *s)
return AVERROR_INVALIDDATA;
st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = AV_CODEC_ID_MJPEG;
@@ -145,25 +154,28 @@ static int parse_content_length(const char *value)
return val;
}
-static int parse_multipart_header(AVFormatContext *s)
+static int parse_multipart_header(AVIOContext *pb, void *log_ctx)
{
char line[128];
int found_content_type = 0;
int ret, size = -1;
- ret = get_line(s->pb, line, sizeof(line));
+ ret = get_line(pb, line, sizeof(line));
if (ret < 0)
return ret;
if (strncmp(line, "--", 2))
return AVERROR_INVALIDDATA;
- while (!s->pb->eof_reached) {
+ while (!pb->eof_reached) {
char *tag, *value;
- ret = get_line(s->pb, line, sizeof(line));
- if (ret < 0)
+ ret = get_line(pb, line, sizeof(line));
+ if (ret < 0) {
+ if (ret == AVERROR_EOF)
+ break;
return ret;
+ }
if (line[0] == '\0')
break;
@@ -174,9 +186,12 @@ static int parse_multipart_header(AVFormatContext *s)
if (!av_strcasecmp(tag, "Content-type")) {
if (av_strcasecmp(value, "image/jpeg")) {
- av_log(s, AV_LOG_ERROR,
- "Unexpected %s : %s\n",
- tag, value);
+ if (log_ctx) {
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Unexpected %s : %s\n",
+ tag, value);
+ }
+
return AVERROR_INVALIDDATA;
} else
found_content_type = 1;
@@ -197,7 +212,7 @@ static int parse_multipart_header(AVFormatContext *s)
static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret;
- int size = parse_multipart_header(s);
+ int size = parse_multipart_header(s->pb, s);
if (size < 0)
return size;
diff --git a/chromium/third_party/ffmpeg/libavformat/mpl2dec.c b/chromium/third_party/ffmpeg/libavformat/mpl2dec.c
index 260b7be0ecd..81cc0bbb2d9 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpl2dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpl2dec.c
@@ -108,7 +108,7 @@ static int mpl2_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&mpl2->q);
+ ff_subtitles_queue_finalize(s, &mpl2->q);
return res;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mpsubdec.c b/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
index 7c26d4f42ce..c5a50ecb5cf 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
@@ -103,7 +103,7 @@ static int mpsub_read_header(AVFormatContext *s)
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id = AV_CODEC_ID_TEXT;
- ff_subtitles_queue_finalize(&mpsub->q);
+ ff_subtitles_queue_finalize(s, &mpsub->q);
end:
av_bprint_finalize(&buf, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/msnwc_tcp.c b/chromium/third_party/ffmpeg/libavformat/msnwc_tcp.c
index 60225af61cd..2ec18fb5542 100644
--- a/chromium/third_party/ffmpeg/libavformat/msnwc_tcp.c
+++ b/chromium/third_party/ffmpeg/libavformat/msnwc_tcp.c
@@ -67,7 +67,7 @@ static int msnwc_tcp_probe(AVProbeData *p)
}
}
- return -1;
+ return 0;
}
static int msnwc_tcp_read_header(AVFormatContext *ctx)
diff --git a/chromium/third_party/ffmpeg/libavformat/mux.c b/chromium/third_party/ffmpeg/libavformat/mux.c
index f1d7927b8ea..3856d8271a4 100644
--- a/chromium/third_party/ffmpeg/libavformat/mux.c
+++ b/chromium/third_party/ffmpeg/libavformat/mux.c
@@ -61,7 +61,7 @@
* @param num must be >= 0
* @param den must be >= 1
*/
-static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
+static void frac_init(FFFrac *f, int64_t val, int64_t num, int64_t den)
{
num += (den >> 1);
if (num >= den) {
@@ -79,7 +79,7 @@ static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
* @param f fractional number
* @param incr increment, can be positive or negative
*/
-static void frac_add(AVFrac *f, int64_t incr)
+static void frac_add(FFFrac *f, int64_t incr)
{
int64_t num, den;
@@ -250,10 +250,23 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
(ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
goto fail;
+ if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) {
+ if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
#if FF_API_LAVF_BITEXACT
- if (s->nb_streams && s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)
- s->flags |= AVFMT_FLAG_BITEXACT;
+ av_log(s, AV_LOG_WARNING,
+ "Setting the AVFormatContext to bitexact mode, because "
+ "the AVCodecContext is in that mode. This behavior will "
+ "change in the future. To keep the current behavior, set "
+ "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");
+ s->flags |= AVFMT_FLAG_BITEXACT;
+#else
+ av_log(s, AV_LOG_WARNING,
+ "The AVFormatContext is not in set to bitexact mode, only "
+ "the AVCodecContext. If this is not intended, set "
+ "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");
#endif
+ }
+ }
// some sanity checks
if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
@@ -348,7 +361,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
if (of->flags & AVFMT_GLOBALHEADER &&
- !(codec->flags & CODEC_FLAG_GLOBAL_HEADER))
+ !(codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER))
av_log(s, AV_LOG_WARNING,
"Codec for stream %d does not use global headers "
"but container format requires global headers\n", i);
@@ -414,13 +427,19 @@ static int init_pts(AVFormatContext *s)
default:
break;
}
+
+ if (!st->priv_pts)
+ st->priv_pts = av_mallocz(sizeof(*st->priv_pts));
+ if (!st->priv_pts)
+ return AVERROR(ENOMEM);
+
if (den != AV_NOPTS_VALUE) {
if (den <= 0)
return AVERROR_INVALIDDATA;
#if FF_API_LAVF_FRAC
FF_DISABLE_DEPRECATION_WARNINGS
- frac_init(&st->pts, 0, 0, den);
+ frac_init(st->priv_pts, 0, 0, den);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
@@ -508,7 +527,7 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
FF_DISABLE_DEPRECATION_WARNINGS
pkt->dts =
// pkt->pts= st->cur_dts;
- pkt->pts = st->pts.val;
+ pkt->pts = st->priv_pts->val;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
@@ -548,7 +567,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
st->cur_dts = pkt->dts;
#if FF_API_LAVF_FRAC
FF_DISABLE_DEPRECATION_WARNINGS
- st->pts.val = pkt->dts;
+ st->priv_pts->val = pkt->dts;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
@@ -564,8 +583,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
* had the real timestamps from the encoder */
#if FF_API_LAVF_FRAC
FF_DISABLE_DEPRECATION_WARNINGS
- if (frame_size >= 0 && (pkt->size || st->pts.num != st->pts.den >> 1 || st->pts.val)) {
- frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
+ if (frame_size >= 0 && (pkt->size || st->priv_pts->num != st->priv_pts->den >> 1 || st->priv_pts->val)) {
+ frac_add(st->priv_pts, (int64_t)st->time_base.den * frame_size);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
@@ -573,7 +592,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
case AVMEDIA_TYPE_VIDEO:
#if FF_API_LAVF_FRAC
FF_DISABLE_DEPRECATION_WARNINGS
- frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
+ frac_add(st->priv_pts, (int64_t)st->time_base.den * st->codec->time_base.num);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
break;
@@ -661,8 +680,13 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
ret = s->oformat->write_packet(s, pkt);
}
- if (s->flush_packets && s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
- avio_flush(s->pb);
+ if (s->pb && ret >= 0) {
+ if (s->flush_packets && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
+ avio_flush(s->pb);
+ if (s->pb->error < 0)
+ ret = s->pb->error;
+ }
+
if (did_split)
av_packet_merge_side_data(pkt);
@@ -737,11 +761,6 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
if (!this_pktl)
return AVERROR(ENOMEM);
this_pktl->pkt = *pkt;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = NULL; // do not free original but only the copy
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
pkt->buf = NULL;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
@@ -1065,7 +1084,8 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
pkt->buf = local_pkt.buf;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = local_pkt.destruct;
+ pkt->side_data = local_pkt.side_data;
+ pkt->side_data_elems = local_pkt.side_data_elems;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
return ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/mxf.c b/chromium/third_party/ffmpeg/libavformat/mxf.c
index ecfb8a23933..4d77ada71e9 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxf.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxf.c
@@ -42,6 +42,16 @@ const MXFCodecUL ff_mxf_codec_uls[] = {
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14, AV_CODEC_ID_MPEG4 }, /* XDCAM proxy_pal030926.mxf */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13, AV_CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x01,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 SP@LL */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x02,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 SP@ML */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x03,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 MP@LL */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x04,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 MP@ML */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x05,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 MP@HL */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x06,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L0 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x07,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L1 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x08,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L2 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x09,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L3 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x0A,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L4 */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, 15, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed 422 8-bit */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x71,0x00,0x00,0x00 }, 13, AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
@@ -69,6 +79,11 @@ const MXFCodecUL ff_mxf_pixel_format_uls[] = {
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_PIX_FMT_NONE },
};
+const MXFCodecUL ff_mxf_codec_tag_uls[] = {
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0E,0x04,0x03,0x01,0x01,0x03,0x01,0x00 }, 15, MKTAG('A', 'V', 'u', 'p') }, /* Avid 1:1 */
+ { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 },
+};
+
static const struct {
enum AVPixelFormat pix_fmt;
const char data[16];
diff --git a/chromium/third_party/ffmpeg/libavformat/mxf.h b/chromium/third_party/ffmpeg/libavformat/mxf.h
index 1763063a695..f3db1f939bb 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxf.h
+++ b/chromium/third_party/ffmpeg/libavformat/mxf.h
@@ -78,6 +78,7 @@ typedef struct {
extern const MXFCodecUL ff_mxf_data_definition_uls[];
extern const MXFCodecUL ff_mxf_codec_uls[];
extern const MXFCodecUL ff_mxf_pixel_format_uls[];
+extern const MXFCodecUL ff_mxf_codec_tag_uls[];
int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt);
const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base);
diff --git a/chromium/third_party/ffmpeg/libavformat/mxfdec.c b/chromium/third_party/ffmpeg/libavformat/mxfdec.c
index b3c25b765e5..00d420b4450 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxfdec.c
@@ -233,6 +233,7 @@ typedef struct MXFIndexTable {
int nb_segments;
MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */
AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */
+ int8_t *offsets; /* temporal offsets for display order to stored order conversion */
} MXFIndexTable;
typedef struct MXFContext {
@@ -1120,7 +1121,11 @@ static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMe
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
// video essence container uls
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000 },
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x10,0x60,0x01 }, 14, AV_CODEC_ID_H264 }, /* H264 Frame wrapped */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x12,0x01,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC-1 Frame wrapped */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MPEG-ES Frame wrapped */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* Type D-10 mapping of 40Mbps 525/60-I */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO }, /* DV 625 25mbps */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed Picture */
{ { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14, AV_CODEC_ID_RAWVIDEO }, /* Legacy ?? Uncompressed Picture */
@@ -1155,11 +1160,6 @@ static const MXFCodecUL mxf_data_essence_container_uls[] = {
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
};
-static const MXFCodecUL mxf_codec_uls[] = {
- { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000 },
- { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
-};
-
static const char* const mxf_data_essence_descriptor[] = {
"vbi_vanc_smpte_436M",
};
@@ -1334,6 +1334,7 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
{
int i, j, x;
int8_t max_temporal_offset = -128;
+ uint8_t *flags;
/* first compute how many entries we have */
for (i = 0; i < index_table->nb_segments; i++) {
@@ -1352,8 +1353,12 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
return 0;
if (!(index_table->ptses = av_calloc(index_table->nb_ptses, sizeof(int64_t))) ||
- !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry)))) {
+ !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry))) ||
+ !(index_table->offsets = av_calloc(index_table->nb_ptses, sizeof(int8_t))) ||
+ !(flags = av_calloc(index_table->nb_ptses, sizeof(uint8_t)))) {
av_freep(&index_table->ptses);
+ av_freep(&index_table->fake_index);
+ av_freep(&index_table->offsets);
return AVERROR(ENOMEM);
}
@@ -1411,8 +1416,7 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
break;
}
- index_table->fake_index[x].timestamp = x;
- index_table->fake_index[x].flags = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0;
+ flags[x] = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0;
if (index < 0 || index >= index_table->nb_ptses) {
av_log(mxf->fc, AV_LOG_ERROR,
@@ -1421,11 +1425,20 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
continue;
}
+ index_table->offsets[x] = offset;
index_table->ptses[index] = x;
max_temporal_offset = FFMAX(max_temporal_offset, offset);
}
}
+ /* calculate the fake index table in display order */
+ for (x = 0; x < index_table->nb_ptses; x++) {
+ index_table->fake_index[x].timestamp = x;
+ if (index_table->ptses[x] != AV_NOPTS_VALUE)
+ index_table->fake_index[index_table->ptses[x]].flags = flags[x];
+ }
+ av_freep(&flags);
+
index_table->first_dts = -max_temporal_offset;
return 0;
@@ -1960,7 +1973,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
st->codec->codec_id = (enum AVCodecID)codec_ul->id;
if (st->codec->codec_id == AV_CODEC_ID_NONE) {
- codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->codec_ul);
+ codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->codec_ul);
st->codec->codec_id = (enum AVCodecID)codec_ul->id;
}
@@ -1988,10 +2001,6 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st->codec->width = descriptor->width;
st->codec->height = descriptor->height; /* Field height, not frame height */
switch (descriptor->frame_layout) {
- case SegmentedFrame:
- /* This one is a weird layout I don't fully understand. */
- av_log(mxf->fc, AV_LOG_INFO, "SegmentedFrame layout isn't currently supported\n");
- break;
case FullFrame:
st->codec->field_order = AV_FIELD_PROGRESSIVE;
break;
@@ -2003,6 +2012,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
It's also for compatibility with the old behavior. */
case MixedFields:
break;
+ case SegmentedFrame:
+ st->codec->field_order = AV_FIELD_PROGRESSIVE;
case SeparateFields:
switch (descriptor->field_dominance) {
case MXF_TFF:
@@ -2031,12 +2042,16 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
&descriptor->essence_codec_ul);
st->codec->pix_fmt = (enum AVPixelFormat)pix_fmt_ul->id;
if (st->codec->pix_fmt == AV_PIX_FMT_NONE) {
- /* support files created before RP224v10 by defaulting to UYVY422
- if subsampling is 4:2:2 and component depth is 8-bit */
- if (descriptor->horiz_subsampling == 2 &&
- descriptor->vert_subsampling == 1 &&
- descriptor->component_depth == 8) {
- st->codec->pix_fmt = AV_PIX_FMT_UYVY422;
+ st->codec->codec_tag = mxf_get_codec_ul(ff_mxf_codec_tag_uls,
+ &descriptor->essence_codec_ul)->id;
+ if (!st->codec->codec_tag) {
+ /* support files created before RP224v10 by defaulting to UYVY422
+ if subsampling is 4:2:2 and component depth is 8-bit */
+ if (descriptor->horiz_subsampling == 2 &&
+ descriptor->vert_subsampling == 1 &&
+ descriptor->component_depth == 8) {
+ st->codec->pix_fmt = AV_PIX_FMT_UYVY422;
+ }
}
}
}
@@ -3085,6 +3100,7 @@ static int mxf_read_close(AVFormatContext *s)
av_freep(&mxf->index_tables[i].segments);
av_freep(&mxf->index_tables[i].ptses);
av_freep(&mxf->index_tables[i].fake_index);
+ av_freep(&mxf->index_tables[i].offsets);
}
}
av_freep(&mxf->index_tables);
@@ -3158,6 +3174,8 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
/* behave as if we have a proper index */
if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0)
return sample_time;
+ /* get the stored order index from the display order index */
+ sample_time += t->offsets[sample_time];
} else {
/* no IndexEntryArray (one or more CBR segments)
* make sure we don't seek past the end */
@@ -3191,6 +3209,7 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
AVInputFormat ff_mxf_demuxer = {
.name = "mxf",
.long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
+ .flags = AVFMT_SEEK_TO_PTS,
.priv_data_size = sizeof(MXFContext),
.read_probe = mxf_probe,
.read_header = mxf_read_header,
diff --git a/chromium/third_party/ffmpeg/libavformat/mxfenc.c b/chromium/third_party/ffmpeg/libavformat/mxfenc.c
index db7d2bf4552..84ce979c610 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxfenc.c
@@ -21,6 +21,10 @@
*/
/*
+ * signal_standard, color_siting and klv_fill_key version fixes sponsored by NOA GmbH
+ */
+
+/*
* References
* SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
* SMPTE 377M MXF File Format Specifications
@@ -2056,7 +2060,7 @@ static int mxf_write_header(AVFormatContext *s)
sc->color_siting = 0xFF;
if (pix_desc) {
- sc->component_depth = pix_desc->comp[0].depth_minus1 + 1;
+ sc->component_depth = pix_desc->comp[0].depth;
sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w;
}
switch (ff_choose_chroma_location(s, st)) {
diff --git a/chromium/third_party/ffmpeg/libavformat/mxg.c b/chromium/third_party/ffmpeg/libavformat/mxg.c
index 34977b8197d..45cc5b5284c 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxg.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxg.c
@@ -111,7 +111,7 @@ static int mxg_update_cache(AVFormatContext *s, unsigned int cache_size)
soi_pos = mxg->soi_ptr - mxg->buffer;
buffer = av_fast_realloc(mxg->buffer, &mxg->buffer_size,
current_pos + cache_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!buffer)
return AVERROR(ENOMEM);
mxg->buffer = buffer;
@@ -171,18 +171,13 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pts = pkt->dts = mxg->dts;
pkt->stream_index = 0;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
pkt->buf = NULL;
pkt->size = mxg->buffer_ptr - mxg->soi_ptr;
pkt->data = mxg->soi_ptr;
if (mxg->soi_ptr - mxg->buffer > mxg->cache_size) {
if (mxg->cache_size > 0) {
- memcpy(mxg->buffer, mxg->buffer_ptr, mxg->cache_size);
+ memmove(mxg->buffer, mxg->buffer_ptr, mxg->cache_size);
}
mxg->buffer_ptr = mxg->buffer;
@@ -214,11 +209,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
/* time (GMT) of first sample in usec since 1970, little-endian */
pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8);
pkt->stream_index = 1;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
pkt->buf = NULL;
pkt->size = size - 14;
pkt->data = startmarker_ptr + 16;
diff --git a/chromium/third_party/ffmpeg/libavformat/network.c b/chromium/third_party/ffmpeg/libavformat/network.c
index 47ade8cb62f..7a326d2c4e1 100644
--- a/chromium/third_party/ffmpeg/libavformat/network.c
+++ b/chromium/third_party/ffmpeg/libavformat/network.c
@@ -187,12 +187,11 @@ int ff_socket(int af, int type, int proto)
return fd;
}
-int ff_listen_bind(int fd, const struct sockaddr *addr,
- socklen_t addrlen, int timeout, URLContext *h)
+int ff_listen(int fd, const struct sockaddr *addr,
+ socklen_t addrlen)
{
int ret;
int reuse = 1;
- struct pollfd lp = { fd, POLLIN, 0 };
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
}
@@ -203,6 +202,13 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
ret = listen(fd, 1);
if (ret)
return ff_neterrno();
+ return ret;
+}
+
+int ff_accept(int fd, int timeout, URLContext *h)
+{
+ int ret;
+ struct pollfd lp = { fd, POLLIN, 0 };
ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
if (ret < 0)
@@ -211,15 +217,24 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
ret = accept(fd, NULL, NULL);
if (ret < 0)
return ff_neterrno();
-
- closesocket(fd);
-
if (ff_socket_nonblock(ret, 1) < 0)
av_log(NULL, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
return ret;
}
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout, URLContext *h)
+{
+ int ret;
+ if ((ret = ff_listen(fd, addr, addrlen)) < 0)
+ return ret;
+ if ((ret = ff_accept(fd, timeout, h)) < 0)
+ return ret;
+ closesocket(fd);
+ return ret;
+}
+
int ff_listen_connect(int fd, const struct sockaddr *addr,
socklen_t addrlen, int timeout, URLContext *h,
int will_try_next)
diff --git a/chromium/third_party/ffmpeg/libavformat/network.h b/chromium/third_party/ffmpeg/libavformat/network.h
index 86fb6561647..f83c796a95a 100644
--- a/chromium/third_party/ffmpeg/libavformat/network.h
+++ b/chromium/third_party/ffmpeg/libavformat/network.h
@@ -255,6 +255,26 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
URLContext *h);
/**
+ * Bind to a file descriptor to an address without accepting connections.
+ * @param fd First argument of bind().
+ * @param addr Second argument of bind().
+ * @param addrlen Third argument of bind().
+ * @return 0 on success or an AVERROR on failure.
+ */
+int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+/**
+ * Poll for a single connection on the passed file descriptor.
+ * @param fd The listening socket file descriptor.
+ * @param timeout Polling timeout in milliseconds.
+ * @param h URLContext providing interrupt check
+ * callback and logging context.
+ * @return A non-blocking file descriptor on success
+ * or an AVERROR on failure.
+ */
+int ff_accept(int fd, int timeout, URLContext *h);
+
+/**
* Connect to a file descriptor and poll for result.
*
* @param fd First argument of connect(),
diff --git a/chromium/third_party/ffmpeg/libavformat/nutdec.c b/chromium/third_party/ffmpeg/libavformat/nutdec.c
index 13fb39924d2..63b0cd2fb95 100644
--- a/chromium/third_party/ffmpeg/libavformat/nutdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/nutdec.c
@@ -1005,6 +1005,9 @@ static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int
AV_WL32(dst+4, skip_end);
}
+ if (avio_tell(bc) >= maxpos)
+ return AVERROR_INVALIDDATA;
+
return 0;
}
@@ -1277,6 +1280,8 @@ static int read_seek(AVFormatContext *s, int stream_index,
next_node[1]->pos, next_node[1]->pos,
next_node[0]->ts, next_node[1]->ts,
AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp);
+ if (pos < 0)
+ return pos;
if (!(flags & AVSEEK_FLAG_BACKWARD)) {
dummy.pos = pos + 16;
diff --git a/chromium/third_party/ffmpeg/libavformat/nutenc.c b/chromium/third_party/ffmpeg/libavformat/nutenc.c
index 1522a0452fe..49d62bfbecc 100644
--- a/chromium/third_party/ffmpeg/libavformat/nutenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/nutenc.c
@@ -933,6 +933,7 @@ static int write_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int
break;
case AV_PKT_DATA_METADATA_UPDATE:
case AV_PKT_DATA_STRINGS_METADATA:
+ case AV_PKT_DATA_QUALITY_STATS:
// belongs into meta, not side data
break;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/oggdec.c b/chromium/third_party/ffmpeg/libavformat/oggdec.c
index 4f4d085dbd1..ae56915b580 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggdec.c
@@ -60,6 +60,7 @@ static const struct ogg_codec * const ogg_codecs[] = {
static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
+static int ogg_restore(AVFormatContext *s, int discard);
//FIXME We could avoid some structure duplication
static int ogg_save(AVFormatContext *s)
@@ -68,6 +69,7 @@ static int ogg_save(AVFormatContext *s)
struct ogg_state *ost =
av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
int i;
+ int ret = 0;
if (!ost)
return AVERROR(ENOMEM);
@@ -80,15 +82,21 @@ static int ogg_save(AVFormatContext *s)
for (i = 0; i < ogg->nstreams; i++) {
struct ogg_stream *os = ogg->streams + i;
- os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
- memcpy(os->buf, ost->streams[i].buf, os->bufpos);
+ os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (os->buf)
+ memcpy(os->buf, ost->streams[i].buf, os->bufpos);
+ else
+ ret = AVERROR(ENOMEM);
os->new_metadata = NULL;
os->new_metadata_size = 0;
}
ogg->state = ost;
- return 0;
+ if (ret < 0)
+ ogg_restore(s, 0);
+
+ return ret;
}
static int ogg_restore(AVFormatContext *s, int discard)
@@ -255,7 +263,7 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
memset(os, 0, sizeof(*os));
os->serial = serial;
os->bufsize = DECODER_BUFFER_SIZE;
- os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
+ os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
os->header = -1;
os->start_granule = OGG_NOGRANULE_VALUE;
if (!os->buf)
@@ -277,7 +285,7 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
static int ogg_new_buf(struct ogg *ogg, int idx)
{
struct ogg_stream *os = ogg->streams + idx;
- uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
+ uint8_t *nb = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
int size = os->bufpos - os->pstart;
if (!nb)
@@ -416,7 +424,7 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
}
if (os->bufsize - os->bufpos < size) {
- uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
+ uint8_t *nb = av_malloc((os->bufsize *= 2) + AV_INPUT_BUFFER_PADDING_SIZE);
if (!nb)
return AVERROR(ENOMEM);
memcpy(nb, os->buf, os->bufpos);
@@ -432,7 +440,7 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
os->granule = gp;
os->flags = flags;
- memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
if (sid)
*sid = idx;
diff --git a/chromium/third_party/ffmpeg/libavformat/oggenc.c b/chromium/third_party/ffmpeg/libavformat/oggenc.c
index 2c0a44e4559..49075129891 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggenc.c
@@ -260,7 +260,7 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
if (i == total_segments)
page->granule = granule;
- if (!header) {
+ {
AVStream *st = s->streams[page->stream_index];
int64_t start = av_rescale_q(page->start_granule, st->time_base,
@@ -268,10 +268,13 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
int64_t next = av_rescale_q(page->granule, st->time_base,
AV_TIME_BASE_Q);
- if (page->segments_count == 255 ||
- (ogg->pref_size > 0 && page->size >= ogg->pref_size) ||
- (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
+ if (page->segments_count == 255) {
ogg_buffer_page(s, oggstream);
+ } else if (!header) {
+ if ((ogg->pref_size > 0 && page->size >= ogg->pref_size) ||
+ (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
+ ogg_buffer_page(s, oggstream);
+ }
}
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparsedirac.c b/chromium/third_party/ffmpeg/libavformat/oggparsedirac.c
index 35be6558214..ab40f96c631 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparsedirac.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparsedirac.c
@@ -31,16 +31,19 @@ static int dirac_header(AVFormatContext *s, int idx)
AVStream *st = s->streams[idx];
dirac_source_params source;
GetBitContext gb;
+ int ret;
// already parsed the header
if (st->codec->codec_id == AV_CODEC_ID_DIRAC)
return 0;
- if (init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8) < 0)
- return -1;
+ ret = init_get_bits8(&gb, os->buf + os->pstart + 13, (os->psize - 13));
+ if (ret < 0)
+ return ret;
- if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
- return -1;
+ ret = avpriv_dirac_parse_sequence_header(st->codec, &gb, &source);
+ if (ret < 0)
+ return ret;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = AV_CODEC_ID_DIRAC;
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparseogm.c b/chromium/third_party/ffmpeg/libavformat/oggparseogm.c
index 54024e0a0ab..ae8c3c850cd 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparseogm.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparseogm.c
@@ -102,7 +102,7 @@ ogm_header(AVFormatContext *s, int idx)
size -= 4;
}
if (size > 52) {
- av_assert0(FF_INPUT_BUFFER_PADDING_SIZE <= 52);
+ av_assert0(AV_INPUT_BUFFER_PADDING_SIZE <= 52);
size -= 52;
ff_alloc_extradata(st->codec, size);
bytestream2_get_buffer(&p, st->codec->extradata, st->codec->extradata_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparsetheora.c b/chromium/third_party/ffmpeg/libavformat/oggparsetheora.c
index 91c70dfec9f..e92d4c5170c 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparsetheora.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparsetheora.c
@@ -127,11 +127,11 @@ static int theora_header(AVFormatContext *s, int idx)
}
if ((err = av_reallocp(&st->codec->extradata,
- cds + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+ cds + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
st->codec->extradata_size = 0;
return err;
}
- memset(st->codec->extradata + cds, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(st->codec->extradata + cds, 0, AV_INPUT_BUFFER_PADDING_SIZE);
cdp = st->codec->extradata + st->codec->extradata_size;
*cdp++ = os->psize >> 8;
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c b/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
index dd443374375..b96be989747 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
@@ -242,7 +242,7 @@ static int fixup_vorbis_headers(AVFormatContext *as,
offset += priv->len[i];
av_freep(&priv->packet[i]);
}
- if ((err = av_reallocp(buf, offset + FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+ if ((err = av_reallocp(buf, offset + AV_INPUT_BUFFER_PADDING_SIZE)) < 0)
return err;
return offset;
}
@@ -406,6 +406,9 @@ static int vorbis_packet(AVFormatContext *s, int idx)
struct oggvorbis_private *priv = os->private;
int duration, flags = 0;
+ if (!priv->vp)
+ return AVERROR_INVALIDDATA;
+
/* first packet handling
* here we parse the duration of each packet in the first page and compare
* the total duration to the page granule to find the encoder delay and
diff --git a/chromium/third_party/ffmpeg/libavformat/options.c b/chromium/third_party/ffmpeg/libavformat/options.c
index d238dd5ab70..9918349703a 100644
--- a/chromium/third_party/ffmpeg/libavformat/options.c
+++ b/chromium/third_party/ffmpeg/libavformat/options.c
@@ -20,6 +20,8 @@
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+
+#include "libavutil/internal.h"
#include "libavutil/opt.h"
/**
@@ -27,7 +29,9 @@
* Options definition for AVFormatContext.
*/
+FF_DISABLE_DEPRECATION_WARNINGS
#include "options_table.h"
+FF_ENABLE_DEPRECATION_WARNINGS
static const char* format_to_name(void* ptr)
{
diff --git a/chromium/third_party/ffmpeg/libavformat/options_table.h b/chromium/third_party/ffmpeg/libavformat/options_table.h
index 58670b0035d..773814a2b96 100644
--- a/chromium/third_party/ffmpeg/libavformat/options_table.h
+++ b/chromium/third_party/ffmpeg/libavformat/options_table.h
@@ -36,7 +36,11 @@
static const AVOption avformat_options[] = {
{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
+#if FF_API_PROBESIZE_32
{"probesize", "set probing size", OFFSET(probesize2), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},
+#else
+{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},
+#endif
{"formatprobesize", "number of bytes to probe file format", OFFSET(format_probesize), AV_OPT_TYPE_INT, {.i64 = PROBE_BUF_MAX}, 0, INT_MAX-1, D},
{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, E},
{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = AVFMT_FLAG_FLUSH_PACKETS }, INT_MIN, INT_MAX, D|E, "fflags"},
@@ -54,7 +58,11 @@ static const AVOption avformat_options[] = {
{"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"},
{"seek2any", "allow seeking to non-keyframes on demuxer level when supported", OFFSET(seek2any), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, D},
{"bitexact", "do not write random/volatile data", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_BITEXACT }, 0, 0, E, "fflags" },
+#if FF_API_PROBESIZE_32
{"analyzeduration", "specify how many microseconds are analyzed to probe the input", OFFSET(max_analyze_duration2), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, D},
+#else
+{"analyzeduration", "specify how many microseconds are analyzed to probe the input", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, D},
+#endif
{"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D},
{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), AV_OPT_TYPE_INT, {.i64 = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
diff --git a/chromium/third_party/ffmpeg/libavformat/os_support.c b/chromium/third_party/ffmpeg/libavformat/os_support.c
index 7950e448891..718bc6ce59b 100644
--- a/chromium/third_party/ffmpeg/libavformat/os_support.c
+++ b/chromium/third_party/ffmpeg/libavformat/os_support.c
@@ -340,3 +340,4 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
#endif /* !HAVE_POLL_H */
#endif /* CONFIG_NETWORK */
+
diff --git a/chromium/third_party/ffmpeg/libavformat/pjsdec.c b/chromium/third_party/ffmpeg/libavformat/pjsdec.c
index 5129b70e5fb..a88d5331928 100644
--- a/chromium/third_party/ffmpeg/libavformat/pjsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/pjsdec.c
@@ -100,7 +100,7 @@ static int pjs_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&pjs->q);
+ ff_subtitles_queue_finalize(s, &pjs->q);
return res;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/psxstr.c b/chromium/third_party/ffmpeg/libavformat/psxstr.c
index fd50e549ae3..3aa08eb93f7 100644
--- a/chromium/third_party/ffmpeg/libavformat/psxstr.c
+++ b/chromium/third_party/ffmpeg/libavformat/psxstr.c
@@ -238,11 +238,6 @@ static int str_read_packet(AVFormatContext *s,
pkt->data= NULL;
pkt->size= -1;
pkt->buf = NULL;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/qcp.c b/chromium/third_party/ffmpeg/libavformat/qcp.c
index 9e2eedfe85d..ad4a8ae79c6 100644
--- a/chromium/third_party/ffmpeg/libavformat/qcp.c
+++ b/chromium/third_party/ffmpeg/libavformat/qcp.c
@@ -57,6 +57,11 @@ static const uint8_t guid_evrc[16] = {
0x91, 0xef, 0x73, 0x6a, 0x51, 0x00, 0xce, 0xb4
};
+static const uint8_t guid_4gv[16] = {
+ 0xca, 0x29, 0xfd, 0x3c, 0x53, 0xf6, 0xf5, 0x4e,
+ 0x90, 0xe9, 0xf4, 0x23, 0x6d, 0x59, 0x9b, 0x61
+};
+
/**
* SMV GUID as stored in the file
*/
@@ -106,6 +111,8 @@ static int qcp_read_header(AVFormatContext *s)
st->codec->codec_id = AV_CODEC_ID_EVRC;
} else if (!memcmp(buf, guid_smv, 16)) {
st->codec->codec_id = AV_CODEC_ID_SMV;
+ } else if (!memcmp(buf, guid_4gv, 16)) {
+ st->codec->codec_id = AV_CODEC_ID_4GV;
} else {
av_log(s, AV_LOG_ERROR, "Unknown codec GUID "FF_PRI_GUID".\n",
FF_ARG_GUID(buf));
diff --git a/chromium/third_party/ffmpeg/libavformat/rawdec.c b/chromium/third_party/ffmpeg/libavformat/rawdec.c
index b903e63fb48..7684e1dd9a0 100644
--- a/chromium/third_party/ffmpeg/libavformat/rawdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rawdec.c
@@ -188,10 +188,10 @@ static int mjpeg_probe(AVProbeData *p)
}
if (nb_invalid*4 + 1 < nb_frames) {
- static const char ct_jpeg[] = "\r\nContent-Type: image/jpeg\r\n\r\n";
+ static const char ct_jpeg[] = "\r\nContent-Type: image/jpeg\r\n";
int i;
- for (i=0; i<FFMIN(p->buf_size - sizeof(ct_jpeg), 100); i++)
+ for (i=0; i<FFMIN(p->buf_size - (int)sizeof(ct_jpeg), 100); i++)
if (!memcmp(p->buf + i, ct_jpeg, sizeof(ct_jpeg) - 1))
return AVPROBE_SCORE_EXTENSION;
diff --git a/chromium/third_party/ffmpeg/libavformat/rawenc.c b/chromium/third_party/ffmpeg/libavformat/rawenc.c
index e59f1ae95e6..d65c7c79097 100644
--- a/chromium/third_party/ffmpeg/libavformat/rawenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/rawenc.c
@@ -56,6 +56,25 @@ AVOutputFormat ff_ac3_muxer = {
#endif
#if CONFIG_ADX_MUXER
+
+static int adx_write_trailer(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVCodecContext *avctx = s->streams[0]->codec;
+
+ if (pb->seekable) {
+ int64_t file_size = avio_tell(pb);
+ uint64_t sample_count = (file_size - 36) / avctx->channels / 18 * 32;
+ if (sample_count <= UINT32_MAX) {
+ avio_seek(pb, 12, SEEK_SET);
+ avio_wb32(pb, sample_count);
+ avio_seek(pb, file_size, SEEK_SET);
+ }
+ }
+
+ return 0;
+}
+
AVOutputFormat ff_adx_muxer = {
.name = "adx",
.long_name = NULL_IF_CONFIG_SMALL("CRI ADX"),
@@ -64,6 +83,7 @@ AVOutputFormat ff_adx_muxer = {
.video_codec = AV_CODEC_ID_NONE,
.write_header = force_one_stream,
.write_packet = ff_raw_write_packet,
+ .write_trailer = adx_write_trailer,
.flags = AVFMT_NOTIMESTAMPS,
};
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/rdt.c b/chromium/third_party/ffmpeg/libavformat/rdt.c
index bb56a8ba817..046d2732a47 100644
--- a/chromium/third_party/ffmpeg/libavformat/rdt.c
+++ b/chromium/third_party/ffmpeg/libavformat/rdt.c
@@ -86,7 +86,7 @@ struct PayloadContext {
RMStream **rmst;
uint8_t *mlti_data;
unsigned int mlti_data_size;
- char buffer[RTP_MAX_PACKET_LENGTH + FF_INPUT_BUFFER_PADDING_SIZE];
+ char buffer[RTP_MAX_PACKET_LENGTH + AV_INPUT_BUFFER_PADDING_SIZE];
int audio_pkt_cnt; /**< remaining audio packets in rmdec */
};
@@ -398,7 +398,7 @@ rdt_parse_b64buf (unsigned int *target_len, const char *p)
len -= 2; /* skip embracing " at start/end */
}
*target_len = len * 3 / 4;
- target = av_mallocz(*target_len + FF_INPUT_BUFFER_PADDING_SIZE);
+ target = av_mallocz(*target_len + AV_INPUT_BUFFER_PADDING_SIZE);
if (!target)
return NULL;
av_base64_decode(target, p, *target_len);
diff --git a/chromium/third_party/ffmpeg/libavformat/realtextdec.c b/chromium/third_party/ffmpeg/libavformat/realtextdec.c
index fff85d6ba92..f13321c91a9 100644
--- a/chromium/third_party/ffmpeg/libavformat/realtextdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/realtextdec.c
@@ -115,7 +115,7 @@ static int realtext_read_header(AVFormatContext *s)
}
av_bprint_clear(&buf);
}
- ff_subtitles_queue_finalize(&rt->q);
+ ff_subtitles_queue_finalize(s, &rt->q);
end:
av_bprint_finalize(&buf, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/redspark.c b/chromium/third_party/ffmpeg/libavformat/redspark.c
index 13a7b37d254..66c2dc5aae1 100644
--- a/chromium/third_party/ffmpeg/libavformat/redspark.c
+++ b/chromium/third_party/ffmpeg/libavformat/redspark.c
@@ -67,7 +67,7 @@ static int redspark_read_header(AVFormatContext *s)
return AVERROR(ENOMEM);
codec = st->codec;
- header = av_malloc(HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ header = av_malloc(HEADER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
if (!header)
return AVERROR(ENOMEM);
pbc = header;
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.c b/chromium/third_party/ffmpeg/libavformat/riff.c
index ddfa829251d..768b406a1f9 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.c
+++ b/chromium/third_party/ffmpeg/libavformat/riff.c
@@ -149,6 +149,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_DVVIDEO, MKTAG('p', 'd', 'v', 'c') },
{ AV_CODEC_ID_DVVIDEO, MKTAG('S', 'L', '2', '5') },
{ AV_CODEC_ID_DVVIDEO, MKTAG('S', 'L', 'D', 'V') },
+ { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') },
{ AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') },
{ AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') },
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', '2') },
@@ -323,6 +324,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'C') },
{ AV_CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'K') },
{ AV_CODEC_ID_JPEG2000, MKTAG('I', 'P', 'J', '2') },
+ { AV_CODEC_ID_JPEG2000, MKTAG('A', 'V', 'j', '2') }, /* Avid jpeg2000 */
{ AV_CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
{ AV_CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
{ AV_CODEC_ID_PNG, MKTAG('M', 'P', 'N', 'G') },
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.h b/chromium/third_party/ffmpeg/libavformat/riff.h
index ae5ecef4c5a..d6d91ef52d6 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.h
+++ b/chromium/third_party/ffmpeg/libavformat/riff.h
@@ -53,6 +53,11 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *t
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX 0x00000001
/**
+ * Tell ff_put_wav_header() to write an empty channel mask.
+ */
+#define FF_PUT_WAV_HEADER_SKIP_CHANNELMASK 0x00000002
+
+/**
* Write WAVEFORMAT header structure.
*
* @param flags a combination of FF_PUT_WAV_HEADER_* constants
@@ -62,7 +67,7 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *t
int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags);
enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps);
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_endian);
+int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec, int size, int big_endian);
extern const AVCodecTag ff_codec_bmp_tags[]; // exposed through avformat_get_riff_video_tags()
extern const AVCodecTag ff_codec_wav_tags[];
diff --git a/chromium/third_party/ffmpeg/libavformat/riffdec.c b/chromium/third_party/ffmpeg/libavformat/riffdec.c
index f44df1e672c..7eecdb24b88 100644
--- a/chromium/third_party/ffmpeg/libavformat/riffdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/riffdec.c
@@ -31,10 +31,12 @@
int ff_get_guid(AVIOContext *s, ff_asf_guid *g)
{
+ int ret;
av_assert0(sizeof(*g) == 16); //compiler will optimize this out
- if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g)) {
+ ret = avio_read(s, *g, sizeof(*g));
+ if (ret < (int)sizeof(*g)) {
memset(*g, 0, sizeof(*g));
- return AVERROR_INVALIDDATA;
+ return ret < 0 ? ret : AVERROR_INVALIDDATA;
}
return 0;
}
@@ -81,25 +83,29 @@ static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c)
}
/* "big_endian" values are needed for RIFX file format */
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_endian)
+int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb,
+ AVCodecContext *codec, int size, int big_endian)
{
int id;
+ uint64_t bitrate;
- if (size < 14)
+ if (size < 14) {
avpriv_request_sample(codec, "wav header size < 14");
+ return AVERROR_INVALIDDATA;
+ }
codec->codec_type = AVMEDIA_TYPE_AUDIO;
if (!big_endian) {
id = avio_rl16(pb);
codec->channels = avio_rl16(pb);
codec->sample_rate = avio_rl32(pb);
- codec->bit_rate = avio_rl32(pb) * 8;
+ bitrate = avio_rl32(pb) * 8LL;
codec->block_align = avio_rl16(pb);
} else {
id = avio_rb16(pb);
codec->channels = avio_rb16(pb);
codec->sample_rate = avio_rb32(pb);
- codec->bit_rate = avio_rb32(pb) * 8;
+ bitrate = avio_rb32(pb) * 8LL;
codec->block_align = avio_rb16(pb);
}
if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */
@@ -142,8 +148,25 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_
if (size > 0)
avio_skip(pb, size);
}
+
+ if (bitrate > INT_MAX) {
+ if (s->error_recognition & AV_EF_EXPLODE) {
+ av_log(s, AV_LOG_ERROR,
+ "The bitrate %"PRIu64" is too large.\n",
+ bitrate);
+ return AVERROR_INVALIDDATA;
+ } else {
+ av_log(s, AV_LOG_WARNING,
+ "The bitrate %"PRIu64" is too large, resetting to 0.",
+ bitrate);
+ codec->bit_rate = 0;
+ }
+ } else {
+ codec->bit_rate = bitrate;
+ }
+
if (codec->sample_rate <= 0) {
- av_log(NULL, AV_LOG_ERROR,
+ av_log(s, AV_LOG_ERROR,
"Invalid sample rate: %d\n", codec->sample_rate);
return AVERROR_INVALIDDATA;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/riffenc.c b/chromium/third_party/ffmpeg/libavformat/riffenc.c
index 85c953f2efe..ceb27f272ca 100644
--- a/chromium/third_party/ffmpeg/libavformat/riffenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/riffenc.c
@@ -168,8 +168,9 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags)
}
/* write WAVEFORMATEXTENSIBLE extensions */
if (waveformatextensible) {
- int write_channel_mask = enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
- enc->channel_layout < 0x40000;
+ int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
+ (enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
+ enc->channel_layout < 0x40000);
/* 22 is WAVEFORMATEXTENSIBLE size */
avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
/* ValidBitsPerSample || SamplesPerBlock || Reserved */
diff --git a/chromium/third_party/ffmpeg/libavformat/rmdec.c b/chromium/third_party/ffmpeg/libavformat/rmdec.c
index 832f15daa45..59a80355e0d 100644
--- a/chromium/third_party/ffmpeg/libavformat/rmdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rmdec.c
@@ -220,7 +220,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
if (version == 5)
avio_r8(pb);
codecdata_length = avio_rb32(pb);
- if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
+ if(codecdata_length + AV_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
return -1;
}
@@ -250,7 +250,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
if (version == 5)
avio_r8(pb);
codecdata_length = avio_rb32(pb);
- if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
+ if(codecdata_length + AV_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
return -1;
}
@@ -327,20 +327,6 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
codec_pos = avio_tell(pb);
v = avio_rb32(pb);
- if (v == MKBETAG('M', 'L', 'T', 'I')) {
- int number_of_streams = avio_rb16(pb);
- int number_of_mdpr;
- int i;
- for (i = 0; i<number_of_streams; i++)
- avio_rb16(pb);
- number_of_mdpr = avio_rb16(pb);
- if (number_of_mdpr != 1) {
- avpriv_request_sample(s, "MLTI with multiple MDPR");
- }
- avio_rb32(pb);
- v = avio_rb32(pb);
- }
-
if (v == MKTAG(0xfd, 'a', 'r', '.')) {
/* ra type header */
if (rm_read_audio_stream_info(s, pb, st, rst, 0))
@@ -514,6 +500,8 @@ static int rm_read_header(AVFormatContext *s)
char buf[128], mime[128];
int flags = 0;
int ret = -1;
+ unsigned size, v;
+ int64_t codec_pos;
tag = avio_rl32(pb);
if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
@@ -584,9 +572,55 @@ static int rm_read_header(AVFormatContext *s)
st->priv_data = ff_rm_alloc_rmstream();
if (!st->priv_data)
return AVERROR(ENOMEM);
- if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
- avio_rb32(pb), mime) < 0)
- goto fail;
+
+ size = avio_rb32(pb);
+ codec_pos = avio_tell(pb);
+
+ ffio_ensure_seekback(pb, 4);
+ v = avio_rb32(pb);
+ if (v == MKBETAG('M', 'L', 'T', 'I')) {
+ int number_of_streams = avio_rb16(pb);
+ int number_of_mdpr;
+ int i;
+ unsigned size2;
+ for (i = 0; i<number_of_streams; i++)
+ avio_rb16(pb);
+ number_of_mdpr = avio_rb16(pb);
+ if (number_of_mdpr != 1) {
+ avpriv_request_sample(s, "MLTI with multiple (%d) MDPR", number_of_mdpr);
+ }
+ for (i = 0; i < number_of_mdpr; i++) {
+ AVStream *st2;
+ if (i > 0) {
+ st2 = avformat_new_stream(s, NULL);
+ if (!st2) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ st2->id = st->id + (i<<16);
+ st2->codec->bit_rate = st->codec->bit_rate;
+ st2->start_time = st->start_time;
+ st2->duration = st->duration;
+ st2->codec->codec_type = AVMEDIA_TYPE_DATA;
+ st2->priv_data = ff_rm_alloc_rmstream();
+ if (!st2->priv_data)
+ return AVERROR(ENOMEM);
+ } else
+ st2 = st;
+
+ size2 = avio_rb32(pb);
+ if (ff_rm_read_mdpr_codecdata(s, s->pb, st2, st2->priv_data,
+ size2, mime) < 0)
+ goto fail;
+ }
+ avio_seek(pb, codec_pos + size, SEEK_SET);
+ } else {
+ avio_skip(pb, -4);
+ if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
+ size, mime) < 0)
+ goto fail;
+ }
+
break;
case MKTAG('D', 'A', 'T', 'A'):
goto header_end;
@@ -644,9 +678,11 @@ static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stre
while(!avio_feof(pb)){
int len, num, i;
+ int mlti_id;
*pos= avio_tell(pb) - 3;
if(rm->remaining_len > 0){
num= rm->current_stream;
+ mlti_id = 0;
len= rm->remaining_len;
*timestamp = AV_NOPTS_VALUE;
*flags= 0;
@@ -682,12 +718,13 @@ static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stre
num = avio_rb16(pb);
*timestamp = avio_rb32(pb);
- avio_r8(pb); /* reserved */
+ mlti_id = (avio_r8(pb)>>1)-1<<16;
+ mlti_id = FFMAX(mlti_id, 0);
*flags = avio_r8(pb); /* flags */
}
for(i=0;i<s->nb_streams;i++) {
st = s->streams[i];
- if (num == st->id)
+ if (mlti_id + num == st->id)
break;
}
if (i == s->nb_streams) {
@@ -797,11 +834,6 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
vst->pkt.data= NULL;
vst->pkt.size= 0;
vst->pkt.buf = NULL;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- vst->pkt.destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
vst->videobufpos - 1 - 8*vst->slices);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmp.h b/chromium/third_party/ffmpeg/libavformat/rtmp.h
index 8fc8040d89e..6600da74f01 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmp.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtmp.h
@@ -29,9 +29,6 @@
#define RTMP_HANDSHAKE_PACKET_SIZE 1536
-#define HMAC_IPAD_VAL 0x36
-#define HMAC_OPAD_VAL 0x5C
-
/**
* emulated Flash client version - 9.0.124.2 on Linux
* @{
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmppkt.c b/chromium/third_party/ffmpeg/libavformat/rtmppkt.c
index c474fb3d588..0d693c27f7f 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmppkt.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmppkt.c
@@ -440,6 +440,7 @@ int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data);
case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
case AMF_DATA_TYPE_NULL: return 1;
+ case AMF_DATA_TYPE_DATE: return 11;
case AMF_DATA_TYPE_ARRAY:
parse_key = 0;
case AMF_DATA_TYPE_MIXEDARRAY:
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmpproto.c b/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
index 43ddfe8ecc4..51d9ac601c8 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
@@ -27,12 +27,12 @@
#include "libavcodec/bytestream.h"
#include "libavutil/avstring.h"
#include "libavutil/base64.h"
+#include "libavutil/hmac.h"
#include "libavutil/intfloat.h"
#include "libavutil/lfg.h"
#include "libavutil/md5.h"
#include "libavutil/opt.h"
#include "libavutil/random_seed.h"
-#include "libavutil/sha.h"
#include "avformat.h"
#include "internal.h"
@@ -49,8 +49,8 @@
#endif
#define APP_MAX_LENGTH 1024
-#define PLAYPATH_MAX_LENGTH 256
-#define TCURL_MAX_LENGTH 512
+#define PLAYPATH_MAX_LENGTH 512
+#define TCURL_MAX_LENGTH 1024
#define FLASHVER_MAX_LENGTH 64
#define RTMP_PKTDATA_DEFAULT_SIZE 4096
#define RTMP_HEADER 11
@@ -956,41 +956,22 @@ static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
const uint8_t *key, int keylen, uint8_t *dst)
{
- struct AVSHA *sha;
- uint8_t hmac_buf[64+32] = {0};
- int i;
+ AVHMAC *hmac;
- sha = av_sha_alloc();
- if (!sha)
+ hmac = av_hmac_alloc(AV_HMAC_SHA256);
+ if (!hmac)
return AVERROR(ENOMEM);
- if (keylen < 64) {
- memcpy(hmac_buf, key, keylen);
- } else {
- av_sha_init(sha, 256);
- av_sha_update(sha,key, keylen);
- av_sha_final(sha, hmac_buf);
- }
- for (i = 0; i < 64; i++)
- hmac_buf[i] ^= HMAC_IPAD_VAL;
-
- av_sha_init(sha, 256);
- av_sha_update(sha, hmac_buf, 64);
+ av_hmac_init(hmac, key, keylen);
if (gap <= 0) {
- av_sha_update(sha, src, len);
+ av_hmac_update(hmac, src, len);
} else { //skip 32 bytes used for storing digest
- av_sha_update(sha, src, gap);
- av_sha_update(sha, src + gap + 32, len - gap - 32);
+ av_hmac_update(hmac, src, gap);
+ av_hmac_update(hmac, src + gap + 32, len - gap - 32);
}
- av_sha_final(sha, hmac_buf + 64);
-
- for (i = 0; i < 64; i++)
- hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
- av_sha_init(sha, 256);
- av_sha_update(sha, hmac_buf, 64+32);
- av_sha_final(sha, dst);
+ av_hmac_final(hmac, dst, 32);
- av_free(sha);
+ av_hmac_free(hmac);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c
index 2ac79dbf5ee..b399be423e3 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c
@@ -119,7 +119,7 @@ int ff_h264_parse_sprop_parameter_sets(AVFormatContext *s,
uint8_t *dest = av_realloc(*data_ptr,
packet_size + sizeof(start_sequence) +
*size_ptr +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!dest) {
av_log(s, AV_LOG_ERROR,
"Unable to allocate memory for extradata!\n");
@@ -132,7 +132,7 @@ int ff_h264_parse_sprop_parameter_sets(AVFormatContext *s,
memcpy(dest + *size_ptr + sizeof(start_sequence),
decoded_packet, packet_size);
memset(dest + *size_ptr + sizeof(start_sequence) +
- packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ packet_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
*size_ptr += sizeof(start_sequence) + packet_size;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_hevc.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_hevc.c
index 51c2094882b..815a72c2b2a 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_hevc.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_hevc.c
@@ -152,7 +152,7 @@ static av_cold int hevc_parse_sdp_line(AVFormatContext *ctx, int st_index,
codec->extradata_size = hevc_data->vps_size + hevc_data->sps_size +
hevc_data->pps_size + hevc_data->sei_size;
codec->extradata = av_malloc(codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE);
if (!codec->extradata) {
ret = AVERROR(ENOMEM);
codec->extradata_size = 0;
@@ -166,7 +166,7 @@ static av_cold int hevc_parse_sdp_line(AVFormatContext *ctx, int st_index,
pos += hevc_data->pps_size;
memcpy(codec->extradata + pos, hevc_data->sei, hevc_data->sei_size);
pos += hevc_data->sei_size;
- memset(codec->extradata + pos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(codec->extradata + pos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
}
av_freep(&hevc_data->vps);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_latm.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_latm.c
index 7db92f60fa3..aebba5741df 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_latm.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_latm.c
@@ -97,7 +97,7 @@ static int parse_fmtp_config(AVStream *st, const char *value)
int audio_mux_version, same_time_framing, num_programs, num_layers;
/* Pad this buffer, too, to avoid out of bounds reads with get_bits below */
- config = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
+ config = av_mallocz(len + AV_INPUT_BUFFER_PADDING_SIZE);
if (!config)
return AVERROR(ENOMEM);
ff_hex_to_data(config, value);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_qt.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_qt.c
index ba701dc6cf3..e11303fe011 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_qt.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_qt.c
@@ -174,14 +174,14 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
if (qt->pkt.size > 0 && qt->timestamp == *timestamp) {
int err;
if ((err = av_reallocp(&qt->pkt.data, qt->pkt.size + alen +
- FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+ AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
qt->pkt.size = 0;
return err;
}
} else {
av_freep(&qt->pkt.data);
av_init_packet(&qt->pkt);
- qt->pkt.data = av_realloc(NULL, alen + FF_INPUT_BUFFER_PADDING_SIZE);
+ qt->pkt.data = av_realloc(NULL, alen + AV_INPUT_BUFFER_PADDING_SIZE);
if (!qt->pkt.data)
return AVERROR(ENOMEM);
qt->pkt.size = 0;
@@ -198,7 +198,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
qt->pkt.data = NULL;
pkt->flags = keyframe ? AV_PKT_FLAG_KEY : 0;
pkt->stream_index = st->index;
- memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
return 0;
}
return AVERROR(EAGAIN);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c
index eceb840580f..9ea3b193864 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c
@@ -262,8 +262,8 @@ parse_packed_headers(const uint8_t * packed_headers,
/* allocate extra space:
* -- length/255 +2 for xiphlacing
* -- one for the '2' marker
- * -- FF_INPUT_BUFFER_PADDING_SIZE required */
- extradata_alloc = length + length/255 + 3 + FF_INPUT_BUFFER_PADDING_SIZE;
+ * -- AV_INPUT_BUFFER_PADDING_SIZE required */
+ extradata_alloc = length + length/255 + 3 + AV_INPUT_BUFFER_PADDING_SIZE;
if (ff_alloc_extradata(codec, extradata_alloc)) {
av_log(codec, AV_LOG_ERROR, "Out of memory\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c b/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c
index 74f306eb96b..96e65efbaa9 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c
@@ -58,7 +58,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
rtpctx->max_delay = s->max_delay;
/* Copy other stream parameters. */
rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio;
- rtpctx->flags |= s->flags & AVFMT_FLAG_MP4A_LATM;
+ rtpctx->flags |= s->flags & (AVFMT_FLAG_MP4A_LATM | AVFMT_FLAG_BITEXACT);
/* Get the payload type from the codec */
if (st->id < RTP_PT_PRIVATE)
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpenc_jpeg.c b/chromium/third_party/ffmpeg/libavformat/rtpenc_jpeg.c
index 7ee26c435e7..a6f2b32df4a 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpenc_jpeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpenc_jpeg.c
@@ -21,13 +21,14 @@
#include "libavcodec/bytestream.h"
#include "libavcodec/mjpeg.h"
+#include "libavcodec/jpegtables.h"
#include "libavutil/intreadwrite.h"
#include "rtpenc.h"
void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
{
RTPMuxContext *s = s1->priv_data;
- const uint8_t *qtables = NULL;
+ const uint8_t *qtables[4] = { NULL };
int nb_qtables = 0;
uint8_t type;
uint8_t w, h;
@@ -63,24 +64,50 @@ void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
continue;
if (buf[i + 1] == DQT) {
- if (buf[i + 4])
+ int tables, j;
+ if (buf[i + 4] & 0xF0)
av_log(s1, AV_LOG_WARNING,
"Only 8-bit precision is supported.\n");
/* a quantization table is 64 bytes long */
- nb_qtables = AV_RB16(&buf[i + 2]) / 65;
- if (i + 4 + nb_qtables * 65 > size) {
+ tables = AV_RB16(&buf[i + 2]) / 65;
+ if (i + 5 + tables * 65 > size) {
av_log(s1, AV_LOG_ERROR, "Too short JPEG header. Aborted!\n");
return;
}
+ if (nb_qtables + tables > 4) {
+ av_log(s1, AV_LOG_ERROR, "Invalid number of quantisation tables\n");
+ return;
+ }
- qtables = &buf[i + 4];
+ for (j = 0; j < tables; j++)
+ qtables[nb_qtables + j] = buf + i + 5 + j * 65;
+ nb_qtables += tables;
} else if (buf[i + 1] == SOF0) {
if (buf[i + 14] != 17 || buf[i + 17] != 17) {
av_log(s1, AV_LOG_ERROR,
"Only 1x1 chroma blocks are supported. Aborted!\n");
return;
}
+ } else if (buf[i + 1] == DHT) {
+ if ( AV_RB16(&buf[i + 2]) < 418
+ || i + 420 >= size
+ || buf[i + 4] != 0x00
+ || buf[i + 33] != 0x01
+ || buf[i + 62] != 0x10
+ || buf[i + 241] != 0x11
+ || memcmp(buf + i + 5, avpriv_mjpeg_bits_dc_luminance + 1, 16)
+ || memcmp(buf + i + 21, avpriv_mjpeg_val_dc, 12)
+ || memcmp(buf + i + 34, avpriv_mjpeg_bits_dc_chrominance + 1, 16)
+ || memcmp(buf + i + 50, avpriv_mjpeg_val_dc, 12)
+ || memcmp(buf + i + 63, avpriv_mjpeg_bits_ac_luminance + 1, 16)
+ || memcmp(buf + i + 79, avpriv_mjpeg_val_ac_luminance, 162)
+ || memcmp(buf + i + 242, avpriv_mjpeg_bits_ac_chrominance + 1, 16)
+ || memcmp(buf + i + 258, avpriv_mjpeg_val_ac_chrominance, 162)) {
+ av_log(s1, AV_LOG_ERROR,
+ "RFC 2435 requires standard Huffman tables for jpeg\n");
+ return;
+ }
} else if (buf[i + 1] == SOS) {
/* SOS is last marker in the header */
i += AV_RB16(&buf[i + 2]) + 2;
@@ -92,6 +119,10 @@ void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
break;
}
}
+ if (nb_qtables && nb_qtables != 2)
+ av_log(s1, AV_LOG_WARNING,
+ "RFC 2435 suggests two quantization tables, %d provided\n",
+ nb_qtables);
/* skip JPEG header */
buf += i;
@@ -130,7 +161,7 @@ void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
bytestream_put_be16(&p, 64 * nb_qtables);
for (i = 0; i < nb_qtables; i++)
- bytestream_put_buffer(&p, &qtables[65 * i + 1], 64);
+ bytestream_put_buffer(&p, qtables[i], 64);
}
/* copy payload data */
diff --git a/chromium/third_party/ffmpeg/libavformat/rtsp.c b/chromium/third_party/ffmpeg/libavformat/rtsp.c
index 98bd4cbe9ab..9aa66d24a4b 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtsp.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtsp.c
@@ -1136,6 +1136,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
unsigned char ch;
const char *p;
int ret, content_length, line_count = 0, request = 0;
+ int first_line = 1;
unsigned char *content = NULL;
start:
@@ -1155,8 +1156,7 @@ start:
return AVERROR_EOF;
if (ch == '\n')
break;
- if (ch == '$') {
- /* XXX: only parse it if first char on line ? */
+ if (ch == '$' && first_line && q == buf) {
if (return_on_interleaved_data) {
return 1;
} else
@@ -1167,6 +1167,7 @@ start:
}
}
*q = '\0';
+ first_line = 0;
av_log(s, AV_LOG_TRACE, "line='%s'\n", buf);
diff --git a/chromium/third_party/ffmpeg/libavformat/samidec.c b/chromium/third_party/ffmpeg/libavformat/samidec.c
index 948e1ed8b13..11c674ce19b 100644
--- a/chromium/third_party/ffmpeg/libavformat/samidec.c
+++ b/chromium/third_party/ffmpeg/libavformat/samidec.c
@@ -68,11 +68,17 @@ static int sami_read_header(AVFormatContext *s)
while (!ff_text_eof(&tr)) {
AVPacket *sub;
const int64_t pos = ff_text_pos(&tr) - (c != 0);
- int is_sync, n = ff_smil_extract_next_text_chunk(&tr, &buf, &c);
+ int is_sync, is_body, n = ff_smil_extract_next_text_chunk(&tr, &buf, &c);
if (n == 0)
break;
+ is_body = !av_strncasecmp(buf.str, "</BODY", 6);
+ if (is_body) {
+ av_bprint_clear(&buf);
+ break;
+ }
+
is_sync = !av_strncasecmp(buf.str, "<SYNC", 5);
if (is_sync)
got_first_sync_point = 1;
@@ -99,7 +105,7 @@ static int sami_read_header(AVFormatContext *s)
if (res < 0)
goto end;
- ff_subtitles_queue_finalize(&sami->q);
+ ff_subtitles_queue_finalize(s, &sami->q);
end:
av_bprint_finalize(&buf, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/sdp.c b/chromium/third_party/ffmpeg/libavformat/sdp.c
index 4d621c7ffc9..45974b394fb 100644
--- a/chromium/third_party/ffmpeg/libavformat/sdp.c
+++ b/chromium/third_party/ffmpeg/libavformat/sdp.c
@@ -685,7 +685,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
const char *mode;
uint64_t vad_option;
- if (c->flags & CODEC_FLAG_QSCALE)
+ if (c->flags & AV_CODEC_FLAG_QSCALE)
mode = "on";
else if (!av_opt_get_int(c, "vad", AV_OPT_FLAG_ENCODING_PARAM, &vad_option) && vad_option)
mode = "vad";
diff --git a/chromium/third_party/ffmpeg/libavformat/segment.c b/chromium/third_party/ffmpeg/libavformat/segment.c
index 42471bb1906..36417f21923 100644
--- a/chromium/third_party/ffmpeg/libavformat/segment.c
+++ b/chromium/third_party/ffmpeg/libavformat/segment.c
@@ -33,6 +33,7 @@
#include "internal.h"
#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/avstring.h"
@@ -113,6 +114,9 @@ typedef struct SegmentContext {
int reference_stream_index;
int break_non_keyframes;
+ int use_rename;
+ char temp_list_filename[1024];
+
SegmentListEntry cur_entry;
SegmentListEntry *segment_list_entries;
SegmentListEntry *segment_list_entries_end;
@@ -258,7 +262,8 @@ static int segment_list_open(AVFormatContext *s)
SegmentContext *seg = s->priv_data;
int ret;
- ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE,
+ snprintf(seg->temp_list_filename, sizeof(seg->temp_list_filename), seg->use_rename ? "%s.tmp" : "%s", seg->list);
+ ret = avio_open2(&seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list);
@@ -347,6 +352,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
/* append new element */
memcpy(entry, &seg->cur_entry, sizeof(*entry));
+ entry->filename = av_strdup(entry->filename);
if (!seg->segment_list_entries)
seg->segment_list_entries = seg->segment_list_entries_end = entry;
else
@@ -368,6 +374,8 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
if (seg->list_type == LIST_TYPE_M3U8 && is_last)
avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
avio_closep(&seg->list_pb);
+ if (seg->use_rename)
+ ff_rename(seg->temp_list_filename, seg->list, s);
} else {
segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry, s);
avio_flush(seg->list_pb);
@@ -644,9 +652,13 @@ static int seg_write_header(AVFormatContext *s)
else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT;
else seg->list_type = LIST_TYPE_FLAT;
}
- if (!seg->list_size && seg->list_type != LIST_TYPE_M3U8)
+ if (!seg->list_size && seg->list_type != LIST_TYPE_M3U8) {
if ((ret = segment_list_open(s)) < 0)
goto fail;
+ } else {
+ const char *proto = avio_find_protocol_name(s->filename);
+ seg->use_rename = proto && !strcmp(proto, "file");
+ }
}
if (seg->list_type == LIST_TYPE_EXT)
av_log(s, AV_LOG_WARNING, "'ext' list type option is deprecated in favor of 'csv'\n");
@@ -774,7 +786,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
}
}
- av_dlog(s, "packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n",
+ ff_dlog(s, "packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n",
pkt->stream_index, av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
av_ts2timestr(pkt->duration, &st->time_base),
pkt->flags & AV_PKT_FLAG_KEY,
@@ -875,6 +887,7 @@ fail:
av_opt_free(seg);
av_freep(&seg->times);
av_freep(&seg->frames);
+ av_freep(&seg->cur_entry.filename);
cur = seg->segment_list_entries;
while (cur) {
diff --git a/chromium/third_party/ffmpeg/libavformat/spdifenc.c b/chromium/third_party/ffmpeg/libavformat/spdifenc.c
index cdcff244212..b4608a1c7c5 100644
--- a/chromium/third_party/ffmpeg/libavformat/spdifenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/spdifenc.c
@@ -525,7 +525,7 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) {
avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
} else {
- av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + AV_INPUT_BUFFER_PADDING_SIZE);
if (!ctx->buffer)
return AVERROR(ENOMEM);
ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
diff --git a/chromium/third_party/ffmpeg/libavformat/srtdec.c b/chromium/third_party/ffmpeg/libavformat/srtdec.c
index b35e50fc367..60d2f48517f 100644
--- a/chromium/third_party/ffmpeg/libavformat/srtdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/srtdec.c
@@ -134,7 +134,7 @@ static int srt_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&srt->q);
+ ff_subtitles_queue_finalize(s, &srt->q);
end:
av_bprint_finalize(&buf, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/stldec.c b/chromium/third_party/ffmpeg/libavformat/stldec.c
index b84c7e9eb0a..8b1f0a6d5bb 100644
--- a/chromium/third_party/ffmpeg/libavformat/stldec.c
+++ b/chromium/third_party/ffmpeg/libavformat/stldec.c
@@ -104,7 +104,7 @@ static int stl_read_header(AVFormatContext *s)
sub->duration = duration;
}
}
- ff_subtitles_queue_finalize(&stl->q);
+ ff_subtitles_queue_finalize(s, &stl->q);
return 0;
}
static int stl_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/subtitles.c b/chromium/third_party/ffmpeg/libavformat/subtitles.c
index 5bdbc8dc512..192043f9177 100644
--- a/chromium/third_party/ffmpeg/libavformat/subtitles.c
+++ b/chromium/third_party/ffmpeg/libavformat/subtitles.c
@@ -166,7 +166,34 @@ static int cmp_pkt_sub_pos_ts(const void *a, const void *b)
return s1->pos > s2->pos ? 1 : -1;
}
-void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q)
+static void drop_dups(void *log_ctx, FFDemuxSubtitlesQueue *q)
+{
+ int i, drop = 0;
+
+ for (i = 1; i < q->nb_subs; i++) {
+ const int last_id = i - 1 - drop;
+ const AVPacket *last = &q->subs[last_id];
+
+ if (q->subs[i].pts == last->pts &&
+ q->subs[i].duration == last->duration &&
+ q->subs[i].stream_index == last->stream_index &&
+ !strcmp(q->subs[i].data, last->data)) {
+
+ av_free_packet(&q->subs[i]);
+ drop++;
+ } else if (drop) {
+ q->subs[last_id + 1] = q->subs[i];
+ memset(&q->subs[i], 0, sizeof(q->subs[i])); // for safety
+ }
+ }
+
+ if (drop) {
+ q->nb_subs -= drop;
+ av_log(log_ctx, AV_LOG_WARNING, "Dropping %d duplicated subtitle events\n", drop);
+ }
+}
+
+void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q)
{
int i;
@@ -176,6 +203,8 @@ void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q)
for (i = 0; i < q->nb_subs; i++)
if (q->subs[i].duration == -1 && i < q->nb_subs - 1)
q->subs[i].duration = q->subs[i + 1].pts - q->subs[i].pts;
+
+ drop_dups(log_ctx, q);
}
int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/subtitles.h b/chromium/third_party/ffmpeg/libavformat/subtitles.h
index 885285cc477..c70f6fffde6 100644
--- a/chromium/third_party/ffmpeg/libavformat/subtitles.h
+++ b/chromium/third_party/ffmpeg/libavformat/subtitles.h
@@ -119,9 +119,10 @@ AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q,
const uint8_t *event, size_t len, int merge);
/**
- * Set missing durations and sort subtitles by PTS, and then byte position.
+ * Set missing durations, sort subtitles by PTS (and then byte position), and
+ * drop duplicated events.
*/
-void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q);
+void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q);
/**
* Generic read_packet() callback for subtitles demuxers using this queue
diff --git a/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c b/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
index 6b38533a882..93db4ebf21a 100644
--- a/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
@@ -86,7 +86,7 @@ static int subviewer1_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&subviewer1->q);
+ ff_subtitles_queue_finalize(s, &subviewer1->q);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/subviewerdec.c b/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
index f1b0fdf0a5c..d4b2fdf4565 100644
--- a/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
@@ -153,7 +153,7 @@ static int subviewer_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&subviewer->q);
+ ff_subtitles_queue_finalize(s, &subviewer->q);
end:
av_bprint_finalize(&header, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/swfdec.c b/chromium/third_party/ffmpeg/libavformat/swfdec.c
index d34d3d90dff..68cd8561fb5 100644
--- a/chromium/third_party/ffmpeg/libavformat/swfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/swfdec.c
@@ -23,6 +23,7 @@
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavcodec/get_bits.h"
#include "swf.h"
@@ -67,7 +68,12 @@ static int swf_probe(AVProbeData *p)
&& AV_RB24(p->buf) != AV_RB24("FWS"))
return 0;
- init_get_bits8(&gb, p->buf + 3, p->buf_size - 3);
+ if ( AV_RB24(p->buf) == AV_RB24("CWS")
+ && p->buf[3] <= 20)
+ return AVPROBE_SCORE_MAX / 4 + 1;
+
+ if (init_get_bits8(&gb, p->buf + 3, p->buf_size - 3) < 0)
+ return 0;
skip_bits(&gb, 40);
len = get_bits(&gb, 5);
@@ -338,7 +344,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
out_len = colormapsize * colormapbpp + linesize * height;
- av_dlog(s, "bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
+ ff_dlog(s, "bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
ch_id, bmp_fmt, width, height, linesize, len, out_len, colormapsize);
zbuf = av_malloc(len);
@@ -407,10 +413,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
}
if (st->codec->pix_fmt != AV_PIX_FMT_NONE && st->codec->pix_fmt != pix_fmt) {
av_log(s, AV_LOG_ERROR, "pixel format change unsupported\n");
- res = AVERROR_PATCHWELCOME;
- goto bitmap_end;
- }
- st->codec->pix_fmt = pix_fmt;
+ } else
+ st->codec->pix_fmt = pix_fmt;
if (linesize * height > pkt->size) {
res = AVERROR_INVALIDDATA;
diff --git a/chromium/third_party/ffmpeg/libavformat/takdec.c b/chromium/third_party/ffmpeg/libavformat/takdec.c
index 3eb1a8ec2d4..970ab4a8b49 100644
--- a/chromium/third_party/ffmpeg/libavformat/takdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/takdec.c
@@ -82,10 +82,10 @@ static int tak_read_header(AVFormatContext *s)
if (size <= 3)
return AVERROR_INVALIDDATA;
- buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE);
+ buffer = av_malloc(size - 3 + AV_INPUT_BUFFER_PADDING_SIZE);
if (!buffer)
return AVERROR(ENOMEM);
- memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(buffer + size - 3, 0, AV_INPUT_BUFFER_PADDING_SIZE);
ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
if (avio_read(pb, buffer, size - 3) != size - 3) {
diff --git a/chromium/third_party/ffmpeg/libavformat/tcp.c b/chromium/third_party/ffmpeg/libavformat/tcp.c
index f24cad2080d..e02c64b8001 100644
--- a/chromium/third_party/ffmpeg/libavformat/tcp.c
+++ b/chromium/third_party/ffmpeg/libavformat/tcp.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "libavutil/avassert.h"
#include "libavutil/parseutils.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
@@ -44,7 +45,7 @@ typedef struct TCPContext {
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "listen", "Listen for incoming connections", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E },
+ { "listen", "Listen for incoming connections", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, .flags = D|E },
{ "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "listen_timeout", "Connection awaiting timeout (in milliseconds)", OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ NULL }
@@ -125,11 +126,16 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
goto fail;
}
- if (s->listen) {
+ if (s->listen == 2) {
+ // multi-client
+ if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0)
+ goto fail1;
+ } else if (s->listen == 1) {
+ // single client
if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
- s->listen_timeout, h)) < 0) {
+ s->listen_timeout, h)) < 0)
goto fail1;
- }
+ // Socket descriptor already closed here. Safe to overwrite to client one.
fd = ret;
} else {
if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
@@ -163,6 +169,22 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
return ret;
}
+static int tcp_accept(URLContext *s, URLContext **c)
+{
+ TCPContext *sc = s->priv_data;
+ TCPContext *cc;
+ int ret;
+ av_assert0(sc->listen);
+ if ((ret = ffurl_alloc(c, s->filename, s->flags, &s->interrupt_callback)) < 0)
+ return ret;
+ cc = (*c)->priv_data;
+ ret = ff_accept(sc->fd, sc->listen_timeout, s);
+ if (ret < 0)
+ return ff_neterrno();
+ cc->fd = ret;
+ return 0;
+}
+
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
TCPContext *s = h->priv_data;
@@ -223,6 +245,7 @@ static int tcp_get_file_handle(URLContext *h)
URLProtocol ff_tcp_protocol = {
.name = "tcp",
.url_open = tcp_open,
+ .url_accept = tcp_accept,
.url_read = tcp_read,
.url_write = tcp_write,
.url_close = tcp_close,
diff --git a/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c b/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
index fb578ebc036..b6dc5170737 100644
--- a/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
@@ -34,7 +34,7 @@ typedef struct {
static const AVOption tedcaptions_options[] = {
{ "start_time", "set the start time (offset) of the subtitles, in ms",
- offsetof(TEDCaptionsDemuxer, start_time), FF_OPT_TYPE_INT64,
+ offsetof(TEDCaptionsDemuxer, start_time), AV_OPT_TYPE_INT64,
{ .i64 = 15000 }, INT64_MIN, INT64_MAX,
AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
@@ -287,7 +287,7 @@ static av_cold int tedcaptions_read_header(AVFormatContext *avf)
ff_subtitles_queue_clean(&tc->subs);
return ret;
}
- ff_subtitles_queue_finalize(&tc->subs);
+ ff_subtitles_queue_finalize(avf, &tc->subs);
for (i = 0; i < tc->subs.nb_subs; i++)
tc->subs.subs[i].pts += tc->start_time;
diff --git a/chromium/third_party/ffmpeg/libavformat/tee.c b/chromium/third_party/ffmpeg/libavformat/tee.c
index e3d466a3eb7..c619eae5db1 100644
--- a/chromium/third_party/ffmpeg/libavformat/tee.c
+++ b/chromium/third_party/ffmpeg/libavformat/tee.c
@@ -396,7 +396,7 @@ static int filter_packet(void *log_ctx, AVPacket *pkt,
&new_pkt.data, &new_pkt.size,
pkt->data, pkt->size,
pkt->flags & AV_PKT_FLAG_KEY);
- if (ret == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
+ if (ret == 0 && new_pkt.data != pkt->data) {
if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)
break;
ret = 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c b/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c
index 6388f37a8e0..4bf94485343 100644
--- a/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c
+++ b/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c
@@ -144,7 +144,7 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
if (ret < 0)
av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
}
-#if GNUTLS_VERSION_MAJOR >= 3
+#if GNUTLS_VERSION_NUMBER >= 0x030020
else
gnutls_certificate_set_x509_system_trust(p->cred);
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/url.h b/chromium/third_party/ffmpeg/libavformat/url.h
index 1a845b77e7c..391e3bca2af 100644
--- a/chromium/third_party/ffmpeg/libavformat/url.h
+++ b/chromium/third_party/ffmpeg/libavformat/url.h
@@ -58,6 +58,8 @@ typedef struct URLProtocol {
* for those nested protocols.
*/
int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);
+ int (*url_accept)(URLContext *s, URLContext **c);
+ int (*url_handshake)(URLContext *c);
/**
* Read data from the protocol.
@@ -90,6 +92,8 @@ typedef struct URLProtocol {
int (*url_open_dir)(URLContext *h);
int (*url_read_dir)(URLContext *h, AVIODirEntry **next);
int (*url_close_dir)(URLContext *h);
+ int (*url_delete)(URLContext *h);
+ int (*url_move)(URLContext *h_src, URLContext *h_dst);
} URLProtocol;
/**
@@ -138,6 +142,29 @@ int ffurl_open(URLContext **puc, const char *filename, int flags,
const AVIOInterruptCB *int_cb, AVDictionary **options);
/**
+ * Accept an URLContext c on an URLContext s
+ *
+ * @param s server context
+ * @param c client context, must be unallocated.
+ * @return >= 0 on success, ff_neterrno() on failure.
+ */
+int ffurl_accept(URLContext *s, URLContext **c);
+
+/**
+ * Perform one step of the protocol handshake to accept a new client.
+ * See avio_handshake() for details.
+ * Implementations should try to return decreasing values.
+ * If the protocol uses an underlying protocol, the underlying handshake is
+ * usually the first step, and the return value can be:
+ * (largest value for this protocol) + (return value from other protocol)
+ *
+ * @param c the client context
+ * @return >= 0 on success or a negative value corresponding
+ * to an AVERROR code on failure
+ */
+int ffurl_handshake(URLContext *c);
+
+/**
* Read up to size bytes from the resource accessed by h, and store
* the read bytes in buf.
*
diff --git a/chromium/third_party/ffmpeg/libavformat/utils.c b/chromium/third_party/ffmpeg/libavformat/utils.c
index caa15abbaed..24eacf39675 100644
--- a/chromium/third_party/ffmpeg/libavformat/utils.c
+++ b/chromium/third_party/ffmpeg/libavformat/utils.c
@@ -116,7 +116,10 @@ MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb)
int64_t av_stream_get_end_pts(const AVStream *st)
{
- return st->pts.val;
+ if (st->priv_pts) {
+ return st->priv_pts->val;
+ } else
+ return AV_NOPTS_VALUE;
}
struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
@@ -1262,12 +1265,6 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
out_pkt.buf = pkt->buf;
pkt->buf = NULL;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- out_pkt.destruct = pkt->destruct;
- pkt->destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
}
if ((ret = av_dup_packet(&out_pkt)) < 0)
goto fail;
@@ -1585,26 +1582,26 @@ int av_find_default_stream_index(AVFormatContext *s)
int i;
AVStream *st;
int best_stream = 0;
- int best_score = -1;
+ int best_score = INT_MIN;
if (s->nb_streams <= 0)
return -1;
for (i = 0; i < s->nb_streams; i++) {
int score = 0;
st = s->streams[i];
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
- !(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
- if (!st->codec->width && !st->codec->height && !st->codec_info_nb_frames)
- score += 25;
- else
- score += 100;
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
+ score -= 400;
+ if (st->codec->width && st->codec->height)
+ score += 50;
+ score+= 25;
}
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (!st->codec->sample_rate && !st->codec_info_nb_frames)
- score += 12;
- else
+ if (st->codec->sample_rate)
score += 50;
}
+ if (st->codec_info_nb_frames)
+ score += 12;
if (st->discard != AVDISCARD_ALL)
score += 200;
@@ -1781,6 +1778,63 @@ int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries,
return m;
}
+void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
+{
+ int ist1, ist2;
+ int64_t pos_delta = 0;
+ int64_t skip = 0;
+ //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
+ const char *proto = avio_find_protocol_name(s->filename);
+
+ if (!proto) {
+ av_log(s, AV_LOG_INFO,
+ "Protocol name not provided, cannot determine if input is local or "
+ "a network protocol, buffers and access patterns cannot be configured "
+ "optimally without knowing the protocol\n");
+ }
+
+ if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache")))
+ return;
+
+ for (ist1 = 0; ist1 < s->nb_streams; ist1++) {
+ AVStream *st1 = s->streams[ist1];
+ for (ist2 = 0; ist2 < s->nb_streams; ist2++) {
+ AVStream *st2 = s->streams[ist2];
+ int i1, i2;
+
+ if (ist1 == ist2)
+ continue;
+
+ for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
+ AVIndexEntry *e1 = &st1->index_entries[i1];
+ int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
+
+ skip = FFMAX(skip, e1->size);
+ for (; i2 < st2->nb_index_entries; i2++) {
+ AVIndexEntry *e2 = &st2->index_entries[i2];
+ int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
+ if (e2_pts - e1_pts < time_tolerance)
+ continue;
+ pos_delta = FFMAX(pos_delta, e1->pos - e2->pos);
+ break;
+ }
+ }
+ }
+ }
+
+ pos_delta *= 2;
+ /* XXX This could be adjusted depending on protocol*/
+ if (s->pb->buffer_size < pos_delta && pos_delta < (1<<24)) {
+ av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta);
+ ffio_set_buf_size(s->pb, pos_delta);
+ s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2);
+ }
+
+ if (skip < (1<<23)) {
+ s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, skip);
+ }
+}
+
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
{
return ff_index_search_timestamp(st->index_entries, st->nb_index_entries,
@@ -2665,7 +2719,7 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
ret >= 0 &&
(!has_codec_parameters(st, NULL) || !has_decode_delay_been_guessed(st) ||
(!st->codec_info_nb_frames &&
- st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
+ (st->codec->codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)))) {
got_picture = 0;
switch (st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
@@ -2865,14 +2919,14 @@ int ff_alloc_extradata(AVCodecContext *avctx, int size)
{
int ret;
- if (size < 0 || size >= INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+ if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
avctx->extradata = NULL;
avctx->extradata_size = 0;
return AVERROR(EINVAL);
}
- avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ avctx->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
if (avctx->extradata) {
- memset(avctx->extradata + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(avctx->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
avctx->extradata_size = size;
ret = 0;
} else {
@@ -3031,9 +3085,18 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
// new streams might appear, no options for those
int orig_nb_streams = ic->nb_streams;
int flush_codecs;
+#if FF_API_PROBESIZE_32
int64_t max_analyze_duration = ic->max_analyze_duration2;
+#else
+ int64_t max_analyze_duration = ic->max_analyze_duration;
+#endif
int64_t max_stream_analyze_duration;
+ int64_t max_subtitle_analyze_duration;
+#if FF_API_PROBESIZE_32
int64_t probesize = ic->probesize2;
+#else
+ int64_t probesize = ic->probesize;
+#endif
if (!max_analyze_duration)
max_analyze_duration = ic->max_analyze_duration;
@@ -3044,11 +3107,13 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
max_stream_analyze_duration = max_analyze_duration;
+ max_subtitle_analyze_duration = max_analyze_duration;
if (!max_analyze_duration) {
max_stream_analyze_duration =
max_analyze_duration = 5*AV_TIME_BASE;
+ max_subtitle_analyze_duration = 30*AV_TIME_BASE;
if (!strcmp(ic->iformat->name, "flv"))
- max_stream_analyze_duration = 30*AV_TIME_BASE;
+ max_stream_analyze_duration = 90*AV_TIME_BASE;
}
if (ic->pb)
@@ -3264,6 +3329,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
}
if (st->codec_info_nb_frames>1) {
int64_t t = 0;
+ int64_t limit;
if (st->time_base.den > 0)
t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q);
@@ -3276,10 +3342,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
&& st->info->fps_last_dts != AV_NOPTS_VALUE)
t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
- if (t >= (analyzed_all_streams ? max_analyze_duration : max_stream_analyze_duration)) {
- av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds\n",
- max_analyze_duration,
- t);
+ if (analyzed_all_streams) limit = max_analyze_duration;
+ else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration;
+ else limit = max_stream_analyze_duration;
+
+ if (t >= limit) {
+ av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds st:%d\n",
+ limit,
+ t, pkt->stream_index);
if (ic->flags & AVFMT_FLAG_NOBUFFER)
av_packet_unref(pkt);
break;
@@ -3308,7 +3378,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
* it takes longer and uses more memory. For MPEG-4, we need to
* decompress for QuickTime.
*
- * If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
+ * If AV_CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
* least one frame of codec data, this makes sure the codec initializes
* the channel configuration and does not only trust the values from
* the container. */
@@ -3603,6 +3673,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st) {
av_freep(&st->info->duration_error);
av_freep(&st->info);
av_freep(&st->recommended_encoder_configuration);
+ av_freep(&st->priv_pts);
av_freep(&s->streams[ --s->nb_streams ]);
}
@@ -4235,8 +4306,9 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
if (*spec <= '9' && *spec >= '0') /* opt:index */
return strtol(spec, NULL, 0) == st->index;
else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
- *spec == 't') { /* opt:[vasdt] */
+ *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
enum AVMediaType type;
+ int nopic = 0;
switch (*spec++) {
case 'v': type = AVMEDIA_TYPE_VIDEO; break;
@@ -4244,15 +4316,20 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
case 'd': type = AVMEDIA_TYPE_DATA; break;
case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+ case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
default: av_assert0(0);
}
if (type != st->codec->codec_type)
return 0;
+ if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ return 0;
if (*spec++ == ':') { /* possibly followed by :index */
int i, index = strtol(spec, NULL, 0);
for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->codec->codec_type == type && index-- == 0)
- return i == st->index;
+ if (s->streams[i]->codec->codec_type == type &&
+ !(nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC)) &&
+ index-- == 0)
+ return i == st->index;
return 0;
}
return 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/version.h b/chromium/third_party/ffmpeg/libavformat/version.h
index 99b71906ba7..18be8b26b61 100644
--- a/chromium/third_party/ffmpeg/libavformat/version.h
+++ b/chromium/third_party/ffmpeg/libavformat/version.h
@@ -29,8 +29,8 @@
#include "libavutil/version.h"
-#define LIBAVFORMAT_VERSION_MAJOR 56
-#define LIBAVFORMAT_VERSION_MINOR 37
+#define LIBAVFORMAT_VERSION_MAJOR 57
+#define LIBAVFORMAT_VERSION_MINOR 0
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -47,18 +47,26 @@
* FF_API_* defines may be placed below to indicate public API that will be
* dropped at a future version bump. The defines themselves are not part of
* the public API and may change, break or disappear at any time.
+ *
+ * @note, when bumping the major version it is recommended to manually
+ * disable each FF_API_* in its own commit instead of disabling them all
+ * at once through the bump. This improves the git bisect-ability of the change.
+ *
*/
#ifndef FF_API_LAVF_BITEXACT
-#define FF_API_LAVF_BITEXACT (LIBAVFORMAT_VERSION_MAJOR < 57)
+#define FF_API_LAVF_BITEXACT (LIBAVFORMAT_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_LAVF_FRAC
-#define FF_API_LAVF_FRAC (LIBAVFORMAT_VERSION_MAJOR < 57)
+#define FF_API_LAVF_FRAC (LIBAVFORMAT_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_LAVF_CODEC_TB
-#define FF_API_LAVF_CODEC_TB (LIBAVFORMAT_VERSION_MAJOR < 57)
+#define FF_API_LAVF_CODEC_TB (LIBAVFORMAT_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_URL_FEOF
-#define FF_API_URL_FEOF (LIBAVFORMAT_VERSION_MAJOR < 57)
+#define FF_API_URL_FEOF (LIBAVFORMAT_VERSION_MAJOR < 58)
+#endif
+#ifndef FF_API_PROBESIZE_32
+#define FF_API_PROBESIZE_32 (LIBAVFORMAT_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_R_FRAME_RATE
diff --git a/chromium/third_party/ffmpeg/libavformat/vplayerdec.c b/chromium/third_party/ffmpeg/libavformat/vplayerdec.c
index 619ccfd4f06..860b7785c9c 100644
--- a/chromium/third_party/ffmpeg/libavformat/vplayerdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/vplayerdec.c
@@ -90,7 +90,7 @@ static int vplayer_read_header(AVFormatContext *s)
}
}
- ff_subtitles_queue_finalize(&vplayer->q);
+ ff_subtitles_queue_finalize(s, &vplayer->q);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/wavdec.c b/chromium/third_party/ffmpeg/libavformat/wavdec.c
index 864185f989b..ef24e1672c7 100644
--- a/chromium/third_party/ffmpeg/libavformat/wavdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/wavdec.c
@@ -134,7 +134,7 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
if (!*st)
return AVERROR(ENOMEM);
- ret = ff_get_wav_header(pb, (*st)->codec, size, wav->rifx);
+ ret = ff_get_wav_header(s, pb, (*st)->codec, size, wav->rifx);
if (ret < 0)
return ret;
handle_stream_probing(*st);
@@ -429,8 +429,29 @@ break_loop:
avio_seek(pb, data_ofs, SEEK_SET);
+ if (data_size > (INT64_MAX>>3)) {
+ av_log(s, AV_LOG_WARNING, "Data size %"PRId64" is too large\n", data_size);
+ data_size = 0;
+ }
+
+ if ( st->codec->bit_rate > 0 && data_size > 0
+ && st->codec->sample_rate > 0
+ && sample_count > 0 && st->codec->channels > 1
+ && sample_count % st->codec->channels == 0) {
+ if (fabs(8.0 * data_size * st->codec->channels * st->codec->sample_rate /
+ sample_count /st->codec->bit_rate - 1.0) < 0.3)
+ sample_count /= st->codec->channels;
+ }
+
if ( data_size > 0 && sample_count && st->codec->channels
- && data_size / sample_count / st->codec->channels > 8) {
+ && (data_size << 3) / sample_count / st->codec->channels > st->codec->bits_per_coded_sample + 1) {
+ av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
+ sample_count = 0;
+ }
+
+ /* G.729 hack (for Ticket4577)
+ * FIXME: Come up with cleaner, more general solution */
+ if (st->codec->codec_id == AV_CODEC_ID_G729 && sample_count && (data_size << 3) > sample_count) {
av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
sample_count = 0;
}
@@ -615,7 +636,7 @@ static int wav_read_seek(AVFormatContext *s,
#define OFFSET(x) offsetof(WAVDemuxContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption demux_options[] = {
- { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC },
+ { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC },
{ NULL },
};
@@ -689,7 +710,7 @@ static int w64_read_header(AVFormatContext *s)
if (!memcmp(guid, ff_w64_guid_fmt, 16)) {
/* subtract chunk header size - normal wav file doesn't count it */
- ret = ff_get_wav_header(pb, st->codec, size - 24, 0);
+ ret = ff_get_wav_header(s, pb, st->codec, size - 24, 0);
if (ret < 0)
return ret;
avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
diff --git a/chromium/third_party/ffmpeg/libavformat/wavenc.c b/chromium/third_party/ffmpeg/libavformat/wavenc.c
index f89c91e8c73..0156f6e8a3b 100644
--- a/chromium/third_party/ffmpeg/libavformat/wavenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/wavenc.c
@@ -502,7 +502,7 @@ static int wav_write_trailer(AVFormatContext *s)
#define OFFSET(x) offsetof(WAVMuxContext, x)
#define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
+ { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
{ "write_peak", "Write Peak Envelope chunk.", OFFSET(write_peak), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, ENC, "peak" },
{ "off", "Do not write peak chunk.", 0, AV_OPT_TYPE_CONST, { .i64 = PEAK_OFF }, 0, 0, ENC, "peak" },
{ "on", "Append peak chunk after wav data.", 0, AV_OPT_TYPE_CONST, { .i64 = PEAK_ON }, 0, 0, ENC, "peak" },
diff --git a/chromium/third_party/ffmpeg/libavformat/webmdashenc.c b/chromium/third_party/ffmpeg/libavformat/webmdashenc.c
index 76ea4237e2b..898e4641d37 100644
--- a/chromium/third_party/ffmpeg/libavformat/webmdashenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/webmdashenc.c
@@ -392,10 +392,10 @@ static int write_adaptation_set(AVFormatContext *s, int as_index)
if (w->is_live) {
AVDictionaryEntry *filename =
av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0);
- if (!filename ||
- (ret = parse_filename(filename->value, &representation_id, NULL, NULL))) {
+ if (!filename)
+ return AVERROR(EINVAL);
+ if (ret = parse_filename(filename->value, &representation_id, NULL, NULL))
return ret;
- }
} else {
representation_id = av_asprintf("%d", w->representation_id++);
if (!representation_id) return AVERROR(ENOMEM);
diff --git a/chromium/third_party/ffmpeg/libavformat/webvttdec.c b/chromium/third_party/ffmpeg/libavformat/webvttdec.c
index e457e8f6d21..43c2a639ad3 100644
--- a/chromium/third_party/ffmpeg/libavformat/webvttdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/webvttdec.c
@@ -161,7 +161,7 @@ static int webvtt_read_header(AVFormatContext *s)
SET_SIDE_DATA(settings, AV_PKT_DATA_WEBVTT_SETTINGS);
}
- ff_subtitles_queue_finalize(&webvtt->q);
+ ff_subtitles_queue_finalize(s, &webvtt->q);
end:
av_bprint_finalize(&cue, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/webvttenc.c b/chromium/third_party/ffmpeg/libavformat/webvttenc.c
index b93993d55ce..c3865387186 100644
--- a/chromium/third_party/ffmpeg/libavformat/webvttenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/webvttenc.c
@@ -46,8 +46,14 @@ static void webvtt_write_time(AVIOContext *pb, int64_t millisec)
static int webvtt_write_header(AVFormatContext *ctx)
{
AVStream *s = ctx->streams[0];
+ AVCodecContext *avctx = ctx->streams[0]->codec;
AVIOContext *pb = ctx->pb;
+ if (ctx->nb_streams != 1 || avctx->codec_id != AV_CODEC_ID_WEBVTT) {
+ av_log(ctx, AV_LOG_ERROR, "Exactly one WebVTT stream is needed.\n");
+ return AVERROR(EINVAL);
+ }
+
avpriv_set_pts_info(s, 64, 1, 1000);
avio_printf(pb, "WEBVTT\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/wtvdec.c b/chromium/third_party/ffmpeg/libavformat/wtvdec.c
index e226690283c..e8f6196a5ed 100644
--- a/chromium/third_party/ffmpeg/libavformat/wtvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/wtvdec.c
@@ -670,7 +670,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
if (!st)
return NULL;
if (!ff_guidcmp(formattype, ff_format_waveformatex)) {
- int ret = ff_get_wav_header(pb, st->codec, size, 0);
+ int ret = ff_get_wav_header(s, pb, st->codec, size, 0);
if (ret < 0)
return NULL;
} else {
diff --git a/chromium/third_party/ffmpeg/libavformat/xwma.c b/chromium/third_party/ffmpeg/libavformat/xwma.c
index 683d3d0d4d2..9edad7d75ac 100644
--- a/chromium/third_party/ffmpeg/libavformat/xwma.c
+++ b/chromium/third_party/ffmpeg/libavformat/xwma.c
@@ -75,7 +75,7 @@ static int xwma_read_header(AVFormatContext *s)
if (!st)
return AVERROR(ENOMEM);
- ret = ff_get_wav_header(pb, st->codec, size, 0);
+ ret = ff_get_wav_header(s, pb, st->codec, size, 0);
if (ret < 0)
return ret;
st->need_parsing = AVSTREAM_PARSE_NONE;
diff --git a/chromium/third_party/ffmpeg/libavformat/yop.c b/chromium/third_party/ffmpeg/libavformat/yop.c
index 81b3cc2b32b..64779d4fb75 100644
--- a/chromium/third_party/ffmpeg/libavformat/yop.c
+++ b/chromium/third_party/ffmpeg/libavformat/yop.c
@@ -132,11 +132,6 @@ static int yop_read_packet(AVFormatContext *s, AVPacket *pkt)
*pkt = yop->video_packet;
yop->video_packet.data = NULL;
yop->video_packet.buf = NULL;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- yop->video_packet.destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
yop->video_packet.size = 0;
pkt->data[0] = yop->odd_frame;
pkt->flags |= AV_PKT_FLAG_KEY;
diff --git a/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.h b/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.h
index 750f4984076..eba7337fe6c 100644
--- a/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.h
+++ b/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.h
@@ -23,5 +23,6 @@
#define Y4M_MAGIC "YUV4MPEG2"
#define Y4M_FRAME_MAGIC "FRAME"
+#define Y4M_FRAME_MAGIC_LEN 6
#endif /* AVFORMAT_YUV4MPEG_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/yuv4mpegdec.c b/chromium/third_party/ffmpeg/libavformat/yuv4mpegdec.c
index 7613c3cdc36..0db42f5933b 100644
--- a/chromium/third_party/ffmpeg/libavformat/yuv4mpegdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/yuv4mpegdec.c
@@ -256,6 +256,12 @@ static int yuv4_read_header(AVFormatContext *s)
st->sample_aspect_ratio = (AVRational){ aspectn, aspectd };
st->codec->chroma_sample_location = chroma_sample_location;
st->codec->field_order = field_order;
+ s->packet_size = avpicture_get_size(st->codec->pix_fmt, width, height) + Y4M_FRAME_MAGIC_LEN;
+ if ((int) s->packet_size < 0)
+ return s->packet_size;
+ s->internal->data_offset = avio_tell(pb);
+
+ st->duration = (avio_size(pb) - avio_tell(pb)) / s->packet_size;
return 0;
}
@@ -264,8 +270,8 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int i;
char header[MAX_FRAME_HEADER+1];
- int packet_size, width, height, ret;
- AVStream *st = s->streams[0];
+ int ret;
+ int64_t off = avio_tell(s->pb);
for (i = 0; i < MAX_FRAME_HEADER; i++) {
header[i] = avio_r8(s->pb);
@@ -284,20 +290,22 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC)))
return AVERROR_INVALIDDATA;
- width = st->codec->width;
- height = st->codec->height;
-
- packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);
- if (packet_size < 0)
- return packet_size;
-
- ret = av_get_packet(s->pb, pkt, packet_size);
+ ret = av_get_packet(s->pb, pkt, s->packet_size - Y4M_FRAME_MAGIC_LEN);
if (ret < 0)
return ret;
- else if (ret != packet_size)
+ else if (ret != s->packet_size - Y4M_FRAME_MAGIC_LEN)
return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO);
pkt->stream_index = 0;
+ pkt->pts = (off - s->internal->data_offset) / s->packet_size;
+ pkt->duration = 1;
+ return 0;
+}
+
+static int yuv4_read_seek(AVFormatContext *s, int stream_index,
+ int64_t pts, int flags)
+{
+ avio_seek(s->pb, pts * s->packet_size + s->internal->data_offset, SEEK_SET);
return 0;
}
@@ -316,5 +324,6 @@ AVInputFormat ff_yuv4mpegpipe_demuxer = {
.read_probe = yuv4_probe,
.read_header = yuv4_read_header,
.read_packet = yuv4_read_packet,
+ .read_seek = yuv4_read_seek,
.extensions = "y4m",
};
diff --git a/chromium/third_party/ffmpeg/libavformat/yuv4mpegenc.c b/chromium/third_party/ffmpeg/libavformat/yuv4mpegenc.c
index cc954fcc630..c15ea1de0cb 100644
--- a/chromium/third_party/ffmpeg/libavformat/yuv4mpegenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/yuv4mpegenc.c
@@ -143,7 +143,6 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
int width, height, h_chroma_shift, v_chroma_shift;
int i;
char buf2[Y4M_LINE_MAX + 1];
- char buf1[20];
uint8_t *ptr, *ptr1, *ptr2;
memcpy(&picture_tmp, pkt->data, sizeof(AVPicture));
@@ -163,8 +162,7 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
/* construct frame header */
- snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
- avio_write(pb, buf1, strlen(buf1));
+ avio_printf(s->pb, "%s\n", Y4M_FRAME_MAGIC);
width = st->codec->width;
height = st->codec->height;