summaryrefslogtreecommitdiff
path: root/chromium/third_party/ffmpeg/libavformat
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-29 10:46:47 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-02 12:02:10 +0000
commit99677208ff3b216fdfec551fbe548da5520cd6fb (patch)
tree476a4865c10320249360e859d8fdd3e01833b03a /chromium/third_party/ffmpeg/libavformat
parentc30a6232df03e1efbd9f3b226777b07e087a1122 (diff)
downloadqtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat')
-rw-r--r--chromium/third_party/ffmpeg/libavformat/3dostr.c13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/4xm.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/Makefile12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aacdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aadec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/adtsenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aiffdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aiffenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/allformats.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ape.c35
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apm.c247
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apngenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aqtitledec.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/argo_asf.c215
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfdec_f.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfdec_o.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/assdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/async.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/au.c78
-rw-r--r--chromium/third_party/ffmpeg/libavformat/audiointerleave.c148
-rw-r--r--chromium/third_party/ffmpeg/libavformat/audiointerleave.h56
-rw-r--r--chromium/third_party/ffmpeg/libavformat/av1.c18
-rw-r--r--chromium/third_party/ffmpeg/libavformat/av1dec.c323
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avc.c31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avc.h4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avformat.h5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avienc.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avio.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aviobuf.c71
-rw-r--r--chromium/third_party/ffmpeg/libavformat/cache.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/concat.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/concatdec.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/crypto.c15
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dashdec.c46
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dashenc.c104
-rw-r--r--chromium/third_party/ffmpeg/libavformat/daudenc.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dsfdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dump.c155
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dv.c86
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dvenc.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/fifo.c59
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flac_picture.c47
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flac_picture.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacenc.c18
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flvdec.c36
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flvenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ftp.c14
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gifdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gopher.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gxfenc.c31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hdsenc.c33
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hevc.c18
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hls.c68
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsenc.c631
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsplaylist.c49
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsplaylist.h32
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsproto.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/http.c10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/icecast.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/id3v2.c64
-rw-r--r--chromium/third_party/ffmpeg/libavformat/id3v2.h25
-rw-r--r--chromium/third_party/ffmpeg/libavformat/iff.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2dec.c21
-rw-r--r--chromium/third_party/ffmpeg/libavformat/internal.h14
-rw-r--r--chromium/third_party/ffmpeg/libavformat/isom.c160
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ivfenc.c37
-rw-r--r--chromium/third_party/ffmpeg/libavformat/jacosubdec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/kvag.c82
-rw-r--r--chromium/third_party/ffmpeg/libavformat/latmenc.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libamqp.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libsrt.c22
-rw-r--r--chromium/third_party/ffmpeg/libavformat/lrcdec.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskadec.c300
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskaenc.c1006
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mccdec.c238
-rw-r--r--chromium/third_party/ffmpeg/libavformat/microdvddec.c21
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mlvdec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mmsh.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mmst.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mov.c334
-rw-r--r--chromium/third_party/ffmpeg/libavformat/movenc.c93
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mp3enc.c15
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpeg.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegts.c74
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegts.h7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegtsenc.c234
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpl2dec.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpsubdec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mux.c328
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mvdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxf.c49
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxf.h3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxfdec.c44
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxfenc.c96
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nutenc.c234
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggdec.c279
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggdec.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggenc.c74
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparsedaala.c261
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparseopus.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/omadec.c57
-rw-r--r--chromium/third_party/ffmpeg/libavformat/options.c64
-rw-r--r--chromium/third_party/ffmpeg/libavformat/pjsdec.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/pp_bnk.c292
-rw-r--r--chromium/third_party/ffmpeg/libavformat/prompeg.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/protocols.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rawdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rawdec.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riffenc.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmpcrypt.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmphttp.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmpproto.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpproto.c13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtsp.c17
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtspdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/samidec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sapdec.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sapenc.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sbgdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sccdec.c109
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sdp.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segafilm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segafilmenc.c234
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segment.c20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sierravmd.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/smacker.c225
-rw-r--r--chromium/third_party/ffmpeg/libavformat/smjpegdec.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c70
-rw-r--r--chromium/third_party/ffmpeg/libavformat/srtdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/srtpproto.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/stldec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subfile.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subviewer1dec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subviewerdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/swfenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tee.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/thp.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tls_gnutls.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tls_libtls.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tls_openssl.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tls_schannel.c12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tls_securetransport.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ttaenc.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ty.c68
-rw-r--r--chromium/third_party/ffmpeg/libavformat/udp.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/url.c266
-rw-r--r--chromium/third_party/ffmpeg/libavformat/url.h49
-rw-r--r--chromium/third_party/ffmpeg/libavformat/utils.c38
-rw-r--r--chromium/third_party/ffmpeg/libavformat/version.h4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vividas.c28
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vorbiscomment.c52
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vorbiscomment.h11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vplayerdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wavdec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wavenc.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webm_chunk.c26
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webmdashenc.c324
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webvttdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wtvenc.c2
169 files changed, 5247 insertions, 3927 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/3dostr.c b/chromium/third_party/ffmpeg/libavformat/3dostr.c
index 6c49f7589c4..3ec3c4393eb 100644
--- a/chromium/third_party/ffmpeg/libavformat/3dostr.c
+++ b/chromium/third_party/ffmpeg/libavformat/3dostr.c
@@ -110,15 +110,12 @@ static int threedostr_read_header(AVFormatContext *s)
static int threedostr_read_packet(AVFormatContext *s, AVPacket *pkt)
{
- unsigned chunk, size, found_ssmp = 0;
+ unsigned chunk, size;
AVStream *st = s->streams[0];
int64_t pos;
int ret = 0;
- while (!found_ssmp) {
- if (avio_feof(s->pb))
- return AVERROR_EOF;
-
+ while (!avio_feof(s->pb)) {
pos = avio_tell(s->pb);
chunk = avio_rl32(s->pb);
size = avio_rb32(s->pb);
@@ -143,9 +140,7 @@ static int threedostr_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pos = pos;
pkt->stream_index = 0;
pkt->duration = size / st->codecpar->channels;
- size = 0;
- found_ssmp = 1;
- break;
+ return ret;
default:
av_log(s, AV_LOG_DEBUG, "skipping unknown chunk: %X\n", chunk);
break;
@@ -154,7 +149,7 @@ static int threedostr_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_skip(s->pb, size);
}
- return ret;
+ return AVERROR_EOF;
}
AVInputFormat ff_threedostr_demuxer = {
diff --git a/chromium/third_party/ffmpeg/libavformat/4xm.c b/chromium/third_party/ffmpeg/libavformat/4xm.c
index aea9226984e..6a227a0b0d2 100644
--- a/chromium/third_party/ffmpeg/libavformat/4xm.c
+++ b/chromium/third_party/ffmpeg/libavformat/4xm.c
@@ -59,8 +59,10 @@
#define GET_LIST_HEADER() \
fourcc_tag = avio_rl32(pb); \
size = avio_rl32(pb); \
- if (fourcc_tag != LIST_TAG) \
- return AVERROR_INVALIDDATA; \
+ if (fourcc_tag != LIST_TAG) { \
+ ret = AVERROR_INVALIDDATA; \
+ goto fail; \
+ } \
fourcc_tag = avio_rl32(pb);
typedef struct AudioTrack {
@@ -210,12 +212,13 @@ static int fourxm_read_header(AVFormatContext *s)
unsigned int size;
int header_size;
FourxmDemuxContext *fourxm = s->priv_data;
- unsigned char *header;
+ unsigned char *header = NULL;
int i, ret;
fourxm->track_count = 0;
fourxm->tracks = NULL;
fourxm->fps = (AVRational){1,1};
+ fourxm->video_stream_index = -1;
/* skip the first 3 32-bit numbers */
avio_skip(pb, 12);
@@ -324,6 +327,8 @@ static int fourxm_read_packet(AVFormatContext *s,
* and size */
if (size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 8)
return AVERROR_INVALIDDATA;
+ if (fourxm->video_stream_index < 0)
+ return AVERROR_INVALIDDATA;
if ((ret = av_new_packet(pkt, size + 8)) < 0)
return ret;
pkt->stream_index = fourxm->video_stream_index;
diff --git a/chromium/third_party/ffmpeg/libavformat/Makefile b/chromium/third_party/ffmpeg/libavformat/Makefile
index d4bed3c1137..cbb33fe37c1 100644
--- a/chromium/third_party/ffmpeg/libavformat/Makefile
+++ b/chromium/third_party/ffmpeg/libavformat/Makefile
@@ -94,6 +94,7 @@ OBJS-$(CONFIG_ANM_DEMUXER) += anm.o
OBJS-$(CONFIG_APC_DEMUXER) += apc.o
OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o img2.o
OBJS-$(CONFIG_APM_DEMUXER) += apm.o
+OBJS-$(CONFIG_APM_MUXER) += apm.o rawenc.o
OBJS-$(CONFIG_APNG_DEMUXER) += apngdec.o
OBJS-$(CONFIG_APNG_MUXER) += apngenc.o
OBJS-$(CONFIG_APTX_DEMUXER) += aptxdec.o rawdec.o
@@ -102,6 +103,7 @@ OBJS-$(CONFIG_APTX_HD_DEMUXER) += aptxdec.o rawdec.o
OBJS-$(CONFIG_APTX_HD_MUXER) += rawenc.o
OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o
OBJS-$(CONFIG_ARGO_ASF_DEMUXER) += argo_asf.o
+OBJS-$(CONFIG_ARGO_ASF_MUXER) += argo_asf.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 \
@@ -205,7 +207,7 @@ OBJS-$(CONFIG_GIF_DEMUXER) += gifdec.o
OBJS-$(CONFIG_GSM_DEMUXER) += gsmdec.o
OBJS-$(CONFIG_GSM_MUXER) += rawenc.o
OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o
-OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o
+OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o
OBJS-$(CONFIG_G722_DEMUXER) += g722.o rawdec.o
OBJS-$(CONFIG_G722_MUXER) += rawenc.o
OBJS-$(CONFIG_G723_1_DEMUXER) += g723_1.o
@@ -285,6 +287,7 @@ OBJS-$(CONFIG_JACOSUB_MUXER) += jacosubenc.o rawenc.o
OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o
OBJS-$(CONFIG_KUX_DEMUXER) += flvdec.o
OBJS-$(CONFIG_KVAG_DEMUXER) += kvag.o
+OBJS-$(CONFIG_KVAG_MUXER) += kvag.o rawenc.o
OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o
OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o
OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o rawdec.o
@@ -302,6 +305,7 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \
av1.o avc.o hevc.o \
flacenc_header.o avlanguage.o \
vorbiscomment.o wv.o
+OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o
OBJS-$(CONFIG_MD5_MUXER) += hashenc.o
OBJS-$(CONFIG_MGSTS_DEMUXER) += mgsts.o
OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o subtitles.o
@@ -347,7 +351,7 @@ OBJS-$(CONFIG_MUSX_DEMUXER) += musx.o
OBJS-$(CONFIG_MV_DEMUXER) += mvdec.o
OBJS-$(CONFIG_MVI_DEMUXER) += mvi.o
OBJS-$(CONFIG_MXF_DEMUXER) += mxfdec.o mxf.o
-OBJS-$(CONFIG_MXF_MUXER) += mxfenc.o mxf.o audiointerleave.o avc.o
+OBJS-$(CONFIG_MXF_MUXER) += mxfenc.o mxf.o avc.o
OBJS-$(CONFIG_MXG_DEMUXER) += mxg.o
OBJS-$(CONFIG_NC_DEMUXER) += ncdec.o
OBJS-$(CONFIG_NISTSPHERE_DEMUXER) += nistspheredec.o pcm.o
@@ -358,9 +362,9 @@ OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o isom.o
OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o
OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o
OBJS-$(CONFIG_AV1_DEMUXER) += av1dec.o
+OBJS-$(CONFIG_OBU_DEMUXER) += av1dec.o
OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
oggparsecelt.o \
- oggparsedaala.o \
oggparsedirac.o \
oggparseflac.o \
oggparseogm.o \
@@ -428,6 +432,7 @@ OBJS-$(CONFIG_PCM_VIDC_DEMUXER) += pcmdec.o pcm.o
OBJS-$(CONFIG_PCM_VIDC_MUXER) += pcmenc.o rawenc.o
OBJS-$(CONFIG_PJS_DEMUXER) += pjsdec.o subtitles.o
OBJS-$(CONFIG_PMP_DEMUXER) += pmpdec.o
+OBJS-$(CONFIG_PP_BNK_DEMUXER) += pp_bnk.o
OBJS-$(CONFIG_PVA_DEMUXER) += pva.o
OBJS-$(CONFIG_PVF_DEMUXER) += pvfdec.o pcm.o
OBJS-$(CONFIG_QCP_DEMUXER) += qcp.o
@@ -669,3 +674,4 @@ TOOLS = aviocat \
probetest \
seek_print \
sidxindex \
+ venc_data_dump
diff --git a/chromium/third_party/ffmpeg/libavformat/aacdec.c b/chromium/third_party/ffmpeg/libavformat/aacdec.c
index ba3f5ccc6dd..a0aa112a8a2 100644
--- a/chromium/third_party/ffmpeg/libavformat/aacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aacdec.c
@@ -146,7 +146,7 @@ static int handle_id3(AVFormatContext *s, AVPacket *pkt)
ffio_init_context(&ioctx, pkt->data, pkt->size, 0, NULL, NULL, NULL, NULL);
ff_id3v2_read_dict(&ioctx, &metadata, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
- if ((ret = ff_id3v2_parse_priv_dict(&metadata, &id3v2_extra_meta)) < 0)
+ if ((ret = ff_id3v2_parse_priv_dict(&metadata, id3v2_extra_meta)) < 0)
goto error;
if (metadata) {
diff --git a/chromium/third_party/ffmpeg/libavformat/aadec.c b/chromium/third_party/ffmpeg/libavformat/aadec.c
index b9dd51ebfc3..63f8176a570 100644
--- a/chromium/third_party/ffmpeg/libavformat/aadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aadec.c
@@ -92,7 +92,7 @@ static int aa_read_header(AVFormatContext *s)
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)
+ if (toc_size > MAX_TOC_ENTRIES || toc_size < 2)
return AVERROR_INVALIDDATA;
for (i = 0; i < toc_size; i++) { // read TOC
avio_skip(pb, 4); // TOC entry index
diff --git a/chromium/third_party/ffmpeg/libavformat/adtsenc.c b/chromium/third_party/ffmpeg/libavformat/adtsenc.c
index d937e2bea9c..9e285752eb5 100644
--- a/chromium/third_party/ffmpeg/libavformat/adtsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/adtsenc.c
@@ -169,7 +169,7 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
if (!par->extradata_size) {
uint8_t *side_data;
- int side_data_size = 0, ret;
+ int side_data_size, ret;
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
&side_data_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/aiffdec.c b/chromium/third_party/ffmpeg/libavformat/aiffdec.c
index cb2f1b60fbe..c650e9074d5 100644
--- a/chromium/third_party/ffmpeg/libavformat/aiffdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aiffdec.c
@@ -261,8 +261,8 @@ static int aiff_read_header(AVFormatContext *s)
position = avio_tell(pb);
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size);
if (id3v2_extra_meta)
- if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0 ||
- (ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) {
+ if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0 ||
+ (ret = ff_id3v2_parse_chapters(s, id3v2_extra_meta)) < 0) {
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/aiffenc.c b/chromium/third_party/ffmpeg/libavformat/aiffenc.c
index 0145596bec8..88c45df3347 100644
--- a/chromium/third_party/ffmpeg/libavformat/aiffenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/aiffenc.c
@@ -49,7 +49,7 @@ static int put_id3v2_tags(AVFormatContext *s, AIFFOutputContext *aiff)
AVIOContext *pb = s->pb;
AVPacketList *pict_list = aiff->pict_list;
- if (!s->metadata && !aiff->pict_list)
+ if (!s->metadata && !s->nb_chapters && !aiff->pict_list)
return 0;
avio_wl32(pb, MKTAG('I', 'D', '3', ' '));
diff --git a/chromium/third_party/ffmpeg/libavformat/allformats.c b/chromium/third_party/ffmpeg/libavformat/allformats.c
index 39d2c352f57..0aa9dd71988 100644
--- a/chromium/third_party/ffmpeg/libavformat/allformats.c
+++ b/chromium/third_party/ffmpeg/libavformat/allformats.c
@@ -55,6 +55,7 @@ extern AVInputFormat ff_anm_demuxer;
extern AVInputFormat ff_apc_demuxer;
extern AVInputFormat ff_ape_demuxer;
extern AVInputFormat ff_apm_demuxer;
+extern AVOutputFormat ff_apm_muxer;
extern AVInputFormat ff_apng_demuxer;
extern AVOutputFormat ff_apng_muxer;
extern AVInputFormat ff_aptx_demuxer;
@@ -63,6 +64,7 @@ extern AVInputFormat ff_aptx_hd_demuxer;
extern AVOutputFormat ff_aptx_hd_muxer;
extern AVInputFormat ff_aqtitle_demuxer;
extern AVInputFormat ff_argo_asf_demuxer;
+extern AVOutputFormat ff_argo_asf_muxer;
extern AVInputFormat ff_asf_demuxer;
extern AVOutputFormat ff_asf_muxer;
extern AVInputFormat ff_asf_o_demuxer;
@@ -220,6 +222,7 @@ extern AVOutputFormat ff_jacosub_muxer;
extern AVInputFormat ff_jv_demuxer;
extern AVInputFormat ff_kux_demuxer;
extern AVInputFormat ff_kvag_demuxer;
+extern AVOutputFormat ff_kvag_muxer;
extern AVOutputFormat ff_latm_muxer;
extern AVInputFormat ff_lmlm4_demuxer;
extern AVInputFormat ff_loas_demuxer;
@@ -229,6 +232,7 @@ extern AVInputFormat ff_lvf_demuxer;
extern AVInputFormat ff_lxf_demuxer;
extern AVInputFormat ff_m4v_demuxer;
extern AVOutputFormat ff_m4v_muxer;
+extern AVInputFormat ff_mcc_demuxer;
extern AVOutputFormat ff_md5_muxer;
extern AVInputFormat ff_matroska_demuxer;
extern AVOutputFormat ff_matroska_muxer;
@@ -289,6 +293,7 @@ extern AVOutputFormat ff_null_muxer;
extern AVInputFormat ff_nut_demuxer;
extern AVOutputFormat ff_nut_muxer;
extern AVInputFormat ff_nuv_demuxer;
+extern AVInputFormat ff_obu_demuxer;
extern AVOutputFormat ff_oga_muxer;
extern AVInputFormat ff_ogg_demuxer;
extern AVOutputFormat ff_ogg_muxer;
@@ -341,6 +346,7 @@ extern AVInputFormat ff_pcm_u8_demuxer;
extern AVOutputFormat ff_pcm_u8_muxer;
extern AVInputFormat ff_pjs_demuxer;
extern AVInputFormat ff_pmp_demuxer;
+extern AVInputFormat ff_pp_bnk_demuxer;
extern AVOutputFormat ff_psp_muxer;
extern AVInputFormat ff_pva_demuxer;
extern AVInputFormat ff_pvf_demuxer;
@@ -485,6 +491,7 @@ extern AVInputFormat ff_image_pbm_pipe_demuxer;
extern AVInputFormat ff_image_pcx_pipe_demuxer;
extern AVInputFormat ff_image_pgmyuv_pipe_demuxer;
extern AVInputFormat ff_image_pgm_pipe_demuxer;
+extern AVInputFormat ff_image_pgx_pipe_demuxer;
extern AVInputFormat ff_image_pictor_pipe_demuxer;
extern AVInputFormat ff_image_png_pipe_demuxer;
extern AVInputFormat ff_image_ppm_pipe_demuxer;
diff --git a/chromium/third_party/ffmpeg/libavformat/ape.c b/chromium/third_party/ffmpeg/libavformat/ape.c
index ed6752a4150..d92cb2867dd 100644
--- a/chromium/third_party/ffmpeg/libavformat/ape.c
+++ b/chromium/third_party/ffmpeg/libavformat/ape.c
@@ -83,6 +83,8 @@ typedef struct APEContext {
uint8_t *bittable;
} APEContext;
+static int ape_read_close(AVFormatContext * s);
+
static int ape_probe(const AVProbeData * p)
{
int version = AV_RL16(p->buf+4);
@@ -251,7 +253,7 @@ static int ape_read_header(AVFormatContext * s)
avio_skip(pb, ape->wavheaderlength);
}
- if(!ape->totalframes){
+ if(!ape->totalframes || pb->eof_reached){
av_log(s, AV_LOG_ERROR, "No frames in the file!\n");
return AVERROR(EINVAL);
}
@@ -281,19 +283,26 @@ static int ape_read_header(AVFormatContext * s)
if (ape->seektablelength > 0) {
ape->seektable = av_mallocz(ape->seektablelength);
- if (!ape->seektable)
- return AVERROR(ENOMEM);
+ if (!ape->seektable) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
for (i = 0; i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; i++)
ape->seektable[i] = avio_rl32(pb);
if (ape->fileversion < 3810) {
ape->bittable = av_mallocz(ape->totalframes);
- if (!ape->bittable)
- return AVERROR(ENOMEM);
+ if (!ape->bittable) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
for (i = 0; i < ape->totalframes && !pb->eof_reached; i++)
ape->bittable[i] = avio_r8(pb);
}
- if (pb->eof_reached)
- av_log(s, AV_LOG_WARNING, "File truncated\n");
+ if (pb->eof_reached) {
+ av_log(s, AV_LOG_ERROR, "File truncated\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
}
ape->frames[0].pos = ape->firstframe;
@@ -341,8 +350,10 @@ static int ape_read_header(AVFormatContext * s)
/* now we are ready: build format streams */
st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks;
@@ -359,7 +370,7 @@ static int ape_read_header(AVFormatContext * s)
avpriv_set_pts_info(st, 64, 1, ape->samplerate);
if ((ret = ff_alloc_extradata(st->codecpar, APE_EXTRADATA_SIZE)) < 0)
- return ret;
+ goto fail;
AV_WL16(st->codecpar->extradata + 0, ape->fileversion);
AV_WL16(st->codecpar->extradata + 2, ape->compressiontype);
AV_WL16(st->codecpar->extradata + 4, ape->formatflags);
@@ -378,6 +389,10 @@ static int ape_read_header(AVFormatContext * s)
}
return 0;
+fail:
+ ape_read_close(s);
+
+ return ret;
}
static int ape_read_packet(AVFormatContext * s, AVPacket * pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/apm.c b/chromium/third_party/ffmpeg/libavformat/apm.c
index 9d2a856cc4c..38a0f6382a9 100644
--- a/chromium/third_party/ffmpeg/libavformat/apm.c
+++ b/chromium/third_party/ffmpeg/libavformat/apm.c
@@ -1,5 +1,5 @@
/*
- * Rayman 2 APM Demuxer
+ * Rayman 2 APM (De)muxer
*
* Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com)
*
@@ -21,14 +21,18 @@
*/
#include "avformat.h"
#include "internal.h"
-#include "riff.h"
+#include "rawenc.h"
+#include "libavutil/avassert.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#define APM_FILE_HEADER_SIZE 20
-#define APM_VS12_CHUNK_SIZE 76
+#define APM_FILE_EXTRADATA_SIZE 80
+#define APM_EXTRADATA_SIZE 28
+
#define APM_MAX_READ_SIZE 4096
+#define APM_TAG_CODEC 0x2000
#define APM_TAG_VS12 MKTAG('v', 's', '1', '2')
#define APM_TAG_DATA MKTAG('D', 'A', 'T', 'A')
@@ -42,38 +46,45 @@ typedef struct APMState {
int32_t saved_l;
} APMState;
-typedef struct APMVS12Chunk {
+typedef struct APMExtraData {
uint32_t magic;
uint32_t file_size;
uint32_t data_size;
uint32_t unk1;
uint32_t unk2;
APMState state;
- uint32_t pad[7];
-} APMVS12Chunk;
+ uint32_t unk3[7];
+ uint32_t data;
+} APMExtraData;
-static void apm_parse_vs12(APMVS12Chunk *vs12, const uint8_t *buf)
+#if CONFIG_APM_DEMUXER
+static void apm_parse_extradata(APMExtraData *ext, const uint8_t *buf)
{
- vs12->magic = AV_RL32(buf + 0);
- vs12->file_size = AV_RL32(buf + 4);
- vs12->data_size = AV_RL32(buf + 8);
- vs12->unk1 = AV_RL32(buf + 12);
- vs12->unk2 = AV_RL32(buf + 16);
-
- vs12->state.has_saved = AV_RL32(buf + 20);
- vs12->state.predictor_r = AV_RL32(buf + 24);
- vs12->state.step_index_r = AV_RL32(buf + 28);
- vs12->state.saved_r = AV_RL32(buf + 32);
- vs12->state.predictor_l = AV_RL32(buf + 36);
- vs12->state.step_index_l = AV_RL32(buf + 40);
- vs12->state.saved_l = AV_RL32(buf + 44);
-
- for (int i = 0; i < FF_ARRAY_ELEMS(vs12->pad); i++)
- vs12->pad[i] = AV_RL32(buf + 48 + (i * 4));
+ ext->magic = AV_RL32(buf + 0);
+ ext->file_size = AV_RL32(buf + 4);
+ ext->data_size = AV_RL32(buf + 8);
+ ext->unk1 = AV_RL32(buf + 12);
+ ext->unk2 = AV_RL32(buf + 16);
+
+ ext->state.has_saved = AV_RL32(buf + 20);
+ ext->state.predictor_r = AV_RL32(buf + 24);
+ ext->state.step_index_r = AV_RL32(buf + 28);
+ ext->state.saved_r = AV_RL32(buf + 32);
+ ext->state.predictor_l = AV_RL32(buf + 36);
+ ext->state.step_index_l = AV_RL32(buf + 40);
+ ext->state.saved_l = AV_RL32(buf + 44);
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(ext->unk3); i++)
+ ext->unk3[i] = AV_RL32(buf + 48 + (i * 4));
+
+ ext->data = AV_RL32(buf + 76);
}
static int apm_probe(const AVProbeData *p)
{
+ if (AV_RL16(p->buf) != APM_TAG_CODEC)
+ return 0;
+
if (p->buf_size < 100)
return 0;
@@ -90,71 +101,82 @@ static int apm_read_header(AVFormatContext *s)
{
int64_t ret;
AVStream *st;
- APMVS12Chunk vs12;
- uint8_t buf[APM_VS12_CHUNK_SIZE];
+ APMExtraData extradata;
+ AVCodecParameters *par;
+ uint8_t buf[APM_FILE_EXTRADATA_SIZE];
if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
- /* The header starts with a WAVEFORMATEX */
- if ((ret = ff_get_wav_header(s, s->pb, st->codecpar, APM_FILE_HEADER_SIZE, 0)) < 0)
+ /*
+ * This is 98% a WAVEFORMATEX, but there's something screwy with the extradata
+ * that ff_get_wav_header() can't (and shouldn't) handle properly.
+ */
+ if (avio_rl16(s->pb) != APM_TAG_CODEC)
+ return AVERROR_INVALIDDATA;
+
+ par = st->codecpar;
+ par->channels = avio_rl16(s->pb);
+ par->sample_rate = avio_rl32(s->pb);
+
+ /* Skip the bitrate, it's usually wrong anyway. */
+ if ((ret = avio_skip(s->pb, 4)) < 0)
return ret;
- if (st->codecpar->bits_per_coded_sample != 4)
+ par->block_align = avio_rl16(s->pb);
+ par->bits_per_coded_sample = avio_rl16(s->pb);
+
+ if (avio_rl32(s->pb) != APM_FILE_EXTRADATA_SIZE)
return AVERROR_INVALIDDATA;
- if (st->codecpar->codec_tag != 0x2000)
+ /* 8 = bits per sample * max channels */
+ if (par->sample_rate > (INT_MAX / 8))
return AVERROR_INVALIDDATA;
- /* ff_get_wav_header() does most of the work, but we need to fix a few things. */
- st->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_APM;
- st->codecpar->codec_tag = 0;
+ if (par->bits_per_coded_sample != 4)
+ return AVERROR_INVALIDDATA;
- if (st->codecpar->channels == 2)
- st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
- else if (st->codecpar->channels == 1)
- st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
+ if (par->channels == 2)
+ par->channel_layout = AV_CH_LAYOUT_STEREO;
+ else if (par->channels == 1)
+ par->channel_layout = AV_CH_LAYOUT_MONO;
else
return AVERROR_INVALIDDATA;
- st->codecpar->format = AV_SAMPLE_FMT_S16;
- st->codecpar->bits_per_raw_sample = 16;
- st->codecpar->bit_rate = st->codecpar->channels *
- st->codecpar->sample_rate *
- st->codecpar->bits_per_coded_sample;
+ par->codec_type = AVMEDIA_TYPE_AUDIO;
+ par->codec_id = AV_CODEC_ID_ADPCM_IMA_APM;
+ par->format = AV_SAMPLE_FMT_S16;
+ par->bits_per_raw_sample = 16;
+ par->bit_rate = par->channels *
+ par->sample_rate *
+ par->bits_per_coded_sample;
- if ((ret = avio_read(s->pb, buf, APM_VS12_CHUNK_SIZE)) < 0)
+ if ((ret = avio_read(s->pb, buf, APM_FILE_EXTRADATA_SIZE)) < 0)
return ret;
- else if (ret != APM_VS12_CHUNK_SIZE)
+ else if (ret != APM_FILE_EXTRADATA_SIZE)
return AVERROR(EIO);
- apm_parse_vs12(&vs12, buf);
+ apm_parse_extradata(&extradata, buf);
- if (vs12.magic != APM_TAG_VS12) {
+ if (extradata.magic != APM_TAG_VS12 || extradata.data != APM_TAG_DATA)
return AVERROR_INVALIDDATA;
- }
- if (vs12.state.has_saved) {
+ if (extradata.state.has_saved) {
avpriv_request_sample(s, "Saved Samples");
return AVERROR_PATCHWELCOME;
}
- if (avio_rl32(s->pb) != APM_TAG_DATA)
- return AVERROR_INVALIDDATA;
-
- if ((ret = ff_alloc_extradata(st->codecpar, 16)) < 0)
+ if ((ret = ff_alloc_extradata(par, APM_EXTRADATA_SIZE)) < 0)
return ret;
- AV_WL32(st->codecpar->extradata + 0, vs12.state.predictor_l);
- AV_WL32(st->codecpar->extradata + 4, vs12.state.step_index_l);
- AV_WL32(st->codecpar->extradata + 8, vs12.state.predictor_r);
- AV_WL32(st->codecpar->extradata + 12, vs12.state.step_index_r);
+ /* Use the entire state as extradata. */
+ memcpy(par->extradata, buf + 20, APM_EXTRADATA_SIZE);
- avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, par->sample_rate);
st->start_time = 0;
- st->duration = vs12.data_size *
- (8 / st->codecpar->bits_per_coded_sample) /
- st->codecpar->channels;
+ st->duration = extradata.data_size *
+ (8 / par->bits_per_coded_sample) /
+ par->channels;
return 0;
}
@@ -186,3 +208,110 @@ AVInputFormat ff_apm_demuxer = {
.read_header = apm_read_header,
.read_packet = apm_read_packet
};
+#endif
+
+#if CONFIG_APM_MUXER
+static int apm_write_init(AVFormatContext *s)
+{
+ AVCodecParameters *par;
+
+ if (s->nb_streams != 1) {
+ av_log(s, AV_LOG_ERROR, "APM files have exactly one stream\n");
+ return AVERROR(EINVAL);
+ }
+
+ par = s->streams[0]->codecpar;
+
+ if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_APM) {
+ av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
+ avcodec_get_name(par->codec_id));
+ return AVERROR(EINVAL);
+ }
+
+ if (par->channels > 2) {
+ av_log(s, AV_LOG_ERROR, "APM files only support up to 2 channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (par->sample_rate > (INT_MAX / 8)) {
+ av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (par->extradata_size != APM_EXTRADATA_SIZE) {
+ av_log(s, AV_LOG_ERROR, "Invalid/missing extradata\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
+ av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n");
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+static int apm_write_header(AVFormatContext *s)
+{
+ uint8_t buf[APM_FILE_EXTRADATA_SIZE] = { 0 };
+ AVCodecParameters *par = s->streams[0]->codecpar;
+
+ /*
+ * Bodge a WAVEFORMATEX manually, ff_put_wav_header() can't
+ * be used because of the extra 2 bytes.
+ */
+ avio_wl16(s->pb, APM_TAG_CODEC);
+ avio_wl16(s->pb, par->channels);
+ avio_wl32(s->pb, par->sample_rate);
+ /* This is the wrong calculation, but it's what the orginal files have. */
+ avio_wl32(s->pb, par->sample_rate * par->channels * 2);
+ avio_wl16(s->pb, par->block_align);
+ avio_wl16(s->pb, par->bits_per_coded_sample);
+ avio_wl32(s->pb, APM_FILE_EXTRADATA_SIZE);
+
+ /*
+ * Build the extradata. Assume the codec's given us correct data.
+ * File and data sizes are fixed later.
+ */
+ AV_WL32(buf + 0, APM_TAG_VS12); /* magic */
+ AV_WL32(buf + 12, 0xFFFFFFFF); /* unk1 */
+ memcpy( buf + 20, par->extradata, APM_EXTRADATA_SIZE);
+ AV_WL32(buf + 76, APM_TAG_DATA); /* data */
+
+ avio_write(s->pb, buf, APM_FILE_EXTRADATA_SIZE);
+ return 0;
+}
+
+static int apm_write_trailer(AVFormatContext *s)
+{
+ int64_t file_size, data_size;
+
+ file_size = avio_tell(s->pb);
+ data_size = file_size - (APM_FILE_HEADER_SIZE + APM_FILE_EXTRADATA_SIZE);
+
+ if (file_size >= UINT32_MAX) {
+ av_log(s, AV_LOG_ERROR,
+ "Filesize %"PRId64" invalid for APM, output file will be broken\n",
+ file_size);
+ return AVERROR(ERANGE);
+ }
+
+ avio_seek(s->pb, 24, SEEK_SET);
+ avio_wl32(s->pb, (uint32_t)file_size);
+ avio_wl32(s->pb, (uint32_t)data_size);
+
+ return 0;
+}
+
+AVOutputFormat ff_apm_muxer = {
+ .name = "apm",
+ .long_name = NULL_IF_CONFIG_SMALL("Ubisoft Rayman 2 APM"),
+ .extensions = "apm",
+ .audio_codec = AV_CODEC_ID_ADPCM_IMA_APM,
+ .video_codec = AV_CODEC_ID_NONE,
+ .init = apm_write_init,
+ .write_header = apm_write_header,
+ .write_packet = ff_raw_write_packet,
+ .write_trailer = apm_write_trailer
+};
+#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/apngenc.c b/chromium/third_party/ffmpeg/libavformat/apngenc.c
index 88cd8054d6d..7ad6a923d5e 100644
--- a/chromium/third_party/ffmpeg/libavformat/apngenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/apngenc.c
@@ -119,7 +119,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet)
AVIOContext *io_context = format_context->pb;
AVStream *codec_stream = format_context->streams[0];
uint8_t *side_data = NULL;
- int side_data_size = 0;
+ int side_data_size;
av_assert0(apng->prev_packet);
diff --git a/chromium/third_party/ffmpeg/libavformat/aqtitledec.c b/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
index 8cc82a8f39a..81630d73b09 100644
--- a/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
@@ -81,11 +81,11 @@ static int aqt_read_header(AVFormatContext *s)
if (!new_event) {
sub = ff_subtitles_queue_insert(&aqt->q, "\n", 1, 1);
if (!sub)
- return AVERROR(ENOMEM);
+ goto fail;
}
sub = ff_subtitles_queue_insert(&aqt->q, line, strlen(line), !new_event);
if (!sub)
- return AVERROR(ENOMEM);
+ goto fail;
if (new_event) {
sub->pts = frame;
sub->duration = -1;
@@ -97,6 +97,9 @@ static int aqt_read_header(AVFormatContext *s)
ff_subtitles_queue_finalize(s, &aqt->q);
return 0;
+fail:
+ ff_subtitles_queue_clean(&aqt->q);
+ return AVERROR(ENOMEM);
}
static int aqt_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/argo_asf.c b/chromium/third_party/ffmpeg/libavformat/argo_asf.c
index 3339425244d..37ad2bf5e9f 100644
--- a/chromium/third_party/ffmpeg/libavformat/argo_asf.c
+++ b/chromium/third_party/ffmpeg/libavformat/argo_asf.c
@@ -1,5 +1,5 @@
/*
- * Argonaut Games ASF demuxer
+ * Argonaut Games ASF (de)muxer
*
* Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com)
*
@@ -23,10 +23,12 @@
#include "internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
#define ASF_TAG MKTAG('A', 'S', 'F', '\0')
#define ASF_FILE_HEADER_SIZE 24
#define ASF_CHUNK_HEADER_SIZE 20
+#define ASF_SAMPLE_COUNT 32
typedef struct ArgoASFFileHeader {
uint32_t magic; /*< Magic Number, {'A', 'S', 'F', '\0'} */
@@ -39,7 +41,7 @@ typedef struct ArgoASFFileHeader {
typedef struct ArgoASFChunkHeader {
uint32_t num_blocks; /*< No. blocks in the chunk. */
- uint32_t num_samples; /*< No. samples per channel in a block. */
+ uint32_t num_samples; /*< No. samples per channel in a block. Always 32. */
uint32_t unk1; /*< Unknown */
uint16_t sample_rate; /*< Sample rate. */
uint16_t unk2; /*< Unknown. */
@@ -62,6 +64,14 @@ typedef struct ArgoASFDemuxContext {
uint32_t blocks_read;
} ArgoASFDemuxContext;
+typedef struct ArgoASFMuxContext {
+ const AVClass *class;
+ int version_major;
+ int version_minor;
+ const char *name;
+} ArgoASFMuxContext;
+
+#if CONFIG_ARGO_ASF_DEMUXER
static void argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf)
{
hdr->magic = AV_RL32(buf + 0);
@@ -85,9 +95,12 @@ static void argo_asf_parse_chunk_header(ArgoASFChunkHeader *hdr, const uint8_t *
/*
* Known versions:
- * 1.1: The sample files in /game-formats/brender/part2.zip
+ * 1.1: https://samples.ffmpeg.org/game-formats/brender/part2.zip
+ * FX Fighter
* 1.2: Croc! Legend of the Gobbos
* 2.1: Croc 2
+ * The Emperor's New Groove
+ * Disney's Aladdin in Nasira's Revenge
*/
static int argo_asf_is_known_version(const ArgoASFFileHeader *hdr)
{
@@ -131,13 +144,6 @@ static int argo_asf_read_header(AVFormatContext *s)
argo_asf_parse_file_header(&asf->fhdr, buf);
- if (!argo_asf_is_known_version(&asf->fhdr)) {
- avpriv_request_sample(s, "Version %hu.%hu",
- asf->fhdr.version_major, asf->fhdr.version_minor
- );
- return AVERROR_PATCHWELCOME;
- }
-
if (asf->fhdr.num_chunks == 0) {
return AVERROR_INVALIDDATA;
} else if (asf->fhdr.num_chunks > 1) {
@@ -158,6 +164,12 @@ static int argo_asf_read_header(AVFormatContext *s)
argo_asf_parse_chunk_header(&asf->ckhdr, buf);
+ if (asf->ckhdr.num_samples != ASF_SAMPLE_COUNT) {
+ av_log(s, AV_LOG_ERROR, "Invalid sample count. Got %u, expected %d\n",
+ asf->ckhdr.num_samples, ASF_SAMPLE_COUNT);
+ return AVERROR_INVALIDDATA;
+ }
+
if ((asf->ckhdr.flags & ASF_CF_ALWAYS1) != ASF_CF_ALWAYS1 || (asf->ckhdr.flags & ASF_CF_ALWAYS0) != 0) {
avpriv_request_sample(s, "Nonstandard flags (0x%08X)", asf->ckhdr.flags);
return AVERROR_PATCHWELCOME;
@@ -247,3 +259,186 @@ AVInputFormat ff_argo_asf_demuxer = {
.read_header = argo_asf_read_header,
.read_packet = argo_asf_read_packet
};
+#endif
+
+#if CONFIG_ARGO_ASF_MUXER
+static int argo_asf_write_init(AVFormatContext *s)
+{
+ const AVCodecParameters *par;
+
+ if (s->nb_streams != 1) {
+ av_log(s, AV_LOG_ERROR, "ASF files have exactly one stream\n");
+ return AVERROR(EINVAL);
+ }
+
+ par = s->streams[0]->codecpar;
+
+ if (par->codec_id != AV_CODEC_ID_ADPCM_ARGO) {
+ av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
+ avcodec_get_name(par->codec_id));
+ return AVERROR(EINVAL);
+ }
+
+ if (par->channels > 2) {
+ av_log(s, AV_LOG_ERROR, "ASF files only support up to 2 channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (par->sample_rate > UINT16_MAX) {
+ av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
+ av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n");
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+static void argo_asf_write_file_header(const ArgoASFFileHeader *fhdr, AVIOContext *pb)
+{
+ avio_wl32( pb, fhdr->magic);
+ avio_wl16( pb, fhdr->version_major);
+ avio_wl16( pb, fhdr->version_minor);
+ avio_wl32( pb, fhdr->num_chunks);
+ avio_wl32( pb, fhdr->chunk_offset);
+ avio_write(pb, fhdr->name, sizeof(fhdr->name));
+}
+
+static void argo_asf_write_chunk_header(const ArgoASFChunkHeader *ckhdr, AVIOContext *pb)
+{
+ avio_wl32(pb, ckhdr->num_blocks);
+ avio_wl32(pb, ckhdr->num_samples);
+ avio_wl32(pb, ckhdr->unk1);
+ avio_wl16(pb, ckhdr->sample_rate);
+ avio_wl16(pb, ckhdr->unk2);
+ avio_wl32(pb, ckhdr->flags);
+}
+
+static int argo_asf_write_header(AVFormatContext *s)
+{
+ const AVCodecParameters *par = s->streams[0]->codecpar;
+ ArgoASFMuxContext *ctx = s->priv_data;
+ ArgoASFFileHeader fhdr;
+ ArgoASFChunkHeader chdr;
+
+ fhdr.magic = ASF_TAG;
+ fhdr.version_major = (uint16_t)ctx->version_major;
+ fhdr.version_minor = (uint16_t)ctx->version_minor;
+ fhdr.num_chunks = 1;
+ fhdr.chunk_offset = ASF_FILE_HEADER_SIZE;
+ /*
+ * If the user specified a name, use it as is. Otherwise take the
+ * basename and lop off the extension (if any).
+ */
+ if (ctx->name) {
+ strncpy(fhdr.name, ctx->name, sizeof(fhdr.name));
+ } else {
+ const char *start = av_basename(s->url);
+ const char *end = strrchr(start, '.');
+ size_t len;
+
+ if(end)
+ len = end - start;
+ else
+ len = strlen(start);
+
+ memcpy(fhdr.name, start, FFMIN(len, sizeof(fhdr.name)));
+ }
+
+ chdr.num_blocks = 0;
+ chdr.num_samples = ASF_SAMPLE_COUNT;
+ chdr.unk1 = 0;
+ chdr.sample_rate = par->sample_rate;
+ chdr.unk2 = ~0;
+ chdr.flags = ASF_CF_BITS_PER_SAMPLE | ASF_CF_ALWAYS1;
+
+ if (par->channels == 2)
+ chdr.flags |= ASF_CF_STEREO;
+
+ argo_asf_write_file_header(&fhdr, s->pb);
+ argo_asf_write_chunk_header(&chdr, s->pb);
+ return 0;
+}
+
+static int argo_asf_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ if (pkt->size != 17 * s->streams[0]->codecpar->channels)
+ return AVERROR_INVALIDDATA;
+
+ if (s->streams[0]->nb_frames >= UINT32_MAX)
+ return AVERROR_INVALIDDATA;
+
+ avio_write(s->pb, pkt->data, pkt->size);
+ return 0;
+}
+
+static int argo_asf_write_trailer(AVFormatContext *s)
+{
+ int64_t ret;
+
+ if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0))
+ return ret;
+
+ avio_wl32(s->pb, (uint32_t)s->streams[0]->nb_frames);
+ return 0;
+}
+
+static const AVOption argo_asf_options[] = {
+ {
+ .name = "version_major",
+ .help = "override file major version",
+ .offset = offsetof(ArgoASFMuxContext, version_major),
+ .type = AV_OPT_TYPE_INT,
+ .default_val = {.i64 = 2},
+ .min = 0,
+ .max = UINT16_MAX,
+ .flags = AV_OPT_FLAG_ENCODING_PARAM
+ },
+ {
+ .name = "version_minor",
+ .help = "override file minor version",
+ .offset = offsetof(ArgoASFMuxContext, version_minor),
+ .type = AV_OPT_TYPE_INT,
+ .default_val = {.i64 = 1},
+ .min = 0,
+ .max = UINT16_MAX,
+ .flags = AV_OPT_FLAG_ENCODING_PARAM
+ },
+ {
+ .name = "name",
+ .help = "embedded file name (max 8 characters)",
+ .offset = offsetof(ArgoASFMuxContext, name),
+ .type = AV_OPT_TYPE_STRING,
+ .default_val = {.str = NULL},
+ .flags = AV_OPT_FLAG_ENCODING_PARAM
+ },
+ { NULL }
+};
+
+static const AVClass argo_asf_muxer_class = {
+ .class_name = "argo_asf_muxer",
+ .item_name = av_default_item_name,
+ .option = argo_asf_options,
+ .version = LIBAVUTIL_VERSION_INT
+};
+
+AVOutputFormat ff_argo_asf_muxer = {
+ .name = "argo_asf",
+ .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games ASF"),
+ /*
+ * NB: Can't do this as it conflicts with the actual ASF format.
+ * .extensions = "asf",
+ */
+ .audio_codec = AV_CODEC_ID_ADPCM_ARGO,
+ .video_codec = AV_CODEC_ID_NONE,
+ .init = argo_asf_write_init,
+ .write_header = argo_asf_write_header,
+ .write_packet = argo_asf_write_packet,
+ .write_trailer = argo_asf_write_trailer,
+ .priv_class = &argo_asf_muxer_class,
+ .priv_data_size = sizeof(ArgoASFMuxContext)
+};
+#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/asfdec_f.c b/chromium/third_party/ffmpeg/libavformat/asfdec_f.c
index f0cb353587d..e9ddca7151d 100644
--- a/chromium/third_party/ffmpeg/libavformat/asfdec_f.c
+++ b/chromium/third_party/ffmpeg/libavformat/asfdec_f.c
@@ -308,8 +308,8 @@ static void get_id3_tag(AVFormatContext *s, int len)
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_parse_chapters(s, &id3v2_extra_meta);
+ ff_id3v2_parse_apic(s, id3v2_extra_meta);
+ ff_id3v2_parse_chapters(s, id3v2_extra_meta);
}
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/asfdec_o.c b/chromium/third_party/ffmpeg/libavformat/asfdec_o.c
index 7891b234455..1b10e47907a 100644
--- a/chromium/third_party/ffmpeg/libavformat/asfdec_o.c
+++ b/chromium/third_party/ffmpeg/libavformat/asfdec_o.c
@@ -461,8 +461,8 @@ static void get_id3_tag(AVFormatContext *s, int len)
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_parse_chapters(s, &id3v2_extra_meta);
+ ff_id3v2_parse_apic(s, id3v2_extra_meta);
+ ff_id3v2_parse_chapters(s, id3v2_extra_meta);
}
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/asfenc.c b/chromium/third_party/ffmpeg/libavformat/asfenc.c
index 73afb13200b..8b24264c947 100644
--- a/chromium/third_party/ffmpeg/libavformat/asfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/asfenc.c
@@ -682,7 +682,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
avio_wl16(pb, 40 + par->extradata_size); /* size */
/* BITMAPINFOHEADER header */
- ff_put_bmp_header(pb, par, 1, 0);
+ ff_put_bmp_header(pb, par, 1, 0, 0);
}
end_header(pb, hpos);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/assdec.c b/chromium/third_party/ffmpeg/libavformat/assdec.c
index f66b2966732..8fb9e8e501b 100644
--- a/chromium/third_party/ffmpeg/libavformat/assdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/assdec.c
@@ -160,6 +160,8 @@ static int ass_read_header(AVFormatContext *s)
ff_subtitles_queue_finalize(s, &ass->q);
end:
+ if (res < 0)
+ ass_read_close(s);
av_bprint_finalize(&header, NULL);
av_bprint_finalize(&line, NULL);
av_bprint_finalize(&rline, NULL);
diff --git a/chromium/third_party/ffmpeg/libavformat/async.c b/chromium/third_party/ffmpeg/libavformat/async.c
index 4e295b5e10f..a0bdfa2ee3a 100644
--- a/chromium/third_party/ffmpeg/libavformat/async.c
+++ b/chromium/third_party/ffmpeg/libavformat/async.c
@@ -293,7 +293,7 @@ cond_wakeup_background_fail:
cond_wakeup_main_fail:
pthread_mutex_destroy(&c->mutex);
mutex_fail:
- ffurl_close(c->inner);
+ ffurl_closep(&c->inner);
url_fail:
ring_destroy(&c->ring);
fifo_fail:
@@ -317,7 +317,7 @@ static int async_close(URLContext *h)
pthread_cond_destroy(&c->cond_wakeup_background);
pthread_cond_destroy(&c->cond_wakeup_main);
pthread_mutex_destroy(&c->mutex);
- ffurl_close(c->inner);
+ ffurl_closep(&c->inner);
ring_destroy(&c->ring);
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/au.c b/chromium/third_party/ffmpeg/libavformat/au.c
index 4afee85a948..c09f4da4c96 100644
--- a/chromium/third_party/ffmpeg/libavformat/au.c
+++ b/chromium/third_party/ffmpeg/libavformat/au.c
@@ -35,8 +35,6 @@
/* if we don't know the size in advance */
#define AU_UNKNOWN_SIZE ((uint32_t)(~0))
-/* the specification requires an annotation field of at least eight bytes */
-#define AU_DEFAULT_HEADER_SIZE (24+8)
static const AVCodecTag codec_au_tags[] = {
{ AV_CODEC_ID_PCM_MULAW, 1 },
@@ -68,20 +66,20 @@ static int au_probe(const AVProbeData *p)
static int au_read_annotation(AVFormatContext *s, int size)
{
- static const char * keys[] = {
+ static const char keys[][7] = {
"title",
"artist",
"album",
"track",
"genre",
- NULL };
+ };
AVIOContext *pb = s->pb;
enum { PARSE_KEY, PARSE_VALUE, PARSE_FINISHED } state = PARSE_KEY;
char c;
AVBPrint bprint;
char * key = NULL;
char * value = NULL;
- int i;
+ int ret, i;
av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
@@ -92,7 +90,9 @@ static int au_read_annotation(AVFormatContext *s, int size)
if (c == '\0') {
state = PARSE_FINISHED;
} else if (c == '=') {
- av_bprint_finalize(&bprint, &key);
+ ret = av_bprint_finalize(&bprint, &key);
+ if (ret < 0)
+ return ret;
av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
state = PARSE_VALUE;
} else {
@@ -105,11 +105,11 @@ static int au_read_annotation(AVFormatContext *s, int size)
av_log(s, AV_LOG_ERROR, "Memory error while parsing AU metadata.\n");
} else {
av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
- for (i = 0; keys[i] != NULL && key != NULL; i++) {
+ for (i = 0; i < FF_ARRAY_ELEMS(keys); i++) {
if (av_strcasecmp(keys[i], key) == 0) {
av_dict_set(&(s->metadata), keys[i], value, AV_DICT_DONT_STRDUP_VAL);
- av_freep(&key);
value = NULL;
+ break;
}
}
}
@@ -143,6 +143,7 @@ static int au_read_header(AVFormatContext *s)
int bps, ba = 0;
enum AVCodecID codec;
AVStream *st;
+ int ret;
tag = avio_rl32(pb);
if (tag != MKTAG('.', 's', 'n', 'd'))
@@ -161,7 +162,9 @@ static int au_read_header(AVFormatContext *s)
if (size > 24) {
/* parse annotation field to get metadata */
- au_read_annotation(s, size - 24);
+ ret = au_read_annotation(s, size - 24);
+ if (ret < 0)
+ return ret;
}
codec = ff_codec_get_id(codec_au_tags, id);
@@ -236,36 +239,31 @@ typedef struct AUContext {
#include "rawenc.h"
-static int au_get_annotations(AVFormatContext *s, char **buffer)
+static int au_get_annotations(AVFormatContext *s, AVBPrint *annotations)
{
- static const char * keys[] = {
+ static const char keys[][7] = {
"Title",
"Artist",
"Album",
"Track",
"Genre",
- NULL };
- int i;
+ };
int cnt = 0;
AVDictionary *m = s->metadata;
AVDictionaryEntry *t = NULL;
- AVBPrint bprint;
- av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
-
- for (i = 0; keys[i] != NULL; i++) {
+ for (int i = 0; i < FF_ARRAY_ELEMS(keys); i++) {
t = av_dict_get(m, keys[i], NULL, 0);
if (t != NULL) {
if (cnt++)
- av_bprint_chars(&bprint, '\n', 1);
- av_bprint_append_data(&bprint, keys[i], strlen(keys[i]));
- av_bprint_chars(&bprint, '=', 1);
- av_bprint_append_data(&bprint, t->value, strlen(t->value));
+ av_bprint_chars(annotations, '\n', 1);
+ av_bprintf(annotations, "%s=%s", keys[i], t->value);
}
}
- /* pad with 0's */
- av_bprint_append_data(&bprint, "\0\0\0\0\0\0\0\0", 8);
- return av_bprint_finalize(&bprint, buffer);
+ /* The specification requires the annotation field to be zero-terminated
+ * and its length to be a multiple of eight, so pad with 0's */
+ av_bprint_chars(annotations, '\0', 8);
+ return av_bprint_is_complete(annotations) ? 0 : AVERROR(ENOMEM);
}
static int au_write_header(AVFormatContext *s)
@@ -274,9 +272,7 @@ static int au_write_header(AVFormatContext *s)
AUContext *au = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecParameters *par = s->streams[0]->codecpar;
- char *annotations = NULL;
-
- au->header_size = AU_DEFAULT_HEADER_SIZE;
+ AVBPrint annotations;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
@@ -289,30 +285,24 @@ static int au_write_header(AVFormatContext *s)
return AVERROR(EINVAL);
}
- if (av_dict_count(s->metadata) > 0) {
- ret = au_get_annotations(s, &annotations);
- if (ret < 0)
- return ret;
- if (annotations != NULL) {
- au->header_size = (24 + strlen(annotations) + 8) & ~7;
- if (au->header_size < AU_DEFAULT_HEADER_SIZE)
- au->header_size = AU_DEFAULT_HEADER_SIZE;
- }
- }
+ av_bprint_init(&annotations, 0, INT_MAX - 24);
+ ret = au_get_annotations(s, &annotations);
+ if (ret < 0)
+ goto fail;
+ au->header_size = 24 + annotations.len & ~7;
+
ffio_wfourcc(pb, ".snd"); /* magic number */
avio_wb32(pb, au->header_size); /* header size */
avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */
avio_wb32(pb, par->codec_tag); /* codec ID */
avio_wb32(pb, par->sample_rate);
avio_wb32(pb, par->channels);
- if (annotations != NULL) {
- avio_write(pb, annotations, au->header_size - 24);
- av_freep(&annotations);
- } else {
- avio_wb64(pb, 0); /* annotation field */
- }
+ avio_write(pb, annotations.str, annotations.len & ~7);
- return 0;
+fail:
+ av_bprint_finalize(&annotations, NULL);
+
+ return ret;
}
static int au_write_trailer(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/audiointerleave.c b/chromium/third_party/ffmpeg/libavformat/audiointerleave.c
deleted file mode 100644
index 36a32882427..00000000000
--- a/chromium/third_party/ffmpeg/libavformat/audiointerleave.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Audio Interleaving functions
- *
- * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot 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
- */
-
-#include "libavutil/fifo.h"
-#include "libavutil/mathematics.h"
-#include "avformat.h"
-#include "audiointerleave.h"
-#include "internal.h"
-
-void ff_audio_interleave_close(AVFormatContext *s)
-{
- int i;
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AudioInterleaveContext *aic = st->priv_data;
-
- if (aic && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
- av_fifo_freep(&aic->fifo);
- }
-}
-
-int ff_audio_interleave_init(AVFormatContext *s,
- const int samples_per_frame,
- AVRational time_base)
-{
- int i;
-
- if (!time_base.num) {
- av_log(s, AV_LOG_ERROR, "timebase not set for audio interleave\n");
- return AVERROR(EINVAL);
- }
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AudioInterleaveContext *aic = st->priv_data;
-
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- int max_samples = samples_per_frame ? samples_per_frame :
- av_rescale_rnd(st->codecpar->sample_rate, time_base.num, time_base.den, AV_ROUND_UP);
- aic->sample_size = (st->codecpar->channels *
- av_get_bits_per_sample(st->codecpar->codec_id)) / 8;
- if (!aic->sample_size) {
- av_log(s, AV_LOG_ERROR, "could not compute sample size\n");
- return AVERROR(EINVAL);
- }
- aic->samples_per_frame = samples_per_frame;
- aic->time_base = time_base;
-
- if (!(aic->fifo = av_fifo_alloc_array(100, max_samples)))
- return AVERROR(ENOMEM);
- aic->fifo_size = 100 * max_samples;
- }
- }
-
- return 0;
-}
-
-static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
- int stream_index, int flush)
-{
- AVStream *st = s->streams[stream_index];
- AudioInterleaveContext *aic = st->priv_data;
- int ret;
- int nb_samples = aic->samples_per_frame ? aic->samples_per_frame :
- (av_rescale_q(aic->n + 1, av_make_q(st->codecpar->sample_rate, 1), av_inv_q(aic->time_base)) - aic->nb_samples);
- int frame_size = nb_samples * aic->sample_size;
- int size = FFMIN(av_fifo_size(aic->fifo), frame_size);
- if (!size || (!flush && size == av_fifo_size(aic->fifo)))
- return 0;
-
- ret = av_new_packet(pkt, frame_size);
- if (ret < 0)
- return ret;
- av_fifo_generic_read(aic->fifo, pkt->data, size, NULL);
-
- if (size < pkt->size)
- memset(pkt->data + size, 0, pkt->size - size);
-
- pkt->dts = pkt->pts = aic->dts;
- pkt->duration = av_rescale_q(nb_samples, st->time_base, aic->time_base);
- pkt->stream_index = stream_index;
- aic->dts += pkt->duration;
- aic->nb_samples += nb_samples;
- aic->n++;
-
- return pkt->size;
-}
-
-int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush,
- int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int),
- int (*compare_ts)(AVFormatContext *, const AVPacket *, const AVPacket *))
-{
- int i, ret;
-
- if (pkt) {
- AVStream *st = s->streams[pkt->stream_index];
- AudioInterleaveContext *aic = st->priv_data;
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- unsigned new_size = av_fifo_size(aic->fifo) + pkt->size;
- if (new_size > aic->fifo_size) {
- if (av_fifo_realloc2(aic->fifo, new_size) < 0)
- return AVERROR(ENOMEM);
- aic->fifo_size = new_size;
- }
- av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL);
- } else {
- // rewrite pts and dts to be decoded time line position
- pkt->pts = pkt->dts = aic->dts;
- aic->dts += pkt->duration;
- if ((ret = ff_interleave_add_packet(s, pkt, compare_ts)) < 0)
- return ret;
- }
- pkt = NULL;
- }
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- AVPacket new_pkt;
- while ((ret = interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
- if ((ret = ff_interleave_add_packet(s, &new_pkt, compare_ts)) < 0)
- return ret;
- }
- if (ret < 0)
- return ret;
- }
- }
-
- return get_packet(s, out, NULL, flush);
-}
diff --git a/chromium/third_party/ffmpeg/libavformat/audiointerleave.h b/chromium/third_party/ffmpeg/libavformat/audiointerleave.h
deleted file mode 100644
index 0933310f4c2..00000000000
--- a/chromium/third_party/ffmpeg/libavformat/audiointerleave.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * audio interleaving prototypes and declarations
- *
- * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot 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
- */
-
-#ifndef AVFORMAT_AUDIOINTERLEAVE_H
-#define AVFORMAT_AUDIOINTERLEAVE_H
-
-#include "libavutil/fifo.h"
-#include "avformat.h"
-
-typedef struct AudioInterleaveContext {
- AVFifoBuffer *fifo;
- unsigned fifo_size; ///< size of currently allocated FIFO
- int64_t n; ///< number of generated packets
- int64_t nb_samples; ///< number of generated samples
- uint64_t dts; ///< current dts
- int sample_size; ///< size of one sample all channels included
- int samples_per_frame; ///< samples per frame if fixed, 0 otherwise
- AVRational time_base; ///< time base of output audio packets
-} AudioInterleaveContext;
-
-int ff_audio_interleave_init(AVFormatContext *s, const int samples_per_frame, AVRational time_base);
-void ff_audio_interleave_close(AVFormatContext *s);
-
-/**
- * Rechunk audio PCM packets per AudioInterleaveContext->samples_per_frame
- * and interleave them correctly.
- * The first element of AVStream->priv_data must be AudioInterleaveContext
- * when using this function.
- *
- * @param get_packet function will output a packet when streams are correctly interleaved.
- * @param compare_ts function will compare AVPackets and decide interleaving order.
- */
-int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush,
- int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int),
- int (*compare_ts)(AVFormatContext *, const AVPacket *, const AVPacket *));
-
-#endif /* AVFORMAT_AUDIOINTERLEAVE_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/av1.c b/chromium/third_party/ffmpeg/libavformat/av1.c
index 1e7a67d2f2b..0cbffb1fd8b 100644
--- a/chromium/third_party/ffmpeg/libavformat/av1.c
+++ b/chromium/third_party/ffmpeg/libavformat/av1.c
@@ -363,11 +363,11 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int
int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
{
- AVIOContext *seq_pb = NULL, *meta_pb = NULL;
+ AVIOContext *meta_pb;
AV1SequenceParameters seq_params;
PutBitContext pbc;
- uint8_t header[4];
- uint8_t *seq, *meta;
+ uint8_t header[4], *meta;
+ const uint8_t *seq;
int64_t obu_size;
int start_pos, type, temporal_id, spatial_id;
int ret, nb_seq = 0, seq_size, meta_size;
@@ -375,12 +375,9 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
if (size <= 0)
return AVERROR_INVALIDDATA;
- ret = avio_open_dyn_buf(&seq_pb);
- if (ret < 0)
- return ret;
ret = avio_open_dyn_buf(&meta_pb);
if (ret < 0)
- goto fail;
+ return ret;
while (size > 0) {
int len = parse_obu_header(buf, size, &obu_size, &start_pos,
@@ -401,7 +398,8 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
if (ret < 0)
goto fail;
- avio_write(seq_pb, buf, len);
+ seq = buf;
+ seq_size = len;
break;
case AV1_OBU_METADATA:
if (!obu_size) {
@@ -417,8 +415,7 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
buf += len;
}
- seq_size = avio_get_dyn_buf(seq_pb, &seq);
- if (!seq_size) {
+ if (!nb_seq) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
@@ -447,7 +444,6 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
avio_write(pb, meta, meta_size);
fail:
- ffio_free_dyn_buf(&seq_pb);
ffio_free_dyn_buf(&meta_pb);
return ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/av1dec.c b/chromium/third_party/ffmpeg/libavformat/av1dec.c
index 1be2fac1c10..0693e40ac1b 100644
--- a/chromium/third_party/ffmpeg/libavformat/av1dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/av1dec.c
@@ -22,12 +22,77 @@
#include "config.h"
#include "libavutil/common.h"
+#include "libavutil/fifo.h"
#include "libavutil/opt.h"
#include "libavcodec/av1_parse.h"
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+//return < 0 if we need more data
+static int get_score(int type, int *seq)
+{
+ switch (type) {
+ case AV1_OBU_SEQUENCE_HEADER:
+ *seq = 1;
+ return -1;
+ case AV1_OBU_FRAME:
+ case AV1_OBU_FRAME_HEADER:
+ return *seq ? AVPROBE_SCORE_EXTENSION + 1 : 0;
+ case AV1_OBU_METADATA:
+ case AV1_OBU_PADDING:
+ return -1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int read_header(AVFormatContext *s, const AVRational *framerate, AVBSFContext **bsf, void *logctx)
+{
+ const AVBitStreamFilter *filter = av_bsf_get_by_name("av1_frame_merge");
+ AVStream *st;
+ int ret;
+
+ if (!filter) {
+ av_log(logctx, AV_LOG_ERROR, "av1_frame_merge bitstream filter "
+ "not found. This is a bug, please report it.\n");
+ return AVERROR_BUG;
+ }
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codecpar->codec_id = AV_CODEC_ID_AV1;
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
+
+ st->internal->avctx->framerate = *framerate;
+ // taken from rawvideo demuxers
+ avpriv_set_pts_info(st, 64, 1, 1200000);
+
+ ret = av_bsf_alloc(filter, bsf);
+ if (ret < 0)
+ return ret;
+
+ ret = avcodec_parameters_copy((*bsf)->par_in, st->codecpar);
+ if (ret < 0) {
+ av_bsf_free(bsf);
+ return ret;
+ }
+
+ ret = av_bsf_init(*bsf);
+ if (ret < 0)
+ av_bsf_free(bsf);
+
+ return ret;
+
+}
+
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+
+#if CONFIG_AV1_DEMUXER
typedef struct AnnexBContext {
const AVClass *class;
AVBSFContext *bsf;
@@ -123,19 +188,9 @@ static int annexb_probe(const AVProbeData *p)
return 0;
cnt += obu_unit_size;
- switch (type) {
- case AV1_OBU_SEQUENCE_HEADER:
- seq = 1;
- break;
- case AV1_OBU_FRAME:
- case AV1_OBU_FRAME_HEADER:
- return seq ? AVPROBE_SCORE_EXTENSION + 1 : 0;
- case AV1_OBU_TILE_GROUP:
- case AV1_OBU_TEMPORAL_DELIMITER:
- return 0;
- default:
- break;
- }
+ ret = get_score(type, &seq);
+ if (ret >= 0)
+ return ret;
temporal_unit_size -= obu_unit_size + ret;
frame_unit_size -= obu_unit_size + ret;
@@ -147,43 +202,7 @@ static int annexb_probe(const AVProbeData *p)
static int annexb_read_header(AVFormatContext *s)
{
AnnexBContext *c = s->priv_data;
- const AVBitStreamFilter *filter = av_bsf_get_by_name("av1_frame_merge");
- AVStream *st;
- int ret;
-
- if (!filter) {
- av_log(c, AV_LOG_ERROR, "av1_frame_merge bitstream filter "
- "not found. This is a bug, please report it.\n");
- return AVERROR_BUG;
- }
-
- st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
-
- st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codecpar->codec_id = AV_CODEC_ID_AV1;
- st->need_parsing = AVSTREAM_PARSE_HEADERS;
-
- st->internal->avctx->framerate = c->framerate;
- // taken from rawvideo demuxers
- avpriv_set_pts_info(st, 64, 1, 1200000);
-
- ret = av_bsf_alloc(filter, &c->bsf);
- if (ret < 0)
- return ret;
-
- ret = avcodec_parameters_copy(c->bsf->par_in, st->codecpar);
- if (ret < 0) {
- av_bsf_free(&c->bsf);
- return ret;
- }
-
- ret = av_bsf_init(c->bsf);
- if (ret < 0)
- av_bsf_free(&c->bsf);
-
- return ret;
+ return read_header(s, &c->framerate, &c->bsf, c);
}
static int annexb_read_packet(AVFormatContext *s, AVPacket *pkt)
@@ -252,11 +271,11 @@ static int annexb_read_close(AVFormatContext *s)
}
#define OFFSET(x) offsetof(AnnexBContext, x)
-#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption annexb_options[] = {
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
{ NULL },
};
+#undef OFFSET
static const AVClass annexb_demuxer_class = {
.class_name = "AV1 Annex B demuxer",
@@ -277,3 +296,205 @@ AVInputFormat ff_av1_demuxer = {
.flags = AVFMT_GENERIC_INDEX,
.priv_class = &annexb_demuxer_class,
};
+#endif
+
+#if CONFIG_OBU_DEMUXER
+typedef struct ObuContext {
+ const AVClass *class;
+ AVBSFContext *bsf;
+ AVRational framerate;
+ AVFifoBuffer *fifo;
+} ObuContext;
+
+//For low overhead obu, we can't foresee the obu size before we parsed the header.
+//So, we can't use parse_obu_header here, since it will check size <= buf_size
+//see c27c7b49dc for more details
+static int read_obu_with_size(const uint8_t *buf, int buf_size, int64_t *obu_size, int *type)
+{
+ GetBitContext gb;
+ int ret, extension_flag, start_pos;
+ int64_t size;
+
+ ret = init_get_bits8(&gb, buf, FFMIN(buf_size, MAX_OBU_HEADER_SIZE));
+ if (ret < 0)
+ return ret;
+
+ if (get_bits1(&gb) != 0) // obu_forbidden_bit
+ return AVERROR_INVALIDDATA;
+
+ *type = get_bits(&gb, 4);
+ extension_flag = get_bits1(&gb);
+ if (!get_bits1(&gb)) // has_size_flag
+ return AVERROR_INVALIDDATA;
+ skip_bits1(&gb); // obu_reserved_1bit
+
+ if (extension_flag) {
+ get_bits(&gb, 3); // temporal_id
+ get_bits(&gb, 2); // spatial_id
+ skip_bits(&gb, 3); // extension_header_reserved_3bits
+ }
+
+ *obu_size = leb128(&gb);
+ if (*obu_size > INT_MAX)
+ return AVERROR_INVALIDDATA;
+
+ if (get_bits_left(&gb) < 0)
+ return AVERROR_INVALIDDATA;
+
+ start_pos = get_bits_count(&gb) / 8;
+
+ size = *obu_size + start_pos;
+ if (size > INT_MAX)
+ return AVERROR_INVALIDDATA;
+ return size;
+}
+
+static int obu_probe(const AVProbeData *p)
+{
+ int64_t obu_size;
+ int seq = 0;
+ int ret, type, cnt;
+
+ // Check that the first OBU is a Temporal Delimiter.
+ cnt = read_obu_with_size(p->buf, p->buf_size, &obu_size, &type);
+ if (cnt < 0 || type != AV1_OBU_TEMPORAL_DELIMITER || obu_size != 0)
+ return 0;
+
+ while (1) {
+ ret = read_obu_with_size(p->buf + cnt, p->buf_size - cnt, &obu_size, &type);
+ if (ret < 0 || obu_size <= 0)
+ return 0;
+ cnt += ret;
+
+ ret = get_score(type, &seq);
+ if (ret >= 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int obu_read_header(AVFormatContext *s)
+{
+ ObuContext *c = s->priv_data;
+ c->fifo = av_fifo_alloc(MAX_OBU_HEADER_SIZE);
+ if (!c->fifo)
+ return AVERROR(ENOMEM);
+ return read_header(s, &c->framerate, &c->bsf, c);
+}
+
+static int obu_prefetch(AVFormatContext *s, uint8_t* dest)
+{
+ ObuContext *c = s->priv_data;
+ int size = av_fifo_space(c->fifo);
+ av_fifo_generic_write(c->fifo, s->pb, size,
+ (int (*)(void*, void*, int))avio_read);
+ size = av_fifo_size(c->fifo);
+ if (size > 0) {
+ av_fifo_generic_peek(c->fifo, dest, size, NULL);
+ }
+ return size;
+}
+
+static int obu_read_data(AVFormatContext *s, AVPacket *pkt, int len)
+{
+ int size, left;
+ ObuContext *c = s->priv_data;
+ int ret = av_new_packet(pkt, len);
+ if (ret < 0) {
+ av_log(c, AV_LOG_ERROR, "Failed to allocate packet for obu\n");
+ return ret;
+ }
+ size = FFMIN(av_fifo_size(c->fifo), len);
+ av_fifo_generic_read(c->fifo, pkt->data, size, NULL);
+ left = len - size;
+ if (left > 0) {
+ ret = avio_read(s->pb, pkt->data + size, left);
+ if (ret != left) {
+ av_log(c, AV_LOG_ERROR, "Failed to read %d frome file\n", left);
+ return ret < 0 ? ret : AVERROR_INVALIDDATA;
+ }
+ }
+ return 0;
+}
+
+static int obu_get_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ ObuContext *c = s->priv_data;
+ int64_t obu_size;
+ int ret, type;
+ uint8_t header[MAX_OBU_HEADER_SIZE];
+
+ ret = obu_prefetch(s, header);
+ if (!ret)
+ return 0;
+
+ ret = read_obu_with_size(header, ret, &obu_size, &type);
+ if (ret < 0) {
+ av_log(c, AV_LOG_ERROR, "Failed to read obu\n");
+ return ret;
+ }
+ return obu_read_data(s, pkt, ret);
+}
+
+static int obu_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ ObuContext *c = s->priv_data;
+ int ret;
+
+ while (1) {
+ ret = obu_get_packet(s, pkt);
+ if (ret < 0)
+ return ret;
+ ret = av_bsf_send_packet(c->bsf, pkt);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to send packet to "
+ "av1_frame_merge filter\n");
+ return ret;
+ }
+ ret = av_bsf_receive_packet(c->bsf, pkt);
+ if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
+ av_log(s, AV_LOG_ERROR, "av1_frame_merge filter failed to "
+ "send output packet\n");
+ if (ret != AVERROR(EAGAIN))
+ break;
+ }
+
+ return ret;
+}
+
+static int obu_read_close(AVFormatContext *s)
+{
+ ObuContext *c = s->priv_data;
+
+ av_fifo_freep(&c->fifo);
+ av_bsf_free(&c->bsf);
+ return 0;
+}
+
+#define OFFSET(x) offsetof(ObuContext, x)
+static const AVOption obu_options[] = {
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
+ { NULL },
+};
+#undef OFFSET
+
+static const AVClass obu_demuxer_class = {
+ .class_name = "AV1 low overhead OBU demuxer",
+ .item_name = av_default_item_name,
+ .option = obu_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_obu_demuxer = {
+ .name = "obu",
+ .long_name = NULL_IF_CONFIG_SMALL("AV1 low overhead OBU"),
+ .priv_data_size = sizeof(ObuContext),
+ .read_probe = obu_probe,
+ .read_header = obu_read_header,
+ .read_packet = obu_read_packet,
+ .read_close = obu_read_close,
+ .extensions = "obu",
+ .flags = AVFMT_GENERIC_INDEX,
+ .priv_class = &obu_demuxer_class,
+};
+#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/avc.c b/chromium/third_party/ffmpeg/libavformat/avc.c
index cd15ac3cdb1..b5e29213881 100644
--- a/chromium/third_party/ffmpeg/libavformat/avc.c
+++ b/chromium/third_party/ffmpeg/libavformat/avc.c
@@ -27,7 +27,7 @@
#include "avc.h"
#include "avio_internal.h"
-static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
+static const uint8_t *avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
{
const uint8_t *a = p + 4 - ((intptr_t)p & 3);
@@ -65,7 +65,7 @@ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uin
}
const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
- const uint8_t *out= ff_avc_find_startcode_internal(p, end);
+ const uint8_t *out = avc_find_startcode_internal(p, end);
if(p<out && out<end && !out[-1]) out--;
return out;
}
@@ -196,18 +196,17 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
avio_write(pb, pps, pps_size);
if (sps[3] != 66 && sps[3] != 77 && sps[3] != 88) {
- H264SequenceParameterSet *seq = ff_avc_decode_sps(sps + 3, sps_size - 3);
- if (!seq) {
- ret = AVERROR(ENOMEM);
+ H264SPS seq;
+ ret = ff_avc_decode_sps(&seq, sps + 3, sps_size - 3);
+ if (ret < 0)
goto fail;
- }
- avio_w8(pb, 0xfc | seq->chroma_format_idc); /* 6 bits reserved (111111) + chroma_format_idc */
- avio_w8(pb, 0xf8 | (seq->bit_depth_luma - 8)); /* 5 bits reserved (11111) + bit_depth_luma_minus8 */
- avio_w8(pb, 0xf8 | (seq->bit_depth_chroma - 8)); /* 5 bits reserved (11111) + bit_depth_chroma_minus8 */
+
+ avio_w8(pb, 0xfc | seq.chroma_format_idc); /* 6 bits reserved (111111) + chroma_format_idc */
+ avio_w8(pb, 0xf8 | (seq.bit_depth_luma - 8)); /* 5 bits reserved (11111) + bit_depth_luma_minus8 */
+ avio_w8(pb, 0xf8 | (seq.bit_depth_chroma - 8)); /* 5 bits reserved (11111) + bit_depth_chroma_minus8 */
avio_w8(pb, nb_sps_ext); /* number of sps ext */
if (nb_sps_ext)
avio_write(pb, sps_ext, sps_ext_size);
- av_free(seq);
}
fail:
@@ -332,27 +331,24 @@ static inline int get_se_golomb(GetBitContext *gb) {
return ((v >> 1) ^ sign) - sign;
}
-H264SequenceParameterSet *ff_avc_decode_sps(const uint8_t *buf, int buf_size)
+int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size)
{
int i, j, ret, rbsp_size, aspect_ratio_idc, pic_order_cnt_type;
int num_ref_frames_in_pic_order_cnt_cycle;
int delta_scale, lastScale = 8, nextScale = 8;
int sizeOfScalingList;
- H264SequenceParameterSet *sps = NULL;
GetBitContext gb;
uint8_t *rbsp_buf;
rbsp_buf = ff_nal_unit_extract_rbsp(buf, buf_size, &rbsp_size, 0);
if (!rbsp_buf)
- return NULL;
+ return AVERROR(ENOMEM);
ret = init_get_bits8(&gb, rbsp_buf, rbsp_size);
if (ret < 0)
goto end;
- sps = av_mallocz(sizeof(*sps));
- if (!sps)
- goto end;
+ memset(sps, 0, sizeof(*sps));
sps->profile_idc = get_bits(&gb, 8);
sps->constraint_set_flags |= get_bits1(&gb) << 0; // constraint_set0_flag
@@ -448,7 +444,8 @@ H264SequenceParameterSet *ff_avc_decode_sps(const uint8_t *buf, int buf_size)
sps->sar.den = 1;
}
+ ret = 0;
end:
av_free(rbsp_buf);
- return sps;
+ return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/avc.h b/chromium/third_party/ffmpeg/libavformat/avc.h
index 5286d19d890..9792b77913d 100644
--- a/chromium/third_party/ffmpeg/libavformat/avc.h
+++ b/chromium/third_party/ffmpeg/libavformat/avc.h
@@ -46,8 +46,8 @@ typedef struct {
uint8_t bit_depth_chroma;
uint8_t frame_mbs_only_flag;
AVRational sar;
-} H264SequenceParameterSet;
+} H264SPS;
-H264SequenceParameterSet *ff_avc_decode_sps(const uint8_t *src, int src_len);
+int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size);
#endif /* AVFORMAT_AVC_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/avformat.h b/chromium/third_party/ffmpeg/libavformat/avformat.h
index 39b99b44818..e91e7f1d33b 100644
--- a/chromium/third_party/ffmpeg/libavformat/avformat.h
+++ b/chromium/third_party/ffmpeg/libavformat/avformat.h
@@ -1120,7 +1120,6 @@ typedef struct AVStream {
* -1 -> probing finished
* 0 -> no probing requested
* rest -> perform probing with request_probe being the minimum score to accept.
- * NOT PART OF PUBLIC API
*/
int request_probe;
/**
@@ -1166,7 +1165,6 @@ typedef struct AVStream {
/**
* Timestamp offset added to timestamps before muxing
- * NOT PART OF PUBLIC API
*/
int64_t mux_ts_offset;
@@ -2191,7 +2189,8 @@ uint8_t *av_stream_new_side_data(AVStream *stream,
*
* @param stream stream
* @param type desired side information type
- * @param size pointer for side information size to store (optional)
+ * @param size If supplied, *size will be set to the size of the side data
+ * or to zero if the desired side data is not present.
* @return pointer to data if present or NULL otherwise
*/
uint8_t *av_stream_get_side_data(const AVStream *stream,
diff --git a/chromium/third_party/ffmpeg/libavformat/avienc.c b/chromium/third_party/ffmpeg/libavformat/avienc.c
index 297d5b8964a..1b2cb529b90 100644
--- a/chromium/third_party/ffmpeg/libavformat/avienc.c
+++ b/chromium/third_party/ffmpeg/libavformat/avienc.c
@@ -72,6 +72,7 @@ typedef struct AVIContext {
int reserve_index_space;
int master_index_max_size;
int write_channel_mask;
+ int flipped_raw_rgb;
} AVIContext;
typedef struct AVIStream {
@@ -449,7 +450,7 @@ static int avi_write_header(AVFormatContext *s)
&& par->bits_per_coded_sample == 15)
par->bits_per_coded_sample = 16;
avist->pal_offset = avio_tell(pb) + 40;
- ff_put_bmp_header(pb, par, 0, 0);
+ ff_put_bmp_header(pb, par, 0, 0, avi->flipped_raw_rgb);
pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi,
par->bits_per_coded_sample);
if ( !par->codec_tag
@@ -993,6 +994,7 @@ static void avi_deinit(AVFormatContext *s)
static const AVOption options[] = {
{ "reserve_index_space", "reserve space (in bytes) at the beginning of the file for each stream index", OFFSET(reserve_index_space), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, ENC },
{ "write_channel_mask", "write channel mask into wave format header", OFFSET(write_channel_mask), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
+ { "flipped_raw_rgb", "Raw RGB bitmaps are stored bottom-up", OFFSET(flipped_raw_rgb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/avio.c b/chromium/third_party/ffmpeg/libavformat/avio.c
index 237966c3030..3886ed7a90f 100644
--- a/chromium/third_party/ffmpeg/libavformat/avio.c
+++ b/chromium/third_party/ffmpeg/libavformat/avio.c
@@ -67,7 +67,10 @@ const AVClass ffurl_context_class = {
.option = options,
.version = LIBAVUTIL_VERSION_INT,
.child_next = urlcontext_child_next,
+#if FF_API_CHILD_CLASS_NEXT
.child_class_next = ff_urlcontext_child_class_next,
+#endif
+ .child_class_iterate = ff_urlcontext_child_class_iterate,
};
/*@}*/
diff --git a/chromium/third_party/ffmpeg/libavformat/aviobuf.c b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
index 85c01c938af..a77517d7121 100644
--- a/chromium/third_party/ffmpeg/libavformat/aviobuf.c
+++ b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
@@ -48,10 +48,19 @@ static void *ff_avio_child_next(void *obj, void *prev)
return prev ? NULL : s->opaque;
}
+#if FF_API_CHILD_CLASS_NEXT
static const AVClass *ff_avio_child_class_next(const AVClass *prev)
{
return prev ? NULL : &ffurl_context_class;
}
+#endif
+
+static const AVClass *child_class_iterate(void **iter)
+{
+ const AVClass *c = *iter ? NULL : &ffurl_context_class;
+ *iter = (void*)(uintptr_t)c;
+ return c;
+}
#define OFFSET(x) offsetof(AVIOContext,x)
#define E AV_OPT_FLAG_ENCODING_PARAM
@@ -67,7 +76,10 @@ const AVClass ff_avio_class = {
.version = LIBAVUTIL_VERSION_INT,
.option = ff_avio_options,
.child_next = ff_avio_child_next,
+#if FF_API_CHILD_CLASS_NEXT
.child_class_next = ff_avio_child_class_next,
+#endif
+ .child_class_iterate = child_class_iterate,
};
static void fill_buffer(AVIOContext *s);
@@ -432,26 +444,6 @@ PUT_STR16(be, 1)
#undef PUT_STR16
-int ff_get_v_length(uint64_t val)
-{
- int i = 1;
-
- while (val >>= 7)
- i++;
-
- return i;
-}
-
-void ff_put_v(AVIOContext *bc, uint64_t val)
-{
- int i = ff_get_v_length(val);
-
- while (--i > 0)
- avio_w8(bc, 128 | (uint8_t)(val >> (7*i)));
-
- avio_w8(bc, val & 127);
-}
-
void avio_wl64(AVIOContext *s, uint64_t val)
{
avio_wl32(s, (uint32_t)(val & 0xffffffff));
@@ -716,7 +708,7 @@ int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
int len;
if (size < 0)
- return -1;
+ return AVERROR(EINVAL);
if (s->read_packet && s->write_flag) {
len = read_packet_wrapper(s, buf, size);
@@ -1292,22 +1284,21 @@ typedef struct DynBuffer {
static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
{
DynBuffer *d = opaque;
- unsigned new_size, new_allocated_size;
+ unsigned new_size;
/* reallocate buffer if needed */
- new_size = d->pos + buf_size;
- new_allocated_size = d->allocated_size;
- if (new_size < d->pos || new_size > INT_MAX/2)
- return -1;
- while (new_size > new_allocated_size) {
- if (!new_allocated_size)
- new_allocated_size = new_size;
- else
+ new_size = (unsigned)d->pos + buf_size;
+ if (new_size < d->pos || new_size > INT_MAX)
+ return AVERROR(ERANGE);
+ if (new_size > d->allocated_size) {
+ unsigned new_allocated_size = d->allocated_size ? d->allocated_size
+ : new_size;
+ int err;
+ while (new_size > new_allocated_size)
new_allocated_size += new_allocated_size / 2 + 1;
- }
- if (new_allocated_size > d->allocated_size) {
- int err;
+ new_allocated_size = FFMIN(new_allocated_size, INT_MAX);
+
if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
d->allocated_size = 0;
d->size = 0;
@@ -1345,8 +1336,10 @@ static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
offset += d->pos;
else if (whence == SEEK_END)
offset += d->size;
- if (offset < 0 || offset > 0x7fffffffLL)
- return -1;
+ if (offset < 0)
+ return AVERROR(EINVAL);
+ if (offset > INT_MAX)
+ return AVERROR(ERANGE);
d->pos = offset;
return 0;
}
@@ -1357,7 +1350,7 @@ static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
- return -1;
+ return AVERROR(ERANGE);
d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
if (!d)
return AVERROR(ENOMEM);
@@ -1381,7 +1374,7 @@ int avio_open_dyn_buf(AVIOContext **s)
int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
{
if (max_packet_size <= 0)
- return -1;
+ return AVERROR(EINVAL);
return url_open_dyn_buf_internal(s, max_packet_size);
}
@@ -1389,13 +1382,13 @@ int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
{
DynBuffer *d;
- if (!s || s->error) {
+ if (!s) {
*pbuffer = NULL;
return 0;
}
d = s->opaque;
- if (!d->size) {
+ if (!s->error && !d->size) {
*pbuffer = d->io_buffer;
return FFMAX(s->buf_ptr, s->buf_ptr_max) - s->buffer;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/cache.c b/chromium/third_party/ffmpeg/libavformat/cache.c
index 09e5d5f832d..1e19dafc6a5 100644
--- a/chromium/third_party/ffmpeg/libavformat/cache.c
+++ b/chromium/third_party/ffmpeg/libavformat/cache.c
@@ -310,7 +310,7 @@ static int cache_close(URLContext *h)
av_log(h, AV_LOG_ERROR, "Could not delete %s.\n", c->filename);
av_freep(&c->filename);
}
- ffurl_close(c->inner);
+ ffurl_closep(&c->inner);
av_tree_enumerate(c->root, NULL, NULL, enu_free);
av_tree_destroy(c->root);
diff --git a/chromium/third_party/ffmpeg/libavformat/concat.c b/chromium/third_party/ffmpeg/libavformat/concat.c
index ea3bc1dfde8..418405dd50b 100644
--- a/chromium/third_party/ffmpeg/libavformat/concat.c
+++ b/chromium/third_party/ffmpeg/libavformat/concat.c
@@ -49,7 +49,7 @@ static av_cold int concat_close(URLContext *h)
struct concat_nodes *nodes = data->nodes;
for (i = 0; i != data->length; i++)
- err |= ffurl_close(nodes[i].uc);
+ err |= ffurl_closep(&nodes[i].uc);
av_freep(&data->nodes);
@@ -75,7 +75,6 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
if (uri[i] == *AV_CAT_SEPARATOR) {
/* integer overflow */
if (++len == UINT_MAX / sizeof(*nodes)) {
- av_freep(&h->priv_data);
return AVERROR(ENAMETOOLONG);
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/concatdec.c b/chromium/third_party/ffmpeg/libavformat/concatdec.c
index 2173911ce45..4b56b61404f 100644
--- a/chromium/third_party/ffmpeg/libavformat/concatdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/concatdec.c
@@ -626,17 +626,16 @@ 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));
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))) {
+ ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
+ packed_metadata, metadata_len);
+ if (ret < 0) {
av_freep(&packed_metadata);
- return AVERROR(ENOMEM);
+ return ret;
}
- memcpy(metadata, packed_metadata, metadata_len);
- av_freep(&packed_metadata);
}
if (cat->cur_file->duration == AV_NOPTS_VALUE && st->cur_dts != AV_NOPTS_VALUE) {
@@ -647,7 +646,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
}
pkt->stream_index = cs->out_stream_index;
- return ret;
+ return 0;
}
static void rescale_interval(AVRational tb_in, AVRational tb_out,
diff --git a/chromium/third_party/ffmpeg/libavformat/crypto.c b/chromium/third_party/ffmpeg/libavformat/crypto.c
index 9a48f2e6f51..1d4514e0f27 100644
--- a/chromium/third_party/ffmpeg/libavformat/crypto.c
+++ b/chromium/third_party/ffmpeg/libavformat/crypto.c
@@ -252,21 +252,17 @@ static int64_t crypto_seek(URLContext *h, int64_t pos, int whence)
case SEEK_CUR:
pos = pos + c->position;
break;
- case SEEK_END: {
- int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE );
+ case SEEK_END:
+ newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE );
if (newpos < 0) {
av_log(h, AV_LOG_ERROR,
"Crypto: seek_end - can't get file size (pos=%lld)\r\n", (long long int)pos);
return newpos;
}
pos = newpos - pos;
- }
- break;
- case AVSEEK_SIZE: {
- int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE );
- return newpos;
- }
break;
+ case AVSEEK_SIZE:
+ return ffurl_seek( c->hd, pos, AVSEEK_SIZE );
default:
av_log(h, AV_LOG_ERROR,
"Crypto: no support for seek where 'whence' is %d\r\n", whence);
@@ -385,8 +381,7 @@ static int crypto_close(URLContext *h)
ret = ffurl_write(c->hd, out_buf, BLOCKSIZE);
}
- if (c->hd)
- ffurl_close(c->hd);
+ ffurl_closep(&c->hd);
av_freep(&c->aes_decrypt);
av_freep(&c->aes_encrypt);
av_freep(&c->write_buf);
diff --git a/chromium/third_party/ffmpeg/libavformat/dashdec.c b/chromium/third_party/ffmpeg/libavformat/dashdec.c
index 5ba7feb245e..c5a5ff607bf 100644
--- a/chromium/third_party/ffmpeg/libavformat/dashdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/dashdec.c
@@ -29,6 +29,8 @@
#include "dash.h"
#define INITIAL_BUFFER_SIZE 32768
+#define MAX_MANIFEST_SIZE 50 * 1024
+#define DEFAULT_MANIFEST_SIZE 8 * 1024
struct fragment {
int64_t url_offset;
@@ -590,7 +592,7 @@ static struct fragment * get_Fragment(char *range)
char *str_end_offset;
char *str_offset = av_strtok(range, "-", &str_end_offset);
seg->url_offset = strtoll(str_offset, NULL, 10);
- seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset;
+ seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset + 1;
}
return seg;
@@ -1220,7 +1222,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
int close_in = 0;
uint8_t *new_url = NULL;
int64_t filesize = 0;
- char *buffer = NULL;
+ AVBPrint buf;
AVDictionary *opts = NULL;
xmlDoc *doc = NULL;
xmlNodePtr root_element = NULL;
@@ -1254,24 +1256,23 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
}
filesize = avio_size(in);
- if (filesize <= 0) {
- filesize = 8 * 1024;
+ if (filesize > MAX_MANIFEST_SIZE) {
+ av_log(s, AV_LOG_ERROR, "Manifest too large: %"PRId64"\n", filesize);
+ return AVERROR_INVALIDDATA;
}
- buffer = av_mallocz(filesize);
- if (!buffer) {
- av_free(c->base_url);
- return AVERROR(ENOMEM);
- }
+ av_bprint_init(&buf, (filesize > 0) ? filesize + 1 : DEFAULT_MANIFEST_SIZE, AV_BPRINT_SIZE_UNLIMITED);
- filesize = avio_read(in, buffer, filesize);
- if (filesize <= 0) {
- av_log(s, AV_LOG_ERROR, "Unable to read to offset '%s'\n", url);
- ret = AVERROR_INVALIDDATA;
+ if ((ret = avio_read_to_bprint(in, &buf, MAX_MANIFEST_SIZE)) < 0 ||
+ !avio_feof(in) ||
+ (filesize = buf.len) == 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to read to manifest '%s'\n", url);
+ if (ret == 0)
+ ret = AVERROR_INVALIDDATA;
} else {
LIBXML_TEST_VERSION
- doc = xmlReadMemory(buffer, filesize, c->base_url, NULL, 0);
+ doc = xmlReadMemory(buf.str, filesize, c->base_url, NULL, 0);
root_element = xmlDocGetRootElement(doc);
node = root_element;
@@ -1394,7 +1395,7 @@ cleanup:
}
av_free(new_url);
- av_free(buffer);
+ av_bprint_finalize(&buf, NULL);
if (close_in) {
avio_close(in);
}
@@ -1942,6 +1943,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
+ pls->ctx->interrupt_callback = s->interrupt_callback;
ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
@@ -2000,6 +2002,20 @@ static int open_demux_for_component(AVFormatContext *s, struct representation *p
st->id = i;
avcodec_parameters_copy(st->codecpar, ist->codecpar);
avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
+
+ // copy disposition
+ st->disposition = ist->disposition;
+
+ // copy side data
+ for (int i = 0; i < ist->nb_side_data; i++) {
+ const AVPacketSideData *sd_src = &ist->side_data[i];
+ uint8_t *dst_data;
+
+ dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size);
+ if (!dst_data)
+ return AVERROR(ENOMEM);
+ memcpy(dst_data, sd_src->data, sd_src->size);
+ }
}
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/dashenc.c b/chromium/third_party/ffmpeg/libavformat/dashenc.c
index 9f837857925..dc3306a56a2 100644
--- a/chromium/third_party/ffmpeg/libavformat/dashenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/dashenc.c
@@ -115,6 +115,7 @@ typedef struct OutputStream {
int64_t last_dts, last_pts;
int last_flags;
int bit_rate;
+ int first_segment_bit_rate;
SegmentType segment_type; /* segment type selected for this particular stream */
const char *format_name;
const char *extension_name;
@@ -171,6 +172,7 @@ typedef struct DASHContext {
const char *user_agent;
AVDictionary *http_opts;
int hls_playlist;
+ const char *hls_master_name;
int http_persistent;
int master_playlist_created;
AVIOContext *mpd_out;
@@ -196,6 +198,7 @@ typedef struct DASHContext {
int target_latency_refid;
AVRational min_playback_rate;
AVRational max_playback_rate;
+ int64_t update_period;
} DASHContext;
static struct codec_string {
@@ -839,8 +842,12 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind
continue;
if (os->bit_rate > 0)
- snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"",
- os->bit_rate);
+ snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->bit_rate);
+ else if (final) {
+ int average_bit_rate = os->pos * 8 * AV_TIME_BASE / c->total_duration;
+ snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", average_bit_rate);
+ } else if (os->first_segment_bit_rate > 0)
+ snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->first_segment_bit_rate);
if (as->media_type == AVMEDIA_TYPE_VIDEO) {
avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"video/%s\" codecs=\"%s\"%s width=\"%d\" height=\"%d\"",
@@ -1178,6 +1185,8 @@ static int write_manifest(AVFormatContext *s, int final)
char now_str[100];
if (c->use_template && !c->use_timeline)
update_period = 500;
+ if (c->update_period)
+ update_period = c->update_period;
avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period);
if (!c->ldash)
avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE);
@@ -1261,9 +1270,9 @@ static int write_manifest(AVFormatContext *s, int final)
return 0;
if (*c->dirname)
- snprintf(filename_hls, sizeof(filename_hls), "%smaster.m3u8", c->dirname);
+ snprintf(filename_hls, sizeof(filename_hls), "%s%s", c->dirname, c->hls_master_name);
else
- snprintf(filename_hls, sizeof(filename_hls), "master.m3u8");
+ snprintf(filename_hls, sizeof(filename_hls), "%s", c->hls_master_name);
snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", filename_hls);
@@ -1304,7 +1313,13 @@ static int write_manifest(AVFormatContext *s, int final)
OutputStream *os = &c->streams[i];
char *agroup = NULL;
char *codec_str_ptr = NULL;
- int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead;
+ int stream_bitrate = os->muxer_overhead;
+ if (os->bit_rate > 0)
+ stream_bitrate += os->bit_rate;
+ else if (final)
+ stream_bitrate += os->pos * 8 * AV_TIME_BASE / c->total_duration;
+ else if (os->first_segment_bit_rate > 0)
+ stream_bitrate += os->first_segment_bit_rate;
if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
continue;
if (os->segment_type != SEGMENT_TYPE_MP4)
@@ -1731,7 +1746,7 @@ static int add_segment(OutputStream *os, const char *file,
Segment *seg;
if (os->nb_segments >= os->segments_size) {
os->segments_size = (os->segments_size + 1) * 2;
- if ((err = av_reallocp(&os->segments, sizeof(*os->segments) *
+ if ((err = av_reallocp_array(&os->segments, sizeof(*os->segments),
os->segments_size)) < 0) {
os->segments_size = 0;
os->nb_segments = 0;
@@ -1850,28 +1865,20 @@ static void dashenc_delete_file(AVFormatContext *s, char *filename) {
static int dashenc_delete_segment_file(AVFormatContext *s, const char* file)
{
DASHContext *c = s->priv_data;
- size_t dirname_len, file_len;
- char filename[1024];
-
- dirname_len = strlen(c->dirname);
- if (dirname_len >= sizeof(filename)) {
- av_log(s, AV_LOG_WARNING, "Cannot delete segments as the directory path is too long: %"PRIu64" characters: %s\n",
- (uint64_t)dirname_len, c->dirname);
- return AVERROR(ENAMETOOLONG);
- }
+ AVBPrint buf;
- memcpy(filename, c->dirname, dirname_len);
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
- file_len = strlen(file);
- if ((dirname_len + file_len) >= sizeof(filename)) {
- av_log(s, AV_LOG_WARNING, "Cannot delete segments as the path is too long: %"PRIu64" characters: %s%s\n",
- (uint64_t)(dirname_len + file_len), c->dirname, file);
- return AVERROR(ENAMETOOLONG);
+ av_bprintf(&buf, "%s%s", c->dirname, file);
+ if (!av_bprint_is_complete(&buf)) {
+ av_bprint_finalize(&buf, NULL);
+ av_log(s, AV_LOG_WARNING, "Out of memory for filename\n");
+ return AVERROR(ENOMEM);
}
- memcpy(filename + dirname_len, file, file_len + 1); // include the terminating zero
- dashenc_delete_file(s, filename);
+ dashenc_delete_file(s, buf.str);
+ av_bprint_finalize(&buf, NULL);
return 0;
}
@@ -1916,6 +1923,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
OutputStream *os = &c->streams[i];
AVStream *st = s->streams[i];
int range_length, index_length = 0;
+ int64_t duration;
if (!os->packets_written)
continue;
@@ -1955,25 +1963,17 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
}
}
- os->last_duration = FFMAX(os->last_duration, av_rescale_q(os->max_pts - os->start_pts,
- st->time_base,
- AV_TIME_BASE_Q));
+ duration = av_rescale_q(os->max_pts - os->start_pts, st->time_base, AV_TIME_BASE_Q);
+ os->last_duration = FFMAX(os->last_duration, duration);
if (!os->muxer_overhead && os->max_pts > os->start_pts)
os->muxer_overhead = ((int64_t) (range_length - os->total_pkt_size) *
- 8 * AV_TIME_BASE) /
- av_rescale_q(os->max_pts - os->start_pts,
- st->time_base, AV_TIME_BASE_Q);
+ 8 * AV_TIME_BASE) / duration;
os->total_pkt_size = 0;
os->total_pkt_duration = 0;
- if (!os->bit_rate) {
- // calculate average bitrate of first segment
- int64_t bitrate = (int64_t) range_length * 8 * AV_TIME_BASE / av_rescale_q(os->max_pts - os->start_pts,
- st->time_base,
- AV_TIME_BASE_Q);
- if (bitrate >= 0)
- os->bit_rate = bitrate;
+ if (!os->bit_rate && !os->first_segment_bit_rate) {
+ os->first_segment_bit_rate = (int64_t) range_length * 8 * AV_TIME_BASE / duration;
}
add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length, next_exp_index);
av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path);
@@ -2149,22 +2149,22 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
av_compare_ts(elapsed_duration, st->time_base,
seg_end_duration, AV_TIME_BASE_Q) >= 0) {
if (!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
- c->last_duration = av_rescale_q(pkt->pts - os->start_pts,
- st->time_base,
- AV_TIME_BASE_Q);
- c->total_duration = av_rescale_q(pkt->pts - os->first_pts,
- st->time_base,
- AV_TIME_BASE_Q);
-
- if ((!c->use_timeline || !c->use_template) && os->last_duration) {
- if (c->last_duration < os->last_duration*9/10 ||
- c->last_duration > os->last_duration*11/10) {
- av_log(s, AV_LOG_WARNING,
- "Segment durations differ too much, enable use_timeline "
- "and use_template, or keep a stricter keyframe interval\n");
+ c->last_duration = av_rescale_q(pkt->pts - os->start_pts,
+ st->time_base,
+ AV_TIME_BASE_Q);
+ c->total_duration = av_rescale_q(pkt->pts - os->first_pts,
+ st->time_base,
+ AV_TIME_BASE_Q);
+
+ if ((!c->use_timeline || !c->use_template) && os->last_duration) {
+ if (c->last_duration < os->last_duration*9/10 ||
+ c->last_duration > os->last_duration*11/10) {
+ av_log(s, AV_LOG_WARNING,
+ "Segment durations differ too much, enable use_timeline "
+ "and use_template, or keep a stricter keyframe interval\n");
+ }
}
}
- }
if (c->write_prft && os->producer_reference_time.wallclock && !os->producer_reference_time_str[0])
format_date(os->producer_reference_time_str,
@@ -2304,7 +2304,7 @@ static int dash_write_trailer(AVFormatContext *s)
if (c->hls_playlist && c->master_playlist_created) {
char filename[1024];
- snprintf(filename, sizeof(filename), "%smaster.m3u8", c->dirname);
+ snprintf(filename, sizeof(filename), "%s%s", c->dirname, c->hls_master_name);
dashenc_delete_file(s, filename);
}
}
@@ -2361,6 +2361,7 @@ static const AVOption options[] = {
{ "http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{ "http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{ "hls_playlist", "Generate HLS playlist files(master.m3u8, media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
+ { "hls_master_name", "HLS master playlist name", OFFSET(hls_master_name), AV_OPT_TYPE_STRING, {.str = "master.m3u8"}, 0, 0, E },
{ "streaming", "Enable/Disable streaming mode of output. Each frame will be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
{ "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
{ "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
@@ -2382,6 +2383,7 @@ static const AVOption options[] = {
{ "target_latency", "Set desired target latency for Low-latency dash", OFFSET(target_latency), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, E },
{ "min_playback_rate", "Set desired minimum playback rate", OFFSET(min_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E },
{ "max_playback_rate", "Set desired maximum playback rate", OFFSET(max_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E },
+ { "update_period", "Set the mpd update interval", OFFSET(update_period), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/daudenc.c b/chromium/third_party/ffmpeg/libavformat/daudenc.c
index 15a5afdfc96..b489659a80b 100644
--- a/chromium/third_party/ffmpeg/libavformat/daudenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/daudenc.c
@@ -21,11 +21,11 @@
#include "avformat.h"
-static int daud_write_header(struct AVFormatContext *s)
+static int daud_init(struct AVFormatContext *s)
{
AVCodecParameters *par = s->streams[0]->codecpar;
if (par->channels!=6 || par->sample_rate!=96000)
- return -1;
+ return AVERROR(EINVAL);
return 0;
}
@@ -34,7 +34,7 @@ static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt)
if (pkt->size > 65535) {
av_log(s, AV_LOG_ERROR,
"Packet size too large for s302m. (%d > 65535)\n", pkt->size);
- return -1;
+ return AVERROR_INVALIDDATA;
}
avio_wb16(s->pb, pkt->size);
avio_wb16(s->pb, 0x8010); // unknown
@@ -48,7 +48,7 @@ AVOutputFormat ff_daud_muxer = {
.extensions = "302",
.audio_codec = AV_CODEC_ID_PCM_S24DAUD,
.video_codec = AV_CODEC_ID_NONE,
- .write_header = daud_write_header,
+ .init = daud_init,
.write_packet = daud_write_packet,
.flags = AVFMT_NOTIMESTAMPS,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/dsfdec.c b/chromium/third_party/ffmpeg/libavformat/dsfdec.c
index 52cddab2c8b..c9740cf28f6 100644
--- a/chromium/third_party/ffmpeg/libavformat/dsfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/dsfdec.c
@@ -56,8 +56,8 @@ static void read_id3(AVFormatContext *s, uint64_t id3pos)
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0);
if (id3v2_extra_meta) {
- ff_id3v2_parse_apic(s, &id3v2_extra_meta);
- ff_id3v2_parse_chapters(s, &id3v2_extra_meta);
+ ff_id3v2_parse_apic(s, id3v2_extra_meta);
+ ff_id3v2_parse_chapters(s, id3v2_extra_meta);
}
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/dump.c b/chromium/third_party/ffmpeg/libavformat/dump.c
index 5e9a03185f1..6d29d85d1fb 100644
--- a/chromium/third_party/ffmpeg/libavformat/dump.c
+++ b/chromium/third_party/ffmpeg/libavformat/dump.c
@@ -34,6 +34,7 @@
#include "libavutil/replaygain.h"
#include "libavutil/spherical.h"
#include "libavutil/stereo3d.h"
+#include "libavutil/timecode.h"
#include "avformat.h"
@@ -131,10 +132,10 @@ static void print_fps(double d, const char *postfix)
av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix);
}
-static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
+static void dump_metadata(void *ctx, const AVDictionary *m, const char *indent)
{
if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))) {
- AVDictionaryEntry *tag = NULL;
+ const AVDictionaryEntry *tag = NULL;
av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX)))
@@ -158,7 +159,7 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
}
/* param change side data*/
-static void dump_paramchange(void *ctx, AVPacketSideData *sd)
+static void dump_paramchange(void *ctx, const AVPacketSideData *sd)
{
int size = sd->size;
const uint8_t *data = sd->data;
@@ -211,7 +212,7 @@ static void dump_paramchange(void *ctx, AVPacketSideData *sd)
return;
fail:
- av_log(ctx, AV_LOG_ERROR, "unknown param");
+ av_log(ctx, AV_LOG_ERROR, "unknown param\n");
}
/* replaygain side data*/
@@ -235,15 +236,15 @@ static void print_peak(void *ctx, const char *str, uint32_t peak)
av_log(ctx, AV_LOG_INFO, ", ");
}
-static void dump_replaygain(void *ctx, AVPacketSideData *sd)
+static void dump_replaygain(void *ctx, const AVPacketSideData *sd)
{
- AVReplayGain *rg;
+ const AVReplayGain *rg;
if (sd->size < sizeof(*rg)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
- rg = (AVReplayGain*)sd->data;
+ rg = (const AVReplayGain *)sd->data;
print_gain(ctx, "track gain", rg->track_gain);
print_peak(ctx, "track peak", rg->track_peak);
@@ -251,16 +252,16 @@ static void dump_replaygain(void *ctx, AVPacketSideData *sd)
print_peak(ctx, "album peak", rg->album_peak);
}
-static void dump_stereo3d(void *ctx, AVPacketSideData *sd)
+static void dump_stereo3d(void *ctx, const AVPacketSideData *sd)
{
- AVStereo3D *stereo;
+ const AVStereo3D *stereo;
if (sd->size < sizeof(*stereo)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
- stereo = (AVStereo3D *)sd->data;
+ stereo = (const AVStereo3D *)sd->data;
av_log(ctx, AV_LOG_INFO, "%s", av_stereo3d_type_name(stereo->type));
@@ -268,12 +269,12 @@ static void dump_stereo3d(void *ctx, AVPacketSideData *sd)
av_log(ctx, AV_LOG_INFO, " (inverted)");
}
-static void dump_audioservicetype(void *ctx, AVPacketSideData *sd)
+static void dump_audioservicetype(void *ctx, const AVPacketSideData *sd)
{
- enum AVAudioServiceType *ast = (enum AVAudioServiceType *)sd->data;
+ const enum AVAudioServiceType *ast = (const enum AVAudioServiceType *)sd->data;
if (sd->size < sizeof(*ast)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
@@ -311,12 +312,12 @@ static void dump_audioservicetype(void *ctx, AVPacketSideData *sd)
}
}
-static void dump_cpb(void *ctx, AVPacketSideData *sd)
+static void dump_cpb(void *ctx, const AVPacketSideData *sd)
{
- AVCPBProperties *cpb = (AVCPBProperties *)sd->data;
+ const AVCPBProperties *cpb = (const AVCPBProperties *)sd->data;
if (sd->size < sizeof(*cpb)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
@@ -334,8 +335,10 @@ static void dump_cpb(void *ctx, AVPacketSideData *sd)
av_log(ctx, AV_LOG_INFO, "vbv_delay: %"PRIu64"", cpb->vbv_delay);
}
-static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) {
- AVMasteringDisplayMetadata* metadata = (AVMasteringDisplayMetadata*)sd->data;
+static void dump_mastering_display_metadata(void *ctx, const AVPacketSideData *sd)
+{
+ const AVMasteringDisplayMetadata *metadata =
+ (const AVMasteringDisplayMetadata *)sd->data;
av_log(ctx, AV_LOG_INFO, "Mastering Display Metadata, "
"has_primaries:%d has_luminance:%d "
"r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) "
@@ -351,21 +354,23 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) {
av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
}
-static void dump_content_light_metadata(void *ctx, AVPacketSideData* sd)
+static void dump_content_light_metadata(void *ctx, const AVPacketSideData *sd)
{
- AVContentLightMetadata* metadata = (AVContentLightMetadata*)sd->data;
+ const AVContentLightMetadata *metadata =
+ (const AVContentLightMetadata *)sd->data;
av_log(ctx, AV_LOG_INFO, "Content Light Level Metadata, "
"MaxCLL=%d, MaxFALL=%d",
metadata->MaxCLL, metadata->MaxFALL);
}
-static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *sd)
+static void dump_spherical(void *ctx, const AVCodecParameters *par,
+ const AVPacketSideData *sd)
{
- AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
+ const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data;
double yaw, pitch, roll;
if (sd->size < sizeof(*spherical)) {
- av_log(ctx, AV_LOG_ERROR, "invalid data");
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
return;
}
@@ -388,9 +393,10 @@ static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *
}
}
-static void dump_dovi_conf(void *ctx, AVPacketSideData* sd)
+static void dump_dovi_conf(void *ctx, const AVPacketSideData *sd)
{
- AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data;
+ const AVDOVIDecoderConfigurationRecord *dovi =
+ (const AVDOVIDecoderConfigurationRecord *)sd->data;
av_log(ctx, AV_LOG_INFO, "version: %d.%d, profile: %d, level: %d, "
"rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d",
@@ -402,7 +408,23 @@ static void dump_dovi_conf(void *ctx, AVPacketSideData* sd)
dovi->dv_bl_signal_compatibility_id);
}
-static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
+static void dump_s12m_timecode(void *ctx, const AVPacketSideData *sd)
+{
+ const uint32_t *tc = (const uint32_t *)sd->data;
+
+ if ((sd->size != sizeof(uint32_t) * 4) || (tc[0] > 3)) {
+ av_log(ctx, AV_LOG_ERROR, "invalid data\n");
+ return;
+ }
+
+ for (int j = 1; j <= tc[0]; j++) {
+ char tcbuf[AV_TIMECODE_STR_SIZE];
+ av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0);
+ av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : "");
+ }
+}
+
+static void dump_sidedata(void *ctx, const AVStream *st, const char *indent)
{
int i;
@@ -410,10 +432,10 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
av_log(ctx, AV_LOG_INFO, "%sSide data:\n", indent);
for (i = 0; i < st->nb_side_data; i++) {
- AVPacketSideData sd = st->side_data[i];
+ const AVPacketSideData *sd = &st->side_data[i];
av_log(ctx, AV_LOG_INFO, "%s ", indent);
- switch (sd.type) {
+ switch (sd->type) {
case AV_PKT_DATA_PALETTE:
av_log(ctx, AV_LOG_INFO, "palette");
break;
@@ -422,55 +444,59 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
break;
case AV_PKT_DATA_PARAM_CHANGE:
av_log(ctx, AV_LOG_INFO, "paramchange: ");
- dump_paramchange(ctx, &sd);
+ dump_paramchange(ctx, sd);
break;
case AV_PKT_DATA_H263_MB_INFO:
av_log(ctx, AV_LOG_INFO, "H.263 macroblock info");
break;
case AV_PKT_DATA_REPLAYGAIN:
av_log(ctx, AV_LOG_INFO, "replaygain: ");
- dump_replaygain(ctx, &sd);
+ dump_replaygain(ctx, sd);
break;
case AV_PKT_DATA_DISPLAYMATRIX:
av_log(ctx, AV_LOG_INFO, "displaymatrix: rotation of %.2f degrees",
- av_display_rotation_get((int32_t *)sd.data));
+ av_display_rotation_get((const int32_t *)sd->data));
break;
case AV_PKT_DATA_STEREO3D:
av_log(ctx, AV_LOG_INFO, "stereo3d: ");
- dump_stereo3d(ctx, &sd);
+ dump_stereo3d(ctx, sd);
break;
case AV_PKT_DATA_AUDIO_SERVICE_TYPE:
av_log(ctx, AV_LOG_INFO, "audio service type: ");
- dump_audioservicetype(ctx, &sd);
+ dump_audioservicetype(ctx, sd);
break;
case AV_PKT_DATA_QUALITY_STATS:
av_log(ctx, AV_LOG_INFO, "quality factor: %"PRId32", pict_type: %c",
- AV_RL32(sd.data), av_get_picture_type_char(sd.data[4]));
+ AV_RL32(sd->data), av_get_picture_type_char(sd->data[4]));
break;
case AV_PKT_DATA_CPB_PROPERTIES:
av_log(ctx, AV_LOG_INFO, "cpb: ");
- dump_cpb(ctx, &sd);
+ dump_cpb(ctx, sd);
break;
case AV_PKT_DATA_MASTERING_DISPLAY_METADATA:
- dump_mastering_display_metadata(ctx, &sd);
+ dump_mastering_display_metadata(ctx, sd);
break;
case AV_PKT_DATA_SPHERICAL:
av_log(ctx, AV_LOG_INFO, "spherical: ");
- dump_spherical(ctx, st->codecpar, &sd);
+ dump_spherical(ctx, st->codecpar, sd);
break;
case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:
- dump_content_light_metadata(ctx, &sd);
+ dump_content_light_metadata(ctx, sd);
break;
case AV_PKT_DATA_ICC_PROFILE:
av_log(ctx, AV_LOG_INFO, "ICC Profile");
break;
case AV_PKT_DATA_DOVI_CONF:
av_log(ctx, AV_LOG_INFO, "DOVI configuration record: ");
- dump_dovi_conf(ctx, &sd);
+ dump_dovi_conf(ctx, sd);
+ break;
+ case AV_PKT_DATA_S12M_TIMECODE:
+ av_log(ctx, AV_LOG_INFO, "SMPTE ST 12-1:2014: ");
+ dump_s12m_timecode(ctx, sd);
break;
default:
av_log(ctx, AV_LOG_INFO,
- "unknown side data type %d (%d bytes)", sd.type, sd.size);
+ "unknown side data type %d (%d bytes)", sd->type, sd->size);
break;
}
@@ -479,14 +505,14 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
}
/* "user interface" functions */
-static void dump_stream_format(AVFormatContext *ic, int i,
+static void dump_stream_format(const AVFormatContext *ic, int i,
int index, int is_output)
{
char buf[256];
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
- AVStream *st = ic->streams[i];
- AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
- char *separator = ic->dump_separator;
+ const AVStream *st = ic->streams[i];
+ const AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
+ const char *separator = ic->dump_separator;
AVCodecContext *avctx;
int ret;
@@ -500,6 +526,8 @@ static void dump_stream_format(AVFormatContext *ic, int i,
return;
}
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
// Fields which are missing from AVCodecParameters need to be taken from the AVCodecContext
avctx->properties = st->codec->properties;
avctx->codec = st->codec->codec;
@@ -507,6 +535,8 @@ static void dump_stream_format(AVFormatContext *ic, int i,
avctx->qmax = st->codec->qmax;
avctx->coded_width = st->codec->coded_width;
avctx->coded_height = st->codec->coded_height;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (separator)
av_opt_set(avctx, "dump_separator", separator, 0);
@@ -541,7 +571,13 @@ static void dump_stream_format(AVFormatContext *ic, int i,
int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
int tbn = st->time_base.den && st->time_base.num;
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
int tbc = st->codec->time_base.den && st->codec->time_base.num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ int tbc = 0;
+#endif
if (fps || tbr || tbn || tbc)
av_log(NULL, AV_LOG_INFO, "%s", separator);
@@ -552,8 +588,12 @@ static void dump_stream_format(AVFormatContext *ic, int i,
print_fps(av_q2d(st->r_frame_rate), tbn || tbc ? "tbr, " : "tbr");
if (tbn)
print_fps(1 / av_q2d(st->time_base), tbc ? "tbn, " : "tbn");
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
if (tbc)
print_fps(1 / av_q2d(st->codec->time_base), "tbc");
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
}
if (st->disposition & AV_DISPOSITION_DEFAULT)
@@ -615,7 +655,7 @@ void av_dump_format(AVFormatContext *ic, int index,
if (!is_output) {
av_log(NULL, AV_LOG_INFO, " Duration: ");
if (ic->duration != AV_NOPTS_VALUE) {
- int hours, mins, secs, us;
+ int64_t hours, mins, secs, us;
int64_t duration = ic->duration + (ic->duration <= INT64_MAX - 5000 ? 5000 : 0);
secs = duration / AV_TIME_BASE;
us = duration % AV_TIME_BASE;
@@ -623,7 +663,7 @@ void av_dump_format(AVFormatContext *ic, int index,
secs %= 60;
hours = mins / 60;
mins %= 60;
- av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%02d", hours, mins, secs,
+ av_log(NULL, AV_LOG_INFO, "%02"PRId64":%02"PRId64":%02"PRId64".%02"PRId64"", hours, mins, secs,
(100 * us) / AV_TIME_BASE);
} else {
av_log(NULL, AV_LOG_INFO, "N/A");
@@ -647,7 +687,7 @@ void av_dump_format(AVFormatContext *ic, int index,
}
for (i = 0; i < ic->nb_chapters; i++) {
- AVChapter *ch = ic->chapters[i];
+ const AVChapter *ch = ic->chapters[i];
av_log(NULL, AV_LOG_INFO, " Chapter #%d:%d: ", index, i);
av_log(NULL, AV_LOG_INFO,
"start %f, ", ch->start * av_q2d(ch->time_base));
@@ -660,17 +700,18 @@ void av_dump_format(AVFormatContext *ic, int index,
if (ic->nb_programs) {
int j, k, total = 0;
for (j = 0; j < ic->nb_programs; j++) {
- AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata,
- "name", NULL, 0);
- av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id,
+ const AVProgram *program = ic->programs[j];
+ const AVDictionaryEntry *name = av_dict_get(program->metadata,
+ "name", NULL, 0);
+ av_log(NULL, AV_LOG_INFO, " Program %d %s\n", program->id,
name ? name->value : "");
- dump_metadata(NULL, ic->programs[j]->metadata, " ");
- for (k = 0; k < ic->programs[j]->nb_stream_indexes; k++) {
- dump_stream_format(ic, ic->programs[j]->stream_index[k],
+ dump_metadata(NULL, program->metadata, " ");
+ for (k = 0; k < program->nb_stream_indexes; k++) {
+ dump_stream_format(ic, program->stream_index[k],
index, is_output);
- printed[ic->programs[j]->stream_index[k]] = 1;
+ printed[program->stream_index[k]] = 1;
}
- total += ic->programs[j]->nb_stream_indexes;
+ total += program->nb_stream_indexes;
}
if (total < ic->nb_streams)
av_log(NULL, AV_LOG_INFO, " No Program\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/dv.c b/chromium/third_party/ffmpeg/libavformat/dv.c
index e99422d4b59..d25641daac0 100644
--- a/chromium/third_party/ffmpeg/libavformat/dv.c
+++ b/chromium/third_party/ffmpeg/libavformat/dv.c
@@ -321,6 +321,21 @@ static int dv_extract_timecode(DVDemuxContext* c, const uint8_t* frame, char *tc
/* The following 3 functions constitute our interface to the world */
+static int dv_init_demux(AVFormatContext *s, DVDemuxContext *c)
+{
+ c->vst = avformat_new_stream(s, NULL);
+ if (!c->vst)
+ return AVERROR(ENOMEM);
+
+ c->fctx = s;
+ c->vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ c->vst->codecpar->codec_id = AV_CODEC_ID_DVVIDEO;
+ c->vst->codecpar->bit_rate = 25000000;
+ c->vst->start_time = 0;
+
+ return 0;
+}
+
DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s)
{
DVDemuxContext *c;
@@ -329,18 +344,11 @@ DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s)
if (!c)
return NULL;
- c->vst = avformat_new_stream(s, NULL);
- if (!c->vst) {
+ if (dv_init_demux(s, c)) {
av_free(c);
return NULL;
}
- c->fctx = s;
- c->vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
- c->vst->codecpar->codec_id = AV_CODEC_ID_DVVIDEO;
- c->vst->codecpar->bit_rate = 25000000;
- c->vst->start_time = 0;
-
return c;
}
@@ -452,7 +460,7 @@ void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
************************************************************/
typedef struct RawDVContext {
- DVDemuxContext *dv_demux;
+ DVDemuxContext dv_demux;
uint8_t buf[DV_MAX_FRAME_SIZE];
} RawDVContext;
@@ -462,31 +470,26 @@ static int dv_read_timecode(AVFormatContext *s) {
int64_t pos = avio_tell(s->pb);
// Read 3 DIF blocks: Header block and 2 Subcode blocks.
- int partial_frame_size = 3 * 80;
- uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) *
- partial_frame_size);
-
+#define PARTIAL_FRAME_SIZE (3 * 80)
+ uint8_t partial_frame[PARTIAL_FRAME_SIZE];
RawDVContext *c = s->priv_data;
- if (!partial_frame)
- return AVERROR(ENOMEM);
- ret = avio_read(s->pb, partial_frame, partial_frame_size);
+ ret = avio_read(s->pb, partial_frame, PARTIAL_FRAME_SIZE);
if (ret < 0)
goto finish;
- if (ret < partial_frame_size) {
+ if (ret < PARTIAL_FRAME_SIZE) {
ret = -1;
goto finish;
}
- ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode);
+ ret = dv_extract_timecode(&c->dv_demux, partial_frame, timecode);
if (ret)
av_dict_set(&s->metadata, "timecode", timecode, 0);
else
av_log(s, AV_LOG_ERROR, "Detected timecode is invalid\n");
finish:
- av_free(partial_frame);
avio_seek(s->pb, pos, SEEK_SET);
return ret;
}
@@ -497,16 +500,14 @@ static int dv_read_header(AVFormatContext *s)
RawDVContext *c = s->priv_data;
int ret;
- c->dv_demux = avpriv_dv_init_demux(s);
- if (!c->dv_demux)
- return AVERROR(ENOMEM);
+ if ((ret = dv_init_demux(s, &c->dv_demux)) < 0)
+ return ret;
state = avio_rb32(s->pb);
while ((state & 0xffffff7f) != 0x1f07003f) {
if (avio_feof(s->pb)) {
av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
+ return AVERROR_INVALIDDATA;
}
if (state == 0x003f0700 || state == 0xff3f0700)
marker_pos = avio_tell(s->pb);
@@ -521,33 +522,26 @@ static int dv_read_header(AVFormatContext *s)
if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) != DV_PROFILE_BYTES - 4 ||
avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0) {
- ret = AVERROR(EIO);
- goto fail;
+ return AVERROR(EIO);
}
- c->dv_demux->sys = av_dv_frame_profile(c->dv_demux->sys,
+ c->dv_demux.sys = av_dv_frame_profile(c->dv_demux.sys,
c->buf,
DV_PROFILE_BYTES);
- if (!c->dv_demux->sys) {
+ if (!c->dv_demux.sys) {
av_log(s, AV_LOG_ERROR,
"Can't determine profile of DV input stream.\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
+ return AVERROR_INVALIDDATA;
}
- s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size,
+ s->bit_rate = av_rescale_q(c->dv_demux.sys->frame_size,
(AVRational) { 8, 1 },
- c->dv_demux->sys->time_base);
+ c->dv_demux.sys->time_base);
if (s->pb->seekable & AVIO_SEEKABLE_NORMAL)
dv_read_timecode(s);
return 0;
-
-fail:
- av_freep(&c->dv_demux);
-
- return ret;
}
static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
@@ -555,14 +549,14 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
int size;
RawDVContext *c = s->priv_data;
- size = avpriv_dv_get_packet(c->dv_demux, 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)
+ if (!c->dv_demux.sys)
return AVERROR(EIO);
- size = c->dv_demux->sys->frame_size;
+ size = c->dv_demux.sys->frame_size;
ret = avio_read(s->pb, c->buf, size);
if (ret < 0) {
return ret;
@@ -570,7 +564,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
}
- size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
+ size = avpriv_dv_produce_packet(&c->dv_demux, pkt, c->buf, size, pos);
}
return size;
@@ -580,7 +574,7 @@ static int dv_read_seek(AVFormatContext *s, int stream_index,
int64_t timestamp, int flags)
{
RawDVContext *r = s->priv_data;
- DVDemuxContext *c = r->dv_demux;
+ DVDemuxContext *c = &r->dv_demux;
int64_t offset = dv_frame_offset(s, c, timestamp, flags);
if (avio_seek(s->pb, offset, SEEK_SET) < 0)
@@ -590,13 +584,6 @@ static int dv_read_seek(AVFormatContext *s, int stream_index,
return 0;
}
-static int dv_read_close(AVFormatContext *s)
-{
- RawDVContext *c = s->priv_data;
- av_freep(&c->dv_demux);
- return 0;
-}
-
static int dv_probe(const AVProbeData *p)
{
unsigned marker_pos = 0;
@@ -646,7 +633,6 @@ AVInputFormat ff_dv_demuxer = {
.read_probe = dv_probe,
.read_header = dv_read_header,
.read_packet = dv_read_packet,
- .read_close = dv_read_close,
.read_seek = dv_read_seek,
.extensions = "dv,dif",
};
diff --git a/chromium/third_party/ffmpeg/libavformat/dvenc.c b/chromium/third_party/ffmpeg/libavformat/dvenc.c
index c71e532771e..b04d6044d76 100644
--- a/chromium/third_party/ffmpeg/libavformat/dvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/dvenc.c
@@ -406,9 +406,10 @@ static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt)
fsize = dv_assemble_frame(s, s->priv_data, s->streams[pkt->stream_index],
pkt->data, pkt->size, &frame);
- if (fsize > 0) {
- avio_write(s->pb, frame, fsize);
+ if (fsize < 0) {
+ return fsize;
}
+ avio_write(s->pb, frame, fsize);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/fifo.c b/chromium/third_party/ffmpeg/libavformat/fifo.c
index d11dc6626c7..17748e94ce5 100644
--- a/chromium/third_party/ffmpeg/libavformat/fifo.c
+++ b/chromium/third_party/ffmpeg/libavformat/fifo.c
@@ -19,6 +19,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdatomic.h>
+
#include "libavutil/avassert.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
@@ -77,6 +79,9 @@ typedef struct FifoContext {
/* Value > 0 signals queue overflow */
volatile uint8_t overflow_flag;
+ atomic_int_least64_t queue_duration;
+ int64_t last_sent_dts;
+ int64_t timeshift;
} FifoContext;
typedef struct FifoThreadContext {
@@ -98,9 +103,12 @@ typedef struct FifoThreadContext {
* so finalization by calling write_trailer and ff_io_close must be done
* before exiting / reinitialization of underlying muxer */
uint8_t header_written;
+
+ int64_t last_received_dts;
} FifoThreadContext;
typedef enum FifoMessageType {
+ FIFO_NOOP,
FIFO_WRITE_HEADER,
FIFO_WRITE_PACKET,
FIFO_FLUSH_OUTPUT
@@ -159,6 +167,15 @@ static int fifo_thread_flush_output(FifoThreadContext *ctx)
return av_write_frame(avf2, NULL);
}
+static int64_t next_duration(AVFormatContext *avf, AVPacket *pkt, int64_t *last_dts)
+{
+ AVStream *st = avf->streams[pkt->stream_index];
+ int64_t dts = av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
+ int64_t duration = (*last_dts == AV_NOPTS_VALUE ? 0 : dts - *last_dts);
+ *last_dts = dts;
+ return duration;
+}
+
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
{
AVFormatContext *avf = ctx->avf;
@@ -167,6 +184,9 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
AVRational src_tb, dst_tb;
int ret, s_idx;
+ if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE)
+ atomic_fetch_sub_explicit(&fifo->queue_duration, next_duration(avf, pkt, &ctx->last_received_dts), memory_order_relaxed);
+
if (ctx->drop_until_keyframe) {
if (pkt->flags & AV_PKT_FLAG_KEY) {
ctx->drop_until_keyframe = 0;
@@ -209,6 +229,9 @@ static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg
{
int ret = AVERROR(EINVAL);
+ if (msg->type == FIFO_NOOP)
+ return 0;
+
if (!ctx->header_written) {
ret = fifo_thread_write_header(ctx);
if (ret < 0)
@@ -390,12 +413,13 @@ static void *fifo_consumer_thread(void *data)
AVFormatContext *avf = data;
FifoContext *fifo = avf->priv_data;
AVThreadMessageQueue *queue = fifo->queue;
- FifoMessage msg = {FIFO_WRITE_HEADER, {0}};
+ FifoMessage msg = {fifo->timeshift ? FIFO_NOOP : FIFO_WRITE_HEADER, {0}};
int ret;
FifoThreadContext fifo_thread_ctx;
memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext));
fifo_thread_ctx.avf = avf;
+ fifo_thread_ctx.last_received_dts = AV_NOPTS_VALUE;
while (1) {
uint8_t just_flushed = 0;
@@ -429,6 +453,10 @@ static void *fifo_consumer_thread(void *data)
if (just_flushed)
av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n");
+ if (fifo->timeshift)
+ while (atomic_load_explicit(&fifo->queue_duration, memory_order_relaxed) < fifo->timeshift)
+ av_usleep(10000);
+
ret = av_thread_message_queue_recv(queue, &msg, 0);
if (ret < 0) {
av_thread_message_queue_set_err_send(queue, ret);
@@ -488,6 +516,8 @@ static int fifo_init(AVFormatContext *avf)
" only when drop_pkts_on_overflow is also turned on\n");
return AVERROR(EINVAL);
}
+ atomic_init(&fifo->queue_duration, 0);
+ fifo->last_sent_dts = AV_NOPTS_VALUE;
oformat = av_guess_format(fifo->format, avf->url, NULL);
if (!oformat) {
@@ -563,6 +593,9 @@ static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
goto fail;
}
+ if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE)
+ atomic_fetch_add_explicit(&fifo->queue_duration, next_duration(avf, pkt, &fifo->last_sent_dts), memory_order_relaxed);
+
return ret;
fail:
if (pkt)
@@ -576,6 +609,27 @@ static int fifo_write_trailer(AVFormatContext *avf)
int ret;
av_thread_message_queue_set_err_recv(fifo->queue, AVERROR_EOF);
+ if (fifo->timeshift) {
+ int64_t now = av_gettime_relative();
+ int64_t elapsed = 0;
+ FifoMessage msg = {FIFO_NOOP};
+ do {
+ int64_t delay = av_gettime_relative() - now;
+ if (delay < 0) { // Discontinuity?
+ delay = 10000;
+ now = av_gettime_relative();
+ } else {
+ now += delay;
+ }
+ atomic_fetch_add_explicit(&fifo->queue_duration, delay, memory_order_relaxed);
+ elapsed += delay;
+ if (elapsed > fifo->timeshift)
+ break;
+ av_usleep(10000);
+ ret = av_thread_message_queue_send(fifo->queue, &msg, AV_THREAD_MESSAGE_NONBLOCK);
+ } while (ret >= 0 || ret == AVERROR(EAGAIN));
+ atomic_store(&fifo->queue_duration, INT64_MAX);
+ }
ret = pthread_join(fifo->writer_thread, NULL);
if (ret < 0) {
@@ -630,6 +684,9 @@ static const AVOption options[] = {
{"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ {"timeshift", "Delay fifo output", OFFSET(timeshift),
+ AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+
{NULL},
};
diff --git a/chromium/third_party/ffmpeg/libavformat/flac_picture.c b/chromium/third_party/ffmpeg/libavformat/flac_picture.c
index 81ddf80465b..53e24b28b74 100644
--- a/chromium/third_party/ffmpeg/libavformat/flac_picture.c
+++ b/chromium/third_party/ffmpeg/libavformat/flac_picture.c
@@ -27,7 +27,9 @@
#include "id3v2.h"
#include "internal.h"
-int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
+#define MAX_TRUNC_PICTURE_SIZE (500 * 1024 * 1024)
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size, int truncate_workaround)
{
const CodecMime *mime = ff_id3v2_mime_tags;
enum AVCodecID id = AV_CODEC_ID_NONE;
@@ -36,7 +38,8 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
GetByteContext g;
AVStream *st;
int width, height, ret = 0;
- unsigned int len, type;
+ unsigned int type;
+ uint32_t len, left, trunclen = 0;
if (buf_size < 34) {
av_log(s, AV_LOG_ERROR, "Attached picture metadata block too short\n");
@@ -114,16 +117,44 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
/* picture data */
len = bytestream2_get_be32u(&g);
- if (len <= 0 || len > bytestream2_get_bytes_left(&g)) {
- av_log(s, AV_LOG_ERROR, "Attached picture metadata block too short\n");
- if (s->error_recognition & AV_EF_EXPLODE)
- ret = AVERROR_INVALIDDATA;
- goto fail;
+
+ left = bytestream2_get_bytes_left(&g);
+ if (len <= 0 || len > left) {
+ if (len > MAX_TRUNC_PICTURE_SIZE || len >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
+ av_log(s, AV_LOG_ERROR, "Attached picture metadata block too big %u\n", len);
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ // Workaround bug for flac muxers that writs truncated metadata picture block size if
+ // the picture size do not fit in 24 bits. lavf flacenc used to have the issue and based
+ // on existing broken files other unknown flac muxers seems to truncate also.
+ if (truncate_workaround &&
+ s->strict_std_compliance <= FF_COMPLIANCE_NORMAL &&
+ len > left && (len & 0xffffff) == left) {
+ av_log(s, AV_LOG_INFO, "Correcting truncated metadata picture size from %u to %u\n", left, len);
+ trunclen = len - left;
+ } else {
+ av_log(s, AV_LOG_ERROR, "Attached picture metadata block too short\n");
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
}
if (!(data = av_buffer_alloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
RETURN_ERROR(AVERROR(ENOMEM));
}
- bytestream2_get_bufferu(&g, data->data, len);
+
+ if (trunclen == 0) {
+ bytestream2_get_bufferu(&g, data->data, len);
+ } else {
+ // If truncation was detected copy all data from block and read missing bytes
+ // not included in the block size
+ bytestream2_get_bufferu(&g, data->data, left);
+ if (avio_read(s->pb, data->data + len - trunclen, trunclen) < trunclen)
+ RETURN_ERROR(AVERROR_INVALIDDATA);
+ }
memset(data->data + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
if (AV_RB64(data->data) == PNGSIG)
diff --git a/chromium/third_party/ffmpeg/libavformat/flac_picture.h b/chromium/third_party/ffmpeg/libavformat/flac_picture.h
index 4374b6f4f60..61fd0c88065 100644
--- a/chromium/third_party/ffmpeg/libavformat/flac_picture.h
+++ b/chromium/third_party/ffmpeg/libavformat/flac_picture.h
@@ -26,6 +26,6 @@
#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
-int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size);
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size, int truncate_workaround);
#endif /* AVFORMAT_FLAC_PICTURE_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/flacdec.c b/chromium/third_party/ffmpeg/libavformat/flacdec.c
index cb516fb1f3e..79c05f14bf7 100644
--- a/chromium/third_party/ffmpeg/libavformat/flacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flacdec.c
@@ -146,7 +146,7 @@ static int flac_read_header(AVFormatContext *s)
}
av_freep(&buffer);
} else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
- ret = ff_flac_parse_picture(s, buffer, metadata_size);
+ ret = ff_flac_parse_picture(s, buffer, metadata_size, 1);
av_freep(&buffer);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/flacenc.c b/chromium/third_party/ffmpeg/libavformat/flacenc.c
index a043274df60..b947a3b067b 100644
--- a/chromium/third_party/ffmpeg/libavformat/flacenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/flacenc.c
@@ -29,7 +29,6 @@
#include "id3v2.h"
#include "internal.h"
#include "vorbiscomment.h"
-#include "libavcodec/bytestream.h"
typedef struct FlacMuxerContext {
@@ -62,25 +61,16 @@ static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,
{
const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
int64_t len;
- uint8_t *p, *p0;
ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
len = ff_vorbiscomment_length(*m, vendor, NULL, 0);
if (len >= ((1<<24) - 4))
return AVERROR(EINVAL);
- p0 = av_malloc(len+4);
- if (!p0)
- return AVERROR(ENOMEM);
- p = p0;
-
- bytestream_put_byte(&p, last_block ? 0x84 : 0x04);
- bytestream_put_be24(&p, len);
- ff_vorbiscomment_write(&p, m, vendor, NULL, 0);
-
- avio_write(pb, p0, len+4);
- av_freep(&p0);
- p = NULL;
+
+ avio_w8(pb, last_block ? 0x84 : 0x04);
+ avio_wb24(pb, len);
+ ff_vorbiscomment_write(pb, *m, vendor, NULL, 0);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/flvdec.c b/chromium/third_party/ffmpeg/libavformat/flvdec.c
index 7c3e5b06c6f..08622739f31 100644
--- a/chromium/third_party/ffmpeg/libavformat/flvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flvdec.c
@@ -514,8 +514,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream,
if (key &&
(ioc->seekable & AVIO_SEEKABLE_NORMAL) &&
!strcmp(KEYFRAMES_TAG, key) && depth == 1)
- if (parse_keyframes_index(s, ioc,
- max_pos) < 0)
+ if (parse_keyframes_index(s, ioc, max_pos) < 0)
av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
else
add_keyframes_index(s);
@@ -732,8 +731,7 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
astream = stream;
if (flv->last_keyframe_stream_index == -1)
flv->last_keyframe_stream_index = i;
- }
- else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
+ } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
dstream = stream;
}
@@ -1058,8 +1056,7 @@ retry:
if (type == 0 && dts == 0 || type < 0) {
if (type < 0 && flv->validate_count &&
flv->validate_index[0].pos > next &&
- flv->validate_index[0].pos - 4 < 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;
}
@@ -1120,7 +1117,6 @@ skip:
st = create_stream(s, stream_types[stream_type]);
if (!st)
return AVERROR(ENOMEM);
-
}
av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard);
@@ -1133,10 +1129,9 @@ skip:
stream_type == FLV_STREAM_TYPE_AUDIO))
av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
- if ( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
- ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
- || st->discard >= AVDISCARD_ALL
- ) {
+ if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) ||
+ (st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) ||
+ st->discard >= AVDISCARD_ALL) {
avio_seek(s->pb, next, SEEK_SET);
ret = FFERROR_REDO;
goto leave;
@@ -1283,12 +1278,11 @@ retry_duration:
pkt->stream_index = st->index;
pkt->pos = pos;
if (flv->new_extradata[stream_type]) {
- uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
- flv->new_extradata_size[stream_type]);
- if (side) {
- memcpy(side, flv->new_extradata[stream_type],
- flv->new_extradata_size[stream_type]);
- av_freep(&flv->new_extradata[stream_type]);
+ int ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
+ flv->new_extradata[stream_type],
+ flv->new_extradata_size[stream_type]);
+ if (ret >= 0) {
+ flv->new_extradata[stream_type] = NULL;
flv->new_extradata_size[stream_type] = 0;
}
}
@@ -1300,10 +1294,10 @@ retry_duration:
ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
}
- if ( stream_type == FLV_STREAM_TYPE_AUDIO ||
- ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) ||
- stream_type == FLV_STREAM_TYPE_SUBTITLE ||
- stream_type == FLV_STREAM_TYPE_DATA)
+ if (stream_type == FLV_STREAM_TYPE_AUDIO ||
+ (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
+ stream_type == FLV_STREAM_TYPE_SUBTITLE ||
+ stream_type == FLV_STREAM_TYPE_DATA)
pkt->flags |= AV_PKT_FLAG_KEY;
leave:
diff --git a/chromium/third_party/ffmpeg/libavformat/flvenc.c b/chromium/third_party/ffmpeg/libavformat/flvenc.c
index 5cf3ce8a1ab..1cfcdc63922 100644
--- a/chromium/third_party/ffmpeg/libavformat/flvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/flvenc.c
@@ -902,7 +902,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
|| par->codec_id == AV_CODEC_ID_MPEG4) {
- int side_size = 0;
+ int side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
ret = ff_alloc_extradata(par, side_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/ftp.c b/chromium/third_party/ffmpeg/libavformat/ftp.c
index e3d194da580..caeea429209 100644
--- a/chromium/third_party/ffmpeg/libavformat/ftp.c
+++ b/chromium/third_party/ffmpeg/libavformat/ftp.c
@@ -333,15 +333,15 @@ static int ftp_passive_mode(FTPContext *s)
*end = '\0';
/* skip ip */
if (!av_strtok(start, ",", &end)) goto fail;
- if (!av_strtok(end, ",", &end)) goto fail;
- if (!av_strtok(end, ",", &end)) goto fail;
- if (!av_strtok(end, ",", &end)) goto fail;
+ if (!av_strtok(NULL, ",", &end)) goto fail;
+ if (!av_strtok(NULL, ",", &end)) goto fail;
+ if (!av_strtok(NULL, ",", &end)) goto fail;
/* parse port number */
- start = av_strtok(end, ",", &end);
+ start = av_strtok(NULL, ",", &end);
if (!start) goto fail;
s->server_data_port = atoi(start) * 256;
- start = av_strtok(end, ",", &end);
+ start = av_strtok(NULL, ",", &end);
if (!start) goto fail;
s->server_data_port += atoi(start);
ff_dlog(s, "Server data port: %d\n", s->server_data_port);
@@ -963,8 +963,10 @@ static int ftp_parse_entry_nlst(char *line, AVIODirEntry *next)
static int ftp_parse_entry_mlsd(char *mlsd, AVIODirEntry *next)
{
char *fact, *value;
+ char *saveptr = NULL, *p = mlsd;
ff_dlog(NULL, "%s\n", mlsd);
- while(fact = av_strtok(mlsd, ";", &mlsd)) {
+ while(fact = av_strtok(p, ";", &saveptr)) {
+ p = NULL;
if (fact[0] == ' ') {
next->name = av_strdup(&fact[1]);
continue;
diff --git a/chromium/third_party/ffmpeg/libavformat/gifdec.c b/chromium/third_party/ffmpeg/libavformat/gifdec.c
index a31644c2a88..d617de5f41a 100644
--- a/chromium/third_party/ffmpeg/libavformat/gifdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/gifdec.c
@@ -144,7 +144,7 @@ static int gif_read_header(AVFormatContext *s)
AVBPrint bp;
int block_size;
- av_bprint_init(&bp, 0, -1);
+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
while ((block_size = avio_r8(pb)) != 0) {
avio_read_to_bprint(pb, &bp, block_size);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/gopher.c b/chromium/third_party/ffmpeg/libavformat/gopher.c
index 3070b24caf2..8b6d14a1f77 100644
--- a/chromium/third_party/ffmpeg/libavformat/gopher.c
+++ b/chromium/third_party/ffmpeg/libavformat/gopher.c
@@ -68,10 +68,7 @@ static int gopher_connect(URLContext *h, const char *path)
static int gopher_close(URLContext *h)
{
GopherContext *s = h->priv_data;
- if (s->hd) {
- ffurl_close(s->hd);
- s->hd = NULL;
- }
+ ffurl_closep(&s->hd);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/gxfenc.c b/chromium/third_party/ffmpeg/libavformat/gxfenc.c
index e7536a6a7eb..6d4df894f63 100644
--- a/chromium/third_party/ffmpeg/libavformat/gxfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/gxfenc.c
@@ -27,8 +27,8 @@
#include "avformat.h"
#include "internal.h"
#include "gxf.h"
-#include "audiointerleave.h"
+#define GXF_SAMPLES_PER_FRAME 32768
#define GXF_AUDIO_PACKET_SIZE 65536
#define GXF_TIMECODE(c, d, h, m, s, f) \
@@ -44,7 +44,7 @@ typedef struct GXFTimecode{
} GXFTimecode;
typedef struct GXFStreamContext {
- AudioInterleaveContext aic;
+ int64_t pkt_cnt;
uint32_t track_type;
uint32_t sample_size;
uint32_t sample_rate;
@@ -663,8 +663,6 @@ static int gxf_write_umf_packet(AVFormatContext *s)
return updatePacketSize(pb, pos);
}
-static const int GXF_samples_per_frame = 32768;
-
static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
{
if (!vsc)
@@ -736,6 +734,9 @@ static int gxf_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
return -1;
}
+ ret = ff_stream_add_bitstream_filter(st, "pcm_rechunk", "n="AV_STRINGIFY(GXF_SAMPLES_PER_FRAME));
+ if (ret < 0)
+ return ret;
sc->track_type = 2;
sc->sample_rate = st->codecpar->sample_rate;
avpriv_set_pts_info(st, 64, 1, sc->sample_rate);
@@ -818,9 +819,6 @@ static int gxf_write_header(AVFormatContext *s)
sc->order = s->nb_streams - st->index;
}
- if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
- return -1;
-
if (tcr && vsc)
gxf_init_timecode(s, &gxf->tc, tcr->value, vsc->fields);
@@ -877,8 +875,6 @@ static void gxf_deinit(AVFormatContext *s)
{
GXFContext *gxf = s->priv_data;
- ff_audio_interleave_close(s);
-
av_freep(&gxf->flt_entries);
av_freep(&gxf->map_offsets);
}
@@ -1014,10 +1010,19 @@ static int gxf_compare_field_nb(AVFormatContext *s, const AVPacket *next,
static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
{
- if (pkt && s->streams[pkt->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
- pkt->duration = 2; // enforce 2 fields
- return ff_audio_rechunk_interleave(s, out, pkt, flush,
- ff_interleave_packet_per_dts, gxf_compare_field_nb);
+ int ret;
+ if (pkt) {
+ AVStream *st = s->streams[pkt->stream_index];
+ GXFStreamContext *sc = st->priv_data;
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+ pkt->pts = pkt->dts = sc->pkt_cnt * 2; // enforce 2 fields
+ else
+ pkt->pts = pkt->dts = sc->pkt_cnt * GXF_SAMPLES_PER_FRAME;
+ sc->pkt_cnt++;
+ if ((ret = ff_interleave_add_packet(s, pkt, gxf_compare_field_nb)) < 0)
+ return ret;
+ }
+ return ff_interleave_packet_per_dts(s, out, NULL, flush);
}
AVOutputFormat ff_gxf_muxer = {
diff --git a/chromium/third_party/ffmpeg/libavformat/hdsenc.c b/chromium/third_party/ffmpeg/libavformat/hdsenc.c
index 46f0026bce9..353a45f6df2 100644
--- a/chromium/third_party/ffmpeg/libavformat/hdsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hdsenc.c
@@ -317,21 +317,18 @@ static int hds_write_header(AVFormatContext *s)
ff_const59 AVOutputFormat *oformat;
if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
- ret = AVERROR(errno);
av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
- goto fail;
+ return AVERROR(errno);
}
oformat = av_guess_format("flv", NULL, NULL);
if (!oformat) {
- ret = AVERROR_MUXER_NOT_FOUND;
- goto fail;
+ return AVERROR_MUXER_NOT_FOUND;
}
c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
if (!c->streams) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
for (i = 0; i < s->nb_streams; i++) {
@@ -341,8 +338,7 @@ static int hds_write_header(AVFormatContext *s)
if (!st->codecpar->bit_rate) {
av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (os->has_video) {
@@ -358,8 +354,7 @@ static int hds_write_header(AVFormatContext *s)
os->has_audio = 1;
} else {
av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
os->bitrate += s->streams[i]->codecpar->bit_rate;
@@ -367,8 +362,7 @@ static int hds_write_header(AVFormatContext *s)
os->first_stream = i;
ctx = avformat_alloc_context();
if (!ctx) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
os->ctx = ctx;
ctx->oformat = oformat;
@@ -379,8 +373,7 @@ static int hds_write_header(AVFormatContext *s)
AVIO_FLAG_WRITE, os,
NULL, hds_write, NULL);
if (!ctx->pb) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
} else {
ctx = os->ctx;
@@ -388,8 +381,7 @@ static int hds_write_header(AVFormatContext *s)
s->streams[i]->id = c->nb_streams;
if (!(st = avformat_new_stream(ctx, NULL))) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
st->codecpar->codec_tag = 0;
@@ -403,7 +395,7 @@ static int hds_write_header(AVFormatContext *s)
OutputStream *os = &c->streams[i];
int j;
if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
- goto fail;
+ return ret;
}
os->ctx_inited = 1;
avio_flush(os->ctx->pb);
@@ -414,7 +406,7 @@ static int hds_write_header(AVFormatContext *s)
"%s/stream%d_temp", s->url, i);
ret = init_file(s, os, 0);
if (ret < 0)
- goto fail;
+ return ret;
if (!os->has_video && c->min_frag_duration <= 0) {
av_log(s, AV_LOG_WARNING,
@@ -425,9 +417,6 @@ static int hds_write_header(AVFormatContext *s)
}
ret = write_manifest(s, 0);
-fail:
- if (ret)
- hds_free(s);
return ret;
}
@@ -557,7 +546,6 @@ static int hds_write_trailer(AVFormatContext *s)
rmdir(s->url);
}
- hds_free(s);
return 0;
}
@@ -588,5 +576,6 @@ AVOutputFormat ff_hds_muxer = {
.write_header = hds_write_header,
.write_packet = hds_write_packet,
.write_trailer = hds_write_trailer,
+ .deinit = hds_free,
.priv_class = &hds_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/hevc.c b/chromium/third_party/ffmpeg/libavformat/hevc.c
index f621cb2f198..94eb3a9cb11 100644
--- a/chromium/third_party/ffmpeg/libavformat/hevc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hevc.c
@@ -1068,29 +1068,27 @@ int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out,
int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data,
int size, int ps_array_completeness)
{
- int ret = 0;
- uint8_t *buf, *end, *start = NULL;
HEVCDecoderConfigurationRecord hvcc;
-
- hvcc_init(&hvcc);
+ uint8_t *buf, *end, *start;
+ int ret;
if (size < 6) {
/* We can't write a valid hvcC from the provided data */
- ret = AVERROR_INVALIDDATA;
- goto end;
+ return AVERROR_INVALIDDATA;
} else if (*data == 1) {
/* Data is already hvcC-formatted */
avio_write(pb, data, size);
- goto end;
+ return 0;
} else if (!(AV_RB24(data) == 1 || AV_RB32(data) == 1)) {
/* Not a valid Annex B start code prefix */
- ret = AVERROR_INVALIDDATA;
- goto end;
+ return AVERROR_INVALIDDATA;
}
ret = ff_avc_parse_nal_units_buf(data, &start, &size);
if (ret < 0)
- goto end;
+ return ret;
+
+ hvcc_init(&hvcc);
buf = start;
end = start + size;
diff --git a/chromium/third_party/ffmpeg/libavformat/hls.c b/chromium/third_party/ffmpeg/libavformat/hls.c
index fc45719d1c0..84f0a5f3238 100644
--- a/chromium/third_party/ffmpeg/libavformat/hls.c
+++ b/chromium/third_party/ffmpeg/libavformat/hls.c
@@ -311,6 +311,8 @@ static struct playlist *new_playlist(HLSContext *c, const char *url,
return NULL;
reset_packet(&pls->pkt);
ff_make_absolute_url(pls->url, sizeof(pls->url), base, url);
+ if (!pls->url[0])
+ return NULL;
pls->seek_timestamp = AV_NOPTS_VALUE;
pls->is_id3_timestamped = -1;
@@ -416,6 +418,10 @@ static struct segment *new_init_section(struct playlist *pls,
ptr = info->uri;
} else {
ff_make_absolute_url(tmp_str, sizeof(tmp_str), url_base, info->uri);
+ if (!tmp_str[0]) {
+ av_free(sec);
+ return NULL;
+ }
}
sec->url = av_strdup(ptr);
if (!sec->url) {
@@ -841,6 +847,11 @@ static int parse_playlist(HLSContext *c, const char *url,
if (key_type != KEY_NONE) {
ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
+ if (!tmp_str[0]) {
+ av_free(cur_init_section);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
cur_init_section->key = av_strdup(tmp_str);
if (!cur_init_section->key) {
av_free(cur_init_section);
@@ -883,8 +894,6 @@ static int parse_playlist(HLSContext *c, const char *url,
ret = AVERROR(ENOMEM);
goto fail;
}
- seg->duration = duration;
- seg->key_type = key_type;
if (has_iv) {
memcpy(seg->iv, iv, sizeof(iv));
} else {
@@ -895,6 +904,11 @@ static int parse_playlist(HLSContext *c, const char *url,
if (key_type != KEY_NONE) {
ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
+ if (!tmp_str[0]) {
+ ret = AVERROR_INVALIDDATA;
+ av_free(seg);
+ goto fail;
+ }
seg->key = av_strdup(tmp_str);
if (!seg->key) {
av_free(seg);
@@ -906,6 +920,13 @@ static int parse_playlist(HLSContext *c, const char *url,
}
ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
+ if (!tmp_str[0]) {
+ ret = AVERROR_INVALIDDATA;
+ if (seg->key)
+ av_free(seg->key);
+ av_free(seg);
+ goto fail;
+ }
seg->url = av_strdup(tmp_str);
if (!seg->url) {
av_free(seg->key);
@@ -914,6 +935,13 @@ static int parse_playlist(HLSContext *c, const char *url,
goto fail;
}
+ if (duration < 0.001 * AV_TIME_BASE) {
+ av_log(c->ctx, AV_LOG_WARNING, "Cannot get correct #EXTINF value of segment %s,"
+ " set to default value to 1ms.\n", seg->url);
+ duration = 0.001 * AV_TIME_BASE;
+ }
+ seg->duration = duration;
+ seg->key_type = key_type;
dynarray_add(&pls->segments, &pls->n_segments, seg);
is_segment = 0;
@@ -1004,7 +1032,7 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb,
ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta);
for (meta = *extra_meta; meta; meta = meta->next) {
if (!strcmp(meta->tag, "PRIV")) {
- ID3v2ExtraMetaPRIV *priv = meta->data;
+ ID3v2ExtraMetaPRIV *priv = &meta->data.priv;
if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) {
/* 33-bit MPEG timestamp */
int64_t ts = AV_RB64(priv->data);
@@ -1015,7 +1043,7 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb,
av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts);
}
} else if (!strcmp(meta->tag, "APIC") && apic)
- *apic = meta->data;
+ *apic = &meta->data.apic;
}
}
@@ -1070,12 +1098,12 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls)
/* get picture attachment and set text metadata */
if (pls->ctx->nb_streams)
- ff_id3v2_parse_apic(pls->ctx, &extra_meta);
+ ff_id3v2_parse_apic(pls->ctx, extra_meta);
else
/* demuxer not yet opened, defer picture attachment */
pls->id3_deferred_extra = extra_meta;
- ff_id3v2_parse_priv_dict(&metadata, &extra_meta);
+ ff_id3v2_parse_priv_dict(&metadata, extra_meta);
av_dict_copy(&pls->ctx->metadata, metadata, 0);
pls->id3_initial = metadata;
@@ -1263,7 +1291,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
* as would be expected. Wrong offset received from the server will not be
* noticed without the call, though.
*/
- if (ret == 0 && !is_http && seg->key_type == KEY_NONE && seg->url_offset) {
+ if (ret == 0 && !is_http && seg->url_offset) {
int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET);
if (seekret < 0) {
av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);
@@ -1740,6 +1768,20 @@ static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls,
else
avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
+ // copy disposition
+ st->disposition = ist->disposition;
+
+ // copy side data
+ for (int i = 0; i < ist->nb_side_data; i++) {
+ const AVPacketSideData *sd_src = &ist->side_data[i];
+ uint8_t *dst_data;
+
+ dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size);
+ if (!dst_data)
+ return AVERROR(ENOMEM);
+ memcpy(dst_data, sd_src->data, sd_src->size);
+ }
+
st->internal->need_context_update = 1;
return 0;
@@ -1904,6 +1946,7 @@ static int hls_read_header(AVFormatContext *s)
/* Open the demuxer for each playlist */
for (i = 0; i < c->n_playlists; i++) {
struct playlist *pls = c->playlists[i];
+ char *url;
ff_const59 AVInputFormat *in_fmt = NULL;
if (!(pls->ctx = avformat_alloc_context())) {
@@ -1941,8 +1984,10 @@ static int hls_read_header(AVFormatContext *s)
read_data, NULL, NULL);
pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
- ret = av_probe_input_buffer(&pls->pb, &in_fmt, pls->segments[0]->url,
- NULL, 0, 0);
+ pls->ctx->interrupt_callback = s->interrupt_callback;
+ url = av_strdup(pls->segments[0]->url);
+ ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0);
+ av_free(url);
if (ret < 0) {
/* Free the ctx - it isn't initialized properly at this point,
* so avformat_close_input shouldn't be called. If
@@ -1965,11 +2010,10 @@ static int hls_read_header(AVFormatContext *s)
goto fail;
if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
- ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
+ ff_id3v2_parse_apic(pls->ctx, pls->id3_deferred_extra);
avformat_queue_attached_pictures(pls->ctx);
- ff_id3v2_parse_priv(pls->ctx, &pls->id3_deferred_extra);
+ ff_id3v2_parse_priv(pls->ctx, pls->id3_deferred_extra);
ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
- pls->id3_deferred_extra = NULL;
}
if (pls->is_id3_timestamped == -1)
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsenc.c b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
index d75684741f9..cb31d6aed7c 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
@@ -41,6 +41,7 @@
#include "libavutil/random_seed.h"
#include "libavutil/opt.h"
#include "libavutil/log.h"
+#include "libavutil/time.h"
#include "libavutil/time_internal.h"
#include "avformat.h"
@@ -56,6 +57,8 @@ typedef enum {
HLS_START_SEQUENCE_AS_START_NUMBER = 0,
HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH = 1,
HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2, // YYYYMMDDhhmmss
+ HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH = 3,
+ HLS_START_SEQUENCE_LAST, // unused
} StartSequenceSourceType;
typedef enum {
@@ -66,6 +69,7 @@ typedef enum {
#define KEYSIZE 16
#define LINE_BUFFER_SIZE MAX_URL_SIZE
#define HLS_MICROSECOND_UNIT 1000000
+#define BUFSIZE (16 * 1024)
#define POSTFIX_PATTERN "_%d"
typedef struct HLSSegment {
@@ -116,6 +120,7 @@ typedef struct VariantStream {
ff_const59 AVOutputFormat *oformat;
ff_const59 AVOutputFormat *vtt_oformat;
AVIOContext *out;
+ AVIOContext *out_single_file;
int packets_written;
int init_range_length;
uint8_t *temp_buffer;
@@ -146,6 +151,7 @@ typedef struct VariantStream {
HLSSegment *last_segment;
HLSSegment *old_segments;
+ char *basename_tmp;
char *basename;
char *vtt_basename;
char *vtt_m3u8_name;
@@ -157,24 +163,30 @@ typedef struct VariantStream {
char *fmp4_init_filename;
char *base_output_dirname;
+ int encrypt_started;
+
+ char key_file[LINE_BUFFER_SIZE + 1];
+ char key_uri[LINE_BUFFER_SIZE + 1];
+ char key_string[KEYSIZE*2 + 1];
+ char iv_string[KEYSIZE*2 + 1];
+
AVStream **streams;
char codec_attr[128];
CodecAttributeStatus attr_status;
unsigned int nb_streams;
int m3u8_created; /* status of media play-list creation */
int is_default; /* default status of audio group */
- char *language; /* audio lauguage name */
- char *agroup; /* audio group name */
- char *sgroup; /* subtitle group name */
- char *ccgroup; /* closed caption group name */
- char *baseurl;
- char *varname; // variant name
+ const char *language; /* audio lauguage name */
+ const char *agroup; /* audio group name */
+ const char *sgroup; /* subtitle group name */
+ const char *ccgroup; /* closed caption group name */
+ const char *varname; /* variant name */
} VariantStream;
typedef struct ClosedCaptionsStream {
- char *ccgroup; /* closed caption group name */
- char *instreamid; /* closed captions INSTREAM-ID */
- char *language; /* closed captions langauge */
+ const char *ccgroup; /* closed caption group name */
+ const char *instreamid; /* closed captions INSTREAM-ID */
+ const char *language; /* closed captions langauge */
} ClosedCaptionsStream;
typedef struct HLSContext {
@@ -356,11 +368,11 @@ fail:
static int replace_str_data_in_filename(char **s, const char *filename, char placeholder, const char *datastring)
{
const char *p;
- char *new_filename;
char c;
int addchar_count;
int found_count = 0;
AVBPrint buf;
+ int ret;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
@@ -386,22 +398,21 @@ static int replace_str_data_in_filename(char **s, const char *filename, char pla
}
if (!av_bprint_is_complete(&buf)) {
av_bprint_finalize(&buf, NULL);
- return -1;
+ return AVERROR(ENOMEM);
}
- if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
- return -1;
- *s = new_filename;
+ if ((ret = av_bprint_finalize(&buf, s)) < 0)
+ return ret;
return found_count;
}
static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
{
const char *p;
- char *new_filename;
char c;
int nd, addchar_count;
int found_count = 0;
AVBPrint buf;
+ int ret;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
@@ -435,11 +446,10 @@ static int replace_int_data_in_filename(char **s, const char *filename, char pla
}
if (!av_bprint_is_complete(&buf)) {
av_bprint_finalize(&buf, NULL);
- return -1;
+ return AVERROR(ENOMEM);
}
- if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
- return -1;
- *s = new_filename;
+ if ((ret = av_bprint_finalize(&buf, s)) < 0)
+ return ret;
return found_count;
}
@@ -515,10 +525,10 @@ static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls,
int ret = 0;
int segment_cnt = 0;
AVBPrint path;
- char *dirname = NULL;
+ const char *dirname = NULL;
char *dirname_r = NULL;
char *dirname_repl = NULL;
- char *vtt_dirname = NULL;
+ const char *vtt_dirname = NULL;
char *vtt_dirname_r = NULL;
const char *proto = NULL;
@@ -549,7 +559,7 @@ static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls,
if (segment && !hls->use_localtime_mkdir) {
dirname_r = hls->segment_filename ? av_strdup(hls->segment_filename): av_strdup(vs->avf->url);
- dirname = (char*)av_dirname(dirname_r);
+ dirname = av_dirname(dirname_r);
}
/* if %v is present in the file's directory
@@ -588,7 +598,7 @@ static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls,
if ((segment->sub_filename[0] != '\0')) {
vtt_dirname_r = av_strdup(vs->vtt_avf->url);
- vtt_dirname = (char*)av_dirname(vtt_dirname_r);
+ vtt_dirname = av_dirname(vtt_dirname_r);
av_bprint_clear(&path);
av_bprintf(&path, "%s%c%s", vtt_dirname, SEPARATOR,
@@ -705,7 +715,7 @@ static int do_encrypt(AVFormatContext *s, VariantStream *vs)
}
-static int hls_encryption_start(AVFormatContext *s)
+static int hls_encryption_start(AVFormatContext *s, VariantStream *vs)
{
HLSContext *hls = s->priv_data;
int ret;
@@ -722,44 +732,44 @@ static int hls_encryption_start(AVFormatContext *s)
return ret;
}
- ff_get_line(pb, hls->key_uri, sizeof(hls->key_uri));
- hls->key_uri[strcspn(hls->key_uri, "\r\n")] = '\0';
+ ff_get_line(pb, vs->key_uri, sizeof(vs->key_uri));
+ vs->key_uri[strcspn(vs->key_uri, "\r\n")] = '\0';
- ff_get_line(pb, hls->key_file, sizeof(hls->key_file));
- hls->key_file[strcspn(hls->key_file, "\r\n")] = '\0';
+ ff_get_line(pb, vs->key_file, sizeof(vs->key_file));
+ vs->key_file[strcspn(vs->key_file, "\r\n")] = '\0';
- ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string));
- hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0';
+ ff_get_line(pb, vs->iv_string, sizeof(vs->iv_string));
+ vs->iv_string[strcspn(vs->iv_string, "\r\n")] = '\0';
ff_format_io_close(s, &pb);
- if (!*hls->key_uri) {
+ if (!*vs->key_uri) {
av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
return AVERROR(EINVAL);
}
- if (!*hls->key_file) {
+ if (!*vs->key_file) {
av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
return AVERROR(EINVAL);
}
set_http_options(s, &options, hls);
- ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, &options);
+ ret = s->io_open(s, &pb, vs->key_file, AVIO_FLAG_READ, &options);
av_dict_free(&options);
if (ret < 0) {
- av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file);
+ av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", vs->key_file);
return ret;
}
ret = avio_read(pb, key, sizeof(key));
ff_format_io_close(s, &pb);
if (ret != sizeof(key)) {
- av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", hls->key_file);
+ av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", vs->key_file);
if (ret >= 0 || ret == AVERROR_EOF)
ret = AVERROR(EINVAL);
return ret;
}
- ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
+ ff_data_to_hex(vs->key_string, key, sizeof(key), 0);
return 0;
}
@@ -783,7 +793,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
if (!oc->url)
return AVERROR(ENOMEM);
- oc->oformat = vs->oformat;
oc->interrupt_callback = s->interrupt_callback;
oc->max_delay = s->max_delay;
oc->opaque = s->opaque;
@@ -797,7 +806,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
if (ret < 0)
return ret;
vtt_oc = vs->vtt_avf;
- vtt_oc->oformat = vs->vtt_oformat;
av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
}
@@ -825,7 +833,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
}
- vs->packets_written = 1;
vs->start_pos = 0;
vs->new_start = 1;
@@ -840,9 +847,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
}
}
- vs->packets_written = 0;
- vs->init_range_length = 0;
-
if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
return ret;
@@ -1081,8 +1085,8 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
}
if (hls->key_info_file || hls->encrypt) {
- av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri));
- av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string));
+ av_strlcpy(en->key_uri, vs->key_uri, sizeof(en->key_uri));
+ av_strlcpy(en->iv_string, vs->iv_string, sizeof(en->iv_string));
}
if (!vs->segments)
@@ -1170,9 +1174,9 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
ptr += strlen("URI=\"");
end = av_stristr(ptr, ",");
if (end) {
- av_strlcpy(hls->key_uri, ptr, end - ptr);
+ av_strlcpy(vs->key_uri, ptr, end - ptr);
} else {
- av_strlcpy(hls->key_uri, ptr, sizeof(hls->key_uri));
+ av_strlcpy(vs->key_uri, ptr, sizeof(vs->key_uri));
}
}
@@ -1181,9 +1185,9 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
ptr += strlen("IV=0x");
end = av_stristr(ptr, ",");
if (end) {
- av_strlcpy(hls->iv_string, ptr, end - ptr);
+ av_strlcpy(vs->iv_string, ptr, end - ptr);
} else {
- av_strlcpy(hls->iv_string, ptr, sizeof(hls->iv_string));
+ av_strlcpy(vs->iv_string, ptr, sizeof(vs->iv_string));
}
}
@@ -1287,8 +1291,8 @@ static int create_master_playlist(AVFormatContext *s,
int ret, bandwidth;
const char *m3u8_rel_name = NULL;
const char *vtt_m3u8_rel_name = NULL;
- char *ccgroup;
- char *sgroup = NULL;
+ const char *ccgroup;
+ const char *sgroup = NULL;
ClosedCaptionsStream *ccs;
const char *proto = avio_find_protocol_name(hls->master_m3u8_url);
int is_file_proto = proto && !strcmp(proto, "file");
@@ -1496,7 +1500,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
ff_hls_write_playlist_header(byterange_mode ? hls->m3u8_out : vs->out, hls->version, hls->allowcache,
target_duration, sequence, hls->pl_type, hls->flags & HLS_I_FRAMES_ONLY);
- if ((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0 ) {
+ if ((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0) {
avio_printf(byterange_mode ? hls->m3u8_out : vs->out, "#EXT-X-DISCONTINUITY\n");
vs->discontinuity_set = 1;
}
@@ -1521,7 +1525,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
ret = ff_hls_write_file_entry(byterange_mode ? hls->m3u8_out : vs->out, en->discont, byterange_mode,
en->duration, hls->flags & HLS_ROUND_DURATIONS,
- en->size, en->pos, vs->baseurl,
+ en->size, en->pos, hls->baseurl,
en->filename, prog_date_time_p, en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY);
if (ret < 0) {
av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
@@ -1543,7 +1547,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
for (en = vs->segments; en; en = en->next) {
ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
en->duration, 0, en->size, en->pos,
- vs->baseurl, en->sub_filename, NULL, 0, 0, 0);
+ hls->baseurl, en->sub_filename, NULL, 0, 0, 0);
if (ret < 0) {
av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
}
@@ -1632,6 +1636,8 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
if (c->use_localtime_mkdir) {
const char *dir;
char *fn_copy = av_strdup(oc->url);
+ if (!fn_copy)
+ return AVERROR(ENOMEM);
dir = av_dirname(fn_copy);
if (ff_mkdir_p(dir) == -1 && errno != EEXIST) {
av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir);
@@ -1654,7 +1660,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
}
ff_format_set_url(oc, filename);
}
- if ( vs->vtt_basename) {
+ if (vs->vtt_basename) {
char *filename = NULL;
if (replace_int_data_in_filename(&filename,
#if FF_API_HLS_WRAP
@@ -1669,7 +1675,6 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
ff_format_set_url(vtt_oc, filename);
}
}
- vs->number++;
proto = avio_find_protocol_name(oc->url);
use_temp_file = proto && !strcmp(proto, "file") && (c->flags & HLS_TEMP_FILE);
@@ -1692,21 +1697,27 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
" ignoring -hls_enc\n");
}
- if (!c->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) {
+ if (!vs->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) {
if (c->key_info_file) {
- if ((err = hls_encryption_start(s)) < 0)
+ if ((err = hls_encryption_start(s, vs)) < 0)
goto fail;
} else {
- if ((err = do_encrypt(s, vs)) < 0)
- goto fail;
+ if (!c->encrypt_started) {
+ if ((err = do_encrypt(s, vs)) < 0)
+ goto fail;
+ c->encrypt_started = 1;
+ }
+ av_strlcpy(vs->key_uri, c->key_uri, sizeof(vs->key_uri));
+ av_strlcpy(vs->key_string, c->key_string, sizeof(vs->key_string));
+ av_strlcpy(vs->iv_string, c->iv_string, sizeof(vs->iv_string));
}
- c->encrypt_started = 1;
+ vs->encrypt_started = 1;
}
- err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
+ err = av_strlcpy(iv_string, vs->iv_string, sizeof(iv_string));
if (!err) {
snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence);
- memset(c->iv_string, 0, sizeof(c->iv_string));
- memcpy(c->iv_string, iv_string, sizeof(iv_string));
+ memset(vs->iv_string, 0, sizeof(vs->iv_string));
+ memcpy(vs->iv_string, iv_string, sizeof(iv_string));
}
}
if (c->segment_type != SEGMENT_TYPE_FMP4) {
@@ -1714,12 +1725,34 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
}
if (c->flags & HLS_SINGLE_FILE) {
+ if (c->key_info_file || c->encrypt) {
+ av_dict_set(&options, "encryption_key", vs->key_string, 0);
+ av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
+
+ /* Write temp file with cryption content */
+ av_freep(&vs->basename_tmp);
+ vs->basename_tmp = av_asprintf("crypto:%s.tmp", oc->url);
+
+ /* append temp file content into single file */
+ av_freep(&vs->basename);
+ vs->basename = av_asprintf("%s", oc->url);
+ } else {
+ vs->basename_tmp = vs->basename;
+ }
set_http_options(s, &options, c);
- if ((err = hlsenc_io_open(s, &vs->out, oc->url, &options)) < 0) {
+ if (!vs->out_single_file)
+ if ((err = hlsenc_io_open(s, &vs->out_single_file, vs->basename, &options)) < 0) {
+ if (c->ignore_io_errors)
+ err = 0;
+ goto fail;
+ }
+
+ if ((err = hlsenc_io_open(s, &vs->out, vs->basename_tmp, &options)) < 0) {
if (c->ignore_io_errors)
err = 0;
goto fail;
}
+
}
}
if (vs->vtt_basename) {
@@ -1786,12 +1819,12 @@ static int validate_name(int nb_vs, const char *fn)
char *fn_dup = NULL;
int ret = 0;
- if (!fn) {
- ret = AVERROR(EINVAL);
- goto fail;
- }
+ if (!fn)
+ return AVERROR(EINVAL);
fn_dup = av_strdup(fn);
+ if (!fn_dup)
+ return AVERROR(ENOMEM);
filename = av_basename(fn);
subdir_name = av_dirname(fn_dup);
@@ -1821,14 +1854,12 @@ static int format_name(const char *buf, char **s, int index, const char *varname
int ret = 0;
orig_buf_dup = av_strdup(buf);
- if (!orig_buf_dup) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
+ if (!orig_buf_dup)
+ return AVERROR(ENOMEM);
if (!av_stristr(buf, "%v")) {
*s = orig_buf_dup;
- return ret;
+ return 0;
}
if (!varname) {
@@ -1864,7 +1895,7 @@ fail:
static int get_nth_codec_stream_index(AVFormatContext *s,
enum AVMediaType codec_type,
- int stream_id)
+ int64_t stream_id)
{
unsigned int stream_index, cnt;
if (stream_id < 0 || stream_id > s->nb_streams - 1)
@@ -1935,10 +1966,13 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
return AVERROR(EINVAL);
q = varstr;
- while (q < varstr + strlen(varstr)) {
+ while (1) {
if (!av_strncasecmp(q, "a:", 2) || !av_strncasecmp(q, "v:", 2) ||
!av_strncasecmp(q, "s:", 2))
vs->nb_streams++;
+ q = strchr(q, ',');
+ if (!q)
+ break;
q++;
}
vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
@@ -1947,12 +1981,11 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
nb_streams = 0;
while (keyval = av_strtok(varstr, ",", &saveptr2)) {
+ int64_t num;
+ char *end;
varstr = NULL;
if (av_strstart(keyval, "language:", &val)) {
- av_free(vs->language);
- vs->language = av_strdup(val);
- if (!vs->language)
- return AVERROR(ENOMEM);
+ vs->language = val;
continue;
} else if (av_strstart(keyval, "default:", &val)) {
vs->is_default = (!av_strncasecmp(val, "YES", strlen("YES")) ||
@@ -1960,28 +1993,16 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
hls->has_default_key = 1;
continue;
} else if (av_strstart(keyval, "name:", &val)) {
- av_free(vs->varname);
- vs->varname = av_strdup(val);
- if (!vs->varname)
- return AVERROR(ENOMEM);
+ vs->varname = val;
continue;
} else if (av_strstart(keyval, "agroup:", &val)) {
- av_free(vs->agroup);
- vs->agroup = av_strdup(val);
- if (!vs->agroup)
- return AVERROR(ENOMEM);
+ vs->agroup = val;
continue;
} else if (av_strstart(keyval, "sgroup:", &val)) {
- av_free(vs->sgroup);
- vs->sgroup = av_strdup(val);
- if (!vs->sgroup)
- return AVERROR(ENOMEM);
+ vs->sgroup = val;
continue;
} else if (av_strstart(keyval, "ccgroup:", &val)) {
- av_free(vs->ccgroup);
- vs->ccgroup = av_strdup(val);
- if (!vs->ccgroup)
- return AVERROR(ENOMEM);
+ vs->ccgroup = val;
continue;
} else if (av_strstart(keyval, "v:", &val)) {
codec_type = AVMEDIA_TYPE_VIDEO;
@@ -1995,10 +2016,12 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
return AVERROR(EINVAL);
}
- stream_index = -1;
- if (av_isdigit(*val))
- stream_index = get_nth_codec_stream_index (s, codec_type,
- atoi(val));
+ num = strtoll(val, &end, 10);
+ if (!av_isdigit(*val) || *end != '\0') {
+ av_log(s, AV_LOG_ERROR, "Invalid stream number: '%s'\n", val);
+ return AVERROR(EINVAL);
+ }
+ stream_index = get_nth_codec_stream_index(s, codec_type, num);
if (stream_index >= 0 && nb_streams < vs->nb_streams) {
for (i = 0; nb_streams > 0 && i < nb_streams; i++) {
@@ -2070,20 +2093,11 @@ static int parse_cc_stream_mapstring(AVFormatContext *s)
ccstr = NULL;
if (av_strstart(keyval, "ccgroup:", &val)) {
- av_free(ccs->ccgroup);
- ccs->ccgroup = av_strdup(val);
- if (!ccs->ccgroup)
- return AVERROR(ENOMEM);
+ ccs->ccgroup = val;
} else if (av_strstart(keyval, "instreamid:", &val)) {
- av_free(ccs->instreamid);
- ccs->instreamid = av_strdup(val);
- if (!ccs->instreamid)
- return AVERROR(ENOMEM);
+ ccs->instreamid = val;
} else if (av_strstart(keyval, "language:", &val)) {
- av_free(ccs->language);
- ccs->language = av_strdup(val);
- if (!ccs->language)
- return AVERROR(ENOMEM);
+ ccs->language = val;
} else {
av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
return AVERROR(EINVAL);
@@ -2142,17 +2156,12 @@ static int update_variant_stream_info(AVFormatContext *s)
hls->var_streams[0].nb_streams = s->nb_streams;
hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
hls->var_streams[0].nb_streams);
- if (!hls->var_streams[0].streams) {
+ if (!hls->var_streams[0].streams)
return AVERROR(ENOMEM);
- }
//by default, the first available ccgroup is mapped to the variant stream
- if (hls->nb_ccstreams) {
- hls->var_streams[0].ccgroup = av_strdup(hls->cc_streams[0].ccgroup);
- if (!hls->var_streams[0].ccgroup) {
- return AVERROR(ENOMEM);
- }
- }
+ if (hls->nb_ccstreams)
+ hls->var_streams[0].ccgroup = hls->cc_streams[0].ccgroup;
for (i = 0; i < s->nb_streams; i++)
hls->var_streams[0].streams[i] = s->streams[i];
@@ -2168,6 +2177,8 @@ static int update_master_pl_info(AVFormatContext *s)
int ret = 0;
fn1 = av_strdup(s->url);
+ if (!fn1)
+ return AVERROR(ENOMEM);
dir = av_dirname(fn1);
/**
@@ -2176,6 +2187,10 @@ static int update_master_pl_info(AVFormatContext *s)
*/
if (dir && av_stristr(av_basename(dir), "%v")) {
fn2 = av_strdup(dir);
+ if (!fn2) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
dir = av_dirname(fn2);
}
@@ -2258,7 +2273,7 @@ static int hls_init_file_resend(AVFormatContext *s, VariantStream *vs)
int ret = 0;
set_http_options(s, &options, hls);
- ret = hlsenc_io_open(s, &vs->out, hls->fmp4_init_filename, &options);
+ ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options);
av_dict_free(&options);
if (ret < 0)
return ret;
@@ -2268,6 +2283,38 @@ static int hls_init_file_resend(AVFormatContext *s, VariantStream *vs)
return ret;
}
+static int64_t append_single_file(AVFormatContext *s, VariantStream *vs)
+{
+ int ret = 0;
+ int64_t read_byte = 0;
+ int64_t total_size = 0;
+ char *filename = NULL;
+ char buf[BUFSIZE];
+ AVFormatContext *oc = vs->avf;
+
+ hlsenc_io_close(s, &vs->out, vs->basename_tmp);
+ filename = av_asprintf("%s.tmp", oc->url);
+ ret = s->io_open(s, &vs->out, filename, AVIO_FLAG_READ, NULL);
+ if (ret < 0) {
+ av_free(filename);
+ return ret;
+ }
+
+ do {
+ memset(buf, 0, sizeof(BUFSIZE));
+ read_byte = avio_read(vs->out, buf, BUFSIZE);
+ avio_write(vs->out_single_file, buf, read_byte);
+ if (read_byte > 0) {
+ total_size += read_byte;
+ ret = total_size;
+ }
+ } while (read_byte > 0);
+
+ hlsenc_io_close(s, &vs->out, filename);
+ av_free(filename);
+
+ return ret;
+}
static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
{
HLSContext *hls = s->priv_data;
@@ -2287,7 +2334,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
vs = &hls->var_streams[i];
for (j = 0; j < vs->nb_streams; j++) {
if (vs->streams[j] == st) {
- if ( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
oc = vs->vtt_avf;
stream_index = 0;
} else {
@@ -2312,7 +2359,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
/* reset end_pts, hls->recording_time at end of the init hls list */
int64_t init_list_dur = hls->init_time * vs->nb_entries * AV_TIME_BASE;
- int64_t after_init_list_dur = (vs->sequence - hls->start_sequence - vs->nb_entries ) * (hls->time * AV_TIME_BASE);
+ int64_t after_init_list_dur = (vs->sequence - hls->start_sequence - vs->nb_entries) * (hls->time * AV_TIME_BASE);
hls->recording_time = hls->time * AV_TIME_BASE;
end_pts = init_list_dur + after_init_list_dur ;
}
@@ -2327,7 +2374,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
vs->start_pts_from_audio = 0;
}
- if (vs->has_video) {
+ if (vs->has_video) {
can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
is_ref_pkt = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->stream_index == vs->reference_stream_index);
@@ -2386,11 +2433,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
}
}
- if (oc->url[0]) {
- proto = avio_find_protocol_name(oc->url);
- use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE);
- }
-
if (hls->flags & HLS_SINGLE_FILE) {
ret = flush_dynbuf(vs, &range_length);
av_freep(&vs->temp_buffer);
@@ -2398,13 +2440,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
vs->size = range_length;
+ if (hls->key_info_file || hls->encrypt)
+ vs->size = append_single_file(s, vs);
} else {
- if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) {
+ if (oc->url[0]) {
+ proto = avio_find_protocol_name(oc->url);
+ use_temp_file = proto && !strcmp(proto, "file")
+ && (hls->flags & HLS_TEMP_FILE);
+ }
+
+ if ((hls->max_seg_size > 0 && (vs->size + vs->start_pos >= hls->max_seg_size)) || !byterange_mode) {
AVDictionary *options = NULL;
char *filename = NULL;
if (hls->key_info_file || hls->encrypt) {
- av_dict_set(&options, "encryption_key", hls->key_string, 0);
- av_dict_set(&options, "encryption_iv", hls->iv_string, 0);
+ av_dict_set(&options, "encryption_key", vs->key_string, 0);
+ av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
filename = av_asprintf("crypto:%s", oc->url);
} else {
filename = av_asprintf("%s", oc->url);
@@ -2424,6 +2474,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
if (ret < 0) {
av_log(s, hls->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR,
"Failed to open file '%s'\n", filename);
+ av_freep(&filename);
av_dict_free(&options);
return hls->ignore_io_errors ? 0 : ret;
}
@@ -2432,6 +2483,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
}
ret = flush_dynbuf(vs, &range_length);
if (ret < 0) {
+ av_freep(&filename);
av_dict_free(&options);
return ret;
}
@@ -2448,10 +2500,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
av_freep(&vs->temp_buffer);
av_freep(&filename);
}
- }
- if (use_temp_file && !(hls->flags & HLS_SINGLE_FILE)) {
- hls_rename_temp_file(s, oc);
+ if (use_temp_file)
+ hls_rename_temp_file(s, oc);
}
old_filename = av_strdup(oc->url);
@@ -2460,7 +2511,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (vs->start_pos || hls->segment_type != SEGMENT_TYPE_FMP4) {
- ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
+ double cur_duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
+ ret = hls_append_segment(s, hls, vs, cur_duration, vs->start_pos, vs->size);
vs->end_pts = pkt->pts;
vs->duration = 0;
if (ret < 0) {
@@ -2474,7 +2526,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
if ((ret = hls_window(s, 0, vs)) < 0) {
av_log(s, AV_LOG_WARNING, "upload playlist failed, will retry with a new http session.\n");
ff_format_io_close(s, &vs->out);
- vs->out = NULL;
if ((ret = hls_window(s, 0, vs)) < 0) {
av_freep(&old_filename);
return ret;
@@ -2491,25 +2542,26 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (hls->flags & HLS_SINGLE_FILE) {
- vs->number++;
vs->start_pos += vs->size;
+ if (hls->key_info_file || hls->encrypt)
+ ret = hls_start(s, vs);
} else if (hls->max_seg_size > 0) {
- vs->start_pos = new_start_pos;
- if (vs->size >= hls->max_seg_size) {
+ if (vs->size + vs->start_pos >= hls->max_seg_size) {
vs->sequence++;
sls_flag_file_rename(hls, vs, old_filename);
ret = hls_start(s, vs);
vs->start_pos = 0;
/* When split segment by byte, the duration is short than hls_time,
* so it is not enough one segment duration as hls_time, */
- vs->number--;
+ } else {
+ vs->start_pos = new_start_pos;
}
- vs->number++;
} else {
vs->start_pos = new_start_pos;
sls_flag_file_rename(hls, vs, old_filename);
ret = hls_start(s, vs);
}
+ vs->number++;
av_freep(&old_filename);
if (ret < 0) {
@@ -2534,25 +2586,22 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
-static void hls_free_variant_streams(struct HLSContext *hls)
+static void hls_deinit(AVFormatContext *s)
{
+ HLSContext *hls = s->priv_data;
int i = 0;
- AVFormatContext *vtt_oc = NULL;
VariantStream *vs = NULL;
for (i = 0; i < hls->nb_varstreams; i++) {
vs = &hls->var_streams[i];
- vtt_oc = vs->vtt_avf;
av_freep(&vs->basename);
av_freep(&vs->base_output_dirname);
av_freep(&vs->fmp4_init_filename);
- if (vtt_oc) {
- av_freep(&vs->vtt_basename);
- av_freep(&vs->vtt_m3u8_name);
- avformat_free_context(vtt_oc);
- }
+ av_freep(&vs->vtt_basename);
+ av_freep(&vs->vtt_m3u8_name);
+ avformat_free_context(vs->vtt_avf);
avformat_free_context(vs->avf);
if (hls->resend_init_file)
av_freep(&vs->init_buffer);
@@ -2560,13 +2609,14 @@ static void hls_free_variant_streams(struct HLSContext *hls)
hls_free_segments(vs->old_segments);
av_freep(&vs->m3u8_name);
av_freep(&vs->streams);
- av_freep(&vs->agroup);
- av_freep(&vs->sgroup);
- av_freep(&vs->language);
- av_freep(&vs->ccgroup);
- av_freep(&vs->baseurl);
- av_freep(&vs->varname);
}
+
+ ff_format_io_close(s, &hls->m3u8_out);
+ ff_format_io_close(s, &hls->sub_m3u8_out);
+ av_freep(&hls->key_basename);
+ av_freep(&hls->var_streams);
+ av_freep(&hls->cc_streams);
+ av_freep(&hls->master_m3u8_url);
}
static int hls_write_trailer(struct AVFormatContext *s)
@@ -2595,8 +2645,8 @@ static int hls_write_trailer(struct AVFormatContext *s)
return AVERROR(ENOMEM);
}
if (hls->key_info_file || hls->encrypt) {
- av_dict_set(&options, "encryption_key", hls->key_string, 0);
- av_dict_set(&options, "encryption_iv", hls->iv_string, 0);
+ av_dict_set(&options, "encryption_key", vs->key_string, 0);
+ av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
filename = av_asprintf("crypto:%s", oc->url);
} else {
filename = av_asprintf("%s", oc->url);
@@ -2606,7 +2656,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
return AVERROR(ENOMEM);
}
- if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
+ if (hls->segment_type == SEGMENT_TYPE_FMP4) {
int range_length = 0;
if (!vs->init_range_length) {
uint8_t *buffer = NULL;
@@ -2641,7 +2691,6 @@ static int hls_write_trailer(struct AVFormatContext *s)
goto failed;
vs->size = range_length;
- hlsenc_io_close(s, &vs->out, filename);
ret = hlsenc_io_close(s, &vs->out, filename);
if (ret < 0) {
av_log(s, AV_LOG_WARNING, "upload segment failed, will retry with a new http session.\n");
@@ -2656,9 +2705,15 @@ static int hls_write_trailer(struct AVFormatContext *s)
if (ret < 0)
av_log(s, AV_LOG_WARNING, "Failed to upload file '%s' at the end.\n", oc->url);
}
- av_freep(&vs->temp_buffer);
-
+ if (hls->flags & HLS_SINGLE_FILE) {
+ if (hls->key_info_file || hls->encrypt) {
+ vs->size = append_single_file(s, vs);
+ }
+ hlsenc_io_close(s, &vs->out_single_file, vs->basename);
+ }
failed:
+ av_freep(&vs->temp_buffer);
+ av_dict_free(&options);
av_freep(&filename);
av_write_trailer(oc);
if (oc->url[0]) {
@@ -2699,21 +2754,6 @@ failed:
av_free(old_filename);
}
- hls_free_variant_streams(hls);
-
- for (i = 0; i < hls->nb_ccstreams; i++) {
- ClosedCaptionsStream *ccs = &hls->cc_streams[i];
- av_freep(&ccs->ccgroup);
- av_freep(&ccs->instreamid);
- av_freep(&ccs->language);
- }
-
- ff_format_io_close(s, &hls->m3u8_out);
- ff_format_io_close(s, &hls->sub_m3u8_out);
- av_freep(&hls->key_basename);
- av_freep(&hls->var_streams);
- av_freep(&hls->cc_streams);
- av_freep(&hls->master_m3u8_url);
return 0;
}
@@ -2724,15 +2764,21 @@ static int hls_init(AVFormatContext *s)
int i = 0;
int j = 0;
HLSContext *hls = s->priv_data;
- const char *pattern = "%d.ts";
+ const char *pattern;
VariantStream *vs = NULL;
- int basename_size = 0;
- const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
- const char *vtt_pattern = "%d.vtt";
+ const char *vtt_pattern = hls->flags & HLS_SINGLE_FILE ? ".vtt" : "%d.vtt";
char *p = NULL;
- int vtt_basename_size = 0;
int http_base_proto = ff_is_http_proto(s->url);
int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
+ double initial_program_date_time = av_gettime() / 1000000.0;
+
+ if (hls->use_localtime) {
+ pattern = get_default_pattern_localtime_fmt(s);
+ } else {
+ pattern = hls->segment_type == SEGMENT_TYPE_FMP4 ? "%d.m4s" : "%d.ts";
+ if (hls->flags & HLS_SINGLE_FILE)
+ pattern += 2;
+ }
hls->has_default_key = 0;
hls->has_video_m3u8 = 0;
@@ -2740,13 +2786,7 @@ static int hls_init(AVFormatContext *s)
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
ret);
- goto fail;
- }
- //TODO: Updates needed to encryption functionality with periodic re-key when more than one variant streams are present
- if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) {
- ret = AVERROR(EINVAL);
- av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more than one variant streams are present\n");
- goto fail;
+ return ret;
}
if (!hls->method && http_base_proto) {
@@ -2755,24 +2795,24 @@ static int hls_init(AVFormatContext *s)
ret = validate_name(hls->nb_varstreams, s->url);
if (ret < 0)
- goto fail;
+ return ret;
if (hls->segment_filename) {
ret = validate_name(hls->nb_varstreams, hls->segment_filename);
if (ret < 0)
- goto fail;
+ return ret;
}
if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
ret = validate_name(hls->nb_varstreams, hls->fmp4_init_filename);
if (ret < 0)
- goto fail;
+ return ret;
}
if (hls->subtitle_filename) {
ret = validate_name(hls->nb_varstreams, hls->subtitle_filename);
if (ret < 0)
- goto fail;
+ return ret;
}
if (hls->master_pl_name) {
@@ -2780,17 +2820,17 @@ static int hls_init(AVFormatContext *s)
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
ret);
- goto fail;
+ return ret;
}
}
- if (hls->segment_type == SEGMENT_TYPE_FMP4) {
- pattern = "%d.m4s";
- }
if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
+ (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH) ||
(hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
- time_t t = time(NULL); // we will need it in either case
- if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
+ time_t t = time(NULL);
+ if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH) {
+ hls->start_sequence = av_gettime();
+ } else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
hls->start_sequence = (int64_t)t;
} else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
char b[15];
@@ -2805,31 +2845,27 @@ static int hls_init(AVFormatContext *s)
}
hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
+
+ if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
+ // Independent segments cannot be guaranteed when splitting by time
+ hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
+ av_log(s, AV_LOG_WARNING,
+ "'split_by_time' and 'independent_segments' cannot be "
+ "enabled together. Disabling 'independent_segments' flag\n");
+ }
+
for (i = 0; i < hls->nb_varstreams; i++) {
vs = &hls->var_streams[i];
ret = format_name(s->url, &vs->m3u8_name, i, vs->varname);
if (ret < 0)
- goto fail;
+ return ret;
- vs->sequence = hls->start_sequence;
- vs->start_pts = AV_NOPTS_VALUE;
- vs->end_pts = AV_NOPTS_VALUE;
+ vs->sequence = hls->start_sequence;
+ vs->start_pts = AV_NOPTS_VALUE;
+ vs->end_pts = AV_NOPTS_VALUE;
vs->current_segment_final_filename_fmt[0] = '\0';
-
- if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
- // Independent segments cannot be guaranteed when splitting by time
- hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
- av_log(s, AV_LOG_WARNING,
- "'split_by_time' and 'independent_segments' cannot be enabled together. "
- "Disabling 'independent_segments' flag\n");
- }
-
- if (hls->flags & HLS_PROGRAM_DATE_TIME) {
- time_t now0;
- time(&now0);
- vs->initial_prog_date_time = now0;
- }
+ vs->initial_prog_date_time = initial_program_date_time;
for (j = 0; j < vs->nb_streams; j++) {
vs->has_video += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
@@ -2848,54 +2884,24 @@ static int hls_init(AVFormatContext *s)
} else {
vs->oformat = av_guess_format("mpegts", NULL, NULL);
}
+ if (!vs->oformat)
+ return AVERROR_MUXER_NOT_FOUND;
- if (!vs->oformat) {
- ret = AVERROR_MUXER_NOT_FOUND;
- goto fail;
- }
-
- if (vs->has_subtitle) {
- vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
- if (!vs->vtt_oformat) {
- ret = AVERROR_MUXER_NOT_FOUND;
- goto fail;
- }
- }
if (hls->segment_filename) {
ret = format_name(hls->segment_filename, &vs->basename, i, vs->varname);
if (ret < 0)
- goto fail;
+ return ret;
} else {
- if (hls->flags & HLS_SINGLE_FILE) {
- if (hls->segment_type == SEGMENT_TYPE_FMP4) {
- pattern = ".m4s";
- } else {
- pattern = ".ts";
- }
- }
-
- if (hls->use_localtime) {
- basename_size = strlen(vs->m3u8_name) + strlen(pattern_localtime_fmt) + 1;
- } else {
- basename_size = strlen(vs->m3u8_name) + strlen(pattern) + 1;
- }
-
- vs->basename = av_malloc(basename_size);
- if (!vs->basename) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
+ p = strrchr(vs->m3u8_name, '.');
+ if (p)
+ *p = '\0';
- av_strlcpy(vs->basename, vs->m3u8_name, basename_size);
+ vs->basename = av_asprintf("%s%s", vs->m3u8_name, pattern);
+ if (!vs->basename)
+ return AVERROR(ENOMEM);
- p = strrchr(vs->basename, '.');
if (p)
- *p = '\0';
- if (hls->use_localtime) {
- av_strlcat(vs->basename, pattern_localtime_fmt, basename_size);
- } else {
- av_strlcat(vs->basename, pattern, basename_size);
- }
+ *p = '.';
}
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
@@ -2903,96 +2909,73 @@ static int hls_init(AVFormatContext *s)
fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
if (hls->flags & HLS_SINGLE_FILE) {
vs->fmp4_init_filename = av_strdup(vs->basename);
- if (!vs->fmp4_init_filename) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
+ if (!vs->fmp4_init_filename)
+ return AVERROR(ENOMEM);
} else {
vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
- if (!vs->fmp4_init_filename ) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
+ if (!vs->fmp4_init_filename)
+ return AVERROR(ENOMEM);
av_strlcpy(vs->fmp4_init_filename, hls->fmp4_init_filename,
fmp4_init_filename_len);
if (hls->nb_varstreams > 1) {
if (av_stristr(vs->fmp4_init_filename, "%v")) {
av_freep(&vs->fmp4_init_filename);
- format_name(hls->fmp4_init_filename, &vs->fmp4_init_filename, i, vs->varname);
+ ret = format_name(hls->fmp4_init_filename,
+ &vs->fmp4_init_filename, i, vs->varname);
} else {
ret = append_postfix(vs->fmp4_init_filename, fmp4_init_filename_len, i);
}
if (ret < 0)
- goto fail;
- }
-
- fmp4_init_filename_len = strlen(vs->m3u8_name) +
- strlen(vs->fmp4_init_filename) + 1;
-
- vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
- if (!vs->base_output_dirname) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return ret;
}
- av_strlcpy(vs->base_output_dirname, vs->m3u8_name,
- fmp4_init_filename_len);
- p = strrchr(vs->base_output_dirname, '/');
+ p = strrchr(vs->m3u8_name, '/');
if (p) {
- *(p + 1) = '\0';
- av_strlcat(vs->base_output_dirname, vs->fmp4_init_filename,
- fmp4_init_filename_len);
+ char tmp = *(++p);
+ *p = '\0';
+ vs->base_output_dirname = av_asprintf("%s%s", vs->m3u8_name,
+ vs->fmp4_init_filename);
+ *p = tmp;
} else {
- av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
- fmp4_init_filename_len);
+ vs->base_output_dirname = av_strdup(vs->fmp4_init_filename);
}
+ if (!vs->base_output_dirname)
+ return AVERROR(ENOMEM);
}
}
ret = hls->use_localtime ? sls_flag_check_duration_size(hls, vs) : sls_flag_check_duration_size_index(hls);
if (ret < 0)
- goto fail;
+ return ret;
if (vs->has_subtitle) {
+ vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
+ if (!vs->vtt_oformat)
+ return AVERROR_MUXER_NOT_FOUND;
- if (hls->flags & HLS_SINGLE_FILE)
- vtt_pattern = ".vtt";
- vtt_basename_size = strlen(vs->m3u8_name) + strlen(vtt_pattern) + 1;
-
- vs->vtt_basename = av_malloc(vtt_basename_size);
- if (!vs->vtt_basename) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- av_strlcpy(vs->vtt_basename, vs->m3u8_name, vtt_basename_size);
- p = strrchr(vs->vtt_basename, '.');
+ p = strrchr(vs->m3u8_name, '.');
if (p)
*p = '\0';
- if ( hls->subtitle_filename ) {
+ vs->vtt_basename = av_asprintf("%s%s", vs->m3u8_name, vtt_pattern);
+ if (!vs->vtt_basename)
+ return AVERROR(ENOMEM);
+
+ if (hls->subtitle_filename) {
ret = format_name(hls->subtitle_filename, &vs->vtt_m3u8_name, i, vs->varname);
if (ret < 0)
- goto fail;
+ return ret;
} else {
- vs->vtt_m3u8_name = av_asprintf("%s_vtt.m3u8", vs->vtt_basename);
- if (!vs->vtt_m3u8_name) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- }
- av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
- }
-
- if (hls->baseurl) {
- vs->baseurl = av_strdup(hls->baseurl);
- if (!vs->baseurl) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ vs->vtt_m3u8_name = av_asprintf("%s_vtt.m3u8", vs->m3u8_name);
+ if (!vs->vtt_m3u8_name)
+ return AVERROR(ENOMEM);
}
+ if (p)
+ *p = '.';
}
if ((ret = hls_mux_init(s, vs)) < 0)
- goto fail;
+ return ret;
if (hls->flags & HLS_APPEND_LIST) {
parse_playlist(s, vs->m3u8_name, vs);
@@ -3006,22 +2989,8 @@ static int hls_init(AVFormatContext *s)
}
if ((ret = hls_start(s, vs)) < 0)
- goto fail;
- }
-
-fail:
- if (ret < 0) {
- hls_free_variant_streams(hls);
- for (i = 0; i < hls->nb_ccstreams; i++) {
- ClosedCaptionsStream *ccs = &hls->cc_streams[i];
- av_freep(&ccs->ccgroup);
- av_freep(&ccs->instreamid);
- av_freep(&ccs->language);
- }
- av_freep(&hls->key_basename);
- av_freep(&hls->var_streams);
- av_freep(&hls->cc_streams);
- av_freep(&hls->master_m3u8_url);
+ return ret;
+ vs->number++;
}
return ret;
@@ -3072,7 +3041,7 @@ static const AVOption options[] = {
{"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
{"iframes_only", "add EXT-X-I-FRAMES-ONLY, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_I_FRAMES_ONLY }, 0, UINT_MAX, E, "flags"},
#if FF_API_HLS_USE_LOCALTIME
- {"use_localtime", "set filename expansion with strftime at segment creation(will be deprecated )", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
+ {"use_localtime", "set filename expansion with strftime at segment creation(will be deprecated)", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
#endif
{"strftime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
#if FF_API_HLS_USE_LOCALTIME
@@ -3083,9 +3052,10 @@ static const AVOption options[] = {
{"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
{"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
{"method", "set the HTTP method(default: PUT)", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
- {"hls_start_number_source", "set source of first number in sequence", OFFSET(start_sequence_source_type), AV_OPT_TYPE_INT, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, 0, HLS_START_SEQUENCE_AS_FORMATTED_DATETIME, E, "start_sequence_source_type" },
+ {"hls_start_number_source", "set source of first number in sequence", OFFSET(start_sequence_source_type), AV_OPT_TYPE_INT, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, 0, HLS_START_SEQUENCE_LAST-1, E, "start_sequence_source_type" },
{"generic", "start_number value (default)", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
{"epoch", "seconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
+ {"epoch_us", "microseconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
{"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
{"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
@@ -3120,5 +3090,6 @@ AVOutputFormat ff_hls_muxer = {
.write_header = hls_write_header,
.write_packet = hls_write_packet,
.write_trailer = hls_write_trailer,
+ .deinit = hls_deinit,
.priv_class = &hls_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsplaylist.c b/chromium/third_party/ffmpeg/libavformat/hlsplaylist.c
index 43f9d281ba0..0e1dcc087f0 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsplaylist.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsplaylist.c
@@ -28,15 +28,18 @@
#include "avformat.h"
#include "hlsplaylist.h"
-void ff_hls_write_playlist_version(AVIOContext *out, int version) {
+void ff_hls_write_playlist_version(AVIOContext *out, int version)
+{
if (!out)
return;
avio_printf(out, "#EXTM3U\n");
avio_printf(out, "#EXT-X-VERSION:%d\n", version);
}
-void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
- const char *filename, char *language, int name_id, int is_default) {
+void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup,
+ const char *filename, const char *language,
+ int name_id, int is_default)
+{
if (!out || !agroup || !filename)
return;
@@ -48,8 +51,10 @@ void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
avio_printf(out, "URI=\"%s\"\n", filename);
}
-void ff_hls_write_subtitle_rendition(AVIOContext *out, char *sgroup,
- const char *filename, char *language, int name_id, int is_default) {
+void ff_hls_write_subtitle_rendition(AVIOContext *out, const char *sgroup,
+ const char *filename, const char *language,
+ int name_id, int is_default)
+{
if (!out || !filename)
return;
@@ -61,10 +66,11 @@ void ff_hls_write_subtitle_rendition(AVIOContext *out, char *sgroup,
avio_printf(out, "URI=\"%s\"\n", filename);
}
-void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
- int bandwidth, const char *filename, char *agroup,
- char *codecs, char *ccgroup, char *sgroup) {
-
+void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth,
+ const char *filename, const char *agroup,
+ const char *codecs, const char *ccgroup,
+ const char *sgroup)
+{
if (!out || !filename)
return;
@@ -91,7 +97,8 @@ void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache,
int target_duration, int64_t sequence,
- uint32_t playlist_type, int iframe_mode) {
+ uint32_t playlist_type, int iframe_mode)
+{
if (!out)
return;
ff_hls_write_playlist_version(out, version);
@@ -112,8 +119,9 @@ void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache,
}
}
-void ff_hls_write_init_file(AVIOContext *out, char *filename,
- int byterange_mode, int64_t size, int64_t pos) {
+void ff_hls_write_init_file(AVIOContext *out, const char *filename,
+ int byterange_mode, int64_t size, int64_t pos)
+{
avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", filename);
if (byterange_mode) {
avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", size, pos);
@@ -122,12 +130,14 @@ void ff_hls_write_init_file(AVIOContext *out, char *filename,
}
int ff_hls_write_file_entry(AVIOContext *out, int insert_discont,
- int byterange_mode,
- double duration, int round_duration,
- int64_t size, int64_t pos, //Used only if HLS_SINGLE_FILE flag is set
- char *baseurl, //Ignored if NULL
- char *filename, double *prog_date_time,
- int64_t video_keyframe_size, int64_t video_keyframe_pos, int iframe_mode) {
+ int byterange_mode, double duration,
+ int round_duration, int64_t size,
+ int64_t pos /* Used only if HLS_SINGLE_FILE flag is set */,
+ const char *baseurl /* Ignored if NULL */,
+ const char *filename, double *prog_date_time,
+ int64_t video_keyframe_size, int64_t video_keyframe_pos,
+ int iframe_mode)
+{
if (!out || !filename)
return AVERROR(EINVAL);
@@ -176,7 +186,8 @@ int ff_hls_write_file_entry(AVIOContext *out, int insert_discont,
return 0;
}
-void ff_hls_write_end_list (AVIOContext *out) {
+void ff_hls_write_end_list(AVIOContext *out)
+{
if (!out)
return;
avio_printf(out, "#EXT-X-ENDLIST\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsplaylist.h b/chromium/third_party/ffmpeg/libavformat/hlsplaylist.h
index a124bdcffb0..29487da3edf 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsplaylist.h
+++ b/chromium/third_party/ffmpeg/libavformat/hlsplaylist.h
@@ -37,25 +37,29 @@ typedef enum {
} PlaylistType;
void ff_hls_write_playlist_version(AVIOContext *out, int version);
-void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
- const char *filename, char *language, int name_id, int is_default);
-void ff_hls_write_subtitle_rendition(AVIOContext *out, char *sgroup,
- const char *filename, char *language, int name_id, int is_default);
-void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
- int bandwidth, const char *filename, char *agroup,
- char *codecs, char *ccgroup, char *sgroup);
+void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup,
+ const char *filename, const char *language,
+ int name_id, int is_default);
+void ff_hls_write_subtitle_rendition(AVIOContext *out, const char *sgroup,
+ const char *filename, const char *language,
+ int name_id, int is_default);
+void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth,
+ const char *filename, const char *agroup,
+ const char *codecs, const char *ccgroup,
+ const char *sgroup);
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache,
int target_duration, int64_t sequence,
uint32_t playlist_type, int iframe_mode);
-void ff_hls_write_init_file(AVIOContext *out, char *filename,
+void ff_hls_write_init_file(AVIOContext *out, const char *filename,
int byterange_mode, int64_t size, int64_t pos);
int ff_hls_write_file_entry(AVIOContext *out, int insert_discont,
- int byterange_mode,
- double duration, int round_duration,
- int64_t size, int64_t pos, //Used only if HLS_SINGLE_FILE flag is set
- char *baseurl, //Ignored if NULL
- char *filename, double *prog_date_time,
- int64_t video_keyframe_size, int64_t video_keyframe_pos, int iframe_mode);
+ int byterange_mode, double duration,
+ int round_duration, int64_t size,
+ int64_t pos /* Used only if HLS_SINGLE_FILE flag is set */,
+ const char *baseurl /* Ignored if NULL */,
+ const char *filename, double *prog_date_time,
+ int64_t video_keyframe_size, int64_t video_keyframe_pos,
+ int iframe_mode);
void ff_hls_write_end_list (AVIOContext *out);
#endif /* AVFORMAT_HLSPLAYLIST_H_ */
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsproto.c b/chromium/third_party/ffmpeg/libavformat/hlsproto.c
index e5673e5e035..de45f771d66 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsproto.c
@@ -178,7 +178,7 @@ static int hls_close(URLContext *h)
free_segment_list(s);
free_variant_list(s);
- ffurl_close(s->seg_hd);
+ ffurl_closep(&s->seg_hd);
return 0;
}
@@ -260,8 +260,7 @@ start:
return ret;
}
if (s->seg_hd) {
- ffurl_close(s->seg_hd);
- s->seg_hd = NULL;
+ ffurl_closep(&s->seg_hd);
s->cur_seq_no++;
}
reload_interval = s->n_segments > 0 ?
diff --git a/chromium/third_party/ffmpeg/libavformat/http.c b/chromium/third_party/ffmpeg/libavformat/http.c
index c9415578aa1..6c39da1a8b8 100644
--- a/chromium/third_party/ffmpeg/libavformat/http.c
+++ b/chromium/third_party/ffmpeg/libavformat/http.c
@@ -46,7 +46,7 @@
/* The IO buffer size is unrelated to the max URL size in itself, but needs
* to be large enough to fit the full request headers (including long
* path names). */
-#define BUFFER_SIZE MAX_URL_SIZE
+#define BUFFER_SIZE (MAX_URL_SIZE + HTTP_HEADERS_SIZE)
#define MAX_REDIRECTS 8
#define HTTP_SINGLE 1
#define HTTP_MUTLI 2
@@ -786,6 +786,7 @@ static int parse_set_cookie_expiry_time(const char *exp_str, struct tm *buf)
static int parse_set_cookie(const char *set_cookie, AVDictionary **dict)
{
char *param, *next_param, *cstr, *back;
+ char *saveptr = NULL;
if (!set_cookie[0])
return 0;
@@ -803,8 +804,9 @@ static int parse_set_cookie(const char *set_cookie, AVDictionary **dict)
}
next_param = cstr;
- while ((param = av_strtok(next_param, ";", &next_param))) {
+ while ((param = av_strtok(next_param, ";", &saveptr))) {
char *name, *value;
+ next_param = NULL;
param += strspn(param, WHITESPACES);
if ((name = av_strtok(param, "=", &value))) {
if (av_dict_set(dict, name, value, 0) < 0) {
@@ -1064,6 +1066,7 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path,
// Set-Cookie fields will result in multiple values delimited by a newline
int ret = 0;
char *cookie, *set_cookies, *next;
+ char *saveptr = NULL;
// destroy any cookies in the dictionary.
av_dict_free(&s->cookie_dict);
@@ -1076,10 +1079,11 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path,
return AVERROR(ENOMEM);
*cookies = NULL;
- while ((cookie = av_strtok(next, "\n", &next)) && !ret) {
+ while ((cookie = av_strtok(next, "\n", &saveptr)) && !ret) {
AVDictionary *cookie_params = NULL;
AVDictionaryEntry *cookie_entry, *e;
+ next = NULL;
// store the cookie in a dict in case it is updated in the response
if (parse_cookie(s, cookie, &s->cookie_dict))
av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie);
diff --git a/chromium/third_party/ffmpeg/libavformat/icecast.c b/chromium/third_party/ffmpeg/libavformat/icecast.c
index 7d8f92fe73f..b06c53cabd5 100644
--- a/chromium/third_party/ffmpeg/libavformat/icecast.c
+++ b/chromium/third_party/ffmpeg/libavformat/icecast.c
@@ -43,6 +43,7 @@ typedef struct IcecastContext {
int public;
char *url;
char *user_agent;
+ int tls;
} IcecastContext;
#define DEFAULT_ICE_USER "source"
@@ -62,6 +63,7 @@ static const AVOption options[] = {
{ "password", "set password", OFFSET(pass), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
{ "content_type", "set content-type, MUST be set if not audio/mpeg", OFFSET(content_type), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
{ "legacy_icecast", "use legacy SOURCE method, for Icecast < v2.4", OFFSET(legacy_icecast), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
+ { "tls", "use a TLS connection", OFFSET(tls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
{ NULL }
};
@@ -75,8 +77,7 @@ static void cat_header(AVBPrint *bp, const char key[], const char value[])
static int icecast_close(URLContext *h)
{
IcecastContext *s = h->priv_data;
- if (s->hd)
- ffurl_close(s->hd);
+ ffurl_closep(&s->hd);
return 0;
}
@@ -163,7 +164,9 @@ static int icecast_open(URLContext *h, const char *uri, int flags)
}
// Build new URI for passing to http protocol
- ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path);
+ ff_url_join(h_url, sizeof(h_url),
+ s->tls ? "https" : "http",
+ auth, host, port, "%s", path);
// Finally open http proto handler
ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL,
&opt_dict, h->protocol_whitelist, h->protocol_blacklist, h);
diff --git a/chromium/third_party/ffmpeg/libavformat/id3v2.c b/chromium/third_party/ffmpeg/libavformat/id3v2.c
index abe073dcc1a..cecd9b9f6d6 100644
--- a/chromium/third_party/ffmpeg/libavformat/id3v2.c
+++ b/chromium/third_party/ffmpeg/libavformat/id3v2.c
@@ -225,7 +225,6 @@ static void free_geobtag(void *obj)
av_freep(&geob->file_name);
av_freep(&geob->description);
av_freep(&geob->data);
- av_free(geob);
}
/**
@@ -459,20 +458,15 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
if (taglen < 1)
return;
- geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
- if (!geob_data) {
- av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
- sizeof(ID3v2ExtraMetaGEOB));
- return;
- }
-
new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
if (!new_extra) {
av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
sizeof(ID3v2ExtraMeta));
- goto fail;
+ return;
}
+ geob_data = &new_extra->data.geob;
+
/* read encoding type byte */
encoding = avio_r8(pb);
taglen--;
@@ -511,7 +505,6 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
/* add data to the list */
new_extra->tag = "GEOB";
- new_extra->data = geob_data;
new_extra->next = *extra_meta;
*extra_meta = new_extra;
@@ -577,7 +570,6 @@ static void free_apic(void *obj)
ID3v2ExtraMetaAPIC *apic = obj;
av_buffer_unref(&apic->buf);
av_freep(&apic->description);
- av_freep(&apic);
}
static void rstrip_spaces(char *buf)
@@ -603,10 +595,11 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
goto fail;
new_extra = av_mallocz(sizeof(*new_extra));
- apic = av_mallocz(sizeof(*apic));
- if (!new_extra || !apic)
+ if (!new_extra)
goto fail;
+ apic = &new_extra->data.apic;
+
enc = avio_r8(pb);
taglen--;
@@ -658,7 +651,6 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
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;
@@ -680,7 +672,6 @@ static void free_chapter(void *obj)
ID3v2ExtraMetaCHAP *chap = obj;
av_freep(&chap->element_id);
av_dict_free(&chap->meta);
- av_freep(&chap);
}
static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ID3v2ExtraMeta **extra_meta, int isv34)
@@ -691,10 +682,10 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const cha
ID3v2ExtraMetaCHAP *chap = NULL;
new_extra = av_mallocz(sizeof(*new_extra));
- chap = av_mallocz(sizeof(*chap));
+ if (!new_extra)
+ return;
- if (!new_extra || !chap)
- goto fail;
+ chap = &new_extra->data.chap;
if (decode_str(s, pb, 0, &chap->element_id, &len) < 0)
goto fail;
@@ -727,15 +718,13 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const cha
ff_metadata_conv(&chap->meta, NULL, ff_id3v2_4_metadata_conv);
new_extra->tag = "CHAP";
- new_extra->data = chap;
new_extra->next = *extra_meta;
*extra_meta = new_extra;
return;
fail:
- if (chap)
- free_chapter(chap);
+ free_chapter(chap);
av_freep(&new_extra);
}
@@ -744,7 +733,6 @@ static void free_priv(void *obj)
ID3v2ExtraMetaPRIV *priv = obj;
av_freep(&priv->owner);
av_freep(&priv->data);
- av_freep(&priv);
}
static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
@@ -754,10 +742,10 @@ static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
ID3v2ExtraMetaPRIV *priv;
meta = av_mallocz(sizeof(*meta));
- priv = av_mallocz(sizeof(*priv));
+ if (!meta)
+ return;
- if (!meta || !priv)
- goto fail;
+ priv = &meta->data.priv;
if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &priv->owner, &taglen) < 0)
goto fail;
@@ -772,15 +760,13 @@ static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
goto fail;
meta->tag = "PRIV";
- meta->data = priv;
meta->next = *extra_meta;
*extra_meta = meta;
return;
fail:
- if (priv)
- free_priv(priv);
+ free_priv(priv);
av_freep(&meta);
}
@@ -1132,7 +1118,7 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
while (current) {
if ((extra_func = get_extra_meta_func(current->tag, 1)))
- extra_func->free(current->data);
+ extra_func->free(&current->data);
next = current->next;
av_freep(&current);
current = next;
@@ -1141,17 +1127,17 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
*extra_meta = NULL;
}
-int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
{
ID3v2ExtraMeta *cur;
- for (cur = *extra_meta; cur; cur = cur->next) {
+ for (cur = extra_meta; cur; cur = cur->next) {
ID3v2ExtraMetaAPIC *apic;
AVStream *st;
if (strcmp(cur->tag, "APIC"))
continue;
- apic = cur->data;
+ apic = &cur->data.apic;
if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
@@ -1181,7 +1167,7 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
return 0;
}
-int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
+int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
{
int ret = 0;
ID3v2ExtraMeta *cur;
@@ -1192,12 +1178,12 @@ int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
// since extra_meta is a linked list where elements are prepended,
// we need to reverse the order of chapters
- for (cur = *extra_meta; cur; cur = cur->next) {
+ for (cur = extra_meta; cur; cur = cur->next) {
ID3v2ExtraMetaCHAP *chap;
if (strcmp(cur->tag, "CHAP"))
continue;
- chap = cur->data;
+ chap = &cur->data.chap;
if ((ret = av_dynarray_add_nofree(&chapters, &num_chapters, chap)) < 0)
goto end;
@@ -1232,14 +1218,14 @@ end:
return ret;
}
-int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta **extra_meta)
+int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta *extra_meta)
{
ID3v2ExtraMeta *cur;
int dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL;
- for (cur = *extra_meta; cur; cur = cur->next) {
+ for (cur = extra_meta; cur; cur = cur->next) {
if (!strcmp(cur->tag, "PRIV")) {
- ID3v2ExtraMetaPRIV *priv = cur->data;
+ ID3v2ExtraMetaPRIV *priv = &cur->data.priv;
AVBPrint bprint;
char *escaped, *key;
int i, ret;
@@ -1272,7 +1258,7 @@ int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta **extra_met
return 0;
}
-int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
+int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
{
return ff_id3v2_parse_priv_dict(&s->metadata, extra_meta);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/id3v2.h b/chromium/third_party/ffmpeg/libavformat/id3v2.h
index 9de0bee3743..a41fb271a42 100644
--- a/chromium/third_party/ffmpeg/libavformat/id3v2.h
+++ b/chromium/third_party/ffmpeg/libavformat/id3v2.h
@@ -54,12 +54,6 @@ typedef struct ID3v2EncContext {
int len; ///< size of the tag written so far
} ID3v2EncContext;
-typedef struct ID3v2ExtraMeta {
- const char *tag;
- void *data;
- struct ID3v2ExtraMeta *next;
-} ID3v2ExtraMeta;
-
typedef struct ID3v2ExtraMetaGEOB {
uint32_t datasize;
uint8_t *mime_type;
@@ -87,6 +81,17 @@ typedef struct ID3v2ExtraMetaCHAP {
AVDictionary *meta;
} ID3v2ExtraMetaCHAP;
+typedef struct ID3v2ExtraMeta {
+ const char *tag;
+ struct ID3v2ExtraMeta *next;
+ union {
+ ID3v2ExtraMetaAPIC apic;
+ ID3v2ExtraMetaCHAP chap;
+ ID3v2ExtraMetaGEOB geob;
+ ID3v2ExtraMetaPRIV priv;
+ } data;
+} ID3v2ExtraMeta;
+
/**
* Detect ID3v2 Header.
* @param buf must be ID3v2_HEADER_SIZE byte long
@@ -162,25 +167,25 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
* Create a stream for each APIC (attached picture) extracted from the
* ID3v2 header.
*/
-int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta);
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta);
/**
* Create chapters for all CHAP tags found in the ID3v2 header.
*/
-int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta **extra_meta);
+int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta *extra_meta);
/**
* Parse PRIV tags into a dictionary. The PRIV owner is the metadata key. The
* PRIV data is the value, with non-printable characters escaped.
*/
-int ff_id3v2_parse_priv_dict(AVDictionary **d, ID3v2ExtraMeta **extra_meta);
+int ff_id3v2_parse_priv_dict(AVDictionary **d, ID3v2ExtraMeta *extra_meta);
/**
* Add metadata for all PRIV tags in the ID3v2 header. The PRIV owner is the
* metadata key. The PRIV data is the value, with non-printable characters
* escaped.
*/
-int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta **extra_meta);
+int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta *extra_meta);
extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
diff --git a/chromium/third_party/ffmpeg/libavformat/iff.c b/chromium/third_party/ffmpeg/libavformat/iff.c
index 9cee31a86b1..7feb121cd02 100644
--- a/chromium/third_party/ffmpeg/libavformat/iff.c
+++ b/chromium/third_party/ffmpeg/libavformat/iff.c
@@ -312,8 +312,8 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof)
id3v2_extra_meta = NULL;
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size);
if (id3v2_extra_meta) {
- if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0 ||
- (ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) {
+ if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0 ||
+ (ret = ff_id3v2_parse_chapters(s, id3v2_extra_meta)) < 0) {
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/img2.c b/chromium/third_party/ffmpeg/libavformat/img2.c
index 16bc9d2abd8..d243d6c1253 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2.c
@@ -40,6 +40,7 @@ const IdStrMap ff_img_tags[] = {
{ AV_CODEC_ID_PGMYUV, "pgmyuv" },
{ AV_CODEC_ID_PBM, "pbm" },
{ AV_CODEC_ID_PAM, "pam" },
+ { AV_CODEC_ID_PFM, "pfm" },
{ AV_CODEC_ID_ALIAS_PIX, "pix" },
{ AV_CODEC_ID_DDS, "dds" },
{ AV_CODEC_ID_MPEG1VIDEO, "mpg1-img" },
diff --git a/chromium/third_party/ffmpeg/libavformat/img2dec.c b/chromium/third_party/ffmpeg/libavformat/img2dec.c
index 40f3e3d499e..a7e89cd056b 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2dec.c
@@ -379,8 +379,7 @@ int ff_img_read_header(AVFormatContext *s1)
* as a dictionary, so it can be used by filters like 'drawtext'.
*/
static int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) {
- uint8_t* metadata;
- int metadata_len;
+ int metadata_len, ret;
AVDictionary *d = NULL;
char *packed_metadata = NULL;
@@ -391,13 +390,12 @@ static int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) {
av_dict_free(&d);
if (!packed_metadata)
return AVERROR(ENOMEM);
- if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) {
+ ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
+ packed_metadata, metadata_len);
+ if (ret < 0) {
av_freep(&packed_metadata);
- return AVERROR(ENOMEM);
+ return ret;
}
- memcpy(metadata, packed_metadata, metadata_len);
- av_freep(&packed_metadata);
-
return 0;
}
@@ -1002,6 +1000,14 @@ static int pgmyuv_probe(const AVProbeData *p) // custom FFmpeg format recognized
return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0;
}
+static int pgx_probe(const AVProbeData *p)
+{
+ const uint8_t *b = p->buf;
+ if (!memcmp(b, "PG ML ", 6))
+ return AVPROBE_SCORE_EXTENSION + 1;
+ return 0;
+}
+
static int ppm_probe(const AVProbeData *p)
{
return pnm_magic_check(p, 3) || pnm_magic_check(p, 6) ? pnm_probe(p) : 0;
@@ -1096,6 +1102,7 @@ IMAGEAUTO_DEMUXER(pbm, AV_CODEC_ID_PBM)
IMAGEAUTO_DEMUXER(pcx, AV_CODEC_ID_PCX)
IMAGEAUTO_DEMUXER(pgm, AV_CODEC_ID_PGM)
IMAGEAUTO_DEMUXER(pgmyuv, AV_CODEC_ID_PGMYUV)
+IMAGEAUTO_DEMUXER(pgx, AV_CODEC_ID_PGX)
IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR)
IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG)
IMAGEAUTO_DEMUXER(ppm, AV_CODEC_ID_PPM)
diff --git a/chromium/third_party/ffmpeg/libavformat/internal.h b/chromium/third_party/ffmpeg/libavformat/internal.h
index 6786b732aca..17a6ab07d35 100644
--- a/chromium/third_party/ffmpeg/libavformat/internal.h
+++ b/chromium/third_party/ffmpeg/libavformat/internal.h
@@ -188,6 +188,8 @@ struct AVStreamInternal {
*/
int need_context_update;
+ int is_intra_only;
+
FFFrac *priv_pts;
};
@@ -290,16 +292,6 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
AVFormatContext *src, int interleave);
/**
- * Get the length in bytes which is needed to store val as v.
- */
-int ff_get_v_length(uint64_t val);
-
-/**
- * Put val using a variable number of bytes.
- */
-void ff_put_v(AVIOContext *bc, uint64_t val);
-
-/**
* Read a whole line of text from AVIOContext. Stop reading after reaching
* either a \\n, a \\0 or EOF. The returned string is always \\0-terminated,
* and may be truncated if the buffer is too small.
@@ -520,6 +512,8 @@ unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id);
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag);
+int ff_is_intra_only(enum AVCodecID id);
+
/**
* Select a PCM codec based on the given parameters.
*
diff --git a/chromium/third_party/ffmpeg/libavformat/isom.c b/chromium/third_party/ffmpeg/libavformat/isom.c
index eefe9277b4f..209bbac5d10 100644
--- a/chromium/third_party/ffmpeg/libavformat/isom.c
+++ b/chromium/third_party/ffmpeg/libavformat/isom.c
@@ -313,6 +313,8 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_PIXLET, MKTAG('p', 'x', 'l', 't') },
+ { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'c', 'l', 'c') },
+
{ AV_CODEC_ID_NONE, 0 },
};
@@ -393,25 +395,145 @@ const AVCodecTag ff_codec_movdata_tags[] = {
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
/* deprecated by putting the code as 3*5 bits ASCII */
static const char mov_mdhd_language_map[][4] = {
- /* 0-9 */
- "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
- "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/,
- "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "",
- "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk",
- "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
- /*?*/
- "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus",
- "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
- "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao",
- /* roman? arabic? */
- "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
- /*==rundi?*/
- "", "run", "", "mlg", "epo", "", "", "", "", "",
- /* 100 */
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "wel", "baq",
- "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
+ "eng", /* 0 English */
+ "fra", /* 1 French */
+ "ger", /* 2 German */
+ "ita", /* 3 Italian */
+ "dut", /* 4 Dutch */
+ "sve", /* 5 Swedish */
+ "spa", /* 6 Spanish */
+ "dan", /* 7 Danish */
+ "por", /* 8 Portuguese */
+ "nor", /* 9 Norwegian */
+ "heb", /* 10 Hebrew */
+ "jpn", /* 11 Japanese */
+ "ara", /* 12 Arabic */
+ "fin", /* 13 Finnish */
+ "gre", /* 14 Greek */
+ "ice", /* 15 Icelandic */
+ "mlt", /* 16 Maltese */
+ "tur", /* 17 Turkish */
+ "hr ", /* 18 Croatian */
+ "chi", /* 19 Traditional Chinese */
+ "urd", /* 20 Urdu */
+ "hin", /* 21 Hindi */
+ "tha", /* 22 Thai */
+ "kor", /* 23 Korean */
+ "lit", /* 24 Lithuanian */
+ "pol", /* 25 Polish */
+ "hun", /* 26 Hungarian */
+ "est", /* 27 Estonian */
+ "lav", /* 28 Latvian */
+ "", /* 29 Sami */
+ "fo ", /* 30 Faroese */
+ "", /* 31 Farsi */
+ "rus", /* 32 Russian */
+ "chi", /* 33 Simplified Chinese */
+ "", /* 34 Flemish */
+ "iri", /* 35 Irish */
+ "alb", /* 36 Albanian */
+ "ron", /* 37 Romanian */
+ "ces", /* 38 Czech */
+ "slk", /* 39 Slovak */
+ "slv", /* 40 Slovenian */
+ "yid", /* 41 Yiddish */
+ "sr ", /* 42 Serbian */
+ "mac", /* 43 Macedonian */
+ "bul", /* 44 Bulgarian */
+ "ukr", /* 45 Ukrainian */
+ "bel", /* 46 Belarusian */
+ "uzb", /* 47 Uzbek */
+ "kaz", /* 48 Kazakh */
+ "aze", /* 49 Azerbaijani */
+ "aze", /* 50 AzerbaijanAr */
+ "arm", /* 51 Armenian */
+ "geo", /* 52 Georgian */
+ "mol", /* 53 Moldavian */
+ "kir", /* 54 Kirghiz */
+ "tgk", /* 55 Tajiki */
+ "tuk", /* 56 Turkmen */
+ "mon", /* 57 Mongolian */
+ "", /* 58 MongolianCyr */
+ "pus", /* 59 Pashto */
+ "kur", /* 60 Kurdish */
+ "kas", /* 61 Kashmiri */
+ "snd", /* 62 Sindhi */
+ "tib", /* 63 Tibetan */
+ "nep", /* 64 Nepali */
+ "san", /* 65 Sanskrit */
+ "mar", /* 66 Marathi */
+ "ben", /* 67 Bengali */
+ "asm", /* 68 Assamese */
+ "guj", /* 69 Gujarati */
+ "pa ", /* 70 Punjabi */
+ "ori", /* 71 Oriya */
+ "mal", /* 72 Malayalam */
+ "kan", /* 73 Kannada */
+ "tam", /* 74 Tamil */
+ "tel", /* 75 Telugu */
+ "", /* 76 Sinhala */
+ "bur", /* 77 Burmese */
+ "khm", /* 78 Khmer */
+ "lao", /* 79 Lao */
+ "vie", /* 80 Vietnamese */
+ "ind", /* 81 Indonesian */
+ "tgl", /* 82 Tagalog */
+ "may", /* 83 MalayRoman */
+ "may", /* 84 MalayArabic */
+ "amh", /* 85 Amharic */
+ "tir", /* 86 Galla */
+ "orm", /* 87 Oromo */
+ "som", /* 88 Somali */
+ "swa", /* 89 Swahili */
+ "", /* 90 Kinyarwanda */
+ "run", /* 91 Rundi */
+ "", /* 92 Nyanja */
+ "mlg", /* 93 Malagasy */
+ "epo", /* 94 Esperanto */
+ "", /* 95 */
+ "", /* 96 */
+ "", /* 97 */
+ "", /* 98 */
+ "", /* 99 */
+ "", /* 100 */
+ "", /* 101 */
+ "", /* 102 */
+ "", /* 103 */
+ "", /* 104 */
+ "", /* 105 */
+ "", /* 106 */
+ "", /* 107 */
+ "", /* 108 */
+ "", /* 109 */
+ "", /* 110 */
+ "", /* 111 */
+ "", /* 112 */
+ "", /* 113 */
+ "", /* 114 */
+ "", /* 115 */
+ "", /* 116 */
+ "", /* 117 */
+ "", /* 118 */
+ "", /* 119 */
+ "", /* 120 */
+ "", /* 121 */
+ "", /* 122 */
+ "", /* 123 */
+ "", /* 124 */
+ "", /* 125 */
+ "", /* 126 */
+ "", /* 127 */
+ "wel", /* 128 Welsh */
+ "baq", /* 129 Basque */
+ "cat", /* 130 Catalan */
+ "lat", /* 131 Latin */
+ "que", /* 132 Quechua */
+ "grn", /* 133 Guarani */
+ "aym", /* 134 Aymara */
+ "tat", /* 135 Tatar */
+ "uig", /* 136 Uighur */
+ "dzo", /* 137 Dzongkha */
+ "jav", /* 138 JavaneseRom */
};
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
diff --git a/chromium/third_party/ffmpeg/libavformat/ivfenc.c b/chromium/third_party/ffmpeg/libavformat/ivfenc.c
index 45e5b238dcb..0951f56c92a 100644
--- a/chromium/third_party/ffmpeg/libavformat/ivfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/ivfenc.c
@@ -26,10 +26,9 @@ typedef struct IVFEncContext {
uint64_t last_pts, sum_delta_pts;
} IVFEncContext;
-static int ivf_write_header(AVFormatContext *s)
+static int ivf_init(AVFormatContext *s)
{
AVCodecParameters *par;
- AVIOContext *pb = s->pb;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Format supports only exactly one video stream\n");
@@ -43,6 +42,25 @@ static int ivf_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "Currently only VP8, VP9 and AV1 are supported!\n");
return AVERROR(EINVAL);
}
+
+ if (par->codec_id == AV_CODEC_ID_VP9) {
+ int ret = ff_stream_add_bitstream_filter(s->streams[0], "vp9_superframe", NULL);
+ if (ret < 0)
+ return ret;
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ int ret = ff_stream_add_bitstream_filter(s->streams[0], "av1_metadata", "td=insert");
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ivf_write_header(AVFormatContext *s)
+{
+ AVCodecParameters *par = s->streams[0]->codecpar;
+ AVIOContext *pb = s->pb;
+
avio_write(pb, "DKIF", 4);
avio_wl16(pb, 0); // version
avio_wl16(pb, 32); // header length
@@ -92,19 +110,6 @@ static int ivf_write_trailer(AVFormatContext *s)
return 0;
}
-static int ivf_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
-{
- int ret = 1;
- AVStream *st = s->streams[pkt->stream_index];
-
- if (st->codecpar->codec_id == AV_CODEC_ID_VP9)
- ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
- else if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
- ret = ff_stream_add_bitstream_filter(st, "av1_metadata", "td=insert");
-
- return ret;
-}
-
static const AVCodecTag codec_ivf_tags[] = {
{ AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') },
{ AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') },
@@ -119,9 +124,9 @@ AVOutputFormat ff_ivf_muxer = {
.extensions = "ivf",
.audio_codec = AV_CODEC_ID_NONE,
.video_codec = AV_CODEC_ID_VP8,
+ .init = ivf_init,
.write_header = ivf_write_header,
.write_packet = ivf_write_packet,
.write_trailer = ivf_write_trailer,
- .check_bitstream = ivf_check_bitstream,
.codec_tag = (const AVCodecTag* const []){ codec_ivf_tags, 0 },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/jacosubdec.c b/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
index 121c86d6596..3414eb39386 100644
--- a/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
@@ -188,8 +188,10 @@ static int jacosub_read_header(AVFormatContext *s)
AVPacket *sub;
sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line);
- if (!sub)
- return AVERROR(ENOMEM);
+ if (!sub) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
sub->pos = pos;
merge_line = len > 1 && !strcmp(&line[len - 2], "\\\n");
continue;
diff --git a/chromium/third_party/ffmpeg/libavformat/kvag.c b/chromium/third_party/ffmpeg/libavformat/kvag.c
index 71b0eb41186..0a11fc05562 100644
--- a/chromium/third_party/ffmpeg/libavformat/kvag.c
+++ b/chromium/third_party/ffmpeg/libavformat/kvag.c
@@ -1,5 +1,5 @@
/*
- * Simon & Schuster Interactive VAG demuxer
+ * Simon & Schuster Interactive VAG (de)muxer
*
* Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com)
*
@@ -21,6 +21,7 @@
*/
#include "avformat.h"
#include "internal.h"
+#include "rawenc.h"
#include "libavutil/intreadwrite.h"
#define KVAG_TAG MKTAG('K', 'V', 'A', 'G')
@@ -34,6 +35,7 @@ typedef struct KVAGHeader {
uint16_t stereo;
} KVAGHeader;
+#if CONFIG_KVAG_DEMUXER
static int kvag_probe(const AVProbeData *p)
{
if (AV_RL32(p->buf) != KVAG_TAG)
@@ -115,3 +117,81 @@ AVInputFormat ff_kvag_demuxer = {
.read_header = kvag_read_header,
.read_packet = kvag_read_packet
};
+#endif
+
+#if CONFIG_KVAG_MUXER
+static int kvag_write_init(AVFormatContext *s)
+{
+ AVCodecParameters *par;
+
+ if (s->nb_streams != 1) {
+ av_log(s, AV_LOG_ERROR, "KVAG files have exactly one stream\n");
+ return AVERROR(EINVAL);
+ }
+
+ par = s->streams[0]->codecpar;
+
+ if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_SSI) {
+ av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
+ avcodec_get_name(par->codec_id));
+ return AVERROR(EINVAL);
+ }
+
+ if (par->channels > 2) {
+ av_log(s, AV_LOG_ERROR, "KVAG files only support up to 2 channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
+ av_log(s, AV_LOG_WARNING, "Stream not seekable, unable to write output file\n");
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+static int kvag_write_header(AVFormatContext *s)
+{
+ uint8_t buf[KVAG_HEADER_SIZE];
+ AVCodecParameters *par = s->streams[0]->codecpar;
+
+ AV_WL32(buf + 0, KVAG_TAG);
+ AV_WL32(buf + 4, 0); /* Data size, we fix this up later. */
+ AV_WL32(buf + 8, par->sample_rate);
+ AV_WL16(buf + 12, par->channels == 2);
+
+ avio_write(s->pb, buf, sizeof(buf));
+ return 0;
+}
+
+static int kvag_write_trailer(AVFormatContext *s)
+{
+ int64_t file_size, data_size;
+
+ file_size = avio_tell(s->pb);
+ data_size = file_size - KVAG_HEADER_SIZE;
+ if (data_size < UINT32_MAX) {
+ avio_seek(s->pb, 4, SEEK_SET);
+ avio_wl32(s->pb, (uint32_t)data_size);
+ avio_seek(s->pb, file_size, SEEK_SET);
+ } else {
+ av_log(s, AV_LOG_WARNING,
+ "Filesize %"PRId64" invalid for KVAG, output file will be broken\n",
+ file_size);
+ }
+
+ return 0;
+}
+
+AVOutputFormat ff_kvag_muxer = {
+ .name = "kvag",
+ .long_name = NULL_IF_CONFIG_SMALL("Simon & Schuster Interactive VAG"),
+ .extensions = "vag",
+ .audio_codec = AV_CODEC_ID_ADPCM_IMA_SSI,
+ .video_codec = AV_CODEC_ID_NONE,
+ .init = kvag_write_init,
+ .write_header = kvag_write_header,
+ .write_packet = ff_raw_write_packet,
+ .write_trailer = kvag_write_trailer
+};
+#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/latmenc.c b/chromium/third_party/ffmpeg/libavformat/latmenc.c
index 5ae677f5dad..5458ce2596b 100644
--- a/chromium/third_party/ffmpeg/libavformat/latmenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/latmenc.c
@@ -165,7 +165,7 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt)
return ff_raw_write_packet(s, pkt);
else {
uint8_t *side_data;
- int side_data_size = 0, ret;
+ int side_data_size, ret;
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
&side_data_size);
@@ -211,7 +211,6 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt)
} else
avpriv_copy_bits(&bs, pkt->data, 8*pkt->size);
- avpriv_align_put_bits(&bs);
flush_put_bits(&bs);
len = put_bits_count(&bs) >> 3;
diff --git a/chromium/third_party/ffmpeg/libavformat/libamqp.c b/chromium/third_party/ffmpeg/libavformat/libamqp.c
index aaf0e511522..81df724a6d4 100644
--- a/chromium/third_party/ffmpeg/libavformat/libamqp.c
+++ b/chromium/third_party/ffmpeg/libavformat/libamqp.c
@@ -39,6 +39,7 @@ typedef struct AMQPContext {
int pkt_size;
int64_t connection_timeout;
int pkt_size_overflow;
+ int delivery_mode;
} AMQPContext;
#define STR_LEN 1024
@@ -52,6 +53,9 @@ static const AVOption options[] = {
{ "exchange", "Exchange to send/read packets", OFFSET(exchange), AV_OPT_TYPE_STRING, { .str = "amq.direct" }, 0, 0, .flags = D | E },
{ "routing_key", "Key to filter streams", OFFSET(routing_key), AV_OPT_TYPE_STRING, { .str = "amqp" }, 0, 0, .flags = D | E },
{ "connection_timeout", "Initial connection timeout", OFFSET(connection_timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT64_MAX, .flags = D | E},
+ { "delivery_mode", "Delivery mode", OFFSET(delivery_mode), AV_OPT_TYPE_INT, { .i64 = AMQP_DELIVERY_PERSISTENT }, 1, 2, .flags = E, "delivery_mode"},
+ { "persistent", "Persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_PERSISTENT }, 0, 0, E, "delivery_mode" },
+ { "non-persistent", "Non-persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_NONPERSISTENT }, 0, 0, E, "delivery_mode" },
{ NULL }
};
@@ -222,7 +226,7 @@ static int amqp_proto_write(URLContext *h, const unsigned char *buf, int size)
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
props.content_type = amqp_cstring_bytes("octet/stream");
- props.delivery_mode = 2; /* persistent delivery mode */
+ props.delivery_mode = s->delivery_mode;
ret = amqp_basic_publish(s->conn, DEFAULT_CHANNEL, amqp_cstring_bytes(s->exchange),
amqp_cstring_bytes(s->routing_key), 0, 0,
diff --git a/chromium/third_party/ffmpeg/libavformat/libsrt.c b/chromium/third_party/ffmpeg/libavformat/libsrt.c
index 2d6fc4b7e7e..4719ce0d4b4 100644
--- a/chromium/third_party/ffmpeg/libavformat/libsrt.c
+++ b/chromium/third_party/ffmpeg/libavformat/libsrt.c
@@ -96,8 +96,8 @@ typedef struct SRTContext {
#define E AV_OPT_FLAG_ENCODING_PARAM
#define OFFSET(x) offsetof(SRTContext, x)
static const AVOption libsrt_options[] = {
- { "timeout", "Timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
- { "listen_timeout", "Connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "timeout", "Timeout of socket I/O operations (in microseconds)", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "listen_timeout", "Connection awaiting timeout (in microseconds)" , OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "recv_buffer_size", "Socket receive buffer size (in bytes)", OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "pkt_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, "payload_size" },
@@ -118,13 +118,13 @@ static const AVOption libsrt_options[] = {
{ "iptos", "IP Type of Service", OFFSET(iptos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
{ "inputbw", "Estimated input stream rate", OFFSET(inputbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "oheadbw", "MaxBW ceiling based on % over input stream rate", OFFSET(oheadbw), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, .flags = D|E },
- { "latency", "receiver delay to absorb bursts of missed packet retransmissions", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "latency", "receiver delay (in microseconds) to absorb bursts of missed packet retransmissions", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "tsbpddelay", "deprecated, same effect as latency option", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
- { "rcvlatency", "receive latency", OFFSET(rcvlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
- { "peerlatency", "peer latency", OFFSET(peerlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "rcvlatency", "receive latency (in microseconds)", OFFSET(rcvlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "peerlatency", "peer latency (in microseconds)", OFFSET(peerlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "tlpktdrop", "Enable receiver pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
{ "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
- { "connect_timeout", "Connect timeout. Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "connect_timeout", "Connect timeout(in milliseconds). Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "mode", "Connection mode (caller, listener, rendezvous)", OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = SRT_MODE_CALLER }, SRT_MODE_CALLER, SRT_MODE_RENDEZVOUS, .flags = D|E, "mode" },
{ "caller", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_CALLER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
{ "listener", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_LISTENER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
@@ -313,8 +313,12 @@ static int libsrt_set_options_pre(URLContext *h, int fd)
(s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
(s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", s->passphrase, strlen(s->passphrase)) < 0) ||
#if SRT_VERSION_VALUE >= 0x010302
+#if SRT_VERSION_VALUE >= 0x010401
+ (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_ENFORCEDENCRYPTION, "SRTO_ENFORCEDENCRYPTION", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) ||
+#else
/* SRTO_STRICTENC == SRTO_ENFORCEDENCRYPTION (53), but for compatibility, we used SRTO_STRICTENC */
(s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_STRICTENC, "SRTO_STRICTENC", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) ||
+#endif
(s->kmrefreshrate >= 0 && libsrt_setsockopt(h, fd, SRTO_KMREFRESHRATE, "SRTO_KMREFRESHRATE", &s->kmrefreshrate, sizeof(s->kmrefreshrate)) < 0) ||
(s->kmpreannounce >= 0 && libsrt_setsockopt(h, fd, SRTO_KMPREANNOUNCE, "SRTO_KMPREANNOUNCE", &s->kmpreannounce, sizeof(s->kmpreannounce)) < 0) ||
#endif
@@ -333,7 +337,11 @@ static int libsrt_set_options_pre(URLContext *h, int fd)
(s->lossmaxttl >= 0 && libsrt_setsockopt(h, fd, SRTO_LOSSMAXTTL, "SRTO_LOSSMAXTTL", &s->lossmaxttl, sizeof(s->lossmaxttl)) < 0) ||
(s->minversion >= 0 && libsrt_setsockopt(h, fd, SRTO_MINVERSION, "SRTO_MINVERSION", &s->minversion, sizeof(s->minversion)) < 0) ||
(s->streamid && libsrt_setsockopt(h, fd, SRTO_STREAMID, "SRTO_STREAMID", s->streamid, strlen(s->streamid)) < 0) ||
+#if SRT_VERSION_VALUE >= 0x010401
+ (s->smoother && libsrt_setsockopt(h, fd, SRTO_CONGESTION, "SRTO_CONGESTION", s->smoother, strlen(s->smoother)) < 0) ||
+#else
(s->smoother && libsrt_setsockopt(h, fd, SRTO_SMOOTHER, "SRTO_SMOOTHER", s->smoother, strlen(s->smoother)) < 0) ||
+#endif
(s->messageapi >= 0 && libsrt_setsockopt(h, fd, SRTO_MESSAGEAPI, "SRTO_MESSAGEAPI", &s->messageapi, sizeof(s->messageapi)) < 0) ||
(s->payload_size >= 0 && libsrt_setsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &s->payload_size, sizeof(s->payload_size)) < 0) ||
((h->flags & AVIO_FLAG_WRITE) && libsrt_setsockopt(h, fd, SRTO_SENDER, "SRTO_SENDER", &yes, sizeof(yes)) < 0)) {
@@ -361,7 +369,7 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags)
int ret;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
- int open_timeout = 0;
+ int64_t open_timeout = 0;
int eid;
eid = srt_epoll_create();
diff --git a/chromium/third_party/ffmpeg/libavformat/lrcdec.c b/chromium/third_party/ffmpeg/libavformat/lrcdec.c
index a9a117691ac..46d5e2bc6a2 100644
--- a/chromium/third_party/ffmpeg/libavformat/lrcdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/lrcdec.c
@@ -202,6 +202,7 @@ static int lrc_read_header(AVFormatContext *s)
sub = ff_subtitles_queue_insert(&lrc->q, line.str + ts_strlength,
line.len - ts_strlength, 0);
if(!sub) {
+ ff_subtitles_queue_clean(&lrc->q);
return AVERROR(ENOMEM);
}
sub->pos = pos;
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskadec.c b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
index b5a6d3ab065..79410e278f3 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
@@ -253,6 +253,7 @@ typedef struct MatroskaTrack {
AVStream *stream;
int64_t end_timecode;
int ms_compat;
+ int needs_decoding;
uint64_t max_block_additional_id;
uint32_t palette[AVPALETTE_COUNT];
@@ -262,6 +263,7 @@ typedef struct MatroskaTrack {
typedef struct MatroskaAttachment {
uint64_t uid;
char *filename;
+ char *description;
char *mime;
EbmlBin bin;
@@ -590,7 +592,7 @@ static EbmlSyntax matroska_attachment[] = {
{ MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachment, filename) },
{ MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachment, mime) },
{ MATROSKA_ID_FILEDATA, EBML_BIN, 0, offsetof(MatroskaAttachment, bin) },
- { MATROSKA_ID_FILEDESC, EBML_NONE },
+ { MATROSKA_ID_FILEDESC, EBML_UTF8, 0, offsetof(MatroskaAttachment, description) },
CHILD_OF(matroska_attachments)
};
@@ -1138,7 +1140,7 @@ static int is_ebml_id_valid(uint32_t id)
* an entry already exists, return the existing entry.
*/
static MatroskaLevel1Element *matroska_find_level1_elem(MatroskaDemuxContext *matroska,
- uint32_t id)
+ uint32_t id, int64_t pos)
{
int i;
MatroskaLevel1Element *elem;
@@ -1150,19 +1152,18 @@ static MatroskaLevel1Element *matroska_find_level1_elem(MatroskaDemuxContext *ma
if (id == MATROSKA_ID_CLUSTER)
return NULL;
- // There can be multiple seekheads.
- if (id != MATROSKA_ID_SEEKHEAD) {
- for (i = 0; i < matroska->num_level1_elems; i++) {
- if (matroska->level1_elems[i].id == id)
+ // There can be multiple SeekHeads and Tags.
+ for (i = 0; i < matroska->num_level1_elems; i++) {
+ if (matroska->level1_elems[i].id == id) {
+ if (matroska->level1_elems[i].pos == pos ||
+ id != MATROSKA_ID_SEEKHEAD && id != MATROSKA_ID_TAGS)
return &matroska->level1_elems[i];
}
}
// Only a completely broken file would have more elements.
- // It also provides a low-effort way to escape from circular seekheads
- // (every iteration will add a level1 entry).
if (matroska->num_level1_elems >= FF_ARRAY_ELEMS(matroska->level1_elems)) {
- av_log(matroska->ctx, AV_LOG_ERROR, "Too many level1 elements or circular seekheads.\n");
+ av_log(matroska->ctx, AV_LOG_ERROR, "Too many level1 elements.\n");
return NULL;
}
@@ -1411,7 +1412,7 @@ static int ebml_parse(MatroskaDemuxContext *matroska,
if (id == MATROSKA_ID_CUES)
matroska->cues_parsing_deferred = 0;
if (syntax->type == EBML_LEVEL1 &&
- (level1_elem = matroska_find_level1_elem(matroska, syntax->id))) {
+ (level1_elem = matroska_find_level1_elem(matroska, syntax->id, pos))) {
if (!level1_elem->pos) {
// Zero is not a valid position for a level 1 element.
level1_elem->pos = pos;
@@ -1775,7 +1776,7 @@ static void matroska_convert_tags(AVFormatContext *s)
}
}
if (!found) {
- av_log(NULL, AV_LOG_WARNING,
+ av_log(s, AV_LOG_WARNING,
"The tags at index %d refer to a "
"non-existent attachment %"PRId64".\n",
i, tags[i].target.attachuid);
@@ -1792,7 +1793,7 @@ static void matroska_convert_tags(AVFormatContext *s)
}
}
if (!found) {
- av_log(NULL, AV_LOG_WARNING,
+ av_log(s, AV_LOG_WARNING,
"The tags at index %d refer to a non-existent chapter "
"%"PRId64".\n",
i, tags[i].target.chapteruid);
@@ -1809,7 +1810,7 @@ static void matroska_convert_tags(AVFormatContext *s)
}
}
if (!found) {
- av_log(NULL, AV_LOG_WARNING,
+ av_log(s, AV_LOG_WARNING,
"The tags at index %d refer to a non-existent track "
"%"PRId64".\n",
i, tags[i].target.trackuid);
@@ -1869,8 +1870,12 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
MatroskaSeekhead *seekheads = seekhead_list->elem;
uint32_t id = seekheads[i].id;
int64_t pos = seekheads[i].pos + matroska->segment_start;
+ MatroskaLevel1Element *elem;
+
+ if (id != seekheads[i].id || pos < matroska->segment_start)
+ continue;
- MatroskaLevel1Element *elem = matroska_find_level1_elem(matroska, id);
+ elem = matroska_find_level1_elem(matroska, id, pos);
if (!elem || elem->parsed)
continue;
@@ -2026,12 +2031,12 @@ static int matroska_parse_flac(AVFormatContext *s,
static int mkv_field_order(MatroskaDemuxContext *matroska, int64_t field_order)
{
- int major, minor, micro, bttb = 0;
+ int minor, micro, bttb = 0;
/* workaround a bug in our Matroska muxer, introduced in version 57.36 alongside
* this function, and fixed in 57.52 */
- if (matroska->muxingapp && sscanf(matroska->muxingapp, "Lavf%d.%d.%d", &major, &minor, &micro) == 3)
- bttb = (major == 57 && minor >= 36 && minor <= 51 && micro >= 100);
+ if (matroska->muxingapp && sscanf(matroska->muxingapp, "Lavf57.%d.%d", &minor, &micro) == 2)
+ bttb = (minor >= 36 && minor <= 51 && micro >= 100);
switch (field_order) {
case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE:
@@ -2157,42 +2162,40 @@ static int mkv_parse_video_color(AVStream *st, const MatroskaTrack *track) {
return 0;
}
-static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) {
+static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track,
+ void *logctx)
+{
AVSphericalMapping *spherical;
+ const MatroskaTrackVideoProjection *mkv_projection = &track->video.projection;
+ const uint8_t *priv_data = mkv_projection->private.data;
enum AVSphericalProjection projection;
size_t spherical_size;
uint32_t l = 0, t = 0, r = 0, b = 0;
uint32_t padding = 0;
int ret;
- GetByteContext gb;
- bytestream2_init(&gb, track->video.projection.private.data,
- track->video.projection.private.size);
-
- if (bytestream2_get_byte(&gb) != 0) {
- av_log(NULL, AV_LOG_WARNING, "Unknown spherical metadata\n");
+ if (mkv_projection->private.size && priv_data[0] != 0) {
+ av_log(logctx, AV_LOG_WARNING, "Unknown spherical metadata\n");
return 0;
}
- bytestream2_skip(&gb, 3); // flags
-
switch (track->video.projection.type) {
case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR:
if (track->video.projection.private.size == 20) {
- t = bytestream2_get_be32(&gb);
- b = bytestream2_get_be32(&gb);
- l = bytestream2_get_be32(&gb);
- r = bytestream2_get_be32(&gb);
+ t = AV_RB32(priv_data + 4);
+ b = AV_RB32(priv_data + 8);
+ l = AV_RB32(priv_data + 12);
+ r = AV_RB32(priv_data + 16);
if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
- av_log(NULL, AV_LOG_ERROR,
+ av_log(logctx, AV_LOG_ERROR,
"Invalid bounding rectangle coordinates "
"%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n",
l, t, r, b);
return AVERROR_INVALIDDATA;
}
} else if (track->video.projection.private.size != 0) {
- av_log(NULL, AV_LOG_ERROR, "Unknown spherical metadata\n");
+ av_log(logctx, AV_LOG_ERROR, "Unknown spherical metadata\n");
return AVERROR_INVALIDDATA;
}
@@ -2203,19 +2206,19 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track)
break;
case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP:
if (track->video.projection.private.size < 4) {
- av_log(NULL, AV_LOG_ERROR, "Missing projection private properties\n");
+ av_log(logctx, AV_LOG_ERROR, "Missing projection private properties\n");
return AVERROR_INVALIDDATA;
} else if (track->video.projection.private.size == 12) {
- uint32_t layout = bytestream2_get_be32(&gb);
+ uint32_t layout = AV_RB32(priv_data + 4);
if (layout) {
- av_log(NULL, AV_LOG_WARNING,
+ av_log(logctx, AV_LOG_WARNING,
"Unknown spherical cubemap layout %"PRIu32"\n", layout);
return 0;
}
projection = AV_SPHERICAL_CUBEMAP;
- padding = bytestream2_get_be32(&gb);
+ padding = AV_RB32(priv_data + 8);
} else {
- av_log(NULL, AV_LOG_ERROR, "Unknown spherical metadata\n");
+ av_log(logctx, AV_LOG_ERROR, "Unknown spherical metadata\n");
return AVERROR_INVALIDDATA;
}
break;
@@ -2223,7 +2226,7 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track)
/* No Spherical metadata */
return 0;
default:
- av_log(NULL, AV_LOG_WARNING,
+ av_log(logctx, AV_LOG_WARNING,
"Unknown spherical metadata type %"PRIu64"\n",
track->video.projection.type);
return 0;
@@ -2409,6 +2412,11 @@ static int matroska_parse_tracks(AVFormatContext *s)
}
}
}
+ track->needs_decoding = encodings && !encodings[0].type &&
+ encodings[0].scope & 1 &&
+ (encodings[0].compression.algo !=
+ MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP ||
+ encodings[0].compression.settings.size);
for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
if (!strncmp(ff_mkv_codec_tags[j].str, track->codec_id,
@@ -2611,28 +2619,34 @@ static int matroska_parse_tracks(AVFormatContext *s)
track->audio.sub_packet_h = avio_rb16(&b);
track->audio.frame_size = avio_rb16(&b);
track->audio.sub_packet_size = avio_rb16(&b);
- if (flavor < 0 ||
- track->audio.coded_framesize <= 0 ||
+ if (track->audio.coded_framesize <= 0 ||
track->audio.sub_packet_h <= 0 ||
- track->audio.frame_size <= 0 ||
- track->audio.sub_packet_size <= 0 && codec_id != AV_CODEC_ID_SIPR)
+ track->audio.frame_size <= 0)
return AVERROR_INVALIDDATA;
- track->audio.buf = av_malloc_array(track->audio.sub_packet_h,
- track->audio.frame_size);
- if (!track->audio.buf)
- return AVERROR(ENOMEM);
+
if (codec_id == AV_CODEC_ID_RA_288) {
+ if (track->audio.sub_packet_h & 1 || 2 * track->audio.frame_size
+ != (int64_t)track->audio.sub_packet_h * track->audio.coded_framesize)
+ return AVERROR_INVALIDDATA;
st->codecpar->block_align = track->audio.coded_framesize;
track->codec_priv.size = 0;
} else {
- if (codec_id == AV_CODEC_ID_SIPR && flavor < 4) {
+ if (codec_id == AV_CODEC_ID_SIPR) {
static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
+ if (flavor > 3)
+ return AVERROR_INVALIDDATA;
track->audio.sub_packet_size = ff_sipr_subpk_size[flavor];
st->codecpar->bit_rate = sipr_bit_rate[flavor];
- }
+ } else if (track->audio.sub_packet_size <= 0 ||
+ track->audio.frame_size % track->audio.sub_packet_size)
+ return AVERROR_INVALIDDATA;
st->codecpar->block_align = track->audio.sub_packet_size;
extradata_offset = 78;
}
+ track->audio.buf = av_malloc_array(track->audio.sub_packet_h,
+ track->audio.frame_size);
+ if (!track->audio.buf)
+ return AVERROR(ENOMEM);
#else
return AVERROR_INVALIDDATA;
#endif
@@ -2772,7 +2786,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
ret = mkv_parse_video_color(st, track);
if (ret < 0)
return ret;
- ret = mkv_parse_video_projection(st, track);
+ ret = mkv_parse_video_projection(st, track, matroska->ctx);
if (ret < 0)
return ret;
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
@@ -2907,6 +2921,8 @@ static int matroska_read_header(AVFormatContext *s)
break;
av_dict_set(&st->metadata, "filename", attachments[j].filename, 0);
av_dict_set(&st->metadata, "mimetype", attachments[j].mime, 0);
+ if (attachments[j].description)
+ av_dict_set(&st->metadata, "title", attachments[j].description, 0);
st->codecpar->codec_id = AV_CODEC_ID_NONE;
for (i = 0; mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
@@ -2926,9 +2942,8 @@ static int matroska_read_header(AVFormatContext *s)
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
av_init_packet(pkt);
- pkt->buf = av_buffer_ref(attachments[j].bin.buf);
- if (!pkt->buf)
- return AVERROR(ENOMEM);
+ pkt->buf = attachments[j].bin.buf;
+ attachments[j].bin.buf = NULL;
pkt->data = attachments[j].bin.data;
pkt->size = attachments[j].bin.size;
pkt->stream_index = st->index;
@@ -3022,10 +3037,12 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
return 0;
}
- av_assert0(size > 0);
- *laces = *data + 1;
- data += 1;
- size -= 1;
+ if (size <= 0)
+ return AVERROR_INVALIDDATA;
+
+ *laces = *data + 1;
+ data += 1;
+ size -= 1;
switch (type) {
case 0x1: /* Xiph lacing */
@@ -3035,31 +3052,26 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
for (n = 0; n < *laces - 1; n++) {
lace_size[n] = 0;
- while (1) {
- if (size <= total) {
+ do {
+ if (size <= total)
return AVERROR_INVALIDDATA;
- }
temp = *data;
total += temp;
lace_size[n] += temp;
data += 1;
size -= 1;
- if (temp != 0xff)
- break;
- }
+ } while (temp == 0xff);
}
- if (size <= total) {
+ if (size < total)
return AVERROR_INVALIDDATA;
- }
lace_size[n] = size - total;
break;
}
case 0x2: /* fixed-size lacing */
- if (size % (*laces)) {
+ if (size % (*laces))
return AVERROR_INVALIDDATA;
- }
for (n = 0; n < *laces; n++)
lace_size[n] = size / *laces;
break;
@@ -3095,15 +3107,15 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
}
data += offset;
size -= offset;
- if (size <= total) {
+ if (size < total)
return AVERROR_INVALIDDATA;
- }
+
lace_size[*laces - 1] = size - total;
break;
}
}
- *buf = data;
+ *buf = data;
return 0;
}
@@ -3113,12 +3125,12 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
uint8_t *data, int size, uint64_t timecode,
int64_t pos)
{
- int a = st->codecpar->block_align;
- int sps = track->audio.sub_packet_size;
- int cfs = track->audio.coded_framesize;
- int h = track->audio.sub_packet_h;
+ const int a = st->codecpar->block_align;
+ const int sps = track->audio.sub_packet_size;
+ const int cfs = track->audio.coded_framesize;
+ const int h = track->audio.sub_packet_h;
+ const int w = track->audio.frame_size;
int y = track->audio.sub_packet_cnt;
- int w = track->audio.frame_size;
int x;
if (!track->audio.pkt_cnt) {
@@ -3141,7 +3153,7 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
}
memcpy(track->audio.buf + y * w, data, w);
} else {
- if (size < sps * w / sps || h<=0 || w%sps) {
+ if (size < w) {
av_log(matroska->ctx, AV_LOG_ERROR,
"Corrupt generic RM-style audio packet size\n");
return AVERROR_INVALIDDATA;
@@ -3191,10 +3203,11 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
}
/* reconstruct full wavpack blocks from mangled matroska ones */
-static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src,
- uint8_t **pdst, int *size)
+static int matroska_parse_wavpack(MatroskaTrack *track,
+ uint8_t **data, int *size)
{
uint8_t *dst = NULL;
+ uint8_t *src = *data;
int dstlen = 0;
int srclen = *size;
uint32_t samples;
@@ -3264,7 +3277,7 @@ static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src,
memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- *pdst = dst;
+ *data = dst;
*size = dstlen;
return 0;
@@ -3274,22 +3287,22 @@ fail:
return ret;
}
-static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src,
- uint8_t **pdst, int *size)
+static int matroska_parse_prores(MatroskaTrack *track,
+ uint8_t **data, int *size)
{
uint8_t *dst;
int dstlen = *size + 8;
- dst = av_malloc(dstlen + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!dst)
- return AVERROR(ENOMEM);
+ dst = av_malloc(dstlen + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!dst)
+ return AVERROR(ENOMEM);
- AV_WB32(dst, dstlen);
- AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f'));
- memcpy(dst + 8, src, dstlen - 8);
- memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ AV_WB32(dst, dstlen);
+ AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f'));
+ memcpy(dst + 8, *data, dstlen - 8);
+ memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- *pdst = dst;
+ *data = dst;
*size = dstlen;
return 0;
@@ -3418,46 +3431,40 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
uint8_t *additional, uint64_t additional_id, int additional_size,
int64_t discard_padding)
{
- MatroskaTrackEncoding *encodings = track->encodings.elem;
uint8_t *pkt_data = data;
- int res;
+ int res = 0;
AVPacket pktl, *pkt = &pktl;
- if (encodings && !encodings->type && encodings->scope & 1) {
- res = matroska_decode_buffer(&pkt_data, &pkt_size, track);
- if (res < 0)
- return res;
- }
-
if (st->codecpar->codec_id == AV_CODEC_ID_WAVPACK) {
- uint8_t *wv_data;
- res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size);
+ res = matroska_parse_wavpack(track, &pkt_data, &pkt_size);
if (res < 0) {
av_log(matroska->ctx, AV_LOG_ERROR,
"Error parsing a wavpack block.\n");
goto fail;
}
- if (pkt_data != data)
- av_freep(&pkt_data);
- pkt_data = wv_data;
+ if (!buf)
+ av_freep(&data);
+ buf = NULL;
}
if (st->codecpar->codec_id == AV_CODEC_ID_PRORES &&
AV_RB32(pkt_data + 4) != MKBETAG('i', 'c', 'p', 'f')) {
- uint8_t *pr_data;
- res = matroska_parse_prores(track, pkt_data, &pr_data, &pkt_size);
+ res = matroska_parse_prores(track, &pkt_data, &pkt_size);
if (res < 0) {
av_log(matroska->ctx, AV_LOG_ERROR,
"Error parsing a prores block.\n");
goto fail;
}
- if (pkt_data != data)
- av_freep(&pkt_data);
- pkt_data = pr_data;
+ if (!buf)
+ av_freep(&data);
+ buf = NULL;
}
+ if (!pkt_size && !additional_size)
+ goto no_output;
+
av_init_packet(pkt);
- if (pkt_data != data)
+ if (!buf)
pkt->buf = av_buffer_create(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE,
NULL, NULL, 0);
else
@@ -3526,9 +3533,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
return 0;
+no_output:
fail:
- if (pkt_data != data)
- av_freep(&pkt_data);
+ if (!buf)
+ av_free(pkt_data);
return res;
}
@@ -3557,16 +3565,20 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf
size -= n;
track = matroska_find_track_by_num(matroska, num);
- if (!track || !track->stream) {
- av_log(matroska->ctx, AV_LOG_INFO,
- "Invalid stream %"PRIu64"\n", num);
+ if (!track || size < 3)
return AVERROR_INVALIDDATA;
- } else if (size <= 3)
+
+ if (!(st = track->stream)) {
+ av_log(matroska->ctx, AV_LOG_VERBOSE,
+ "No stream associated to TrackNumber %"PRIu64". "
+ "Ignoring Block with this TrackNumber.\n", num);
return 0;
- st = track->stream;
+ }
+
if (st->discard >= AVDISCARD_ALL)
return res;
- av_assert1(block_duration != AV_NOPTS_VALUE);
+ if (block_duration > INT64_MAX)
+ block_duration = INT64_MAX;
block_time = sign_extend(AV_RB16(data), 16);
data += 2;
@@ -3627,33 +3639,41 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf
for (n = 0; n < laces; n++) {
int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces;
+ uint8_t *out_data = data;
+ int out_size = lace_size[n];
- if ((st->codecpar->codec_id == AV_CODEC_ID_RA_288 ||
- st->codecpar->codec_id == AV_CODEC_ID_COOK ||
- st->codecpar->codec_id == AV_CODEC_ID_SIPR ||
- st->codecpar->codec_id == AV_CODEC_ID_ATRAC3) &&
- st->codecpar->block_align && track->audio.sub_packet_size) {
-#if CONFIG_RA_288_DECODER || CONFIG_COOK_DECODER || CONFIG_ATRAC3_DECODER || CONFIG_SIPR_DECODER
- res = matroska_parse_rm_audio(matroska, track, st, data,
- lace_size[n],
+ if (track->needs_decoding) {
+ res = matroska_decode_buffer(&out_data, &out_size, track);
+ if (res < 0)
+ return res;
+ /* Given that we are here means that out_data is no longer
+ * owned by buf, so set it to NULL. This depends upon
+ * zero-length header removal compression being ignored. */
+ av_assert1(out_data != data);
+ buf = NULL;
+ }
+
+ if (track->audio.buf) {
+ res = matroska_parse_rm_audio(matroska, track, st,
+ out_data, out_size,
timecode, pos);
-#else
- res = AVERROR_INVALIDDATA;
-#endif
+ if (!buf)
+ av_free(out_data);
if (res)
return res;
-
} else if (st->codecpar->codec_id == AV_CODEC_ID_WEBVTT) {
res = matroska_parse_webvtt(matroska, track, st,
- data, lace_size[n],
+ out_data, out_size,
timecode, lace_duration,
pos);
+ if (!buf)
+ av_free(out_data);
if (res)
return res;
} else {
- res = matroska_parse_frame(matroska, track, st, buf, data, lace_size[n],
- timecode, lace_duration, pos,
- !n ? is_keyframe : 0,
+ res = matroska_parse_frame(matroska, track, st, buf, out_data,
+ out_size, timecode, lace_duration,
+ pos, !n ? is_keyframe : 0,
additional, additional_id, additional_size,
discard_padding);
if (res)
@@ -4170,15 +4190,18 @@ static int webm_dash_manifest_read_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "Failed to read file headers\n");
return -1;
}
- if (!s->nb_streams) {
- matroska_read_close(s);
- av_log(s, AV_LOG_ERROR, "No streams found\n");
- return AVERROR_INVALIDDATA;
+ if (!matroska->tracks.nb_elem || !s->nb_streams) {
+ av_log(s, AV_LOG_ERROR, "No track found\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
}
if (!matroska->is_live) {
buf = av_asprintf("%g", matroska->duration);
- if (!buf) return AVERROR(ENOMEM);
+ if (!buf) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
av_dict_set(&s->streams[0]->metadata, DURATION,
buf, AV_DICT_DONT_STRDUP_VAL);
@@ -4201,7 +4224,7 @@ static int webm_dash_manifest_read_header(AVFormatContext *s)
ret = webm_dash_manifest_cues(s, init_range);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Error parsing Cues\n");
- return ret;
+ goto fail;
}
}
@@ -4211,6 +4234,9 @@ static int webm_dash_manifest_read_header(AVFormatContext *s)
matroska->bandwidth, 0);
}
return 0;
+fail:
+ matroska_read_close(s);
+ return ret;
}
static int webm_dash_manifest_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
index 784973a9515..233c472b8f3 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
@@ -55,8 +55,11 @@
#include "libavcodec/mpeg4audio.h"
/* Level 1 elements we create a SeekHead entry for:
- * Info, Tracks, Chapters, Attachments, Tags and Cues */
-#define MAX_SEEKHEAD_ENTRIES 6
+ * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */
+#define MAX_SEEKHEAD_ENTRIES 7
+
+#define IS_SEEKABLE(pb, mkv) (((pb)->seekable & AVIO_SEEKABLE_NORMAL) && \
+ !(mkv)->is_live)
enum {
DEFAULT_MODE_INFER,
@@ -69,6 +72,11 @@ typedef struct ebml_master {
int sizebytes; ///< how many bytes were reserved for the size
} ebml_master;
+typedef struct ebml_stored_master {
+ AVIOContext *bc;
+ int64_t pos;
+} ebml_stored_master;
+
typedef struct mkv_seekhead_entry {
uint32_t elementid;
uint64_t segmentpos;
@@ -90,7 +98,7 @@ typedef struct mkv_cuepoint {
} mkv_cuepoint;
typedef struct mkv_cues {
- mkv_cuepoint *entries;
+ mkv_cuepoint *entries;
int num_entries;
} mkv_cues;
@@ -113,46 +121,43 @@ typedef struct mkv_track {
#define MODE_WEBM 0x02
typedef struct MatroskaMuxContext {
- const AVClass *class;
- int mode;
- AVIOContext *tags_bc;
- int64_t tags_pos;
- AVIOContext *info_bc;
- int64_t info_pos;
- AVIOContext *tracks_bc;
- int64_t tracks_pos;
- ebml_master segment;
- int64_t segment_offset;
- AVIOContext *cluster_bc;
- int64_t cluster_pos; ///< file offset of the current cluster
- int64_t cluster_pts;
- int64_t duration_offset;
- int64_t duration;
- mkv_seekhead seekhead;
- mkv_cues cues;
- mkv_track *tracks;
-
- AVPacket cur_audio_pkt;
-
- unsigned nb_attachments;
- int have_video;
-
- int reserve_cues_space;
- int cluster_size_limit;
- int64_t cues_pos;
- int64_t cluster_time_limit;
- int is_dash;
- int dash_track_number;
- int is_live;
- int write_crc;
-
- uint32_t chapter_id_offset;
- int wrote_chapters;
-
- int allow_raw_vfw;
- int default_mode;
-
- uint32_t segment_uid[4];
+ const AVClass *class;
+ int mode;
+ ebml_stored_master info;
+ ebml_stored_master track;
+ ebml_stored_master tags;
+ int64_t segment_offset;
+ AVIOContext *cluster_bc;
+ int64_t cluster_pos; ///< file offset of the current Cluster
+ int64_t cluster_pts;
+ int64_t duration_offset;
+ int64_t duration;
+ mkv_track *tracks;
+ mkv_seekhead seekhead;
+ mkv_cues cues;
+ int64_t cues_pos;
+
+ AVPacket cur_audio_pkt;
+
+ unsigned nb_attachments;
+ int have_video;
+
+ int wrote_chapters;
+ int wrote_tags;
+
+ int reserve_cues_space;
+ int cluster_size_limit;
+ int64_t cluster_time_limit;
+ int write_crc;
+ int is_live;
+
+ int is_dash;
+ int dash_track_number;
+ int allow_raw_vfw;
+ int flipped_raw_rgb;
+ int default_mode;
+
+ uint32_t segment_uid[4];
} MatroskaMuxContext;
/** 2 bytes * 7 for EBML IDs, 7 1-byte EBML lengths, 6 1-byte uint,
@@ -349,6 +354,17 @@ static void end_ebml_master(AVIOContext *pb, ebml_master master)
avio_seek(pb, pos, SEEK_SET);
}
+static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid,
+ uint64_t filepos)
+{
+ mkv_seekhead *seekhead = &mkv->seekhead;
+
+ av_assert1(seekhead->num_entries < MAX_SEEKHEAD_ENTRIES);
+
+ seekhead->entries[seekhead->num_entries].elementid = elementid;
+ seekhead->entries[seekhead->num_entries++].segmentpos = filepos - mkv->segment_offset;
+}
+
static int start_ebml_master_crc32(AVIOContext **dyn_cp, MatroskaMuxContext *mkv)
{
int ret;
@@ -362,15 +378,22 @@ static int start_ebml_master_crc32(AVIOContext **dyn_cp, MatroskaMuxContext *mkv
return 0;
}
-static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp,
- MatroskaMuxContext *mkv, uint32_t id,
- int length_size, int keep_buffer)
+static int end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp,
+ MatroskaMuxContext *mkv, uint32_t id,
+ int length_size, int keep_buffer,
+ int add_seekentry)
{
uint8_t *buf, crc[4];
- int size, skip = 0;
+ int ret, size, skip = 0;
- put_ebml_id(pb, id);
size = avio_get_dyn_buf(*dyn_cp, &buf);
+ if ((ret = (*dyn_cp)->error) < 0)
+ goto fail;
+
+ if (add_seekentry)
+ mkv_add_seekhead_entry(mkv, id, avio_tell(pb));
+
+ put_ebml_id(pb, id);
put_ebml_length(pb, size, length_size);
if (mkv->write_crc) {
skip = 6; /* Skip reserved 6-byte long void element from the dynamic buffer. */
@@ -379,27 +402,40 @@ static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp,
}
avio_write(pb, buf + skip, size - skip);
+fail:
if (keep_buffer) {
ffio_reset_dyn_buf(*dyn_cp);
} else {
ffio_free_dyn_buf(dyn_cp);
}
+ return ret;
}
/**
-* Complete ebml master without destroying the buffer, allowing for later updates
-*/
-static void end_ebml_master_crc32_preliminary(AVIOContext *pb, AVIOContext *dyn_cp,
- uint32_t id, int64_t *pos)
+ * Output EBML master. Keep the buffer if seekable, allowing for later updates.
+ * Furthermore always add a SeekHead Entry for this element.
+ */
+static int end_ebml_master_crc32_tentatively(AVIOContext *pb,
+ ebml_stored_master *elem,
+ MatroskaMuxContext *mkv, uint32_t id)
{
- uint8_t *buf;
- int size = avio_get_dyn_buf(dyn_cp, &buf);
+ if (IS_SEEKABLE(pb, mkv)) {
+ uint8_t *buf;
+ int size = avio_get_dyn_buf(elem->bc, &buf);
- *pos = avio_tell(pb);
+ if (elem->bc->error < 0)
+ return elem->bc->error;
- put_ebml_id(pb, id);
- put_ebml_length(pb, size, 0);
- avio_write(pb, buf, size);
+ elem->pos = avio_tell(pb);
+ mkv_add_seekhead_entry(mkv, id, elem->pos);
+
+ put_ebml_id(pb, id);
+ put_ebml_length(pb, size, 0);
+ avio_write(pb, buf, size);
+
+ return 0;
+ } else
+ return end_ebml_master_crc32(pb, &elem->bc, mkv, id, 0, 0, 1);
}
static void put_xiph_size(AVIOContext *pb, int size)
@@ -418,9 +454,9 @@ static void mkv_deinit(AVFormatContext *s)
av_packet_unref(&mkv->cur_audio_pkt);
ffio_free_dyn_buf(&mkv->cluster_bc);
- ffio_free_dyn_buf(&mkv->info_bc);
- ffio_free_dyn_buf(&mkv->tracks_bc);
- ffio_free_dyn_buf(&mkv->tags_bc);
+ ffio_free_dyn_buf(&mkv->info.bc);
+ ffio_free_dyn_buf(&mkv->track.bc);
+ ffio_free_dyn_buf(&mkv->tags.bc);
av_freep(&mkv->cues.entries);
av_freep(&mkv->tracks);
@@ -441,17 +477,6 @@ static void mkv_start_seekhead(MatroskaMuxContext *mkv, AVIOContext *pb)
put_ebml_void(pb, mkv->seekhead.reserved_size);
}
-static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid,
- uint64_t filepos)
-{
- mkv_seekhead *seekhead = &mkv->seekhead;
-
- av_assert1(seekhead->num_entries < MAX_SEEKHEAD_ENTRIES);
-
- seekhead->entries[seekhead->num_entries].elementid = elementid;
- seekhead->entries[seekhead->num_entries++].segmentpos = filepos - mkv->segment_offset;
-}
-
/**
* Write the SeekHead to the file at the location reserved for it
* and seek to destpos afterwards. When error_on_seek_failure
@@ -489,7 +514,10 @@ static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv,
put_ebml_uint(dyn_cp, MATROSKA_ID_SEEKPOSITION, entry->segmentpos);
end_ebml_master(dyn_cp, seekentry);
}
- end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD, 0, 0);
+ ret = end_ebml_master_crc32(pb, &dyn_cp, mkv,
+ MATROSKA_ID_SEEKHEAD, 0, 0, 0);
+ if (ret < 0)
+ return ret;
remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
put_ebml_void(pb, remaining);
@@ -562,12 +590,14 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp,
end_ebml_master(cuepoint, track_positions);
} while (++entry < end && entry->pts == pts);
size = avio_get_dyn_buf(cuepoint, &buf);
+ if ((ret = cuepoint->error) < 0)
+ break;
put_ebml_binary(dyn_cp, MATROSKA_ID_POINTENTRY, buf, size);
ffio_reset_dyn_buf(cuepoint);
}
ffio_free_dyn_buf(&cuepoint);
- return 0;
+ return ret;
}
static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb,
@@ -576,17 +606,18 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb,
const uint8_t *header_start[3];
int header_len[3];
int first_header_size;
- int j;
+ int err, j;
if (par->codec_id == AV_CODEC_ID_VORBIS)
first_header_size = 30;
else
first_header_size = 42;
- if (avpriv_split_xiph_headers(par->extradata, par->extradata_size,
- first_header_size, header_start, header_len) < 0) {
+ err = avpriv_split_xiph_headers(par->extradata, par->extradata_size,
+ first_header_size, header_start, header_len);
+ if (err < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
- return -1;
+ return err;
}
avio_w8(pb, 2); // number packets - 1
@@ -624,42 +655,29 @@ static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb,
const char *vendor = (s->flags & AVFMT_FLAG_BITEXACT) ?
"Lavf" : LIBAVFORMAT_IDENT;
AVDictionary *dict = NULL;
- uint8_t buf[32], *data, *p;
+ uint8_t buf[32];
int64_t len;
snprintf(buf, sizeof(buf), "0x%"PRIx64, par->channel_layout);
av_dict_set(&dict, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", buf, 0);
len = ff_vorbiscomment_length(dict, vendor, NULL, 0);
- if (len >= (1 << 24) - 4) {
- av_dict_free(&dict);
- return AVERROR(EINVAL);
- }
-
- data = av_malloc(len + 4);
- if (!data) {
- av_dict_free(&dict);
- return AVERROR(ENOMEM);
- }
-
- data[0] = 0x84;
- AV_WB24(data + 1, len);
+ av_assert1(len < (1 << 24) - 4);
- p = data + 4;
- ff_vorbiscomment_write(&p, &dict, vendor, NULL, 0);
+ avio_w8(pb, 0x84);
+ avio_wb24(pb, len);
- avio_write(pb, data, len + 4);
+ ff_vorbiscomment_write(pb, dict, vendor, NULL, 0);
- av_freep(&data);
av_dict_free(&dict);
}
return 0;
}
-static int get_aac_sample_rates(AVFormatContext *s, const uint8_t *extradata,
- int extradata_size, int *sample_rate,
- int *output_sample_rate)
+static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv,
+ const uint8_t *extradata, int extradata_size,
+ int *sample_rate, int *output_sample_rate)
{
MPEG4AudioConfig mp4ac;
int ret;
@@ -670,7 +688,7 @@ static int get_aac_sample_rates(AVFormatContext *s, const uint8_t *extradata,
* first packet.
* Abort however if s->pb is not seekable, as we would not be able to seek back
* to write the sample rate elements once the extradata shows up, anyway. */
- if (ret < 0 && (extradata_size || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL))) {
+ if (ret < 0 && (extradata_size || !IS_SEEKABLE(s->pb, mkv))) {
av_log(s, AV_LOG_ERROR,
"Error parsing AAC extradata, unable to determine samplerate.\n");
return AVERROR(EINVAL);
@@ -747,6 +765,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
int native_id, int qt_id)
{
AVIOContext *dyn_cp;
+ MatroskaMuxContext *mkv = s->priv_data;
uint8_t *codecpriv;
int ret, codecpriv_size;
@@ -785,7 +804,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
ret = AVERROR(EINVAL);
}
- ff_put_bmp_header(dyn_cp, par, 0, 0);
+ ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb);
}
} else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
unsigned int tag;
@@ -801,26 +820,28 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
ff_put_wav_header(s, dyn_cp, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX);
}
- codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv);
- if (codecpriv_size)
- put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv,
- codecpriv_size);
+ if (ret >= 0) {
+ codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv);
+ if ((ret = dyn_cp->error) >= 0 && codecpriv_size)
+ put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv,
+ codecpriv_size);
+ }
ffio_free_dyn_buf(&dyn_cp);
return ret;
}
-static int mkv_write_video_color(AVIOContext *pb, const AVCodecParameters *par,
- const AVStream *st)
+static void mkv_write_video_color(AVIOContext *pb, const AVStream *st,
+ const AVCodecParameters *par)
{
- AVIOContext *dyn_cp;
- uint8_t *colorinfo_ptr;
- int side_data_size = 0;
- int ret, colorinfo_size;
- const uint8_t *side_data;
+ /* 18 Elements with two bytes ID, one byte length field, 8 bytes payload
+ * a master element with two bytes ID and one byte length field
+ * plus another byte to stay clear of the end. */
+ uint8_t colour[(2 + 1 + 8) * 18 + (2 + 1) + 1];
+ AVIOContext buf, *dyn_cp = &buf;
+ int colorinfo_size;
+ const void *side_data;
- ret = avio_open_dyn_buf(&dyn_cp);
- if (ret < 0)
- return ret;
+ ffio_init_context(dyn_cp, colour, sizeof(colour), 1, NULL, NULL, NULL, NULL);
if (par->color_trc != AVCOL_TRC_UNSPECIFIED &&
par->color_trc < AVCOL_TRC_NB) {
@@ -849,21 +870,19 @@ static int mkv_write_video_color(AVIOContext *pb, const AVCodecParameters *par,
}
side_data = av_stream_get_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
- &side_data_size);
- if (side_data_size) {
- const AVContentLightMetadata *metadata =
- (const AVContentLightMetadata*)side_data;
+ NULL);
+ if (side_data) {
+ const AVContentLightMetadata *metadata = side_data;
put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORMAXCLL, metadata->MaxCLL);
put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORMAXFALL, metadata->MaxFALL);
}
side_data = av_stream_get_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
- &side_data_size);
- if (side_data_size == sizeof(AVMasteringDisplayMetadata)) {
+ NULL);
+ if (side_data) {
ebml_master meta_element = start_ebml_master(
dyn_cp, MATROSKA_ID_VIDEOCOLORMASTERINGMETA, 10 * (2 + 1 + 8));
- const AVMasteringDisplayMetadata *metadata =
- (const AVMasteringDisplayMetadata*)side_data;
+ const AVMasteringDisplayMetadata *metadata = side_data;
if (metadata->has_primaries) {
put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_RX,
av_q2d(metadata->display_primaries[0][0]));
@@ -891,35 +910,29 @@ static int mkv_write_video_color(AVIOContext *pb, const AVCodecParameters *par,
end_ebml_master(dyn_cp, meta_element);
}
- colorinfo_size = avio_get_dyn_buf(dyn_cp, &colorinfo_ptr);
- if (colorinfo_size) {
- ebml_master colorinfo = start_ebml_master(pb, MATROSKA_ID_VIDEOCOLOR, colorinfo_size);
- avio_write(pb, colorinfo_ptr, colorinfo_size);
- end_ebml_master(pb, colorinfo);
- }
- ffio_free_dyn_buf(&dyn_cp);
- return 0;
+ colorinfo_size = avio_tell(dyn_cp);
+ if (colorinfo_size)
+ put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLOR, colour, colorinfo_size);
}
-static int mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb,
- const AVStream *st)
+static void mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb,
+ const AVStream *st)
{
ebml_master projection;
- int side_data_size = 0;
uint8_t private[20];
const AVSphericalMapping *spherical =
(const AVSphericalMapping *)av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL,
- &side_data_size);
+ NULL);
- if (!side_data_size)
- return 0;
+ if (!spherical)
+ return;
if (spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
spherical->projection != AV_SPHERICAL_CUBEMAP) {
av_log(s, AV_LOG_WARNING, "Unknown projection type\n");
- return 0;
+ return;
}
// Maximally 4 8-byte elements with id-length 2 + 1 byte length field
@@ -967,8 +980,6 @@ static int mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb,
(double) spherical->roll / (1 << 16));
end_ebml_master(pb, projection);
-
- return 0;
}
static void mkv_write_field_order(AVIOContext *pb, int mode,
@@ -1013,10 +1024,9 @@ static void mkv_write_field_order(AVIOContext *pb, int mode,
static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
AVStream *st, int mode, int *h_width, int *h_height)
{
- int i;
- int ret = 0;
const AVDictionaryEntry *tag;
MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
+ const AVStereo3D *stereo;
*h_width = 1;
*h_height = 1;
@@ -1025,7 +1035,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
(tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
int stereo_mode = atoi(tag->value);
- for (i=0; i<MATROSKA_VIDEO_STEREOMODE_TYPE_NB; i++)
+ for (int i = 0; i < MATROSKA_VIDEO_STEREOMODE_TYPE_NB; i++)
if (!strcmp(tag->value, ff_matroska_video_stereo_mode[i])){
stereo_mode = i;
break;
@@ -1039,57 +1049,52 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
}
}
- // iterate to find the stereo3d side data
- for (i = 0; i < st->nb_side_data; i++) {
- AVPacketSideData sd = st->side_data[i];
- if (sd.type == AV_PKT_DATA_STEREO3D) {
- AVStereo3D *stereo = (AVStereo3D *)sd.data;
-
- switch (stereo->type) {
- case AV_STEREO3D_2D:
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_MONO;
- break;
- case AV_STEREO3D_SIDEBYSIDE:
- format = (stereo->flags & AV_STEREO3D_FLAG_INVERT)
- ? MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT
- : MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT;
- *h_width = 2;
- break;
- case AV_STEREO3D_TOPBOTTOM:
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM;
- if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
- format--;
- *h_height = 2;
- break;
- case AV_STEREO3D_CHECKERBOARD:
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR;
- if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
- format--;
- break;
- case AV_STEREO3D_LINES:
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR;
- if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
- format--;
- *h_height = 2;
- break;
- case AV_STEREO3D_COLUMNS:
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR;
- if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
- format--;
- *h_width = 2;
- break;
- case AV_STEREO3D_FRAMESEQUENCE:
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR;
- if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
- format++;
- break;
- }
+ stereo = (const AVStereo3D*)av_stream_get_side_data(st, AV_PKT_DATA_STEREO3D,
+ NULL);
+ if (stereo) {
+ switch (stereo->type) {
+ case AV_STEREO3D_2D:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_MONO;
+ break;
+ case AV_STEREO3D_SIDEBYSIDE:
+ format = (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ ? MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT
+ : MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT;
+ *h_width = 2;
+ break;
+ case AV_STEREO3D_TOPBOTTOM:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ *h_height = 2;
+ break;
+ case AV_STEREO3D_CHECKERBOARD:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ break;
+ case AV_STEREO3D_LINES:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ *h_height = 2;
+ break;
+ case AV_STEREO3D_COLUMNS:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ *h_width = 2;
+ break;
+ case AV_STEREO3D_FRAMESEQUENCE:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format++;
break;
}
}
if (format == MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
- return ret;
+ return 0;
// if webm, do not write unsupported modes
if ((mode == MODE_WEBM &&
@@ -1098,14 +1103,13 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
|| format >= MATROSKA_VIDEO_STEREOMODE_TYPE_NB) {
av_log(s, AV_LOG_ERROR,
"The specified stereo mode is not valid.\n");
- format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
return AVERROR(EINVAL);
}
// write StereoMode if format is valid
put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, format);
- return ret;
+ return 0;
}
static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
@@ -1128,8 +1132,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
return 0;
if (par->codec_id == AV_CODEC_ID_AAC) {
- ret = get_aac_sample_rates(s, par->extradata, par->extradata_size, &sample_rate,
- &output_sample_rate);
+ ret = get_aac_sample_rates(s, mkv, par->extradata, par->extradata_size,
+ &sample_rate, &output_sample_rate);
if (ret < 0)
return ret;
}
@@ -1291,12 +1295,9 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
uint32_t color_space = av_le2ne32(par->codec_tag);
put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space));
}
- ret = mkv_write_video_color(pb, par, st);
- if (ret < 0)
- return ret;
- ret = mkv_write_video_projection(s, pb, st);
- if (ret < 0)
- return ret;
+ mkv_write_video_color(pb, st, par);
+ mkv_write_video_projection(s, pb, st);
+
end_ebml_master(pb, subinfo);
break;
@@ -1383,9 +1384,7 @@ static int mkv_write_tracks(AVFormatContext *s)
if (mkv->nb_attachments == s->nb_streams)
return 0;
- mkv_add_seekhead_entry(mkv, MATROSKA_ID_TRACKS, avio_tell(pb));
-
- ret = start_ebml_master_crc32(&mkv->tracks_bc, mkv);
+ ret = start_ebml_master_crc32(&mkv->track.bc, mkv);
if (ret < 0)
return ret;
@@ -1425,72 +1424,13 @@ static int mkv_write_tracks(AVFormatContext *s)
i == video_default_idx || i == audio_default_idx ||
i == subtitle_default_idx;
ret = mkv_write_track(s, mkv, st, &mkv->tracks[i],
- mkv->tracks_bc, is_default);
+ mkv->track.bc, is_default);
if (ret < 0)
return ret;
}
- if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
- end_ebml_master_crc32_preliminary(pb, mkv->tracks_bc,
- MATROSKA_ID_TRACKS, &mkv->tracks_pos);
- else
- end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, MATROSKA_ID_TRACKS, 0, 0);
-
- return 0;
-}
-
-static int mkv_write_chapters(AVFormatContext *s)
-{
- MatroskaMuxContext *mkv = s->priv_data;
- AVIOContext *dyn_cp = NULL, *pb = s->pb;
- ebml_master editionentry;
- AVRational scale = {1, 1E9};
- int i, ret;
-
- if (!s->nb_chapters || mkv->wrote_chapters)
- return 0;
-
- mkv_add_seekhead_entry(mkv, MATROSKA_ID_CHAPTERS, avio_tell(pb));
-
- ret = start_ebml_master_crc32(&dyn_cp, mkv);
- if (ret < 0)
- return ret;
-
- editionentry = start_ebml_master(dyn_cp, MATROSKA_ID_EDITIONENTRY, 0);
- if (mkv->mode != MODE_WEBM)
- put_ebml_uint(dyn_cp, MATROSKA_ID_EDITIONFLAGDEFAULT, 1);
-
- for (i = 0; i < s->nb_chapters; i++) {
- ebml_master chapteratom, chapterdisplay;
- const AVChapter *c = s->chapters[i];
- int64_t chapterstart = av_rescale_q(c->start, c->time_base, scale);
- int64_t chapterend = av_rescale_q(c->end, c->time_base, scale);
- const AVDictionaryEntry *t;
- if (chapterstart < 0 || chapterstart > chapterend || chapterend < 0) {
- av_log(s, AV_LOG_ERROR,
- "Invalid chapter start (%"PRId64") or end (%"PRId64").\n",
- chapterstart, chapterend);
- return AVERROR_INVALIDDATA;
- }
-
- chapteratom = start_ebml_master(dyn_cp, MATROSKA_ID_CHAPTERATOM, 0);
- put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERUID,
- (uint32_t)c->id + (uint64_t)mkv->chapter_id_offset);
- put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMESTART, chapterstart);
- put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMEEND, chapterend);
- if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
- chapterdisplay = start_ebml_master(dyn_cp, MATROSKA_ID_CHAPTERDISPLAY, 0);
- put_ebml_string(dyn_cp, MATROSKA_ID_CHAPSTRING, t->value);
- put_ebml_string(dyn_cp, MATROSKA_ID_CHAPLANG , "und");
- end_ebml_master(dyn_cp, chapterdisplay);
- }
- end_ebml_master(dyn_cp, chapteratom);
- }
- end_ebml_master(dyn_cp, editionentry);
- end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS, 0, 0);
-
- mkv->wrote_chapters = 1;
- return 0;
+ return end_ebml_master_crc32_tentatively(pb, &mkv->track, mkv,
+ MATROSKA_ID_TRACKS);
}
static int mkv_write_simpletag(AVIOContext *pb, const AVDictionaryEntry *t)
@@ -1527,28 +1467,23 @@ static int mkv_write_simpletag(AVIOContext *pb, const AVDictionaryEntry *t)
return 0;
}
-static int mkv_write_tag_targets(AVFormatContext *s, uint32_t elementid,
- uint64_t uid, ebml_master *tag)
+static int mkv_write_tag_targets(MatroskaMuxContext *mkv, AVIOContext **pb,
+ ebml_master *tag, uint32_t elementid, uint64_t uid)
{
- AVIOContext *pb;
- MatroskaMuxContext *mkv = s->priv_data;
ebml_master targets;
int ret;
- if (!mkv->tags_bc) {
- mkv_add_seekhead_entry(mkv, MATROSKA_ID_TAGS, avio_tell(s->pb));
-
- ret = start_ebml_master_crc32(&mkv->tags_bc, mkv);
+ if (!*pb) {
+ ret = start_ebml_master_crc32(pb, mkv);
if (ret < 0)
return ret;
}
- pb = mkv->tags_bc;
- *tag = start_ebml_master(pb, MATROSKA_ID_TAG, 0);
- targets = start_ebml_master(pb, MATROSKA_ID_TAGTARGETS, 4 + 1 + 8);
+ *tag = start_ebml_master(*pb, MATROSKA_ID_TAG, 0);
+ targets = start_ebml_master(*pb, MATROSKA_ID_TAGTARGETS, 4 + 1 + 8);
if (elementid)
- put_ebml_uid(pb, elementid, uid);
- end_ebml_master(pb, targets);
+ put_ebml_uid(*pb, elementid, uid);
+ end_ebml_master(*pb, targets);
return 0;
}
@@ -1566,28 +1501,28 @@ static int mkv_check_tag_name(const char *name, uint32_t elementid)
av_strcasecmp(name, "mimetype")));
}
-static int mkv_write_tag(AVFormatContext *s, const AVDictionary *m,
- uint32_t elementid, uint64_t uid, ebml_master *tag)
+static int mkv_write_tag(MatroskaMuxContext *mkv, const AVDictionary *m,
+ AVIOContext **pb, ebml_master *tag,
+ uint32_t elementid, uint64_t uid)
{
- MatroskaMuxContext *mkv = s->priv_data;
const AVDictionaryEntry *t = NULL;
ebml_master tag2;
int ret;
- ret = mkv_write_tag_targets(s, elementid, uid, tag ? tag : &tag2);
+ ret = mkv_write_tag_targets(mkv, pb, tag ? tag : &tag2, elementid, uid);
if (ret < 0)
return ret;
while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
if (mkv_check_tag_name(t->key, elementid)) {
- ret = mkv_write_simpletag(mkv->tags_bc, t);
+ ret = mkv_write_simpletag(*pb, t);
if (ret < 0)
return ret;
}
}
if (!tag)
- end_ebml_master(mkv->tags_bc, tag2);
+ end_ebml_master(*pb, tag2);
return 0;
}
@@ -1606,18 +1541,19 @@ static int mkv_check_tag(const AVDictionary *m, uint32_t elementid)
static int mkv_write_tags(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
- ebml_master tag, *tagp;
+ ebml_master tag, *tagp = IS_SEEKABLE(s->pb, mkv) ? &tag : NULL;
int i, ret;
+ mkv->wrote_tags = 1;
+
ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
if (mkv_check_tag(s->metadata, 0)) {
- ret = mkv_write_tag(s, s->metadata, 0, 0, NULL);
+ ret = mkv_write_tag(mkv, s->metadata, &mkv->tags.bc, NULL, 0, 0);
if (ret < 0)
return ret;
}
- tagp = (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live ? &tag : NULL;
for (i = 0; i < s->nb_streams; i++) {
const AVStream *st = s->streams[i];
mkv_track *track = &mkv->tracks[i];
@@ -1628,13 +1564,13 @@ static int mkv_write_tags(AVFormatContext *s)
if (!tagp && !mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID))
continue;
- ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID,
- track->uid, tagp);
+ ret = mkv_write_tag(mkv, st->metadata, &mkv->tags.bc, tagp,
+ MATROSKA_ID_TAGTARGETS_TRACKUID, track->uid);
if (ret < 0)
return ret;
if (tagp) {
- AVIOContext *pb = mkv->tags_bc;
+ AVIOContext *pb = mkv->tags.bc;
ebml_master simpletag;
simpletag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG,
@@ -1650,21 +1586,6 @@ static int mkv_write_tags(AVFormatContext *s)
}
}
- if (mkv->mode != MODE_WEBM) {
- for (i = 0; i < s->nb_chapters; i++) {
- AVChapter *ch = s->chapters[i];
-
- if (!mkv_check_tag(ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID))
- continue;
-
- ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID,
- (uint32_t)ch->id + (uint64_t)mkv->chapter_id_offset,
- NULL);
- if (ret < 0)
- return ret;
- }
- }
-
if (mkv->nb_attachments && mkv->mode != MODE_WEBM) {
for (i = 0; i < s->nb_streams; i++) {
const mkv_track *track = &mkv->tracks[i];
@@ -1676,23 +1597,124 @@ static int mkv_write_tags(AVFormatContext *s)
if (!mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_ATTACHUID))
continue;
- ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_ATTACHUID,
- track->uid, NULL);
+ ret = mkv_write_tag(mkv, st->metadata, &mkv->tags.bc, NULL,
+ MATROSKA_ID_TAGTARGETS_ATTACHUID, track->uid);
if (ret < 0)
return ret;
}
}
- if (mkv->tags_bc) {
- if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
- end_ebml_master_crc32_preliminary(s->pb, mkv->tags_bc,
- MATROSKA_ID_TAGS, &mkv->tags_pos);
- else
- end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS, 0, 0);
+ if (mkv->tags.bc) {
+ return end_ebml_master_crc32_tentatively(s->pb, &mkv->tags, mkv,
+ MATROSKA_ID_TAGS);
}
return 0;
}
+static int mkv_write_chapters(AVFormatContext *s)
+{
+ MatroskaMuxContext *mkv = s->priv_data;
+ AVIOContext *dyn_cp = NULL, *dyn_tags = NULL, **tags, *pb = s->pb;
+ ebml_master editionentry;
+ uint64_t chapter_id_offset = 0;
+ AVRational scale = {1, 1E9};
+ int i, ret;
+
+ if (!s->nb_chapters || mkv->wrote_chapters)
+ return 0;
+
+ for (i = 0; i < s->nb_chapters; i++)
+ if (!s->chapters[i]->id) {
+ chapter_id_offset = 1;
+ break;
+ }
+
+ ret = start_ebml_master_crc32(&dyn_cp, mkv);
+ if (ret < 0)
+ return ret;
+
+ editionentry = start_ebml_master(dyn_cp, MATROSKA_ID_EDITIONENTRY, 0);
+ if (mkv->mode != MODE_WEBM) {
+ put_ebml_uint(dyn_cp, MATROSKA_ID_EDITIONFLAGDEFAULT, 1);
+ /* If mkv_write_tags() has already been called, then any tags
+ * corresponding to chapters will be put into a new Tags element. */
+ tags = mkv->wrote_tags ? &dyn_tags : &mkv->tags.bc;
+ } else
+ tags = NULL;
+
+ for (i = 0; i < s->nb_chapters; i++) {
+ ebml_master chapteratom, chapterdisplay;
+ const AVChapter *c = s->chapters[i];
+ int64_t chapterstart = av_rescale_q(c->start, c->time_base, scale);
+ int64_t chapterend = av_rescale_q(c->end, c->time_base, scale);
+ const AVDictionaryEntry *t;
+ if (chapterstart < 0 || chapterstart > chapterend || chapterend < 0) {
+ av_log(s, AV_LOG_ERROR,
+ "Invalid chapter start (%"PRId64") or end (%"PRId64").\n",
+ chapterstart, chapterend);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ chapteratom = start_ebml_master(dyn_cp, MATROSKA_ID_CHAPTERATOM, 0);
+ put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERUID,
+ (uint32_t)c->id + chapter_id_offset);
+ put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMESTART, chapterstart);
+ put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMEEND, chapterend);
+ if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
+ chapterdisplay = start_ebml_master(dyn_cp, MATROSKA_ID_CHAPTERDISPLAY, 0);
+ put_ebml_string(dyn_cp, MATROSKA_ID_CHAPSTRING, t->value);
+ put_ebml_string(dyn_cp, MATROSKA_ID_CHAPLANG , "und");
+ end_ebml_master(dyn_cp, chapterdisplay);
+ }
+ end_ebml_master(dyn_cp, chapteratom);
+
+ if (tags && mkv_check_tag(c->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) {
+ ret = mkv_write_tag(mkv, c->metadata, tags, NULL,
+ MATROSKA_ID_TAGTARGETS_CHAPTERUID,
+ (uint32_t)c->id + chapter_id_offset);
+ if (ret < 0)
+ goto fail;
+ }
+ }
+ end_ebml_master(dyn_cp, editionentry);
+ mkv->wrote_chapters = 1;
+
+ ret = end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS, 0, 0, 1);
+ if (ret < 0)
+ goto fail;
+ if (dyn_tags)
+ return end_ebml_master_crc32(pb, &dyn_tags, mkv,
+ MATROSKA_ID_TAGS, 0, 0, 1);
+ return 0;
+
+fail:
+ if (tags) {
+ /* tags == &mkv->tags.bc can only happen if mkv->tags.bc was
+ * initially NULL, so we never free older tags. */
+ ffio_free_dyn_buf(tags);
+ }
+ ffio_free_dyn_buf(&dyn_cp);
+ return ret;
+}
+
+static const char *get_mimetype(const AVStream *st)
+{
+ const AVDictionaryEntry *t;
+
+ if (t = av_dict_get(st->metadata, "mimetype", NULL, 0))
+ return t->value;
+ if (st->codecpar->codec_id != AV_CODEC_ID_NONE) {
+ const AVCodecDescriptor *desc = avcodec_descriptor_get(st->codecpar->codec_id);
+ if (desc && desc->mime_types) {
+ return desc->mime_types[0];
+ } else if (st->codecpar->codec_id == AV_CODEC_ID_TEXT)
+ return "text/plain";
+ }
+
+ return NULL;
+}
+
static int mkv_write_attachments(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
@@ -1702,8 +1724,6 @@ static int mkv_write_attachments(AVFormatContext *s)
if (!mkv->nb_attachments)
return 0;
- mkv_add_seekhead_entry(mkv, MATROSKA_ID_ATTACHMENTS, avio_tell(pb));
-
ret = start_ebml_master_crc32(&dyn_cp, mkv);
if (ret < 0)
return ret;
@@ -1713,7 +1733,7 @@ static int mkv_write_attachments(AVFormatContext *s)
mkv_track *track = &mkv->tracks[i];
ebml_master attached_file;
const AVDictionaryEntry *t;
- const char *mimetype = NULL;
+ const char *mimetype;
if (st->codecpar->codec_type != AVMEDIA_TYPE_ATTACHMENT)
continue;
@@ -1727,29 +1747,16 @@ static int mkv_write_attachments(AVFormatContext *s)
return AVERROR(EINVAL);
}
put_ebml_string(dyn_cp, MATROSKA_ID_FILENAME, t->value);
- if (t = av_dict_get(st->metadata, "mimetype", NULL, 0))
- mimetype = t->value;
- else if (st->codecpar->codec_id != AV_CODEC_ID_NONE ) {
- const AVCodecDescriptor *desc = avcodec_descriptor_get(st->codecpar->codec_id);
- if (desc && desc->mime_types) {
- mimetype = desc->mime_types[0];
- } else if (st->codecpar->codec_id == AV_CODEC_ID_TEXT)
- mimetype = "text/plain";
- }
- if (!mimetype) {
- av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and "
- "it cannot be deduced from the codec id.\n", i);
- return AVERROR(EINVAL);
- }
+ mimetype = get_mimetype(st);
+ av_assert0(mimetype);
put_ebml_string(dyn_cp, MATROSKA_ID_FILEMIMETYPE, mimetype);
put_ebml_binary(dyn_cp, MATROSKA_ID_FILEDATA, st->codecpar->extradata, st->codecpar->extradata_size);
put_ebml_uid(dyn_cp, MATROSKA_ID_FILEUID, track->uid);
end_ebml_master(dyn_cp, attached_file);
}
- end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS, 0, 0);
-
- return 0;
+ return end_ebml_master_crc32(pb, &dyn_cp, mkv,
+ MATROSKA_ID_ATTACHMENTS, 0, 0, 1);
}
static int64_t get_metadata_duration(AVFormatContext *s)
@@ -1807,19 +1814,18 @@ static int mkv_write_header(AVFormatContext *s)
put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION, 2);
end_ebml_master(pb, ebml_header);
- mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT, 0);
+ put_ebml_id(pb, MATROSKA_ID_SEGMENT);
+ put_ebml_size_unknown(pb, 8);
mkv->segment_offset = avio_tell(pb);
- // we write a seek head at the beginning to point to all other level
+ // We write a SeekHead at the beginning to point to all other level
// one elements (except Clusters).
mkv_start_seekhead(mkv, pb);
- mkv_add_seekhead_entry(mkv, MATROSKA_ID_INFO, avio_tell(pb));
-
- ret = start_ebml_master_crc32(&mkv->info_bc, mkv);
+ ret = start_ebml_master_crc32(&mkv->info.bc, mkv);
if (ret < 0)
return ret;
- pb = mkv->info_bc;
+ pb = mkv->info.bc;
put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
if ((tag = av_dict_get(s->metadata, "title", NULL, 0)))
@@ -1861,27 +1867,20 @@ static int mkv_write_header(AVFormatContext *s)
int64_t scaledDuration = av_rescale(metadata_duration, 1000, AV_TIME_BASE);
put_ebml_float(pb, MATROSKA_ID_DURATION, scaledDuration);
av_log(s, AV_LOG_DEBUG, "Write early duration from metadata = %" PRIu64 "\n", scaledDuration);
- } else {
+ } else if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
put_ebml_void(pb, 11); // assumes double-precision float to be written
}
}
- if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
- end_ebml_master_crc32_preliminary(s->pb, mkv->info_bc,
- MATROSKA_ID_INFO, &mkv->info_pos);
- else
- end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO, 0, 0);
+ ret = end_ebml_master_crc32_tentatively(s->pb, &mkv->info,
+ mkv, MATROSKA_ID_INFO);
+ if (ret < 0)
+ return ret;
pb = s->pb;
ret = mkv_write_tracks(s);
if (ret < 0)
return ret;
- for (i = 0; i < s->nb_chapters; i++)
- if (!s->chapters[i]->id) {
- mkv->chapter_id_offset = 1;
- break;
- }
-
ret = mkv_write_chapters(s);
if (ret < 0)
return ret;
@@ -1892,11 +1891,13 @@ static int mkv_write_header(AVFormatContext *s)
return ret;
}
+ /* Must come after mkv_write_chapters() to write chapter tags
+ * into the same Tags element as the other tags. */
ret = mkv_write_tags(s);
if (ret < 0)
return ret;
- if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
+ if (!IS_SEEKABLE(pb, mkv)) {
ret = mkv_write_seekhead(pb, mkv, 0, avio_tell(pb));
if (ret < 0)
return ret;
@@ -1908,11 +1909,14 @@ static int mkv_write_header(AVFormatContext *s)
put_ebml_void(pb, s->metadata_header_padding);
}
- if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && mkv->reserve_cues_space) {
- mkv->cues_pos = avio_tell(pb);
- if (mkv->reserve_cues_space == 1)
- mkv->reserve_cues_space++;
- put_ebml_void(pb, mkv->reserve_cues_space);
+ if (mkv->reserve_cues_space) {
+ if (IS_SEEKABLE(pb, mkv)) {
+ mkv->cues_pos = avio_tell(pb);
+ if (mkv->reserve_cues_space == 1)
+ mkv->reserve_cues_space++;
+ put_ebml_void(pb, mkv->reserve_cues_space);
+ } else
+ mkv->reserve_cues_space = -1;
}
av_init_packet(&mkv->cur_audio_pkt);
@@ -1921,7 +1925,7 @@ static int mkv_write_header(AVFormatContext *s)
// start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
// after 4k and on a keyframe
- if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
+ if (IS_SEEKABLE(pb, mkv)) {
if (mkv->cluster_time_limit < 0)
mkv->cluster_time_limit = 5000;
if (mkv->cluster_size_limit < 0)
@@ -2005,7 +2009,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
mkv_track *track = &mkv->tracks[pkt->stream_index];
uint8_t *data = NULL, *side_data = NULL;
- int err = 0, offset = 0, size = pkt->size, side_data_size = 0;
+ int err = 0, offset = 0, size = pkt->size, side_data_size;
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
uint64_t additional_id;
int64_t discard_padding = 0;
@@ -2116,17 +2120,17 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac
mkv_track *track = &mkv->tracks[pkt->stream_index];
ebml_master blockgroup;
int id_size, settings_size, size;
- uint8_t *id, *settings;
+ const char *id, *settings;
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
const int flags = 0;
- id_size = 0;
id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER,
&id_size);
+ id = id ? id : "";
- settings_size = 0;
settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
&settings_size);
+ settings = settings ? settings : "";
size = id_size + 1 + settings_size + 1 + pkt->size;
@@ -2155,17 +2159,23 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac
return pkt->duration;
}
-static void mkv_end_cluster(AVFormatContext *s)
+static int mkv_end_cluster(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
+ int ret;
- end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER, 0, 1);
if (!mkv->have_video) {
for (unsigned i = 0; i < s->nb_streams; i++)
mkv->tracks[i].has_cue = 0;
}
mkv->cluster_pos = -1;
+ ret = end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv,
+ MATROSKA_ID_CLUSTER, 0, 1, 0);
+ if (ret < 0)
+ return ret;
+
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
+ return 0;
}
static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
@@ -2174,17 +2184,17 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
mkv_track *track = &mkv->tracks[pkt->stream_index];
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
uint8_t *side_data;
- int side_data_size = 0, ret;
+ int side_data_size, ret;
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
&side_data_size);
switch (par->codec_id) {
case AV_CODEC_ID_AAC:
- if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
+ if (side_data_size && mkv->track.bc) {
int filler, output_sample_rate = 0;
- ret = get_aac_sample_rates(s, side_data, side_data_size, &track->sample_rate,
- &output_sample_rate);
+ ret = get_aac_sample_rates(s, mkv, side_data, side_data_size,
+ &track->sample_rate, &output_sample_rate);
if (ret < 0)
return ret;
if (!output_sample_rate)
@@ -2193,14 +2203,14 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
if (ret < 0)
return ret;
memcpy(par->extradata, side_data, side_data_size);
- avio_seek(mkv->tracks_bc, track->codecpriv_offset, SEEK_SET);
- mkv_write_codecprivate(s, mkv->tracks_bc, par, 1, 0);
- filler = MAX_PCE_SIZE + 2 + 4 - (avio_tell(mkv->tracks_bc) - track->codecpriv_offset);
+ avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
+ mkv_write_codecprivate(s, mkv->track.bc, par, 1, 0);
+ filler = MAX_PCE_SIZE + 2 + 4 - (avio_tell(mkv->track.bc) - track->codecpriv_offset);
if (filler)
- put_ebml_void(mkv->tracks_bc, filler);
- avio_seek(mkv->tracks_bc, track->sample_rate_offset, SEEK_SET);
- put_ebml_float(mkv->tracks_bc, MATROSKA_ID_AUDIOSAMPLINGFREQ, track->sample_rate);
- put_ebml_float(mkv->tracks_bc, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate);
+ put_ebml_void(mkv->track.bc, filler);
+ avio_seek(mkv->track.bc, track->sample_rate_offset, SEEK_SET);
+ put_ebml_float(mkv->track.bc, MATROSKA_ID_AUDIOSAMPLINGFREQ, track->sample_rate);
+ put_ebml_float(mkv->track.bc, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate);
} else if (!par->extradata_size && !track->sample_rate) {
// No extradata (codecpar or packet side data).
av_log(s, AV_LOG_ERROR, "Error parsing AAC extradata, unable to determine samplerate.\n");
@@ -2208,7 +2218,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
}
break;
case AV_CODEC_ID_FLAC:
- if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
+ if (side_data_size && mkv->track.bc) {
uint8_t *old_extradata = par->extradata;
if (side_data_size != par->extradata_size) {
av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n",
@@ -2216,16 +2226,15 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
return AVERROR(EINVAL);
}
par->extradata = side_data;
- avio_seek(mkv->tracks_bc, track->codecpriv_offset, SEEK_SET);
- mkv_write_codecprivate(s, mkv->tracks_bc, par, 1, 0);
+ avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
+ mkv_write_codecprivate(s, mkv->track.bc, par, 1, 0);
par->extradata = old_extradata;
}
break;
// FIXME: Remove the following once libaom starts propagating extradata during init()
// See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012
case AV_CODEC_ID_AV1:
- if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live &&
- !par->extradata_size) {
+ if (side_data_size && mkv->track.bc && !par->extradata_size) {
AVIOContext *dyn_cp;
uint8_t *codecpriv;
int codecpriv_size;
@@ -2233,15 +2242,16 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
if (ret < 0)
return ret;
ff_isom_write_av1c(dyn_cp, side_data, side_data_size);
- codecpriv_size = avio_close_dyn_buf(dyn_cp, &codecpriv);
- if (!codecpriv_size) {
- av_free(codecpriv);
- return AVERROR_INVALIDDATA;
+ codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv);
+ if ((ret = dyn_cp->error) < 0 ||
+ !codecpriv_size && (ret = AVERROR_INVALIDDATA)) {
+ ffio_free_dyn_buf(&dyn_cp);
+ return ret;
}
- avio_seek(mkv->tracks_bc, track->codecpriv_offset, SEEK_SET);
+ avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
// Do not write the OBUs as we don't have space saved for them
- put_ebml_binary(mkv->tracks_bc, MATROSKA_ID_CODECPRIVATE, codecpriv, 4);
- av_free(codecpriv);
+ put_ebml_binary(mkv->track.bc, MATROSKA_ID_CODECPRIVATE, codecpriv, 4);
+ ffio_free_dyn_buf(&dyn_cp);
ret = ff_alloc_extradata(par, side_data_size);
if (ret < 0)
return ret;
@@ -2279,7 +2289,9 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt)
if (mkv->cluster_pos != -1) {
int64_t cluster_time = ts - mkv->cluster_pts;
if ((int16_t)cluster_time != cluster_time) {
- mkv_end_cluster(s);
+ ret = mkv_end_cluster(s);
+ if (ret < 0)
+ return ret;
av_log(s, AV_LOG_WARNING, "Starting new cluster due to timestamp\n");
}
}
@@ -2304,7 +2316,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt)
ret = mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe);
if (ret < 0)
return ret;
- if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && keyframe &&
+ if (keyframe && IS_SEEKABLE(s->pb, mkv) &&
(par->codec_type == AVMEDIA_TYPE_VIDEO || !mkv->have_video && !track->has_cue)) {
ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts,
mkv->cluster_pos, relative_packet_pos, -1);
@@ -2334,7 +2346,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
end_ebml_master(pb, blockgroup);
}
- if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
+ if (IS_SEEKABLE(s->pb, mkv)) {
ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts,
mkv->cluster_pos, relative_packet_pos, duration);
if (ret < 0)
@@ -2389,8 +2401,11 @@ static int mkv_write_packet(AVFormatContext *s, const AVPacket *pkt)
} else
start_new_cluster = 0;
- if (start_new_cluster)
- mkv_end_cluster(s);
+ if (start_new_cluster) {
+ ret = mkv_end_cluster(s);
+ if (ret < 0)
+ return ret;
+ }
}
if (!mkv->cluster_pos)
@@ -2425,7 +2440,9 @@ static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt)
if (!pkt) {
if (mkv->cluster_pos != -1) {
- mkv_end_cluster(s);
+ int ret = mkv_end_cluster(s);
+ if (ret < 0)
+ return ret;
av_log(s, AV_LOG_DEBUG,
"Flushing cluster at offset %" PRIu64 " bytes\n",
avio_tell(s->pb));
@@ -2439,7 +2456,8 @@ static int mkv_write_trailer(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
AVIOContext *pb = s->pb;
- int ret;
+ int64_t endpos, ret64;
+ int ret, ret2 = 0;
// check if we have an audio packet cached
if (mkv->cur_audio_pkt.size > 0) {
@@ -2451,130 +2469,143 @@ static int mkv_write_trailer(AVFormatContext *s)
}
}
- if (mkv->cluster_bc) {
- end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv,
- MATROSKA_ID_CLUSTER, 0, 0);
+ if (mkv->cluster_pos != -1) {
+ ret = end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv,
+ MATROSKA_ID_CLUSTER, 0, 0, 0);
+ if (ret < 0)
+ return ret;
}
ret = mkv_write_chapters(s);
if (ret < 0)
return ret;
+ if (!IS_SEEKABLE(pb, mkv))
+ return 0;
- if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
- int64_t endpos, ret64;
-
- endpos = avio_tell(pb);
+ endpos = avio_tell(pb);
- if (mkv->cues.num_entries) {
- AVIOContext *cues = NULL;
- uint64_t size;
- int64_t cuespos = endpos;
- int length_size = 0;
+ if (mkv->cues.num_entries && mkv->reserve_cues_space >= 0) {
+ AVIOContext *cues = NULL;
+ uint64_t size;
+ int length_size = 0;
- ret = start_ebml_master_crc32(&cues, mkv);
- if (ret < 0)
- return ret;
+ ret = start_ebml_master_crc32(&cues, mkv);
+ if (ret < 0)
+ return ret;
- ret = mkv_assemble_cues(s->streams, cues, &mkv->cues,
- mkv->tracks, s->nb_streams);
- if (ret < 0) {
- ffio_free_dyn_buf(&cues);
- return ret;
- }
+ ret = mkv_assemble_cues(s->streams, cues, &mkv->cues,
+ mkv->tracks, s->nb_streams);
+ if (ret < 0) {
+ ffio_free_dyn_buf(&cues);
+ return ret;
+ }
- if (mkv->reserve_cues_space) {
- size = avio_tell(cues);
- length_size = ebml_length_size(size);
- size += 4 + length_size;
- if (mkv->reserve_cues_space < size) {
- av_log(s, AV_LOG_WARNING,
- "Insufficient space reserved for Cues: "
- "%d < %"PRIu64". No Cues will be output.\n",
- mkv->reserve_cues_space, size);
- mkv->reserve_cues_space = -1;
+ if (mkv->reserve_cues_space) {
+ size = avio_tell(cues);
+ length_size = ebml_length_size(size);
+ size += 4 + length_size;
+ if (mkv->reserve_cues_space < size) {
+ av_log(s, AV_LOG_WARNING,
+ "Insufficient space reserved for Cues: "
+ "%d < %"PRIu64". No Cues will be output.\n",
+ mkv->reserve_cues_space, size);
+ ret2 = AVERROR(EINVAL);
+ goto after_cues;
+ } else {
+ if ((ret64 = avio_seek(pb, mkv->cues_pos, SEEK_SET)) < 0) {
ffio_free_dyn_buf(&cues);
- goto after_cues;
- } else {
- cuespos = mkv->cues_pos;
- if ((ret64 = avio_seek(pb, mkv->cues_pos, SEEK_SET)) < 0) {
- ffio_free_dyn_buf(&cues);
- return ret64;
- }
- if (mkv->reserve_cues_space == size + 1) {
- /* There is no way to reserve a single byte because
- * the minimal size of an EBML Void element is 2
- * (1 byte ID, 1 byte length field). This problem
- * is solved by writing the Cues' length field on
- * one byte more than necessary. */
- length_size++;
- size++;
- }
+ return ret64;
+ }
+ if (mkv->reserve_cues_space == size + 1) {
+ /* There is no way to reserve a single byte because
+ * the minimal size of an EBML Void element is 2
+ * (1 byte ID, 1 byte length field). This problem
+ * is solved by writing the Cues' length field on
+ * one byte more than necessary. */
+ length_size++;
+ size++;
}
}
- mkv_add_seekhead_entry(mkv, MATROSKA_ID_CUES, cuespos);
- end_ebml_master_crc32(pb, &cues, mkv, MATROSKA_ID_CUES,
- length_size, 0);
- if (mkv->reserve_cues_space) {
- if (size < mkv->reserve_cues_space)
- put_ebml_void(pb, mkv->reserve_cues_space - size);
- } else
- endpos = avio_tell(pb);
}
-
- after_cues:
- ret = mkv_write_seekhead(pb, mkv, 1, mkv->info_pos);
+ ret = end_ebml_master_crc32(pb, &cues, mkv, MATROSKA_ID_CUES,
+ length_size, 0, 1);
if (ret < 0)
return ret;
+ if (mkv->reserve_cues_space) {
+ if (size < mkv->reserve_cues_space)
+ put_ebml_void(pb, mkv->reserve_cues_space - size);
+ } else
+ endpos = avio_tell(pb);
+ }
+after_cues:
+ /* Lengths greater than (1ULL << 56) - 1 can't be represented
+ * via an EBML number, so leave the unknown length field. */
+ if (endpos - mkv->segment_offset < (1ULL << 56) - 1) {
+ if ((ret64 = avio_seek(pb, mkv->segment_offset - 8, SEEK_SET)) < 0)
+ return ret64;
+ put_ebml_length(pb, endpos - mkv->segment_offset, 8);
+ }
+
+ ret = mkv_write_seekhead(pb, mkv, 1, mkv->info.pos);
+ if (ret < 0)
+ return ret;
+
+ if (mkv->info.bc) {
// update the duration
av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
- avio_seek(mkv->info_bc, mkv->duration_offset, SEEK_SET);
- put_ebml_float(mkv->info_bc, MATROSKA_ID_DURATION, mkv->duration);
- end_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO, 0, 0);
-
- if (mkv->tracks_bc) {
- // write Tracks master
- avio_seek(pb, mkv->tracks_pos, SEEK_SET);
- end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv,
- MATROSKA_ID_TRACKS, 0, 0);
- }
+ avio_seek(mkv->info.bc, mkv->duration_offset, SEEK_SET);
+ put_ebml_float(mkv->info.bc, MATROSKA_ID_DURATION, mkv->duration);
+ ret = end_ebml_master_crc32(pb, &mkv->info.bc, mkv,
+ MATROSKA_ID_INFO, 0, 0, 0);
+ if (ret < 0)
+ return ret;
+ }
- // update stream durations
- if (mkv->tags_bc) {
- int i;
- for (i = 0; i < s->nb_streams; ++i) {
- const AVStream *st = s->streams[i];
- const mkv_track *track = &mkv->tracks[i];
+ if (mkv->track.bc) {
+ // write Tracks master
+ avio_seek(pb, mkv->track.pos, SEEK_SET);
+ ret = end_ebml_master_crc32(pb, &mkv->track.bc, mkv,
+ MATROSKA_ID_TRACKS, 0, 0, 0);
+ if (ret < 0)
+ return ret;
+ }
- if (track->duration_offset > 0) {
- double duration_sec = track->duration * av_q2d(st->time_base);
- char duration_string[20] = "";
+ // update stream durations
+ if (mkv->tags.bc) {
+ int i;
+ for (i = 0; i < s->nb_streams; ++i) {
+ const AVStream *st = s->streams[i];
+ const mkv_track *track = &mkv->tracks[i];
- av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i,
- track->duration);
+ if (track->duration_offset > 0) {
+ double duration_sec = track->duration * av_q2d(st->time_base);
+ char duration_string[20] = "";
- avio_seek(mkv->tags_bc, track->duration_offset, SEEK_SET);
+ av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i,
+ track->duration);
- snprintf(duration_string, 20, "%02d:%02d:%012.9f",
- (int) duration_sec / 3600, ((int) duration_sec / 60) % 60,
- fmod(duration_sec, 60));
+ avio_seek(mkv->tags.bc, track->duration_offset, SEEK_SET);
- put_ebml_binary(mkv->tags_bc, MATROSKA_ID_TAGSTRING, duration_string, 20);
- }
- }
+ snprintf(duration_string, 20, "%02d:%02d:%012.9f",
+ (int) duration_sec / 3600, ((int) duration_sec / 60) % 60,
+ fmod(duration_sec, 60));
- avio_seek(pb, mkv->tags_pos, SEEK_SET);
- end_ebml_master_crc32(pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS, 0, 0);
+ put_ebml_binary(mkv->tags.bc, MATROSKA_ID_TAGSTRING, duration_string, 20);
+ }
}
- avio_seek(pb, endpos, SEEK_SET);
+ avio_seek(pb, mkv->tags.pos, SEEK_SET);
+ ret = end_ebml_master_crc32(pb, &mkv->tags.bc, mkv,
+ MATROSKA_ID_TAGS, 0, 0, 0);
+ if (ret < 0)
+ return ret;
}
- if (!mkv->is_live)
- end_ebml_master(pb, mkv->segment);
+ avio_seek(pb, endpos, SEEK_SET);
- return mkv->reserve_cues_space < 0 ? AVERROR(EINVAL) : 0;
+ return ret2;
}
static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance)
@@ -2683,6 +2714,10 @@ static int mkv_init(struct AVFormatContext *s)
if (mkv->mode == MODE_WEBM) {
av_log(s, AV_LOG_WARNING, "Stream %d will be ignored "
"as WebM doesn't support attachments.\n", i);
+ } else if (!get_mimetype(st)) {
+ av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype "
+ "tag and it cannot be deduced from the codec id.\n", i);
+ return AVERROR(EINVAL);
}
mkv->nb_attachments++;
continue;
@@ -2754,6 +2789,7 @@ static const AVOption options[] = {
{ "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, FLAGS },
{ "live", "Write files assuming it is a live stream.", OFFSET(is_live), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
{ "allow_raw_vfw", "allow RAW VFW mode", OFFSET(allow_raw_vfw), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+ { "flipped_raw_rgb", "Raw RGB bitmaps in VFW mode are stored bottom-up", OFFSET(flipped_raw_rgb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
{ "write_crc32", "write a CRC32 element inside every Level 1 element", OFFSET(write_crc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
{ "default_mode", "Controls how a track's FlagDefault is inferred", OFFSET(default_mode), AV_OPT_TYPE_INT, { .i64 = DEFAULT_MODE_INFER }, DEFAULT_MODE_INFER, DEFAULT_MODE_PASSTHROUGH, FLAGS, "default_mode" },
{ "infer", "For each track type, mark the first track of disposition default as default; if none exists, mark the first track as default.", 0, AV_OPT_TYPE_CONST, { .i64 = DEFAULT_MODE_INFER }, 0, 0, FLAGS, "default_mode" },
diff --git a/chromium/third_party/ffmpeg/libavformat/mccdec.c b/chromium/third_party/ffmpeg/libavformat/mccdec.c
new file mode 100644
index 00000000000..874ff45cdf3
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/mccdec.c
@@ -0,0 +1,238 @@
+/*
+ * MCC subtitle demuxer
+ * Copyright (c) 2020 Paul B Mahol
+ *
+ * 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 "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct MCCContext {
+ FFDemuxSubtitlesQueue q;
+} MCCContext;
+
+static int mcc_probe(const AVProbeData *p)
+{
+ char buf[28];
+ FFTextReader tr;
+
+ ff_text_init_buf(&tr, p->buf, p->buf_size);
+
+ while (ff_text_peek_r8(&tr) == '\r' || ff_text_peek_r8(&tr) == '\n')
+ ff_text_r8(&tr);
+
+ ff_text_read(&tr, buf, sizeof(buf));
+
+ if (!memcmp(buf, "File Format=MacCaption_MCC V", 28))
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+static int convert(uint8_t x)
+{
+ if (x >= 'a')
+ x -= 87;
+ else if (x >= 'A')
+ x -= 55;
+ else
+ x -= '0';
+ return x;
+}
+
+typedef struct alias {
+ uint8_t key;
+ int len;
+ const char *value;
+} alias;
+
+static const alias aliases[20] = {
+ { .key = 16, .len = 3, .value = "\xFA\x0\x0", },
+ { .key = 17, .len = 6, .value = "\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 18, .len = 9, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 19, .len = 12, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 20, .len = 15, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 21, .len = 18, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 22, .len = 21, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 23, .len = 24, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 24, .len = 27, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
+ { .key = 25, .len = 3, .value = "\xFB\x80\x80", },
+ { .key = 26, .len = 3, .value = "\xFC\x80\x80", },
+ { .key = 27, .len = 3, .value = "\xFD\x80\x80", },
+ { .key = 28, .len = 2, .value = "\x96\x69", },
+ { .key = 29, .len = 2, .value = "\x61\x01", },
+ { .key = 30, .len = 3, .value = "\xFC\x80\x80", },
+ { .key = 31, .len = 3, .value = "\xFC\x80\x80", },
+ { .key = 32, .len = 4, .value = "\xE1\x00\x00\x00", },
+ { .key = 33, .len = 0, .value = NULL, },
+ { .key = 34, .len = 0, .value = NULL, },
+ { .key = 35, .len = 1, .value = "\x0", },
+};
+
+static int mcc_read_header(AVFormatContext *s)
+{
+ MCCContext *mcc = s->priv_data;
+ AVStream *st = avformat_new_stream(s, NULL);
+ AVRational rate;
+ int64_t ts, pos;
+ uint8_t out[4096];
+ char line[4096];
+ FFTextReader tr;
+ int ret = 0;
+
+ ff_text_init_avio(s, &tr, s->pb);
+
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
+ avpriv_set_pts_info(st, 64, 1, 30);
+
+ while (!ff_text_eof(&tr)) {
+ int hh, mm, ss, fs, i = 0, j = 0;
+ int start = 12, count = 0;
+ AVPacket *sub;
+ char *lline;
+
+ ff_subtitles_read_line(&tr, line, sizeof(line));
+ if (!strncmp(line, "File Format=MacCaption_MCC V", 28))
+ continue;
+ if (!strncmp(line, "//", 2))
+ continue;
+ if (!strncmp(line, "Time Code Rate=", 15)) {
+ char *rate_str = line + 15;
+ char *df = NULL;
+ int num = -1, den = -1;
+
+ if (rate_str[0]) {
+ num = strtol(rate_str, &df, 10);
+ den = 1;
+ if (df && !av_strncasecmp(df, "DF", 2)) {
+ num *= 1000;
+ den = 1001;
+ }
+ }
+
+ if (num > 0 && den > 0) {
+ rate = av_make_q(num, den);
+ avpriv_set_pts_info(st, 64, rate.den, rate.num);
+ }
+ continue;
+ }
+
+ if (av_sscanf(line, "%d:%d:%d:%d", &hh, &mm, &ss, &fs) != 4)
+ continue;
+
+ ts = av_rescale(hh * 3600LL + mm * 60LL + ss, rate.num, rate.den) + fs;
+
+ lline = (char *)&line;
+ lline += 12;
+ pos = ff_text_pos(&tr);
+
+ while (lline[i]) {
+ uint8_t v = convert(lline[i]);
+
+ if (v >= 16 && v <= 35) {
+ int idx = v - 16;
+ if (aliases[idx].len) {
+ if (j >= sizeof(out) - 1 - aliases[idx].len) {
+ j = 0;
+ break;
+ }
+ memcpy(out + j, aliases[idx].value, aliases[idx].len);
+ j += aliases[idx].len;
+ }
+ } else {
+ uint8_t vv;
+
+ if (i + 13 >= sizeof(line) - 1)
+ break;
+ vv = convert(lline[i + 1]);
+ if (j >= sizeof(out) - 1) {
+ j = 0;
+ break;
+ }
+ out[j++] = vv | (v << 4);
+ i++;
+ }
+
+ i++;
+ }
+ out[j] = 0;
+
+ if (out[7] & 0x80)
+ start += 4;
+ count = (out[11] & 0x1f) * 3;
+ if (j < start + count + 1)
+ continue;
+
+ if (!count)
+ continue;
+ sub = ff_subtitles_queue_insert(&mcc->q, out + start, count, 0);
+ if (!sub)
+ goto fail;
+
+ sub->pos = pos;
+ sub->pts = ts;
+ sub->duration = 1;
+ }
+
+ ff_subtitles_queue_finalize(s, &mcc->q);
+
+ return ret;
+fail:
+ ff_subtitles_queue_clean(&mcc->q);
+ return AVERROR(ENOMEM);
+}
+
+static int mcc_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ MCCContext *mcc = s->priv_data;
+ return ff_subtitles_queue_read_packet(&mcc->q, pkt);
+}
+
+static int mcc_read_seek(AVFormatContext *s, int stream_index,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ MCCContext *mcc = s->priv_data;
+ return ff_subtitles_queue_seek(&mcc->q, s, stream_index,
+ min_ts, ts, max_ts, flags);
+}
+
+static int mcc_read_close(AVFormatContext *s)
+{
+ MCCContext *mcc = s->priv_data;
+ ff_subtitles_queue_clean(&mcc->q);
+ return 0;
+}
+
+AVInputFormat ff_mcc_demuxer = {
+ .name = "mcc",
+ .long_name = NULL_IF_CONFIG_SMALL("MacCaption"),
+ .priv_data_size = sizeof(MCCContext),
+ .read_probe = mcc_probe,
+ .read_header = mcc_read_header,
+ .read_packet = mcc_read_packet,
+ .read_seek2 = mcc_read_seek,
+ .read_close = mcc_read_close,
+ .extensions = "mcc",
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/microdvddec.c b/chromium/third_party/ffmpeg/libavformat/microdvddec.c
index 08e6fca09cc..1f871b25182 100644
--- a/chromium/third_party/ffmpeg/libavformat/microdvddec.c
+++ b/chromium/third_party/ffmpeg/libavformat/microdvddec.c
@@ -81,7 +81,7 @@ static int microdvd_read_header(AVFormatContext *s)
AVRational pts_info = (AVRational){ 2997, 125 }; /* default: 23.976 fps */
MicroDVDContext *microdvd = s->priv_data;
AVStream *st = avformat_new_stream(s, NULL);
- int i = 0;
+ int i = 0, ret;
char line_buf[MAX_LINESIZE];
int has_real_fps = 0;
@@ -94,6 +94,7 @@ static int microdvd_read_header(AVFormatContext *s)
int64_t pos = avio_tell(s->pb);
int len = ff_get_line(s->pb, line_buf, sizeof(line_buf));
char *line = line_buf;
+ int64_t pts;
if (!strncmp(line, bom, 3))
line += 3;
@@ -117,10 +118,10 @@ static int microdvd_read_header(AVFormatContext *s)
continue;
}
if (!st->codecpar->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
- int ret, size = strlen(line + 11);
+ int size = strlen(line + 11);
ret = ff_alloc_extradata(st->codecpar, size);
if (ret < 0)
- return ret;
+ goto fail;
memcpy(st->codecpar->extradata, line + 11, size);
continue;
}
@@ -137,11 +138,16 @@ static int microdvd_read_header(AVFormatContext *s)
SKIP_FRAME_ID;
if (!*p)
continue;
+ pts = get_pts(line);
+ if (pts == AV_NOPTS_VALUE)
+ continue;
sub = ff_subtitles_queue_insert(&microdvd->q, p, strlen(p), 0);
- if (!sub)
- return AVERROR(ENOMEM);
+ if (!sub) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
sub->pos = pos;
- sub->pts = get_pts(line);
+ sub->pts = pts;
sub->duration = get_duration(line);
}
ff_subtitles_queue_finalize(s, &microdvd->q);
@@ -156,6 +162,9 @@ static int microdvd_read_header(AVFormatContext *s)
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codecpar->codec_id = AV_CODEC_ID_MICRODVD;
return 0;
+fail:
+ ff_subtitles_queue_clean(&microdvd->q);
+ return ret;
}
static int microdvd_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/mlvdec.c b/chromium/third_party/ffmpeg/libavformat/mlvdec.c
index dae13cae53a..03aed710244 100644
--- a/chromium/third_party/ffmpeg/libavformat/mlvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mlvdec.c
@@ -393,10 +393,14 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
{
MlvContext *mlv = avctx->priv_data;
AVIOContext *pb;
- AVStream *st = avctx->streams[mlv->stream_index];
+ AVStream *st;
int index, ret;
unsigned int size, space;
+ if (!avctx->nb_streams)
+ return AVERROR_EOF;
+
+ st = avctx->streams[mlv->stream_index];
if (mlv->pts >= st->duration)
return AVERROR_EOF;
diff --git a/chromium/third_party/ffmpeg/libavformat/mm.c b/chromium/third_party/ffmpeg/libavformat/mm.c
index d40fd12accc..02ffbcd8242 100644
--- a/chromium/third_party/ffmpeg/libavformat/mm.c
+++ b/chromium/third_party/ffmpeg/libavformat/mm.c
@@ -175,6 +175,8 @@ static int read_packet(AVFormatContext *s,
return 0;
case MM_TYPE_AUDIO :
+ if (s->nb_streams < 2)
+ return AVERROR_INVALIDDATA;
if ((ret = av_get_packet(s->pb, pkt, length)) < 0)
return ret;
pkt->stream_index = 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/mmsh.c b/chromium/third_party/ffmpeg/libavformat/mmsh.c
index 13c0ffe4387..495d7fb73ba 100644
--- a/chromium/third_party/ffmpeg/libavformat/mmsh.c
+++ b/chromium/third_party/ffmpeg/libavformat/mmsh.c
@@ -65,8 +65,7 @@ static int mmsh_close(URLContext *h)
{
MMSHContext *mmsh = (MMSHContext *)h->priv_data;
MMSContext *mms = &mmsh->mms;
- if (mms->mms_hd)
- ffurl_closep(&mms->mms_hd);
+ ffurl_closep(&mms->mms_hd);
av_freep(&mms->streams);
av_freep(&mms->asf_header);
return 0;
@@ -265,7 +264,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim
}
// close the socket and then reopen it for sending the second play request.
- ffurl_close(mms->mms_hd);
+ ffurl_closep(&mms->mms_hd);
memset(headers, 0, sizeof(headers));
if ((err = ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ,
&h->interrupt_callback)) < 0) {
diff --git a/chromium/third_party/ffmpeg/libavformat/mmst.c b/chromium/third_party/ffmpeg/libavformat/mmst.c
index 533cbe76986..377323fe274 100644
--- a/chromium/third_party/ffmpeg/libavformat/mmst.c
+++ b/chromium/third_party/ffmpeg/libavformat/mmst.c
@@ -473,7 +473,7 @@ static int mms_close(URLContext *h)
MMSContext *mms = &mmst->mms;
if(mms->mms_hd) {
send_close_packet(mmst);
- ffurl_close(mms->mms_hd);
+ ffurl_closep(&mms->mms_hd);
}
/* free all separately allocated pointers in mms */
diff --git a/chromium/third_party/ffmpeg/libavformat/mov.c b/chromium/third_party/ffmpeg/libavformat/mov.c
index 2fc5bd65286..88faea491c4 100644
--- a/chromium/third_party/ffmpeg/libavformat/mov.c
+++ b/chromium/third_party/ffmpeg/libavformat/mov.c
@@ -181,7 +181,6 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
{
- AVPacket pkt;
AVStream *st;
MOVStreamContext *sc;
enum AVCodecID id;
@@ -205,12 +204,12 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
return AVERROR(ENOMEM);
st->priv_data = sc;
- ret = av_get_packet(pb, &pkt, len);
+ ret = av_get_packet(pb, &st->attached_pic, len);
if (ret < 0)
return ret;
- if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
- if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
+ if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
+ if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
id = AV_CODEC_ID_PNG;
} else {
id = AV_CODEC_ID_MJPEG;
@@ -219,7 +218,6 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
- st->attached_pic = pkt;
st->attached_pic.stream_index = st->index;
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
@@ -299,7 +297,7 @@ static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- char tmp_key[5];
+ char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
char key2[32], language[4] = {0};
char *str = NULL;
const char *key = NULL;
@@ -446,8 +444,7 @@ retry:
str_size = atom.size;
if (c->export_all && !key) {
- snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
- key = tmp_key;
+ key = av_fourcc_make_string(tmp_key, atom.type);
}
if (!key)
@@ -646,7 +643,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_skip(pb, 16);
for (type = 0; type != -1 && avio_tell(pb) < next; ) {
- if(avio_feof(pb))
+ if (avio_feof(pb))
return AVERROR_EOF;
type = avio_rb16(pb);
len = avio_rb16(pb);
@@ -859,26 +856,20 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- const uint32_t ddts_size = 20;
+#define DDTS_SIZE 20
+ uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
AVStream *st = NULL;
- uint8_t *buf = NULL;
uint32_t frame_duration_code = 0;
uint32_t channel_layout_code = 0;
GetBitContext gb;
+ int ret;
- buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!buf) {
- return AVERROR(ENOMEM);
- }
- if (avio_read(pb, buf, ddts_size) < ddts_size) {
- av_free(buf);
- return AVERROR_INVALIDDATA;
- }
+ if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
+ return ret;
- init_get_bits(&gb, buf, 8*ddts_size);
+ init_get_bits(&gb, buf, 8 * DDTS_SIZE);
if (c->fc->nb_streams < 1) {
- av_free(buf);
return 0;
}
st = c->fc->streams[c->fc->nb_streams-1];
@@ -886,7 +877,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
st->codecpar->sample_rate = get_bits_long(&gb, 32);
if (st->codecpar->sample_rate <= 0) {
av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
- av_free(buf);
return AVERROR_INVALIDDATA;
}
skip_bits_long(&gb, 32); /* max bitrate */
@@ -903,7 +893,7 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
(frame_duration_code == 3) ? 4096 : 0;
if (channel_layout_code > 0xff) {
- av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
+ av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
}
st->codecpar->channel_layout =
((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
@@ -914,7 +904,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
- av_free(buf);
return 0;
}
@@ -1119,7 +1108,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
comp_brand_size = atom.size - 8;
- if (comp_brand_size < 0)
+ if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
return AVERROR_INVALIDDATA;
comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
if (!comp_brands_str)
@@ -1318,7 +1307,7 @@ static int update_frag_index(MOVContext *c, int64_t offset)
&c->frag_index.allocated_size,
(c->frag_index.nb_items + 1) *
sizeof(*c->frag_index.item));
- if(!item)
+ if (!item)
return -1;
c->frag_index.item = item;
@@ -1402,7 +1391,7 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
{
if (time) {
- if(time >= 2082844800)
+ if (time >= 2082844800)
time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
@@ -1576,8 +1565,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
ret = ffio_read_size(pb, icc_profile, atom.size - 4);
if (ret < 0)
return ret;
- }
- else {
+ } else {
color_primaries = avio_rb16(pb);
color_trc = avio_rb16(pb);
color_matrix = avio_rb16(pb);
@@ -1730,7 +1718,7 @@ static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
- if(ret == 0)
+ if (!ret)
ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
return ret;
}
@@ -2351,18 +2339,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
uint32_t format = AV_RB32(st->codecpar->extradata + 22);
if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
- if (str_size > 0 && size >= (int)str_size + 26) {
+ if (str_size > 0 && size >= (int)str_size + 30 &&
+ st->codecpar->extradata[30] /* Don't add empty string */) {
char *reel_name = av_malloc(str_size + 1);
if (!reel_name)
return AVERROR(ENOMEM);
memcpy(reel_name, st->codecpar->extradata + 30, str_size);
reel_name[str_size] = 0; /* Add null terminator */
- /* don't add reel_name if emtpy string */
- if (*reel_name == 0) {
- av_free(reel_name);
- } else {
- av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
- }
+ av_dict_set(&st->metadata, "reel_name", reel_name,
+ AV_DICT_DONT_STRDUP_VAL);
}
}
}
@@ -2559,11 +2544,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
/* Move the current stream extradata to the stream context one. */
sc->extradata_size[pseudo_stream_id] = extra_size;
- sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!sc->extradata[pseudo_stream_id])
- return AVERROR(ENOMEM);
- memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
- av_freep(&st->codecpar->extradata);
+ sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
+ st->codecpar->extradata = NULL;
st->codecpar->extradata_size = 0;
}
sc->stsd_count++;
@@ -2798,8 +2780,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
- if (!entries)
- {
+ if (!entries) {
sc->keyframe_absent = 1;
if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
@@ -2927,8 +2908,8 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
AVStream *st;
MOVStreamContext *sc;
unsigned int i, entries, alloc_size = 0;
- int64_t duration=0;
- int64_t total_sample_count=0;
+ int64_t duration = 0;
+ int64_t total_sample_count = 0;
if (c->fc->nb_streams < 1)
return 0;
@@ -2963,7 +2944,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->stts_count = min_entries;
sc->stts_data = stts_data;
- sample_count=avio_rb32(pb);
+ sample_count = avio_rb32(pb);
sample_duration = avio_rb32(pb);
sc->stts_data[i].count= sample_count;
@@ -2980,8 +2961,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (duration > 0 &&
duration <= INT64_MAX - sc->duration_for_fps &&
- total_sample_count <= INT_MAX - sc->nb_frames_for_fps
- ) {
+ total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
sc->duration_for_fps += duration;
sc->nb_frames_for_fps += total_sample_count;
}
@@ -3070,8 +3050,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR(ENOMEM);
for (i = 0; i < entries && !pb->eof_reached; i++) {
- int count =avio_rb32(pb);
- int duration =avio_rb32(pb);
+ int count = avio_rb32(pb);
+ int duration = avio_rb32(pb);
if (count <= 0) {
av_log(c->fc, AV_LOG_TRACE,
@@ -3311,13 +3291,13 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
min_size_needed;
- if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
+ if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
return -1;
entries = av_fast_realloc(st->index_entries,
&st->index_entries_allocated_size,
requested_size);
- if(!entries)
+ if (!entries)
return -1;
st->index_entries= entries;
@@ -3362,12 +3342,12 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
FFMAX(min_size_needed, 2 * (*allocated_size)) :
min_size_needed;
- if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
+ if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
return -1;
ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
- if(!ctts_buf_new)
+ if (!ctts_buf_new)
return -1;
*ctts_data = ctts_buf_new;
@@ -3380,7 +3360,8 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
}
#define MAX_REORDER_DELAY 16
-static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
+static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
+{
MOVStreamContext *msc = st->priv_data;
int ind;
int ctts_ind = 0;
@@ -3395,7 +3376,7 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
st->codecpar->codec_id == AV_CODEC_ID_H264) {
st->codecpar->video_delay = 0;
- for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
+ for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
// Point j to the last elem of the buffer and insert the current pts there.
j = buf_start;
buf_start = (buf_start + 1);
@@ -4193,10 +4174,10 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr
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))
+ 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);
}
@@ -4451,6 +4432,9 @@ static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
} else
break;
+ if (*p)
+ break;
+
*p = av_malloc(len + 1);
if (!*p) {
ret = AVERROR(ENOMEM);
@@ -4827,8 +4811,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
frag_stream_info = get_current_frag_stream_info(&c->frag_index);
- if (frag_stream_info)
- {
+ if (frag_stream_info) {
if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
dts = frag_stream_info->next_trun_dts - sc->time_offset;
} else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
@@ -4877,7 +4860,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
new_entries = av_fast_realloc(st->index_entries,
&st->index_entries_allocated_size,
requested_size);
- if(!new_entries)
+ if (!new_entries)
return AVERROR(ENOMEM);
st->index_entries= new_entries;
@@ -5048,8 +5031,9 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
+ int64_t stream_size = avio_size(pb);
int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
- uint8_t version;
+ uint8_t version, is_complete;
unsigned i, j, track_id, item_count;
AVStream *st = NULL;
AVStream *ref_st = NULL;
@@ -5126,7 +5110,22 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->has_sidx = 1;
- if (offset == avio_size(pb)) {
+ // See if the remaining bytes are just an mfra which we can ignore.
+ is_complete = offset == stream_size;
+ if (!is_complete) {
+ int ret;
+ int64_t original_pos = avio_tell(pb);
+ int32_t mfra_size;
+ if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
+ return ret;
+ mfra_size = avio_rb32(pb);
+ if (offset + mfra_size == stream_size)
+ is_complete = 1;
+ if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
+ return ret;
+ }
+
+ if (is_complete) {
// Find first entry in fragment index that came from an sidx.
// This will pretty much always be the first entry.
for (i = 0; i < c->frag_index.nb_items; i++) {
@@ -5256,7 +5255,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
} else {
edit_count = atom.size / elst_entry_size;
if (edit_count * elst_entry_size != atom.size) {
- av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
+ av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
}
}
}
@@ -5791,12 +5790,9 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
st = c->fc->streams[c->fc->nb_streams - 1];
sc = st->priv_data;
- ret = avio_read(pb, uuid, sizeof(uuid));
- if (ret < 0) {
+ ret = ffio_read_size(pb, uuid, sizeof(uuid));
+ if (ret < 0)
return ret;
- } else if (ret != sizeof(uuid)) {
- return AVERROR_INVALIDDATA;
- }
if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
uint8_t *buffer, *ptr;
char *endptr;
@@ -5812,13 +5808,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (!buffer) {
return AVERROR(ENOMEM);
}
- ret = avio_read(pb, buffer, len);
+ ret = ffio_read_size(pb, buffer, len);
if (ret < 0) {
av_free(buffer);
return ret;
- } else if (ret != len) {
- av_free(buffer);
- return AVERROR_INVALIDDATA;
}
ptr = buffer;
@@ -5849,13 +5842,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (!buffer) {
return AVERROR(ENOMEM);
}
- ret = avio_read(pb, buffer, len);
+ ret = ffio_read_size(pb, buffer, len);
if (ret < 0) {
av_free(buffer);
return ret;
- } else if (ret != len) {
- av_free(buffer);
- return AVERROR_INVALIDDATA;
}
buffer[len] = '\0';
av_dict_set(&c->fc->metadata, "xmp",
@@ -5999,7 +5989,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
{
- int i;
+ int i, ret;
unsigned int subsample_count;
AVSubsampleEncryptionInfo *subsamples;
@@ -6013,11 +6003,11 @@ static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVSt
return AVERROR(ENOMEM);
if (sc->cenc.per_sample_iv_size != 0) {
- if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
+ if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
av_encryption_info_free(*sample);
*sample = NULL;
- return AVERROR_INVALIDDATA;
+ return ret;
}
}
@@ -6385,9 +6375,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (!info)
return AVERROR(ENOMEM);
- if (avio_read(pb, info->system_id, 16) != 16) {
+ if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
- ret = AVERROR_INVALIDDATA;
goto finish;
}
@@ -6415,9 +6404,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
}
info->num_key_ids = i + 1;
- if (avio_read(pb, info->key_ids[i], 16) != 16) {
+ if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
- ret = AVERROR_INVALIDDATA;
goto finish;
}
}
@@ -6638,15 +6626,13 @@ static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *s
av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
- if (!sample->subsample_count)
- {
+ if (!sample->subsample_count) {
/* decrypt the whole packet */
av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
return 0;
}
- for (i = 0; i < sample->subsample_count; i++)
- {
+ for (i = 0; i < sample->subsample_count; i++) {
if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
return AVERROR_INVALIDDATA;
@@ -6855,7 +6841,7 @@ static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
(uint8_t *)dovi, dovi_size);
if (ret < 0) {
- av_freep(dovi);
+ av_free(dovi);
return ret;
}
@@ -6997,22 +6983,20 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
a.type == MKTAG('h','o','o','v')) &&
a.size >= 8 &&
c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
- uint8_t buf[8];
- uint32_t *type = (uint32_t *)buf + 1;
- if (avio_read(pb, buf, 8) != 8)
- return AVERROR_INVALIDDATA;
+ uint32_t type;
+ avio_skip(pb, 4);
+ type = avio_rl32(pb);
avio_seek(pb, -8, SEEK_CUR);
- if (*type == MKTAG('m','v','h','d') ||
- *type == MKTAG('c','m','o','v')) {
+ if (type == MKTAG('m','v','h','d') ||
+ type == MKTAG('c','m','o','v')) {
av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
a.type = MKTAG('m','o','o','v');
}
}
if (atom.type != MKTAG('r','o','o','t') &&
- atom.type != MKTAG('m','o','o','v'))
- {
- if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
- {
+ atom.type != MKTAG('m','o','o','v')) {
+ if (a.type == MKTAG('t','r','a','k') ||
+ a.type == MKTAG('m','d','a','t')) {
av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
avio_skip(pb, -8);
c->atom_depth --;
@@ -7050,7 +7034,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
if (!parse && c->found_hdlr_mdta &&
atom.type == MKTAG('m','e','t','a') &&
- a.type == MKTAG('k','e','y','s')) {
+ a.type == MKTAG('k','e','y','s') &&
+ c->meta_keys_count == 0) {
parse = mov_read_keys;
}
@@ -7077,8 +7062,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_skip(pb, left);
else if (left < 0) {
av_log(c->fc, AV_LOG_WARNING,
- "overread end of atom '%.4s' by %"PRId64" bytes\n",
- (char*)&a.type, -left);
+ "overread end of atom '%s' by %"PRId64" bytes\n",
+ av_fourcc2str(a.type), -left);
avio_seek(pb, left, SEEK_CUR);
}
}
@@ -7151,25 +7136,26 @@ static int mov_probe(const AVProbeData *p)
offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
}
}
- if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
+ if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
/* moov atom in the header - we should make sure that this is not a
* MOV-packed MPEG-PS */
offset = moov_offset;
- while(offset < (p->buf_size - 16)){ /* Sufficient space */
+ while (offset < (p->buf_size - 16)) { /* Sufficient space */
/* We found an actual hdlr atom */
- if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
- AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
- AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
+ if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
+ AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
+ AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
/* We found a media handler reference atom describing an
* MPEG-PS-in-MOV, return a
* low score to force expanding the probe window until
* mpegps_probe finds what it needs */
return 5;
- }else
+ } else {
/* Keep looking */
- offset+=2;
+ offset += 2;
+ }
}
}
@@ -7206,17 +7192,15 @@ static void mov_read_chapters(AVFormatContext *s)
st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
if (st->nb_index_entries) {
// Retrieve the first frame, if possible
- AVPacket pkt;
AVIndexEntry *sample = &st->index_entries[0];
if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
goto finish;
}
- if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
+ if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
goto finish;
- st->attached_pic = pkt;
st->attached_pic.stream_index = st->index;
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
}
@@ -7410,10 +7394,9 @@ static int mov_read_close(AVFormatContext *s)
av_freep(&sc->coll);
}
- if (mov->dv_demux) {
- avformat_free_context(mov->dv_fctx);
- mov->dv_fctx = NULL;
- }
+ av_freep(&mov->dv_demux);
+ avformat_free_context(mov->dv_fctx);
+ mov->dv_fctx = NULL;
if (mov->meta_keys) {
for (i = 1; i < mov->meta_keys_count; i++) {
@@ -7602,14 +7585,13 @@ static int mov_read_header(AVFormatContext *s)
avio_seek(pb, 0, SEEK_SET);
if ((err = mov_read_default(mov, pb, atom)) < 0) {
av_log(s, AV_LOG_ERROR, "error reading header\n");
- mov_read_close(s);
- return err;
+ goto fail;
}
} while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
if (!mov->found_moov) {
av_log(s, AV_LOG_ERROR, "moov atom not found\n");
- mov_read_close(s);
- return AVERROR_INVALIDDATA;
+ err = AVERROR_INVALIDDATA;
+ goto fail;
}
av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
@@ -7649,7 +7631,8 @@ static int mov_read_header(AVFormatContext *s)
AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
fix_timescale(mov, sc);
- if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
+ st->codecpar->codec_id == AV_CODEC_ID_AAC) {
st->skip_samples = sc->start_pad;
}
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
@@ -7662,13 +7645,12 @@ static int mov_read_header(AVFormatContext *s)
}
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
- return err;
+ goto fail;
}
}
if (mov->handbrake_version &&
mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
- st->codecpar->codec_id == AV_CODEC_ID_MP3
- ) {
+ st->codecpar->codec_id == AV_CODEC_ID_MP3) {
av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
st->need_parsing = AVSTREAM_PARSE_FULL;
}
@@ -7682,8 +7664,8 @@ static int mov_read_header(AVFormatContext *s)
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
sc->data_size, sc->time_scale);
- mov_read_close(s);
- return AVERROR_INVALIDDATA;
+ err = AVERROR_INVALIDDATA;
+ goto fail;
}
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
}
@@ -7698,8 +7680,8 @@ static int mov_read_header(AVFormatContext *s)
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
sc->data_size, sc->time_scale);
- mov_read_close(s);
- return AVERROR_INVALIDDATA;
+ err = AVERROR_INVALIDDATA;
+ goto fail;
}
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
sc->duration_for_fps;
@@ -7722,17 +7704,15 @@ static int mov_read_header(AVFormatContext *s)
switch (st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
err = ff_replaygain_export(st, s->metadata);
- if (err < 0) {
- mov_read_close(s);
- return err;
- }
+ if (err < 0)
+ goto fail;
break;
case AVMEDIA_TYPE_VIDEO:
if (sc->display_matrix) {
err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
sizeof(int32_t) * 9);
if (err < 0)
- return err;
+ goto fail;
sc->display_matrix = NULL;
}
@@ -7741,7 +7721,7 @@ static int mov_read_header(AVFormatContext *s)
(uint8_t *)sc->stereo3d,
sizeof(*sc->stereo3d));
if (err < 0)
- return err;
+ goto fail;
sc->stereo3d = NULL;
}
@@ -7750,7 +7730,7 @@ static int mov_read_header(AVFormatContext *s)
(uint8_t *)sc->spherical,
sc->spherical_size);
if (err < 0)
- return err;
+ goto fail;
sc->spherical = NULL;
}
@@ -7759,7 +7739,7 @@ static int mov_read_header(AVFormatContext *s)
(uint8_t *)sc->mastering,
sizeof(*sc->mastering));
if (err < 0)
- return err;
+ goto fail;
sc->mastering = NULL;
}
@@ -7768,7 +7748,7 @@ static int mov_read_header(AVFormatContext *s)
(uint8_t *)sc->coll,
sc->coll_size);
if (err < 0)
- return err;
+ goto fail;
sc->coll = NULL;
}
@@ -7782,6 +7762,9 @@ static int mov_read_header(AVFormatContext *s)
mov->frag_index.item[i].headers_read = 1;
return 0;
+fail:
+ mov_read_close(s);
+ return err;
}
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
@@ -7876,6 +7859,27 @@ static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
return 0;
}
+static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
+{
+ int new_size, ret;
+
+ if (size <= 8)
+ return AVERROR_INVALIDDATA;
+ new_size = ((size - 8) / 2) * 3;
+ ret = av_new_packet(pkt, new_size);
+ if (ret < 0)
+ return ret;
+
+ avio_skip(pb, 8);
+ for (int j = 0; j < new_size; j += 3) {
+ pkt->data[j] = 0xFC;
+ pkt->data[j+1] = avio_r8(pb);
+ pkt->data[j+2] = avio_r8(pb);
+ }
+
+ return 0;
+}
+
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
{
MOVContext *mov = s->priv_data;
@@ -7915,18 +7919,34 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR_INVALIDDATA;
}
- if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
+ if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
goto retry;
}
- ret = av_get_packet(sc->pb, pkt, sample->size);
+ if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
+ ret = get_eia608_packet(sc->pb, pkt, sample->size);
+ else
+ ret = av_get_packet(sc->pb, pkt, sample->size);
if (ret < 0) {
if (should_retry(sc->pb, ret)) {
mov_current_sample_dec(sc);
}
return ret;
}
+#if CONFIG_DV_DEMUXER
+ if (mov->dv_demux && sc->dv_audio_container) {
+ AVBufferRef *buf = pkt->buf;
+ ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
+ pkt->buf = buf;
+ av_packet_unref(pkt);
+ if (ret < 0)
+ return ret;
+ ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
+ if (ret < 0)
+ return ret;
+ }
+#endif
if (sc->has_palette) {
uint8_t *pal;
@@ -7938,16 +7958,6 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
sc->has_palette = 0;
}
}
-#if CONFIG_DV_DEMUXER
- if (mov->dv_demux && sc->dv_audio_container) {
- avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
- av_freep(&pkt->data);
- pkt->size = 0;
- ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
- if (ret < 0)
- return ret;
- }
-#endif
if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
st->need_parsing = AVSTREAM_PARSE_FULL;
@@ -8073,17 +8083,17 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
/* adjust stsd index */
if (sc->chunk_count) {
- time_sample = 0;
- for (i = 0; i < sc->stsc_count; i++) {
- int64_t next = time_sample + mov_get_stsc_samples(sc, i);
- if (next > sc->current_sample) {
- sc->stsc_index = i;
- sc->stsc_sample = sc->current_sample - time_sample;
- break;
+ time_sample = 0;
+ for (i = 0; i < sc->stsc_count; i++) {
+ int64_t next = time_sample + mov_get_stsc_samples(sc, i);
+ if (next > sc->current_sample) {
+ sc->stsc_index = i;
+ sc->stsc_sample = sc->current_sample - time_sample;
+ break;
+ }
+ av_assert0(next == (int)next);
+ time_sample = next;
}
- av_assert0(next == (int)next);
- time_sample = next;
- }
}
return sample;
diff --git a/chromium/third_party/ffmpeg/libavformat/movenc.c b/chromium/third_party/ffmpeg/libavformat/movenc.c
index 32e81092687..7db2e288407 100644
--- a/chromium/third_party/ffmpeg/libavformat/movenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/movenc.c
@@ -4798,28 +4798,40 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
{
- int64_t pos = avio_tell(pb);
- int i;
+ AVIOContext *mfra_pb;
+ int i, ret, sz;
+ uint8_t *buf;
- avio_wb32(pb, 0); /* size placeholder */
- ffio_wfourcc(pb, "mfra");
+ ret = avio_open_dyn_buf(&mfra_pb);
+ if (ret < 0)
+ return ret;
+
+ avio_wb32(mfra_pb, 0); /* size placeholder */
+ ffio_wfourcc(mfra_pb, "mfra");
/* An empty mfra atom is enough to indicate to the publishing point that
* the stream has ended. */
if (mov->flags & FF_MOV_FLAG_ISML)
- return update_size(pb, pos);
+ goto done_mfra;
for (i = 0; i < mov->nb_streams; i++) {
MOVTrack *track = &mov->tracks[i];
if (track->nb_frag_info)
- mov_write_tfra_tag(pb, track);
+ mov_write_tfra_tag(mfra_pb, track);
}
- avio_wb32(pb, 16);
- ffio_wfourcc(pb, "mfro");
- avio_wb32(pb, 0); /* version + flags */
- avio_wb32(pb, avio_tell(pb) + 4 - pos);
+ avio_wb32(mfra_pb, 16);
+ ffio_wfourcc(mfra_pb, "mfro");
+ avio_wb32(mfra_pb, 0); /* version + flags */
+ avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
- return update_size(pb, pos);
+done_mfra:
+
+ sz = update_size(mfra_pb, 0);
+ ret = avio_get_dyn_buf(mfra_pb, &buf);
+ avio_write(pb, buf, ret);
+ ffio_free_dyn_buf(&mfra_pb);
+
+ return sz;
}
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
@@ -4875,7 +4887,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
{
MOVMuxContext *mov = s->priv_data;
int64_t pos = avio_tell(pb);
- int has_h264 = 0, has_video = 0;
+ int has_h264 = 0, has_av1 = 0, has_video = 0;
int i;
for (i = 0; i < s->nb_streams; i++) {
@@ -4886,6 +4898,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
has_video = 1;
if (st->codecpar->codec_id == AV_CODEC_ID_H264)
has_h264 = 1;
+ if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
+ has_av1 = 1;
}
avio_wb32(pb, 0); /* size */
@@ -4909,6 +4923,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
ffio_wfourcc(pb, "cmfc");
if (mov->flags & FF_MOV_FLAG_FRAGMENT && !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS))
ffio_wfourcc(pb, "iso6");
+ if (has_av1)
+ ffio_wfourcc(pb, "av01");
} else {
if (mov->flags & FF_MOV_FLAG_FRAGMENT)
ffio_wfourcc(pb, "iso6");
@@ -5504,6 +5520,23 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
}
+ if ((par->codec_id == AV_CODEC_ID_DNXHD ||
+ par->codec_id == AV_CODEC_ID_H264 ||
+ par->codec_id == AV_CODEC_ID_HEVC ||
+ par->codec_id == AV_CODEC_ID_TRUEHD ||
+ par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len &&
+ !TAG_IS_AVCI(trk->tag)) {
+ /* copy frame to create needed atoms */
+ trk->vos_len = size;
+ trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!trk->vos_data) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+ memcpy(trk->vos_data, pkt->data, size);
+ memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ }
+
if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -5565,6 +5598,22 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
goto end;
avio_write(pb, pkt->data, size);
#endif
+ } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
+ size = 8;
+
+ for (int i = 0; i < pkt->size; i += 3) {
+ if (pkt->data[i] == 0xFC) {
+ size += 2;
+ }
+ }
+ avio_wb32(pb, size);
+ ffio_wfourcc(pb, "cdat");
+ for (int i = 0; i < pkt->size; i += 3) {
+ if (pkt->data[i] == 0xFC) {
+ avio_w8(pb, pkt->data[i + 1]);
+ avio_w8(pb, pkt->data[i + 2]);
+ }
+ }
} else {
if (trk->cenc.aes_ctr) {
if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
@@ -5582,20 +5631,6 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
}
}
- if ((par->codec_id == AV_CODEC_ID_DNXHD ||
- par->codec_id == AV_CODEC_ID_TRUEHD ||
- par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
- /* copy frame to create needed atoms */
- trk->vos_len = size;
- trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!trk->vos_data) {
- ret = AVERROR(ENOMEM);
- goto err;
- }
- memcpy(trk->vos_data, pkt->data, size);
- memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- }
-
if (trk->entry >= trk->cluster_capacity) {
unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
if (av_reallocp_array(&trk->cluster, new_capacity,
@@ -5765,7 +5800,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
trk->par->codec_id == AV_CODEC_ID_AAC ||
trk->par->codec_id == AV_CODEC_ID_AV1 ||
trk->par->codec_id == AV_CODEC_ID_FLAC) {
- int side_size = 0;
+ int side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
@@ -6964,7 +6999,9 @@ static int mov_write_trailer(AVFormatContext *s)
}
if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
- mov_write_mfra_tag(pb, mov);
+ res = mov_write_mfra_tag(pb, mov);
+ if (res < 0)
+ return res;
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mp3enc.c b/chromium/third_party/ffmpeg/libavformat/mp3enc.c
index 34b753ffa06..a3586e1f860 100644
--- a/chromium/third_party/ffmpeg/libavformat/mp3enc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mp3enc.c
@@ -45,6 +45,7 @@ static int id3v1_set_string(AVFormatContext *s, const char *key,
return !!tag;
}
+// refer to: http://id3.org/ID3v1
static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
{
AVDictionaryEntry *tag;
@@ -58,7 +59,17 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
count += id3v1_set_string(s, "TIT2", buf + 3, 30 + 1); //title
count += id3v1_set_string(s, "TPE1", buf + 33, 30 + 1); //author|artist
count += id3v1_set_string(s, "TALB", buf + 63, 30 + 1); //album
- count += id3v1_set_string(s, "TDRC", buf + 93, 4 + 1); //date
+ if ((tag = av_dict_get(s->metadata, "TYER", NULL, 0))) { //year
+ av_strlcpy(buf + 93, tag->value, 4 + 1);
+ count++;
+ } else if ((tag = av_dict_get(s->metadata, "TDRC", NULL, 0))) {
+ av_strlcpy(buf + 93, tag->value, 4 + 1);
+ count++;
+ } else if ((tag = av_dict_get(s->metadata, "TDAT", NULL, 0))) {
+ av_strlcpy(buf + 93, tag->value, 4 + 1);
+ count++;
+ }
+
count += id3v1_set_string(s, "comment", buf + 97, 30 + 1);
if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
buf[125] = 0;
@@ -343,7 +354,7 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
if (mp3->xing_offset) {
uint8_t *side_data = NULL;
- int side_data_size = 0;
+ int side_data_size;
mp3_xing_add_frame(mp3, pkt);
mp3->audio_size += pkt->size;
diff --git a/chromium/third_party/ffmpeg/libavformat/mpeg.c b/chromium/third_party/ffmpeg/libavformat/mpeg.c
index 33c03980606..265b2bd1adb 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpeg.c
@@ -99,7 +99,7 @@ static int mpegps_probe(const AVProbeData *p)
if (sys > invalid && sys * 9 <= pspack * 10)
return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2
- : AVPROBE_SCORE_EXTENSION / 2 + 1; // 1 more than mp3
+ : AVPROBE_SCORE_EXTENSION / 2 + (audio + vid + pspack > 1); // 1 more than mp3
if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9)
return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2
: AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegenc.c b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
index 669ff9d152b..9bd0a555d46 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
@@ -1210,7 +1210,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
if (s->is_dvd) {
// min VOBU length 0.4 seconds (mpucoder)
if (is_iframe &&
- (s->packet_number == 0 ||
+ (s->packet_number == 0 || pts != AV_NOPTS_VALUE &&
(pts - stream->vobu_start_pts >= 36000))) {
stream->bytes_to_iframe = av_fifo_size(stream->fifo);
stream->align_iframe = 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegts.c b/chromium/third_party/ffmpeg/libavformat/mpegts.c
index ff3898c3a56..f71f18a57d9 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegts.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegts.c
@@ -123,10 +123,6 @@ struct MpegTSContext {
/** raw packet size, including FEC if present */
int raw_packet_size;
- int size_stat[3];
- int size_stat_count;
-#define SIZE_STAT_THRESHOLD 10
-
int64_t pos47_full;
/** if true, all pids are analyzed to find streams */
@@ -514,20 +510,22 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts,
{
MpegTSFilter *filter;
MpegTSSectionFilter *sec;
+ uint8_t *section_buf = av_mallocz(MAX_SECTION_SIZE);
+
+ if (!section_buf)
+ return NULL;
- if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION)))
+ if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION))) {
+ av_free(section_buf);
return NULL;
+ }
sec = &filter->u.section_filter;
sec->section_cb = section_cb;
sec->opaque = opaque;
- sec->section_buf = av_mallocz(MAX_SECTION_SIZE);
+ sec->section_buf = section_buf;
sec->check_crc = check_crc;
sec->last_ver = -1;
- if (!sec->section_buf) {
- av_free(filter);
- return NULL;
- }
return filter;
}
@@ -2180,7 +2178,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
(uint8_t *)dovi, dovi_size);
if (ret < 0) {
- av_freep(dovi);
+ av_free(dovi);
return ret;
}
@@ -2840,63 +2838,39 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet, int64_t pos)
return 0;
}
-static void reanalyze(MpegTSContext *ts) {
- AVIOContext *pb = ts->stream->pb;
- int64_t pos = avio_tell(pb);
- if (pos < 0)
- return;
- pos -= ts->pos47_full;
- if (pos == TS_PACKET_SIZE) {
- ts->size_stat[0] ++;
- } else if (pos == TS_DVHS_PACKET_SIZE) {
- ts->size_stat[1] ++;
- } else if (pos == TS_FEC_PACKET_SIZE) {
- ts->size_stat[2] ++;
- }
-
- ts->size_stat_count ++;
- if (ts->size_stat_count > SIZE_STAT_THRESHOLD) {
- int newsize = 0;
- if (ts->size_stat[0] > SIZE_STAT_THRESHOLD) {
- newsize = TS_PACKET_SIZE;
- } else if (ts->size_stat[1] > SIZE_STAT_THRESHOLD) {
- newsize = TS_DVHS_PACKET_SIZE;
- } else if (ts->size_stat[2] > SIZE_STAT_THRESHOLD) {
- newsize = TS_FEC_PACKET_SIZE;
- }
- if (newsize && newsize != ts->raw_packet_size) {
- av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", newsize);
- ts->raw_packet_size = newsize;
- }
- ts->size_stat_count = 0;
- memset(ts->size_stat, 0, sizeof(ts->size_stat));
- }
-}
-
-/* XXX: try to find a better synchro over several packets (use
- * get_packet_size() ?) */
static int mpegts_resync(AVFormatContext *s, int seekback, const uint8_t *current_packet)
{
MpegTSContext *ts = s->priv_data;
AVIOContext *pb = s->pb;
int c, i;
uint64_t pos = avio_tell(pb);
-
- avio_seek(pb, -FFMIN(seekback, pos), SEEK_CUR);
+ int64_t back = FFMIN(seekback, pos);
//Special case for files like 01c56b0dc1.ts
if (current_packet[0] == 0x80 && current_packet[12] == 0x47) {
- avio_seek(pb, 12, SEEK_CUR);
+ avio_seek(pb, 12 - back, SEEK_CUR);
return 0;
}
+ avio_seek(pb, -back, SEEK_CUR);
+
for (i = 0; i < ts->resync_size; i++) {
c = avio_r8(pb);
if (avio_feof(pb))
return AVERROR_EOF;
if (c == 0x47) {
+ int new_packet_size, ret;
avio_seek(pb, -1, SEEK_CUR);
- reanalyze(s->priv_data);
+ pos = avio_tell(pb);
+ ret = ffio_ensure_seekback(pb, PROBE_PACKET_MAX_BUF);
+ if (ret < 0)
+ return ret;
+ new_packet_size = get_packet_size(s);
+ if (new_packet_size > 0 && new_packet_size != ts->raw_packet_size) {
+ av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", new_packet_size);
+ ts->raw_packet_size = new_packet_size;
+ }
+ avio_seek(pb, pos, SEEK_SET);
return 0;
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegts.h b/chromium/third_party/ffmpeg/libavformat/mpegts.h
index 059b693f078..fe10b38691b 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegts.h
+++ b/chromium/third_party/ffmpeg/libavformat/mpegts.h
@@ -137,6 +137,13 @@
#define STREAM_TYPE_AUDIO_TRUEHD 0x83
#define STREAM_TYPE_AUDIO_EAC3 0x87
+/* ISO/IEC 13818-1 Table 2-22 */
+#define STREAM_ID_PRIVATE_STREAM_1 0xbd
+#define STREAM_ID_AUDIO_STREAM_0 0xc0
+#define STREAM_ID_VIDEO_STREAM_0 0xe0
+#define STREAM_ID_METADATA_STREAM 0xfc
+#define STREAM_ID_EXTENDED_STREAM_ID 0xfd
+
typedef struct MpegTSContext MpegTSContext;
MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s);
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
index f2be6c66327..718ddabff7e 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
@@ -79,8 +79,6 @@ typedef struct MpegTSWrite {
int64_t sdt_period; /* SDT period in PCR time base */
int64_t pat_period; /* PAT/PMT period in PCR time base */
int nb_services;
- int onid;
- int tsid;
int64_t first_pcr;
int64_t next_pcr;
int mux_rate; ///< set to 1 when VBR
@@ -261,7 +259,7 @@ static void mpegts_write_pat(AVFormatContext *s)
put16(&q, service->sid);
put16(&q, 0xe000 | service->pmt.pid);
}
- mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 0,
+ mpegts_write_section1(&ts->pat, PAT_TID, ts->transport_stream_id, ts->tables_version, 0, 0,
data, q - data);
}
@@ -355,6 +353,13 @@ static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
case AV_CODEC_ID_DVB_TELETEXT:
stream_type = STREAM_TYPE_PRIVATE_DATA;
break;
+ case AV_CODEC_ID_SMPTE_KLV:
+ if (st->codecpar->profile == FF_PROFILE_KLVA_SYNC) {
+ stream_type = STREAM_TYPE_METADATA;
+ } else {
+ stream_type = STREAM_TYPE_PRIVATE_DATA;
+ }
+ break;
default:
av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning,
"Stream %d, codec %s, is muxed as a private data stream "
@@ -448,6 +453,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
AVStream *st = s->streams[i];
MpegTSWriteStream *ts_st = st->priv_data;
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
+ enum AVCodecID codec_id = st->codecpar->codec_id;
if (s->nb_programs) {
int k, found = 0;
@@ -478,19 +484,20 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
/* write optional descriptors here */
switch (st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- if (st->codecpar->codec_id==AV_CODEC_ID_AC3 && (ts->flags & MPEGTS_FLAG_SYSTEM_B)) {
- *q++=0x6a; // AC3 descriptor see A038 DVB SI
- *q++=1; // 1 byte, all flags sets to 0
- *q++=0; // omit all fields...
- }
- if (st->codecpar->codec_id==AV_CODEC_ID_EAC3 && (ts->flags & MPEGTS_FLAG_SYSTEM_B)) {
- *q++=0x7a; // EAC3 descriptor see A038 DVB SI
- *q++=1; // 1 byte, all flags sets to 0
- *q++=0; // omit all fields...
+ if (ts->flags & MPEGTS_FLAG_SYSTEM_B) {
+ if (codec_id == AV_CODEC_ID_AC3) {
+ *q++=0x6a; // AC3 descriptor see A038 DVB SI
+ *q++=1; // 1 byte, all flags sets to 0
+ *q++=0; // omit all fields...
+ } else if (codec_id == AV_CODEC_ID_EAC3) {
+ *q++=0x7a; // EAC3 descriptor see A038 DVB SI
+ *q++=1; // 1 byte, all flags sets to 0
+ *q++=0; // omit all fields...
+ }
}
- if (st->codecpar->codec_id==AV_CODEC_ID_S302M)
+ if (codec_id == AV_CODEC_ID_S302M)
put_registration_descriptor(&q, MKTAG('B', 'S', 'S', 'D'));
- if (st->codecpar->codec_id==AV_CODEC_ID_OPUS) {
+ if (codec_id == AV_CODEC_ID_OPUS) {
/* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */
if (q - data > SECTION_LENGTH - 6 - 4) {
err = 1;
@@ -605,7 +612,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
const char default_language[] = "und";
const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language;
- if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
+ if (codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
uint8_t *len_ptr;
int extradata_copied = 0;
@@ -647,7 +654,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
}
*len_ptr = q - len_ptr - 1;
- } else if (st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+ } else if (codec_id == AV_CODEC_ID_DVB_TELETEXT) {
uint8_t *len_ptr = NULL;
int extradata_copied = 0;
@@ -691,9 +698,9 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
}
break;
case AVMEDIA_TYPE_DATA:
- if (st->codecpar->codec_id == AV_CODEC_ID_SMPTE_KLV) {
+ if (codec_id == AV_CODEC_ID_SMPTE_KLV) {
put_registration_descriptor(&q, MKTAG('K', 'L', 'V', 'A'));
- } else if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
+ } else if (codec_id == AV_CODEC_ID_TIMED_ID3) {
const char *tag = "ID3 ";
*q++ = 0x26; /* metadata descriptor */
*q++ = 13;
@@ -731,7 +738,7 @@ static void mpegts_write_sdt(AVFormatContext *s)
int i, running_status, free_ca_mode, val;
q = data;
- put16(&q, ts->onid);
+ put16(&q, ts->original_network_id);
*q++ = 0xff;
for (i = 0; i < ts->nb_services; i++) {
service = ts->services[i];
@@ -757,7 +764,7 @@ static void mpegts_write_sdt(AVFormatContext *s)
desc_list_len_ptr[0] = val >> 8;
desc_list_len_ptr[1] = val;
}
- mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, ts->tables_version, 0, 0,
+ mpegts_write_section1(&ts->sdt, SDT_TID, ts->transport_stream_id, ts->tables_version, 0, 0,
data, q - data);
}
@@ -931,7 +938,6 @@ static int mpegts_init(AVFormatContext *s)
{
MpegTSWrite *ts = s->priv_data;
int i, j;
- int *pids;
int ret;
if (ts->m2ts_mode == -1) {
@@ -961,8 +967,6 @@ static int mpegts_init(AVFormatContext *s)
// round up to a whole number of TS packets
ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
- ts->tsid = ts->transport_stream_id;
- ts->onid = ts->original_network_id;
if (!s->nb_programs) {
/* allocate a single DVB service */
if (!mpegts_add_service(s, ts->service_id, s->metadata, NULL))
@@ -989,12 +993,6 @@ static int mpegts_init(AVFormatContext *s)
ts->sdt.write_packet = section_write_packet;
ts->sdt.opaque = s;
- pids = av_malloc_array(s->nb_streams, sizeof(*pids));
- if (!pids) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
/* assign pids to each stream */
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
@@ -1002,8 +1000,7 @@ static int mpegts_init(AVFormatContext *s)
ts_st = av_mallocz(sizeof(MpegTSWriteStream));
if (!ts_st) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
st->priv_data = ts_st;
@@ -1011,8 +1008,7 @@ static int mpegts_init(AVFormatContext *s)
ts_st->payload = av_mallocz(ts->pes_payload_size);
if (!ts_st->payload) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
/* MPEG pid values < 16 are reserved. Applications which set st->id in
@@ -1043,8 +1039,7 @@ static int mpegts_init(AVFormatContext *s)
ts->m2ts_textsub_pid > M2TS_TEXTSUB_PID + 1 ||
ts_st->pid < 16) {
av_log(s, AV_LOG_ERROR, "Cannot automatically assign PID for stream %d\n", st->index);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
} else {
ts_st->pid = ts->start_pid + i;
@@ -1055,30 +1050,26 @@ static int mpegts_init(AVFormatContext *s)
if (ts_st->pid >= 0x1FFF) {
av_log(s, AV_LOG_ERROR,
"Invalid stream id %d, must be less than 8191\n", st->id);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
for (j = 0; j < ts->nb_services; j++) {
if (ts->services[j]->pmt.pid > LAST_OTHER_PID) {
av_log(s, AV_LOG_ERROR,
"Invalid PMT PID %d, must be less than %d\n", ts->services[j]->pmt.pid, LAST_OTHER_PID + 1);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
if (ts_st->pid == ts->services[j]->pmt.pid) {
av_log(s, AV_LOG_ERROR, "PID %d cannot be both elementary and PMT PID\n", ts_st->pid);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
}
for (j = 0; j < i; j++) {
- if (pids[j] == ts_st->pid) {
+ MpegTSWriteStream *ts_st_prev = s->streams[j]->priv_data;
+ if (ts_st_prev->pid == ts_st->pid) {
av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
}
- pids[i] = ts_st->pid;
ts_st->payload_pts = AV_NOPTS_VALUE;
ts_st->payload_dts = AV_NOPTS_VALUE;
ts_st->first_pts_check = 1;
@@ -1089,35 +1080,30 @@ static int mpegts_init(AVFormatContext *s)
AVStream *ast;
ts_st->amux = avformat_alloc_context();
if (!ts_st->amux) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
ts_st->amux->oformat =
av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts",
NULL, NULL);
if (!ts_st->amux->oformat) {
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
if (!(ast = avformat_new_stream(ts_st->amux, NULL))) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
ret = avcodec_parameters_copy(ast->codecpar, st->codecpar);
if (ret != 0)
- goto fail;
+ return ret;
ast->time_base = st->time_base;
ret = avformat_write_header(ts_st->amux, NULL);
if (ret < 0)
- goto fail;
+ return ret;
}
if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
ts_st->opus_pending_trim_start = st->codecpar->initial_padding * 48000 / st->codecpar->sample_rate;
}
}
- av_freep(&pids);
-
if (ts->copyts < 1)
ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
@@ -1138,10 +1124,6 @@ static int mpegts_init(AVFormatContext *s)
av_rescale(ts->pat_period, 1000, PCR_TIME_BASE));
return 0;
-
-fail:
- av_freep(&pids);
- return ret;
}
/* send SDT, PAT and PMT tables regularly */
@@ -1402,28 +1384,28 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
is_dvb_teletext = 0;
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (st->codecpar->codec_id == AV_CODEC_ID_DIRAC)
- *q++ = 0xfd;
+ *q++ = STREAM_ID_EXTENDED_STREAM_ID;
else
- *q++ = 0xe0;
+ *q++ = STREAM_ID_VIDEO_STREAM_0;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
(st->codecpar->codec_id == AV_CODEC_ID_MP2 ||
st->codecpar->codec_id == AV_CODEC_ID_MP3 ||
st->codecpar->codec_id == AV_CODEC_ID_AAC)) {
- *q++ = 0xc0;
+ *q++ = STREAM_ID_AUDIO_STREAM_0;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->codec_id == AV_CODEC_ID_AC3 &&
ts->m2ts_mode) {
- *q++ = 0xfd;
+ *q++ = STREAM_ID_EXTENDED_STREAM_ID;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&
st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
- *q++ = 0xbd;
+ *q++ = STREAM_ID_PRIVATE_STREAM_1;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
- *q++ = stream_id != -1 ? stream_id : 0xfc;
+ *q++ = stream_id != -1 ? stream_id : STREAM_ID_METADATA_STREAM;
- if (stream_id == 0xbd) /* asynchronous KLV */
+ if (stream_id == STREAM_ID_PRIVATE_STREAM_1) /* asynchronous KLV */
pts = dts = AV_NOPTS_VALUE;
} else {
- *q++ = 0xbd;
+ *q++ = STREAM_ID_PRIVATE_STREAM_1;
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
is_dvb_subtitle = 1;
@@ -1459,10 +1441,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
if (ts->m2ts_mode &&
st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->codec_id == AV_CODEC_ID_AC3) {
- /* set PES_extension_flag */
- pes_extension = 1;
- flags |= 0x01;
- header_len += 3;
+ /* set PES_extension_flag */
+ pes_extension = 1;
+ flags |= 0x01;
+ header_len += 3;
}
if (is_dvb_teletext) {
pes_header_stuffing_bytes = 0x24 - header_len;
@@ -1505,14 +1487,14 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*q++ = 0x00 | 0x60;
}
/* For Blu-ray AC3 Audio Setting extended flags */
- if (ts->m2ts_mode &&
- pes_extension &&
- st->codecpar->codec_id == AV_CODEC_ID_AC3) {
- flags = 0x01; /* set PES_extension_flag_2 */
- *q++ = flags;
- *q++ = 0x80 | 0x01; /* marker bit + extension length */
- *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */
- }
+ if (ts->m2ts_mode &&
+ pes_extension &&
+ st->codecpar->codec_id == AV_CODEC_ID_AC3) {
+ flags = 0x01; /* set PES_extension_flag_2 */
+ *q++ = flags;
+ *q++ = 0x80 | 0x01; /* marker bit + extension length */
+ *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */
+ }
if (is_dvb_subtitle) {
@@ -1989,94 +1971,62 @@ static int mpegts_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt
return ret;
}
+#define OFFSET(x) offsetof(MpegTSWrite, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
{ "mpegts_transport_stream_id", "Set transport_stream_id field.",
- offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT,
- { .i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(transport_stream_id), AV_OPT_TYPE_INT, { .i64 = 0x0001 }, 0x0001, 0xffff, ENC },
{ "mpegts_original_network_id", "Set original_network_id field.",
- offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT,
- { .i64 = DVB_PRIVATE_NETWORK_START }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(original_network_id), AV_OPT_TYPE_INT, { .i64 = DVB_PRIVATE_NETWORK_START }, 0x0001, 0xffff, ENC },
{ "mpegts_service_id", "Set service_id field.",
- offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT,
- { .i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(service_id), AV_OPT_TYPE_INT, { .i64 = 0x0001 }, 0x0001, 0xffff, ENC },
{ "mpegts_service_type", "Set service_type field.",
- offsetof(MpegTSWrite, service_type), AV_OPT_TYPE_INT,
- { .i64 = 0x01 }, 0x01, 0xff, AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ OFFSET(service_type), AV_OPT_TYPE_INT, { .i64 = 0x01 }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "digital_tv", "Digital Television.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_DIGITAL_TV }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_DIGITAL_TV }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "digital_radio", "Digital Radio.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_DIGITAL_RADIO }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_DIGITAL_RADIO }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "teletext", "Teletext.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_TELETEXT }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_TELETEXT }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "advanced_codec_digital_radio", "Advanced Codec Digital Radio.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_RADIO }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_RADIO }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "mpeg2_digital_hdtv", "MPEG2 Digital HDTV.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_MPEG2_DIGITAL_HDTV }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_MPEG2_DIGITAL_HDTV }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "advanced_codec_digital_sdtv", "Advanced Codec Digital SDTV.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_SDTV }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_SDTV }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "advanced_codec_digital_hdtv", "Advanced Codec Digital HDTV.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_HDTV }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_HDTV }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "hevc_digital_hdtv", "HEVC Digital Television Service.",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_HEVC_DIGITAL_HDTV }, 0x01, 0xff,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_service_type" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_HEVC_DIGITAL_HDTV }, 0x01, 0xff, ENC, "mpegts_service_type" },
{ "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
- offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT,
- { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(pmt_start_pid), AV_OPT_TYPE_INT, { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, ENC },
{ "mpegts_start_pid", "Set the first pid.",
- offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
- { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
- { "mpegts_m2ts_mode", "Enable m2ts mode.",
- offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
- { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
- { "muxrate", NULL,
- offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
- { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(start_pid), AV_OPT_TYPE_INT, { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, ENC },
+ { "mpegts_m2ts_mode", "Enable m2ts mode.", OFFSET(m2ts_mode), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, ENC },
+ { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, ENC },
{ "pes_payload_size", "Minimum PES packet payload in bytes",
- offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT,
- { .i64 = DEFAULT_PES_PAYLOAD_SIZE }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
- { "mpegts_flags", "MPEG-TS muxing flags",
- offsetof(MpegTSWrite, flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, 0, INT_MAX,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
+ OFFSET(pes_payload_size), AV_OPT_TYPE_INT, { .i64 = DEFAULT_PES_PAYLOAD_SIZE }, 0, INT_MAX, ENC },
+ { "mpegts_flags", "MPEG-TS muxing flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, 0, INT_MAX, ENC, "mpegts_flags" },
{ "resend_headers", "Reemit PAT/PMT before writing the next packet",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_REEMIT_PAT_PMT }, 0, INT_MAX,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_REEMIT_PAT_PMT }, 0, INT_MAX, ENC, "mpegts_flags" },
{ "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" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_AAC_LATM }, 0, INT_MAX, ENC, "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" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_PAT_PMT_AT_FRAMES}, 0, INT_MAX, ENC, "mpegts_flags" },
{ "system_b", "Conform to System B (DVB) instead of System A (ATSC)",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_SYSTEM_B }, 0, INT_MAX,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_SYSTEM_B }, 0, INT_MAX, ENC, "mpegts_flags" },
{ "initial_discontinuity", "Mark initial packets as discontinuous",
- 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_DISCONT }, 0, INT_MAX,
- AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
- { "mpegts_copyts", "don't offset dts/pts",
- offsetof(MpegTSWrite, copyts), AV_OPT_TYPE_BOOL,
- { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
- { "tables_version", "set PAT, PMT and SDT version",
- offsetof(MpegTSWrite, tables_version), AV_OPT_TYPE_INT,
- { .i64 = 0 }, 0, 31, AV_OPT_FLAG_ENCODING_PARAM },
+ 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_DISCONT }, 0, INT_MAX, ENC, "mpegts_flags" },
+ { "mpegts_copyts", "don't offset dts/pts", OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, ENC },
+ { "tables_version", "set PAT, PMT and SDT version", OFFSET(tables_version), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 31, ENC },
{ "omit_video_pes_length", "Omit the PES packet length for video packets",
- offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL,
- { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(omit_video_pes_length), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
{ "pcr_period", "PCR retransmission time in milliseconds",
- offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_INT,
- { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(pcr_period_ms), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC },
{ "pat_period", "PAT/PMT retransmission time limit in seconds",
- offsetof(MpegTSWrite, pat_period_us), AV_OPT_TYPE_DURATION,
- { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(pat_period_us), AV_OPT_TYPE_DURATION, { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC },
{ "sdt_period", "SDT retransmission time limit in seconds",
- offsetof(MpegTSWrite, sdt_period_us), AV_OPT_TYPE_DURATION,
- { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ OFFSET(sdt_period_us), AV_OPT_TYPE_DURATION, { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC },
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/mpl2dec.c b/chromium/third_party/ffmpeg/libavformat/mpl2dec.c
index 4ae18390f0b..38445c7aad3 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpl2dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpl2dec.c
@@ -55,7 +55,7 @@ static int mpl2_probe(const AVProbeData *p)
return AVPROBE_SCORE_MAX;
}
-static int read_ts(char **line, int64_t *pts_start, int *duration)
+static int read_ts(char **line, int64_t *pts_start, int64_t *duration)
{
char c;
int len;
@@ -69,7 +69,10 @@ static int read_ts(char **line, int64_t *pts_start, int *duration)
}
if (sscanf(*line, "[%"SCNd64"][%"SCNd64"]%c%n",
pts_start, &end, &c, &len) >= 3) {
- *duration = end - *pts_start;
+ if (end < *pts_start || end - (uint64_t)*pts_start > INT64_MAX) {
+ *duration = -1;
+ } else
+ *duration = end - *pts_start;
*line += len - 1;
return 0;
}
@@ -80,7 +83,6 @@ static int mpl2_read_header(AVFormatContext *s)
{
MPL2Context *mpl2 = s->priv_data;
AVStream *st = avformat_new_stream(s, NULL);
- int res = 0;
if (!st)
return AVERROR(ENOMEM);
@@ -97,7 +99,7 @@ static int mpl2_read_header(AVFormatContext *s)
const int64_t pos = avio_tell(s->pb);
int len = ff_get_line(s->pb, line, sizeof(line));
int64_t pts_start;
- int duration;
+ int64_t duration;
if (!len)
break;
@@ -108,8 +110,10 @@ static int mpl2_read_header(AVFormatContext *s)
AVPacket *sub;
sub = ff_subtitles_queue_insert(&mpl2->q, p, strlen(p), 0);
- if (!sub)
+ if (!sub) {
+ ff_subtitles_queue_clean(&mpl2->q);
return AVERROR(ENOMEM);
+ }
sub->pos = pos;
sub->pts = pts_start;
sub->duration = duration;
@@ -117,7 +121,7 @@ static int mpl2_read_header(AVFormatContext *s)
}
ff_subtitles_queue_finalize(s, &mpl2->q);
- return res;
+ return 0;
}
static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/mpsubdec.c b/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
index 82c73457ead..e7b83a1d85f 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
@@ -154,8 +154,10 @@ static int mpsub_read_header(AVFormatContext *s)
}
st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
+ if (!st) {
+ res = AVERROR(ENOMEM);
+ goto end;
+ }
avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codecpar->codec_id = AV_CODEC_ID_TEXT;
diff --git a/chromium/third_party/ffmpeg/libavformat/mux.c b/chromium/third_party/ffmpeg/libavformat/mux.c
index 3d1f71ab1ad..44d5e5d1c0b 100644
--- a/chromium/third_party/ffmpeg/libavformat/mux.c
+++ b/chromium/third_party/ffmpeg/libavformat/mux.c
@@ -344,6 +344,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (desc && desc->props & AV_CODEC_PROP_REORDER)
st->internal->reorder = 1;
+ st->internal->is_intra_only = ff_is_intra_only(par->codec_id);
+
if (of->codec_tag) {
if ( par->codec_tag
&& par->codec_id == AV_CODEC_ID_RAWVIDEO
@@ -757,18 +759,11 @@ static int check_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
-static int prepare_input_packet(AVFormatContext *s, AVPacket *pkt)
+static int prepare_input_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
{
- int ret;
-
- ret = check_packet(s, pkt);
- if (ret < 0)
- return ret;
-
#if !FF_API_COMPUTE_PKT_FIELDS2 || !FF_API_LAVF_AVCTX
/* sanitize the timestamps */
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
- AVStream *st = s->streams[pkt->stream_index];
/* when there is no reordering (so dts is equal to pts), but
* only one of them is set, set the other as well */
@@ -805,114 +800,13 @@ static int prepare_input_packet(AVFormatContext *s, AVPacket *pkt)
}
}
#endif
+ /* update flags */
+ if (st->internal->is_intra_only)
+ pkt->flags |= AV_PKT_FLAG_KEY;
return 0;
}
-static int do_packet_auto_bsf(AVFormatContext *s, AVPacket *pkt) {
- AVStream *st = s->streams[pkt->stream_index];
- int ret;
-
- if (!(s->flags & AVFMT_FLAG_AUTO_BSF))
- return 1;
-
- if (s->oformat->check_bitstream) {
- if (!st->internal->bitstream_checked) {
- if ((ret = s->oformat->check_bitstream(s, pkt)) < 0)
- return ret;
- else if (ret == 1)
- st->internal->bitstream_checked = 1;
- }
- }
-
- if (st->internal->bsfc) {
- AVBSFContext *ctx = st->internal->bsfc;
- // TODO: when any bitstream filter requires flushing at EOF, we'll need to
- // flush each stream's BSF chain on write_trailer.
- if ((ret = av_bsf_send_packet(ctx, pkt)) < 0) {
- av_log(ctx, AV_LOG_ERROR,
- "Failed to send packet to filter %s for stream %d\n",
- ctx->filter->name, pkt->stream_index);
- return ret;
- }
- // TODO: when any automatically-added bitstream filter is generating multiple
- // output packets for a single input one, we'll need to call this in a loop
- // and write each output packet.
- if ((ret = av_bsf_receive_packet(ctx, pkt)) < 0) {
- if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
- return 0;
- av_log(ctx, AV_LOG_ERROR,
- "Failed to receive packet from filter %s for stream %d\n",
- ctx->filter->name, pkt->stream_index);
- if (s->error_recognition & AV_EF_EXPLODE)
- return ret;
- return 0;
- }
- }
- return 1;
-}
-
-int av_write_frame(AVFormatContext *s, AVPacket *in)
-{
- AVPacket local_pkt, *pkt = &local_pkt;
- int ret;
-
- if (!in) {
- if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
- ret = s->oformat->write_packet(s, NULL);
- flush_if_needed(s);
- if (ret >= 0 && s->pb && s->pb->error < 0)
- ret = s->pb->error;
- return ret;
- }
- return 1;
- }
-
- if (in->flags & AV_PKT_FLAG_UNCODED_FRAME) {
- pkt = in;
- } else {
- /* We don't own in, so we have to make sure not to modify it.
- * The following avoids copying in's data unnecessarily.
- * Copying side data is unavoidable as a bitstream filter
- * may change it, e.g. free it on errors. */
- pkt->buf = NULL;
- pkt->data = in->data;
- pkt->size = in->size;
- ret = av_packet_copy_props(pkt, in);
- if (ret < 0)
- return ret;
- if (in->buf) {
- pkt->buf = av_buffer_ref(in->buf);
- if (!pkt->buf) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- }
- }
-
- ret = prepare_input_packet(s, pkt);
- if (ret < 0)
- goto fail;
-
- ret = do_packet_auto_bsf(s, pkt);
- if (ret <= 0)
- goto fail;
-
-#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
- ret = compute_muxer_pkt_fields(s, s->streams[pkt->stream_index], pkt);
-
- if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
- goto fail;
-#endif
-
- ret = write_packet(s, pkt);
-
-fail:
- // Uncoded frames using the noninterleaved codepath are also freed here
- av_packet_unref(pkt);
- return ret;
-}
-
#define CHUNK_START 0x1000
int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
@@ -1173,49 +1067,32 @@ int ff_interleaved_peek(AVFormatContext *s, int stream,
static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush)
{
if (s->oformat->interleave_packet) {
- int ret = s->oformat->interleave_packet(s, out, in, flush);
- if (in)
- av_packet_unref(in);
- return ret;
+ return s->oformat->interleave_packet(s, out, in, flush);
} else
return ff_interleave_packet_per_dts(s, out, in, flush);
}
-int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
+static int check_bitstream(AVFormatContext *s, AVStream *st, AVPacket *pkt)
{
- int ret, flush = 0;
-
- if (pkt) {
- AVStream *st = s->streams[pkt->stream_index];
-
- ret = prepare_input_packet(s, pkt);
- if (ret < 0)
- goto fail;
-
- ret = do_packet_auto_bsf(s, pkt);
- if (ret == 0)
- return 0;
- else if (ret < 0)
- goto fail;
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG, "av_interleaved_write_frame size:%d dts:%s pts:%s\n",
- pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
+ int ret;
-#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
- if ((ret = compute_muxer_pkt_fields(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
- goto fail;
-#endif
+ if (!(s->flags & AVFMT_FLAG_AUTO_BSF))
+ return 1;
- if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
- ret = AVERROR(EINVAL);
- goto fail;
+ if (s->oformat->check_bitstream) {
+ if (!st->internal->bitstream_checked) {
+ if ((ret = s->oformat->check_bitstream(s, pkt)) < 0)
+ return ret;
+ else if (ret == 1)
+ st->internal->bitstream_checked = 1;
}
- } else {
- av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n");
- flush = 1;
}
+ return 1;
+}
+
+static int interleaved_write_packet(AVFormatContext *s, AVPacket *pkt, int flush)
+{
for (;; ) {
AVPacket opkt;
int ret = interleave_packet(s, &opkt, pkt, flush);
@@ -1231,32 +1108,165 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
if (ret < 0)
return ret;
}
-fail:
- av_packet_unref(pkt);
+}
+
+static int write_packet_common(AVFormatContext *s, AVStream *st, AVPacket *pkt, int interleaved)
+{
+ int ret;
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_DEBUG, "%s size:%d dts:%s pts:%s\n", __FUNCTION__,
+ pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
+
+#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
+ if ((ret = compute_muxer_pkt_fields(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
+ return ret;
+#endif
+
+ if (interleaved) {
+ if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
+ return AVERROR(EINVAL);
+ return interleaved_write_packet(s, pkt, 0);
+ } else {
+ return write_packet(s, pkt);
+ }
+}
+
+static int write_packets_from_bsfs(AVFormatContext *s, AVStream *st, AVPacket *pkt, int interleaved)
+{
+ AVBSFContext *bsfc = st->internal->bsfc;
+ int ret;
+
+ if ((ret = av_bsf_send_packet(bsfc, pkt)) < 0) {
+ av_log(s, AV_LOG_ERROR,
+ "Failed to send packet to filter %s for stream %d\n",
+ bsfc->filter->name, st->index);
+ return ret;
+ }
+
+ do {
+ ret = av_bsf_receive_packet(bsfc, pkt);
+ if (ret < 0) {
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+ return 0;
+ av_log(s, AV_LOG_ERROR, "Error applying bitstream filters to an output "
+ "packet for stream #%d: %s\n", st->index, av_err2str(ret));
+ if (!(s->error_recognition & AV_EF_EXPLODE) && ret != AVERROR(ENOMEM))
+ continue;
+ return ret;
+ }
+ av_packet_rescale_ts(pkt, bsfc->time_base_out, st->time_base);
+ ret = write_packet_common(s, st, pkt, interleaved);
+ if (ret >= 0 && !interleaved) // a successful write_packet_common already unrefed pkt for interleaved
+ av_packet_unref(pkt);
+ } while (ret >= 0);
+
return ret;
}
-int av_write_trailer(AVFormatContext *s)
+static int write_packets_common(AVFormatContext *s, AVPacket *pkt, int interleaved)
{
- int ret, i;
+ AVStream *st;
+ int ret = check_packet(s, pkt);
+ if (ret < 0)
+ return ret;
+ st = s->streams[pkt->stream_index];
- for (;; ) {
- AVPacket pkt;
- ret = interleave_packet(s, &pkt, NULL, 1);
- if (ret < 0)
- goto fail;
- if (!ret)
- break;
+ ret = prepare_input_packet(s, st, pkt);
+ if (ret < 0)
+ return ret;
- ret = write_packet(s, &pkt);
+ ret = check_bitstream(s, st, pkt);
+ if (ret < 0)
+ return ret;
+
+ if (st->internal->bsfc) {
+ return write_packets_from_bsfs(s, st, pkt, interleaved);
+ } else {
+ return write_packet_common(s, st, pkt, interleaved);
+ }
+}
- av_packet_unref(&pkt);
+int av_write_frame(AVFormatContext *s, AVPacket *in)
+{
+ AVPacket local_pkt, *pkt = &local_pkt;
+ int ret;
+ if (!in) {
+ if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
+ ret = s->oformat->write_packet(s, NULL);
+ flush_if_needed(s);
+ if (ret >= 0 && s->pb && s->pb->error < 0)
+ ret = s->pb->error;
+ return ret;
+ }
+ return 1;
+ }
+
+ if (in->flags & AV_PKT_FLAG_UNCODED_FRAME) {
+ pkt = in;
+ } else {
+ /* We don't own in, so we have to make sure not to modify it.
+ * The following avoids copying in's data unnecessarily.
+ * Copying side data is unavoidable as a bitstream filter
+ * may change it, e.g. free it on errors. */
+ pkt->buf = NULL;
+ pkt->data = in->data;
+ pkt->size = in->size;
+ ret = av_packet_copy_props(pkt, in);
if (ret < 0)
- goto fail;
+ return ret;
+ if (in->buf) {
+ pkt->buf = av_buffer_ref(in->buf);
+ if (!pkt->buf) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ }
}
+ ret = write_packets_common(s, pkt, 0/*non-interleaved*/);
+
fail:
+ // Uncoded frames using the noninterleaved codepath are also freed here
+ av_packet_unref(pkt);
+ return ret;
+}
+
+int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret;
+
+ if (pkt) {
+ ret = write_packets_common(s, pkt, 1/*interleaved*/);
+ if (ret < 0)
+ av_packet_unref(pkt);
+ return ret;
+ } else {
+ av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n");
+ return interleaved_write_packet(s, NULL, 1/*flush*/);
+ }
+}
+
+int av_write_trailer(AVFormatContext *s)
+{
+ int i, ret1, ret = 0;
+ AVPacket pkt = {0};
+ av_init_packet(&pkt);
+
+ for (i = 0; i < s->nb_streams; i++) {
+ if (s->streams[i]->internal->bsfc) {
+ ret1 = write_packets_from_bsfs(s, s->streams[i], &pkt, 1/*interleaved*/);
+ if (ret1 < 0)
+ av_packet_unref(&pkt);
+ if (ret >= 0)
+ ret = ret1;
+ }
+ }
+ ret1 = interleaved_write_packet(s, NULL, 1);
+ if (ret >= 0)
+ ret = ret1;
+
if (s->oformat->write_trailer) {
if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
diff --git a/chromium/third_party/ffmpeg/libavformat/mvdec.c b/chromium/third_party/ffmpeg/libavformat/mvdec.c
index 64166a84b1f..d5b400213df 100644
--- a/chromium/third_party/ffmpeg/libavformat/mvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mvdec.c
@@ -268,7 +268,7 @@ static void read_index(AVIOContext *pb, AVStream *st)
avio_skip(pb, 8);
av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME);
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- timestamp += size / (st->codecpar->channels * 2);
+ timestamp += size / (st->codecpar->channels * 2LL);
} else {
timestamp++;
}
@@ -355,7 +355,7 @@ static int mv_read_header(AVFormatContext *avctx)
avio_skip(pb, 8);
av_add_index_entry(ast, pos, timestamp, asize, 0, AVINDEX_KEYFRAME);
av_add_index_entry(vst, pos + asize, i, vsize, 0, AVINDEX_KEYFRAME);
- timestamp += asize / (ast->codecpar->channels * 2);
+ timestamp += asize / (ast->codecpar->channels * 2LL);
}
} else if (!version && avio_rb16(pb) == 3) {
avio_skip(pb, 4);
diff --git a/chromium/third_party/ffmpeg/libavformat/mxf.c b/chromium/third_party/ffmpeg/libavformat/mxf.c
index 7d154ca9d3e..e51fc48a842 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxf.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxf.c
@@ -86,6 +86,55 @@ const MXFCodecUL ff_mxf_codec_tag_uls[] = {
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 },
};
+const MXFCodecUL ff_mxf_color_primaries_uls[] = {
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x01,0x00,0x00 }, 14, AVCOL_PRI_SMPTE170M }, /* SMPTE 170M */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x02,0x00,0x00 }, 14, AVCOL_PRI_BT470BG }, /* ITU-R BT.470 PAL */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x03,0x00,0x00 }, 14, AVCOL_PRI_BT709 }, /* ITU-R BT.709 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x04,0x00,0x00 }, 14, AVCOL_PRI_BT2020 }, /* ITU-R BT.2020 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x05,0x00,0x00 }, 14, AVCOL_PRI_SMPTE428 }, /* SMPTE-DC28 DCDM */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x06,0x00,0x00 }, 14, AVCOL_PRI_SMPTE432 }, /* P3D65 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x08,0x00,0x00 }, 14, AVCOL_PRI_SMPTE428 }, /* Cinema Mezzanine */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x0a,0x00,0x00 }, 14, AVCOL_PRI_SMPTE431 }, /* P3DCI */
+ /* alternate mappings for encoding */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x01,0x00,0x00 }, 14, AVCOL_PRI_SMPTE240M }, /* = AVCOL_PRI_SMPTE170M */
+
+ { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVCOL_PRI_UNSPECIFIED },
+};
+
+const MXFCodecUL ff_mxf_color_trc_uls[] = {
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00 }, 14, AVCOL_TRC_GAMMA22 }, /* ITU-R BT.470 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00 }, 14, AVCOL_TRC_BT709 }, /* ITU-R BT.709 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x03,0x00,0x00 }, 14, AVCOL_TRC_SMPTE240M }, /* SMPTE 240M */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x04,0x00,0x00 }, 14, AVCOL_TRC_BT709 }, /* SMPTE 274/296M (must appear after ITU-R BT.709) */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x05,0x00,0x00 }, 14, AVCOL_TRC_BT1361_ECG }, /* ITU-R BT.1361 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x06,0x00,0x00 }, 14, AVCOL_TRC_LINEAR }, /* Linear */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00 }, 14, AVCOL_TRC_SMPTE428 }, /* SMPTE-DC28 DCDM */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x08,0x00,0x00 }, 14, AVCOL_TRC_IEC61966_2_4 }, /* IEC 61966-2-4 xvYCC */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0E,0x04,0x01,0x01,0x01,0x01,0x09,0x00,0x00 }, 14, AVCOL_TRC_BT2020_10 }, /* ITU-R BT.2020 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0A,0x00,0x00 }, 14, AVCOL_TRC_SMPTE2084 }, /* SMPTE ST 2084 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0B,0x00,0x00 }, 14, AVCOL_TRC_ARIB_STD_B67 }, /* Hybrid Log-Gamma OETF */
+ /* alternate mappings for encoding */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00 }, 14, AVCOL_TRC_GAMMA28 }, /* = AVCOL_TRC_GAMMA22 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00 }, 14, AVCOL_TRC_SMPTE170M }, /* = AVCOL_TRC_BT709 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0E,0x04,0x01,0x01,0x01,0x01,0x09,0x00,0x00 }, 14, AVCOL_TRC_BT2020_12 }, /* = AVCOL_TRC_BT2020_10 */
+
+ { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVCOL_TRC_UNSPECIFIED },
+};
+
+/* aka Coding Equations */
+const MXFCodecUL ff_mxf_color_space_uls[] = {
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x02,0x01,0x00,0x00 }, 14, AVCOL_SPC_BT470BG }, /* ITU-R BT.601 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x02,0x02,0x00,0x00 }, 14, AVCOL_SPC_BT709 }, /* ITU-R BT.709 */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x02,0x03,0x00,0x00 }, 14, AVCOL_SPC_SMPTE240M }, /* SMPTE 240M */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x04,0x00,0x00 }, 14, AVCOL_SPC_YCGCO }, /* YCgCo */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x05,0x00,0x00 }, 14, AVCOL_SPC_RGB }, /* GBR */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x06,0x00,0x00 }, 14, AVCOL_SPC_BT2020_NCL }, /* ITU-R BT.2020 Non-Constant Luminance */
+ /* alternate mappings for encoding */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x02,0x03,0x00,0x00 }, 14, AVCOL_SPC_SMPTE170M }, /* = AVCOL_SPC_SMPTE240M */
+
+ { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVCOL_SPC_UNSPECIFIED },
+};
+
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 f2fff2781e8..fc587f19f00 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxf.h
+++ b/chromium/third_party/ffmpeg/libavformat/mxf.h
@@ -91,6 +91,9 @@ 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[];
+extern const MXFCodecUL ff_mxf_color_primaries_uls[];
+extern const MXFCodecUL ff_mxf_color_trc_uls[];
+extern const MXFCodecUL ff_mxf_color_space_uls[];
int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt);
int ff_mxf_get_content_package_rate(AVRational time_base);
diff --git a/chromium/third_party/ffmpeg/libavformat/mxfdec.c b/chromium/third_party/ffmpeg/libavformat/mxfdec.c
index fdd0dd2a88a..4b56984b777 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxfdec.c
@@ -207,6 +207,9 @@ typedef struct MXFDescriptor {
uint8_t *extradata;
int extradata_size;
enum AVPixelFormat pix_fmt;
+ UID color_primaries_ul;
+ UID color_trc_ul;
+ UID color_space_ul;
} MXFDescriptor;
typedef struct MXFIndexTableSegment {
@@ -362,8 +365,9 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
default:
break;
}
- if (freectx)
- av_freep(ctx);
+ if (freectx) {
+ av_freep(ctx);
+ }
}
static int64_t klv_decode_ber_length(AVIOContext *pb)
@@ -821,15 +825,17 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size
return 0;
}
-static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
+static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set)
{
MXFMetadataSet **tmp;
tmp = av_realloc_array(mxf->metadata_sets, mxf->metadata_sets_count + 1, sizeof(*mxf->metadata_sets));
- if (!tmp)
+ if (!tmp) {
+ mxf_free_metadataset(metadata_set, 1);
return AVERROR(ENOMEM);
+ }
mxf->metadata_sets = tmp;
- mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
+ mxf->metadata_sets[mxf->metadata_sets_count] = *metadata_set;
mxf->metadata_sets_count++;
return 0;
}
@@ -847,6 +853,7 @@ static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, i
static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
{
*count = avio_rb32(pb);
+ av_free(*refs);
*refs = av_calloc(*count, sizeof(UID));
if (!*refs) {
*count = 0;
@@ -866,6 +873,7 @@ static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, i
return AVERROR(EINVAL);
buf_size = size + size / 2 + 1;
+ av_free(*str);
*str = av_malloc(buf_size);
if (!*str)
return AVERROR(ENOMEM);
@@ -899,10 +907,8 @@ static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int siz
case 0x1901:
if (mxf->packages_refs)
av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple packages_refs\n");
- av_free(mxf->packages_refs);
return mxf_read_strong_ref_array(pb, &mxf->packages_refs, &mxf->packages_count);
case 0x1902:
- av_free(mxf->essence_container_data_refs);
return mxf_read_strong_ref_array(pb, &mxf->essence_container_data_refs, &mxf->essence_container_data_count);
}
return 0;
@@ -1198,9 +1204,18 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
descriptor->aspect_ratio.num = avio_rb32(pb);
descriptor->aspect_ratio.den = avio_rb32(pb);
break;
+ case 0x3210:
+ avio_read(pb, descriptor->color_trc_ul, 16);
+ break;
case 0x3212:
descriptor->field_dominance = avio_r8(pb);
break;
+ case 0x3219:
+ avio_read(pb, descriptor->color_primaries_ul, 16);
+ break;
+ case 0x321A:
+ avio_read(pb, descriptor->color_space_ul, 16);
+ break;
case 0x3301:
descriptor->component_depth = avio_rb32(pb);
break;
@@ -2477,6 +2492,9 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
}
if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den)
st->display_aspect_ratio = descriptor->aspect_ratio;
+ st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id;
+ st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id;
+ st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
/* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */
@@ -2710,6 +2728,7 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type)
{
+ ctx->type = type;
switch (type){
case MultipleDescriptor:
case Descriptor:
@@ -2730,7 +2749,8 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF
if (!ctx)
return AVERROR(ENOMEM);
- mxf_metadataset_init(ctx, type);
+ if (ctx_size)
+ mxf_metadataset_init(ctx, type);
while (avio_tell(pb) + 4 < klv_end && !avio_feof(pb)) {
int ret;
int tag = avio_rb16(pb);
@@ -2766,7 +2786,6 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF
* it extending past the end of the KLV though (zzuf5.mxf). */
if (avio_tell(pb) > klv_end) {
if (ctx_size) {
- ctx->type = type;
mxf_free_metadataset(&ctx, 1);
}
@@ -2777,8 +2796,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF
} else if (avio_tell(pb) <= next) /* only seek forward, else this can loop for a long time */
avio_seek(pb, next, SEEK_SET);
}
- if (ctx_size) ctx->type = type;
- return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
+ return ctx_size ? mxf_add_metadata_set(mxf, &ctx) : 0;
}
/**
@@ -3081,10 +3099,8 @@ static int mxf_handle_missing_index_segment(MXFContext *mxf, AVStream *st)
if (!(segment = av_mallocz(sizeof(*segment))))
return AVERROR(ENOMEM);
- if ((ret = mxf_add_metadata_set(mxf, segment))) {
- mxf_free_metadataset((MXFMetadataSet**)&segment, 1);
+ if ((ret = mxf_add_metadata_set(mxf, (MXFMetadataSet**)&segment)))
return ret;
- }
/* Make sure we have nonzero unique index_sid, body_sid will be ok, because
* using the same SID for index is forbidden in MXF. */
diff --git a/chromium/third_party/ffmpeg/libavformat/mxfenc.c b/chromium/third_party/ffmpeg/libavformat/mxfenc.c
index 23147e9b84d..a38fa6b9836 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxfenc.c
@@ -52,7 +52,6 @@
#include "libavcodec/h264_ps.h"
#include "libavcodec/golomb.h"
#include "libavcodec/internal.h"
-#include "audiointerleave.h"
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
@@ -79,7 +78,7 @@ typedef struct MXFIndexEntry {
} MXFIndexEntry;
typedef struct MXFStreamContext {
- AudioInterleaveContext aic;
+ int64_t pkt_cnt; ///< pkt counter for muxed packets
UID track_essence_element_key;
int index; ///< index in mxf_essence_container_uls table
const UID *codec_ul;
@@ -554,11 +553,10 @@ static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value)
avio_wb24(pb, value);
}
-static const MXFCodecUL *mxf_get_data_definition_ul(int type)
+static const MXFCodecUL *mxf_get_codec_ul_by_id(const MXFCodecUL *uls, int id)
{
- const MXFCodecUL *uls = ff_mxf_data_definition_uls;
while (uls->uid[0]) {
- if (type == uls->id)
+ if (id == uls->id)
break;
uls++;
}
@@ -848,7 +846,7 @@ static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
if (st == mxf->timecode_track)
avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
else {
- const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codecpar->codec_type);
+ const MXFCodecUL *data_def_ul = mxf_get_codec_ul_by_id(ff_mxf_data_definition_uls, st->codecpar->codec_type);
avio_write(pb, data_def_ul->uid, 16);
}
@@ -1050,34 +1048,6 @@ static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0
static const UID mxf_avc_subdescriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6E,0x00 };
-static int get_trc(UID ul, enum AVColorTransferCharacteristic trc)
-{
- switch (trc){
- case AVCOL_TRC_GAMMA28 :
- case AVCOL_TRC_GAMMA22 :
- memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00}), 16);
- return 0;
- case AVCOL_TRC_BT709 :
- case AVCOL_TRC_SMPTE170M :
- memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00}), 16);
- return 0;
- case AVCOL_TRC_SMPTE240M :
- memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x03,0x00,0x00}), 16);
- return 0;
- case AVCOL_TRC_BT1361_ECG:
- memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x05,0x00,0x00}), 16);
- return 0;
- case AVCOL_TRC_LINEAR :
- memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x06,0x00,0x00}), 16);
- return 0;
- case AVCOL_TRC_SMPTE428 :
- memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00}), 16);
- return 0;
- default:
- return -1;
- }
-}
-
static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key)
{
MXFStreamContext *sc = st->priv_data;
@@ -1086,10 +1056,14 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
int stored_height = (st->codecpar->height+15)/16*16;
int display_height;
int f1, f2;
- UID transfer_ul = {0};
+ const MXFCodecUL *color_primaries_ul;
+ const MXFCodecUL *color_trc_ul;
+ const MXFCodecUL *color_space_ul;
int64_t pos = mxf_write_generic_desc(s, st, key);
- get_trc(transfer_ul, st->codecpar->color_trc);
+ color_primaries_ul = mxf_get_codec_ul_by_id(ff_mxf_color_primaries_uls, st->codecpar->color_primaries);
+ color_trc_ul = mxf_get_codec_ul_by_id(ff_mxf_color_trc_uls, st->codecpar->color_trc);
+ color_space_ul = mxf_get_codec_ul_by_id(ff_mxf_color_space_uls, st->codecpar->color_space);
if (st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO) {
if (st->codecpar->height == 1080)
@@ -1236,10 +1210,19 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
avio_wb32(pb, sc->aspect_ratio.num);
avio_wb32(pb, sc->aspect_ratio.den);
- //Transfer characteristic
- if (transfer_ul[0]) {
+ if (color_primaries_ul->uid[0]) {
+ mxf_write_local_tag(pb, 16, 0x3219);
+ avio_write(pb, color_primaries_ul->uid, 16);
+ };
+
+ if (color_trc_ul->uid[0]) {
mxf_write_local_tag(pb, 16, 0x3210);
- avio_write(pb, transfer_ul, 16);
+ avio_write(pb, color_trc_ul->uid, 16);
+ };
+
+ if (color_space_ul->uid[0]) {
+ mxf_write_local_tag(pb, 16, 0x321A);
+ avio_write(pb, color_space_ul->uid, 16);
};
mxf_write_local_tag(pb, 16, 0x3201);
@@ -2172,14 +2155,14 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
{
MXFContext *mxf = s->priv_data;
MXFStreamContext *sc = st->priv_data;
- H264SequenceParameterSet *sps = NULL;
+ H264SPS seq, *const sps = &seq;
GetBitContext gb;
const uint8_t *buf = pkt->data;
const uint8_t *buf_end = pkt->data + pkt->size;
const uint8_t *nal_end;
uint32_t state = -1;
int extra_size = 512; // support AVC Intra files without SPS/PPS header
- int i, frame_size, slice_type, intra_only = 0;
+ int i, frame_size, slice_type, has_sps = 0, intra_only = 0, ret;
for (;;) {
buf = avpriv_find_start_code(buf, buf_end, &state);
@@ -2194,11 +2177,12 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
break;
nal_end = ff_avc_find_startcode(buf, buf_end);
- sps = ff_avc_decode_sps(buf, nal_end - buf);
- if (!sps) {
+ ret = ff_avc_decode_sps(sps, buf, nal_end - buf);
+ if (ret < 0) {
av_log(s, AV_LOG_ERROR, "error parsing sps\n");
return 0;
}
+ has_sps = 1;
sc->aspect_ratio.num = st->codecpar->width * sps->sar.num;
sc->aspect_ratio.den = st->codecpar->height * sps->sar.den;
@@ -2244,7 +2228,7 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
if (mxf->header_written)
return 1;
- if (!sps)
+ if (!has_sps)
sc->interlaced = st->codecpar->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0;
sc->codec_ul = NULL;
frame_size = pkt->size + extra_size;
@@ -2261,7 +2245,7 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
if (sc->interlaced)
sc->field_dominance = 1; // top field first is mandatory for AVC Intra
break;
- } else if (sps && mxf_h264_codec_uls[i].frame_size == 0 &&
+ } else if (has_sps && mxf_h264_codec_uls[i].frame_size == 0 &&
mxf_h264_codec_uls[i].profile == sps->profile_idc &&
(mxf_h264_codec_uls[i].intra_only < 0 ||
mxf_h264_codec_uls[i].intra_only == intra_only)) {
@@ -2272,8 +2256,6 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
}
}
- av_free(sps);
-
if (!sc->codec_ul) {
av_log(s, AV_LOG_ERROR, "h264 profile not supported\n");
return 0;
@@ -2538,6 +2520,7 @@ static int mxf_write_header(AVFormatContext *s)
if (mxf->signal_standard >= 0)
sc->signal_standard = mxf->signal_standard;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ char bsf_arg[32];
if (st->codecpar->sample_rate != 48000) {
av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
return -1;
@@ -2580,6 +2563,10 @@ static int mxf_write_header(AVFormatContext *s)
av_rescale_rnd(st->codecpar->sample_rate, mxf->time_base.num, mxf->time_base.den, AV_ROUND_UP) *
av_get_bits_per_sample(st->codecpar->codec_id) / 8;
}
+ snprintf(bsf_arg, sizeof(bsf_arg), "r=%d/%d", mxf->tc.rate.num, mxf->tc.rate.den);
+ ret = ff_stream_add_bitstream_filter(st, "pcm_rechunk", bsf_arg);
+ if (ret < 0)
+ return ret;
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
AVDictionaryEntry *e = av_dict_get(st->metadata, "data_type", NULL, 0);
if (e && !strcmp(e->value, "vbi_vanc_smpte_436M")) {
@@ -2646,9 +2633,6 @@ static int mxf_write_header(AVFormatContext *s)
return AVERROR(ENOMEM);
mxf->timecode_track->index = -1;
- if (ff_audio_interleave_init(s, 0, av_inv_q(mxf->tc.rate)) < 0)
- return -1;
-
return 0;
}
@@ -3010,8 +2994,6 @@ static void mxf_deinit(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
- ff_audio_interleave_close(s);
-
av_freep(&mxf->index_entries);
av_freep(&mxf->body_partition_offset);
if (mxf->timecode_track) {
@@ -3086,8 +3068,14 @@ static int mxf_compare_timestamps(AVFormatContext *s, const AVPacket *next,
static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
{
- return ff_audio_rechunk_interleave(s, out, pkt, flush,
- mxf_interleave_get_packet, mxf_compare_timestamps);
+ int ret;
+ if (pkt) {
+ MXFStreamContext *sc = s->streams[pkt->stream_index]->priv_data;
+ pkt->pts = pkt->dts = sc->pkt_cnt++;
+ if ((ret = ff_interleave_add_packet(s, pkt, mxf_compare_timestamps)) < 0)
+ return ret;
+ }
+ return mxf_interleave_get_packet(s, out, NULL, flush);
}
#define MXF_COMMON_OPTIONS \
diff --git a/chromium/third_party/ffmpeg/libavformat/nutenc.c b/chromium/third_party/ffmpeg/libavformat/nutenc.c
index 1d486258154..6d3bf6c21e2 100644
--- a/chromium/third_party/ffmpeg/libavformat/nutenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/nutenc.c
@@ -277,11 +277,37 @@ static void build_frame_code(AVFormatContext *s)
nut->frame_code['N'].flags = FLAG_INVALID;
}
+/**
+ * Get the length in bytes which is needed to store val as v.
+ */
+static int get_v_length(uint64_t val)
+{
+ int i = 1;
+
+ while (val >>= 7)
+ i++;
+
+ return i;
+}
+
+/**
+ * Put val using a variable number of bytes.
+ */
+static void put_v(AVIOContext *bc, uint64_t val)
+{
+ int i = get_v_length(val);
+
+ while (--i > 0)
+ avio_w8(bc, 128 | (uint8_t)(val >> (7*i)));
+
+ avio_w8(bc, val & 127);
+}
+
static void put_tt(NUTContext *nut, AVRational *time_base, AVIOContext *bc, uint64_t val)
{
val *= nut->time_base_count;
val += time_base - nut->time_base;
- ff_put_v(bc, val);
+ put_v(bc, val);
}
/**
* Store a string as vb.
@@ -290,37 +316,34 @@ static void put_str(AVIOContext *bc, const char *string)
{
size_t len = strlen(string);
- ff_put_v(bc, len);
+ put_v(bc, len);
avio_write(bc, string, len);
}
static void put_s(AVIOContext *bc, int64_t val)
{
- ff_put_v(bc, 2 * FFABS(val) - (val > 0));
+ put_v(bc, 2 * FFABS(val) - (val > 0));
}
-//FIXME remove calculate_checksum
static void put_packet(NUTContext *nut, AVIOContext *bc, AVIOContext *dyn_bc,
- int calculate_checksum, uint64_t startcode)
+ uint64_t startcode)
{
uint8_t *dyn_buf = NULL;
- int dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
- int forw_ptr = dyn_size + 4 * calculate_checksum;
+ int dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
+ int forw_ptr = dyn_size + 4;
if (forw_ptr > 4096)
ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
avio_wb64(bc, startcode);
- ff_put_v(bc, forw_ptr);
+ put_v(bc, forw_ptr);
if (forw_ptr > 4096)
avio_wl32(bc, ffio_get_checksum(bc));
- if (calculate_checksum)
- ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
+ ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
avio_write(bc, dyn_buf, dyn_size);
- if (calculate_checksum)
- avio_wl32(bc, ffio_get_checksum(bc));
+ avio_wl32(bc, ffio_get_checksum(bc));
- av_free(dyn_buf);
+ ffio_reset_dyn_buf(dyn_bc);
}
static void write_mainheader(NUTContext *nut, AVIOContext *bc)
@@ -329,16 +352,16 @@ static void write_mainheader(NUTContext *nut, AVIOContext *bc)
tmp_head_idx;
int64_t tmp_match;
- ff_put_v(bc, nut->version);
+ put_v(bc, nut->version);
if (nut->version > 3)
- ff_put_v(bc, nut->minor_version = 1);
- ff_put_v(bc, nut->avf->nb_streams);
- ff_put_v(bc, nut->max_distance);
- ff_put_v(bc, nut->time_base_count);
+ put_v(bc, nut->minor_version = 1);
+ put_v(bc, nut->avf->nb_streams);
+ put_v(bc, nut->max_distance);
+ put_v(bc, nut->time_base_count);
for (i = 0; i < nut->time_base_count; i++) {
- ff_put_v(bc, nut->time_base[i].num);
- ff_put_v(bc, nut->time_base[i].den);
+ put_v(bc, nut->time_base[i].num);
+ put_v(bc, nut->time_base[i].den);
}
tmp_pts = 0;
@@ -382,25 +405,25 @@ static void write_mainheader(NUTContext *nut, AVIOContext *bc)
if (j != tmp_mul - tmp_size)
tmp_fields = 6;
- ff_put_v(bc, tmp_flags);
- ff_put_v(bc, tmp_fields);
+ put_v(bc, tmp_flags);
+ put_v(bc, tmp_fields);
if (tmp_fields > 0) put_s(bc, tmp_pts);
- if (tmp_fields > 1) ff_put_v(bc, tmp_mul);
- if (tmp_fields > 2) ff_put_v(bc, tmp_stream);
- if (tmp_fields > 3) ff_put_v(bc, tmp_size);
- if (tmp_fields > 4) ff_put_v(bc, 0 /*tmp_res*/);
- if (tmp_fields > 5) ff_put_v(bc, j);
- if (tmp_fields > 6) ff_put_v(bc, tmp_match);
- if (tmp_fields > 7) ff_put_v(bc, tmp_head_idx);
+ if (tmp_fields > 1) put_v(bc, tmp_mul);
+ if (tmp_fields > 2) put_v(bc, tmp_stream);
+ if (tmp_fields > 3) put_v(bc, tmp_size);
+ if (tmp_fields > 4) put_v(bc, 0 /*tmp_res*/);
+ if (tmp_fields > 5) put_v(bc, j);
+ if (tmp_fields > 6) put_v(bc, tmp_match);
+ if (tmp_fields > 7) put_v(bc, tmp_head_idx);
}
- ff_put_v(bc, nut->header_count - 1);
+ put_v(bc, nut->header_count - 1);
for (i = 1; i < nut->header_count; i++) {
- ff_put_v(bc, nut->header_len[i]);
+ put_v(bc, nut->header_len[i]);
avio_write(bc, nut->header[i], nut->header_len[i]);
}
// flags had been effectively introduced in version 4
if (nut->version > 3)
- ff_put_v(bc, nut->flags);
+ put_v(bc, nut->flags);
}
static int write_streamheader(AVFormatContext *avctx, AVIOContext *bc,
@@ -409,14 +432,14 @@ static int write_streamheader(AVFormatContext *avctx, AVIOContext *bc,
NUTContext *nut = avctx->priv_data;
AVCodecParameters *par = st->codecpar;
- ff_put_v(bc, i);
+ put_v(bc, i);
switch (par->codec_type) {
- case AVMEDIA_TYPE_VIDEO: ff_put_v(bc, 0); break;
- case AVMEDIA_TYPE_AUDIO: ff_put_v(bc, 1); break;
- case AVMEDIA_TYPE_SUBTITLE: ff_put_v(bc, 2); break;
- default: ff_put_v(bc, 3); break;
+ case AVMEDIA_TYPE_VIDEO: put_v(bc, 0); break;
+ case AVMEDIA_TYPE_AUDIO: put_v(bc, 1); break;
+ case AVMEDIA_TYPE_SUBTITLE: put_v(bc, 2); break;
+ default: put_v(bc, 3); break;
}
- ff_put_v(bc, 4);
+ put_v(bc, 4);
if (par->codec_tag) {
avio_wl32(bc, par->codec_tag);
@@ -425,34 +448,34 @@ static int write_streamheader(AVFormatContext *avctx, AVIOContext *bc,
return AVERROR(EINVAL);
}
- ff_put_v(bc, nut->stream[i].time_base - nut->time_base);
- ff_put_v(bc, nut->stream[i].msb_pts_shift);
- ff_put_v(bc, nut->stream[i].max_pts_distance);
- ff_put_v(bc, par->video_delay);
+ put_v(bc, nut->stream[i].time_base - nut->time_base);
+ put_v(bc, nut->stream[i].msb_pts_shift);
+ put_v(bc, nut->stream[i].max_pts_distance);
+ put_v(bc, par->video_delay);
avio_w8(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
- ff_put_v(bc, par->extradata_size);
+ put_v(bc, par->extradata_size);
avio_write(bc, par->extradata, par->extradata_size);
switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- ff_put_v(bc, par->sample_rate);
- ff_put_v(bc, 1);
- ff_put_v(bc, par->channels);
+ put_v(bc, par->sample_rate);
+ put_v(bc, 1);
+ put_v(bc, par->channels);
break;
case AVMEDIA_TYPE_VIDEO:
- ff_put_v(bc, par->width);
- ff_put_v(bc, par->height);
+ put_v(bc, par->width);
+ put_v(bc, par->height);
if (st->sample_aspect_ratio.num <= 0 ||
st->sample_aspect_ratio.den <= 0) {
- ff_put_v(bc, 0);
- ff_put_v(bc, 0);
+ put_v(bc, 0);
+ put_v(bc, 0);
} else {
- ff_put_v(bc, st->sample_aspect_ratio.num);
- ff_put_v(bc, st->sample_aspect_ratio.den);
+ put_v(bc, st->sample_aspect_ratio.num);
+ put_v(bc, st->sample_aspect_ratio.den);
}
- ff_put_v(bc, 0); /* csp type -- unknown */
+ put_v(bc, 0); /* csp type -- unknown */
break;
default:
break;
@@ -483,12 +506,12 @@ static int write_globalinfo(NUTContext *nut, AVIOContext *bc)
while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)))
count += add_info(dyn_bc, t->key, t->value);
- ff_put_v(bc, 0); //stream_if_plus1
- ff_put_v(bc, 0); //chapter_id
- ff_put_v(bc, 0); //timestamp_start
- ff_put_v(bc, 0); //length
+ put_v(bc, 0); //stream_if_plus1
+ put_v(bc, 0); //chapter_id
+ put_v(bc, 0); //timestamp_start
+ put_v(bc, 0); //length
- ff_put_v(bc, count);
+ put_v(bc, count);
dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
avio_write(bc, dyn_buf, dyn_size);
@@ -524,12 +547,12 @@ static int write_streaminfo(NUTContext *nut, AVIOContext *bc, int stream_id) {
dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
if (count) {
- ff_put_v(bc, stream_id + 1); //stream_id_plus1
- ff_put_v(bc, 0); //chapter_id
- ff_put_v(bc, 0); //timestamp_start
- ff_put_v(bc, 0); //length
+ put_v(bc, stream_id + 1); //stream_id_plus1
+ put_v(bc, 0); //chapter_id
+ put_v(bc, 0); //timestamp_start
+ put_v(bc, 0); //length
- ff_put_v(bc, count);
+ put_v(bc, count);
avio_write(bc, dyn_buf, dyn_size);
}
@@ -550,15 +573,15 @@ static int write_chapter(NUTContext *nut, AVIOContext *bc, int id)
if (ret < 0)
return ret;
- ff_put_v(bc, 0); // stream_id_plus1
+ put_v(bc, 0); // stream_id_plus1
put_s(bc, id + 1); // chapter_id
put_tt(nut, nut->chapter[id].time_base, bc, ch->start); // chapter_start
- ff_put_v(bc, ch->end - ch->start); // chapter_len
+ put_v(bc, ch->end - ch->start); // chapter_len
while ((t = av_dict_get(ch->metadata, "", t, AV_DICT_IGNORE_SUFFIX)))
count += add_info(dyn_bc, t->key, t->value);
- ff_put_v(bc, count);
+ put_v(bc, count);
dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
avio_write(bc, dyn_buf, dyn_size);
@@ -575,11 +598,11 @@ static int write_index(NUTContext *nut, AVIOContext *bc) {
put_tt(nut, nut->max_pts_tb, bc, nut->max_pts);
- ff_put_v(bc, nut->sp_count);
+ put_v(bc, nut->sp_count);
for (i=0; i<nut->sp_count; i++) {
av_tree_find(nut->syncpoints, &dummy, ff_nut_sp_pos_cmp, (void**)next_node);
- ff_put_v(bc, (next_node[1]->pos >> 4) - (dummy.pos>>4));
+ put_v(bc, (next_node[1]->pos >> 4) - (dummy.pos>>4));
dummy.pos = next_node[1]->pos;
}
@@ -600,12 +623,12 @@ static int write_index(NUTContext *nut, AVIOContext *bc) {
for (; j<nut->sp_count && (nus->keyframe_pts[j] != AV_NOPTS_VALUE) == flag; j++)
n++;
- ff_put_v(bc, 1 + 2*flag + 4*n);
+ put_v(bc, 1 + 2 * flag + 4 * n);
for (k= j - n; k<=j && k<nut->sp_count; k++) {
if (nus->keyframe_pts[k] == AV_NOPTS_VALUE)
continue;
av_assert0(nus->keyframe_pts[k] > last_pts);
- ff_put_v(bc, nus->keyframe_pts[k] - last_pts);
+ put_v(bc, nus->keyframe_pts[k] - last_pts);
last_pts = nus->keyframe_pts[k];
}
}
@@ -630,55 +653,44 @@ static int write_headers(AVFormatContext *avctx, AVIOContext *bc)
if (ret < 0)
return ret;
write_mainheader(nut, dyn_bc);
- put_packet(nut, bc, dyn_bc, 1, MAIN_STARTCODE);
+ put_packet(nut, bc, dyn_bc, MAIN_STARTCODE);
for (i = 0; i < nut->avf->nb_streams; i++) {
- ret = avio_open_dyn_buf(&dyn_bc);
- if (ret < 0)
- return ret;
ret = write_streamheader(avctx, dyn_bc, nut->avf->streams[i], i);
if (ret < 0) {
- ffio_free_dyn_buf(&dyn_bc);
- return ret;
+ goto fail;
}
- put_packet(nut, bc, dyn_bc, 1, STREAM_STARTCODE);
+ put_packet(nut, bc, dyn_bc, STREAM_STARTCODE);
}
- ret = avio_open_dyn_buf(&dyn_bc);
- if (ret < 0)
- return ret;
write_globalinfo(nut, dyn_bc);
- put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
+ put_packet(nut, bc, dyn_bc, INFO_STARTCODE);
for (i = 0; i < nut->avf->nb_streams; i++) {
- ret = avio_open_dyn_buf(&dyn_bc);
- if (ret < 0)
- return ret;
ret = write_streaminfo(nut, dyn_bc, i);
if (ret > 0)
- put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
- else {
- ffio_free_dyn_buf(&dyn_bc);
- if (ret < 0)
- return ret;
+ put_packet(nut, bc, dyn_bc, INFO_STARTCODE);
+ else if (ret < 0) {
+ goto fail;
}
}
for (i = 0; i < nut->avf->nb_chapters; i++) {
- ret = avio_open_dyn_buf(&dyn_bc);
- if (ret < 0)
- return ret;
ret = write_chapter(nut, dyn_bc, i);
if (ret < 0) {
- ffio_free_dyn_buf(&dyn_bc);
- return ret;
+ goto fail;
}
- put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
+ put_packet(nut, bc, dyn_bc, INFO_STARTCODE);
}
nut->last_syncpoint_pos = INT_MIN;
nut->header_count++;
- return 0;
+
+ ret = 0;
+fail:
+ ffio_free_dyn_buf(&dyn_bc);
+
+ return ret;
}
static int nut_write_header(AVFormatContext *s)
@@ -876,7 +888,7 @@ static int write_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int
}
put_s(dyn_bc, -2);
put_str(dyn_bc, "bin");
- ff_put_v(dyn_bc, pkt->side_data[i].size);
+ put_v(dyn_bc, pkt->side_data[i].size);
avio_write(dyn_bc, data, pkt->side_data[i].size);
sm_data_count++;
break;
@@ -891,7 +903,7 @@ static int write_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int
put_str(dyn_bc, "ChannelLayout");
put_s(dyn_bc, -2);
put_str(dyn_bc, "u64");
- ff_put_v(bc, 8);
+ put_v(dyn_bc, 8);
avio_write(dyn_bc, data, 8); data+=8;
sm_data_count++;
}
@@ -930,7 +942,7 @@ static int write_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int
}
fail:
- ff_put_v(bc, sm_data_count);
+ put_v(bc, sm_data_count);
dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
avio_write(bc, dyn_buf, dyn_size);
av_freep(&dyn_buf);
@@ -1016,13 +1028,14 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
if (ret < 0)
goto fail;
put_tt(nut, nus->time_base, dyn_bc, pkt->dts);
- ff_put_v(dyn_bc, sp_pos != INT64_MAX ? (nut->last_syncpoint_pos - sp_pos) >> 4 : 0);
+ put_v(dyn_bc, sp_pos != INT64_MAX ? (nut->last_syncpoint_pos - sp_pos) >> 4 : 0);
if (nut->flags & NUT_BROADCAST) {
put_tt(nut, nus->time_base, dyn_bc,
av_rescale_q(av_gettime(), AV_TIME_BASE_Q, *nus->time_base));
}
- put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);
+ put_packet(nut, bc, dyn_bc, SYNCPOINT_STARTCODE);
+ ffio_free_dyn_buf(&dyn_bc);
if (nut->write_index) {
if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts)) < 0)
@@ -1073,18 +1086,18 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
continue;
if (flags & FLAG_STREAM_ID)
- length += ff_get_v_length(pkt->stream_index);
+ length += get_v_length(pkt->stream_index);
if (data_size % fc->size_mul != fc->size_lsb)
continue;
if (flags & FLAG_SIZE_MSB)
- length += ff_get_v_length(data_size / fc->size_mul);
+ length += get_v_length(data_size / fc->size_mul);
if (flags & FLAG_CHECKSUM)
length += 4;
if (flags & FLAG_CODED_PTS)
- length += ff_get_v_length(coded_pts);
+ length += get_v_length(coded_pts);
if ( (flags & FLAG_CODED)
&& nut->header_len[best_header_idx] > nut->header_len[fc->header_idx] + 1) {
@@ -1116,13 +1129,13 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
avio_w8(bc, frame_code);
if (flags & FLAG_CODED) {
- ff_put_v(bc, (flags ^ needed_flags) & ~(FLAG_CODED));
+ put_v(bc, (flags ^ needed_flags) & ~(FLAG_CODED));
flags = needed_flags;
}
- if (flags & FLAG_STREAM_ID) ff_put_v(bc, pkt->stream_index);
- if (flags & FLAG_CODED_PTS) ff_put_v(bc, coded_pts);
- if (flags & FLAG_SIZE_MSB ) ff_put_v(bc, data_size / fc->size_mul);
- if (flags & FLAG_HEADER_IDX) ff_put_v(bc, header_idx = best_header_idx);
+ if (flags & FLAG_STREAM_ID) put_v(bc, pkt->stream_index);
+ if (flags & FLAG_CODED_PTS) put_v(bc, coded_pts);
+ if (flags & FLAG_SIZE_MSB ) put_v(bc, data_size / fc->size_mul);
+ if (flags & FLAG_HEADER_IDX) put_v(bc, header_idx = best_header_idx);
if (flags & FLAG_CHECKSUM) avio_wl32(bc, ffio_get_checksum(bc));
else ffio_get_checksum(bc);
@@ -1175,7 +1188,8 @@ static int nut_write_trailer(AVFormatContext *s)
if (ret >= 0) {
av_assert1(nut->write_index); // sp_count should be 0 if no index is going to be written
write_index(nut, dyn_bc);
- put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE);
+ put_packet(nut, bc, dyn_bc, INDEX_STARTCODE);
+ ffio_free_dyn_buf(&dyn_bc);
}
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/oggdec.c b/chromium/third_party/ffmpeg/libavformat/oggdec.c
index 15e86940767..52cd410d0f9 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggdec.c
@@ -31,6 +31,7 @@
#include <stdio.h>
#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
+#include "avio_internal.h"
#include "oggdec.h"
#include "avformat.h"
#include "internal.h"
@@ -42,7 +43,6 @@
static const struct ogg_codec * const ogg_codecs[] = {
&ff_skeleton_codec,
#if 0 // These codecs are not supported by Chromium.
- &ff_daala_codec,
&ff_dirac_codec,
&ff_speex_codec,
#endif
@@ -104,7 +104,13 @@ static int ogg_save(AVFormatContext *s)
for (i = 0; i < ogg->nstreams; i++) {
struct ogg_stream *os = ogg->streams + i;
+// Chromium: always allocate |buf| using av_realloc().
+// av_mallocz() will use posix_memalign(), preventing reallocation.
+#if 0
os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
+#else
+ os->buf = av_realloc(NULL, os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
+#endif
if (os->buf)
memcpy(os->buf, ost->streams[i].buf, os->bufpos);
else
@@ -183,6 +189,7 @@ static int ogg_reset(AVFormatContext *s)
if (start_pos <= s->internal->data_offset) {
os->lastpts = 0;
}
+ os->start_trimming = 0;
os->end_trimming = 0;
av_freep(&os->new_metadata);
os->new_metadata_size = 0;
@@ -211,60 +218,43 @@ static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
* situation where a new audio stream spawn (identified with a new serial) and
* must replace the previous one (track switch).
*/
-static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
+static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, int page_size,
+ int probing)
{
struct ogg *ogg = s->priv_data;
struct ogg_stream *os;
const struct ogg_codec *codec;
int i = 0;
- if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
- uint8_t magic[8];
- int64_t pos = avio_tell(s->pb);
- avio_skip(s->pb, nsegs);
- if (avio_read(s->pb, magic, sizeof(magic)) != sizeof(magic))
- return AVERROR_INVALIDDATA;
- avio_seek(s->pb, pos, SEEK_SET);
- codec = ogg_find_codec(magic, sizeof(magic));
- if (!codec) {
- av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < ogg->nstreams; i++) {
- if (ogg->streams[i].codec == codec)
- break;
- }
- if (i >= ogg->nstreams)
- return ogg_new_stream(s, serial);
- } else if (ogg->nstreams != 1) {
+ if (ogg->nstreams != 1) {
avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
return AVERROR_PATCHWELCOME;
}
- os = &ogg->streams[i];
-
- os->serial = serial;
- return i;
-
-#if 0
- buf = os->buf;
- bufsize = os->bufsize;
- codec = os->codec;
+ /* Check for codecs */
+ codec = ogg_find_codec(magic, page_size);
+ if (!codec && !probing) {
+ av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
+ return AVERROR_INVALIDDATA;
+ }
- if (!ogg->state || ogg->state->streams[i].private != os->private)
- av_freep(&ogg->streams[i].private);
+ os = &ogg->streams[0];
+ if (os->codec != codec)
+ return AVERROR(EINVAL);
- /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
- * also re-use the ogg_stream allocated buffer */
- memset(os, 0, sizeof(*os));
os->serial = serial;
- os->bufsize = bufsize;
- os->buf = buf;
- os->header = -1;
os->codec = codec;
+ os->serial = serial;
+ os->lastpts = 0;
+ os->lastdts = 0;
+ os->start_trimming = 0;
+ os->end_trimming = 0;
+
+ /* Chained files have extradata as a new packet */
+ if (codec == &ff_opus_codec)
+ os->header = -1;
return i;
-#endif
}
static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
@@ -290,7 +280,13 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
memset(os, 0, sizeof(*os));
os->serial = serial;
os->bufsize = DECODER_BUFFER_SIZE;
+// Chromium: always allocate |buf| using av_realloc().
+// av_malloc() will use posix_memalign(), preventing reallocation.
+#if 0
os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
+#else
+ os->buf = av_realloc(NULL, os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
+#endif
os->header = -1;
os->start_granule = OGG_NOGRANULE_VALUE;
if (!os->buf)
@@ -309,27 +305,6 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
return idx;
}
-static int ogg_new_buf(struct ogg *ogg, int idx)
-{
- struct ogg_stream *os = ogg->streams + idx;
- uint8_t *nb = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
- int size = os->bufpos - os->pstart;
-
- if (!nb)
- return AVERROR(ENOMEM);
-
- if (os->buf) {
- memcpy(nb, os->buf + os->pstart, size);
- av_free(os->buf);
- }
-
- os->buf = nb;
- os->bufpos = size;
- os->pstart = 0;
-
- return 0;
-}
-
static int data_packets_seen(const struct ogg *ogg)
{
int i;
@@ -340,7 +315,21 @@ static int data_packets_seen(const struct ogg *ogg)
return 0;
}
-static int ogg_read_page(AVFormatContext *s, int *sid)
+static int buf_realloc(struct ogg_stream *os, int size)
+{
+ /* Even if invalid guarantee there's enough memory to read the page */
+ if (os->bufsize - os->bufpos < size) {
+ uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!nb)
+ return AVERROR(ENOMEM);
+ os->buf = nb;
+ os->bufsize *= 2;
+ }
+
+ return 0;
+}
+
+static int ogg_read_page(AVFormatContext *s, int *sid, int probing)
{
AVIOContext *bc = s->pb;
struct ogg *ogg = s->priv_data;
@@ -349,8 +338,13 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
int flags, nsegs;
uint64_t gp;
uint32_t serial;
- int size, idx;
+ uint32_t crc, crc_tmp;
+ int size = 0, idx;
+ int64_t version, page_pos;
+ int64_t start_pos;
uint8_t sync[4];
+ uint8_t segments[255];
+ uint8_t *readout_buf;
int sp = 0;
ret = avio_read(bc, sync, 4);
@@ -384,56 +378,109 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
return AVERROR_INVALIDDATA;
}
- if (avio_r8(bc) != 0) { /* version */
- av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
- return AVERROR_INVALIDDATA;
- }
+ /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
+ ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
+
+ /* To rewind if checksum is bad/check magic on switches - this is the max packet size */
+ ffio_ensure_seekback(bc, MAX_PAGE_SIZE);
+ start_pos = avio_tell(bc);
+
+ version = avio_r8(bc);
+ flags = avio_r8(bc);
+ gp = avio_rl64(bc);
+ serial = avio_rl32(bc);
+ avio_skip(bc, 4); /* seq */
- flags = avio_r8(bc);
- gp = avio_rl64(bc);
- serial = avio_rl32(bc);
- avio_skip(bc, 8); /* seq, crc */
- nsegs = avio_r8(bc);
+ crc_tmp = ffio_get_checksum(bc);
+ crc = avio_rb32(bc);
+ crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
+ ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
- if (avio_feof(bc))
- return AVERROR_EOF;
+ nsegs = avio_r8(bc);
+ page_pos = avio_tell(bc) - 27;
+
+ ret = avio_read(bc, segments, nsegs);
+ if (ret < nsegs)
+ return ret < 0 ? ret : AVERROR_EOF;
+
+ for (i = 0; i < nsegs; i++)
+ size += segments[i];
idx = ogg_find_stream(ogg, serial);
+ if (idx >= 0) {
+ os = ogg->streams + idx;
+
+ ret = buf_realloc(os, size);
+ if (ret < 0)
+ return ret;
+
+ readout_buf = os->buf + os->bufpos;
+ } else {
+ readout_buf = av_malloc(size);
+ }
+
+ ret = avio_read(bc, readout_buf, size);
+ if (ret < size) {
+ if (idx < 0)
+ av_free(readout_buf);
+ return ret < 0 ? ret : AVERROR_EOF;
+ }
+
+ if (crc ^ ffio_get_checksum(bc)) {
+ av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
+ if (idx < 0)
+ av_free(readout_buf);
+ avio_seek(bc, start_pos, SEEK_SET);
+ *sid = -1;
+ return 0;
+ }
+
+ /* Since we're almost sure its a valid packet, checking the version after
+ * the checksum lets the demuxer be more tolerant */
+ if (version) {
+ av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
+ if (idx < 0)
+ av_free(readout_buf);
+ avio_seek(bc, start_pos, SEEK_SET);
+ *sid = -1;
+ return 0;
+ }
+
+ /* CRC is correct so we can be 99% sure there's an actual change here */
if (idx < 0) {
if (data_packets_seen(ogg))
- idx = ogg_replace_stream(s, serial, nsegs);
+ idx = ogg_replace_stream(s, serial, readout_buf, size, probing);
else
idx = ogg_new_stream(s, serial);
if (idx < 0) {
av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
+ av_free(readout_buf);
return idx;
}
- }
- os = ogg->streams + idx;
- ogg->page_pos =
- os->page_pos = avio_tell(bc) - 27;
+ os = ogg->streams + idx;
- if (os->psize > 0) {
- ret = ogg_new_buf(ogg, idx);
- if (ret < 0)
+ ret = buf_realloc(os, size);
+ if (ret < 0) {
+ av_free(readout_buf);
return ret;
- }
-
- ret = avio_read(bc, os->segments, nsegs);
- if (ret < nsegs)
- return ret < 0 ? ret : AVERROR_EOF;
-
- os->nsegs = nsegs;
- os->segp = 0;
+ }
- size = 0;
- for (i = 0; i < nsegs; i++)
- size += os->segments[i];
+ memcpy(os->buf + os->bufpos, readout_buf, size);
+ av_free(readout_buf);
+ }
- if (!(flags & OGG_FLAG_BOS))
- os->got_data = 1;
+ ogg->page_pos = page_pos;
+ os->page_pos = page_pos;
+ os->nsegs = nsegs;
+ os->segp = 0;
+ os->got_data = !(flags & OGG_FLAG_BOS);
+ os->bufpos += size;
+ os->granule = gp;
+ os->flags = flags;
+ memcpy(os->segments, segments, nsegs);
+ memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
if (flags & OGG_FLAG_CONT || os->incomplete) {
if (!os->psize) {
@@ -453,26 +500,8 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
os->sync_pos = os->page_pos;
}
- if (os->bufsize - os->bufpos < 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);
- av_free(os->buf);
- os->buf = nb;
- }
-
- ret = avio_read(bc, os->buf + os->bufpos, size);
- if (ret < size)
- return ret < 0 ? ret : AVERROR_EOF;
-
- os->bufpos += size;
- os->granule = gp;
- os->flags = flags;
-
- memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- if (sid)
- *sid = idx;
+ /* This function is always called with sid != NULL */
+ *sid = idx;
return 0;
}
@@ -501,7 +530,7 @@ static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
idx = ogg->curidx;
while (idx < 0) {
- ret = ogg_read_page(s, &idx);
+ ret = ogg_read_page(s, &idx, 0);
if (ret < 0)
return ret;
}
@@ -652,8 +681,8 @@ static int ogg_get_length(AVFormatContext *s)
avio_seek(s->pb, end, SEEK_SET);
ogg->page_pos = -1;
- while (!ogg_read_page(s, &i)) {
- if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
+ while (!ogg_read_page(s, &i, 1)) {
+ if (i >= 0 && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
ogg->streams[i].codec) {
s->streams[i]->duration =
ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
@@ -856,25 +885,25 @@ retry:
pkt->duration = os->pduration;
pkt->pos = fpos;
- if (os->end_trimming) {
+ if (os->start_trimming || os->end_trimming) {
uint8_t *side_data = av_packet_new_side_data(pkt,
AV_PKT_DATA_SKIP_SAMPLES,
10);
if(!side_data)
return AVERROR(ENOMEM);
+ AV_WL32(side_data + 0, os->start_trimming);
AV_WL32(side_data + 4, os->end_trimming);
+ os->start_trimming = 0;
os->end_trimming = 0;
}
if (os->new_metadata) {
- uint8_t *side_data = av_packet_new_side_data(pkt,
- AV_PKT_DATA_METADATA_UPDATE,
- os->new_metadata_size);
- if(!side_data)
- return AVERROR(ENOMEM);
+ ret = av_packet_add_side_data(pkt, AV_PKT_DATA_METADATA_UPDATE,
+ os->new_metadata, os->new_metadata_size);
+ if (ret < 0)
+ return ret;
- memcpy(side_data, os->new_metadata, os->new_metadata_size);
- av_freep(&os->new_metadata);
+ os->new_metadata = NULL;
os->new_metadata_size = 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/oggdec.h b/chromium/third_party/ffmpeg/libavformat/oggdec.h
index 4a2b6ddee8f..629a1d62628 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggdec.h
+++ b/chromium/third_party/ffmpeg/libavformat/oggdec.h
@@ -84,6 +84,7 @@ struct ogg_stream {
int got_start;
int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise
int nb_header; ///< set to the number of parsed headers
+ int start_trimming; ///< set the number of packets to drop from the start
int end_trimming; ///< set the number of packets to drop from the end
uint8_t *new_metadata;
unsigned int new_metadata_size;
@@ -114,7 +115,6 @@ struct ogg {
#define OGG_NOGRANULE_VALUE (-1ull)
extern const struct ogg_codec ff_celt_codec;
-extern const struct ogg_codec ff_daala_codec;
extern const struct ogg_codec ff_dirac_codec;
extern const struct ogg_codec ff_flac_codec;
extern const struct ogg_codec ff_ogm_audio_codec;
diff --git a/chromium/third_party/ffmpeg/libavformat/oggenc.c b/chromium/third_party/ffmpeg/libavformat/oggenc.c
index fbd14fedf9b..f5032759a64 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggenc.c
@@ -99,50 +99,32 @@ static const AVClass flavor ## _muxer_class = {\
.version = LIBAVUTIL_VERSION_INT,\
};
-static void ogg_update_checksum(AVFormatContext *s, AVIOContext *pb, int64_t crc_offset)
-{
- int64_t pos = avio_tell(pb);
- uint32_t checksum = ffio_get_checksum(pb);
- avio_seek(pb, crc_offset, SEEK_SET);
- avio_wb32(pb, checksum);
- avio_seek(pb, pos, SEEK_SET);
-}
-
-static int ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
+static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
{
OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data;
- AVIOContext *pb;
- int64_t crc_offset;
- int ret, size;
- uint8_t *buf;
-
- ret = avio_open_dyn_buf(&pb);
- if (ret < 0)
- return ret;
- ffio_init_checksum(pb, ff_crc04C11DB7_update, 0);
- ffio_wfourcc(pb, "OggS");
- avio_w8(pb, 0);
- avio_w8(pb, page->flags | extra_flags);
- avio_wl64(pb, page->granule);
- avio_wl32(pb, oggstream->serial_num);
- avio_wl32(pb, oggstream->page_counter++);
- crc_offset = avio_tell(pb);
- avio_wl32(pb, 0); // crc
- avio_w8(pb, page->segments_count);
- avio_write(pb, page->segments, page->segments_count);
- avio_write(pb, page->data, page->size);
-
- ogg_update_checksum(s, pb, crc_offset);
-
- size = avio_close_dyn_buf(pb, &buf);
- if (size < 0)
- return size;
-
- avio_write(s->pb, buf, size);
+ uint8_t buf[4 + 1 + 1 + 8 + 4 + 4 + 4 + 1 + 255], *ptr = buf, *crc_pos;
+ const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE);
+ uint32_t crc;
+
+ bytestream_put_le32(&ptr, MKTAG('O', 'g', 'g', 'S'));
+ bytestream_put_byte(&ptr, 0);
+ bytestream_put_byte(&ptr, page->flags | extra_flags);
+ bytestream_put_le64(&ptr, page->granule);
+ bytestream_put_le32(&ptr, oggstream->serial_num);
+ bytestream_put_le32(&ptr, oggstream->page_counter++);
+ crc_pos = ptr;
+ bytestream_put_le32(&ptr, 0);
+ bytestream_put_byte(&ptr, page->segments_count);
+ bytestream_put_buffer(&ptr, page->segments, page->segments_count);
+
+ crc = av_crc(crc_table, 0, buf, ptr - buf);
+ crc = av_crc(crc_table, crc, page->data, page->size);
+ bytestream_put_be32(&crc_pos, crc);
+
+ avio_write(s->pb, buf, ptr - buf);
+ avio_write(s->pb, page->data, page->size);
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
- av_free(buf);
oggstream->page_count--;
- return 0;
}
static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
@@ -294,8 +276,9 @@ static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact,
AVChapter **chapters, unsigned int nb_chapters)
{
const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
+ AVIOContext pb;
int64_t size;
- uint8_t *p, *p0;
+ uint8_t *p;
ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
@@ -305,15 +288,14 @@ static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact,
p = av_mallocz(size);
if (!p)
return NULL;
- p0 = p;
- p += offset;
- ff_vorbiscomment_write(&p, m, vendor, chapters, nb_chapters);
+ ffio_init_context(&pb, p + offset, size - offset, 1, NULL, NULL, NULL, NULL);
+ ff_vorbiscomment_write(&pb, *m, vendor, chapters, nb_chapters);
if (framing_bit)
- bytestream_put_byte(&p, 1);
+ avio_w8(&pb, 1);
*header_len = size;
- return p0;
+ return p;
}
static int ogg_build_flac_headers(AVCodecParameters *par,
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparsedaala.c b/chromium/third_party/ffmpeg/libavformat/oggparsedaala.c
deleted file mode 100644
index e944470aca3..00000000000
--- a/chromium/third_party/ffmpeg/libavformat/oggparsedaala.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Ogg Daala parser
- * Copyright (C) 2015 Rostislav Pehlivanov <atomnuker gmail com>
- * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara 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
- */
-
-#include <stdlib.h>
-#include "libavcodec/bytestream.h"
-#include "avformat.h"
-#include "internal.h"
-#include "oggdec.h"
-
-struct DaalaPixFmtMap {
- enum AVPixelFormat ffmpeg_fmt;
- int depth;
- int planes;
- int xdec[4];
- int ydec[4];
-};
-
-/* Currently supported formats only */
-static const struct DaalaPixFmtMap list_fmts[] = {
- { AV_PIX_FMT_YUV420P, 8, 3, {0, 1, 1, 0}, {0, 1, 1, 0} },
- { AV_PIX_FMT_YUV444P, 8, 3, {0, 0, 0, 0}, {0, 0, 0, 0} }
-};
-
-typedef struct DaalaInfoHeader {
- int init_d;
- int fpr;
- int gpshift;
- int gpmask;
- int version_maj;
- int version_min;
- int version_sub;
- int frame_duration;
- int keyframe_granule_shift;
- struct DaalaPixFmtMap format;
-} DaalaInfoHeader;
-
-static inline int daala_match_pix_fmt(struct DaalaPixFmtMap *fmt)
-{
- int i, j;
- for (i = 0; i < FF_ARRAY_ELEMS(list_fmts); i++) {
- int match = 0;
- if (fmt->depth != list_fmts[i].depth)
- continue;
- if (fmt->planes != list_fmts[i].planes)
- continue;
- for (j = 0; j < fmt->planes; j++) {
- if (fmt->xdec[j] != list_fmts[i].xdec[j])
- continue;
- if (fmt->ydec[j] != list_fmts[i].ydec[j])
- continue;
- match++;
- }
- if (match == fmt->planes)
- return list_fmts[i].ffmpeg_fmt;
- }
- return -1;
-}
-
-static int daala_header(AVFormatContext *s, int idx)
-{
- int i, err;
- uint8_t *cdp;
- GetByteContext gb;
- AVRational timebase;
- struct ogg *ogg = s->priv_data;
- struct ogg_stream *os = ogg->streams + idx;
- AVStream *st = s->streams[idx];
- int cds = st->codecpar->extradata_size + os->psize + 2;
- DaalaInfoHeader *hdr = os->private;
-
- if (!(os->buf[os->pstart] & 0x80))
- return 0;
-
- if (!hdr) {
- hdr = av_mallocz(sizeof(*hdr));
- if (!hdr)
- return AVERROR(ENOMEM);
- os->private = hdr;
- }
-
- switch (os->buf[os->pstart]) {
- case 0x80:
- bytestream2_init(&gb, os->buf + os->pstart, os->psize);
- bytestream2_skip(&gb, ff_daala_codec.magicsize);
-
- hdr->version_maj = bytestream2_get_byte(&gb);
- hdr->version_min = bytestream2_get_byte(&gb);
- hdr->version_sub = bytestream2_get_byte(&gb);
-
- st->codecpar->width = bytestream2_get_ne32(&gb);
- st->codecpar->height = bytestream2_get_ne32(&gb);
-
- st->sample_aspect_ratio.num = bytestream2_get_ne32(&gb);
- st->sample_aspect_ratio.den = bytestream2_get_ne32(&gb);
-
- timebase.num = bytestream2_get_ne32(&gb);
- timebase.den = bytestream2_get_ne32(&gb);
- if (timebase.num < 0 && timebase.den < 0) {
- av_log(s, AV_LOG_WARNING, "Invalid timebase, assuming 30 FPS\n");
- timebase.num = 1;
- timebase.den = 30;
- }
- avpriv_set_pts_info(st, 64, timebase.den, timebase.num);
-
- hdr->frame_duration = bytestream2_get_ne32(&gb);
- hdr->gpshift = bytestream2_get_byte(&gb);
- if (hdr->gpshift >= 32) {
- av_log(s, AV_LOG_ERROR, "Too large gpshift %d (>= 32).\n",
- hdr->gpshift);
- hdr->gpshift = 0;
- return AVERROR_INVALIDDATA;
- }
- hdr->gpmask = (1U << hdr->gpshift) - 1;
-
- hdr->format.depth = 8 + 2*(bytestream2_get_byte(&gb)-1);
-
- hdr->fpr = bytestream2_get_byte(&gb);
-
- hdr->format.planes = bytestream2_get_byte(&gb);
- if (hdr->format.planes > 4) {
- av_log(s, AV_LOG_ERROR,
- "Invalid number of planes %d in daala pixel format map.\n",
- hdr->format.planes);
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < hdr->format.planes; i++) {
- hdr->format.xdec[i] = bytestream2_get_byte(&gb);
- hdr->format.ydec[i] = bytestream2_get_byte(&gb);
- }
-
- if ((st->codecpar->format = daala_match_pix_fmt(&hdr->format)) < 0)
- av_log(s, AV_LOG_ERROR, "Unsupported pixel format - %i %i\n",
- hdr->format.depth, hdr->format.planes);
-
- st->codecpar->codec_id = AV_CODEC_ID_DAALA;
- st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
- st->need_parsing = AVSTREAM_PARSE_HEADERS;
-
- hdr->init_d = 1;
- break;
- case 0x81:
- if (!hdr->init_d)
- return AVERROR_INVALIDDATA;
- ff_vorbis_stream_comment(s, st,
- os->buf + os->pstart + ff_daala_codec.magicsize,
- os->psize - ff_daala_codec.magicsize);
- break;
- case 0x82:
- if (!hdr->init_d)
- return AVERROR_INVALIDDATA;
- break;
- default:
- av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
- return AVERROR_INVALIDDATA;
- break;
- }
-
- if ((err = av_reallocp(&st->codecpar->extradata,
- cds + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
- st->codecpar->extradata_size = 0;
- return err;
- }
-
- memset(st->codecpar->extradata + cds, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- cdp = st->codecpar->extradata + st->codecpar->extradata_size;
- *cdp++ = os->psize >> 8;
- *cdp++ = os->psize & 0xff;
- memcpy(cdp, os->buf + os->pstart, os->psize);
- st->codecpar->extradata_size = cds;
-
- return 1;
-}
-
-static uint64_t daala_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
- int64_t *dts)
-{
- uint64_t iframe, pframe;
- struct ogg *ogg = ctx->priv_data;
- struct ogg_stream *os = ogg->streams + idx;
- DaalaInfoHeader *hdr = os->private;
-
- if (!hdr)
- return AV_NOPTS_VALUE;
-
- iframe = gp >> hdr->gpshift;
- pframe = gp & hdr->gpmask;
-
- if (!pframe)
- os->pflags |= AV_PKT_FLAG_KEY;
-
- if (dts)
- *dts = iframe + pframe;
-
- return iframe + pframe;
-}
-
-static int daala_packet(AVFormatContext *s, int idx)
-{
- int seg, duration = 1;
- struct ogg *ogg = s->priv_data;
- struct ogg_stream *os = ogg->streams + idx;
- int64_t pts;
-
- /*
- * 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 set the first timestamp
- */
-
- if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
- for (seg = os->segp; seg < os->nsegs; seg++)
- if (os->segments[seg] < 255)
- duration++;
-
- pts = daala_gptopts(s, idx, os->granule, NULL);
- if (pts != AV_NOPTS_VALUE)
- pts -= duration;
- os->lastpts = os->lastdts = pts;
- if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
- s->streams[idx]->start_time = os->lastpts;
- if (s->streams[idx]->duration != AV_NOPTS_VALUE)
- s->streams[idx]->duration -= s->streams[idx]->start_time;
- }
- }
-
- /* parse packet duration */
- if (os->psize > 0)
- os->pduration = 1;
-
- return 0;
-}
-
-const struct ogg_codec ff_daala_codec = {
- .name = "Daala",
- .magic = "\200daala",
- .magicsize = 6,
- .header = daala_header,
- .packet = daala_packet,
- .gptopts = daala_gptopts,
- .granule_is_start = 1,
- .nb_header = 3,
-};
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparseopus.c b/chromium/third_party/ffmpeg/libavformat/oggparseopus.c
index 56b53e74e8d..36d691e9aaf 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparseopus.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparseopus.c
@@ -59,6 +59,7 @@ static int opus_header(AVFormatContext *avf, int idx)
priv->pre_skip = AV_RL16(packet + 10);
st->codecpar->initial_padding = priv->pre_skip;
+ os->start_trimming = priv->pre_skip;
/*orig_sample_rate = AV_RL32(packet + 12);*/
/*gain = AV_RL16(packet + 16);*/
/*channel_map = AV_RL8 (packet + 18);*/
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c b/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
index 27d2c686b69..0e8c25c030b 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
@@ -165,7 +165,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
av_freep(&tt);
av_freep(&ct);
if (ret > 0)
- ret = ff_flac_parse_picture(as, pict, ret);
+ ret = ff_flac_parse_picture(as, pict, ret, 0);
av_freep(&pict);
if (ret < 0) {
av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
@@ -287,7 +287,7 @@ static int vorbis_update_metadata(AVFormatContext *s, int idx)
os->new_metadata = av_packet_pack_dictionary(st->metadata, &os->new_metadata_size);
/* Send an empty dictionary to indicate that metadata has been cleared. */
} else {
- os->new_metadata = av_malloc(1);
+ os->new_metadata = av_mallocz(1);
os->new_metadata_size = 0;
}
@@ -385,7 +385,12 @@ static int vorbis_header(AVFormatContext *s, int idx)
}
}
} else {
- int ret = fixup_vorbis_headers(s, priv, &st->codecpar->extradata);
+ int ret;
+
+ if (priv->vp)
+ return AVERROR_INVALIDDATA;
+
+ ret = fixup_vorbis_headers(s, priv, &st->codecpar->extradata);
if (ret < 0) {
st->codecpar->extradata_size = 0;
return ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/omadec.c b/chromium/third_party/ffmpeg/libavformat/omadec.c
index 9521b6d59e9..5675d86e75e 100644
--- a/chromium/third_party/ffmpeg/libavformat/omadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/omadec.c
@@ -79,6 +79,13 @@ typedef struct OMAContext {
int (*read_packet)(AVFormatContext *s, AVPacket *pkt);
} OMAContext;
+static int oma_read_close(AVFormatContext *s)
+{
+ OMAContext *oc = s->priv_data;
+ av_freep(&oc->av_des);
+ return 0;
+}
+
static void hex_log(AVFormatContext *s, int level,
const char *name, const uint8_t *value, int len)
{
@@ -217,14 +224,13 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
av_log(s, AV_LOG_INFO, "File is encrypted\n");
/* find GEOB metadata */
- while (em) {
- if (!strcmp(em->tag, "GEOB") &&
- (geob = em->data) &&
- (!strcmp(geob->description, "OMG_LSI") ||
- !strcmp(geob->description, "OMG_BKLSI"))) {
+ for (; em; em = em->next) {
+ if (strcmp(em->tag, "GEOB"))
+ continue;
+ geob = &em->data.geob;
+ if (!strcmp(geob->description, "OMG_LSI") ||
+ !strcmp(geob->description, "OMG_BKLSI"))
break;
- }
- em = em->next;
}
if (!em) {
av_log(s, AV_LOG_ERROR, "No encryption header found\n");
@@ -397,17 +403,20 @@ static int oma_read_header(AVFormatContext *s)
OMAContext *oc = s->priv_data;
ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0);
- if ((ret = ff_id3v2_parse_chapters(s, &extra_meta)) < 0) {
+ if ((ret = ff_id3v2_parse_chapters(s, extra_meta)) < 0) {
ff_id3v2_free_extra_meta(&extra_meta);
return ret;
}
ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
- if (ret < EA3_HEADER_SIZE)
+ if (ret < EA3_HEADER_SIZE) {
+ ff_id3v2_free_extra_meta(&extra_meta);
return -1;
+ }
if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) ||
buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
+ ff_id3v2_free_extra_meta(&extra_meta);
av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
return AVERROR_INVALIDDATA;
}
@@ -426,8 +435,10 @@ static int oma_read_header(AVFormatContext *s)
codec_params = AV_RB24(&buf[33]);
st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
st->start_time = 0;
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -442,7 +453,8 @@ static int oma_read_header(AVFormatContext *s)
samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
if (!samplerate) {
av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
}
if (samplerate != 44100)
avpriv_request_sample(s, "Sample rate %d", samplerate);
@@ -460,7 +472,7 @@ static int oma_read_header(AVFormatContext *s)
/* fake the ATRAC3 extradata
* (wav format, makes stream copy to wav work) */
if ((ret = ff_alloc_extradata(st->codecpar, 14)) < 0)
- return ret;
+ goto fail;
edata = st->codecpar->extradata;
AV_WL16(&edata[0], 1); // always 1
@@ -477,7 +489,8 @@ static int oma_read_header(AVFormatContext *s)
if (!channel_id) {
av_log(s, AV_LOG_ERROR,
"Invalid ATRAC-X channel id: %"PRIu32"\n", channel_id);
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
}
st->codecpar->channel_layout = ff_oma_chid_to_native_layout[channel_id - 1];
st->codecpar->channels = ff_oma_chid_to_num_channels[channel_id - 1];
@@ -485,7 +498,8 @@ static int oma_read_header(AVFormatContext *s)
samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
if (!samplerate) {
av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
}
st->codecpar->sample_rate = samplerate;
st->codecpar->bit_rate = samplerate * framesize / (2048 / 8);
@@ -525,12 +539,16 @@ static int oma_read_header(AVFormatContext *s)
break;
default:
av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]);
- return AVERROR(ENOSYS);
+ ret = AVERROR(ENOSYS);
+ goto fail;
}
st->codecpar->block_align = framesize;
return 0;
+fail:
+ oma_read_close(s);
+ return ret;
}
static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
@@ -592,13 +610,6 @@ wipe:
return err;
}
-static int oma_read_close(AVFormatContext *s)
-{
- OMAContext *oc = s->priv_data;
- av_free(oc->av_des);
- return 0;
-}
-
AVInputFormat ff_oma_demuxer = {
.name = "oma",
.long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
diff --git a/chromium/third_party/ffmpeg/libavformat/options.c b/chromium/third_party/ffmpeg/libavformat/options.c
index e14510504f7..3160904fda9 100644
--- a/chromium/third_party/ffmpeg/libavformat/options.c
+++ b/chromium/third_party/ffmpeg/libavformat/options.c
@@ -21,6 +21,7 @@
#include "avio_internal.h"
#include "internal.h"
+#include "libavutil/avassert.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
@@ -53,6 +54,8 @@ static void *format_child_next(void *obj, void *prev)
return NULL;
}
+#if FF_API_CHILD_CLASS_NEXT
+FF_DISABLE_DEPRECATION_WARNINGS
static const AVClass *format_child_class_next(const AVClass *prev)
{
AVInputFormat *ifmt = NULL;
@@ -80,6 +83,64 @@ static const AVClass *format_child_class_next(const AVClass *prev)
return NULL;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+enum {
+ CHILD_CLASS_ITER_AVIO = 0,
+ CHILD_CLASS_ITER_MUX,
+ CHILD_CLASS_ITER_DEMUX,
+ CHILD_CLASS_ITER_DONE,
+
+};
+
+#define ITER_STATE_SHIFT 16
+
+static const AVClass *format_child_class_iterate(void **iter)
+{
+ // we use the low 16 bits of iter as the value to be passed to
+ // av_(de)muxer_iterate()
+ void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1));
+ unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT;
+ const AVClass *ret = NULL;
+
+ if (state == CHILD_CLASS_ITER_AVIO) {
+ ret = &ff_avio_class;
+ state++;
+ goto finish;
+ }
+
+ if (state == CHILD_CLASS_ITER_MUX) {
+ const AVOutputFormat *ofmt;
+
+ while ((ofmt = av_muxer_iterate(&val))) {
+ ret = ofmt->priv_class;
+ if (ret)
+ goto finish;
+ }
+
+ val = NULL;
+ state++;
+ }
+
+ if (state == CHILD_CLASS_ITER_DEMUX) {
+ const AVInputFormat *ifmt;
+
+ while ((ifmt = av_demuxer_iterate(&val))) {
+ ret = ifmt->priv_class;
+ if (ret)
+ goto finish;
+ }
+ val = NULL;
+ state++;
+ }
+
+finish:
+ // make sure none av_(de)muxer_iterate does not set the high bits of val
+ av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT));
+ *iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT));
+ return ret;
+}
static AVClassCategory get_category(void *ptr)
{
@@ -94,7 +155,10 @@ static const AVClass av_format_context_class = {
.option = avformat_options,
.version = LIBAVUTIL_VERSION_INT,
.child_next = format_child_next,
+#if FF_API_CHILD_CLASS_NEXT
.child_class_next = format_child_class_next,
+#endif
+ .child_class_iterate = format_child_class_iterate,
.category = AV_CLASS_CATEGORY_MUXER,
.get_category = get_category,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/pjsdec.c b/chromium/third_party/ffmpeg/libavformat/pjsdec.c
index 8a5cc04f841..1f1d51c4049 100644
--- a/chromium/third_party/ffmpeg/libavformat/pjsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/pjsdec.c
@@ -67,7 +67,6 @@ static int pjs_read_header(AVFormatContext *s)
{
PJSContext *pjs = s->priv_data;
AVStream *st = avformat_new_stream(s, NULL);
- int res = 0;
if (!st)
return AVERROR(ENOMEM);
@@ -94,8 +93,10 @@ static int pjs_read_header(AVFormatContext *s)
p[strcspn(p, "\"")] = 0;
sub = ff_subtitles_queue_insert(&pjs->q, p, strlen(p), 0);
- if (!sub)
+ if (!sub) {
+ ff_subtitles_queue_clean(&pjs->q);
return AVERROR(ENOMEM);
+ }
sub->pos = pos;
sub->pts = pts_start;
sub->duration = duration;
@@ -103,7 +104,7 @@ static int pjs_read_header(AVFormatContext *s)
}
ff_subtitles_queue_finalize(s, &pjs->q);
- return res;
+ return 0;
}
static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/pp_bnk.c b/chromium/third_party/ffmpeg/libavformat/pp_bnk.c
new file mode 100644
index 00000000000..8364de1fd9c
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/pp_bnk.c
@@ -0,0 +1,292 @@
+/*
+ * Pro Pinball Series Soundbank (44c, 22c, 11c, 5c) demuxer.
+ *
+ * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.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
+ */
+#include "avformat.h"
+#include "internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
+
+#define PP_BNK_MAX_READ_SIZE 4096
+#define PP_BNK_FILE_HEADER_SIZE 20
+#define PP_BNK_TRACK_SIZE 20
+
+typedef struct PPBnkHeader {
+ uint32_t bank_id; /*< Bank ID, useless for our purposes. */
+ uint32_t sample_rate; /*< Sample rate of the contained tracks. */
+ uint32_t always1; /*< Unknown, always seems to be 1. */
+ uint32_t track_count; /*< Number of tracks in the file. */
+ uint32_t flags; /*< Flags. */
+} PPBnkHeader;
+
+typedef struct PPBnkTrack {
+ uint32_t id; /*< Track ID. Usually track[i].id == track[i-1].id + 1, but not always */
+ uint32_t size; /*< Size of the data in bytes. */
+ uint32_t sample_rate; /*< Sample rate. */
+ uint32_t always1_1; /*< Unknown, always seems to be 1. */
+ uint32_t always1_2; /*< Unknown, always seems to be 1. */
+} PPBnkTrack;
+
+typedef struct PPBnkCtxTrack {
+ int64_t data_offset;
+ uint32_t data_size;
+ uint32_t bytes_read;
+} PPBnkCtxTrack;
+
+typedef struct PPBnkCtx {
+ int track_count;
+ PPBnkCtxTrack *tracks;
+ uint32_t current_track;
+} PPBnkCtx;
+
+enum {
+ PP_BNK_FLAG_PERSIST = (1 << 0), /*< This is a large file, keep in memory. */
+ PP_BNK_FLAG_MUSIC = (1 << 1), /*< This is music. */
+ PP_BNK_FLAG_MASK = (PP_BNK_FLAG_PERSIST | PP_BNK_FLAG_MUSIC)
+};
+
+static void pp_bnk_parse_header(PPBnkHeader *hdr, const uint8_t *buf)
+{
+ hdr->bank_id = AV_RL32(buf + 0);
+ hdr->sample_rate = AV_RL32(buf + 4);
+ hdr->always1 = AV_RL32(buf + 8);
+ hdr->track_count = AV_RL32(buf + 12);
+ hdr->flags = AV_RL32(buf + 16);
+}
+
+static void pp_bnk_parse_track(PPBnkTrack *trk, const uint8_t *buf)
+{
+ trk->id = AV_RL32(buf + 0);
+ trk->size = AV_RL32(buf + 4);
+ trk->sample_rate = AV_RL32(buf + 8);
+ trk->always1_1 = AV_RL32(buf + 12);
+ trk->always1_2 = AV_RL32(buf + 16);
+}
+
+static int pp_bnk_probe(const AVProbeData *p)
+{
+ uint32_t sample_rate = AV_RL32(p->buf + 4);
+ uint32_t track_count = AV_RL32(p->buf + 12);
+ uint32_t flags = AV_RL32(p->buf + 16);
+
+ if (track_count == 0 || track_count > INT_MAX)
+ return 0;
+
+ if ((sample_rate != 5512) && (sample_rate != 11025) &&
+ (sample_rate != 22050) && (sample_rate != 44100))
+ return 0;
+
+ /* Check the first track header. */
+ if (AV_RL32(p->buf + 28) != sample_rate)
+ return 0;
+
+ if ((flags & ~PP_BNK_FLAG_MASK) != 0)
+ return 0;
+
+ return AVPROBE_SCORE_MAX / 4 + 1;
+}
+
+static int pp_bnk_read_header(AVFormatContext *s)
+{
+ int64_t ret;
+ AVStream *st;
+ AVCodecParameters *par;
+ PPBnkCtx *ctx = s->priv_data;
+ uint8_t buf[FFMAX(PP_BNK_FILE_HEADER_SIZE, PP_BNK_TRACK_SIZE)];
+ PPBnkHeader hdr;
+
+ if ((ret = avio_read(s->pb, buf, PP_BNK_FILE_HEADER_SIZE)) < 0)
+ return ret;
+ else if (ret != PP_BNK_FILE_HEADER_SIZE)
+ return AVERROR(EIO);
+
+ pp_bnk_parse_header(&hdr, buf);
+
+ if (hdr.track_count == 0 || hdr.track_count > INT_MAX)
+ return AVERROR_INVALIDDATA;
+
+ if (hdr.sample_rate == 0 || hdr.sample_rate > INT_MAX)
+ return AVERROR_INVALIDDATA;
+
+ if (hdr.always1 != 1) {
+ avpriv_request_sample(s, "Non-one header value");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ ctx->track_count = hdr.track_count;
+
+ if (!(ctx->tracks = av_malloc_array(hdr.track_count, sizeof(PPBnkCtxTrack))))
+ return AVERROR(ENOMEM);
+
+ /* Parse and validate each track. */
+ for (int i = 0; i < hdr.track_count; i++) {
+ PPBnkTrack e;
+ PPBnkCtxTrack *trk = ctx->tracks + i;
+
+ ret = avio_read(s->pb, buf, PP_BNK_TRACK_SIZE);
+ if (ret < 0 && ret != AVERROR_EOF)
+ goto fail;
+
+ /* Short byte-count or EOF, we have a truncated file. */
+ if (ret != PP_BNK_TRACK_SIZE) {
+ av_log(s, AV_LOG_WARNING, "File truncated at %d/%u track(s)\n",
+ i, hdr.track_count);
+ ctx->track_count = i;
+ break;
+ }
+
+ pp_bnk_parse_track(&e, buf);
+
+ /* The individual sample rates of all tracks must match that of the file header. */
+ if (e.sample_rate != hdr.sample_rate) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if (e.always1_1 != 1 || e.always1_2 != 1) {
+ avpriv_request_sample(s, "Non-one track header values");
+ ret = AVERROR_PATCHWELCOME;
+ goto fail;
+ }
+
+ trk->data_offset = avio_tell(s->pb);
+ trk->data_size = e.size;
+ trk->bytes_read = 0;
+
+ /*
+ * Skip over the data to the next stream header.
+ * Sometimes avio_skip() doesn't detect EOF. If it doesn't, either:
+ * - the avio_read() above will, or
+ * - pp_bnk_read_packet() will read a truncated last track.
+ */
+ if ((ret = avio_skip(s->pb, e.size)) == AVERROR_EOF) {
+ ctx->track_count = i + 1;
+ av_log(s, AV_LOG_WARNING,
+ "Track %d has truncated data, assuming track count == %d\n",
+ i, ctx->track_count);
+ break;
+ } else if (ret < 0) {
+ goto fail;
+ }
+ }
+
+ /* File is only a header. */
+ if (ctx->track_count == 0) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ /* Build the streams. */
+ for (int i = 0; i < ctx->track_count; i++) {
+ if (!(st = avformat_new_stream(s, NULL))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ par = st->codecpar;
+ par->codec_type = AVMEDIA_TYPE_AUDIO;
+ par->codec_id = AV_CODEC_ID_ADPCM_IMA_CUNNING;
+ par->format = AV_SAMPLE_FMT_S16;
+ par->channel_layout = AV_CH_LAYOUT_MONO;
+ par->channels = 1;
+ par->sample_rate = hdr.sample_rate;
+ par->bits_per_coded_sample = 4;
+ par->bits_per_raw_sample = 16;
+ par->block_align = 1;
+ par->bit_rate = par->sample_rate * par->bits_per_coded_sample;
+
+ avpriv_set_pts_info(st, 64, 1, par->sample_rate);
+ st->start_time = 0;
+ st->duration = ctx->tracks[i].data_size * 2;
+ }
+
+ return 0;
+
+fail:
+ av_freep(&ctx->tracks);
+ return ret;
+}
+
+static int pp_bnk_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ PPBnkCtx *ctx = s->priv_data;
+
+ /*
+ * Read a packet from each track, round-robin style.
+ * This method is nasty, but needed to avoid "Too many packets buffered" errors.
+ */
+ for (int i = 0; i < ctx->track_count; i++, ctx->current_track++)
+ {
+ int64_t ret;
+ int size;
+ PPBnkCtxTrack *trk;
+
+ ctx->current_track %= ctx->track_count;
+
+ trk = ctx->tracks + ctx->current_track;
+
+ if (trk->bytes_read == trk->data_size)
+ continue;
+
+ if ((ret = avio_seek(s->pb, trk->data_offset + trk->bytes_read, SEEK_SET)) < 0)
+ return ret;
+ else if (ret != trk->data_offset + trk->bytes_read)
+ return AVERROR(EIO);
+
+ size = FFMIN(trk->data_size - trk->bytes_read, PP_BNK_MAX_READ_SIZE);
+
+ if ((ret = av_get_packet(s->pb, pkt, size)) == AVERROR_EOF) {
+ /* If we've hit EOF, don't attempt this track again. */
+ trk->data_size = trk->bytes_read;
+ continue;
+ } else if (ret < 0) {
+ return ret;
+ }
+
+ trk->bytes_read += ret;
+ pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
+ pkt->stream_index = ctx->current_track++;
+ pkt->duration = ret * 2;
+ return 0;
+ }
+
+ /* If we reach here, we're done. */
+ return AVERROR_EOF;
+}
+
+static int pp_bnk_read_close(AVFormatContext *s)
+{
+ PPBnkCtx *ctx = s->priv_data;
+
+ av_freep(&ctx->tracks);
+
+ return 0;
+}
+
+AVInputFormat ff_pp_bnk_demuxer = {
+ .name = "pp_bnk",
+ .long_name = NULL_IF_CONFIG_SMALL("Pro Pinball Series Soundbank"),
+ .priv_data_size = sizeof(PPBnkCtx),
+ .read_probe = pp_bnk_probe,
+ .read_header = pp_bnk_read_header,
+ .read_packet = pp_bnk_read_packet,
+ .read_close = pp_bnk_read_close
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/prompeg.c b/chromium/third_party/ffmpeg/libavformat/prompeg.c
index 9770a916a2b..59faa824bb3 100644
--- a/chromium/third_party/ffmpeg/libavformat/prompeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/prompeg.c
@@ -291,8 +291,7 @@ static int prompeg_open(URLContext *h, const char *uri, int flags) {
}
if (s->ttl > 0) {
- snprintf(buf, sizeof (buf), "%d", s->ttl);
- av_dict_set(&udp_opts, "ttl", buf, 0);
+ av_dict_set_int(&udp_opts, "ttl", s->ttl, 0);
}
ff_url_join(buf, sizeof (buf), "udp", NULL, hostname, rtp_port + 2, NULL);
@@ -388,7 +387,7 @@ static int prompeg_write(URLContext *h, const uint8_t *buf, int size) {
PrompegFec *fec_tmp;
uint8_t *bitstring = NULL;
int col_idx, col_out_idx, row_idx;
- int ret, written = 0;
+ int ret = 0;
if (s->init && ((ret = prompeg_init(h, buf, size)) < 0))
goto end;
@@ -404,7 +403,6 @@ static int prompeg_write(URLContext *h, const uint8_t *buf, int size) {
if (!s->first || s->packet_idx > 0) {
if ((ret = prompeg_write_fec(h, s->fec_row, PROMPEG_FEC_ROW)) < 0)
goto end;
- written += ret;
}
memcpy(s->fec_row->bitstring, bitstring, s->bitstring_size);
s->fec_row->sn = AV_RB16(buf + 2);
@@ -435,7 +433,6 @@ static int prompeg_write(URLContext *h, const uint8_t *buf, int size) {
col_out_idx = s->packet_idx / s->d;
if ((ret = prompeg_write_fec(h, s->fec_col[col_out_idx], PROMPEG_FEC_COL)) < 0)
goto end;
- written += ret;
}
if (++s->packet_idx >= s->packet_idx_max) {
@@ -444,7 +441,7 @@ static int prompeg_write(URLContext *h, const uint8_t *buf, int size) {
s->first = 0;
}
- ret = written;
+ ret = size;
end:
av_free(bitstring);
diff --git a/chromium/third_party/ffmpeg/libavformat/protocols.c b/chromium/third_party/ffmpeg/libavformat/protocols.c
index f1b8eab0fd6..7df18fbb3b9 100644
--- a/chromium/third_party/ffmpeg/libavformat/protocols.c
+++ b/chromium/third_party/ffmpeg/libavformat/protocols.c
@@ -73,6 +73,7 @@ extern const URLProtocol ff_libzmq_protocol;
#include "libavformat/protocol_list.c"
+#if FF_API_CHILD_CLASS_NEXT
const AVClass *ff_urlcontext_child_class_next(const AVClass *prev)
{
int i;
@@ -91,7 +92,22 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev)
return url_protocols[i]->priv_data_class;
return NULL;
}
+#endif
+const AVClass *ff_urlcontext_child_class_iterate(void **iter)
+{
+ const AVClass *ret = NULL;
+ uintptr_t i;
+
+ for (i = (uintptr_t)*iter; url_protocols[i]; i++) {
+ ret = url_protocols[i]->priv_data_class;
+ if (ret)
+ break;
+ }
+
+ *iter = (void*)(uintptr_t)(url_protocols[i] ? i + 1 : i);
+ return ret;
+}
const char *avio_enum_protocols(void **opaque, int output)
{
diff --git a/chromium/third_party/ffmpeg/libavformat/rawdec.c b/chromium/third_party/ffmpeg/libavformat/rawdec.c
index fee016cc7f0..10c37c5cb91 100644
--- a/chromium/third_party/ffmpeg/libavformat/rawdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rawdec.c
@@ -123,6 +123,8 @@ const AVOption ff_rawvideo_options[] = {
{ "raw_packet_size", "", OFFSET(raw_packet_size), AV_OPT_TYPE_INT, {.i64 = RAW_PACKET_SIZE }, 1, INT_MAX, DEC},
{ NULL },
};
+#undef OFFSET
+#define OFFSET(x) offsetof(FFRawDemuxerContext, x)
const AVOption ff_raw_options[] = {
{ "raw_packet_size", "", OFFSET(raw_packet_size), AV_OPT_TYPE_INT, {.i64 = RAW_PACKET_SIZE }, 1, INT_MAX, DEC},
{ NULL },
diff --git a/chromium/third_party/ffmpeg/libavformat/rawdec.h b/chromium/third_party/ffmpeg/libavformat/rawdec.h
index 85e0790c86e..34c8adcb199 100644
--- a/chromium/third_party/ffmpeg/libavformat/rawdec.h
+++ b/chromium/third_party/ffmpeg/libavformat/rawdec.h
@@ -95,7 +95,7 @@ static const AVClass name ## _demuxer_class = {\
};
#define FF_DEF_RAWSUB_DEMUXER(shortname, longname, probe, ext, id, flag)\
-FF_RAWVIDEO_DEMUXER_CLASS(shortname)\
+FF_RAWSUB_DEMUXER_CLASS(shortname)\
AVInputFormat ff_ ## shortname ## _demuxer = {\
.name = #shortname,\
.long_name = NULL_IF_CONFIG_SMALL(longname),\
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.c b/chromium/third_party/ffmpeg/libavformat/riff.c
index bf6a8f47f85..162e2b1bf20 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.c
+++ b/chromium/third_party/ffmpeg/libavformat/riff.c
@@ -493,6 +493,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_MVDV, MKTAG('M', 'V', 'D', 'V') },
{ AV_CODEC_ID_MVHA, MKTAG('M', 'V', 'H', 'A') },
{ AV_CODEC_ID_MV30, MKTAG('M', 'V', '3', '0') },
+ { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'l', 'c', '1') },
{ AV_CODEC_ID_NONE, 0 }
};
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.h b/chromium/third_party/ffmpeg/libavformat/riff.h
index 21078b77c8e..127138d2bca 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.h
+++ b/chromium/third_party/ffmpeg/libavformat/riff.h
@@ -46,7 +46,7 @@ void ff_end_tag(AVIOContext *pb, int64_t start);
*/
int ff_get_bmp_header(AVIOContext *pb, AVStream *st, uint32_t *size);
-void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, int for_asf, int ignore_extradata);
+void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, int for_asf, int ignore_extradata, int rgb_frame_is_flipped);
/**
* Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs.
diff --git a/chromium/third_party/ffmpeg/libavformat/riffenc.c b/chromium/third_party/ffmpeg/libavformat/riffenc.c
index c04d55c4230..04a21fcffaa 100644
--- a/chromium/third_party/ffmpeg/libavformat/riffenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/riffenc.c
@@ -207,11 +207,12 @@ int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb,
/* BITMAPINFOHEADER header */
void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
- int for_asf, int ignore_extradata)
+ int for_asf, int ignore_extradata, int rgb_frame_is_flipped)
{
- int keep_height = par->extradata_size >= 9 &&
- !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9);
- int extradata_size = par->extradata_size - 9*keep_height;
+ int flipped_extradata = (par->extradata_size >= 9 &&
+ !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9));
+ int keep_height = flipped_extradata || rgb_frame_is_flipped;
+ int extradata_size = par->extradata_size - 9*flipped_extradata;
enum AVPixelFormat pix_fmt = par->format;
int pal_avi;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmpcrypt.c b/chromium/third_party/ffmpeg/libavformat/rtmpcrypt.c
index 253b8ca2ce1..a835ab263f5 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmpcrypt.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmpcrypt.c
@@ -240,7 +240,7 @@ static int rtmpe_close(URLContext *h)
RTMPEContext *rt = h->priv_data;
ff_dh_free(rt->dh);
- ffurl_close(rt->stream);
+ ffurl_closep(&rt->stream);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmphttp.c b/chromium/third_party/ffmpeg/libavformat/rtmphttp.c
index ef6146ca864..c920c19ab5b 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmphttp.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmphttp.c
@@ -176,7 +176,7 @@ static int rtmp_http_close(URLContext *h)
}
av_freep(&rt->out_data);
- ffurl_close(rt->stream);
+ ffurl_closep(&rt->stream);
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmpproto.c b/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
index 42aacbd1b99..d9741bc622c 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
@@ -163,7 +163,7 @@ static int add_tracked_method(RTMPContext *rt, const char *name, int id)
if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
- if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
+ if ((err = av_reallocp_array(&rt->tracked_methods, rt->tracked_methods_size,
sizeof(*rt->tracked_methods))) < 0) {
rt->nb_tracked_methods = 0;
rt->tracked_methods_size = 0;
@@ -2511,7 +2511,7 @@ static int rtmp_close(URLContext *h)
free_tracked_methods(rt);
av_freep(&rt->flv_data);
- ffurl_close(rt->stream);
+ ffurl_closep(&rt->stream);
return ret;
}
@@ -2824,8 +2824,7 @@ reconnect:
if (rt->do_reconnect) {
int i;
- ffurl_close(rt->stream);
- rt->stream = NULL;
+ ffurl_closep(&rt->stream);
rt->do_reconnect = 0;
rt->nb_invokes = 0;
for (i = 0; i < 2; i++)
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpenc.c b/chromium/third_party/ffmpeg/libavformat/rtpenc.c
index 63047beccc8..9ef7e9094dd 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpenc.c
@@ -589,7 +589,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
break;
case AV_CODEC_ID_H263:
if (s->flags & FF_RTP_FLAG_RFC2190) {
- int mb_info_size = 0;
+ int mb_info_size;
const uint8_t *mb_info =
av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO,
&mb_info_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpproto.c b/chromium/third_party/ffmpeg/libavformat/rtpproto.c
index 1f0a82ac7e5..19e940d01e6 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpproto.c
@@ -301,8 +301,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
goto fail;
}
if (s->ttl > 0) {
- snprintf(buf, sizeof (buf), "%d", s->ttl);
- av_dict_set(&fec_opts, "ttl", buf, 0);
+ av_dict_set_int(&fec_opts, "ttl", s->ttl, 0);
}
}
@@ -363,10 +362,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
return 0;
fail:
- if (s->rtp_hd)
- ffurl_close(s->rtp_hd);
- if (s->rtcp_hd)
- ffurl_close(s->rtcp_hd);
+ ffurl_closep(&s->rtp_hd);
+ ffurl_closep(&s->rtcp_hd);
ffurl_closep(&s->fec_hd);
av_free(fec_protocol);
av_dict_free(&fec_opts);
@@ -506,8 +503,8 @@ static int rtp_close(URLContext *h)
ff_ip_reset_filters(&s->filters);
- ffurl_close(s->rtp_hd);
- ffurl_close(s->rtcp_hd);
+ ffurl_closep(&s->rtp_hd);
+ ffurl_closep(&s->rtcp_hd);
ffurl_closep(&s->fec_hd);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtsp.c b/chromium/third_party/ffmpeg/libavformat/rtsp.c
index b2b3f320113..5d8491b74ba 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtsp.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtsp.c
@@ -763,9 +763,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
ff_rtp_parse_close(rtsp_st->transport_priv);
}
rtsp_st->transport_priv = NULL;
- if (rtsp_st->rtp_handle)
- ffurl_close(rtsp_st->rtp_handle);
- rtsp_st->rtp_handle = NULL;
+ ffurl_closep(&rtsp_st->rtp_handle);
}
}
@@ -1666,9 +1664,10 @@ fail:
void ff_rtsp_close_connections(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
- if (rt->rtsp_hd_out != rt->rtsp_hd) ffurl_close(rt->rtsp_hd_out);
- ffurl_close(rt->rtsp_hd);
- rt->rtsp_hd = rt->rtsp_hd_out = NULL;
+ if (rt->rtsp_hd_out != rt->rtsp_hd)
+ ffurl_closep(&rt->rtsp_hd_out);
+ rt->rtsp_hd_out = NULL;
+ ffurl_closep(&rt->rtsp_hd);
}
int ff_rtsp_connect(AVFormatContext *s)
@@ -2496,8 +2495,7 @@ static int rtp_read_header(AVFormatContext *s)
break;
}
getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
- ffurl_close(in);
- in = NULL;
+ ffurl_closep(&in);
par = avcodec_parameters_alloc();
if (!par) {
@@ -2571,8 +2569,7 @@ fail_nobuf:
av_bprint_finalize(&sdp, NULL);
fail:
avcodec_parameters_free(&par);
- if (in)
- ffurl_close(in);
+ ffurl_closep(&in);
ff_network_close();
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtspdec.c b/chromium/third_party/ffmpeg/libavformat/rtspdec.c
index bd2e8f47f1a..dfa29913bff 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtspdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtspdec.c
@@ -289,9 +289,7 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
} else {
do {
AVDictionary *opts = NULL;
- char buf[256];
- snprintf(buf, sizeof(buf), "%d", rt->buffer_size);
- av_dict_set(&opts, "buffer_size", buf, 0);
+ av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0);
ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
av_log(s, AV_LOG_TRACE, "Opening: %s", url);
ret = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
diff --git a/chromium/third_party/ffmpeg/libavformat/samidec.c b/chromium/third_party/ffmpeg/libavformat/samidec.c
index fd98393086b..3070ef9bacf 100644
--- a/chromium/third_party/ffmpeg/libavformat/samidec.c
+++ b/chromium/third_party/ffmpeg/libavformat/samidec.c
@@ -108,6 +108,8 @@ static int sami_read_header(AVFormatContext *s)
ff_subtitles_queue_finalize(s, &sami->q);
end:
+ if (res < 0)
+ ff_subtitles_queue_clean(&sami->q);
av_bprint_finalize(&buf, NULL);
return res;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/sapdec.c b/chromium/third_party/ffmpeg/libavformat/sapdec.c
index b3644b436b5..eec73aa2f45 100644
--- a/chromium/third_party/ffmpeg/libavformat/sapdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/sapdec.c
@@ -54,8 +54,7 @@ static int sap_read_close(AVFormatContext *s)
struct SAPState *sap = s->priv_data;
if (sap->sdp_ctx)
avformat_close_input(&sap->sdp_ctx);
- if (sap->ann_fd)
- ffurl_close(sap->ann_fd);
+ ffurl_closep(&sap->ann_fd);
av_freep(&sap->sdp);
ff_network_close();
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/sapenc.c b/chromium/third_party/ffmpeg/libavformat/sapenc.c
index f9afab0c33e..dc1c2104082 100644
--- a/chromium/third_party/ffmpeg/libavformat/sapenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/sapenc.c
@@ -60,8 +60,7 @@ static int sap_write_close(AVFormatContext *s)
}
av_freep(&sap->ann);
- if (sap->ann_fd)
- ffurl_close(sap->ann_fd);
+ ffurl_closep(&sap->ann_fd);
ff_network_close();
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/sbgdec.c b/chromium/third_party/ffmpeg/libavformat/sbgdec.c
index de1de271bbe..c11244ef3df 100644
--- a/chromium/third_party/ffmpeg/libavformat/sbgdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/sbgdec.c
@@ -474,6 +474,8 @@ static int parse_timestamp(struct sbg_parser *p,
while (lex_char(p, '+')) {
if (!lex_time(p, &dt))
return AVERROR_INVALIDDATA;
+ if (av_sat_add64(rel, dt) - dt != rel)
+ return AVERROR_INVALIDDATA;
rel += dt;
r = 1;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/sccdec.c b/chromium/third_party/ffmpeg/libavformat/sccdec.c
index b9042b39ac9..751dee7c6c1 100644
--- a/chromium/third_party/ffmpeg/libavformat/sccdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/sccdec.c
@@ -63,10 +63,9 @@ static int scc_read_header(AVFormatContext *s)
{
SCCContext *scc = s->priv_data;
AVStream *st = avformat_new_stream(s, NULL);
- char line[4096], line2[4096];
- int64_t ts_start, ts_end;
- int count = 0, ret = 0;
- ptrdiff_t len2, len;
+ char line2[4096], line[4096];
+ int64_t pos, ts, next_ts = AV_NOPTS_VALUE;
+ ptrdiff_t len;
uint8_t out[4096];
FFTextReader tr;
@@ -78,83 +77,107 @@ static int scc_read_header(AVFormatContext *s)
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
- while (!ff_text_eof(&tr)) {
- int64_t current_pos, next_pos;
+ while (!ff_text_eof(&tr) || next_ts == AV_NOPTS_VALUE || line2[0]) {
char *saveptr = NULL, *lline;
- int hh1, mm1, ss1, fs1, i;
- int hh2, mm2, ss2, fs2;
+ int hh, mm, ss, fs, i;
AVPacket *sub;
- if (count == 0) {
- current_pos = ff_text_pos(&tr);
+ if (next_ts == AV_NOPTS_VALUE) {
while (!ff_text_eof(&tr)) {
len = ff_subtitles_read_line(&tr, line, sizeof(line));
- if (len > 13)
+ if (len <= 13)
+ continue;
+ if (!strncmp(line, "Scenarist_SCC V1.0", 18))
+ continue;
+ if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4)
break;
}
- }
- if (!strncmp(line, "Scenarist_SCC V1.0", 18))
- continue;
- if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh1, &mm1, &ss1, &fs1) != 4)
- continue;
+ ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33;
- ts_start = (hh1 * 3600LL + mm1 * 60LL + ss1) * 1000LL + fs1 * 33;
+ while (!ff_text_eof(&tr)) {
+ len = ff_subtitles_read_line(&tr, line2, sizeof(line2));
+ if (len <= 13)
+ continue;
- next_pos = ff_text_pos(&tr);
- while (!ff_text_eof(&tr)) {
- len2 = ff_subtitles_read_line(&tr, line2, sizeof(line2));
- if (len2 > 13)
- break;
+ if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4)
+ break;
+ }
+ } else {
+ memmove(line, line2, sizeof(line));
+ line2[0] = 0;
+
+ while (!ff_text_eof(&tr)) {
+ len = ff_subtitles_read_line(&tr, line2, sizeof(line2));
+ if (len <= 13)
+ continue;
+
+ if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4)
+ break;
+ }
}
- if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh2, &mm2, &ss2, &fs2) != 4)
- continue;
- ts_end = (hh2 * 3600LL + mm2 * 60LL + ss2) * 1000LL + fs2 * 33;
- count++;
+ next_ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33;
-try_again:
+ pos = ff_text_pos(&tr);
lline = (char *)&line;
lline += 12;
for (i = 0; i < 4095; i += 3) {
char *ptr = av_strtok(lline, " ", &saveptr);
char c1, c2, c3, c4;
+ uint8_t o1, o2;
if (!ptr)
break;
if (av_sscanf(ptr, "%c%c%c%c", &c1, &c2, &c3, &c4) != 4)
break;
+ o1 = convert(c2) | (convert(c1) << 4);
+ o2 = convert(c4) | (convert(c3) << 4);
lline = NULL;
+
+ if (i > 12 && o1 == 0x94 && o2 == 0x20 && saveptr &&
+ (av_strncasecmp(saveptr, "942f", 4) && !av_strncasecmp(saveptr, "942c", 4))) {
+
+ out[i] = 0;
+
+ sub = ff_subtitles_queue_insert(&scc->q, out, i, 0);
+ if (!sub)
+ goto fail;
+
+ sub->pos = pos;
+ pos += i;
+ sub->pts = ts;
+ sub->duration = i * 11;
+ ts += sub->duration;
+ i = 0;
+ }
+
out[i+0] = 0xfc;
- out[i+1] = convert(c2) | (convert(c1) << 4);
- out[i+2] = convert(c4) | (convert(c3) << 4);
+ out[i+1] = o1;
+ out[i+2] = o2;
}
+
out[i] = 0;
sub = ff_subtitles_queue_insert(&scc->q, out, i, 0);
if (!sub)
- return AVERROR(ENOMEM);
-
- sub->pos = current_pos;
- sub->pts = ts_start;
- sub->duration = ts_end - ts_start;
- memmove(line, line2, sizeof(line));
- current_pos = next_pos;
- line2[0] = 0;
- }
+ goto fail;
- if (line[0]) {
- ts_start = ts_end;
- ts_end += 1200;
- goto try_again;
+ sub->pos = pos;
+ sub->pts = ts;
+ sub->duration = next_ts - ts;
+ ts = next_ts;
}
ff_subtitles_queue_finalize(s, &scc->q);
- return ret;
+ return 0;
+fail:
+ ff_subtitles_queue_clean(&scc->q);
+ return AVERROR(ENOMEM);
}
static int scc_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/sdp.c b/chromium/third_party/ffmpeg/libavformat/sdp.c
index 34e9839b67a..2ce1a62262d 100644
--- a/chromium/third_party/ffmpeg/libavformat/sdp.c
+++ b/chromium/third_party/ffmpeg/libavformat/sdp.c
@@ -212,7 +212,7 @@ static char *extradata2psets(AVFormatContext *s, AVCodecParameters *par)
p += strlen(p);
r = r1;
}
- if (sps && sps_end - sps >= 4) {
+ if (sps && sps_end - sps >= 4 && p - psets <= MAX_PSET_SIZE - strlen(profile_string) - 7) {
memcpy(p, profile_string, strlen(profile_string));
p += strlen(p);
ff_data_to_hex(p, sps + 1, 3, 0);
diff --git a/chromium/third_party/ffmpeg/libavformat/segafilm.c b/chromium/third_party/ffmpeg/libavformat/segafilm.c
index 777606bcb64..4d14b81d163 100644
--- a/chromium/third_party/ffmpeg/libavformat/segafilm.c
+++ b/chromium/third_party/ffmpeg/libavformat/segafilm.c
@@ -40,8 +40,8 @@
typedef struct film_sample {
int stream;
- int64_t sample_offset;
unsigned int sample_size;
+ int64_t sample_offset;
int64_t pts;
int keyframe;
} film_sample;
diff --git a/chromium/third_party/ffmpeg/libavformat/segafilmenc.c b/chromium/third_party/ffmpeg/libavformat/segafilmenc.c
index 93c482ef7d8..42249d4effe 100644
--- a/chromium/third_party/ffmpeg/libavformat/segafilmenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/segafilmenc.c
@@ -29,87 +29,28 @@
* http://wiki.multimedia.cx/index.php?title=Sega_FILM
*/
+#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
+#include "libavcodec/bytestream.h"
#include "avformat.h"
#include "internal.h"
#include "avio_internal.h"
-typedef struct FILMPacket {
- int audio;
- int keyframe;
- int32_t pts;
- int32_t duration;
- int32_t size;
- int32_t index;
- struct FILMPacket *next;
-} FILMPacket;
-
typedef struct FILMOutputContext {
+ AVIOContext *header;
+ unsigned index;
int audio_index;
int video_index;
- int64_t stab_pos;
- FILMPacket *start;
- FILMPacket *last;
- int64_t packet_count;
} FILMOutputContext;
-static int film_write_packet_to_header(AVFormatContext *format_context, FILMPacket *pkt)
-{
- AVIOContext *pb = format_context->pb;
- /* The bits in these two 32-bit integers contain info about the contents of this sample */
- int32_t info1 = 0;
- int32_t info2 = 0;
-
- if (pkt->audio) {
- /* Always the same, carries no more information than "this is audio" */
- info1 = 0xFFFFFFFF;
- info2 = 1;
- } else {
- info1 = pkt->pts;
- info2 = pkt->duration;
- /* The top bit being set indicates a key frame */
- if (!pkt->keyframe)
- info1 |= 1U << 31;
- }
-
- /* Write the 16-byte sample info packet to the STAB chunk in the header */
- avio_wb32(pb, pkt->index);
- avio_wb32(pb, pkt->size);
- avio_wb32(pb, info1);
- avio_wb32(pb, info2);
-
- return 0;
-}
-
static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt)
{
- FILMPacket *metadata;
AVIOContext *pb = format_context->pb;
FILMOutputContext *film = format_context->priv_data;
- int encoded_buf_size = 0;
+ int encoded_buf_size, size = pkt->size;
+ uint32_t info1, info2;
enum AVCodecID codec_id;
- /* Track the metadata used to write the header and add it to the linked list */
- metadata = av_mallocz(sizeof(FILMPacket));
- if (!metadata)
- return AVERROR(ENOMEM);
- metadata->audio = pkt->stream_index == film->audio_index;
- metadata->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
- metadata->pts = pkt->pts;
- metadata->duration = pkt->duration;
- metadata->size = pkt->size;
- if (film->last == NULL) {
- metadata->index = 0;
- } else {
- metadata->index = film->last->index + film->last->size;
- film->last->next = metadata;
- }
- metadata->next = NULL;
- if (film->start == NULL)
- film->start = metadata;
- film->packet_count++;
- film->last = metadata;
-
codec_id = format_context->streams[pkt->stream_index]->codecpar->codec_id;
/* Sega Cinepak has an extra two-byte header; write dummy data there,
@@ -120,15 +61,14 @@ static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt)
if (encoded_buf_size != pkt->size && (pkt->size % encoded_buf_size) != 0) {
avio_write(pb, pkt->data, pkt->size);
} else {
- uint8_t padding[2] = {0, 0};
/* In Sega Cinepak, the reported size in the Cinepak header is
* 8 bytes too short. However, the size in the STAB section of the header
* is correct, taking into account the extra two bytes. */
AV_WB24(&pkt->data[1], pkt->size - 8 + 2);
- metadata->size += 2;
+ size += 2;
avio_write(pb, pkt->data, 10);
- avio_write(pb, padding, 2);
+ avio_wb16(pb, 0);
avio_write(pb, &pkt->data[10], pkt->size - 10);
}
} else {
@@ -136,7 +76,27 @@ static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt)
avio_write(pb, pkt->data, pkt->size);
}
- return 0;
+ /* Add the 16-byte sample info entry to the dynamic buffer
+ * for the STAB chunk in the header */
+ pb = film->header;
+ avio_wb32(pb, film->index);
+ film->index += size;
+ avio_wb32(pb, size);
+ if (film->audio_index == pkt->stream_index) {
+ /* Always the same, carries no more information than "this is audio" */
+ info1 = 0xFFFFFFFF;
+ info2 = 1;
+ } else {
+ info1 = pkt->pts;
+ info2 = pkt->duration;
+ /* The top bit being set indicates a key frame */
+ if (!(pkt->flags & AV_PKT_FLAG_KEY))
+ info1 |= 1U << 31;
+ }
+ avio_wb32(pb, info1);
+ avio_wb32(pb, info2);
+
+ return pb->error;
}
static int get_audio_codec_id(enum AVCodecID codec_id)
@@ -156,12 +116,10 @@ static int get_audio_codec_id(enum AVCodecID codec_id)
static int film_init(AVFormatContext *format_context)
{
FILMOutputContext *film = format_context->priv_data;
+ int ret;
+
film->audio_index = -1;
film->video_index = -1;
- film->stab_pos = 0;
- film->packet_count = 0;
- film->start = NULL;
- film->last = NULL;
for (int i = 0; i < format_context->nb_streams; i++) {
AVStream *st = format_context->streams[i];
@@ -202,11 +160,15 @@ static int film_init(AVFormatContext *format_context)
av_log(format_context, AV_LOG_ERROR, "No video stream present.\n");
return AVERROR(EINVAL);
}
+ if ((ret = avio_open_dyn_buf(&film->header)) < 0)
+ return ret;
+ ffio_fill(film->header, 0, 16 + 32 + 16);
return 0;
}
-static int shift_data(AVFormatContext *format_context, int64_t shift_size)
+static int write_header(AVFormatContext *format_context, uint8_t *header,
+ unsigned header_size)
{
int ret = 0;
int64_t pos, pos_end;
@@ -215,11 +177,12 @@ static int shift_data(AVFormatContext *format_context, int64_t shift_size)
int read_size[2];
AVIOContext *read_pb;
- buf = av_malloc(shift_size * 2);
+ buf = av_malloc(header_size);
if (!buf)
return AVERROR(ENOMEM);
read_buf[0] = buf;
- read_buf[1] = buf + shift_size;
+ read_buf[1] = header;
+ read_size[1] = header_size;
/* Write the header at the beginning of the file, shifting all content as necessary;
* based on the approach used by MOV faststart. */
@@ -232,25 +195,20 @@ static int shift_data(AVFormatContext *format_context, int64_t shift_size)
return ret;
}
- /* mark the end of the shift to up to the last data we wrote, and get ready
- * for writing */
- pos_end = avio_tell(format_context->pb);
- avio_seek(format_context->pb, shift_size, SEEK_SET);
+ /* Mark the end of the shift to up to the last data we are going to write,
+ * and get ready for writing */
+ pos_end = avio_tell(format_context->pb) + header_size;
+ pos = avio_seek(format_context->pb, 0, SEEK_SET);
/* start reading at where the new header will be placed */
avio_seek(read_pb, 0, SEEK_SET);
- pos = avio_tell(read_pb);
-#define READ_BLOCK do { \
- read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
- read_buf_id ^= 1; \
-} while (0)
-
- /* shift data by chunk of at most shift_size */
- READ_BLOCK;
+ /* shift data by chunk of at most header_size */
do {
int n;
- READ_BLOCK;
+ read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id],
+ header_size);
+ read_buf_id ^= 1;
n = read_size[read_buf_id];
if (n <= 0)
break;
@@ -266,79 +224,75 @@ static int shift_data(AVFormatContext *format_context, int64_t shift_size)
static int film_write_header(AVFormatContext *format_context)
{
int ret = 0;
- int64_t sample_table_size, stabsize, headersize;
- AVIOContext *pb = format_context->pb;
+ unsigned stabsize, headersize, packet_count;
FILMOutputContext *film = format_context->priv_data;
- FILMPacket *prev, *packet;
AVStream *video = NULL;
+ uint8_t *header, *ptr;
/* Calculate how much we need to reserve for the header;
* this is the amount the rest of the data will be shifted up by. */
- sample_table_size = film->packet_count * 16;
- stabsize = 16 + sample_table_size;
+ headersize = avio_get_dyn_buf(film->header, &header);
+ if (headersize < 64) {
+ av_assert1(film->header->error < 0);
+ return film->header->error;
+ }
+ packet_count = (headersize - 64) / 16;
+ stabsize = 16 + 16 * packet_count;
headersize = 16 + /* FILM header base */
32 + /* FDSC chunk */
stabsize;
- ret = shift_data(format_context, headersize);
- if (ret < 0)
- return ret;
- /* Seek back to the beginning to start writing the header now */
- avio_seek(pb, 0, SEEK_SET);
-
- /* First, write the FILM header; this is very simple */
-
- ffio_wfourcc(pb, "FILM");
- avio_wb32(pb, 48 + stabsize);
+ /* Write the header at the position in the buffer reserved for it.
+ * First, write the FILM header; this is very simple */
+ ptr = header;
+ bytestream_put_be32(&ptr, MKBETAG('F', 'I', 'L', 'M'));
+ bytestream_put_be32(&ptr, headersize);
/* This seems to be okay to hardcode, since this muxer targets 1.09 features;
* videos produced by this muxer are readable by 1.08 and lower players. */
- ffio_wfourcc(pb, "1.09");
- /* I have no idea what this field does, might be reserved */
- avio_wb32(pb, 0);
+ bytestream_put_be32(&ptr, MKBETAG('1', '.', '0', '9'));
+ /* I have no idea what the next four bytes do, might be reserved */
+ ptr += 4;
/* Next write the FDSC (file description) chunk */
- ffio_wfourcc(pb, "FDSC");
- avio_wb32(pb, 0x20); /* Size of FDSC chunk */
+ bytestream_put_be32(&ptr, MKBETAG('F', 'D', 'S', 'C'));
+ bytestream_put_be32(&ptr, 0x20); /* Size of FDSC chunk */
video = format_context->streams[film->video_index];
/* The only two supported codecs; raw video is rare */
switch (video->codecpar->codec_id) {
case AV_CODEC_ID_CINEPAK:
- ffio_wfourcc(pb, "cvid");
+ bytestream_put_be32(&ptr, MKBETAG('c', 'v', 'i', 'd'));
break;
case AV_CODEC_ID_RAWVIDEO:
- ffio_wfourcc(pb, "raw ");
+ bytestream_put_be32(&ptr, MKBETAG('r', 'a', 'w', ' '));
break;
}
- avio_wb32(pb, video->codecpar->height);
- avio_wb32(pb, video->codecpar->width);
- avio_w8(pb, 24); /* Bits per pixel - observed to always be 24 */
+ bytestream_put_be32(&ptr, video->codecpar->height);
+ bytestream_put_be32(&ptr, video->codecpar->width);
+ bytestream_put_byte(&ptr, 24); /* Bits per pixel - observed to always be 24 */
if (film->audio_index > -1) {
AVStream *audio = format_context->streams[film->audio_index];
int audio_codec = get_audio_codec_id(audio->codecpar->codec_id);
- avio_w8(pb, audio->codecpar->channels); /* Audio channels */
- avio_w8(pb, audio->codecpar->bits_per_coded_sample); /* Audio bit depth */
- avio_w8(pb, audio_codec); /* Compression - 0 is PCM, 2 is ADX */
- avio_wb16(pb, audio->codecpar->sample_rate); /* Audio sampling rate */
+ bytestream_put_byte(&ptr, audio->codecpar->channels); /* Audio channels */
+ bytestream_put_byte(&ptr, audio->codecpar->bits_per_coded_sample); /* Audio bit depth */
+ bytestream_put_byte(&ptr, audio_codec); /* Compression - 0 is PCM, 2 is ADX */
+ bytestream_put_be16(&ptr, audio->codecpar->sample_rate); /* Audio sampling rate */
} else {
- /* Set all these fields to 0 if there's no audio */
- avio_w8(pb, 0);
- avio_w8(pb, 0);
- avio_w8(pb, 0);
- avio_wb16(pb, 0);
+ /* If there is no audio, all the audio fields should be set to zero.
+ * ffio_fill() already did this for us. */
+ ptr += 1 + 1 + 1 + 2;
}
/* I have no idea what this pair of fields does either, might be reserved */
- avio_wb32(pb, 0);
- avio_wb16(pb, 0);
+ ptr += 4 + 2;
/* Finally, write the STAB (sample table) chunk */
- ffio_wfourcc(pb, "STAB");
- avio_wb32(pb, 16 + (film->packet_count * 16));
+ bytestream_put_be32(&ptr, MKBETAG('S', 'T', 'A', 'B'));
+ bytestream_put_be32(&ptr, stabsize);
/* Framerate base frequency. Here we're assuming that the frame rate is even.
* In real world Sega FILM files, there are usually a couple of approaches:
* a) framerate base frequency is the same as the framerate, and ticks
@@ -348,19 +302,14 @@ static int film_write_header(AVFormatContext *format_context)
* The latter occurs even in cases where the frame rate is even; for example, in
* Lunar: Silver Star Story, the base frequency is 600 and each frame, the ticks
* are incremented by 25 for an evenly spaced framerate of 24fps. */
- avio_wb32(pb, av_q2d(av_inv_q(video->time_base)));
+ bytestream_put_be32(&ptr, av_q2d(av_inv_q(video->time_base)));
- avio_wb32(pb, film->packet_count);
+ bytestream_put_be32(&ptr, packet_count);
- /* Finally, write out each packet's data to the header */
- packet = film->start;
- while (packet != NULL) {
- film_write_packet_to_header(format_context, packet);
- prev = packet;
- packet = packet->next;
- av_freep(&prev);
- }
- film->start = film->last = NULL;
+ /* Finally, shift the data and write out the header. */
+ ret = write_header(format_context, header, headersize);
+ if (ret < 0)
+ return ret;
return 0;
}
@@ -368,13 +317,8 @@ static int film_write_header(AVFormatContext *format_context)
static void film_deinit(AVFormatContext *format_context)
{
FILMOutputContext *film = format_context->priv_data;
- FILMPacket *packet = film->start;
- while (packet != NULL) {
- FILMPacket *next = packet->next;
- av_free(packet);
- packet = next;
- }
- film->start = film->last = NULL;
+
+ ffio_free_dyn_buf(&film->header);
}
AVOutputFormat ff_segafilm_muxer = {
diff --git a/chromium/third_party/ffmpeg/libavformat/segment.c b/chromium/third_party/ffmpeg/libavformat/segment.c
index 32c09827eb6..f67456fa571 100644
--- a/chromium/third_party/ffmpeg/libavformat/segment.c
+++ b/chromium/third_party/ffmpeg/libavformat/segment.c
@@ -162,12 +162,11 @@ static int segment_mux_init(AVFormatContext *s)
oc->flags = s->flags;
for (i = 0; i < s->nb_streams; i++) {
- AVStream *st;
- AVCodecParameters *ipar, *opar;
+ AVStream *st, *ist = s->streams[i];
+ AVCodecParameters *ipar = ist->codecpar, *opar;
if (!(st = avformat_new_stream(oc, NULL)))
return AVERROR(ENOMEM);
- ipar = s->streams[i]->codecpar;
opar = st->codecpar;
avcodec_parameters_copy(opar, ipar);
if (!oc->oformat->codec_tag ||
@@ -177,16 +176,17 @@ static int segment_mux_init(AVFormatContext *s)
} else {
opar->codec_tag = 0;
}
- st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
- st->time_base = s->streams[i]->time_base;
- st->avg_frame_rate = s->streams[i]->avg_frame_rate;
+ st->sample_aspect_ratio = ist->sample_aspect_ratio;
+ st->time_base = ist->time_base;
+ st->avg_frame_rate = ist->avg_frame_rate;
+ st->disposition = ist->disposition;
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
- if (s->streams[i]->codecpar->codec_tag == MKTAG('t','m','c','d'))
- st->codec->time_base = s->streams[i]->codec->time_base;
+ if (ipar->codec_tag == MKTAG('t','m','c','d'))
+ st->codec->time_base = ist->codec->time_base;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- av_dict_copy(&st->metadata, s->streams[i]->metadata, 0);
+ av_dict_copy(&st->metadata, ist->metadata, 0);
}
return 0;
@@ -873,7 +873,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EINVAL);
if (!st->codecpar->extradata_size) {
- int pkt_extradata_size = 0;
+ int pkt_extradata_size;
uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size);
if (pkt_extradata && pkt_extradata_size > 0) {
ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/sierravmd.c b/chromium/third_party/ffmpeg/libavformat/sierravmd.c
index 531fc415316..40bcb779861 100644
--- a/chromium/third_party/ffmpeg/libavformat/sierravmd.c
+++ b/chromium/third_party/ffmpeg/libavformat/sierravmd.c
@@ -174,6 +174,8 @@ static int vmd_read_header(AVFormatContext *s)
avpriv_set_pts_info(vst, 33, num, den);
avpriv_set_pts_info(st, 33, num, den);
}
+ if (!s->nb_streams)
+ return AVERROR_INVALIDDATA;
toc_offset = AV_RL32(&vmd->vmd_header[812]);
vmd->frame_count = AV_RL16(&vmd->vmd_header[6]);
@@ -241,6 +243,8 @@ static int vmd_read_header(AVFormatContext *s)
current_audio_pts++;
break;
case 2: /* Video Chunk */
+ if (!vst)
+ break;
vmd->frame_table[total_frames].frame_offset = current_offset;
vmd->frame_table[total_frames].stream_index = vmd->video_stream_index;
vmd->frame_table[total_frames].frame_size = size;
diff --git a/chromium/third_party/ffmpeg/libavformat/smacker.c b/chromium/third_party/ffmpeg/libavformat/smacker.c
index 8b1e185817e..9966a670553 100644
--- a/chromium/third_party/ffmpeg/libavformat/smacker.c
+++ b/chromium/third_party/ffmpeg/libavformat/smacker.c
@@ -48,16 +48,17 @@ typedef struct SmackerContext {
uint32_t *frm_size;
uint8_t *frm_flags;
/* internal variables */
+ int64_t next_frame_pos;
int cur_frame;
+ int videoindex;
+ int indexes[7];
+ int duration_size[7];
/* current frame for demuxing */
+ uint32_t frame_size;
+ int flags;
+ int next_audio_index;
+ int new_palette;
uint8_t pal[768];
- int indexes[7];
- int videoindex;
- uint8_t *bufs[7];
- int buf_sizes[7];
- int stream_id[7];
- int curstream;
- int64_t nextpos;
int64_t aud_pts[7];
} SmackerContext;
@@ -197,6 +198,8 @@ static int smacker_read_header(AVFormatContext *s)
if (par->bits_per_coded_sample == 16 &&
par->codec_id == AV_CODEC_ID_PCM_U8)
par->codec_id = AV_CODEC_ID_PCM_S16LE;
+ else
+ smk->duration_size[i] = 4;
avpriv_set_pts_info(ast, 64, 1, par->sample_rate * par->channels
* par->bits_per_coded_sample / 8);
}
@@ -205,85 +208,75 @@ static int smacker_read_header(AVFormatContext *s)
avio_rl32(pb); /* padding */
/* setup data */
- smk->frm_size = av_malloc_array(smk->frames, sizeof(*smk->frm_size));
- smk->frm_flags = av_malloc(smk->frames);
- if (!smk->frm_size || !smk->frm_flags) {
- av_freep(&smk->frm_size);
- av_freep(&smk->frm_flags);
+ st->priv_data = av_malloc_array(smk->frames, sizeof(*smk->frm_size) +
+ sizeof(*smk->frm_flags));
+ if (!st->priv_data)
return AVERROR(ENOMEM);
- }
+ smk->frm_size = st->priv_data;
+ smk->frm_flags = (void*)(smk->frm_size + smk->frames);
/* read frame info */
for (i = 0; i < smk->frames; i++) {
smk->frm_size[i] = avio_rl32(pb);
}
- for (i = 0; i < smk->frames; i++) {
- smk->frm_flags[i] = avio_r8(pb);
- }
-
- /* load trees to extradata, they will be unpacked by decoder */
- ret = avio_read(pb, par->extradata + 16, par->extradata_size - 16);
- if (ret != par->extradata_size - 16) {
- av_freep(&smk->frm_size);
- av_freep(&smk->frm_flags);
- return AVERROR(EIO);
+ if ((ret = ffio_read_size(pb, smk->frm_flags, smk->frames)) < 0 ||
+ /* load trees to extradata, they will be unpacked by decoder */
+ (ret = ffio_read_size(pb, par->extradata + 16,
+ par->extradata_size - 16)) < 0) {
+ return ret;
}
- smk->curstream = -1;
- smk->nextpos = avio_tell(pb);
-
return 0;
}
-
static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
{
SmackerContext *smk = s->priv_data;
int flags;
int ret;
- int i;
- int frame_size = 0;
- int palchange = 0;
if (avio_feof(s->pb) || smk->cur_frame >= smk->frames)
return AVERROR_EOF;
/* if we demuxed all streams, pass another frame */
- if(smk->curstream < 0) {
- avio_seek(s->pb, smk->nextpos, 0);
- frame_size = smk->frm_size[smk->cur_frame] & (~3);
+ if (!smk->next_audio_index) {
+ smk->frame_size = smk->frm_size[smk->cur_frame] & (~3);
+ smk->next_frame_pos = avio_tell(s->pb) + smk->frame_size;
flags = smk->frm_flags[smk->cur_frame];
+ smk->flags = flags >> 1;
/* handle palette change event */
- if(flags & SMACKER_PAL){
+ if (flags & SMACKER_PAL) {
int size, sz, t, off, j, pos;
uint8_t *pal = smk->pal;
uint8_t oldpal[768];
memcpy(oldpal, pal, 768);
size = avio_r8(s->pb);
- size = size * 4 - 1;
- if(size + 1 > frame_size)
- return AVERROR_INVALIDDATA;
- frame_size -= size;
- frame_size--;
+ size = size * 4;
+ if (size > smk->frame_size) {
+ ret = AVERROR_INVALIDDATA;
+ goto next_frame;
+ }
+ smk->frame_size -= size--;
sz = 0;
pos = avio_tell(s->pb) + size;
- while(sz < 256){
+ while (sz < 256) {
t = avio_r8(s->pb);
- if(t & 0x80){ /* skip palette entries */
- sz += (t & 0x7F) + 1;
+ if (t & 0x80) { /* skip palette entries */
+ sz += (t & 0x7F) + 1;
pal += ((t & 0x7F) + 1) * 3;
- } else if(t & 0x40){ /* copy with offset */
+ } else if (t & 0x40) { /* copy with offset */
off = avio_r8(s->pb);
j = (t & 0x3F) + 1;
if (off + j > 0x100) {
av_log(s, AV_LOG_ERROR,
"Invalid palette update, offset=%d length=%d extends beyond palette size\n",
off, j);
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto next_frame;
}
off *= 3;
- while(j-- && sz < 256) {
+ while (j-- && sz < 256) {
*pal++ = oldpal[off + 0];
*pal++ = oldpal[off + 1];
*pal++ = oldpal[off + 2];
@@ -298,77 +291,97 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
}
}
avio_seek(s->pb, pos, 0);
- palchange |= 1;
+ smk->new_palette = 1;
}
- flags >>= 1;
- smk->curstream = -1;
- /* if audio chunks are present, put them to stack and retrieve later */
- for(i = 0; i < 7; i++) {
- if(flags & 1) {
- uint32_t size;
- int err;
-
- size = avio_rl32(s->pb) - 4;
- if (!size || size + 4LL > frame_size) {
- av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
- return AVERROR_INVALIDDATA;
- }
- frame_size -= size;
- frame_size -= 4;
- smk->curstream++;
- if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
- smk->buf_sizes[smk->curstream] = 0;
- return err;
- }
- smk->buf_sizes[smk->curstream] = size;
- ret = avio_read(s->pb, smk->bufs[smk->curstream], size);
- if(ret != size)
- return AVERROR(EIO);
- smk->stream_id[smk->curstream] = smk->indexes[i];
+ }
+
+ for (int i = smk->next_audio_index; i < 7; i++) {
+ if (smk->flags & (1 << i)) {
+ uint32_t size;
+
+ size = avio_rl32(s->pb);
+ if ((int)size < 4 + smk->duration_size[i] || size > smk->frame_size) {
+ av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
+ ret = AVERROR_INVALIDDATA;
+ goto next_frame;
}
- flags >>= 1;
+ smk->frame_size -= size;
+ size -= 4;
+
+ if (smk->indexes[i] < 0 ||
+ s->streams[smk->indexes[i]]->discard >= AVDISCARD_ALL) {
+ smk->aud_pts[i] += smk->duration_size[i] ? avio_rl32(s->pb)
+ : size;
+ avio_skip(s->pb, size - smk->duration_size[i]);
+ continue;
+ }
+ if ((ret = av_get_packet(s->pb, pkt, size)) != size) {
+ ret = ret < 0 ? ret : AVERROR_INVALIDDATA;
+ goto next_frame;
+ }
+ pkt->stream_index = smk->indexes[i];
+ pkt->pts = smk->aud_pts[i];
+ pkt->duration = smk->duration_size[i] ? AV_RL32(pkt->data)
+ : size;
+ smk->aud_pts[i] += pkt->duration;
+ smk->next_audio_index = i + 1;
+ return 0;
}
- if (frame_size < 0 || frame_size >= INT_MAX/2)
- return AVERROR_INVALIDDATA;
- if ((ret = av_new_packet(pkt, frame_size + 769)) < 0)
- return ret;
- if(smk->frm_size[smk->cur_frame] & 1)
- palchange |= 2;
- pkt->data[0] = palchange;
- memcpy(pkt->data + 1, smk->pal, 768);
- ret = avio_read(s->pb, pkt->data + 769, frame_size);
- if(ret != frame_size)
- return AVERROR(EIO);
- pkt->stream_index = smk->videoindex;
- pkt->pts = smk->cur_frame;
- pkt->size = ret + 769;
- smk->cur_frame++;
- smk->nextpos = avio_tell(s->pb);
- } else {
- if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream])
- return AVERROR_INVALIDDATA;
- if ((ret = av_new_packet(pkt, smk->buf_sizes[smk->curstream])) < 0)
- return ret;
- memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);
- pkt->size = smk->buf_sizes[smk->curstream];
- pkt->stream_index = smk->stream_id[smk->curstream];
- pkt->pts = smk->aud_pts[smk->curstream];
- smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);
- smk->curstream--;
}
+ if (s->streams[smk->videoindex]->discard >= AVDISCARD_ALL) {
+ ret = FFERROR_REDO;
+ goto next_frame;
+ }
+ if (smk->frame_size >= INT_MAX/2) {
+ ret = AVERROR_INVALIDDATA;
+ goto next_frame;
+ }
+ if ((ret = av_new_packet(pkt, smk->frame_size + 769)) < 0)
+ goto next_frame;
+ flags = smk->new_palette;
+ if (smk->frm_size[smk->cur_frame] & 1)
+ flags |= 2;
+ pkt->data[0] = flags;
+ memcpy(pkt->data + 1, smk->pal, 768);
+ ret = ffio_read_size(s->pb, pkt->data + 769, smk->frame_size);
+ if (ret < 0)
+ goto next_frame;
+ pkt->stream_index = smk->videoindex;
+ pkt->pts = smk->cur_frame;
+ smk->next_audio_index = 0;
+ smk->new_palette = 0;
+ smk->cur_frame++;
+
return 0;
+next_frame:
+ avio_seek(s->pb, smk->next_frame_pos, SEEK_SET);
+ smk->next_audio_index = 0;
+ smk->cur_frame++;
+ return ret;
}
-static int smacker_read_close(AVFormatContext *s)
+static int smacker_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
{
SmackerContext *smk = s->priv_data;
- int i;
+ int64_t ret;
+
+ /* only rewinding to start is supported */
+ if (timestamp != 0) {
+ av_log(s, AV_LOG_ERROR,
+ "Random seeks are not supported (can only seek to start).\n");
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
+ return ret;
- for(i = 0; i < 7; i++)
- av_freep(&smk->bufs[i]);
- av_freep(&smk->frm_size);
- av_freep(&smk->frm_flags);
+ smk->cur_frame = 0;
+ smk->next_audio_index = 0;
+ smk->new_palette = 0;
+ memset(smk->pal, 0, sizeof(smk->pal));
+ memset(smk->aud_pts, 0, sizeof(smk->aud_pts));
return 0;
}
@@ -380,5 +393,5 @@ AVInputFormat ff_smacker_demuxer = {
.read_probe = smacker_probe,
.read_header = smacker_read_header,
.read_packet = smacker_read_packet,
- .read_close = smacker_read_close,
+ .read_seek = smacker_read_seek,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/smjpegdec.c b/chromium/third_party/ffmpeg/libavformat/smjpegdec.c
index 5bc04921fe0..a4e1f957ed8 100644
--- a/chromium/third_party/ffmpeg/libavformat/smjpegdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/smjpegdec.c
@@ -51,6 +51,9 @@ static int smjpeg_read_header(AVFormatContext *s)
uint32_t version, htype, hlength, duration;
char *comment;
+ sc->audio_stream_index =
+ sc->video_stream_index = -1;
+
avio_skip(pb, 8); // magic
version = avio_rb32(pb);
if (version)
@@ -147,6 +150,8 @@ static int smjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
dtype = avio_rl32(s->pb);
switch (dtype) {
case SMJPEG_SNDD:
+ if (sc->audio_stream_index < 0)
+ return AVERROR_INVALIDDATA;
timestamp = avio_rb32(s->pb);
size = avio_rb32(s->pb);
ret = av_get_packet(s->pb, pkt, size);
@@ -155,6 +160,8 @@ static int smjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pos = pos;
break;
case SMJPEG_VIDD:
+ if (sc->video_stream_index < 0)
+ return AVERROR_INVALIDDATA;
timestamp = avio_rb32(s->pb);
size = avio_rb32(s->pb);
ret = av_get_packet(s->pb, pkt, size);
diff --git a/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c b/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c
index 0e4f531f90d..ba5cc27ca01 100644
--- a/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c
@@ -49,7 +49,6 @@ typedef struct Fragment {
typedef struct OutputStream {
AVFormatContext *ctx;
- int ctx_inited;
char dirname[1024];
uint8_t iobuf[32768];
URLContext *out; // Current output stream where all output is written
@@ -99,14 +98,9 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence)
if (whence != SEEK_SET)
return AVERROR(ENOSYS);
if (os->tail_out) {
- if (os->out) {
- ffurl_close(os->out);
- }
- if (os->out2) {
- ffurl_close(os->out2);
- }
+ ffurl_closep(&os->out);
+ ffurl_closep(&os->out2);
os->out = os->tail_out;
- os->out2 = NULL;
os->tail_out = NULL;
}
if (offset >= os->cur_start_pos) {
@@ -175,12 +169,9 @@ static void ism_free(AVFormatContext *s)
return;
for (i = 0; i < s->nb_streams; i++) {
OutputStream *os = &c->streams[i];
- ffurl_close(os->out);
- ffurl_close(os->out2);
- ffurl_close(os->tail_out);
- os->out = os->out2 = os->tail_out = NULL;
- if (os->ctx && os->ctx_inited)
- av_write_trailer(os->ctx);
+ ffurl_closep(&os->out);
+ ffurl_closep(&os->out2);
+ ffurl_closep(&os->tail_out);
if (os->ctx && os->ctx->pb)
avio_context_free(&os->ctx->pb);
avformat_free_context(os->ctx);
@@ -295,21 +286,18 @@ static int ism_write_header(AVFormatContext *s)
ff_const59 AVOutputFormat *oformat;
if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
- ret = AVERROR(errno);
av_log(s, AV_LOG_ERROR, "mkdir failed\n");
- goto fail;
+ return AVERROR(errno);
}
oformat = av_guess_format("ismv", NULL, NULL);
if (!oformat) {
- ret = AVERROR_MUXER_NOT_FOUND;
- goto fail;
+ return AVERROR_MUXER_NOT_FOUND;
}
c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
if (!c->streams) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
for (i = 0; i < s->nb_streams; i++) {
@@ -327,22 +315,21 @@ static int ism_write_header(AVFormatContext *s)
}
if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) {
- ret = AVERROR(errno);
av_log(s, AV_LOG_ERROR, "mkdir failed\n");
- goto fail;
+ return AVERROR(errno);
}
os->ctx = ctx = avformat_alloc_context();
- if (!ctx || ff_copy_whiteblacklists(ctx, s) < 0) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ if (!ctx) {
+ return AVERROR(ENOMEM);
}
+ if ((ret = ff_copy_whiteblacklists(ctx, s)) < 0)
+ return ret;
ctx->oformat = oformat;
ctx->interrupt_callback = s->interrupt_callback;
if (!(st = avformat_new_stream(ctx, NULL))) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
@@ -350,8 +337,7 @@ static int ism_write_header(AVFormatContext *s)
ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek);
if (!ctx->pb) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ return AVERROR(ENOMEM);
}
av_dict_set_int(&opts, "ism_lookahead", c->lookahead_count, 0);
@@ -359,9 +345,8 @@ static int ism_write_header(AVFormatContext *s)
ret = avformat_write_header(ctx, &opts);
av_dict_free(&opts);
if (ret < 0) {
- goto fail;
+ return ret;
}
- os->ctx_inited = 1;
avio_flush(ctx->pb);
s->streams[i]->time_base = st->time_base;
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -373,8 +358,7 @@ static int ism_write_header(AVFormatContext *s)
os->fourcc = "WVC1";
} else {
av_log(s, AV_LOG_ERROR, "Unsupported video codec\n");
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
} else {
c->has_audio = 1;
@@ -387,8 +371,7 @@ static int ism_write_header(AVFormatContext *s)
os->audio_tag = 0x0162;
} else {
av_log(s, AV_LOG_ERROR, "Unsupported audio codec\n");
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
os->packet_size = st->codecpar->block_align ? st->codecpar->block_align : 4;
}
@@ -397,15 +380,13 @@ static int ism_write_header(AVFormatContext *s)
if (!c->has_video && c->min_frag_duration <= 0) {
av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n");
- ret = AVERROR(EINVAL);
- goto fail;
+ return AVERROR(EINVAL);
}
ret = write_manifest(s, 0);
+ if (ret < 0)
+ return ret;
-fail:
- if (ret)
- ism_free(s);
- return ret;
+ return 0;
}
static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *start_ts, int64_t *duration, int64_t *moof_size, int64_t size)
@@ -464,7 +445,7 @@ static int add_fragment(OutputStream *os, const char *file, const char *infofile
Fragment *frag;
if (os->nb_fragments >= os->fragments_size) {
os->fragments_size = (os->fragments_size + 1) * 2;
- if ((err = av_reallocp(&os->fragments, sizeof(*os->fragments) *
+ if ((err = av_reallocp_array(&os->fragments, sizeof(*os->fragments),
os->fragments_size)) < 0) {
os->fragments_size = 0;
os->nb_fragments = 0;
@@ -537,8 +518,7 @@ static int ism_flush(AVFormatContext *s, int final)
if (!os->out || os->tail_out)
return AVERROR(EIO);
- ffurl_close(os->out);
- os->out = NULL;
+ ffurl_closep(&os->out);
size = os->tail_pos - os->cur_start_pos;
if ((ret = parse_fragment(s, filename, &start_ts, &duration, &moof_size, size)) < 0)
break;
@@ -635,7 +615,6 @@ static int ism_write_trailer(AVFormatContext *s)
rmdir(s->url);
}
- ism_free(s);
return 0;
}
@@ -668,5 +647,6 @@ AVOutputFormat ff_smoothstreaming_muxer = {
.write_header = ism_write_header,
.write_packet = ism_write_packet,
.write_trailer = ism_write_trailer,
+ .deinit = ism_free,
.priv_class = &ism_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/srtdec.c b/chromium/third_party/ffmpeg/libavformat/srtdec.c
index 40d324b44d1..d6ff00ba6d3 100644
--- a/chromium/third_party/ffmpeg/libavformat/srtdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/srtdec.c
@@ -207,6 +207,8 @@ static int srt_read_header(AVFormatContext *s)
ff_subtitles_queue_finalize(s, &srt->q);
end:
+ if (res < 0)
+ ff_subtitles_queue_clean(&srt->q);
av_bprint_finalize(&buf, NULL);
return res;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/srtpproto.c b/chromium/third_party/ffmpeg/libavformat/srtpproto.c
index 5e6e5164d75..13e2245015f 100644
--- a/chromium/third_party/ffmpeg/libavformat/srtpproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/srtpproto.c
@@ -59,8 +59,7 @@ static int srtp_close(URLContext *h)
SRTPProtoContext *s = h->priv_data;
ff_srtp_free(&s->srtp_out);
ff_srtp_free(&s->srtp_in);
- ffurl_close(s->rtp_hd);
- s->rtp_hd = NULL;
+ ffurl_closep(&s->rtp_hd);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/stldec.c b/chromium/third_party/ffmpeg/libavformat/stldec.c
index d6e0713f8c1..fb67407ac56 100644
--- a/chromium/third_party/ffmpeg/libavformat/stldec.c
+++ b/chromium/third_party/ffmpeg/libavformat/stldec.c
@@ -97,8 +97,10 @@ static int stl_read_header(AVFormatContext *s)
if (pts_start != AV_NOPTS_VALUE) {
AVPacket *sub;
sub = ff_subtitles_queue_insert(&stl->q, p, strlen(p), 0);
- if (!sub)
+ if (!sub) {
+ ff_subtitles_queue_clean(&stl->q);
return AVERROR(ENOMEM);
+ }
sub->pos = pos;
sub->pts = pts_start;
sub->duration = duration;
diff --git a/chromium/third_party/ffmpeg/libavformat/subfile.c b/chromium/third_party/ffmpeg/libavformat/subfile.c
index 5d8659c8c42..300672e657d 100644
--- a/chromium/third_party/ffmpeg/libavformat/subfile.c
+++ b/chromium/third_party/ffmpeg/libavformat/subfile.c
@@ -86,7 +86,7 @@ static int subfile_open(URLContext *h, const char *filename, int flags,
return ret;
c->pos = c->start;
if ((ret = slave_seek(h)) < 0) {
- ffurl_close(c->h);
+ ffurl_closep(&c->h);
return ret;
}
return 0;
@@ -95,7 +95,7 @@ static int subfile_open(URLContext *h, const char *filename, int flags,
static int subfile_close(URLContext *h)
{
SubfileContext *c = h->priv_data;
- return ffurl_close(c->h);
+ return ffurl_closep(&c->h);
}
static int subfile_read(URLContext *h, unsigned char *buf, int size)
diff --git a/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c b/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
index 1360d9b7d9e..f2eee294a1c 100644
--- a/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
@@ -77,8 +77,10 @@ static int subviewer1_read_header(AVFormatContext *s)
sub->duration = pts_start - sub->pts;
} else {
sub = ff_subtitles_queue_insert(&subviewer1->q, line, len, 0);
- if (!sub)
+ if (!sub) {
+ ff_subtitles_queue_clean(&subviewer1->q);
return AVERROR(ENOMEM);
+ }
sub->pos = pos;
sub->pts = pts_start;
sub->duration = -1;
diff --git a/chromium/third_party/ffmpeg/libavformat/subviewerdec.c b/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
index 83378eab5f9..fdca3a48205 100644
--- a/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
@@ -172,6 +172,8 @@ static int subviewer_read_header(AVFormatContext *s)
ff_subtitles_queue_finalize(s, &subviewer->q);
end:
+ if (res < 0)
+ ff_subtitles_queue_clean(&subviewer->q);
av_bprint_finalize(&header, NULL);
return res;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/swfenc.c b/chromium/third_party/ffmpeg/libavformat/swfenc.c
index 84f924eda52..9da4aad9597 100644
--- a/chromium/third_party/ffmpeg/libavformat/swfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/swfenc.c
@@ -256,7 +256,7 @@ static int swf_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "Invalid (too large) frame rate %d/%d\n", rate, rate_base);
return AVERROR(EINVAL);
}
- avio_wl16(pb, (rate * 256) / rate_base); /* frame rate */
+ avio_wl16(pb, (rate * 256LL) / rate_base); /* frame rate */
swf->duration_pos = avio_tell(pb);
avio_wl16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
diff --git a/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c b/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
index 5572bfd9316..3255819e77c 100644
--- a/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
@@ -275,10 +275,13 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs)
static av_cold int tedcaptions_read_header(AVFormatContext *avf)
{
TEDCaptionsDemuxer *tc = avf->priv_data;
- AVStream *st;
+ AVStream *st = avformat_new_stream(avf, NULL);
int ret, i;
AVPacket *last;
+ if (!st)
+ return AVERROR(ENOMEM);
+
ret = parse_file(avf->pb, &tc->subs);
if (ret < 0) {
if (ret == AVERROR_INVALIDDATA)
@@ -292,9 +295,6 @@ static av_cold int tedcaptions_read_header(AVFormatContext *avf)
tc->subs.subs[i].pts += tc->start_time;
last = &tc->subs.subs[tc->subs.nb_subs - 1];
- st = avformat_new_stream(avf, NULL);
- if (!st)
- return AVERROR(ENOMEM);
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codecpar->codec_id = AV_CODEC_ID_TEXT;
avpriv_set_pts_info(st, 64, 1, 1000);
diff --git a/chromium/third_party/ffmpeg/libavformat/tee.c b/chromium/third_party/ffmpeg/libavformat/tee.c
index f2b11fcb359..c5c59975e6b 100644
--- a/chromium/third_party/ffmpeg/libavformat/tee.c
+++ b/chromium/third_party/ffmpeg/libavformat/tee.c
@@ -295,7 +295,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
goto end;
}
- ret = ff_format_output_open(avf2, filename, NULL);
+ ret = ff_format_output_open(avf2, filename, &options);
if (ret < 0) {
av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n", slave,
av_err2str(ret));
diff --git a/chromium/third_party/ffmpeg/libavformat/thp.c b/chromium/third_party/ffmpeg/libavformat/thp.c
index 332ed791284..bcc3febaa19 100644
--- a/chromium/third_party/ffmpeg/libavformat/thp.c
+++ b/chromium/third_party/ffmpeg/libavformat/thp.c
@@ -75,6 +75,8 @@ static int thp_read_header(AVFormatContext *s)
avio_rb32(pb); /* Max samples. */
thp->fps = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);
+ if (thp->fps.den <= 0 || thp->fps.num < 0)
+ return AVERROR_INVALIDDATA;
thp->framecnt = avio_rb32(pb);
thp->first_framesz = avio_rb32(pb);
pb->maxsize = avio_rb32(pb);
@@ -93,6 +95,9 @@ static int thp_read_header(AVFormatContext *s)
avio_seek (pb, thp->compoff, SEEK_SET);
thp->compcount = avio_rb32(pb);
+ if (thp->compcount > FF_ARRAY_ELEMS(thp->components))
+ return AVERROR_INVALIDDATA;
+
/* Read the list of component types. */
avio_read(pb, thp->components, 16);
@@ -145,6 +150,9 @@ static int thp_read_header(AVFormatContext *s)
}
}
+ if (!thp->vst)
+ return AVERROR_INVALIDDATA;
+
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c b/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c
index e41156cc30e..0c4ef34f5fc 100644
--- a/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c
+++ b/chromium/third_party/ffmpeg/libavformat/tls_gnutls.c
@@ -100,8 +100,7 @@ static int tls_close(URLContext *h)
gnutls_deinit(c->session);
if (c->cred)
gnutls_certificate_free_credentials(c->cred);
- if (c->tls_shared.tcp)
- ffurl_close(c->tls_shared.tcp);
+ ffurl_closep(&c->tls_shared.tcp);
ff_gnutls_deinit();
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/tls_libtls.c b/chromium/third_party/ffmpeg/libavformat/tls_libtls.c
index ba83b56ffe2..dff7f2d9fb4 100644
--- a/chromium/third_party/ffmpeg/libavformat/tls_libtls.c
+++ b/chromium/third_party/ffmpeg/libavformat/tls_libtls.c
@@ -44,8 +44,7 @@ static int ff_tls_close(URLContext *h)
tls_close(p->ctx);
tls_free(p->ctx);
}
- if (p->tls_shared.tcp)
- ffurl_close(p->tls_shared.tcp);
+ ffurl_closep(&p->tls_shared.tcp);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/tls_openssl.c b/chromium/third_party/ffmpeg/libavformat/tls_openssl.c
index e305b2465a0..002197fa76d 100644
--- a/chromium/third_party/ffmpeg/libavformat/tls_openssl.c
+++ b/chromium/third_party/ffmpeg/libavformat/tls_openssl.c
@@ -142,8 +142,7 @@ static int tls_close(URLContext *h)
}
if (c->ctx)
SSL_CTX_free(c->ctx);
- if (c->tls_shared.tcp)
- ffurl_close(c->tls_shared.tcp);
+ ffurl_closep(&c->tls_shared.tcp);
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
if (c->url_bio_method)
BIO_meth_free(c->url_bio_method);
diff --git a/chromium/third_party/ffmpeg/libavformat/tls_schannel.c b/chromium/third_party/ffmpeg/libavformat/tls_schannel.c
index 4f0badcb8dd..4bfaa852284 100644
--- a/chromium/third_party/ffmpeg/libavformat/tls_schannel.c
+++ b/chromium/third_party/ffmpeg/libavformat/tls_schannel.c
@@ -138,8 +138,7 @@ static int tls_close(URLContext *h)
av_freep(&c->dec_buf);
c->dec_buf_size = c->dec_buf_offset = 0;
- if (c->tls_shared.tcp)
- ffurl_close(c->tls_shared.tcp);
+ ffurl_closep(&c->tls_shared.tcp);
return 0;
}
@@ -392,7 +391,12 @@ static int tls_read(URLContext *h, uint8_t *buf, int len)
int size, ret;
int min_enc_buf_size = len + SCHANNEL_FREE_BUFFER_SIZE;
- if (len <= c->dec_buf_offset)
+ /* If we have some left-over data from previous network activity,
+ * return it first in case it is enough. It may contain
+ * data that is required to know whether this connection
+ * is still required or not, esp. in case of HTTP keep-alive
+ * connections. */
+ if (c->dec_buf_offset > 0)
goto cleanup;
if (c->sspi_close_notify)
@@ -424,7 +428,7 @@ static int tls_read(URLContext *h, uint8_t *buf, int len)
c->enc_buf_offset += ret;
}
- while (c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK && c->dec_buf_offset < len) {
+ while (c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK) {
/* input buffer */
init_sec_buffer(&inbuf[0], SECBUFFER_DATA, c->enc_buf, c->enc_buf_offset);
diff --git a/chromium/third_party/ffmpeg/libavformat/tls_securetransport.c b/chromium/third_party/ffmpeg/libavformat/tls_securetransport.c
index 37380541b11..3250b230517 100644
--- a/chromium/third_party/ffmpeg/libavformat/tls_securetransport.c
+++ b/chromium/third_party/ffmpeg/libavformat/tls_securetransport.c
@@ -251,8 +251,7 @@ static int tls_close(URLContext *h)
}
if (c->ca_array)
CFRelease(c->ca_array);
- if (c->tls_shared.tcp)
- ffurl_close(c->tls_shared.tcp);
+ ffurl_closep(&c->tls_shared.tcp);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/ttaenc.c b/chromium/third_party/ffmpeg/libavformat/ttaenc.c
index 4860aab4c13..becd3e71536 100644
--- a/chromium/third_party/ffmpeg/libavformat/ttaenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/ttaenc.c
@@ -145,10 +145,8 @@ static int tta_write_trailer(AVFormatContext *s)
/* Write Seek table */
crc = ffio_get_checksum(tta->seek_table) ^ UINT32_MAX;
avio_wl32(tta->seek_table, crc);
- size = avio_close_dyn_buf(tta->seek_table, &ptr);
+ size = avio_get_dyn_buf(tta->seek_table, &ptr);
avio_write(s->pb, ptr, size);
- tta->seek_table = NULL;
- av_free(ptr);
/* Write audio data */
tta_queue_flush(s);
diff --git a/chromium/third_party/ffmpeg/libavformat/ty.c b/chromium/third_party/ffmpeg/libavformat/ty.c
index 738a22e7de6..c8e1067c0e8 100644
--- a/chromium/third_party/ffmpeg/libavformat/ty.c
+++ b/chromium/third_party/ffmpeg/libavformat/ty.c
@@ -72,11 +72,6 @@ typedef enum {
TIVO_AUDIO_MPEG
} TiVo_audio;
-typedef struct TySeqTable {
- uint64_t timestamp;
- uint8_t chunk_bitmask[8];
-} TySeqTable;
-
typedef struct TYDemuxContext {
unsigned cur_chunk;
unsigned cur_chunk_pos;
@@ -90,7 +85,6 @@ typedef struct TYDemuxContext {
int pes_buf_cnt; /* how many bytes in our buffer */
size_t ac3_pkt_size; /* length of ac3 pkt we've seen so far */
uint64_t last_ty_pts; /* last TY timestamp we've seen */
- unsigned seq_table_size; /* number of entries in SEQ table */
int64_t first_audio_pts;
int64_t last_audio_pts;
@@ -99,8 +93,6 @@ typedef struct TYDemuxContext {
TyRecHdr *rec_hdrs; /* record headers array */
int cur_rec; /* current record in this chunk */
int num_recs; /* number of recs in this chunk */
- int seq_rec; /* record number where seq start is */
- TySeqTable *seq_table; /* table of SEQ entries from mstr chk */
int first_chunk;
uint8_t chunk[CHUNK_SIZE];
@@ -339,58 +331,6 @@ static int ty_read_header(AVFormatContext *s)
return 0;
}
-/* parse a master chunk, filling the SEQ table and other variables.
- * We assume the stream is currently pointing to it.
- */
-static void parse_master(AVFormatContext *s)
-{
- TYDemuxContext *ty = s->priv_data;
- unsigned map_size; /* size of bitmask, in bytes */
- unsigned i, j;
-
- /* Note that the entries in the SEQ table in the stream may have
- different sizes depending on the bits per entry. We store them
- all in the same size structure, so we have to parse them out one
- by one. If we had a dynamic structure, we could simply read the
- entire table directly from the stream into memory in place. */
-
- /* clear the SEQ table */
- av_freep(&ty->seq_table);
-
- /* parse header info */
-
- map_size = AV_RB32(ty->chunk + 20); /* size of bitmask, in bytes */
- i = AV_RB32(ty->chunk + 28); /* size of SEQ table, in bytes */
-
- ty->seq_table_size = i / (8LL + map_size);
-
- if (ty->seq_table_size == 0) {
- ty->seq_table = NULL;
- return;
- }
-
- /* parse all the entries */
- ty->seq_table = av_calloc(ty->seq_table_size, sizeof(TySeqTable));
- if (ty->seq_table == NULL) {
- ty->seq_table_size = 0;
- return;
- }
-
- ty->cur_chunk_pos = 32;
- for (j = 0; j < ty->seq_table_size; j++) {
- if (ty->cur_chunk_pos >= CHUNK_SIZE - 8)
- return;
- ty->seq_table[j].timestamp = AV_RB64(ty->chunk + ty->cur_chunk_pos);
- ty->cur_chunk_pos += 8;
- if (map_size > 8) {
- av_log(s, AV_LOG_ERROR, "Unsupported SEQ bitmap size in master chunk.\n");
- ty->cur_chunk_pos += map_size;
- } else {
- memcpy(ty->seq_table[j].chunk_bitmask, ty->chunk + ty->cur_chunk_pos, map_size);
- }
- }
-}
-
static int get_chunk(AVFormatContext *s)
{
TYDemuxContext *ty = s->priv_data;
@@ -413,7 +353,7 @@ static int get_chunk(AVFormatContext *s)
/* check if it's a PART Header */
if (AV_RB32(ty->chunk) == TIVO_PES_FILEID) {
- parse_master(s); /* parse master chunk */
+ /* skip master chunk and read new chunk */
return get_chunk(s);
}
@@ -421,14 +361,9 @@ static int get_chunk(AVFormatContext *s)
if (ty->chunk[3] & 0x80) {
/* 16 bit rec cnt */
ty->num_recs = num_recs = (ty->chunk[1] << 8) + ty->chunk[0];
- ty->seq_rec = (ty->chunk[3] << 8) + ty->chunk[2];
- if (ty->seq_rec != 0xffff) {
- ty->seq_rec &= ~0x8000;
- }
} else {
/* 8 bit reclen - TiVo 1.3 format */
ty->num_recs = num_recs = ty->chunk[0];
- ty->seq_rec = ty->chunk[1];
}
ty->cur_rec = 0;
ty->first_chunk = 0;
@@ -770,7 +705,6 @@ static int ty_read_close(AVFormatContext *s)
{
TYDemuxContext *ty = s->priv_data;
- av_freep(&ty->seq_table);
av_freep(&ty->rec_hdrs);
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/udp.c b/chromium/third_party/ffmpeg/libavformat/udp.c
index ad6992c57db..30d80414337 100644
--- a/chromium/third_party/ffmpeg/libavformat/udp.c
+++ b/chromium/third_party/ffmpeg/libavformat/udp.c
@@ -852,7 +852,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
goto fail;
}
} else {
- /* set udp recv buffer size to the requested value (default 64K) */
+ /* set udp recv buffer size to the requested value (default UDP_RX_BUF_SIZE) */
tmp = s->buffer_size;
if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {
ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)");
diff --git a/chromium/third_party/ffmpeg/libavformat/url.c b/chromium/third_party/ffmpeg/libavformat/url.c
index 596fb49cfcf..3c858f0257c 100644
--- a/chromium/third_party/ffmpeg/libavformat/url.c
+++ b/chromium/third_party/ffmpeg/libavformat/url.c
@@ -21,11 +21,13 @@
#include "avformat.h"
+#include "internal.h"
#include "config.h"
#include "url.h"
#if CONFIG_NETWORK
#include "network.h"
#endif
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
/**
@@ -77,73 +79,219 @@ int ff_url_join(char *str, int size, const char *proto,
return strlen(str);
}
-void ff_make_absolute_url(char *buf, int size, const char *base,
- const char *rel)
+static const char *find_delim(const char *delim, const char *cur, const char *end)
{
- char *sep, *path_query;
- /* Absolute path, relative to the current server */
- if (base && strstr(base, "://") && rel[0] == '/') {
- if (base != buf)
- av_strlcpy(buf, base, size);
- sep = strstr(buf, "://");
- if (sep) {
- /* Take scheme from base url */
- if (rel[1] == '/') {
- sep[1] = '\0';
- } else {
- /* Take scheme and host from base url */
- sep += 3;
- sep = strchr(sep, '/');
- if (sep)
- *sep = '\0';
- }
+ while (cur < end && !strchr(delim, *cur))
+ cur++;
+ return cur;
+}
+
+int ff_url_decompose(URLComponents *uc, const char *url, const char *end)
+{
+ const char *cur, *aend, *p;
+
+ av_assert0(url);
+ if (!end)
+ end = url + strlen(url);
+ cur = uc->url = url;
+
+ /* scheme */
+ uc->scheme = cur;
+ p = find_delim(":/", cur, end); /* lavf "schemes" can contain options */
+ if (*p == ':')
+ cur = p + 1;
+
+ /* authority */
+ uc->authority = cur;
+ if (end - cur >= 2 && cur[0] == '/' && cur[1] == '/') {
+ cur += 2;
+ aend = find_delim("/?#", cur, end);
+
+ /* userinfo */
+ uc->userinfo = cur;
+ p = find_delim("@", cur, aend);
+ if (*p == '@')
+ cur = p + 1;
+
+ /* host */
+ uc->host = cur;
+ if (*cur == '[') { /* hello IPv6, thanks for using colons! */
+ p = find_delim("]", cur, aend);
+ if (*p != ']')
+ return AVERROR(EINVAL);
+ if (p + 1 < aend && p[1] != ':')
+ return AVERROR(EINVAL);
+ cur = p + 1;
+ } else {
+ cur = find_delim(":", cur, aend);
}
- av_strlcat(buf, rel, size);
- return;
+
+ /* port */
+ uc->port = cur;
+ cur = aend;
+ } else {
+ uc->userinfo = uc->host = uc->port = cur;
}
- /* If rel actually is an absolute url, just copy it */
- if (!base || strstr(rel, "://") || rel[0] == '/') {
- av_strlcpy(buf, rel, size);
- return;
+
+ /* path */
+ uc->path = cur;
+ cur = find_delim("?#", cur, end);
+
+ /* query */
+ uc->query = cur;
+ if (*cur == '?')
+ cur = find_delim("#", cur, end);
+
+ /* fragment */
+ uc->fragment = cur;
+
+ uc->end = end;
+ return 0;
+}
+
+static int append_path(char *root, char *out_end, char **rout,
+ const char *in, const char *in_end)
+{
+ char *out = *rout;
+ const char *d, *next;
+
+ if (in < in_end && *in == '/')
+ in++; /* already taken care of */
+ while (in < in_end) {
+ d = find_delim("/", in, in_end);
+ next = d + (d < in_end && *d == '/');
+ if (d - in == 1 && in[0] == '.') {
+ /* skip */
+ } else if (d - in == 2 && in[0] == '.' && in[1] == '.') {
+ av_assert1(out[-1] == '/');
+ if (out - root > 1)
+ while (out > root && (--out)[-1] != '/');
+ } else {
+ if (out_end - out < next - in)
+ return AVERROR(ENOMEM);
+ memmove(out, in, next - in);
+ out += next - in;
+ }
+ in = next;
}
- if (base != buf)
- av_strlcpy(buf, base, size);
-
- /* Strip off any query string from base */
- path_query = strchr(buf, '?');
- if (path_query)
- *path_query = '\0';
-
- /* Is relative path just a new query part? */
- if (rel[0] == '?') {
- av_strlcat(buf, rel, size);
- return;
+ *rout = out;
+ return 0;
+}
+
+int ff_make_absolute_url(char *buf, int size, const char *base,
+ const char *rel)
+{
+ URLComponents ub, uc;
+ char *out, *out_end, *path;
+ const char *keep, *base_path_end;
+ int use_base_path, simplify_path = 0, ret;
+
+ /* This is tricky.
+ For HTTP, http://server/site/page + ../media/file
+ should resolve into http://server/media/file
+ but for filesystem access, dir/playlist + ../media/file
+ should resolve into dir/../media/file
+ because dir could be a symlink, and .. points to
+ the actual parent of the target directory.
+
+ We'll consider that URLs with an actual scheme and authority,
+ i.e. starting with scheme://, need parent dir simplification,
+ while bare paths or pseudo-URLs starting with proto: without
+ the double slash do not.
+
+ For real URLs, the processing is similar to the algorithm described
+ here:
+ https://tools.ietf.org/html/rfc3986#section-5
+ */
+
+ if (!size)
+ return AVERROR(ENOMEM);
+ out = buf;
+ out_end = buf + size - 1;
+
+ if (!base)
+ base = "";
+ if ((ret = ff_url_decompose(&ub, base, NULL) < 0) ||
+ (ret = ff_url_decompose(&uc, rel, NULL) < 0))
+ goto error;
+
+ keep = ub.url;
+#define KEEP(component, also) do { \
+ if (uc.url_component_end_##component == uc.url && \
+ ub.url_component_end_##component > keep) { \
+ keep = ub.url_component_end_##component; \
+ also \
+ } \
+ } while (0)
+ KEEP(scheme, );
+ KEEP(authority_full, simplify_path = 1;);
+ KEEP(path,);
+ KEEP(query,);
+ KEEP(fragment,);
+#undef KEEP
+#define COPY(start, end) do { \
+ size_t len = end - start; \
+ if (len > out_end - out) { \
+ ret = AVERROR(ENOMEM); \
+ goto error; \
+ } \
+ memmove(out, start, len); \
+ out += len; \
+ } while (0)
+ COPY(ub.url, keep);
+ COPY(uc.url, uc.path);
+
+ use_base_path = URL_COMPONENT_HAVE(ub, path) && keep <= ub.path;
+ if (uc.path > uc.url)
+ use_base_path = 0;
+ if (URL_COMPONENT_HAVE(uc, path) && uc.path[0] == '/')
+ use_base_path = 0;
+ if (use_base_path) {
+ base_path_end = ub.url_component_end_path;
+ if (URL_COMPONENT_HAVE(uc, path))
+ while (base_path_end > ub.path && base_path_end[-1] != '/')
+ base_path_end--;
}
+ if (keep > ub.path)
+ simplify_path = 0;
+ if (URL_COMPONENT_HAVE(uc, scheme))
+ simplify_path = 0;
+ if (URL_COMPONENT_HAVE(uc, authority))
+ simplify_path = 1;
+ /* No path at all, leave it */
+ if (!use_base_path && !URL_COMPONENT_HAVE(uc, path))
+ simplify_path = 0;
- /* Remove the file name from the base url */
- sep = strrchr(buf, '/');
- if (sep)
- sep[1] = '\0';
- else
- buf[0] = '\0';
- while (av_strstart(rel, "../", NULL) && sep) {
- /* Remove the path delimiter at the end */
- sep[0] = '\0';
- sep = strrchr(buf, '/');
- /* If the next directory name to pop off is "..", break here */
- if (!strcmp(sep ? &sep[1] : buf, "..")) {
- /* Readd the slash we just removed */
- av_strlcat(buf, "/", size);
- break;
+ if (simplify_path) {
+ const char *root = "/";
+ COPY(root, root + 1);
+ path = out;
+ if (use_base_path) {
+ ret = append_path(path, out_end, &out, ub.path, base_path_end);
+ if (ret < 0)
+ goto error;
+ }
+ if (URL_COMPONENT_HAVE(uc, path)) {
+ ret = append_path(path, out_end, &out, uc.path, uc.url_component_end_path);
+ if (ret < 0)
+ goto error;
}
- /* Cut off the directory name */
- if (sep)
- sep[1] = '\0';
- else
- buf[0] = '\0';
- rel += 3;
+ } else {
+ if (use_base_path)
+ COPY(ub.path, base_path_end);
+ COPY(uc.path, uc.url_component_end_path);
}
- av_strlcat(buf, rel, size);
+
+ COPY(uc.url_component_end_path, uc.end);
+#undef COPY
+ *out = 0;
+ return 0;
+
+error:
+ snprintf(buf, size, "invalid:%s",
+ ret == AVERROR(ENOMEM) ? "truncated" :
+ ret == AVERROR(EINVAL) ? "syntax_error" : "");
+ return ret;
}
AVIODirEntry *ff_alloc_dir_entry(void)
diff --git a/chromium/third_party/ffmpeg/libavformat/url.h b/chromium/third_party/ffmpeg/libavformat/url.h
index 4750bfff825..e33edf0cb98 100644
--- a/chromium/third_party/ffmpeg/libavformat/url.h
+++ b/chromium/third_party/ffmpeg/libavformat/url.h
@@ -312,8 +312,8 @@ int ff_url_join(char *str, int size, const char *proto,
* @param base the base url, may be equal to buf.
* @param rel the new url, which is interpreted relative to base
*/
-void ff_make_absolute_url(char *buf, int size, const char *base,
- const char *rel);
+int ff_make_absolute_url(char *buf, int size, const char *base,
+ const char *rel);
/**
* Allocate directory entry with default values.
@@ -322,7 +322,11 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
*/
AVIODirEntry *ff_alloc_dir_entry(void);
+#if FF_API_CHILD_CLASS_NEXT
const AVClass *ff_urlcontext_child_class_next(const AVClass *prev);
+#endif
+
+const AVClass *ff_urlcontext_child_class_iterate(void **iter);
/**
* Construct a list of protocols matching a given whitelist and/or blacklist.
@@ -340,4 +344,45 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev);
const URLProtocol **ffurl_get_protocols(const char *whitelist,
const char *blacklist);
+typedef struct URLComponents {
+ const char *url; /**< whole URL, for reference */
+ const char *scheme; /**< possibly including lavf-specific options */
+ const char *authority; /**< "//" if it is a real URL */
+ const char *userinfo; /**< including final '@' if present */
+ const char *host;
+ const char *port; /**< including initial ':' if present */
+ const char *path;
+ const char *query; /**< including initial '?' if present */
+ const char *fragment; /**< including initial '#' if present */
+ const char *end;
+} URLComponents;
+
+#define url_component_end_scheme authority
+#define url_component_end_authority userinfo
+#define url_component_end_userinfo host
+#define url_component_end_host port
+#define url_component_end_port path
+#define url_component_end_path query
+#define url_component_end_query fragment
+#define url_component_end_fragment end
+#define url_component_end_authority_full path
+
+#define URL_COMPONENT_HAVE(uc, component) \
+ ((uc).url_component_end_##component > (uc).component)
+
+/**
+ * Parse an URL to find the components.
+ *
+ * Each component runs until the start of the next component,
+ * possibly including a mandatory delimiter.
+ *
+ * @param uc structure to fill with pointers to the components.
+ * @param url URL to parse.
+ * @param end end of the URL, or NULL to parse to the end of string.
+ *
+ * @return >= 0 for success or an AVERROR code, especially if the URL is
+ * malformed.
+ */
+int ff_url_decompose(URLComponents *uc, const char *url, const char *end);
+
#endif /* AVFORMAT_URL_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/utils.c b/chromium/third_party/ffmpeg/libavformat/utils.c
index f3bea05cf49..7e2954bbb17 100644
--- a/chromium/third_party/ffmpeg/libavformat/utils.c
+++ b/chromium/third_party/ffmpeg/libavformat/utils.c
@@ -219,7 +219,7 @@ static const AVCodec *find_probe_decoder(AVFormatContext *s, const AVStream *st,
const AVCodec *probe_codec = NULL;
void *iter = NULL;
while ((probe_codec = av_codec_iterate(&iter))) {
- if (probe_codec->id == codec_id &&
+ if (probe_codec->id == codec->id &&
av_codec_is_decoder(probe_codec) &&
!(probe_codec->capabilities & (AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_EXPERIMENTAL))) {
return probe_codec;
@@ -638,11 +638,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (id3v2_extra_meta) {
if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") ||
!strcmp(s->iformat->name, "tta") || !strcmp(s->iformat->name, "wav")) {
- if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
+ if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0)
goto close;
- if ((ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0)
+ if ((ret = ff_id3v2_parse_chapters(s, id3v2_extra_meta)) < 0)
goto close;
- if ((ret = ff_id3v2_parse_priv(s, &id3v2_extra_meta)) < 0)
+ if ((ret = ff_id3v2_parse_priv(s, id3v2_extra_meta)) < 0)
goto close;
} else
av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n");
@@ -1011,7 +1011,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
-static int is_intra_only(enum AVCodecID id)
+int ff_is_intra_only(enum AVCodecID id)
{
const AVCodecDescriptor *d = avcodec_descriptor_get(id);
if (!d)
@@ -1174,7 +1174,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index,
}
static void update_initial_durations(AVFormatContext *s, AVStream *st,
- int stream_index, int duration)
+ int stream_index, int64_t duration)
{
AVPacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue;
int64_t cur_dts = RELATIVE_TS_BASE;
@@ -1410,7 +1410,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), st->index, st->id);
/* update flags */
- if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || is_intra_only(st->codecpar->codec_id))
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || ff_is_intra_only(st->codecpar->codec_id))
pkt->flags |= AV_PKT_FLAG_KEY;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
@@ -2783,7 +2783,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic)
st = ic->streams[i];
if ( st->time_base.num <= INT64_MAX / ic->bit_rate
&& st->duration == AV_NOPTS_VALUE) {
- duration = av_rescale(8 * filesize, st->time_base.den,
+ duration = av_rescale(filesize, 8LL * st->time_base.den,
ic->bit_rate *
(int64_t) st->time_base.num);
st->duration = duration;
@@ -2985,16 +2985,16 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset)
for (i = 0; i < ic->nb_streams; i++) {
st = ic->streams[i];
if (st->time_base.den)
- av_log(ic, AV_LOG_TRACE, "stream %d: start_time: %0.3f duration: %0.3f\n", i,
- (double) st->start_time * av_q2d(st->time_base),
- (double) st->duration * av_q2d(st->time_base));
+ av_log(ic, AV_LOG_TRACE, "stream %d: start_time: %s duration: %s\n", i,
+ av_ts2timestr(st->start_time, &st->time_base),
+ av_ts2timestr(st->duration, &st->time_base));
}
av_log(ic, AV_LOG_TRACE,
- "format: start_time: %0.3f duration: %0.3f (estimate from %s) bitrate=%"PRId64" kb/s\n",
- (double) ic->start_time / AV_TIME_BASE,
- (double) ic->duration / AV_TIME_BASE,
- duration_estimate_name(ic->duration_estimation_method),
- (int64_t)ic->bit_rate / 1000);
+ "format: start_time: %s duration: %s (estimate from %s) bitrate=%"PRId64" kb/s\n",
+ av_ts2timestr(ic->start_time, &AV_TIME_BASE_Q),
+ av_ts2timestr(ic->duration, &AV_TIME_BASE_Q),
+ duration_estimate_name(ic->duration_estimation_method),
+ (int64_t)ic->bit_rate / 1000);
}
}
@@ -4133,8 +4133,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
avcodec_string(buf, sizeof(buf), st->internal->avctx, 0);
av_log(ic, AV_LOG_WARNING,
"Could not find codec parameters for stream %d (%s): %s\n"
- "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n",
- i, buf, errmsg);
+ "Consider increasing the value for the 'analyzeduration' (%"PRId64") and 'probesize' (%"PRId64") options\n",
+ i, buf, errmsg, ic->max_analyze_duration, ic->probesize);
} else {
ret = 0;
}
@@ -5508,6 +5508,8 @@ uint8_t *av_stream_get_side_data(const AVStream *st,
return st->side_data[i].data;
}
}
+ if (size)
+ *size = 0;
return NULL;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/version.h b/chromium/third_party/ffmpeg/libavformat/version.h
index 719cda6b980..aa309ecc773 100644
--- a/chromium/third_party/ffmpeg/libavformat/version.h
+++ b/chromium/third_party/ffmpeg/libavformat/version.h
@@ -32,8 +32,8 @@
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
// Also please add any ticket numbers that you believe might be affected here
#define LIBAVFORMAT_VERSION_MAJOR 58
-#define LIBAVFORMAT_VERSION_MINOR 42
-#define LIBAVFORMAT_VERSION_MICRO 101
+#define LIBAVFORMAT_VERSION_MINOR 51
+#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
diff --git a/chromium/third_party/ffmpeg/libavformat/vividas.c b/chromium/third_party/ffmpeg/libavformat/vividas.c
index 4f54a4302e1..36c007b0d26 100644
--- a/chromium/third_party/ffmpeg/libavformat/vividas.c
+++ b/chromium/third_party/ffmpeg/libavformat/vividas.c
@@ -432,19 +432,20 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu
AVIOContext pb0, *pb = &pb0;
int i;
int64_t filesize = avio_size(s->pb);
+ uint64_t n_sb_blocks_tmp;
ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL);
ffio_read_varlen(pb); // track_index_len
avio_r8(pb); // 'c'
- viv->n_sb_blocks = ffio_read_varlen(pb);
- if (viv->n_sb_blocks < 0 || viv->n_sb_blocks > size / 2)
- goto error;
- viv->sb_blocks = av_calloc(viv->n_sb_blocks, sizeof(VIV_SB_block));
+ n_sb_blocks_tmp = ffio_read_varlen(pb);
+ if (n_sb_blocks_tmp > size / 2)
+ return AVERROR_INVALIDDATA;
+ viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
if (!viv->sb_blocks) {
- viv->n_sb_blocks = 0;
return AVERROR(ENOMEM);
}
+ viv->n_sb_blocks = n_sb_blocks_tmp;
off = 0;
poff = 0;
@@ -454,7 +455,7 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu
uint64_t n_packets_tmp = ffio_read_varlen(pb);
if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
- goto error;
+ return AVERROR_INVALIDDATA;
viv->sb_blocks[i].byte_offset = off;
viv->sb_blocks[i].packet_offset = poff;
@@ -470,15 +471,13 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu
}
if (filesize > 0 && poff > filesize)
- goto error;
+ return AVERROR_INVALIDDATA;
viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
+ if (!viv->sb_entries)
+ return AVERROR(ENOMEM);
return 0;
-error:
- viv->n_sb_blocks = 0;
- av_freep(&viv->sb_blocks);
- return AVERROR_INVALIDDATA;
}
static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
@@ -607,7 +606,7 @@ static int viv_read_header(AVFormatContext *s)
ret = track_index(viv, s, buf, v);
av_free(buf);
if (ret < 0)
- return ret;
+ goto fail;
viv->sb_offset = avio_tell(pb);
if (viv->n_sb_blocks > 0) {
@@ -618,6 +617,9 @@ static int viv_read_header(AVFormatContext *s)
}
return 0;
+fail:
+ av_freep(&viv->sb_blocks);
+ return ret;
}
static int viv_read_packet(AVFormatContext *s,
@@ -646,7 +648,7 @@ static int viv_read_packet(AVFormatContext *s,
pkt->stream_index = 1;
astream = s->streams[pkt->stream_index];
- pkt->pts = av_rescale(viv->audio_sample, astream->time_base.den, astream->time_base.num) / astream->codecpar->sample_rate;
+ pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
viv->audio_sample += viv->audio_subpackets[viv->current_audio_subpacket].pcm_bytes / 2 / astream->codecpar->channels;
pkt->flags |= AV_PKT_FLAG_KEY;
viv->current_audio_subpacket++;
diff --git a/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c b/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c
index fb5c655a23f..a929634cc04 100644
--- a/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c
+++ b/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c
@@ -19,10 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "avio.h"
#include "avformat.h"
#include "metadata.h"
#include "vorbiscomment.h"
-#include "libavcodec/bytestream.h"
#include "libavutil/dict.h"
/**
@@ -38,7 +38,7 @@ const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
{ 0 }
};
-int64_t ff_vorbiscomment_length(AVDictionary *m, const char *vendor_string,
+int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string,
AVChapter **chapters, unsigned int nb_chapters)
{
int64_t len = 8;
@@ -62,31 +62,31 @@ int64_t ff_vorbiscomment_length(AVDictionary *m, const char *vendor_string,
return len;
}
-int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m,
+int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m,
const char *vendor_string,
AVChapter **chapters, unsigned int nb_chapters)
{
int cm_count = 0;
- bytestream_put_le32(p, strlen(vendor_string));
- bytestream_put_buffer(p, vendor_string, strlen(vendor_string));
+ avio_wl32(pb, strlen(vendor_string));
+ avio_write(pb, vendor_string, strlen(vendor_string));
if (chapters && nb_chapters) {
for (int i = 0; i < nb_chapters; i++) {
cm_count += av_dict_count(chapters[i]->metadata) + 1;
}
}
- if (*m) {
- int count = av_dict_count(*m) + cm_count;
+ if (m) {
+ int count = av_dict_count(m) + cm_count;
AVDictionaryEntry *tag = NULL;
- bytestream_put_le32(p, count);
- while ((tag = av_dict_get(*m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ avio_wl32(pb, count);
+ while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
int64_t len1 = strlen(tag->key);
int64_t len2 = strlen(tag->value);
if (len1+1+len2 > UINT32_MAX)
return AVERROR(EINVAL);
- bytestream_put_le32(p, len1+1+len2);
- bytestream_put_buffer(p, tag->key, len1);
- bytestream_put_byte(p, '=');
- bytestream_put_buffer(p, tag->value, len2);
+ avio_wl32(pb, len1 + 1 + len2);
+ avio_write(pb, tag->key, len1);
+ avio_w8(pb, '=');
+ avio_write(pb, tag->value, len2);
}
for (int i = 0; i < nb_chapters; i++) {
AVChapter *chp = chapters[i];
@@ -101,11 +101,11 @@ int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m,
s = s % 60;
snprintf(chapter_number, sizeof(chapter_number), "%03d", i);
snprintf(chapter_time, sizeof(chapter_time), "%02d:%02d:%02d.%03d", h, m, s, ms);
- bytestream_put_le32(p, 10+1+12);
- bytestream_put_buffer(p, "CHAPTER", 7);
- bytestream_put_buffer(p, chapter_number, 3);
- bytestream_put_byte(p, '=');
- bytestream_put_buffer(p, chapter_time, 12);
+ avio_wl32(pb, 10 + 1 + 12);
+ avio_write(pb, "CHAPTER", 7);
+ avio_write(pb, chapter_number, 3);
+ avio_w8(pb, '=');
+ avio_write(pb, chapter_time, 12);
tag = NULL;
while ((tag = av_dict_get(chapters[i]->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
@@ -113,18 +113,18 @@ int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m,
int64_t len2 = strlen(tag->value);
if (len1+1+len2+10 > UINT32_MAX)
return AVERROR(EINVAL);
- bytestream_put_le32(p, 10+len1+1+len2);
- bytestream_put_buffer(p, "CHAPTER", 7);
- bytestream_put_buffer(p, chapter_number, 3);
+ avio_wl32(pb, 10 + len1 + 1 + len2);
+ avio_write(pb, "CHAPTER", 7);
+ avio_write(pb, chapter_number, 3);
if (!strcmp(tag->key, "title"))
- bytestream_put_buffer(p, "NAME", 4);
+ avio_write(pb, "NAME", 4);
else
- bytestream_put_buffer(p, tag->key, len1);
- bytestream_put_byte(p, '=');
- bytestream_put_buffer(p, tag->value, len2);
+ avio_write(pb, tag->key, len1);
+ avio_w8(pb, '=');
+ avio_write(pb, tag->value, len2);
}
}
} else
- bytestream_put_le32(p, 0);
+ avio_wl32(pb, 0);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/vorbiscomment.h b/chromium/third_party/ffmpeg/libavformat/vorbiscomment.h
index 4ff3dd6c278..7cacd0b2a09 100644
--- a/chromium/third_party/ffmpeg/libavformat/vorbiscomment.h
+++ b/chromium/third_party/ffmpeg/libavformat/vorbiscomment.h
@@ -34,22 +34,21 @@
* For no string, set to an empty string.
* @return The length in bytes.
*/
-int64_t ff_vorbiscomment_length(AVDictionary *m, const char *vendor_string,
+int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string,
AVChapter **chapters, unsigned int nb_chapters);
/**
- * Write a VorbisComment into a buffer. The buffer, p, must have enough
- * data to hold the whole VorbisComment. The minimum size required can be
- * obtained by passing the same AVDictionary and vendor_string to
+ * Write a VorbisComment into an AVIOContext. The output size can be obtained
+ * in advance by passing the same chapters, AVDictionary and vendor_string to
* ff_vorbiscomment_length()
*
- * @param p The buffer in which to write.
+ * @param pb The AVIOContext to write the output.
* @param m The metadata struct to write.
* @param vendor_string The vendor string to write.
* @param chapters The chapters to write.
* @param nb_chapters The number of chapters to write.
*/
-int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m,
+int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m,
const char *vendor_string,
AVChapter **chapters, unsigned int nb_chapters);
diff --git a/chromium/third_party/ffmpeg/libavformat/vplayerdec.c b/chromium/third_party/ffmpeg/libavformat/vplayerdec.c
index e3e7b4efb82..ca23ec76ac5 100644
--- a/chromium/third_party/ffmpeg/libavformat/vplayerdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/vplayerdec.c
@@ -83,8 +83,10 @@ static int vplayer_read_header(AVFormatContext *s)
AVPacket *sub;
sub = ff_subtitles_queue_insert(&vplayer->q, p, strlen(p), 0);
- if (!sub)
+ if (!sub) {
+ ff_subtitles_queue_clean(&vplayer->q);
return AVERROR(ENOMEM);
+ }
sub->pos = pos;
sub->pts = pts_start;
sub->duration = -1;
diff --git a/chromium/third_party/ffmpeg/libavformat/wavdec.c b/chromium/third_party/ffmpeg/libavformat/wavdec.c
index 3297f59a5f9..d6ae54f7218 100644
--- a/chromium/third_party/ffmpeg/libavformat/wavdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/wavdec.c
@@ -509,9 +509,9 @@ static int wav_read_header(AVFormatContext *s)
ID3v2ExtraMeta *id3v2_extra_meta = NULL;
ff_id3v2_read_dict(pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
if (id3v2_extra_meta) {
- ff_id3v2_parse_apic(s, &id3v2_extra_meta);
- ff_id3v2_parse_chapters(s, &id3v2_extra_meta);
- ff_id3v2_parse_priv(s, &id3v2_extra_meta);
+ ff_id3v2_parse_apic(s, id3v2_extra_meta);
+ ff_id3v2_parse_chapters(s, id3v2_extra_meta);
+ ff_id3v2_parse_priv(s, id3v2_extra_meta);
}
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/wavenc.c b/chromium/third_party/ffmpeg/libavformat/wavenc.c
index f6f5710802d..1027f107eed 100644
--- a/chromium/third_party/ffmpeg/libavformat/wavenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/wavenc.c
@@ -434,10 +434,9 @@ static int wav_write_trailer(AVFormatContext *s)
"Filesize %"PRId64" invalid for wav, output file will be broken\n",
file_size);
}
-
- number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
- s->streams[0]->codecpar->sample_rate * (int64_t)s->streams[0]->time_base.num,
- s->streams[0]->time_base.den);
+ number_of_samples = av_rescale_q(wav->maxpts - wav->minpts + wav->last_duration,
+ s->streams[0]->time_base,
+ av_make_q(1, s->streams[0]->codecpar->sample_rate));
if(s->streams[0]->codecpar->codec_tag != 0x01) {
/* Update num_samps in fact chunk */
diff --git a/chromium/third_party/ffmpeg/libavformat/webm_chunk.c b/chromium/third_party/ffmpeg/libavformat/webm_chunk.c
index 17495099756..f1bee5fa9ff 100644
--- a/chromium/third_party/ffmpeg/libavformat/webm_chunk.c
+++ b/chromium/third_party/ffmpeg/libavformat/webm_chunk.c
@@ -44,6 +44,7 @@ typedef struct WebMChunkContext {
uint64_t duration_written;
int64_t prev_pts;
AVFormatContext *avf;
+ int header_written;
} WebMChunkContext;
static int webm_chunk_init(AVFormatContext *s)
@@ -101,6 +102,15 @@ static int webm_chunk_init(AVFormatContext *s)
avpriv_set_pts_info(st, ost->pts_wrap_bits, ost->time_base.num,
ost->time_base.den);
+ if (wc->http_method)
+ if ((ret = av_dict_set(&dict, "method", wc->http_method, 0)) < 0)
+ return ret;
+ ret = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, &dict);
+ av_dict_free(&dict);
+ if (ret < 0)
+ return ret;
+ oc->pb->seekable = 0;
+
if ((ret = av_dict_set_int(&dict, "dash", 1, 0)) < 0 ||
(ret = av_dict_set_int(&dict, "cluster_time_limit",
wc->chunk_duration, 0)) < 0 ||
@@ -147,19 +157,10 @@ static int webm_chunk_write_header(AVFormatContext *s)
WebMChunkContext *wc = s->priv_data;
AVFormatContext *oc = wc->avf;
int ret;
- AVDictionary *options = NULL;
- if (wc->http_method)
- if ((ret = av_dict_set(&options, "method", wc->http_method, 0)) < 0)
- return ret;
- ret = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, &options);
- av_dict_free(&options);
- if (ret < 0)
- return ret;
-
- oc->pb->seekable = 0;
ret = avformat_write_header(oc, NULL);
ff_format_io_close(s, &oc->pb);
+ wc->header_written = 1;
if (ret < 0)
return ret;
return 0;
@@ -270,7 +271,10 @@ static void webm_chunk_deinit(AVFormatContext *s)
if (!wc->avf)
return;
- ffio_free_dyn_buf(&wc->avf->pb);
+ if (wc->header_written)
+ ffio_free_dyn_buf(&wc->avf->pb);
+ else
+ ff_format_io_close(s, &wc->avf->pb);
avformat_free_context(wc->avf);
wc->avf = NULL;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/webmdashenc.c b/chromium/third_party/ffmpeg/libavformat/webmdashenc.c
index 465485c90ca..04f8cbe39df 100644
--- a/chromium/third_party/ffmpeg/libavformat/webmdashenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/webmdashenc.c
@@ -79,19 +79,20 @@ static double get_duration(AVFormatContext *s)
static int write_header(AVFormatContext *s)
{
WebMDashMuxContext *w = s->priv_data;
+ AVIOContext *pb = s->pb;
double min_buffer_time = 1.0;
- avio_printf(s->pb, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- avio_printf(s->pb, "<MPD\n");
- avio_printf(s->pb, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
- avio_printf(s->pb, " xmlns=\"urn:mpeg:DASH:schema:MPD:2011\"\n");
- avio_printf(s->pb, " xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011\"\n");
- avio_printf(s->pb, " type=\"%s\"\n", w->is_live ? "dynamic" : "static");
+ avio_printf(pb, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ avio_printf(pb, "<MPD\n");
+ avio_printf(pb, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
+ avio_printf(pb, " xmlns=\"urn:mpeg:DASH:schema:MPD:2011\"\n");
+ avio_printf(pb, " xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011\"\n");
+ avio_printf(pb, " type=\"%s\"\n", w->is_live ? "dynamic" : "static");
if (!w->is_live) {
- avio_printf(s->pb, " mediaPresentationDuration=\"PT%gS\"\n",
+ avio_printf(pb, " mediaPresentationDuration=\"PT%gS\"\n",
get_duration(s));
}
- avio_printf(s->pb, " minBufferTime=\"PT%gS\"\n", min_buffer_time);
- avio_printf(s->pb, " profiles=\"%s\"%s",
+ avio_printf(pb, " minBufferTime=\"PT%gS\"\n", min_buffer_time);
+ avio_printf(pb, " profiles=\"%s\"%s",
w->is_live ? "urn:mpeg:dash:profile:isoff-live:2011" : "urn:webm:dash:profile:webm-on-demand:2012",
w->is_live ? "\n" : ">\n");
if (w->is_live) {
@@ -105,14 +106,14 @@ static int write_header(AVFormatContext *s)
if (s->flags & AVFMT_FLAG_BITEXACT) {
av_strlcpy(gmt_iso, "", 1);
}
- avio_printf(s->pb, " availabilityStartTime=\"%s\"\n", gmt_iso);
- avio_printf(s->pb, " timeShiftBufferDepth=\"PT%gS\"\n", w->time_shift_buffer_depth);
- avio_printf(s->pb, " minimumUpdatePeriod=\"PT%dS\"", w->minimum_update_period);
- avio_printf(s->pb, ">\n");
+ avio_printf(pb, " availabilityStartTime=\"%s\"\n", gmt_iso);
+ avio_printf(pb, " timeShiftBufferDepth=\"PT%gS\"\n", w->time_shift_buffer_depth);
+ avio_printf(pb, " minimumUpdatePeriod=\"PT%dS\"", w->minimum_update_period);
+ avio_printf(pb, ">\n");
if (w->utc_timing_url) {
- avio_printf(s->pb, "<UTCTiming\n");
- avio_printf(s->pb, " schemeIdUri=\"urn:mpeg:dash:utc:http-iso:2014\"\n");
- avio_printf(s->pb, " value=\"%s\"/>\n", w->utc_timing_url);
+ avio_printf(pb, "<UTCTiming\n");
+ avio_printf(pb, " schemeIdUri=\"urn:mpeg:dash:utc:http-iso:2014\"\n");
+ avio_printf(pb, " value=\"%s\"/>\n", w->utc_timing_url);
}
}
return 0;
@@ -123,7 +124,8 @@ static void write_footer(AVFormatContext *s)
avio_printf(s->pb, "</MPD>\n");
}
-static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) {
+static int subsegment_alignment(AVFormatContext *s, const AdaptationSet *as)
+{
int i;
AVDictionaryEntry *gold = av_dict_get(s->streams[as->streams[0]]->metadata,
CUE_TIMESTAMPS, NULL, 0);
@@ -136,16 +138,19 @@ static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) {
return 1;
}
-static int bitstream_switching(AVFormatContext *s, AdaptationSet *as) {
+static int bitstream_switching(AVFormatContext *s, const AdaptationSet *as)
+{
int i;
- AVDictionaryEntry *gold_track_num = av_dict_get(s->streams[as->streams[0]]->metadata,
+ const AVStream *gold_st = s->streams[as->streams[0]];
+ AVDictionaryEntry *gold_track_num = av_dict_get(gold_st->metadata,
TRACK_NUMBER, NULL, 0);
- AVCodecParameters *gold_par = s->streams[as->streams[0]]->codecpar;
+ AVCodecParameters *gold_par = gold_st->codecpar;
if (!gold_track_num) return 0;
for (i = 1; i < as->nb_streams; i++) {
- AVDictionaryEntry *track_num = av_dict_get(s->streams[as->streams[i]]->metadata,
+ const AVStream *st = s->streams[as->streams[i]];
+ AVDictionaryEntry *track_num = av_dict_get(st->metadata,
TRACK_NUMBER, NULL, 0);
- AVCodecParameters *par = s->streams[as->streams[i]]->codecpar;
+ AVCodecParameters *par = st->codecpar;
if (!track_num ||
strncmp(gold_track_num->value, track_num->value, strlen(gold_track_num->value)) ||
gold_par->codec_id != par->codec_id ||
@@ -161,60 +166,65 @@ static int bitstream_switching(AVFormatContext *s, AdaptationSet *as) {
* Writes a Representation within an Adaptation Set. Returns 0 on success and
* < 0 on failure.
*/
-static int write_representation(AVFormatContext *s, AVStream *stream, char *id,
+static int write_representation(AVFormatContext *s, AVStream *st, char *id,
int output_width, int output_height,
- int output_sample_rate) {
+ int output_sample_rate)
+{
WebMDashMuxContext *w = s->priv_data;
- AVDictionaryEntry *irange = av_dict_get(stream->metadata, INITIALIZATION_RANGE, NULL, 0);
- AVDictionaryEntry *cues_start = av_dict_get(stream->metadata, CUES_START, NULL, 0);
- AVDictionaryEntry *cues_end = av_dict_get(stream->metadata, CUES_END, NULL, 0);
- AVDictionaryEntry *filename = av_dict_get(stream->metadata, FILENAME, NULL, 0);
- AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0);
+ AVIOContext *pb = s->pb;
+ const AVCodecParameters *par = st->codecpar;
+ AVDictionaryEntry *bandwidth = av_dict_get(st->metadata, BANDWIDTH, NULL, 0);
const char *bandwidth_str;
- if ((w->is_live && (!filename)) ||
- (!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) {
- return AVERROR_INVALIDDATA;
- }
- avio_printf(s->pb, "<Representation id=\"%s\"", id);
- // if bandwidth for live was not provided, use a default
- if (w->is_live && !bandwidth) {
- bandwidth_str = (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ? "128000" : "1000000";
- } else {
+ avio_printf(pb, "<Representation id=\"%s\"", id);
+ if (bandwidth) {
bandwidth_str = bandwidth->value;
+ } else if (w->is_live) {
+ // if bandwidth for live was not provided, use a default
+ bandwidth_str = (par->codec_type == AVMEDIA_TYPE_AUDIO) ? "128000" : "1000000";
+ } else {
+ return AVERROR(EINVAL);
}
- avio_printf(s->pb, " bandwidth=\"%s\"", bandwidth_str);
- if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && output_width)
- avio_printf(s->pb, " width=\"%d\"", stream->codecpar->width);
- if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && output_height)
- avio_printf(s->pb, " height=\"%d\"", stream->codecpar->height);
- if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && output_sample_rate)
- avio_printf(s->pb, " audioSamplingRate=\"%d\"", stream->codecpar->sample_rate);
+ avio_printf(pb, " bandwidth=\"%s\"", bandwidth_str);
+ if (par->codec_type == AVMEDIA_TYPE_VIDEO && output_width)
+ avio_printf(pb, " width=\"%d\"", par->width);
+ if (par->codec_type == AVMEDIA_TYPE_VIDEO && output_height)
+ avio_printf(pb, " height=\"%d\"", par->height);
+ if (par->codec_type == AVMEDIA_TYPE_AUDIO && output_sample_rate)
+ avio_printf(pb, " audioSamplingRate=\"%d\"", par->sample_rate);
if (w->is_live) {
// For live streams, Codec and Mime Type always go in the Representation tag.
- avio_printf(s->pb, " codecs=\"%s\"", get_codec_name(stream->codecpar->codec_id));
- avio_printf(s->pb, " mimeType=\"%s/webm\"",
- stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
+ avio_printf(pb, " codecs=\"%s\"", get_codec_name(par->codec_id));
+ avio_printf(pb, " mimeType=\"%s/webm\"",
+ par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
// For live streams, subsegments always start with key frames. So this
// is always 1.
- avio_printf(s->pb, " startsWithSAP=\"1\"");
- avio_printf(s->pb, ">");
+ avio_printf(pb, " startsWithSAP=\"1\"");
+ avio_printf(pb, ">");
} else {
- avio_printf(s->pb, ">\n");
- avio_printf(s->pb, "<BaseURL>%s</BaseURL>\n", filename->value);
- avio_printf(s->pb, "<SegmentBase\n");
- avio_printf(s->pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);
- avio_printf(s->pb, "<Initialization\n");
- avio_printf(s->pb, " range=\"0-%s\" />\n", irange->value);
- avio_printf(s->pb, "</SegmentBase>\n");
+ AVDictionaryEntry *irange = av_dict_get(st->metadata, INITIALIZATION_RANGE, NULL, 0);
+ AVDictionaryEntry *cues_start = av_dict_get(st->metadata, CUES_START, NULL, 0);
+ AVDictionaryEntry *cues_end = av_dict_get(st->metadata, CUES_END, NULL, 0);
+ AVDictionaryEntry *filename = av_dict_get(st->metadata, FILENAME, NULL, 0);
+ if (!irange || !cues_start || !cues_end || !filename)
+ return AVERROR(EINVAL);
+
+ avio_printf(pb, ">\n");
+ avio_printf(pb, "<BaseURL>%s</BaseURL>\n", filename->value);
+ avio_printf(pb, "<SegmentBase\n");
+ avio_printf(pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);
+ avio_printf(pb, "<Initialization\n");
+ avio_printf(pb, " range=\"0-%s\" />\n", irange->value);
+ avio_printf(pb, "</SegmentBase>\n");
}
- avio_printf(s->pb, "</Representation>\n");
+ avio_printf(pb, "</Representation>\n");
return 0;
}
/*
* Checks if width of all streams are the same. Returns 1 if true, 0 otherwise.
*/
-static int check_matching_width(AVFormatContext *s, AdaptationSet *as) {
+static int check_matching_width(AVFormatContext *s, const AdaptationSet *as)
+{
int first_width, i;
if (as->nb_streams < 2) return 1;
first_width = s->streams[as->streams[0]]->codecpar->width;
@@ -227,7 +237,8 @@ static int check_matching_width(AVFormatContext *s, AdaptationSet *as) {
/*
* Checks if height of all streams are the same. Returns 1 if true, 0 otherwise.
*/
-static int check_matching_height(AVFormatContext *s, AdaptationSet *as) {
+static int check_matching_height(AVFormatContext *s, const AdaptationSet *as)
+{
int first_height, i;
if (as->nb_streams < 2) return 1;
first_height = s->streams[as->streams[0]]->codecpar->height;
@@ -240,7 +251,8 @@ static int check_matching_height(AVFormatContext *s, AdaptationSet *as) {
/*
* Checks if sample rate of all streams are the same. Returns 1 if true, 0 otherwise.
*/
-static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) {
+static int check_matching_sample_rate(AVFormatContext *s, const AdaptationSet *as)
+{
int first_sample_rate, i;
if (as->nb_streams < 2) return 1;
first_sample_rate = s->streams[as->streams[0]]->codecpar->sample_rate;
@@ -250,7 +262,8 @@ static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) {
return 1;
}
-static void free_adaptation_sets(AVFormatContext *s) {
+static void free_adaptation_sets(AVFormatContext *s)
+{
WebMDashMuxContext *w = s->priv_data;
int i;
for (i = 0; i < w->nb_as; i++) {
@@ -261,70 +274,24 @@ static void free_adaptation_sets(AVFormatContext *s) {
}
/*
- * Parses a live header filename and computes the representation id,
- * initialization pattern and the media pattern. Pass NULL if you don't want to
- * compute any of those 3. Returns 0 on success and non-zero on failure.
+ * Parses a live header filename and returns the position of the '_' and '.'
+ * delimiting <file_description> and <representation_id>.
*
* Name of the header file should conform to the following pattern:
* <file_description>_<representation_id>.hdr where <file_description> can be
* anything. The chunks should be named according to the following pattern:
* <file_description>_<representation_id>_<chunk_number>.chk
*/
-static int parse_filename(char *filename, char **representation_id,
- char **initialization_pattern, char **media_pattern) {
- char *underscore_pos = NULL;
- char *period_pos = NULL;
- char *temp_pos = NULL;
- char *filename_str = av_strdup(filename);
- int ret = 0;
-
- if (!filename_str) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- temp_pos = av_stristr(filename_str, "_");
- while (temp_pos) {
- underscore_pos = temp_pos + 1;
- temp_pos = av_stristr(temp_pos + 1, "_");
- }
- if (!underscore_pos) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- period_pos = av_stristr(underscore_pos, ".");
- if (!period_pos) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- *(underscore_pos - 1) = 0;
- if (representation_id) {
- *representation_id = av_malloc(period_pos - underscore_pos + 1);
- if (!(*representation_id)) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- av_strlcpy(*representation_id, underscore_pos, period_pos - underscore_pos + 1);
- }
- if (initialization_pattern) {
- *initialization_pattern = av_asprintf("%s_$RepresentationID$.hdr",
- filename_str);
- if (!(*initialization_pattern)) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- }
- if (media_pattern) {
- *media_pattern = av_asprintf("%s_$RepresentationID$_$Number$.chk",
- filename_str);
- if (!(*media_pattern)) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- }
-
-end:
- av_freep(&filename_str);
- return ret;
+static int split_filename(char *filename, char **underscore_pos,
+ char **period_pos)
+{
+ *underscore_pos = strrchr(filename, '_');
+ if (!*underscore_pos)
+ return AVERROR(EINVAL);
+ *period_pos = strchr(*underscore_pos, '.');
+ if (!*period_pos)
+ return AVERROR(EINVAL);
+ return 0;
}
/*
@@ -334,8 +301,10 @@ static int write_adaptation_set(AVFormatContext *s, int as_index)
{
WebMDashMuxContext *w = s->priv_data;
AdaptationSet *as = &w->as[as_index];
- AVCodecParameters *par = s->streams[as->streams[0]]->codecpar;
+ const AVStream *st = s->streams[as->streams[0]];
+ AVCodecParameters *par = st->codecpar;
AVDictionaryEntry *lang;
+ AVIOContext *pb = s->pb;
int i;
static const char boolean[2][6] = { "false", "true" };
int subsegmentStartsWithSAP = 1;
@@ -346,30 +315,31 @@ static int write_adaptation_set(AVFormatContext *s, int as_index)
// in the Representation tag.
int width_in_as = 1, height_in_as = 1, sample_rate_in_as = 1;
if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
- width_in_as = !w->is_live && check_matching_width(s, as);
+ width_in_as = !w->is_live && check_matching_width (s, as);
height_in_as = !w->is_live && check_matching_height(s, as);
} else {
sample_rate_in_as = !w->is_live && check_matching_sample_rate(s, as);
}
- avio_printf(s->pb, "<AdaptationSet id=\"%s\"", as->id);
- avio_printf(s->pb, " mimeType=\"%s/webm\"",
+ avio_printf(pb, "<AdaptationSet id=\"%s\"", as->id);
+ avio_printf(pb, " mimeType=\"%s/webm\"",
par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
- avio_printf(s->pb, " codecs=\"%s\"", get_codec_name(par->codec_id));
+ avio_printf(pb, " codecs=\"%s\"", get_codec_name(par->codec_id));
- lang = av_dict_get(s->streams[as->streams[0]]->metadata, "language", NULL, 0);
- if (lang) avio_printf(s->pb, " lang=\"%s\"", lang->value);
+ lang = av_dict_get(st->metadata, "language", NULL, 0);
+ if (lang)
+ avio_printf(pb, " lang=\"%s\"", lang->value);
if (par->codec_type == AVMEDIA_TYPE_VIDEO && width_in_as)
- avio_printf(s->pb, " width=\"%d\"", par->width);
+ avio_printf(pb, " width=\"%d\"", par->width);
if (par->codec_type == AVMEDIA_TYPE_VIDEO && height_in_as)
- avio_printf(s->pb, " height=\"%d\"", par->height);
+ avio_printf(pb, " height=\"%d\"", par->height);
if (par->codec_type == AVMEDIA_TYPE_AUDIO && sample_rate_in_as)
- avio_printf(s->pb, " audioSamplingRate=\"%d\"", par->sample_rate);
+ avio_printf(pb, " audioSamplingRate=\"%d\"", par->sample_rate);
- avio_printf(s->pb, " bitstreamSwitching=\"%s\"",
+ avio_printf(pb, " bitstreamSwitching=\"%s\"",
boolean[bitstream_switching(s, as)]);
- avio_printf(s->pb, " subsegmentAlignment=\"%s\"",
+ avio_printf(pb, " subsegmentAlignment=\"%s\"",
boolean[w->is_live || subsegment_alignment(s, as)]);
for (i = 0; i < as->nb_streams; i++) {
@@ -377,66 +347,60 @@ static int write_adaptation_set(AVFormatContext *s, int as_index)
CLUSTER_KEYFRAME, NULL, 0);
if (!w->is_live && (!kf || !strncmp(kf->value, "0", 1))) subsegmentStartsWithSAP = 0;
}
- avio_printf(s->pb, " subsegmentStartsWithSAP=\"%d\"", subsegmentStartsWithSAP);
- avio_printf(s->pb, ">\n");
+ avio_printf(pb, " subsegmentStartsWithSAP=\"%d\"", subsegmentStartsWithSAP);
+ avio_printf(pb, ">\n");
if (w->is_live) {
AVDictionaryEntry *filename =
- av_dict_get(s->streams[as->streams[0]]->metadata, FILENAME, NULL, 0);
- char *initialization_pattern = NULL;
- char *media_pattern = NULL;
- int ret = parse_filename(filename->value, NULL, &initialization_pattern,
- &media_pattern);
+ av_dict_get(st->metadata, FILENAME, NULL, 0);
+ char *underscore_pos, *period_pos;
+ int ret;
+ if (!filename)
+ return AVERROR(EINVAL);
+ ret = split_filename(filename->value, &underscore_pos, &period_pos);
if (ret) return ret;
- avio_printf(s->pb, "<ContentComponent id=\"1\" type=\"%s\"/>\n",
+ *underscore_pos = '\0';
+ avio_printf(pb, "<ContentComponent id=\"1\" type=\"%s\"/>\n",
par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
- avio_printf(s->pb, "<SegmentTemplate");
- avio_printf(s->pb, " timescale=\"1000\"");
- avio_printf(s->pb, " duration=\"%d\"", w->chunk_duration);
- avio_printf(s->pb, " media=\"%s\"", media_pattern);
- avio_printf(s->pb, " startNumber=\"%d\"", w->chunk_start_index);
- avio_printf(s->pb, " initialization=\"%s\"", initialization_pattern);
- avio_printf(s->pb, "/>\n");
- av_free(initialization_pattern);
- av_free(media_pattern);
+ avio_printf(pb, "<SegmentTemplate");
+ avio_printf(pb, " timescale=\"1000\"");
+ avio_printf(pb, " duration=\"%d\"", w->chunk_duration);
+ avio_printf(pb, " media=\"%s_$RepresentationID$_$Number$.chk\"",
+ filename->value);
+ avio_printf(pb, " startNumber=\"%d\"", w->chunk_start_index);
+ avio_printf(pb, " initialization=\"%s_$RepresentationID$.hdr\"",
+ filename->value);
+ avio_printf(pb, "/>\n");
+ *underscore_pos = '_';
}
for (i = 0; i < as->nb_streams; i++) {
- char *representation_id = NULL;
+ char buf[25], *representation_id = buf, *underscore_pos, *period_pos;
+ AVStream *st = s->streams[as->streams[i]];
int ret;
if (w->is_live) {
AVDictionaryEntry *filename =
- av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0);
+ av_dict_get(st->metadata, FILENAME, NULL, 0);
if (!filename)
return AVERROR(EINVAL);
- if (ret = parse_filename(filename->value, &representation_id, NULL, NULL))
+ ret = split_filename(filename->value, &underscore_pos, &period_pos);
+ if (ret < 0)
return ret;
+ representation_id = underscore_pos + 1;
+ *period_pos = '\0';
} else {
- representation_id = av_asprintf("%d", w->representation_id++);
- if (!representation_id) return AVERROR(ENOMEM);
+ snprintf(buf, sizeof(buf), "%d", w->representation_id++);
}
- ret = write_representation(s, s->streams[as->streams[i]],
- representation_id, !width_in_as,
+ ret = write_representation(s, st, representation_id, !width_in_as,
!height_in_as, !sample_rate_in_as);
- av_free(representation_id);
if (ret) return ret;
+ if (w->is_live)
+ *period_pos = '.';
}
avio_printf(s->pb, "</AdaptationSet>\n");
return 0;
}
-static int to_integer(char *p, int len)
-{
- int ret;
- char *q = av_malloc(len);
- if (!q)
- return AVERROR(ENOMEM);
- av_strlcpy(q, p, len);
- ret = atoi(q);
- av_free(q);
- return ret;
-}
-
static int parse_adaptation_sets(AVFormatContext *s)
{
WebMDashMuxContext *w = s->priv_data;
@@ -449,10 +413,16 @@ static int parse_adaptation_sets(AVFormatContext *s)
}
// syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on
state = new_set;
- while (p < w->adaptation_sets + strlen(w->adaptation_sets)) {
- if (*p == ' ')
+ while (1) {
+ if (*p == '\0') {
+ if (state == new_set)
+ break;
+ else
+ return AVERROR(EINVAL);
+ } else if (state == new_set && *p == ' ') {
+ p++;
continue;
- else if (state == new_set && !strncmp(p, "id=", 3)) {
+ } else if (state == new_set && !strncmp(p, "id=", 3)) {
void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1));
const char *comma;
if (mem == NULL)
@@ -477,18 +447,18 @@ static int parse_adaptation_sets(AVFormatContext *s)
state = parsing_streams;
} else if (state == parsing_streams) {
struct AdaptationSet *as = &w->as[w->nb_as - 1];
+ int64_t num;
int ret = av_reallocp_array(&as->streams, ++as->nb_streams,
sizeof(*as->streams));
if (ret < 0)
return ret;
- q = p;
- while (*q != '\0' && *q != ',' && *q != ' ') q++;
- as->streams[as->nb_streams - 1] = to_integer(p, q - p + 1);
- if (as->streams[as->nb_streams - 1] < 0 ||
- as->streams[as->nb_streams - 1] >= s->nb_streams) {
+ num = strtoll(p, &q, 10);
+ if (!av_isdigit(*p) || (*q != ' ' && *q != '\0' && *q != ',') ||
+ num < 0 || num >= s->nb_streams) {
av_log(s, AV_LOG_ERROR, "Invalid value for 'streams' in adapation_sets.\n");
return AVERROR(EINVAL);
}
+ as->streams[as->nb_streams - 1] = num;
if (*q == '\0') break;
if (*q == ' ') state = new_set;
p = ++q;
diff --git a/chromium/third_party/ffmpeg/libavformat/webvttdec.c b/chromium/third_party/ffmpeg/libavformat/webvttdec.c
index 6c4d5f6736e..8d2fdfed37d 100644
--- a/chromium/third_party/ffmpeg/libavformat/webvttdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/webvttdec.c
@@ -125,7 +125,7 @@ static int webvtt_read_header(AVFormatContext *s)
break;
/* optional cue settings */
- p += strcspn(p, "\n\t ");
+ p += strcspn(p, "\n\r\t ");
while (*p == '\t' || *p == ' ')
p++;
settings = p;
@@ -164,6 +164,8 @@ static int webvtt_read_header(AVFormatContext *s)
ff_subtitles_queue_finalize(s, &webvtt->q);
end:
+ if (res < 0)
+ ff_subtitles_queue_clean(&webvtt->q);
av_bprint_finalize(&cue, NULL);
return res;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/wtvenc.c b/chromium/third_party/ffmpeg/libavformat/wtvenc.c
index 498bc640195..b53fdf90487 100644
--- a/chromium/third_party/ffmpeg/libavformat/wtvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/wtvenc.c
@@ -241,7 +241,7 @@ static void put_videoinfoheader2(AVIOContext *pb, AVStream *st)
avio_wl32(pb, 0);
avio_wl32(pb, 0);
- ff_put_bmp_header(pb, st->codecpar, 0, 1);
+ ff_put_bmp_header(pb, st->codecpar, 0, 1, 0);
if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
int padding = (st->codecpar->extradata_size & 3) ? 4 - (st->codecpar->extradata_size & 3) : 0;