summaryrefslogtreecommitdiff
path: root/chromium/third_party/ffmpeg/libavformat
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2013-12-11 21:33:03 +0100
committerAndras Becsi <andras.becsi@digia.com>2013-12-13 12:34:07 +0100
commitf2a33ff9cbc6d19943f1c7fbddd1f23d23975577 (patch)
tree0586a32aa390ade8557dfd6b4897f43a07449578 /chromium/third_party/ffmpeg/libavformat
parent5362912cdb5eea702b68ebe23702468d17c3017a (diff)
downloadqtwebengine-chromium-f2a33ff9cbc6d19943f1c7fbddd1f23d23975577.tar.gz
Update Chromium to branch 1650 (31.0.1650.63)
Change-Id: I57d8c832eaec1eb2364e0a8e7352a6dd354db99f Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat')
-rw-r--r--chromium/third_party/ffmpeg/libavformat/4xm.c259
-rw-r--r--chromium/third_party/ffmpeg/libavformat/Makefile40
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aacdec.c14
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ac3dec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/act.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/adp.c91
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aiff.h1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aiffdec.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/allformats.c12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ape.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apetag.c74
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apetag.h4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/apetagenc.c65
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aqtitledec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asf.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/asfdec.c87
-rw-r--r--chromium/third_party/ffmpeg/libavformat/audiointerleave.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avformat.h99
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avidec.c1060
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avienc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avio.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avio_internal.h26
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aviobuf.c55
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avisynth.c73
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avr.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avs.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/bfi.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/bit.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/boadec.c78
-rw-r--r--chromium/third_party/ffmpeg/libavformat/cafenc.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/cavsvideodec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/cdxl.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/concatdec.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dtsdec.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dv.c173
-rw-r--r--chromium/third_party/ffmpeg/libavformat/electronicarts.c414
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ffmenc.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/file.c26
-rw-r--r--chromium/third_party/ffmpeg/libavformat/file_open.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacdec.c132
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacdec.h31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacdec_picture.c150
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacenc.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flic.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flvdec.c780
-rw-r--r--chromium/third_party/ffmpeg/libavformat/format.c184
-rw-r--r--chromium/third_party/ffmpeg/libavformat/framecrcenc.c20
-rw-r--r--chromium/third_party/ffmpeg/libavformat/ftp.c721
-rw-r--r--chromium/third_party/ffmpeg/libavformat/g723_1.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gif.c27
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gsmdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gxf.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/gxfenc.c58
-rw-r--r--chromium/third_party/ffmpeg/libavformat/h261dec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/h263dec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/h264dec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hls.c79
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsenc.c31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsproto.c14
-rw-r--r--chromium/third_party/ffmpeg/libavformat/http.c134
-rw-r--r--chromium/third_party/ffmpeg/libavformat/id3v2.c330
-rw-r--r--chromium/third_party/ffmpeg/libavformat/id3v2enc.c99
-rw-r--r--chromium/third_party/ffmpeg/libavformat/idcin.c18
-rw-r--r--chromium/third_party/ffmpeg/libavformat/iff.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2dec.c36
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2enc.c19
-rw-r--r--chromium/third_party/ffmpeg/libavformat/internal.h41
-rw-r--r--chromium/third_party/ffmpeg/libavformat/isom.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/isom.h4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/jacosubdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/jvdec.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/latmenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libgme.c201
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libmodplug.c21
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libquvi.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/loasdec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/lvfdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/lxfdec.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/m4vdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroska.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroska.h6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskadec.c310
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskaenc.c468
-rw-r--r--chromium/third_party/ffmpeg/libavformat/md5enc.c71
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mmf.c79
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mmsh.c33
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mov.c171
-rw-r--r--chromium/third_party/ffmpeg/libavformat/movenc.c652
-rw-r--r--chromium/third_party/ffmpeg/libavformat/movenc.h13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/movenchint.c42
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mp3dec.c68
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpc8.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpeg.c8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegenc.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegts.c205
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegtsenc.c25
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegvideodec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpsubdec.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mtv.c10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mux.c124
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxfdec.c12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxfenc.c59
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxg.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/network.c182
-rw-r--r--chromium/third_party/ffmpeg/libavformat/network.h44
-rw-r--r--chromium/third_party/ffmpeg/libavformat/noproxy-test.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nsvdec.c29
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nut.c289
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nut.h5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nutdec.c44
-rw-r--r--chromium/third_party/ffmpeg/libavformat/nutenc.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggdec.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggenc.c11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparseskeleton.c13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c35
-rw-r--r--chromium/third_party/ffmpeg/libavformat/omadec.c265
-rw-r--r--chromium/third_party/ffmpeg/libavformat/options.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/options_table.h8
-rw-r--r--chromium/third_party/ffmpeg/libavformat/os_support.c40
-rw-r--r--chromium/third_party/ffmpeg/libavformat/os_support.h5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/paf.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/pmpdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/psxstr.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/pva.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/r3d.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rawdec.c21
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rawenc.c9
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rdt.c12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/realtextdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/redspark.c167
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.c522
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.h1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riffdec.c247
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riffenc.c312
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rmdec.c26
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rsd.c170
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmp.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmppkt.c116
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmppkt.h11
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmpproto.c163
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtp.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtp.h3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec.h4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_g726.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_h263.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_h263_rfc2190.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg12.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg4.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_mpegts.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpenc.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpenc.h4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpproto.c271
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtpproto.h31
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtsp.c153
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtsp.h15
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtspdec.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtspenc.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sctp.c10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/seek-test.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segafilm.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segment.c51
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sierravmd.c64
-rw-r--r--chromium/third_party/ffmpeg/libavformat/smacker.c12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/spdifdec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/spdifenc.c10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/srtdec.c6
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subviewer1dec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/subviewerdec.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/swf.h3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/swfenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/takdec.c39
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tcp.c100
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tee.c279
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tta.c82
-rw-r--r--chromium/third_party/ffmpeg/libavformat/udp.c98
-rw-r--r--chromium/third_party/ffmpeg/libavformat/unix.c155
-rw-r--r--chromium/third_party/ffmpeg/libavformat/url-test.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/url.c147
-rw-r--r--chromium/third_party/ffmpeg/libavformat/url.h37
-rw-r--r--chromium/third_party/ffmpeg/libavformat/utils.c534
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vc1test.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/version.h10
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vorbiscomment.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/vqf.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/w64.c33
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wavdec.c184
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webvttdec.c69
-rw-r--r--chromium/third_party/ffmpeg/libavformat/webvttenc.c99
-rw-r--r--chromium/third_party/ffmpeg/libavformat/westwood_aud.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/westwood_vqa.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wtv.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wtvdec.c23
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wtvenc.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wv.c387
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wv.h56
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wvdec.c354
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wvenc.c132
-rw-r--r--chromium/third_party/ffmpeg/libavformat/xa.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/yuv4mpeg.c4
206 files changed, 9760 insertions, 4925 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/4xm.c b/chromium/third_party/ffmpeg/libavformat/4xm.c
index 1e142f550f2..3714297dae3 100644
--- a/chromium/third_party/ffmpeg/libavformat/4xm.c
+++ b/chromium/third_party/ffmpeg/libavformat/4xm.c
@@ -57,7 +57,7 @@
#define GET_LIST_HEADER() \
fourcc_tag = avio_rl32(pb); \
- size = avio_rl32(pb); \
+ size = avio_rl32(pb); \
if (fourcc_tag != LIST_TAG) \
return AVERROR_INVALIDDATA; \
fourcc_tag = avio_rl32(pb);
@@ -72,8 +72,6 @@ typedef struct AudioTrack {
} AudioTrack;
typedef struct FourxmDemuxContext {
- int width;
- int height;
int video_stream_index;
int track_count;
AudioTrack *tracks;
@@ -91,6 +89,107 @@ static int fourxm_probe(AVProbeData *p)
return AVPROBE_SCORE_MAX;
}
+static int parse_vtrk(AVFormatContext *s,
+ FourxmDemuxContext *fourxm, uint8_t *buf, int size,
+ int left)
+{
+ AVStream *st;
+ /* check that there is enough data */
+ if (size != vtrk_SIZE || left < size + 8) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* allocate a new AVStream */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ avpriv_set_pts_info(st, 60, 1, fourxm->fps);
+
+ fourxm->video_stream_index = st->index;
+
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_4XM;
+ st->codec->extradata_size = 4;
+ st->codec->extradata = av_malloc(4);
+ AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
+ st->codec->width = AV_RL32(buf + 36);
+ st->codec->height = AV_RL32(buf + 40);
+
+ return 0;
+}
+
+
+static int parse_strk(AVFormatContext *s,
+ FourxmDemuxContext *fourxm, uint8_t *buf, int size,
+ int left)
+{
+ AVStream *st;
+ int track;
+ /* check that there is enough data */
+ if (size != strk_SIZE || left < size + 8)
+ return AVERROR_INVALIDDATA;
+
+ track = AV_RL32(buf + 8);
+ if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
+ av_log(s, AV_LOG_ERROR, "current_track too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (track + 1 > fourxm->track_count) {
+ if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack)))
+ return AVERROR(ENOMEM);
+ memset(&fourxm->tracks[fourxm->track_count], 0,
+ sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
+ fourxm->track_count = track + 1;
+ }
+ fourxm->tracks[track].adpcm = AV_RL32(buf + 12);
+ fourxm->tracks[track].channels = AV_RL32(buf + 36);
+ fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
+ fourxm->tracks[track].bits = AV_RL32(buf + 44);
+ fourxm->tracks[track].audio_pts = 0;
+
+ if (fourxm->tracks[track].channels <= 0 ||
+ fourxm->tracks[track].sample_rate <= 0 ||
+ fourxm->tracks[track].bits < 0) {
+ av_log(s, AV_LOG_ERROR, "audio header invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {
+ av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* allocate a new AVStream */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->id = track;
+ avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
+
+ fourxm->tracks[track].stream_index = st->index;
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_tag = 0;
+ st->codec->channels = fourxm->tracks[track].channels;
+ st->codec->sample_rate = fourxm->tracks[track].sample_rate;
+ st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
+ st->codec->bit_rate = st->codec->channels *
+ st->codec->sample_rate *
+ st->codec->bits_per_coded_sample;
+ st->codec->block_align = st->codec->channels *
+ st->codec->bits_per_coded_sample;
+
+ if (fourxm->tracks[track].adpcm){
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
+ } else if (st->codec->bits_per_coded_sample == 8) {
+ st->codec->codec_id = AV_CODEC_ID_PCM_U8;
+ } else
+ st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+
+ return 0;
+}
+
static int fourxm_read_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
@@ -100,11 +199,10 @@ static int fourxm_read_header(AVFormatContext *s)
FourxmDemuxContext *fourxm = s->priv_data;
unsigned char *header;
int i, ret;
- AVStream *st;
fourxm->track_count = 0;
- fourxm->tracks = NULL;
- fourxm->fps = 1.0;
+ fourxm->tracks = NULL;
+ fourxm->fps = 1.0;
/* skip the first 3 32-bit numbers */
avio_skip(pb, 12);
@@ -119,7 +217,7 @@ static int fourxm_read_header(AVFormatContext *s)
header = av_malloc(header_size);
if (!header)
return AVERROR(ENOMEM);
- if (avio_read(pb, header, header_size) != header_size){
+ if (avio_read(pb, header, header_size) != header_size) {
av_free(header);
return AVERROR(EIO);
}
@@ -127,123 +225,38 @@ static int fourxm_read_header(AVFormatContext *s)
/* take the lazy approach and search for any and all vtrk and strk chunks */
for (i = 0; i < header_size - 8; i++) {
fourcc_tag = AV_RL32(&header[i]);
- size = AV_RL32(&header[i + 4]);
+ size = AV_RL32(&header[i + 4]);
if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
return AVERROR_INVALIDDATA;
}
if (fourcc_tag == std__TAG) {
- if (header_size < i + 16) {
+ if (header_size - i < 16) {
av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
}
fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
} else if (fourcc_tag == vtrk_TAG) {
- /* check that there is enough data */
- if (size != vtrk_SIZE) {
- ret= AVERROR_INVALIDDATA;
+ if ((ret = parse_vtrk(s, fourxm, header + i, size,
+ header_size - i)) < 0)
goto fail;
- }
- fourxm->width = AV_RL32(&header[i + 36]);
- fourxm->height = AV_RL32(&header[i + 40]);
-
- /* allocate a new AVStream */
- st = avformat_new_stream(s, NULL);
- if (!st){
- ret= AVERROR(ENOMEM);
- goto fail;
- }
- avpriv_set_pts_info(st, 60, 1, fourxm->fps);
-
- fourxm->video_stream_index = st->index;
-
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_4XM;
- st->codec->extradata_size = 4;
- st->codec->extradata = av_malloc(4);
- AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
- st->codec->width = fourxm->width;
- st->codec->height = fourxm->height;
i += 8 + size;
} else if (fourcc_tag == strk_TAG) {
- int current_track;
- /* check that there is enough data */
- if (size != strk_SIZE) {
- ret= AVERROR_INVALIDDATA;
- goto fail;
- }
- current_track = AV_RL32(&header[i + 8]);
- if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
- av_log(s, AV_LOG_ERROR, "current_track too large\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- if (current_track + 1 > fourxm->track_count) {
- fourxm->tracks = av_realloc_f(fourxm->tracks,
- sizeof(AudioTrack),
- current_track + 1);
- if (!fourxm->tracks) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- memset(&fourxm->tracks[fourxm->track_count], 0,
- sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
- fourxm->track_count = current_track + 1;
- }
- fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
- fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
- fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
- fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
- fourxm->tracks[current_track].audio_pts = 0;
- if( fourxm->tracks[current_track].channels <= 0
- || fourxm->tracks[current_track].sample_rate <= 0
- || fourxm->tracks[current_track].bits < 0){
- av_log(s, AV_LOG_ERROR, "audio header invalid\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
- av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
- ret = AVERROR_INVALIDDATA;
+ if ((ret = parse_strk(s, fourxm, header + i, size,
+ header_size - i)) < 0)
goto fail;
- }
- i += 8 + size;
- /* allocate a new AVStream */
- st = avformat_new_stream(s, NULL);
- if (!st){
- ret= AVERROR(ENOMEM);
- goto fail;
- }
-
- st->id = current_track;
- avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
-
- fourxm->tracks[current_track].stream_index = st->index;
-
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_tag = 0;
- st->codec->channels = fourxm->tracks[current_track].channels;
- st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;
- st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
- st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
- st->codec->bits_per_coded_sample;
- st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
- if (fourxm->tracks[current_track].adpcm){
- st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
- }else if (st->codec->bits_per_coded_sample == 8){
- st->codec->codec_id = AV_CODEC_ID_PCM_U8;
- }else
- st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+ i += 8 + size;
}
}
/* skip over the LIST-MOVI chunk (which is where the stream should be */
GET_LIST_HEADER();
- if (fourcc_tag != MOVI_TAG){
- ret= AVERROR_INVALIDDATA;
+ if (fourcc_tag != MOVI_TAG) {
+ ret = AVERROR_INVALIDDATA;
goto fail;
}
@@ -262,7 +275,7 @@ static int fourxm_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
FourxmDemuxContext *fourxm = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
unsigned int fourcc_tag;
unsigned int size;
int ret = 0;
@@ -272,18 +285,16 @@ static int fourxm_read_packet(AVFormatContext *s,
int audio_frame_count;
while (!packet_read) {
-
if ((ret = avio_read(s->pb, header, 8)) < 0)
return ret;
fourcc_tag = AV_RL32(&header[0]);
- size = AV_RL32(&header[4]);
+ size = AV_RL32(&header[4]);
if (url_feof(pb))
return AVERROR(EIO);
switch (fourcc_tag) {
-
case LIST_TAG:
/* this is a good time to bump the video pts */
- fourxm->video_pts ++;
+ fourxm->video_pts++;
/* skip the LIST-* tag and move on to the next fourcc */
avio_rl32(pb);
@@ -300,45 +311,43 @@ static int fourxm_read_packet(AVFormatContext *s,
if (size + 8 < size || av_new_packet(pkt, size + 8))
return AVERROR(EIO);
pkt->stream_index = fourxm->video_stream_index;
- pkt->pts = fourxm->video_pts;
- pkt->pos = avio_tell(s->pb);
+ pkt->pts = fourxm->video_pts;
+ pkt->pos = avio_tell(s->pb);
memcpy(pkt->data, header, 8);
ret = avio_read(s->pb, &pkt->data[8], size);
- if (ret < 0){
+ if (ret < 0) {
av_free_packet(pkt);
- }else
+ } else
packet_read = 1;
break;
case snd__TAG:
track_number = avio_rl32(pb);
avio_skip(pb, 4);
- size-=8;
+ size -= 8;
- if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
- ret= av_get_packet(s->pb, pkt, size);
- if(ret<0)
+ if (track_number < fourxm->track_count &&
+ fourxm->tracks[track_number].channels > 0) {
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < 0)
return AVERROR(EIO);
pkt->stream_index =
fourxm->tracks[track_number].stream_index;
- pkt->pts = fourxm->tracks[track_number].audio_pts;
+ pkt->pts = fourxm->tracks[track_number].audio_pts;
packet_read = 1;
/* pts accounting */
audio_frame_count = size;
if (fourxm->tracks[track_number].adpcm)
- audio_frame_count -=
- 2 * (fourxm->tracks[track_number].channels);
- audio_frame_count /=
- fourxm->tracks[track_number].channels;
- if (fourxm->tracks[track_number].adpcm){
+ audio_frame_count -= 2 * (fourxm->tracks[track_number].channels);
+ audio_frame_count /= fourxm->tracks[track_number].channels;
+ if (fourxm->tracks[track_number].adpcm) {
audio_frame_count *= 2;
- }else
+ } else
audio_frame_count /=
- (fourxm->tracks[track_number].bits / 8);
+ (fourxm->tracks[track_number].bits / 8);
fourxm->tracks[track_number].audio_pts += audio_frame_count;
-
} else {
avio_skip(pb, size);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/Makefile b/chromium/third_party/ffmpeg/libavformat/Makefile
index 470e7f34e84..35d49f73024 100644
--- a/chromium/third_party/ffmpeg/libavformat/Makefile
+++ b/chromium/third_party/ffmpeg/libavformat/Makefile
@@ -11,6 +11,7 @@ OBJS = allformats.o \
avio.o \
aviobuf.o \
cutils.o \
+ format.o \
id3v1.o \
id3v2.o \
metadata.o \
@@ -20,9 +21,14 @@ OBJS = allformats.o \
riff.o \
sdp.o \
seek.o \
+ url.o \
utils.o \
+OBJS-$(HAVE_MSVCRT) += file_open.o
+
OBJS-$(CONFIG_NETWORK) += network.o
+OBJS-$(CONFIG_RIFFDEC) += riffdec.o
+OBJS-$(CONFIG_RIFFENC) += riffenc.o
OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtp.o \
rtpdec.o \
@@ -50,11 +56,12 @@ OBJS-$(CONFIG_SHARED) += log2_tab.o
# muxers/demuxers
OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o
-OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o rawdec.o
+OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o
OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o
OBJS-$(CONFIG_AC3_MUXER) += rawenc.o
OBJS-$(CONFIG_ACT_DEMUXER) += act.o
OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o
+OBJS-$(CONFIG_ADP_DEMUXER) += adp.o
OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o
OBJS-$(CONFIG_ADX_MUXER) += rawenc.o
OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
@@ -91,6 +98,7 @@ OBJS-$(CONFIG_BINTEXT_DEMUXER) += bintext.o sauce.o
OBJS-$(CONFIG_BIT_DEMUXER) += bit.o
OBJS-$(CONFIG_BIT_MUXER) += bit.o
OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o
+OBJS-$(CONFIG_BOA_DEMUXER) += boadec.o
OBJS-$(CONFIG_BRSTM_DEMUXER) += brstm.o
OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o
OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \
@@ -102,6 +110,8 @@ OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o
OBJS-$(CONFIG_CDXL_DEMUXER) += cdxl.o
OBJS-$(CONFIG_CONCAT_DEMUXER) += concatdec.o
OBJS-$(CONFIG_CRC_MUXER) += crcenc.o
+OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o
+OBJS-$(CONFIG_DATA_MUXER) += rawdec.o
OBJS-$(CONFIG_DAUD_DEMUXER) += daud.o
OBJS-$(CONFIG_DAUD_MUXER) += daud.o
OBJS-$(CONFIG_DFA_DEMUXER) += dfa.o
@@ -128,6 +138,7 @@ OBJS-$(CONFIG_FFMETADATA_MUXER) += ffmetaenc.o
OBJS-$(CONFIG_FILMSTRIP_DEMUXER) += filmstripdec.o
OBJS-$(CONFIG_FILMSTRIP_MUXER) += filmstripenc.o
OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o rawdec.o \
+ flacdec_picture.o \
oggparsevorbis.o \
vorbiscomment.o
OBJS-$(CONFIG_FLAC_MUXER) += flacenc.o flacenc_header.o \
@@ -156,7 +167,7 @@ OBJS-$(CONFIG_H263_MUXER) += rawenc.o
OBJS-$(CONFIG_H264_DEMUXER) += h264dec.o rawdec.o
OBJS-$(CONFIG_H264_MUXER) += rawenc.o
OBJS-$(CONFIG_HLS_DEMUXER) += hls.o
-OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o mpegtsenc.o
+OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o
OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o
OBJS-$(CONFIG_ICO_MUXER) += icoenc.o
OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o
@@ -191,7 +202,7 @@ OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \
isom.o rmsipr.o
OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \
isom.o avc.o \
- flacenc_header.o avlanguage.o
+ flacenc_header.o avlanguage.o wv.o
OBJS-$(CONFIG_MD5_MUXER) += md5enc.o
OBJS-$(CONFIG_MGSTS_DEMUXER) += mgsts.o
OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o subtitles.o
@@ -249,7 +260,8 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
oggparsespeex.o \
oggparsetheora.o \
oggparsevorbis.o \
- vorbiscomment.o
+ vorbiscomment.o \
+ flacdec_picture.o
OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \
vorbiscomment.o
OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o oma.o
@@ -304,11 +316,13 @@ OBJS-$(CONFIG_R3D_DEMUXER) += r3d.o
OBJS-$(CONFIG_RAWVIDEO_DEMUXER) += rawvideodec.o
OBJS-$(CONFIG_RAWVIDEO_MUXER) += rawenc.o
OBJS-$(CONFIG_REALTEXT_DEMUXER) += realtextdec.o subtitles.o
+OBJS-$(CONFIG_REDSPARK_DEMUXER) += redspark.o
OBJS-$(CONFIG_RL2_DEMUXER) += rl2.o
OBJS-$(CONFIG_RM_DEMUXER) += rmdec.o rm.o rmsipr.o
OBJS-$(CONFIG_RM_MUXER) += rmenc.o rm.o
OBJS-$(CONFIG_ROQ_DEMUXER) += idroqdec.o
OBJS-$(CONFIG_ROQ_MUXER) += idroqenc.o rawenc.o
+OBJS-$(CONFIG_RSD_DEMUXER) += rsd.o
OBJS-$(CONFIG_RSO_DEMUXER) += rsodec.o rso.o pcm.o
OBJS-$(CONFIG_RSO_MUXER) += rsoenc.o rso.o
OBJS-$(CONFIG_RPL_DEMUXER) += rpl.o
@@ -364,10 +378,11 @@ OBJS-$(CONFIG_MKVTIMESTAMP_V2_MUXER) += mkvtimestamp_v2.o
OBJS-$(CONFIG_TMV_DEMUXER) += tmv.o
OBJS-$(CONFIG_TRUEHD_DEMUXER) += rawdec.o
OBJS-$(CONFIG_TRUEHD_MUXER) += rawenc.o
-OBJS-$(CONFIG_TTA_DEMUXER) += tta.o
+OBJS-$(CONFIG_TTA_DEMUXER) += tta.o apetag.o img2.o
OBJS-$(CONFIG_TTY_DEMUXER) += tty.o sauce.o
OBJS-$(CONFIG_TXD_DEMUXER) += txd.o
OBJS-$(CONFIG_VC1_DEMUXER) += rawdec.o
+OBJS-$(CONFIG_VC1_MUXER) += rawenc.o
OBJS-$(CONFIG_VC1T_DEMUXER) += vc1test.o
OBJS-$(CONFIG_VC1T_MUXER) += vc1testenc.o
OBJS-$(CONFIG_VIVO_DEMUXER) += vivo.o
@@ -384,15 +399,16 @@ OBJS-$(CONFIG_WAV_MUXER) += wavenc.o
OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o
OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \
isom.o avc.o \
- flacenc_header.o avlanguage.o
+ flacenc_header.o avlanguage.o wv.o
OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o
+OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o
OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o
OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \
avlanguage.o mpegts.o isom.o
OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o
-OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o img2.o
-OBJS-$(CONFIG_WV_MUXER) += wvenc.o apetagenc.o
+OBJS-$(CONFIG_WV_DEMUXER) += wvdec.o wv.o apetag.o img2.o
+OBJS-$(CONFIG_WV_MUXER) += wvenc.o wv.o apetag.o img2.o
OBJS-$(CONFIG_XA_DEMUXER) += xa.o
OBJS-$(CONFIG_XBIN_DEMUXER) += bintext.o sauce.o
OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o
@@ -402,6 +418,7 @@ OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o
OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o
# external libraries
+OBJS-$(CONFIG_LIBGME_DEMUXER) += libgme.o
OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o
OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o
OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o
@@ -418,6 +435,7 @@ OBJS-$(CONFIG_DATA_PROTOCOL) += data_uri.o
OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpcrypt.o rtmpdh.o
OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL) += rtmphttp.o
OBJS-$(CONFIG_FILE_PROTOCOL) += file.o
+OBJS-$(CONFIG_FTP_PROTOCOL) += ftp.o
OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o
OBJS-$(CONFIG_HLS_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o urldecode.o
@@ -439,14 +457,16 @@ OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o
OBJS-$(CONFIG_TLS_PROTOCOL) += tls.o
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
+OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o
SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h
-TESTPROGS = noproxy \
- seek \
+TESTPROGS = seek \
srtp \
url \
+TESTPROGS-$(CONFIG_NETWORK) += noproxy
+
TOOLS = aviocat \
ismindex \
pktdumper \
diff --git a/chromium/third_party/ffmpeg/libavformat/aacdec.c b/chromium/third_party/ffmpeg/libavformat/aacdec.c
index 7c17dd05fa6..d93e75ec52c 100644
--- a/chromium/third_party/ffmpeg/libavformat/aacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aacdec.c
@@ -25,7 +25,7 @@
#include "internal.h"
#include "rawdec.h"
#include "id3v1.h"
-
+#include "apetag.h"
static int adts_aac_probe(AVProbeData *p)
{
@@ -55,9 +55,9 @@ static int adts_aac_probe(AVProbeData *p)
if(buf == buf0)
first_frames= frames;
}
- if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
- else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
- else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+ if (first_frames>=3) return AVPROBE_SCORE_EXTENSION + 1;
+ else if(max_frames>500)return AVPROBE_SCORE_EXTENSION;
+ else if(max_frames>=3) return AVPROBE_SCORE_EXTENSION / 2;
else if(max_frames>=1) return 1;
else return 0;
}
@@ -75,6 +75,12 @@ static int adts_aac_read_header(AVFormatContext *s)
st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
ff_id3v1_read(s);
+ if (s->pb->seekable &&
+ !av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
+ int64_t cur = avio_tell(s->pb);
+ ff_ape_parse_tag(s);
+ avio_seek(s->pb, cur, SEEK_SET);
+ }
//LCM of all possible ADTS sample rates
avpriv_set_pts_info(st, 64, 1, 28224000);
diff --git a/chromium/third_party/ffmpeg/libavformat/ac3dec.c b/chromium/third_party/ffmpeg/libavformat/ac3dec.c
index c531f8a179e..3db23397d0d 100644
--- a/chromium/third_party/ffmpeg/libavformat/ac3dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/ac3dec.c
@@ -79,9 +79,9 @@ static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)
if(codec_id != expected_codec_id) return 0;
// keep this in sync with mp3 probe, both need to avoid
// issues with MPEG-files!
- if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
- else if(max_frames>200)return AVPROBE_SCORE_MAX/2;
- else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
+ if (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1;
+ else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
+ else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION/2;
else if(max_frames>=1) return 1;
else return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/act.c b/chromium/third_party/ffmpeg/libavformat/act.c
index 78f1d3bb9a6..3f223d57b6a 100644
--- a/chromium/third_party/ffmpeg/libavformat/act.c
+++ b/chromium/third_party/ffmpeg/libavformat/act.c
@@ -42,7 +42,7 @@ static int probe(AVProbeData *p)
(AV_RL32(&p->buf[16]) != 16))
return 0;
- //We cant be sure that this is ACT and not regular WAV
+ //We can't be sure that this is ACT and not regular WAV
if (p->buf_size<512)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/adp.c b/chromium/third_party/ffmpeg/libavformat/adp.c
new file mode 100644
index 00000000000..c5feac4fa5b
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/adp.c
@@ -0,0 +1,91 @@
+/*
+ * ADP demuxer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+
+static int adp_probe(AVProbeData *p)
+{
+ int i;
+
+ if (p->buf_size < 32)
+ return 0;
+
+ for (i = 0; i < p->buf_size - 3; i+=32)
+ if (p->buf[i] != p->buf[i+2] || p->buf[i+1] != p->buf[i+3])
+ return 0;
+
+ return p->buf_size < 260 ? 1 : AVPROBE_SCORE_MAX / 4;
+}
+
+static int adp_read_header(AVFormatContext *s)
+{
+ AVStream *st;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_DTK;
+ st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+ st->codec->channels = 2;
+ st->codec->sample_rate = 48000;
+ st->start_time = 0;
+ if (s->pb->seekable)
+ st->duration = av_get_audio_frame_duration(st->codec, avio_size(s->pb));
+
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+ return 0;
+}
+
+static int adp_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret, size = 1024;
+
+ if (url_feof(s->pb))
+ return AVERROR_EOF;
+
+ ret = av_get_packet(s->pb, pkt, size);
+
+ if (ret != size) {
+ if (ret < 0) {
+ av_free_packet(pkt);
+ return ret;
+ }
+ av_shrink_packet(pkt, ret);
+ }
+ pkt->stream_index = 0;
+
+ return ret;
+}
+
+AVInputFormat ff_adp_demuxer = {
+ .name = "adp",
+ .long_name = NULL_IF_CONFIG_SMALL("ADP"),
+ .read_probe = adp_probe,
+ .read_header = adp_read_header,
+ .read_packet = adp_read_packet,
+ .extensions = "adp,dtk",
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/aiff.h b/chromium/third_party/ffmpeg/libavformat/aiff.h
index b3ef577ff36..c13bcc065da 100644
--- a/chromium/third_party/ffmpeg/libavformat/aiff.h
+++ b/chromium/third_party/ffmpeg/libavformat/aiff.h
@@ -45,6 +45,7 @@ static const AVCodecTag ff_codec_aiff_tags[] = {
{ AV_CODEC_ID_MACE3, MKTAG('M','A','C','3') },
{ AV_CODEC_ID_MACE6, MKTAG('M','A','C','6') },
{ AV_CODEC_ID_GSM, MKTAG('G','S','M',' ') },
+ { AV_CODEC_ID_ADPCM_G722, MKTAG('G','7','2','2') },
{ AV_CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') },
{ AV_CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') },
{ AV_CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') },
diff --git a/chromium/third_party/ffmpeg/libavformat/aiffdec.c b/chromium/third_party/ffmpeg/libavformat/aiffdec.c
index 62af3dca7b7..851091e5cbf 100644
--- a/chromium/third_party/ffmpeg/libavformat/aiffdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aiffdec.c
@@ -141,6 +141,7 @@ static unsigned int get_aiff_header(AVFormatContext *s, int size,
case AV_CODEC_ID_MACE3:
codec->block_align = 2*codec->channels;
break;
+ case AV_CODEC_ID_ADPCM_G722:
case AV_CODEC_ID_MACE6:
codec->block_align = 1*codec->channels;
break;
diff --git a/chromium/third_party/ffmpeg/libavformat/allformats.c b/chromium/third_party/ffmpeg/libavformat/allformats.c
index 80c53f6c6e9..b3b2a3bba53 100644
--- a/chromium/third_party/ffmpeg/libavformat/allformats.c
+++ b/chromium/third_party/ffmpeg/libavformat/allformats.c
@@ -65,6 +65,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX(AC3, ac3);
REGISTER_DEMUXER (ACT, act);
REGISTER_DEMUXER (ADF, adf);
+ REGISTER_DEMUXER (ADP, adp);
REGISTER_MUXER (ADTS, adts);
REGISTER_MUXDEMUX(ADX, adx);
REGISTER_DEMUXER (AEA, aea);
@@ -92,6 +93,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX(BIT, bit);
REGISTER_DEMUXER (BMV, bmv);
REGISTER_DEMUXER (BRSTM, brstm);
+ REGISTER_DEMUXER (BOA, boa);
REGISTER_DEMUXER (C93, c93);
REGISTER_MUXDEMUX(CAF, caf);
REGISTER_MUXDEMUX(CAVSVIDEO, cavsvideo);
@@ -99,6 +101,7 @@ void av_register_all(void)
REGISTER_DEMUXER (CDXL, cdxl);
REGISTER_DEMUXER (CONCAT, concat);
REGISTER_MUXER (CRC, crc);
+ REGISTER_MUXDEMUX(DATA, data);
REGISTER_MUXDEMUX(DAUD, daud);
REGISTER_DEMUXER (DFA, dfa);
REGISTER_MUXDEMUX(DIRAC, dirac);
@@ -230,10 +233,12 @@ void av_register_all(void)
REGISTER_DEMUXER (R3D, r3d);
REGISTER_MUXDEMUX(RAWVIDEO, rawvideo);
REGISTER_DEMUXER (REALTEXT, realtext);
+ REGISTER_DEMUXER (REDSPARK, redspark);
REGISTER_DEMUXER (RL2, rl2);
REGISTER_MUXDEMUX(RM, rm);
REGISTER_MUXDEMUX(ROQ, roq);
REGISTER_DEMUXER (RPL, rpl);
+ REGISTER_DEMUXER (RSD, rsd);
REGISTER_MUXDEMUX(RSO, rso);
REGISTER_MUXDEMUX(RTP, rtp);
REGISTER_MUXDEMUX(RTSP, rtsp);
@@ -263,7 +268,7 @@ void av_register_all(void)
REGISTER_DEMUXER (SUBVIEWER, subviewer);
REGISTER_MUXDEMUX(SWF, swf);
REGISTER_DEMUXER (TAK, tak);
- REGISTER_MUXER (TEE, tee);
+ REGISTER_MUXER (TEE, tee);
REGISTER_DEMUXER (TEDCAPTIONS, tedcaptions);
REGISTER_MUXER (TG2, tg2);
REGISTER_MUXER (TGP, tgp);
@@ -287,7 +292,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX(WAV, wav);
REGISTER_DEMUXER (WC3, wc3);
REGISTER_MUXER (WEBM, webm);
- REGISTER_DEMUXER (WEBVTT, webvtt);
+ REGISTER_MUXDEMUX(WEBVTT, webvtt);
REGISTER_DEMUXER (WSAUD, wsaud);
REGISTER_DEMUXER (WSVQA, wsvqa);
REGISTER_MUXDEMUX(WTV, wtv);
@@ -308,6 +313,7 @@ void av_register_all(void)
REGISTER_PROTOCOL(FFRTMPCRYPT, ffrtmpcrypt);
REGISTER_PROTOCOL(FFRTMPHTTP, ffrtmphttp);
REGISTER_PROTOCOL(FILE, file);
+ REGISTER_PROTOCOL(FTP, ftp);
REGISTER_PROTOCOL(GOPHER, gopher);
REGISTER_PROTOCOL(HLS, hls);
REGISTER_PROTOCOL(HTTP, http);
@@ -329,8 +335,10 @@ void av_register_all(void)
REGISTER_PROTOCOL(TCP, tcp);
REGISTER_PROTOCOL(TLS, tls);
REGISTER_PROTOCOL(UDP, udp);
+ REGISTER_PROTOCOL(UNIX, unix);
/* external libraries */
+ REGISTER_DEMUXER (LIBGME, libgme);
REGISTER_DEMUXER (LIBMODPLUG, libmodplug);
REGISTER_MUXDEMUX(LIBNUT, libnut);
REGISTER_DEMUXER (LIBQUVI, libquvi);
diff --git a/chromium/third_party/ffmpeg/libavformat/ape.c b/chromium/third_party/ffmpeg/libavformat/ape.c
index e2b8adae864..bb61a2498dd 100644
--- a/chromium/third_party/ffmpeg/libavformat/ape.c
+++ b/chromium/third_party/ffmpeg/libavformat/ape.c
@@ -414,6 +414,8 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt)
AV_WL32(pkt->data , nblocks);
AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip);
ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size);
+ if (ret < 0)
+ return ret;
pkt->pts = ape->frames[ape->currentframe].pts;
pkt->stream_index = 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/apetag.c b/chromium/third_party/ffmpeg/libavformat/apetag.c
index a445c84aef3..ab937367183 100644
--- a/chromium/third_party/ffmpeg/libavformat/apetag.c
+++ b/chromium/third_party/ffmpeg/libavformat/apetag.c
@@ -23,10 +23,12 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "apetag.h"
#include "internal.h"
#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31)
+#define APE_TAG_FLAG_CONTAINS_FOOTER (1 << 30)
#define APE_TAG_FLAG_IS_HEADER (1 << 29)
#define APE_TAG_FLAG_IS_BINARY (1 << 1)
@@ -114,7 +116,7 @@ static int ape_tag_read_field(AVFormatContext *s)
int64_t ff_ape_parse_tag(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
- int file_size = avio_size(pb);
+ int64_t file_size = avio_size(pb);
uint32_t val, fields, tag_bytes;
uint8_t buf[8];
int64_t tag_start;
@@ -167,3 +169,73 @@ int64_t ff_ape_parse_tag(AVFormatContext *s)
return tag_start;
}
+
+static int string_is_ascii(const uint8_t *str)
+{
+ while (*str && *str >= 0x20 && *str <= 0x7e ) str++;
+ return !*str;
+}
+
+int ff_ape_write_tag(AVFormatContext *s)
+{
+ AVDictionaryEntry *e = NULL;
+ int size, ret, count = 0;
+ AVIOContext *dyn_bc = NULL;
+ uint8_t *dyn_buf = NULL;
+
+ if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
+ goto end;
+
+ // flags
+ avio_wl32(dyn_bc, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |
+ APE_TAG_FLAG_IS_HEADER);
+ ffio_fill(dyn_bc, 0, 8); // reserved
+
+ while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
+ int val_len;
+
+ if (!string_is_ascii(e->key)) {
+ av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
+ continue;
+ }
+
+ val_len = strlen(e->value);
+ avio_wl32(dyn_bc, val_len); // value length
+ avio_wl32(dyn_bc, 0); // item flags
+ avio_put_str(dyn_bc, e->key); // key
+ avio_write(dyn_bc, e->value, val_len); // value
+ count++;
+ }
+ if (!count)
+ goto end;
+
+ size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
+ if (size <= 0)
+ goto end;
+ size += 20;
+
+ // header
+ avio_write(s->pb, "APETAGEX", 8); // id
+ avio_wl32(s->pb, APE_TAG_VERSION); // version
+ avio_wl32(s->pb, size);
+ avio_wl32(s->pb, count);
+
+ avio_write(s->pb, dyn_buf, size - 20);
+
+ // footer
+ avio_write(s->pb, "APETAGEX", 8); // id
+ avio_wl32(s->pb, APE_TAG_VERSION); // version
+ avio_wl32(s->pb, size); // size
+ avio_wl32(s->pb, count); // tag count
+
+ // flags
+ avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);
+ ffio_fill(s->pb, 0, 8); // reserved
+
+end:
+ if (dyn_bc && !dyn_buf)
+ avio_close_dyn_buf(dyn_bc, &dyn_buf);
+ av_freep(&dyn_buf);
+
+ return ret;
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/apetag.h b/chromium/third_party/ffmpeg/libavformat/apetag.h
index 0330c8986ae..cf2a5f8ab48 100644
--- a/chromium/third_party/ffmpeg/libavformat/apetag.h
+++ b/chromium/third_party/ffmpeg/libavformat/apetag.h
@@ -37,8 +37,8 @@
int64_t ff_ape_parse_tag(AVFormatContext *s);
/**
- * Write an APEv2 tag
+ * Write an APE tag into a file.
*/
-void ff_ape_write(AVFormatContext *s);
+int ff_ape_write_tag(AVFormatContext *s);
#endif /* AVFORMAT_APETAG_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/apetagenc.c b/chromium/third_party/ffmpeg/libavformat/apetagenc.c
deleted file mode 100644
index 42f58362a6b..00000000000
--- a/chromium/third_party/ffmpeg/libavformat/apetagenc.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * APE tag writer
- * Copyright (c) 2012 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 "libavutil/dict.h"
-#include "avio_internal.h"
-#include "avformat.h"
-#include "apetag.h"
-
-static int string_is_ascii(const uint8_t *str)
-{
- while (*str && *str >= 0x20 && *str <= 0x7e ) str++;
- return !*str;
-}
-
-void ff_ape_write(AVFormatContext *s)
-{
- int64_t tag_bytes;
- AVDictionaryEntry *t = NULL;
- AVIOContext *pb = s->pb;
- int tags = 0, vlen;
-
- tag_bytes = avio_tell(s->pb);
- while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
- if (!string_is_ascii(t->key)) {
- av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
- continue;
- }
-
- vlen = strlen(t->value);
- avio_wl32(pb, vlen + 1);
- avio_wl32(pb, 0); // flags
- avio_put_str(pb, t->key);
- avio_put_str(pb, t->value);
- tags++;
- }
- tag_bytes = avio_tell(s->pb) - tag_bytes;
-
- if (!tags)
- return;
-
- avio_write(pb, APE_TAG_PREAMBLE, 8);
- avio_wl32(pb, APE_TAG_VERSION);
- avio_wl32(pb, tag_bytes + APE_TAG_FOOTER_BYTES);
- avio_wl32(pb, tags); // item count
- avio_wl32(pb, 0); // global flags
- ffio_fill(pb, 0, 8); // reserved
-}
diff --git a/chromium/third_party/ffmpeg/libavformat/aqtitledec.c b/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
index a78fd814d7f..810f95b4935 100644
--- a/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aqtitledec.c
@@ -43,7 +43,7 @@ static int aqt_probe(AVProbeData *p)
const char *ptr = p->buf;
if (sscanf(ptr, "-->> %d", &frame) == 1)
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/asf.h b/chromium/third_party/ffmpeg/libavformat/asf.h
index 5ffc7465a86..30d6c1e4884 100644
--- a/chromium/third_party/ffmpeg/libavformat/asf.h
+++ b/chromium/third_party/ffmpeg/libavformat/asf.h
@@ -39,8 +39,10 @@ typedef struct ASFStream {
/* use for reading */
AVPacket pkt;
int frag_offset;
+ int packet_obj_size;
int timestamp;
int64_t duration;
+ int skip_to_key;
int ds_span; /* descrambling */
int ds_packet_size;
diff --git a/chromium/third_party/ffmpeg/libavformat/asfdec.c b/chromium/third_party/ffmpeg/libavformat/asfdec.c
index 1d7f26cefe8..0d6370dc9ab 100644
--- a/chromium/third_party/ffmpeg/libavformat/asfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/asfdec.c
@@ -19,14 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define DEBUG
-
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
#include "libavutil/common.h"
#include "libavutil/dict.h"
+#include "libavutil/internal.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "avformat.h"
@@ -69,7 +68,6 @@ typedef struct {
unsigned int packet_frag_size;
int64_t packet_frag_timestamp;
int packet_multi_size;
- int packet_obj_size;
int packet_time_delta;
int packet_time_start;
int64_t packet_pos;
@@ -368,14 +366,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
if (!st)
return AVERROR(ENOMEM);
avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
- asf_st = av_mallocz(sizeof(ASFStream));
- if (!asf_st)
- return AVERROR(ENOMEM);
- st->priv_data = asf_st;
start_time = asf->hdr.preroll;
- asf_st->stream_language_index = 128; // invalid stream index means no language info
-
if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
int64_t fsize = avio_size(pb);
if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || FFABS(fsize - (int64_t)asf->hdr.file_size) < 10000)
@@ -407,6 +399,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
st->id = avio_rl16(pb) & 0x7f; /* stream id */
// mapping of asf ID to AV stream ID;
asf->asfid2avid[st->id] = s->nb_streams - 1;
+ asf_st = &asf->streams[st->id];
avio_rl32(pb);
@@ -731,6 +724,10 @@ static int asf_read_header(AVFormatContext *s)
avio_r8(pb);
avio_r8(pb);
memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
+
+ for (i = 0; i<128; i++)
+ asf->streams[i].stream_language_index = 128; // invalid stream index means no language info
+
for (;;) {
uint64_t gpos = avio_tell(pb);
ff_get_guid(pb, &g);
@@ -883,7 +880,7 @@ static int asf_read_header(AVFormatContext *s)
* @param pb context to read data from
* @return 0 on success, <0 on error
*/
-static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
+static int asf_get_packet(AVFormatContext *s, AVIOContext *pb)
{
ASFContext *asf = s->priv_data;
uint32_t packet_length, padsize;
@@ -1009,10 +1006,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
if (asf->packet_replic_size >= 8) {
int64_t end = avio_tell(pb) + asf->packet_replic_size;
AVRational aspect;
- asf->packet_obj_size = avio_rl32(pb);
- if (asf->packet_obj_size >= (1 << 24) || asf->packet_obj_size <= 0) {
+ asfst->packet_obj_size = avio_rl32(pb);
+ if (asfst->packet_obj_size >= (1 << 24) || asfst->packet_obj_size <= 0) {
av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
- asf->packet_obj_size = 0;
+ asfst->packet_obj_size = 0;
return AVERROR_INVALIDDATA;
}
asf->packet_frag_timestamp = avio_rl32(pb); // timestamp
@@ -1110,7 +1107,7 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
* @return 0 if data was stored in pkt, <0 on error or 1 if more ASF
* packets need to be loaded (through asf_get_packet())
*/
-static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
+static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
{
ASFContext *asf = s->priv_data;
ASFStream *asf_st = 0;
@@ -1141,7 +1138,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
if (asf->stream_index < 0 ||
s->streams[asf->stream_index]->discard >= AVDISCARD_ALL ||
(!asf->packet_key_frame &&
- s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)) {
+ (s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY || asf->streams[s->streams[asf->stream_index]->id].skip_to_key))) {
asf->packet_time_start = 0;
/* unhandled packet (should not happen) */
avio_skip(pb, asf->packet_frag_size);
@@ -1151,7 +1148,8 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
asf->packet_frag_size);
continue;
}
- asf->asf_st = s->streams[asf->stream_index]->priv_data;
+ asf->asf_st = &asf->streams[s->streams[asf->stream_index]->id];
+ asf->asf_st->skip_to_key = 0;
}
asf_st = asf->asf_st;
av_assert0(asf_st);
@@ -1160,37 +1158,30 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
// frag_offset is here used as the beginning timestamp
asf->packet_frag_timestamp = asf->packet_time_start;
asf->packet_time_start += asf->packet_time_delta;
- asf->packet_obj_size = asf->packet_frag_size = avio_r8(pb);
+ asf_st->packet_obj_size = asf->packet_frag_size = avio_r8(pb);
asf->packet_size_left--;
asf->packet_multi_size--;
- if (asf->packet_multi_size < asf->packet_obj_size) {
+ if (asf->packet_multi_size < asf_st->packet_obj_size) {
asf->packet_time_start = 0;
avio_skip(pb, asf->packet_multi_size);
asf->packet_size_left -= asf->packet_multi_size;
continue;
}
- asf->packet_multi_size -= asf->packet_obj_size;
- }
- if (asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size &&
- asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size) {
- av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
- asf_st->frag_offset, asf->packet_frag_size,
- asf->packet_obj_size, asf_st->pkt.size);
- asf->packet_obj_size = asf_st->pkt.size;
+ asf->packet_multi_size -= asf_st->packet_obj_size;
}
- if (asf_st->pkt.size != asf->packet_obj_size ||
+ if (asf_st->pkt.size != asf_st->packet_obj_size ||
// FIXME is this condition sufficient?
asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {
if (asf_st->pkt.data) {
av_log(s, AV_LOG_INFO,
"freeing incomplete packet size %d, new %d\n",
- asf_st->pkt.size, asf->packet_obj_size);
+ asf_st->pkt.size, asf_st->packet_obj_size);
asf_st->frag_offset = 0;
av_free_packet(&asf_st->pkt);
}
/* new packet */
- av_new_packet(&asf_st->pkt, asf->packet_obj_size);
+ av_new_packet(&asf_st->pkt, asf_st->packet_obj_size);
asf_st->seq = asf->packet_seq;
asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll;
asf_st->pkt.stream_index = asf->stream_index;
@@ -1211,7 +1202,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
asf->stream_index, asf->packet_key_frame,
asf_st->pkt.flags & AV_PKT_FLAG_KEY,
s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO,
- asf->packet_obj_size);
+ asf_st->packet_obj_size);
if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
asf->packet_key_frame = 1;
if (asf->packet_key_frame)
@@ -1310,7 +1301,9 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
asf_st->frag_offset = 0;
*pkt = asf_st->pkt;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
asf_st->pkt.destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
asf_st->pkt.buf = 0;
asf_st->pkt.size = 0;
@@ -1331,9 +1324,9 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
int ret;
/* parse cached packets, if any */
- if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
+ if ((ret = asf_parse_packet(s, s->pb, pkt)) <= 0)
return ret;
- if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
+ if ((ret = asf_get_packet(s, s->pb)) < 0)
assert(asf->packet_size_left < FRAME_HEADER_SIZE ||
asf->packet_segments < 1);
asf->packet_time_start = 0;
@@ -1364,21 +1357,34 @@ static void asf_reset_header(AVFormatContext *s)
asf->packet_frag_size = 0;
asf->packet_frag_timestamp = 0;
asf->packet_multi_size = 0;
- asf->packet_obj_size = 0;
asf->packet_time_delta = 0;
asf->packet_time_start = 0;
- for (i = 0; i < s->nb_streams; i++) {
- asf_st = s->streams[i]->priv_data;
- if (!asf_st)
- continue;
+ for (i = 0; i < 128; i++) {
+ asf_st = &asf->streams[i];
av_free_packet(&asf_st->pkt);
+ asf_st->packet_obj_size = 0;
asf_st->frag_offset = 0;
asf_st->seq = 0;
}
asf->asf_st = NULL;
}
+static void skip_to_key(AVFormatContext *s)
+{
+ ASFContext *asf = s->priv_data;
+ int i;
+
+ for (i = 0; i < 128; i++) {
+ int j = asf->asfid2avid[i];
+ ASFStream *asf_st = &asf->streams[i];
+ if (j < 0 || s->streams[j]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+ continue;
+
+ asf_st->skip_to_key = 1;
+ }
+}
+
static int asf_read_close(AVFormatContext *s)
{
asf_reset_header(s);
@@ -1389,6 +1395,7 @@ static int asf_read_close(AVFormatContext *s)
static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
int64_t *ppos, int64_t pos_limit)
{
+ ASFContext *asf = s->priv_data;
AVPacket pkt1, *pkt = &pkt1;
ASFStream *asf_st;
int64_t pts;
@@ -1407,6 +1414,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
if (avio_seek(s->pb, pos, SEEK_SET) < 0)
return AV_NOPTS_VALUE;
+ ff_read_frame_flush(s);
asf_reset_header(s);
for (;;) {
if (av_read_frame(s, pkt) < 0) {
@@ -1420,8 +1428,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
if (pkt->flags & AV_PKT_FLAG_KEY) {
i = pkt->stream_index;
- asf_st = s->streams[i]->priv_data;
- av_assert0(asf_st);
+ asf_st = &asf->streams[s->streams[i]->id];
// assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
pos = asf_st->packet_pos;
@@ -1528,6 +1535,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index,
if(avio_seek(s->pb, pos, SEEK_SET) < 0)
return -1;
asf_reset_header(s);
+ skip_to_key(s);
return 0;
}
}
@@ -1535,6 +1543,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index,
if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0)
return -1;
asf_reset_header(s);
+ skip_to_key(s);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/audiointerleave.c b/chromium/third_party/ffmpeg/libavformat/audiointerleave.c
index 35dd8d5e625..2aa95f3dc6a 100644
--- a/chromium/third_party/ffmpeg/libavformat/audiointerleave.c
+++ b/chromium/third_party/ffmpeg/libavformat/audiointerleave.c
@@ -74,8 +74,8 @@ int ff_audio_interleave_init(AVFormatContext *s,
return 0;
}
-static int ff_interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
- int stream_index, int flush)
+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;
@@ -134,7 +134,7 @@ int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
AVPacket new_pkt;
int ret;
- while ((ret = ff_interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
+ while ((ret = interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
ret = ff_interleave_add_packet(s, &new_pkt, compare_ts);
if (ret < 0)
return ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/avformat.h b/chromium/third_party/ffmpeg/libavformat/avformat.h
index 80d693a1137..77efc61e72b 100644
--- a/chromium/third_party/ffmpeg/libavformat/avformat.h
+++ b/chromium/third_party/ffmpeg/libavformat/avformat.h
@@ -337,8 +337,10 @@ typedef struct AVProbeData {
int buf_size; /**< Size of buf except extra allocated bytes */
} AVProbeData;
-#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection
#define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4)
+#define AVPROBE_SCORE_EXTENSION 50 ///< score for file extension
+#define AVPROBE_SCORE_MAX 100 ///< maximum score
+
#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer
/// Demuxer will use avio_open, no opened file should be provided by the caller.
@@ -354,8 +356,8 @@ typedef struct AVProbeData {
#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */
#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */
#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */
-#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
-#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fallback to generic search */
+#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fall back on binary search via read_timestamp */
+#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fall back on generic search */
#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
#define AVFMT_ALLOW_FLUSH 0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
#if LIBAVFORMAT_VERSION_MAJOR <= 54
@@ -366,6 +368,14 @@ typedef struct AVProbeData {
/**< Format does not require strictly
increasing timestamps, but they must
still be monotonic */
+#define AVFMT_TS_NEGATIVE 0x40000 /**< Format allows muxing negative
+ timestamps. If not set the timestamp
+ will be shifted in av_write_frame and
+ av_interleaved_write_frame so they
+ start from 0.
+ The user or muxer can override this through
+ AVFormatContext.avoid_negative_ts
+ */
#define AVFMT_SEEK_TO_PTS 0x4000000 /**< Seeking is based on PTS */
@@ -626,6 +636,13 @@ typedef struct AVIndexEntry {
#define AV_DISPOSITION_ATTACHED_PIC 0x0400
/**
+ * To specify text track kind (different from subtitles default).
+ */
+#define AV_DISPOSITION_CAPTIONS 0x10000
+#define AV_DISPOSITION_DESCRIPTIONS 0x20000
+#define AV_DISPOSITION_METADATA 0x40000
+
+/**
* Options for behavior on timestamp wrap detection.
*/
#define AV_PTS_WRAP_IGNORE 0 ///< ignore the wrap
@@ -723,19 +740,6 @@ typedef struct AVStream {
*/
AVPacket attached_pic;
- /**
- * Real base framerate of the stream.
- * This is the lowest framerate with which all timestamps can be
- * represented accurately (it is the least common multiple of all
- * framerates in the stream). Note, this value is just a guess!
- * For example, if the time base is 1/90000 and all frames have either
- * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
- *
- * Code outside avformat should access this field using:
- * av_stream_get/set_r_frame_rate(stream)
- */
- AVRational r_frame_rate;
-
/*****************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
@@ -796,16 +800,6 @@ typedef struct AVStream {
*/
int codec_info_nb_frames;
- /**
- * Stream Identifier
- * This is the MPEG-TS stream identifier +1
- * 0 means unknown
- */
- int stream_identifier;
-
- int64_t interleaver_chunk_size;
- int64_t interleaver_chunk_duration;
-
/* av_read_frame() support */
enum AVStreamParseType need_parsing;
struct AVCodecParserContext *parser;
@@ -824,6 +818,29 @@ typedef struct AVStream {
unsigned int index_entries_allocated_size;
/**
+ * Real base framerate of the stream.
+ * This is the lowest framerate with which all timestamps can be
+ * represented accurately (it is the least common multiple of all
+ * framerates in the stream). Note, this value is just a guess!
+ * For example, if the time base is 1/90000 and all frames have either
+ * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
+ *
+ * Code outside avformat should access this field using:
+ * av_stream_get/set_r_frame_rate(stream)
+ */
+ AVRational r_frame_rate;
+
+ /**
+ * Stream Identifier
+ * This is the MPEG-TS stream identifier +1
+ * 0 means unknown
+ */
+ int stream_identifier;
+
+ int64_t interleaver_chunk_size;
+ int64_t interleaver_chunk_duration;
+
+ /**
* stream probing state
* -1 -> probing finished
* 0 -> no probing requested
@@ -1259,6 +1276,18 @@ typedef struct AVFormatContext {
int raw_packet_buffer_remaining_size;
/**
+ * Offset to remap timestamps to be non-negative.
+ * Expressed in timebase units.
+ * @see AVStream.mux_ts_offset
+ */
+ int64_t offset;
+
+ /**
+ * Timebase for the timestamp offset.
+ */
+ AVRational offset_timebase;
+
+ /**
* IO repositioned flag.
* This is set by avformat when the underlaying IO context read pointer
* is repositioned, for example when doing byte based seeking.
@@ -1376,6 +1405,9 @@ const AVClass *avformat_get_class(void);
*
* When muxing, should be called by the user before avformat_write_header().
*
+ * User is required to call avcodec_close() and avformat_free_context() to
+ * clean up the allocation by avformat_new_stream().
+ *
* @param c If non-NULL, the AVCodecContext corresponding to the new stream
* will be initialized to use this codec. This is needed for e.g. codec-specific
* defaults to be set, so codec should be provided if it is known.
@@ -1391,12 +1423,6 @@ AVProgram *av_new_program(AVFormatContext *s, int id);
*/
-#if FF_API_PKT_DUMP
-attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
-attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
- int dump_payload);
-#endif
-
#if FF_API_ALLOC_OUTPUT_CONTEXT
/**
* @deprecated deprecated in favor of avformat_alloc_output_context2()
@@ -1487,7 +1513,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
/**
* Open an input stream and read the header. The codecs are not opened.
- * The stream must be closed with av_close_input_file().
+ * The stream must be closed with avformat_close_input().
*
* @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
* May be a pointer to NULL, in which case an AVFormatContext is allocated by this
@@ -1622,8 +1648,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt);
* information possible for decoding.
*
* If pkt->buf is NULL, then the packet is valid until the next
- * av_read_frame() or until av_close_input_file(). Otherwise the packet is valid
- * indefinitely. In both cases the packet must be freed with
+ * av_read_frame() or until avformat_close_input(). Otherwise the packet
+ * is valid indefinitely. In both cases the packet must be freed with
* av_free_packet when it is no longer needed. For video, the packet contains
* exactly one frame. For audio, it contains an integer number of frames if each
* frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames
@@ -1667,6 +1693,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
* or if stream_index is -1, in AV_TIME_BASE units.
* If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as
* keyframes (this may not be supported by all demuxers).
+ * If flags contain AVSEEK_FLAG_BACKWARD, it is ignored.
*
* @param stream_index index of the stream which is used as time base reference
* @param min_ts smallest acceptable timestamp
@@ -1753,7 +1780,7 @@ void av_set_pts_info(AVStream *s, int pts_wrap_bits,
*
* @param s Media file handle, must be allocated with avformat_alloc_context().
* Its oformat field must be set to the desired output format;
- * Its pb field must be set to an already openened AVIOContext.
+ * Its pb field must be set to an already opened AVIOContext.
* @param options An AVDictionary filled with AVFormatContext and muxer-private options.
* On return this parameter will be destroyed and replaced with a dict containing
* options that were not found. May be NULL.
diff --git a/chromium/third_party/ffmpeg/libavformat/avidec.c b/chromium/third_party/ffmpeg/libavformat/avidec.c
index 3105d339ca3..2827064331f 100644
--- a/chromium/third_party/ffmpeg/libavformat/avidec.c
+++ b/chromium/third_party/ffmpeg/libavformat/avidec.c
@@ -19,36 +19,38 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mathematics.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
-#include "libavutil/avstring.h"
-#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
-#include "internal.h"
#include "avi.h"
#include "dv.h"
+#include "internal.h"
#include "riff.h"
typedef struct AVIStream {
- int64_t frame_offset; /* current frame (video) or byte (audio) counter
- (used to compute the pts) */
+ int64_t frame_offset; /* current frame (video) or byte (audio) counter
+ * (used to compute the pts) */
int remaining;
int packet_size;
uint32_t scale;
uint32_t rate;
- int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
+ int sample_size; /* size of one sample (or packet)
+ * (in the rate/scale sense) in bytes */
- int64_t cum_len; /* temporary storage (used during seek) */
-
- int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
+ int64_t cum_len; /* temporary storage (used during seek) */
+ int prefix; /* normally 'd'<<8 + 'c' or 'w'<<8 + 'b' */
int prefix_count;
uint32_t pal[256];
int has_pal;
- int dshow_block_align; ///< block align variable used to emulate bugs in the MS dshow demuxer
+ int dshow_block_align; /* block align variable used to emulate bugs in
+ * the MS dshow demuxer */
AVFormatContext *sub_ctx;
AVPacket sub_pkt;
@@ -59,9 +61,9 @@ typedef struct AVIStream {
typedef struct {
const AVClass *class;
- int64_t riff_end;
- int64_t movi_end;
- int64_t fsize;
+ int64_t riff_end;
+ int64_t movi_end;
+ int64_t fsize;
int64_t io_fsize;
int64_t movi_list;
int64_t last_pkt_pos;
@@ -69,7 +71,7 @@ typedef struct {
int is_odml;
int non_interleaved;
int stream_index;
- DVDemuxContext* dv_demux;
+ DVDemuxContext *dv_demux;
int odml_depth;
int use_odml;
#define MAX_ODML_DEPTH 1000
@@ -92,11 +94,11 @@ static const AVClass demuxer_class = {
static const char avi_headers[][8] = {
- { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
- { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
- { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19},
- { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
- { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
+ { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
+ { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
+ { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
+ { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
+ { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
{ 0 }
};
@@ -108,20 +110,21 @@ static const AVMetadataConv avi_metadata_conv[] = {
static int avi_load_index(AVFormatContext *s);
static int guess_ni_flag(AVFormatContext *s);
-#define print_tag(str, tag, size) \
- av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \
- str, tag & 0xff, \
- (tag >> 8) & 0xff, \
- (tag >> 16) & 0xff, \
- (tag >> 24) & 0xff, \
- size)
+#define print_tag(str, tag, size) \
+ av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \
+ str, tag & 0xff, \
+ (tag >> 8) & 0xff, \
+ (tag >> 16) & 0xff, \
+ (tag >> 24) & 0xff, \
+ size)
-static inline int get_duration(AVIStream *ast, int len){
- if(ast->sample_size){
+static inline int get_duration(AVIStream *ast, int len)
+{
+ if (ast->sample_size)
return len;
- }else if (ast->dshow_block_align){
- return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
- }else
+ else if (ast->dshow_block_align)
+ return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
+ else
return 1;
}
@@ -133,164 +136,180 @@ static int get_riff(AVFormatContext *s, AVIOContext *pb)
/* check RIFF header */
avio_read(pb, header, 4);
- avi->riff_end = avio_rl32(pb); /* RIFF chunk size */
+ avi->riff_end = avio_rl32(pb); /* RIFF chunk size */
avi->riff_end += avio_tell(pb); /* RIFF chunk end */
- avio_read(pb, header+4, 4);
+ avio_read(pb, header + 4, 4);
- for(i=0; avi_headers[i][0]; i++)
- if(!memcmp(header, avi_headers[i], 8))
+ for (i = 0; avi_headers[i][0]; i++)
+ if (!memcmp(header, avi_headers[i], 8))
break;
- if(!avi_headers[i][0])
+ if (!avi_headers[i][0])
return AVERROR_INVALIDDATA;
- if(header[7] == 0x19)
- av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
+ if (header[7] == 0x19)
+ av_log(s, AV_LOG_INFO,
+ "This file has been generated by a totally broken muxer.\n");
return 0;
}
-static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- int longs_pre_entry= avio_rl16(pb);
- int index_sub_type = avio_r8(pb);
- int index_type = avio_r8(pb);
- int entries_in_use = avio_rl32(pb);
- int chunk_id = avio_rl32(pb);
- int64_t base = avio_rl64(pb);
- int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
+static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int longs_pre_entry = avio_rl16(pb);
+ int index_sub_type = avio_r8(pb);
+ int index_type = avio_r8(pb);
+ int entries_in_use = avio_rl32(pb);
+ int chunk_id = avio_rl32(pb);
+ int64_t base = avio_rl64(pb);
+ int stream_id = ((chunk_id & 0xFF) - '0') * 10 +
+ ((chunk_id >> 8 & 0xFF) - '0');
AVStream *st;
AVIStream *ast;
int i;
- int64_t last_pos= -1;
- int64_t filesize= avi->fsize;
-
- av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
- longs_pre_entry,index_type, entries_in_use, chunk_id, base);
-
- if(stream_id >= s->nb_streams || stream_id < 0)
+ int64_t last_pos = -1;
+ int64_t filesize = avi->fsize;
+
+ av_dlog(s,
+ "longs_pre_entry:%d index_type:%d entries_in_use:%d "
+ "chunk_id:%X base:%16"PRIX64"\n",
+ longs_pre_entry,
+ index_type,
+ entries_in_use,
+ chunk_id,
+ base);
+
+ if (stream_id >= s->nb_streams || stream_id < 0)
return AVERROR_INVALIDDATA;
- st= s->streams[stream_id];
+ st = s->streams[stream_id];
ast = st->priv_data;
- if(index_sub_type)
+ if (index_sub_type)
return AVERROR_INVALIDDATA;
avio_rl32(pb);
- if(index_type && longs_pre_entry != 2)
+ if (index_type && longs_pre_entry != 2)
return AVERROR_INVALIDDATA;
- if(index_type>1)
+ if (index_type > 1)
return AVERROR_INVALIDDATA;
- if(filesize > 0 && base >= filesize){
+ if (filesize > 0 && base >= filesize) {
av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
- if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
+ if (base >> 32 == (base & 0xFFFFFFFF) &&
+ (base & 0xFFFFFFFF) < filesize &&
+ filesize <= 0xFFFFFFFF)
base &= 0xFFFFFFFF;
else
return AVERROR_INVALIDDATA;
}
- for(i=0; i<entries_in_use; i++){
- if(index_type){
- int64_t pos= avio_rl32(pb) + base - 8;
- int len = avio_rl32(pb);
- int key= len >= 0;
+ for (i = 0; i < entries_in_use; i++) {
+ if (index_type) {
+ int64_t pos = avio_rl32(pb) + base - 8;
+ int len = avio_rl32(pb);
+ int key = len >= 0;
len &= 0x7FFFFFFF;
#ifdef DEBUG_SEEK
av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
#endif
- if(url_feof(pb))
+ if (url_feof(pb))
return AVERROR_INVALIDDATA;
- if(last_pos == pos || pos == base - 8)
- avi->non_interleaved= 1;
- if(last_pos != pos && (len || !ast->sample_size))
- av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
+ if (last_pos == pos || pos == base - 8)
+ avi->non_interleaved = 1;
+ if (last_pos != pos && (len || !ast->sample_size))
+ av_add_index_entry(st, pos, ast->cum_len, len, 0,
+ key ? AVINDEX_KEYFRAME : 0);
ast->cum_len += get_duration(ast, len);
- last_pos= pos;
- }else{
+ last_pos = pos;
+ } else {
int64_t offset, pos;
int duration;
offset = avio_rl64(pb);
avio_rl32(pb); /* size */
duration = avio_rl32(pb);
- if(url_feof(pb))
+ if (url_feof(pb))
return AVERROR_INVALIDDATA;
pos = avio_tell(pb);
- if(avi->odml_depth > MAX_ODML_DEPTH){
+ if (avi->odml_depth > MAX_ODML_DEPTH) {
av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
return AVERROR_INVALIDDATA;
}
- if(avio_seek(pb, offset+8, SEEK_SET) < 0)
+ if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
return -1;
avi->odml_depth++;
read_braindead_odml_indx(s, frame_num);
avi->odml_depth--;
frame_num += duration;
- if(avio_seek(pb, pos, SEEK_SET) < 0) {
+ if (avio_seek(pb, pos, SEEK_SET) < 0) {
av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
return -1;
}
}
}
- avi->index_loaded=2;
+ avi->index_loaded = 2;
return 0;
}
-static void clean_index(AVFormatContext *s){
+static void clean_index(AVFormatContext *s)
+{
int i;
int64_t j;
- for(i=0; i<s->nb_streams; i++){
- AVStream *st = s->streams[i];
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
AVIStream *ast = st->priv_data;
- int n= st->nb_index_entries;
- int max= ast->sample_size;
+ int n = st->nb_index_entries;
+ int max = ast->sample_size;
int64_t pos, size, ts;
- if(n != 1 || ast->sample_size==0)
+ if (n != 1 || ast->sample_size == 0)
continue;
- while(max < 1024) max+=max;
+ while (max < 1024)
+ max += max;
- pos= st->index_entries[0].pos;
- size= st->index_entries[0].size;
- ts= st->index_entries[0].timestamp;
+ pos = st->index_entries[0].pos;
+ size = st->index_entries[0].size;
+ ts = st->index_entries[0].timestamp;
- for(j=0; j<size; j+=max){
- av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
- }
+ for (j = 0; j < size; j += max)
+ av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
+ AVINDEX_KEYFRAME);
}
}
-static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
+static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
+ uint32_t size)
{
AVIOContext *pb = s->pb;
- char key[5] = {0}, *value;
+ char key[5] = { 0 };
+ char *value;
size += (size & 1);
if (size == UINT_MAX)
return AVERROR(EINVAL);
- value = av_malloc(size+1);
+ value = av_malloc(size + 1);
if (!value)
return AVERROR(ENOMEM);
avio_read(pb, value, size);
- value[size]=0;
+ value[size] = 0;
AV_WL32(key, tag);
return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
- AV_DICT_DONT_STRDUP_VAL);
+ AV_DICT_DONT_STRDUP_VAL);
}
static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -303,10 +322,10 @@ static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
/* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
month, &day, time, &year) == 4) {
- for (i=0; i<12; i++)
+ for (i = 0; i < 12; i++)
if (!av_strcasecmp(month, months[i])) {
snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
- year, i+1, day, time);
+ year, i + 1, day, time);
av_dict_set(metadata, "creation_time", buffer, 0);
}
} else if (date[4] == '/' && date[7] == '/') {
@@ -321,19 +340,25 @@ static void avi_read_nikon(AVFormatContext *s, uint64_t end)
uint32_t tag = avio_rl32(s->pb);
uint32_t size = avio_rl32(s->pb);
switch (tag) {
- case MKTAG('n', 'c', 't', 'g'): { /* Nikon Tags */
+ case MKTAG('n', 'c', 't', 'g'): /* Nikon Tags */
+ {
uint64_t tag_end = avio_tell(s->pb) + size;
while (avio_tell(s->pb) < tag_end) {
- uint16_t tag = avio_rl16(s->pb);
- uint16_t size = avio_rl16(s->pb);
+ uint16_t tag = avio_rl16(s->pb);
+ uint16_t size = avio_rl16(s->pb);
const char *name = NULL;
- char buffer[64] = {0};
+ char buffer[64] = { 0 };
size -= avio_read(s->pb, buffer,
- FFMIN(size, sizeof(buffer)-1));
+ FFMIN(size, sizeof(buffer) - 1));
switch (tag) {
- case 0x03: name = "maker"; break;
- case 0x04: name = "model"; break;
- case 0x13: name = "creation_time";
+ case 0x03:
+ name = "maker";
+ break;
+ case 0x04:
+ name = "model";
+ break;
+ case 0x13:
+ name = "creation_time";
if (buffer[4] == ':' && buffer[7] == ':')
buffer[4] = buffer[7] = '-';
break;
@@ -360,13 +385,14 @@ static int avi_read_header(AVFormatContext *s)
unsigned int size;
int i;
AVStream *st;
- AVIStream *ast = NULL;
- int avih_width=0, avih_height=0;
- int amv_file_format=0;
- uint64_t list_end = 0;
+ AVIStream *ast = NULL;
+ int avih_width = 0, avih_height = 0;
+ int amv_file_format = 0;
+ uint64_t list_end = 0;
int ret;
+ AVDictionaryEntry *dict_entry;
- avi->stream_index= -1;
+ avi->stream_index = -1;
ret = get_riff(s, pb);
if (ret < 0)
@@ -375,22 +401,22 @@ static int avi_read_header(AVFormatContext *s)
av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
avi->io_fsize = avi->fsize = avio_size(pb);
- if(avi->fsize<=0 || avi->fsize < avi->riff_end)
- avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
+ if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
+ avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
/* first list tag */
stream_index = -1;
- codec_type = -1;
+ codec_type = -1;
frame_period = 0;
- for(;;) {
+ for (;;) {
if (url_feof(pb))
goto fail;
- tag = avio_rl32(pb);
+ tag = avio_rl32(pb);
size = avio_rl32(pb);
print_tag("tag", tag, size);
- switch(tag) {
+ switch (tag) {
case MKTAG('L', 'I', 'S', 'T'):
list_end = avio_tell(pb) + size;
/* Ignored, except at start of video packets. */
@@ -400,21 +426,23 @@ static int avi_read_header(AVFormatContext *s)
if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
avi->movi_list = avio_tell(pb) - 4;
- if(size) avi->movi_end = avi->movi_list + size + (size & 1);
- else avi->movi_end = avi->fsize;
+ if (size)
+ avi->movi_end = avi->movi_list + size + (size & 1);
+ else
+ avi->movi_end = avi->fsize;
av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
goto end_of_header;
- }
- else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
+ } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
ff_read_riff_info(s, size - 4);
else if (tag1 == MKTAG('n', 'c', 'd', 't'))
avi_read_nikon(s, list_end);
break;
- case MKTAG('I', 'D', 'I', 'T'): {
- unsigned char date[64] = {0};
+ case MKTAG('I', 'D', 'I', 'T'):
+ {
+ unsigned char date[64] = { 0 };
size += (size & 1);
- size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1));
+ size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
avio_skip(pb, size);
avi_metadata_creation_time(&s->metadata, date);
break;
@@ -424,7 +452,7 @@ static int avi_read_header(AVFormatContext *s)
avio_skip(pb, size + (size & 1));
break;
case MKTAG('a', 'm', 'v', 'h'):
- amv_file_format=1;
+ amv_file_format = 1;
case MKTAG('a', 'v', 'i', 'h'):
/* AVI header */
/* using frame_period is bad idea */
@@ -436,51 +464,51 @@ static int avi_read_header(AVFormatContext *s)
avio_skip(pb, 2 * 4);
avio_rl32(pb);
avio_rl32(pb);
- avih_width=avio_rl32(pb);
- avih_height=avio_rl32(pb);
+ avih_width = avio_rl32(pb);
+ avih_height = avio_rl32(pb);
avio_skip(pb, size - 10 * 4);
break;
case MKTAG('s', 't', 'r', 'h'):
/* stream header */
- tag1 = avio_rl32(pb);
+ tag1 = avio_rl32(pb);
handler = avio_rl32(pb); /* codec tag */
- if(tag1 == MKTAG('p', 'a', 'd', 's')){
+ if (tag1 == MKTAG('p', 'a', 'd', 's')) {
avio_skip(pb, size - 8);
break;
- }else{
+ } else {
stream_index++;
st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
st->id = stream_index;
- ast = av_mallocz(sizeof(AVIStream));
+ ast = av_mallocz(sizeof(AVIStream));
if (!ast)
goto fail;
st->priv_data = ast;
}
- if(amv_file_format)
- tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
+ if (amv_file_format)
+ tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
+ : MKTAG('v', 'i', 'd', 's');
print_tag("strh", tag1, -1);
- if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
+ if (tag1 == MKTAG('i', 'a', 'v', 's') ||
+ tag1 == MKTAG('i', 'v', 'a', 's')) {
int64_t dv_dur;
- /*
- * After some consideration -- I don't think we
- * have to support anything but DV in type1 AVIs.
- */
+ /* After some consideration -- I don't think we
+ * have to support anything but DV in type1 AVIs. */
if (s->nb_streams != 1)
goto fail;
if (handler != MKTAG('d', 'v', 's', 'd') &&
handler != MKTAG('d', 'v', 'h', 'd') &&
handler != MKTAG('d', 'v', 's', 'l'))
- goto fail;
+ goto fail;
ast = s->streams[0]->priv_data;
av_freep(&s->streams[0]->codec->extradata);
@@ -498,46 +526,48 @@ static int avi_read_header(AVFormatContext *s)
s->streams[0]->priv_data = ast;
avio_skip(pb, 3 * 4);
ast->scale = avio_rl32(pb);
- ast->rate = avio_rl32(pb);
+ ast->rate = avio_rl32(pb);
avio_skip(pb, 4); /* start time */
dv_dur = avio_rl32(pb);
if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
- dv_dur *= AV_TIME_BASE;
+ dv_dur *= AV_TIME_BASE;
s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
}
- /*
- * else, leave duration alone; timing estimation in utils.c
- * will make a guess based on bitrate.
- */
+ /* else, leave duration alone; timing estimation in utils.c
+ * will make a guess based on bitrate. */
stream_index = s->nb_streams - 1;
- avio_skip(pb, size - 9*4);
+ avio_skip(pb, size - 9 * 4);
break;
}
av_assert0(stream_index < s->nb_streams);
- st->codec->stream_codec_tag= handler;
+ st->codec->stream_codec_tag = handler;
avio_rl32(pb); /* flags */
avio_rl16(pb); /* priority */
avio_rl16(pb); /* language */
avio_rl32(pb); /* initial frame */
ast->scale = avio_rl32(pb);
- ast->rate = avio_rl32(pb);
- if(!(ast->scale && ast->rate)){
- av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate);
- if(frame_period){
- ast->rate = 1000000;
+ ast->rate = avio_rl32(pb);
+ if (!(ast->scale && ast->rate)) {
+ av_log(s, AV_LOG_WARNING,
+ "scale/rate is %u/%u which is invalid. "
+ "(This file has been generated by broken software.)\n",
+ ast->scale,
+ ast->rate);
+ if (frame_period) {
+ ast->rate = 1000000;
ast->scale = frame_period;
- }else{
- ast->rate = 25;
+ } else {
+ ast->rate = 25;
ast->scale = 1;
}
}
avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
- ast->cum_len=avio_rl32(pb); /* start */
+ ast->cum_len = avio_rl32(pb); /* start */
st->nb_frames = avio_rl32(pb);
st->start_time = 0;
@@ -548,11 +578,11 @@ static int avi_read_header(AVFormatContext *s)
return AVERROR_INVALIDDATA;
}
ast->sample_size = avio_rl32(pb); /* sample ssize */
- ast->cum_len *= FFMAX(1, ast->sample_size);
+ ast->cum_len *= FFMAX(1, ast->sample_size);
av_dlog(s, "%"PRIu32" %"PRIu32" %d\n",
ast->rate, ast->scale, ast->sample_size);
- switch(tag1) {
+ switch (tag1) {
case MKTAG('v', 'i', 'd', 's'):
codec_type = AVMEDIA_TYPE_VIDEO;
@@ -570,14 +600,14 @@ static int avi_read_header(AVFormatContext *s)
default:
av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
}
- if(ast->sample_size == 0) {
+ if (ast->sample_size == 0) {
st->duration = st->nb_frames;
if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
}
}
- ast->frame_offset= ast->cum_len;
+ ast->frame_offset = ast->cum_len;
avio_skip(pb, size - 12 * 4);
break;
case MKTAG('s', 't', 'r', 'f'):
@@ -592,49 +622,59 @@ static int avi_read_header(AVFormatContext *s)
if (cur_pos < list_end)
size = FFMIN(size, list_end - cur_pos);
st = s->streams[stream_index];
- switch(codec_type) {
+ switch (codec_type) {
case AVMEDIA_TYPE_VIDEO:
- if(amv_file_format){
- st->codec->width=avih_width;
- st->codec->height=avih_height;
+ if (amv_file_format) {
+ st->codec->width = avih_width;
+ st->codec->height = avih_height;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_AMV;
+ st->codec->codec_id = AV_CODEC_ID_AMV;
avio_skip(pb, size);
break;
}
tag1 = ff_get_bmp_header(pb, st, &esize);
- if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
+ if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
+ tag1 == MKTAG('D', 'X', 'S', 'A')) {
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_tag = tag1;
- st->codec->codec_id = AV_CODEC_ID_XSUB;
+ st->codec->codec_tag = tag1;
+ st->codec->codec_id = AV_CODEC_ID_XSUB;
break;
}
- if(size > 10*4 && size<(1<<30) && size < avi->fsize){
- if(esize == size-1 && (esize&1)) st->codec->extradata_size= esize - 10*4;
- else st->codec->extradata_size= size - 10*4;
- st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
+ if (esize == size-1 && (esize&1)) {
+ st->codec->extradata_size = esize - 10 * 4;
+ } else
+ st->codec->extradata_size = size - 10 * 4;
+ st->codec->extradata = av_malloc(st->codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata) {
- st->codec->extradata_size= 0;
+ st->codec->extradata_size = 0;
return AVERROR(ENOMEM);
}
- avio_read(pb, st->codec->extradata, st->codec->extradata_size);
+ avio_read(pb,
+ st->codec->extradata,
+ st->codec->extradata_size);
}
- if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+ // FIXME: check if the encoder really did this correctly
+ if (st->codec->extradata_size & 1)
avio_r8(pb);
- /* Extract palette from extradata if bpp <= 8. */
- /* This code assumes that extradata contains only palette. */
- /* This is true for all paletted codecs implemented in FFmpeg. */
- if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
+ /* Extract palette from extradata if bpp <= 8.
+ * This code assumes that extradata contains only palette.
+ * This is true for all paletted codecs implemented in
+ * FFmpeg. */
+ if (st->codec->extradata_size &&
+ (st->codec->bits_per_coded_sample <= 8)) {
int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
const uint8_t *pal_src;
pal_size = FFMIN(pal_size, st->codec->extradata_size);
- pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
- for (i = 0; i < pal_size/4; i++)
+ pal_src = st->codec->extradata +
+ st->codec->extradata_size - pal_size;
+ for (i = 0; i < pal_size / 4; i++)
ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
ast->has_pal = 1;
}
@@ -642,17 +682,25 @@ static int avi_read_header(AVFormatContext *s)
print_tag("video", tag1, 0);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_tag = tag1;
- st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
- st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
-
- if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
- st->codec->extradata_size+= 9;
- st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if(st->codec->extradata)
- memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
+ st->codec->codec_tag = tag1;
+ st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags,
+ tag1);
+ /* This is needed to get the pict type which is necessary
+ * for generating correct pts. */
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
+
+ if (st->codec->codec_tag == 0 && st->codec->height > 0 &&
+ st->codec->extradata_size < 1U << 30) {
+ st->codec->extradata_size += 9;
+ st->codec->extradata = av_realloc_f(st->codec->extradata,
+ 1,
+ st->codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (st->codec->extradata)
+ memcpy(st->codec->extradata + st->codec->extradata_size - 9,
+ "BottomUp", 9);
}
- st->codec->height= FFABS(st->codec->height);
+ st->codec->height = FFABS(st->codec->height);
// avio_skip(pb, size - 5 * 4);
break;
@@ -660,12 +708,19 @@ static int avi_read_header(AVFormatContext *s)
ret = ff_get_wav_header(pb, st->codec, size);
if (ret < 0)
return ret;
- ast->dshow_block_align= st->codec->block_align;
- if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
- av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
- ast->sample_size= st->codec->block_align;
+ ast->dshow_block_align = st->codec->block_align;
+ if (ast->sample_size && st->codec->block_align &&
+ ast->sample_size != st->codec->block_align) {
+ av_log(s,
+ AV_LOG_WARNING,
+ "sample size (%d) != block align (%d)\n",
+ ast->sample_size,
+ st->codec->block_align);
+ ast->sample_size = st->codec->block_align;
}
- if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+ /* 2-aligned
+ * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+ if (size & 1)
avio_skip(pb, 1);
/* Force parsing as several audio frames can be in
* one packet and timestamps refer to packet start. */
@@ -673,24 +728,25 @@ static int avi_read_header(AVFormatContext *s)
/* ADTS header is in extradata, AAC without header must be
* stored as exact frames. Parser not needed and it will
* fail. */
- if (st->codec->codec_id == AV_CODEC_ID_AAC && st->codec->extradata_size)
+ if (st->codec->codec_id == AV_CODEC_ID_AAC &&
+ st->codec->extradata_size)
st->need_parsing = AVSTREAM_PARSE_NONE;
/* AVI files with Xan DPCM audio (wrongly) declare PCM
* audio in the header but have Axan as stream_code_tag. */
- if (st->codec->stream_codec_tag == AV_RL32("Axan")){
+ if (st->codec->stream_codec_tag == AV_RL32("Axan")) {
st->codec->codec_id = AV_CODEC_ID_XAN_DPCM;
st->codec->codec_tag = 0;
ast->dshow_block_align = 0;
}
- if (amv_file_format){
- st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV;
+ if (amv_file_format) {
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV;
ast->dshow_block_align = 0;
}
- if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
+ if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
ast->dshow_block_align = 0;
}
- if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
+ if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
@@ -704,15 +760,17 @@ static int avi_read_header(AVFormatContext *s)
break;
default:
st->codec->codec_type = AVMEDIA_TYPE_DATA;
- st->codec->codec_id= AV_CODEC_ID_NONE;
- st->codec->codec_tag= 0;
+ st->codec->codec_id = AV_CODEC_ID_NONE;
+ st->codec->codec_tag = 0;
avio_skip(pb, size);
break;
}
}
break;
case MKTAG('s', 't', 'r', 'd'):
- if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) {
+ if (stream_index >= (unsigned)s->nb_streams
+ || s->streams[stream_index]->codec->extradata_size
+ || s->streams[stream_index]->codec->codec_tag == MKTAG('H','2','6','4')) {
avio_skip(pb, size);
} else {
uint64_t cur_pos = avio_tell(pb);
@@ -720,7 +778,7 @@ static int avi_read_header(AVFormatContext *s)
size = FFMIN(size, list_end - cur_pos);
st = s->streams[stream_index];
- if(size<(1<<30)){
+ if (size<(1<<30)) {
st->codec->extradata_size= size;
st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata) {
@@ -730,19 +788,21 @@ static int avi_read_header(AVFormatContext *s)
avio_read(pb, st->codec->extradata, st->codec->extradata_size);
}
- if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+ if (st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
avio_r8(pb);
}
break;
case MKTAG('i', 'n', 'd', 'x'):
- i= avio_tell(pb);
- if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml &&
- read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE))
+ i = avio_tell(pb);
+ if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
+ avi->use_odml &&
+ read_braindead_odml_indx(s, 0) < 0 &&
+ (s->error_recognition & AV_EF_EXPLODE))
goto fail;
- avio_seek(pb, i+size, SEEK_SET);
+ avio_seek(pb, i + size, SEEK_SET);
break;
case MKTAG('v', 'p', 'r', 'p'):
- if(stream_index < (unsigned)s->nb_streams && size > 9*4){
+ if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
AVRational active, active_aspect;
st = s->streams[stream_index];
@@ -752,33 +812,35 @@ static int avi_read_header(AVFormatContext *s)
avio_rl32(pb);
avio_rl32(pb);
- active_aspect.den= avio_rl16(pb);
- active_aspect.num= avio_rl16(pb);
- active.num = avio_rl32(pb);
- active.den = avio_rl32(pb);
- avio_rl32(pb); //nbFieldsPerFrame
+ active_aspect.den = avio_rl16(pb);
+ active_aspect.num = avio_rl16(pb);
+ active.num = avio_rl32(pb);
+ active.den = avio_rl32(pb);
+ avio_rl32(pb); // nbFieldsPerFrame
- if(active_aspect.num && active_aspect.den && active.num && active.den){
- st->sample_aspect_ratio= av_div_q(active_aspect, active);
+ if (active_aspect.num && active_aspect.den &&
+ active.num && active.den) {
+ st->sample_aspect_ratio = av_div_q(active_aspect, active);
av_dlog(s, "vprp %d/%d %d/%d\n",
active_aspect.num, active_aspect.den,
active.num, active.den);
}
- size -= 9*4;
+ size -= 9 * 4;
}
avio_skip(pb, size);
break;
case MKTAG('s', 't', 'r', 'n'):
- if(s->nb_streams){
- ret = avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
+ if (s->nb_streams) {
+ ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
if (ret < 0)
return ret;
break;
}
default:
- if(size > 1000000){
- av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
- "I will ignore it and try to continue anyway.\n");
+ if (size > 1000000) {
+ av_log(s, AV_LOG_ERROR,
+ "Something went wrong during header parsing, "
+ "I will ignore it and try to continue anyway.\n");
if (s->error_recognition & AV_EF_EXPLODE)
goto fail;
avi->movi_list = avio_tell(pb) - 4;
@@ -791,32 +853,45 @@ static int avi_read_header(AVFormatContext *s)
break;
}
}
- end_of_header:
+
+end_of_header:
/* check stream number */
if (stream_index != s->nb_streams - 1) {
- fail:
+
+fail:
return AVERROR_INVALIDDATA;
}
- if(!avi->index_loaded && pb->seekable)
+ if (!avi->index_loaded && pb->seekable)
avi_load_index(s);
- avi->index_loaded |= 1;
+ avi->index_loaded |= 1;
avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
- for(i=0; i<s->nb_streams; i++){
+
+ dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
+ if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ if ( st->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO
+ || st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- if(st->nb_index_entries)
+ if (st->nb_index_entries)
break;
}
// DV-in-AVI cannot be non-interleaved, if set this must be
// a mis-detection.
- if(avi->dv_demux)
- avi->non_interleaved=0;
- if(i==s->nb_streams && avi->non_interleaved) {
- av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
- avi->non_interleaved=0;
+ if (avi->dv_demux)
+ avi->non_interleaved = 0;
+ if (i == s->nb_streams && avi->non_interleaved) {
+ av_log(s, AV_LOG_WARNING,
+ "Non-interleaved AVI without index, switching to interleaved\n");
+ avi->non_interleaved = 0;
}
- if(avi->non_interleaved) {
+ if (avi->non_interleaved) {
av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
clean_index(s);
}
@@ -827,16 +902,17 @@ static int avi_read_header(AVFormatContext *s)
return 0;
}
-static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
- if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
+static int read_gab2_sub(AVStream *st, AVPacket *pkt)
+{
+ if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
uint8_t desc[256];
- int score = AVPROBE_SCORE_MAX / 2, ret;
+ int score = AVPROBE_SCORE_EXTENSION, ret;
AVIStream *ast = st->priv_data;
AVInputFormat *sub_demuxer;
AVRational time_base;
- AVIOContext *pb = avio_alloc_context( pkt->data + 7,
- pkt->size - 7,
- 0, NULL, NULL, NULL, NULL);
+ AVIOContext *pb = avio_alloc_context(pkt->data + 7,
+ pkt->size - 7,
+ 0, NULL, NULL, NULL, NULL);
AVProbeData pd;
unsigned int desc_len = avio_rl32(pb);
@@ -851,14 +927,15 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
avio_rl16(pb); /* flags? */
avio_rl32(pb); /* data size */
- pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
+ pd = (AVProbeData) { .buf = pb->buf_ptr,
+ .buf_size = pb->buf_end - pb->buf_ptr };
if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
goto error;
if (!(ast->sub_ctx = avformat_alloc_context()))
goto error;
- ast->sub_ctx->pb = pb;
+ ast->sub_ctx->pb = pb;
if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
*st->codec = *ast->sub_ctx->streams[0]->codec;
@@ -869,6 +946,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
ast->sub_buffer = pkt->data;
memset(pkt, 0, sizeof(*pkt));
return 1;
+
error:
av_freep(&pb);
}
@@ -886,7 +964,7 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
AV_TIME_BASE_Q);
- for (i=0; i<s->nb_streams; i++) {
+ for (i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
ast = st->priv_data;
if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
@@ -899,21 +977,23 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
}
if (sub_st) {
- ast = sub_st->priv_data;
- *pkt = ast->sub_pkt;
+ ast = sub_st->priv_data;
+ *pkt = ast->sub_pkt;
pkt->stream_index = sub_st->index;
+
if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
ast->sub_pkt.data = NULL;
}
return sub_st;
}
-static int get_stream_idx(int *d){
- if( d[0] >= '0' && d[0] <= '9'
- && d[1] >= '0' && d[1] <= '9'){
+static int get_stream_idx(int *d)
+{
+ if (d[0] >= '0' && d[0] <= '9' &&
+ d[1] >= '0' && d[1] <= '9') {
return (d[0] - '0') * 10 + (d[1] - '0');
- }else{
- return 100; //invalid stream ID
+ } else {
+ return 100; // invalid stream ID
}
}
@@ -932,52 +1012,53 @@ static int avi_sync(AVFormatContext *s, int exit_early)
start_sync:
memset(d, -1, sizeof(d));
- for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
+ for (i = sync = avio_tell(pb); !url_feof(pb); i++) {
int j;
- for(j=0; j<7; j++)
- d[j]= d[j+1];
- d[7]= avio_r8(pb);
+ for (j = 0; j < 7; j++)
+ d[j] = d[j + 1];
+ d[7] = avio_r8(pb);
- size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
+ size = d[4] + (d[5] << 8) + (d[6] << 16) + (d[7] << 24);
- n= get_stream_idx(d+2);
+ n = get_stream_idx(d + 2);
av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
- if(i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
+ if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
continue;
- //parse ix##
- if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
- //parse JUNK
- ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
- ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
+ // parse ix##
+ if ((d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) ||
+ // parse JUNK
+ (d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') ||
+ (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')) {
avio_skip(pb, size);
goto start_sync;
}
- //parse stray LIST
- if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
+ // parse stray LIST
+ if (d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T') {
avio_skip(pb, 4);
goto start_sync;
}
- n= get_stream_idx(d);
+ n = get_stream_idx(d);
- if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
+ if (!((i - avi->last_pkt_pos) & 1) &&
+ get_stream_idx(d + 1) < s->nb_streams)
continue;
- //detect ##ix chunk and skip
- if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
+ // detect ##ix chunk and skip
+ if (d[2] == 'i' && d[3] == 'x' && n < s->nb_streams) {
avio_skip(pb, size);
goto start_sync;
}
- //parse ##dc/##wb
- if(n < s->nb_streams){
+ // parse ##dc/##wb
+ if (n < s->nb_streams) {
AVStream *st;
AVIStream *ast;
- st = s->streams[n];
+ st = s->streams[n];
ast = st->priv_data;
if (!ast) {
@@ -985,67 +1066,74 @@ start_sync:
continue;
}
- if(s->nb_streams>=2){
- AVStream *st1 = s->streams[1];
- AVIStream *ast1= st1->priv_data;
- //workaround for broken small-file-bug402.avi
- if( d[2] == 'w' && d[3] == 'b'
- && n==0
+ if (s->nb_streams >= 2) {
+ AVStream *st1 = s->streams[1];
+ AVIStream *ast1 = st1->priv_data;
+ // workaround for broken small-file-bug402.avi
+ if ( d[2] == 'w' && d[3] == 'b'
+ && n == 0
&& st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
&& st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
&& ast->prefix == 'd'*256+'c'
&& (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
- ){
- n=1;
- st = st1;
+ ) {
+ n = 1;
+ st = st1;
ast = ast1;
- av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
+ av_log(s, AV_LOG_WARNING,
+ "Invalid stream + prefix combination, assuming audio.\n");
}
}
-
- if( (st->discard >= AVDISCARD_DEFAULT && size==0)
- /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
- || st->discard >= AVDISCARD_ALL){
+ if (!avi->dv_demux &&
+ ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* ||
+ // FIXME: needs a little reordering
+ (st->discard >= AVDISCARD_NONKEY &&
+ !(pkt->flags & AV_PKT_FLAG_KEY)) */
+ || st->discard >= AVDISCARD_ALL)) {
if (!exit_early) {
ast->frame_offset += get_duration(ast, size);
+ avio_skip(pb, size);
+ goto start_sync;
}
- avio_skip(pb, size);
- goto start_sync;
}
- if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
- int k = avio_r8(pb);
+ if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) {
+ int k = avio_r8(pb);
int last = (k + avio_r8(pb) - 1) & 0xFF;
- avio_rl16(pb); //flags
+ avio_rl16(pb); // flags
+ // b + (g << 8) + (r << 16);
for (; k <= last; k++)
- ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
- ast->has_pal= 1;
- goto start_sync;
- } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
- d[2]*256+d[3] == ast->prefix /*||
- (d[2] == 'd' && d[3] == 'c') ||
- (d[2] == 'w' && d[3] == 'b')*/) {
+ ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
+ ast->has_pal = 1;
+ goto start_sync;
+ } else if (((ast->prefix_count < 5 || sync + 9 > i) &&
+ d[2] < 128 && d[3] < 128) ||
+ d[2] * 256 + d[3] == ast->prefix /* ||
+ (d[2] == 'd' && d[3] == 'c') ||
+ (d[2] == 'w' && d[3] == 'b') */) {
if (exit_early)
return 0;
- if(d[2]*256+d[3] == ast->prefix)
+ if (d[2] * 256 + d[3] == ast->prefix)
ast->prefix_count++;
- else{
- ast->prefix= d[2]*256+d[3];
- ast->prefix_count= 0;
+ else {
+ ast->prefix = d[2] * 256 + d[3];
+ ast->prefix_count = 0;
}
- avi->stream_index= n;
- ast->packet_size= size + 8;
- ast->remaining= size;
+ avi->stream_index = n;
+ ast->packet_size = size + 8;
+ ast->remaining = size;
- if(size || !ast->sample_size){
- uint64_t pos= avio_tell(pb) - 8;
- if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
- av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
+ if (size || !ast->sample_size) {
+ uint64_t pos = avio_tell(pb) - 8;
+ if (!st->index_entries || !st->nb_index_entries ||
+ st->index_entries[st->nb_index_entries - 1].pos < pos) {
+ av_add_index_entry(st, pos, ast->frame_offset, size,
+ 0, AVINDEX_KEYFRAME);
}
}
return 0;
@@ -1053,7 +1141,7 @@ start_sync:
}
}
- if(pb->error)
+ if (pb->error)
return pb->error;
return AVERROR_EOF;
}
@@ -1064,7 +1152,7 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
AVIOContext *pb = s->pb;
int err;
#if FF_API_DESTRUCT_PACKET
- void* dstr;
+ void *dstr;
#endif
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
@@ -1073,97 +1161,106 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
return size;
}
- if(avi->non_interleaved){
+ if (avi->non_interleaved) {
int best_stream_index = 0;
- AVStream *best_st= NULL;
+ AVStream *best_st = NULL;
AVIStream *best_ast;
- int64_t best_ts= INT64_MAX;
+ int64_t best_ts = INT64_MAX;
int i;
- for(i=0; i<s->nb_streams; i++){
- AVStream *st = s->streams[i];
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
AVIStream *ast = st->priv_data;
- int64_t ts= ast->frame_offset;
+ int64_t ts = ast->frame_offset;
int64_t last_ts;
- if(!st->nb_index_entries)
+ if (!st->nb_index_entries)
continue;
last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
- if(!ast->remaining && ts > last_ts)
+ if (!ast->remaining && ts > last_ts)
continue;
- ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
+ ts = av_rescale_q(ts, st->time_base,
+ (AVRational) { FFMAX(1, ast->sample_size),
+ AV_TIME_BASE });
av_dlog(s, "%"PRId64" %d/%d %"PRId64"\n", ts,
st->time_base.num, st->time_base.den, ast->frame_offset);
- if(ts < best_ts){
- best_ts= ts;
- best_st= st;
- best_stream_index= i;
+ if (ts < best_ts) {
+ best_ts = ts;
+ best_st = st;
+ best_stream_index = i;
}
}
- if(!best_st)
+ if (!best_st)
return AVERROR_EOF;
best_ast = best_st->priv_data;
- best_ts = best_ast->frame_offset;
- if(best_ast->remaining)
- i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
- else{
- i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
- if(i>=0)
- best_ast->frame_offset= best_st->index_entries[i].timestamp;
+ best_ts = best_ast->frame_offset;
+ if (best_ast->remaining) {
+ i = av_index_search_timestamp(best_st,
+ best_ts,
+ AVSEEK_FLAG_ANY |
+ AVSEEK_FLAG_BACKWARD);
+ } else {
+ i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
+ if (i >= 0)
+ best_ast->frame_offset = best_st->index_entries[i].timestamp;
}
- if(i>=0){
- int64_t pos= best_st->index_entries[i].pos;
+ if (i >= 0) {
+ int64_t pos = best_st->index_entries[i].pos;
pos += best_ast->packet_size - best_ast->remaining;
- if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
+ if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
return AVERROR_EOF;
av_assert0(best_ast->remaining <= best_ast->packet_size);
- avi->stream_index= best_stream_index;
- if(!best_ast->remaining)
- best_ast->packet_size=
- best_ast->remaining= best_st->index_entries[i].size;
+ avi->stream_index = best_stream_index;
+ if (!best_ast->remaining)
+ best_ast->packet_size =
+ best_ast->remaining = best_st->index_entries[i].size;
}
else
return AVERROR_EOF;
}
resync:
- if(avi->stream_index >= 0){
- AVStream *st= s->streams[ avi->stream_index ];
- AVIStream *ast= st->priv_data;
+ if (avi->stream_index >= 0) {
+ AVStream *st = s->streams[avi->stream_index];
+ AVIStream *ast = st->priv_data;
int size, err;
- if(get_subtitle_pkt(s, st, pkt))
+ if (get_subtitle_pkt(s, st, pkt))
return 0;
- if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
- size= INT_MAX;
- else if(ast->sample_size < 32)
+ // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
+ if (ast->sample_size <= 1)
+ size = INT_MAX;
+ else if (ast->sample_size < 32)
// arbitrary multiplier to avoid tiny packets for raw PCM data
- size= 1024*ast->sample_size;
+ size = 1024 * ast->sample_size;
else
- size= ast->sample_size;
+ size = ast->sample_size;
- if(size > ast->remaining)
- size= ast->remaining;
- avi->last_pkt_pos= avio_tell(pb);
- err= av_get_packet(pb, pkt, size);
- if(err<0)
+ if (size > ast->remaining)
+ size = ast->remaining;
+ avi->last_pkt_pos = avio_tell(pb);
+ err = av_get_packet(pb, pkt, size);
+ if (err < 0)
return err;
size = err;
- if(ast->has_pal && pkt->size<(unsigned)INT_MAX/2){
+ if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
uint8_t *pal;
- pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
- if(!pal){
- av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n");
- }else{
+ pal = av_packet_new_side_data(pkt,
+ AV_PKT_DATA_PALETTE,
+ AVPALETTE_SIZE);
+ if (!pal) {
+ av_log(s, AV_LOG_ERROR,
+ "Failed to allocate data for palette\n");
+ } else {
memcpy(pal, ast->pal, AVPALETTE_SIZE);
ast->has_pal = 0;
}
@@ -1172,32 +1269,44 @@ resync:
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
AVBufferRef *avbuf = pkt->buf;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
dstr = pkt->destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
- pkt->data, pkt->size, pkt->pos);
+ pkt->data, pkt->size, pkt->pos);
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = dstr;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
- pkt->buf = avbuf;
+ pkt->buf = avbuf;
pkt->flags |= AV_PKT_FLAG_KEY;
if (size < 0)
av_free_packet(pkt);
- } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
- && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
+ !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
ast->frame_offset++;
avi->stream_index = -1;
- ast->remaining = 0;
+ ast->remaining = 0;
goto resync;
} else {
/* XXX: How to handle B-frames in AVI? */
pkt->dts = ast->frame_offset;
// pkt->dts += ast->start;
- if(ast->sample_size)
+ if (ast->sample_size)
pkt->dts /= ast->sample_size;
- av_dlog(s, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n",
- pkt->dts, ast->frame_offset, ast->scale, ast->rate,
- ast->sample_size, AV_TIME_BASE, avi->stream_index, size);
+ av_dlog(s,
+ "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d "
+ "base:%d st:%d size:%d\n",
+ pkt->dts,
+ ast->frame_offset,
+ ast->scale,
+ ast->rate,
+ ast->sample_size,
+ AV_TIME_BASE,
+ avi->stream_index,
+ size);
pkt->stream_index = avi->stream_index;
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -1205,17 +1314,17 @@ resync:
int index;
av_assert0(st->index_entries);
- index= av_index_search_timestamp(st, ast->frame_offset, 0);
- e= &st->index_entries[index];
+ index = av_index_search_timestamp(st, ast->frame_offset, 0);
+ e = &st->index_entries[index];
- if(index >= 0 && e->timestamp == ast->frame_offset){
- if (index == st->nb_index_entries-1){
+ if (index >= 0 && e->timestamp == ast->frame_offset) {
+ if (index == st->nb_index_entries-1) {
int key=1;
int i;
uint32_t state=-1;
- for(i=0; i<FFMIN(size,256); i++){
- if(st->codec->codec_id == AV_CODEC_ID_MPEG4){
- if(state == 0x1B6){
+ for (i=0; i<FFMIN(size,256); i++) {
+ if (st->codec->codec_id == AV_CODEC_ID_MPEG4) {
+ if (state == 0x1B6) {
key= !(pkt->data[i]&0xC0);
break;
}
@@ -1223,7 +1332,7 @@ resync:
break;
state= (state<<8) + pkt->data[i];
}
- if(!key)
+ if (!key)
e->flags &= ~AVINDEX_KEYFRAME;
}
if (e->flags & AVINDEX_KEYFRAME)
@@ -1235,24 +1344,24 @@ resync:
ast->frame_offset += get_duration(ast, pkt->size);
}
ast->remaining -= err;
- if(!ast->remaining){
- avi->stream_index= -1;
- ast->packet_size= 0;
+ if (!ast->remaining) {
+ avi->stream_index = -1;
+ ast->packet_size = 0;
}
- if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
+ if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
av_free_packet(pkt);
goto resync;
}
ast->seek_pos= 0;
- if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
+ if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
- if(avi->dts_max - dts > 2*AV_TIME_BASE){
+ if (avi->dts_max - dts > 2*AV_TIME_BASE) {
avi->non_interleaved= 1;
av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
- }else if(avi->dts_max < dts)
+ }else if (avi->dts_max < dts)
avi->dts_max = dts;
}
@@ -1265,7 +1374,7 @@ resync:
}
/* XXX: We make the implicit supposition that the positions are sorted
- for each stream. */
+ * for each stream. */
static int avi_read_idx1(AVFormatContext *s, int size)
{
AVIContext *avi = s->priv_data;
@@ -1274,8 +1383,8 @@ static int avi_read_idx1(AVFormatContext *s, int size)
AVStream *st;
AVIStream *ast;
unsigned int index, tag, flags, pos, len, first_packet = 1;
- unsigned last_pos= -1;
- unsigned last_idx= -1;
+ unsigned last_pos = -1;
+ unsigned last_idx = -1;
int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
int anykey = 0;
@@ -1284,39 +1393,38 @@ static int avi_read_idx1(AVFormatContext *s, int size)
return AVERROR_INVALIDDATA;
idx1_pos = avio_tell(pb);
- avio_seek(pb, avi->movi_list+4, SEEK_SET);
- if (avi_sync(s, 1) == 0) {
+ avio_seek(pb, avi->movi_list + 4, SEEK_SET);
+ if (avi_sync(s, 1) == 0)
first_packet_pos = avio_tell(pb) - 8;
- }
avi->stream_index = -1;
avio_seek(pb, idx1_pos, SEEK_SET);
- if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")){
+ if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")) {
first_packet_pos = 0;
data_offset = avi->movi_list;
}
/* Read the entries and sort them in each stream component. */
- for(i = 0; i < nb_index_entries; i++) {
- if(url_feof(pb))
+ for (i = 0; i < nb_index_entries; i++) {
+ if (url_feof(pb))
return -1;
- tag = avio_rl32(pb);
+ tag = avio_rl32(pb);
flags = avio_rl32(pb);
- pos = avio_rl32(pb);
- len = avio_rl32(pb);
+ pos = avio_rl32(pb);
+ len = avio_rl32(pb);
av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
i, tag, flags, pos, len);
- index = ((tag & 0xff) - '0') * 10;
- index += ((tag >> 8) & 0xff) - '0';
+ index = ((tag & 0xff) - '0') * 10;
+ index += (tag >> 8 & 0xff) - '0';
if (index >= s->nb_streams)
continue;
- st = s->streams[index];
+ st = s->streams[index];
ast = st->priv_data;
- if(first_packet && first_packet_pos && len) {
- data_offset = first_packet_pos - pos;
+ if (first_packet && first_packet_pos && len) {
+ data_offset = first_packet_pos - pos;
first_packet = 0;
}
pos += data_offset;
@@ -1325,15 +1433,16 @@ static int avi_read_idx1(AVFormatContext *s, int size)
// even if we have only a single stream, we should
// switch to non-interleaved to get correct timestamps
- if(last_pos == pos)
- avi->non_interleaved= 1;
- if(last_idx != pos && len) {
- av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
+ if (last_pos == pos)
+ avi->non_interleaved = 1;
+ if (last_idx != pos && len) {
+ av_add_index_entry(st, pos, ast->cum_len, len, 0,
+ (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
last_idx= pos;
}
ast->cum_len += get_duration(ast, len);
- last_pos= pos;
- anykey |= flags&AVIIF_INDEX;
+ last_pos = pos;
+ anykey |= flags&AVIIF_INDEX;
}
if (!anykey) {
for (index = 0; index < s->nb_streams; index++) {
@@ -1345,34 +1454,35 @@ static int avi_read_idx1(AVFormatContext *s, int size)
return 0;
}
-static int guess_ni_flag(AVFormatContext *s){
+static int guess_ni_flag(AVFormatContext *s)
+{
int i;
- int64_t last_start=0;
- int64_t first_end= INT64_MAX;
- int64_t oldpos= avio_tell(s->pb);
+ int64_t last_start = 0;
+ int64_t first_end = INT64_MAX;
+ int64_t oldpos = avio_tell(s->pb);
int *idx;
int64_t min_pos, pos;
- for(i=0; i<s->nb_streams; i++){
+ for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- int n= st->nb_index_entries;
+ int n = st->nb_index_entries;
unsigned int size;
- if(n <= 0)
+ if (n <= 0)
continue;
- if(n >= 2){
- int64_t pos= st->index_entries[0].pos;
+ if (n >= 2) {
+ int64_t pos = st->index_entries[0].pos;
avio_seek(s->pb, pos + 4, SEEK_SET);
- size= avio_rl32(s->pb);
- if(pos + size > st->index_entries[1].pos)
- last_start= INT64_MAX;
+ size = avio_rl32(s->pb);
+ if (pos + size > st->index_entries[1].pos)
+ last_start = INT64_MAX;
}
- if(st->index_entries[0].pos > last_start)
- last_start= st->index_entries[0].pos;
- if(st->index_entries[n-1].pos < first_end)
- first_end= st->index_entries[n-1].pos;
+ if (st->index_entries[0].pos > last_start)
+ last_start = st->index_entries[0].pos;
+ if (st->index_entries[n - 1].pos < first_end)
+ first_end = st->index_entries[n - 1].pos;
}
avio_seek(s->pb, oldpos, SEEK_SET);
if (last_start > first_end)
@@ -1384,17 +1494,18 @@ static int guess_ni_flag(AVFormatContext *s){
for (i=0; i<s->nb_streams; i++) {
AVStream *st = s->streams[i];
+ AVIStream *ast = st->priv_data;
int n= st->nb_index_entries;
while (idx[i]<n && st->index_entries[idx[i]].pos < pos)
idx[i]++;
if (idx[i] < n) {
- min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q));
+ min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));
min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
}
if (idx[i])
- max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q));
+ max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));
}
- if(max_dts - min_dts > 2*AV_TIME_BASE) {
+ if (max_dts - min_dts > 2*AV_TIME_BASE) {
av_free(idx);
return 1;
}
@@ -1408,15 +1519,15 @@ static int avi_load_index(AVFormatContext *s)
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
uint32_t tag, size;
- int64_t pos= avio_tell(pb);
+ int64_t pos = avio_tell(pb);
int64_t next;
- int ret = -1;
+ int ret = -1;
if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
goto the_end; // maybe truncated file
av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
- for(;;) {
- tag = avio_rl32(pb);
+ for (;;) {
+ tag = avio_rl32(pb);
size = avio_rl32(pb);
if (url_feof(pb))
break;
@@ -1433,18 +1544,19 @@ static int avi_load_index(AVFormatContext *s)
avi_read_idx1(s, size) >= 0) {
avi->index_loaded=2;
ret = 0;
- }else if(tag == MKTAG('L', 'I', 'S', 'T')) {
+ }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
uint32_t tag1 = avio_rl32(pb);
if (tag1 == MKTAG('I', 'N', 'F', 'O'))
ff_read_riff_info(s, size - 4);
- }else if(!ret)
+ }else if (!ret)
break;
if (avio_seek(pb, next, SEEK_SET) < 0)
break; // something is wrong here
}
- the_end:
+
+the_end:
avio_seek(pb, pos, SEEK_SET);
return ret;
}
@@ -1452,14 +1564,15 @@ static int avi_load_index(AVFormatContext *s)
static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
{
AVIStream *ast2 = st2->priv_data;
- int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
+ int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
av_free_packet(&ast2->sub_pkt);
if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
}
-static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int avi_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
{
AVIContext *avi = s->priv_data;
AVStream *st;
@@ -1472,12 +1585,14 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
avi_load_index(s);
avi->index_loaded |= 1;
}
- av_assert0(stream_index>= 0);
-
- st = s->streams[stream_index];
- ast= st->priv_data;
- index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
- if (index<0) {
+ av_assert0(stream_index >= 0);
+
+ st = s->streams[stream_index];
+ ast = st->priv_data;
+ index = av_index_search_timestamp(st,
+ timestamp * FFMAX(ast->sample_size, 1),
+ flags);
+ if (index < 0) {
if (st->nb_index_entries > 0)
av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
timestamp * FFMAX(ast->sample_size, 1),
@@ -1487,7 +1602,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
/* find the position */
- pos = st->index_entries[index].pos;
+ pos = st->index_entries[index].pos;
timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
av_dlog(s, "XX %"PRId64" %d %"PRId64"\n",
@@ -1499,24 +1614,24 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
/* the av_index_search_timestamp call above. */
av_assert0(stream_index == 0);
- if(avio_seek(s->pb, pos, SEEK_SET) < 0)
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
return -1;
/* Feed the DV video stream version of the timestamp to the */
/* DV demux so it can synthesize correct timestamps. */
ff_dv_offset_reset(avi->dv_demux, timestamp);
- avi->stream_index= -1;
+ avi->stream_index = -1;
return 0;
}
- pos_min= pos;
- for(i = 0; i < s->nb_streams; i++) {
- AVStream *st2 = s->streams[i];
+ pos_min = pos;
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st2 = s->streams[i];
AVIStream *ast2 = st2->priv_data;
- ast2->packet_size=
- ast2->remaining= 0;
+ ast2->packet_size =
+ ast2->remaining = 0;
if (ast2->sub_ctx) {
seek_subtitle(st, st2, timestamp);
@@ -1527,17 +1642,22 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
continue;
// av_assert1(st2->codec->block_align);
- av_assert0((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
- index = av_index_search_timestamp(
- st2,
- av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
- flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
- if(index<0)
- index=0;
- ast2->seek_pos= st2->index_entries[index].pos;
- pos_min= FFMIN(pos_min,ast2->seek_pos);
+ av_assert0((int64_t)st2->time_base.num * ast2->rate ==
+ (int64_t)st2->time_base.den * ast2->scale);
+ index = av_index_search_timestamp(st2,
+ av_rescale_q(timestamp,
+ st->time_base,
+ st2->time_base) *
+ FFMAX(ast2->sample_size, 1),
+ flags |
+ AVSEEK_FLAG_BACKWARD |
+ (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
+ if (index < 0)
+ index = 0;
+ ast2->seek_pos = st2->index_entries[index].pos;
+ pos_min = FFMIN(pos_min,ast2->seek_pos);
}
- for(i = 0; i < s->nb_streams; i++) {
+ for (i = 0; i < s->nb_streams; i++) {
AVStream *st2 = s->streams[i];
AVIStream *ast2 = st2->priv_data;
@@ -1548,9 +1668,9 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
st2,
av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
- if(index<0)
- index=0;
- while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
+ if (index < 0)
+ index = 0;
+ while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
index--;
ast2->frame_offset = st2->index_entries[index].timestamp;
}
@@ -1560,8 +1680,8 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
av_log(s, AV_LOG_ERROR, "Seek failed\n");
return -1;
}
- avi->stream_index= -1;
- avi->dts_max= INT_MIN;
+ avi->stream_index = -1;
+ avi->dts_max = INT_MIN;
return 0;
}
@@ -1570,8 +1690,8 @@ static int avi_read_close(AVFormatContext *s)
int i;
AVIContext *avi = s->priv_data;
- for(i=0;i<s->nb_streams;i++) {
- AVStream *st = s->streams[i];
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
AVIStream *ast = st->priv_data;
if (ast) {
if (ast->sub_ctx) {
@@ -1593,9 +1713,9 @@ static int avi_probe(AVProbeData *p)
int i;
/* check file header */
- for(i=0; avi_headers[i][0]; i++)
- if(!memcmp(p->buf , avi_headers[i] , 4) &&
- !memcmp(p->buf+8, avi_headers[i]+4, 4))
+ for (i = 0; avi_headers[i][0]; i++)
+ if (!memcmp(p->buf, avi_headers[i], 4) &&
+ !memcmp(p->buf + 8, avi_headers[i] + 4, 4))
return AVPROBE_SCORE_MAX;
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/avienc.c b/chromium/third_party/ffmpeg/libavformat/avienc.c
index f2fa9dc8a3b..3511c8181df 100644
--- a/chromium/third_party/ffmpeg/libavformat/avienc.c
+++ b/chromium/third_party/ffmpeg/libavformat/avienc.c
@@ -523,7 +523,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
int size= pkt->size;
av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index);
- while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB){
+ while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count){
AVPacket empty_packet;
if(pkt->dts - avist->packet_count > 60000){
diff --git a/chromium/third_party/ffmpeg/libavformat/avio.c b/chromium/third_party/ffmpeg/libavformat/avio.c
index f6af0cb9e6d..2c7a35eced5 100644
--- a/chromium/third_party/ffmpeg/libavformat/avio.c
+++ b/chromium/third_party/ffmpeg/libavformat/avio.c
@@ -241,6 +241,8 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags,
return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
}
*puc = NULL;
+ if (!strcmp("https", proto_str))
+ av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile with openssl or gnutls enabled.\n");
return AVERROR_PROTOCOL_NOT_FOUND;
}
@@ -271,6 +273,8 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
len = 0;
while (len < size_min) {
+ if (ff_check_interrupt(&h->interrupt_callback))
+ return AVERROR_EXIT;
ret = transfer_func(h, buf+len, size-len);
if (ret == AVERROR(EINTR))
continue;
@@ -290,12 +294,10 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
av_usleep(1000);
}
} else if (ret < 1)
- return ret < 0 ? ret : len;
+ return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
if (ret)
fast_retries = FFMAX(fast_retries, 2);
len += ret;
- if (len < size && ff_check_interrupt(&h->interrupt_callback))
- return AVERROR_EXIT;
}
return len;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/avio_internal.h b/chromium/third_party/ffmpeg/libavformat/avio_internal.h
index cf3676402b9..e67ba738122 100644
--- a/chromium/third_party/ffmpeg/libavformat/avio_internal.h
+++ b/chromium/third_party/ffmpeg/libavformat/avio_internal.h
@@ -38,6 +38,23 @@ int ffio_init_context(AVIOContext *s,
/**
+ * Read size bytes from AVIOContext, returning a pointer.
+ * Note that the data pointed at by the returned pointer is only
+ * valid until the next call that references the same IO context.
+ * @param s IO context
+ * @param buf pointer to buffer into which to assemble the requested
+ * data if it is not available in contiguous addresses in the
+ * underlying buffer
+ * @param size number of bytes requested
+ * @param data address at which to store pointer: this will be a
+ * a direct pointer into the underlying buffer if the requested
+ * number of bytes are available at contiguous addresses, otherwise
+ * will be a copy of buf
+ * @return number of bytes read or AVERROR
+ */
+int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data);
+
+/**
* Read size bytes from AVIOContext into buf.
* This reads at most 1 packet. If that is not enough fewer bytes will be
* returned.
@@ -71,6 +88,15 @@ uint64_t ffio_read_varlen(AVIOContext *bc);
/** @warning must be called before any I/O */
int ffio_set_buf_size(AVIOContext *s, int buf_size);
+/**
+ * Ensures that the requested seekback buffer size will be available
+ *
+ * Will ensure that when reading sequentially up to buf_size, seeking
+ * within the current pos and pos+buf_size is possible.
+ * Once the stream position moves outside this window this gurantee is lost.
+ */
+int ffio_ensure_seekback(AVIOContext *s, int buf_size);
+
int ffio_limit(AVIOContext *s, int size);
void ffio_init_checksum(AVIOContext *s,
diff --git a/chromium/third_party/ffmpeg/libavformat/aviobuf.c b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
index 966e0e6a3db..3707fda8bf9 100644
--- a/chromium/third_party/ffmpeg/libavformat/aviobuf.c
+++ b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
@@ -92,7 +92,7 @@ int ffio_init_context(AVIOContext *s,
s->must_flush = 0;
s->eof_reached = 0;
s->error = 0;
- s->seekable = AVIO_SEEKABLE_NORMAL;
+ s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
s->max_packet_size = 0;
s->update_checksum = NULL;
@@ -392,12 +392,11 @@ void avio_wb24(AVIOContext *s, unsigned int val)
static void fill_buffer(AVIOContext *s)
{
- uint8_t *dst = !s->max_packet_size &&
- s->buf_end - s->buffer < s->buffer_size ?
- s->buf_end : s->buffer;
- int len = s->buffer_size - (dst - s->buffer);
int max_buffer_size = s->max_packet_size ?
s->max_packet_size : IO_BUFFER_SIZE;
+ uint8_t *dst = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ?
+ s->buf_end : s->buffer;
+ int len = s->buffer_size - (dst - s->buffer);
/* can't fill the buffer without read_packet, just set EOF if appropriate */
if (!s->read_packet && s->buf_ptr >= s->buf_end)
@@ -416,10 +415,13 @@ static void fill_buffer(AVIOContext *s)
/* make buffer smaller in case it ended up large after probing */
if (s->read_packet && s->buffer_size > max_buffer_size) {
- ffio_set_buf_size(s, max_buffer_size);
+ if (dst == s->buffer) {
+ ffio_set_buf_size(s, max_buffer_size);
- s->checksum_ptr = dst = s->buffer;
- len = s->buffer_size;
+ s->checksum_ptr = dst = s->buffer;
+ }
+ av_assert0(len >= max_buffer_size);
+ len = max_buffer_size;
}
if (s->read_packet)
@@ -523,6 +525,18 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
return size1 - size;
}
+int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
+{
+ if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
+ *data = s->buf_ptr;
+ s->buf_ptr += size;
+ return size;
+ } else {
+ *data = buf;
+ return avio_read(s, buf, size);
+ }
+}
+
int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
{
int len;
@@ -723,6 +737,31 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
return 0;
}
+int ffio_ensure_seekback(AVIOContext *s, int buf_size)
+{
+ uint8_t *buffer;
+ int max_buffer_size = s->max_packet_size ?
+ s->max_packet_size : IO_BUFFER_SIZE;
+
+ buf_size += s->buf_ptr - s->buffer + max_buffer_size;
+
+ if (buf_size < s->buffer_size || s->seekable)
+ return 0;
+ av_assert0(!s->write_flag);
+
+ buffer = av_malloc(buf_size);
+ if (!buffer)
+ return AVERROR(ENOMEM);
+
+ memcpy(buffer, s->buffer, s->buffer_size);
+ av_free(s->buffer);
+ s->buf_ptr = buffer + (s->buf_ptr - s->buffer);
+ s->buf_end = buffer + (s->buf_end - s->buffer);
+ s->buffer = buffer;
+ s->buffer_size = buf_size;
+ return 0;
+}
+
int ffio_set_buf_size(AVIOContext *s, int buf_size)
{
uint8_t *buffer;
diff --git a/chromium/third_party/ffmpeg/libavformat/avisynth.c b/chromium/third_party/ffmpeg/libavformat/avisynth.c
index a5a4fcc6c98..afacf04dd18 100644
--- a/chromium/third_party/ffmpeg/libavformat/avisynth.c
+++ b/chromium/third_party/ffmpeg/libavformat/avisynth.c
@@ -36,6 +36,7 @@
#include <windows.h>
#undef EXTERN_C
#include "compat/avisynth/avisynth_c.h"
+ #include "compat/avisynth/avisynth_c_25.h"
#define AVISYNTH_LIB "avisynth"
#else
#include <dlfcn.h>
@@ -62,19 +63,20 @@
typedef struct {
void *library;
#define AVSC_DECLARE_FUNC(name) name##_func name
+ AVSC_DECLARE_FUNC(avs_bit_blt);
+ AVSC_DECLARE_FUNC(avs_clip_get_error);
AVSC_DECLARE_FUNC(avs_create_script_environment);
AVSC_DECLARE_FUNC(avs_delete_script_environment);
+ AVSC_DECLARE_FUNC(avs_get_audio);
AVSC_DECLARE_FUNC(avs_get_error);
- AVSC_DECLARE_FUNC(avs_clip_get_error);
- AVSC_DECLARE_FUNC(avs_invoke);
- AVSC_DECLARE_FUNC(avs_release_value);
+ AVSC_DECLARE_FUNC(avs_get_frame);
+ AVSC_DECLARE_FUNC(avs_get_version);
AVSC_DECLARE_FUNC(avs_get_video_info);
- AVSC_DECLARE_FUNC(avs_take_clip);
+ AVSC_DECLARE_FUNC(avs_invoke);
AVSC_DECLARE_FUNC(avs_release_clip);
- AVSC_DECLARE_FUNC(avs_bit_blt);
- AVSC_DECLARE_FUNC(avs_get_audio);
- AVSC_DECLARE_FUNC(avs_get_frame);
+ AVSC_DECLARE_FUNC(avs_release_value);
AVSC_DECLARE_FUNC(avs_release_video_frame);
+ AVSC_DECLARE_FUNC(avs_take_clip);
#undef AVSC_DECLARE_FUNC
} AviSynthLibrary;
@@ -127,19 +129,20 @@ static av_cold int avisynth_load_library(void) {
if(!continue_on_fail && !avs_library->name) \
goto fail; \
}
+ LOAD_AVS_FUNC(avs_bit_blt, 0);
+ LOAD_AVS_FUNC(avs_clip_get_error, 0);
LOAD_AVS_FUNC(avs_create_script_environment, 0);
LOAD_AVS_FUNC(avs_delete_script_environment, 0);
+ LOAD_AVS_FUNC(avs_get_audio, 0);
LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
- LOAD_AVS_FUNC(avs_clip_get_error, 0);
- LOAD_AVS_FUNC(avs_invoke, 0);
- LOAD_AVS_FUNC(avs_release_value, 0);
+ LOAD_AVS_FUNC(avs_get_frame, 0);
+ LOAD_AVS_FUNC(avs_get_version, 0);
LOAD_AVS_FUNC(avs_get_video_info, 0);
- LOAD_AVS_FUNC(avs_take_clip, 0);
+ LOAD_AVS_FUNC(avs_invoke, 0);
LOAD_AVS_FUNC(avs_release_clip, 0);
- LOAD_AVS_FUNC(avs_bit_blt, 0);
- LOAD_AVS_FUNC(avs_get_audio, 0);
- LOAD_AVS_FUNC(avs_get_frame, 0);
+ LOAD_AVS_FUNC(avs_release_value, 0);
LOAD_AVS_FUNC(avs_release_video_frame, 0);
+ LOAD_AVS_FUNC(avs_take_clip, 0);
#undef LOAD_AVS_FUNC
atexit(avisynth_atexit_handler);
@@ -239,37 +242,37 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) {
switch (avs->vi->pixel_type) {
#ifdef _WIN32
case AVS_CS_YV24:
- st->codec->pix_fmt = PIX_FMT_YUV444P;
+ st->codec->pix_fmt = AV_PIX_FMT_YUV444P;
planar = 1;
break;
case AVS_CS_YV16:
- st->codec->pix_fmt = PIX_FMT_YUV422P;
+ st->codec->pix_fmt = AV_PIX_FMT_YUV422P;
planar = 1;
break;
case AVS_CS_YV411:
- st->codec->pix_fmt = PIX_FMT_YUV411P;
+ st->codec->pix_fmt = AV_PIX_FMT_YUV411P;
planar = 1;
break;
case AVS_CS_Y8:
- st->codec->pix_fmt = PIX_FMT_GRAY8;
+ st->codec->pix_fmt = AV_PIX_FMT_GRAY8;
planar = 2;
break;
#endif
case AVS_CS_BGR24:
- st->codec->pix_fmt = PIX_FMT_BGR24;
+ st->codec->pix_fmt = AV_PIX_FMT_BGR24;
break;
case AVS_CS_BGR32:
- st->codec->pix_fmt = PIX_FMT_RGB32;
+ st->codec->pix_fmt = AV_PIX_FMT_RGB32;
break;
case AVS_CS_YUY2:
- st->codec->pix_fmt = PIX_FMT_YUYV422;
+ st->codec->pix_fmt = AV_PIX_FMT_YUYV422;
break;
case AVS_CS_YV12:
- st->codec->pix_fmt = PIX_FMT_YUV420P;
+ st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
planar = 1;
break;
case AVS_CS_I420: // Is this even used anywhere?
- st->codec->pix_fmt = PIX_FMT_YUV420P;
+ st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
planar = 1;
break;
default:
@@ -355,11 +358,22 @@ static int avisynth_open_file(AVFormatContext *s) {
AviSynthContext *avs = (AviSynthContext *)s->priv_data;
AVS_Value arg, val;
int ret;
+#ifdef _WIN32
+ char filename_ansi[MAX_PATH * 4];
+ wchar_t filename_wc[MAX_PATH * 4];
+#endif
if (ret = avisynth_context_create(s))
return ret;
+#ifdef _WIN32
+ // Convert UTF-8 to ANSI code page
+ MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wc, MAX_PATH * 4);
+ WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, MAX_PATH * 4, NULL, NULL);
+ arg = avs_new_value_string(filename_ansi);
+#else
arg = avs_new_value_string(s->filename);
+#endif
val = avs_library->avs_invoke(avs->env, "Import", arg, 0);
if (avs_is_error(val)) {
av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
@@ -458,9 +472,20 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int dis
for (i = 0; i < avs->n_planes; i++) {
plane = avs->planes[i];
src_p = avs_get_read_ptr_p(frame, plane);
+ pitch = avs_get_pitch_p(frame, plane);
+
+#ifdef _WIN32
+ if (avs_library->avs_get_version(avs->clip) == 3) {
+ rowsize = avs_get_row_size_p_25(frame, plane);
+ planeheight = avs_get_height_p_25(frame, plane);
+ } else {
+ rowsize = avs_get_row_size_p(frame, plane);
+ planeheight = avs_get_height_p(frame, plane);
+ }
+#else
rowsize = avs_get_row_size_p(frame, plane);
planeheight = avs_get_height_p(frame, plane);
- pitch = avs_get_pitch_p(frame, plane);
+#endif
// Flip RGB video.
if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {
diff --git a/chromium/third_party/ffmpeg/libavformat/avr.c b/chromium/third_party/ffmpeg/libavformat/avr.c
index 473136ec3cb..e03f1a46f7d 100644
--- a/chromium/third_party/ffmpeg/libavformat/avr.c
+++ b/chromium/third_party/ffmpeg/libavformat/avr.c
@@ -27,7 +27,7 @@
static int avr_probe(AVProbeData *p)
{
if (AV_RL32(p->buf) == MKTAG('2', 'B', 'I', 'T'))
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/avs.c b/chromium/third_party/ffmpeg/libavformat/avs.c
index ec9198b7e59..78143012444 100644
--- a/chromium/third_party/ffmpeg/libavformat/avs.c
+++ b/chromium/third_party/ffmpeg/libavformat/avs.c
@@ -50,7 +50,9 @@ static int avs_probe(AVProbeData * p)
d = p->buf;
if (d[0] == 'w' && d[1] == 'W' && d[2] == 0x10 && d[3] == 0)
- return 55;
+ /* Ensure the buffer probe scores higher than the extension probe.
+ * This avoids problems with misdetection as AviSynth scripts. */
+ return AVPROBE_SCORE_EXTENSION + 5;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/bfi.c b/chromium/third_party/ffmpeg/libavformat/bfi.c
index a28e09a4f1c..7a4f436bf37 100644
--- a/chromium/third_party/ffmpeg/libavformat/bfi.c
+++ b/chromium/third_party/ffmpeg/libavformat/bfi.c
@@ -81,6 +81,8 @@ static int bfi_read_header(AVFormatContext * s)
/*Load the palette to extradata */
avio_skip(pb, 8);
vstream->codec->extradata = av_malloc(768);
+ if (!vstream->codec->extradata)
+ return AVERROR(ENOMEM);
vstream->codec->extradata_size = 768;
avio_read(pb, vstream->codec->extradata,
vstream->codec->extradata_size);
diff --git a/chromium/third_party/ffmpeg/libavformat/bit.c b/chromium/third_party/ffmpeg/libavformat/bit.c
index 9b2246ca85e..0be471ac4f8 100644
--- a/chromium/third_party/ffmpeg/libavformat/bit.c
+++ b/chromium/third_party/ffmpeg/libavformat/bit.c
@@ -44,7 +44,7 @@ static int probe(AVProbeData *p)
return 0;
i+=j;
}
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
}
static int read_header(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/boadec.c b/chromium/third_party/ffmpeg/libavformat/boadec.c
new file mode 100644
index 00000000000..45f6b3976b8
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/boadec.c
@@ -0,0 +1,78 @@
+/*
+ * Black ops audio demuxer
+ * Copyright (c) 2013 Michael Niedermayer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+
+static int probe(AVProbeData *p)
+{
+ if (p->buf_size < 2096)
+ return 0;
+ if ( AV_RL32(p->buf ) != 1
+ || AV_RL32(p->buf + 8) > 100000
+ || AV_RL32(p->buf + 12) > 8
+ || AV_RL32(p->buf + 16) != 2096
+ ||!AV_RL32(p->buf + 21)
+ || AV_RL16(p->buf + 25) != 2096
+ || AV_RL32(p->buf + 48) % AV_RL32(p->buf + 21)
+ )
+ return 0;
+ return AVPROBE_SCORE_EXTENSION;
+}
+
+
+static int read_header(AVFormatContext *s)
+{
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_MS;
+
+ avio_rl32(s->pb);
+ avio_rl32(s->pb);
+ st->codec->sample_rate = avio_rl32(s->pb);
+ st->codec->channels = avio_rl32(s->pb);
+ s->data_offset = avio_rl32(s->pb);
+ avio_r8(s->pb);
+ st->codec->block_align = st->codec->channels * avio_rl32(s->pb);
+
+ avio_seek(s->pb, s->data_offset, SEEK_SET);
+
+ return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVStream *st = s->streams[0];
+
+ return av_get_packet(s->pb, pkt, st->codec->block_align);
+}
+
+AVInputFormat ff_boa_demuxer = {
+ .name = "boa",
+ .long_name = NULL_IF_CONFIG_SMALL("Black Ops Audio"),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .flags = AVFMT_GENERIC_INDEX,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/cafenc.c b/chromium/third_party/ffmpeg/libavformat/cafenc.c
index 11bb0559657..cd3a0be907f 100644
--- a/chromium/third_party/ffmpeg/libavformat/cafenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/cafenc.c
@@ -86,8 +86,9 @@ static uint32_t samples_per_packet(enum AVCodecID codec_id, int channels) {
return 1152;
case AV_CODEC_ID_AC3:
return 1536;
- case AV_CODEC_ID_ALAC:
case AV_CODEC_ID_QDM2:
+ return 2048 * channels;
+ case AV_CODEC_ID_ALAC:
return 4096;
case AV_CODEC_ID_ADPCM_IMA_WAV:
return (1024 - 4 * channels) * 8 / (4 * channels) + 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/cavsvideodec.c b/chromium/third_party/ffmpeg/libavformat/cavsvideodec.c
index c035128bcf3..5ca3c80b32f 100644
--- a/chromium/third_party/ffmpeg/libavformat/cavsvideodec.c
+++ b/chromium/third_party/ffmpeg/libavformat/cavsvideodec.c
@@ -61,7 +61,7 @@ static int cavsvideo_probe(AVProbeData *p)
}
}
if(seq && seq*9<=pic*10)
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/cdxl.c b/chromium/third_party/ffmpeg/libavformat/cdxl.c
index 185b745bb00..ab8a846cc51 100644
--- a/chromium/third_party/ffmpeg/libavformat/cdxl.c
+++ b/chromium/third_party/ffmpeg/libavformat/cdxl.c
@@ -41,7 +41,7 @@ typedef struct CDXLDemuxContext {
static int cdxl_read_probe(AVProbeData *p)
{
- int score = AVPROBE_SCORE_MAX / 2 + 10;
+ int score = AVPROBE_SCORE_EXTENSION + 10;
if (p->buf_size < CDXL_HEADER_SIZE)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/concatdec.c b/chromium/third_party/ffmpeg/libavformat/concatdec.c
index 5359ad149d4..428c749ab24 100644
--- a/chromium/third_party/ffmpeg/libavformat/concatdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/concatdec.c
@@ -23,6 +23,7 @@
#include "libavutil/parseutils.h"
#include "avformat.h"
#include "internal.h"
+#include "url.h"
typedef struct {
char *url;
@@ -216,6 +217,8 @@ static int concat_read_header(AVFormatContext *avf)
}
if (ret < 0)
FAIL(ret);
+ if (!cat->nb_files)
+ FAIL(AVERROR_INVALIDDATA);
for (i = 0; i < cat->nb_files; i++) {
if (cat->files[i].start_time == AV_NOPTS_VALUE)
@@ -341,7 +344,7 @@ static int real_seek(AVFormatContext *avf, int stream,
return ret;
ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
- if (ret < 0 && !(flags & AVSEEK_FLAG_BACKWARD) &&
+ if (ret < 0 &&
left < cat->nb_files - 1 &&
cat->files[left + 1].start_time < max_ts) {
if ((ret = open_file(avf, left + 1)) < 0)
diff --git a/chromium/third_party/ffmpeg/libavformat/dtsdec.c b/chromium/third_party/ffmpeg/libavformat/dtsdec.c
index 5c05758327f..23cbe93516a 100644
--- a/chromium/third_party/ffmpeg/libavformat/dtsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/dtsdec.c
@@ -34,6 +34,7 @@ static int dts_probe(AVProbeData *p)
uint32_t state = -1;
int markers[3] = {0};
int sum, max;
+ int64_t diff = 0;
buf = p->buf;
@@ -54,13 +55,17 @@ static int dts_probe(AVProbeData *p)
if (state == DCA_MARKER_14B_LE)
if ((bytestream_get_be16(&bufp) & 0xF0FF) == 0xF007)
markers[2]++;
+
+ if (buf - p->buf >= 4)
+ diff += FFABS(AV_RL16(buf) - AV_RL16(buf-4));
}
sum = markers[0] + markers[1] + markers[2];
max = markers[1] > markers[0];
max = markers[2] > markers[max] ? 2 : max;
if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 &&
- markers[max] * 4 > sum * 3)
- return AVPROBE_SCORE_MAX/2+1;
+ markers[max] * 4 > sum * 3 &&
+ diff / p->buf_size > 200)
+ return AVPROBE_SCORE_EXTENSION + 1;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/dv.c b/chromium/third_party/ffmpeg/libavformat/dv.c
index a04735ac252..cc48f483eb8 100644
--- a/chromium/third_party/ffmpeg/libavformat/dv.c
+++ b/chromium/third_party/ffmpeg/libavformat/dv.c
@@ -65,7 +65,7 @@ static inline uint16_t dv_audio_12to16(uint16_t sample)
shift--;
result = (sample - (256 * shift)) << shift;
} else {
- shift = 0xe - shift;
+ shift = 0xe - shift;
result = ((sample + ((256 * shift) + 1)) << shift) - 1;
}
@@ -77,19 +77,19 @@ static inline uint16_t dv_audio_12to16(uint16_t sample)
* a fixed offset and if pack isn't there -- fails. We might want
* to have a fallback mechanism for complete search of missing packs.
*/
-static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
+static const uint8_t *dv_extract_pack(uint8_t *frame, enum dv_pack_type t)
{
int offs;
switch (t) {
case dv_audio_source:
- offs = (80*6 + 80*16*3 + 3);
+ offs = (80 * 6 + 80 * 16 * 3 + 3);
break;
case dv_audio_control:
- offs = (80*6 + 80*16*4 + 3);
+ offs = (80 * 6 + 80 * 16 * 4 + 3);
break;
case dv_video_control:
- offs = (80*5 + 48 + 5);
+ offs = (80 * 5 + 48 + 5);
break;
case dv_timecode:
offs = (80*1 + 3 + 3);
@@ -113,29 +113,29 @@ static const int dv_audio_frequency[3] = {
* 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
* are converted into 16bit linear ones.
*/
-static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
+static int dv_extract_audio(uint8_t *frame, uint8_t *ppcm[4],
const DVprofile *sys)
{
int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
uint16_t lc, rc;
- const uint8_t* as_pack;
+ const uint8_t *as_pack;
uint8_t *pcm, ipcm;
as_pack = dv_extract_pack(frame, dv_audio_source);
if (!as_pack) /* No audio ? */
return 0;
- smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
- freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
- quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
+ smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
+ freq = as_pack[4] >> 3 & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
+ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
if (quant > 1)
- return -1; /* unsupported quantization */
+ return -1; /* unsupported quantization */
if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
return AVERROR_INVALIDDATA;
- size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
+ size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
half_ch = sys->difseg_size / 2;
/* We work with 720p frames split in half, thus even frames have
@@ -169,32 +169,41 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
for (j = 0; j < 9; j++) {
for (d = 8; d < 80; d += 2) {
if (quant == 0) { /* 16bit quantization */
- of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
- if (of*2 >= size)
+ of = sys->audio_shuffle[i][j] +
+ (d - 8) / 2 * sys->audio_stride;
+ if (of * 2 >= size)
continue;
- pcm[of*2] = frame[d+1]; // FIXME: maybe we have to admit
- pcm[of*2+1] = frame[d]; // that DV is a big-endian PCM
- if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
- pcm[of*2+1] = 0;
+ /* FIXME: maybe we have to admit that DV is a
+ * big-endian PCM */
+ pcm[of * 2] = frame[d + 1];
+ pcm[of * 2 + 1] = frame[d];
+
+ if (pcm[of * 2 + 1] == 0x80 && pcm[of * 2] == 0x00)
+ pcm[of * 2 + 1] = 0;
} else { /* 12bit quantization */
- lc = ((uint16_t)frame[d] << 4) |
- ((uint16_t)frame[d+2] >> 4);
- rc = ((uint16_t)frame[d+1] << 4) |
- ((uint16_t)frame[d+2] & 0x0f);
+ lc = ((uint16_t)frame[d] << 4) |
+ ((uint16_t)frame[d + 2] >> 4);
+ rc = ((uint16_t)frame[d + 1] << 4) |
+ ((uint16_t)frame[d + 2] & 0x0f);
lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
- of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
- if (of*2 >= size)
+ of = sys->audio_shuffle[i % half_ch][j] +
+ (d - 8) / 3 * sys->audio_stride;
+ if (of * 2 >= size)
continue;
- pcm[of*2] = lc & 0xff; // FIXME: maybe we have to admit
- pcm[of*2+1] = lc >> 8; // that DV is a big-endian PCM
- of = sys->audio_shuffle[i%half_ch+half_ch][j] +
- (d - 8) / 3 * sys->audio_stride;
- pcm[of*2] = rc & 0xff; // FIXME: maybe we have to admit
- pcm[of*2+1] = rc >> 8; // that DV is a big-endian PCM
+ /* FIXME: maybe we have to admit that DV is a
+ * big-endian PCM */
+ pcm[of * 2] = lc & 0xff;
+ pcm[of * 2 + 1] = lc >> 8;
+ of = sys->audio_shuffle[i % half_ch + half_ch][j] +
+ (d - 8) / 3 * sys->audio_stride;
+ /* FIXME: maybe we have to admit that DV is a
+ * big-endian PCM */
+ pcm[of * 2] = rc & 0xff;
+ pcm[of * 2 + 1] = rc >> 8;
++d;
}
}
@@ -207,9 +216,9 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
return size;
}
-static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
+static int dv_extract_audio_info(DVDemuxContext *c, uint8_t *frame)
{
- const uint8_t* as_pack;
+ const uint8_t *as_pack;
int freq, stype, smpls, quant, i, ach;
as_pack = dv_extract_pack(frame, dv_audio_source);
@@ -218,10 +227,10 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
return 0;
}
- smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
- freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
- stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
- quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
+ smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
+ freq = as_pack[4] >> 3 & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
+ stype = as_pack[3] & 0x1f; /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
+ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
av_log(c->fctx, AV_LOG_ERROR,
@@ -236,7 +245,7 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
}
/* note: ach counts PAIRS of channels (i.e. stereo channels) */
- ach = ((int[4]){ 1, 0, 2, 4})[stype];
+ ach = ((int[4]) { 1, 0, 2, 4 })[stype];
if (ach == 1 && quant && freq == 2)
ach = 2;
@@ -256,21 +265,21 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
c->audio_pkt[i].stream_index = c->ast[i]->index;
c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY;
}
- c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
- c->ast[i]->codec->channels = 2;
+ c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
+ c->ast[i]->codec->channels = 2;
c->ast[i]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
- c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;
- c->ast[i]->start_time = 0;
+ c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;
+ c->ast[i]->start_time = 0;
}
c->ach = i;
- return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */;
+ return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
}
-static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
+static int dv_extract_video_info(DVDemuxContext *c, uint8_t *frame)
{
- const uint8_t* vsc_pack;
- AVCodecContext* avctx;
+ const uint8_t *vsc_pack;
+ AVCodecContext *avctx;
int apt, is16_9;
int size = 0;
@@ -279,7 +288,7 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
c->sys->time_base.den);
- avctx->time_base= c->sys->time_base;
+ avctx->time_base = c->sys->time_base;
/* finding out SAR is a little bit messy */
vsc_pack = dv_extract_pack(frame, dv_video_control);
@@ -287,7 +296,8 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
(!apt && (vsc_pack[2] & 0x07) == 0x07)));
c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
- avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
+ avctx->bit_rate = av_rescale_q(c->sys->frame_size,
+ (AVRational) { 8, 1 },
c->sys->time_base);
size = c->sys->frame_size;
}
@@ -310,11 +320,9 @@ static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char *tc)
return 1;
}
-/*
- * The following 3 functions constitute our interface to the world
- */
+/* The following 3 functions constitute our interface to the world */
-DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
+DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s)
{
DVDemuxContext *c;
@@ -344,9 +352,9 @@ int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
for (i = 0; i < c->ach; i++) {
if (c->ast[i] && c->audio_pkt[i].size) {
- *pkt = c->audio_pkt[i];
+ *pkt = c->audio_pkt[i];
c->audio_pkt[i].size = 0;
- size = pkt->size;
+ size = pkt->size;
break;
}
}
@@ -355,10 +363,10 @@ int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
}
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
- uint8_t* buf, int buf_size, int64_t pos)
+ uint8_t *buf, int buf_size, int64_t pos)
{
int size, i;
- uint8_t *ppcm[4] = {0};
+ uint8_t *ppcm[4] = { 0 };
if (buf_size < DV_PROFILE_BYTES ||
!(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
@@ -372,7 +380,8 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
for (i = 0; i < c->ach; i++) {
c->audio_pkt[i].pos = pos;
c->audio_pkt[i].size = size;
- c->audio_pkt[i].pts = c->abytes * 30000 * 8 / c->ast[i]->codec->bit_rate;
+ c->audio_pkt[i].pts = c->abytes * 30000 * 8 /
+ c->ast[i]->codec->bit_rate;
ppcm[i] = c->audio_buf[i];
}
if (c->ach)
@@ -385,7 +394,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
} else {
c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
- c->abytes += size;
+ c->abytes += size;
}
} else {
c->abytes += size;
@@ -407,30 +416,32 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
}
static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
- int64_t timestamp, int flags)
+ int64_t timestamp, int flags)
{
// FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
- const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
+ const DVprofile *sys = avpriv_dv_codec_profile(c->vst->codec);
int64_t offset;
- int64_t size = avio_size(s->pb) - s->data_offset;
- int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
+ int64_t size = avio_size(s->pb) - s->data_offset;
+ int64_t max_offset = ((size - 1) / sys->frame_size) * sys->frame_size;
offset = sys->frame_size * timestamp;
- if (size >= 0 && offset > max_offset) offset = max_offset;
- else if (offset < 0) offset = 0;
+ if (size >= 0 && offset > max_offset)
+ offset = max_offset;
+ else if (offset < 0)
+ offset = 0;
return offset + s->data_offset;
}
void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
{
- c->frames= frame_offset;
+ c->frames = frame_offset;
if (c->ach) {
if (c->sys) {
- c->abytes= av_rescale_q(c->frames, c->sys->time_base,
- (AVRational){8, c->ast[0]->codec->bit_rate});
- }else
+ c->abytes = av_rescale_q(c->frames, c->sys->time_base,
+ (AVRational) { 8, c->ast[0]->codec->bit_rate });
+ } else
av_log(c->fctx, AV_LOG_ERROR, "cannot adjust audio bytes\n");
}
c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
@@ -442,7 +453,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;
@@ -508,13 +519,17 @@ static int dv_read_header(AVFormatContext *s)
avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
return AVERROR(EIO);
- c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
+ c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys,
+ c->buf,
+ DV_PROFILE_BYTES);
if (!c->dv_demux->sys) {
- av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
+ av_log(s, AV_LOG_ERROR,
+ "Can't determine profile of DV input stream.\n");
return -1;
}
- s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
+ s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size,
+ (AVRational) { 8, 1 },
c->dv_demux->sys->time_base);
if (s->pb->seekable)
@@ -523,7 +538,6 @@ static int dv_read_header(AVFormatContext *s)
return 0;
}
-
static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int size;
@@ -546,7 +560,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
}
static int dv_read_seek(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
+ int64_t timestamp, int flags)
{
RawDVContext *r = s->priv_data;
DVDemuxContext *c = r->dv_demux;
@@ -570,7 +584,7 @@ static int dv_probe(AVProbeData *p)
{
unsigned state, marker_pos = 0;
int i;
- int matches = 0;
+ int matches = 0;
int secondary_matches = 0;
if (p->buf_size < 5)
@@ -591,10 +605,13 @@ static int dv_probe(AVProbeData *p)
state = (state << 8) | p->buf[i];
}
- if (matches && p->buf_size / matches < 1024*1024) {
- if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
- return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match
- return AVPROBE_SCORE_MAX/4;
+ if (matches && p->buf_size / matches < 1024 * 1024) {
+ if (matches > 4 ||
+ (secondary_matches >= 10 &&
+ p->buf_size / secondary_matches < 24000))
+ // not max to avoid dv in mov to match
+ return AVPROBE_SCORE_MAX * 3 / 4;
+ return AVPROBE_SCORE_MAX / 4;
}
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/electronicarts.c b/chromium/third_party/ffmpeg/libavformat/electronicarts.c
index dae40b1dd99..69e4cbf952e 100644
--- a/chromium/third_party/ffmpeg/libavformat/electronicarts.c
+++ b/chromium/third_party/ffmpeg/libavformat/electronicarts.c
@@ -30,35 +30,35 @@
#include "internal.h"
#define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
-#define SEAD_TAG MKTAG('S', 'E', 'A', 'D') /* Sxxx header */
-#define SNDC_TAG MKTAG('S', 'N', 'D', 'C') /* Sxxx data */
-#define SEND_TAG MKTAG('S', 'E', 'N', 'D') /* Sxxx end */
-#define SHEN_TAG MKTAG('S', 'H', 'E', 'N') /* SxEN header */
-#define SDEN_TAG MKTAG('S', 'D', 'E', 'N') /* SxEN data */
-#define SEEN_TAG MKTAG('S', 'E', 'E', 'N') /* SxEN end */
-#define ISNh_TAG MKTAG('1', 'S', 'N', 'h') /* 1SNx header */
+#define SEAD_TAG MKTAG('S', 'E', 'A', 'D') /* Sxxx header */
+#define SNDC_TAG MKTAG('S', 'N', 'D', 'C') /* Sxxx data */
+#define SEND_TAG MKTAG('S', 'E', 'N', 'D') /* Sxxx end */
+#define SHEN_TAG MKTAG('S', 'H', 'E', 'N') /* SxEN header */
+#define SDEN_TAG MKTAG('S', 'D', 'E', 'N') /* SxEN data */
+#define SEEN_TAG MKTAG('S', 'E', 'E', 'N') /* SxEN end */
+#define ISNh_TAG MKTAG('1', 'S', 'N', 'h') /* 1SNx header */
#define EACS_TAG MKTAG('E', 'A', 'C', 'S')
-#define ISNd_TAG MKTAG('1', 'S', 'N', 'd') /* 1SNx data */
-#define ISNe_TAG MKTAG('1', 'S', 'N', 'e') /* 1SNx end */
+#define ISNd_TAG MKTAG('1', 'S', 'N', 'd') /* 1SNx data */
+#define ISNe_TAG MKTAG('1', 'S', 'N', 'e') /* 1SNx end */
#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
#define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
#define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
#define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
-#define kVGT_TAG MKTAG('k', 'V', 'G', 'T') /* TGV i-frame */
-#define fVGT_TAG MKTAG('f', 'V', 'G', 'T') /* TGV p-frame */
-#define mTCD_TAG MKTAG('m', 'T', 'C', 'D') /* MDEC */
-#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */
-#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */
-#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */
-#define MPCh_TAG MKTAG('M', 'P', 'C', 'h') /* MPEG2 */
-#define TGQs_TAG MKTAG('T', 'G', 'Q', 's') /* TGQ i-frame (appears in .TGQ files) */
-#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T') /* TGQ i-frame (appears in .UV files) */
-#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T') /* TQI/UV2 i-frame (.UV2/.WVE) */
+#define kVGT_TAG MKTAG('k', 'V', 'G', 'T') /* TGV I-frame */
+#define fVGT_TAG MKTAG('f', 'V', 'G', 'T') /* TGV P-frame */
+#define mTCD_TAG MKTAG('m', 'T', 'C', 'D') /* MDEC */
+#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD I-frame */
+#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD P-frame */
+#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */
+#define MPCh_TAG MKTAG('M', 'P', 'C', 'h') /* MPEG-2 */
+#define TGQs_TAG MKTAG('T', 'G', 'Q', 's') /* TGQ I-frame (appears in .TGQ files) */
+#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T') /* TGQ I-frame (appears in .UV files) */
+#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T') /* TQI/UV2 I-frame (.UV2/.WVE) */
#define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
#define MV0K_TAG MKTAG('M', 'V', '0', 'K')
#define MV0F_TAG MKTAG('M', 'V', '0', 'F')
-#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */
-#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV i-frame */
+#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */
+#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV I-frame */
typedef struct EaDemuxContext {
int big_endian;
@@ -78,7 +78,8 @@ typedef struct EaDemuxContext {
int num_samples;
} EaDemuxContext;
-static uint32_t read_arbitary(AVIOContext *pb) {
+static uint32_t read_arbitrary(AVIOContext *pb)
+{
uint8_t size, byte;
int i;
uint32_t word;
@@ -87,108 +88,135 @@ static uint32_t read_arbitary(AVIOContext *pb) {
word = 0;
for (i = 0; i < size; i++) {
- byte = avio_r8(pb);
+ byte = avio_r8(pb);
word <<= 8;
- word |= byte;
+ word |= byte;
}
return word;
}
-/*
- * Process PT/GSTR sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
static int process_audio_header_elements(AVFormatContext *s)
{
- int inHeader = 1;
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
+ int in_header = 1;
int compression_type = -1, revision = -1, revision2 = -1;
- ea->bytes = 2;
- ea->sample_rate = -1;
+ ea->bytes = 2;
+ ea->sample_rate = -1;
ea->num_channels = 1;
- while (!url_feof(pb) && inHeader) {
- int inSubheader;
+ while (!url_feof(pb) && in_header) {
+ int in_subheader;
uint8_t byte;
byte = avio_r8(pb);
switch (byte) {
case 0xFD:
- av_log (s, AV_LOG_DEBUG, "entered audio subheader\n");
- inSubheader = 1;
- while (!url_feof(pb) && inSubheader) {
+ av_log(s, AV_LOG_DEBUG, "entered audio subheader\n");
+ in_subheader = 1;
+ while (!url_feof(pb) && in_subheader) {
uint8_t subbyte;
subbyte = avio_r8(pb);
switch (subbyte) {
case 0x80:
- revision = read_arbitary(pb);
- av_log (s, AV_LOG_DEBUG, "revision (element 0x80) set to 0x%08x\n", revision);
+ revision = read_arbitrary(pb);
+ av_log(s, AV_LOG_DEBUG,
+ "revision (element 0x80) set to 0x%08x\n", revision);
break;
case 0x82:
- ea->num_channels = read_arbitary(pb);
- av_log (s, AV_LOG_DEBUG, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels);
+ ea->num_channels = read_arbitrary(pb);
+ av_log(s, AV_LOG_DEBUG,
+ "num_channels (element 0x82) set to 0x%08x\n",
+ ea->num_channels);
break;
case 0x83:
- compression_type = read_arbitary(pb);
- av_log (s, AV_LOG_DEBUG, "compression_type (element 0x83) set to 0x%08x\n", compression_type);
+ compression_type = read_arbitrary(pb);
+ av_log(s, AV_LOG_DEBUG,
+ "compression_type (element 0x83) set to 0x%08x\n",
+ compression_type);
break;
case 0x84:
- ea->sample_rate = read_arbitary(pb);
- av_log (s, AV_LOG_DEBUG, "sample_rate (element 0x84) set to %i\n", ea->sample_rate);
+ ea->sample_rate = read_arbitrary(pb);
+ av_log(s, AV_LOG_DEBUG,
+ "sample_rate (element 0x84) set to %i\n",
+ ea->sample_rate);
break;
case 0x85:
- ea->num_samples = read_arbitary(pb);
- av_log (s, AV_LOG_DEBUG, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples);
+ ea->num_samples = read_arbitrary(pb);
+ av_log(s, AV_LOG_DEBUG,
+ "num_samples (element 0x85) set to 0x%08x\n",
+ ea->num_samples);
break;
case 0x8A:
- av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
- av_log (s, AV_LOG_DEBUG, "exited audio subheader\n");
- inSubheader = 0;
+ av_log(s, AV_LOG_DEBUG,
+ "element 0x%02x set to 0x%08x\n",
+ subbyte, read_arbitrary(pb));
+ av_log(s, AV_LOG_DEBUG, "exited audio subheader\n");
+ in_subheader = 0;
break;
case 0xA0:
- revision2 = read_arbitary(pb);
- av_log (s, AV_LOG_DEBUG, "revision2 (element 0xA0) set to 0x%08x\n", revision2);
+ revision2 = read_arbitrary(pb);
+ av_log(s, AV_LOG_DEBUG,
+ "revision2 (element 0xA0) set to 0x%08x\n",
+ revision2);
break;
case 0xFF:
- av_log (s, AV_LOG_DEBUG, "end of header block reached (within audio subheader)\n");
- inSubheader = 0;
- inHeader = 0;
+ av_log(s, AV_LOG_DEBUG,
+ "end of header block reached (within audio subheader)\n");
+ in_subheader = 0;
+ in_header = 0;
break;
default:
- av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
+ av_log(s, AV_LOG_DEBUG,
+ "element 0x%02x set to 0x%08x\n",
+ subbyte, read_arbitrary(pb));
break;
}
}
break;
case 0xFF:
- av_log (s, AV_LOG_DEBUG, "end of header block reached\n");
- inHeader = 0;
+ av_log(s, AV_LOG_DEBUG, "end of header block reached\n");
+ in_header = 0;
break;
default:
- av_log (s, AV_LOG_DEBUG, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb));
+ av_log(s, AV_LOG_DEBUG,
+ "header element 0x%02x set to 0x%08x\n",
+ byte, read_arbitrary(pb));
break;
}
}
switch (compression_type) {
- case 0: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break;
- case 7: ea->audio_codec = AV_CODEC_ID_ADPCM_EA; break;
+ case 0:
+ ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
+ break;
+ case 7:
+ ea->audio_codec = AV_CODEC_ID_ADPCM_EA;
+ break;
case -1:
switch (revision) {
- case 1: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break;
- case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
- case 3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3; break;
- case -1: break;
+ case 1:
+ ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1;
+ break;
+ case 2:
+ ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2;
+ break;
+ case 3:
+ ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3;
+ break;
+ case -1:
+ break;
default:
avpriv_request_sample(s, "stream type; revision=%i", revision);
return 0;
}
switch (revision2) {
- case 8: ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
+ case 8:
+ ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR;
+ break;
case 10:
switch (revision) {
case -1:
@@ -199,8 +227,11 @@ static int process_audio_header_elements(AVFormatContext *s)
return 0;
}
break;
- case 16: ea->audio_codec = AV_CODEC_ID_MP3; break;
- case -1: break;
+ case 16:
+ ea->audio_codec = AV_CODEC_ID_MP3;
+ break;
+ case -1:
+ break;
default:
ea->audio_codec = AV_CODEC_ID_NONE;
avpriv_request_sample(s, "stream type; revision2=%i", revision2);
@@ -208,24 +239,22 @@ static int process_audio_header_elements(AVFormatContext *s)
}
break;
default:
- avpriv_request_sample(s, "stream type; compression_type=%i", compression_type);
+ avpriv_request_sample(s,
+ "stream type; compression_type=%i",
+ compression_type);
return 0;
}
if (ea->sample_rate == -1)
- ea->sample_rate = revision==3 ? 48000 : 22050;
+ ea->sample_rate = revision == 3 ? 48000 : 22050;
return 1;
}
-/*
- * Process EACS sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
-static int process_audio_header_eacs(AVFormatContext *s)
+static void process_audio_header_eacs(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
int compression_type;
ea->sample_rate = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
@@ -237,52 +266,54 @@ static int process_audio_header_eacs(AVFormatContext *s)
switch (compression_type) {
case 0:
switch (ea->bytes) {
- case 1: ea->audio_codec = AV_CODEC_ID_PCM_S8; break;
- case 2: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break;
+ case 1:
+ ea->audio_codec = AV_CODEC_ID_PCM_S8;
+ break;
+ case 2:
+ ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
+ break;
}
break;
- case 1: ea->audio_codec = AV_CODEC_ID_PCM_MULAW; ea->bytes = 1; break;
- case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS; break;
+ case 1:
+ ea->audio_codec = AV_CODEC_ID_PCM_MULAW;
+ ea->bytes = 1;
+ break;
+ case 2:
+ ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS;
+ break;
default:
- avpriv_request_sample(s, "stream type; audio compression_type=%i", compression_type);
+ avpriv_request_sample(s,
+ "stream type; audio compression_type=%i",
+ compression_type);
}
-
- return 1;
}
-/*
- * Process SEAD sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
-static int process_audio_header_sead(AVFormatContext *s)
+static void process_audio_header_sead(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
ea->sample_rate = avio_rl32(pb);
ea->bytes = avio_rl32(pb); /* 1=8-bit, 2=16-bit */
ea->num_channels = avio_rl32(pb);
ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
-
- return 1;
}
-static int process_video_header_mdec(AVFormatContext *s)
+static void process_video_header_mdec(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
avio_skip(pb, 4);
- ea->width = avio_rl16(pb);
- ea->height = avio_rl16(pb);
- ea->time_base = (AVRational){1,15};
+ ea->width = avio_rl16(pb);
+ ea->height = avio_rl16(pb);
+ ea->time_base = (AVRational) { 1, 15 };
ea->video_codec = AV_CODEC_ID_MDEC;
- return 1;
}
static int process_video_header_vp6(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
avio_skip(pb, 8);
ea->nb_frames = avio_rl32(pb);
@@ -293,12 +324,12 @@ static int process_video_header_vp6(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
return AVERROR_INVALIDDATA;
}
- ea->video_codec = AV_CODEC_ID_VP6;
+ ea->video_codec = AV_CODEC_ID_VP6;
return 1;
}
-static int process_video_header_cmv(AVFormatContext *s)
+static void process_video_header_cmv(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
int fps;
@@ -306,90 +337,87 @@ static int process_video_header_cmv(AVFormatContext *s)
avio_skip(s->pb, 10);
fps = avio_rl16(s->pb);
if (fps)
- ea->time_base = (AVRational){1, fps};
+ ea->time_base = (AVRational) { 1, fps };
ea->video_codec = AV_CODEC_ID_CMV;
-
- return 0;
}
-/*
- * Process EA file header
- * Returns 1 if the EA file is valid and successfully opened, 0 otherwise
- */
-static int process_ea_header(AVFormatContext *s) {
+/* Process EA file header.
+ * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
+static int process_ea_header(AVFormatContext *s)
+{
uint32_t blockid, size = 0;
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
int i;
- for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) {
+ for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
unsigned int startpos = avio_tell(pb);
- int err = 0;
+ int err = 0;
blockid = avio_rl32(pb);
- size = avio_rl32(pb);
+ size = avio_rl32(pb);
if (i == 0)
ea->big_endian = size > 0x000FFFFF;
if (ea->big_endian)
size = av_bswap32(size);
switch (blockid) {
- case ISNh_TAG:
- if (avio_rl32(pb) != EACS_TAG) {
- avpriv_request_sample(s, "unknown 1SNh headerid");
- return 0;
- }
- err = process_audio_header_eacs(s);
- break;
+ case ISNh_TAG:
+ if (avio_rl32(pb) != EACS_TAG) {
+ avpriv_request_sample(s, "unknown 1SNh headerid");
+ return 0;
+ }
+ process_audio_header_eacs(s);
+ break;
- case SCHl_TAG :
- case SHEN_TAG :
- blockid = avio_rl32(pb);
- if (blockid == GSTR_TAG) {
- avio_skip(pb, 4);
- } else if ((blockid & 0xFFFF)!=PT00_TAG) {
- avpriv_request_sample(s, "unknown SCHl headerid");
- return 0;
- }
- err = process_audio_header_elements(s);
- break;
+ case SCHl_TAG:
+ case SHEN_TAG:
+ blockid = avio_rl32(pb);
+ if (blockid == GSTR_TAG) {
+ avio_skip(pb, 4);
+ } else if ((blockid & 0xFFFF) != PT00_TAG) {
+ avpriv_request_sample(s, "unknown SCHl headerid");
+ return 0;
+ }
+ err = process_audio_header_elements(s);
+ break;
- case SEAD_TAG:
- err = process_audio_header_sead(s);
- break;
+ case SEAD_TAG:
+ process_audio_header_sead(s);
+ break;
- case MVIh_TAG :
- err = process_video_header_cmv(s);
- break;
+ case MVIh_TAG:
+ process_video_header_cmv(s);
+ break;
- case kVGT_TAG:
- ea->video_codec = AV_CODEC_ID_TGV;
- break;
+ case kVGT_TAG:
+ ea->video_codec = AV_CODEC_ID_TGV;
+ break;
- case mTCD_TAG :
- err = process_video_header_mdec(s);
- break;
+ case mTCD_TAG:
+ process_video_header_mdec(s);
+ break;
- case MPCh_TAG:
- ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
- break;
+ case MPCh_TAG:
+ ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
+ break;
- case pQGT_TAG:
- case TGQs_TAG:
- ea->video_codec = AV_CODEC_ID_TGQ;
- break;
+ case pQGT_TAG:
+ case TGQs_TAG:
+ ea->video_codec = AV_CODEC_ID_TGQ;
+ break;
- case pIQT_TAG:
- ea->video_codec = AV_CODEC_ID_TQI;
- break;
+ case pIQT_TAG:
+ ea->video_codec = AV_CODEC_ID_TQI;
+ break;
- case MADk_TAG :
- ea->video_codec = AV_CODEC_ID_MAD;
- break;
+ case MADk_TAG:
+ ea->video_codec = AV_CODEC_ID_MAD;
+ break;
- case MVhd_TAG :
- err = process_video_header_vp6(s);
- break;
+ case MVhd_TAG:
+ err = process_video_header_vp6(s);
+ break;
}
if (err < 0) {
@@ -405,7 +433,6 @@ static int process_ea_header(AVFormatContext *s) {
return 1;
}
-
static int ea_probe(AVProbeData *p)
{
switch (AV_RL32(&p->buf[0])) {
@@ -424,6 +451,7 @@ static int ea_probe(AVProbeData *p)
}
if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff)
return 0;
+
return AVPROBE_SCORE_MAX;
}
@@ -441,34 +469,37 @@ static int ea_read_header(AVFormatContext *s)
if (!st)
return AVERROR(ENOMEM);
ea->video_stream_index = st->index;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = ea->video_codec;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = ea->video_codec;
// parsing is necessary to make FFmpeg generate correct timestamps
if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
- st->codec->codec_tag = 0; /* no fourcc */
- st->codec->width = ea->width;
- st->codec->height = ea->height;
- st->duration = st->nb_frames = ea->nb_frames;
+ st->codec->codec_tag = 0; /* no fourcc */
+ st->codec->width = ea->width;
+ st->codec->height = ea->height;
+ st->duration = st->nb_frames = ea->nb_frames;
if (ea->time_base.num)
avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
- st->r_frame_rate =
- st->avg_frame_rate = av_inv_q(ea->time_base);
+ st->r_frame_rate =
+ st->avg_frame_rate = av_inv_q(ea->time_base);
}
if (ea->audio_codec) {
if (ea->num_channels <= 0) {
- av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels);
+ av_log(s, AV_LOG_WARNING,
+ "Unsupported number of channels: %d\n", ea->num_channels);
ea->audio_codec = 0;
return 1;
}
if (ea->sample_rate <= 0) {
- av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate);
+ av_log(s, AV_LOG_ERROR,
+ "Unsupported sample rate: %d\n", ea->sample_rate);
ea->audio_codec = 0;
return 1;
}
if (ea->bytes <= 0) {
- av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes);
+ av_log(s, AV_LOG_ERROR,
+ "Invalid number of bytes per sample: %d\n", ea->bytes);
ea->audio_codec = AV_CODEC_ID_NONE;
return 1;
}
@@ -478,32 +509,31 @@ static int ea_read_header(AVFormatContext *s)
if (!st)
return AVERROR(ENOMEM);
avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = ea->audio_codec;
- st->codec->codec_tag = 0; /* no tag */
- st->codec->channels = ea->num_channels;
- st->codec->sample_rate = ea->sample_rate;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = ea->audio_codec;
+ st->codec->codec_tag = 0; /* no tag */
+ st->codec->channels = ea->num_channels;
+ st->codec->sample_rate = ea->sample_rate;
st->codec->bits_per_coded_sample = ea->bytes * 8;
- st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
- st->codec->bits_per_coded_sample / 4;
- st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample;
- ea->audio_stream_index = st->index;
- st->start_time = 0;
+ st->codec->bit_rate = st->codec->channels *
+ st->codec->sample_rate *
+ st->codec->bits_per_coded_sample / 4;
+ st->codec->block_align = st->codec->channels *
+ st->codec->bits_per_coded_sample;
+ ea->audio_stream_index = st->index;
+ st->start_time = 0;
}
return 1;
}
-static int ea_read_packet(AVFormatContext *s,
- AVPacket *pkt)
+static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
{
EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
- int ret = 0;
- int packet_read = 0;
+ AVIOContext *pb = s->pb;
int partial_packet = 0;
unsigned int chunk_type, chunk_size;
- int key = 0;
+ int ret = 0, packet_read = 0, key = 0;
int av_uninit(num_samples);
while (!packet_read || partial_packet) {
@@ -516,7 +546,7 @@ static int ea_read_packet(AVFormatContext *s,
switch (chunk_type) {
/* audio data */
case ISNh_TAG:
- /* header chunk also contains data; skip over the header portion*/
+ /* header chunk also contains data; skip over the header portion */
if (chunk_size < 32)
return AVERROR_INVALIDDATA;
avio_skip(pb, 32);
@@ -576,7 +606,7 @@ static int ea_read_packet(AVFormatContext *s,
case SCEl_TAG:
case SEND_TAG:
case SEEN_TAG:
- ret = AVERROR(EIO);
+ ret = AVERROR(EIO);
packet_read = 1;
break;
@@ -590,12 +620,12 @@ static int ea_read_packet(AVFormatContext *s,
case fVGT_TAG:
case MADm_TAG:
case MADe_TAG:
- avio_seek(pb, -8, SEEK_CUR); // include chunk preamble
+ avio_seek(pb, -8, SEEK_CUR); // include chunk preamble
chunk_size += 8;
goto get_video_packet;
case mTCD_TAG:
- avio_skip(pb, 8); // skip ea dct header
+ avio_skip(pb, 8); // skip ea DCT header
chunk_size -= 8;
goto get_video_packet;
@@ -615,8 +645,8 @@ get_video_packet:
}
partial_packet = chunk_type == MVIh_TAG;
pkt->stream_index = ea->video_stream_index;
- pkt->flags |= key;
- packet_read = 1;
+ pkt->flags |= key;
+ packet_read = 1;
break;
default:
diff --git a/chromium/third_party/ffmpeg/libavformat/ffmenc.c b/chromium/third_party/ffmpeg/libavformat/ffmenc.c
index 522945ec586..eb809eb64ce 100644
--- a/chromium/third_party/ffmpeg/libavformat/ffmenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/ffmenc.c
@@ -277,4 +277,5 @@ AVOutputFormat ff_ffm_muxer = {
.write_header = ffm_write_header,
.write_packet = ffm_write_packet,
.write_trailer = ffm_write_trailer,
+ .flags = AVFMT_TS_NEGATIVE,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/file.c b/chromium/third_party/ffmpeg/libavformat/file.c
index e09a64b37cf..2defc75e5f7 100644
--- a/chromium/third_party/ffmpeg/libavformat/file.c
+++ b/chromium/third_party/ffmpeg/libavformat/file.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/avstring.h"
+#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "avformat.h"
#include <fcntl.h>
@@ -49,10 +50,17 @@ typedef struct FileContext {
const AVClass *class;
int fd;
int trunc;
+ int blocksize;
} FileContext;
static const AVOption file_options[] = {
{ "truncate", "Truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVOption pipe_options[] = {
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }
};
@@ -63,17 +71,28 @@ static const AVClass file_class = {
.version = LIBAVUTIL_VERSION_INT,
};
+static const AVClass pipe_class = {
+ .class_name = "pipe",
+ .item_name = av_default_item_name,
+ .option = pipe_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
static int file_read(URLContext *h, unsigned char *buf, int size)
{
FileContext *c = h->priv_data;
- int r = read(c->fd, buf, size);
+ int r;
+ size = FFMIN(size, c->blocksize);
+ r = read(c->fd, buf, size);
return (-1 == r)?AVERROR(errno):r;
}
static int file_write(URLContext *h, const unsigned char *buf, int size)
{
FileContext *c = h->priv_data;
- int r = write(c->fd, buf, size);
+ int r;
+ size = FFMIN(size, c->blocksize);
+ r = write(c->fd, buf, size);
return (-1 == r)?AVERROR(errno):r;
}
@@ -132,7 +151,7 @@ static int file_open(URLContext *h, const char *filename, int flags)
#ifdef O_BINARY
access |= O_BINARY;
#endif
- fd = open(filename, access, 0666);
+ fd = avpriv_open(filename, access, 0666);
if (fd == -1)
return AVERROR(errno);
c->fd = fd;
@@ -213,6 +232,7 @@ URLProtocol ff_pipe_protocol = {
.url_get_file_handle = file_get_handle,
.url_check = file_check,
.priv_data_size = sizeof(FileContext),
+ .priv_data_class = &pipe_class,
};
#endif /* CONFIG_PIPE_PROTOCOL */
diff --git a/chromium/third_party/ffmpeg/libavformat/file_open.c b/chromium/third_party/ffmpeg/libavformat/file_open.c
new file mode 100644
index 00000000000..494a5d37a4a
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/chromium/third_party/ffmpeg/libavformat/flacdec.c b/chromium/third_party/ffmpeg/libavformat/flacdec.c
index d5aacfd15f8..8384076b3d8 100644
--- a/chromium/third_party/ffmpeg/libavformat/flacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flacdec.c
@@ -21,139 +21,13 @@
#include "libavcodec/flac.h"
#include "avformat.h"
-#include "id3v2.h"
+#include "flacdec.h"
#include "internal.h"
#include "rawdec.h"
#include "oggdec.h"
#include "vorbiscomment.h"
#include "libavcodec/bytestream.h"
-#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
-
-static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
-{
- const CodecMime *mime = ff_id3v2_mime_tags;
- enum AVCodecID id = AV_CODEC_ID_NONE;
- AVBufferRef *data = NULL;
- uint8_t mimetype[64], *desc = NULL;
- AVIOContext *pb = NULL;
- AVStream *st;
- int type, width, height;
- int len, ret = 0;
-
- pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
- if (!pb)
- return AVERROR(ENOMEM);
-
- /* read the picture type */
- type = avio_rb32(pb);
- if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
- av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
- if (s->error_recognition & AV_EF_EXPLODE) {
- RETURN_ERROR(AVERROR_INVALIDDATA);
- }
- type = 0;
- }
-
- /* picture mimetype */
- len = avio_rb32(pb);
- if (len <= 0 ||
- avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
- av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
- "picture.\n");
- if (s->error_recognition & AV_EF_EXPLODE)
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- mimetype[len] = 0;
-
- while (mime->id != AV_CODEC_ID_NONE) {
- if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
- id = mime->id;
- break;
- }
- mime++;
- }
- if (id == AV_CODEC_ID_NONE) {
- av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
- mimetype);
- if (s->error_recognition & AV_EF_EXPLODE)
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- /* picture description */
- len = avio_rb32(pb);
- if (len > 0) {
- if (!(desc = av_malloc(len + 1))) {
- RETURN_ERROR(AVERROR(ENOMEM));
- }
-
- if (avio_read(pb, desc, len) != len) {
- av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n");
- if (s->error_recognition & AV_EF_EXPLODE)
- ret = AVERROR(EIO);
- goto fail;
- }
- desc[len] = 0;
- }
-
- /* picture metadata */
- width = avio_rb32(pb);
- height = avio_rb32(pb);
- avio_skip(pb, 8);
-
- /* picture data */
- len = avio_rb32(pb);
- if (len <= 0) {
- av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
- if (s->error_recognition & AV_EF_EXPLODE)
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- if (!(data = av_buffer_alloc(len))) {
- RETURN_ERROR(AVERROR(ENOMEM));
- }
- if (avio_read(pb, data->data, len) != len) {
- av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
- if (s->error_recognition & AV_EF_EXPLODE)
- ret = AVERROR(EIO);
- goto fail;
- }
-
- st = avformat_new_stream(s, NULL);
- if (!st) {
- RETURN_ERROR(AVERROR(ENOMEM));
- }
-
- av_init_packet(&st->attached_pic);
- st->attached_pic.buf = data;
- st->attached_pic.data = data->data;
- st->attached_pic.size = len;
- st->attached_pic.stream_index = st->index;
- st->attached_pic.flags |= AV_PKT_FLAG_KEY;
-
- st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = id;
- st->codec->width = width;
- st->codec->height = height;
- av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
- if (desc)
- av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
-
- av_freep(&pb);
-
- return 0;
-
-fail:
- av_buffer_unref(&data);
- av_freep(&desc);
- av_freep(&pb);
- return ret;
-
-}
-
static int flac_read_header(AVFormatContext *s)
{
int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
@@ -248,7 +122,7 @@ static int flac_read_header(AVFormatContext *s)
}
av_freep(&buffer);
} else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
- ret = parse_picture(s, buffer, metadata_size);
+ ret = ff_flac_parse_picture(s, buffer, metadata_size);
av_freep(&buffer);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
@@ -280,7 +154,7 @@ static int flac_probe(AVProbeData *p)
{
if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4))
return 0;
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
}
AVInputFormat ff_flac_demuxer = {
diff --git a/chromium/third_party/ffmpeg/libavformat/flacdec.h b/chromium/third_party/ffmpeg/libavformat/flacdec.h
new file mode 100644
index 00000000000..dff0660311b
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/flacdec.h
@@ -0,0 +1,31 @@
+/*
+ * Raw FLAC demuxer
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * 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_FLACDEC_H
+#define AVFORMAT_FLACDEC_H
+
+#include "avformat.h"
+
+#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size);
+
+#endif /* AVFORMAT_FLACDEC_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/flacdec_picture.c b/chromium/third_party/ffmpeg/libavformat/flacdec_picture.c
new file mode 100644
index 00000000000..1b0bea2dd0d
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/flacdec_picture.c
@@ -0,0 +1,150 @@
+/*
+ * Raw FLAC demuxer
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * 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/avassert.h"
+#include "avformat.h"
+#include "flacdec.h"
+#include "id3v2.h"
+#include "internal.h"
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
+{
+ const CodecMime *mime = ff_id3v2_mime_tags;
+ enum AVCodecID id = AV_CODEC_ID_NONE;
+ AVBufferRef *data = NULL;
+ uint8_t mimetype[64], *desc = NULL;
+ AVIOContext *pb = NULL;
+ AVStream *st;
+ int type, width, height;
+ int len, ret = 0;
+
+ pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
+ if (!pb)
+ return AVERROR(ENOMEM);
+
+ /* read the picture type */
+ type = avio_rb32(pb);
+ if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+ av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
+ if (s->error_recognition & AV_EF_EXPLODE) {
+ RETURN_ERROR(AVERROR_INVALIDDATA);
+ }
+ type = 0;
+ }
+
+ /* picture mimetype */
+ len = avio_rb32(pb);
+ if (len <= 0 ||
+ avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
+ av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
+ "picture.\n");
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ av_assert0(len < sizeof(mimetype));
+ mimetype[len] = 0;
+
+ while (mime->id != AV_CODEC_ID_NONE) {
+ if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
+ id = mime->id;
+ break;
+ }
+ mime++;
+ }
+ if (id == AV_CODEC_ID_NONE) {
+ av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
+ mimetype);
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ /* picture description */
+ len = avio_rb32(pb);
+ if (len > 0) {
+ if (!(desc = av_malloc(len + 1))) {
+ RETURN_ERROR(AVERROR(ENOMEM));
+ }
+
+ if (avio_read(pb, desc, len) != len) {
+ av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n");
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+ desc[len] = 0;
+ }
+
+ /* picture metadata */
+ width = avio_rb32(pb);
+ height = avio_rb32(pb);
+ avio_skip(pb, 8);
+
+ /* picture data */
+ len = avio_rb32(pb);
+ if (len <= 0) {
+ av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ if (!(data = av_buffer_alloc(len))) {
+ RETURN_ERROR(AVERROR(ENOMEM));
+ }
+ if (avio_read(pb, data->data, len) != len) {
+ av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
+ if (s->error_recognition & AV_EF_EXPLODE)
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+
+ st = avformat_new_stream(s, NULL);
+ if (!st) {
+ RETURN_ERROR(AVERROR(ENOMEM));
+ }
+
+ av_init_packet(&st->attached_pic);
+ st->attached_pic.buf = data;
+ st->attached_pic.data = data->data;
+ st->attached_pic.size = len;
+ st->attached_pic.stream_index = st->index;
+ st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = id;
+ st->codec->width = width;
+ st->codec->height = height;
+ av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
+ if (desc)
+ av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
+
+ av_freep(&pb);
+
+ return 0;
+
+fail:
+ av_buffer_unref(&data);
+ av_freep(&desc);
+ av_freep(&pb);
+ return ret;
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/flacenc.c b/chromium/third_party/ffmpeg/libavformat/flacenc.c
index 8c1a1bb7bd3..87e93625f28 100644
--- a/chromium/third_party/ffmpeg/libavformat/flacenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/flacenc.c
@@ -21,6 +21,7 @@
#include "libavcodec/flac.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "flacenc.h"
#include "vorbiscomment.h"
#include "libavcodec/bytestream.h"
@@ -31,10 +32,7 @@ static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_byte
{
avio_w8(pb, last_block ? 0x81 : 0x01);
avio_wb24(pb, n_padding_bytes);
- while (n_padding_bytes > 0) {
- avio_w8(pb, 0);
- n_padding_bytes--;
- }
+ ffio_fill(pb, 0, n_padding_bytes);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/flic.c b/chromium/third_party/ffmpeg/libavformat/flic.c
index 8d49116acf9..2835cf557b6 100644
--- a/chromium/third_party/ffmpeg/libavformat/flic.c
+++ b/chromium/third_party/ffmpeg/libavformat/flic.c
@@ -80,7 +80,7 @@ static int flic_probe(AVProbeData *p)
return 0;
- return AVPROBE_SCORE_MAX;
+ return AVPROBE_SCORE_MAX - 1;
}
static int flic_read_header(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/flvdec.c b/chromium/third_party/ffmpeg/libavformat/flvdec.c
index 8bb56e85c0c..e0b79bb7540 100644
--- a/chromium/third_party/ffmpeg/libavformat/flvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flvdec.c
@@ -41,12 +41,12 @@
typedef struct {
const AVClass *class; ///< Class for private options.
- int trust_metadata; ///< configure streams according onMetaData
- int wrong_dts; ///< wrong dts due to negative cts
+ int trust_metadata; ///< configure streams according onMetaData
+ int wrong_dts; ///< wrong dts due to negative cts
uint8_t *new_extradata[FLV_STREAM_TYPE_NB];
- int new_extradata_size[FLV_STREAM_TYPE_NB];
- int last_sample_rate;
- int last_channels;
+ int new_extradata_size[FLV_STREAM_TYPE_NB];
+ int last_sample_rate;
+ int last_channels;
struct {
int64_t dts;
int64_t pos;
@@ -61,7 +61,11 @@ static int flv_probe(AVProbeData *p)
const uint8_t *d;
d = p->buf;
- if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0 && AV_RB32(d+5)>8) {
+ if (d[0] == 'F' &&
+ d[1] == 'L' &&
+ d[2] == 'V' &&
+ d[3] < 5 && d[5] == 0 &&
+ AV_RB32(d + 5) > 8) {
return AVPROBE_SCORE_MAX;
}
return 0;
@@ -73,7 +77,7 @@ static AVStream *create_stream(AVFormatContext *s, int codec_type)
if (!st)
return NULL;
st->codec->codec_type = codec_type;
- if(s->nb_streams>=3 ||( s->nb_streams==2
+ if (s->nb_streams>=3 ||( s->nb_streams==2
&& s->streams[0]->codec->codec_type != AVMEDIA_TYPE_DATA
&& s->streams[1]->codec->codec_type != AVMEDIA_TYPE_DATA))
s->ctx_flags &= ~AVFMTCTX_NOHEADER;
@@ -81,10 +85,11 @@ static AVStream *create_stream(AVFormatContext *s, int codec_type)
avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
return st;
}
+
static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
{
int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
- int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
+ int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
int codec_id;
if (!acodec->codec_id && !acodec->codec_tag)
@@ -93,18 +98,21 @@ static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
if (acodec->bits_per_coded_sample != bits_per_coded_sample)
return 0;
- switch(flv_codecid) {
- //no distinction between S16 and S8 PCM codec flags
+ switch (flv_codecid) {
+ // no distinction between S16 and S8 PCM codec flags
case FLV_CODECID_PCM:
- codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 :
+ codec_id = bits_per_coded_sample == 8
+ ? AV_CODEC_ID_PCM_U8
#if HAVE_BIGENDIAN
- AV_CODEC_ID_PCM_S16BE;
+ : AV_CODEC_ID_PCM_S16BE;
#else
- AV_CODEC_ID_PCM_S16LE;
+ : AV_CODEC_ID_PCM_S16LE;
#endif
return codec_id == acodec->codec_id;
case FLV_CODECID_PCM_LE:
- codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE;
+ codec_id = bits_per_coded_sample == 8
+ ? AV_CODEC_ID_PCM_U8
+ : AV_CODEC_ID_PCM_S16LE;
return codec_id == acodec->codec_id;
case FLV_CODECID_AAC:
return acodec->codec_id == AV_CODEC_ID_AAC;
@@ -120,57 +128,72 @@ static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
return acodec->codec_id == AV_CODEC_ID_NELLYMOSER;
case FLV_CODECID_PCM_MULAW:
return acodec->sample_rate == 8000 &&
- acodec->codec_id == AV_CODEC_ID_PCM_MULAW;
+ acodec->codec_id == AV_CODEC_ID_PCM_MULAW;
case FLV_CODECID_PCM_ALAW:
- return acodec->sample_rate = 8000 &&
- acodec->codec_id == AV_CODEC_ID_PCM_ALAW;
+ return acodec->sample_rate == 8000 &&
+ acodec->codec_id == AV_CODEC_ID_PCM_ALAW;
default:
return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
}
}
-static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
- switch(flv_codecid) {
- //no distinction between S16 and S8 PCM codec flags
- case FLV_CODECID_PCM:
- acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 :
+static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
+ AVCodecContext *acodec, int flv_codecid)
+{
+ switch (flv_codecid) {
+ // no distinction between S16 and S8 PCM codec flags
+ case FLV_CODECID_PCM:
+ acodec->codec_id = acodec->bits_per_coded_sample == 8
+ ? AV_CODEC_ID_PCM_U8
#if HAVE_BIGENDIAN
- AV_CODEC_ID_PCM_S16BE;
+ : AV_CODEC_ID_PCM_S16BE;
#else
- AV_CODEC_ID_PCM_S16LE;
+ : AV_CODEC_ID_PCM_S16LE;
#endif
- break;
- case FLV_CODECID_PCM_LE:
- acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE; break;
- case FLV_CODECID_AAC : acodec->codec_id = AV_CODEC_ID_AAC; break;
- case FLV_CODECID_ADPCM: acodec->codec_id = AV_CODEC_ID_ADPCM_SWF; break;
- case FLV_CODECID_SPEEX:
- acodec->codec_id = AV_CODEC_ID_SPEEX;
- acodec->sample_rate = 16000;
- break;
- case FLV_CODECID_MP3 : acodec->codec_id = AV_CODEC_ID_MP3 ; astream->need_parsing = AVSTREAM_PARSE_FULL; break;
- case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
- acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate
- acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
- break;
- case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
- acodec->sample_rate = 16000;
- acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
- break;
- case FLV_CODECID_NELLYMOSER:
- acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
- break;
- case FLV_CODECID_PCM_MULAW:
- acodec->sample_rate = 8000;
- acodec->codec_id = AV_CODEC_ID_PCM_MULAW;
- break;
- case FLV_CODECID_PCM_ALAW:
- acodec->sample_rate = 8000;
- acodec->codec_id = AV_CODEC_ID_PCM_ALAW;
- break;
- default:
- av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
- acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
+ break;
+ case FLV_CODECID_PCM_LE:
+ acodec->codec_id = acodec->bits_per_coded_sample == 8
+ ? AV_CODEC_ID_PCM_U8
+ : AV_CODEC_ID_PCM_S16LE;
+ break;
+ case FLV_CODECID_AAC:
+ acodec->codec_id = AV_CODEC_ID_AAC;
+ break;
+ case FLV_CODECID_ADPCM:
+ acodec->codec_id = AV_CODEC_ID_ADPCM_SWF;
+ break;
+ case FLV_CODECID_SPEEX:
+ acodec->codec_id = AV_CODEC_ID_SPEEX;
+ acodec->sample_rate = 16000;
+ break;
+ case FLV_CODECID_MP3:
+ acodec->codec_id = AV_CODEC_ID_MP3;
+ astream->need_parsing = AVSTREAM_PARSE_FULL;
+ break;
+ case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
+ // in case metadata does not otherwise declare samplerate
+ acodec->sample_rate = 8000;
+ acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
+ break;
+ case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
+ acodec->sample_rate = 16000;
+ acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
+ break;
+ case FLV_CODECID_NELLYMOSER:
+ acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
+ break;
+ case FLV_CODECID_PCM_MULAW:
+ acodec->sample_rate = 8000;
+ acodec->codec_id = AV_CODEC_ID_PCM_MULAW;
+ break;
+ case FLV_CODECID_PCM_ALAW:
+ acodec->sample_rate = 8000;
+ acodec->codec_id = AV_CODEC_ID_PCM_ALAW;
+ break;
+ default:
+ av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n",
+ flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
+ acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
}
}
@@ -182,63 +205,75 @@ static int flv_same_video_codec(AVCodecContext *vcodec, int flags)
return 1;
switch (flv_codecid) {
- case FLV_CODECID_H263:
- return vcodec->codec_id == AV_CODEC_ID_FLV1;
- case FLV_CODECID_SCREEN:
- return vcodec->codec_id == AV_CODEC_ID_FLASHSV;
- case FLV_CODECID_SCREEN2:
- return vcodec->codec_id == AV_CODEC_ID_FLASHSV2;
- case FLV_CODECID_VP6:
- return vcodec->codec_id == AV_CODEC_ID_VP6F;
- case FLV_CODECID_VP6A:
- return vcodec->codec_id == AV_CODEC_ID_VP6A;
- case FLV_CODECID_H264:
- return vcodec->codec_id == AV_CODEC_ID_H264;
- default:
- return vcodec->codec_tag == flv_codecid;
+ case FLV_CODECID_H263:
+ return vcodec->codec_id == AV_CODEC_ID_FLV1;
+ case FLV_CODECID_SCREEN:
+ return vcodec->codec_id == AV_CODEC_ID_FLASHSV;
+ case FLV_CODECID_SCREEN2:
+ return vcodec->codec_id == AV_CODEC_ID_FLASHSV2;
+ case FLV_CODECID_VP6:
+ return vcodec->codec_id == AV_CODEC_ID_VP6F;
+ case FLV_CODECID_VP6A:
+ return vcodec->codec_id == AV_CODEC_ID_VP6A;
+ case FLV_CODECID_H264:
+ return vcodec->codec_id == AV_CODEC_ID_H264;
+ default:
+ return vcodec->codec_tag == flv_codecid;
}
}
-static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid, int read) {
+static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
+ int flv_codecid, int read)
+{
AVCodecContext *vcodec = vstream->codec;
- switch(flv_codecid) {
- case FLV_CODECID_H263 : vcodec->codec_id = AV_CODEC_ID_FLV1 ; break;
- case FLV_CODECID_REALH263: vcodec->codec_id = AV_CODEC_ID_H263 ; break; // Really mean it this time
- case FLV_CODECID_SCREEN: vcodec->codec_id = AV_CODEC_ID_FLASHSV; break;
- case FLV_CODECID_SCREEN2: vcodec->codec_id = AV_CODEC_ID_FLASHSV2; break;
- case FLV_CODECID_VP6 : vcodec->codec_id = AV_CODEC_ID_VP6F ;
- case FLV_CODECID_VP6A :
- if(flv_codecid == FLV_CODECID_VP6A)
- vcodec->codec_id = AV_CODEC_ID_VP6A;
- if (read) {
- if (vcodec->extradata_size != 1) {
- vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE);
- if (vcodec->extradata)
- vcodec->extradata_size = 1;
- }
+ switch (flv_codecid) {
+ case FLV_CODECID_H263:
+ vcodec->codec_id = AV_CODEC_ID_FLV1;
+ break;
+ case FLV_CODECID_REALH263:
+ vcodec->codec_id = AV_CODEC_ID_H263;
+ break; // Really mean it this time
+ case FLV_CODECID_SCREEN:
+ vcodec->codec_id = AV_CODEC_ID_FLASHSV;
+ break;
+ case FLV_CODECID_SCREEN2:
+ vcodec->codec_id = AV_CODEC_ID_FLASHSV2;
+ break;
+ case FLV_CODECID_VP6:
+ vcodec->codec_id = AV_CODEC_ID_VP6F;
+ case FLV_CODECID_VP6A:
+ if (flv_codecid == FLV_CODECID_VP6A)
+ vcodec->codec_id = AV_CODEC_ID_VP6A;
+ if (read) {
+ if (vcodec->extradata_size != 1) {
+ vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE);
if (vcodec->extradata)
- vcodec->extradata[0] = avio_r8(s->pb);
- else
- avio_skip(s->pb, 1);
+ vcodec->extradata_size = 1;
}
- return 1; // 1 byte body size adjustment for flv_read_packet()
- case FLV_CODECID_H264:
- vcodec->codec_id = AV_CODEC_ID_H264;
- return 3; // not 4, reading packet type will consume one byte
- case FLV_CODECID_MPEG4:
- vcodec->codec_id = AV_CODEC_ID_MPEG4;
- return 3;
- default:
- av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
- vcodec->codec_tag = flv_codecid;
+ if (vcodec->extradata)
+ vcodec->extradata[0] = avio_r8(s->pb);
+ else
+ avio_skip(s->pb, 1);
+ }
+ return 1; // 1 byte body size adjustment for flv_read_packet()
+ case FLV_CODECID_H264:
+ vcodec->codec_id = AV_CODEC_ID_H264;
+ return 3; // not 4, reading packet type will consume one byte
+ case FLV_CODECID_MPEG4:
+ vcodec->codec_id = AV_CODEC_ID_MPEG4;
+ return 3;
+ default:
+ av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
+ vcodec->codec_tag = flv_codecid;
}
return 0;
}
-static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
+static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)
+{
int length = avio_rb16(ioc);
- if(length >= buffsize) {
+ if (length >= buffsize) {
avio_skip(ioc, length);
return -1;
}
@@ -250,16 +285,18 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
return length;
}
-static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) {
- FLVContext *flv = s->priv_data;
+static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc,
+ AVStream *vstream, int64_t max_pos)
+{
+ FLVContext *flv = s->priv_data;
unsigned int timeslen = 0, fileposlen = 0, i;
char str_val[256];
- int64_t *times = NULL;
+ int64_t *times = NULL;
int64_t *filepositions = NULL;
- int ret = AVERROR(ENOSYS);
- int64_t initial_pos = avio_tell(ioc);
+ int ret = AVERROR(ENOSYS);
+ int64_t initial_pos = avio_tell(ioc);
- if(vstream->nb_index_entries>0){
+ if (vstream->nb_index_entries>0) {
av_log(s, AV_LOG_WARNING, "Skiping duplicate index\n");
return 0;
}
@@ -267,8 +304,9 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
if (s->flags & AVFMT_FLAG_IGNIDX)
return 0;
- while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
- int64_t** current_array;
+ while (avio_tell(ioc) < max_pos - 2 &&
+ amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
+ int64_t **current_array;
unsigned int arraylen;
// Expect array object in context
@@ -276,16 +314,19 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
break;
arraylen = avio_rb32(ioc);
- if(arraylen>>28)
+ if (arraylen>>28)
break;
- if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times){
- current_array= &times;
- timeslen= arraylen;
- }else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions){
- current_array= &filepositions;
- fileposlen= arraylen;
- }else // unexpected metatag inside keyframes, will not use such metadata for indexing
+ if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) {
+ current_array = &times;
+ timeslen = arraylen;
+ } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) &&
+ !filepositions) {
+ current_array = &filepositions;
+ fileposlen = arraylen;
+ } else
+ // unexpected metatag inside keyframes, will not use such
+ // metadata for indexing
break;
if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
@@ -308,12 +349,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
for (i = 0; i < fileposlen; i++) {
- av_add_index_entry(vstream, filepositions[i], times[i]*1000,
+ av_add_index_entry(vstream, filepositions[i], times[i] * 1000,
0, 0, AVINDEX_KEYFRAME);
if (i < 2) {
flv->validate_index[i].pos = filepositions[i];
flv->validate_index[i].dts = times[i] * 1000;
- flv->validate_count = i + 1;
+ flv->validate_count = i + 1;
}
}
} else {
@@ -328,7 +369,10 @@ finish:
return ret;
}
-static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
+static int amf_parse_object(AVFormatContext *s, AVStream *astream,
+ AVStream *vstream, const char *key,
+ int64_t max_pos, int depth)
+{
AVCodecContext *acodec, *vcodec;
FLVContext *flv = s->priv_data;
AVIOContext *ioc;
@@ -336,74 +380,85 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
char str_val[256];
double num_val;
- num_val = 0;
- ioc = s->pb;
-
+ num_val = 0;
+ ioc = s->pb;
amf_type = avio_r8(ioc);
- switch(amf_type) {
- case AMF_DATA_TYPE_NUMBER:
- num_val = av_int2double(avio_rb64(ioc)); break;
- case AMF_DATA_TYPE_BOOL:
- num_val = avio_r8(ioc); break;
- case AMF_DATA_TYPE_STRING:
- if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
- return -1;
- break;
- case AMF_DATA_TYPE_OBJECT:
- if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
- if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
- max_pos) < 0)
- av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
-
- while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
- if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
- return -1; //if we couldn't skip, bomb out.
- }
- if(avio_r8(ioc) != AMF_END_OF_OBJECT)
- return -1;
- break;
- case AMF_DATA_TYPE_NULL:
- case AMF_DATA_TYPE_UNDEFINED:
- case AMF_DATA_TYPE_UNSUPPORTED:
- break; //these take up no additional space
- case AMF_DATA_TYPE_MIXEDARRAY:
- avio_skip(ioc, 4); //skip 32-bit max array index
- while(avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
- //this is the only case in which we would want a nested parse to not skip over the object
- if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
- return -1;
- }
- if(avio_r8(ioc) != AMF_END_OF_OBJECT)
+ switch (amf_type) {
+ case AMF_DATA_TYPE_NUMBER:
+ num_val = av_int2double(avio_rb64(ioc));
+ break;
+ case AMF_DATA_TYPE_BOOL:
+ num_val = avio_r8(ioc);
+ break;
+ case AMF_DATA_TYPE_STRING:
+ if (amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
+ return -1;
+ break;
+ case AMF_DATA_TYPE_OBJECT:
+ if ((vstream || astream) && key &&
+ ioc->seekable &&
+ !strcmp(KEYFRAMES_TAG, key) && depth == 1)
+ if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
+ max_pos) < 0)
+ av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
+
+ while (avio_tell(ioc) < max_pos - 2 &&
+ amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
+ if (amf_parse_object(s, astream, vstream, str_val, max_pos,
+ depth + 1) < 0)
+ return -1; // if we couldn't skip, bomb out.
+ if (avio_r8(ioc) != AMF_END_OF_OBJECT)
+ return -1;
+ break;
+ case AMF_DATA_TYPE_NULL:
+ case AMF_DATA_TYPE_UNDEFINED:
+ case AMF_DATA_TYPE_UNSUPPORTED:
+ break; // these take up no additional space
+ case AMF_DATA_TYPE_MIXEDARRAY:
+ avio_skip(ioc, 4); // skip 32-bit max array index
+ while (avio_tell(ioc) < max_pos - 2 &&
+ amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
+ // this is the only case in which we would want a nested
+ // parse to not skip over the object
+ if (amf_parse_object(s, astream, vstream, str_val, max_pos,
+ depth + 1) < 0)
return -1;
- break;
- case AMF_DATA_TYPE_ARRAY: {
- unsigned int arraylen, i;
-
- arraylen = avio_rb32(ioc);
- for(i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
- if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)
- return -1; //if we couldn't skip, bomb out.
- }
- }
- break;
- case AMF_DATA_TYPE_DATE:
- avio_skip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)
- break;
- default: //unsupported type, we couldn't skip
+ if (avio_r8(ioc) != AMF_END_OF_OBJECT)
return -1;
+ break;
+ case AMF_DATA_TYPE_ARRAY:
+ {
+ unsigned int arraylen, i;
+
+ arraylen = avio_rb32(ioc);
+ for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++)
+ if (amf_parse_object(s, NULL, NULL, NULL, max_pos,
+ depth + 1) < 0)
+ return -1; // if we couldn't skip, bomb out.
+ }
+ break;
+ case AMF_DATA_TYPE_DATE:
+ avio_skip(ioc, 8 + 2); // timestamp (double) and UTC offset (int16)
+ break;
+ default: // unsupported type, we couldn't skip
+ return -1;
}
- if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
+ // only look for metadata values when we are not nested and key != NULL
+ if (depth == 1 && key) {
acodec = astream ? astream->codec : NULL;
vcodec = vstream ? vstream->codec : NULL;
- if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) {
+ if (amf_type == AMF_DATA_TYPE_NUMBER ||
+ amf_type == AMF_DATA_TYPE_BOOL) {
if (!strcmp(key, "duration"))
s->duration = num_val * AV_TIME_BASE;
- else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
+ else if (!strcmp(key, "videodatarate") && vcodec &&
+ 0 <= (int)(num_val * 1024.0))
vcodec->bit_rate = num_val * 1024.0;
- else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
+ else if (!strcmp(key, "audiodatarate") && acodec &&
+ 0 <= (int)(num_val * 1024.0))
acodec->bit_rate = num_val * 1024.0;
else if (!strcmp(key, "datastream")) {
AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA);
@@ -413,25 +468,21 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
} else if (flv->trust_metadata) {
if (!strcmp(key, "videocodecid") && vcodec) {
flv_set_video_codec(s, vstream, num_val, 0);
- } else
- if (!strcmp(key, "audiocodecid") && acodec) {
+ } else if (!strcmp(key, "audiocodecid") && acodec) {
int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
flv_set_audio_codec(s, astream, acodec, id);
- } else
- if (!strcmp(key, "audiosamplerate") && acodec) {
+ } else if (!strcmp(key, "audiosamplerate") && acodec) {
acodec->sample_rate = num_val;
} else if (!strcmp(key, "audiosamplesize") && acodec) {
acodec->bits_per_coded_sample = num_val;
} else if (!strcmp(key, "stereo") && acodec) {
- acodec->channels = num_val + 1;
+ acodec->channels = num_val + 1;
acodec->channel_layout = acodec->channels == 2 ?
AV_CH_LAYOUT_STEREO :
AV_CH_LAYOUT_MONO;
- } else
- if (!strcmp(key, "width") && vcodec) {
+ } else if (!strcmp(key, "width") && vcodec) {
vcodec->width = num_val;
- } else
- if (!strcmp(key, "height") && vcodec) {
+ } else if (!strcmp(key, "height") && vcodec) {
vcodec->height = num_val;
}
}
@@ -456,10 +507,11 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
!strcmp(key, "audiocodecid"))
return 0;
- if(amf_type == AMF_DATA_TYPE_BOOL) {
- av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
+ if (amf_type == AMF_DATA_TYPE_BOOL) {
+ av_strlcpy(str_val, num_val > 0 ? "true" : "false",
+ sizeof(str_val));
av_dict_set(&s->metadata, key, str_val, 0);
- } else if(amf_type == AMF_DATA_TYPE_NUMBER) {
+ } else if (amf_type == AMF_DATA_TYPE_NUMBER) {
snprintf(str_val, sizeof(str_val), "%.f", num_val);
av_dict_set(&s->metadata, key, str_val, 0);
} else if (amf_type == AMF_DATA_TYPE_STRING)
@@ -469,17 +521,23 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
return 0;
}
-static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
+static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
+{
AMFDataType type;
- AVStream *stream, *astream, *vstream, *dstream;
+ AVStream *stream, *astream, *vstream;
+ AVStream av_unused *dstream;
AVIOContext *ioc;
int i;
- char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
+ // only needs to hold the string "onMetaData".
+ // Anything longer is something we don't want.
+ char buffer[11];
- vstream = astream = dstream = NULL;
- ioc = s->pb;
+ astream = NULL;
+ vstream = NULL;
+ dstream = NULL;
+ ioc = s->pb;
- //first object needs to be "onMetaData" string
+ // first object needs to be "onMetaData" string
type = avio_r8(ioc);
if (type != AMF_DATA_TYPE_STRING ||
amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
@@ -491,16 +549,20 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
if (strcmp(buffer, "onMetaData"))
return -1;
- //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
- for(i = 0; i < s->nb_streams; i++) {
+ // find the streams now so that amf_parse_object doesn't need to do
+ // the lookup every time it is called.
+ for (i = 0; i < s->nb_streams; i++) {
stream = s->streams[i];
- if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
- else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
- else if(stream->codec->codec_type == AVMEDIA_TYPE_DATA) dstream = stream;
+ if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ vstream = stream;
+ else if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ astream = stream;
+ else if (stream->codec->codec_type == AVMEDIA_TYPE_DATA)
+ dstream = stream;
}
- //parse the second object (we want a mixed array)
- if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
+ // parse the second object (we want a mixed array)
+ if (amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
return -1;
return 0;
@@ -516,19 +578,19 @@ static int flv_read_header(AVFormatContext *s)
/* FIXME: better fix needed */
if (!flags) {
flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO;
- av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n");
+ av_log(s, AV_LOG_WARNING,
+ "Broken FLV file, which says no streams present, "
+ "this might fail\n");
}
s->ctx_flags |= AVFMTCTX_NOHEADER;
- if(flags & FLV_HEADER_FLAG_HASVIDEO){
- if(!create_stream(s, AVMEDIA_TYPE_VIDEO))
+ if (flags & FLV_HEADER_FLAG_HASVIDEO)
+ if (!create_stream(s, AVMEDIA_TYPE_VIDEO))
return AVERROR(ENOMEM);
- }
- if(flags & FLV_HEADER_FLAG_HASAUDIO){
- if(!create_stream(s, AVMEDIA_TYPE_AUDIO))
+ if (flags & FLV_HEADER_FLAG_HASAUDIO)
+ if (!create_stream(s, AVMEDIA_TYPE_AUDIO))
return AVERROR(ENOMEM);
- }
// Flag doesn't indicate whether or not there is script-data present. Must
// create that stream if it's encountered.
@@ -545,7 +607,7 @@ static int flv_read_close(AVFormatContext *s)
{
int i;
FLVContext *flv = s->priv_data;
- for(i=0; i<FLV_STREAM_TYPE_NB; i++)
+ for (i=0; i<FLV_STREAM_TYPE_NB; i++)
av_freep(&flv->new_extradata[i]);
return 0;
}
@@ -565,7 +627,8 @@ static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
int size)
{
av_free(flv->new_extradata[stream]);
- flv->new_extradata[stream] = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ flv->new_extradata[stream] = av_mallocz(size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
if (!flv->new_extradata[stream])
return AVERROR(ENOMEM);
flv->new_extradata_size[stream] = size;
@@ -576,52 +639,48 @@ static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
static void clear_index_entries(AVFormatContext *s, int64_t pos)
{
int i, j, out;
- av_log(s, AV_LOG_WARNING, "Found invalid index entries, clearing the index.\n");
+ av_log(s, AV_LOG_WARNING,
+ "Found invalid index entries, clearing the index.\n");
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
/* Remove all index entries that point to >= pos */
out = 0;
- for (j = 0; j < st->nb_index_entries; j++) {
+ for (j = 0; j < st->nb_index_entries; j++)
if (st->index_entries[j].pos < pos)
st->index_entries[out++] = st->index_entries[j];
- }
st->nb_index_entries = out;
}
}
-
static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
int64_t dts, int64_t next)
{
- int ret = AVERROR_INVALIDDATA, i;
AVIOContext *pb = s->pb;
- AVStream *st = NULL;
+ AVStream *st = NULL;
AMFDataType type;
char buf[20];
- int length;
+ int ret, i, length;
type = avio_r8(pb);
if (type == AMF_DATA_TYPE_MIXEDARRAY)
avio_seek(pb, 4, SEEK_CUR);
else if (type != AMF_DATA_TYPE_OBJECT)
- goto out;
+ return AVERROR_INVALIDDATA;
amf_get_string(pb, buf, sizeof(buf));
if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
- goto out;
+ return AVERROR_INVALIDDATA;
amf_get_string(pb, buf, sizeof(buf));
- //FIXME parse it as codec_id
+ // FIXME parse it as codec_id
amf_get_string(pb, buf, sizeof(buf));
if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
- goto out;
+ return AVERROR_INVALIDDATA;
length = avio_rb16(pb);
- ret = av_get_packet(s->pb, pkt, length);
- if (ret < 0) {
- ret = AVERROR(EIO);
- goto out;
- }
+ ret = av_get_packet(s->pb, pkt, length);
+ if (ret < 0)
+ return AVERROR(EIO);
for (i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
@@ -632,7 +691,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
if (i == s->nb_streams) {
st = create_stream(s, AVMEDIA_TYPE_DATA);
if (!st)
- goto out;
+ return AVERROR_INVALIDDATA;
st->codec->codec_id = AV_CODEC_ID_TEXT;
}
@@ -641,10 +700,10 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
pkt->size = ret;
pkt->stream_index = st->index;
- pkt->flags |= AV_PKT_FLAG_KEY;
+ pkt->flags |= AV_PKT_FLAG_KEY;
avio_seek(s->pb, next + 4, SEEK_SET);
-out:
+
return ret;
}
@@ -653,131 +712,131 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
FLVContext *flv = s->priv_data;
int ret, i, type, size, flags;
int stream_type=-1;
- int64_t next, pos;
+ int64_t next, pos, meta_pos;
int64_t dts, pts = AV_NOPTS_VALUE;
int av_uninit(channels);
int av_uninit(sample_rate);
- AVStream *st = NULL;
-
- for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */
- pos = avio_tell(s->pb);
- type = avio_r8(s->pb);
- size = avio_rb24(s->pb);
- dts = avio_rb24(s->pb);
- dts |= avio_r8(s->pb) << 24;
- av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
- if (url_feof(s->pb))
- return AVERROR_EOF;
- avio_skip(s->pb, 3); /* stream id, always 0 */
- flags = 0;
-
- if (flv->validate_next < flv->validate_count) {
- int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
- if (pos == validate_pos) {
- if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
- VALIDATE_INDEX_TS_THRESH) {
- flv->validate_next++;
- } else {
+ AVStream *st = NULL;
+
+ /* pkt size is repeated at end. skip it */
+ for (;; avio_skip(s->pb, 4)) {
+ pos = avio_tell(s->pb);
+ type = avio_r8(s->pb);
+ size = avio_rb24(s->pb);
+ dts = avio_rb24(s->pb);
+ dts |= avio_r8(s->pb) << 24;
+ av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
+ if (url_feof(s->pb))
+ return AVERROR_EOF;
+ avio_skip(s->pb, 3); /* stream id, always 0 */
+ flags = 0;
+
+ if (flv->validate_next < flv->validate_count) {
+ int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
+ if (pos == validate_pos) {
+ if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
+ VALIDATE_INDEX_TS_THRESH) {
+ flv->validate_next++;
+ } else {
+ clear_index_entries(s, validate_pos);
+ flv->validate_count = 0;
+ }
+ } else if (pos > validate_pos) {
clear_index_entries(s, validate_pos);
flv->validate_count = 0;
}
- } else if (pos > validate_pos) {
- clear_index_entries(s, validate_pos);
- flv->validate_count = 0;
}
- }
-
- if(size == 0)
- continue;
-
- next= size + avio_tell(s->pb);
- if (type == FLV_TAG_TYPE_AUDIO) {
- stream_type=FLV_STREAM_TYPE_AUDIO;
- flags = avio_r8(s->pb);
- size--;
- } else if (type == FLV_TAG_TYPE_VIDEO) {
- stream_type=FLV_STREAM_TYPE_VIDEO;
- flags = avio_r8(s->pb);
- size--;
- if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
- goto skip;
- } else if (type == FLV_TAG_TYPE_META) {
- if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
- flv_read_metabody(s, next);
- goto skip;
- } else if (dts != 0) { // Script-data "special" metadata frames - don't skip
+ if (size == 0)
+ continue;
+
+ next = size + avio_tell(s->pb);
+
+ if (type == FLV_TAG_TYPE_AUDIO) {
+ stream_type = FLV_STREAM_TYPE_AUDIO;
+ flags = avio_r8(s->pb);
+ size--;
+ } else if (type == FLV_TAG_TYPE_VIDEO) {
+ stream_type = FLV_STREAM_TYPE_VIDEO;
+ flags = avio_r8(s->pb);
+ size--;
+ if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
+ goto skip;
+ } else if (type == FLV_TAG_TYPE_META) {
stream_type=FLV_STREAM_TYPE_DATA;
+ if (size > 13 + 1 + 4 && dts == 0) { // Header-type metadata stuff
+ meta_pos = avio_tell(s->pb);
+ if (flv_read_metabody(s, next) == 0) {
+ goto skip;
+ }
+ avio_seek(s->pb, meta_pos, SEEK_SET);
+ }
} else {
- goto skip;
+ av_log(s, AV_LOG_DEBUG,
+ "skipping flv packet: type %d, size %d, flags %d\n",
+ type, size, flags);
+skip:
+ avio_seek(s->pb, next, SEEK_SET);
+ continue;
}
- } else {
- av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
- skip:
- avio_seek(s->pb, next, SEEK_SET);
- continue;
- }
-
- /* skip empty data packets */
- if (!size)
- continue;
- /* now find stream */
- for(i=0;i<s->nb_streams;i++) {
- st = s->streams[i];
- if (stream_type == FLV_STREAM_TYPE_AUDIO) {
- if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
- (s->audio_codec_id || flv_same_audio_codec(st->codec, flags))) {
- break;
- }
- } else
- if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
- (s->video_codec_id || flv_same_video_codec(st->codec, flags))) {
- break;
+ /* skip empty data packets */
+ if (!size)
+ continue;
+
+ /* now find stream */
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (stream_type == FLV_STREAM_TYPE_AUDIO) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+ (s->audio_codec_id || flv_same_audio_codec(st->codec, flags)))
+ break;
+ } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ (s->video_codec_id || flv_same_video_codec(st->codec, flags)))
+ break;
+ } else if (stream_type == FLV_STREAM_TYPE_DATA) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
+ break;
}
- } else if (stream_type == FLV_STREAM_TYPE_DATA) {
- if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
- break;
}
- }
- if(i == s->nb_streams){
- static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA};
- av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
- st = create_stream(s,
- stream_types[stream_type]);
- if (!st)
- return AVERROR(ENOMEM);
+ if (i == s->nb_streams) {
+ static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA};
+ av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
+ st = create_stream(s, stream_types[stream_type]);
+ if (!st)
+ return AVERROR(ENOMEM);
+ }
+ av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
+ 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);
+ continue;
+ }
+ if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)
+ av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
+ break;
}
- av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
- 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);
- continue;
- }
- if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)
- av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
- break;
- }
- // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
- if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE) && !flv->searched_for_end){
+ // if not streamed and no duration from metadata then seek to end to find
+ // the duration from the timestamps
+ if (s->pb->seekable && (!s->duration || s->duration == AV_NOPTS_VALUE) && !flv->searched_for_end) {
int size;
- const int64_t pos= avio_tell(s->pb);
- int64_t fsize= avio_size(s->pb);
+ const int64_t pos = avio_tell(s->pb);
+ int64_t fsize = avio_size(s->pb);
retry_duration:
- avio_seek(s->pb, fsize-4, SEEK_SET);
- size= avio_rb32(s->pb);
- avio_seek(s->pb, fsize-3-size, SEEK_SET);
- if(size == avio_rb24(s->pb) + 11){
+ avio_seek(s->pb, fsize - 4, SEEK_SET);
+ size = avio_rb32(s->pb);
+ avio_seek(s->pb, fsize - 3 - size, SEEK_SET);
+ if (size == avio_rb24(s->pb) + 11) {
uint32_t ts = avio_rb24(s->pb);
- ts |= avio_r8(s->pb) << 24;
- if(ts)
+ ts |= avio_r8(s->pb) << 24;
+ if (ts)
s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
- else if (fsize >= 8 && fsize - 8 >= size){
+ else if (fsize >= 8 && fsize - 8 >= size) {
fsize -= size+4;
goto retry_duration;
}
@@ -787,29 +846,35 @@ retry_duration:
flv->searched_for_end = 1;
}
- if(stream_type == FLV_STREAM_TYPE_AUDIO){
+ if (stream_type == FLV_STREAM_TYPE_AUDIO) {
int bits_per_coded_sample;
- channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
- sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
+ channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
+ sample_rate = 44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >>
+ FLV_AUDIO_SAMPLERATE_OFFSET) >> 3;
bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
- if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
+ if (!st->codec->channels || !st->codec->sample_rate ||
+ !st->codec->bits_per_coded_sample) {
st->codec->channels = channels;
- st->codec->channel_layout = channels == 1 ? AV_CH_LAYOUT_MONO :
- AV_CH_LAYOUT_STEREO;
+ st->codec->channel_layout = channels == 1
+ ? AV_CH_LAYOUT_MONO
+ : AV_CH_LAYOUT_STEREO;
st->codec->sample_rate = sample_rate;
st->codec->bits_per_coded_sample = bits_per_coded_sample;
}
- if(!st->codec->codec_id){
- flv_set_audio_codec(s, st, st->codec, flags & FLV_AUDIO_CODECID_MASK);
- flv->last_sample_rate = sample_rate = st->codec->sample_rate;
- flv->last_channels = channels = st->codec->channels;
+ if (!st->codec->codec_id) {
+ flv_set_audio_codec(s, st, st->codec,
+ flags & FLV_AUDIO_CODECID_MASK);
+ flv->last_sample_rate =
+ sample_rate = st->codec->sample_rate;
+ flv->last_channels =
+ channels = st->codec->channels;
} else {
AVCodecContext ctx;
ctx.sample_rate = sample_rate;
flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
sample_rate = ctx.sample_rate;
}
- } else if(stream_type == FLV_STREAM_TYPE_VIDEO) {
+ } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
}
@@ -819,11 +884,13 @@ retry_duration:
int type = avio_r8(s->pb);
size--;
if (st->codec->codec_id == AV_CODEC_ID_H264 || st->codec->codec_id == AV_CODEC_ID_MPEG4) {
- int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension
+ // sign extension
+ int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = dts + cts;
if (cts < 0) { // dts are wrong
flv->wrong_dts = 1;
- av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n");
+ av_log(s, AV_LOG_WARNING,
+ "negative cts, previous timestamps might be wrong\n");
}
if (flv->wrong_dts)
dts = AV_NOPTS_VALUE;
@@ -841,7 +908,7 @@ retry_duration:
MPEG4AudioConfig cfg;
if (avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
st->codec->extradata_size * 8, 1) >= 0) {
- st->codec->channels = cfg.channels;
+ st->codec->channels = cfg.channels;
st->codec->channel_layout = 0;
if (cfg.ext_sample_rate)
st->codec->sample_rate = cfg.ext_sample_rate;
@@ -863,11 +930,11 @@ retry_duration:
goto leave;
}
- ret= av_get_packet(s->pb, pkt, size);
+ ret = av_get_packet(s->pb, pkt, size);
if (ret < 0)
return ret;
- pkt->dts = dts;
- pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
+ pkt->dts = dts;
+ pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
pkt->stream_index = st->index;
if (flv->new_extradata[stream_type]) {
uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
@@ -879,8 +946,9 @@ retry_duration:
flv->new_extradata_size[stream_type] = 0;
}
}
- if (stream_type == FLV_STREAM_TYPE_AUDIO && (sample_rate != flv->last_sample_rate ||
- channels != flv->last_channels)) {
+ if (stream_type == FLV_STREAM_TYPE_AUDIO &&
+ (sample_rate != flv->last_sample_rate ||
+ channels != flv->last_channels)) {
flv->last_sample_rate = sample_rate;
flv->last_channels = channels;
ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
@@ -897,7 +965,7 @@ leave:
}
static int flv_read_seek(AVFormatContext *s, int stream_index,
- int64_t ts, int flags)
+ int64_t ts, int flags)
{
FLVContext *flv = s->priv_data;
flv->validate_count = 0;
@@ -907,11 +975,11 @@ static int flv_read_seek(AVFormatContext *s, int stream_index,
#define OFFSET(x) offsetof(FLVContext, x)
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "flv_metadata", "Allocate streams according the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD},
+ { "flv_metadata", "Allocate streams according the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
{ NULL }
};
-static const AVClass class = {
+static const AVClass flv_class = {
.class_name = "flvdec",
.item_name = av_default_item_name,
.option = options,
@@ -928,5 +996,5 @@ AVInputFormat ff_flv_demuxer = {
.read_seek = flv_read_seek,
.read_close = flv_read_close,
.extensions = "flv",
- .priv_class = &class,
+ .priv_class = &flv_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/format.c b/chromium/third_party/ffmpeg/libavformat/format.c
new file mode 100644
index 00000000000..ac9100b6045
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/format.c
@@ -0,0 +1,184 @@
+/*
+ * Format register and lookup
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * 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/atomic.h"
+#include "libavutil/avstring.h"
+
+/**
+ * @file
+ * Format register and lookup
+ */
+/** head of registered input format linked list */
+static AVInputFormat *first_iformat = NULL;
+/** head of registered output format linked list */
+static AVOutputFormat *first_oformat = NULL;
+
+AVInputFormat *av_iformat_next(AVInputFormat *f)
+{
+ if (f)
+ return f->next;
+ else
+ return first_iformat;
+}
+
+AVOutputFormat *av_oformat_next(AVOutputFormat *f)
+{
+ if (f)
+ return f->next;
+ else
+ return first_oformat;
+}
+
+void av_register_input_format(AVInputFormat *format)
+{
+ AVInputFormat **p = &first_iformat;
+
+ format->next = NULL;
+ while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
+ p = &(*p)->next;
+}
+
+void av_register_output_format(AVOutputFormat *format)
+{
+ AVOutputFormat **p = &first_oformat;
+
+ format->next = NULL;
+ while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
+ p = &(*p)->next;
+}
+
+int av_match_ext(const char *filename, const char *extensions)
+{
+ const char *ext, *p;
+ char ext1[32], *q;
+
+ if (!filename)
+ return 0;
+
+ ext = strrchr(filename, '.');
+ if (ext) {
+ ext++;
+ p = extensions;
+ for (;;) {
+ q = ext1;
+ while (*p != '\0' && *p != ',' && q - ext1 < sizeof(ext1) - 1)
+ *q++ = *p++;
+ *q = '\0';
+ if (!av_strcasecmp(ext1, ext))
+ return 1;
+ if (*p == '\0')
+ break;
+ p++;
+ }
+ }
+ return 0;
+}
+
+static int match_format(const char *name, const char *names)
+{
+ const char *p;
+ int len, namelen;
+
+ if (!name || !names)
+ return 0;
+
+ namelen = strlen(name);
+ while ((p = strchr(names, ','))) {
+ len = FFMAX(p - names, namelen);
+ if (!av_strncasecmp(name, names, len))
+ return 1;
+ names = p + 1;
+ }
+ return !av_strcasecmp(name, names);
+}
+
+AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
+ const char *mime_type)
+{
+ AVOutputFormat *fmt = NULL, *fmt_found;
+ int score_max, score;
+
+ /* specific test for image sequences */
+#if CONFIG_IMAGE2_MUXER
+ if (!short_name && filename &&
+ av_filename_number_test(filename) &&
+ ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
+ return av_guess_format("image2", NULL, NULL);
+ }
+#endif
+ /* Find the proper file type. */
+ fmt_found = NULL;
+ score_max = 0;
+ while ((fmt = av_oformat_next(fmt))) {
+ score = 0;
+ if (fmt->name && short_name && match_format(short_name, fmt->name))
+ score += 100;
+ if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
+ score += 10;
+ if (filename && fmt->extensions &&
+ av_match_ext(filename, fmt->extensions)) {
+ score += 5;
+ }
+ if (score > score_max) {
+ score_max = score;
+ fmt_found = fmt;
+ }
+ }
+ return fmt_found;
+}
+
+enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+ const char *filename, const char *mime_type,
+ enum AVMediaType type)
+{
+ if (!strcmp(fmt->name, "segment") || !strcmp(fmt->name, "ssegment")) {
+ fmt = av_guess_format(NULL, filename, NULL);
+ }
+
+ if (type == AVMEDIA_TYPE_VIDEO) {
+ enum AVCodecID codec_id = AV_CODEC_ID_NONE;
+
+#if CONFIG_IMAGE2_MUXER
+ if (!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")) {
+ codec_id = ff_guess_image2_codec(filename);
+ }
+#endif
+ if (codec_id == AV_CODEC_ID_NONE)
+ codec_id = fmt->video_codec;
+ return codec_id;
+ } else if (type == AVMEDIA_TYPE_AUDIO)
+ return fmt->audio_codec;
+ else if (type == AVMEDIA_TYPE_SUBTITLE)
+ return fmt->subtitle_codec;
+ else
+ return AV_CODEC_ID_NONE;
+}
+
+AVInputFormat *av_find_input_format(const char *short_name)
+{
+ AVInputFormat *fmt = NULL;
+ while ((fmt = av_iformat_next(fmt)))
+ if (match_format(short_name, fmt->name))
+ return fmt;
+ return NULL;
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/framecrcenc.c b/chromium/third_party/ffmpeg/libavformat/framecrcenc.c
index df0ae79330a..dbe49b5ba1e 100644
--- a/chromium/third_party/ffmpeg/libavformat/framecrcenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/framecrcenc.c
@@ -34,13 +34,22 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
if (pkt->flags != AV_PKT_FLAG_KEY)
av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags);
if (pkt->side_data_elems) {
- int i;
+ int i, j;
av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems);
for (i=0; i<pkt->side_data_elems; i++) {
- uint32_t side_data_crc = av_adler32_update(0,
- pkt->side_data[i].data,
- pkt->side_data[i].size);
+ uint32_t side_data_crc = 0;
+ if (HAVE_BIGENDIAN && AV_PKT_DATA_PALETTE == pkt->side_data[i].type) {
+ for (j=0; j<pkt->side_data[i].size; j++) {
+ side_data_crc = av_adler32_update(side_data_crc,
+ pkt->side_data[i].data + (j^3),
+ 1);
+ }
+ } else {
+ side_data_crc = av_adler32_update(0,
+ pkt->side_data[i].data,
+ pkt->side_data[i].size);
+ }
av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08x", pkt->side_data[i].size, side_data_crc);
}
}
@@ -56,5 +65,6 @@ AVOutputFormat ff_framecrc_muxer = {
.video_codec = AV_CODEC_ID_RAWVIDEO,
.write_header = ff_framehash_write_header,
.write_packet = framecrc_write_packet,
- .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+ AVFMT_TS_NEGATIVE,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/ftp.c b/chromium/third_party/ffmpeg/libavformat/ftp.c
new file mode 100644
index 00000000000..1a4708109b3
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/ftp.c
@@ -0,0 +1,721 @@
+/*
+ * Copyright (c) 2013 Lukasz Marek <lukasz.m.luki@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 "libavutil/avstring.h"
+#include "avformat.h"
+#include "internal.h"
+#include "url.h"
+#include "libavutil/opt.h"
+#include "libavutil/bprint.h"
+
+#define CONTROL_BUFFER_SIZE 1024
+#define CREDENTIALS_BUFFER_SIZE 128
+
+typedef enum {
+ UNKNOWN,
+ READY,
+ DOWNLOADING,
+ UPLOADING,
+ DISCONNECTED
+} FTPState;
+
+typedef struct {
+ const AVClass *class;
+ URLContext *conn_control; /**< Control connection */
+ URLContext *conn_data; /**< Data connection, NULL when not connected */
+ uint8_t control_buffer[CONTROL_BUFFER_SIZE]; /**< Control connection buffer */
+ uint8_t *control_buf_ptr, *control_buf_end;
+ int server_data_port; /**< Data connection port opened by server, -1 on error. */
+ int server_control_port; /**< Control connection port, default is 21 */
+ char hostname[512]; /**< Server address. */
+ char credencials[CREDENTIALS_BUFFER_SIZE]; /**< Authentication data */
+ char path[MAX_URL_SIZE]; /**< Path to resource on server. */
+ int64_t filesize; /**< Size of file on server, -1 on error. */
+ int64_t position; /**< Current position, calculated. */
+ int rw_timeout; /**< Network timeout. */
+ const char *anonymous_password; /**< Password to be used for anonymous user. An email should be used. */
+ int write_seekable; /**< Control seekability, 0 = disable, 1 = enable. */
+ FTPState state; /**< State of data connection */
+} FTPContext;
+
+#define OFFSET(x) offsetof(FTPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
+ {"ftp-write-seekable", "control seekability of connection during encoding", OFFSET(write_seekable), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+ {"ftp-anonymous-password", "password for anonymous login. E-mail address should be used.", OFFSET(anonymous_password), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
+ {NULL}
+};
+
+static const AVClass ftp_context_class = {
+ .class_name = "ftp",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int ftp_getc(FTPContext *s)
+{
+ int len;
+ if (s->control_buf_ptr >= s->control_buf_end) {
+ len = ffurl_read(s->conn_control, s->control_buffer, CONTROL_BUFFER_SIZE);
+ if (len < 0) {
+ return len;
+ } else if (!len) {
+ return -1;
+ } else {
+ s->control_buf_ptr = s->control_buffer;
+ s->control_buf_end = s->control_buffer + len;
+ }
+ }
+ return *s->control_buf_ptr++;
+}
+
+static int ftp_get_line(FTPContext *s, char *line, int line_size)
+{
+ int ch;
+ char *q = line;
+
+ for (;;) {
+ ch = ftp_getc(s);
+ if (ch < 0) {
+ return ch;
+ }
+ if (ch == '\n') {
+ /* process line */
+ if (q > line && q[-1] == '\r')
+ q--;
+ *q = '\0';
+ return 0;
+ } else {
+ if ((q - line) < line_size - 1)
+ *q++ = ch;
+ }
+ }
+}
+
+/*
+ * This routine returns ftp server response code.
+ * Server may send more than one response for a certain command.
+ * First expected code is returned.
+ */
+static int ftp_status(FTPContext *s, char **line, const int response_codes[])
+{
+ int err, i, dash = 0, result = 0, code_found = 0;
+ char buf[CONTROL_BUFFER_SIZE];
+ AVBPrint line_buffer;
+
+ if (line)
+ av_bprint_init(&line_buffer, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
+ while (!code_found || dash) {
+ if ((err = ftp_get_line(s, buf, sizeof(buf))) < 0) {
+ av_bprint_finalize(&line_buffer, NULL);
+ return err;
+ }
+
+ av_log(s, AV_LOG_DEBUG, "%s\n", buf);
+
+ if (strlen(buf) < 4)
+ continue;
+
+ err = 0;
+ for (i = 0; i < 3; ++i) {
+ if (buf[i] < '0' || buf[i] > '9')
+ continue;
+ err *= 10;
+ err += buf[i] - '0';
+ }
+ dash = !!(buf[3] == '-');
+
+ for (i = 0; response_codes[i]; ++i) {
+ if (err == response_codes[i]) {
+ if (line)
+ av_bprintf(&line_buffer, "%s", buf);
+ code_found = 1;
+ result = err;
+ break;
+ }
+ }
+ }
+
+ if (line)
+ av_bprint_finalize(&line_buffer, line);
+ return result;
+}
+
+static int ftp_send_command(FTPContext *s, const char *command,
+ const int response_codes[], char **response)
+{
+ int err;
+
+ if ((err = ffurl_write(s->conn_control, command, strlen(command))) < 0)
+ return err;
+ if (!err)
+ return -1;
+
+ /* return status */
+ if (response_codes) {
+ return ftp_status(s, response, response_codes);
+ }
+ return 0;
+}
+
+static void ftp_close_data_connection(FTPContext *s)
+{
+ ffurl_closep(&s->conn_data);
+ s->position = 0;
+ s->state = DISCONNECTED;
+}
+
+static void ftp_close_both_connections(FTPContext *s)
+{
+ ffurl_closep(&s->conn_control);
+ ftp_close_data_connection(s);
+}
+
+static int ftp_auth(FTPContext *s)
+{
+ const char *user = NULL, *pass = NULL;
+ char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE];
+ int err;
+ const int user_codes[] = {331, 230, 500, 530, 0}; /* 500, 530 are incorrect codes */
+ const int pass_codes[] = {230, 503, 530, 0}; /* 503, 530 are incorrect codes */
+
+ /* Authentication may be repeated, original string has to be saved */
+ av_strlcpy(credencials, s->credencials, sizeof(credencials));
+
+ user = av_strtok(credencials, ":", &end);
+ pass = av_strtok(end, ":", &end);
+
+ if (!user) {
+ user = "anonymous";
+ pass = s->anonymous_password ? s->anonymous_password : "nopassword";
+ }
+
+ snprintf(buf, sizeof(buf), "USER %s\r\n", user);
+ err = ftp_send_command(s, buf, user_codes, NULL);
+ if (err == 331) {
+ if (pass) {
+ snprintf(buf, sizeof(buf), "PASS %s\r\n", pass);
+ err = ftp_send_command(s, buf, pass_codes, NULL);
+ } else
+ return AVERROR(EACCES);
+ }
+ if (err != 230)
+ return AVERROR(EACCES);
+
+ return 0;
+}
+
+static int ftp_passive_mode(FTPContext *s)
+{
+ char *res = NULL, *start = NULL, *end = NULL;
+ int i;
+ const char *command = "PASV\r\n";
+ const int pasv_codes[] = {227, 501, 0}; /* 501 is incorrect code */
+
+ if (ftp_send_command(s, command, pasv_codes, &res) != 227 || !res)
+ goto fail;
+
+ for (i = 0; res[i]; ++i) {
+ if (res[i] == '(') {
+ start = res + i + 1;
+ } else if (res[i] == ')') {
+ end = res + i;
+ break;
+ }
+ }
+ if (!start || !end)
+ goto fail;
+
+ *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;
+
+ /* parse port number */
+ start = av_strtok(end, ",", &end);
+ if (!start) goto fail;
+ s->server_data_port = atoi(start) * 256;
+ start = av_strtok(end, ",", &end);
+ if (!start) goto fail;
+ s->server_data_port += atoi(start);
+ av_dlog(s, "Server data port: %d\n", s->server_data_port);
+
+ av_free(res);
+ return 0;
+
+ fail:
+ av_free(res);
+ s->server_data_port = -1;
+ return AVERROR(EIO);
+}
+
+static int ftp_current_dir(FTPContext *s)
+{
+ char *res = NULL, *start = NULL, *end = NULL;
+ int i;
+ const char *command = "PWD\r\n";
+ const int pwd_codes[] = {257, 0};
+
+ if (ftp_send_command(s, command, pwd_codes, &res) != 257 || !res)
+ goto fail;
+
+ for (i = 0; res[i]; ++i) {
+ if (res[i] == '"') {
+ if (!start) {
+ start = res + i + 1;
+ continue;
+ }
+ end = res + i;
+ break;
+ }
+ }
+
+ if (!end)
+ goto fail;
+
+ if (end > res && end[-1] == '/') {
+ end[-1] = '\0';
+ } else
+ *end = '\0';
+ av_strlcpy(s->path, start, sizeof(s->path));
+
+ av_free(res);
+ return 0;
+
+ fail:
+ av_free(res);
+ return AVERROR(EIO);
+}
+
+static int ftp_file_size(FTPContext *s)
+{
+ char command[CONTROL_BUFFER_SIZE];
+ char *res = NULL;
+ const int size_codes[] = {213, 501, 550, 0}; /* 501, 550 are incorrect codes */
+
+ snprintf(command, sizeof(command), "SIZE %s\r\n", s->path);
+ if (ftp_send_command(s, command, size_codes, &res) == 213 && res) {
+ s->filesize = strtoll(&res[4], NULL, 10);
+ } else {
+ s->filesize = -1;
+ av_free(res);
+ return AVERROR(EIO);
+ }
+
+ av_free(res);
+ return 0;
+}
+
+static int ftp_retrieve(FTPContext *s)
+{
+ char command[CONTROL_BUFFER_SIZE];
+ const int retr_codes[] = {150, 550, 554, 0}; /* 550, 554 are incorrect codes */
+
+ snprintf(command, sizeof(command), "RETR %s\r\n", s->path);
+ if (ftp_send_command(s, command, retr_codes, NULL) != 150)
+ return AVERROR(EIO);
+
+ s->state = DOWNLOADING;
+
+ return 0;
+}
+
+static int ftp_store(FTPContext *s)
+{
+ char command[CONTROL_BUFFER_SIZE];
+ const int stor_codes[] = {150, 0};
+
+ snprintf(command, sizeof(command), "STOR %s\r\n", s->path);
+ if (ftp_send_command(s, command, stor_codes, NULL) != 150)
+ return AVERROR(EIO);
+
+ s->state = UPLOADING;
+
+ return 0;
+}
+
+static int ftp_type(FTPContext *s)
+{
+ const char *command = "TYPE I\r\n";
+ const int type_codes[] = {200, 500, 504, 0}; /* 500, 504 are incorrect codes */
+
+ if (ftp_send_command(s, command, type_codes, NULL) != 200)
+ return AVERROR(EIO);
+
+ return 0;
+}
+
+static int ftp_restart(FTPContext *s, int64_t pos)
+{
+ char command[CONTROL_BUFFER_SIZE];
+ const int rest_codes[] = {350, 500, 501, 0}; /* 500, 501 are incorrect codes */
+
+ snprintf(command, sizeof(command), "REST %"PRId64"\r\n", pos);
+ if (ftp_send_command(s, command, rest_codes, NULL) != 350)
+ return AVERROR(EIO);
+
+ return 0;
+}
+
+static int ftp_connect_control_connection(URLContext *h)
+{
+ char buf[CONTROL_BUFFER_SIZE], opts_format[20], *response = NULL;
+ int err;
+ AVDictionary *opts = NULL;
+ FTPContext *s = h->priv_data;
+ const int connect_codes[] = {220, 0};
+
+ if (!s->conn_control) {
+ ff_url_join(buf, sizeof(buf), "tcp", NULL,
+ s->hostname, s->server_control_port, NULL);
+ if (s->rw_timeout != -1) {
+ snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+ av_dict_set(&opts, "timeout", opts_format, 0);
+ } /* if option is not given, don't pass it and let tcp use its own default */
+ err = ffurl_open(&s->conn_control, buf, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, &opts);
+ av_dict_free(&opts);
+ if (err < 0) {
+ av_log(h, AV_LOG_ERROR, "Cannot open control connection\n");
+ return err;
+ }
+
+ /* check if server is ready */
+ if (ftp_status(s, ((h->flags & AVIO_FLAG_WRITE) ? &response : NULL), connect_codes) != 220) {
+ av_log(h, AV_LOG_ERROR, "FTP server not ready for new users\n");
+ return AVERROR(EACCES);
+ }
+
+ if ((h->flags & AVIO_FLAG_WRITE) && av_stristr(response, "pure-ftpd")) {
+ av_log(h, AV_LOG_WARNING, "Pure-FTPd server is used as an output protocol. It is known issue this implementation may produce incorrect content and it cannot be fixed at this moment.");
+ }
+ av_free(response);
+
+ if ((err = ftp_auth(s)) < 0) {
+ av_log(h, AV_LOG_ERROR, "FTP authentication failed\n");
+ return err;
+ }
+
+ if ((err = ftp_type(s)) < 0) {
+ av_dlog(h, "Set content type failed\n");
+ return err;
+ }
+ }
+ return 0;
+}
+
+static int ftp_connect_data_connection(URLContext *h)
+{
+ int err;
+ char buf[CONTROL_BUFFER_SIZE], opts_format[20];
+ AVDictionary *opts = NULL;
+ FTPContext *s = h->priv_data;
+
+ if (!s->conn_data) {
+ /* Enter passive mode */
+ if ((err = ftp_passive_mode(s)) < 0) {
+ av_dlog(h, "Set passive mode failed\n");
+ return err;
+ }
+ /* Open data connection */
+ ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);
+ if (s->rw_timeout != -1) {
+ snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+ av_dict_set(&opts, "timeout", opts_format, 0);
+ } /* if option is not given, don't pass it and let tcp use its own default */
+ err = ffurl_open(&s->conn_data, buf, h->flags,
+ &h->interrupt_callback, &opts);
+ av_dict_free(&opts);
+ if (err < 0)
+ return err;
+
+ if (s->position)
+ if ((err = ftp_restart(s, s->position)) < 0)
+ return err;
+ }
+ s->state = READY;
+ return 0;
+}
+
+static int ftp_abort(URLContext *h)
+{
+ const char *command = "ABOR\r\n";
+ int err;
+ const int abor_codes[] = {225, 226, 0};
+ FTPContext *s = h->priv_data;
+
+ /* According to RCF 959:
+ "ABOR command tells the server to abort the previous FTP
+ service command and any associated transfer of data."
+
+ There are FTP server implementations that don't response
+ to any commands during data transfer in passive mode (including ABOR).
+
+ This implementation closes data connection by force.
+ */
+
+ if (ftp_send_command(s, command, NULL, NULL) < 0) {
+ ftp_close_both_connections(s);
+ if ((err = ftp_connect_control_connection(h)) < 0) {
+ av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
+ return err;
+ }
+ } else {
+ ftp_close_data_connection(s);
+ }
+
+ if (ftp_status(s, NULL, abor_codes) < 225) {
+ /* wu-ftpd also closes control connection after data connection closing */
+ ffurl_closep(&s->conn_control);
+ if ((err = ftp_connect_control_connection(h)) < 0) {
+ av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int ftp_open(URLContext *h, const char *url, int flags)
+{
+ char proto[10], path[MAX_URL_SIZE];
+ int err;
+ FTPContext *s = h->priv_data;
+
+ av_dlog(h, "ftp protocol open\n");
+
+ s->state = DISCONNECTED;
+ s->filesize = -1;
+ s->position = 0;
+
+ av_url_split(proto, sizeof(proto),
+ s->credencials, sizeof(s->credencials),
+ s->hostname, sizeof(s->hostname),
+ &s->server_control_port,
+ path, sizeof(path),
+ url);
+
+ if (s->server_control_port < 0 || s->server_control_port > 65535)
+ s->server_control_port = 21;
+
+ if ((err = ftp_connect_control_connection(h)) < 0)
+ goto fail;
+
+ if ((err = ftp_current_dir(s)) < 0)
+ goto fail;
+ av_strlcat(s->path, path, sizeof(s->path));
+
+ if (ftp_restart(s, 0) < 0) {
+ h->is_streamed = 1;
+ } else {
+ if (ftp_file_size(s) < 0 && flags & AVIO_FLAG_READ)
+ h->is_streamed = 1;
+ if (s->write_seekable != 1 && flags & AVIO_FLAG_WRITE)
+ h->is_streamed = 1;
+ }
+
+ return 0;
+
+ fail:
+ av_log(h, AV_LOG_ERROR, "FTP open failed\n");
+ ffurl_closep(&s->conn_control);
+ ffurl_closep(&s->conn_data);
+ return err;
+}
+
+static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
+{
+ FTPContext *s = h->priv_data;
+ int err;
+ int64_t new_pos, fake_pos;
+
+ av_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);
+
+ switch(whence) {
+ case AVSEEK_SIZE:
+ return s->filesize;
+ case SEEK_SET:
+ new_pos = pos;
+ break;
+ case SEEK_CUR:
+ new_pos = s->position + pos;
+ break;
+ case SEEK_END:
+ if (s->filesize < 0)
+ return AVERROR(EIO);
+ new_pos = s->filesize + pos;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ if (h->is_streamed)
+ return AVERROR(EIO);
+
+ /* XXX: Simulate behaviour of lseek in file protocol, which could be treated as a reference */
+ new_pos = FFMAX(0, new_pos);
+ fake_pos = s->filesize != -1 ? FFMIN(new_pos, s->filesize) : new_pos;
+
+ if (fake_pos != s->position) {
+ if ((err = ftp_abort(h)) < 0)
+ return err;
+ s->position = fake_pos;
+ }
+ return new_pos;
+}
+
+static int ftp_read(URLContext *h, unsigned char *buf, int size)
+{
+ FTPContext *s = h->priv_data;
+ int read, err, retry_done = 0;
+
+ av_dlog(h, "ftp protocol read %d bytes\n", size);
+ retry:
+ if (s->state == DISCONNECTED) {
+ /* optimization */
+ if (s->position >= s->filesize)
+ return 0;
+ if ((err = ftp_connect_data_connection(h)) < 0)
+ return err;
+ }
+ if (s->state == READY) {
+ if (s->position >= s->filesize)
+ return 0;
+ if ((err = ftp_retrieve(s)) < 0)
+ return err;
+ }
+ if (s->conn_data && s->state == DOWNLOADING) {
+ read = ffurl_read(s->conn_data, buf, size);
+ if (read >= 0) {
+ s->position += read;
+ if (s->position >= s->filesize) {
+ /* server will terminate, but keep current position to avoid madness */
+ /* save position to restart from it */
+ int64_t pos = s->position;
+ if (ftp_abort(h) < 0) {
+ s->position = pos;
+ return AVERROR(EIO);
+ }
+ s->position = pos;
+ }
+ }
+ if (read <= 0 && s->position < s->filesize && !h->is_streamed) {
+ /* Server closed connection. Probably due to inactivity */
+ int64_t pos = s->position;
+ av_log(h, AV_LOG_INFO, "Reconnect to FTP server.\n");
+ if ((err = ftp_abort(h)) < 0)
+ return err;
+ if ((err = ftp_seek(h, pos, SEEK_SET)) < 0) {
+ av_log(h, AV_LOG_ERROR, "Position cannot be restored.\n");
+ return err;
+ }
+ if (!retry_done) {
+ retry_done = 1;
+ goto retry;
+ }
+ }
+ return read;
+ }
+
+ av_log(h, AV_LOG_DEBUG, "FTP read failed\n");
+ return AVERROR(EIO);
+}
+
+static int ftp_write(URLContext *h, const unsigned char *buf, int size)
+{
+ int err;
+ FTPContext *s = h->priv_data;
+ int written;
+
+ av_dlog(h, "ftp protocol write %d bytes\n", size);
+
+ if (s->state == DISCONNECTED) {
+ if ((err = ftp_connect_data_connection(h)) < 0)
+ return err;
+ }
+ if (s->state == READY) {
+ if ((err = ftp_store(s)) < 0)
+ return err;
+ }
+ if (s->conn_data && s->state == UPLOADING) {
+ written = ffurl_write(s->conn_data, buf, size);
+ if (written > 0) {
+ s->position += written;
+ s->filesize = FFMAX(s->filesize, s->position);
+ }
+ return written;
+ }
+
+ av_log(h, AV_LOG_ERROR, "FTP write failed\n");
+ return AVERROR(EIO);
+}
+
+static int ftp_close(URLContext *h)
+{
+ av_dlog(h, "ftp protocol close\n");
+
+ ftp_close_both_connections(h->priv_data);
+
+ return 0;
+}
+
+static int ftp_get_file_handle(URLContext *h)
+{
+ FTPContext *s = h->priv_data;
+
+ av_dlog(h, "ftp protocol get_file_handle\n");
+
+ if (s->conn_data)
+ return ffurl_get_file_handle(s->conn_data);
+
+ return AVERROR(EIO);
+}
+
+static int ftp_shutdown(URLContext *h, int flags)
+{
+ FTPContext *s = h->priv_data;
+
+ av_dlog(h, "ftp protocol shutdown\n");
+
+ if (s->conn_data)
+ return ffurl_shutdown(s->conn_data, flags);
+
+ return AVERROR(EIO);
+}
+
+URLProtocol ff_ftp_protocol = {
+ .name = "ftp",
+ .url_open = ftp_open,
+ .url_read = ftp_read,
+ .url_write = ftp_write,
+ .url_seek = ftp_seek,
+ .url_close = ftp_close,
+ .url_get_file_handle = ftp_get_file_handle,
+ .url_shutdown = ftp_shutdown,
+ .priv_data_size = sizeof(FTPContext),
+ .priv_data_class = &ftp_context_class,
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/g723_1.c b/chromium/third_party/ffmpeg/libavformat/g723_1.c
index 8d35f885a8a..4f3ce8f0aeb 100644
--- a/chromium/third_party/ffmpeg/libavformat/g723_1.c
+++ b/chromium/third_party/ffmpeg/libavformat/g723_1.c
@@ -24,13 +24,14 @@
* G.723.1 demuxer
*/
+#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
#include "avformat.h"
#include "internal.h"
static const uint8_t frame_size[4] = { 24, 20, 4, 1 };
-static int g723_1_init(AVFormatContext *s)
+static av_cold int g723_1_init(AVFormatContext *s)
{
AVStream *st;
diff --git a/chromium/third_party/ffmpeg/libavformat/gif.c b/chromium/third_party/ffmpeg/libavformat/gif.c
index d459bd6032a..f6e76254da3 100644
--- a/chromium/third_party/ffmpeg/libavformat/gif.c
+++ b/chromium/third_party/ffmpeg/libavformat/gif.c
@@ -52,21 +52,24 @@ static int gif_image_write_header(AVIOContext *pb, int width, int height,
avio_w8(pb, 0); /* aspect ratio */
}
- /* "NETSCAPE EXTENSION" for looped animation GIF */
- avio_w8(pb, 0x21); /* GIF Extension code */
- avio_w8(pb, 0xff); /* Application Extension Label */
- avio_w8(pb, 0x0b); /* Length of Application Block */
- avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1);
- avio_w8(pb, 0x03); /* Length of Data Sub-Block */
- avio_w8(pb, 0x01);
- avio_wl16(pb, (uint16_t)loop_count);
- avio_w8(pb, 0x00); /* Data Sub-block Terminator */
+
+ if (loop_count >= 0 ) {
+ /* "NETSCAPE EXTENSION" for looped animation GIF */
+ avio_w8(pb, 0x21); /* GIF Extension code */
+ avio_w8(pb, 0xff); /* Application Extension Label */
+ avio_w8(pb, 0x0b); /* Length of Application Block */
+ avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1);
+ avio_w8(pb, 0x03); /* Length of Data Sub-Block */
+ avio_w8(pb, 0x01);
+ avio_wl16(pb, (uint16_t)loop_count);
+ avio_w8(pb, 0x00); /* Data Sub-block Terminator */
+ }
return 0;
}
typedef struct {
- AVClass *class; /** Class for private options. */
+ AVClass *class;
int loop;
int last_delay;
AVPacket *prev_pkt;
@@ -189,8 +192,8 @@ static int gif_write_trailer(AVFormatContext *s)
#define OFFSET(x) offsetof(GIFContext, x)
#define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "loop", "Number of times to loop the output.", OFFSET(loop),
- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 65535, ENC },
+ { "loop", "Number of times to loop the output: -1 - no loop, 0 - infinite loop", OFFSET(loop),
+ AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 65535, ENC },
{ "final_delay", "Force delay (in ms) after the last frame", OFFSET(last_delay),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, ENC },
{ NULL },
diff --git a/chromium/third_party/ffmpeg/libavformat/gsmdec.c b/chromium/third_party/ffmpeg/libavformat/gsmdec.c
index 98992661737..a51822ad235 100644
--- a/chromium/third_party/ffmpeg/libavformat/gsmdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/gsmdec.c
@@ -80,7 +80,7 @@ static const AVOption options[] = {
{ NULL },
};
-static const AVClass class = {
+static const AVClass gsm_class = {
.class_name = "gsm demuxer",
.item_name = av_default_item_name,
.option = options,
@@ -96,5 +96,5 @@ AVInputFormat ff_gsm_demuxer = {
.flags = AVFMT_GENERIC_INDEX,
.extensions = "gsm",
.raw_codec_id = AV_CODEC_ID_GSM,
- .priv_class = &class,
+ .priv_class = &gsm_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/gxf.c b/chromium/third_party/ffmpeg/libavformat/gxf.c
index 86e629135d9..e15d06aaf9b 100644
--- a/chromium/third_party/ffmpeg/libavformat/gxf.c
+++ b/chromium/third_party/ffmpeg/libavformat/gxf.c
@@ -116,12 +116,10 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
st->codec->codec_id = AV_CODEC_ID_MJPEG;
break;
case 13:
- case 15:
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_DVVIDEO;
- break;
case 14:
+ case 15:
case 16:
+ case 25:
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = AV_CODEC_ID_DVVIDEO;
break;
@@ -165,6 +163,12 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
st->codec->sample_rate = 48000;
break;
+ case 26: /* AVCi50 / AVCi100 (AVC Intra) */
+ case 29: /* AVCHD */
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = CODEC_ID_H264;
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
+ break;
// timecode tracks:
case 7:
case 8:
@@ -172,6 +176,10 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
st->codec->codec_type = AVMEDIA_TYPE_DATA;
st->codec->codec_id = AV_CODEC_ID_NONE;
break;
+ case 30:
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_DNXHD;
+ break;
default:
st->codec->codec_type = AVMEDIA_TYPE_UNKNOWN;
st->codec->codec_id = AV_CODEC_ID_NONE;
diff --git a/chromium/third_party/ffmpeg/libavformat/gxfenc.c b/chromium/third_party/ffmpeg/libavformat/gxfenc.c
index 9322f7b88b7..57bb26cd0d3 100644
--- a/chromium/third_party/ffmpeg/libavformat/gxfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/gxfenc.c
@@ -217,12 +217,27 @@ static int gxf_write_mpeg_auxiliary(AVIOContext *pb, AVStream *st)
return size + 3;
}
+static int gxf_write_dv_auxiliary(AVIOContext *pb, AVStream *st)
+{
+ int64_t track_aux_data = 0;
+
+ avio_w8(pb, TRACK_AUX);
+ avio_w8(pb, 8);
+ if (st->codec->pix_fmt == AV_PIX_FMT_YUV420P)
+ track_aux_data |= 0x01; /* marks stream as DVCAM instead of DVPRO */
+ track_aux_data |= 0x40000000; /* aux data is valid */
+ avio_wl64(pb, track_aux_data);
+ return 8;
+}
+
static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFContext *gxf)
{
uint32_t timecode = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
gxf->tc.hh, gxf->tc.mm,
gxf->tc.ss, gxf->tc.ff);
+ avio_w8(pb, TRACK_AUX);
+ avio_w8(pb, 8);
avio_wl32(pb, timecode);
/* reserved */
avio_wl32(pb, 0);
@@ -234,7 +249,6 @@ static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc,
GXFContext *gxf = s->priv_data;
AVIOContext *pb = s->pb;
int64_t pos;
- int mpeg = sc->track_type == 4 || sc->track_type == 9;
/* track description section */
avio_w8(pb, sc->media_type + 0x80);
@@ -250,13 +264,21 @@ static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc,
avio_wb16(pb, sc->media_info);
avio_w8(pb, 0);
- if (!mpeg) {
- /* auxiliary information */
- avio_w8(pb, TRACK_AUX);
- avio_w8(pb, 8);
- if (sc->track_type == 3)
+ switch (sc->track_type) {
+ case 3: /* timecode */
gxf_write_timecode_auxiliary(pb, gxf);
- else
+ break;
+ case 4: /* MPEG2 */
+ case 9: /* MPEG1 */
+ gxf_write_mpeg_auxiliary(pb, s->streams[index]);
+ break;
+ case 5: /* DV25 */
+ case 6: /* DV50 */
+ gxf_write_dv_auxiliary(pb, s->streams[index]);
+ break;
+ default:
+ avio_w8(pb, TRACK_AUX);
+ avio_w8(pb, 8);
avio_wl64(pb, 0);
}
@@ -265,9 +287,6 @@ static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc,
avio_w8(pb, 4);
avio_wb32(pb, 0);
- if (mpeg)
- gxf_write_mpeg_auxiliary(pb, s->streams[index]);
-
/* frame rate */
avio_w8(pb, TRACK_FPS);
avio_w8(pb, 4);
@@ -534,13 +553,20 @@ static int gxf_write_umf_media_timecode(AVIOContext *pb, int drop)
return 32;
}
-static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc)
+static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc, AVStream *st)
{
- int i;
+ int dv_umf_data = 0;
- for (i = 0; i < 8; i++) {
- avio_wb32(pb, 0);
- }
+ if (st->codec->pix_fmt == AV_PIX_FMT_YUV420P)
+ dv_umf_data |= 0x20; /* marks as DVCAM instead of DVPRO */
+ avio_wl32(pb, dv_umf_data);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
return 32;
}
@@ -604,7 +630,7 @@ static int gxf_write_umf_media_description(AVFormatContext *s)
gxf_write_umf_media_audio(pb, sc);
break;
case AV_CODEC_ID_DVVIDEO:
- gxf_write_umf_media_dv(pb, sc);
+ gxf_write_umf_media_dv(pb, sc, st);
break;
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/h261dec.c b/chromium/third_party/ffmpeg/libavformat/h261dec.c
index 1b254d613ac..8d882aec61a 100644
--- a/chromium/third_party/ffmpeg/libavformat/h261dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/h261dec.c
@@ -33,7 +33,7 @@ static int h261_probe(AVProbeData *p)
int src_fmt=0;
GetBitContext gb;
- init_get_bits(&gb, p->buf, p->buf_size*8);
+ init_get_bits8(&gb, p->buf, p->buf_size);
for(i=0; i<p->buf_size*8; i++){
if ((code & 0x01ff0000) || !(code & 0xff00)) {
@@ -56,9 +56,9 @@ static int h261_probe(AVProbeData *p)
}
}
if(valid_psc > 2*invalid_psc + 6){
- return 50;
+ return AVPROBE_SCORE_EXTENSION;
}else if(valid_psc > 2*invalid_psc + 2)
- return 25;
+ return AVPROBE_SCORE_EXTENSION / 2;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/h263dec.c b/chromium/third_party/ffmpeg/libavformat/h263dec.c
index 667fdbdcbbc..e6e0345b690 100644
--- a/chromium/third_party/ffmpeg/libavformat/h263dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/h263dec.c
@@ -56,9 +56,9 @@ static int h263_probe(AVProbeData *p)
}
}
if(valid_psc > 2*invalid_psc + 2*res_change + 3){
- return 50;
+ return AVPROBE_SCORE_EXTENSION;
}else if(valid_psc > 2*invalid_psc)
- return 25;
+ return AVPROBE_SCORE_EXTENSION / 2;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/h264dec.c b/chromium/third_party/ffmpeg/libavformat/h264dec.c
index 9c67ab9545d..5de582be667 100644
--- a/chromium/third_party/ffmpeg/libavformat/h264dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/h264dec.c
@@ -63,7 +63,7 @@ static int h264_probe(AVProbeData *p)
}
}
if(sps && pps && (idr||sli>3) && res<(sps+pps+idr))
- return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg
+ return AVPROBE_SCORE_EXTENSION + 1; // 1 more than .mpg
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/hls.c b/chromium/third_party/ffmpeg/libavformat/hls.c
index 7de6059c5a2..8554b7e84f1 100644
--- a/chromium/third_party/ffmpeg/libavformat/hls.c
+++ b/chromium/third_party/ffmpeg/libavformat/hls.c
@@ -56,7 +56,7 @@ enum KeyType {
};
struct segment {
- int duration;
+ int64_t duration;
char url[MAX_URL_SIZE];
char key[MAX_URL_SIZE];
enum KeyType key_type;
@@ -81,7 +81,7 @@ struct variant {
int stream_offset;
int finished;
- int target_duration;
+ int64_t target_duration;
int start_seq_no;
int n_segments;
struct segment **segments;
@@ -206,7 +206,8 @@ static void handle_key_args(struct key_info *info, const char *key,
static int parse_playlist(HLSContext *c, const char *url,
struct variant *var, AVIOContext *in)
{
- int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+ int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+ int64_t duration = 0;
enum KeyType key_type = KEY_NONE;
uint8_t iv[16] = "";
int has_iv = 0;
@@ -218,7 +219,7 @@ static int parse_playlist(HLSContext *c, const char *url,
if (!in) {
AVDictionary *opts = NULL;
close_in = 1;
- /* Some HLS servers dont like being sent the range header */
+ /* Some HLS servers don't like being sent the range header */
av_dict_set(&opts, "seekable", "0", 0);
// broker prior HTTP options that should be consistent across requests
@@ -271,7 +272,7 @@ static int parse_playlist(HLSContext *c, const char *url,
goto fail;
}
}
- var->target_duration = atoi(ptr);
+ var->target_duration = atoi(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
if (!var) {
var = new_variant(c, 0, url, NULL);
@@ -286,7 +287,7 @@ static int parse_playlist(HLSContext *c, const char *url,
var->finished = 1;
} else if (av_strstart(line, "#EXTINF:", &ptr)) {
is_segment = 1;
- duration = atoi(ptr);
+ duration = atof(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#", NULL)) {
continue;
} else if (line[0]) {
@@ -413,7 +414,6 @@ restart:
int64_t reload_interval = v->n_segments > 0 ?
v->segments[v->n_segments - 1]->duration :
v->target_duration;
- reload_interval *= 1000000;
reload:
if (!v->finished &&
@@ -423,7 +423,7 @@ reload:
/* If we need to reload the playlist again below (if
* there's still no more segments), switch to a reload
* interval of half the target duration. */
- reload_interval = v->target_duration * 500000LL;
+ reload_interval = v->target_duration / 2;
}
if (v->cur_seq_no < v->start_seq_no) {
av_log(NULL, AV_LOG_WARNING,
@@ -457,7 +457,8 @@ reload:
c->end_of_segment = 1;
c->cur_seq_no = v->cur_seq_no;
- if (v->ctx && v->ctx->nb_streams && v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
+ if (v->ctx && v->ctx->nb_streams &&
+ v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
v->needed = 0;
for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
i++) {
@@ -526,7 +527,7 @@ static int hls_read_header(AVFormatContext *s)
int64_t duration = 0;
for (i = 0; i < c->variants[0]->n_segments; i++)
duration += c->variants[0]->segments[i]->duration;
- s->duration = duration * AV_TIME_BASE;
+ s->duration = duration;
}
/* Open the demuxer for each variant */
@@ -534,7 +535,8 @@ static int hls_read_header(AVFormatContext *s)
struct variant *v = c->variants[i];
AVInputFormat *in_fmt = NULL;
char bitrate_str[20];
- AVProgram *program = NULL;
+ AVProgram *program;
+
if (v->n_segments == 0)
continue;
@@ -570,18 +572,17 @@ static int hls_read_header(AVFormatContext *s)
goto fail;
}
v->ctx->pb = &v->pb;
+ v->stream_offset = stream_offset;
ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
if (ret < 0)
goto fail;
- v->stream_offset = stream_offset;
v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
ret = avformat_find_stream_info(v->ctx, NULL);
if (ret < 0)
goto fail;
snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
- /* Create new AVprogram for variant i */
program = av_new_program(s, i);
if (!program)
goto fail;
@@ -678,8 +679,11 @@ start:
reset_packet(&var->pkt);
break;
} else {
- if (c->first_timestamp == AV_NOPTS_VALUE)
- c->first_timestamp = var->pkt.dts;
+ if (c->first_timestamp == AV_NOPTS_VALUE &&
+ var->pkt.dts != AV_NOPTS_VALUE)
+ c->first_timestamp = av_rescale_q(var->pkt.dts,
+ var->ctx->streams[var->pkt.stream_index]->time_base,
+ AV_TIME_BASE_Q);
}
if (c->seek_timestamp == AV_NOPTS_VALUE)
@@ -699,24 +703,34 @@ start:
c->seek_timestamp = AV_NOPTS_VALUE;
break;
}
+ av_free_packet(&var->pkt);
+ reset_packet(&var->pkt);
}
}
- /* Check if this stream has the packet with the lowest dts */
+ /* Check if this stream still is on an earlier segment number, or
+ * has the packet with the lowest dts */
if (var->pkt.data) {
- if(minvariant < 0) {
+ struct variant *minvar = c->variants[minvariant];
+ if (minvariant < 0 || var->cur_seq_no < minvar->cur_seq_no) {
minvariant = i;
- } else {
- struct variant *minvar = c->variants[minvariant];
- int64_t dts = var->pkt.dts;
- int64_t mindts = minvar->pkt.dts;
- AVStream *st = var->ctx->streams[ var->pkt.stream_index];
- AVStream *minst= minvar->ctx->streams[minvar->pkt.stream_index];
-
- if( st->start_time != AV_NOPTS_VALUE) dts -= st->start_time;
- if(minst->start_time != AV_NOPTS_VALUE) mindts -= minst->start_time;
+ } else if (var->cur_seq_no == minvar->cur_seq_no) {
+ int64_t dts = var->pkt.dts;
+ int64_t mindts = minvar->pkt.dts;
+ AVStream *st = var->ctx->streams[var->pkt.stream_index];
+ AVStream *minst = minvar->ctx->streams[minvar->pkt.stream_index];
- if (av_compare_ts(dts, st->time_base, mindts, minst->time_base) < 0)
+ if (dts == AV_NOPTS_VALUE) {
minvariant = i;
+ } else if (mindts != AV_NOPTS_VALUE) {
+ if (st->start_time != AV_NOPTS_VALUE)
+ dts -= st->start_time;
+ if (minst->start_time != AV_NOPTS_VALUE)
+ mindts -= minst->start_time;
+
+ if (av_compare_ts(dts, st->time_base,
+ mindts, minst->time_base) < 0)
+ minvariant = i;
+ }
}
}
}
@@ -757,7 +771,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
s->streams[stream_index]->time_base.den,
flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP);
- timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
+ timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE, stream_index >= 0 ?
s->streams[stream_index]->time_base.den :
AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP);
@@ -770,12 +784,9 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
for (i = 0; i < c->n_variants; i++) {
/* Reset reading */
struct variant *var = c->variants[i];
- int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
- av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
- s->streams[stream_index]->time_base.den :
- AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
- AV_ROUND_DOWN : AV_ROUND_UP);
- if (var->input) {
+ int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
+ 0 : c->first_timestamp;
+ if (var->input) {
ffurl_close(var->input);
var->input = NULL;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsenc.c b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
index 18914c026a9..dcd53e5f406 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
@@ -49,7 +49,7 @@ typedef struct HLSContext {
int has_video;
int64_t start_pts;
int64_t end_pts;
- int64_t duration; ///< last segment duration computed so far, in seconds
+ int64_t duration; // last segment duration computed so far, in seconds
int nb_entries;
ListEntry *list;
ListEntry *end_list;
@@ -164,14 +164,12 @@ static int hls_start(AVFormatContext *s)
AVFormatContext *oc = c->avf;
int err = 0;
- if (c->wrap)
- c->number %= c->wrap;
-
if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
- c->basename, c->number++) < 0) {
+ c->basename, c->wrap ? c->number % c->wrap : c->number) < 0) {
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename);
return AVERROR(EINVAL);
}
+ c->number++;
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL)) < 0)
@@ -253,25 +251,28 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
AVFormatContext *oc = hls->avf;
AVStream *st = s->streams[pkt->stream_index];
int64_t end_pts = hls->recording_time * hls->number;
- int ret, is_ref_pkt = 0;
+ int is_ref_pkt = 1;
+ int ret, can_split = 1;
if (hls->start_pts == AV_NOPTS_VALUE) {
hls->start_pts = pkt->pts;
hls->end_pts = pkt->pts;
}
- if ((hls->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
- pkt->pts != AV_NOPTS_VALUE) {
- is_ref_pkt = 1;
- hls->duration = av_rescale(pkt->pts - hls->end_pts,
- st->time_base.num, st->time_base.den);
+ if (hls->has_video) {
+ can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ pkt->flags & AV_PKT_FLAG_KEY;
+ is_ref_pkt = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
}
+ if (pkt->pts == AV_NOPTS_VALUE)
+ is_ref_pkt = can_split = 0;
- if (is_ref_pkt &&
- av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
- end_pts, AV_TIME_BASE_Q) >= 0 &&
- pkt->flags & AV_PKT_FLAG_KEY) {
+ if (is_ref_pkt)
+ hls->duration = av_rescale(pkt->pts - hls->end_pts,
+ st->time_base.num, st->time_base.den);
+ if (can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
+ end_pts, AV_TIME_BASE_Q) >= 0) {
ret = append_entry(hls, hls->duration);
if (ret)
return ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsproto.c b/chromium/third_party/ffmpeg/libavformat/hlsproto.c
index 4e35043a3e6..f6fcbe5e0eb 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsproto.c
@@ -45,7 +45,7 @@
*/
struct segment {
- int duration;
+ int64_t duration;
char url[MAX_URL_SIZE];
};
@@ -56,7 +56,7 @@ struct variant {
typedef struct HLSContext {
char playlisturl[MAX_URL_SIZE];
- int target_duration;
+ int64_t target_duration;
int start_seq_no;
int finished;
int n_segments;
@@ -111,7 +111,8 @@ static int parse_playlist(URLContext *h, const char *url)
{
HLSContext *s = h->priv_data;
AVIOContext *in;
- int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+ int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+ int64_t duration = 0;
char line[1024];
const char *ptr;
@@ -134,14 +135,14 @@ static int parse_playlist(URLContext *h, const char *url)
&info);
bandwidth = atoi(info.bandwidth);
} else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
- s->target_duration = atoi(ptr);
+ s->target_duration = atoi(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
s->start_seq_no = atoi(ptr);
} else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
s->finished = 1;
} else if (av_strstart(line, "#EXTINF:", &ptr)) {
is_segment = 1;
- duration = atoi(ptr);
+ duration = atof(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#", NULL)) {
continue;
} else if (line[0]) {
@@ -270,7 +271,6 @@ start:
reload_interval = s->n_segments > 0 ?
s->segments[s->n_segments - 1]->duration :
s->target_duration;
- reload_interval *= 1000000;
retry:
if (!s->finished) {
int64_t now = av_gettime();
@@ -280,7 +280,7 @@ retry:
/* If we need to reload the playlist again below (if
* there's still no more segments), switch to a reload
* interval of half the target duration. */
- reload_interval = s->target_duration * 500000LL;
+ reload_interval = s->target_duration / 2;
}
}
if (s->cur_seq_no < s->start_seq_no) {
diff --git a/chromium/third_party/ffmpeg/libavformat/http.c b/chromium/third_party/ffmpeg/libavformat/http.c
index 7f33ecaf292..3edddbfb173 100644
--- a/chromium/third_party/ffmpeg/libavformat/http.c
+++ b/chromium/third_party/ffmpeg/libavformat/http.c
@@ -29,6 +29,10 @@
#include "url.h"
#include "libavutil/opt.h"
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
/* XXX: POST protocol is not completely implemented because ffmpeg uses
only a subset of it. */
@@ -49,6 +53,8 @@ typedef struct {
char *content_type;
char *user_agent;
int64_t off, filesize;
+ int icy_data_read; ///< how much data was read since last ICY metadata packet
+ int icy_metaint; ///< after how many bytes of read data a new metadata packet will be found
char location[MAX_URL_SIZE];
HTTPAuthState auth_state;
HTTPAuthState proxy_auth_state;
@@ -65,12 +71,20 @@ typedef struct {
int rw_timeout;
char *mime_type;
char *cookies; ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
+ int icy;
+ char *icy_metadata_headers;
+ char *icy_metadata_packet;
+#if CONFIG_ZLIB
+ int compressed;
+ z_stream inflate_stream;
+ uint8_t *inflate_buffer;
+#endif
} HTTPContext;
#define OFFSET(x) offsetof(HTTPContext, x)
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
-#define DEFAULT_USER_AGENT "Mozilla/5.0 Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION)
+#define DEFAULT_USER_AGENT "Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION)
static const AVOption options[] = {
{"seekable", "control seekability of connection", OFFSET(seekable), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, D },
{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
@@ -82,6 +96,9 @@ static const AVOption options[] = {
{"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
{"mime_type", "set MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
{"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
+{"icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D },
+{"icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
+{"icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
{NULL}
};
#define HTTP_CLASS(flavor)\
@@ -218,6 +235,7 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
HTTPContext *s = h->priv_data;
s->off = 0;
+ s->icy_data_read = 0;
av_strlcpy(s->location, uri, sizeof(s->location));
return http_open_cnx(h);
@@ -289,6 +307,7 @@ static int process_line(URLContext *h, char *line, int line_count,
{
HTTPContext *s = h->priv_data;
char *tag, *p, *end;
+ char redirected_location[MAX_URL_SIZE];
/* end of header */
if (line[0] == '\0') {
@@ -328,7 +347,8 @@ static int process_line(URLContext *h, char *line, int line_count,
while (av_isspace(*p))
p++;
if (!av_strcasecmp(tag, "Location")) {
- av_strlcpy(s->location, p, sizeof(s->location));
+ ff_make_absolute_url(redirected_location, sizeof(redirected_location), s->location, p);
+ av_strlcpy(s->location, redirected_location, sizeof(s->location));
*new_location = 1;
} else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
s->filesize = strtoll(p, NULL, 10);
@@ -375,6 +395,41 @@ static int process_line(URLContext *h, char *line, int line_count,
snprintf(s->cookies, str_size, "%s\n%s", tmp, p);
av_free(tmp);
}
+ } else if (!av_strcasecmp (tag, "Icy-MetaInt")) {
+ s->icy_metaint = strtoll(p, NULL, 10);
+ } else if (!av_strncasecmp(tag, "Icy-", 4)) {
+ // Concat all Icy- header lines
+ char *buf = av_asprintf("%s%s: %s\n",
+ s->icy_metadata_headers ? s->icy_metadata_headers : "", tag, p);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ av_freep(&s->icy_metadata_headers);
+ s->icy_metadata_headers = buf;
+ } else if (!av_strcasecmp (tag, "Content-Encoding")) {
+ if (!av_strncasecmp(p, "gzip", 4) || !av_strncasecmp(p, "deflate", 7)) {
+#if CONFIG_ZLIB
+ s->compressed = 1;
+ inflateEnd(&s->inflate_stream);
+ if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
+ av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
+ s->inflate_stream.msg);
+ return AVERROR(ENOSYS);
+ }
+ if (zlibCompileFlags() & (1 << 17)) {
+ av_log(h, AV_LOG_WARNING, "Your zlib was compiled without gzip support.\n");
+ return AVERROR(ENOSYS);
+ }
+#else
+ av_log(h, AV_LOG_WARNING, "Compressed (%s) content, need zlib with gzip support\n", p);
+ return AVERROR(ENOSYS);
+#endif
+ } else if (!av_strncasecmp(p, "identity", 8)) {
+ // The normal, no-encoding case (although servers shouldn't include
+ // the header at all if this is the case).
+ } else {
+ av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
+ return AVERROR(ENOSYS);
+ }
}
}
return 1;
@@ -421,6 +476,8 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path,
cvalue = av_strdup(param);
}
}
+ if (!cdomain)
+ cdomain = av_strdup(domain);
// ensure all of the necessary values are valid
if (!cdomain || !cpath || !cvalue) {
@@ -578,6 +635,10 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
av_free(cookies);
}
}
+ if (!has_header(s->headers, "\r\nIcy-MetaData: ") && s->icy) {
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Icy-MetaData: %d\r\n", 1);
+ }
/* now add in custom headers */
if (s->headers)
@@ -611,6 +672,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
s->buf_end = s->buffer;
s->line_count = 0;
s->off = 0;
+ s->icy_data_read = 0;
s->filesize = -1;
s->willclose = 0;
s->end_chunked_post = 0;
@@ -650,12 +712,45 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
}
if (len > 0) {
s->off += len;
+ s->icy_data_read += len;
if (s->chunksize > 0)
s->chunksize -= len;
}
return len;
}
+#if CONFIG_ZLIB
+#define DECOMPRESS_BUF_SIZE (256 * 1024)
+static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+ int ret;
+
+ if (!s->inflate_buffer) {
+ s->inflate_buffer = av_malloc(DECOMPRESS_BUF_SIZE);
+ if (!s->inflate_buffer)
+ return AVERROR(ENOMEM);
+ }
+
+ if (s->inflate_stream.avail_in == 0) {
+ int read = http_buf_read(h, s->inflate_buffer, DECOMPRESS_BUF_SIZE);
+ if (read <= 0)
+ return read;
+ s->inflate_stream.next_in = s->inflate_buffer;
+ s->inflate_stream.avail_in = read;
+ }
+
+ s->inflate_stream.avail_out = size;
+ s->inflate_stream.next_out = buf;
+
+ ret = inflate(&s->inflate_stream, Z_SYNC_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ av_log(h, AV_LOG_WARNING, "inflate return value: %d, %s\n", ret, s->inflate_stream.msg);
+
+ return size - s->inflate_stream.avail_out;
+}
+#endif
+
static int http_read(URLContext *h, uint8_t *buf, int size)
{
HTTPContext *s = h->priv_data;
@@ -691,6 +786,36 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
}
size = FFMIN(size, s->chunksize);
}
+ if (s->icy_metaint > 0) {
+ int remaining = s->icy_metaint - s->icy_data_read; /* until next metadata packet */
+ if (!remaining) {
+ // The metadata packet is variable sized. It has a 1 byte header
+ // which sets the length of the packet (divided by 16). If it's 0,
+ // the metadata doesn't change. After the packet, icy_metaint bytes
+ // of normal data follow.
+ int ch = http_getc(s);
+ if (ch < 0)
+ return ch;
+ if (ch > 0) {
+ char data[255 * 16 + 1];
+ int n;
+ int ret;
+ ch *= 16;
+ for (n = 0; n < ch; n++)
+ data[n] = http_getc(s);
+ data[ch + 1] = 0;
+ if ((ret = av_opt_set(s, "icy_metadata_packet", data, 0)) < 0)
+ return ret;
+ }
+ s->icy_data_read = 0;
+ remaining = s->icy_metaint;
+ }
+ size = FFMIN(size, remaining);
+ }
+#if CONFIG_ZLIB
+ if (s->compressed)
+ return http_buf_read_compressed(h, buf, size);
+#endif
return http_buf_read(h, buf, size);
}
@@ -742,6 +867,11 @@ static int http_close(URLContext *h)
int ret = 0;
HTTPContext *s = h->priv_data;
+#if CONFIG_ZLIB
+ inflateEnd(&s->inflate_stream);
+ av_freep(&s->inflate_buffer);
+#endif
+
if (!s->end_chunked_post) {
/* Close the write direction by sending the end of chunked encoding. */
ret = http_shutdown(h, h->flags);
diff --git a/chromium/third_party/ffmpeg/libavformat/id3v2.c b/chromium/third_party/ffmpeg/libavformat/id3v2.c
index 3567bbc57b0..4bc76a321ca 100644
--- a/chromium/third_party/ffmpeg/libavformat/id3v2.c
+++ b/chromium/third_party/ffmpeg/libavformat/id3v2.c
@@ -32,72 +32,71 @@
#include <zlib.h>
#endif
-#include "id3v2.h"
-#include "id3v1.h"
#include "libavutil/avstring.h"
-#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
#include "avio_internal.h"
#include "internal.h"
+#include "id3v1.h"
+#include "id3v2.h"
const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
- { "TALB", "album"},
- { "TCOM", "composer"},
- { "TCON", "genre"},
- { "TCOP", "copyright"},
- { "TENC", "encoded_by"},
- { "TIT2", "title"},
- { "TLAN", "language"},
- { "TPE1", "artist"},
- { "TPE2", "album_artist"},
- { "TPE3", "performer"},
- { "TPOS", "disc"},
- { "TPUB", "publisher"},
- { "TRCK", "track"},
- { "TSSE", "encoder"},
+ { "TALB", "album" },
+ { "TCOM", "composer" },
+ { "TCON", "genre" },
+ { "TCOP", "copyright" },
+ { "TENC", "encoded_by" },
+ { "TIT2", "title" },
+ { "TLAN", "language" },
+ { "TPE1", "artist" },
+ { "TPE2", "album_artist" },
+ { "TPE3", "performer" },
+ { "TPOS", "disc" },
+ { "TPUB", "publisher" },
+ { "TRCK", "track" },
+ { "TSSE", "encoder" },
{ 0 }
};
const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
- { "TDRL", "date"},
- { "TDRC", "date"},
- { "TDEN", "creation_time"},
- { "TSOA", "album-sort"},
- { "TSOP", "artist-sort"},
- { "TSOT", "title-sort"},
+ { "TDRL", "date" },
+ { "TDRC", "date" },
+ { "TDEN", "creation_time" },
+ { "TSOA", "album-sort" },
+ { "TSOP", "artist-sort" },
+ { "TSOT", "title-sort" },
{ 0 }
};
static const AVMetadataConv id3v2_2_metadata_conv[] = {
- { "TAL", "album"},
- { "TCO", "genre"},
- { "TT2", "title"},
- { "TEN", "encoded_by"},
- { "TP1", "artist"},
- { "TP2", "album_artist"},
- { "TP3", "performer"},
- { "TRK", "track"},
+ { "TAL", "album" },
+ { "TCO", "genre" },
+ { "TT2", "title" },
+ { "TEN", "encoded_by" },
+ { "TP1", "artist" },
+ { "TP2", "album_artist" },
+ { "TP3", "performer" },
+ { "TRK", "track" },
{ 0 }
};
-
const char ff_id3v2_tags[][4] = {
- "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
- "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
- "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
- "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
- { 0 },
+ "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
+ "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
+ "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
+ "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
+ { 0 },
};
const char ff_id3v2_4_tags[][4] = {
- "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
- "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
- { 0 },
+ "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
+ "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
+ { 0 },
};
const char ff_id3v2_3_tags[][4] = {
- "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
- { 0 },
+ "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
+ { 0 },
};
const char *ff_id3v2_picture_types[21] = {
@@ -125,36 +124,36 @@ const char *ff_id3v2_picture_types[21] = {
};
const CodecMime ff_id3v2_mime_tags[] = {
- {"image/gif" , AV_CODEC_ID_GIF},
- {"image/jpeg", AV_CODEC_ID_MJPEG},
- {"image/jpg", AV_CODEC_ID_MJPEG},
- {"image/png" , AV_CODEC_ID_PNG},
- {"image/tiff", AV_CODEC_ID_TIFF},
- {"image/bmp", AV_CODEC_ID_BMP},
- {"JPG", AV_CODEC_ID_MJPEG}, /* ID3v2.2 */
- {"PNG" , AV_CODEC_ID_PNG}, /* ID3v2.2 */
- {"", AV_CODEC_ID_NONE},
+ { "image/gif", AV_CODEC_ID_GIF },
+ { "image/jpeg", AV_CODEC_ID_MJPEG },
+ { "image/jpg", AV_CODEC_ID_MJPEG },
+ { "image/png", AV_CODEC_ID_PNG },
+ { "image/tiff", AV_CODEC_ID_TIFF },
+ { "image/bmp", AV_CODEC_ID_BMP },
+ { "JPG", AV_CODEC_ID_MJPEG }, /* ID3v2.2 */
+ { "PNG", AV_CODEC_ID_PNG }, /* ID3v2.2 */
+ { "", AV_CODEC_ID_NONE },
};
-int ff_id3v2_match(const uint8_t *buf, const char * magic)
+int ff_id3v2_match(const uint8_t *buf, const char *magic)
{
return buf[0] == magic[0] &&
buf[1] == magic[1] &&
buf[2] == magic[2] &&
- buf[3] != 0xff &&
- buf[4] != 0xff &&
- (buf[6] & 0x80) == 0 &&
- (buf[7] & 0x80) == 0 &&
- (buf[8] & 0x80) == 0 &&
- (buf[9] & 0x80) == 0;
+ buf[3] != 0xff &&
+ buf[4] != 0xff &&
+ (buf[6] & 0x80) == 0 &&
+ (buf[7] & 0x80) == 0 &&
+ (buf[8] & 0x80) == 0 &&
+ (buf[9] & 0x80) == 0;
}
-int ff_id3v2_tag_len(const uint8_t * buf)
+int ff_id3v2_tag_len(const uint8_t *buf)
{
int len = ((buf[6] & 0x7f) << 21) +
((buf[7] & 0x7f) << 14) +
((buf[8] & 0x7f) << 7) +
- (buf[9] & 0x7f) +
+ (buf[9] & 0x7f) +
ID3v2_HEADER_SIZE;
if (buf[5] & 0x10)
len += ID3v2_HEADER_SIZE;
@@ -210,7 +209,6 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
}
switch (encoding) {
-
case ID3v2_ENCODING_ISO8859:
while (left && ch) {
ch = avio_r8(pb);
@@ -246,7 +244,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
}
if (left < 0)
- left += 2; /* did not read last char from pb */
+ left += 2; /* did not read last char from pb */
break;
case ID3v2_ENCODING_UTF8:
@@ -272,7 +270,8 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
/**
* Parse a text tag.
*/
-static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
+ AVDictionary **metadata, const char *key)
{
uint8_t *dst;
int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
@@ -289,9 +288,9 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
return;
}
- if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))
- && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1)
- && genre <= ID3v1_GENRE_MAX) {
+ if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) &&
+ (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
+ genre <= ID3v1_GENRE_MAX) {
av_freep(&dst);
dst = av_strdup(ff_id3v1_genre_str[genre]);
} else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
@@ -307,16 +306,17 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
av_freep(&dst);
if (dst)
- av_dict_set(&s->metadata, key, dst, dict_flags);
+ av_dict_set(metadata, key, dst, dict_flags);
}
/**
* Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
*/
-static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
+ char *tag, ID3v2ExtraMeta **extra_meta)
{
ID3v2ExtraMetaGEOB *geob_data = NULL;
- ID3v2ExtraMeta *new_extra = NULL;
+ ID3v2ExtraMeta *new_extra = NULL;
char encoding;
unsigned int len;
@@ -325,13 +325,15 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
if (!geob_data) {
- av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB));
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
+ sizeof(ID3v2ExtraMetaGEOB));
return;
}
new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
if (!new_extra) {
- av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta));
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
+ sizeof(ID3v2ExtraMeta));
goto fail;
}
@@ -340,18 +342,19 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
taglen--;
/* read MIME type (always ISO-8859) */
- if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0
- || taglen <= 0)
+ if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
+ &taglen) < 0 ||
+ taglen <= 0)
goto fail;
/* read file name */
- if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0
- || taglen <= 0)
+ if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
+ taglen <= 0)
goto fail;
/* read content description */
- if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0
- || taglen < 0)
+ if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
+ taglen < 0)
goto fail;
if (taglen) {
@@ -362,18 +365,19 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
goto fail;
}
if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
- av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n");
+ av_log(s, AV_LOG_WARNING,
+ "Error reading GEOB frame, data truncated.\n");
geob_data->datasize = len;
} else {
- geob_data->data = NULL;
+ geob_data->data = NULL;
geob_data->datasize = 0;
}
/* add data to the list */
- new_extra->tag = "GEOB";
+ new_extra->tag = "GEOB";
new_extra->data = geob_data;
new_extra->next = *extra_meta;
- *extra_meta = new_extra;
+ *extra_meta = new_extra;
return;
@@ -386,11 +390,12 @@ fail:
static int is_number(const char *str)
{
- while (*str >= '0' && *str <= '9') str++;
+ while (*str >= '0' && *str <= '9')
+ str++;
return !*str;
}
-static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
+static AVDictionaryEntry *get_date_tag(AVDictionary *m, const char *tag)
{
AVDictionaryEntry *t;
if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
@@ -402,28 +407,29 @@ static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
static void merge_date(AVDictionary **m)
{
AVDictionaryEntry *t;
- char date[17] = {0}; // YYYY-MM-DD hh:mm
+ char date[17] = { 0 }; // YYYY-MM-DD hh:mm
if (!(t = get_date_tag(*m, "TYER")) &&
!(t = get_date_tag(*m, "TYE")))
return;
av_strlcpy(date, t->value, 5);
av_dict_set(m, "TYER", NULL, 0);
- av_dict_set(m, "TYE", NULL, 0);
+ av_dict_set(m, "TYE", NULL, 0);
if (!(t = get_date_tag(*m, "TDAT")) &&
!(t = get_date_tag(*m, "TDA")))
goto finish;
snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
av_dict_set(m, "TDAT", NULL, 0);
- av_dict_set(m, "TDA", NULL, 0);
+ av_dict_set(m, "TDA", NULL, 0);
if (!(t = get_date_tag(*m, "TIME")) &&
!(t = get_date_tag(*m, "TIM")))
goto finish;
- snprintf(date + 10, sizeof(date) - 10, " %.2s:%.2s", t->value, t->value + 2);
+ snprintf(date + 10, sizeof(date) - 10,
+ " %.2s:%.2s", t->value, t->value + 2);
av_dict_set(m, "TIME", NULL, 0);
- av_dict_set(m, "TIM", NULL, 0);
+ av_dict_set(m, "TIM", NULL, 0);
finish:
if (date[0])
@@ -438,15 +444,16 @@ static void free_apic(void *obj)
av_freep(&apic);
}
-static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
+ char *tag, ID3v2ExtraMeta **extra_meta)
{
int enc, pic_type;
- char mimetype[64];
- const CodecMime *mime = ff_id3v2_mime_tags;
- enum AVCodecID id = AV_CODEC_ID_NONE;
- ID3v2ExtraMetaAPIC *apic = NULL;
+ char mimetype[64];
+ const CodecMime *mime = ff_id3v2_mime_tags;
+ enum AVCodecID id = AV_CODEC_ID_NONE;
+ ID3v2ExtraMetaAPIC *apic = NULL;
ID3v2ExtraMeta *new_extra = NULL;
- int64_t end = avio_tell(pb) + taglen;
+ int64_t end = avio_tell(pb) + taglen;
if (taglen <= 4)
goto fail;
@@ -469,7 +476,8 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
mime++;
}
if (id == AV_CODEC_ID_NONE) {
- av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
+ av_log(s, AV_LOG_WARNING,
+ "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
goto fail;
}
apic->id = id;
@@ -478,14 +486,16 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
pic_type = avio_r8(pb);
taglen--;
if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
- av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n", pic_type);
+ av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
+ pic_type);
pic_type = 0;
}
apic->type = ff_id3v2_picture_types[pic_type];
/* description and picture data */
if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
- av_log(s, AV_LOG_ERROR, "Error decoding attached picture description.\n");
+ av_log(s, AV_LOG_ERROR,
+ "Error decoding attached picture description.\n");
goto fail;
}
@@ -494,10 +504,10 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
goto fail;
memset(apic->buf->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
- new_extra->tag = "APIC";
- new_extra->data = apic;
- new_extra->next = *extra_meta;
- *extra_meta = new_extra;
+ new_extra->tag = "APIC";
+ new_extra->data = apic;
+ new_extra->next = *extra_meta;
+ *extra_meta = new_extra;
return;
@@ -508,47 +518,65 @@ fail:
avio_seek(pb, end, SEEK_SET);
}
-static void read_chapter(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *ttag, ID3v2ExtraMeta **extra_meta)
{
AVRational time_base = {1, 1000};
- char title[1024];
uint32_t start, end;
+ AVChapter *chapter;
+ uint8_t *dst = NULL;
+ int taglen;
+ char tag[5];
- taglen -= avio_get_str(pb, taglen, title, sizeof(title));
- if (taglen < 16)
+ if (decode_str(s, pb, 0, &dst, &len) < 0)
+ return;
+ if (len < 16)
return;
start = avio_rb32(pb);
end = avio_rb32(pb);
- taglen -= 27;
- if (taglen > 0) {
- char tag[4];
+ avio_skip(pb, 8);
+
+ chapter = avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst);
+ if (!chapter) {
+ av_free(dst);
+ return;
+ }
- avio_skip(pb, 8);
+ len -= 16;
+ while (len > 10) {
avio_read(pb, tag, 4);
- if (!memcmp(tag, "TIT2", 4)) {
- taglen = FFMIN(taglen, avio_rb32(pb));
- if (taglen < 0)
- return;
- avio_skip(pb, 3);
- avio_get_str(pb, taglen, title, sizeof(title));
+ tag[4] = 0;
+ taglen = avio_rb32(pb);
+ avio_skip(pb, 2);
+ len -= 10;
+ if (taglen < 0 || taglen > len) {
+ av_free(dst);
+ return;
}
+ if (tag[0] == 'T')
+ read_ttag(s, pb, taglen, &chapter->metadata, tag);
+ else
+ avio_skip(pb, taglen);
+ len -= taglen;
}
- avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, title);
+ ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv);
+ ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv);
+ av_free(dst);
}
typedef struct ID3v2EMFunc {
const char *tag3;
const char *tag4;
- void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **);
+ void (*read)(AVFormatContext *, AVIOContext *, int, char *,
+ ID3v2ExtraMeta **);
void (*free)(void *obj);
} ID3v2EMFunc;
static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
{ "GEO", "GEOB", read_geobtag, free_geobtag },
- { "PIC", "APIC", read_apic, free_apic },
- { "CHAP","CHAP", read_chapter, NULL },
+ { "PIC", "APIC", read_apic, free_apic },
+ { "CHAP","CHAP", read_chapter, NULL },
{ NULL }
};
@@ -571,7 +599,8 @@ static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
return NULL;
}
-static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
+static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
+ uint8_t flags, ID3v2ExtraMeta **extra_meta)
{
int isv34, unsync;
unsigned tlen;
@@ -582,7 +611,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
AVIOContext pb;
AVIOContext *pbx;
unsigned char *buffer = NULL;
- int buffer_size = 0;
+ int buffer_size = 0;
const ID3v2EMFunc *extra_func = NULL;
unsigned char *uncompressed_buffer = NULL;
int uncompressed_buffer_size = 0;
@@ -595,13 +624,13 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
reason = "compression";
goto error;
}
- isv34 = 0;
+ isv34 = 0;
taghdrlen = 6;
break;
case 3:
case 4:
- isv34 = 1;
+ isv34 = 1;
taghdrlen = 10;
break;
@@ -615,7 +644,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
int extlen = get_size(s->pb, 4);
if (version == 4)
- extlen -= 4; // in v2.4 the length includes the length field we just read
+ /* In v2.4 the length includes the length field we just read. */
+ extlen -= 4;
if (extlen < 0) {
reason = "invalid extended header length";
@@ -631,24 +661,24 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
while (len >= taghdrlen) {
unsigned int tflags = 0;
- int tunsync = 0;
- int tcomp = 0;
- int tencr = 0;
+ int tunsync = 0;
+ int tcomp = 0;
+ int tencr = 0;
unsigned long dlen;
if (isv34) {
avio_read(s->pb, tag, 4);
tag[4] = 0;
- if(version==3){
+ if (version == 3) {
tlen = avio_rb32(s->pb);
- }else
+ } else
tlen = get_size(s->pb, 4);
- tflags = avio_rb16(s->pb);
+ tflags = avio_rb16(s->pb);
tunsync = tflags & ID3v2_FLAG_UNSYNCH;
} else {
avio_read(s->pb, tag, 3);
tag[3] = 0;
- tlen = avio_rb24(s->pb);
+ tlen = avio_rb24(s->pb);
}
if (tlen > (1<<28))
break;
@@ -661,7 +691,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
if (!tlen) {
if (tag[0])
- av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag);
+ av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
+ tag);
continue;
}
@@ -689,7 +720,9 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
avio_skip(s->pb, tlen);
/* check for text tag or supported special meta tag */
- } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
+ } else if (tag[0] == 'T' ||
+ (extra_meta &&
+ (extra_func = get_extra_meta_func(tag, isv34)))) {
pbx = s->pb;
if (unsync || tunsync || tcomp) {
@@ -704,16 +737,19 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
uint8_t *b;
b = buffer;
- while (avio_tell(s->pb) < end && b - buffer < tlen) {
+ while (avio_tell(s->pb) < end && b - buffer < tlen && !s->pb->eof_reached) {
*b++ = avio_r8(s->pb);
- if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && b - buffer < tlen) {
+ if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 &&
+ b - buffer < tlen &&
+ !s->pb->eof_reached ) {
uint8_t val = avio_r8(s->pb);
*b++ = val ? val : avio_r8(s->pb);
}
}
- ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL);
+ ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL,
+ NULL);
tlen = b - buffer;
- pbx = &pb; // read from sync buffer
+ pbx = &pb; // read from sync buffer
}
#if CONFIG_ZLIB
@@ -749,12 +785,11 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
#endif
if (tag[0] == 'T')
/* parse text tag */
- read_ttag(s, pbx, tlen, tag);
+ read_ttag(s, pbx, tlen, &s->metadata, tag);
else
/* parse special meta tag */
extra_func->read(s, pbx, tlen, tag, extra_meta);
- }
- else if (!tag[0]) {
+ } else if (!tag[0]) {
if (tag[1])
av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
avio_skip(s->pb, tlen);
@@ -765,23 +800,26 @@ seek:
avio_seek(s->pb, next, SEEK_SET);
}
- if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */
+ /* Footer preset, always 10 bytes, skip over it */
+ if (version == 4 && flags & 0x10)
end += 10;
- error:
+error:
if (reason)
- av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason);
+ av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
+ version, reason);
avio_seek(s->pb, end, SEEK_SET);
av_free(buffer);
av_free(uncompressed_buffer);
return;
}
-void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta)
+void ff_id3v2_read(AVFormatContext *s, const char *magic,
+ ID3v2ExtraMeta **extra_meta)
{
int len, ret;
uint8_t buf[ID3v2_HEADER_SIZE];
- int found_header;
+ int found_header;
int64_t off;
do {
@@ -799,7 +837,7 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra
((buf[7] & 0x7f) << 14) |
((buf[8] & 0x7f) << 7) |
(buf[9] & 0x7f);
- ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta);
+ id3v2_parse(s, len, buf[3], buf[5], extra_meta);
} else {
avio_seek(s->pb, off, SEEK_SET);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/id3v2enc.c b/chromium/third_party/ffmpeg/libavformat/id3v2enc.c
index a10d6799462..60522444fc6 100644
--- a/chromium/third_party/ffmpeg/libavformat/id3v2enc.c
+++ b/chromium/third_party/ffmpeg/libavformat/id3v2enc.c
@@ -26,8 +26,11 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "avio.h"
+#include "avio_internal.h"
#include "id3v2.h"
+#define PADDING_BYTES 10
+
static void id3v2_put_size(AVIOContext *pb, int size)
{
avio_w8(pb, size >> 21 & 0x7f);
@@ -162,33 +165,31 @@ void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
avio_wb32(pb, 0);
}
-int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+static int write_metadata(AVIOContext *pb, AVDictionary **metadata,
+ ID3v2EncContext *id3, int enc)
{
AVDictionaryEntry *t = NULL;
- int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
- ID3v2_ENCODING_UTF8;
+ int ret;
- ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
+ ff_metadata_conv(metadata, ff_id3v2_34_metadata_conv, NULL);
if (id3->version == 3)
- id3v2_3_metadata_split_date(&s->metadata);
+ id3v2_3_metadata_split_date(metadata);
else if (id3->version == 4)
- ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
-
- while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
- int ret;
+ ff_metadata_conv(metadata, ff_id3v2_4_metadata_conv, NULL);
- if ((ret = id3v2_check_write_tag(id3, s->pb, t, ff_id3v2_tags, enc)) > 0) {
+ while ((t = av_dict_get(*metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ if ((ret = id3v2_check_write_tag(id3, pb, t, ff_id3v2_tags, enc)) > 0) {
id3->len += ret;
continue;
}
- if ((ret = id3v2_check_write_tag(id3, s->pb, t, id3->version == 3 ?
- ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
+ if ((ret = id3v2_check_write_tag(id3, pb, t, id3->version == 3 ?
+ ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
id3->len += ret;
continue;
}
/* unknown tag, write as TXXX frame */
- if ((ret = id3v2_put_ttag(id3, s->pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
+ if ((ret = id3v2_put_ttag(id3, pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
return ret;
id3->len += ret;
}
@@ -196,6 +197,64 @@ int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
return 0;
}
+static int write_chapter(AVFormatContext *s, ID3v2EncContext *id3, int id, int enc)
+{
+ const AVRational time_base = {1, 1000};
+ AVChapter *ch = s->chapters[id];
+ uint8_t *dyn_buf = NULL;
+ AVIOContext *dyn_bc = NULL;
+ char name[123];
+ int len, start, end, ret;
+
+ if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
+ goto fail;
+
+ start = av_rescale_q(ch->start, ch->time_base, time_base);
+ end = av_rescale_q(ch->end, ch->time_base, time_base);
+
+ snprintf(name, 122, "ch%d", id);
+ id3->len += avio_put_str(dyn_bc, name);
+ avio_wb32(dyn_bc, start);
+ avio_wb32(dyn_bc, end);
+ avio_wb32(dyn_bc, 0xFFFFFFFFu);
+ avio_wb32(dyn_bc, 0xFFFFFFFFu);
+
+ if ((ret = write_metadata(dyn_bc, &ch->metadata, id3, enc)) < 0)
+ goto fail;
+
+ len = avio_close_dyn_buf(dyn_bc, &dyn_buf);
+ id3->len += 16 + ID3v2_HEADER_SIZE;
+
+ avio_wb32(s->pb, MKBETAG('C', 'H', 'A', 'P'));
+ avio_wb32(s->pb, len);
+ avio_wb16(s->pb, 0);
+ avio_write(s->pb, dyn_buf, len);
+
+fail:
+ if (dyn_bc && !dyn_buf)
+ avio_close_dyn_buf(dyn_bc, &dyn_buf);
+ av_freep(&dyn_buf);
+
+ return ret;
+}
+
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+{
+ int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
+ ID3v2_ENCODING_UTF8;
+ int i, ret;
+
+ if ((ret = write_metadata(s->pb, &s->metadata, id3, enc)) < 0)
+ return ret;
+
+ for (i = 0; i < s->nb_chapters; i++) {
+ if ((ret = write_chapter(s, id3, i, enc)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt)
{
AVStream *st = s->streams[pkt->stream_index];
@@ -236,6 +295,10 @@ int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt)
if ((e = av_dict_get(st->metadata, "title", NULL, 0)))
desc = e->value;
+ /* use UTF16 only for non-ASCII strings */
+ if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(desc))
+ enc = ID3v2_ENCODING_ISO8859;
+
/* start writing */
if (avio_open_dyn_buf(&dyn_buf) < 0)
return AVERROR(ENOMEM);
@@ -263,7 +326,15 @@ int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt)
void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb)
{
- int64_t cur_pos = avio_tell(pb);
+ int64_t cur_pos;
+
+ /* adding an arbitrary amount of padding bytes at the end of the
+ * ID3 metadata fixes cover art display for some software (iTunes,
+ * Traktor, Serato, Torq) */
+ ffio_fill(pb, 0, PADDING_BYTES);
+ id3->len += PADDING_BYTES;
+
+ cur_pos = avio_tell(pb);
avio_seek(pb, id3->size_pos, SEEK_SET);
id3v2_put_size(pb, id3->len);
avio_seek(pb, cur_pos, SEEK_SET);
diff --git a/chromium/third_party/ffmpeg/libavformat/idcin.c b/chromium/third_party/ffmpeg/libavformat/idcin.c
index 2a8af406763..85d538c4f37 100644
--- a/chromium/third_party/ffmpeg/libavformat/idcin.c
+++ b/chromium/third_party/ffmpeg/libavformat/idcin.c
@@ -93,7 +93,7 @@ typedef struct IdcinDemuxContext {
static int idcin_probe(AVProbeData *p)
{
- unsigned int number;
+ unsigned int number, sample_rate;
/*
* This is what you could call a "probabilistic" file check: id CIN
@@ -122,22 +122,22 @@ static int idcin_probe(AVProbeData *p)
return 0;
/* check the audio sample rate */
- number = AV_RL32(&p->buf[8]);
- if ((number != 0) && ((number < 8000) | (number > 48000)))
+ sample_rate = AV_RL32(&p->buf[8]);
+ if (sample_rate && (sample_rate < 8000 || sample_rate > 48000))
return 0;
/* check the audio bytes/sample */
number = AV_RL32(&p->buf[12]);
- if (number > 2)
+ if (number > 2 || sample_rate && !number)
return 0;
/* check the audio channels */
number = AV_RL32(&p->buf[16]);
- if (number > 2)
+ if (number > 2 || sample_rate && !number)
return 0;
- /* return half certainly since this check is a bit sketchy */
- return AVPROBE_SCORE_MAX / 2;
+ /* return half certainty since this check is a bit sketchy */
+ return AVPROBE_SCORE_EXTENSION;
}
static int idcin_read_header(AVFormatContext *s)
@@ -196,8 +196,10 @@ static int idcin_read_header(AVFormatContext *s)
st->codec->height = height;
/* load up the Huffman tables into extradata */
- st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE);
if (ret < 0) {
return ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/iff.c b/chromium/third_party/ffmpeg/libavformat/iff.c
index 1efc1472cc2..edf308b1355 100644
--- a/chromium/third_party/ffmpeg/libavformat/iff.c
+++ b/chromium/third_party/ffmpeg/libavformat/iff.c
@@ -481,5 +481,5 @@ AVInputFormat ff_iff_demuxer = {
.read_probe = iff_probe,
.read_header = iff_read_header,
.read_packet = iff_read_packet,
- .flags = AVFMT_GENERIC_INDEX,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_NO_BYTE_SEEK,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/img2dec.c b/chromium/third_party/ffmpeg/libavformat/img2dec.c
index 12cf46265bf..5163e69f65b 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2dec.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <sys/stat.h>
#include "libavutil/avstring.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
@@ -63,6 +64,7 @@ typedef struct {
int start_number;
int start_number_range;
int frame_size;
+ int ts_from_file;
} VideoDemuxData;
static const int sizes[][2] = {
@@ -185,7 +187,7 @@ static int img_read_probe(AVProbeData *p)
else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif"))
return 5;
else
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
}
return 0;
}
@@ -223,7 +225,10 @@ static int img_read_header(AVFormatContext *s1)
st->need_parsing = AVSTREAM_PARSE_FULL;
}
- avpriv_set_pts_info(st, 60, s->framerate.den, s->framerate.num);
+ if (s->ts_from_file)
+ avpriv_set_pts_info(st, 64, 1, 1);
+ else
+ avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num);
if (s->width && s->height) {
st->codec->width = s->width;
@@ -267,7 +272,7 @@ static int img_read_header(AVFormatContext *s1)
if (find_image_range(&first_index, &last_index, s->path,
s->start_number, s->start_number_range) < 0) {
av_log(s1, AV_LOG_ERROR,
- "Could find no file with with path '%s' and index in the range %d-%d\n",
+ "Could find no file with path '%s' and index in the range %d-%d\n",
s->path, s->start_number, s->start_number + s->start_number_range - 1);
return AVERROR(ENOENT);
}
@@ -296,8 +301,10 @@ static int img_read_header(AVFormatContext *s1)
s->img_last = last_index;
s->img_number = first_index;
/* compute duration */
- st->start_time = 0;
- st->duration = last_index - first_index + 1;
+ if (!s->ts_from_file) {
+ st->start_time = 0;
+ st->duration = last_index - first_index + 1;
+ }
}
if (s1->video_codec_id) {
@@ -381,8 +388,15 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
return AVERROR(ENOMEM);
pkt->stream_index = 0;
pkt->flags |= AV_PKT_FLAG_KEY;
- if (!s->is_pipe)
+ if (s->ts_from_file) {
+ struct stat img_stat;
+ if (stat(filename, &img_stat))
+ return AVERROR(EIO);
+ pkt->pts = (int64_t)img_stat.st_mtime;
+ av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+ } else if (!s->is_pipe) {
pkt->pts = s->pts;
+ }
pkt->size = 0;
for (i = 0; i < 3; i++) {
@@ -420,6 +434,15 @@ static int img_read_close(struct AVFormatContext* s1)
static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
VideoDemuxData *s1 = s->priv_data;
+ AVStream *st = s->streams[0];
+
+ if (s1->ts_from_file) {
+ int index = av_index_search_timestamp(st, timestamp, flags);
+ if(index < 0)
+ return -1;
+ s1->img_number = st->index_entries[index].pos;
+ return 0;
+ }
if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first)
return -1;
@@ -444,6 +467,7 @@ static const AVOption options[] = {
{ "start_number_range", "set range for looking at the first sequence number", OFFSET(start_number_range), AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX, DEC },
{ "video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },
{ "frame_size", "force frame size in bytes", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC },
+ { "ts_from_file", "set frame timestamp from file's one", OFFSET(ts_from_file), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, DEC },
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/img2enc.c b/chromium/third_party/ffmpeg/libavformat/img2enc.c
index fb297da20bf..11223fba821 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2enc.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2enc.c
@@ -37,6 +37,7 @@ typedef struct {
int split_planes; /**< use independent file for each Y, U, V plane */
char path[1024];
int update;
+ int use_strftime;
} VideoMuxData;
static int write_header(AVFormatContext *s)
@@ -60,7 +61,7 @@ static int write_header(AVFormatContext *s)
&& s->nb_streams == 1
&& st->codec->codec_id == AV_CODEC_ID_RAWVIDEO
&& desc
- &&(desc->flags & PIX_FMT_PLANAR)
+ &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR)
&& desc->nb_components >= 3;
return 0;
}
@@ -77,6 +78,15 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
if (!img->is_pipe) {
if (img->update) {
av_strlcpy(filename, img->path, sizeof(filename));
+ } else if (img->use_strftime) {
+ time_t now0;
+ struct tm *tm;
+ time(&now0);
+ tm = localtime(&now0);
+ if (!strftime(filename, sizeof(filename), img->path, tm)) {
+ av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n");
+ return AVERROR(EINVAL);
+ }
} else if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 &&
img->img_number > 1) {
av_log(s, AV_LOG_ERROR,
@@ -101,7 +111,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
if (img->split_planes) {
int ysize = codec->width * codec->height;
- int usize = ((-codec->width)>>desc->log2_chroma_w) * ((-codec->height)>>desc->log2_chroma_h);
+ int usize = FF_CEIL_RSHIFT(codec->width, desc->log2_chroma_w) * FF_CEIL_RSHIFT(codec->height, desc->log2_chroma_h);
if (desc->comp[0].depth_minus1 >= 8) {
ysize *= 2;
usize *= 2;
@@ -132,7 +142,8 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
static const AVOption muxoptions[] = {
{ "updatefirst", "continuously overwrite one file", OFFSET(update), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
{ "update", "continuously overwrite one file", OFFSET(update), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
- { "start_number", "set first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, ENC },
+ { "start_number", "set first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, ENC },
+ { "strftime", "use strftime for filename", OFFSET(use_strftime), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
{ NULL },
};
@@ -148,7 +159,7 @@ AVOutputFormat ff_image2_muxer = {
.name = "image2",
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
.extensions = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
- "ppm,sgi,tga,tif,tiff,jp2,j2c,xwd,sun,ras,rs,im1,im8,im24,"
+ "ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,"
"sunras,xbm,xface",
.priv_data_size = sizeof(VideoMuxData),
.video_codec = AV_CODEC_ID_MJPEG,
diff --git a/chromium/third_party/ffmpeg/libavformat/internal.h b/chromium/third_party/ffmpeg/libavformat/internal.h
index 4d563883128..1f74069bcc0 100644
--- a/chromium/third_party/ffmpeg/libavformat/internal.h
+++ b/chromium/third_party/ffmpeg/libavformat/internal.h
@@ -90,31 +90,6 @@ void ff_read_frame_flush(AVFormatContext *s);
uint64_t ff_ntp_time(void);
/**
- * Assemble a URL string from components. This is the reverse operation
- * of av_url_split.
- *
- * Note, this requires networking to be initialized, so the caller must
- * ensure ff_network_init has been called.
- *
- * @see av_url_split
- *
- * @param str the buffer to fill with the url
- * @param size the size of the str buffer
- * @param proto the protocol identifier, if null, the separator
- * after the identifier is left out, too
- * @param authorization an optional authorization string, may be null.
- * An empty string is treated the same as a null string.
- * @param hostname the host name string
- * @param port the port number, left out from the string if negative
- * @param fmt a generic format string for everything to add after the
- * host/port, may be null
- * @return the number of characters written to the destination buffer
- */
-int ff_url_join(char *str, int size, const char *proto,
- const char *authorization, const char *hostname,
- int port, const char *fmt, ...) av_printf_format(7, 8);
-
-/**
* Append the media-specific SDP fragment for the media stream c
* to the buffer buff.
*
@@ -240,17 +215,6 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
*/
void ff_reduce_index(AVFormatContext *s, int stream_index);
-/**
- * Convert a relative url into an absolute url, given a base url.
- *
- * @param buf the buffer where output absolute url is written
- * @param size the size of buf
- * @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);
-
enum AVCodecID ff_guess_image2_codec(const char *filename);
/**
@@ -278,6 +242,9 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index,
*/
void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
+
/**
* Perform a binary search using read_timestamp().
*
@@ -390,6 +357,4 @@ AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precissi
*/
void ff_generate_avci_extradata(AVStream *st);
-int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
-
#endif /* AVFORMAT_INTERNAL_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/isom.c b/chromium/third_party/ffmpeg/libavformat/isom.c
index 4078c0d12c5..ec372288cad 100644
--- a/chromium/third_party/ffmpeg/libavformat/isom.c
+++ b/chromium/third_party/ffmpeg/libavformat/isom.c
@@ -21,8 +21,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define DEBUG
-
#include "avformat.h"
#include "internal.h"
#include "isom.h"
@@ -188,6 +186,7 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') }, /* MPEG2 IMX PAL 625/50 40mb/s produced by FCP */
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX NTSC 525/60 30mb/s produced by FCP */
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG2 IMX PAL 625/50 30mb/s produced by FCP */
+ { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '1') }, /* XDCAM HD422 720p30 CBR */
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') }, /* XDCAM HD422 720p24 CBR */
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '5') }, /* XDCAM HD422 720p25 CBR */
{ AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') }, /* XDCAM HD422 720p60 CBR */
@@ -244,6 +243,8 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */
{ AV_CODEC_ID_FLIC, MKTAG('f', 'l', 'i', 'c') },
+ { AV_CODEC_ID_AIC, MKTAG('i', 'c', 'o', 'd') },
+
{ AV_CODEC_ID_NONE, 0 },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/isom.h b/chromium/third_party/ffmpeg/libavformat/isom.h
index 4154baf8278..b0fa453de65 100644
--- a/chromium/third_party/ffmpeg/libavformat/isom.h
+++ b/chromium/third_party/ffmpeg/libavformat/isom.h
@@ -110,7 +110,7 @@ typedef struct MOVStreamContext {
int ctts_index;
int ctts_sample;
unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom
- unsigned int alt_sample_size; ///< always contains sample size from stsz atom
+ unsigned int stsz_sample_size; ///< always contains sample size from stsz atom
unsigned int sample_count;
int *sample_sizes;
int keyframe_absent;
@@ -162,6 +162,8 @@ typedef struct MOVContext {
int use_absolute_path;
int ignore_editlist;
int64_t next_root_atom; ///< offset of the next root atom
+ int *bitrates; ///< bitrates read before streams creation
+ int bitrates_count;
} MOVContext;
int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/chromium/third_party/ffmpeg/libavformat/jacosubdec.c b/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
index 89e7e1bf546..da1afadf1b2 100644
--- a/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/jacosubdec.c
@@ -60,7 +60,7 @@ static int jacosub_probe(AVProbeData *p)
ptr++;
if (*ptr != '#' && *ptr != '\n') {
if (timed_line(ptr))
- return AVPROBE_SCORE_MAX/2 + 1;
+ return AVPROBE_SCORE_EXTENSION + 1;
return 0;
}
ptr += strcspn(ptr, "\n") + 1;
diff --git a/chromium/third_party/ffmpeg/libavformat/jvdec.c b/chromium/third_party/ffmpeg/libavformat/jvdec.c
index e9414927621..69ac8f27fd3 100644
--- a/chromium/third_party/ffmpeg/libavformat/jvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/jvdec.c
@@ -33,10 +33,10 @@
#define JV_PREAMBLE_SIZE 5
typedef struct {
- int audio_size; /** audio packet size (bytes) */
- int video_size; /** video packet size (bytes) */
- int palette_size; /** palette size (bytes) */
- int video_type; /** per-frame video compression type */
+ int audio_size; /**< audio packet size (bytes) */
+ int video_size; /**< video packet size (bytes) */
+ int palette_size; /**< palette size (bytes) */
+ int video_type; /**< per-frame video compression type */
} JVFrame;
typedef struct {
diff --git a/chromium/third_party/ffmpeg/libavformat/latmenc.c b/chromium/third_party/ffmpeg/libavformat/latmenc.c
index 9dfb4e4fab2..b3430d785d3 100644
--- a/chromium/third_party/ffmpeg/libavformat/latmenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/latmenc.c
@@ -124,7 +124,7 @@ static void latm_write_frame_header(AVFormatContext *s, PutBitContext *bs)
if (!ctx->channel_conf) {
GetBitContext gb;
- init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
+ init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
skip_bits_long(&gb, ctx->off + 3);
avpriv_copy_pce_data(bs, &gb);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/libgme.c b/chromium/third_party/ffmpeg/libavformat/libgme.c
new file mode 100644
index 00000000000..1ae63dc454c
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/libgme.c
@@ -0,0 +1,201 @@
+/*
+ * 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
+ */
+
+/**
+* @file
+* libgme demuxer
+*/
+
+#include <gme/gme.h>
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct GMEContext {
+ const AVClass *class;
+ Music_Emu *music_emu;
+ gme_info_t *info; ///< selected track
+
+ /* options */
+ int track_index;
+ int sample_rate;
+ int64_t max_size;
+} GMEContext;
+
+#define OFFSET(x) offsetof(GMEContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define D AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ {"track_index", "set track that should be played", OFFSET(track_index), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, A|D},
+ {"sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 44100}, 1000, 999999, A|D},
+ {"max_size", "set max file size supported (in bytes)", OFFSET(max_size), AV_OPT_TYPE_INT64, {.i64 = 50 * 1024 * 1024}, 0, SIZE_MAX, A|D},
+ {NULL}
+};
+
+static void add_meta(AVFormatContext *s, const char *name, const char *value)
+{
+ if (value && value[0])
+ av_dict_set(&s->metadata, name, value, 0);
+}
+
+static int load_metadata(AVFormatContext *s)
+{
+ GMEContext *gme = s->priv_data;
+ gme_info_t *info = gme->info;
+ char buf[30];
+
+ add_meta(s, "system", info->system);
+ add_meta(s, "game", info->game);
+ add_meta(s, "song", info->song);
+ add_meta(s, "author", info->author);
+ add_meta(s, "copyright", info->copyright);
+ add_meta(s, "comment", info->comment);
+ add_meta(s, "dumper", info->dumper);
+
+ snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu));
+ add_meta(s, "tracks", buf);
+
+ return 0;
+}
+
+#define AUDIO_PKT_SIZE 512
+
+static int read_header_gme(AVFormatContext *s)
+{
+ AVStream *st;
+ AVIOContext *pb = s->pb;
+ GMEContext *gme = s->priv_data;
+ int64_t sz = avio_size(pb);
+ char *buf;
+ char dummy;
+
+ if (sz < 0) {
+ av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
+ sz = gme->max_size;
+ } else if (gme->max_size && sz > gme->max_size) {
+ sz = gme->max_size;
+ }
+
+ buf = av_malloc(sz);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ sz = avio_read(pb, buf, sz);
+
+ // Data left means our buffer (the max_size option) is too small
+ if (avio_read(pb, &dummy, 1) == 1) {
+ av_log(s, AV_LOG_ERROR, "File size is larger than max_size option "
+ "value %"PRIi64", consider increasing the max_size option\n",
+ gme->max_size);
+ return AVERROR_BUFFER_TOO_SMALL;
+ }
+
+ if (gme_open_data(buf, sz, &gme->music_emu, gme->sample_rate)) {
+ av_freep(&buf);
+ return AVERROR_INVALIDDATA;
+ }
+ av_freep(&buf);
+
+ if (gme_track_info(gme->music_emu, &gme->info, gme->track_index))
+ return AVERROR_STREAM_NOT_FOUND;
+
+ if (gme_start_track(gme->music_emu, gme->track_index))
+ return AVERROR_UNKNOWN;
+
+ load_metadata(s);
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ avpriv_set_pts_info(st, 64, 1, 1000);
+ if (st->duration > 0)
+ st->duration = gme->info->length;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE);
+ st->codec->channels = 2;
+ st->codec->sample_rate = gme->sample_rate;
+
+ return 0;
+}
+
+static int read_packet_gme(AVFormatContext *s, AVPacket *pkt)
+{
+ GMEContext *gme = s->priv_data;
+ int n_samples = AUDIO_PKT_SIZE / 2;
+ int ret;
+
+ if (gme_track_ended(gme->music_emu))
+ return AVERROR_EOF;
+
+ if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0)
+ return ret;
+
+ if (gme_play(gme->music_emu, n_samples, (short *)pkt->data))
+ return AVERROR_EXTERNAL;
+ pkt->size = AUDIO_PKT_SIZE;
+
+ return 0;
+}
+
+static int read_close_gme(AVFormatContext *s)
+{
+ GMEContext *gme = s->priv_data;
+ gme_free_info(gme->info);
+ gme_delete(gme->music_emu);
+ return 0;
+}
+
+static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
+{
+ GMEContext *gme = s->priv_data;
+ if (!gme_seek(gme->music_emu, (int)ts))
+ return AVERROR_EXTERNAL;
+ return 0;
+}
+
+static int probe_gme(AVProbeData *p)
+{
+ // Reads 4 bytes - returns "" if unknown format.
+ if (gme_identify_header(p->buf)[0]) {
+ if (p->buf_size < 16384)
+ return AVPROBE_SCORE_MAX / 4 + 1;
+ else
+ return AVPROBE_SCORE_MAX / 2;
+ }
+ return 0;
+}
+
+static const AVClass class_gme = {
+ .class_name = "Game Music Emu demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_libgme_demuxer = {
+ .name = "libgme",
+ .long_name = NULL_IF_CONFIG_SMALL("Game Music Emu demuxer"),
+ .priv_data_size = sizeof(GMEContext),
+ .read_probe = probe_gme,
+ .read_header = read_header_gme,
+ .read_packet = read_packet_gme,
+ .read_close = read_close_gme,
+ .read_seek = read_seek_gme,
+ .priv_class = &class_gme,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/libmodplug.c b/chromium/third_party/ffmpeg/libavformat/libmodplug.c
index aa8edccb598..836b7c2ec06 100644
--- a/chromium/third_party/ffmpeg/libavformat/libmodplug.c
+++ b/chromium/third_party/ffmpeg/libavformat/libmodplug.c
@@ -166,14 +166,14 @@ static int modplug_read_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
ModPlug_Settings settings;
ModPlugContext *modplug = s->priv_data;
- int sz = avio_size(pb);
+ int64_t sz = avio_size(pb);
if (sz < 0) {
av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
sz = modplug->max_size;
} else if (modplug->max_size && sz > modplug->max_size) {
sz = modplug->max_size;
- av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %dB "
+ av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %"PRIi64"B "
"but demuxing is likely to fail due to incomplete buffer\n",
sz == FF_MODPLUG_DEF_FILE_SIZE ? " (see -max_size)" : "", sz);
}
@@ -347,6 +347,19 @@ static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int
return 0;
}
+static const char modplug_extensions[] = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm,itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz";
+
+static int modplug_probe(AVProbeData *p)
+{
+ if (av_match_ext(p->filename, modplug_extensions)) {
+ if (p->buf_size < 16384)
+ return AVPROBE_SCORE_EXTENSION/2-1;
+ else
+ return AVPROBE_SCORE_EXTENSION;
+ }
+ return 0;
+}
+
static const AVClass modplug_class = {
.class_name = "ModPlug demuxer",
.item_name = av_default_item_name,
@@ -358,11 +371,11 @@ AVInputFormat ff_libmodplug_demuxer = {
.name = "libmodplug",
.long_name = NULL_IF_CONFIG_SMALL("ModPlug demuxer"),
.priv_data_size = sizeof(ModPlugContext),
+ .read_probe = modplug_probe,
.read_header = modplug_read_header,
.read_packet = modplug_read_packet,
.read_close = modplug_read_close,
.read_seek = modplug_read_seek,
- .extensions = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm"
- ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods
+ .extensions = modplug_extensions,
.priv_class = &modplug_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/libquvi.c b/chromium/third_party/ffmpeg/libavformat/libquvi.c
index fbae74c6c41..ca71f9fd8c1 100644
--- a/chromium/third_party/ffmpeg/libavformat/libquvi.c
+++ b/chromium/third_party/ffmpeg/libavformat/libquvi.c
@@ -127,7 +127,7 @@ static int libquvi_probe(AVProbeData *p)
rc = quvi_init(&q);
if (rc != QUVI_OK)
return AVERROR(ENOMEM);
- score = quvi_supported(q, (char *)p->filename) == QUVI_OK ? AVPROBE_SCORE_MAX/2 : 0;
+ score = quvi_supported(q, (char *)p->filename) == QUVI_OK ? AVPROBE_SCORE_EXTENSION : 0;
quvi_close(&q);
return score;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/loasdec.c b/chromium/third_party/ffmpeg/libavformat/loasdec.c
index d3a8dbd6cdd..05ef0fe3ad5 100644
--- a/chromium/third_party/ffmpeg/libavformat/loasdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/loasdec.c
@@ -52,9 +52,9 @@ static int loas_probe(AVProbeData *p)
if(buf == buf0)
first_frames= frames;
}
- if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
- else if(max_frames>100)return AVPROBE_SCORE_MAX/2;
- else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+ if (first_frames>=3) return AVPROBE_SCORE_EXTENSION+1;
+ else if(max_frames>100)return AVPROBE_SCORE_EXTENSION;
+ else if(max_frames>=3) return AVPROBE_SCORE_EXTENSION / 2;
else return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/lvfdec.c b/chromium/third_party/ffmpeg/libavformat/lvfdec.c
index f8dda585711..a809c6767bd 100644
--- a/chromium/third_party/ffmpeg/libavformat/lvfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/lvfdec.c
@@ -26,7 +26,7 @@
static int lvf_probe(AVProbeData *p)
{
if (AV_RL32(p->buf) == MKTAG('L', 'V', 'F', 'F'))
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/lxfdec.c b/chromium/third_party/ffmpeg/libavformat/lxfdec.c
index 876f988ef55..5c61d4fcb07 100644
--- a/chromium/third_party/ffmpeg/libavformat/lxfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/lxfdec.c
@@ -29,7 +29,6 @@
#define LXF_IDENT "LEITCH\0"
#define LXF_IDENT_LENGTH 8
#define LXF_SAMPLERATE 48000
-#define LXF_MAX_AUDIO_PACKET (8008*15*4) ///< 15-channel 32-bit NTSC audio frame
static const AVCodecTag lxf_tags[] = {
{ AV_CODEC_ID_MJPEG, 0 },
@@ -309,13 +308,6 @@ static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR_INVALIDDATA;
}
- //make sure the data fits in the de-planerization buffer
- if (ast && ret > LXF_MAX_AUDIO_PACKET) {
- av_log(s, AV_LOG_ERROR, "audio packet too large (%i > %i)\n",
- ret, LXF_MAX_AUDIO_PACKET);
- return AVERROR_INVALIDDATA;
- }
-
if ((ret2 = av_new_packet(pkt, ret)) < 0)
return ret2;
diff --git a/chromium/third_party/ffmpeg/libavformat/m4vdec.c b/chromium/third_party/ffmpeg/libavformat/m4vdec.c
index e72fb42f1de..c2fd4d7ab6f 100644
--- a/chromium/third_party/ffmpeg/libavformat/m4vdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/m4vdec.c
@@ -45,7 +45,7 @@ static int mpeg4video_probe(AVProbeData *probe_packet)
}
if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0)
- return VOP+VO > 3 ? AVPROBE_SCORE_MAX/2 : AVPROBE_SCORE_MAX/4;
+ return VOP+VO > 3 ? AVPROBE_SCORE_EXTENSION : AVPROBE_SCORE_EXTENSION/2;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/matroska.c b/chromium/third_party/ffmpeg/libavformat/matroska.c
index ee57c1820a8..953c5721b6c 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroska.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroska.c
@@ -57,6 +57,11 @@ const CodecTags ff_mkv_codec_tags[]={
{"A_VORBIS" , AV_CODEC_ID_VORBIS},
{"A_WAVPACK4" , AV_CODEC_ID_WAVPACK},
+ {"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT},
+ {"D_WEBVTT/CAPTIONS" , AV_CODEC_ID_WEBVTT},
+ {"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT},
+ {"D_WEBVTT/METADATA" , AV_CODEC_ID_WEBVTT},
+
{"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP},
{"S_TEXT/UTF8" , AV_CODEC_ID_TEXT},
{"S_TEXT/UTF8" , AV_CODEC_ID_SRT},
diff --git a/chromium/third_party/ffmpeg/libavformat/matroska.h b/chromium/third_party/ffmpeg/libavformat/matroska.h
index 8a7e10b64dc..7cf423c5027 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroska.h
+++ b/chromium/third_party/ffmpeg/libavformat/matroska.h
@@ -91,6 +91,7 @@
#define MATROSKA_ID_CODECINFOURL 0x3B4040
#define MATROSKA_ID_CODECDOWNLOADURL 0x26B240
#define MATROSKA_ID_CODECDECODEALL 0xAA
+#define MATROSKA_ID_SEEKPREROLL 0x56BB
#define MATROSKA_ID_TRACKNAME 0x536E
#define MATROSKA_ID_TRACKLANGUAGE 0x22B59C
#define MATROSKA_ID_TRACKFLAGENABLED 0xB9
@@ -156,6 +157,7 @@
/* IDs in the cuetrackposition master */
#define MATROSKA_ID_CUETRACK 0xF7
#define MATROSKA_ID_CUECLUSTERPOSITION 0xF1
+#define MATROSKA_ID_CUERELATIVEPOSITION 0xF0
#define MATROSKA_ID_CUEBLOCKNUMBER 0x5378
/* IDs in the tags master */
@@ -195,6 +197,7 @@
#define MATROSKA_ID_BLOCK 0xA1
#define MATROSKA_ID_BLOCKDURATION 0x9B
#define MATROSKA_ID_BLOCKREFERENCE 0xFB
+#define MATROSKA_ID_CODECSTATE 0xA4
/* IDs in the attachments master */
#define MATROSKA_ID_ATTACHEDFILE 0x61A7
@@ -229,6 +232,7 @@ typedef enum {
MATROSKA_TRACK_TYPE_LOGO = 0x10,
MATROSKA_TRACK_TYPE_SUBTITLE = 0x11,
MATROSKA_TRACK_TYPE_CONTROL = 0x20,
+ MATROSKA_TRACK_TYPE_METADATA = 0x21,
} MatroskaTrackType;
typedef enum {
@@ -261,7 +265,7 @@ typedef enum {
*/
typedef struct CodecTags{
- char str[20];
+ char str[22];
enum AVCodecID id;
}CodecTags;
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskadec.c b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
index d17bf611ac6..a90475d47cf 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
@@ -570,6 +570,7 @@ static EbmlSyntax matroska_blockgroup[] = {
{ MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) },
{ MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration) },
{ MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
+ { MATROSKA_ID_CODECSTATE, EBML_NONE },
{ 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} },
{ 0 }
};
@@ -633,21 +634,20 @@ static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos)
matroska->current_id = 0;
matroska->num_levels = 0;
- // seek to next position to resync from
- if (avio_seek(pb, last_pos + 1, SEEK_SET) < 0 || avio_tell(pb) <= last_pos)
+ /* seek to next position to resync from */
+ if (avio_seek(pb, last_pos + 1, SEEK_SET) < 0)
goto eof;
id = avio_rb32(pb);
// try to find a toplevel element
while (!url_feof(pb)) {
- if (id == MATROSKA_ID_INFO || id == MATROSKA_ID_TRACKS ||
- id == MATROSKA_ID_CUES || id == MATROSKA_ID_TAGS ||
+ if (id == MATROSKA_ID_INFO || id == MATROSKA_ID_TRACKS ||
+ id == MATROSKA_ID_CUES || id == MATROSKA_ID_TAGS ||
id == MATROSKA_ID_SEEKHEAD || id == MATROSKA_ID_ATTACHMENTS ||
- id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS)
- {
- matroska->current_id = id;
- return 0;
+ id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS) {
+ matroska->current_id = id;
+ return 0;
}
id = (id << 8) | avio_r8(pb);
}
@@ -1066,7 +1066,7 @@ static int matroska_probe(AVProbeData *p)
}
// probably valid EBML header but no recognized doctype
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
}
static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
@@ -1572,7 +1572,8 @@ static int matroska_read_header(AVFormatContext *s)
/* Apply some sanity checks. */
if (track->type != MATROSKA_TRACK_TYPE_VIDEO &&
track->type != MATROSKA_TRACK_TYPE_AUDIO &&
- track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
+ track->type != MATROSKA_TRACK_TYPE_SUBTITLE &&
+ track->type != MATROSKA_TRACK_TYPE_METADATA) {
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown or unsupported track type %"PRIu64"\n",
track->type);
@@ -1689,18 +1690,6 @@ static int matroska_read_header(AVFormatContext *s)
&& (track->codec_priv.data != NULL)) {
fourcc = AV_RL32(track->codec_priv.data);
codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
- } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - FF_INPUT_BUFFER_PADDING_SIZE) {
- /* Only ALAC's magic cookie is stored in Matroska's track headers.
- Create the "atom size", "tag", and "tag version" fields the
- decoder expects manually. */
- extradata_size = 12 + track->codec_priv.size;
- extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (extradata == NULL)
- return AVERROR(ENOMEM);
- AV_WB32(extradata, extradata_size);
- memcpy(&extradata[4], "alac", 4);
- AV_WB32(&extradata[8], 0);
- memcpy(&extradata[12], track->codec_priv.data, track->codec_priv.size);
} else if (codec_id == AV_CODEC_ID_PCM_S16BE) {
switch (track->audio.bitdepth) {
case 8: codec_id = AV_CODEC_ID_PCM_U8; break;
@@ -1731,6 +1720,19 @@ static int matroska_read_header(AVFormatContext *s)
extradata_size = 5;
} else
extradata_size = 2;
+ } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - FF_INPUT_BUFFER_PADDING_SIZE) {
+ /* Only ALAC's magic cookie is stored in Matroska's track headers.
+ Create the "atom size", "tag", and "tag version" fields the
+ decoder expects manually. */
+ extradata_size = 12 + track->codec_priv.size;
+ extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (extradata == NULL)
+ return AVERROR(ENOMEM);
+ AV_WB32(extradata, extradata_size);
+ memcpy(&extradata[4], "alac", 4);
+ AV_WB32(&extradata[8], 0);
+ memcpy(&extradata[12], track->codec_priv.data,
+ track->codec_priv.size);
} else if (codec_id == AV_CODEC_ID_TTA) {
extradata_size = 30;
extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -1742,8 +1744,10 @@ static int matroska_read_header(AVFormatContext *s)
avio_wl16(&b, 1);
avio_wl16(&b, track->audio.channels);
avio_wl16(&b, track->audio.bitdepth);
+ if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX)
+ return AVERROR_INVALIDDATA;
avio_wl32(&b, track->audio.out_samplerate);
- avio_wl32(&b, matroska->ctx->duration * track->audio.out_samplerate);
+ avio_wl32(&b, av_rescale((matroska->duration * matroska->time_scale), track->audio.out_samplerate, AV_TIME_BASE * 1000));
} else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 ||
codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) {
extradata_offset = 26;
@@ -1771,7 +1775,7 @@ static int matroska_read_header(AVFormatContext *s)
track->codec_priv.size = 0;
} else {
if (codec_id == AV_CODEC_ID_SIPR && flavor < 4) {
- const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
+ static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
track->audio.sub_packet_size = ff_sipr_subpk_size[flavor];
st->codec->bit_rate = sipr_bit_rate[flavor];
}
@@ -1871,6 +1875,16 @@ static int matroska_read_header(AVFormatContext *s)
st->codec->bits_per_coded_sample = track->audio.bitdepth;
if (st->codec->codec_id != AV_CODEC_ID_AAC)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
+ } else if (codec_id == AV_CODEC_ID_WEBVTT) {
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+
+ if (!strcmp(track->codec_id, "D_WEBVTT/CAPTIONS")) {
+ st->disposition |= AV_DISPOSITION_CAPTIONS;
+ } else if (!strcmp(track->codec_id, "D_WEBVTT/DESCRIPTIONS")) {
+ st->disposition |= AV_DISPOSITION_DESCRIPTIONS;
+ } else if (!strcmp(track->codec_id, "D_WEBVTT/METADATA")) {
+ st->disposition |= AV_DISPOSITION_METADATA;
+ }
} else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
#if FF_API_ASS_SSA
@@ -2160,6 +2174,202 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
return 0;
}
+
+/* reconstruct full wavpack blocks from mangled matroska ones */
+static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src,
+ uint8_t **pdst, int *size)
+{
+ uint8_t *dst = NULL;
+ int dstlen = 0;
+ int srclen = *size;
+ uint32_t samples;
+ uint16_t ver;
+ int ret, offset = 0;
+
+ if (srclen < 12 || track->stream->codec->extradata_size < 2)
+ return AVERROR_INVALIDDATA;
+
+ ver = AV_RL16(track->stream->codec->extradata);
+
+ samples = AV_RL32(src);
+ src += 4;
+ srclen -= 4;
+
+ while (srclen >= 8) {
+ int multiblock;
+ uint32_t blocksize;
+ uint8_t *tmp;
+
+ uint32_t flags = AV_RL32(src);
+ uint32_t crc = AV_RL32(src + 4);
+ src += 8;
+ srclen -= 8;
+
+ multiblock = (flags & 0x1800) != 0x1800;
+ if (multiblock) {
+ if (srclen < 4) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ blocksize = AV_RL32(src);
+ src += 4;
+ srclen -= 4;
+ } else
+ blocksize = srclen;
+
+ if (blocksize > srclen) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ tmp = av_realloc(dst, dstlen + blocksize + 32);
+ if (!tmp) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ dst = tmp;
+ dstlen += blocksize + 32;
+
+ AV_WL32(dst + offset, MKTAG('w', 'v', 'p', 'k')); // tag
+ AV_WL32(dst + offset + 4, blocksize + 24); // blocksize - 8
+ AV_WL16(dst + offset + 8, ver); // version
+ AV_WL16(dst + offset + 10, 0); // track/index_no
+ AV_WL32(dst + offset + 12, 0); // total samples
+ AV_WL32(dst + offset + 16, 0); // block index
+ AV_WL32(dst + offset + 20, samples); // number of samples
+ AV_WL32(dst + offset + 24, flags); // flags
+ AV_WL32(dst + offset + 28, crc); // crc
+ memcpy (dst + offset + 32, src, blocksize); // block data
+
+ src += blocksize;
+ srclen -= blocksize;
+ offset += blocksize + 32;
+ }
+
+ *pdst = dst;
+ *size = dstlen;
+
+ return 0;
+
+fail:
+ av_freep(&dst);
+ return ret;
+}
+
+static int matroska_parse_webvtt(MatroskaDemuxContext *matroska,
+ MatroskaTrack *track,
+ AVStream *st,
+ uint8_t *data, int data_len,
+ uint64_t timecode,
+ uint64_t duration,
+ int64_t pos)
+{
+ AVPacket *pkt;
+ uint8_t *id, *settings, *text, *buf;
+ int id_len, settings_len, text_len;
+ uint8_t *p, *q;
+ int err;
+
+ if (data_len <= 0)
+ return AVERROR_INVALIDDATA;
+
+ p = data;
+ q = data + data_len;
+
+ id = p;
+ id_len = -1;
+ while (p < q) {
+ if (*p == '\r' || *p == '\n') {
+ id_len = p - id;
+ if (*p == '\r')
+ p++;
+ break;
+ }
+ p++;
+ }
+
+ if (p >= q || *p != '\n')
+ return AVERROR_INVALIDDATA;
+ p++;
+
+ settings = p;
+ settings_len = -1;
+ while (p < q) {
+ if (*p == '\r' || *p == '\n') {
+ settings_len = p - settings;
+ if (*p == '\r')
+ p++;
+ break;
+ }
+ p++;
+ }
+
+ if (p >= q || *p != '\n')
+ return AVERROR_INVALIDDATA;
+ p++;
+
+ text = p;
+ text_len = q - p;
+ while (text_len > 0) {
+ const int len = text_len - 1;
+ const uint8_t c = p[len];
+ if (c != '\r' && c != '\n')
+ break;
+ text_len = len;
+ }
+
+ if (text_len <= 0)
+ return AVERROR_INVALIDDATA;
+
+ pkt = av_mallocz(sizeof(*pkt));
+ err = av_new_packet(pkt, text_len);
+ if (err < 0) {
+ av_free(pkt);
+ return AVERROR(err);
+ }
+
+ memcpy(pkt->data, text, text_len);
+
+ if (id_len > 0) {
+ buf = av_packet_new_side_data(pkt,
+ AV_PKT_DATA_WEBVTT_IDENTIFIER,
+ id_len);
+ if (buf == NULL) {
+ av_free(pkt);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(buf, id, id_len);
+ }
+
+ if (settings_len > 0) {
+ buf = av_packet_new_side_data(pkt,
+ AV_PKT_DATA_WEBVTT_SETTINGS,
+ settings_len);
+ if (buf == NULL) {
+ av_free(pkt);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(buf, settings, settings_len);
+ }
+
+ // Do we need this for subtitles?
+ // pkt->flags = AV_PKT_FLAG_KEY;
+
+ pkt->stream_index = st->index;
+ pkt->pts = timecode;
+
+ // Do we need this for subtitles?
+ // pkt->dts = timecode;
+
+ pkt->duration = duration;
+ pkt->pos = pos;
+
+ dynarray_add(&matroska->packets, &matroska->num_packets, pkt);
+ matroska->prev_pkt = pkt;
+
+ return 0;
+}
+
static int matroska_parse_frame(MatroskaDemuxContext *matroska,
MatroskaTrack *track,
AVStream *st,
@@ -2179,6 +2389,18 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
return res;
}
+ if (st->codec->codec_id == AV_CODEC_ID_WAVPACK) {
+ uint8_t *wv_data;
+ res = matroska_parse_wavpack(track, pkt_data, &wv_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 (st->codec->codec_id == AV_CODEC_ID_PRORES)
offset = 8;
@@ -2186,7 +2408,8 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
/* XXX: prevent data copy... */
if (av_new_packet(pkt, pkt_size + offset) < 0) {
av_free(pkt);
- return AVERROR(ENOMEM);
+ res = AVERROR(ENOMEM);
+ goto fail;
}
if (st->codec->codec_id == AV_CODEC_ID_PRORES) {
@@ -2198,7 +2421,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
memcpy(pkt->data + offset, pkt_data, pkt_size);
if (pkt_data != data)
- av_free(pkt_data);
+ av_freep(&pkt_data);
pkt->flags = is_keyframe;
pkt->stream_index = st->index;
@@ -2265,6 +2488,10 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
#endif
return 0;
+fail:
+ if (pkt_data != data)
+ av_freep(&pkt_data);
+ return res;
}
static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
@@ -2281,6 +2508,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
uint32_t *lace_size = NULL;
int n, flags, laces = 0;
uint64_t num;
+ int trust_default_duration = 1;
if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {
av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");
@@ -2301,7 +2529,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
return res;
av_assert1(block_duration != AV_NOPTS_VALUE);
- block_time = AV_RB16(data);
+ block_time = sign_extend(AV_RB16(data), 16);
data += 2;
flags = *data++;
size -= 3;
@@ -2335,7 +2563,15 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (res)
goto end;
- if (!block_duration)
+ if (track->audio.samplerate == 8000) {
+ // If this is needed for more codecs, then add them here
+ if (st->codec->codec_id == AV_CODEC_ID_AC3) {
+ if(track->audio.samplerate != st->codec->sample_rate || !st->codec->frame_size)
+ trust_default_duration = 0;
+ }
+ }
+
+ if (!block_duration && trust_default_duration)
block_duration = track->default_duration * laces / matroska->time_scale;
if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time))
@@ -2366,6 +2602,14 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (res)
goto end;
+ } else if (st->codec->codec_id == AV_CODEC_ID_WEBVTT) {
+ res = matroska_parse_webvtt(matroska, track, st,
+ data, lace_size[n],
+ timecode, lace_duration,
+ pos);
+ if (res)
+ goto end;
+
} else {
res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
timecode, lace_duration,
@@ -2441,7 +2685,6 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
}
}
- if (res < 0) matroska->done = 1;
return res;
}
@@ -2530,10 +2773,11 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE
&& tracks[i].stream->discard != AVDISCARD_ALL) {
index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD);
- if (index_sub >= 0
- && st->index_entries[index_sub].pos < st->index_entries[index_min].pos
- && st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale)
- index_min = index_sub;
+ while(index_sub >= 0
+ && index_min >= 0
+ && tracks[i].stream->index_entries[index_sub].pos < st->index_entries[index_min].pos
+ && st->index_entries[index].timestamp - tracks[i].stream->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale)
+ index_min--;
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
index 6726fd98124..92df6cbef1c 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
@@ -19,23 +19,28 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "avc.h"
#include "avformat.h"
+#include "avio_internal.h"
+#include "avlanguage.h"
+#include "flacenc.h"
#include "internal.h"
-#include "riff.h"
#include "isom.h"
#include "matroska.h"
-#include "avc.h"
-#include "flacenc.h"
-#include "avlanguage.h"
-#include "libavutil/samplefmt.h"
-#include "libavutil/sha.h"
-#include "libavutil/intreadwrite.h"
+#include "riff.h"
+#include "wv.h"
+
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/lfg.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "libavutil/random_seed.h"
-#include "libavutil/lfg.h"
-#include "libavutil/dict.h"
-#include "libavutil/avstring.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/sha.h"
+
#include "libavcodec/xiph.h"
#include "libavcodec/mpeg4audio.h"
@@ -62,6 +67,7 @@ typedef struct {
uint64_t pts;
int tracknum;
int64_t cluster_pos; ///< file offset of the cluster containing the block
+ int64_t relative_pos; ///< relative offset from the position of the cluster containing the block
} mkv_cuepoint;
typedef struct {
@@ -79,6 +85,7 @@ typedef struct {
#define MODE_WEBM 0x02
typedef struct MatroskaMuxContext {
+ const AVClass *class;
int mode;
AVIOContext *dyn_bc;
ebml_master segment;
@@ -95,6 +102,13 @@ typedef struct MatroskaMuxContext {
AVPacket cur_audio_pkt;
int have_attachments;
+
+ int reserve_cues_space;
+ int cluster_size_limit;
+ int64_t cues_pos;
+ int64_t cluster_time_limit;
+
+ uint32_t chapter_id_offset;
} MatroskaMuxContext;
@@ -102,13 +116,16 @@ typedef struct MatroskaMuxContext {
* offset, 4 bytes for target EBML ID */
#define MAX_SEEKENTRY_SIZE 21
-/** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2
+/** per-cuepoint-track - 4 1-byte EBML IDs, 4 1-byte EBML sizes, 3
* 8-byte uint max */
-#define MAX_CUETRACKPOS_SIZE 22
+#define MAX_CUETRACKPOS_SIZE 32
/** per-cuepoint - 2 1-byte EBML IDs, 2 1-byte EBML sizes, 8-byte uint max */
#define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks
+/** Seek preroll value for opus */
+#define OPUS_SEEK_PREROLL 80000000
+
static int ebml_id_size(unsigned int id)
{
@@ -131,8 +148,7 @@ static void put_ebml_size_unknown(AVIOContext *pb, int bytes)
{
av_assert0(bytes <= 8);
avio_w8(pb, 0x1ff >> bytes);
- while (--bytes)
- avio_w8(pb, 0xff);
+ ffio_fill(pb, 0xff, bytes - 1);
}
/**
@@ -222,8 +238,7 @@ static void put_ebml_void(AVIOContext *pb, uint64_t size)
put_ebml_num(pb, size-1, 0);
else
put_ebml_num(pb, size-9, 8);
- while(avio_tell(pb) < currentpos + size)
- avio_w8(pb, 0);
+ ffio_fill(pb, 0, currentpos + size - avio_tell(pb));
}
static ebml_master start_ebml_master(AVIOContext *pb, unsigned int elementid, uint64_t expectedsize)
@@ -246,9 +261,7 @@ static void end_ebml_master(AVIOContext *pb, ebml_master master)
static void put_xiph_size(AVIOContext *pb, int size)
{
- int i;
- for (i = 0; i < size / 255; i++)
- avio_w8(pb, 255);
+ ffio_fill(pb, 255, size / 255);
avio_w8(pb, size % 255);
}
@@ -365,7 +378,7 @@ static mkv_cues * mkv_start_cues(int64_t segment_offset)
return cues;
}
-static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos)
+static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos, int64_t relative_pos)
{
mkv_cuepoint *entries = cues->entries;
@@ -378,7 +391,8 @@ static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t clus
entries[cues->num_entries ].pts = ts;
entries[cues->num_entries ].tracknum = stream + 1;
- entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset;
+ entries[cues->num_entries ].cluster_pos = cluster_pos - cues->segment_offset;
+ entries[cues->num_entries++].relative_pos = relative_pos;
cues->entries = entries;
return 0;
@@ -412,8 +426,9 @@ static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, mkv_track *tracks
continue;
tracks[tracknum].has_cue = 1;
track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);
- put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum );
- put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos);
+ put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum );
+ put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION , entry[j].cluster_pos);
+ put_ebml_uint(pb, MATROSKA_ID_CUERELATIVEPOSITION, entry[j].relative_pos);
end_ebml_master(pb, track_positions);
}
i += j - 1;
@@ -452,6 +467,15 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, AVCodecContex
return 0;
}
+static int put_wv_codecpriv(AVIOContext *pb, AVCodecContext *codec)
+{
+ if (codec->extradata && codec->extradata_size == 2)
+ avio_write(pb, codec->extradata, 2);
+ else
+ avio_wl16(pb, 0x403); // fallback to the version mentioned in matroska specs
+ return 0;
+}
+
static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate)
{
MPEG4AudioConfig mp4ac;
@@ -481,6 +505,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo
ret = put_xiph_codecpriv(s, dyn_cp, codec);
else if (codec->codec_id == AV_CODEC_ID_FLAC)
ret = ff_flac_write_header(dyn_cp, codec, 1);
+ else if (codec->codec_id == AV_CODEC_ID_WAVPACK)
+ ret = put_wv_codecpriv(dyn_cp, codec);
else if (codec->codec_id == AV_CODEC_ID_H264)
ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
else if (codec->codec_id == AV_CODEC_ID_ALAC) {
@@ -581,7 +607,11 @@ static int mkv_write_tracks(AVFormatContext *s)
if ((tag = av_dict_get(st->metadata, "title", NULL, 0)))
put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
tag = av_dict_get(st->metadata, "language", NULL, 0);
- put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
+ if (mkv->mode != MODE_WEBM || codec->codec_id != AV_CODEC_ID_WEBVTT) {
+ put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
+ } else if (tag && tag->value) {
+ put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag->value);
+ }
if (default_stream_exists) {
put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
@@ -589,20 +619,45 @@ static int mkv_write_tracks(AVFormatContext *s)
if (st->disposition & AV_DISPOSITION_FORCED)
put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1);
- // look for a codec ID string specific to mkv to use,
- // if none are found, use AVI codes
- for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
- if (ff_mkv_codec_tags[j].id == codec->codec_id) {
- put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
- native_id = 1;
- break;
+ if (mkv->mode == MODE_WEBM && codec->codec_id == AV_CODEC_ID_WEBVTT) {
+ const char *codec_id;
+ if (st->disposition & AV_DISPOSITION_CAPTIONS) {
+ codec_id = "D_WEBVTT/CAPTIONS";
+ native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
+ } else if (st->disposition & AV_DISPOSITION_DESCRIPTIONS) {
+ codec_id = "D_WEBVTT/DESCRIPTIONS";
+ native_id = MATROSKA_TRACK_TYPE_METADATA;
+ } else if (st->disposition & AV_DISPOSITION_METADATA) {
+ codec_id = "D_WEBVTT/METADATA";
+ native_id = MATROSKA_TRACK_TYPE_METADATA;
+ } else {
+ codec_id = "D_WEBVTT/SUBTITLES";
+ native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
}
+ put_ebml_string(pb, MATROSKA_ID_CODECID, codec_id);
+ } else {
+ // look for a codec ID string specific to mkv to use,
+ // if none are found, use AVI codes
+ for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
+ if (ff_mkv_codec_tags[j].id == codec->codec_id) {
+ put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
+ native_id = 1;
+ break;
+ }
+ }
+ }
+
+ if (codec->codec_id == AV_CODEC_ID_OPUS) {
+ put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL);
}
if (mkv->mode == MODE_WEBM && !(codec->codec_id == AV_CODEC_ID_VP8 ||
- codec->codec_id == AV_CODEC_ID_VORBIS)) {
+ codec->codec_id == AV_CODEC_ID_VP9 ||
+ ((codec->codec_id == AV_CODEC_ID_OPUS)&&(codec->strict_std_compliance <= FF_COMPLIANCE_EXPERIMENTAL)) ||
+ codec->codec_id == AV_CODEC_ID_VORBIS ||
+ codec->codec_id == AV_CODEC_ID_WEBVTT)) {
av_log(s, AV_LOG_ERROR,
- "Only VP8 video and Vorbis audio are supported for WebM.\n");
+ "Only VP8,VP9 video and Vorbis,Opus(experimental, use -strict -2) audio and WebVTT subtitles are supported for WebM.\n");
return AVERROR(EINVAL);
}
@@ -655,6 +710,12 @@ static int mkv_write_tracks(AVFormatContext *s)
put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode);
}
+ if ((tag = av_dict_get(st->metadata, "alpha_mode", NULL, 0)) ||
+ (tag = av_dict_get( s->metadata, "alpha_mode", NULL, 0)) ||
+ (codec->pix_fmt == AV_PIX_FMT_YUVA420P)) {
+ put_ebml_uint(pb, MATROSKA_ID_VIDEOALPHAMODE, 1);
+ }
+
if (st->sample_aspect_ratio.num) {
int64_t d_width = av_rescale(codec->width, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
if (d_width > INT_MAX) {
@@ -690,18 +751,25 @@ static int mkv_write_tracks(AVFormatContext *s)
break;
case AVMEDIA_TYPE_SUBTITLE:
- put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_SUBTITLE);
if (!native_id) {
av_log(s, AV_LOG_ERROR, "Subtitle codec %d is not supported.\n", codec->codec_id);
return AVERROR(ENOSYS);
}
+
+ if (mkv->mode != MODE_WEBM || codec->codec_id != AV_CODEC_ID_WEBVTT)
+ native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
+
+ put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, native_id);
break;
default:
av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska.\n");
- break;
+ return AVERROR(EINVAL);
+ }
+
+ if (mkv->mode != MODE_WEBM || codec->codec_id != AV_CODEC_ID_WEBVTT) {
+ ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id);
+ if (ret < 0) return ret;
}
- ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id);
- if (ret < 0) return ret;
end_ebml_master(pb, track);
@@ -736,7 +804,7 @@ static int mkv_write_chapters(AVFormatContext *s)
AVDictionaryEntry *t = NULL;
chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0);
- put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id);
+ put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id + mkv->chapter_id_offset);
put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART,
av_rescale_q(c->start, c->time_base, scale));
put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND,
@@ -815,14 +883,26 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme
return 0;
}
+static int mkv_check_tag(AVDictionary *m)
+{
+ AVDictionaryEntry *t = NULL;
+
+ while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
+ if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode"))
+ return 1;
+
+ return 0;
+}
+
static int mkv_write_tags(AVFormatContext *s)
{
+ MatroskaMuxContext *mkv = s->priv_data;
ebml_master tags = {0};
int i, ret;
ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
- if (av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
+ if (mkv_check_tag(s->metadata)) {
ret = mkv_write_tag(s, s->metadata, 0, 0, &tags);
if (ret < 0) return ret;
}
@@ -830,7 +910,7 @@ static int mkv_write_tags(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- if (!av_dict_get(st->metadata, "", 0, AV_DICT_IGNORE_SUFFIX))
+ if (!mkv_check_tag(st->metadata))
continue;
ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags);
@@ -840,10 +920,10 @@ static int mkv_write_tags(AVFormatContext *s)
for (i = 0; i < s->nb_chapters; i++) {
AVChapter *ch = s->chapters[i];
- if (!av_dict_get(ch->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
+ if (!mkv_check_tag(ch->metadata))
continue;
- ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags);
+ ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &tags);
if (ret < 0) return ret;
}
@@ -1022,6 +1102,9 @@ static int mkv_write_header(AVFormatContext *s)
ret = mkv_write_tracks(s);
if (ret < 0) return ret;
+ for (i = 0; i < s->nb_chapters; i++)
+ mkv->chapter_id_offset = FFMAX(mkv->chapter_id_offset, 1LL - s->chapters[i]->id);
+
if (mkv->mode != MODE_WEBM) {
ret = mkv_write_chapters(s);
if (ret < 0) return ret;
@@ -1040,11 +1123,31 @@ static int mkv_write_header(AVFormatContext *s)
if (mkv->cues == NULL)
return AVERROR(ENOMEM);
+ if (pb->seekable && mkv->reserve_cues_space) {
+ mkv->cues_pos = avio_tell(pb);
+ put_ebml_void(pb, mkv->reserve_cues_space);
+ }
+
av_init_packet(&mkv->cur_audio_pkt);
mkv->cur_audio_pkt.size = 0;
mkv->cluster_pos = -1;
avio_flush(pb);
+
+ // 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) {
+ if (mkv->cluster_time_limit < 0)
+ mkv->cluster_time_limit = 5000;
+ if (mkv->cluster_size_limit < 0)
+ mkv->cluster_size_limit = 5 * 1024 * 1024;
+ } else {
+ if (mkv->cluster_time_limit < 0)
+ mkv->cluster_time_limit = 1000;
+ if (mkv->cluster_size_limit < 0)
+ mkv->cluster_size_limit = 32 * 1024;
+ }
+
return 0;
}
@@ -1119,14 +1222,69 @@ static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p
}
#endif
+static int mkv_strip_wavpack(const uint8_t *src, uint8_t **pdst, int *size)
+{
+ uint8_t *dst;
+ int srclen = *size;
+ int offset = 0;
+ int ret;
+
+ dst = av_malloc(srclen);
+ if (!dst)
+ return AVERROR(ENOMEM);
+
+ while (srclen >= WV_HEADER_SIZE) {
+ WvHeader header;
+
+ ret = ff_wv_parse_header(&header, src);
+ if (ret < 0)
+ goto fail;
+ src += WV_HEADER_SIZE;
+ srclen -= WV_HEADER_SIZE;
+
+ if (srclen < header.blocksize) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if (header.initial) {
+ AV_WL32(dst + offset, header.samples);
+ offset += 4;
+ }
+ AV_WL32(dst + offset, header.flags);
+ AV_WL32(dst + offset + 4, header.crc);
+ offset += 8;
+
+ if (!(header.initial && header.final)) {
+ AV_WL32(dst + offset, header.blocksize);
+ offset += 4;
+ }
+
+ memcpy(dst + offset, src, header.blocksize);
+ src += header.blocksize;
+ srclen -= header.blocksize;
+ offset += header.blocksize;
+ }
+
+ *pdst = dst;
+ *size = offset;
+
+ return 0;
+fail:
+ av_freep(&dst);
+ return ret;
+}
+
static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
unsigned int blockid, AVPacket *pkt, int flags)
{
MatroskaMuxContext *mkv = s->priv_data;
AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
- uint8_t *data = NULL;
- int offset = 0, size = pkt->size;
+ uint8_t *data = NULL, *side_data = NULL;
+ int offset = 0, size = pkt->size, side_data_size = 0;
int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
+ uint64_t additional_id = 0;
+ ebml_master block_group, block_additions, block_more;
av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
"pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
@@ -1134,7 +1292,13 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
if (codec->codec_id == AV_CODEC_ID_H264 && codec->extradata_size > 0 &&
(AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1))
ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
- else
+ else if (codec->codec_id == AV_CODEC_ID_WAVPACK) {
+ int ret = mkv_strip_wavpack(pkt->data, &data, &size);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Error stripping a WavPack packet.\n");
+ return;
+ }
+ } else
data = pkt->data;
if (codec->codec_id == AV_CODEC_ID_PRORES) {
@@ -1144,6 +1308,20 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
offset = 8;
}
+ side_data = av_packet_get_side_data(pkt,
+ AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+ &side_data_size);
+ if (side_data) {
+ additional_id = AV_RB64(side_data);
+ side_data += 8;
+ side_data_size -= 8;
+ }
+
+ if (side_data_size && additional_id == 1) {
+ block_group = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, 0);
+ blockid = MATROSKA_ID_BLOCK;
+ }
+
put_ebml_id(pb, blockid);
put_ebml_num(pb, size+4, 0);
avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126
@@ -1152,6 +1330,18 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
avio_write(pb, data + offset, size);
if (data != pkt->data)
av_free(data);
+
+ if (side_data_size && additional_id == 1) {
+ block_additions = start_ebml_master(pb, MATROSKA_ID_BLOCKADDITIONS, 0);
+ block_more = start_ebml_master(pb, MATROSKA_ID_BLOCKMORE, 0);
+ put_ebml_uint(pb, MATROSKA_ID_BLOCKADDID, 1);
+ put_ebml_id(pb, MATROSKA_ID_BLOCKADDITIONAL);
+ put_ebml_num(pb, side_data_size, 0);
+ avio_write(pb, side_data, side_data_size);
+ end_ebml_master(pb, block_more);
+ end_ebml_master(pb, block_additions);
+ end_ebml_master(pb, block_group);
+ }
}
static int srt_get_duration(uint8_t **buf)
@@ -1189,6 +1379,44 @@ static int mkv_write_srt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p
return duration;
}
+static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
+{
+ MatroskaMuxContext *mkv = s->priv_data;
+ ebml_master blockgroup;
+ int id_size, settings_size, size;
+ uint8_t *id, *settings;
+ int64_t ts = mkv->tracks[pkt->stream_index].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);
+
+ settings_size = 0;
+ settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
+ &settings_size);
+
+ size = id_size + 1 + settings_size + 1 + pkt->size;
+
+ av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
+ "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
+ avio_tell(pb), size, pkt->pts, pkt->dts, pkt->duration, flags);
+
+ blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size));
+
+ put_ebml_id(pb, MATROSKA_ID_BLOCK);
+ put_ebml_num(pb, size+4, 0);
+ avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126
+ avio_wb16(pb, ts - mkv->cluster_pts);
+ avio_w8(pb, flags);
+ avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, pkt->size, pkt->data);
+
+ put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, pkt->duration);
+ end_ebml_master(pb, blockgroup);
+
+ return pkt->duration;
+}
+
static void mkv_flush_dynbuf(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
@@ -1213,6 +1441,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
int duration = pkt->duration;
int ret;
int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
+ int64_t relative_packet_pos;
if (ts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n");
@@ -1236,6 +1465,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
mkv->cluster_pts = FFMAX(0, ts);
}
+ relative_packet_pos = avio_tell(s->pb) - mkv->cluster.pos;
+
if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7);
#if FF_API_ASS_SSA
@@ -1244,6 +1475,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
#endif
} else if (codec->codec_id == AV_CODEC_ID_SRT) {
duration = mkv_write_srt_blocks(s, pb, pkt);
+ } else if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
+ duration = mkv_write_vtt_blocks(s, pb, pkt);
} else {
ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size));
/* For backward compatibility, prefer convergence_duration. */
@@ -1256,7 +1489,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
}
if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) {
- ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos);
+ ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos, relative_packet_pos);
if (ret < 0) return ret;
}
@@ -1267,24 +1500,41 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
{
MatroskaMuxContext *mkv = s->priv_data;
- AVIOContext *pb = s->pb->seekable ? s->pb : mkv->dyn_bc;
- AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
- int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
- int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
- int cluster_size = avio_tell(pb) - (s->pb->seekable ? mkv->cluster_pos : 0);
+ int codec_type = s->streams[pkt->stream_index]->codec->codec_type;
+ int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
+ int cluster_size;
+ int64_t cluster_time;
+ AVIOContext *pb;
+ int ret;
+
+ if (mkv->tracks[pkt->stream_index].write_dts)
+ cluster_time = pkt->dts - mkv->cluster_pts;
+ else
+ cluster_time = pkt->pts - mkv->cluster_pts;
// start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
// after 4k and on a keyframe
+ if (s->pb->seekable) {
+ pb = s->pb;
+ cluster_size = avio_tell(pb) - mkv->cluster_pos;
+ } else {
+ pb = mkv->dyn_bc;
+ cluster_size = avio_tell(pb);
+ }
+
if (mkv->cluster_pos != -1 &&
- ((!s->pb->seekable && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
- || cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000
- || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) {
+ (cluster_size > mkv->cluster_size_limit ||
+ cluster_time > mkv->cluster_time_limit ||
+ (codec_type == AVMEDIA_TYPE_VIDEO && keyframe &&
+ cluster_size > 4 * 1024))) {
av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
- " bytes, pts %" PRIu64 "\n", avio_tell(pb), ts);
+ " bytes, pts %" PRIu64 "dts %" PRIu64 "\n",
+ avio_tell(pb), pkt->pts, pkt->dts);
end_ebml_master(pb, mkv->cluster);
mkv->cluster_pos = -1;
if (mkv->dyn_bc)
mkv_flush_dynbuf(s);
+ avio_flush(s->pb);
}
// check if we have an audio packet cached
@@ -1299,15 +1549,41 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
// buffer an audio packet to ensure the packet containing the video
// keyframe's timecode is contained in the same cluster for WebM
- if (codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (codec_type == AVMEDIA_TYPE_AUDIO) {
mkv->cur_audio_pkt = *pkt;
- mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf);
- ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM);
+ if (pkt->buf) {
+ mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf);
+ ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM);
+ } else
+ ret = av_dup_packet(&mkv->cur_audio_pkt);
} else
ret = mkv_write_packet_internal(s, pkt);
return ret;
}
+static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ MatroskaMuxContext *mkv = s->priv_data;
+ AVIOContext *pb;
+ if (s->pb->seekable)
+ pb = s->pb;
+ else
+ pb = mkv->dyn_bc;
+ if (!pkt) {
+ if (mkv->cluster_pos != -1) {
+ av_log(s, AV_LOG_DEBUG, "Flushing cluster at offset %" PRIu64
+ " bytes\n", avio_tell(pb));
+ end_ebml_master(pb, mkv->cluster);
+ mkv->cluster_pos = -1;
+ if (mkv->dyn_bc)
+ mkv_flush_dynbuf(s);
+ avio_flush(s->pb);
+ }
+ return 0;
+ }
+ return mkv_write_packet(s, pkt);
+}
+
static int mkv_write_trailer(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
@@ -1334,7 +1610,28 @@ static int mkv_write_trailer(AVFormatContext *s)
if (pb->seekable) {
if (mkv->cues->num_entries) {
- cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams);
+ if (mkv->reserve_cues_space) {
+ int64_t cues_end;
+
+ currentpos = avio_tell(pb);
+ avio_seek(pb, mkv->cues_pos, SEEK_SET);
+
+ cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams);
+ cues_end = avio_tell(pb);
+ if (cues_end > cuespos + mkv->reserve_cues_space) {
+ av_log(s, AV_LOG_ERROR, "Insufficient space reserved for cues: %d "
+ "(needed: %"PRId64").\n", mkv->reserve_cues_space,
+ cues_end - cuespos);
+ return AVERROR(EINVAL);
+ }
+
+ if (cues_end < cuespos + mkv->reserve_cues_space)
+ put_ebml_void(pb, mkv->reserve_cues_space - (cues_end - cuespos));
+
+ avio_seek(pb, currentpos, SEEK_SET);
+ } else {
+ cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams);
+ }
ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES, cuespos);
if (ret < 0) return ret;
@@ -1375,7 +1672,7 @@ static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance)
return 0;
}
-const AVCodecTag additional_audio_tags[] = {
+static const AVCodecTag additional_audio_tags[] = {
{ AV_CODEC_ID_ALAC, 0XFFFFFFFF },
{ AV_CODEC_ID_EAC3, 0XFFFFFFFF },
{ AV_CODEC_ID_MLP, 0xFFFFFFFF },
@@ -1388,11 +1685,10 @@ const AVCodecTag additional_audio_tags[] = {
{ AV_CODEC_ID_RA_288, 0xFFFFFFFF },
{ AV_CODEC_ID_COOK, 0xFFFFFFFF },
{ AV_CODEC_ID_TRUEHD, 0xFFFFFFFF },
- { AV_CODEC_ID_WAVPACK, 0xFFFFFFFF },
{ AV_CODEC_ID_NONE, 0xFFFFFFFF }
};
-const AVCodecTag additional_video_tags[] = {
+static const AVCodecTag additional_video_tags[] = {
{ AV_CODEC_ID_PRORES, 0xFFFFFFFF },
{ AV_CODEC_ID_RV10, 0xFFFFFFFF },
{ AV_CODEC_ID_RV20, 0xFFFFFFFF },
@@ -1402,7 +1698,23 @@ const AVCodecTag additional_video_tags[] = {
{ AV_CODEC_ID_NONE, 0xFFFFFFFF }
};
+#define OFFSET(x) offsetof(MatroskaMuxContext, x)
+#define FLAGS AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "reserve_index_space", "Reserve a given amount of space (in bytes) at the beginning of the file for the index (cues).", OFFSET(reserve_cues_space), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
+ { "cluster_size_limit", "Store at most the provided amount of bytes in a cluster. ", OFFSET(cluster_size_limit), AV_OPT_TYPE_INT , { .i64 = -1 }, -1, INT_MAX, FLAGS },
+ { "cluster_time_limit", "Store at most the provided number of milliseconds in a cluster.", OFFSET(cluster_time_limit), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS },
+ { NULL },
+};
+
#if CONFIG_MATROSKA_MUXER
+static const AVClass matroska_class = {
+ .class_name = "matroska muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_matroska_muxer = {
.name = "matroska",
.long_name = NULL_IF_CONFIG_SMALL("Matroska"),
@@ -1414,10 +1726,10 @@ AVOutputFormat ff_matroska_muxer = {
.video_codec = CONFIG_LIBX264_ENCODER ?
AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
.write_header = mkv_write_header,
- .write_packet = mkv_write_packet,
+ .write_packet = mkv_write_flush_packet,
.write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
- AVFMT_TS_NONSTRICT,
+ AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
.codec_tag = (const AVCodecTag* const []){
ff_codec_bmp_tags, ff_codec_wav_tags,
additional_audio_tags, additional_video_tags, 0
@@ -1428,10 +1740,18 @@ AVOutputFormat ff_matroska_muxer = {
.subtitle_codec = AV_CODEC_ID_ASS,
#endif
.query_codec = mkv_query_codec,
+ .priv_class = &matroska_class,
};
#endif
#if CONFIG_WEBM_MUXER
+static const AVClass webm_class = {
+ .class_name = "webm muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_webm_muxer = {
.name = "webm",
.long_name = NULL_IF_CONFIG_SMALL("WebM"),
@@ -1440,18 +1760,26 @@ AVOutputFormat ff_webm_muxer = {
.priv_data_size = sizeof(MatroskaMuxContext),
.audio_codec = AV_CODEC_ID_VORBIS,
.video_codec = AV_CODEC_ID_VP8,
+ .subtitle_codec = AV_CODEC_ID_WEBVTT,
.write_header = mkv_write_header,
- .write_packet = mkv_write_packet,
+ .write_packet = mkv_write_flush_packet,
.write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
- AVFMT_TS_NONSTRICT,
+ AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
+ .priv_class = &webm_class,
};
#endif
#if CONFIG_MATROSKA_AUDIO_MUXER
+static const AVClass mka_class = {
+ .class_name = "matroska audio muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
AVOutputFormat ff_matroska_audio_muxer = {
.name = "matroska",
- .long_name = NULL_IF_CONFIG_SMALL("Matroska"),
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska Audio"),
.mime_type = "audio/x-matroska",
.extensions = "mka",
.priv_data_size = sizeof(MatroskaMuxContext),
@@ -1459,11 +1787,13 @@ AVOutputFormat ff_matroska_audio_muxer = {
AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3,
.video_codec = AV_CODEC_ID_NONE,
.write_header = mkv_write_header,
- .write_packet = mkv_write_packet,
+ .write_packet = mkv_write_flush_packet,
.write_trailer = mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT |
+ AVFMT_ALLOW_FLUSH,
.codec_tag = (const AVCodecTag* const []){
ff_codec_wav_tags, additional_audio_tags, 0
},
+ .priv_class = &mka_class,
};
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/md5enc.c b/chromium/third_party/ffmpeg/libavformat/md5enc.c
index 050efb1513a..270d9fb660f 100644
--- a/chromium/third_party/ffmpeg/libavformat/md5enc.c
+++ b/chromium/third_party/ffmpeg/libavformat/md5enc.c
@@ -19,21 +19,28 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/md5.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/hash.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
struct MD5Context {
- struct AVMD5 *md5;
+ const AVClass *avclass;
+ struct AVHashContext *hash;
+ char *hash_name;
};
static void md5_finish(struct AVFormatContext *s, char *buf)
{
struct MD5Context *c = s->priv_data;
- uint8_t md5[16];
+ uint8_t md5[AV_HASH_MAX_SIZE];
int i, offset = strlen(buf);
- av_md5_final(c->md5, md5);
- for (i = 0; i < sizeof(md5); i++) {
+ int len = av_hash_get_size(c->hash);
+ av_assert0(len > 0 && len <= sizeof(md5));
+ av_hash_final(c->hash, md5);
+ for (i = 0; i < len; i++) {
snprintf(buf + offset, 3, "%02"PRIx8, md5[i]);
offset += 2;
}
@@ -44,32 +51,48 @@ static void md5_finish(struct AVFormatContext *s, char *buf)
avio_flush(s->pb);
}
+#define OFFSET(x) offsetof(struct MD5Context, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption hash_options[] = {
+ { "hash", "set hash to use", OFFSET(hash_name), AV_OPT_TYPE_STRING, {.str = "md5"}, 0, 0, ENC },
+ { NULL },
+};
+
+static const AVClass md5enc_class = {
+ .class_name = "hash encoder class",
+ .item_name = av_default_item_name,
+ .option = hash_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
#if CONFIG_MD5_MUXER
static int write_header(struct AVFormatContext *s)
{
struct MD5Context *c = s->priv_data;
- c->md5 = av_md5_alloc();
- if (!c->md5)
- return AVERROR(ENOMEM);
- av_md5_init(c->md5);
+ int res = av_hash_alloc(&c->hash, c->hash_name);
+ if (res < 0)
+ return res;
+ av_hash_init(c->hash);
return 0;
}
static int write_packet(struct AVFormatContext *s, AVPacket *pkt)
{
struct MD5Context *c = s->priv_data;
- av_md5_update(c->md5, pkt->data, pkt->size);
+ av_hash_update(c->hash, pkt->data, pkt->size);
return 0;
}
static int write_trailer(struct AVFormatContext *s)
{
struct MD5Context *c = s->priv_data;
- char buf[64] = "MD5=";
+ char buf[256];
+ av_strlcpy(buf, av_hash_get_name(c->hash), sizeof(buf) - 200);
+ av_strlcat(buf, "=", sizeof(buf) - 200);
md5_finish(s, buf);
- av_freep(&c->md5);
+ av_hash_freep(&c->hash);
return 0;
}
@@ -83,6 +106,7 @@ AVOutputFormat ff_md5_muxer = {
.write_packet = write_packet,
.write_trailer = write_trailer,
.flags = AVFMT_NOTIMESTAMPS,
+ .priv_class = &md5enc_class,
};
#endif
@@ -90,9 +114,9 @@ AVOutputFormat ff_md5_muxer = {
static int framemd5_write_header(struct AVFormatContext *s)
{
struct MD5Context *c = s->priv_data;
- c->md5 = av_md5_alloc();
- if (!c->md5)
- return AVERROR(ENOMEM);
+ int res = av_hash_alloc(&c->hash, c->hash_name);
+ if (res < 0)
+ return res;
return ff_framehash_write_header(s);
}
@@ -100,8 +124,8 @@ static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
{
struct MD5Context *c = s->priv_data;
char buf[256];
- av_md5_init(c->md5);
- av_md5_update(c->md5, pkt->data, pkt->size);
+ av_hash_init(c->hash);
+ av_hash_update(c->hash, pkt->data, pkt->size);
snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8d, %8d, ",
pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size);
@@ -112,10 +136,17 @@ static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
static int framemd5_write_trailer(struct AVFormatContext *s)
{
struct MD5Context *c = s->priv_data;
- av_freep(&c->md5);
+ av_hash_freep(&c->hash);
return 0;
}
+static const AVClass framemd5_class = {
+ .class_name = "frame hash encoder class",
+ .item_name = av_default_item_name,
+ .option = hash_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_framemd5_muxer = {
.name = "framemd5",
.long_name = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"),
@@ -125,6 +156,8 @@ AVOutputFormat ff_framemd5_muxer = {
.write_header = framemd5_write_header,
.write_packet = framemd5_write_packet,
.write_trailer = framemd5_write_trailer,
- .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+ AVFMT_TS_NEGATIVE,
+ .priv_class = &framemd5_class,
};
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/mm.c b/chromium/third_party/ffmpeg/libavformat/mm.c
index 12a11ac69d5..4315802f733 100644
--- a/chromium/third_party/ffmpeg/libavformat/mm.c
+++ b/chromium/third_party/ffmpeg/libavformat/mm.c
@@ -79,7 +79,7 @@ static int probe(AVProbeData *p)
return 0;
/* only return half certainty since this check is a bit sketchy */
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
}
static int read_header(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/mmf.c b/chromium/third_party/ffmpeg/libavformat/mmf.c
index d074d7c57cb..cb87a6dddb9 100644
--- a/chromium/third_party/ffmpeg/libavformat/mmf.c
+++ b/chromium/third_party/ffmpeg/libavformat/mmf.c
@@ -21,8 +21,8 @@
#include "libavutil/channel_layout.h"
#include "avformat.h"
-#include "internal.h"
#include "avio_internal.h"
+#include "internal.h"
#include "pcm.h"
#include "rawenc.h"
#include "riff.h"
@@ -37,7 +37,7 @@ static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 };
static int mmf_rate(int code)
{
- if((code < 0) || (code > 4))
+ if ((code < 0) || (code > 4))
return -1;
return mmf_rates[code];
}
@@ -46,8 +46,8 @@ static int mmf_rate(int code)
static int mmf_rate_code(int rate)
{
int i;
- for(i = 0; i < 5; i++)
- if(mmf_rates[i] == rate)
+ for (i = 0; i < 5; i++)
+ if (mmf_rates[i] == rate)
return i;
return -1;
}
@@ -74,8 +74,9 @@ static int mmf_write_header(AVFormatContext *s)
"VN:"LIBAVFORMAT_IDENT",";
rate = mmf_rate_code(s->streams[0]->codec->sample_rate);
- if(rate < 0) {
- av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n", s->streams[0]->codec->sample_rate);
+ if (rate < 0) {
+ av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n",
+ s->streams[0]->codec->sample_rate);
return AVERROR(EINVAL);
}
@@ -97,6 +98,7 @@ static int mmf_write_header(AVFormatContext *s)
avio_w8(pb, 0); /* status */
avio_w8(pb, 0); /* counts */
end_tag_be(pb, pos);
+
pos = ff_start_tag(pb, "OPDA");
avio_write(pb, version, strlen(version)); /* metadata ("ST:songtitle,VN:version,...") */
end_tag_be(pb, pos);
@@ -129,7 +131,7 @@ static int mmf_write_header(AVFormatContext *s)
/* Write a variable-length symbol */
static void put_varlength(AVIOContext *pb, int val)
{
- if(val < 128)
+ if (val < 128)
avio_w8(pb, val);
else {
val -= 128;
@@ -151,7 +153,7 @@ static int mmf_write_trailer(AVFormatContext *s)
end_tag_be(pb, mmf->atrpos);
end_tag_be(pb, 8);
- pos = avio_tell(pb);
+ pos = avio_tell(pb);
size = pos - mmf->awapos;
/* Fill Atsq chunk */
@@ -206,11 +208,13 @@ static int mmf_read_header(AVFormatContext *s)
avio_skip(pb, 4); /* file_size */
/* Skip some unused chunks that may or may not be present */
- for(;; avio_skip(pb, size)) {
- tag = avio_rl32(pb);
+ for (;; avio_skip(pb, size)) {
+ tag = avio_rl32(pb);
size = avio_rb32(pb);
- if(tag == MKTAG('C','N','T','I')) continue;
- if(tag == MKTAG('O','P','D','A')) continue;
+ if (tag == MKTAG('C', 'N', 'T', 'I'))
+ continue;
+ if (tag == MKTAG('O', 'P', 'D', 'A'))
+ continue;
break;
}
@@ -227,8 +231,8 @@ static int mmf_read_header(AVFormatContext *s)
avio_r8(pb); /* format type */
avio_r8(pb); /* sequence type */
params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */
- rate = mmf_rate(params & 0x0f);
- if(rate < 0) {
+ rate = mmf_rate(params & 0x0f);
+ if (rate < 0) {
av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
return AVERROR_INVALIDDATA;
}
@@ -237,11 +241,13 @@ static int mmf_read_header(AVFormatContext *s)
avio_r8(pb); /* time base g */
/* Skip some unused chunks that may or may not be present */
- for(;; avio_skip(pb, size)) {
- tag = avio_rl32(pb);
+ for (;; avio_skip(pb, size)) {
+ tag = avio_rl32(pb);
size = avio_rb32(pb);
- if(tag == MKTAG('A','t','s','q')) continue;
- if(tag == MKTAG('A','s','p','I')) continue;
+ if (tag == MKTAG('A', 't', 's', 'q'))
+ continue;
+ if (tag == MKTAG('A', 's', 'p', 'I'))
+ continue;
break;
}
@@ -256,13 +262,14 @@ static int mmf_read_header(AVFormatContext *s)
if (!st)
return AVERROR(ENOMEM);
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = AV_CODEC_ID_ADPCM_YAMAHA;
- st->codec->sample_rate = rate;
- st->codec->channels = (params >> 7) + 1;
- st->codec->channel_layout = params >> 7 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_YAMAHA;
+ st->codec->sample_rate = rate;
+ st->codec->channels = (params >> 7) + 1;
+ st->codec->channel_layout = params >> 7 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
st->codec->bits_per_coded_sample = 4;
- st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;
+ st->codec->bit_rate = st->codec->sample_rate *
+ st->codec->bits_per_coded_sample;
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
@@ -271,8 +278,7 @@ static int mmf_read_header(AVFormatContext *s)
#define MAX_SIZE 4096
-static int mmf_read_packet(AVFormatContext *s,
- AVPacket *pkt)
+static int mmf_read_packet(AVFormatContext *s, AVPacket *pkt)
{
MMFContext *mmf = s->priv_data;
int64_t left, size;
@@ -303,17 +309,18 @@ AVInputFormat ff_mmf_demuxer = {
.flags = AVFMT_GENERIC_INDEX,
};
#endif
+
#if CONFIG_MMF_MUXER
AVOutputFormat ff_mmf_muxer = {
- .name = "mmf",
- .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
- .mime_type = "application/vnd.smaf",
- .extensions = "mmf",
- .priv_data_size = sizeof(MMFContext),
- .audio_codec = AV_CODEC_ID_ADPCM_YAMAHA,
- .video_codec = AV_CODEC_ID_NONE,
- .write_header = mmf_write_header,
- .write_packet = ff_raw_write_packet,
- .write_trailer = mmf_write_trailer,
+ .name = "mmf",
+ .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+ .mime_type = "application/vnd.smaf",
+ .extensions = "mmf",
+ .priv_data_size = sizeof(MMFContext),
+ .audio_codec = AV_CODEC_ID_ADPCM_YAMAHA,
+ .video_codec = AV_CODEC_ID_NONE,
+ .write_header = mmf_write_header,
+ .write_packet = ff_raw_write_packet,
+ .write_trailer = mmf_write_trailer,
};
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/mmsh.c b/chromium/third_party/ffmpeg/libavformat/mmsh.c
index 86a0575e59d..482ece40316 100644
--- a/chromium/third_party/ffmpeg/libavformat/mmsh.c
+++ b/chromium/third_party/ffmpeg/libavformat/mmsh.c
@@ -66,9 +66,9 @@ static int mmsh_close(URLContext *h)
MMSHContext *mmsh = (MMSHContext *)h->priv_data;
MMSContext *mms = &mmsh->mms;
if (mms->mms_hd)
- ffurl_close(mms->mms_hd);
- av_free(mms->streams);
- av_free(mms->asf_header);
+ ffurl_closep(&mms->mms_hd);
+ av_freep(&mms->streams);
+ av_freep(&mms->asf_header);
return 0;
}
@@ -368,23 +368,26 @@ static int mmsh_read(URLContext *h, uint8_t *buf, int size)
static int64_t mmsh_read_seek(URLContext *h, int stream_index,
int64_t timestamp, int flags)
{
- MMSHContext *mmsh = h->priv_data;
- MMSContext *mms = &mmsh->mms;
+ MMSHContext *mmsh_old = h->priv_data;
+ MMSHContext *mmsh = av_mallocz(sizeof(*mmsh));
int ret;
- ret= mmsh_open_internal(h, mmsh->location, 0, FFMAX(timestamp, 0), 0);
+ if (!mmsh)
+ return AVERROR(ENOMEM);
+ h->priv_data = mmsh;
+ ret= mmsh_open_internal(h, mmsh_old->location, 0, FFMAX(timestamp, 0), 0);
if(ret>=0){
- if (mms->mms_hd)
- ffurl_close(mms->mms_hd);
- av_freep(&mms->streams);
- av_freep(&mms->asf_header);
+ h->priv_data = mmsh_old;
+ mmsh_close(h);
+ h->priv_data = mmsh;
+ av_free(mmsh_old);
+ mmsh->mms.asf_header_read_size = mmsh->mms.asf_header_size;
+ }else {
+ h->priv_data = mmsh_old;
av_free(mmsh);
- mmsh = h->priv_data;
- mms = &mmsh->mms;
- mms->asf_header_read_size= mms->asf_header_size;
- }else
- h->priv_data= mmsh;
+ }
+
return ret;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mov.c b/chromium/third_party/ffmpeg/libavformat/mov.c
index 3e48f15e20d..ed5fb9563f2 100644
--- a/chromium/third_party/ffmpeg/libavformat/mov.c
+++ b/chromium/third_party/ffmpeg/libavformat/mov.c
@@ -25,7 +25,6 @@
#include <limits.h>
-//#define DEBUG
//#define MOV_EXPORT_ALL_METADATA
#include "libavutil/attributes.h"
@@ -786,6 +785,12 @@ static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
int ret;
+ if (c->found_moov) {
+ av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
+ avio_skip(pb, atom.size);
+ return 0;
+ }
+
if ((ret = mov_read_default(c, pb, atom)) < 0)
return ret;
/* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
@@ -831,6 +836,11 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
st = c->fc->streams[c->fc->nb_streams-1];
sc = st->priv_data;
+ if (sc->time_scale) {
+ av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
+ return AVERROR_INVALIDDATA;
+ }
+
version = avio_r8(pb);
if (version > 1) {
avpriv_request_sample(c->fc, "Version %d", version);
@@ -878,7 +888,7 @@ static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
// set the AVCodecContext duration because the duration of individual tracks
// may be inaccurate
- if (c->time_scale > 0)
+ if (c->time_scale > 0 && !c->trex_data)
c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
avio_rb32(pb); /* preferred scale */
@@ -1015,6 +1025,36 @@ static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
}
+static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
+
+ if (!ret && c->fc->nb_streams >= 1) {
+ AVCodecContext *avctx = c->fc->streams[c->fc->nb_streams-1]->codec;
+ if (avctx->extradata_size >= 40) {
+ avctx->height = AV_RB16(&avctx->extradata[36]);
+ avctx->width = AV_RB16(&avctx->extradata[38]);
+ }
+ }
+ return ret;
+}
+
+static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
+ if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
+ codec->codec_id == AV_CODEC_ID_H264 &&
+ atom.size > 11) {
+ avio_skip(pb, 10);
+ /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
+ if (avio_rb16(pb) == 0xd4d)
+ codec->width = 1440;
+ return 0;
+ }
+
+ return mov_read_avid(c, pb, atom);
+}
+
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
@@ -1550,6 +1590,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
case AV_CODEC_ID_ADPCM_MS:
case AV_CODEC_ID_ADPCM_IMA_WAV:
case AV_CODEC_ID_ILBC:
+ case AV_CODEC_ID_MACE3:
+ case AV_CODEC_ID_MACE6:
+ case AV_CODEC_ID_QDM2:
st->codec->block_align = sc->bytes_per_frame;
break;
case AV_CODEC_ID_ALAC:
@@ -1720,7 +1763,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sample_size = avio_rb32(pb);
if (!sc->sample_size) /* do not overwrite value computed in stsd */
sc->sample_size = sample_size;
- sc->alt_sample_size = sample_size;
+ sc->stsz_sample_size = sample_size;
field_size = 32;
} else {
sample_size = 0;
@@ -1838,6 +1881,13 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
+{
+ if (duration < 0) {
+ sc->dts_shift = FFMAX(sc->dts_shift, -duration);
+ }
+}
+
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
@@ -1880,8 +1930,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
- if (duration < 0 && i+2<entries)
- sc->dts_shift = FFMAX(sc->dts_shift, -duration);
+ if (i+2<entries)
+ mov_update_dts_shift(sc, duration);
}
sc->ctts_count = i;
@@ -1987,10 +2037,22 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
for (i = 0; i < sc->chunk_count; i++) {
+ int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
current_offset = sc->chunk_offsets[i];
while (stsc_index + 1 < sc->stsc_count &&
i + 1 == sc->stsc_data[stsc_index + 1].first)
stsc_index++;
+
+ if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
+ sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
+ av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
+ sc->stsz_sample_size = sc->sample_size;
+ }
+ if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
+ av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
+ sc->stsz_sample_size = sc->sample_size;
+ }
+
for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
int keyframe = 0;
if (current_sample >= sc->sample_count) {
@@ -2017,7 +2079,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
if (keyframe)
distance = 0;
- sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample];
+ sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
if (sc->pseudo_stream_id == -1 ||
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
@@ -2549,6 +2611,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->ctts_data[sc->ctts_count].count = 1;
sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
avio_rb32(pb) : 0;
+ mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration);
sc->ctts_count++;
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
keyframe = 1;
@@ -2709,11 +2772,77 @@ static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ int ret;
+ uint8_t uuid[16];
+ static const uint8_t uuid_isml_manifest[] = {
+ 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
+ 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
+ };
+
+ if (atom.size < sizeof(uuid) || atom.size == INT64_MAX)
+ return AVERROR_INVALIDDATA;
+
+ ret = avio_read(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;
+ size_t len = atom.size - sizeof(uuid);
+
+ if (len < 4) {
+ return AVERROR_INVALIDDATA;
+ }
+ ret = avio_skip(pb, 4); // zeroes
+ len -= 4;
+
+ buffer = av_mallocz(len + 1);
+ if (!buffer) {
+ return AVERROR(ENOMEM);
+ }
+ ret = avio_read(pb, buffer, len);
+ if (ret < 0) {
+ av_free(buffer);
+ return ret;
+ } else if (ret != len) {
+ av_free(buffer);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ptr = buffer;
+ while ((ptr = av_stristr(ptr, "systemBitrate=\"")) != NULL) {
+ ptr += sizeof("systemBitrate=\"") - 1;
+ c->bitrates_count++;
+ c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
+ if (!c->bitrates) {
+ c->bitrates_count = 0;
+ av_free(buffer);
+ return AVERROR(ENOMEM);
+ }
+ errno = 0;
+ ret = strtol(ptr, &endptr, 10);
+ if (ret < 0 || errno || *endptr != '"') {
+ c->bitrates[c->bitrates_count - 1] = 0;
+ } else {
+ c->bitrates[c->bitrates_count - 1] = ret;
+ }
+ }
+
+ av_free(buffer);
+ }
+ return 0;
+}
+
static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('A','C','L','R'), mov_read_avid },
{ MKTAG('A','P','R','G'), mov_read_avid },
{ MKTAG('A','A','L','P'), mov_read_avid },
-{ MKTAG('A','R','E','S'), mov_read_avid },
+{ MKTAG('A','R','E','S'), mov_read_ares },
{ MKTAG('a','v','s','s'), mov_read_avss },
{ MKTAG('c','h','p','l'), mov_read_chpl },
{ MKTAG('c','o','6','4'), mov_read_stco },
@@ -2772,6 +2901,8 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
{ MKTAG('d','v','c','1'), mov_read_dvc1 },
{ MKTAG('s','b','g','p'), mov_read_sbgp },
+{ MKTAG('u','u','i','d'), mov_read_uuid },
+{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
{ 0, NULL }
};
@@ -2845,8 +2976,10 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
left = a.size - avio_tell(pb) + start_pos;
if (left > 0) /* skip garbage at atom end */
avio_skip(pb, left);
- else if(left < 0) {
- av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %"PRId64" in '%.4s'\n", -left, (char*)&a.type);
+ else if (left < 0) {
+ av_log(c->fc, AV_LOG_WARNING,
+ "overread end of atom '%.4s' by %"PRId64" bytes\n",
+ (char*)&a.type, -left);
avio_seek(pb, left, SEEK_CUR);
}
}
@@ -2887,7 +3020,7 @@ static int mov_probe(AVProbeData *p)
(AV_RB32(p->buf+offset) != 1 ||
offset + 12 > (unsigned int)p->buf_size ||
AV_RB64(p->buf+offset + 8) == 0)) {
- score = FFMAX(score, AVPROBE_SCORE_MAX - 50);
+ score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
} else {
score = AVPROBE_SCORE_MAX;
}
@@ -2907,7 +3040,7 @@ static int mov_probe(AVProbeData *p)
case MKTAG('u','u','i','d'):
case MKTAG('p','r','f','l'):
/* if we only find those cause probedata is too small at least rate them */
- score = FFMAX(score, AVPROBE_SCORE_MAX - 50);
+ score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
break;
default:
@@ -3088,6 +3221,7 @@ static int mov_read_close(AVFormatContext *s)
}
av_freep(&mov->trex_data);
+ av_freep(&mov->bitrates);
return 0;
}
@@ -3200,6 +3334,12 @@ static int mov_read_header(AVFormatContext *s)
}
}
+ for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
+ if (mov->bitrates[i]) {
+ s->streams[i]->codec->bit_rate = mov->bitrates[i];
+ }
+ }
+
return 0;
}
@@ -3255,6 +3395,11 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
/* must be done just before reading, to avoid infinite loop on sample */
sc->current_sample++;
+ if (mov->next_root_atom) {
+ sample->pos = FFMIN(sample->pos, mov->next_root_atom);
+ sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
+ }
+
if (st->discard != AVDISCARD_ALL) {
if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
@@ -3387,7 +3532,7 @@ static const AVOption options[] = {
{NULL}
};
-static const AVClass class = {
+static const AVClass mov_class = {
.class_name = "mov,mp4,m4a,3gp,3g2,mj2",
.item_name = av_default_item_name,
.option = options,
@@ -3403,6 +3548,6 @@ AVInputFormat ff_mov_demuxer = {
.read_packet = mov_read_packet,
.read_close = mov_read_close,
.read_seek = mov_read_seek,
- .priv_class = &class,
+ .priv_class = &mov_class,
.flags = AVFMT_NO_BYTE_SEEK,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/movenc.c b/chromium/third_party/ffmpeg/libavformat/movenc.c
index 8f3b1bc57a3..13ffa24c2cb 100644
--- a/chromium/third_party/ffmpeg/libavformat/movenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/movenc.c
@@ -52,7 +52,7 @@ static const AVOption options[] = {
{ "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
- { "faststart", "Run a second pass to put the moov at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
{ "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
{ "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
@@ -62,6 +62,7 @@ static const AVOption options[] = {
{ "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
@@ -73,6 +74,8 @@ static const AVClass flavor ## _muxer_class = {\
.version = LIBAVUTIL_VERSION_INT,\
};
+static int get_moov_size(AVFormatContext *s);
+
//FIXME support 64 bit variant with wide placeholders
static int64_t update_size(AVIOContext *pb, int64_t pos)
{
@@ -86,20 +89,14 @@ static int64_t update_size(AVIOContext *pb, int64_t pos)
static int supports_edts(MOVMuxContext *mov)
{
- // EDTS with fragments is tricky as we dont know the duration when its written
+ // EDTS with fragments is tricky as we don't know the duration when its written
return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0;
}
-static int is_co64_required(const MOVTrack *track)
+static int co64_required(const MOVTrack *track)
{
- int i;
-
- for (i = 0; i < track->entry; i++) {
- if (!track->cluster[i].chunkNum)
- continue;
- if (track->cluster[i].pos + track->data_offset > UINT32_MAX)
- return 1;
- }
+ if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
+ return 1;
return 0;
}
@@ -107,7 +104,7 @@ static int is_co64_required(const MOVTrack *track)
static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
{
int i;
- int mode64 = is_co64_required(track); // use 32 bit size variant if possible
+ int mode64 = co64_required(track); // use 32 bit size variant if possible
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0); /* size */
if (mode64)
@@ -116,10 +113,10 @@ static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
ffio_wfourcc(pb, "stco");
avio_wb32(pb, 0); /* version & flags */
avio_wb32(pb, track->chunkCount); /* entry count */
- for (i=0; i<track->entry; i++) {
- if(!track->cluster[i].chunkNum)
+ for (i = 0; i < track->entry; i++) {
+ if (!track->cluster[i].chunkNum)
continue;
- if(mode64 == 1)
+ if (mode64 == 1)
avio_wb64(pb, track->cluster[i].pos + track->data_offset);
else
avio_wb32(pb, track->cluster[i].pos + track->data_offset);
@@ -138,27 +135,25 @@ static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
ffio_wfourcc(pb, "stsz");
avio_wb32(pb, 0); /* version & flags */
- for (i=0; i<track->entry; i++) {
- tst = track->cluster[i].size/track->cluster[i].entries;
- if(oldtst != -1 && tst != oldtst) {
+ for (i = 0; i < track->entry; i++) {
+ tst = track->cluster[i].size / track->cluster[i].entries;
+ if (oldtst != -1 && tst != oldtst)
equalChunks = 0;
- }
oldtst = tst;
entries += track->cluster[i].entries;
}
if (equalChunks && track->entry) {
- int sSize = track->entry ? track->cluster[0].size/track->cluster[0].entries : 0;
+ int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
avio_wb32(pb, sSize); // sample size
avio_wb32(pb, entries); // sample count
- }
- else {
+ } else {
avio_wb32(pb, 0); // sample size
avio_wb32(pb, entries); // sample count
- for (i=0; i<track->entry; i++) {
- for (j=0; j<track->cluster[i].entries; j++) {
+ for (i = 0; i < track->entry; i++) {
+ for (j = 0; j < track->cluster[i].entries; j++) {
avio_wb32(pb, track->cluster[i].size /
- track->cluster[i].entries);
+ track->cluster[i].entries);
}
}
}
@@ -177,9 +172,8 @@ static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, 0); // version & flags
entryPos = avio_tell(pb);
avio_wb32(pb, track->chunkCount); // entry count
- for (i=0; i<track->entry; i++) {
- if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum)
- {
+ for (i = 0; i < track->entry; i++) {
+ if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) {
avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
avio_wb32(pb, 0x1); // sample description index
@@ -206,9 +200,9 @@ static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
avio_wb32(pb, 0); // version & flags
entryPos = avio_tell(pb);
avio_wb32(pb, track->entry); // entry count
- for (i=0; i<track->entry; i++) {
+ for (i = 0; i < track->entry; i++) {
if (track->cluster[i].flags & flag) {
- avio_wb32(pb, i+1);
+ avio_wb32(pb, i + 1);
index++;
}
}
@@ -268,7 +262,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
put_bits(&pbc, 3, bsmod);
put_bits(&pbc, 3, acmod);
put_bits(&pbc, 1, lfeon);
- put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code
+ put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
put_bits(&pbc, 5, 0); // reserved
flush_put_bits(&pbc);
@@ -307,8 +301,8 @@ static void put_descr(AVIOContext *pb, int tag, unsigned int size)
{
int i = 3;
avio_w8(pb, tag);
- for(; i>0; i--)
- avio_w8(pb, (size>>(7*i)) | 0x80);
+ for (; i > 0; i--)
+ avio_w8(pb, (size >> (7 * i)) | 0x80);
avio_w8(pb, size & 0x7F);
}
@@ -351,7 +345,7 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
// the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
// plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
- if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+ if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
avio_w8(pb, 0x15); // flags (= Audiostream)
else
avio_w8(pb, 0x11); // flags (= Visualstream)
@@ -707,7 +701,7 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
avio_wb16(pb, 0); /* Reserved */
}
- if(version == 1) { /* SoundDescription V1 extended info */
+ if (version == 1) { /* SoundDescription V1 extended info */
if (mov_pcm_le_gt16(track->enc->codec_id) ||
mov_pcm_be_gt16(track->enc->codec_id))
avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
@@ -718,24 +712,24 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, 2); /* Bytes per sample */
}
- if(track->mode == MODE_MOV &&
- (track->enc->codec_id == AV_CODEC_ID_AAC ||
- track->enc->codec_id == AV_CODEC_ID_AC3 ||
- track->enc->codec_id == AV_CODEC_ID_AMR_NB ||
- track->enc->codec_id == AV_CODEC_ID_ALAC ||
- track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
- track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
- track->enc->codec_id == AV_CODEC_ID_QDM2 ||
- (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
- (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
+ if (track->mode == MODE_MOV &&
+ (track->enc->codec_id == AV_CODEC_ID_AAC ||
+ track->enc->codec_id == AV_CODEC_ID_AC3 ||
+ track->enc->codec_id == AV_CODEC_ID_AMR_NB ||
+ track->enc->codec_id == AV_CODEC_ID_ALAC ||
+ track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
+ track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
+ track->enc->codec_id == AV_CODEC_ID_QDM2 ||
+ (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
+ (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
mov_write_wave_tag(pb, track);
- else if(track->tag == MKTAG('m','p','4','a'))
+ else if (track->tag == MKTAG('m','p','4','a'))
mov_write_esds_tag(pb, track);
- else if(track->enc->codec_id == AV_CODEC_ID_AMR_NB)
+ else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB)
mov_write_amr_tag(pb, track);
- else if(track->enc->codec_id == AV_CODEC_ID_AC3)
+ else if (track->enc->codec_id == AV_CODEC_ID_AC3)
mov_write_ac3_tag(pb, track);
- else if(track->enc->codec_id == AV_CODEC_ID_ALAC)
+ else if (track->enc->codec_id == AV_CODEC_ID_ALAC)
mov_write_extradata_tag(pb, track);
else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
mov_write_wfex_tag(pb, track);
@@ -796,7 +790,7 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, track->enc->width);
/* values below are based on samples created with quicktime and avid codecs */
if (track->vos_data[5] & 2) { // interlaced
- avio_wb32(pb, track->enc->height/2);
+ avio_wb32(pb, track->enc->height / 2);
avio_wb32(pb, 2); /* unknown */
avio_wb32(pb, 0); /* unknown */
avio_wb32(pb, 4); /* unknown */
@@ -830,18 +824,18 @@ static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track)
else if (track->enc->codec_id == AV_CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c');
else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g');
else if (track->enc->codec_id == AV_CODEC_ID_VC1) tag = MKTAG('v','c','-','1');
- else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
- else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
+ else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
+ else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
return tag;
}
static const AVCodecTag codec_ipod_tags[] = {
- { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
- { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
- { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
- { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
- { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
+ { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
+ { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
+ { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
+ { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
+ { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
{ AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
{ AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
{ AV_CODEC_ID_NONE, 0 },
@@ -853,8 +847,8 @@ static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track)
// keep original tag for subs, ipod supports both formats
if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
- (tag == MKTAG('t','x','3','g') ||
- tag == MKTAG('t','e','x','t'))))
+ (tag == MKTAG('t', 'x', '3', 'g') ||
+ tag == MKTAG('t', 'e', 'x', 't'))))
tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v"))
@@ -871,16 +865,16 @@ static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
if (track->enc->width == 720) { /* SD */
if (track->enc->height == 480) { /* NTSC */
if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
- else tag = MKTAG('d','v','c',' ');
+ else tag = MKTAG('d','v','c',' ');
}else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
- else tag = MKTAG('d','v','p','p');
+ else tag = MKTAG('d','v','p','p');
} else if (track->enc->height == 720) { /* HD 720 line */
- if (track->enc->time_base.den == 50) tag = MKTAG('d','v','h','q');
- else tag = MKTAG('d','v','h','p');
+ if (track->enc->time_base.den == 50) tag = MKTAG('d','v','h','q');
+ else tag = MKTAG('d','v','h','p');
} else if (track->enc->height == 1080) { /* HD 1080 line */
- if (track->enc->time_base.den == 25) tag = MKTAG('d','v','h','5');
- else tag = MKTAG('d','v','h','6');
+ if (track->enc->time_base.den == 25) tag = MKTAG('d','v','h','5');
+ else tag = MKTAG('d','v','h','6');
} else {
av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
return 0;
@@ -967,12 +961,12 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
}
static const AVCodecTag codec_3gp_tags[] = {
- { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
- { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
- { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
- { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
- { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
- { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
+ { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
+ { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
+ { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
+ { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
+ { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
+ { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
{ AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
{ AV_CODEC_ID_NONE, 0 },
};
@@ -1083,7 +1077,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
avio_wb16(pb, 0); /* Codec stream revision (=0) */
if (track->mode == MODE_MOV) {
ffio_wfourcc(pb, "FFMP"); /* Vendor */
- if(track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
+ if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
avio_wb32(pb, 0); /* Temporal Quality */
avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
} else {
@@ -1104,7 +1098,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
/* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
- av_strlcpy(compressor_name,track->enc->codec->name,32);
+ av_strlcpy(compressor_name, track->enc->codec->name, 32);
avio_w8(pb, strlen(compressor_name));
avio_write(pb, compressor_name, 31);
@@ -1113,19 +1107,19 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
else
avio_wb16(pb, 0x18); /* Reserved */
avio_wb16(pb, 0xffff); /* Reserved */
- if(track->tag == MKTAG('m','p','4','v'))
+ if (track->tag == MKTAG('m','p','4','v'))
mov_write_esds_tag(pb, track);
- else if(track->enc->codec_id == AV_CODEC_ID_H263)
+ else if (track->enc->codec_id == AV_CODEC_ID_H263)
mov_write_d263_tag(pb);
- else if(track->enc->codec_id == AV_CODEC_ID_AVUI ||
+ else if (track->enc->codec_id == AV_CODEC_ID_AVUI ||
track->enc->codec_id == AV_CODEC_ID_SVQ3) {
mov_write_extradata_tag(pb, track);
avio_wb32(pb, 0);
- } else if(track->enc->codec_id == AV_CODEC_ID_DNXHD)
+ } else if (track->enc->codec_id == AV_CODEC_ID_DNXHD)
mov_write_avid_tag(pb, track);
- else if(track->enc->codec_id == AV_CODEC_ID_H264) {
+ else if (track->enc->codec_id == AV_CODEC_ID_H264) {
mov_write_avcc_tag(pb, track);
- if(track->mode == MODE_IPOD)
+ if (track->mode == MODE_IPOD)
mov_write_uuid_tag_ipod(pb);
} else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
mov_write_dvc1_tag(pb, track);
@@ -1221,7 +1215,7 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
ctts_entries[0].count = 1;
ctts_entries[0].duration = track->cluster[0].cts;
- for (i=1; i<track->entry; i++) {
+ for (i = 1; i < track->entry; i++) {
if (track->cluster[i].cts == ctts_entries[entries].duration) {
ctts_entries[entries].count++; /* compress */
} else {
@@ -1236,7 +1230,7 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
ffio_wfourcc(pb, "ctts");
avio_wb32(pb, 0); /* version & flags */
avio_wb32(pb, entries); /* entry count */
- for (i=0; i<entries; i++) {
+ for (i = 0; i < entries; i++) {
avio_wb32(pb, ctts_entries[i].count);
avio_wb32(pb, ctts_entries[i].duration);
}
@@ -1261,7 +1255,7 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
stts_entries = track->entry ?
av_malloc(track->entry * sizeof(*stts_entries)) : /* worst case */
NULL;
- for (i=0; i<track->entry; i++) {
+ for (i = 0; i < track->entry; i++) {
int duration = get_cluster_duration(track, i);
if (i && duration == stts_entries[entries].duration) {
stts_entries[entries].count++; /* compress */
@@ -1278,7 +1272,7 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
ffio_wfourcc(pb, "stts");
avio_wb32(pb, 0); /* version & flags */
avio_wb32(pb, entries); /* entry count */
- for (i=0; i<entries; i++) {
+ for (i = 0; i < entries; i++) {
avio_wb32(pb, stts_entries[i].count);
avio_wb32(pb, stts_entries[i].duration);
}
@@ -1432,18 +1426,18 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
const char *hdlr, *descr = NULL, *hdlr_type = NULL;
int64_t pos = avio_tell(pb);
- if (!track) { /* no media --> data handler */
- hdlr = "dhlr";
- hdlr_type = "url ";
- descr = "DataHandler";
- } else {
+ hdlr = "dhlr";
+ hdlr_type = "url ";
+ descr = "DataHandler";
+
+ if (track) {
hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
hdlr_type = "vide";
- descr = "VideoHandler";
+ descr = "VideoHandler";
} else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
hdlr_type = "soun";
- descr = "SoundHandler";
+ descr = "SoundHandler";
} else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
if (track->tag == MKTAG('c','6','0','8')) {
hdlr_type = "clcp";
@@ -1453,16 +1447,20 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
else hdlr_type = "text";
descr = "SubtitleHandler";
}
+ } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
+ hdlr_type = "hint";
+ descr = "HintHandler";
} else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
hdlr_type = "tmcd";
descr = "TimeCodeHandler";
- } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
- hdlr_type = "hint";
- descr = "HintHandler";
} else {
- hdlr = "dhlr";
- hdlr_type = "url ";
- descr = "DataHandler";
+ char tag_buf[32];
+ av_get_codec_tag_string(tag_buf, sizeof(tag_buf),
+ track->enc->codec_tag);
+
+ av_log(track->enc, AV_LOG_WARNING,
+ "Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
+ tag_buf, track->enc->codec_tag);
}
}
@@ -1471,9 +1469,9 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, 0); /* Version & flags */
avio_write(pb, hdlr, 4); /* handler */
ffio_wfourcc(pb, hdlr_type); /* handler type */
- avio_wb32(pb ,0); /* reserved */
- avio_wb32(pb ,0); /* reserved */
- avio_wb32(pb ,0); /* reserved */
+ avio_wb32(pb, 0); /* reserved */
+ avio_wb32(pb, 0); /* reserved */
+ avio_wb32(pb, 0); /* reserved */
if (!track || track->mode == MODE_MOV)
avio_w8(pb, strlen(descr)); /* pascal string */
avio_write(pb, descr, strlen(descr)); /* handler description */
@@ -1502,7 +1500,7 @@ static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0); /* size */
ffio_wfourcc(pb, "minf");
- if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
+ if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
mov_write_vmhd_tag(pb);
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
mov_write_smhd_tag(pb);
@@ -1550,11 +1548,11 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
avio_wb16(pb, track->language); /* language */
avio_wb16(pb, 0); /* reserved (quality) */
- if(version!=0 && track->mode == MODE_MOV){
+ if (version != 0 && track->mode == MODE_MOV) {
av_log(NULL, AV_LOG_ERROR,
- "FATAL error, file duration too long for timebase, this file will not be\n"
- "playable with quicktime. Choose a different timebase or a different\n"
- "container format\n");
+ "FATAL error, file duration too long for timebase, this file will not be\n"
+ "playable with quicktime. Choose a different timebase or a different\n"
+ "container format\n");
}
return 32;
@@ -1622,7 +1620,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
avio_wb16(pb, 0); /* layer */
avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
/* Volume, only for audio */
- if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+ if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
avio_wb16(pb, 0x0100);
else
avio_wb16(pb, 0);
@@ -1643,20 +1641,19 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
write_matrix(pb, 1, 0, 0, 1, 0, 0);
}
/* Track width and height, for visual only */
- if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
- track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
- if(track->mode == MODE_MOV) {
+ if (st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
+ track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
+ if (track->mode == MODE_MOV) {
avio_wb32(pb, track->enc->width << 16);
avio_wb32(pb, track->height << 16);
} else {
double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
- if(!sample_aspect_ratio || track->height != track->enc->height)
+ if (!sample_aspect_ratio || track->height != track->enc->height)
sample_aspect_ratio = 1;
- avio_wb32(pb, sample_aspect_ratio * track->enc->width*0x10000);
- avio_wb32(pb, track->height*0x10000);
+ avio_wb32(pb, sample_aspect_ratio * track->enc->width * 0x10000);
+ avio_wb32(pb, track->height * 0x10000);
}
- }
- else {
+ } else {
avio_wb32(pb, 0);
avio_wb32(pb, 0);
}
@@ -1777,7 +1774,6 @@ static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
{
-
AVFormatContext *ctx = track->rtp_ctx;
char buf[1000] = "";
int len;
@@ -1810,14 +1806,14 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_tref_tag(pb, track);
mov_write_mdia_tag(pb, track);
if (track->mode == MODE_PSP)
- mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box
+ mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
if (track->tag == MKTAG('r','t','p',' '))
mov_write_udta_sdp(pb, track);
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio)
mov_write_tapt_tag(pb, track);
- };
+ }
return update_size(pb, pos);
}
@@ -1828,7 +1824,7 @@ static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
int audio_profile = mov->iods_audio_profile;
int video_profile = mov->iods_video_profile;
for (i = 0; i < mov->nb_streams; i++) {
- if(mov->tracks[i].entry > 0) {
+ if (mov->tracks[i].entry > 0) {
has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
}
@@ -1880,8 +1876,8 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
int64_t max_track_len_temp, max_track_len = 0;
int version;
- for (i=0; i<mov->nb_streams; i++) {
- if(mov->tracks[i].entry > 0) {
+ for (i = 0; i < mov->nb_streams; i++) {
+ if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,
MOV_TIMESCALE,
mov->tracks[i].timescale,
@@ -1945,7 +1941,7 @@ static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov,
/* helper function to write a data tag with the specified string as data */
static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
{
- if(long_style){
+ if (long_style) {
int size = 16 + strlen(data);
avio_wb32(pb, size); /* size */
ffio_wfourcc(pb, "data");
@@ -1953,7 +1949,7 @@ static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang
avio_wb32(pb, 0);
avio_write(pb, data, strlen(data));
return size;
- }else{
+ } else {
if (!lang)
lang = ff_mov_iso639_to_lang("und", 1);
avio_wb16(pb, strlen(data)); /* string length */
@@ -1963,7 +1959,9 @@ static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang
}
}
-static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style){
+static int mov_write_string_tag(AVIOContext *pb, const char *name,
+ const char *value, int lang, int long_style)
+{
int size = 0;
if (value && value[0]) {
int64_t pos = avio_tell(pb);
@@ -1990,8 +1988,8 @@ static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
snprintf(tag2, sizeof(tag2), "%s-", tag);
while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
len2 = strlen(t2->key);
- if (len2 == len+4 && !strcmp(t->value, t2->value)
- && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) {
+ if (len2 == len + 4 && !strcmp(t->value, t2->value)
+ && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
lang = l;
break;
}
@@ -2017,23 +2015,29 @@ static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
return size;
}
-/* iTunes track number */
+/* iTunes track or disc number */
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
- AVFormatContext *s)
+ AVFormatContext *s, int disc)
{
- AVDictionaryEntry *t = av_dict_get(s->metadata, "track", NULL, 0);
+ AVDictionaryEntry *t = av_dict_get(s->metadata,
+ disc ? "disc" : "track",
+ NULL, 0);
int size = 0, track = t ? atoi(t->value) : 0;
if (track) {
+ int tracks = 0;
+ char *slash = strchr(t->value, '/');
+ if (slash)
+ tracks = atoi(slash + 1);
avio_wb32(pb, 32); /* size */
- ffio_wfourcc(pb, "trkn");
- avio_wb32(pb, 24); /* size */
- ffio_wfourcc(pb, "data");
- avio_wb32(pb, 0); // 8 bytes empty
- avio_wb32(pb, 0);
- avio_wb16(pb, 0); // empty
- avio_wb16(pb, track); // track number
- avio_wb16(pb, 0); // total track number
- avio_wb16(pb, 0); // empty
+ ffio_wfourcc(pb, disc ? "disk" : "trkn");
+ avio_wb32(pb, 24); /* size */
+ ffio_wfourcc(pb, "data");
+ avio_wb32(pb, 0); // 8 bytes empty
+ avio_wb32(pb, 0);
+ avio_wb16(pb, 0); // empty
+ avio_wb16(pb, track); // track / disc number
+ avio_wb16(pb, tracks); // total track / disc number
+ avio_wb16(pb, 0); // empty
size = 32;
}
return size;
@@ -2045,16 +2049,25 @@ static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb,
{
AVDictionaryEntry *t = NULL;
uint8_t num;
+ int size = 24 + len;
+
+ if (len != 1 && len != 4)
+ return -1;
if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
return 0;
num = atoi(t->value);
- avio_wb32(pb, len+8);
+ avio_wb32(pb, size);
ffio_wfourcc(pb, name);
+ avio_wb32(pb, size - 8);
+ ffio_wfourcc(pb, "data");
+ avio_wb32(pb, 0x15);
+ avio_wb32(pb, 0);
if (len==4) avio_wb32(pb, num);
else avio_w8 (pb, num);
- return len+8;
+
+ return size;
}
/* iTunes meta data list */
@@ -2086,7 +2099,8 @@ static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_int8_metadata (s, pb, "stik", "media_type",1);
mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
- mov_write_trkn_tag(pb, mov, s);
+ mov_write_trkn_tag(pb, mov, s, 0); // track number
+ mov_write_trkn_tag(pb, mov, s, 1); // disc number
mov_write_tmpo_tag(pb, s);
return update_size(pb, pos);
}
@@ -2108,9 +2122,9 @@ static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov,
static int utf8len(const uint8_t *b)
{
- int len=0;
+ int len = 0;
int val;
- while(*b){
+ while (*b) {
GET_UTF8(val, *b++, return -1;)
len++;
}
@@ -2120,7 +2134,7 @@ static int utf8len(const uint8_t *b)
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
{
int val;
- while(*b){
+ while (*b) {
GET_UTF8(val, *b++, return -1;)
avio_wb16(pb, val);
}
@@ -2130,7 +2144,9 @@ static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
static uint16_t language_code(const char *str)
{
- return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
+ return (((str[0] - 0x60) & 0x1F) << 10) +
+ (((str[1] - 0x60) & 0x1F) << 5) +
+ (( str[2] - 0x60) & 0x1F);
}
static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
@@ -2147,7 +2163,7 @@ static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
avio_wb16(pb, atoi(t->value));
else {
avio_wb16(pb, language_code("eng")); /* language */
- avio_write(pb, t->value, strlen(t->value)+1); /* UTF8 string value */
+ avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
if (!strcmp(tag, "albm") &&
(t = av_dict_get(s->metadata, "track", NULL, 0)))
avio_w8(pb, atoi(t->value));
@@ -2194,7 +2210,7 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
}
ret = avio_open_dyn_buf(&pb_buf);
- if(ret < 0)
+ if (ret < 0)
return ret;
if (mov->mode & MODE_3GP) {
@@ -2207,18 +2223,18 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
} else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
- mov_write_string_metadata(s, pb_buf, "\251ART", "artist" , 0);
- mov_write_string_metadata(s, pb_buf, "\251nam", "title" , 0);
- mov_write_string_metadata(s, pb_buf, "\251aut", "author" , 0);
- mov_write_string_metadata(s, pb_buf, "\251alb", "album" , 0);
- mov_write_string_metadata(s, pb_buf, "\251day", "date" , 0);
- mov_write_string_metadata(s, pb_buf, "\251swr", "encoder" , 0);
+ mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
+ mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
+ mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
+ mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
+ mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
+ mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
// currently ignored by mov.c
- mov_write_string_metadata(s, pb_buf, "\251des", "comment" , 0);
+ mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
// add support for libquicktime, this atom is also actually read by mov.c
- mov_write_string_metadata(s, pb_buf, "\251cmt", "comment" , 0);
- mov_write_string_metadata(s, pb_buf, "\251gen", "genre" , 0);
- mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright" , 0);
+ mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
+ mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
+ mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
} else {
/* iTunes meta data */
mov_write_meta_tag(pb_buf, mov, s);
@@ -2228,7 +2244,7 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_chpl_tag(pb_buf, s);
if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
- avio_wb32(pb, size+8);
+ avio_wb32(pb, size + 8);
ffio_wfourcc(pb, "udta");
avio_write(pb, buf, size);
}
@@ -2238,12 +2254,12 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
}
static void mov_write_psp_udta_tag(AVIOContext *pb,
- const char *str, const char *lang, int type)
+ const char *str, const char *lang, int type)
{
- int len = utf8len(str)+1;
- if(len<=0)
+ int len = utf8len(str) + 1;
+ if (len <= 0)
return;
- avio_wb16(pb, len*2+10); /* size */
+ avio_wb16(pb, len * 2 + 10); /* size */
avio_wb32(pb, type); /* type */
avio_wb16(pb, language_code(lang)); /* language */
avio_wb16(pb, 0x01); /* ? */
@@ -2290,18 +2306,18 @@ static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
static void build_chunks(MOVTrack *trk)
{
int i;
- MOVIentry *chunk= &trk->cluster[0];
+ MOVIentry *chunk = &trk->cluster[0];
uint64_t chunkSize = chunk->size;
- chunk->chunkNum= 1;
+ chunk->chunkNum = 1;
if (trk->chunkCount)
return;
- trk->chunkCount= 1;
- for(i=1; i<trk->entry; i++){
- if(chunk->pos + chunkSize == trk->cluster[i].pos &&
+ trk->chunkCount = 1;
+ for (i = 1; i<trk->entry; i++){
+ if (chunk->pos + chunkSize == trk->cluster[i].pos &&
chunkSize + trk->cluster[i].size < (1<<20)){
chunkSize += trk->cluster[i].size;
chunk->samples_in_chunk += trk->cluster[i].entries;
- }else{
+ } else {
trk->cluster[i].chunkNum = chunk->chunkNum+1;
chunk=&trk->cluster[i];
chunkSize = chunk->size;
@@ -2319,21 +2335,21 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
avio_wb32(pb, 0); /* size placeholder*/
ffio_wfourcc(pb, "moov");
- for (i=0; i<mov->nb_streams; i++) {
+ for (i = 0; i < mov->nb_streams; i++) {
if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
continue;
- mov->tracks[i].time = mov->time;
- mov->tracks[i].track_id = i+1;
+ mov->tracks[i].time = mov->time;
+ mov->tracks[i].track_id = i + 1;
if (mov->tracks[i].entry)
build_chunks(&mov->tracks[i]);
}
if (mov->chapter_track)
- for (i=0; i<s->nb_streams; i++) {
+ for (i = 0; i < s->nb_streams; i++) {
mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
- mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
+ mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
}
for (i = 0; i < mov->nb_streams; i++) {
if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
@@ -2354,11 +2370,11 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_mvhd_tag(pb, mov);
if (mov->mode != MODE_MOV && !mov->iods_skip)
mov_write_iods_tag(pb, mov);
- for (i=0; i<mov->nb_streams; i++) {
+ for (i = 0; i < mov->nb_streams; i++) {
if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
- if(i < s->nb_streams){
+ if (i < s->nb_streams){
int codec_type= s->streams[i]->codec->codec_type;
- if(codec_type==AVMEDIA_TYPE_AUDIO || codec_type==AVMEDIA_TYPE_SUBTITLE){
+ if (codec_type==AVMEDIA_TYPE_AUDIO || codec_type==AVMEDIA_TYPE_SUBTITLE){
mov->tracks[i].secondary= not_first[codec_type];
not_first[codec_type]= 1;
}
@@ -2390,9 +2406,9 @@ static void param_write_string(AVIOContext *pb, const char *name, const char *va
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
{
char buf[150];
- len = FFMIN(sizeof(buf)/2 - 1, len);
+ len = FFMIN(sizeof(buf) / 2 - 1, len);
ff_data_to_hex(buf, value, len, 0);
- buf[2*len] = '\0';
+ buf[2 * len] = '\0';
avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
}
@@ -2400,7 +2416,7 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
{
int64_t pos = avio_tell(pb);
int i;
- const uint8_t uuid[] = {
+ static const uint8_t uuid[] = {
0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
};
@@ -2466,7 +2482,7 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
track->enc->extradata_size);
param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
- track->enc->codec_id));
+ track->enc->codec_id));
param_write_int(pb, "Channels", track->enc->channels);
param_write_int(pb, "SamplingRate", track->enc->sample_rate);
param_write_int(pb, "BitsPerSample", 16);
@@ -2505,9 +2521,11 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
/* Don't set a default sample size, the silverlight player refuses
* to play files with that set. Don't set a default sample duration,
- * WMP freaks out if it is set. */
+ * WMP freaks out if it is set. Don't set a base data offset, PIFF
+ * file format says it MUST NOT be set. */
if (track->mode == MODE_ISM)
- flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION);
+ flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
+ MOV_TFHD_BASE_DATA_OFFSET);
avio_wb32(pb, 0); /* size placeholder */
ffio_wfourcc(pb, "tfhd");
@@ -2591,7 +2609,7 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
- const uint8_t uuid[] = {
+ static const uint8_t uuid[] = {
0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
};
@@ -2613,7 +2631,7 @@ static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
{
int n = track->nb_frag_info - 1 - entry, i;
int size = 8 + 16 + 4 + 1 + 16*n;
- const uint8_t uuid[] = {
+ static const uint8_t uuid[] = {
0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
};
@@ -2634,11 +2652,10 @@ static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
avio_wb64(pb, track->frag_info[index].duration);
}
if (n < mov->ism_lookahead) {
- int free_size = 16*(mov->ism_lookahead - n);
+ int free_size = 16 * (mov->ism_lookahead - n);
avio_wb32(pb, free_size);
ffio_wfourcc(pb, "free");
- for (i = 0; i < free_size - 8; i++)
- avio_w8(pb, 0);
+ ffio_fill(pb, 0, free_size - 8);
}
return 0;
@@ -2671,7 +2688,7 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
mov_write_tfxd_tag(pb, track);
if (mov->ism_lookahead) {
- int i, size = 16 + 4 + 1 + 16*mov->ism_lookahead;
+ int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
track->tfrf_offset = avio_tell(pb);
avio_wb32(pb, 8 + size);
@@ -2805,7 +2822,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
} else if (mov->mode & MODE_3G2) {
ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
minor = has_h264 ? 0x20000 : 0x10000;
- }else if (mov->mode == MODE_PSP)
+ } else if (mov->mode == MODE_PSP)
ffio_wfourcc(pb, "MSNV");
else if (mov->mode == MODE_MP4)
ffio_wfourcc(pb, "isom");
@@ -2820,7 +2837,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
avio_wb32(pb, minor);
- if(mov->mode == MODE_MOV)
+ if (mov->mode == MODE_MOV)
ffio_wfourcc(pb, "qt ");
else if (mov->mode == MODE_ISM) {
ffio_wfourcc(pb, "piff");
@@ -2828,7 +2845,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
} else {
ffio_wfourcc(pb, "isom");
ffio_wfourcc(pb, "iso2");
- if(has_h264)
+ if (has_h264)
ffio_wfourcc(pb, "avc1");
}
@@ -2848,7 +2865,7 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
AVCodecContext *video_codec = s->streams[0]->codec;
AVCodecContext *audio_codec = s->streams[1]->codec;
int audio_rate = audio_codec->sample_rate;
- int frame_rate = ((video_codec->time_base.den) * (0x10000))/ (video_codec->time_base.num);
+ int frame_rate = ((video_codec->time_base.den) * (0x10000)) / (video_codec->time_base.num);
int audio_kbitrate = audio_codec->bit_rate / 1000;
int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
@@ -2870,7 +2887,7 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
avio_wb32(pb, 0x0); /* ? */
avio_wb32(pb, 0x2c); /* size */
- ffio_wfourcc(pb, "APRF");/* audio */
+ ffio_wfourcc(pb, "APRF"); /* audio */
avio_wb32(pb, 0x0);
avio_wb32(pb, 0x2); /* TrackID */
ffio_wfourcc(pb, "mp4a");
@@ -2910,11 +2927,11 @@ static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
int i, closed_gop = 0;
for (i = 0; i < pkt->size - 4; i++) {
- c = (c<<8) + pkt->data[i];
+ c = (c << 8) + pkt->data[i];
if (c == 0x1b8) { // gop
- closed_gop = pkt->data[i+4]>>6 & 0x01;
+ closed_gop = pkt->data[i + 4] >> 6 & 0x01;
} else if (c == 0x100) { // pic
- int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
+ int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
if (!temp_ref || closed_gop) // I picture is not reordered
*flags = MOV_SYNC_SAMPLE;
else
@@ -2982,21 +2999,6 @@ static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk, int fragment)
}
}
-static int get_moov_size(AVFormatContext *s)
-{
- int ret;
- uint8_t *buf;
- AVIOContext *moov_buf;
- MOVMuxContext *mov = s->priv_data;
-
- if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
- return ret;
- mov_write_moov_tag(moov_buf, mov, s);
- ret = avio_close_dyn_buf(moov_buf, &buf);
- av_free(buf);
- return ret;
-}
-
static int mov_flush_fragment(AVFormatContext *s)
{
MOVMuxContext *mov = s->priv_data;
@@ -3082,9 +3084,14 @@ static int mov_flush_fragment(AVFormatContext *s)
MOVFragmentInfo *info;
avio_flush(s->pb);
track->nb_frag_info++;
- track->frag_info = av_realloc(track->frag_info,
- sizeof(*track->frag_info) *
- track->nb_frag_info);
+ if (track->nb_frag_info >= track->frag_info_capacity) {
+ unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
+ if (av_reallocp_array(&track->frag_info,
+ new_capacity,
+ sizeof(*track->frag_info)))
+ return AVERROR(ENOMEM);
+ track->frag_info_capacity = new_capacity;
+ }
info = &track->frag_info[track->nb_frag_info - 1];
info->offset = avio_tell(s->pb);
info->time = mov->tracks[i].frag_start;
@@ -3124,7 +3131,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
MOVTrack *trk = &mov->tracks[pkt->stream_index];
AVCodecContext *enc = trk->enc;
unsigned int samples_in_chunk = 0;
- int size= pkt->size;
+ int size = pkt->size;
uint8_t *reformatted_data = NULL;
if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
@@ -3168,7 +3175,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
/* copy extradata if it exists */
if (trk->vos_len == 0 && enc->extradata_size > 0) {
- trk->vos_len = enc->extradata_size;
+ trk->vos_len = enc->extradata_size;
trk->vos_data = av_malloc(trk->vos_len);
memcpy(trk->vos_data, enc->extradata, trk->vos_len);
}
@@ -3176,7 +3183,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
- av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
+ av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
+ "use audio bitstream filter 'aac_adtstoasc' to fix it "
+ "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
return -1;
}
av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
@@ -3198,25 +3207,27 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if ((enc->codec_id == AV_CODEC_ID_DNXHD ||
enc->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
/* copy frame to create needed atoms */
- trk->vos_len = size;
+ trk->vos_len = size;
trk->vos_data = av_malloc(size);
if (!trk->vos_data)
return AVERROR(ENOMEM);
memcpy(trk->vos_data, pkt->data, size);
}
- if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
- trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE));
- if (!trk->cluster)
- return -1;
+ if (trk->entry >= trk->cluster_capacity) {
+ unsigned new_capacity = 2 * (trk->entry + MOV_INDEX_CLUSTER_SIZE);
+ if (av_reallocp_array(&trk->cluster, new_capacity,
+ sizeof(*trk->cluster)))
+ return AVERROR(ENOMEM);
+ trk->cluster_capacity = new_capacity;
}
- trk->cluster[trk->entry].pos = avio_tell(pb) - size;
+ trk->cluster[trk->entry].pos = avio_tell(pb) - size;
trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
- trk->cluster[trk->entry].chunkNum = 0;
- trk->cluster[trk->entry].size = size;
- trk->cluster[trk->entry].entries = samples_in_chunk;
- trk->cluster[trk->entry].dts = pkt->dts;
+ trk->cluster[trk->entry].chunkNum = 0;
+ trk->cluster[trk->entry].size = size;
+ trk->cluster[trk->entry].entries = samples_in_chunk;
+ trk->cluster[trk->entry].dts = pkt->dts;
if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
/* First packet of a new fragment. We already wrote the duration
* of the last packet of the previous fragment based on track_duration,
@@ -3238,7 +3249,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (pkt->dts != pkt->pts)
trk->flags |= MOV_TRACK_CTTS;
- trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
+ trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
trk->cluster[trk->entry].flags = 0;
if (enc->codec_id == AV_CODEC_ID_VC1) {
mov_parse_vc1_frame(pkt, trk, mov->fragments);
@@ -3256,7 +3267,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
}
trk->entry++;
trk->sample_count += samples_in_chunk;
- mov->mdat_size += size;
+ mov->mdat_size += size;
avio_flush(pb);
@@ -3275,7 +3286,8 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
int64_t frag_duration = 0;
int size = pkt->size;
- if (!pkt->size) return 0; /* Discard 0 sized packets */
+ if (!pkt->size)
+ return 0; /* Discard 0 sized packets */
if (trk->entry && pkt->stream_index < s->nb_streams)
frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
@@ -3364,7 +3376,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
// QuickTime chapters involve an additional text track with the chapter names
// as samples, and a tref pointing from the other tracks to the chapter one.
-static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
+static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
{
AVIOContext *pb;
@@ -3372,13 +3384,21 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
MOVTrack *track = &mov->tracks[tracknum];
AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
int i, len;
+ // These properties are required to make QT recognize the chapter track
+ uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
track->mode = mov->mode;
track->tag = MKTAG('t','e','x','t');
track->timescale = MOV_TIMESCALE;
track->enc = avcodec_alloc_context3(NULL);
track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
-
+#if 0
+ track->enc->extradata = av_malloc(sizeof(chapter_properties));
+ if (track->enc->extradata == NULL)
+ return AVERROR(ENOMEM);
+ track->enc->extradata_size = sizeof(chapter_properties);
+ memcpy(track->enc->extradata, chapter_properties, sizeof(chapter_properties));
+#else
if (avio_open_dyn_buf(&pb) >= 0) {
int size;
uint8_t *buf;
@@ -3422,6 +3442,7 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
av_free(&buf);
}
}
+#endif
for (i = 0; i < s->nb_chapters; i++) {
AVChapter *c = s->chapters[i];
@@ -3432,15 +3453,17 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
pkt.duration = end - pkt.dts;
if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
- len = strlen(t->value);
- pkt.size = len+2;
+ len = strlen(t->value);
+ pkt.size = len + 2;
pkt.data = av_malloc(pkt.size);
AV_WB16(pkt.data, len);
- memcpy(pkt.data+2, t->value, len);
+ memcpy(pkt.data + 2, t->value, len);
ff_mov_write_packet(s, &pkt);
av_freep(&pkt.data);
}
}
+
+ return 0;
}
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr)
@@ -3504,7 +3527,8 @@ static int mov_write_header(AVFormatContext *s)
/* faststart: moov at the beginning of the file, if supported */
if (mov->flags & FF_MOV_FLAG_FASTSTART) {
- if (mov->flags & FF_MOV_FLAG_FRAGMENT)
+ if ((mov->flags & FF_MOV_FLAG_FRAGMENT) ||
+ (s->flags & AVFMT_FLAG_CUSTOM_IO))
mov->flags &= ~FF_MOV_FLAG_FASTSTART;
else
mov->reserved_moov_size = -1;
@@ -3518,7 +3542,7 @@ static int mov_write_header(AVFormatContext *s)
* is enabled, we don't support non-seekable output at all. */
if (!s->pb->seekable &&
((!(mov->flags & FF_MOV_FLAG_FRAGMENT) &&
- !(s->oformat && !strcmp(s->oformat->name, "ismv")))
+ strcmp(s->oformat->name, "ismv"))
|| mov->ism_lookahead)) {
av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
return -1;
@@ -3527,27 +3551,36 @@ static int mov_write_header(AVFormatContext *s)
/* Default mode == MP4 */
mov->mode = MODE_MP4;
- if (s->oformat != NULL) {
- if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
- else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
- else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
- else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
- else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
- else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
- else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
-
- mov_write_ftyp_tag(pb,s);
- if (mov->mode == MODE_PSP) {
- if (s->nb_streams != 2) {
- av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
- return -1;
+ if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
+ else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
+ else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
+ else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
+ else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
+ else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
+ else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
+
+ mov_write_ftyp_tag(pb,s);
+ if (mov->mode == MODE_PSP) {
+ int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ video_streams_nb++;
+ else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ audio_streams_nb++;
+ else
+ other_streams_nb++;
}
- mov_write_uuidprof_tag(pb,s);
+
+ if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
+ av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
+ return -1;
}
+ mov_write_uuidprof_tag(pb, s);
}
mov->nb_streams = s->nb_streams;
- if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
+ if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
mov->chapter_track = mov->nb_streams++;
if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
@@ -3588,11 +3621,13 @@ static int mov_write_header(AVFormatContext *s)
mov->nb_streams += mov->nb_meta_tmcd;
}
- mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
+ // Reserve an extra stream for chapters for the case where chapters
+ // are written in the trailer
+ mov->tracks = av_mallocz((mov->nb_streams + 1) * sizeof(*mov->tracks));
if (!mov->tracks)
return AVERROR(ENOMEM);
- for(i=0; i<s->nb_streams; i++){
+ for (i = 0; i < s->nb_streams; i++) {
AVStream *st= s->streams[i];
MOVTrack *track= &mov->tracks[i];
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
@@ -3602,7 +3637,7 @@ static int mov_write_header(AVFormatContext *s)
if (track->language < 0)
track->language = 0;
track->mode = mov->mode;
- track->tag = mov_find_codec_tag(s, track);
+ track->tag = mov_find_codec_tag(s, track);
if (!track->tag) {
av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
"codec not currently supported in container\n", i);
@@ -3611,8 +3646,8 @@ static int mov_write_header(AVFormatContext *s)
/* If hinting of this track is enabled by a later hint track,
* this is updated. */
track->hint_track = -1;
- track->start_dts = AV_NOPTS_VALUE;
- if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
+ track->start_dts = AV_NOPTS_VALUE;
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
@@ -3620,22 +3655,26 @@ static int mov_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
goto error;
}
- track->height = track->tag>>24 == 'n' ? 486 : 576;
+ track->height = track->tag >> 24 == 'n' ? 486 : 576;
+ }
+ if (mov->video_track_timescale) {
+ track->timescale = mov->video_track_timescale;
+ } else {
+ track->timescale = st->codec->time_base.den;
+ while(track->timescale < 10000)
+ track->timescale *= 2;
}
- track->timescale = st->codec->time_base.den;
- while(track->timescale < 10000)
- track->timescale *= 2;
if (track->mode == MODE_MOV && track->timescale > 100000)
av_log(s, AV_LOG_WARNING,
"WARNING codec timebase is very high. If duration is too long,\n"
"file may not be playable by quicktime. Specify a shorter timebase\n"
"or choose different container.\n");
- }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
track->timescale = st->codec->sample_rate;
- if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
+ if (!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
track->audio_vbr = 1;
- }else if(st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
+ }else if (st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
st->codec->codec_id == AV_CODEC_ID_ILBC){
if (!st->codec->block_align) {
@@ -3643,20 +3682,25 @@ static int mov_write_header(AVFormatContext *s)
goto error;
}
track->sample_size = st->codec->block_align;
- }else if(st->codec->frame_size > 1){ /* assume compressed audio */
+ }else if (st->codec->frame_size > 1){ /* assume compressed audio */
track->audio_vbr = 1;
}else{
track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
}
+ if (st->codec->codec_id == AV_CODEC_ID_ILBC) {
+ track->audio_vbr = 1;
+ }
if (track->mode != MODE_MOV &&
track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n",
i, track->enc->sample_rate);
goto error;
}
- }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
track->timescale = st->codec->time_base.den;
- }else{
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
+ track->timescale = st->codec->time_base.den;
+ } else {
track->timescale = MOV_TIMESCALE;
}
if (!track->height)
@@ -3686,14 +3730,17 @@ static int mov_write_header(AVFormatContext *s)
FF_MOV_FLAG_FRAGMENT;
}
- if(mov->reserved_moov_size){
+ if (mov->reserved_moov_size){
mov->reserved_moov_pos= avio_tell(pb);
if (mov->reserved_moov_size > 0)
avio_skip(pb, mov->reserved_moov_size);
}
- if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
+ if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+ if (mov->flags & FF_MOV_FLAG_FASTSTART)
+ mov->reserved_moov_pos = avio_tell(pb);
mov_write_mdat_tag(pb, mov);
+ }
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
mov->time = ff_iso8601_to_unix_time(t->value);
@@ -3709,7 +3756,8 @@ static int mov_write_header(AVFormatContext *s)
AVStream *st = s->streams[i];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- ff_mov_init_hinting(s, hint_track, i);
+ if (ff_mov_init_hinting(s, hint_track, i) < 0)
+ goto error;
hint_track++;
}
}
@@ -3749,11 +3797,26 @@ static int mov_write_header(AVFormatContext *s)
return -1;
}
-/**
+static int get_moov_size(AVFormatContext *s)
+{
+ int ret;
+ uint8_t *buf;
+ AVIOContext *moov_buf;
+ MOVMuxContext *mov = s->priv_data;
+
+ if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
+ return ret;
+ mov_write_moov_tag(moov_buf, mov, s);
+ ret = avio_close_dyn_buf(moov_buf, &buf);
+ av_free(buf);
+ return ret;
+}
+
+/*
* This function gets the moov size if moved to the top of the file: the chunk
* offset table can switch between stco (32-bit entries) to co64 (64-bit
- * entries) when the moov is moved to the top, so the size of the moov would
- * change. It also updates the chunk offset tables.
+ * entries) when the moov is moved to the beginning, so the size of the moov
+ * would change. It also updates the chunk offset tables.
*/
static int compute_moov_size(AVFormatContext *s)
{
@@ -3771,7 +3834,7 @@ static int compute_moov_size(AVFormatContext *s)
if (moov_size2 < 0)
return moov_size2;
- /* if the size changed, we just switched from stco to co64 and needs to
+ /* if the size changed, we just switched from stco to co64 and need to
* update the offsets */
if (moov_size2 != moov_size)
for (i = 0; i < mov->nb_streams; i++)
@@ -3847,9 +3910,9 @@ static int mov_write_trailer(AVFormatContext *s)
{
MOVMuxContext *mov = s->priv_data;
AVIOContext *pb = s->pb;
- int64_t moov_pos;
int res = 0;
int i;
+ int64_t moov_pos;
/*
* Before actually writing the trailer, make sure that there are no
@@ -3864,9 +3927,19 @@ static int mov_write_trailer(AVFormatContext *s)
}
}
- moov_pos = avio_tell(pb);
+ // If there were no chapters when the header was written, but there
+ // are chapters now, write them in the trailer. This only works
+ // when we are not doing fragments.
+ if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+ if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
+ mov->chapter_track = mov->nb_streams++;
+ mov_create_chapter_track(s, mov->chapter_track);
+ }
+ }
if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+ moov_pos = avio_tell(pb);
+
/* Write size of mdat tag */
if (mov->mdat_size + 8 <= UINT32_MAX) {
avio_seek(pb, mov->mdat_pos, SEEK_SET);
@@ -3882,8 +3955,8 @@ static int mov_write_trailer(AVFormatContext *s)
}
avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
- if (mov->reserved_moov_size == -1) {
- av_log(s, AV_LOG_INFO, "Starting second pass: moving header on top of the file\n");
+ if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+ av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
res = shift_data(s);
if (res == 0) {
avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
@@ -3893,13 +3966,13 @@ static int mov_write_trailer(AVFormatContext *s)
int64_t size;
mov_write_moov_tag(pb, mov, s);
size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
- if(size < 8){
+ if (size < 8){
av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
return -1;
}
avio_wb32(pb, size);
ffio_wfourcc(pb, "free");
- for(i=0; i<size; i++)
+ for (i = 0; i < size; i++)
avio_w8(pb, 0);
avio_seek(pb, moov_pos, SEEK_SET);
} else {
@@ -3910,10 +3983,12 @@ static int mov_write_trailer(AVFormatContext *s)
mov_write_mfra_tag(pb, mov);
}
- if (mov->chapter_track)
+ if (mov->chapter_track) {
+ av_free(mov->tracks[mov->chapter_track].enc->extradata);
av_freep(&mov->tracks[mov->chapter_track].enc);
+ }
- for (i=0; i<mov->nb_streams; i++) {
+ for (i = 0; i < mov->nb_streams; i++) {
if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
ff_mov_close_hinting(&mov->tracks[i]);
else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
@@ -3933,7 +4008,6 @@ static int mov_write_trailer(AVFormatContext *s)
if (mov->tracks[i].vos_len)
av_free(mov->tracks[i].vos_data);
-
}
av_freep(&mov->tracks);
@@ -3954,7 +4028,7 @@ AVOutputFormat ff_mov_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){
ff_codec_movvideo_tags, ff_codec_movaudio_tags, 0
},
@@ -3973,7 +4047,7 @@ AVOutputFormat ff_tgp_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
.priv_class = &tgp_muxer_class,
};
@@ -3992,7 +4066,7 @@ AVOutputFormat ff_mp4_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
.priv_class = &mp4_muxer_class,
};
@@ -4010,7 +4084,7 @@ AVOutputFormat ff_psp_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
.priv_class = &psp_muxer_class,
};
@@ -4027,7 +4101,7 @@ AVOutputFormat ff_tg2_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
.priv_class = &tg2_muxer_class,
};
@@ -4045,7 +4119,7 @@ AVOutputFormat ff_ipod_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
.priv_class = &ipod_muxer_class,
};
@@ -4063,7 +4137,7 @@ AVOutputFormat ff_ismv_muxer = {
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
.priv_class = &ismv_muxer_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/movenc.h b/chromium/third_party/ffmpeg/libavformat/movenc.h
index a5db8950ab9..79d8fa2d21d 100644
--- a/chromium/third_party/ffmpeg/libavformat/movenc.h
+++ b/chromium/third_party/ffmpeg/libavformat/movenc.h
@@ -26,7 +26,8 @@
#include "avformat.h"
-#define MOV_INDEX_CLUSTER_SIZE 16384
+#define MOV_FRAG_INFO_ALLOC_INCREMENT 64
+#define MOV_INDEX_CLUSTER_SIZE 1024
#define MOV_TIMESCALE 1000
#define RTP_MAX_PACKET_SIZE 1450
@@ -75,7 +76,7 @@ typedef struct MOVFragmentInfo {
int64_t tfrf_offset;
} MOVFragmentInfo;
-typedef struct MOVIndex {
+typedef struct MOVTrack {
int mode;
int entry;
unsigned timescale;
@@ -102,6 +103,7 @@ typedef struct MOVIndex {
int vos_len;
uint8_t *vos_data;
MOVIentry *cluster;
+ unsigned cluster_capacity;
int audio_vbr;
int height; ///< active picture (w/o VBI) height for D-10/IMX
uint32_t tref_tag;
@@ -129,6 +131,7 @@ typedef struct MOVIndex {
int nb_frag_info;
MOVFragmentInfo *frag_info;
+ unsigned frag_info_capacity;
struct {
int64_t struct_offset;
@@ -153,8 +156,6 @@ typedef struct MOVMuxContext {
int flags;
int rtp_flags;
- int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
- int64_t reserved_moov_pos;
int iods_skip;
int iods_video_profile;
@@ -168,6 +169,10 @@ typedef struct MOVMuxContext {
AVIOContext *mdat_buf;
int use_editlist;
+ int video_track_timescale;
+
+ int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
+ int64_t reserved_moov_pos;
} MOVMuxContext;
#define FF_MOV_FLAG_RTP_HINT 1
diff --git a/chromium/third_party/ffmpeg/libavformat/movenchint.c b/chromium/third_party/ffmpeg/libavformat/movenchint.c
index cc90f0b45ac..943680e9ad0 100644
--- a/chromium/third_party/ffmpeg/libavformat/movenchint.c
+++ b/chromium/third_party/ffmpeg/libavformat/movenchint.c
@@ -87,7 +87,7 @@ static void sample_queue_free(HintSampleQueue *queue)
if (queue->samples[i].own_data)
av_free(queue->samples[i].data);
av_freep(&queue->samples);
- queue->len = 0;
+ queue->len = 0;
queue->size = 0;
}
@@ -104,7 +104,7 @@ static void sample_queue_push(HintSampleQueue *queue, uint8_t *data, int size,
if (size <= 14)
return;
if (!queue->samples || queue->len >= queue->size) {
- HintSample* samples;
+ HintSample *samples;
queue->size += 10;
samples = av_realloc(queue->samples, sizeof(HintSample)*queue->size);
if (!samples)
@@ -114,7 +114,7 @@ static void sample_queue_push(HintSampleQueue *queue, uint8_t *data, int size,
queue->samples[queue->len].data = data;
queue->samples[queue->len].size = size;
queue->samples[queue->len].sample_number = sample;
- queue->samples[queue->len].offset = 0;
+ queue->samples[queue->len].offset = 0;
queue->samples[queue->len].own_data = 0;
queue->len++;
}
@@ -128,7 +128,7 @@ static void sample_queue_retain(HintSampleQueue *queue)
for (i = 0; i < queue->len; ) {
HintSample *sample = &queue->samples[i];
if (!sample->own_data) {
- uint8_t* ptr = av_malloc(sample->size);
+ uint8_t *ptr = av_malloc(sample->size);
if (!ptr) {
/* Unable to allocate memory for this one, remove it */
memmove(queue->samples + i, queue->samples + i + 1,
@@ -309,11 +309,11 @@ static void describe_payload(const uint8_t *data, int size,
* @param data buffer containing RTP packets
* @param size the size of the data buffer
* @param trk the MOVTrack for the hint track
- * @param pts pointer where the timestamp for the written RTP hint is stored
+ * @param dts pointer where the timestamp for the written RTP hint is stored
* @return the number of RTP packets in the written hint
*/
static int write_hint_packets(AVIOContext *out, const uint8_t *data,
- int size, MOVTrack *trk, int64_t *pts)
+ int size, MOVTrack *trk, int64_t *dts)
{
int64_t curpos;
int64_t count_pos, entries_pos;
@@ -328,6 +328,7 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
uint32_t packet_len = AV_RB32(data);
uint16_t seq;
uint32_t ts;
+ int32_t ts_diff;
data += 4;
size -= 4;
@@ -344,25 +345,35 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
trk->max_packet_size = packet_len;
seq = AV_RB16(&data[2]);
- ts = AV_RB32(&data[4]);
+ ts = AV_RB32(&data[4]);
if (trk->prev_rtp_ts == 0)
trk->prev_rtp_ts = ts;
/* Unwrap the 32-bit RTP timestamp that wraps around often
* into a not (as often) wrapping 64-bit timestamp. */
- trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts);
- trk->prev_rtp_ts = ts;
- if (*pts == AV_NOPTS_VALUE)
- *pts = trk->cur_rtp_ts_unwrapped;
+ ts_diff = ts - trk->prev_rtp_ts;
+ if (ts_diff > 0) {
+ trk->cur_rtp_ts_unwrapped += ts_diff;
+ trk->prev_rtp_ts = ts;
+ ts_diff = 0;
+ }
+ if (*dts == AV_NOPTS_VALUE)
+ *dts = trk->cur_rtp_ts_unwrapped;
count++;
/* RTPpacket header */
avio_wb32(out, 0); /* relative_time */
avio_write(out, data, 2); /* RTP header */
avio_wb16(out, seq); /* RTPsequenceseed */
- avio_wb16(out, 0); /* reserved + flags */
+ avio_wb16(out, ts_diff ? 4 : 0); /* reserved + flags (extra_flag) */
entries_pos = avio_tell(out);
avio_wb16(out, 0); /* entry count */
+ if (ts_diff) { /* if extra_flag is set */
+ avio_wb32(out, 16); /* extra_information_length */
+ avio_wb32(out, 12); /* rtpoffsetTLV box */
+ avio_write(out, "rtpo", 4);
+ avio_wb32(out, ts_diff);
+ }
data += 12;
size -= 12;
@@ -417,7 +428,7 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
* for next time. */
size = avio_close_dyn_buf(rtp_ctx->pb, &buf);
if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb,
- RTP_MAX_PACKET_SIZE)) < 0)
+ RTP_MAX_PACKET_SIZE)) < 0)
goto done;
if (size <= 0)
@@ -445,8 +456,9 @@ done:
return ret;
}
-void ff_mov_close_hinting(MOVTrack *track) {
- AVFormatContext* rtp_ctx = track->rtp_ctx;
+void ff_mov_close_hinting(MOVTrack *track)
+{
+ AVFormatContext *rtp_ctx = track->rtp_ctx;
uint8_t *ptr;
av_freep(&track->enc);
diff --git a/chromium/third_party/ffmpeg/libavformat/mp3dec.c b/chromium/third_party/ffmpeg/libavformat/mp3dec.c
index d599c9c489c..472bad9b6ae 100644
--- a/chromium/third_party/ffmpeg/libavformat/mp3dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mp3dec.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/opt.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
@@ -36,10 +37,14 @@
#define XING_TOC_COUNT 100
typedef struct {
+ AVClass *class;
int64_t filesize;
+ int64_t header_filesize;
int xing_toc;
int start_pad;
int end_pad;
+ int usetoc;
+ int is_cbr;
} MP3DecContext;
/* mp3 read */
@@ -76,11 +81,11 @@ static int mp3_read_probe(AVProbeData *p)
}
// keep this in sync with ac3 probe, both need to avoid
// issues with MPEG-files!
- if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
- else if(max_frames>200)return AVPROBE_SCORE_MAX/2;
- else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
+ if (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1;
+ else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
+ else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION / 2;
else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size)
- return AVPROBE_SCORE_MAX/8;
+ return AVPROBE_SCORE_EXTENSION / 4;
else if(max_frames>=1) return 1;
else return 0;
//mpegps_mp3_unrecognized_format.mpg has max_frames=3
@@ -90,22 +95,24 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration
{
int i;
MP3DecContext *mp3 = s->priv_data;
+ int fill_index = mp3->usetoc && duration > 0;
if (!filesize &&
!(filesize = avio_size(s->pb))) {
av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n");
- return;
+ fill_index = 0;
}
for (i = 0; i < XING_TOC_COUNT; i++) {
uint8_t b = avio_r8(s->pb);
-
- av_add_index_entry(s->streams[0],
+ if (fill_index)
+ av_add_index_entry(s->streams[0],
av_rescale(b, filesize, 256),
av_rescale(i, duration, XING_TOC_COUNT),
0, 0, AVINDEX_KEYFRAME);
}
- mp3->xing_toc = 1;
+ if (fill_index)
+ mp3->xing_toc = 1;
}
/**
@@ -117,7 +124,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
uint32_t v, spf;
unsigned frames = 0; /* Total number of frames in file */
unsigned size = 0; /* Total number of bytes in the stream */
- const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
+ static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
MPADecodeHeader c;
int vbrtag_size = 0;
int is_cbr;
@@ -143,7 +150,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
frames = avio_rb32(s->pb);
if(v & XING_FLAG_SIZE)
size = avio_rb32(s->pb);
- if (v & XING_FLAG_TOC && frames)
+ if (v & XING_FLAG_TOC)
read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate},
st->time_base));
if(v & 8)
@@ -185,6 +192,9 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
if (size && frames && !is_cbr)
st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf);
+ mp3->is_cbr = is_cbr;
+ mp3->header_filesize = size;
+
return 0;
}
@@ -274,21 +284,33 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
int flags)
{
MP3DecContext *mp3 = s->priv_data;
- AVIndexEntry *ie;
+ AVIndexEntry *ie, ie1;
AVStream *st = s->streams[0];
int64_t ret = av_index_search_timestamp(st, timestamp, flags);
int i, j;
- if (!mp3->xing_toc) {
+ if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) {
+ int64_t filesize = avio_size(s->pb);
+ int64_t duration;
+ if (filesize <= s->data_offset)
+ filesize = mp3->header_filesize;
+ filesize -= s->data_offset;
+ duration = av_rescale(st->duration, filesize, mp3->header_filesize - s->data_offset);
+ ie = &ie1;
+ timestamp = av_clip64(timestamp, 0, duration);
+ ie->timestamp = timestamp;
+ ie->pos = av_rescale(timestamp, filesize, duration) + s->data_offset;
+ } else if (mp3->xing_toc) {
+ if (ret < 0)
+ return ret;
+
+ ie = &st->index_entries[ret];
+ } else {
st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
return -1;
}
- if (ret < 0)
- return ret;
-
- ie = &st->index_entries[ret];
ret = avio_seek(s->pb, ie->pos, SEEK_SET);
if (ret < 0)
return ret;
@@ -316,6 +338,19 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
return 0;
}
+static const AVOption options[] = {
+ { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
+ { NULL },
+};
+
+static const AVClass demuxer_class = {
+ .class_name = "mp3",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DEMUXER,
+};
+
AVInputFormat ff_mp3_demuxer = {
.name = "mp3",
.long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"),
@@ -326,4 +361,5 @@ AVInputFormat ff_mp3_demuxer = {
.priv_data_size = sizeof(MP3DecContext),
.flags = AVFMT_GENERIC_INDEX,
.extensions = "mp2,mp3,m2a", /* XXX: use probe */
+ .priv_class = &demuxer_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/mpc8.c b/chromium/third_party/ffmpeg/libavformat/mpc8.c
index 73f805711d2..73b7eb739c7 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpc8.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpc8.c
@@ -92,7 +92,7 @@ static int mpc8_probe(AVProbeData *p)
if (size < 2)
return 0;
if (bs + size - 2 >= bs_end)
- return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet
+ return AVPROBE_SCORE_EXTENSION - 1; // seems to be valid MPC but no header yet
if (header_found) {
if (size < 11 || size > 28)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/mpeg.c b/chromium/third_party/ffmpeg/libavformat/mpeg.c
index 8f835ad0568..5d5b09fc079 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpeg.c
@@ -89,14 +89,14 @@ static int mpegps_probe(AVProbeData *p)
}
if(vid+audio > invalid+1) /* invalid VDR files nd short PES streams */
- score= AVPROBE_SCORE_MAX/4;
+ score = AVPROBE_SCORE_EXTENSION / 2;
if(sys>invalid && sys*9 <= pspack*10)
- return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+ return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
- return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+ return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */
- return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
+ return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2;
//02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
//mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegenc.c b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
index b467bb5de5f..6f6da5c83de 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
#include "libavutil/fifo.h"
#include "libavutil/log.h"
#include "libavutil/mathematics.h"
@@ -293,7 +294,7 @@ static int get_system_header_size(AVFormatContext *ctx)
return buf_index;
}
-static int mpeg_mux_init(AVFormatContext *ctx)
+static av_cold int mpeg_mux_init(AVFormatContext *ctx)
{
MpegMuxContext *s = ctx->priv_data;
int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j;
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegts.c b/chromium/third_party/ffmpeg/libavformat/mpegts.c
index 85b5146255f..c6417945560 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegts.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegts.c
@@ -29,6 +29,7 @@
#include "libavutil/avassert.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/get_bits.h"
+#include "libavcodec/mathops.h"
#include "avformat.h"
#include "mpegts.h"
#include "internal.h"
@@ -52,7 +53,7 @@ enum MpegTSFilterType {
typedef struct MpegTSFilter MpegTSFilter;
-typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos);
+typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos, int64_t cur_pcr);
typedef struct MpegTSPESFilter {
PESCallback *pes_cb;
@@ -98,7 +99,11 @@ struct MpegTSContext {
/** raw packet size, including FEC if present */
int raw_packet_size;
- int pos47;
+ 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 */
int auto_guess;
@@ -106,6 +111,9 @@ struct MpegTSContext {
/** compute exact PCR for each transport stream packet */
int mpeg2ts_compute_pcr;
+ /** fix dvb teletext pts */
+ int fix_teletext_pts;
+
int64_t cur_pcr; /**< used to estimate the exact PCR */
int pcr_incr; /**< used to estimate the exact PCR */
@@ -131,7 +139,7 @@ struct MpegTSContext {
int current_pid;
};
-static const AVOption options[] = {
+static const AVOption mpegtsraw_options[] = {
{"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
@@ -140,7 +148,20 @@ static const AVOption options[] = {
static const AVClass mpegtsraw_class = {
.class_name = "mpegtsraw demuxer",
.item_name = av_default_item_name,
- .option = options,
+ .option = mpegtsraw_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVOption mpegts_options[] = {
+ {"fix_teletext_pts", "Try to fix pts values of dvb teletext streams.", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT,
+ {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass mpegts_class = {
+ .class_name = "mpegts demuxer",
+ .item_name = av_default_item_name,
+ .option = mpegts_options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -179,6 +200,7 @@ typedef struct PESContext {
uint8_t header[MAX_PES_HEADER_SIZE];
AVBufferRef *buffer;
SLConfigDescr sl;
+ int64_t last_pcr;
} PESContext;
extern AVInputFormat ff_mpegts_demuxer;
@@ -268,6 +290,17 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid)
int i, j, k;
int used = 0, discarded = 0;
struct Program *p;
+
+ /* If none of the programs have .discard=AVDISCARD_ALL then there's
+ * no way we have to discard this packet
+ */
+ for (k = 0; k < ts->stream->nb_programs; k++) {
+ if (ts->stream->programs[k]->discard == AVDISCARD_ALL)
+ break;
+ }
+ if (k == ts->stream->nb_programs)
+ return 0;
+
for(i=0; i<ts->nb_prg; i++) {
p = &ts->prg[i];
for(j=0; j<p->nb_pids; j++) {
@@ -808,7 +841,7 @@ static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf
/* return non zero if a packet could be constructed */
static int mpegts_push_data(MpegTSFilter *filter,
const uint8_t *buf, int buf_size, int is_start,
- int64_t pos)
+ int64_t pos, int64_t pcr)
{
PESContext *pes = filter->u.pes_filter.opaque;
MpegTSContext *ts = pes->ts;
@@ -818,6 +851,9 @@ static int mpegts_push_data(MpegTSFilter *filter,
if(!ts->pkt)
return 0;
+ if (pcr != -1)
+ pes->last_pcr = pcr;
+
if (is_start) {
if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
new_pes_packet(pes, ts->pkt);
@@ -964,6 +1000,32 @@ static int mpegts_push_data(MpegTSFilter *filter,
p += sl_header_bytes;
buf_size -= sl_header_bytes;
}
+ if (pes->ts->fix_teletext_pts && pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+ AVProgram *p = NULL;
+ while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) {
+ if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) {
+ MpegTSFilter *f = pes->ts->pids[p->pcr_pid];
+ if (f && f->type == MPEGTS_PES) {
+ PESContext *pcrpes = f->u.pes_filter.opaque;
+ if (pcrpes && pcrpes->last_pcr != -1 && pcrpes->st && pcrpes->st->discard != AVDISCARD_ALL) {
+ // teletext packets do not always have correct timestamps,
+ // the standard says they should be handled after 40.6 ms at most,
+ // and the pcr error to this packet should be no more than 100 ms.
+ // TODO: we should interpolate the PCR, not just use the last one
+ int64_t pcr = pcrpes->last_pcr / 300;
+ pes->st->pts_wrap_reference = pcrpes->st->pts_wrap_reference;
+ pes->st->pts_wrap_behavior = pcrpes->st->pts_wrap_behavior;
+ if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) {
+ pes->pts = pes->dts = pcr;
+ } else if (pes->dts > pcr + 3654 + 9000) {
+ pes->pts = pes->dts = pcr + 3654 + 9000;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
}
break;
case MPEGTS_PAYLOAD:
@@ -1020,6 +1082,7 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid)
pes->state = MPEGTS_SKIP;
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
+ pes->last_pcr = -1;
tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
if (!tss) {
av_free(pes);
@@ -1625,12 +1688,18 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (sid == 0x0000) {
/* NIT info */
} else {
+ MpegTSFilter *fil = ts->pids[pmt_pid];
program = av_new_program(ts->stream, sid);
program->program_num = sid;
program->pmt_pid = pmt_pid;
- if (ts->pids[pmt_pid])
- mpegts_close_filter(ts, ts->pids[pmt_pid]);
- mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
+ if (fil)
+ if ( fil->type != MPEGTS_SECTION
+ || fil->pid != pmt_pid
+ || fil->u.section_filter.section_cb != pmt_cb)
+ mpegts_close_filter(ts, ts->pids[pmt_pid]);
+
+ if (!ts->pids[pmt_pid])
+ mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
add_pat_entry(ts, sid);
add_pid_to_pmt(ts, sid, 0); //add pat pid to program
add_pid_to_pmt(ts, sid, pmt_pid);
@@ -1726,6 +1795,9 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
}
}
+static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
+ const uint8_t *packet);
+
/* handle one TS packet */
static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
{
@@ -1790,7 +1862,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
return 0;
pos = avio_tell(ts->stream->pb);
- ts->pos47= pos % ts->raw_packet_size;
+ av_assert0(pos >= TS_PACKET_SIZE);
+ ts->pos47_full = pos - TS_PACKET_SIZE;
if (tss->type == MPEGTS_SECTION) {
if (is_start) {
@@ -1819,15 +1892,53 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
}
} else {
int ret;
+ int64_t pcr = -1;
+ int64_t pcr_h;
+ int pcr_l;
+ if (parse_pcr(&pcr_h, &pcr_l, packet) == 0)
+ pcr = pcr_h * 300 + pcr_l;
// Note: The position here points actually behind the current packet.
if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
- pos - ts->raw_packet_size)) < 0)
+ pos - ts->raw_packet_size, pcr)) < 0)
return ret;
}
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)
@@ -1841,6 +1952,7 @@ static int mpegts_resync(AVFormatContext *s)
return -1;
if (c == 0x47) {
avio_seek(pb, -1, SEEK_CUR);
+ reanalyze(s->priv_data);
return 0;
}
}
@@ -1850,37 +1962,43 @@ static int mpegts_resync(AVFormatContext *s)
}
/* return -1 if error or EOF. Return 0 if OK. */
-static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
+static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size, const uint8_t **data)
{
AVIOContext *pb = s->pb;
- int skip, len;
+ int len;
for(;;) {
- len = avio_read(pb, buf, TS_PACKET_SIZE);
+ len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);
if (len != TS_PACKET_SIZE)
return len < 0 ? len : AVERROR_EOF;
/* check packet sync byte */
- if (buf[0] != 0x47) {
+ if ((*data)[0] != 0x47) {
/* find a new packet start */
- avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR);
+ avio_seek(pb, -raw_packet_size, SEEK_CUR);
if (mpegts_resync(s) < 0)
return AVERROR(EAGAIN);
else
continue;
} else {
- skip = raw_packet_size - TS_PACKET_SIZE;
- if (skip > 0)
- avio_skip(pb, skip);
break;
}
}
return 0;
}
+static void finished_reading_packet(AVFormatContext *s, int raw_packet_size)
+{
+ AVIOContext *pb = s->pb;
+ int skip = raw_packet_size - TS_PACKET_SIZE;
+ if (skip > 0)
+ avio_skip(pb, skip);
+}
+
static int handle_packets(MpegTSContext *ts, int nb_packets)
{
AVFormatContext *s = ts->stream;
uint8_t packet[TS_PACKET_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
+ const uint8_t *data;
int packet_num, ret = 0;
if (avio_tell(s->pb) != ts->last_pos) {
@@ -1894,6 +2012,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
av_buffer_unref(&pes->buffer);
pes->data_index = 0;
pes->state = MPEGTS_SKIP; /* skip until pes header */
+ pes->last_pcr = -1;
}
ts->pids[i]->last_cc = -1;
}
@@ -1913,10 +2032,11 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
if (ts->stop_parse > 0)
break;
- ret = read_packet(s, packet, ts->raw_packet_size);
+ ret = read_packet(s, packet, ts->raw_packet_size, &data);
if (ret != 0)
break;
- ret = handle_packet(ts, packet);
+ ret = handle_packet(ts, data);
+ finished_reading_packet(s, ts->raw_packet_size);
if (ret != 0)
break;
}
@@ -1986,6 +2106,15 @@ static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
return 0;
}
+static void seek_back(AVFormatContext *s, AVIOContext *pb, int64_t pos) {
+
+ /* NOTE: We attempt to seek on non-seekable files as well, as the
+ * probe buffer usually is big enough. Only warn if the seek failed
+ * on files where the seek should work. */
+ if (avio_seek(pb, pos, SEEK_SET) < 0)
+ av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
+}
+
static int mpegts_read_header(AVFormatContext *s)
{
MpegTSContext *ts = s->priv_data;
@@ -1994,6 +2123,8 @@ static int mpegts_read_header(AVFormatContext *s)
int len;
int64_t pos;
+ ffio_ensure_seekback(pb, s->probesize);
+
/* read the first 8192 bytes to get packet size */
pos = avio_tell(pb);
len = avio_read(pb, buf, sizeof(buf));
@@ -2009,11 +2140,7 @@ static int mpegts_read_header(AVFormatContext *s)
/* normal demux */
/* first do a scan to get all the services */
- /* NOTE: We attempt to seek on non-seekable files as well, as the
- * probe buffer usually is big enough. Only warn if the seek failed
- * on files where the seek should work. */
- if (avio_seek(pb, pos, SEEK_SET) < 0)
- av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
+ seek_back(s, pb, pos);
mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
@@ -2033,6 +2160,7 @@ static int mpegts_read_header(AVFormatContext *s)
int64_t pcrs[2], pcr_h;
int packet_count[2];
uint8_t packet[TS_PACKET_SIZE];
+ const uint8_t *data;
/* only read packets */
@@ -2048,18 +2176,21 @@ static int mpegts_read_header(AVFormatContext *s)
nb_pcrs = 0;
nb_packets = 0;
for(;;) {
- ret = read_packet(s, packet, ts->raw_packet_size);
+ ret = read_packet(s, packet, ts->raw_packet_size, &data);
if (ret < 0)
- return -1;
- pid = AV_RB16(packet + 1) & 0x1fff;
+ goto fail;
+ pid = AV_RB16(data + 1) & 0x1fff;
if ((pcr_pid == -1 || pcr_pid == pid) &&
- parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
+ parse_pcr(&pcr_h, &pcr_l, data) == 0) {
+ finished_reading_packet(s, ts->raw_packet_size);
pcr_pid = pid;
packet_count[nb_pcrs] = nb_packets;
pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
nb_pcrs++;
if (nb_pcrs >= 2)
break;
+ } else {
+ finished_reading_packet(s, ts->raw_packet_size);
}
nb_packets++;
}
@@ -2075,7 +2206,7 @@ static int mpegts_read_header(AVFormatContext *s)
st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
}
- avio_seek(pb, pos, SEEK_SET);
+ seek_back(s, pb, pos);
return 0;
fail:
return -1;
@@ -2091,15 +2222,19 @@ static int mpegts_raw_read_packet(AVFormatContext *s,
int64_t pcr_h, next_pcr_h, pos;
int pcr_l, next_pcr_l;
uint8_t pcr_buf[12];
+ const uint8_t *data;
if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
return AVERROR(ENOMEM);
pkt->pos= avio_tell(s->pb);
- ret = read_packet(s, pkt->data, ts->raw_packet_size);
+ ret = read_packet(s, pkt->data, ts->raw_packet_size, &data);
if (ret < 0) {
av_free_packet(pkt);
return ret;
}
+ if (data != pkt->data)
+ memcpy(pkt->data, data, ts->raw_packet_size);
+ finished_reading_packet(s, ts->raw_packet_size);
if (ts->mpeg2ts_compute_pcr) {
/* compute exact PCR for each packet */
if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {
@@ -2181,13 +2316,15 @@ static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
int64_t pos, timestamp;
uint8_t buf[TS_PACKET_SIZE];
int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
- pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
+ int pos47 = ts->pos47_full % ts->raw_packet_size;
+ pos = ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;
while(pos < pos_limit) {
if (avio_seek(s->pb, pos, SEEK_SET) < 0)
return AV_NOPTS_VALUE;
if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
return AV_NOPTS_VALUE;
if (buf[0] != 0x47) {
+ avio_seek(s->pb, -TS_PACKET_SIZE, SEEK_CUR);
if (mpegts_resync(s) < 0)
return AV_NOPTS_VALUE;
pos = avio_tell(s->pb);
@@ -2209,7 +2346,8 @@ static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,
{
MpegTSContext *ts = s->priv_data;
int64_t pos;
- pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
+ int pos47 = ts->pos47_full % ts->raw_packet_size;
+ pos = ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;
ff_read_frame_flush(s);
if (avio_seek(s->pb, pos, SEEK_SET) < 0)
return AV_NOPTS_VALUE;
@@ -2298,6 +2436,7 @@ AVInputFormat ff_mpegts_demuxer = {
.read_close = mpegts_read_close,
.read_timestamp = mpegts_get_dts,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
+ .priv_class = &mpegts_class,
};
AVInputFormat ff_mpegtsraw_demuxer = {
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
index 0ddae651de0..1d51b97bdf0 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
@@ -85,6 +85,7 @@ typedef struct MpegTSWrite {
#define MPEGTS_FLAG_AAC_LATM 0x02
int flags;
int copyts;
+ int tables_version;
} MpegTSWrite;
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -119,8 +120,10 @@ static const AVOption options[] = {
// backward compatibility
{ "resend_headers", "Reemit PAT/PMT before writing the next packet",
offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
- { "mpegts_copyts", "dont offset dts/pts",
+ { "mpegts_copyts", "don't offset dts/pts",
offsetof(MpegTSWrite, copyts), AV_OPT_TYPE_INT, {.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},
{ NULL },
};
@@ -252,7 +255,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, 0, 0, 0,
+ mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 0,
data, q - data);
}
@@ -397,13 +400,23 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
*q++ = 'c';
}
break;
+ case AVMEDIA_TYPE_DATA:
+ if (st->codec->codec_id == AV_CODEC_ID_SMPTE_KLV) {
+ *q++ = 0x05; /* MPEG-2 registration descriptor */
+ *q++ = 4;
+ *q++ = 'K';
+ *q++ = 'L';
+ *q++ = 'V';
+ *q++ = 'A';
+ }
+ break;
}
val = 0xf000 | (q - desc_length_ptr - 2);
desc_length_ptr[0] = val >> 8;
desc_length_ptr[1] = val;
}
- mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0,
+ mpegts_write_section1(&service->pmt, PMT_TID, service->sid, ts->tables_version, 0, 0,
data, q - data);
}
@@ -458,7 +471,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, 0, 0, 0,
+ mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, ts->tables_version, 0, 0,
data, q - data);
}
@@ -977,8 +990,8 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*q++ = len >> 8;
*q++ = len;
val = 0x80;
- /* data alignment indicator is required for subtitle data */
- if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+ /* data alignment indicator is required for subtitle and data streams */
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA)
val |= 0x04;
*q++ = val;
*q++ = flags;
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegvideodec.c b/chromium/third_party/ffmpeg/libavformat/mpegvideodec.c
index 471d2f4d943..a400978d024 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegvideodec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegvideodec.c
@@ -63,8 +63,8 @@ static int mpegvideo_probe(AVProbeData *p)
}
}
if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !apes && !res && slice > sicle) {
- if(vpes) return AVPROBE_SCORE_MAX/8;
- else return pic>1 ? AVPROBE_SCORE_MAX/2+1 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+ if(vpes) return AVPROBE_SCORE_EXTENSION / 4;
+ else return pic>1 ? AVPROBE_SCORE_EXTENSION + 1 : AVPROBE_SCORE_EXTENSION / 2; // +1 for .mpg
}
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mpsubdec.c b/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
index 2acafaa81b4..6a0cefbeb68 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpsubdec.c
@@ -37,11 +37,10 @@ static int mpsub_probe(AVProbeData *p)
const char *ptr_end = p->buf + p->buf_size;
while (ptr < ptr_end) {
- int n;
-
- if (!memcmp(ptr, "FORMAT=TIME", 11) ||
- sscanf(ptr, "FORMAT=%d", &n) == 1)
- return AVPROBE_SCORE_MAX/2;
+ if (!memcmp(ptr, "FORMAT=TIME", 11))
+ return AVPROBE_SCORE_EXTENSION;
+ if (!memcmp(ptr, "FORMAT=", 7))
+ return AVPROBE_SCORE_EXTENSION / 3;
ptr += strcspn(ptr, "\n") + 1;
}
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/mtv.c b/chromium/third_party/ffmpeg/libavformat/mtv.c
index 6ffbb51ff2c..29c26c6811d 100644
--- a/chromium/third_party/ffmpeg/libavformat/mtv.c
+++ b/chromium/third_party/ffmpeg/libavformat/mtv.c
@@ -42,10 +42,10 @@ typedef struct MTVDemuxContext {
unsigned int audio_br; ///< bitrate of audio channel (mp3)
unsigned int img_colorfmt; ///< frame colorfmt rgb 565/555
unsigned int img_bpp; ///< frame bits per pixel
- unsigned int img_width; //
- unsigned int img_height; //
+ unsigned int img_width;
+ unsigned int img_height;
unsigned int img_segment_size; ///< size of image segment
- unsigned int video_fps; //
+ unsigned int video_fps;
unsigned int full_segment_size;
} MTVDemuxContext;
@@ -64,13 +64,13 @@ static int mtv_probe(AVProbeData *p)
if(!AV_RL16(&p->buf[52]) || !AV_RL16(&p->buf[54]))
{
if(!!AV_RL16(&p->buf[56]))
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
else
return 0;
}
if(p->buf[51] != 16)
- return AVPROBE_SCORE_MAX/4; // But we are going to assume 16bpp anyway ..
+ return AVPROBE_SCORE_EXTENSION / 2; // But we are going to assume 16bpp anyway ..
return AVPROBE_SCORE_MAX;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mux.c b/chromium/third_party/ffmpeg/libavformat/mux.c
index 1153ab69a84..aa5d5edebc9 100644
--- a/chromium/third_party/ffmpeg/libavformat/mux.c
+++ b/chromium/third_party/ffmpeg/libavformat/mux.c
@@ -19,8 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* #define DEBUG */
-
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
@@ -34,6 +32,7 @@
#include "id3v2.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
+#include "libavutil/internal.h"
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "libavutil/time.h"
@@ -275,13 +274,18 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
&& FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
) {
- av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
- "(%d/%d) and encoder layer (%d/%d)\n",
- st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
- codec->sample_aspect_ratio.num,
- codec->sample_aspect_ratio.den);
- ret = AVERROR(EINVAL);
- goto fail;
+ if (st->sample_aspect_ratio.num != 0 &&
+ st->sample_aspect_ratio.den != 0 &&
+ codec->sample_aspect_ratio.den != 0 &&
+ codec->sample_aspect_ratio.den != 0) {
+ av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
+ "(%d/%d) and encoder layer (%d/%d)\n",
+ st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
+ codec->sample_aspect_ratio.num,
+ codec->sample_aspect_ratio.den);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
}
break;
}
@@ -298,12 +302,12 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
}
if (codec->codec_tag) {
if (!validate_codec_tag(s, st)) {
- char tagbuf[32], cortag[32];
+ char tagbuf[32], tagbuf2[32];
av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
- av_get_codec_tag_string(cortag, sizeof(cortag), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
+ av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
av_log(s, AV_LOG_ERROR,
"Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",
- tagbuf, codec->codec_tag, codec->codec_id, cortag);
+ tagbuf, codec->codec_tag, codec->codec_id, tagbuf2);
ret = AVERROR_INVALIDDATA;
goto fail;
}
@@ -398,6 +402,13 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
if ((ret = init_pts(s)) < 0)
return ret;
+ if (s->avoid_negative_ts < 0) {
+ if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
+ s->avoid_negative_ts = 0;
+ } else
+ s->avoid_negative_ts = 1;
+ }
+
return 0;
}
@@ -485,13 +496,43 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
}
/**
- * Move side data from payload to internal struct, call muxer, and restore
- * original packet.
+ * Make timestamps non negative, move side data from payload to internal struct, call muxer, and restore
+ * sidedata.
+ *
+ * FIXME: this function should NEVER get undefined pts/dts beside when the
+ * AVFMT_NOTIMESTAMPS is set.
+ * Those additional safety checks should be dropped once the correct checks
+ * are set in the callers.
*/
-static inline int split_write_packet(AVFormatContext *s, AVPacket *pkt)
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret, did_split;
+ if (s->avoid_negative_ts > 0) {
+ AVStream *st = s->streams[pkt->stream_index];
+ int64_t offset = st->mux_ts_offset;
+
+ if (pkt->dts < 0 && pkt->dts != AV_NOPTS_VALUE && !s->offset) {
+ s->offset = -pkt->dts;
+ s->offset_timebase = st->time_base;
+ }
+
+ if (s->offset && !offset) {
+ offset = st->mux_ts_offset =
+ av_rescale_q_rnd(s->offset,
+ s->offset_timebase,
+ st->time_base,
+ AV_ROUND_UP);
+ }
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += offset;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += offset;
+
+ av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0);
+ }
+
did_split = av_packet_split_side_data(pkt);
ret = s->oformat->write_packet(s, pkt);
if (s->flush_packets && s->pb && s->pb->error >= 0)
@@ -522,7 +563,7 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
return ret;
- ret = split_write_packet(s, pkt);
+ ret = write_packet(s, pkt);
if (ret >= 0 && s->pb && s->pb->error < 0)
ret = s->pb->error;
@@ -545,10 +586,13 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
return AVERROR(ENOMEM);
this_pktl->pkt = *pkt;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = NULL; // do not free original but only the copy
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt->buf = NULL;
av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-allocated memory
+ av_copy_packet_side_data(&this_pktl->pkt, &this_pktl->pkt); // copy side data
if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
next_point = &(st->last_in_packet_buffer->next);
@@ -600,7 +644,8 @@ next_non_null:
return 0;
}
-static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
+static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
+ AVPacket *pkt)
{
AVStream *st = s->streams[pkt->stream_index];
AVStream *st2 = s->streams[next->stream_index];
@@ -631,7 +676,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
int i, ret;
if (pkt) {
- ret = ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+ ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts);
if (ret < 0)
return ret;
}
@@ -679,23 +724,6 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
st->last_in_packet_buffer = NULL;
av_freep(&pktl);
- if (s->avoid_negative_ts > 0) {
- if (out->dts != AV_NOPTS_VALUE) {
- if (!st->mux_ts_offset && out->dts < 0) {
- for (i = 0; i < s->nb_streams; i++) {
- s->streams[i]->mux_ts_offset =
- av_rescale_q_rnd(-out->dts,
- st->time_base,
- s->streams[i]->time_base,
- AV_ROUND_UP);
- }
- }
- out->dts += st->mux_ts_offset;
- }
- if (out->pts != AV_NOPTS_VALUE)
- out->pts += st->mux_ts_offset;
- }
-
return 1;
} else {
av_init_packet(out);
@@ -752,7 +780,7 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
if (ret <= 0) //FIXME cleanup needed for ret<0 ?
return ret;
- ret = split_write_packet(s, &opkt);
+ ret = write_packet(s, &opkt);
if (ret >= 0)
s->streams[opkt.stream_index]->nb_frames++;
@@ -778,7 +806,7 @@ int av_write_trailer(AVFormatContext *s)
if (!ret)
break;
- ret = split_write_packet(s, &pkt);
+ ret = write_packet(s, &pkt);
if (ret >= 0)
s->streams[pkt.stream_index]->nb_frames++;
@@ -816,3 +844,25 @@ int av_get_output_timestamp(struct AVFormatContext *s, int stream,
s->oformat->get_output_timestamp(s, stream, dts, wall);
return 0;
}
+
+int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
+ AVFormatContext *src)
+{
+ AVPacket local_pkt;
+
+ local_pkt = *pkt;
+ local_pkt.stream_index = dst_stream;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ local_pkt.pts = av_rescale_q(pkt->pts,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
+ if (pkt->dts != AV_NOPTS_VALUE)
+ local_pkt.dts = av_rescale_q(pkt->dts,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
+ if (pkt->duration)
+ local_pkt.duration = av_rescale_q(pkt->duration,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
+ return av_write_frame(dst, &local_pkt);
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/mxfdec.c b/chromium/third_party/ffmpeg/libavformat/mxfdec.c
index 286a884cc7e..29a2f563e6c 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxfdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxfdec.c
@@ -43,8 +43,6 @@
* Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
*/
-//#define DEBUG
-
#include "libavutil/aes.h"
#include "libavutil/avassert.h"
#include "libavutil/mathematics.h"
@@ -1603,8 +1601,10 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
}
if (descriptor->extradata) {
st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (st->codec->extradata)
+ if (st->codec->extradata) {
memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size);
+ st->codec->extradata_size = descriptor->extradata_size;
+ }
} else if(st->codec->codec_id == AV_CODEC_ID_H264) {
ff_generate_avci_extradata(st);
}
@@ -2210,10 +2210,8 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
KLVPacket klv;
MXFContext *mxf = s->priv_data;
- while (!url_feof(s->pb)) {
+ while (klv_read_packet(&klv, s->pb) == 0) {
int ret;
- if (klv_read_packet(&klv, s->pb) < 0)
- return -1;
PRINT_KEY(s, "read packet", klv.key);
av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
@@ -2298,7 +2296,7 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
skip:
avio_skip(s->pb, klv.length);
}
- return AVERROR_EOF;
+ return url_feof(s->pb) ? AVERROR_EOF : -1;
}
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/mxfenc.c b/chromium/third_party/ffmpeg/libavformat/mxfenc.c
index ea13ee06503..52cb2826b8f 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxfenc.c
@@ -30,8 +30,6 @@
* SMPTE RP224: Registry of SMPTE Universal Labels
*/
-//#define DEBUG
-
#include <inttypes.h>
#include <math.h>
#include <time.h>
@@ -44,6 +42,7 @@
#include "libavcodec/dnxhddata.h"
#include "audiointerleave.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "internal.h"
#include "mxf.h"
#include "config.h"
@@ -1296,13 +1295,12 @@ static void mxf_write_klv_fill(AVFormatContext *s)
avio_write(s->pb, klv_fill_key, 16);
pad -= 16 + 4;
klv_encode_ber4_length(s->pb, pad);
- for (; pad; pad--)
- avio_w8(s->pb, 0);
+ ffio_fill(s->pb, 0, pad);
av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
}
}
-static void mxf_write_partition(AVFormatContext *s, int bodysid,
+static int mxf_write_partition(AVFormatContext *s, int bodysid,
int indexsid,
const uint8_t *key, int write_metadata)
{
@@ -1311,6 +1309,7 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
int64_t header_byte_count_offset;
unsigned index_byte_count = 0;
uint64_t partition_offset = avio_tell(pb);
+ int err;
if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
@@ -1325,10 +1324,11 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
}
if (!memcmp(key, body_partition_key, 16)) {
- mxf->body_partition_offset =
- av_realloc(mxf->body_partition_offset,
- (mxf->body_partitions_count+1)*
- sizeof(*mxf->body_partition_offset));
+ if ((err = av_reallocp_array(&mxf->body_partition_offset, mxf->body_partitions_count + 1,
+ sizeof(*mxf->body_partition_offset))) < 0) {
+ mxf->body_partitions_count = 0;
+ return err;
+ }
mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
}
@@ -1393,6 +1393,8 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
}
avio_flush(pb);
+
+ return 0;
}
static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
@@ -1872,13 +1874,11 @@ static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacke
avio_write(s->pb, klv_fill_key, 16);
pad -= 16 + 4;
klv_encode_ber4_length(s->pb, pad);
- for (; pad; pad--)
- avio_w8(s->pb, 0);
+ ffio_fill(s->pb, 0, pad);
av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
} else {
av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
- for (; pad > 0; pad--)
- avio_w8(s->pb, 0);
+ ffio_fill(s->pb, 0, pad);
}
}
@@ -1921,13 +1921,14 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
AVStream *st = s->streams[pkt->stream_index];
MXFStreamContext *sc = st->priv_data;
MXFIndexEntry ie = {0};
+ int err;
if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
- mxf->index_entries = av_realloc(mxf->index_entries,
- (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
- if (!mxf->index_entries) {
+ if ((err = av_reallocp_array(&mxf->index_entries, mxf->edit_units_count
+ + EDIT_UNITS_PER_BODY, sizeof(*mxf->index_entries))) < 0) {
+ mxf->edit_units_count = 0;
av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
- return -1;
+ return err;
}
}
@@ -1950,11 +1951,13 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
if (!mxf->header_written) {
if (mxf->edit_unit_byte_count) {
- mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
+ if ((err = mxf_write_partition(s, 1, 2, header_open_partition_key, 1)) < 0)
+ return err;
mxf_write_klv_fill(s);
mxf_write_index_table_segment(s);
} else {
- mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
+ if ((err = mxf_write_partition(s, 0, 0, header_open_partition_key, 1)) < 0)
+ return err;
}
mxf->header_written = 1;
}
@@ -1964,8 +1967,8 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
(!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
!(ie.flags & 0x33)) { // I frame, Gop start
mxf_write_klv_fill(s);
- mxf_write_partition(s, 1, 2, body_partition_key, 0);
-
+ if ((err = mxf_write_partition(s, 1, 2, body_partition_key, 0)) < 0)
+ return err;
mxf_write_klv_fill(s);
mxf_write_index_table_segment(s);
}
@@ -2034,16 +2037,18 @@ static int mxf_write_footer(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
AVIOContext *pb = s->pb;
+ int err;
mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
mxf_write_klv_fill(s);
mxf->footer_partition_offset = avio_tell(pb);
if (mxf->edit_unit_byte_count) { // no need to repeat index
- mxf_write_partition(s, 0, 0, footer_partition_key, 0);
+ if ((err = mxf_write_partition(s, 0, 0, footer_partition_key, 0)) < 0)
+ return err;
} else {
- mxf_write_partition(s, 0, 2, footer_partition_key, 0);
-
+ if ((err = mxf_write_partition(s, 0, 2, footer_partition_key, 0)) < 0)
+ return err;
mxf_write_klv_fill(s);
mxf_write_index_table_segment(s);
}
@@ -2054,11 +2059,13 @@ static int mxf_write_footer(AVFormatContext *s)
if (s->pb->seekable) {
avio_seek(pb, 0, SEEK_SET);
if (mxf->edit_unit_byte_count) {
- mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
+ if ((err = mxf_write_partition(s, 1, 2, header_closed_partition_key, 1)) < 0)
+ return err;
mxf_write_klv_fill(s);
mxf_write_index_table_segment(s);
} else {
- mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
+ if ((err = mxf_write_partition(s, 0, 0, header_closed_partition_key, 1)) < 0)
+ return err;
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mxg.c b/chromium/third_party/ffmpeg/libavformat/mxg.c
index 604be785bcf..b2b5b86c6f7 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxg.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxg.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavcodec/mjpeg.h"
#include "avformat.h"
@@ -74,7 +75,7 @@ static int mxg_read_header(AVFormatContext *s)
static uint8_t* mxg_find_startmarker(uint8_t *p, uint8_t *end)
{
for (; p < end - 3; p += 4) {
- uint32_t x = *(uint32_t*)p;
+ uint32_t x = AV_RN32(p);
if (x & (~(x+0x01010101)) & 0x80808080) {
if (p[0] == 0xff) {
@@ -171,7 +172,9 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pts = pkt->dts = mxg->dts;
pkt->stream_index = 0;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt->buf = NULL;
pkt->size = mxg->buffer_ptr - mxg->soi_ptr;
@@ -212,7 +215,9 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8);
pkt->stream_index = 1;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt->buf = NULL;
pkt->size = size - 14;
diff --git a/chromium/third_party/ffmpeg/libavformat/network.c b/chromium/third_party/ffmpeg/libavformat/network.c
index ceed719356d..73409616cdd 100644
--- a/chromium/third_party/ffmpeg/libavformat/network.c
+++ b/chromium/third_party/ffmpeg/libavformat/network.c
@@ -18,9 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/avutil.h"
+#include <fcntl.h>
#include "network.h"
+#include "url.h"
#include "libavcodec/internal.h"
+#include "libavutil/avutil.h"
#include "libavutil/mem.h"
#include "url.h"
#include "libavutil/time.h"
@@ -29,9 +31,9 @@
#if HAVE_PTHREADS
#include <pthread.h>
#elif HAVE_OS2THREADS
-#include "libavcodec/os2threads.h"
+#include "compat/os2threads.h"
#else
-#include "libavcodec/w32pthreads.h"
+#include "compat/w32pthreads.h"
#endif
#endif
@@ -156,12 +158,12 @@ int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterrupt
int64_t wait_start = 0;
while (1) {
+ if (ff_check_interrupt(int_cb))
+ return AVERROR_EXIT;
ret = ff_network_wait_fd(fd, write);
if (ret != AVERROR(EAGAIN))
return ret;
- if (ff_check_interrupt(int_cb))
- return AVERROR_EXIT;
- if (timeout) {
+ if (timeout > 0) {
if (!wait_start)
wait_start = av_gettime();
else if (av_gettime() - wait_start > timeout)
@@ -212,3 +214,171 @@ int ff_is_multicast_address(struct sockaddr *addr)
return 0;
}
+
+static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,
+ AVIOInterruptCB *cb)
+{
+ int runs = timeout / POLLING_TIME;
+ int ret = 0;
+
+ do {
+ if (ff_check_interrupt(cb))
+ return AVERROR_EXIT;
+ ret = poll(p, nfds, POLLING_TIME);
+ if (ret != 0)
+ break;
+ } while (timeout <= 0 || runs-- > 0);
+
+ if (!ret)
+ return AVERROR(ETIMEDOUT);
+ if (ret < 0)
+ return AVERROR(errno);
+ return ret;
+}
+
+int ff_socket(int af, int type, int proto)
+{
+ int fd;
+
+#ifdef SOCK_CLOEXEC
+ fd = socket(af, type | SOCK_CLOEXEC, proto);
+ if (fd == -1 && errno == EINVAL)
+#endif
+ {
+ fd = socket(af, type, proto);
+#if HAVE_FCNTL
+ if (fd != -1)
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+ }
+ return fd;
+}
+
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout, URLContext *h)
+{
+ int ret;
+ int reuse = 1;
+ struct pollfd lp = { fd, POLLIN, 0 };
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
+ av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
+ }
+ ret = bind(fd, addr, addrlen);
+ if (ret)
+ return ff_neterrno();
+
+ ret = listen(fd, 1);
+ if (ret)
+ return ff_neterrno();
+
+ ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
+ if (ret < 0)
+ return ret;
+
+ ret = accept(fd, NULL, NULL);
+ if (ret < 0)
+ return ff_neterrno();
+
+ closesocket(fd);
+
+ ff_socket_nonblock(ret, 1);
+ return ret;
+}
+
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout, URLContext *h,
+ int will_try_next)
+{
+ struct pollfd p = {fd, POLLOUT, 0};
+ int ret;
+ socklen_t optlen;
+
+ ff_socket_nonblock(fd, 1);
+
+ while ((ret = connect(fd, addr, addrlen))) {
+ ret = ff_neterrno();
+ switch (ret) {
+ case AVERROR(EINTR):
+ if (ff_check_interrupt(&h->interrupt_callback))
+ return AVERROR_EXIT;
+ continue;
+ case AVERROR(EINPROGRESS):
+ case AVERROR(EAGAIN):
+ ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback);
+ if (ret < 0)
+ return ret;
+ optlen = sizeof(ret);
+ if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
+ ret = AVUNERROR(ff_neterrno());
+ if (ret != 0) {
+ char errbuf[100];
+ ret = AVERROR(ret);
+ av_strerror(ret, errbuf, sizeof(errbuf));
+ if (will_try_next)
+ av_log(h, AV_LOG_WARNING,
+ "Connection to %s failed (%s), trying next address\n",
+ h->filename, errbuf);
+ else
+ av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
+ h->filename, errbuf);
+ }
+ default:
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int match_host_pattern(const char *pattern, const char *hostname)
+{
+ int len_p, len_h;
+ if (!strcmp(pattern, "*"))
+ return 1;
+ // Skip a possible *. at the start of the pattern
+ if (pattern[0] == '*')
+ pattern++;
+ if (pattern[0] == '.')
+ pattern++;
+ len_p = strlen(pattern);
+ len_h = strlen(hostname);
+ if (len_p > len_h)
+ return 0;
+ // Simply check if the end of hostname is equal to 'pattern'
+ if (!strcmp(pattern, &hostname[len_h - len_p])) {
+ if (len_h == len_p)
+ return 1; // Exact match
+ if (hostname[len_h - len_p - 1] == '.')
+ return 1; // The matched substring is a domain and not just a substring of a domain
+ }
+ return 0;
+}
+
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
+{
+ char *buf, *start;
+ int ret = 0;
+ if (!no_proxy)
+ return 0;
+ if (!hostname)
+ return 0;
+ buf = av_strdup(no_proxy);
+ if (!buf)
+ return 0;
+ start = buf;
+ while (start) {
+ char *sep, *next = NULL;
+ start += strspn(start, " ,");
+ sep = start + strcspn(start, " ,");
+ if (*sep) {
+ next = sep + 1;
+ *sep = '\0';
+ }
+ if (match_host_pattern(start, hostname)) {
+ ret = 1;
+ break;
+ }
+ start = next;
+ }
+ av_free(buf);
+ return ret;
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/network.h b/chromium/third_party/ffmpeg/libavformat/network.h
index f8b4dee50e7..c60e1424a1c 100644
--- a/chromium/third_party/ffmpeg/libavformat/network.h
+++ b/chromium/third_party/ffmpeg/libavformat/network.h
@@ -28,6 +28,7 @@
#include "libavutil/error.h"
#include "os_support.h"
#include "avio.h"
+#include "url.h"
#if HAVE_UNISTD_H
#include <unistd.h>
@@ -89,7 +90,7 @@ int ff_network_wait_fd(int fd, int write);
* @fd Socket descriptor
* @write Set 1 to wait for socket able to be read, 0 to be written
* @timeout Timeout interval, in microseconds. Actual precision is 100000 mcs, due to ff_network_wait_fd usage
- * @param int_cb Interrupt callback, is checked after each ff_network_wait_fd call
+ * @param int_cb Interrupt callback, is checked before each ff_network_wait_fd call
* @return 0 if data can be read/written, AVERROR(ETIMEDOUT) if timeout expired, or negative error code
*/
int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb);
@@ -222,4 +223,45 @@ const char *ff_gai_strerror(int ecode);
int ff_is_multicast_address(struct sockaddr *addr);
+#define POLLING_TIME 100 /// Time in milliseconds between interrupt check
+
+/**
+ * Bind to a file descriptor and poll for a connection.
+ *
+ * @param fd First argument of bind().
+ * @param addr Second argument of bind().
+ * @param addrlen Third argument of bind().
+ * @param timeout Polling timeout in milliseconds.
+ * @param h URLContext providing interrupt check
+ * callback and logging context.
+ * @return A non-blocking file descriptor on success
+ * or an AVERROR on failure.
+ */
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout,
+ URLContext *h);
+
+/**
+ * Connect to a file descriptor and poll for result.
+ *
+ * @param fd First argument of connect(),
+ * will be set as non-blocking.
+ * @param addr Second argument of connect().
+ * @param addrlen Third argument of connect().
+ * @param timeout Polling timeout in milliseconds.
+ * @param h URLContext providing interrupt check
+ * callback and logging context.
+ * @param will_try_next Whether the caller will try to connect to another
+ * address for the same host name, affecting the form of
+ * logged errors.
+ * @return 0 on success, AVERROR on failure.
+ */
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout,
+ URLContext *h, int will_try_next);
+
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
+
+int ff_socket(int domain, int type, int protocol);
+
#endif /* AVFORMAT_NETWORK_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/noproxy-test.c b/chromium/third_party/ffmpeg/libavformat/noproxy-test.c
index a156620271a..4524764cbf0 100644
--- a/chromium/third_party/ffmpeg/libavformat/noproxy-test.c
+++ b/chromium/third_party/ffmpeg/libavformat/noproxy-test.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "internal.h"
+#include "network.h"
static void test(const char *pattern, const char *host)
{
diff --git a/chromium/third_party/ffmpeg/libavformat/nsvdec.c b/chromium/third_party/ffmpeg/libavformat/nsvdec.c
index e582f0f6cca..4a749a2feb3 100644
--- a/chromium/third_party/ffmpeg/libavformat/nsvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/nsvdec.c
@@ -28,10 +28,6 @@
#include "libavutil/dict.h"
#include "libavutil/intreadwrite.h"
-//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
-#define CHECK_SUBSEQUENT_NSVS
-//#define DISABLE_AUDIO
-
/* max bytes to crawl for trying to resync
* stupid streaming servers don't start at chunk boundaries...
*/
@@ -370,25 +366,6 @@ static int nsv_parse_NSVf_header(AVFormatContext *s)
av_dlog(s, "NSV got index; filepos %"PRId64"\n", avio_tell(pb));
-#ifdef DEBUG_DUMP_INDEX
-#define V(v) ((v<0x20 || v > 127)?'.':v)
- /* dump index */
- av_dlog(s, "NSV %d INDEX ENTRIES:\n", table_entries);
- av_dlog(s, "NSV [dataoffset][fileoffset]\n", table_entries);
- for (i = 0; i < table_entries; i++) {
- unsigned char b[8];
- avio_seek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET);
- avio_read(pb, b, 8);
- av_dlog(s, "NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x"
- "%c%c%c%c%c%c%c%c\n",
- nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i],
- b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
- V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) );
- }
- //avio_seek(pb, size, SEEK_SET); /* go back to end of header */
-#undef V
-#endif
-
avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
if (url_feof(pb))
@@ -479,7 +456,6 @@ static int nsv_parse_NSVs_header(AVFormatContext *s)
}
}
if (atag != T_NONE) {
-#ifndef DISABLE_AUDIO
st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
@@ -499,15 +475,12 @@ static int nsv_parse_NSVs_header(AVFormatContext *s)
avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
st->start_time = 0;
st->duration = (int64_t)nsv->duration * framerate.num;
-#endif
}
-#ifdef CHECK_SUBSEQUENT_NSVS
} else {
if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) {
av_dlog(s, "NSV NSVs header values differ from the first one!!!\n");
//return -1;
}
-#endif /* CHECK_SUBSEQUENT_NSVS */
}
nsv->state = NSV_HAS_READ_NSVS;
@@ -786,7 +759,7 @@ static int nsv_probe(AVProbeData *p)
}
/* so we'll have more luck on extension... */
if (av_match_ext(p->filename, "nsv"))
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
/* FIXME: add mime-type check */
return score;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/nut.c b/chromium/third_party/ffmpeg/libavformat/nut.c
index 2abe9693080..7e7997998f9 100644
--- a/chromium/third_party/ffmpeg/libavformat/nut.c
+++ b/chromium/third_party/ffmpeg/libavformat/nut.c
@@ -26,125 +26,138 @@
#include "internal.h"
const AVCodecTag ff_nut_subtitle_tags[] = {
- { AV_CODEC_ID_TEXT , MKTAG('U', 'T', 'F', '8') },
- { AV_CODEC_ID_SSA , MKTAG('S', 'S', 'A', 0 ) },
- { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') },
- { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') },
- { AV_CODEC_ID_DVB_TELETEXT, MKTAG('D', 'V', 'B', 'T') },
- { AV_CODEC_ID_NONE , 0 }
+ { AV_CODEC_ID_TEXT, MKTAG('U', 'T', 'F', '8') },
+ { AV_CODEC_ID_SSA, MKTAG('S', 'S', 'A', 0 ) },
+ { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') },
+ { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') },
+ { AV_CODEC_ID_DVB_TELETEXT, MKTAG('D', 'V', 'B', 'T') },
+ { AV_CODEC_ID_NONE, 0 }
};
const AVCodecTag ff_nut_data_tags[] = {
- { AV_CODEC_ID_TEXT , MKTAG('U', 'T', 'F', '8') },
- { AV_CODEC_ID_NONE , 0 }
+ { AV_CODEC_ID_TEXT, MKTAG('U', 'T', 'F', '8') },
+ { AV_CODEC_ID_NONE, 0 }
};
const AVCodecTag ff_nut_video_tags[] = {
- { AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'B', 'G', 'R') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'R', 'G', 'B') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'B', 'G', 'R') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'R', 'G', 'B') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 12 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 12 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'B', 'G', 'R') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'R', 'G', 'B') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 0 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 0 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'B', 'G', 'R') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'R', 'G', 'B') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'R', 'G', 'B') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 24 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 24 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '1', '1', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '1', 'W', '0') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '0', 'W', '1') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 8 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 8 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 4 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 4 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '4', 'B', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', 'B', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 48 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'R', 'A', 64 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'B', 'A', 64 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'B', 'R', 'A') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'R', 'B', 'A') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 12 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 11 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 12 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 10 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 12 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 0 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 14 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 11 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 14 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 10 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 14 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 0 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '1', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '3', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 8 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 8 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 8 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '2', 0 , 8 ) },
+ { AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 16 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 16 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'B', 'G', 'R') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'R', 'G', 'B') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'B', 'G', 'R') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'R', 'G', 'B') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 12 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 12 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'B', 'G', 'R') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'R', 'G', 'B') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 0 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 0 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'B', 'G', 'R') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'R', 'G', 'B') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'R', 'G', 'B') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 24 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 24 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '1', '1', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '1', 'W', '0') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '0', 'W', '1') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 8 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 8 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 4 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 4 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '4', 'B', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', 'B', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 48 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'R', 'A', 64 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'B', 'A', 64 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'B', 'R', 'A') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'R', 'B', 'A') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 10 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 10 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 10 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 12 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 11 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 12 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 10 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 12 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 0 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 14 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 11 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 14 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 10 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 14 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 0 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 16 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '1', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 16 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 16 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '3', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 8 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 8 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 8 ) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '2', 0 , 8 ) },
+
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0, 9) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(9, 0, '1', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11, 9) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(9, 11, '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10, 9) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(9, 10, '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0, 9) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(9, 0, '4', 'Y') },
+
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0, 10) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10, 0, '1', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11, 10) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10, 11, '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10, 10) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10, 10, '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0, 10) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10, 0, '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 9 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 0 , '1', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 9 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 11 , '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 9 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 10 , '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 9 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 0 , '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0, 16) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16, 0, '1', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11, 16) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16, 11, '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10, 16) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16, 10, '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0, 16) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16, 0, '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '1', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 10 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('G', '3', 0, 8) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '1', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '4', 'Y') },
- { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 16 ) },
- { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '4', 'Y') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('G', '3', 0, 9) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG( 9, 0, '3', 'G') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('G', '3', 0, 10) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(10, 0, '3', 'G') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('G', '3', 0, 12) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(12, 0, '3', 'G') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('G', '3', 0, 14) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(14, 0, '3', 'G') },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG('G', '3', 0, 16) },
+ { AV_CODEC_ID_RAWVIDEO, MKTAG(16, 0, '3', 'G') },
- { AV_CODEC_ID_NONE , 0 }
+ { AV_CODEC_ID_NONE, 0 }
};
static const AVCodecTag nut_audio_extra_tags[] = {
@@ -186,42 +199,46 @@ const AVCodecTag * const ff_nut_codec_tags[] = {
ff_codec_bmp_tags, ff_codec_wav_tags, nut_audio_extra_tags, ff_nut_data_tags, 0
};
-void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val){
+void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val)
+{
int i;
- for(i=0; i<nut->avf->nb_streams; i++){
- nut->stream[i].last_pts= av_rescale_rnd(
- val,
- time_base.num * (int64_t)nut->stream[i].time_base->den,
- time_base.den * (int64_t)nut->stream[i].time_base->num,
- AV_ROUND_DOWN);
- }
+ for (i = 0; i < nut->avf->nb_streams; i++)
+ nut->stream[i].last_pts =
+ av_rescale_rnd(val,
+ time_base.num * (int64_t)nut->stream[i].time_base->den,
+ time_base.den * (int64_t)nut->stream[i].time_base->num,
+ AV_ROUND_DOWN);
}
-int64_t ff_lsb2full(StreamContext *stream, int64_t lsb){
- int64_t mask = (1ULL<<stream->msb_pts_shift)-1;
- int64_t delta= stream->last_pts - mask/2;
- return ((lsb - delta)&mask) + delta;
+int64_t ff_lsb2full(StreamContext *stream, int64_t lsb)
+{
+ int64_t mask = (1ULL << stream->msb_pts_shift) - 1;
+ int64_t delta = stream->last_pts - mask / 2;
+ return ((lsb - delta) & mask) + delta;
}
-int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b){
+int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b)
+{
return ((a->pos - b->pos) >> 32) - ((b->pos - a->pos) >> 32);
}
-int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b){
+int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b)
+{
return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32);
}
-void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){
- Syncpoint *sp= av_mallocz(sizeof(Syncpoint));
+void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts)
+{
+ Syncpoint *sp = av_mallocz(sizeof(Syncpoint));
struct AVTreeNode *node = av_tree_node_alloc();
nut->sp_count++;
- sp->pos= pos;
- sp->back_ptr= back_ptr;
- sp->ts= ts;
+ sp->pos = pos;
+ sp->back_ptr = back_ptr;
+ sp->ts = ts;
av_tree_insert(&nut->syncpoints, sp, (void *) ff_nut_sp_pos_cmp, &node);
- if(node){
+ if (node) {
av_free(sp);
av_free(node);
}
@@ -240,13 +257,13 @@ void ff_nut_free_sp(NUTContext *nut)
}
const Dispositions ff_nut_dispositions[] = {
- {"default" , AV_DISPOSITION_DEFAULT},
- {"dub" , AV_DISPOSITION_DUB},
- {"original" , AV_DISPOSITION_ORIGINAL},
- {"comment" , AV_DISPOSITION_COMMENT},
- {"lyrics" , AV_DISPOSITION_LYRICS},
- {"karaoke" , AV_DISPOSITION_KARAOKE},
- {"" , 0}
+ { "default", AV_DISPOSITION_DEFAULT },
+ { "dub", AV_DISPOSITION_DUB },
+ { "original", AV_DISPOSITION_ORIGINAL },
+ { "comment", AV_DISPOSITION_COMMENT },
+ { "lyrics", AV_DISPOSITION_LYRICS },
+ { "karaoke", AV_DISPOSITION_KARAOKE },
+ { "", 0 }
};
const AVMetadataConv ff_nut_metadata_conv[] = {
diff --git a/chromium/third_party/ffmpeg/libavformat/nut.h b/chromium/third_party/ffmpeg/libavformat/nut.h
index ab31c274291..dc5af15a572 100644
--- a/chromium/third_party/ffmpeg/libavformat/nut.h
+++ b/chromium/third_party/ffmpeg/libavformat/nut.h
@@ -22,9 +22,6 @@
#ifndef AVFORMAT_NUT_H
#define AVFORMAT_NUT_H
-//#include <limits.h>
-//#include "libavutil/adler32.h"
-//#include "libavcodec/mpegaudio.h"
#include "avformat.h"
#include "internal.h"
#include "metadata.h"
@@ -39,6 +36,8 @@
#define MAX_DISTANCE (1024*32-1)
+#define NUT_VERSION 3
+
typedef enum{
FLAG_KEY = 1, ///<if set, frame is keyframe
FLAG_EOR = 2, ///<if set, stream has no relevance on presentation. (EOR)
diff --git a/chromium/third_party/ffmpeg/libavformat/nutdec.c b/chromium/third_party/ffmpeg/libavformat/nutdec.c
index 88965181424..13048fba970 100644
--- a/chromium/third_party/ffmpeg/libavformat/nutdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/nutdec.c
@@ -196,7 +196,7 @@ static int nut_probe(AVProbeData *p)
tmp = ffio_read_varlen(bc); \
if (!(check)) { \
av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \
- return -1; \
+ return AVERROR_INVALIDDATA; \
} \
dst = tmp; \
} while (0)
@@ -206,7 +206,7 @@ static int skip_reserved(AVIOContext *bc, int64_t pos)
pos -= avio_tell(bc);
if (pos < 0) {
avio_seek(bc, pos, SEEK_CUR);
- return -1;
+ return AVERROR_INVALIDDATA;
} else {
while (pos--)
avio_r8(bc);
@@ -226,7 +226,13 @@ static int decode_main_header(NUTContext *nut)
end = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
end += avio_tell(bc);
- GET_V(tmp, tmp >= 2 && tmp <= 3);
+ tmp = ffio_read_varlen(bc);
+ if (tmp < 2 && tmp > NUT_VERSION) {
+ av_log(s, AV_LOG_ERROR, "Version %"PRId64" not supported.\n",
+ tmp);
+ return AVERROR(ENOSYS);
+ }
+
GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS);
nut->max_distance = ffio_read_varlen(bc);
@@ -389,7 +395,7 @@ static int decode_stream_header(NUTContext *nut)
break;
default:
av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
- return -1;
+ return AVERROR(ENOSYS);
}
if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE)
av_log(s, AV_LOG_ERROR,
@@ -418,7 +424,7 @@ static int decode_stream_header(NUTContext *nut)
if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n",
st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
- return -1;
+ return AVERROR_INVALIDDATA;
}
ffio_read_varlen(bc); /* csp type */
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -429,7 +435,7 @@ static int decode_stream_header(NUTContext *nut)
if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
av_log(s, AV_LOG_ERROR,
"stream header %d checksum mismatch\n", stream_id);
- return -1;
+ return AVERROR_INVALIDDATA;
}
stc->time_base = &nut->time_base[stc->time_base_id];
avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num,
@@ -537,7 +543,7 @@ static int decode_info_header(NUTContext *nut)
if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
return 0;
}
@@ -580,14 +586,8 @@ static int64_t find_duration(NUTContext *nut, int64_t filesize)
AVFormatContext *s = nut->avf;
int64_t duration = 0;
- int64_t pos = FFMAX(0, filesize - 2*nut->max_distance);
- for(;;){
- int64_t ts = nut_read_timestamp(s, -1, &pos, INT64_MAX);
- if(ts < 0)
- break;
- duration = FFMAX(duration, ts);
- pos++;
- }
+ ff_find_last_ts(s, -1, &duration, NULL, nut_read_timestamp);
+
if(duration > 0)
s->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
return duration;
@@ -601,8 +601,9 @@ static int find_and_decode_index(NUTContext *nut)
int i, j, syncpoint_count;
int64_t filesize = avio_size(bc);
int64_t *syncpoints;
+ uint64_t max_pts;
int8_t *has_keyframe;
- int ret = -1;
+ int ret = AVERROR_INVALIDDATA;
if(filesize <= 0)
return -1;
@@ -614,13 +615,18 @@ static int find_and_decode_index(NUTContext *nut)
if(s->duration<=0)
s->duration = find_duration(nut, filesize);
- return -1;
+ return ret;
}
end = get_packetheader(nut, bc, 1, INDEX_STARTCODE);
end += avio_tell(bc);
- ffio_read_varlen(bc); // max_pts
+ max_pts = ffio_read_varlen(bc);
+ s->duration = av_rescale_q(max_pts / nut->time_base_count,
+ nut->time_base[max_pts % nut->time_base_count],
+ AV_TIME_BASE_Q);
+ s->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
+
GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0);
syncpoints = av_malloc(sizeof(int64_t) * syncpoint_count);
has_keyframe = av_malloc(sizeof(int8_t) * (syncpoint_count + 1));
@@ -891,7 +897,7 @@ static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
} else {
frame_code = avio_r8(bc);
if (url_feof(bc))
- return -1;
+ return AVERROR_EOF;
if (frame_code == 'N') {
tmp = frame_code;
for (i = 1; i < 8; i++)
diff --git a/chromium/third_party/ffmpeg/libavformat/nutenc.c b/chromium/third_party/ffmpeg/libavformat/nutenc.c
index 2d8d2652ee5..9b7f41af8da 100644
--- a/chromium/third_party/ffmpeg/libavformat/nutenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/nutenc.c
@@ -91,7 +91,7 @@ static int find_expected_header(AVCodecContext *c, int size, int key_frame,
header |= (bitrate_index & 1) << 9;
return 2; //FIXME actually put the needed ones in build_elision_headers()
- return 3; //we guess that the private bit is not set
+ //return 3; //we guess that the private bit is not set
//FIXME the above assumptions should be checked, if these turn out false too often something should be done
}
return 0;
@@ -335,7 +335,7 @@ static void write_mainheader(NUTContext *nut, AVIOContext *bc)
tmp_head_idx;
int64_t tmp_match;
- ff_put_v(bc, 3); /* version */
+ ff_put_v(bc, NUT_VERSION);
ff_put_v(bc, nut->avf->nb_streams);
ff_put_v(bc, nut->max_distance);
ff_put_v(bc, nut->time_base_count);
diff --git a/chromium/third_party/ffmpeg/libavformat/oggdec.c b/chromium/third_party/ffmpeg/libavformat/oggdec.c
index fd954b805b8..03a2618bec6 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggdec.c
@@ -671,7 +671,12 @@ static int ogg_read_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
ogg->streams[i].codec = NULL;
} else if (os->codec && os->nb_header < os->codec->nb_header) {
- av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
+ av_log(s, AV_LOG_WARNING,
+ "Headers mismatch for stream %d: "
+ "expected %d received %d.\n",
+ i, os->codec->nb_header, os->nb_header);
+ if (s->error_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
if (os->start_granule != OGG_NOGRANULE_VALUE)
os->lastpts = s->streams[i]->start_time =
@@ -854,5 +859,5 @@ AVInputFormat ff_ogg_demuxer = {
.read_seek = ogg_read_seek,
.read_timestamp = ogg_read_timestamp,
.extensions = "ogg",
- .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/oggenc.c b/chromium/third_party/ffmpeg/libavformat/oggenc.c
index 9a815d14a2e..3135de67767 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggenc.c
@@ -447,11 +447,13 @@ static int ogg_write_header(AVFormatContext *s)
} while (j < i);
oggstream->serial_num = serial_num;
+ av_dict_copy(&st->metadata, s->metadata, AV_DICT_DONT_OVERWRITE);
+
st->priv_data = oggstream;
if (st->codec->codec_id == AV_CODEC_ID_FLAC) {
int err = ogg_build_flac_headers(st->codec, oggstream,
st->codec->flags & CODEC_FLAG_BITEXACT,
- &s->metadata);
+ &st->metadata);
if (err) {
av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
av_freep(&st->priv_data);
@@ -460,7 +462,7 @@ static int ogg_write_header(AVFormatContext *s)
} else if (st->codec->codec_id == AV_CODEC_ID_SPEEX) {
int err = ogg_build_speex_headers(st->codec, oggstream,
st->codec->flags & CODEC_FLAG_BITEXACT,
- &s->metadata);
+ &st->metadata);
if (err) {
av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
av_freep(&st->priv_data);
@@ -469,7 +471,7 @@ static int ogg_write_header(AVFormatContext *s)
} else if (st->codec->codec_id == AV_CODEC_ID_OPUS) {
int err = ogg_build_opus_headers(st->codec, oggstream,
st->codec->flags & CODEC_FLAG_BITEXACT,
- &s->metadata);
+ &st->metadata);
if (err) {
av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
av_freep(&st->priv_data);
@@ -490,7 +492,7 @@ static int ogg_write_header(AVFormatContext *s)
}
p = ogg_write_vorbiscomment(7, st->codec->flags & CODEC_FLAG_BITEXACT,
- &oggstream->header_len[1], &s->metadata,
+ &oggstream->header_len[1], &st->metadata,
framing_bit);
oggstream->header[1] = p;
if (!p)
@@ -632,5 +634,6 @@ AVOutputFormat ff_ogg_muxer = {
.write_header = ogg_write_header,
.write_packet = ogg_write_packet,
.write_trailer = ogg_write_trailer,
+ .flags = AVFMT_TS_NEGATIVE,
.priv_class = &ogg_muxer_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparseskeleton.c b/chromium/third_party/ffmpeg/libavformat/oggparseskeleton.c
index 307387d065a..d94b0c2e07b 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparseskeleton.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparseskeleton.c
@@ -37,6 +37,9 @@ static int skeleton_header(AVFormatContext *s, int idx)
strcpy(st->codec->codec_name, "skeleton");
st->codec->codec_type = AVMEDIA_TYPE_DATA;
+ if ((os->flags & OGG_FLAG_EOS) && os->psize == 0)
+ return 1;
+
if (os->psize < 8)
return -1;
@@ -74,12 +77,16 @@ static int skeleton_header(AVFormatContext *s, int idx)
target_idx = ogg_find_stream(ogg, AV_RL32(buf+12));
start_granule = AV_RL64(buf+36);
+ if (target_idx < 0) {
+ av_log(s, AV_LOG_WARNING, "Serial number in fisbone doesn't match any stream\n");
+ return 1;
+ }
+ os = ogg->streams + target_idx;
if (os->start_granule != OGG_NOGRANULE_VALUE) {
- avpriv_report_missing_feature(s,
- "Multiple fisbone for the same stream");
+ av_log(s, AV_LOG_WARNING, "Multiple fisbone for the same stream\n");
return 1;
}
- if (target_idx >= 0 && start_granule != OGG_NOGRANULE_VALUE) {
+ if (start_granule != OGG_NOGRANULE_VALUE) {
os->start_granule = start_granule;
}
}
diff --git a/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c b/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
index da029a47df8..7d525f43dcf 100644
--- a/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
+++ b/chromium/third_party/ffmpeg/libavformat/oggparsevorbis.c
@@ -24,12 +24,14 @@
#include <stdlib.h>
#include "libavutil/avstring.h"
+#include "libavutil/base64.h"
#include "libavutil/bswap.h"
#include "libavutil/dict.h"
#include "libavcodec/get_bits.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/vorbis_parser.h"
#include "avformat.h"
+#include "flacdec.h"
#include "internal.h"
#include "oggdec.h"
#include "vorbiscomment.h"
@@ -39,10 +41,10 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
int i, cnum, h, m, s, ms, keylen = strlen(key);
AVChapter *chapter = NULL;
- if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
+ if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1)
return 0;
- if (keylen == 9) {
+ if (keylen <= 10) {
if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
return 0;
@@ -50,7 +52,7 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
ms + 1000*(s + 60*(m + 60*h)),
AV_NOPTS_VALUE, NULL);
av_free(val);
- } else if (!strcmp(key+9, "NAME")) {
+ } else if (!strcmp(key+(keylen-4), "NAME")) {
for(i = 0; i < as->nb_chapters; i++)
if (as->chapters[i]->id == cnum) {
chapter = as->chapters[i];
@@ -128,7 +130,26 @@ ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, in
memcpy(ct, v, vl);
ct[vl] = 0;
- if (!ogm_chapter(as, tt, ct))
+ if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) {
+ int ret;
+ char *pict = av_malloc(vl);
+
+ if (!pict) {
+ av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
+ av_freep(&tt);
+ av_freep(&ct);
+ continue;
+ }
+ if ((ret = av_base64_decode(pict, ct, vl)) > 0)
+ ret = ff_flac_parse_picture(as, pict, ret);
+ av_freep(&pict);
+ av_freep(&tt);
+ av_freep(&ct);
+ if (ret < 0) {
+ av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
+ continue;
+ }
+ } else if (!ogm_chapter(as, tt, ct))
av_dict_set(m, tt, ct,
AV_DICT_DONT_STRDUP_KEY |
AV_DICT_DONT_STRDUP_VAL);
@@ -216,15 +237,15 @@ vorbis_header (AVFormatContext * s, int idx)
struct oggvorbis_private *priv;
int pkt_type = os->buf[os->pstart];
- if (!(pkt_type & 1))
- return os->private ? 0 : -1;
-
if (!os->private) {
os->private = av_mallocz(sizeof(struct oggvorbis_private));
if (!os->private)
return -1;
}
+ if (!(pkt_type & 1))
+ return 0;
+
if (os->psize < 1 || pkt_type > 5)
return -1;
diff --git a/chromium/third_party/ffmpeg/libavformat/omadec.c b/chromium/third_party/ffmpeg/libavformat/omadec.c
index ae359074f9d..d05795494c8 100644
--- a/chromium/third_party/ffmpeg/libavformat/omadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/omadec.c
@@ -73,18 +73,20 @@ typedef struct OMAContext {
struct AVDES av_des;
} OMAContext;
-static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len)
+static void hex_log(AVFormatContext *s, int level,
+ const char *name, const uint8_t *value, int len)
{
char buf[33];
len = FFMIN(len, 16);
if (av_log_get_level() < level)
return;
ff_data_to_hex(buf, value, len, 1);
- buf[len<<1] = '\0';
+ buf[len << 1] = '\0';
av_log(s, level, "%s: %s\n", name, buf);
}
-static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len)
+static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val,
+ int len)
{
OMAContext *oc = s->priv_data;
@@ -112,13 +114,18 @@ static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val,
return 0;
}
-static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
+#define OMA_RPROBE_M_VAL 48 + 1
+
+static int rprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
+ const uint8_t *r_val)
{
OMAContext *oc = s->priv_data;
unsigned int pos;
struct AVDES av_des;
- if (!enc_header || !r_val)
+ if (!enc_header || !r_val ||
+ size < OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size ||
+ size < OMA_RPROBE_M_VAL)
return -1;
/* m_val */
@@ -139,35 +146,41 @@ static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
}
-static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val)
+static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
+ const uint8_t *n_val)
{
OMAContext *oc = s->priv_data;
- uint32_t pos, taglen, datalen;
+ uint64_t pos;
+ uint32_t taglen, datalen;
struct AVDES av_des;
- if (!enc_header || !n_val)
+ if (!enc_header || !n_val ||
+ size < OMA_ENC_HEADER_SIZE + oc->k_size + 4)
return -1;
pos = OMA_ENC_HEADER_SIZE + oc->k_size;
if (!memcmp(&enc_header[pos], "EKB ", 4))
pos += 32;
+ if (size < pos + 44)
+ return -1;
+
if (AV_RB32(&enc_header[pos]) != oc->rid)
av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
- taglen = AV_RB32(&enc_header[pos+32]);
- datalen = AV_RB32(&enc_header[pos+36]) >> 4;
-
- if(pos + (uint64_t)taglen + (((uint64_t)datalen)<<4) + 44 > size)
- return -1;
+ taglen = AV_RB32(&enc_header[pos + 32]);
+ datalen = AV_RB32(&enc_header[pos + 36]) >> 4;
pos += 44 + taglen;
+ if (pos + (((uint64_t)datalen) << 4) > size)
+ return -1;
+
av_des_init(&av_des, n_val, 192, 1);
while (datalen-- > 0) {
av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
kset(s, oc->r_val, NULL, 16);
- if (!rprobe(s, enc_header, oc->r_val))
+ if (!rprobe(s, enc_header, size, oc->r_val))
return 0;
pos += 16;
}
@@ -196,12 +209,13 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
}
if (!em) {
av_log(s, AV_LOG_ERROR, "No encryption header found\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (geob->datasize < 64) {
- av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize);
- return -1;
+ av_log(s, AV_LOG_ERROR,
+ "Invalid GEOB data size: %u\n", geob->datasize);
+ return AVERROR_INVALIDDATA;
}
gdata = geob->data;
@@ -216,7 +230,7 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) {
av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if ( OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize
|| OMA_ENC_HEADER_SIZE + 48 > geob->datasize
@@ -230,32 +244,36 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
memcpy(oc->iv, &header[0x58], 8);
hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
- hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8);
+ hex_log(s, AV_LOG_DEBUG, "CBC-MAC",
+ &gdata[OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size],
+ 8);
if (s->keylen > 0) {
kset(s, s->key, s->key, s->keylen);
}
if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
- rprobe(s, gdata, oc->r_val) < 0 &&
+ rprobe(s, gdata, geob->datasize, oc->r_val) < 0 &&
nprobe(s, gdata, geob->datasize, oc->n_val) < 0) {
int i;
for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
uint8_t buf[16];
- AV_WL64(buf, leaf_table[i]);
- AV_WL64(&buf[8], leaf_table[i+1]);
+ AV_WL64(buf, leaf_table[i]);
+ AV_WL64(&buf[8], leaf_table[i + 1]);
kset(s, buf, buf, 16);
- if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val))
+ if (!rprobe(s, gdata, geob->datasize, oc->r_val) ||
+ !nprobe(s, gdata, geob->datasize, oc->n_val))
break;
}
if (i >= FF_ARRAY_ELEMS(leaf_table)) {
av_log(s, AV_LOG_ERROR, "Invalid key\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
/* e_val */
av_des_init(&oc->av_des, oc->m_val, 64, 0);
- av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
+ av_des_crypt(&oc->av_des, oc->e_val,
+ &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
/* init e_val */
@@ -280,9 +298,10 @@ static int oma_read_header(AVFormatContext *s)
if (ret < EA3_HEADER_SIZE)
return -1;
- if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
+ if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) ||
+ buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
oc->content_start = avio_tell(s->pb);
@@ -303,74 +322,80 @@ static int oma_read_header(AVFormatContext *s)
return AVERROR(ENOMEM);
st->start_time = 0;
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_tag = buf[32];
- st->codec->codec_id = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag);
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_tag = buf[32];
+ st->codec->codec_id = ff_codec_get_id(ff_oma_codec_tags,
+ st->codec->codec_tag);
switch (buf[32]) {
- case OMA_CODECID_ATRAC3:
- 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;
- }
- if (samplerate != 44100)
- avpriv_request_sample(s, "Sample rate %d", samplerate);
-
- framesize = (codec_params & 0x3FF) * 8;
- jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
- st->codec->channels = 2;
- st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
- st->codec->sample_rate = samplerate;
- st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
-
- /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
- st->codec->extradata_size = 14;
- edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!edata)
- return AVERROR(ENOMEM);
-
- st->codec->extradata = edata;
- AV_WL16(&edata[0], 1); // always 1
- AV_WL32(&edata[2], samplerate); // samples rate
- AV_WL16(&edata[6], jsflag); // coding mode
- AV_WL16(&edata[8], jsflag); // coding mode
- AV_WL16(&edata[10], 1); // always 1
- // AV_WL16(&edata[12], 0); // always 0
-
- avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
- break;
- case OMA_CODECID_ATRAC3P:
- st->codec->channels = (codec_params >> 10) & 7;
- framesize = ((codec_params & 0x3FF) * 8) + 8;
- 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;
- }
- st->codec->sample_rate = samplerate;
- st->codec->bit_rate = samplerate * framesize * 8 / 1024;
- avpriv_set_pts_info(st, 64, 1, samplerate);
- av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
- break;
- case OMA_CODECID_MP3:
- st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
- framesize = 1024;
- break;
- case OMA_CODECID_LPCM:
- /* PCM 44.1 kHz 16 bit stereo big-endian */
- st->codec->channels = 2;
- st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
- st->codec->sample_rate = 44100;
- framesize = 1024;
- /* bit rate = sample rate x PCM block align (= 4) x 8 */
- st->codec->bit_rate = st->codec->sample_rate * 32;
- st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
- avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
- break;
- default:
- av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
- return -1;
+ case OMA_CODECID_ATRAC3:
+ 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;
+ }
+ if (samplerate != 44100)
+ avpriv_request_sample(s, "Sample rate %d", samplerate);
+
+ framesize = (codec_params & 0x3FF) * 8;
+
+ /* get stereo coding mode, 1 for joint-stereo */
+ jsflag = (codec_params >> 17) & 1;
+
+ st->codec->channels = 2;
+ st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+ st->codec->sample_rate = samplerate;
+ st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
+
+ /* fake the atrac3 extradata
+ * (wav format, makes stream copy to wav work) */
+ st->codec->extradata_size = 14;
+ edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!edata)
+ return AVERROR(ENOMEM);
+
+ st->codec->extradata = edata;
+ AV_WL16(&edata[0], 1); // always 1
+ AV_WL32(&edata[2], samplerate); // samples rate
+ AV_WL16(&edata[6], jsflag); // coding mode
+ AV_WL16(&edata[8], jsflag); // coding mode
+ AV_WL16(&edata[10], 1); // always 1
+ // AV_WL16(&edata[12], 0); // always 0
+
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ break;
+ case OMA_CODECID_ATRAC3P:
+ st->codec->channels = (codec_params >> 10) & 7;
+ framesize = ((codec_params & 0x3FF) * 8) + 8;
+ 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;
+ }
+ st->codec->sample_rate = samplerate;
+ st->codec->bit_rate = samplerate * framesize * 8 / 1024;
+ avpriv_set_pts_info(st, 64, 1, samplerate);
+ av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
+ break;
+ case OMA_CODECID_MP3:
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+ framesize = 1024;
+ break;
+ case OMA_CODECID_LPCM:
+ /* PCM 44.1 kHz 16 bit stereo big-endian */
+ st->codec->channels = 2;
+ st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+ st->codec->sample_rate = 44100;
+ framesize = 1024;
+ /* bit rate = sample rate x PCM block align (= 4) x 8 */
+ st->codec->bit_rate = st->codec->sample_rate * 32;
+ st->codec->bits_per_coded_sample =
+ av_get_bits_per_sample(st->codec->codec_id);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]);
+ return AVERROR(ENOSYS);
}
st->codec->block_align = framesize;
@@ -385,14 +410,24 @@ static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
int packet_size = s->streams[0]->codec->block_align;
int ret = av_get_packet(s->pb, pkt, packet_size);
- if (ret <= 0)
- return AVERROR(EIO);
+ if (ret < packet_size)
+ pkt->flags |= AV_PKT_FLAG_CORRUPT;
+
+ if (ret < 0)
+ return ret;
+ if (!ret)
+ return AVERROR_EOF;
pkt->stream_index = 0;
if (oc->encrypted) {
- /* previous unencrypted block saved in IV for the next packet (CBC mode) */
- av_des_crypt(&oc->av_des, pkt->data, pkt->data, (ret >> 3), oc->iv, 1);
+ /* previous unencrypted block saved in IV for
+ * the next packet (CBC mode) */
+ if (ret == packet_size)
+ av_des_crypt(&oc->av_des, pkt->data, pkt->data,
+ (packet_size >> 3), oc->iv, 1);
+ else
+ memset(oc->iv, 0, 8);
}
return ret;
@@ -416,7 +451,7 @@ static int oma_read_probe(AVProbeData *p)
/* This check cannot overflow as tag_len has at most 28 bits */
if (p->buf_size < tag_len + 5)
/* EA3 header comes late, might be outside of the probe buffer */
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
buf += tag_len;
@@ -426,26 +461,30 @@ static int oma_read_probe(AVProbeData *p)
return 0;
}
-static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int oma_read_seek(struct AVFormatContext *s,
+ int stream_index, int64_t timestamp, int flags)
{
OMAContext *oc = s->priv_data;
-
- ff_pcm_read_seek(s, stream_index, timestamp, flags);
-
- if (oc->encrypted) {
- /* readjust IV for CBC */
- int64_t pos = avio_tell(s->pb);
- if (pos < oc->content_start)
- memset(oc->iv, 0, 8);
- else {
- if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
- memset(oc->iv, 0, 8);
- return -1;
- }
- }
+ int err = ff_pcm_read_seek(s, stream_index, timestamp, flags);
+
+ if (!oc->encrypted)
+ return err;
+
+ /* readjust IV for CBC */
+ if (err || avio_tell(s->pb) < oc->content_start)
+ goto wipe;
+ if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0)
+ goto wipe;
+ if ((err = avio_read(s->pb, oc->iv, 8)) < 8) {
+ if (err >= 0)
+ err = AVERROR_EOF;
+ goto wipe;
}
return 0;
+wipe:
+ memset(oc->iv, 0, 8);
+ return err;
}
AVInputFormat ff_oma_demuxer = {
diff --git a/chromium/third_party/ffmpeg/libavformat/options.c b/chromium/third_party/ffmpeg/libavformat/options.c
index 42307d170f6..5218e5b92a4 100644
--- a/chromium/third_party/ffmpeg/libavformat/options.c
+++ b/chromium/third_party/ffmpeg/libavformat/options.c
@@ -86,7 +86,7 @@ static AVClassCategory get_category(void *ptr)
static const AVClass av_format_context_class = {
.class_name = "AVFormatContext",
.item_name = format_to_name,
- .option = options,
+ .option = avformat_options,
.version = LIBAVUTIL_VERSION_INT,
.child_next = format_child_next,
.child_class_next = format_child_class_next,
diff --git a/chromium/third_party/ffmpeg/libavformat/options_table.h b/chromium/third_party/ffmpeg/libavformat/options_table.h
index 9f8613764c5..a87868e162f 100644
--- a/chromium/third_party/ffmpeg/libavformat/options_table.h
+++ b/chromium/third_party/ffmpeg/libavformat/options_table.h
@@ -32,7 +32,7 @@
#define E AV_OPT_FLAG_ENCODING_PARAM
#define D AV_OPT_FLAG_DECODING_PARAM
-static const AVOption options[]={
+static const AVOption avformat_options[] = {
{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.i64 = 5000000 }, 32, INT_MAX, D},
@@ -45,7 +45,7 @@ static const AVOption options[]={
{"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
{"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
{"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
-{"keepside", "dont merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
+{"keepside", "don't merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
{"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"},
{"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"},
{"seek2any", "forces seeking to enable seek to any mode", OFFSET(seek2any), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, D},
@@ -70,9 +70,9 @@ static const AVOption options[]={
{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"},
{"careful", "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, "err_detect"},
{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"},
-{"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
+{"aggressive", "consider things that a sane encoder shouldn't do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
{"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D},
-{"avoid_negative_ts", "shift timestamps to make them positive. 1 enables, 0 disables, default of -1 enables when required by target format.", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
+{"avoid_negative_ts", "shift timestamps to make them non-negative. 1 enables, 0 disables, default of -1 enables when required by target format.", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
{"skip_initial_bytes", "skip initial bytes", OFFSET(skip_initial_bytes), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D},
{"correct_ts_overflow", "correct single timestamp overflows", OFFSET(correct_ts_overflow), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, D},
{"flush_packets", "enable flushing of the I/O context after each packet", OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E},
diff --git a/chromium/third_party/ffmpeg/libavformat/os_support.c b/chromium/third_party/ffmpeg/libavformat/os_support.c
index dc88834bf33..3218956df5e 100644
--- a/chromium/third_party/ffmpeg/libavformat/os_support.c
+++ b/chromium/third_party/ffmpeg/libavformat/os_support.c
@@ -27,46 +27,6 @@
#include "avformat.h"
#include "os_support.h"
-#if defined(_WIN32) && !defined(__MINGW32CE__)
-#undef open
-#undef lseek
-#undef stat
-#undef fstat
-#include <fcntl.h>
-#include <io.h>
-#include <windows.h>
-#include <share.h>
-#include <errno.h>
-
-int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
-{
- int fd;
- int num_chars;
- wchar_t *filename_w;
-
- /* convert UTF-8 to wide chars */
- num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
- if (num_chars <= 0)
- goto fallback;
- filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
- if (!filename_w) {
- errno = ENOMEM;
- return -1;
- }
- MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
-
- fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
- av_freep(&filename_w);
-
- if (fd != -1 || (oflag & O_CREAT))
- return fd;
-
-fallback:
- /* filename may be be in CP_ACP */
- return _sopen(filename_utf8, oflag, SH_DENYNO, pmode);
-}
-#endif
-
#if CONFIG_NETWORK
#include <fcntl.h>
#if !HAVE_POLL_H
diff --git a/chromium/third_party/ffmpeg/libavformat/os_support.h b/chromium/third_party/ffmpeg/libavformat/os_support.h
index e5f31e05a4c..b0f02c11f14 100644
--- a/chromium/third_party/ffmpeg/libavformat/os_support.h
+++ b/chromium/third_party/ffmpeg/libavformat/os_support.h
@@ -86,11 +86,6 @@ static inline int is_dos_path(const char *path)
#endif
#endif
-#if defined(_WIN32) && !defined(__MINGW32CE__)
-int ff_win32_open(const char *filename, int oflag, int pmode);
-#define open ff_win32_open
-#endif
-
#if CONFIG_NETWORK
#if !HAVE_SOCKLEN_T
typedef int socklen_t;
diff --git a/chromium/third_party/ffmpeg/libavformat/paf.c b/chromium/third_party/ffmpeg/libavformat/paf.c
index 09786eb34f1..09aefe6770b 100644
--- a/chromium/third_party/ffmpeg/libavformat/paf.c
+++ b/chromium/third_party/ffmpeg/libavformat/paf.c
@@ -233,10 +233,11 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
p->current_frame_block++;
}
- size = p->video_size - p->frames_offset_table[p->current_frame];
- if (size < 1)
+ if (p->frames_offset_table[p->current_frame] >= p->video_size)
return AVERROR_INVALIDDATA;
+ size = p->video_size - p->frames_offset_table[p->current_frame];
+
if (av_new_packet(pkt, size) < 0)
return AVERROR(ENOMEM);
diff --git a/chromium/third_party/ffmpeg/libavformat/pmpdec.c b/chromium/third_party/ffmpeg/libavformat/pmpdec.c
index 2fe6c46e13d..71f450e9d37 100644
--- a/chromium/third_party/ffmpeg/libavformat/pmpdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/pmpdec.c
@@ -174,7 +174,7 @@ static int pmp_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags)
{
PMPContext *pmp = s->priv_data;
pmp->cur_stream = 0;
- // fallback to default seek now
+ // fall back on default seek now
return -1;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/psxstr.c b/chromium/third_party/ffmpeg/libavformat/psxstr.c
index 90c933ecd62..3409d6a5af8 100644
--- a/chromium/third_party/ffmpeg/libavformat/psxstr.c
+++ b/chromium/third_party/ffmpeg/libavformat/psxstr.c
@@ -30,6 +30,7 @@
*/
#include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "internal.h"
@@ -126,7 +127,7 @@ static int str_probe(AVProbeData *p)
}
/* MPEG files (like those ripped from VCDs) can also look like this;
* only return half certainty */
- if(vid+aud > 3) return 50;
+ if(vid+aud > 3) return AVPROBE_SCORE_EXTENSION;
else if(vid+aud) return 1;
else return 0;
}
@@ -237,7 +238,9 @@ static int str_read_packet(AVFormatContext *s,
pkt->size= -1;
pkt->buf = NULL;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/pva.c b/chromium/third_party/ffmpeg/libavformat/pva.c
index ae42c8363d2..9b7a40a0682 100644
--- a/chromium/third_party/ffmpeg/libavformat/pva.c
+++ b/chromium/third_party/ffmpeg/libavformat/pva.c
@@ -49,7 +49,7 @@ static int pva_probe(AVProbeData * pd) {
if (pd->buf_size >= len + 8 &&
pva_check(buf + len) >= 0)
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
return AVPROBE_SCORE_MAX / 4;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/r3d.c b/chromium/third_party/ffmpeg/libavformat/r3d.c
index 3b3ecce3d93..8459cddc705 100644
--- a/chromium/third_party/ffmpeg/libavformat/r3d.c
+++ b/chromium/third_party/ffmpeg/libavformat/r3d.c
@@ -19,8 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define DEBUG
-
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/mathematics.h"
diff --git a/chromium/third_party/ffmpeg/libavformat/rawdec.c b/chromium/third_party/ffmpeg/libavformat/rawdec.c
index 153cc7b04ea..a9ff22ae182 100644
--- a/chromium/third_party/ffmpeg/libavformat/rawdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rawdec.c
@@ -90,6 +90,17 @@ fail:
return ret;
}
+static int ff_raw_data_read_header(AVFormatContext *s)
+{
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_type = AVMEDIA_TYPE_DATA;
+ st->codec->codec_id = s->iformat->raw_codec_id;
+ st->start_time = 0;
+ return 0;
+}
+
/* Note: Do not forget to add new entries to the Makefile as well. */
#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
@@ -99,6 +110,16 @@ const AVOption ff_rawvideo_options[] = {
{ NULL },
};
+#if CONFIG_DATA_DEMUXER
+AVInputFormat ff_data_demuxer = {
+ .name = "data",
+ .long_name = NULL_IF_CONFIG_SMALL("raw data"),
+ .read_header = ff_raw_data_read_header,
+ .read_packet = ff_raw_read_partial_packet,
+ .raw_codec_id = AV_CODEC_ID_NONE,
+};
+#endif
+
#if CONFIG_LATM_DEMUXER
AVInputFormat ff_latm_demuxer = {
.name = "latm",
diff --git a/chromium/third_party/ffmpeg/libavformat/rawenc.c b/chromium/third_party/ffmpeg/libavformat/rawenc.c
index 7894c8e0c5d..7a1fa93e8ba 100644
--- a/chromium/third_party/ffmpeg/libavformat/rawenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/rawenc.c
@@ -68,6 +68,15 @@ AVOutputFormat ff_cavsvideo_muxer = {
};
#endif
+#if CONFIG_DATA_MUXER
+AVOutputFormat ff_data_muxer = {
+ .name = "data",
+ .long_name = NULL_IF_CONFIG_SMALL("raw data"),
+ .write_packet = ff_raw_write_packet,
+ .flags = AVFMT_NOTIMESTAMPS,
+};
+#endif
+
#if CONFIG_DIRAC_MUXER
AVOutputFormat ff_dirac_muxer = {
.name = "dirac",
diff --git a/chromium/third_party/ffmpeg/libavformat/rdt.c b/chromium/third_party/ffmpeg/libavformat/rdt.c
index 695323ab0fe..54111a5adad 100644
--- a/chromium/third_party/ffmpeg/libavformat/rdt.c
+++ b/chromium/third_party/ffmpeg/libavformat/rdt.c
@@ -98,7 +98,7 @@ ff_rdt_calc_response_and_checksum(char response[41], char chksum[9],
unsigned char zres[16],
buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 };
#define XOR_TABLE_SIZE 37
- const unsigned char xor_table[XOR_TABLE_SIZE] = {
+ static const unsigned char xor_table[XOR_TABLE_SIZE] = {
0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53,
0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70,
0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09,
@@ -548,7 +548,7 @@ rdt_free_context (PayloadContext *rdt)
}
#define RDT_HANDLER(n, s, t) \
-static RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \
+static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \
.enc_name = s, \
.codec_type = t, \
.codec_id = AV_CODEC_ID_NONE, \
@@ -565,8 +565,8 @@ RDT_HANDLER(audio, "x-pn-realaudio", AVMEDIA_TYPE_AUDIO);
void av_register_rdt_dynamic_payload_handlers(void)
{
- ff_register_dynamic_payload_handler(&ff_rdt_video_handler);
- ff_register_dynamic_payload_handler(&ff_rdt_audio_handler);
- ff_register_dynamic_payload_handler(&ff_rdt_live_video_handler);
- ff_register_dynamic_payload_handler(&ff_rdt_live_audio_handler);
+ ff_register_dynamic_payload_handler(&rdt_video_handler);
+ ff_register_dynamic_payload_handler(&rdt_audio_handler);
+ ff_register_dynamic_payload_handler(&rdt_live_video_handler);
+ ff_register_dynamic_payload_handler(&rdt_live_audio_handler);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/realtextdec.c b/chromium/third_party/ffmpeg/libavformat/realtextdec.c
index 67bc33983a5..5e4981a40b5 100644
--- a/chromium/third_party/ffmpeg/libavformat/realtextdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/realtextdec.c
@@ -41,7 +41,7 @@ static int realtext_probe(AVProbeData *p)
if (AV_RB24(ptr) == 0xEFBBBF)
ptr += 3; /* skip UTF-8 BOM */
- return !av_strncasecmp(ptr, "<window", 7) ? AVPROBE_SCORE_MAX/2 : 0;
+ return !av_strncasecmp(ptr, "<window", 7) ? AVPROBE_SCORE_EXTENSION : 0;
}
static int read_ts(const char *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/redspark.c b/chromium/third_party/ffmpeg/libavformat/redspark.c
new file mode 100644
index 00000000000..44d5da77fb3
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/redspark.c
@@ -0,0 +1,167 @@
+/*
+ * RedSpark demuxer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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 "libavcodec/bytestream.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "avio.h"
+#include "internal.h"
+
+#define HEADER_SIZE 4096
+
+typedef struct RedSparkContext {
+ int samples_count;
+} RedSparkContext;
+
+static int redspark_probe(AVProbeData *p)
+{
+ uint32_t key, data;
+ uint8_t header[8];
+
+ /* Decrypt first 8 bytes of the header */
+ data = AV_RB32(p->buf);
+ data = data ^ (key = data ^ 0x52656453);
+ AV_WB32(header, data);
+ key = (key << 11) | (key >> 21);
+
+ data = AV_RB32(p->buf + 4) ^ (((key << 3) | (key >> 29)) + key);
+ AV_WB32(header + 4, data);
+
+ if (AV_RB64(header) == AV_RB64("RedSpark"))
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+static int redspark_read_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ RedSparkContext *redspark = s->priv_data;
+ AVCodecContext *codec;
+ GetByteContext gbc;
+ int i, coef_off, ret = 0;
+ uint32_t key, data;
+ uint8_t *header, *pbc;
+ AVStream *st;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ codec = st->codec;
+
+ header = av_malloc(HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!header)
+ return AVERROR(ENOMEM);
+ pbc = header;
+
+ /* Decrypt header */
+ data = avio_rb32(pb);
+ data = data ^ (key = data ^ 0x52656453);
+ bytestream_put_be32(&pbc, data);
+ key = (key << 11) | (key >> 21);
+
+ for (i = 4; i < HEADER_SIZE; i += 4) {
+ data = avio_rb32(pb) ^ (key = ((key << 3) | (key >> 29)) + key);
+ bytestream_put_be32(&pbc, data);
+ }
+
+ codec->codec_id = AV_CODEC_ID_ADPCM_THP;
+ codec->codec_type = AVMEDIA_TYPE_AUDIO;
+
+ bytestream2_init(&gbc, header, HEADER_SIZE);
+ bytestream2_seek(&gbc, 0x3c, SEEK_SET);
+ codec->sample_rate = bytestream2_get_be32u(&gbc);
+ if (codec->sample_rate <= 0 || codec->sample_rate > 96000) {
+ av_log(s, AV_LOG_ERROR, "Invalid sample rate: %d\n", codec->sample_rate);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ st->duration = bytestream2_get_be32u(&gbc) * 14;
+ redspark->samples_count = 0;
+ bytestream2_skipu(&gbc, 10);
+ codec->channels = bytestream2_get_byteu(&gbc);
+ if (!codec->channels) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ coef_off = 0x54 + codec->channels * 8;
+ if (bytestream2_get_byteu(&gbc)) // Loop flag
+ coef_off += 16;
+
+ codec->extradata_size = 32 * codec->channels;
+ codec->extradata = av_malloc(codec->extradata_size);
+ if (!codec->extradata) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ /* Get the ADPCM table */
+ bytestream2_seek(&gbc, coef_off, SEEK_SET);
+ for (i = 0; i < codec->channels; i++) {
+ if (bytestream2_get_bufferu(&gbc, codec->extradata + i * 32, 32) != 32) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ bytestream2_skipu(&gbc, 14);
+ }
+
+ avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
+
+fail:
+ av_free(header);
+
+ return ret;
+}
+
+static int redspark_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVCodecContext *codec = s->streams[0]->codec;
+ RedSparkContext *redspark = s->priv_data;
+ uint32_t size = 8 * codec->channels;
+ int ret;
+
+ if (url_feof(s->pb) || redspark->samples_count == s->streams[0]->duration)
+ return AVERROR_EOF;
+
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret != size) {
+ av_free_packet(pkt);
+ return AVERROR(EIO);
+ }
+
+ pkt->duration = 14;
+ redspark->samples_count += pkt->duration;
+ pkt->stream_index = 0;
+
+ return ret;
+}
+
+AVInputFormat ff_redspark_demuxer = {
+ .name = "redspark",
+ .long_name = NULL_IF_CONFIG_SMALL("RedSpark"),
+ .priv_data_size = sizeof(RedSparkContext),
+ .read_probe = redspark_probe,
+ .read_header = redspark_read_header,
+ .read_packet = redspark_read_packet,
+ .extensions = "rsd",
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.c b/chromium/third_party/ffmpeg/libavformat/riff.c
index 7ad96a8a76c..38d12fd64fe 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.c
+++ b/chromium/third_party/ffmpeg/libavformat/riff.c
@@ -19,13 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/mathematics.h"
+#include "libavutil/error.h"
#include "libavcodec/avcodec.h"
#include "avformat.h"
-#include "avio_internal.h"
#include "riff.h"
-#include "libavcodec/bytestream.h"
-#include "libavutil/avassert.h"
/* Note: When encoding, the first matching tag is used, so order is
* important if multiple tags are possible for a given codec.
@@ -87,6 +84,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'X') },
/* flipped video */
{ AV_CODEC_ID_MPEG4, MKTAG('H', 'D', 'X', '4') },
+ { AV_CODEC_ID_MPEG4, MKTAG('D', 'M', '4', 'V') },
{ AV_CODEC_ID_MPEG4, MKTAG('D', 'M', 'K', '2') },
{ AV_CODEC_ID_MPEG4, MKTAG('D', 'I', 'G', 'I') },
{ AV_CODEC_ID_MPEG4, MKTAG('I', 'N', 'M', 'C') },
@@ -325,21 +323,20 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
{ AV_CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') },
{ AV_CODEC_ID_LAGARITH, MKTAG('L', 'A', 'G', 'S') },
- { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '2') },
- { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '3') },
- { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '4') },
{ AV_CODEC_ID_AMV, MKTAG('A', 'M', 'V', 'F') },
{ AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'A') },
{ AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'G') },
{ AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '0') },
{ AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '2') },
+ /* Ut Video version 13.0.1 BT.709 codecs */
+ { AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'H', '0') },
+ { AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'H', '2') },
{ AV_CODEC_ID_VBLE, MKTAG('V', 'B', 'L', 'E') },
{ AV_CODEC_ID_ESCAPE130, MKTAG('E', '1', '3', '0') },
{ AV_CODEC_ID_DXTORY, MKTAG('x', 't', 'o', 'r') },
{ AV_CODEC_ID_ZEROCODEC, MKTAG('Z', 'E', 'C', 'O') },
{ AV_CODEC_ID_Y41P, MKTAG('Y', '4', '1', 'P') },
{ AV_CODEC_ID_FLIC, MKTAG('A', 'F', 'L', 'C') },
- { AV_CODEC_ID_EXR, MKTAG('e', 'x', 'r', ' ') },
{ AV_CODEC_ID_MSS1, MKTAG('M', 'S', 'S', '1') },
{ AV_CODEC_ID_MSA1, MKTAG('M', 'S', 'A', '1') },
{ AV_CODEC_ID_TSCC2, MKTAG('T', 'S', 'C', '2') },
@@ -349,6 +346,9 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },
{ AV_CODEC_ID_012V, MKTAG('0', '1', '2', 'v') },
{ AV_CODEC_ID_012V, MKTAG('a', '1', '2', 'v') },
+ { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '2') },
+ { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '3') },
+ { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '4') },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -373,6 +373,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ AV_CODEC_ID_ADPCM_YAMAHA, 0x0020 },
{ AV_CODEC_ID_TRUESPEECH, 0x0022 },
{ AV_CODEC_ID_GSM_MS, 0x0031 },
+ { AV_CODEC_ID_GSM_MS, 0x0032 }, /* msn audio */
{ AV_CODEC_ID_AMR_NB, 0x0038 }, /* rogue format number */
{ AV_CODEC_ID_G723_1, 0x0042 },
{ AV_CODEC_ID_ADPCM_G726, 0x0045 },
@@ -385,7 +386,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
/* rogue format number */
{ AV_CODEC_ID_ADPCM_IMA_DK3, 0x0062 },
{ AV_CODEC_ID_ADPCM_IMA_WAV, 0x0069 },
- { AV_CODEC_ID_VOXWARE, 0x0075 },
+ { AV_CODEC_ID_METASOUND, 0x0075 },
{ AV_CODEC_ID_AAC, 0x00ff },
{ AV_CODEC_ID_SIPR, 0x0130 },
{ AV_CODEC_ID_WMAV1, 0x0160 },
@@ -419,14 +420,6 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ AV_CODEC_ID_NONE, 0 },
};
-const AVCodecGuid ff_codec_wav_guids[] = {
- { AV_CODEC_ID_AC3, { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
- { AV_CODEC_ID_ATRAC3P, { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } },
- { AV_CODEC_ID_EAC3, { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } },
- { AV_CODEC_ID_MP2, { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
- { AV_CODEC_ID_NONE }
-};
-
const AVMetadataConv ff_riff_info_conv[] = {
{ "IART", "artist" },
{ "ICMT", "comment" },
@@ -437,504 +430,19 @@ const AVMetadataConv ff_riff_info_conv[] = {
{ "INAM", "title" },
{ "IPRD", "album" },
{ "IPRT", "track" },
+ { "ITRK", "track" },
{ "ISFT", "encoder" },
{ "ISMP", "timecode" },
{ "ITCH", "encoded_by" },
{ 0 },
};
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
-{
- av_assert0(sizeof(*g) == 16); //compiler will optimize this out
- if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g))
- memset(*g, 0, sizeof(*g));
-}
-
-enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
-{
- int i;
- for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++)
- if (!ff_guidcmp(guids[i].guid, guid))
- return guids[i].id;
- return AV_CODEC_ID_NONE;
-}
-
-#if CONFIG_MUXERS
-int64_t ff_start_tag(AVIOContext *pb, const char *tag)
-{
- ffio_wfourcc(pb, tag);
- avio_wl32(pb, 0);
- return avio_tell(pb);
-}
-
-void ff_end_tag(AVIOContext *pb, int64_t start)
-{
- int64_t pos;
-
- av_assert0((start&1) == 0);
-
- pos = avio_tell(pb);
- if (pos & 1)
- avio_w8(pb, 0);
- avio_seek(pb, start - 4, SEEK_SET);
- avio_wl32(pb, (uint32_t)(pos - start));
- avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
-}
-
-/* WAVEFORMATEX header */
-/* returns the size or -1 on error */
-int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
-{
- int bps, blkalign, bytespersec, frame_size;
- int hdrsize = 18;
- int waveformatextensible;
- uint8_t temp[256];
- uint8_t *riff_extradata = temp;
- uint8_t *riff_extradata_start = temp;
-
- if (!enc->codec_tag || enc->codec_tag > 0xffff)
- return -1;
-
- /* We use the known constant frame size for the codec if known, otherwise
- * fall back on using AVCodecContext.frame_size, which is not as reliable
- * for indicating packet duration. */
- frame_size = av_get_audio_frame_duration(enc, 0);
- if (!frame_size)
- frame_size = enc->frame_size;
-
- waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
- enc->sample_rate > 48000 ||
- av_get_bits_per_sample(enc->codec_id) > 16;
-
- if (waveformatextensible)
- avio_wl16(pb, 0xfffe);
- else
- avio_wl16(pb, enc->codec_tag);
-
- avio_wl16(pb, enc->channels);
- avio_wl32(pb, enc->sample_rate);
- if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
- enc->codec_id == AV_CODEC_ID_G723_1 ||
- enc->codec_id == AV_CODEC_ID_MP2 ||
- enc->codec_id == AV_CODEC_ID_MP3 ||
- enc->codec_id == AV_CODEC_ID_GSM_MS) {
- bps = 0;
- } else {
- if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
- if (enc->bits_per_coded_sample)
- bps = enc->bits_per_coded_sample;
- else
- bps = 16; // default to 16
- }
- }
- if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
- av_log(enc, AV_LOG_WARNING,
- "requested bits_per_coded_sample (%d) "
- "and actually stored (%d) differ\n",
- enc->bits_per_coded_sample, bps);
- }
-
- if (enc->codec_id == AV_CODEC_ID_MP2 ||
- enc->codec_id == AV_CODEC_ID_MP3) {
- /* This is wrong, but it seems many demuxers do not work if this
- * is set correctly. */
- blkalign = frame_size;
- // blkalign = 144 * enc->bit_rate/enc->sample_rate;
- } else if (enc->codec_id == AV_CODEC_ID_AC3) {
- blkalign = 3840; /* maximum bytes per frame */
- } else if (enc->codec_id == AV_CODEC_ID_AAC) {
- blkalign = 768 * enc->channels; /* maximum bytes per frame */
- } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
- blkalign = 24;
- } else if (enc->block_align != 0) { /* specified by the codec */
- blkalign = enc->block_align;
- } else
- blkalign = bps * enc->channels / av_gcd(8, bps);
- if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
- enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
- enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
- enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
- enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
- enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
- bytespersec = enc->sample_rate * blkalign;
- } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
- bytespersec = 800;
- } else {
- bytespersec = enc->bit_rate / 8;
- }
- avio_wl32(pb, bytespersec); /* bytes per second */
- avio_wl16(pb, blkalign); /* block align */
- avio_wl16(pb, bps); /* bits per sample */
- if (enc->codec_id == AV_CODEC_ID_MP3) {
- hdrsize += 12;
- bytestream_put_le16(&riff_extradata, 1); /* wID */
- bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
- bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
- bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
- bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
- } else if (enc->codec_id == AV_CODEC_ID_MP2) {
- hdrsize += 22;
- /* fwHeadLayer */
- bytestream_put_le16(&riff_extradata, 2);
- /* dwHeadBitrate */
- bytestream_put_le32(&riff_extradata, enc->bit_rate);
- /* fwHeadMode */
- bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
- /* fwHeadModeExt */
- bytestream_put_le16(&riff_extradata, 0);
- /* wHeadEmphasis */
- bytestream_put_le16(&riff_extradata, 1);
- /* fwHeadFlags */
- bytestream_put_le16(&riff_extradata, 16);
- /* dwPTSLow */
- bytestream_put_le32(&riff_extradata, 0);
- /* dwPTSHigh */
- bytestream_put_le32(&riff_extradata, 0);
- } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
- hdrsize += 20;
- bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
- bytestream_put_le32(&riff_extradata, 0xaea2f732);
- bytestream_put_le16(&riff_extradata, 0xacde);
- } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
- enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
- hdrsize += 2;
- /* wSamplesPerBlock */
- bytestream_put_le16(&riff_extradata, frame_size);
- } else if (enc->extradata_size) {
- riff_extradata_start = enc->extradata;
- riff_extradata = enc->extradata + enc->extradata_size;
- hdrsize += enc->extradata_size;
- }
- /* write WAVEFORMATEXTENSIBLE extensions */
- if (waveformatextensible) {
- hdrsize += 22;
- /* 22 is WAVEFORMATEXTENSIBLE size */
- avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
- /* ValidBitsPerSample || SamplesPerBlock || Reserved */
- avio_wl16(pb, bps);
- /* dwChannelMask */
- avio_wl32(pb, enc->channel_layout);
- /* GUID + next 3 */
- avio_wl32(pb, enc->codec_tag);
- avio_wl32(pb, 0x00100000);
- avio_wl32(pb, 0xAA000080);
- avio_wl32(pb, 0x719B3800);
- } else {
- avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
- }
- avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
- if (hdrsize & 1) {
- hdrsize++;
- avio_w8(pb, 0);
- }
-
- return hdrsize;
-}
-
-/* BITMAPINFOHEADER header */
-void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
- const AVCodecTag *tags, int for_asf)
-{
- /* size */
- avio_wl32(pb, 40 + enc->extradata_size);
- avio_wl32(pb, enc->width);
- //We always store RGB TopDown
- avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
- /* planes */
- avio_wl16(pb, 1);
- /* depth */
- avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
- /* compression type */
- avio_wl32(pb, enc->codec_tag);
- avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
- avio_wl32(pb, 0);
- avio_wl32(pb, 0);
- avio_wl32(pb, 0);
- avio_wl32(pb, 0);
-
- avio_write(pb, enc->extradata, enc->extradata_size);
-
- if (!for_asf && enc->extradata_size & 1)
- avio_w8(pb, 0);
-}
-
-void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
- int *au_ssize, int *au_scale)
-{
- int gcd;
- int audio_frame_size;
-
- /* We use the known constant frame size for the codec if known, otherwise
- * fall back on using AVCodecContext.frame_size, which is not as reliable
- * for indicating packet duration. */
- audio_frame_size = av_get_audio_frame_duration(stream, 0);
- if (!audio_frame_size)
- audio_frame_size = stream->frame_size;
-
- *au_ssize = stream->block_align;
- if (audio_frame_size && stream->sample_rate) {
- *au_scale = audio_frame_size;
- *au_rate = stream->sample_rate;
- } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
- stream->codec_type == AVMEDIA_TYPE_DATA ||
- stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
- *au_scale = stream->time_base.num;
- *au_rate = stream->time_base.den;
- } else {
- *au_scale = stream->block_align ? stream->block_align * 8 : 8;
- *au_rate = stream->bit_rate ? stream->bit_rate :
- 8 * stream->sample_rate;
- }
- gcd = av_gcd(*au_scale, *au_rate);
- *au_scale /= gcd;
- *au_rate /= gcd;
-}
-
-void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
-{
- int len = strlen(str);
- if (len > 0) {
- len++;
- ffio_wfourcc(pb, tag);
- avio_wl32(pb, len);
- avio_put_str(pb, str);
- if (len & 1)
- avio_w8(pb, 0);
- }
-}
-
-static const char riff_tags[][5] = {
- "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
- "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
- "IPRT", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
- { 0 }
-};
-
-static int riff_has_valid_tags(AVFormatContext *s)
-{
- int i;
-
- for (i = 0; *riff_tags[i]; i++)
- if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
- return 1;
-
- return 0;
-}
-
-void ff_riff_write_info(AVFormatContext *s)
-{
- AVIOContext *pb = s->pb;
- int i;
- int64_t list_pos;
- AVDictionaryEntry *t = NULL;
-
- ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
-
- /* writing empty LIST is not nice and may cause problems */
- if (!riff_has_valid_tags(s))
- return;
-
- list_pos = ff_start_tag(pb, "LIST");
- ffio_wfourcc(pb, "INFO");
- for (i = 0; *riff_tags[i]; i++)
- if ((t = av_dict_get(s->metadata, riff_tags[i],
- NULL, AV_DICT_MATCH_CASE)))
- ff_riff_write_info_tag(s->pb, t->key, t->value);
- ff_end_tag(pb, list_pos);
-}
-#endif /* CONFIG_MUXERS */
-
-#if CONFIG_DEMUXERS
-/* We could be given one of the three possible structures here:
- * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
- * is an expansion of the previous one with the fields added
- * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
- * WAVEFORMATEX adds 'WORD cbSize' and basically makes itself
- * an openended structure.
- */
-
-static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c)
+const struct AVCodecTag *avformat_get_riff_video_tags(void)
{
- ff_asf_guid subformat;
- int bps = avio_rl16(pb);
- if (bps)
- c->bits_per_coded_sample = bps;
-
- c->channel_layout = avio_rl32(pb); /* dwChannelMask */
-
- ff_get_guid(pb, &subformat);
- if (!memcmp(subformat + 4,
- (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) {
- c->codec_tag = AV_RL32(subformat);
- c->codec_id = ff_wav_codec_get_id(c->codec_tag,
- c->bits_per_coded_sample);
- } else {
- c->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
- if (!c->codec_id)
- av_log(c, AV_LOG_WARNING,
- "unknown subformat:"FF_PRI_GUID"\n",
- FF_ARG_GUID(subformat));
- }
+ return ff_codec_bmp_tags;
}
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
+const struct AVCodecTag *avformat_get_riff_audio_tags(void)
{
- int id;
-
- id = avio_rl16(pb);
- codec->codec_type = AVMEDIA_TYPE_AUDIO;
- codec->channels = avio_rl16(pb);
- codec->sample_rate = avio_rl32(pb);
- codec->bit_rate = avio_rl32(pb) * 8;
- codec->block_align = avio_rl16(pb);
- if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */
- codec->bits_per_coded_sample = 8;
- } else
- codec->bits_per_coded_sample = avio_rl16(pb);
- if (id == 0xFFFE) {
- codec->codec_tag = 0;
- } else {
- codec->codec_tag = id;
- codec->codec_id = ff_wav_codec_get_id(id,
- codec->bits_per_coded_sample);
- }
- if (size >= 18) { /* We're obviously dealing with WAVEFORMATEX */
- int cbSize = avio_rl16(pb); /* cbSize */
- size -= 18;
- cbSize = FFMIN(size, cbSize);
- if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
- parse_waveformatex(pb, codec);
- cbSize -= 22;
- size -= 22;
- }
- codec->extradata_size = cbSize;
- if (cbSize > 0) {
- av_free(codec->extradata);
- codec->extradata = av_mallocz(codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
- if (!codec->extradata)
- return AVERROR(ENOMEM);
- avio_read(pb, codec->extradata, codec->extradata_size);
- size -= cbSize;
- }
-
- /* It is possible for the chunk to contain garbage at the end */
- if (size > 0)
- avio_skip(pb, size);
- }
- if (codec->codec_id == AV_CODEC_ID_AAC_LATM) {
- /* Channels and sample_rate values are those prior to applying SBR
- * and/or PS. */
- codec->channels = 0;
- codec->sample_rate = 0;
- }
- /* override bits_per_coded_sample for G.726 */
- if (codec->codec_id == AV_CODEC_ID_ADPCM_G726 && codec->sample_rate)
- codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
-
- return 0;
-}
-
-enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
-{
- enum AVCodecID id;
- id = ff_codec_get_id(ff_codec_wav_tags, tag);
- if (id <= 0)
- return id;
-
- if (id == AV_CODEC_ID_PCM_S16LE)
- id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
- else if (id == AV_CODEC_ID_PCM_F32LE)
- id = ff_get_pcm_codec_id(bps, 1, 0, 0);
-
- if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
- id = AV_CODEC_ID_PCM_ZORK;
- return id;
-}
-
-int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize)
-{
- int tag1;
- if(esize) *esize = avio_rl32(pb);
- else avio_rl32(pb);
- st->codec->width = avio_rl32(pb);
- st->codec->height = (int32_t)avio_rl32(pb);
- avio_rl16(pb); /* planes */
- st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
- tag1 = avio_rl32(pb);
- avio_rl32(pb); /* ImageSize */
- avio_rl32(pb); /* XPelsPerMeter */
- avio_rl32(pb); /* YPelsPerMeter */
- avio_rl32(pb); /* ClrUsed */
- avio_rl32(pb); /* ClrImportant */
- return tag1;
-}
-
-int ff_read_riff_info(AVFormatContext *s, int64_t size)
-{
- int64_t start, end, cur;
- AVIOContext *pb = s->pb;
-
- start = avio_tell(pb);
- end = start + size;
-
- while ((cur = avio_tell(pb)) >= 0 &&
- cur <= end - 8 /* = tag + size */) {
- uint32_t chunk_code;
- int64_t chunk_size;
- char key[5] = { 0 };
- char *value;
-
- chunk_code = avio_rl32(pb);
- chunk_size = avio_rl32(pb);
- if (url_feof(pb)) {
- if (chunk_code || chunk_size) {
- av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n");
- return AVERROR_INVALIDDATA;
- }
- return AVERROR_EOF;
- }
- if (chunk_size > end ||
- end - chunk_size < cur ||
- chunk_size == UINT_MAX) {
- avio_seek(pb, -9, SEEK_CUR);
- chunk_code = avio_rl32(pb);
- chunk_size = avio_rl32(pb);
- if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
- av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- chunk_size += (chunk_size & 1);
-
- if (!chunk_code) {
- if (chunk_size)
- avio_skip(pb, chunk_size);
- else if (pb->eof_reached) {
- av_log(s, AV_LOG_WARNING, "truncated file\n");
- return AVERROR_EOF;
- }
- continue;
- }
-
- value = av_mallocz(chunk_size + 1);
- if (!value) {
- av_log(s, AV_LOG_ERROR,
- "out of memory, unable to read INFO tag\n");
- return AVERROR(ENOMEM);
- }
-
- AV_WL32(key, chunk_code);
-
- if (avio_read(pb, value, chunk_size) != chunk_size) {
- av_log(s, AV_LOG_WARNING,
- "premature end of file while reading INFO tag\n");
- }
-
- av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
- }
-
- return 0;
+ return ff_codec_wav_tags;
}
-#endif /* CONFIG_DEMUXERS */
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.h b/chromium/third_party/ffmpeg/libavformat/riff.h
index cb8378922f6..1bf437e06c8 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.h
+++ b/chromium/third_party/ffmpeg/libavformat/riff.h
@@ -34,7 +34,6 @@
#include "metadata.h"
extern const AVMetadataConv ff_riff_info_conv[];
-extern const char ff_riff_tags[][5];
int64_t ff_start_tag(AVIOContext *pb, const char *tag);
void ff_end_tag(AVIOContext *pb, int64_t start);
diff --git a/chromium/third_party/ffmpeg/libavformat/riffdec.c b/chromium/third_party/ffmpeg/libavformat/riffdec.c
new file mode 100644
index 00000000000..973f3fada9c
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/riffdec.c
@@ -0,0 +1,247 @@
+/*
+ * RIFF demuxing functions and data
+ * Copyright (c) 2000 Fabrice Bellard
+ *
+ * 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/dict.h"
+#include "libavutil/error.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "riff.h"
+
+const AVCodecGuid ff_codec_wav_guids[] = {
+ { AV_CODEC_ID_AC3, { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
+ { AV_CODEC_ID_ATRAC3P, { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } },
+ { AV_CODEC_ID_EAC3, { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } },
+ { AV_CODEC_ID_MP2, { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
+ { AV_CODEC_ID_NONE }
+};
+
+void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
+{
+ av_assert0(sizeof(*g) == 16); //compiler will optimize this out
+ if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g))
+ memset(*g, 0, sizeof(*g));
+}
+
+enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
+{
+ int i;
+ for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++)
+ if (!ff_guidcmp(guids[i].guid, guid))
+ return guids[i].id;
+ return AV_CODEC_ID_NONE;
+}
+
+/* We could be given one of the three possible structures here:
+ * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
+ * is an expansion of the previous one with the fields added
+ * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
+ * WAVEFORMATEX adds 'WORD cbSize' and basically makes itself
+ * an openended structure.
+ */
+
+static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c)
+{
+ ff_asf_guid subformat;
+ int bps = avio_rl16(pb);
+ if (bps)
+ c->bits_per_coded_sample = bps;
+
+ c->channel_layout = avio_rl32(pb); /* dwChannelMask */
+
+ ff_get_guid(pb, &subformat);
+ if (!memcmp(subformat + 4,
+ (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) {
+ c->codec_tag = AV_RL32(subformat);
+ c->codec_id = ff_wav_codec_get_id(c->codec_tag,
+ c->bits_per_coded_sample);
+ } else {
+ c->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
+ if (!c->codec_id)
+ av_log(c, AV_LOG_WARNING,
+ "unknown subformat:"FF_PRI_GUID"\n",
+ FF_ARG_GUID(subformat));
+ }
+}
+
+int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
+{
+ int id;
+
+ id = avio_rl16(pb);
+ codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ codec->channels = avio_rl16(pb);
+ codec->sample_rate = avio_rl32(pb);
+ codec->bit_rate = avio_rl32(pb) * 8;
+ codec->block_align = avio_rl16(pb);
+ if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */
+ codec->bits_per_coded_sample = 8;
+ } else
+ codec->bits_per_coded_sample = avio_rl16(pb);
+ if (id == 0xFFFE) {
+ codec->codec_tag = 0;
+ } else {
+ codec->codec_tag = id;
+ codec->codec_id = ff_wav_codec_get_id(id,
+ codec->bits_per_coded_sample);
+ }
+ if (size >= 18) { /* We're obviously dealing with WAVEFORMATEX */
+ int cbSize = avio_rl16(pb); /* cbSize */
+ size -= 18;
+ cbSize = FFMIN(size, cbSize);
+ if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
+ parse_waveformatex(pb, codec);
+ cbSize -= 22;
+ size -= 22;
+ }
+ codec->extradata_size = cbSize;
+ if (cbSize > 0) {
+ av_free(codec->extradata);
+ codec->extradata = av_mallocz(codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!codec->extradata)
+ return AVERROR(ENOMEM);
+ avio_read(pb, codec->extradata, codec->extradata_size);
+ size -= cbSize;
+ }
+
+ /* It is possible for the chunk to contain garbage at the end */
+ if (size > 0)
+ avio_skip(pb, size);
+ }
+ if (codec->codec_id == AV_CODEC_ID_AAC_LATM) {
+ /* Channels and sample_rate values are those prior to applying SBR
+ * and/or PS. */
+ codec->channels = 0;
+ codec->sample_rate = 0;
+ }
+ /* override bits_per_coded_sample for G.726 */
+ if (codec->codec_id == AV_CODEC_ID_ADPCM_G726 && codec->sample_rate)
+ codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
+
+ return 0;
+}
+
+enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
+{
+ enum AVCodecID id;
+ id = ff_codec_get_id(ff_codec_wav_tags, tag);
+ if (id <= 0)
+ return id;
+
+ if (id == AV_CODEC_ID_PCM_S16LE)
+ id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
+ else if (id == AV_CODEC_ID_PCM_F32LE)
+ id = ff_get_pcm_codec_id(bps, 1, 0, 0);
+
+ if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
+ id = AV_CODEC_ID_PCM_ZORK;
+ return id;
+}
+
+int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize)
+{
+ int tag1;
+ if(esize) *esize = avio_rl32(pb);
+ else avio_rl32(pb);
+ st->codec->width = avio_rl32(pb);
+ st->codec->height = (int32_t)avio_rl32(pb);
+ avio_rl16(pb); /* planes */
+ st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
+ tag1 = avio_rl32(pb);
+ avio_rl32(pb); /* ImageSize */
+ avio_rl32(pb); /* XPelsPerMeter */
+ avio_rl32(pb); /* YPelsPerMeter */
+ avio_rl32(pb); /* ClrUsed */
+ avio_rl32(pb); /* ClrImportant */
+ return tag1;
+}
+
+int ff_read_riff_info(AVFormatContext *s, int64_t size)
+{
+ int64_t start, end, cur;
+ AVIOContext *pb = s->pb;
+
+ start = avio_tell(pb);
+ end = start + size;
+
+ while ((cur = avio_tell(pb)) >= 0 &&
+ cur <= end - 8 /* = tag + size */) {
+ uint32_t chunk_code;
+ int64_t chunk_size;
+ char key[5] = { 0 };
+ char *value;
+
+ chunk_code = avio_rl32(pb);
+ chunk_size = avio_rl32(pb);
+ if (url_feof(pb)) {
+ if (chunk_code || chunk_size) {
+ av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n");
+ return AVERROR_INVALIDDATA;
+ }
+ return AVERROR_EOF;
+ }
+ if (chunk_size > end ||
+ end - chunk_size < cur ||
+ chunk_size == UINT_MAX) {
+ avio_seek(pb, -9, SEEK_CUR);
+ chunk_code = avio_rl32(pb);
+ chunk_size = avio_rl32(pb);
+ if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
+ av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ chunk_size += (chunk_size & 1);
+
+ if (!chunk_code) {
+ if (chunk_size)
+ avio_skip(pb, chunk_size);
+ else if (pb->eof_reached) {
+ av_log(s, AV_LOG_WARNING, "truncated file\n");
+ return AVERROR_EOF;
+ }
+ continue;
+ }
+
+ value = av_mallocz(chunk_size + 1);
+ if (!value) {
+ av_log(s, AV_LOG_ERROR,
+ "out of memory, unable to read INFO tag\n");
+ return AVERROR(ENOMEM);
+ }
+
+ AV_WL32(key, chunk_code);
+
+ if (avio_read(pb, value, chunk_size) != chunk_size) {
+ av_log(s, AV_LOG_WARNING,
+ "premature end of file while reading INFO tag\n");
+ }
+
+ av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
+ }
+
+ return 0;
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/riffenc.c b/chromium/third_party/ffmpeg/libavformat/riffenc.c
new file mode 100644
index 00000000000..bcfe018f74e
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/riffenc.c
@@ -0,0 +1,312 @@
+/*
+ * RIFF muxing functions
+ * Copyright (c) 2000 Fabrice Bellard
+ *
+ * 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/dict.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "riff.h"
+
+int64_t ff_start_tag(AVIOContext *pb, const char *tag)
+{
+ ffio_wfourcc(pb, tag);
+ avio_wl32(pb, 0);
+ return avio_tell(pb);
+}
+
+void ff_end_tag(AVIOContext *pb, int64_t start)
+{
+ int64_t pos;
+
+ av_assert0((start&1) == 0);
+
+ pos = avio_tell(pb);
+ if (pos & 1)
+ avio_w8(pb, 0);
+ avio_seek(pb, start - 4, SEEK_SET);
+ avio_wl32(pb, (uint32_t)(pos - start));
+ avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
+}
+
+/* WAVEFORMATEX header */
+/* returns the size or -1 on error */
+int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
+{
+ int bps, blkalign, bytespersec, frame_size;
+ int hdrsize = 18;
+ int waveformatextensible;
+ uint8_t temp[256];
+ uint8_t *riff_extradata = temp;
+ uint8_t *riff_extradata_start = temp;
+
+ if (!enc->codec_tag || enc->codec_tag > 0xffff)
+ return -1;
+
+ /* We use the known constant frame size for the codec if known, otherwise
+ * fall back on using AVCodecContext.frame_size, which is not as reliable
+ * for indicating packet duration. */
+ frame_size = av_get_audio_frame_duration(enc, 0);
+ if (!frame_size)
+ frame_size = enc->frame_size;
+
+ waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
+ enc->sample_rate > 48000 ||
+ av_get_bits_per_sample(enc->codec_id) > 16;
+
+ if (waveformatextensible)
+ avio_wl16(pb, 0xfffe);
+ else
+ avio_wl16(pb, enc->codec_tag);
+
+ avio_wl16(pb, enc->channels);
+ avio_wl32(pb, enc->sample_rate);
+ if (enc->codec_id == AV_CODEC_ID_ATRAC3 ||
+ enc->codec_id == AV_CODEC_ID_G723_1 ||
+ enc->codec_id == AV_CODEC_ID_MP2 ||
+ enc->codec_id == AV_CODEC_ID_MP3 ||
+ enc->codec_id == AV_CODEC_ID_GSM_MS) {
+ bps = 0;
+ } else {
+ if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
+ if (enc->bits_per_coded_sample)
+ bps = enc->bits_per_coded_sample;
+ else
+ bps = 16; // default to 16
+ }
+ }
+ if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
+ av_log(enc, AV_LOG_WARNING,
+ "requested bits_per_coded_sample (%d) "
+ "and actually stored (%d) differ\n",
+ enc->bits_per_coded_sample, bps);
+ }
+
+ if (enc->codec_id == AV_CODEC_ID_MP2 ||
+ enc->codec_id == AV_CODEC_ID_MP3) {
+ /* This is wrong, but it seems many demuxers do not work if this
+ * is set correctly. */
+ blkalign = frame_size;
+ // blkalign = 144 * enc->bit_rate/enc->sample_rate;
+ } else if (enc->codec_id == AV_CODEC_ID_AC3) {
+ blkalign = 3840; /* maximum bytes per frame */
+ } else if (enc->codec_id == AV_CODEC_ID_AAC) {
+ blkalign = 768 * enc->channels; /* maximum bytes per frame */
+ } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+ blkalign = 24;
+ } else if (enc->block_align != 0) { /* specified by the codec */
+ blkalign = enc->block_align;
+ } else
+ blkalign = bps * enc->channels / av_gcd(8, bps);
+ if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
+ enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
+ enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
+ enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
+ enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
+ enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
+ bytespersec = enc->sample_rate * blkalign;
+ } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+ bytespersec = 800;
+ } else {
+ bytespersec = enc->bit_rate / 8;
+ }
+ avio_wl32(pb, bytespersec); /* bytes per second */
+ avio_wl16(pb, blkalign); /* block align */
+ avio_wl16(pb, bps); /* bits per sample */
+ if (enc->codec_id == AV_CODEC_ID_MP3) {
+ hdrsize += 12;
+ bytestream_put_le16(&riff_extradata, 1); /* wID */
+ bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
+ bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
+ bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
+ bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
+ } else if (enc->codec_id == AV_CODEC_ID_MP2) {
+ hdrsize += 22;
+ /* fwHeadLayer */
+ bytestream_put_le16(&riff_extradata, 2);
+ /* dwHeadBitrate */
+ bytestream_put_le32(&riff_extradata, enc->bit_rate);
+ /* fwHeadMode */
+ bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
+ /* fwHeadModeExt */
+ bytestream_put_le16(&riff_extradata, 0);
+ /* wHeadEmphasis */
+ bytestream_put_le16(&riff_extradata, 1);
+ /* fwHeadFlags */
+ bytestream_put_le16(&riff_extradata, 16);
+ /* dwPTSLow */
+ bytestream_put_le32(&riff_extradata, 0);
+ /* dwPTSHigh */
+ bytestream_put_le32(&riff_extradata, 0);
+ } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+ hdrsize += 20;
+ bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
+ bytestream_put_le32(&riff_extradata, 0xaea2f732);
+ bytestream_put_le16(&riff_extradata, 0xacde);
+ } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
+ enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
+ hdrsize += 2;
+ /* wSamplesPerBlock */
+ bytestream_put_le16(&riff_extradata, frame_size);
+ } else if (enc->extradata_size) {
+ riff_extradata_start = enc->extradata;
+ riff_extradata = enc->extradata + enc->extradata_size;
+ hdrsize += enc->extradata_size;
+ }
+ /* write WAVEFORMATEXTENSIBLE extensions */
+ if (waveformatextensible) {
+ hdrsize += 22;
+ /* 22 is WAVEFORMATEXTENSIBLE size */
+ avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
+ /* ValidBitsPerSample || SamplesPerBlock || Reserved */
+ avio_wl16(pb, bps);
+ /* dwChannelMask */
+ avio_wl32(pb, enc->channel_layout);
+ /* GUID + next 3 */
+ avio_wl32(pb, enc->codec_tag);
+ avio_wl32(pb, 0x00100000);
+ avio_wl32(pb, 0xAA000080);
+ avio_wl32(pb, 0x719B3800);
+ } else {
+ avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
+ }
+ avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
+ if (hdrsize & 1) {
+ hdrsize++;
+ avio_w8(pb, 0);
+ }
+
+ return hdrsize;
+}
+
+/* BITMAPINFOHEADER header */
+void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
+ const AVCodecTag *tags, int for_asf)
+{
+ /* size */
+ avio_wl32(pb, 40 + enc->extradata_size);
+ avio_wl32(pb, enc->width);
+ //We always store RGB TopDown
+ avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
+ /* planes */
+ avio_wl16(pb, 1);
+ /* depth */
+ avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
+ /* compression type */
+ avio_wl32(pb, enc->codec_tag);
+ avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+
+ avio_write(pb, enc->extradata, enc->extradata_size);
+
+ if (!for_asf && enc->extradata_size & 1)
+ avio_w8(pb, 0);
+}
+
+void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
+ int *au_ssize, int *au_scale)
+{
+ int gcd;
+ int audio_frame_size;
+
+ /* We use the known constant frame size for the codec if known, otherwise
+ * fall back on using AVCodecContext.frame_size, which is not as reliable
+ * for indicating packet duration. */
+ audio_frame_size = av_get_audio_frame_duration(stream, 0);
+ if (!audio_frame_size)
+ audio_frame_size = stream->frame_size;
+
+ *au_ssize = stream->block_align;
+ if (audio_frame_size && stream->sample_rate) {
+ *au_scale = audio_frame_size;
+ *au_rate = stream->sample_rate;
+ } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
+ stream->codec_type == AVMEDIA_TYPE_DATA ||
+ stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ *au_scale = stream->time_base.num;
+ *au_rate = stream->time_base.den;
+ } else {
+ *au_scale = stream->block_align ? stream->block_align * 8 : 8;
+ *au_rate = stream->bit_rate ? stream->bit_rate :
+ 8 * stream->sample_rate;
+ }
+ gcd = av_gcd(*au_scale, *au_rate);
+ *au_scale /= gcd;
+ *au_rate /= gcd;
+}
+
+void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
+{
+ int len = strlen(str);
+ if (len > 0) {
+ len++;
+ ffio_wfourcc(pb, tag);
+ avio_wl32(pb, len);
+ avio_put_str(pb, str);
+ if (len & 1)
+ avio_w8(pb, 0);
+ }
+}
+
+static const char riff_tags[][5] = {
+ "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
+ "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
+ "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
+ { 0 }
+};
+
+static int riff_has_valid_tags(AVFormatContext *s)
+{
+ int i;
+
+ for (i = 0; *riff_tags[i]; i++)
+ if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
+ return 1;
+
+ return 0;
+}
+
+void ff_riff_write_info(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ int i;
+ int64_t list_pos;
+ AVDictionaryEntry *t = NULL;
+
+ ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
+
+ /* writing empty LIST is not nice and may cause problems */
+ if (!riff_has_valid_tags(s))
+ return;
+
+ list_pos = ff_start_tag(pb, "LIST");
+ ffio_wfourcc(pb, "INFO");
+ for (i = 0; *riff_tags[i]; i++)
+ if ((t = av_dict_get(s->metadata, riff_tags[i],
+ NULL, AV_DICT_MATCH_CASE)))
+ ff_riff_write_info_tag(s->pb, t->key, t->value);
+ ff_end_tag(pb, list_pos);
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/rmdec.c b/chromium/third_party/ffmpeg/libavformat/rmdec.c
index 13d1d25758d..38bddc37600 100644
--- a/chromium/third_party/ffmpeg/libavformat/rmdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rmdec.c
@@ -22,6 +22,7 @@
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
@@ -95,13 +96,14 @@ static int rm_read_extradata(AVIOContext *pb, AVCodecContext *avctx, unsigned si
return 0;
}
-static void rm_read_metadata(AVFormatContext *s, int wide)
+static void rm_read_metadata(AVFormatContext *s, AVIOContext *pb, int wide)
{
char buf[1024];
int i;
+
for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
- int len = wide ? avio_rb16(s->pb) : avio_r8(s->pb);
- get_strl(s->pb, buf, sizeof(buf), len);
+ int len = wide ? avio_rb16(pb) : avio_r8(pb);
+ get_strl(pb, buf, sizeof(buf), len);
av_dict_set(&s->metadata, ff_rm_metadata[i], buf, 0);
}
}
@@ -134,7 +136,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
avio_skip(pb, 8);
bytes_per_minute = avio_rb16(pb);
avio_skip(pb, 4);
- rm_read_metadata(s, 0);
+ rm_read_metadata(s, pb, 0);
if ((startpos + header_size) >= avio_tell(pb) + 2) {
// fourcc (should always be "lpcJ")
avio_r8(pb);
@@ -293,7 +295,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
avio_r8(pb);
avio_r8(pb);
avio_r8(pb);
- rm_read_metadata(s, 0);
+ rm_read_metadata(s, pb, 0);
}
}
return 0;
@@ -516,7 +518,7 @@ static int rm_read_header(AVFormatContext *s)
flags = avio_rb16(pb); /* flags */
break;
case MKTAG('C', 'O', 'N', 'T'):
- rm_read_metadata(s, 1);
+ rm_read_metadata(s, pb, 1);
break;
case MKTAG('M', 'D', 'P', 'R'):
st = avformat_new_stream(s, NULL);
@@ -721,6 +723,8 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
if(++vst->cur_slice > vst->slices)
return 1;
+ if(!vst->pkt.data)
+ return AVERROR(ENOMEM);
AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);
AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
if(vst->videobufpos + len > vst->videobufsize)
@@ -737,7 +741,9 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
vst->pkt.size= 0;
vst->pkt.buf = NULL;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
vst->pkt.destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
@@ -773,11 +779,13 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
int *seq, int flags, int64_t timestamp)
{
RMDemuxContext *rm = s->priv_data;
+ int ret;
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
rm->current_stream= st->id;
- if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp))
- return -1; //got partial frame
+ ret = rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp);
+ if(ret)
+ return ret; //got partial frame or error
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if ((ast->deint_id == DEINT_ID_GENR) ||
(ast->deint_id == DEINT_ID_INT4) ||
@@ -924,6 +932,8 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
&seq, flags, timestamp);
+ if (res < -1)
+ return res;
if((flags&2) && (seq&0x7F) == 1)
av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
if (res)
diff --git a/chromium/third_party/ffmpeg/libavformat/rsd.c b/chromium/third_party/ffmpeg/libavformat/rsd.c
new file mode 100644
index 00000000000..5b53cef9c09
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/rsd.c
@@ -0,0 +1,170 @@
+/*
+ * RSD demuxer
+ * Copyright (c) 2013 James Almer
+ *
+ * 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 "libavcodec/bytestream.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "avio.h"
+#include "internal.h"
+
+static const AVCodecTag rsd_tags[] = {
+ { AV_CODEC_ID_ADPCM_THP, MKTAG('G','A','D','P') },
+ { AV_CODEC_ID_ADPCM_IMA_RAD, MKTAG('R','A','D','P') },
+ { AV_CODEC_ID_PCM_S16BE, MKTAG('P','C','M','B') },
+ { AV_CODEC_ID_PCM_S16LE, MKTAG('P','C','M',' ') },
+ { AV_CODEC_ID_NONE, 0 },
+};
+
+static const uint32_t rsd_unsupported_tags[] = {
+ MKTAG('O','G','G',' '),
+ MKTAG('V','A','G',' '),
+ MKTAG('W','A','D','P'),
+ MKTAG('X','A','D','P'),
+ MKTAG('X','M','A',' '),
+};
+
+static int rsd_probe(AVProbeData *p)
+{
+ if (!memcmp(p->buf, "RSD", 3) &&
+ p->buf[3] - '0' >= 2 && p->buf[3] - '0' <= 6)
+ return AVPROBE_SCORE_EXTENSION;
+ return 0;
+}
+
+static int rsd_read_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ int i, version, start = 0x800;
+ AVCodecContext *codec;
+ AVStream *st = avformat_new_stream(s, NULL);
+
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ avio_skip(pb, 3); // "RSD"
+ version = avio_r8(pb) - '0';
+
+ codec = st->codec;
+ codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ codec->codec_tag = avio_rl32(pb);
+ codec->codec_id = ff_codec_get_id(rsd_tags, codec->codec_tag);
+ if (!codec->codec_id) {
+ char tag_buf[5];
+
+ av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag);
+ for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) {
+ if (codec->codec_tag == rsd_unsupported_tags[i]) {
+ avpriv_request_sample(s, "Codec tag: %s", tag_buf);
+ return AVERROR_PATCHWELCOME;
+ }
+ }
+ av_log(s, AV_LOG_ERROR, "Unknown codec tag: %s\n", tag_buf);
+ return AVERROR_INVALIDDATA;
+ }
+
+ codec->channels = avio_rl32(pb);
+ if (!codec->channels)
+ return AVERROR_INVALIDDATA;
+
+ avio_skip(pb, 4); // Bit depth
+ codec->sample_rate = avio_rl32(pb);
+ if (!codec->sample_rate)
+ return AVERROR_INVALIDDATA;
+
+ avio_skip(pb, 4); // Unknown
+
+ switch (codec->codec_id) {
+ case AV_CODEC_ID_ADPCM_IMA_RAD:
+ codec->block_align = 20 * codec->channels;
+ if (pb->seekable)
+ st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start);
+ break;
+ case AV_CODEC_ID_ADPCM_THP:
+ /* RSD3GADP is mono, so only alloc enough memory
+ to store the coeff table for a single channel. */
+
+ codec->extradata_size = 32;
+ codec->extradata = av_malloc(codec->extradata_size);
+ if (!codec->extradata)
+ return AVERROR(ENOMEM);
+
+ start = avio_rl32(pb);
+
+ if (avio_read(s->pb, codec->extradata, 32) != 32)
+ return AVERROR_INVALIDDATA;
+
+ for (i = 0; i < 16; i++)
+ AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2));
+
+ if (pb->seekable)
+ st->duration = (avio_size(pb) - start) / 8 * 14;
+ break;
+ case AV_CODEC_ID_PCM_S16LE:
+ case AV_CODEC_ID_PCM_S16BE:
+ if (version != 4)
+ start = avio_rl32(pb);
+
+ if (pb->seekable)
+ st->duration = (avio_size(pb) - start) / 2 / codec->channels;
+ break;
+ }
+
+ avio_skip(pb, start - avio_tell(pb));
+
+ avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
+
+ return 0;
+}
+
+static int rsd_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVCodecContext *codec = s->streams[0]->codec;
+ int ret, size = 1024;
+
+ if (url_feof(s->pb))
+ return AVERROR_EOF;
+
+ if (codec->codec_id == AV_CODEC_ID_ADPCM_IMA_RAD)
+ ret = av_get_packet(s->pb, pkt, codec->block_align);
+ else
+ ret = av_get_packet(s->pb, pkt, size);
+
+ if (ret != size) {
+ if (ret < 0) {
+ av_free_packet(pkt);
+ return ret;
+ }
+ av_shrink_packet(pkt, ret);
+ }
+ pkt->stream_index = 0;
+
+ return ret;
+}
+
+AVInputFormat ff_rsd_demuxer = {
+ .name = "rsd",
+ .long_name = NULL_IF_CONFIG_SMALL("GameCube RSD"),
+ .read_probe = rsd_probe,
+ .read_header = rsd_read_header,
+ .read_packet = rsd_read_packet,
+ .extensions = "rsd",
+ .codec_tag = (const AVCodecTag* const []){rsd_tags, 0},
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmp.h b/chromium/third_party/ffmpeg/libavformat/rtmp.h
index 7c9bb6d766c..8fc8040d89e 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmp.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtmp.h
@@ -1,6 +1,6 @@
/*
* RTMP definitions
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmppkt.c b/chromium/third_party/ffmpeg/libavformat/rtmppkt.c
index 3bd28eb6147..0982775135f 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmppkt.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmppkt.c
@@ -1,6 +1,6 @@
/*
* RTMP input format
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
@@ -145,25 +145,25 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
{
uint8_t t, buf[16];
- int channel_id, timestamp, data_size, offset = 0;
+ int channel_id, timestamp, size, offset = 0;
uint32_t extra = 0;
enum RTMPPacketType type;
- int size = 0;
+ int written = 0;
int ret;
- size++;
+ written++;
channel_id = hdr & 0x3F;
if (channel_id < 2) { //special case for channel number >= 64
buf[1] = 0;
if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)
return AVERROR(EIO);
- size += channel_id + 1;
+ written += channel_id + 1;
channel_id = AV_RL16(buf) + 64;
}
- data_size = prev_pkt[channel_id].data_size;
- type = prev_pkt[channel_id].type;
- extra = prev_pkt[channel_id].extra;
+ size = prev_pkt[channel_id].size;
+ type = prev_pkt[channel_id].type;
+ extra = prev_pkt[channel_id].extra;
hdr >>= 6;
if (hdr == RTMP_PS_ONEBYTE) {
@@ -171,21 +171,21 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
} else {
if (ffurl_read_complete(h, buf, 3) != 3)
return AVERROR(EIO);
- size += 3;
+ written += 3;
timestamp = AV_RB24(buf);
if (hdr != RTMP_PS_FOURBYTES) {
if (ffurl_read_complete(h, buf, 3) != 3)
return AVERROR(EIO);
- size += 3;
- data_size = AV_RB24(buf);
+ written += 3;
+ size = AV_RB24(buf);
if (ffurl_read_complete(h, buf, 1) != 1)
return AVERROR(EIO);
- size++;
+ written++;
type = buf[0];
if (hdr == RTMP_PS_TWELVEBYTES) {
if (ffurl_read_complete(h, buf, 4) != 4)
return AVERROR(EIO);
- size += 4;
+ written += 4;
extra = AV_RL32(buf);
}
}
@@ -199,36 +199,36 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
timestamp += prev_pkt[channel_id].timestamp;
if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
- data_size)) < 0)
+ size)) < 0)
return ret;
p->extra = extra;
// save history
prev_pkt[channel_id].channel_id = channel_id;
prev_pkt[channel_id].type = type;
- prev_pkt[channel_id].data_size = data_size;
+ prev_pkt[channel_id].size = size;
prev_pkt[channel_id].ts_delta = timestamp - prev_pkt[channel_id].timestamp;
prev_pkt[channel_id].timestamp = timestamp;
prev_pkt[channel_id].extra = extra;
- while (data_size > 0) {
- int toread = FFMIN(data_size, chunk_size);
+ while (size > 0) {
+ int toread = FFMIN(size, chunk_size);
if (ffurl_read_complete(h, p->data + offset, toread) != toread) {
ff_rtmp_packet_destroy(p);
return AVERROR(EIO);
}
- data_size -= chunk_size;
- offset += chunk_size;
- size += chunk_size;
- if (data_size > 0) {
+ size -= chunk_size;
+ offset += chunk_size;
+ written += chunk_size;
+ if (size > 0) {
if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker
ff_rtmp_packet_destroy(p);
return ret;
}
- size++;
+ written++;
if (t != (0xC0 + channel_id))
return -1;
}
}
- return size;
+ return written;
}
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
@@ -237,7 +237,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
uint8_t pkt_hdr[16], *p = pkt_hdr;
int mode = RTMP_PS_TWELVEBYTES;
int off = 0;
- int size = 0;
+ int written = 0;
int ret;
pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
@@ -246,7 +246,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
if (prev_pkt[pkt->channel_id].channel_id &&
pkt->extra == prev_pkt[pkt->channel_id].extra) {
if (pkt->type == prev_pkt[pkt->channel_id].type &&
- pkt->data_size == prev_pkt[pkt->channel_id].data_size) {
+ pkt->size == prev_pkt[pkt->channel_id].size) {
mode = RTMP_PS_FOURBYTES;
if (pkt->ts_delta == prev_pkt[pkt->channel_id].ts_delta)
mode = RTMP_PS_ONEBYTE;
@@ -270,7 +270,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
timestamp = pkt->ts_delta;
bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp);
if (mode != RTMP_PS_FOURBYTES) {
- bytestream_put_be24(&p, pkt->data_size);
+ bytestream_put_be24(&p, pkt->size);
bytestream_put_byte(&p, pkt->type);
if (mode == RTMP_PS_TWELVEBYTES)
bytestream_put_le32(&p, pkt->extra);
@@ -281,7 +281,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
// save history
prev_pkt[pkt->channel_id].channel_id = pkt->channel_id;
prev_pkt[pkt->channel_id].type = pkt->type;
- prev_pkt[pkt->channel_id].data_size = pkt->data_size;
+ prev_pkt[pkt->channel_id].size = pkt->size;
prev_pkt[pkt->channel_id].timestamp = pkt->timestamp;
if (mode != RTMP_PS_TWELVEBYTES) {
prev_pkt[pkt->channel_id].ts_delta = pkt->ts_delta;
@@ -292,20 +292,20 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)
return ret;
- size = p - pkt_hdr + pkt->data_size;
- while (off < pkt->data_size) {
- int towrite = FFMIN(chunk_size, pkt->data_size - off);
+ written = p - pkt_hdr + pkt->size;
+ while (off < pkt->size) {
+ int towrite = FFMIN(chunk_size, pkt->size - off);
if ((ret = ffurl_write(h, pkt->data + off, towrite)) < 0)
return ret;
off += towrite;
- if (off < pkt->data_size) {
+ if (off < pkt->size) {
uint8_t marker = 0xC0 | pkt->channel_id;
if ((ret = ffurl_write(h, &marker, 1)) < 0)
return ret;
- size++;
+ written++;
}
}
- return size;
+ return written;
}
int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
@@ -316,7 +316,7 @@ int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
if (!pkt->data)
return AVERROR(ENOMEM);
}
- pkt->data_size = size;
+ pkt->size = size;
pkt->channel_id = channel_id;
pkt->type = type;
pkt->timestamp = timestamp;
@@ -331,7 +331,7 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
if (!pkt)
return;
av_freep(&pkt->data);
- pkt->data_size = 0;
+ pkt->size = 0;
}
int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
@@ -438,7 +438,8 @@ static const char* rtmp_packet_type(int type)
}
}
-static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end)
+static void amf_tag_contents(void *ctx, const uint8_t *data,
+ const uint8_t *data_end)
{
unsigned int size;
char buf[1024];
@@ -484,7 +485,7 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d
return;
data += size;
av_log(ctx, AV_LOG_DEBUG, " %s: ", buf);
- ff_amf_tag_contents(ctx, data, data_end);
+ amf_tag_contents(ctx, data, data_end);
t = ff_amf_tag_size(data, data_end);
if (t < 0 || t >= data_end - data)
return;
@@ -502,12 +503,12 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d
void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
{
av_log(ctx, AV_LOG_DEBUG, "RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n",
- rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->data_size);
+ rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->size);
if (p->type == RTMP_PT_INVOKE || p->type == RTMP_PT_NOTIFY) {
- uint8_t *src = p->data, *src_end = p->data + p->data_size;
+ uint8_t *src = p->data, *src_end = p->data + p->size;
while (src < src_end) {
int sz;
- ff_amf_tag_contents(ctx, src, src_end);
+ amf_tag_contents(ctx, src, src_end);
sz = ff_amf_tag_size(src, src_end);
if (sz < 0)
break;
@@ -519,8 +520,41 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data));
} else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) {
int i;
- for (i = 0; i < p->data_size; i++)
+ for (i = 0; i < p->size; i++)
av_log(ctx, AV_LOG_DEBUG, " %02X", p->data[i]);
av_log(ctx, AV_LOG_DEBUG, "\n");
}
}
+
+int ff_amf_match_string(const uint8_t *data, int size, const char *str)
+{
+ int len = strlen(str);
+ int amf_len, type;
+
+ if (size < 1)
+ return 0;
+
+ type = *data++;
+
+ if (type != AMF_DATA_TYPE_LONG_STRING &&
+ type != AMF_DATA_TYPE_STRING)
+ return 0;
+
+ if (type == AMF_DATA_TYPE_LONG_STRING) {
+ if ((size -= 4 + 1) < 0)
+ return 0;
+ amf_len = bytestream_get_be32(&data);
+ } else {
+ if ((size -= 2 + 1) < 0)
+ return 0;
+ amf_len = bytestream_get_be16(&data);
+ }
+
+ if (amf_len > size)
+ return 0;
+
+ if (amf_len != len)
+ return 0;
+
+ return !memcmp(data, str, len);
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmppkt.h b/chromium/third_party/ffmpeg/libavformat/rtmppkt.h
index a9422954f56..9ca6382a17a 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmppkt.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtmppkt.h
@@ -1,6 +1,6 @@
/*
* RTMP packet utilities
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
@@ -81,7 +81,7 @@ typedef struct RTMPPacket {
uint32_t ts_delta; ///< timestamp increment to the previous one in milliseconds (latter only for media packets)
uint32_t extra; ///< probably an additional channel ID used during streaming data
uint8_t *data; ///< packet payload
- int data_size; ///< packet payload size
+ int size; ///< packet payload size
} RTMPPacket;
/**
@@ -282,6 +282,13 @@ int ff_amf_read_string(GetByteContext *gbc, uint8_t *str,
*/
int ff_amf_read_null(GetByteContext *gbc);
+/**
+ * Match AMF string with a NULL-terminated string.
+ *
+ * @return 0 if the strings do not match.
+ */
+
+int ff_amf_match_string(const uint8_t *data, int size, const char *str);
/** @} */ // AMF funcs
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmpproto.c b/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
index d73e015d55a..f230f9eca1b 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmpproto.c
@@ -1,6 +1,6 @@
/*
* RTMP network protocol
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
@@ -48,8 +48,6 @@
#include <zlib.h>
#endif
-//#define DEBUG
-
#define APP_MAX_LENGTH 1024
#define PLAYPATH_MAX_LENGTH 256
#define TCURL_MAX_LENGTH 512
@@ -62,6 +60,7 @@ typedef enum {
STATE_HANDSHAKED, ///< client has performed handshake
STATE_FCPUBLISH, ///< client FCPublishing stream (for output)
STATE_PLAYING, ///< client has started receiving multimedia data from server
+ STATE_SEEKING, ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
STATE_RECEIVING, ///< received a publish command (for input)
STATE_STOPPED, ///< the broadcast has been stopped
@@ -186,7 +185,7 @@ static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
int ret;
int i;
- bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset);
+ bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
return ret;
@@ -224,7 +223,7 @@ static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
double pkt_id;
int len;
- bytestream2_init(&gbc, pkt->data, pkt->data_size);
+ bytestream2_init(&gbc, pkt->data, pkt->size);
if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
goto fail;
@@ -385,7 +384,7 @@ static int gen_connect(URLContext *s, RTMPContext *rt)
}
}
- pkt.data_size = p - pkt.data;
+ pkt.size = p - pkt.data;
return rtmp_send_packet(rt, &pkt, 1);
}
@@ -406,7 +405,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
rt->prev_pkt[1])) < 0)
return ret;
cp = pkt.data;
- bytestream2_init(&gbc, cp, pkt.data_size);
+ bytestream2_init(&gbc, cp, pkt.size);
if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
ff_rtmp_packet_destroy(&pkt);
@@ -437,7 +436,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
return ret;
p = pkt.data;
bytestream_put_be32(&p, rt->server_bw);
- pkt.data_size = p - pkt.data;
+ pkt.size = p - pkt.data;
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
@@ -450,7 +449,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
p = pkt.data;
bytestream_put_be32(&p, rt->server_bw);
bytestream_put_byte(&p, 2); // dynamic
- pkt.data_size = p - pkt.data;
+ pkt.size = p - pkt.data;
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
@@ -512,7 +511,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
ff_amf_write_number(&p, 0);
ff_amf_write_object_end(&p);
- pkt.data_size = p - pkt.data;
+ pkt.size = p - pkt.data;
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
@@ -527,7 +526,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
ff_amf_write_number(&p, 0);
ff_amf_write_null(&p);
ff_amf_write_number(&p, 8192);
- pkt.data_size = p - pkt.data;
+ pkt.size = p - pkt.data;
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
@@ -706,6 +705,29 @@ static int gen_play(URLContext *s, RTMPContext *rt)
return rtmp_send_packet(rt, &pkt, 1);
}
+static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
+{
+ RTMPPacket pkt;
+ uint8_t *p;
+ int ret;
+
+ av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
+ timestamp);
+
+ if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
+ return ret;
+
+ pkt.extra = rt->main_channel_id;
+
+ p = pkt.data;
+ ff_amf_write_string(&p, "seek");
+ ff_amf_write_number(&p, 0); //no tracking back responses
+ ff_amf_write_null(&p); //as usual, the first null param
+ ff_amf_write_number(&p, timestamp); //where we want to jump
+
+ return rtmp_send_packet(rt, &pkt, 1);
+}
+
/**
* Generate 'publish' call and send it to the server.
*/
@@ -742,9 +764,9 @@ static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
uint8_t *p;
int ret;
- if (ppkt->data_size < 6) {
+ if (ppkt->size < 6) {
av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
- ppkt->data_size);
+ ppkt->size);
return AVERROR_INVALIDDATA;
}
@@ -1418,10 +1440,10 @@ static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
RTMPContext *rt = s->priv_data;
int ret;
- if (pkt->data_size < 4) {
+ if (pkt->size < 4) {
av_log(s, AV_LOG_ERROR,
"Too short chunk size change packet (%d)\n",
- pkt->data_size);
+ pkt->size);
return AVERROR_INVALIDDATA;
}
@@ -1451,9 +1473,9 @@ static int handle_ping(URLContext *s, RTMPPacket *pkt)
RTMPContext *rt = s->priv_data;
int t, ret;
- if (pkt->data_size < 2) {
+ if (pkt->size < 2) {
av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
- pkt->data_size);
+ pkt->size);
return AVERROR_INVALIDDATA;
}
@@ -1477,10 +1499,10 @@ static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
{
RTMPContext *rt = s->priv_data;
- if (pkt->data_size < 4) {
+ if (pkt->size < 4) {
av_log(s, AV_LOG_ERROR,
"Client bandwidth report packet is less than 4 bytes long (%d)\n",
- pkt->data_size);
+ pkt->size);
return AVERROR_INVALIDDATA;
}
@@ -1501,10 +1523,10 @@ static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
{
RTMPContext *rt = s->priv_data;
- if (pkt->data_size < 4) {
+ if (pkt->size < 4) {
av_log(s, AV_LOG_ERROR,
"Too short server bandwidth report packet (%d)\n",
- pkt->data_size);
+ pkt->size);
return AVERROR_INVALIDDATA;
}
@@ -1704,7 +1726,7 @@ static int handle_connect_error(URLContext *s, const char *desc)
static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
{
RTMPContext *rt = s->priv_data;
- const uint8_t *data_end = pkt->data + pkt->data_size;
+ const uint8_t *data_end = pkt->data + pkt->size;
char *tracked_method = NULL;
int level = AV_LOG_ERROR;
uint8_t tmpstr[256];
@@ -1752,7 +1774,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
GetByteContext gbc;
int ret;
- bytestream2_init(&gbc, p, pkt->data_size);
+ bytestream2_init(&gbc, p, pkt->size);
if (ff_amf_read_string(&gbc, command, sizeof(command),
&stringlen)) {
av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
@@ -1804,7 +1826,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
return ret;
}
pp = spkt.data;
- bytestream2_init_writer(&pbc, pp, spkt.data_size);
+ bytestream2_init_writer(&pbc, pp, spkt.size);
bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin
bytestream2_put_be32(&pbc, rt->nb_streamid);
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
@@ -1863,7 +1885,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
* if a client creates more than 2^32 - 2 streams. */
}
}
- spkt.data_size = pp - spkt.data;
+ spkt.size = pp - spkt.data;
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&spkt);
@@ -1884,7 +1906,7 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
return ret;
}
- if (!memcmp(tracked_method, "connect", 7)) {
+ if (!strcmp(tracked_method, "connect")) {
if (!rt->is_input) {
if ((ret = gen_release_stream(s, rt)) < 0)
goto fail;
@@ -1910,7 +1932,7 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
goto fail;
}
}
- } else if (!memcmp(tracked_method, "createStream", 12)) {
+ } else if (!strcmp(tracked_method, "createStream")) {
//extract a number from the result
if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
@@ -1937,7 +1959,7 @@ fail:
static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
{
RTMPContext *rt = s->priv_data;
- const uint8_t *data_end = pkt->data + pkt->data_size;
+ const uint8_t *data_end = pkt->data + pkt->size;
const uint8_t *ptr = pkt->data + 11;
uint8_t tmpstr[256];
int i, t;
@@ -1962,6 +1984,7 @@ static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
+ if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
return 0;
}
@@ -1972,23 +1995,23 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt)
int ret = 0;
//TODO: check for the messages sent for wrong state?
- if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
+ if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
if ((ret = handle_invoke_error(s, pkt)) < 0)
return ret;
- } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
+ } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
if ((ret = handle_invoke_result(s, pkt)) < 0)
return ret;
- } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
+ } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
if ((ret = handle_invoke_status(s, pkt)) < 0)
return ret;
- } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
+ } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
if ((ret = gen_check_bw(s, rt)) < 0)
return ret;
- } else if (!memcmp(pkt->data, "\002\000\015releaseStream", 16) ||
- !memcmp(pkt->data, "\002\000\011FCPublish", 12) ||
- !memcmp(pkt->data, "\002\000\007publish", 10) ||
- !memcmp(pkt->data, "\002\000\010_checkbw", 11) ||
- !memcmp(pkt->data, "\002\000\014createStream", 15)) {
+ } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
+ ff_amf_match_string(pkt->data, pkt->size, "FCPublish") ||
+ ff_amf_match_string(pkt->data, pkt->size, "publish") ||
+ ff_amf_match_string(pkt->data, pkt->size, "_checkbw") ||
+ ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
if ((ret = send_invoke_response(s, pkt)) < 0)
return ret;
}
@@ -2011,7 +2034,7 @@ static int handle_notify(URLContext *s, RTMPPacket *pkt) {
unsigned datatowritelength;
p = pkt->data;
- bytestream2_init(&gbc, p, pkt->data_size);
+ bytestream2_init(&gbc, p, pkt->size);
if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
&stringlen))
return AVERROR_INVALIDDATA;
@@ -2125,7 +2148,7 @@ static int get_packet(URLContext *s, int for_header)
int ret;
uint8_t *p;
const uint8_t *next;
- uint32_t data_size;
+ uint32_t size;
uint32_t ts, cts, pts=0;
if (rt->state == STATE_STOPPED)
@@ -2150,6 +2173,17 @@ static int get_packet(URLContext *s, int for_header)
}
ret = rtmp_parse_result(s, rt, &rpkt);
+
+ // At this point we must check if we are in the seek state and continue
+ // with the next packet. handle_invoke will get us out of this state
+ // when the right message is encountered
+ if (rt->state == STATE_SEEKING) {
+ ff_rtmp_packet_destroy(&rpkt);
+ // We continue, let the natural flow of things happen:
+ // AVERROR(EAGAIN) or handle_invoke gets us out of here
+ continue;
+ }
+
if (ret < 0) {//serious error in current packet
ff_rtmp_packet_destroy(&rpkt);
return ret;
@@ -2168,24 +2202,25 @@ static int get_packet(URLContext *s, int for_header)
ff_rtmp_packet_destroy(&rpkt);
return 0;
}
- if (!rpkt.data_size || !rt->is_input) {
+ if (!rpkt.size || !rt->is_input) {
ff_rtmp_packet_destroy(&rpkt);
continue;
}
if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
- (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
+ (rpkt.type == RTMP_PT_NOTIFY &&
+ ff_amf_match_string(rpkt.data, rpkt.size, "onMetaData"))) {
ts = rpkt.timestamp;
// generate packet header and put data into buffer for FLV demuxer
rt->flv_off = 0;
- rt->flv_size = rpkt.data_size + 15;
+ rt->flv_size = rpkt.size + 15;
rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
bytestream_put_byte(&p, rpkt.type);
- bytestream_put_be24(&p, rpkt.data_size);
+ bytestream_put_be24(&p, rpkt.size);
bytestream_put_be24(&p, ts);
bytestream_put_byte(&p, ts >> 24);
bytestream_put_be24(&p, 0);
- bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
+ bytestream_put_buffer(&p, rpkt.data, rpkt.size);
bytestream_put_be32(&p, 0);
ff_rtmp_packet_destroy(&rpkt);
return 0;
@@ -2200,14 +2235,14 @@ static int get_packet(URLContext *s, int for_header)
} else if (rpkt.type == RTMP_PT_METADATA) {
// we got raw FLV data, make it available for FLV demuxer
rt->flv_off = 0;
- rt->flv_size = rpkt.data_size;
+ rt->flv_size = rpkt.size;
rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
/* rewrite timestamps */
next = rpkt.data;
ts = rpkt.timestamp;
- while (next - rpkt.data < rpkt.data_size - 11) {
+ while (next - rpkt.data < rpkt.size - 11) {
next++;
- data_size = bytestream_get_be24(&next);
+ size = bytestream_get_be24(&next);
p=next;
cts = bytestream_get_be24(&next);
cts |= bytestream_get_byte(&next) << 24;
@@ -2217,9 +2252,9 @@ static int get_packet(URLContext *s, int for_header)
pts = cts;
bytestream_put_be24(&p, ts);
bytestream_put_byte(&p, ts >> 24);
- next += data_size + 3 + 4;
+ next += size + 3 + 4;
}
- memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
+ memcpy(rt->flv_data, rpkt.data, rpkt.size);
ff_rtmp_packet_destroy(&rpkt);
return 0;
}
@@ -2234,7 +2269,7 @@ static int rtmp_close(URLContext *h)
if (!rt->is_input) {
rt->flv_data = NULL;
- if (rt->out_pkt.data_size)
+ if (rt->out_pkt.size)
ff_rtmp_packet_destroy(&rt->out_pkt);
if (rt->state > STATE_FCPUBLISH)
ret = gen_fcunpublish_stream(h, rt);
@@ -2276,6 +2311,13 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
hostname, sizeof(hostname), &port,
path, sizeof(path), s->filename);
+ if (strchr(path, ' ')) {
+ av_log(s, AV_LOG_WARNING,
+ "Detected librtmp style URL parameters, these aren't supported "
+ "by the libavformat internal RTMP handler currently enabled. "
+ "See the documentation for the correct way to pass parameters.\n");
+ }
+
if (auth[0]) {
char *ptr = strchr(auth, ':');
if (ptr) {
@@ -2514,6 +2556,26 @@ static int rtmp_read(URLContext *s, uint8_t *buf, int size)
return orig_size;
}
+static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
+ int flags)
+{
+ RTMPContext *rt = s->priv_data;
+ int ret;
+ av_log(s, AV_LOG_DEBUG,
+ "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
+ stream_index, timestamp, flags);
+ if ((ret = gen_seek(s, rt, timestamp)) < 0) {
+ av_log(s, AV_LOG_ERROR,
+ "Unable to send seek command on stream index %d at timestamp "
+ "%"PRId64" with flags %08x\n",
+ stream_index, timestamp, flags);
+ return ret;
+ }
+ rt->flv_off = rt->flv_size;
+ rt->state = STATE_SEEKING;
+ return timestamp;
+}
+
static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
{
RTMPContext *rt = s->priv_data;
@@ -2665,6 +2727,7 @@ URLProtocol ff_##flavor##_protocol = { \
.name = #flavor, \
.url_open = rtmp_open, \
.url_read = rtmp_read, \
+ .url_read_seek = rtmp_seek, \
.url_write = rtmp_write, \
.url_close = rtmp_close, \
.priv_data_size = sizeof(RTMPContext), \
diff --git a/chromium/third_party/ffmpeg/libavformat/rtp.c b/chromium/third_party/ffmpeg/libavformat/rtp.c
index c4dcf6ae8d4..4d41350f3cd 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtp.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtp.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "avformat.h"
@@ -144,7 +145,7 @@ enum AVCodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type)
int i;
for (i = 0; rtp_payload_types[i].pt >= 0; i++)
- if (!strcmp(buf, rtp_payload_types[i].enc_name) && (codec_type == rtp_payload_types[i].codec_type))
+ if (!av_strcasecmp(buf, rtp_payload_types[i].enc_name) && (codec_type == rtp_payload_types[i].codec_type))
return rtp_payload_types[i].codec_id;
return AV_CODEC_ID_NONE;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtp.h b/chromium/third_party/ffmpeg/libavformat/rtp.h
index 1732af8a918..66a4f3afbd9 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtp.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtp.h
@@ -23,6 +23,7 @@
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
+#include "libavutil/mathematics.h"
/**
* Return the payload type for a given stream used in the given format context.
@@ -109,4 +110,6 @@ enum RTCPType {
#define RTP_PT_IS_RTCP(x) (((x) >= RTCP_FIR && (x) <= RTCP_IJ) || \
((x) >= RTCP_SR && (x) <= RTCP_TOKEN))
+#define NTP_TO_RTP_FORMAT(x) av_rescale((x), INT64_C(1) << 32, 1000000)
+
#endif /* AVFORMAT_RTP_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec.c b/chromium/third_party/ffmpeg/libavformat/rtpdec.c
index b512b8975ff..b2342f18249 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec.c
@@ -78,8 +78,8 @@ void av_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler);
- ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
+ ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec.h b/chromium/third_party/ffmpeg/libavformat/rtpdec.h
index 623d911b997..2a191ec762d 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec.h
@@ -51,10 +51,6 @@ int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
void ff_rtp_parse_close(RTPDemuxContext *s);
int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s);
void ff_rtp_reset_packet_queue(RTPDemuxContext *s);
-int ff_rtp_get_local_rtp_port(URLContext *h);
-int ff_rtp_get_local_rtcp_port(URLContext *h);
-
-int ff_rtp_set_remote_url(URLContext *h, const char *uri);
/**
* Send a dummy packet on both port pairs to set up the connection
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_g726.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_g726.c
index ec37f09155d..7e9ef56e066 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_g726.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_g726.c
@@ -18,11 +18,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
#include "avformat.h"
#include "rtpdec_formats.h"
#define RTP_G726_HANDLER(bitrate) \
-static int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, PayloadContext *data) \
+static av_cold int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, \
+ PayloadContext *data) \
{ \
AVStream *stream = s->streams[st_index]; \
AVCodecContext *codec = stream->codec; \
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_h263.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_h263.c
index dd7aa60fd51..ae4cc270407 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_h263.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_h263.c
@@ -21,9 +21,11 @@
#include "avformat.h"
#include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
-static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int h263_init(AVFormatContext *ctx, int st_index,
+ PayloadContext *data)
{
if (st_index < 0)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_h263_rfc2190.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_h263_rfc2190.c
index 4b6e9967701..116db750658 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_h263_rfc2190.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_h263_rfc2190.c
@@ -27,6 +27,7 @@
#include "avformat.h"
#include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
#include "libavcodec/get_bits.h"
@@ -55,7 +56,7 @@ static void h263_free_context(PayloadContext *data)
av_free(data);
}
-static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
{
if (st_index < 0)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c
index d1133b78e1b..be657c0ccc7 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_h264.c
@@ -33,6 +33,7 @@
* FU-B packet types)
*/
+#include "libavutil/attributes.h"
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavcodec/get_bits.h"
@@ -338,7 +339,8 @@ static void h264_free_context(PayloadContext *data)
av_free(data);
}
-static int h264_init(AVFormatContext *s, int st_index, PayloadContext *data)
+static av_cold int h264_init(AVFormatContext *s, int st_index,
+ PayloadContext *data)
{
if (st_index < 0)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg12.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg12.c
index 82e58a097ab..d73ff1e1441 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg12.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg12.c
@@ -19,10 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
+#include "rtpdec_formats.h"
-static int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
{
if (st_index < 0)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg4.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg4.c
index 3f1f244b83d..571b7392e09 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg4.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_mpeg4.c
@@ -29,6 +29,7 @@
#include "rtpdec_formats.h"
#include "internal.h"
+#include "libavutil/attributes.h"
#include "libavutil/avstring.h"
#include "libavcodec/get_bits.h"
@@ -252,7 +253,8 @@ static int parse_sdp_line(AVFormatContext *s, int st_index,
return 0;
}
-static int init_video(AVFormatContext *s, int st_index, PayloadContext *data)
+static av_cold int init_video(AVFormatContext *s, int st_index,
+ PayloadContext *data)
{
if (st_index < 0)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_mpegts.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_mpegts.c
index cbb8eb49f7e..5b851c4fd77 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_mpegts.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_mpegts.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
#include "mpegts.h"
#include "rtpdec_formats.h"
@@ -43,7 +44,8 @@ static void mpegts_free_context(PayloadContext *data)
av_free(data);
}
-static int mpegts_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+static av_cold int mpegts_init(AVFormatContext *ctx, int st_index,
+ PayloadContext *data)
{
data->ts = ff_mpegts_parse_open(ctx);
if (!data->ts)
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c b/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c
index eddb781ddb8..52a94b31598 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpdec_xiph.c
@@ -27,6 +27,7 @@
* @author Josh Allmann <joshua.allmann@gmail.com>
*/
+#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/base64.h"
@@ -69,8 +70,8 @@ static void xiph_free_context(PayloadContext * data)
av_free(data);
}
-static int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
- PayloadContext *data)
+static av_cold int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
+ PayloadContext *data)
{
if (st_index < 0)
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpenc.c b/chromium/third_party/ffmpeg/libavformat/rtpenc.c
index 7adf687c7f9..9fd361d3036 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpenc.c
@@ -28,8 +28,6 @@
#include "rtpenc.h"
-//#define DEBUG
-
static const AVOption options[] = {
FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
{ "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
@@ -278,8 +276,7 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
avio_w8(s1->pb, RTCP_SR);
avio_wb16(s1->pb, 6); /* length in words - 1 */
avio_wb32(s1->pb, s->ssrc);
- avio_wb32(s1->pb, ntp_time / 1000000);
- avio_wb32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
+ avio_wb64(s1->pb, NTP_TO_RTP_FORMAT(ntp_time));
avio_wb32(s1->pb, rtp_ts);
avio_wb32(s1->pb, s->packet_count);
avio_wb32(s1->pb, s->octet_count);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpenc.h b/chromium/third_party/ffmpeg/libavformat/rtpenc.h
index 72a5fa4c8f4..b0c9630ee91 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpenc.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtpenc.h
@@ -38,11 +38,9 @@ struct RTPMuxContext {
int max_payload_size;
int num_frames;
- /* rtcp sender statistics receive */
+ /* rtcp sender statistics */
int64_t last_rtcp_ntp_time;
int64_t first_rtcp_ntp_time;
-
- /* rtcp sender statistics */
unsigned int packet_count;
unsigned int octet_count;
unsigned int last_octet_count;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c b/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c
index 70d68ce5341..9379d94697b 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpenc_chain.c
@@ -78,16 +78,19 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
avcodec_copy_context(rtpctx->streams[0]->codec, st->codec);
if (handle) {
- ffio_fdopen(&rtpctx->pb, handle);
+ ret = ffio_fdopen(&rtpctx->pb, handle);
+ if (ret < 0)
+ ffurl_close(handle);
} else
- ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
- ret = avformat_write_header(rtpctx, &opts);
+ ret = ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
+ if (!ret)
+ ret = avformat_write_header(rtpctx, &opts);
av_dict_free(&opts);
if (ret) {
- if (handle) {
+ if (handle && rtpctx->pb) {
avio_close(rtpctx->pb);
- } else {
+ } else if (rtpctx->pb) {
uint8_t *ptr;
avio_close_dyn_buf(rtpctx->pb, &ptr);
av_free(ptr);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpproto.c b/chromium/third_party/ffmpeg/libavformat/rtpproto.c
index 62ec4c9d7de..bf9c60d9998 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtpproto.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtpproto.c
@@ -28,7 +28,8 @@
#include "libavutil/avstring.h"
#include "avformat.h"
#include "avio_internal.h"
-#include "rtpdec.h"
+#include "rtp.h"
+#include "rtpproto.h"
#include "url.h"
#include <stdarg.h>
@@ -42,7 +43,11 @@
typedef struct RTPContext {
URLContext *rtp_hd, *rtcp_hd;
- int rtp_fd, rtcp_fd;
+ int rtp_fd, rtcp_fd, nb_ssm_include_addrs, nb_ssm_exclude_addrs;
+ struct sockaddr_storage **ssm_include_addrs, **ssm_exclude_addrs;
+ int write_to_source;
+ struct sockaddr_storage last_rtp_source, last_rtcp_source;
+ socklen_t last_rtp_source_len, last_rtcp_source_len;
} RTPContext;
/**
@@ -59,22 +64,109 @@ int ff_rtp_set_remote_url(URLContext *h, const char *uri)
{
RTPContext *s = h->priv_data;
char hostname[256];
- int port;
+ int port, rtcp_port;
+ const char *p;
char buf[1024];
char path[1024];
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
path, sizeof(path), uri);
+ rtcp_port = port + 1;
+
+ p = strchr(uri, '?');
+ if (p) {
+ if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
+ rtcp_port = strtol(buf, NULL, 10);
+ }
+ }
ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port, "%s", path);
ff_udp_set_remote_url(s->rtp_hd, buf);
- ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port + 1, "%s", path);
+ ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, rtcp_port, "%s", path);
ff_udp_set_remote_url(s->rtcp_hd, buf);
return 0;
}
+static struct addrinfo* rtp_resolve_host(const char *hostname, int port,
+ int type, int family, int flags)
+{
+ struct addrinfo hints = { 0 }, *res = 0;
+ int error;
+ char service[16];
+
+ snprintf(service, sizeof(service), "%d", port);
+ hints.ai_socktype = type;
+ hints.ai_family = family;
+ hints.ai_flags = flags;
+ if ((error = getaddrinfo(hostname, service, &hints, &res))) {
+ res = NULL;
+ av_log(NULL, AV_LOG_ERROR, "rtp_resolve_host: %s\n", gai_strerror(error));
+ }
+
+ return res;
+}
+
+static int compare_addr(const struct sockaddr_storage *a,
+ const struct sockaddr_storage *b)
+{
+ if (a->ss_family != b->ss_family)
+ return 1;
+ if (a->ss_family == AF_INET) {
+ return (((const struct sockaddr_in *)a)->sin_addr.s_addr !=
+ ((const struct sockaddr_in *)b)->sin_addr.s_addr);
+ }
+
+#if HAVE_STRUCT_SOCKADDR_IN6
+ if (a->ss_family == AF_INET6) {
+ const uint8_t *s6_addr_a = ((const struct sockaddr_in6 *)a)->sin6_addr.s6_addr;
+ const uint8_t *s6_addr_b = ((const struct sockaddr_in6 *)b)->sin6_addr.s6_addr;
+ return memcmp(s6_addr_a, s6_addr_b, 16);
+ }
+#endif
+ return 1;
+}
+
+static int get_port(const struct sockaddr_storage *ss)
+{
+ if (ss->ss_family == AF_INET)
+ return ntohs(((const struct sockaddr_in *)ss)->sin_port);
+#if HAVE_STRUCT_SOCKADDR_IN6
+ if (ss->ss_family == AF_INET6)
+ return ntohs(((const struct sockaddr_in6 *)ss)->sin6_port);
+#endif
+ return 0;
+}
+
+static void set_port(struct sockaddr_storage *ss, int port)
+{
+ if (ss->ss_family == AF_INET)
+ ((struct sockaddr_in *)ss)->sin_port = htons(port);
+#if HAVE_STRUCT_SOCKADDR_IN6
+ else if (ss->ss_family == AF_INET6)
+ ((struct sockaddr_in6 *)ss)->sin6_port = htons(port);
+#endif
+}
+
+static int rtp_check_source_lists(RTPContext *s, struct sockaddr_storage *source_addr_ptr)
+{
+ int i;
+ if (s->nb_ssm_exclude_addrs) {
+ for (i = 0; i < s->nb_ssm_exclude_addrs; i++) {
+ if (!compare_addr(source_addr_ptr, s->ssm_exclude_addrs[i]))
+ return 1;
+ }
+ }
+ if (s->nb_ssm_include_addrs) {
+ for (i = 0; i < s->nb_ssm_include_addrs; i++) {
+ if (!compare_addr(source_addr_ptr, s->ssm_include_addrs[i]))
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
/**
* add option to url of the form:
@@ -99,7 +191,9 @@ static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const
static void build_udp_url(char *buf, int buf_size,
const char *hostname, int port,
int local_port, int ttl,
- int max_packet_size, int connect)
+ int max_packet_size, int connect,
+ const char *include_sources,
+ const char *exclude_sources)
{
ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
if (local_port >= 0)
@@ -111,6 +205,50 @@ static void build_udp_url(char *buf, int buf_size,
if (connect)
url_add_option(buf, buf_size, "connect=1");
url_add_option(buf, buf_size, "fifo_size=0");
+ if (include_sources && include_sources[0])
+ url_add_option(buf, buf_size, "sources=%s", include_sources);
+ if (exclude_sources && exclude_sources[0])
+ url_add_option(buf, buf_size, "block=%s", exclude_sources);
+}
+
+static void rtp_parse_addr_list(URLContext *h, char *buf,
+ struct sockaddr_storage ***address_list_ptr,
+ int *address_list_size_ptr)
+{
+ struct addrinfo *ai = NULL;
+ struct sockaddr_storage *source_addr;
+ char tmp = '\0', *p = buf, *next;
+
+ /* Resolve all of the IPs */
+
+ while (p && p[0]) {
+ next = strchr(p, ',');
+
+ if (next) {
+ tmp = *next;
+ *next = '\0';
+ }
+
+ ai = rtp_resolve_host(p, 0, SOCK_DGRAM, AF_UNSPEC, 0);
+ if (ai) {
+ source_addr = av_mallocz(sizeof(struct sockaddr_storage));
+ if (!source_addr)
+ break;
+
+ memcpy(source_addr, ai->ai_addr, ai->ai_addrlen);
+ freeaddrinfo(ai);
+ dynarray_add(address_list_ptr, address_list_size_ptr, source_addr);
+ } else {
+ av_log(h, AV_LOG_WARNING, "Unable to resolve %s\n", p);
+ }
+
+ if (next) {
+ *next = tmp;
+ p = next + 1;
+ } else {
+ p = NULL;
+ }
+ }
}
/**
@@ -121,6 +259,9 @@ static void build_udp_url(char *buf, int buf_size,
* 'localrtcpport=n' : set the local rtcp port to n
* 'pkt_size=n' : set max packet size
* 'connect=0/1' : do a connect() on the UDP socket
+ * 'sources=ip[,ip]' : list allowed source IP addresses
+ * 'block=ip[,ip]' : list disallowed source IP addresses
+ * 'write_to_source=0/1' : send packets to the source address of the latest received packet
* deprecated option:
* 'localport=n' : set the local port to n
*
@@ -136,7 +277,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
int rtp_port, rtcp_port,
ttl, connect,
local_rtp_port, local_rtcp_port, max_packet_size;
- char hostname[256];
+ char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
char buf[1024];
char path[1024];
const char *p;
@@ -174,11 +315,22 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
connect = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
+ s->write_to_source = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
+ av_strlcpy(include_sources, buf, sizeof(include_sources));
+ rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
+ av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
+ rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
+ }
}
build_udp_url(buf, sizeof(buf),
hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
- connect);
+ connect, include_sources, exclude_sources);
if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
goto fail;
if (local_rtp_port>=0 && local_rtcp_port<0)
@@ -186,7 +338,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
build_udp_url(buf, sizeof(buf),
hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
- connect);
+ connect, include_sources, exclude_sources);
if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
goto fail;
@@ -210,48 +362,41 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
static int rtp_read(URLContext *h, uint8_t *buf, int size)
{
RTPContext *s = h->priv_data;
- struct sockaddr_storage from;
- socklen_t from_len;
- int len, n;
+ int len, n, i;
struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
+ int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100;
+ struct sockaddr_storage *addrs[2] = { &s->last_rtp_source, &s->last_rtcp_source };
+ socklen_t *addr_lens[2] = { &s->last_rtp_source_len, &s->last_rtcp_source_len };
for(;;) {
if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
- /* build fdset to listen to RTP and RTCP packets */
- n = poll(p, 2, 100);
+ n = poll(p, 2, poll_delay);
if (n > 0) {
- /* first try RTCP */
- if (p[1].revents & POLLIN) {
- from_len = sizeof(from);
- len = recvfrom (s->rtcp_fd, buf, size, 0,
- (struct sockaddr *)&from, &from_len);
- if (len < 0) {
- if (ff_neterrno() == AVERROR(EAGAIN) ||
- ff_neterrno() == AVERROR(EINTR))
- continue;
- return AVERROR(EIO);
- }
- break;
- }
- /* then RTP */
- if (p[0].revents & POLLIN) {
- from_len = sizeof(from);
- len = recvfrom (s->rtp_fd, buf, size, 0,
- (struct sockaddr *)&from, &from_len);
+ /* first try RTCP, then RTP */
+ for (i = 1; i >= 0; i--) {
+ if (!(p[i].revents & POLLIN))
+ continue;
+ *addr_lens[i] = sizeof(*addrs[i]);
+ len = recvfrom(p[i].fd, buf, size, 0,
+ (struct sockaddr *)addrs[i], addr_lens[i]);
if (len < 0) {
if (ff_neterrno() == AVERROR(EAGAIN) ||
ff_neterrno() == AVERROR(EINTR))
continue;
return AVERROR(EIO);
}
- break;
+ if (rtp_check_source_lists(s, addrs[i]))
+ continue;
+ return len;
}
} else if (n < 0) {
if (ff_neterrno() == AVERROR(EINTR))
continue;
return AVERROR(EIO);
}
+ if (h->flags & AVIO_FLAG_NONBLOCK)
+ return AVERROR(EAGAIN);
}
return len;
}
@@ -262,6 +407,60 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
int ret;
URLContext *hd;
+ if (size < 2)
+ return AVERROR(EINVAL);
+
+ if (s->write_to_source) {
+ int fd;
+ struct sockaddr_storage *source, temp_source;
+ socklen_t *source_len, temp_len;
+ if (!s->last_rtp_source.ss_family && !s->last_rtcp_source.ss_family) {
+ av_log(h, AV_LOG_ERROR,
+ "Unable to send packet to source, no packets received yet\n");
+ // Intentionally not returning an error here
+ return size;
+ }
+
+ if (RTP_PT_IS_RTCP(buf[1])) {
+ fd = s->rtcp_fd;
+ source = &s->last_rtcp_source;
+ source_len = &s->last_rtcp_source_len;
+ } else {
+ fd = s->rtp_fd;
+ source = &s->last_rtp_source;
+ source_len = &s->last_rtp_source_len;
+ }
+ if (!source->ss_family) {
+ source = &temp_source;
+ source_len = &temp_len;
+ if (RTP_PT_IS_RTCP(buf[1])) {
+ temp_source = s->last_rtp_source;
+ temp_len = s->last_rtp_source_len;
+ set_port(source, get_port(source) + 1);
+ av_log(h, AV_LOG_INFO,
+ "Not received any RTCP packets yet, inferring peer port "
+ "from the RTP port\n");
+ } else {
+ temp_source = s->last_rtcp_source;
+ temp_len = s->last_rtcp_source_len;
+ set_port(source, get_port(source) - 1);
+ av_log(h, AV_LOG_INFO,
+ "Not received any RTP packets yet, inferring peer port "
+ "from the RTCP port\n");
+ }
+ }
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = ff_network_wait_fd(fd, 1);
+ if (ret < 0)
+ return ret;
+ }
+ ret = sendto(fd, buf, size, 0, (struct sockaddr *) source,
+ *source_len);
+
+ return ret < 0 ? ff_neterrno() : ret;
+ }
+
if (RTP_PT_IS_RTCP(buf[1])) {
/* RTCP payload type */
hd = s->rtcp_hd;
@@ -277,6 +476,14 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
static int rtp_close(URLContext *h)
{
RTPContext *s = h->priv_data;
+ int i;
+
+ for (i = 0; i < s->nb_ssm_include_addrs; i++)
+ av_free(s->ssm_include_addrs[i]);
+ av_freep(&s->ssm_include_addrs);
+ for (i = 0; i < s->nb_ssm_exclude_addrs; i++)
+ av_free(s->ssm_exclude_addrs[i]);
+ av_freep(&s->ssm_exclude_addrs);
ffurl_close(s->rtp_hd);
ffurl_close(s->rtcp_hd);
diff --git a/chromium/third_party/ffmpeg/libavformat/rtpproto.h b/chromium/third_party/ffmpeg/libavformat/rtpproto.h
new file mode 100644
index 00000000000..5b243fb2486
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/rtpproto.h
@@ -0,0 +1,31 @@
+/*
+ * RTP network protocol
+ *
+ * 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_RTPPROTO_H
+#define AVFORMAT_RTPPROTO_H
+
+#include "url.h"
+
+int ff_rtp_set_remote_url(URLContext *h, const char *uri);
+
+int ff_rtp_get_local_rtp_port(URLContext *h);
+int ff_rtp_get_local_rtcp_port(URLContext *h);
+
+#endif /* AVFORMAT_RTPPROTO_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/rtsp.c b/chromium/third_party/ffmpeg/libavformat/rtsp.c
index dc94f0f795c..2abb36b4a5d 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtsp.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtsp.c
@@ -42,6 +42,7 @@
#include "rtsp.h"
#include "rtpdec.h"
+#include "rtpproto.h"
#include "rdt.h"
#include "rtpdec_formats.h"
#include "rtpenc_chain.h"
@@ -49,8 +50,6 @@
#include "rtpenc.h"
#include "mpegts.h"
-//#define DEBUG
-
/* Timeout values for socket poll, in ms,
* and read_packet(), in seconds */
#define POLL_TIMEOUT_MS 100
@@ -66,8 +65,7 @@
#define RTSP_FLAG_OPTS(name, longname) \
{ name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
- { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }, \
- { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" }
+ { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
#define RTSP_MEDIATYPE_OPTS(name, longname) \
{ name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_DATA+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
@@ -87,18 +85,21 @@ const AVOption ff_rtsp_options[] = {
{ "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
{ "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
+ { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" },
RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
{ "min_port", "Minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
{ "max_port", "Maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
{ "timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies flag listen", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
{ "stimeout", "timeout (in micro seconds) of socket i/o operations.", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
RTSP_REORDERING_OPTS(),
+ { "user-agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
{ NULL },
};
static const AVOption sdp_options[] = {
RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
{ "custom_io", "Use custom IO", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" },
+ { "rtcp_to_source", "Send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, "rtsp_flags" },
RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
RTSP_REORDERING_OPTS(),
{ NULL },
@@ -290,8 +291,27 @@ typedef struct SDPParseState {
struct sockaddr_storage default_ip;
int default_ttl;
int skip_media; ///< set if an unknown m= line occurs
+ int nb_default_include_source_addrs; /**< Number of source-specific multicast include source IP address (from SDP content) */
+ struct RTSPSource **default_include_source_addrs; /**< Source-specific multicast include source IP address (from SDP content) */
+ int nb_default_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP address (from SDP content) */
+ struct RTSPSource **default_exclude_source_addrs; /**< Source-specific multicast exclude source IP address (from SDP content) */
} SDPParseState;
+static void copy_default_source_addrs(struct RTSPSource **addrs, int count,
+ struct RTSPSource ***dest, int *dest_count)
+{
+ RTSPSource *rtsp_src, *rtsp_src2;
+ int i;
+ for (i = 0; i < count; i++) {
+ rtsp_src = addrs[i];
+ rtsp_src2 = av_malloc(sizeof(*rtsp_src2));
+ if (!rtsp_src2)
+ continue;
+ memcpy(rtsp_src2, rtsp_src, sizeof(*rtsp_src));
+ dynarray_add(dest, dest_count, rtsp_src2);
+ }
+}
+
static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
int letter, const char *buf)
{
@@ -302,6 +322,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
int payload_type, i;
AVStream *st;
RTSPStream *rtsp_st;
+ RTSPSource *rtsp_src;
struct sockaddr_storage sdp_ip;
int ttl;
@@ -370,6 +391,15 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
rtsp_st->sdp_ip = s1->default_ip;
rtsp_st->sdp_ttl = s1->default_ttl;
+ copy_default_source_addrs(s1->default_include_source_addrs,
+ s1->nb_default_include_source_addrs,
+ &rtsp_st->include_source_addrs,
+ &rtsp_st->nb_include_source_addrs);
+ copy_default_source_addrs(s1->default_exclude_source_addrs,
+ s1->nb_default_exclude_source_addrs,
+ &rtsp_st->exclude_source_addrs,
+ &rtsp_st->nb_exclude_source_addrs);
+
get_word(buf1, sizeof(buf1), &p); /* port */
rtsp_st->sdp_port = atoi(buf1);
@@ -499,6 +529,43 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
p += strspn(p, SPACE_CHARS);
if (av_strstart(p, "inline:", &p))
get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
+ } else if (av_strstart(p, "source-filter:", &p)) {
+ int exclude = 0;
+ get_word(buf1, sizeof(buf1), &p);
+ if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
+ return;
+ exclude = !strcmp(buf1, "excl");
+
+ get_word(buf1, sizeof(buf1), &p);
+ if (strcmp(buf1, "IN") != 0)
+ return;
+ get_word(buf1, sizeof(buf1), &p);
+ if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
+ return;
+ // not checking that the destination address actually matches or is wildcard
+ get_word(buf1, sizeof(buf1), &p);
+
+ while (*p != '\0') {
+ rtsp_src = av_mallocz(sizeof(*rtsp_src));
+ if (!rtsp_src)
+ return;
+ get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
+ if (exclude) {
+ if (s->nb_streams == 0) {
+ dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
+ } else {
+ rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+ dynarray_add(&rtsp_st->exclude_source_addrs, &rtsp_st->nb_exclude_source_addrs, rtsp_src);
+ }
+ } else {
+ if (s->nb_streams == 0) {
+ dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
+ } else {
+ rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+ dynarray_add(&rtsp_st->include_source_addrs, &rtsp_st->nb_include_source_addrs, rtsp_src);
+ }
+ }
+ }
} else {
if (rt->server_type == RTSP_SERVER_WMS)
ff_wms_parse_sdp_a_line(s, p);
@@ -523,7 +590,7 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
{
RTSPState *rt = s->priv_data;
const char *p;
- int letter;
+ int letter, i;
/* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
* contain long SDP lines containing complete ASF Headers (several
* kB) or arrays of MDPR (RM stream descriptor) headers plus
@@ -560,6 +627,14 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
if (*p == '\n')
p++;
}
+
+ for (i = 0; i < s1->nb_default_include_source_addrs; i++)
+ av_free(s1->default_include_source_addrs[i]);
+ av_freep(&s1->default_include_source_addrs);
+ for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
+ av_free(s1->default_exclude_source_addrs[i]);
+ av_freep(&s1->default_exclude_source_addrs);
+
rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
if (!rt->p) return AVERROR(ENOMEM);
return 0;
@@ -603,7 +678,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
void ff_rtsp_close_streams(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
- int i;
+ int i, j;
RTSPStream *rtsp_st;
ff_rtsp_undo_setup(s);
@@ -613,6 +688,13 @@ void ff_rtsp_close_streams(AVFormatContext *s)
if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
rtsp_st->dynamic_handler->free(
rtsp_st->dynamic_protocol_context);
+ for (j = 0; j < rtsp_st->nb_include_source_addrs; j++)
+ av_free(rtsp_st->include_source_addrs[j]);
+ av_freep(&rtsp_st->include_source_addrs);
+ for (j = 0; j < rtsp_st->nb_exclude_source_addrs; j++)
+ av_free(rtsp_st->exclude_source_addrs[j]);
+ av_freep(&rtsp_st->exclude_source_addrs);
+
av_free(rtsp_st);
}
}
@@ -1120,11 +1202,11 @@ start:
*
* @return zero if success, nonzero otherwise
*/
-static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
- const char *method, const char *url,
- const char *headers,
- const unsigned char *send_content,
- int send_content_length)
+static int rtsp_send_cmd_with_content_async(AVFormatContext *s,
+ const char *method, const char *url,
+ const char *headers,
+ const unsigned char *send_content,
+ int send_content_length)
{
RTSPState *rt = s->priv_data;
char buf[4096], *out_buf;
@@ -1137,6 +1219,7 @@ static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
if (headers)
av_strlcat(buf, headers, sizeof(buf));
av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
+ av_strlcatf(buf, sizeof(buf), "User-Agent: %s\r\n", rt->user_agent);
if (rt->session_id[0] != '\0' && (!headers ||
!strstr(headers, "\nIf-Match:"))) {
av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
@@ -1177,7 +1260,7 @@ static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
const char *url, const char *headers)
{
- return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
+ return rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
}
int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
@@ -1202,9 +1285,9 @@ int ff_rtsp_send_cmd_with_content(AVFormatContext *s,
retry:
cur_auth_type = rt->auth_state.auth_type;
- if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
- send_content,
- send_content_length)))
+ if ((ret = rtsp_send_cmd_with_content_async(s, method, url, header,
+ send_content,
+ send_content_length)))
return ret;
if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
@@ -1399,18 +1482,15 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
case RTSP_LOWER_TRANSPORT_UDP: {
char url[1024], options[30] = "";
+ const char *peer = host;
if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
av_strlcpy(options, "?connect=1", sizeof(options));
/* Use source address if specified */
- if (reply->transports[0].source[0]) {
- ff_url_join(url, sizeof(url), "rtp", NULL,
- reply->transports[0].source,
- reply->transports[0].server_port_min, "%s", options);
- } else {
- ff_url_join(url, sizeof(url), "rtp", NULL, host,
- reply->transports[0].server_port_min, "%s", options);
- }
+ if (reply->transports[0].source[0])
+ peer = reply->transports[0].source;
+ ff_url_join(url, sizeof(url), "rtp", NULL, peer,
+ reply->transports[0].server_port_min, "%s", options);
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
err = AVERROR_INVALIDDATA;
@@ -2030,7 +2110,7 @@ static int sdp_probe(AVProbeData *p1)
while (p < p_end && *p != '\0') {
if (p + sizeof("c=IN IP") - 1 < p_end &&
av_strstart(p, "c=IN IP", NULL))
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
while (p < p_end - 1 && *p != '\n') p++;
if (++p >= p_end)
@@ -2041,6 +2121,17 @@ static int sdp_probe(AVProbeData *p1)
return 0;
}
+static void append_source_addrs(char *buf, int size, const char *name,
+ int count, struct RTSPSource **addrs)
+{
+ int i;
+ if (!count)
+ return;
+ av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
+ for (i = 1; i < count; i++)
+ av_strlcatf(buf, size, ",%s", addrs[i]->addr);
+}
+
static int sdp_read_header(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
@@ -2081,9 +2172,17 @@ static int sdp_read_header(AVFormatContext *s)
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
- "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
- rtsp_st->sdp_ttl,
- rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
+ "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
+ rtsp_st->sdp_port, rtsp_st->sdp_ttl,
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
+ rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
+
+ append_source_addrs(url, sizeof(url), "sources",
+ rtsp_st->nb_include_source_addrs,
+ rtsp_st->include_source_addrs);
+ append_source_addrs(url, sizeof(url), "block",
+ rtsp_st->nb_exclude_source_addrs,
+ rtsp_st->exclude_source_addrs);
if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
&s->interrupt_callback, NULL) < 0) {
err = AVERROR_INVALIDDATA;
diff --git a/chromium/third_party/ffmpeg/libavformat/rtsp.h b/chromium/third_party/ffmpeg/libavformat/rtsp.h
index 4af3507d733..2dc4b6cbae6 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtsp.h
+++ b/chromium/third_party/ffmpeg/libavformat/rtsp.h
@@ -399,6 +399,11 @@ typedef struct RTSPState {
* Size of RTP packet reordering queue.
*/
int reordering_queue_size;
+
+ /**
+ * User-Agent string
+ */
+ char *user_agent;
} RTSPState;
#define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets -
@@ -406,6 +411,12 @@ typedef struct RTSPState {
source address and port. */
#define RTSP_FLAG_LISTEN 0x2 /**< Wait for incoming connections. */
#define RTSP_FLAG_CUSTOM_IO 0x4 /**< Do all IO via the AVIOContext. */
+#define RTSP_FLAG_RTCP_TO_SOURCE 0x8 /**< Send RTCP packets to the source
+ address of received packets. */
+
+typedef struct RTSPSource {
+ char addr[128]; /**< Source-specific multicast include source IP address (from SDP content) */
+} RTSPSource;
/**
* Describe a single stream, as identified by a single m= line block in the
@@ -430,6 +441,10 @@ typedef struct RTSPStream {
//@{
int sdp_port; /**< port (from SDP content) */
struct sockaddr_storage sdp_ip; /**< IP address (from SDP content) */
+ int nb_include_source_addrs; /**< Number of source-specific multicast include source IP addresses (from SDP content) */
+ struct RTSPSource **include_source_addrs; /**< Source-specific multicast include source IP addresses (from SDP content) */
+ int nb_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP addresses (from SDP content) */
+ struct RTSPSource **exclude_source_addrs; /**< Source-specific multicast exclude source IP addresses (from SDP content) */
int sdp_ttl; /**< IP Time-To-Live (from SDP content) */
int sdp_payload_type; /**< payload type */
//@}
diff --git a/chromium/third_party/ffmpeg/libavformat/rtspdec.c b/chromium/third_party/ffmpeg/libavformat/rtspdec.c
index da571a8ee8e..3615226ac00 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtspdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtspdec.c
@@ -29,6 +29,7 @@
#include "internal.h"
#include "network.h"
#include "os_support.h"
+#include "rtpproto.h"
#include "rtsp.h"
#include "rdt.h"
#include "url.h"
diff --git a/chromium/third_party/ffmpeg/libavformat/rtspenc.c b/chromium/third_party/ffmpeg/libavformat/rtspenc.c
index bad6fbd3a29..bea18317fd1 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtspenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtspenc.c
@@ -145,6 +145,7 @@ static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
uint8_t *interleave_header, *interleaved_packet;
size = avio_close_dyn_buf(rtpctx->pb, &buf);
+ rtpctx->pb = NULL;
ptr = buf;
while (size > 4) {
uint32_t packet_len = AV_RB32(ptr);
@@ -171,8 +172,7 @@ static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
size -= packet_len;
}
av_free(buf);
- ffio_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
- return 0;
+ return ffio_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
}
static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
diff --git a/chromium/third_party/ffmpeg/libavformat/sctp.c b/chromium/third_party/ffmpeg/libavformat/sctp.c
index 2fd5400ae5d..e3585b44b57 100644
--- a/chromium/third_party/ffmpeg/libavformat/sctp.c
+++ b/chromium/third_party/ffmpeg/libavformat/sctp.c
@@ -56,10 +56,10 @@
/*
* The sctp_recvmsg and sctp_sendmsg functions are part of the user
- * library that offers support
- * for the SCTP kernel Implementation. The main purpose of this
- * code is to provide the SCTP Socket API mappings for user
- * application to interface with the SCTP in kernel.
+ * library that offers support for the SCTP kernel Implementation.
+ * To avoid build-time clashes the functions sport an ff_-prefix here.
+ * The main purpose of this code is to provide the SCTP Socket API
+ * mappings for user applications to interface with SCTP in the kernel.
*
* This implementation is based on the Socket API Extensions for SCTP
* defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
@@ -198,7 +198,7 @@ static int sctp_open(URLContext *h, const char *uri, int flags)
cur_ai = ai;
- fd = socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
+ fd = ff_socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
if (fd < 0)
goto fail;
diff --git a/chromium/third_party/ffmpeg/libavformat/seek-test.c b/chromium/third_party/ffmpeg/libavformat/seek-test.c
index 34ac4deff26..8b0611db71a 100644
--- a/chromium/third_party/ffmpeg/libavformat/seek-test.c
+++ b/chromium/third_party/ffmpeg/libavformat/seek-test.c
@@ -64,6 +64,7 @@ int main(int argc, char **argv)
int64_t seekfirst = AV_NOPTS_VALUE;
int firstback=0;
int frame_count = 1;
+ int duration = 4;
for(i=2; i<argc; i+=2){
if (!strcmp(argv[i], "-seekforw")){
@@ -73,6 +74,8 @@ int main(int argc, char **argv)
firstback = 1;
} else if(!strcmp(argv[i], "-frames")){
frame_count = atoi(argv[i+1]);
+ } else if(!strcmp(argv[i], "-duration")){
+ duration = atoi(argv[i+1]);
} else {
argc = 1;
}
@@ -133,7 +136,7 @@ int main(int argc, char **argv)
if(i>25) break;
stream_id= (i>>1)%(ic->nb_streams+1) - 1;
- timestamp= (i*19362894167LL) % (4*AV_TIME_BASE) - AV_TIME_BASE;
+ timestamp= (i*19362894167LL) % (duration*AV_TIME_BASE) - AV_TIME_BASE;
if(stream_id>=0){
st= ic->streams[stream_id];
timestamp= av_rescale_q(timestamp, AV_TIME_BASE_Q, st->time_base);
diff --git a/chromium/third_party/ffmpeg/libavformat/segafilm.c b/chromium/third_party/ffmpeg/libavformat/segafilm.c
index a33ad858f57..232a93117fa 100644
--- a/chromium/third_party/ffmpeg/libavformat/segafilm.c
+++ b/chromium/third_party/ffmpeg/libavformat/segafilm.c
@@ -215,6 +215,8 @@ static int film_read_header(AVFormatContext *s)
film->sample_table[i].sample_offset =
data_offset + AV_RB32(&scratch[0]);
film->sample_table[i].sample_size = AV_RB32(&scratch[4]);
+ if (film->sample_table[i].sample_size > INT_MAX / 4)
+ return AVERROR_INVALIDDATA;
if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) {
film->sample_table[i].stream = film->audio_stream_index;
film->sample_table[i].pts = audio_frame_counter;
diff --git a/chromium/third_party/ffmpeg/libavformat/segment.c b/chromium/third_party/ffmpeg/libavformat/segment.c
index dbcfe898cf1..95984bd1160 100644
--- a/chromium/third_party/ffmpeg/libavformat/segment.c
+++ b/chromium/third_party/ffmpeg/libavformat/segment.c
@@ -43,6 +43,7 @@ typedef struct SegmentListEntry {
int index;
double start_time, end_time;
int64_t start_pts;
+ int64_t offset_pts;
char filename[1024];
struct SegmentListEntry *next;
} SegmentListEntry;
@@ -85,12 +86,12 @@ typedef struct {
int nb_frames; ///< number of elments in the frames array
int frame_count;
- char *time_delta_str; ///< approximation value duration used for the segment times
int64_t time_delta;
int individual_header_trailer; /**< Set by a private option. */
int write_header_trailer; /**< Set by a private option. */
int reset_timestamps; ///< reset timestamps at the begin of each segment
+ int64_t initial_offset; ///< initial timestamps offset, expressed in microseconds
char *reference_stream_specifier; ///< reference stream specifier
int reference_stream_index;
@@ -554,15 +555,6 @@ static int seg_write_header(AVFormatContext *s)
}
}
- if (seg->time_delta_str) {
- if ((ret = av_parse_time(&seg->time_delta, seg->time_delta_str, 1)) < 0) {
- av_log(s, AV_LOG_ERROR,
- "Invalid time duration specification '%s' for delta option\n",
- seg->time_delta_str);
- return ret;
- }
- }
-
if (seg->list) {
if (seg->list_type == LIST_TYPE_UNDEFINED) {
if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
@@ -644,7 +636,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
SegmentContext *seg = s->priv_data;
AVFormatContext *oc = seg->avf;
AVStream *st = s->streams[pkt->stream_index];
- int64_t end_pts = INT64_MAX;
+ int64_t end_pts = INT64_MAX, offset;
int start_frame = INT_MAX;
int ret;
@@ -694,23 +686,23 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
seg->is_first_pkt = 0;
}
- if (seg->reset_timestamps) {
- av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
- pkt->stream_index,
- av_ts2timestr(seg->cur_entry.start_pts, &AV_TIME_BASE_Q),
- av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
- av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
-
- /* compute new timestamps */
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts -= av_rescale_q(seg->cur_entry.start_pts, AV_TIME_BASE_Q, st->time_base);
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts -= av_rescale_q(seg->cur_entry.start_pts, AV_TIME_BASE_Q, st->time_base);
-
- av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
- av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
- av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
- }
+ av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
+ pkt->stream_index,
+ av_ts2timestr(seg->cur_entry.start_pts, &AV_TIME_BASE_Q),
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
+
+ /* compute new timestamps */
+ offset = av_rescale_q(seg->initial_offset - (seg->reset_timestamps ? seg->cur_entry.start_pts : 0),
+ AV_TIME_BASE_Q, st->time_base);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += offset;
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += offset;
+
+ av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
@@ -784,7 +776,7 @@ static const AVOption options[] = {
{ "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
{ "segment_time", "set segment duration", OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
- { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta_str), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, E },
+ { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0, E },
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
{ "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
{ "segment_wrap", "set number after which the index wraps", OFFSET(segment_idx_wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
@@ -793,6 +785,7 @@ static const AVOption options[] = {
{ "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
{ "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
{ "reset_timestamps", "reset timestamps at the begin of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+ { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/sierravmd.c b/chromium/third_party/ffmpeg/libavformat/sierravmd.c
index b0b582d719e..b2d1e5dd590 100644
--- a/chromium/third_party/ffmpeg/libavformat/sierravmd.c
+++ b/chromium/third_party/ffmpeg/libavformat/sierravmd.c
@@ -64,8 +64,8 @@ typedef struct VmdDemuxContext {
static int vmd_probe(AVProbeData *p)
{
- int w, h;
- if (p->buf_size < 16)
+ int w, h, sample_rate;
+ if (p->buf_size < 806)
return 0;
/* check if the first 2 bytes of the file contain the appropriate size
* of a VMD header chunk */
@@ -73,23 +73,25 @@ static int vmd_probe(AVProbeData *p)
return 0;
w = AV_RL16(&p->buf[12]);
h = AV_RL16(&p->buf[14]);
- if (!w || w > 2048 || !h || h > 2048)
+ sample_rate = AV_RL16(&p->buf[804]);
+ if ((!w || w > 2048 || !h || h > 2048) &&
+ sample_rate != 22050)
return 0;
/* only return half certainty since this check is a bit sketchy */
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
}
static int vmd_read_header(AVFormatContext *s)
{
VmdDemuxContext *vmd = s->priv_data;
AVIOContext *pb = s->pb;
- AVStream *st = NULL, *vst;
+ AVStream *st = NULL, *vst = NULL;
unsigned int toc_offset;
unsigned char *raw_frame_table;
int raw_frame_table_size;
int64_t current_offset;
- int i, j;
+ int i, j, width, height;
unsigned int total_frames;
int64_t current_audio_pts = 0;
unsigned char chunk[BYTES_PER_FRAME_RECORD];
@@ -101,28 +103,33 @@ static int vmd_read_header(AVFormatContext *s)
if (avio_read(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)
return AVERROR(EIO);
- if(vmd->vmd_header[24] == 'i' && vmd->vmd_header[25] == 'v' && vmd->vmd_header[26] == '3')
- vmd->is_indeo3 = 1;
- else
- vmd->is_indeo3 = 0;
- /* start up the decoders */
- vst = avformat_new_stream(s, NULL);
- if (!vst)
- return AVERROR(ENOMEM);
- avpriv_set_pts_info(vst, 33, 1, 10);
- vmd->video_stream_index = vst->index;
- vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- vst->codec->codec_id = vmd->is_indeo3 ? AV_CODEC_ID_INDEO3 : AV_CODEC_ID_VMDVIDEO;
- vst->codec->codec_tag = 0; /* no fourcc */
- vst->codec->width = AV_RL16(&vmd->vmd_header[12]);
- vst->codec->height = AV_RL16(&vmd->vmd_header[14]);
- if(vmd->is_indeo3 && vst->codec->width > 320){
- vst->codec->width >>= 1;
- vst->codec->height >>= 1;
+ width = AV_RL16(&vmd->vmd_header[12]);
+ height = AV_RL16(&vmd->vmd_header[14]);
+ if (width && height) {
+ if(vmd->vmd_header[24] == 'i' && vmd->vmd_header[25] == 'v' && vmd->vmd_header[26] == '3') {
+ vmd->is_indeo3 = 1;
+ } else {
+ vmd->is_indeo3 = 0;
+ }
+ /* start up the decoders */
+ vst = avformat_new_stream(s, NULL);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ avpriv_set_pts_info(vst, 33, 1, 10);
+ vmd->video_stream_index = vst->index;
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = vmd->is_indeo3 ? AV_CODEC_ID_INDEO3 : AV_CODEC_ID_VMDVIDEO;
+ vst->codec->codec_tag = 0; /* no fourcc */
+ vst->codec->width = width;
+ vst->codec->height = height;
+ if(vmd->is_indeo3 && vst->codec->width > 320){
+ vst->codec->width >>= 1;
+ vst->codec->height >>= 1;
+ }
+ vst->codec->extradata_size = VMD_HEADER_SIZE;
+ vst->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(vst->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);
}
- vst->codec->extradata_size = VMD_HEADER_SIZE;
- vst->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
- memcpy(vst->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);
/* if sample rate is 0, assume no audio */
vmd->sample_rate = AV_RL16(&vmd->vmd_header[804]);
@@ -156,7 +163,8 @@ static int vmd_read_header(AVFormatContext *s)
num = st->codec->block_align;
den = st->codec->sample_rate * st->codec->channels;
av_reduce(&num, &den, num, den, (1UL<<31)-1);
- avpriv_set_pts_info(vst, 33, num, den);
+ if (vst)
+ avpriv_set_pts_info(vst, 33, num, den);
avpriv_set_pts_info(st, 33, num, den);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/smacker.c b/chromium/third_party/ffmpeg/libavformat/smacker.c
index 84481e22a68..b4c1bf43358 100644
--- a/chromium/third_party/ffmpeg/libavformat/smacker.c
+++ b/chromium/third_party/ffmpeg/libavformat/smacker.c
@@ -210,7 +210,8 @@ static int smacker_read_header(AVFormatContext *s)
/* load trees to extradata, they will be unpacked by decoder */
- st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_mallocz(smk->treesize + 16 +
+ FF_INPUT_BUFFER_PADDING_SIZE);
st->codec->extradata_size = smk->treesize + 16;
if(!st->codec->extradata){
av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
@@ -276,7 +277,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
} else if(t & 0x40){ /* copy with offset */
off = avio_r8(s->pb);
j = (t & 0x3F) + 1;
- if (off + j - 1 > 0xff) {
+ if (off + j > 0x100) {
av_log(s, AV_LOG_ERROR,
"Invalid palette update, offset=%d length=%d extends beyond palette size\n",
off, j);
@@ -305,12 +306,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
/* if audio chunks are present, put them to stack and retrieve later */
for(i = 0; i < 7; i++) {
if(flags & 1) {
- unsigned int size;
+ uint32_t size;
uint8_t *tmpbuf;
size = avio_rl32(s->pb) - 4;
- if(size + 4L > frame_size)
+ if (!size || size + 4L > frame_size) {
+ av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
return AVERROR_INVALIDDATA;
+ }
frame_size -= size;
frame_size -= 4;
smk->curstream++;
@@ -338,6 +341,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
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);
diff --git a/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c b/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c
index 096bf79c302..7163c90c4da 100644
--- a/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/smoothstreamingenc.c
@@ -428,7 +428,7 @@ static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *sta
if (len < 8 || len >= *moof_size)
goto fail;
if (tag == MKTAG('u','u','i','d')) {
- const uint8_t tfxd[] = {
+ static const uint8_t tfxd[] = {
0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
};
diff --git a/chromium/third_party/ffmpeg/libavformat/spdifdec.c b/chromium/third_party/ffmpeg/libavformat/spdifdec.c
index 726a85cbe58..69843503b00 100644
--- a/chromium/third_party/ffmpeg/libavformat/spdifdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/spdifdec.c
@@ -154,10 +154,10 @@ int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec)
if (sync_codes >= 6)
/* good amount of sync codes but with unexpected offsets */
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
/* some sync codes were found */
- return AVPROBE_SCORE_MAX / 8;
+ return AVPROBE_SCORE_EXTENSION / 4;
}
static int spdif_read_header(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/spdifenc.c b/chromium/third_party/ffmpeg/libavformat/spdifenc.c
index 857c20de221..210d63f39cd 100644
--- a/chromium/third_party/ffmpeg/libavformat/spdifenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/spdifenc.c
@@ -92,7 +92,7 @@ static const AVOption options[] = {
{ NULL },
};
-static const AVClass class = {
+static const AVClass spdif_class = {
.class_name = "spdif",
.item_name = av_default_item_name,
.option = options,
@@ -395,15 +395,15 @@ static int spdif_header_truehd(AVFormatContext *s, AVPacket *pkt)
{
IEC61937Context *ctx = s->priv_data;
int mat_code_length = 0;
- const char mat_end_code[16] = { 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11 };
+ static const char mat_end_code[16] = { 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11 };
if (!ctx->hd_buf_count) {
- const char mat_start_code[20] = { 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0 };
+ static const char mat_start_code[20] = { 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0 };
mat_code_length = sizeof(mat_start_code) + BURST_HEADER_SIZE;
memcpy(ctx->hd_buf, mat_start_code, sizeof(mat_start_code));
} else if (ctx->hd_buf_count == 12) {
- const char mat_middle_code[12] = { 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0 };
+ static const char mat_middle_code[12] = { 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0 };
mat_code_length = sizeof(mat_middle_code) + MAT_MIDDLE_CODE_OFFSET;
memcpy(&ctx->hd_buf[12 * TRUEHD_FRAME_OFFSET - BURST_HEADER_SIZE + MAT_MIDDLE_CODE_OFFSET],
mat_middle_code, sizeof(mat_middle_code));
@@ -552,5 +552,5 @@ AVOutputFormat ff_spdif_muxer = {
.write_packet = spdif_write_packet,
.write_trailer = spdif_write_trailer,
.flags = AVFMT_NOTIMESTAMPS,
- .priv_class = &class,
+ .priv_class = &spdif_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/srtdec.c b/chromium/third_party/ffmpeg/libavformat/srtdec.c
index 76e06e41654..dbf1866202d 100644
--- a/chromium/third_party/ffmpeg/libavformat/srtdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/srtdec.c
@@ -63,10 +63,12 @@ static int64_t get_pts(const char **buf, int *duration,
int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1;
int64_t end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2;
*duration = end - start;
- *buf += strcspn(*buf, "\n") + 1;
+ *buf += strcspn(*buf, "\n");
+ *buf += !!**buf;
return start;
}
- *buf += strcspn(*buf, "\n") + 1;
+ *buf += strcspn(*buf, "\n");
+ *buf += !!**buf;
}
return AV_NOPTS_VALUE;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c b/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
index 0dc1942a428..1b831b7b8ff 100644
--- a/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/subviewer1dec.c
@@ -36,7 +36,7 @@ static int subviewer1_probe(AVProbeData *p)
const unsigned char *ptr = p->buf;
if (strstr(ptr, "******** START SCRIPT ********"))
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/subviewerdec.c b/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
index 7cacd973dbc..9e645d25c7c 100644
--- a/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/subviewerdec.c
@@ -44,7 +44,7 @@ static int subviewer_probe(AVProbeData *p)
if (AV_RB24(ptr) == 0xEFBBBF)
ptr += 3; /* skip UTF-8 BOM */
if (sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1)
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
if (!strncmp(ptr, "[INFORMATION]", 13))
return AVPROBE_SCORE_MAX/3;
return 0;
diff --git a/chromium/third_party/ffmpeg/libavformat/swf.h b/chromium/third_party/ffmpeg/libavformat/swf.h
index b9722c1c9a8..c1667b3c24c 100644
--- a/chromium/third_party/ffmpeg/libavformat/swf.h
+++ b/chromium/third_party/ffmpeg/libavformat/swf.h
@@ -120,9 +120,6 @@ enum {
#define VIDEO_ID 0
#define SHAPE_ID 1
-#undef NDEBUG
-#include <assert.h>
-
typedef struct SWFContext {
int64_t duration_pos;
int64_t tag_pos;
diff --git a/chromium/third_party/ffmpeg/libavformat/swfenc.c b/chromium/third_party/ffmpeg/libavformat/swfenc.c
index 70183625c37..8d9cf0c246c 100644
--- a/chromium/third_party/ffmpeg/libavformat/swfenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/swfenc.c
@@ -234,7 +234,7 @@ static int swf_write_header(AVFormatContext *s)
}
if (!swf->audio_enc)
- swf->samples_per_frame = (44100. * rate_base) / rate;
+ swf->samples_per_frame = (44100.0 * rate_base) / rate;
else
swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate;
diff --git a/chromium/third_party/ffmpeg/libavformat/takdec.c b/chromium/third_party/ffmpeg/libavformat/takdec.c
index 377c10c1abd..2ed8a1e3b71 100644
--- a/chromium/third_party/ffmpeg/libavformat/takdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/takdec.c
@@ -19,8 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/crc.h"
#include "libavcodec/tak.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "internal.h"
#include "rawdec.h"
#include "apetag.h"
@@ -33,10 +35,16 @@ typedef struct TAKDemuxContext {
static int tak_probe(AVProbeData *p)
{
if (!memcmp(p->buf, "tBaK", 4))
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
return 0;
}
+static unsigned long tak_check_crc(unsigned long checksum, const uint8_t *buf,
+ unsigned int len)
+{
+ return av_crc(av_crc_get_table(AV_CRC_24_IEEE), checksum, buf, len);
+}
+
static int tak_read_header(AVFormatContext *s)
{
TAKDemuxContext *tc = s->priv_data;
@@ -71,16 +79,27 @@ static int tak_read_header(AVFormatContext *s)
case TAK_METADATA_STREAMINFO:
case TAK_METADATA_LAST_FRAME:
case TAK_METADATA_ENCODER:
- buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (size <= 3)
+ return AVERROR_INVALIDDATA;
+
+ buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE);
if (!buffer)
return AVERROR(ENOMEM);
- if (avio_read(pb, buffer, size) != size) {
+ ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
+ if (avio_read(pb, buffer, size - 3) != size - 3) {
av_freep(&buffer);
return AVERROR(EIO);
}
+ if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
+ av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type);
+ if (s->error_recognition & AV_EF_EXPLODE) {
+ av_freep(&buffer);
+ return AVERROR_INVALIDDATA;
+ }
+ }
- init_get_bits(&gb, buffer, size * 8);
+ init_get_bits8(&gb, buffer, size - 3);
break;
case TAK_METADATA_MD5: {
uint8_t md5[16];
@@ -88,8 +107,14 @@ static int tak_read_header(AVFormatContext *s)
if (size != 19)
return AVERROR_INVALIDDATA;
+ ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
avio_read(pb, md5, 16);
- avio_skip(pb, 3);
+ if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
+ av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n");
+ if (s->error_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+
av_log(s, AV_LOG_VERBOSE, "MD5=");
for (i = 0; i < 16; i++)
av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
@@ -127,7 +152,7 @@ static int tak_read_header(AVFormatContext *s)
st->start_time = 0;
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->codec->extradata = buffer;
- st->codec->extradata_size = size;
+ st->codec->extradata_size = size - 3;
buffer = NULL;
} else if (type == TAK_METADATA_LAST_FRAME) {
if (size != 11)
@@ -155,7 +180,7 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
AVIOContext *pb = s->pb;
int64_t size, left;
- left = tc->data_end - avio_tell(s->pb);
+ left = tc->data_end - avio_tell(pb);
size = FFMIN(left, 1024);
if (size <= 0)
return AVERROR_EOF;
diff --git a/chromium/third_party/ffmpeg/libavformat/tcp.c b/chromium/third_party/ffmpeg/libavformat/tcp.c
index 0d792e75b42..36af37a94a1 100644
--- a/chromium/third_party/ffmpeg/libavformat/tcp.c
+++ b/chromium/third_party/ffmpeg/libavformat/tcp.c
@@ -34,6 +34,7 @@ typedef struct TCPContext {
const AVClass *class;
int fd;
int listen;
+ int open_timeout;
int rw_timeout;
int listen_timeout;
} TCPContext;
@@ -43,7 +44,7 @@ typedef struct TCPContext {
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
{"listen", "listen on port instead of connecting", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
-{"timeout", "timeout of socket i/o operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
+{"timeout", "timeout of socket i/o operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
{"listen_timeout", "connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
{NULL}
};
@@ -64,10 +65,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
const char *p;
char buf[256];
int ret;
- socklen_t optlen;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
- h->rw_timeout = 5000000;
+ s->open_timeout = 5000000;
av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
&port, path, sizeof(path), uri);
@@ -88,7 +88,10 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
s->listen_timeout = strtol(buf, NULL, 10);
}
}
- h->rw_timeout = s->rw_timeout;
+ if (s->rw_timeout >= 0) {
+ s->open_timeout =
+ h->rw_timeout = s->rw_timeout;
+ }
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", port);
@@ -108,89 +111,31 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
cur_ai = ai;
restart:
- ret = AVERROR(EIO);
- fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
- if (fd < 0)
+ fd = ff_socket(cur_ai->ai_family,
+ cur_ai->ai_socktype,
+ cur_ai->ai_protocol);
+ if (fd < 0) {
+ ret = ff_neterrno();
goto fail;
+ }
if (s->listen) {
- int fd1;
- int reuse = 1;
- struct pollfd lp = { fd, POLLIN, 0 };
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
- ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
- if (ret) {
- ret = ff_neterrno();
- goto fail1;
- }
- ret = listen(fd, 1);
- if (ret) {
- ret = ff_neterrno();
- goto fail1;
- }
- ret = poll(&lp, 1, s->listen_timeout >= 0 ? s->listen_timeout : -1);
- if (ret <= 0) {
- ret = AVERROR(ETIMEDOUT);
- goto fail1;
- }
- fd1 = accept(fd, NULL, NULL);
- if (fd1 < 0) {
- ret = ff_neterrno();
+ if ((fd = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+ s->listen_timeout, h)) < 0) {
+ ret = fd;
goto fail1;
}
- closesocket(fd);
- fd = fd1;
- ff_socket_nonblock(fd, 1);
} else {
- redo:
- ff_socket_nonblock(fd, 1);
- ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
- }
-
- if (ret < 0) {
- struct pollfd p = {fd, POLLOUT, 0};
- int64_t wait_started;
- ret = ff_neterrno();
- if (ret == AVERROR(EINTR)) {
- if (ff_check_interrupt(&h->interrupt_callback)) {
- ret = AVERROR_EXIT;
- goto fail1;
- }
- goto redo;
- }
- if (ret != AVERROR(EINPROGRESS) &&
- ret != AVERROR(EAGAIN))
- goto fail;
+ if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+ s->open_timeout / 1000, h, cur_ai->ai_next)) < 0) {
- /* wait until we are connected or until abort */
- wait_started = av_gettime();
- do {
- if (ff_check_interrupt(&h->interrupt_callback)) {
- ret = AVERROR_EXIT;
+ if (ret == AVERROR_EXIT)
goto fail1;
- }
- ret = poll(&p, 1, 100);
- if (ret > 0)
- break;
- } while (!h->rw_timeout || (av_gettime() - wait_started < h->rw_timeout));
- if (ret <= 0) {
- ret = AVERROR(ETIMEDOUT);
- goto fail;
- }
- /* test error */
- optlen = sizeof(ret);
- if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
- ret = AVUNERROR(ff_neterrno());
- if (ret != 0) {
- char errbuf[100];
- ret = AVERROR(ret);
- av_strerror(ret, errbuf, sizeof(errbuf));
- av_log(h, AV_LOG_ERROR,
- "TCP connection to %s:%d failed: %s\n",
- hostname, port, errbuf);
- goto fail;
+ else
+ goto fail;
}
}
+
h->is_streamed = 1;
s->fd = fd;
freeaddrinfo(ai);
@@ -202,6 +147,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
cur_ai = cur_ai->ai_next;
if (fd >= 0)
closesocket(fd);
+ ret = 0;
goto restart;
}
fail1:
diff --git a/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c b/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
index 048ba96981d..68063fafbe0 100644
--- a/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/tedcaptionsdec.c
@@ -153,7 +153,8 @@ static int parse_label(AVIOContext *pb, int *cur_byte, AVBPrint *bp)
static int parse_boolean(AVIOContext *pb, int *cur_byte, int *result)
{
- const char *text[] = { "false", "true" }, *p;
+ static const char * const text[] = { "false", "true" };
+ const char *p;
int i;
skip_spaces(pb, cur_byte);
@@ -340,7 +341,7 @@ static av_cold int tedcaptions_read_probe(AVProbeData *p)
count++;
}
return count == FF_ARRAY_ELEMS(tags) ? AVPROBE_SCORE_MAX :
- count ? AVPROBE_SCORE_MAX / 2 : 0;
+ count ? AVPROBE_SCORE_EXTENSION : 0;
}
static int tedcaptions_read_seek(AVFormatContext *avf, int stream_index,
diff --git a/chromium/third_party/ffmpeg/libavformat/tee.c b/chromium/third_party/ffmpeg/libavformat/tee.c
index 10787cad294..71f245e4f11 100644
--- a/chromium/third_party/ffmpeg/libavformat/tee.c
+++ b/chromium/third_party/ffmpeg/libavformat/tee.c
@@ -1,5 +1,5 @@
/*
- * Tee pesudo-muxer
+ * Tee pseudo-muxer
* Copyright (c) 2012 Nicolas George
*
* This file is part of FFmpeg.
@@ -27,16 +27,26 @@
#define MAX_SLAVES 16
+typedef struct {
+ AVFormatContext *avf;
+ AVBitStreamFilterContext **bsfs; ///< bitstream filters per stream
+
+ /** map from input to output streams indexes,
+ * disabled output streams are set to -1 */
+ int *stream_map;
+} TeeSlave;
+
typedef struct TeeContext {
const AVClass *class;
unsigned nb_slaves;
- AVFormatContext *slaves[MAX_SLAVES];
+ TeeSlave slaves[MAX_SLAVES];
} TeeContext;
static const char *const slave_delim = "|";
static const char *const slave_opt_open = "[";
static const char *const slave_opt_close = "]";
static const char *const slave_opt_delim = ":]"; /* must have the close too */
+static const char *const slave_bsfs_spec_sep = "/";
static const AVClass tee_muxer_class = {
.class_name = "Tee muxer",
@@ -82,34 +92,103 @@ fail:
return ret;
}
-static int open_slave(AVFormatContext *avf, char *slave, AVFormatContext **ravf)
+/**
+ * Parse list of bitstream filters and add them to the list of filters
+ * pointed to by bsfs.
+ *
+ * The list must be specified in the form:
+ * BSFS ::= BSF[,BSFS]
+ */
+static int parse_bsfs(void *log_ctx, const char *bsfs_spec,
+ AVBitStreamFilterContext **bsfs)
+{
+ char *bsf_name, *buf, *saveptr;
+ int ret = 0;
+
+ if (!(buf = av_strdup(bsfs_spec)))
+ return AVERROR(ENOMEM);
+
+ while (bsf_name = av_strtok(buf, ",", &saveptr)) {
+ AVBitStreamFilterContext *bsf = av_bitstream_filter_init(bsf_name);
+
+ if (!bsf) {
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Cannot initialize bitstream filter with name '%s', "
+ "unknown filter or internal error happened\n",
+ bsf_name);
+ ret = AVERROR_UNKNOWN;
+ goto end;
+ }
+
+ /* append bsf context to the list of bsf contexts */
+ *bsfs = bsf;
+ bsfs = &bsf->next;
+
+ buf = NULL;
+ }
+
+end:
+ av_free(buf);
+ return ret;
+}
+
+static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
{
int i, ret;
AVDictionary *options = NULL;
AVDictionaryEntry *entry;
char *filename;
- char *format = NULL;
+ char *format = NULL, *select = NULL;
AVFormatContext *avf2 = NULL;
AVStream *st, *st2;
+ int stream_count;
if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0)
return ret;
- if ((entry = av_dict_get(options, "f", NULL, 0))) {
- format = entry->value;
- entry->value = NULL; /* prevent it from being freed */
- av_dict_set(&options, "f", NULL, 0);
- }
+
+#define STEAL_OPTION(option, field) do { \
+ if ((entry = av_dict_get(options, option, NULL, 0))) { \
+ field = entry->value; \
+ entry->value = NULL; /* prevent it from being freed */ \
+ av_dict_set(&options, option, NULL, 0); \
+ } \
+ } while (0)
+
+ STEAL_OPTION("f", format);
+ STEAL_OPTION("select", select);
ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
if (ret < 0)
- goto fail;
- av_free(format);
+ goto end;
+ tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map));
+ if (!tee_slave->stream_map) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ stream_count = 0;
for (i = 0; i < avf->nb_streams; i++) {
st = avf->streams[i];
+ if (select) {
+ ret = avformat_match_stream_specifier(avf, avf->streams[i], select);
+ if (ret < 0) {
+ av_log(avf, AV_LOG_ERROR,
+ "Invalid stream specifier '%s' for output '%s'\n",
+ select, slave);
+ goto end;
+ }
+
+ if (ret == 0) { /* no match */
+ tee_slave->stream_map[i] = -1;
+ continue;
+ }
+ }
+ tee_slave->stream_map[i] = stream_count++;
+
if (!(st2 = avformat_new_stream(avf2, NULL))) {
ret = AVERROR(ENOMEM);
- goto fail;
+ goto end;
}
st2->id = st->id;
st2->r_frame_rate = st->r_frame_rate;
@@ -122,34 +201,84 @@ static int open_slave(AVFormatContext *avf, char *slave, AVFormatContext **ravf)
st2->avg_frame_rate = st->avg_frame_rate;
av_dict_copy(&st2->metadata, st->metadata, 0);
if ((ret = avcodec_copy_context(st2->codec, st->codec)) < 0)
- goto fail;
+ goto end;
}
if (!(avf2->oformat->flags & AVFMT_NOFILE)) {
if ((ret = avio_open(&avf2->pb, filename, AVIO_FLAG_WRITE)) < 0) {
av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n",
slave, av_err2str(ret));
- goto fail;
+ goto end;
}
}
if ((ret = avformat_write_header(avf2, &options)) < 0) {
av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n",
slave, av_err2str(ret));
- goto fail;
+ goto end;
}
+
+ tee_slave->avf = avf2;
+ tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(TeeSlave));
+ if (!tee_slave->bsfs) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ entry = NULL;
+ while (entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX)) {
+ const char *spec = entry->key + strlen("bsfs");
+ if (*spec) {
+ if (strspn(spec, slave_bsfs_spec_sep) != 1) {
+ av_log(avf, AV_LOG_ERROR,
+ "Specifier separator in '%s' is '%c', but only characters '%s' "
+ "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep);
+ return AVERROR(EINVAL);
+ }
+ spec++; /* consume separator */
+ }
+
+ for (i = 0; i < avf2->nb_streams; i++) {
+ ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec);
+ if (ret < 0) {
+ av_log(avf, AV_LOG_ERROR,
+ "Invalid stream specifier '%s' in bsfs option '%s' for slave "
+ "output '%s'\n", spec, entry->key, filename);
+ goto end;
+ }
+
+ if (ret > 0) {
+ av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave "
+ "output '%s'\n", spec, entry->value, i, filename);
+ if (tee_slave->bsfs[i]) {
+ av_log(avf, AV_LOG_WARNING,
+ "Duplicate bsfs specification associated to stream %d of slave "
+ "output '%s', filters will be ignored\n", i, filename);
+ continue;
+ }
+ ret = parse_bsfs(avf, entry->value, &tee_slave->bsfs[i]);
+ if (ret < 0) {
+ av_log(avf, AV_LOG_ERROR,
+ "Error parsing bitstream filter sequence '%s' associated to "
+ "stream %d of slave output '%s'\n", entry->value, i, filename);
+ goto end;
+ }
+ }
+ }
+
+ av_dict_set(&options, entry->key, NULL, 0);
+ }
+
if (options) {
entry = NULL;
while ((entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX)))
av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
ret = AVERROR_OPTION_NOT_FOUND;
- goto fail;
+ goto end;
}
- *ravf = avf2;
- return 0;
-
-fail:
+end:
+ av_free(format);
av_dict_free(&options);
return ret;
}
@@ -158,14 +287,49 @@ static void close_slaves(AVFormatContext *avf)
{
TeeContext *tee = avf->priv_data;
AVFormatContext *avf2;
- unsigned i;
+ unsigned i, j;
for (i = 0; i < tee->nb_slaves; i++) {
- avf2 = tee->slaves[i];
+ avf2 = tee->slaves[i].avf;
+
+ for (j = 0; j < avf2->nb_streams; j++) {
+ AVBitStreamFilterContext *bsf_next, *bsf = tee->slaves[i].bsfs[j];
+ while (bsf) {
+ bsf_next = bsf->next;
+ av_bitstream_filter_close(bsf);
+ bsf = bsf_next;
+ }
+ }
+ av_freep(&tee->slaves[i].stream_map);
+
avio_close(avf2->pb);
avf2->pb = NULL;
avformat_free_context(avf2);
- tee->slaves[i] = NULL;
+ tee->slaves[i].avf = NULL;
+ }
+}
+
+static void log_slave(TeeSlave *slave, void *log_ctx, int log_level)
+{
+ int i;
+ av_log(log_ctx, log_level, "filename:'%s' format:%s\n",
+ slave->avf->filename, slave->avf->oformat->name);
+ for (i = 0; i < slave->avf->nb_streams; i++) {
+ AVStream *st = slave->avf->streams[i];
+ AVBitStreamFilterContext *bsf = slave->bsfs[i];
+
+ av_log(log_ctx, log_level, " stream:%d codec:%s type:%s",
+ i, avcodec_get_name(st->codec->codec_id),
+ av_get_media_type_string(st->codec->codec_type));
+ if (bsf) {
+ av_log(log_ctx, log_level, " bsfs:");
+ while (bsf) {
+ av_log(log_ctx, log_level, "%s%s",
+ bsf->filter->name, bsf->next ? "," : "");
+ bsf = bsf->next;
+ }
+ }
+ av_log(log_ctx, log_level, "\n");
}
}
@@ -195,10 +359,20 @@ static int tee_write_header(AVFormatContext *avf)
for (i = 0; i < nb_slaves; i++) {
if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0)
goto fail;
+ log_slave(&tee->slaves[i], avf, AV_LOG_VERBOSE);
av_freep(&slaves[i]);
}
tee->nb_slaves = nb_slaves;
+
+ for (i = 0; i < avf->nb_streams; i++) {
+ int j, mapped = 0;
+ for (j = 0; j < tee->nb_slaves; j++)
+ mapped += tee->slaves[j].stream_map[i] >= 0;
+ if (!mapped)
+ av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped "
+ "to any slave.\n", i);
+ }
return 0;
fail:
@@ -208,6 +382,46 @@ fail:
return ret;
}
+static int filter_packet(void *log_ctx, AVPacket *pkt,
+ AVFormatContext *fmt_ctx, AVBitStreamFilterContext *bsf_ctx)
+{
+ AVCodecContext *enc_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+ int ret;
+
+ while (bsf_ctx) {
+ AVPacket new_pkt = *pkt;
+ ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,
+ &new_pkt.data, &new_pkt.size,
+ pkt->data, pkt->size,
+ pkt->flags & AV_PKT_FLAG_KEY);
+ if (ret == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
+ if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)
+ break;
+ ret = 1;
+ }
+
+ if (ret > 0) {
+ av_free_packet(pkt);
+ new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
+ av_buffer_default_free, NULL, 0);
+ if (!new_pkt.buf)
+ break;
+ }
+ *pkt = new_pkt;
+
+ bsf_ctx = bsf_ctx->next;
+ }
+
+ if (ret < 0) {
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Failed to filter bitstream with filter %s for stream %d in file '%s' with codec %s\n",
+ bsf_ctx->filter->name, pkt->stream_index, fmt_ctx->filename,
+ avcodec_get_name(enc_ctx->codec_id));
+ }
+
+ return ret;
+}
+
static int tee_write_trailer(AVFormatContext *avf)
{
TeeContext *tee = avf->priv_data;
@@ -216,7 +430,7 @@ static int tee_write_trailer(AVFormatContext *avf)
unsigned i;
for (i = 0; i < tee->nb_slaves; i++) {
- avf2 = tee->slaves[i];
+ avf2 = tee->slaves[i].avf;
if ((ret = av_write_trailer(avf2)) < 0)
if (!ret_all)
ret_all = ret;
@@ -238,27 +452,30 @@ static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt)
AVPacket pkt2;
int ret_all = 0, ret;
unsigned i, s;
+ int s2;
AVRational tb, tb2;
for (i = 0; i < tee->nb_slaves; i++) {
- avf2 = tee->slaves[i];
+ avf2 = tee->slaves[i].avf;
s = pkt->stream_index;
- if (s >= avf2->nb_streams) {
- if (!ret_all)
- ret_all = AVERROR(EINVAL);
+ s2 = tee->slaves[i].stream_map[s];
+ if (s2 < 0)
continue;
- }
+
if ((ret = av_copy_packet(&pkt2, pkt)) < 0 ||
(ret = av_dup_packet(&pkt2))< 0)
if (!ret_all) {
ret = ret_all;
continue;
}
- tb = avf ->streams[s]->time_base;
- tb2 = avf2->streams[s]->time_base;
+ tb = avf ->streams[s ]->time_base;
+ tb2 = avf2->streams[s2]->time_base;
pkt2.pts = av_rescale_q(pkt->pts, tb, tb2);
pkt2.dts = av_rescale_q(pkt->dts, tb, tb2);
pkt2.duration = av_rescale_q(pkt->duration, tb, tb2);
+ pkt2.stream_index = s2;
+
+ filter_packet(avf2, &pkt2, avf2, tee->slaves[i].bsfs[s2]);
if ((ret = av_interleaved_write_frame(avf2, &pkt2)) < 0)
if (!ret_all)
ret_all = ret;
diff --git a/chromium/third_party/ffmpeg/libavformat/tta.c b/chromium/third_party/ffmpeg/libavformat/tta.c
index 445389ed954..bbb6a2292c5 100644
--- a/chromium/third_party/ffmpeg/libavformat/tta.c
+++ b/chromium/third_party/ffmpeg/libavformat/tta.c
@@ -20,9 +20,12 @@
*/
#include "libavcodec/get_bits.h"
+#include "apetag.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "internal.h"
#include "id3v1.h"
+#include "libavutil/crc.h"
#include "libavutil/dict.h"
typedef struct {
@@ -31,12 +34,20 @@ typedef struct {
int last_frame_size;
} TTAContext;
-static int tta_probe(AVProbeData *p)
+static unsigned long tta_check_crc(unsigned long checksum, const uint8_t *buf,
+ unsigned int len)
{
- const uint8_t *d = p->buf;
+ return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
+}
- if (d[0] == 'T' && d[1] == 'T' && d[2] == 'A' && d[3] == '1')
- return 80;
+static int tta_probe(AVProbeData *p)
+{
+ if (AV_RL32(&p->buf[0]) == MKTAG('T', 'T', 'A', '1') &&
+ (AV_RL16(&p->buf[4]) == 1 || AV_RL16(&p->buf[4]) == 2) &&
+ AV_RL16(&p->buf[6]) > 0 &&
+ AV_RL16(&p->buf[8]) > 0 &&
+ AV_RL32(&p->buf[10]) > 0)
+ return AVPROBE_SCORE_EXTENSION + 30;
return 0;
}
@@ -46,14 +57,14 @@ static int tta_read_header(AVFormatContext *s)
AVStream *st;
int i, channels, bps, samplerate;
uint64_t framepos, start_offset;
- uint32_t datalen;
+ uint32_t nb_samples, crc;
- if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
- ff_id3v1_read(s);
+ ff_id3v1_read(s);
start_offset = avio_tell(s->pb);
+ ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX);
if (avio_rl32(s->pb) != AV_RL32("TTA1"))
- return -1; // not tta file
+ return AVERROR_INVALIDDATA;
avio_skip(s->pb, 2); // FIXME: flags
channels = avio_rl16(s->pb);
@@ -61,27 +72,31 @@ static int tta_read_header(AVFormatContext *s)
samplerate = avio_rl32(s->pb);
if(samplerate <= 0 || samplerate > 1000000){
av_log(s, AV_LOG_ERROR, "nonsense samplerate\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- datalen = avio_rl32(s->pb);
- if (!datalen) {
- av_log(s, AV_LOG_ERROR, "invalid datalen\n");
+ nb_samples = avio_rl32(s->pb);
+ if (!nb_samples) {
+ av_log(s, AV_LOG_ERROR, "invalid number of samples\n");
return AVERROR_INVALIDDATA;
}
- avio_skip(s->pb, 4); // header crc
+ crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
+ if (crc != avio_rl32(s->pb)) {
+ av_log(s, AV_LOG_ERROR, "Header CRC error\n");
+ return AVERROR_INVALIDDATA;
+ }
c->frame_size = samplerate * 256 / 245;
- c->last_frame_size = datalen % c->frame_size;
+ c->last_frame_size = nb_samples % c->frame_size;
if (!c->last_frame_size)
c->last_frame_size = c->frame_size;
- c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size);
+ c->totalframes = nb_samples / c->frame_size + (c->last_frame_size < c->frame_size);
c->currentframe = 0;
if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){
av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes);
- return -1;
+ return AVERROR_INVALIDDATA;
}
st = avformat_new_stream(s, NULL);
@@ -90,17 +105,32 @@ static int tta_read_header(AVFormatContext *s)
avpriv_set_pts_info(st, 64, 1, samplerate);
st->start_time = 0;
- st->duration = datalen;
+ st->duration = nb_samples;
framepos = avio_tell(s->pb) + 4*c->totalframes + 4;
+ st->codec->extradata_size = avio_tell(s->pb) - start_offset;
+ st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata) {
+ st->codec->extradata_size = 0;
+ return AVERROR(ENOMEM);
+ }
+
+ avio_seek(s->pb, start_offset, SEEK_SET);
+ avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
+
+ ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX);
for (i = 0; i < c->totalframes; i++) {
uint32_t size = avio_rl32(s->pb);
av_add_index_entry(st, framepos, i * c->frame_size, size, 0,
AVINDEX_KEYFRAME);
framepos += size;
}
- avio_skip(s->pb, 4); // seektable crc
+ crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
+ if (crc != avio_rl32(s->pb)) {
+ av_log(s, AV_LOG_ERROR, "Seek table CRC error\n");
+ return AVERROR_INVALIDDATA;
+ }
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = AV_CODEC_ID_TTA;
@@ -108,19 +138,11 @@ static int tta_read_header(AVFormatContext *s)
st->codec->sample_rate = samplerate;
st->codec->bits_per_coded_sample = bps;
- st->codec->extradata_size = avio_tell(s->pb) - start_offset;
- if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){
- //this check is redundant as avio_read should fail
- av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
- return -1;
+ if (s->pb->seekable) {
+ int64_t pos = avio_tell(s->pb);
+ ff_ape_parse_tag(s);
+ avio_seek(s->pb, pos, SEEK_SET);
}
- st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
- if (!st->codec->extradata) {
- st->codec->extradata_size = 0;
- return AVERROR(ENOMEM);
- }
- avio_seek(s->pb, start_offset, SEEK_SET);
- avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
return 0;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/udp.c b/chromium/third_party/ffmpeg/libavformat/udp.c
index e8a01dbd286..3c0d6bf0123 100644
--- a/chromium/third_party/ffmpeg/libavformat/udp.c
+++ b/chromium/third_party/ffmpeg/libavformat/udp.c
@@ -237,7 +237,7 @@ static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
SOCK_DGRAM, AF_UNSPEC,
- AI_NUMERICHOST);
+ 0);
if (!sourceaddr)
return AVERROR(ENOENT);
@@ -267,7 +267,7 @@ static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
struct ip_mreq_source mreqs;
struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
SOCK_DGRAM, AF_UNSPEC,
- AI_NUMERICHOST);
+ 0);
if (!sourceaddr)
return AVERROR(ENOENT);
if (sourceaddr->ai_addr->sa_family != AF_INET) {
@@ -326,7 +326,7 @@ static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
if (res0 == 0)
goto fail;
for (res = res0; res; res=res->ai_next) {
- udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
+ udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0);
if (udp_fd != -1) break;
log_net_error(NULL, AV_LOG_ERROR, "socket");
}
@@ -494,6 +494,27 @@ end:
}
#endif
+static int parse_source_list(char *buf, char **sources, int *num_sources,
+ int max_sources)
+{
+ char *source_start;
+
+ source_start = buf;
+ while (1) {
+ char *next = strchr(source_start, ',');
+ if (next)
+ *next = '\0';
+ sources[*num_sources] = av_strdup(source_start);
+ if (!sources[*num_sources])
+ return AVERROR(ENOMEM);
+ source_start = next + 1;
+ (*num_sources)++;
+ if (*num_sources >= max_sources || !next)
+ break;
+ }
+ return 0;
+}
+
/* put it in UDP context */
/* return non zero if error */
static int udp_open(URLContext *h, const char *uri, int flags)
@@ -507,8 +528,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
struct sockaddr_storage my_addr;
socklen_t len;
int reuse_specified = 0;
- int i, include = 0, num_sources = 0;
- char *sources[32];
+ int i, num_include_sources = 0, num_exclude_sources = 0;
+ char *include_sources[32], *exclude_sources[32];
h->is_streamed = 1;
@@ -562,31 +583,26 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
av_strlcpy(localaddr, buf, sizeof(localaddr));
}
- if (av_find_info_tag(buf, sizeof(buf), "sources", p))
- include = 1;
- if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {
- char *source_start;
-
- source_start = buf;
- while (1) {
- char *next = strchr(source_start, ',');
- if (next)
- *next = '\0';
- sources[num_sources] = av_strdup(source_start);
- if (!sources[num_sources])
- goto fail;
- source_start = next + 1;
- num_sources++;
- if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)
- break;
- }
+ if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
+ if (parse_source_list(buf, include_sources, &num_include_sources,
+ FF_ARRAY_ELEMS(include_sources)))
+ goto fail;
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
+ if (parse_source_list(buf, exclude_sources, &num_exclude_sources,
+ FF_ARRAY_ELEMS(exclude_sources)))
+ goto fail;
}
if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
s->timeout = strtol(buf, NULL, 10);
}
/* handling needed to support options picking from both AVOption and URL */
s->circular_buffer_size *= 188;
- h->max_packet_size = s->packet_size;
+ if (flags & AVIO_FLAG_WRITE) {
+ h->max_packet_size = s->packet_size;
+ } else {
+ h->max_packet_size = UDP_MAX_PKT_SIZE;
+ }
h->rw_timeout = s->timeout;
/* fill the dest addr */
@@ -644,20 +660,20 @@ static int udp_open(URLContext *h, const char *uri, int flags)
}
if (h->flags & AVIO_FLAG_READ) {
/* input */
- if (num_sources == 0 || !include) {
+ if (num_include_sources && num_exclude_sources) {
+ av_log(h, AV_LOG_ERROR, "Simultaneously including and excluding multicast sources is not supported\n");
+ goto fail;
+ }
+ if (num_include_sources) {
+ if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, include_sources, num_include_sources, 1) < 0)
+ goto fail;
+ } else {
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
goto fail;
-
- if (num_sources) {
- if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)
- goto fail;
- }
- } else if (include && num_sources) {
- if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)
+ }
+ if (num_exclude_sources) {
+ if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, exclude_sources, num_exclude_sources, 0) < 0)
goto fail;
- } else {
- av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");
- goto fail;
}
}
}
@@ -686,8 +702,10 @@ static int udp_open(URLContext *h, const char *uri, int flags)
}
}
- for (i = 0; i < num_sources; i++)
- av_freep(&sources[i]);
+ for (i = 0; i < num_include_sources; i++)
+ av_freep(&include_sources[i]);
+ for (i = 0; i < num_exclude_sources; i++)
+ av_freep(&exclude_sources[i]);
s->udp_fd = udp_fd;
@@ -727,8 +745,10 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (udp_fd >= 0)
closesocket(udp_fd);
av_fifo_free(s->fifo);
- for (i = 0; i < num_sources; i++)
- av_freep(&sources[i]);
+ for (i = 0; i < num_include_sources; i++)
+ av_freep(&include_sources[i]);
+ for (i = 0; i < num_exclude_sources; i++)
+ av_freep(&exclude_sources[i]);
return AVERROR(EIO);
}
diff --git a/chromium/third_party/ffmpeg/libavformat/unix.c b/chromium/third_party/ffmpeg/libavformat/unix.c
new file mode 100644
index 00000000000..0e61318fbd8
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/unix.c
@@ -0,0 +1,155 @@
+/*
+ * Unix socket protocol
+ * Copyright (c) 2013 Luca Barbato
+ *
+ * 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
+ */
+
+/**
+ * @file
+ *
+ * Unix socket url_protocol
+ *
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "os_support.h"
+#include "network.h"
+#include <sys/un.h>
+#include "url.h"
+
+typedef struct UnixContext {
+ const AVClass *class;
+ struct sockaddr_un addr;
+ int timeout;
+ int listen;
+ int type;
+ int fd;
+} UnixContext;
+
+#define OFFSET(x) offsetof(UnixContext, x)
+#define ED AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption unix_options[] = {
+ { "listen", "Open socket for listening", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ED },
+ { "timeout", "Timeout in ms", OFFSET(timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ED },
+ { "type", "Socket type", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = SOCK_STREAM }, INT_MIN, INT_MAX, ED, "type" },
+ { "stream", "Stream (reliable stream-oriented)", 0, AV_OPT_TYPE_CONST, { .i64 = SOCK_STREAM }, INT_MIN, INT_MAX, ED, "type" },
+ { "datagram", "Datagram (unreliable packet-oriented)", 0, AV_OPT_TYPE_CONST, { .i64 = SOCK_DGRAM }, INT_MIN, INT_MAX, ED, "type" },
+ { "seqpacket", "Seqpacket (reliable packet-oriented", 0, AV_OPT_TYPE_CONST, { .i64 = SOCK_SEQPACKET }, INT_MIN, INT_MAX, ED, "type" },
+ { NULL }
+};
+
+static const AVClass unix_class = {
+ .class_name = "unix",
+ .item_name = av_default_item_name,
+ .option = unix_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int unix_open(URLContext *h, const char *filename, int flags)
+{
+ UnixContext *s = h->priv_data;
+ int fd, ret;
+
+ av_strstart(filename, "unix:", &filename);
+ s->addr.sun_family = AF_UNIX;
+ av_strlcpy(s->addr.sun_path, filename, sizeof(s->addr.sun_path));
+
+ if ((fd = ff_socket(AF_UNIX, s->type, 0)) < 0)
+ return ff_neterrno();
+
+ if (s->listen) {
+ fd = ff_listen_bind(fd, (struct sockaddr *)&s->addr,
+ sizeof(s->addr), s->timeout, h);
+ if (fd < 0) {
+ ret = fd;
+ goto fail;
+ }
+ } else {
+ ret = ff_listen_connect(fd, (struct sockaddr *)&s->addr,
+ sizeof(s->addr), s->timeout, h, 0);
+ if (ret < 0)
+ goto fail;
+ }
+
+ s->fd = fd;
+
+ return 0;
+
+fail:
+ if (s->listen && AVUNERROR(ret) != EADDRINUSE)
+ unlink(s->addr.sun_path);
+ if (fd >= 0)
+ closesocket(fd);
+ return ret;
+}
+
+static int unix_read(URLContext *h, uint8_t *buf, int size)
+{
+ UnixContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = ff_network_wait_fd(s->fd, 0);
+ if (ret < 0)
+ return ret;
+ }
+ ret = recv(s->fd, buf, size, 0);
+ return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int unix_write(URLContext *h, const uint8_t *buf, int size)
+{
+ UnixContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = ff_network_wait_fd(s->fd, 1);
+ if (ret < 0)
+ return ret;
+ }
+ ret = send(s->fd, buf, size, 0);
+ return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int unix_close(URLContext *h)
+{
+ UnixContext *s = h->priv_data;
+ if (s->listen)
+ unlink(s->addr.sun_path);
+ closesocket(s->fd);
+ return 0;
+}
+
+static int unix_get_file_handle(URLContext *h)
+{
+ UnixContext *s = h->priv_data;
+ return s->fd;
+}
+
+URLProtocol ff_unix_protocol = {
+ .name = "unix",
+ .url_open = unix_open,
+ .url_read = unix_read,
+ .url_write = unix_write,
+ .url_close = unix_close,
+ .url_get_file_handle = unix_get_file_handle,
+ .priv_data_size = sizeof(UnixContext),
+ .priv_data_class = &unix_class,
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/url-test.c b/chromium/third_party/ffmpeg/libavformat/url-test.c
index ee5f06e9ee1..a1da82e4936 100644
--- a/chromium/third_party/ffmpeg/libavformat/url-test.c
+++ b/chromium/third_party/ffmpeg/libavformat/url-test.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "internal.h"
+#include "url.h"
static void test(const char *base, const char *rel)
{
diff --git a/chromium/third_party/ffmpeg/libavformat/url.c b/chromium/third_party/ffmpeg/libavformat/url.c
new file mode 100644
index 00000000000..47e15843cf4
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/url.c
@@ -0,0 +1,147 @@
+/*
+ * URL utility functions
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * 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 "config.h"
+#include "url.h"
+#if CONFIG_NETWORK
+#include "network.h"
+#endif
+#include "libavutil/avstring.h"
+
+/**
+ * @file
+ * URL utility functions.
+ */
+
+int ff_url_join(char *str, int size, const char *proto,
+ const char *authorization, const char *hostname,
+ int port, const char *fmt, ...)
+{
+#if CONFIG_NETWORK
+ struct addrinfo hints = { 0 }, *ai;
+#endif
+
+ str[0] = '\0';
+ if (proto)
+ av_strlcatf(str, size, "%s://", proto);
+ if (authorization && authorization[0])
+ av_strlcatf(str, size, "%s@", authorization);
+#if CONFIG_NETWORK && defined(AF_INET6)
+ /* Determine if hostname is a numerical IPv6 address,
+ * properly escape it within [] in that case. */
+ hints.ai_flags = AI_NUMERICHOST;
+ if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
+ if (ai->ai_family == AF_INET6) {
+ av_strlcat(str, "[", size);
+ av_strlcat(str, hostname, size);
+ av_strlcat(str, "]", size);
+ } else {
+ av_strlcat(str, hostname, size);
+ }
+ freeaddrinfo(ai);
+ } else
+#endif
+ /* Not an IPv6 address, just output the plain string. */
+ av_strlcat(str, hostname, size);
+
+ if (port >= 0)
+ av_strlcatf(str, size, ":%d", port);
+ if (fmt) {
+ va_list vl;
+ int len = strlen(str);
+
+ va_start(vl, fmt);
+ vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
+ va_end(vl);
+ }
+ return strlen(str);
+}
+
+void ff_make_absolute_url(char *buf, int size, const char *base,
+ const char *rel)
+{
+ 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';
+ }
+ }
+ av_strlcat(buf, rel, size);
+ return;
+ }
+ /* If rel actually is an absolute url, just copy it */
+ if (!base || strstr(rel, "://") || rel[0] == '/') {
+ av_strlcpy(buf, rel, size);
+ return;
+ }
+ if (base != buf)
+ av_strlcpy(buf, base, size);
+
+ /* Strip off any query string from base */
+ path_query = strchr(buf, '?');
+ if (path_query != NULL)
+ *path_query = '\0';
+
+ /* Is relative path just a new query part? */
+ if (rel[0] == '?') {
+ av_strlcat(buf, rel, size);
+ return;
+ }
+
+ /* 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;
+ }
+ /* Cut off the directory name */
+ if (sep)
+ sep[1] = '\0';
+ else
+ buf[0] = '\0';
+ rel += 3;
+ }
+ av_strlcat(buf, rel, size);
+}
diff --git a/chromium/third_party/ffmpeg/libavformat/url.h b/chromium/third_party/ffmpeg/libavformat/url.h
index 5f75dc91e17..06dfda111da 100644
--- a/chromium/third_party/ffmpeg/libavformat/url.h
+++ b/chromium/third_party/ffmpeg/libavformat/url.h
@@ -248,4 +248,41 @@ URLProtocol *ffurl_protocol_next(URLProtocol *prev);
int ff_udp_set_remote_url(URLContext *h, const char *uri);
int ff_udp_get_local_port(URLContext *h);
+/**
+ * Assemble a URL string from components. This is the reverse operation
+ * of av_url_split.
+ *
+ * Note, this requires networking to be initialized, so the caller must
+ * ensure ff_network_init has been called.
+ *
+ * @see av_url_split
+ *
+ * @param str the buffer to fill with the url
+ * @param size the size of the str buffer
+ * @param proto the protocol identifier, if null, the separator
+ * after the identifier is left out, too
+ * @param authorization an optional authorization string, may be null.
+ * An empty string is treated the same as a null string.
+ * @param hostname the host name string
+ * @param port the port number, left out from the string if negative
+ * @param fmt a generic format string for everything to add after the
+ * host/port, may be null
+ * @return the number of characters written to the destination buffer
+ */
+int ff_url_join(char *str, int size, const char *proto,
+ const char *authorization, const char *hostname,
+ int port, const char *fmt, ...) av_printf_format(7, 8);
+
+/**
+ * Convert a relative url into an absolute url, given a base url.
+ *
+ * @param buf the buffer where output absolute url is written
+ * @param size the size of buf
+ * @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);
+
+
#endif /* AVFORMAT_URL_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/utils.c b/chromium/third_party/ffmpeg/libavformat/utils.c
index 04b61f78cae..dca4304963d 100644
--- a/chromium/third_party/ffmpeg/libavformat/utils.c
+++ b/chromium/third_party/ffmpeg/libavformat/utils.c
@@ -19,8 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* #define DEBUG */
-
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
@@ -30,6 +28,7 @@
#include "libavutil/avassert.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
+#include "libavutil/internal.h"
#include "libavutil/pixdesc.h"
#include "metadata.h"
#include "id3v2.h"
@@ -99,162 +98,8 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)
return timestamp;
}
-#define MAKE_ACCESSORS(str, name, type, field) \
- type av_##name##_get_##field(const str *s) { return s->field; } \
- void av_##name##_set_##field(str *s, type v) { s->field = v; }
-
MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
-/** head of registered input format linked list */
-static AVInputFormat *first_iformat = NULL;
-/** head of registered output format linked list */
-static AVOutputFormat *first_oformat = NULL;
-
-AVInputFormat *av_iformat_next(AVInputFormat *f)
-{
- if(f) return f->next;
- else return first_iformat;
-}
-
-AVOutputFormat *av_oformat_next(AVOutputFormat *f)
-{
- if(f) return f->next;
- else return first_oformat;
-}
-
-void av_register_input_format(AVInputFormat *format)
-{
- AVInputFormat **p;
- p = &first_iformat;
- while (*p != NULL) p = &(*p)->next;
- *p = format;
- format->next = NULL;
-}
-
-void av_register_output_format(AVOutputFormat *format)
-{
- AVOutputFormat **p;
- p = &first_oformat;
- while (*p != NULL) p = &(*p)->next;
- *p = format;
- format->next = NULL;
-}
-
-int av_match_ext(const char *filename, const char *extensions)
-{
- const char *ext, *p;
- char ext1[32], *q;
-
- if(!filename)
- return 0;
-
- ext = strrchr(filename, '.');
- if (ext) {
- ext++;
- p = extensions;
- for(;;) {
- q = ext1;
- while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
- *q++ = *p++;
- *q = '\0';
- if (!av_strcasecmp(ext1, ext))
- return 1;
- if (*p == '\0')
- break;
- p++;
- }
- }
- return 0;
-}
-
-static int match_format(const char *name, const char *names)
-{
- const char *p;
- int len, namelen;
-
- if (!name || !names)
- return 0;
-
- namelen = strlen(name);
- while ((p = strchr(names, ','))) {
- len = FFMAX(p - names, namelen);
- if (!av_strncasecmp(name, names, len))
- return 1;
- names = p+1;
- }
- return !av_strcasecmp(name, names);
-}
-
-AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
- const char *mime_type)
-{
- AVOutputFormat *fmt = NULL, *fmt_found;
- int score_max, score;
-
- /* specific test for image sequences */
-#if CONFIG_IMAGE2_MUXER
- if (!short_name && filename &&
- av_filename_number_test(filename) &&
- ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
- return av_guess_format("image2", NULL, NULL);
- }
-#endif
- /* Find the proper file type. */
- fmt_found = NULL;
- score_max = 0;
- while ((fmt = av_oformat_next(fmt))) {
- score = 0;
- if (fmt->name && short_name && match_format(short_name, fmt->name))
- score += 100;
- if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
- score += 10;
- if (filename && fmt->extensions &&
- av_match_ext(filename, fmt->extensions)) {
- score += 5;
- }
- if (score > score_max) {
- score_max = score;
- fmt_found = fmt;
- }
- }
- return fmt_found;
-}
-
-enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
- const char *filename, const char *mime_type, enum AVMediaType type){
- if (!strcmp(fmt->name, "segment") || !strcmp(fmt->name, "ssegment")) {
- fmt = av_guess_format(NULL, filename, NULL);
- }
-
- if(type == AVMEDIA_TYPE_VIDEO){
- enum AVCodecID codec_id= AV_CODEC_ID_NONE;
-
-#if CONFIG_IMAGE2_MUXER
- if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
- codec_id= ff_guess_image2_codec(filename);
- }
-#endif
- if(codec_id == AV_CODEC_ID_NONE)
- codec_id= fmt->video_codec;
- return codec_id;
- }else if(type == AVMEDIA_TYPE_AUDIO)
- return fmt->audio_codec;
- else if (type == AVMEDIA_TYPE_SUBTITLE)
- return fmt->subtitle_codec;
- else
- return AV_CODEC_ID_NONE;
-}
-
-AVInputFormat *av_find_input_format(const char *short_name)
-{
- AVInputFormat *fmt = NULL;
- while ((fmt = av_iformat_next(fmt))) {
- if (match_format(short_name, fmt->name))
- return fmt;
- }
- return NULL;
-}
-
/* an arbitrarily chosen "sane" max packet size -- 50M */
#define SANE_CHUNK_SIZE (50000000)
@@ -376,10 +221,10 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score
if (fmt1->read_probe) {
score = fmt1->read_probe(&lpd);
if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
- score = FFMAX(score, nodat ? AVPROBE_SCORE_MAX/4-1 : 1);
+ score = FFMAX(score, nodat ? AVPROBE_SCORE_EXTENSION / 2 - 1 : 1);
} else if (fmt1->extensions) {
if (av_match_ext(lpd.filename, fmt1->extensions)) {
- score = 50;
+ score = AVPROBE_SCORE_EXTENSION;
}
}
if (score > score_max) {
@@ -389,7 +234,7 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score
fmt = NULL;
}
if(nodat)
- score_max = FFMIN(AVPROBE_SCORE_MAX/4-1, score_max);
+ score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
*score_ret= score_max;
return fmt;
@@ -671,7 +516,8 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
goto fail;
if (id3v2_extra_meta) {
- if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac")) {
+ if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") ||
+ !strcmp(s->iformat->name, "tta")) {
if((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
goto fail;
} else
@@ -876,7 +722,7 @@ int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux)
if ((frame_size = av_get_audio_frame_duration(enc, size)) > 0)
return frame_size;
- /* fallback to using frame_size if muxing */
+ /* Fall back on using frame_size if muxing. */
if (enc->frame_size > 1)
return enc->frame_size;
@@ -956,7 +802,7 @@ static int is_intra_only(AVCodecContext *enc){
static int has_decode_delay_been_guessed(AVStream *st)
{
if(st->codec->codec_id != AV_CODEC_ID_H264) return 1;
- if(!st->info) // if we have left find_stream_info then nb_decoded_frames wont increase anymore for stream copy
+ if(!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy
return 1;
#if CONFIG_H264_DECODER
if(st->codec->has_b_frames &&
@@ -1168,7 +1014,9 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
pc && pc->pict_type != AV_PICTURE_TYPE_B)
presentation_delayed = 1;
- if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && st->pts_wrap_bits<63 && pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > pkt->pts){
+ if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE &&
+ st->pts_wrap_bits < 63 &&
+ pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) {
if(is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > st->cur_dts) {
pkt->dts -= 1LL<<st->pts_wrap_bits;
} else
@@ -1344,6 +1192,13 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
if (!out_pkt.size)
continue;
+ if (pkt->side_data) {
+ out_pkt.side_data = pkt->side_data;
+ out_pkt.side_data_elems = pkt->side_data_elems;
+ pkt->side_data = NULL;
+ pkt->side_data_elems = 0;
+ }
+
/* set the duration */
out_pkt.duration = 0;
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -1383,8 +1238,10 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
out_pkt.buf = pkt->buf;
pkt->buf = NULL;
#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
out_pkt.destruct = pkt->destruct;
pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
if ((ret = av_dup_packet(&out_pkt)) < 0)
@@ -1889,14 +1746,50 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
return 0;
}
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+ int64_t step= 1024;
+ int64_t limit, ts_max;
+ int64_t filesize = avio_size(s->pb);
+ int64_t pos_max = filesize - 1;
+ do{
+ limit = pos_max;
+ pos_max = FFMAX(0, (pos_max) - step);
+ ts_max = ff_read_timestamp(s, stream_index, &pos_max, limit, read_timestamp);
+ step += step;
+ }while(ts_max == AV_NOPTS_VALUE && 2*limit > step);
+ if (ts_max == AV_NOPTS_VALUE)
+ return -1;
+
+ for(;;){
+ int64_t tmp_pos = pos_max + 1;
+ int64_t tmp_ts = ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
+ if(tmp_ts == AV_NOPTS_VALUE)
+ break;
+ ts_max = tmp_ts;
+ pos_max = tmp_pos;
+ if(tmp_pos >= filesize)
+ break;
+ }
+
+ if (ts)
+ *ts = ts_max;
+ if (pos)
+ *pos = pos_max;
+
+ return 0;
+}
+
int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
int64_t pos_min, int64_t pos_max, int64_t pos_limit,
int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
{
int64_t pos, ts;
- int64_t start_pos, filesize;
+ int64_t start_pos;
int no_change;
+ int ret;
av_dlog(s, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
@@ -1913,27 +1806,8 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
}
if(ts_max == AV_NOPTS_VALUE){
- int step= 1024;
- filesize = avio_size(s->pb);
- pos_max = filesize - 1;
- do{
- pos_max = FFMAX(0, pos_max - step);
- ts_max = ff_read_timestamp(s, stream_index, &pos_max, pos_max + step, read_timestamp);
- step += step;
- }while(ts_max == AV_NOPTS_VALUE && pos_max > 0);
- if (ts_max == AV_NOPTS_VALUE)
- return -1;
-
- for(;;){
- int64_t tmp_pos= pos_max + 1;
- int64_t tmp_ts= ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
- if(tmp_ts == AV_NOPTS_VALUE)
- break;
- ts_max= tmp_ts;
- pos_max= tmp_pos;
- if(tmp_pos >= filesize)
- break;
- }
+ if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp)) < 0)
+ return ret;
pos_limit= pos_max;
}
@@ -2138,7 +2012,19 @@ static int seek_frame_internal(AVFormatContext *s, int stream_index,
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
- int ret = seek_frame_internal(s, stream_index, timestamp, flags);
+ int ret;
+
+ if (s->iformat->read_seek2 && !s->iformat->read_seek) {
+ int64_t min_ts = INT64_MIN, max_ts = INT64_MAX;
+ if ((flags & AVSEEK_FLAG_BACKWARD))
+ max_ts = timestamp;
+ else
+ min_ts = timestamp;
+ return avformat_seek_file(s, stream_index, min_ts, timestamp, max_ts,
+ flags & ~AVSEEK_FLAG_BACKWARD);
+ }
+
+ ret = seek_frame_internal(s, stream_index, timestamp, flags);
if (ret >= 0)
ret = avformat_queue_attached_pictures(s);
@@ -2155,6 +2041,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
if(s->seek2any>0)
flags |= AVSEEK_FLAG_ANY;
+ flags &= ~AVSEEK_FLAG_BACKWARD;
if (s->iformat->read_seek2) {
int ret;
@@ -2182,8 +2069,8 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
//try to seek via read_timestamp()
}
- //Fallback to old API if new is not implemented but old is
- //Note the old has somewhat different semantics
+ // Fall back on old API if new is not implemented but old is.
+ // Note the old API has somewhat different semantics.
if (s->iformat->read_seek || 1) {
int dir = (ts - (uint64_t)min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0);
int ret = av_seek_frame(s, stream_index, ts, flags | dir);
@@ -2750,7 +2637,7 @@ int av_find_stream_info(AVFormatContext *ic)
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
- int i, count, ret, j;
+ int i, count, ret = 0, j;
int64_t read_size;
AVStream *st;
AVPacket pkt1, *pkt;
@@ -2892,11 +2779,15 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
break;
}
- if (ic->flags & AVFMT_FLAG_NOBUFFER) {
- pkt = &pkt1;
- } else {
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ free_packet_buffer(&ic->packet_buffer, &ic->packet_buffer_end);
+ {
pkt = add_to_pktbuf(&ic->packet_buffer, &pkt1,
&ic->packet_buffer_end);
+ if (!pkt) {
+ ret = AVERROR(ENOMEM);
+ goto find_stream_info_err;
+ }
if ((ret = av_dup_packet(pkt)) < 0)
goto find_stream_info_err;
}
@@ -2943,8 +2834,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
if (st->avg_frame_rate.num > 0)
t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q));
+ if ( t==0
+ && st->codec_info_nb_frames>30
+ && st->info->fps_first_dts != AV_NOPTS_VALUE
+ && st->info->fps_last_dts != AV_NOPTS_VALUE)
+ t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
+
if (t >= ic->max_analyze_duration) {
- av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64" microseconds\n", ic->max_analyze_duration, t);
+ av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %d reached at %"PRId64" microseconds\n", ic->max_analyze_duration, t);
break;
}
if (pkt->duration) {
@@ -2963,6 +2860,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
if (!st->info->duration_error)
st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2);
+ if (!st->info->duration_error)
+ return AVERROR(ENOMEM);
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
@@ -3017,9 +2916,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
int err = 0;
av_init_packet(&empty_pkt);
- ret = -1; /* we could not have all the codec parameters before EOF */
for(i=0;i<ic->nb_streams;i++) {
- const char *errmsg;
st = ic->streams[i];
@@ -3036,17 +2933,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
"decoding for stream %d failed\n", st->index);
}
}
-
- if (!has_codec_parameters(st, &errmsg)) {
- char buf[256];
- avcodec_string(buf, sizeof(buf), st->codec, 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);
- } else {
- ret = 0;
- }
}
}
@@ -3069,6 +2955,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
int best_fps = 0;
double best_error = 0.01;
+ if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2||
+ st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den)
+ continue;
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
st->info->codec_info_duration_fields*(int64_t)st->time_base.den,
st->info->codec_info_duration*2*(int64_t)st->time_base.num, 60000);
@@ -3156,12 +3045,29 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
if(ic->probesize)
estimate_timings(ic, old_offset);
+ if (ret >= 0 && ic->nb_streams)
+ ret = -1; /* we could not have all the codec parameters before EOF */
+ for(i=0;i<ic->nb_streams;i++) {
+ const char *errmsg;
+ st = ic->streams[i];
+ if (!has_codec_parameters(st, &errmsg)) {
+ char buf[256];
+ avcodec_string(buf, sizeof(buf), st->codec, 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);
+ } else {
+ ret = 0;
+ }
+ }
+
compute_chapters_end(ic);
find_stream_info_err:
for (i=0; i < ic->nb_streams; i++) {
st = ic->streams[i];
- if (ic->streams[i]->codec)
+ if (ic->streams[i]->codec && ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
ic->streams[i]->codec->thread_count = 0;
if (st->info)
av_freep(&st->info->duration_error);
@@ -3803,27 +3709,11 @@ static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int
av_hex_dump(f, pkt->data, pkt->size);
}
-#if FF_API_PKT_DUMP
-void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
-{
- AVRational tb = { 1, AV_TIME_BASE };
- pkt_dump_internal(NULL, f, 0, pkt, dump_payload, tb);
-}
-#endif
-
void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st)
{
pkt_dump_internal(NULL, f, 0, pkt, dump_payload, st->time_base);
}
-#if FF_API_PKT_DUMP
-void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
-{
- AVRational tb = { 1, AV_TIME_BASE };
- pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, tb);
-}
-#endif
-
void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
AVStream *st)
{
@@ -3971,72 +3861,6 @@ void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
s->pts_wrap_bits = pts_wrap_bits;
}
-int ff_url_join(char *str, int size, const char *proto,
- const char *authorization, const char *hostname,
- int port, const char *fmt, ...)
-{
-#if CONFIG_NETWORK
- struct addrinfo hints = { 0 }, *ai;
-#endif
-
- str[0] = '\0';
- if (proto)
- av_strlcatf(str, size, "%s://", proto);
- if (authorization && authorization[0])
- av_strlcatf(str, size, "%s@", authorization);
-#if CONFIG_NETWORK && defined(AF_INET6)
- /* Determine if hostname is a numerical IPv6 address,
- * properly escape it within [] in that case. */
- hints.ai_flags = AI_NUMERICHOST;
- if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
- if (ai->ai_family == AF_INET6) {
- av_strlcat(str, "[", size);
- av_strlcat(str, hostname, size);
- av_strlcat(str, "]", size);
- } else {
- av_strlcat(str, hostname, size);
- }
- freeaddrinfo(ai);
- } else
-#endif
- /* Not an IPv6 address, just output the plain string. */
- av_strlcat(str, hostname, size);
-
- if (port >= 0)
- av_strlcatf(str, size, ":%d", port);
- if (fmt) {
- va_list vl;
- int len = strlen(str);
-
- va_start(vl, fmt);
- vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
- va_end(vl);
- }
- return strlen(str);
-}
-
-int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
- AVFormatContext *src)
-{
- AVPacket local_pkt;
-
- local_pkt = *pkt;
- local_pkt.stream_index = dst_stream;
- if (pkt->pts != AV_NOPTS_VALUE)
- local_pkt.pts = av_rescale_q(pkt->pts,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- if (pkt->dts != AV_NOPTS_VALUE)
- local_pkt.dts = av_rescale_q(pkt->dts,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- if (pkt->duration)
- local_pkt.duration = av_rescale_q(pkt->duration,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- return av_write_frame(dst, &local_pkt);
-}
-
void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
void *context)
{
@@ -4101,75 +3925,6 @@ int ff_find_stream_index(AVFormatContext *s, int id)
return -1;
}
-void ff_make_absolute_url(char *buf, int size, const char *base,
- const char *rel)
-{
- 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';
- }
- }
- av_strlcat(buf, rel, size);
- return;
- }
- /* If rel actually is an absolute url, just copy it */
- if (!base || strstr(rel, "://") || rel[0] == '/') {
- av_strlcpy(buf, rel, size);
- return;
- }
- if (base != buf)
- av_strlcpy(buf, base, size);
-
- /* Strip off any query string from base */
- path_query = strchr(buf, '?');
- if (path_query != NULL)
- *path_query = '\0';
-
- /* Is relative path just a new query part? */
- if (rel[0] == '?') {
- av_strlcat(buf, rel, size);
- return;
- }
-
- /* 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;
- }
- /* Cut off the directory name */
- if (sep)
- sep[1] = '\0';
- else
- buf[0] = '\0';
- rel += 3;
- }
- av_strlcat(buf, rel, size);
-}
-
int64_t ff_iso8601_to_unix_time(const char *datestr)
{
struct tm time1 = {0}, time2 = {0};
@@ -4259,15 +4014,6 @@ int ff_add_param_change(AVPacket *pkt, int32_t channels,
return 0;
}
-const struct AVCodecTag *avformat_get_riff_video_tags(void)
-{
- return ff_codec_bmp_tags;
-}
-const struct AVCodecTag *avformat_get_riff_audio_tags(void)
-{
- return ff_codec_wav_tags;
-}
-
AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
{
AVRational undef = {0, 1};
@@ -4462,57 +4208,3 @@ void ff_generate_avci_extradata(AVStream *st)
memcpy(st->codec->extradata, data, size);
st->codec->extradata_size = size;
}
-
-static int match_host_pattern(const char *pattern, const char *hostname)
-{
- int len_p, len_h;
- if (!strcmp(pattern, "*"))
- return 1;
- // Skip a possible *. at the start of the pattern
- if (pattern[0] == '*')
- pattern++;
- if (pattern[0] == '.')
- pattern++;
- len_p = strlen(pattern);
- len_h = strlen(hostname);
- if (len_p > len_h)
- return 0;
- // Simply check if the end of hostname is equal to 'pattern'
- if (!strcmp(pattern, &hostname[len_h - len_p])) {
- if (len_h == len_p)
- return 1; // Exact match
- if (hostname[len_h - len_p - 1] == '.')
- return 1; // The matched substring is a domain and not just a substring of a domain
- }
- return 0;
-}
-
-int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
-{
- char *buf, *start;
- int ret = 0;
- if (!no_proxy)
- return 0;
- if (!hostname)
- return 0;
- buf = av_strdup(no_proxy);
- if (!buf)
- return 0;
- start = buf;
- while (start) {
- char *sep, *next = NULL;
- start += strspn(start, " ,");
- sep = start + strcspn(start, " ,");
- if (*sep) {
- next = sep + 1;
- *sep = '\0';
- }
- if (match_host_pattern(start, hostname)) {
- ret = 1;
- break;
- }
- start = next;
- }
- av_free(buf);
- return ret;
-}
diff --git a/chromium/third_party/ffmpeg/libavformat/vc1test.c b/chromium/third_party/ffmpeg/libavformat/vc1test.c
index e411a257f13..7c6bcde089e 100644
--- a/chromium/third_party/ffmpeg/libavformat/vc1test.c
+++ b/chromium/third_party/ffmpeg/libavformat/vc1test.c
@@ -39,7 +39,7 @@ static int vc1t_probe(AVProbeData *p)
if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC)
return 0;
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
}
static int vc1t_read_header(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/version.h b/chromium/third_party/ffmpeg/libavformat/version.h
index 8fd08cf032d..1dfde221a20 100644
--- a/chromium/third_party/ffmpeg/libavformat/version.h
+++ b/chromium/third_party/ffmpeg/libavformat/version.h
@@ -30,8 +30,8 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR 3
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MINOR 14
+#define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
@@ -49,12 +49,6 @@
* the public API and may change, break or disappear at any time.
*/
-#ifndef FF_API_OLD_AVIO
-#define FF_API_OLD_AVIO (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_PKT_DUMP
-#define FF_API_PKT_DUMP (LIBAVFORMAT_VERSION_MAJOR < 54)
-#endif
#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
#define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 56)
#endif
diff --git a/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c b/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c
index 9b38e6a7910..f17a0c1d13e 100644
--- a/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c
+++ b/chromium/third_party/ffmpeg/libavformat/vorbiscomment.c
@@ -34,6 +34,7 @@ const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
{ "ALBUMARTIST", "album_artist"},
{ "TRACKNUMBER", "track" },
{ "DISCNUMBER", "disc" },
+ { "DESCRIPTION", "comment" },
{ 0 }
};
diff --git a/chromium/third_party/ffmpeg/libavformat/vqf.c b/chromium/third_party/ffmpeg/libavformat/vqf.c
index f1e6aafd989..1ce53595d60 100644
--- a/chromium/third_party/ffmpeg/libavformat/vqf.c
+++ b/chromium/third_party/ffmpeg/libavformat/vqf.c
@@ -43,7 +43,7 @@ static int vqf_probe(AVProbeData *probe_packet)
if (!memcmp(probe_packet->buf + 4, "00052200", 8))
return AVPROBE_SCORE_MAX;
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
}
static void add_metadata(AVFormatContext *s, uint32_t tag,
@@ -132,6 +132,11 @@ static int vqf_read_header(AVFormatContext *s)
rate_flag = AV_RB32(comm_chunk + 8);
avio_skip(s->pb, len-12);
+ if (st->codec->channels <= 0) {
+ av_log(s, AV_LOG_ERROR, "Invalid number of channels\n");
+ return AVERROR_INVALIDDATA;
+ }
+
st->codec->bit_rate = read_bitrate*1000;
break;
case MKTAG('D','S','I','Z'): // size of compressed data
diff --git a/chromium/third_party/ffmpeg/libavformat/w64.c b/chromium/third_party/ffmpeg/libavformat/w64.c
index 7bf5502f7cd..ef2d90a600c 100644
--- a/chromium/third_party/ffmpeg/libavformat/w64.c
+++ b/chromium/third_party/ffmpeg/libavformat/w64.c
@@ -20,20 +20,31 @@
#include "w64.h"
-const uint8_t ff_w64_guid_riff[16] = { 'r', 'i', 'f', 'f',
- 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
+const uint8_t ff_w64_guid_riff[16] = {
+ 'r', 'i', 'f', 'f',
+ 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+};
-const uint8_t ff_w64_guid_wave[16] = { 'w', 'a', 'v', 'e',
- 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_wave[16] = {
+ 'w', 'a', 'v', 'e',
+ 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
-const uint8_t ff_w64_guid_fmt [16] = { 'f', 'm', 't', ' ',
- 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_fmt [16] = {
+ 'f', 'm', 't', ' ',
+ 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
const uint8_t ff_w64_guid_fact[16] = { 'f', 'a', 'c', 't',
- 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+ 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
-const uint8_t ff_w64_guid_data[16] = { 'd', 'a', 't', 'a',
- 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_data[16] = {
+ 'd', 'a', 't', 'a',
+ 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
-const uint8_t ff_w64_guid_summarylist[16] = { 0xBC, 0x94, 0x5F, 0x92,
- 0x5A, 0x52, 0xD2, 0x11, 0x86, 0xDC, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+const uint8_t ff_w64_guid_summarylist[16] = {
+ 0xBC, 0x94, 0x5F, 0x92,
+ 0x5A, 0x52, 0xD2, 0x11, 0x86, 0xDC, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/wavdec.c b/chromium/third_party/ffmpeg/libavformat/wavdec.c
index 14c52f810a7..d5b3b9ef2f3 100644
--- a/chromium/third_party/ffmpeg/libavformat/wavdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/wavdec.c
@@ -25,17 +25,18 @@
#include "libavutil/avassert.h"
#include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "avformat.h"
-#include "internal.h"
+#include "avio.h"
#include "avio_internal.h"
+#include "internal.h"
+#include "metadata.h"
#include "pcm.h"
#include "riff.h"
#include "w64.h"
-#include "avio.h"
-#include "metadata.h"
#include "spdif.h"
typedef struct WAVDemuxContext {
@@ -51,9 +52,11 @@ typedef struct WAVDemuxContext {
int audio_eof;
int ignore_length;
int spdif;
+ int smv_cur_pt;
+ int smv_given_first;
+ int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended
} WAVDemuxContext;
-
#if CONFIG_WAV_DEMUXER
static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
@@ -62,19 +65,27 @@ static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
return avio_rl32(pb);
}
+/* RIFF chunks are always at even offsets relative to where they start. */
+static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset, int whence)
+{
+ offset += offset < INT64_MAX && offset + wav->unaligned & 1;
+
+ return avio_seek(s, offset, whence);
+}
+
/* return the size of the found tag */
-static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
+static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1)
{
unsigned int tag;
int64_t size;
for (;;) {
if (url_feof(pb))
- return -1;
+ return AVERROR_EOF;
size = next_tag(pb, &tag);
if (tag == tag1)
break;
- avio_skip(pb, size + (size & 1));
+ wav_seek_tag(wav, pb, size, SEEK_CUR);
}
return size;
}
@@ -86,11 +97,9 @@ static int wav_probe(AVProbeData *p)
return 0;
if (!memcmp(p->buf + 8, "WAVE", 4)) {
if (!memcmp(p->buf, "RIFF", 4))
- /*
- Since ACT demuxer has standard WAV header at top of it's own,
- returning score is decreased to avoid probe conflict
- between ACT and WAV.
- */
+ /* Since the ACT demuxer has a standard WAV header at the top of
+ * its own, the returned score is decreased to avoid a probe
+ * conflict between ACT and WAV. */
return AVPROBE_SCORE_MAX - 1;
else if (!memcmp(p->buf, "RF64", 4) &&
!memcmp(p->buf + 12, "ds64", 4))
@@ -102,7 +111,7 @@ static int wav_probe(AVProbeData *p)
static void handle_stream_probing(AVStream *st)
{
if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
- st->request_probe = AVPROBE_SCORE_MAX/2;
+ st->request_probe = AVPROBE_SCORE_EXTENSION;
st->probe_packets = FFMIN(st->probe_packets, 4);
}
}
@@ -173,16 +182,22 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
if (umid_mask) {
/* the string formatting below is per SMPTE 330M-2004 Annex C */
- if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
+ if (umid_parts[4] == 0 && umid_parts[5] == 0 &&
+ umid_parts[6] == 0 && umid_parts[7] == 0) {
/* basic UMID */
- snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
- umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
+ snprintf(temp, sizeof(temp),
+ "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1],
+ umid_parts[2], umid_parts[3]);
} else {
/* extended UMID */
- snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
- "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
- umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
- umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
+ snprintf(temp, sizeof(temp),
+ "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
+ "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1],
+ umid_parts[2], umid_parts[3],
+ umid_parts[4], umid_parts[5],
+ umid_parts[6], umid_parts[7]);
}
if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
@@ -197,7 +212,7 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
/* CodingHistory present */
size -= 602;
- if (!(coding_history = av_malloc(size+1)))
+ if (!(coding_history = av_malloc(size + 1)))
return AVERROR(ENOMEM);
if ((ret = avio_read(s->pb, coding_history, size)) < 0)
@@ -213,26 +228,28 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
}
static const AVMetadataConv wav_metadata_conv[] = {
- {"description", "comment" },
- {"originator", "encoded_by" },
- {"origination_date", "date" },
- {"origination_time", "creation_time"},
- {0},
+ { "description", "comment" },
+ { "originator", "encoded_by" },
+ { "origination_date", "date" },
+ { "origination_time", "creation_time" },
+ { 0 },
};
/* wav input */
static int wav_read_header(AVFormatContext *s)
{
int64_t size, av_uninit(data_size);
- int64_t sample_count=0;
+ int64_t sample_count = 0;
int rf64;
uint32_t tag;
- AVIOContext *pb = s->pb;
- AVStream *st = NULL;
+ AVIOContext *pb = s->pb;
+ AVStream *st = NULL;
WAVDemuxContext *wav = s->priv_data;
int ret, got_fmt = 0;
int64_t next_tag_ofs, data_ofs = -1;
+ wav->unaligned = avio_tell(s->pb) & 1;
+
wav->smv_data_ofs = -1;
/* check RIFF header */
@@ -240,21 +257,23 @@ static int wav_read_header(AVFormatContext *s)
rf64 = tag == MKTAG('R', 'F', '6', '4');
if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
- return -1;
+ return AVERROR_INVALIDDATA;
avio_rl32(pb); /* file size */
tag = avio_rl32(pb);
if (tag != MKTAG('W', 'A', 'V', 'E'))
- return -1;
+ return AVERROR_INVALIDDATA;
if (rf64) {
if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
- return -1;
+ return AVERROR_INVALIDDATA;
size = avio_rl32(pb);
if (size < 24)
- return -1;
+ return AVERROR_INVALIDDATA;
avio_rl64(pb); /* RIFF size */
- data_size = avio_rl64(pb);
+
+ data_size = avio_rl64(pb);
sample_count = avio_rl64(pb);
+
if (data_size < 0 || sample_count < 0) {
av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
"ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
@@ -267,7 +286,7 @@ static int wav_read_header(AVFormatContext *s)
for (;;) {
AVStream *vst;
- size = next_tag(pb, &tag);
+ size = next_tag(pb, &tag);
next_tag_ofs = avio_tell(pb) + size;
if (url_feof(pb))
@@ -285,14 +304,15 @@ static int wav_read_header(AVFormatContext *s)
break;
case MKTAG('d', 'a', 't', 'a'):
if (!got_fmt) {
- av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
+ av_log(s, AV_LOG_ERROR,
+ "found no 'fmt ' tag before the 'data' tag\n");
return AVERROR_INVALIDDATA;
}
if (rf64) {
next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
} else {
- data_size = size;
+ data_size = size;
next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
}
@@ -304,11 +324,11 @@ static int wav_read_header(AVFormatContext *s)
if (!pb->seekable || (!rf64 && !size))
goto break_loop;
break;
- case MKTAG('f','a','c','t'):
+ case MKTAG('f', 'a', 'c', 't'):
if (!sample_count)
sample_count = avio_rl32(pb);
break;
- case MKTAG('b','e','x','t'):
+ case MKTAG('b', 'e', 'x', 't'):
if ((ret = wav_parse_bext_tag(s, size)) < 0)
return ret;
break;
@@ -323,15 +343,23 @@ static int wav_read_header(AVFormatContext *s)
goto break_loop;
}
av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
+ wav->smv_given_first = 0;
vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
avio_r8(pb);
vst->id = 1;
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- vst->codec->codec_id = AV_CODEC_ID_MJPEG;
+ vst->codec->codec_id = AV_CODEC_ID_SMVJPEG;
vst->codec->width = avio_rl24(pb);
vst->codec->height = avio_rl24(pb);
+ vst->codec->extradata_size = 4;
+ vst->codec->extradata = av_malloc(vst->codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!vst->codec->extradata) {
+ av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n");
+ return AVERROR(ENOMEM);
+ }
size = avio_rl24(pb);
wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
avio_rl24(pb);
@@ -341,6 +369,8 @@ static int wav_read_header(AVFormatContext *s)
avio_rl24(pb);
avio_rl24(pb);
wav->smv_frames_per_jpeg = avio_rl24(pb);
+ AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg);
+ wav->smv_cur_pt = 0;
goto break_loop;
case MKTAG('L', 'I', 'S', 'T'):
if (size < 4) {
@@ -354,15 +384,13 @@ static int wav_read_header(AVFormatContext *s)
break;
}
- /* skip padding byte */
- next_tag_ofs += (next_tag_ofs < INT64_MAX && next_tag_ofs & 1);
-
/* seek to next tag unless we know that we'll run into EOF */
if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
- avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
+ wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) {
break;
}
}
+
break_loop:
if (data_ofs < 0) {
av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
@@ -371,8 +399,11 @@ break_loop:
avio_seek(pb, data_ofs, SEEK_SET);
- if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb))
- sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+ if (!sample_count && st->codec->channels &&
+ av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb))
+ sample_count = (data_size << 3) /
+ (st->codec->channels *
+ (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
if (sample_count)
st->duration = sample_count;
@@ -382,7 +413,8 @@ break_loop:
return 0;
}
-/** Find chunk with w64 GUID by skipping over other chunks
+/**
+ * Find chunk with w64 GUID by skipping over other chunks.
* @return the size of the found chunk
*/
static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
@@ -394,18 +426,17 @@ static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
avio_read(pb, guid, 16);
size = avio_rl64(pb);
if (size <= 24)
- return -1;
+ return AVERROR_INVALIDDATA;
if (!memcmp(guid, guid1, 16))
return size;
avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
}
- return -1;
+ return AVERROR_EOF;
}
#define MAX_SIZE 4096
-static int wav_read_packet(AVFormatContext *s,
- AVPacket *pkt)
+static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret, size;
int64_t left;
@@ -417,7 +448,7 @@ static int wav_read_packet(AVFormatContext *s,
enum AVCodecID codec;
ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
&codec);
- if (ret > AVPROBE_SCORE_MAX / 2) {
+ if (ret > AVPROBE_SCORE_EXTENSION) {
s->streams[0]->codec->codec_id = codec;
wav->spdif = 1;
} else {
@@ -432,10 +463,13 @@ static int wav_read_packet(AVFormatContext *s,
smv_retry:
audio_dts = s->streams[0]->cur_dts;
video_dts = s->streams[1]->cur_dts;
+
if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
- audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q);
- video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q);
- wav->smv_last_stream = video_dts >= audio_dts;
+ /*We always return a video frame first to get the pixel format first*/
+ wav->smv_last_stream = wav->smv_given_first ?
+ av_compare_ts(video_dts, s->streams[1]->time_base,
+ audio_dts, s->streams[0]->time_base) > 0 : 0;
+ wav->smv_given_first = 1;
}
wav->smv_last_stream = !wav->smv_last_stream;
wav->smv_last_stream |= wav->audio_eof;
@@ -453,8 +487,13 @@ smv_retry:
if (ret < 0)
goto smv_out;
pkt->pos -= 3;
- pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
- wav->smv_block++;
+ pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg + wav->smv_cur_pt;
+ wav->smv_cur_pt++;
+ if (wav->smv_frames_per_jpeg > 0)
+ wav->smv_cur_pt %= wav->smv_frames_per_jpeg;
+ if (!wav->smv_cur_pt)
+ wav->smv_block++;
+
pkt->stream_index = 1;
smv_out:
avio_seek(s->pb, old_pos, SEEK_SET);
@@ -470,19 +509,19 @@ smv_out:
left = wav->data_end - avio_tell(s->pb);
if (wav->ignore_length)
- left= INT_MAX;
- if (left <= 0){
+ left = INT_MAX;
+ if (left <= 0) {
if (CONFIG_W64_DEMUXER && wav->w64)
left = find_guid(s->pb, ff_w64_guid_data) - 24;
else
- left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
+ left = find_tag(wav, s->pb, MKTAG('d', 'a', 't', 'a'));
if (left < 0) {
wav->audio_eof = 1;
if (wav->smv_data_ofs > 0 && !wav->smv_eof)
goto smv_retry;
return AVERROR_EOF;
}
- wav->data_end= avio_tell(s->pb) + left;
+ wav->data_end = avio_tell(s->pb) + left;
}
size = MAX_SIZE;
@@ -513,7 +552,10 @@ static int wav_read_seek(AVFormatContext *s,
smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
else
timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
- wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
+ if (wav->smv_frames_per_jpeg > 0) {
+ wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
+ wav->smv_cur_pt = smv_timestamp % wav->smv_frames_per_jpeg;
+ }
}
st = s->streams[0];
@@ -552,12 +594,11 @@ AVInputFormat ff_wav_demuxer = {
.read_packet = wav_read_packet,
.read_seek = wav_read_seek,
.flags = AVFMT_GENERIC_INDEX,
- .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+ .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
.priv_class = &wav_demuxer_class,
};
#endif /* CONFIG_WAV_DEMUXER */
-
#if CONFIG_W64_DEMUXER
static int w64_probe(AVProbeData *p)
{
@@ -573,23 +614,24 @@ static int w64_probe(AVProbeData *p)
static int w64_read_header(AVFormatContext *s)
{
int64_t size, data_ofs = 0;
- AVIOContext *pb = s->pb;
- WAVDemuxContext *wav = s->priv_data;
+ AVIOContext *pb = s->pb;
+ WAVDemuxContext *wav = s->priv_data;
AVStream *st;
uint8_t guid[16];
int ret;
avio_read(pb, guid, 16);
if (memcmp(guid, ff_w64_guid_riff, 16))
- return -1;
+ return AVERROR_INVALIDDATA;
- if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */
- return -1;
+ /* riff + wave + fmt + sizes */
+ if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
+ return AVERROR_INVALIDDATA;
avio_read(pb, guid, 16);
if (memcmp(guid, ff_w64_guid_wave, 16)) {
av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
wav->w64 = 1;
@@ -685,6 +727,6 @@ AVInputFormat ff_w64_demuxer = {
.read_packet = wav_read_packet,
.read_seek = wav_read_seek,
.flags = AVFMT_GENERIC_INDEX,
- .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+ .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
};
#endif /* CONFIG_W64_DEMUXER */
diff --git a/chromium/third_party/ffmpeg/libavformat/webvttdec.c b/chromium/third_party/ffmpeg/libavformat/webvttdec.c
index 694a020b198..065448532d3 100644
--- a/chromium/third_party/ffmpeg/libavformat/webvttdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/webvttdec.c
@@ -29,9 +29,12 @@
#include "subtitles.h"
#include "libavutil/bprint.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
typedef struct {
+ const AVClass *class;
FFDemuxSubtitlesQueue q;
+ int kind;
} WebVTTContext;
static int webvtt_probe(AVProbeData *p)
@@ -66,6 +69,7 @@ static int webvtt_read_header(AVFormatContext *s)
avpriv_set_pts_info(st, 64, 1, 1000);
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id = AV_CODEC_ID_WEBVTT;
+ st->disposition |= webvtt->kind;
av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_init(&cue, 0, AV_BPRINT_SIZE_UNLIMITED);
@@ -74,8 +78,8 @@ static int webvtt_read_header(AVFormatContext *s)
int i;
int64_t pos;
AVPacket *sub;
- const char *p, *identifier;
- //const char *settings = NULL;
+ const char *p, *identifier, *settings;
+ int identifier_len, settings_len;
int64_t ts_start, ts_end;
ff_subtitles_read_chunk(s->pb, &cue);
@@ -92,15 +96,23 @@ static int webvtt_read_header(AVFormatContext *s)
continue;
/* optional cue identifier (can be a number like in SRT or some kind of
- * chaptering id), silently skip it */
- for (i = 0; p[i] && p[i] != '\n'; i++) {
+ * chaptering id) */
+ for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) {
if (!strncmp(p + i, "-->", 3)) {
identifier = NULL;
break;
}
}
- if (identifier)
- p += strcspn(p, "\n");
+ if (!identifier)
+ identifier_len = 0;
+ else {
+ identifier_len = strcspn(p, "\r\n");
+ p += identifier_len;
+ if (*p == '\r')
+ p++;
+ if (*p == '\n')
+ p++;
+ }
/* cue timestamps */
if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE)
@@ -112,14 +124,15 @@ static int webvtt_read_header(AVFormatContext *s)
if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE)
break;
- /* optional cue settings, TODO: store in side_data */
+ /* optional cue settings */
p += strcspn(p, "\n\t ");
while (*p == '\t' || *p == ' ')
p++;
- if (*p != '\n') {
- //settings = p;
- p += strcspn(p, "\n");
- }
+ settings = p;
+ settings_len = strcspn(p, "\r\n");
+ p += settings_len;
+ if (*p == '\r')
+ p++;
if (*p == '\n')
p++;
@@ -132,6 +145,20 @@ static int webvtt_read_header(AVFormatContext *s)
sub->pos = pos;
sub->pts = ts_start;
sub->duration = ts_end - ts_start;
+
+#define SET_SIDE_DATA(name, type) do { \
+ if (name##_len) { \
+ uint8_t *buf = av_packet_new_side_data(sub, type, name##_len); \
+ if (!buf) { \
+ res = AVERROR(ENOMEM); \
+ goto end; \
+ } \
+ memcpy(buf, name, name##_len); \
+ } \
+} while (0)
+
+ SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER);
+ SET_SIDE_DATA(settings, AV_PKT_DATA_WEBVTT_SETTINGS);
}
ff_subtitles_queue_finalize(&webvtt->q);
@@ -163,6 +190,25 @@ static int webvtt_read_close(AVFormatContext *s)
return 0;
}
+#define OFFSET(x) offsetof(WebVTTContext, x)
+#define KIND_FLAGS AV_OPT_FLAG_SUBTITLE_PARAM
+
+static const AVOption options[] = {
+ { "kind", "Set kind of WebVTT track", OFFSET(kind), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, KIND_FLAGS, "webvtt_kind" },
+ { "subtitles", "WebVTT subtitles kind", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { "captions", "WebVTT captions kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { "descriptions", "WebVTT descriptions kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { "metadata", "WebVTT metadata kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { NULL }
+};
+
+static const AVClass webvtt_demuxer_class = {
+ .class_name = "WebVTT demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_webvtt_demuxer = {
.name = "webvtt",
.long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
@@ -173,4 +219,5 @@ AVInputFormat ff_webvtt_demuxer = {
.read_seek2 = webvtt_read_seek,
.read_close = webvtt_read_close,
.extensions = "vtt",
+ .priv_class = &webvtt_demuxer_class,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/webvttenc.c b/chromium/third_party/ffmpeg/libavformat/webvttenc.c
new file mode 100644
index 00000000000..bd19a834546
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/webvttenc.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013 Matthew Heaney
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * WebVTT subtitle muxer
+ * @see http://dev.w3.org/html5/webvtt/
+ */
+
+#include "avformat.h"
+#include "internal.h"
+
+static void webvtt_write_time(AVIOContext *pb, int64_t millisec)
+{
+ int64_t sec, min, hour;
+ sec = millisec / 1000;
+ millisec -= 1000 * sec;
+ min = sec / 60;
+ sec -= 60 * min;
+ hour = min / 60;
+ min -= 60 * hour;
+
+ if (hour > 0)
+ avio_printf(pb, "%"PRId64":", hour);
+
+ avio_printf(pb, "%02"PRId64":%02"PRId64".%03"PRId64"", min, sec, millisec);
+}
+
+static int webvtt_write_header(AVFormatContext *ctx)
+{
+ AVStream *s = ctx->streams[0];
+ AVIOContext *pb = ctx->pb;
+
+ avpriv_set_pts_info(s, 64, 1, 1000);
+
+ avio_printf(pb, "WEBVTT\n");
+ avio_flush(pb);
+
+ return 0;
+}
+
+static int webvtt_write_packet(AVFormatContext *ctx, AVPacket *pkt)
+{
+ AVIOContext *pb = ctx->pb;
+ int id_size, settings_size;
+ uint8_t *id, *settings;
+
+ avio_printf(pb, "\n");
+
+ id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER,
+ &id_size);
+
+ if (id && id_size > 0)
+ avio_printf(pb, "%.*s\n", id_size, id);
+
+ webvtt_write_time(pb, pkt->pts);
+ avio_printf(pb, " --> ");
+ webvtt_write_time(pb, pkt->pts + pkt->duration);
+
+ settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
+ &settings_size);
+
+ if (settings && settings_size > 0)
+ avio_printf(pb, " %.*s", settings_size, settings);
+
+ avio_printf(pb, "\n");
+
+ avio_write(pb, pkt->data, pkt->size);
+ avio_printf(pb, "\n");
+
+ return 0;
+}
+
+AVOutputFormat ff_webvtt_muxer = {
+ .name = "webvtt",
+ .long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
+ .extensions = "vtt",
+ .mime_type = "text/vtt",
+ .subtitle_codec = AV_CODEC_ID_WEBVTT,
+ .write_header = webvtt_write_header,
+ .write_packet = webvtt_write_packet,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/westwood_aud.c b/chromium/third_party/ffmpeg/libavformat/westwood_aud.c
index d66611758be..f2bd3a130e1 100644
--- a/chromium/third_party/ffmpeg/libavformat/westwood_aud.c
+++ b/chromium/third_party/ffmpeg/libavformat/westwood_aud.c
@@ -77,7 +77,7 @@ static int wsaud_probe(AVProbeData *p)
return 0;
/* return 1/2 certainty since this file check is a little sketchy */
- return AVPROBE_SCORE_MAX / 2;
+ return AVPROBE_SCORE_EXTENSION;
}
static int wsaud_read_header(AVFormatContext *s)
diff --git a/chromium/third_party/ffmpeg/libavformat/westwood_vqa.c b/chromium/third_party/ffmpeg/libavformat/westwood_vqa.c
index c996dad8a25..d8791da1319 100644
--- a/chromium/third_party/ffmpeg/libavformat/westwood_vqa.c
+++ b/chromium/third_party/ffmpeg/libavformat/westwood_vqa.c
@@ -101,12 +101,13 @@ static int wsvqa_read_header(AVFormatContext *s)
avio_seek(pb, 20, SEEK_SET);
/* the VQA header needs to go to the decoder */
- st->codec->extradata_size = VQA_HEADER_SIZE;
st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata_size = VQA_HEADER_SIZE;
header = (unsigned char *)st->codec->extradata;
if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) !=
VQA_HEADER_SIZE) {
- av_free(st->codec->extradata);
return AVERROR(EIO);
}
st->codec->width = AV_RL16(&header[6]);
diff --git a/chromium/third_party/ffmpeg/libavformat/wtv.h b/chromium/third_party/ffmpeg/libavformat/wtv.h
index efe90d68466..51ac626115b 100644
--- a/chromium/third_party/ffmpeg/libavformat/wtv.h
+++ b/chromium/third_party/ffmpeg/libavformat/wtv.h
@@ -25,7 +25,7 @@
#include "riff.h"
#include "asf.h"
-#define WTV_SECTOR_BITS 12
+#define WTV_SECTOR_BITS INT64_C(12)
#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
#define WTV_BIGSECTOR_BITS 18
#define WTV_PAD8(x) (((x) + 7) & ~7)
diff --git a/chromium/third_party/ffmpeg/libavformat/wtvdec.c b/chromium/third_party/ffmpeg/libavformat/wtvdec.c
index e423370a9b8..551242d8a1f 100644
--- a/chromium/third_party/ffmpeg/libavformat/wtvdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/wtvdec.c
@@ -47,11 +47,11 @@
*/
typedef struct {
- AVIOContext *pb_filesystem; /** file system (AVFormatContext->pb) */
+ AVIOContext *pb_filesystem; /**< file system (AVFormatContext->pb) */
- int sector_bits; /** sector shift bits; used to convert sector number into pb_filesystem offset */
- uint32_t *sectors; /** file allocation table */
- int nb_sectors; /** number of sectors */
+ int sector_bits; /**< sector shift bits; used to convert sector number into pb_filesystem offset */
+ uint32_t *sectors; /**< file allocation table */
+ int nb_sectors; /**< number of sectors */
int error;
int64_t position;
@@ -88,7 +88,7 @@ static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
int i = wf->position >> wf->sector_bits;
if (i >= wf->nb_sectors ||
(wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
- avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
+ avio_seek(pb, wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
wf->error = 1;
break;
}
@@ -113,7 +113,7 @@ static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
offset = wf->length;
wf->error = offset < 0 || offset >= wf->length ||
- avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
+ avio_seek(pb, (wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
+ (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
wf->position = offset;
return offset;
@@ -183,7 +183,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
}
wf->nb_sectors = 0;
for (i = 0; i < nb_sectors1; i++) {
- if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ if (avio_seek(s->pb, sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
break;
wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
}
@@ -213,7 +213,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
/* seek to initial sector */
wf->position = 0;
- if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+ if (avio_seek(s->pb, wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
av_free(wf->sectors);
av_free(wf);
return NULL;
@@ -306,10 +306,10 @@ typedef struct {
} WtvStream;
typedef struct {
- AVIOContext *pb; /** timeline file */
+ AVIOContext *pb; /**< timeline file */
int64_t epoch;
- int64_t pts; /** pts for next data chunk */
- int64_t last_valid_pts; /** latest valid pts, used for interative seeking */
+ int64_t pts; /**< pts for next data chunk */
+ int64_t last_valid_pts; /**< latest valid pts, used for interative seeking */
/* maintain private seek index, as the AVIndexEntry->pos is relative to the
start of the 'timeline' file, not the file system (AVFormatContext->pb) */
@@ -436,6 +436,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
av_dict_set(&st->metadata, "title", description, 0);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = AV_CODEC_ID_MJPEG;
+ st->id = -1;
ret = av_get_packet(pb, &st->attached_pic, filesize);
if (ret < 0)
goto done;
diff --git a/chromium/third_party/ffmpeg/libavformat/wtvenc.c b/chromium/third_party/ffmpeg/libavformat/wtvenc.c
index 410a2dc355e..04e6cc22f8d 100644
--- a/chromium/third_party/ffmpeg/libavformat/wtvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/wtvenc.c
@@ -28,6 +28,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avassert.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "internal.h"
#include "wtv.h"
#include "asf.h"
@@ -87,10 +88,10 @@ typedef struct {
typedef struct {
int64_t timeline_start_pos;
WtvFile file[WTV_FILES];
- int64_t serial; /** chunk serial number */
- int64_t last_chunk_pos; /** last chunk position */
- int64_t last_timestamp_pos; /** last timestamp chunk position */
- int64_t first_index_pos; /** first index_chunk position */
+ int64_t serial; /**< chunk serial number */
+ int64_t last_chunk_pos; /**< last chunk position */
+ int64_t last_timestamp_pos; /**< last timestamp chunk position */
+ int64_t first_index_pos; /**< first index_chunk position */
WtvChunkEntry index[MAX_NB_INDEX];
int nb_index;
@@ -127,12 +128,7 @@ typedef struct {
WTVHeaderWriteFunc *write_header;
} WTVRootEntryTable;
-static int write_pad(AVIOContext *pb, int size)
-{
- for (; size > 0; size--)
- avio_w8(pb, 0);
- return 0;
-}
+#define write_pad(pb, size) ffio_fill(pb, 0, size)
static const ff_asf_guid *get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
{
diff --git a/chromium/third_party/ffmpeg/libavformat/wv.c b/chromium/third_party/ffmpeg/libavformat/wv.c
index 97a6c1f2e8d..0f4f80761ac 100644
--- a/chromium/third_party/ffmpeg/libavformat/wv.c
+++ b/chromium/third_party/ffmpeg/libavformat/wv.c
@@ -1,6 +1,5 @@
/*
- * WavPack demuxer
- * Copyright (c) 2006,2011 Konstantin Shishkov
+ * WavPack shared functions
*
* This file is part of FFmpeg.
*
@@ -19,379 +18,35 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/channel_layout.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/dict.h"
-#include "avformat.h"
-#include "internal.h"
-#include "apetag.h"
-#include "id3v1.h"
-
-// specs say that maximum block size is 1Mb
-#define WV_BLOCK_LIMIT 1047576
-
-#define WV_EXTRA_SIZE 12
-
-#define WV_START_BLOCK 0x0800
-#define WV_END_BLOCK 0x1000
-#define WV_SINGLE_BLOCK (WV_START_BLOCK | WV_END_BLOCK)
-
-enum WV_FLAGS {
- WV_MONO = 0x0004,
- WV_HYBRID = 0x0008,
- WV_JOINT = 0x0010,
- WV_CROSSD = 0x0020,
- WV_HSHAPE = 0x0040,
- WV_FLOAT = 0x0080,
- WV_INT32 = 0x0100,
- WV_HBR = 0x0200,
- WV_HBAL = 0x0400,
- WV_MCINIT = 0x0800,
- WV_MCEND = 0x1000,
-};
+#include <stdint.h>
+#include <string.h>
-static const int wv_rates[16] = {
- 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000, 192000, -1
-};
-
-typedef struct {
- uint32_t blksize, flags;
- int rate, chan, bpp;
- uint32_t chmask;
- uint32_t samples, soff;
- int multichannel;
- int block_parsed;
- uint8_t extra[WV_EXTRA_SIZE];
- int64_t pos;
-
- int64_t apetag_start;
-} WVContext;
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
-static int wv_probe(AVProbeData *p)
-{
- /* check file header */
- if (p->buf_size <= 32)
- return 0;
- if (p->buf[0] == 'w' && p->buf[1] == 'v' &&
- p->buf[2] == 'p' && p->buf[3] == 'k')
- return AVPROBE_SCORE_MAX;
- else
- return 0;
-}
+#include "wv.h"
-static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb,
- int append)
+int ff_wv_parse_header(WvHeader *wv, const uint8_t *data)
{
- WVContext *wc = ctx->priv_data;
- uint32_t tag, ver;
- int size;
- int rate, bpp, chan;
- uint32_t chmask;
-
- wc->pos = avio_tell(pb);
-
- /* don't return bogus packets with the ape tag data */
- if (wc->apetag_start && wc->pos >= wc->apetag_start)
- return AVERROR_EOF;
+ memset(wv, 0, sizeof(*wv));
- if (!append) {
- tag = avio_rl32(pb);
- if (tag != MKTAG('w', 'v', 'p', 'k'))
- return AVERROR_INVALIDDATA;
- size = avio_rl32(pb);
- if (size < 24 || size > WV_BLOCK_LIMIT) {
- av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
- return AVERROR_INVALIDDATA;
- }
- wc->blksize = size;
- ver = avio_rl16(pb);
- if (ver < 0x402 || ver > 0x410) {
- av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
- return AVERROR_PATCHWELCOME;
- }
- avio_r8(pb); // track no
- avio_r8(pb); // track sub index
- wc->samples = avio_rl32(pb); // total samples in file
- wc->soff = avio_rl32(pb); // offset in samples of current block
- avio_read(pb, wc->extra, WV_EXTRA_SIZE);
- } else {
- size = wc->blksize;
- }
- wc->flags = AV_RL32(wc->extra + 4);
- /* Blocks with zero samples don't contain actual audio information
- * and should be ignored */
- if (!AV_RN32(wc->extra))
- return 0;
- // parse flags
- bpp = ((wc->flags & 3) + 1) << 3;
- chan = 1 + !(wc->flags & WV_MONO);
- chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
- rate = wv_rates[(wc->flags >> 23) & 0xF];
- wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK);
- if (wc->multichannel) {
- chan = wc->chan;
- chmask = wc->chmask;
- }
- if ((rate == -1 || !chan) && !wc->block_parsed) {
- int64_t block_end = avio_tell(pb) + wc->blksize - 24;
- if (!pb->seekable) {
- av_log(ctx, AV_LOG_ERROR,
- "Cannot determine additional parameters\n");
- return AVERROR_INVALIDDATA;
- }
- while (avio_tell(pb) < block_end) {
- int id, size;
- id = avio_r8(pb);
- size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
- size <<= 1;
- if (id & 0x40)
- size--;
- switch (id & 0x3F) {
- case 0xD:
- if (size <= 1) {
- av_log(ctx, AV_LOG_ERROR,
- "Insufficient channel information\n");
- return AVERROR_INVALIDDATA;
- }
- chan = avio_r8(pb);
- switch (size - 2) {
- case 0:
- chmask = avio_r8(pb);
- break;
- case 1:
- chmask = avio_rl16(pb);
- break;
- case 2:
- chmask = avio_rl24(pb);
- break;
- case 3:
- chmask = avio_rl32(pb);
- break;
- case 5:
- avio_skip(pb, 1);
- chan |= (avio_r8(pb) & 0xF) << 8;
- chmask = avio_rl24(pb);
- break;
- default:
- av_log(ctx, AV_LOG_ERROR,
- "Invalid channel info size %d\n", size);
- return AVERROR_INVALIDDATA;
- }
- break;
- case 0x27:
- rate = avio_rl24(pb);
- break;
- default:
- avio_skip(pb, size);
- }
- if (id & 0x40)
- avio_skip(pb, 1);
- }
- if (rate == -1) {
- av_log(ctx, AV_LOG_ERROR,
- "Cannot determine custom sampling rate\n");
- return AVERROR_INVALIDDATA;
- }
- avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET);
- }
- if (!wc->bpp)
- wc->bpp = bpp;
- if (!wc->chan)
- wc->chan = chan;
- if (!wc->chmask)
- wc->chmask = chmask;
- if (!wc->rate)
- wc->rate = rate;
-
- if (wc->flags && bpp != wc->bpp) {
- av_log(ctx, AV_LOG_ERROR,
- "Bits per sample differ, this block: %i, header block: %i\n",
- bpp, wc->bpp);
- return AVERROR_INVALIDDATA;
- }
- if (wc->flags && !wc->multichannel && chan != wc->chan) {
- av_log(ctx, AV_LOG_ERROR,
- "Channels differ, this block: %i, header block: %i\n",
- chan, wc->chan);
+ if (AV_RL32(data) != MKTAG('w', 'v', 'p', 'k'))
return AVERROR_INVALIDDATA;
- }
- if (wc->flags && rate != -1 && rate != wc->rate) {
- av_log(ctx, AV_LOG_ERROR,
- "Sampling rate differ, this block: %i, header block: %i\n",
- rate, wc->rate);
- return AVERROR_INVALIDDATA;
- }
- wc->blksize = size - 24;
- return 0;
-}
-static int wv_read_header(AVFormatContext *s)
-{
- AVIOContext *pb = s->pb;
- WVContext *wc = s->priv_data;
- AVStream *st;
- int ret;
-
- wc->block_parsed = 0;
- for (;;) {
- if ((ret = wv_read_block_header(s, pb, 0)) < 0)
- return ret;
- if (!AV_RN32(wc->extra))
- avio_skip(pb, wc->blksize - 24);
- else
- break;
- }
-
- /* now we are ready: build format streams */
- st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = AV_CODEC_ID_WAVPACK;
- st->codec->channels = wc->chan;
- st->codec->channel_layout = wc->chmask;
- st->codec->sample_rate = wc->rate;
- st->codec->bits_per_coded_sample = wc->bpp;
- avpriv_set_pts_info(st, 64, 1, wc->rate);
- st->start_time = 0;
- if (wc->samples != 0xFFFFFFFFu)
- st->duration = wc->samples;
-
- if (s->pb->seekable) {
- int64_t cur = avio_tell(s->pb);
- wc->apetag_start = ff_ape_parse_tag(s);
- if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
- ff_id3v1_read(s);
- avio_seek(s->pb, cur, SEEK_SET);
- }
-
- return 0;
-}
-
-static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- WVContext *wc = s->priv_data;
- int ret;
- int size, ver, off;
- int64_t pos;
- uint32_t block_samples;
-
- if (url_feof(s->pb))
- return AVERROR_EOF;
- if (wc->block_parsed) {
- if ((ret = wv_read_block_header(s, s->pb, 0)) < 0)
- return ret;
- }
-
- pos = wc->pos;
- off = wc->multichannel ? 4 : 0;
- if (av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
- return AVERROR(ENOMEM);
- if (wc->multichannel)
- AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12);
- memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE);
- ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize);
- if (ret != wc->blksize) {
- av_free_packet(pkt);
- return AVERROR(EIO);
- }
- while (!(wc->flags & WV_END_BLOCK)) {
- if (avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')) {
- av_free_packet(pkt);
- return AVERROR_INVALIDDATA;
- }
- if ((ret = av_append_packet(s->pb, pkt, 4)) < 0) {
- av_free_packet(pkt);
- return ret;
- }
- size = AV_RL32(pkt->data + pkt->size - 4);
- if (size < 24 || size > WV_BLOCK_LIMIT) {
- av_free_packet(pkt);
- av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size);
- return AVERROR_INVALIDDATA;
- }
- wc->blksize = size;
- ver = avio_rl16(s->pb);
- if (ver < 0x402 || ver > 0x410) {
- av_free_packet(pkt);
- av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
- return AVERROR_PATCHWELCOME;
- }
- avio_r8(s->pb); // track no
- avio_r8(s->pb); // track sub index
- wc->samples = avio_rl32(s->pb); // total samples in file
- wc->soff = avio_rl32(s->pb); // offset in samples of current block
- if ((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0) {
- av_free_packet(pkt);
- return ret;
- }
- memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE);
-
- if ((ret = wv_read_block_header(s, s->pb, 1)) < 0) {
- av_free_packet(pkt);
- return ret;
- }
- ret = av_append_packet(s->pb, pkt, wc->blksize);
- if (ret < 0) {
- av_free_packet(pkt);
- return ret;
- }
- }
- pkt->stream_index = 0;
- wc->block_parsed = 1;
- pkt->pts = wc->soff;
- block_samples = AV_RL32(wc->extra);
- if (block_samples > INT32_MAX)
- av_log(s, AV_LOG_WARNING,
- "Too many samples in block: %"PRIu32"\n", block_samples);
- else
- pkt->duration = block_samples;
-
- av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
- return 0;
-}
+ wv->blocksize = AV_RL32(data + 4);
+ if (wv->blocksize < 24 || wv->blocksize > WV_BLOCK_LIMIT)
+ return AVERROR_INVALIDDATA;
+ wv->blocksize -= 24;
-static int wv_read_seek(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
-{
- AVStream *st = s->streams[stream_index];
- WVContext *wc = s->priv_data;
- AVPacket pkt1, *pkt = &pkt1;
- int ret;
- int index = av_index_search_timestamp(st, timestamp, flags);
- int64_t pos, pts;
+ wv->version = AV_RL16(data + 8);
+ wv->total_samples = AV_RL32(data + 12);
+ wv->block_idx = AV_RL32(data + 16);
+ wv->samples = AV_RL32(data + 20);
+ wv->flags = AV_RL32(data + 24);
+ wv->crc = AV_RL32(data + 28);
- /* if found, seek there */
- if (index >= 0 &&
- timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
- wc->block_parsed = 1;
- avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
- return 0;
- }
- /* if timestamp is out of bounds, return error */
- if (timestamp < 0 || timestamp >= s->duration)
- return AVERROR(EINVAL);
+ wv->initial = !!(wv->flags & WV_FLAG_INITIAL_BLOCK);
+ wv->final = !!(wv->flags & WV_FLAG_FINAL_BLOCK);
- pos = avio_tell(s->pb);
- do {
- ret = av_read_frame(s, pkt);
- if (ret < 0) {
- avio_seek(s->pb, pos, SEEK_SET);
- return ret;
- }
- pts = pkt->pts;
- av_free_packet(pkt);
- } while(pts < timestamp);
return 0;
}
-
-AVInputFormat ff_wv_demuxer = {
- .name = "wv",
- .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
- .priv_data_size = sizeof(WVContext),
- .read_probe = wv_probe,
- .read_header = wv_read_header,
- .read_packet = wv_read_packet,
- .read_seek = wv_read_seek,
-};
diff --git a/chromium/third_party/ffmpeg/libavformat/wv.h b/chromium/third_party/ffmpeg/libavformat/wv.h
new file mode 100644
index 00000000000..07d2e1bc0a8
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/wv.h
@@ -0,0 +1,56 @@
+/*
+ * WavPack shared functions
+ *
+ * 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_WV_H
+#define AVFORMAT_WV_H
+
+#include <stdint.h>
+
+#define WV_HEADER_SIZE 32
+
+#define WV_FLAG_INITIAL_BLOCK (1 << 11)
+#define WV_FLAG_FINAL_BLOCK (1 << 12)
+
+// specs say that maximum block size is 1Mb
+#define WV_BLOCK_LIMIT 1048576
+
+typedef struct WvHeader {
+ uint32_t blocksize; //< size of the block data (excluding the header)
+ uint16_t version; //< bitstream version
+ uint32_t total_samples; //< total number of samples in the stream
+ uint32_t block_idx; //< index of the first sample in this block
+ uint32_t samples; //< number of samples in this block
+ uint32_t flags;
+ uint32_t crc;
+
+ int initial, final;
+} WvHeader;
+
+/**
+ * Parse a WavPack block header.
+ *
+ * @param wv this struct will be filled with parse header information
+ * @param data header data, must be WV_HEADER_SIZE bytes long
+ *
+ * @return 0 on success, a negative AVERROR code on failure
+ */
+int ff_wv_parse_header(WvHeader *wv, const uint8_t *data);
+
+#endif /* AVFORMAT_WV_H */
diff --git a/chromium/third_party/ffmpeg/libavformat/wvdec.c b/chromium/third_party/ffmpeg/libavformat/wvdec.c
new file mode 100644
index 00000000000..4eaec402f71
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/wvdec.c
@@ -0,0 +1,354 @@
+/*
+ * WavPack demuxer
+ * Copyright (c) 2006,2011 Konstantin Shishkov
+ *
+ * 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/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
+#include "avformat.h"
+#include "internal.h"
+#include "apetag.h"
+#include "id3v1.h"
+#include "wv.h"
+
+enum WV_FLAGS {
+ WV_MONO = 0x0004,
+ WV_HYBRID = 0x0008,
+ WV_JOINT = 0x0010,
+ WV_CROSSD = 0x0020,
+ WV_HSHAPE = 0x0040,
+ WV_FLOAT = 0x0080,
+ WV_INT32 = 0x0100,
+ WV_HBR = 0x0200,
+ WV_HBAL = 0x0400,
+ WV_MCINIT = 0x0800,
+ WV_MCEND = 0x1000,
+};
+
+static const int wv_rates[16] = {
+ 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000,
+ 32000, 44100, 48000, 64000, 88200, 96000, 192000, -1
+};
+
+typedef struct {
+ uint8_t block_header[WV_HEADER_SIZE];
+ WvHeader header;
+ int rate, chan, bpp;
+ uint32_t chmask;
+ int multichannel;
+ int block_parsed;
+ int64_t pos;
+
+ int64_t apetag_start;
+} WVContext;
+
+static int wv_probe(AVProbeData *p)
+{
+ /* check file header */
+ if (p->buf_size <= 32)
+ return 0;
+ if (AV_RL32(&p->buf[0]) == MKTAG('w', 'v', 'p', 'k') &&
+ AV_RL32(&p->buf[4]) >= 24 &&
+ AV_RL32(&p->buf[4]) <= WV_BLOCK_LIMIT &&
+ AV_RL16(&p->buf[8]) >= 0x402 &&
+ AV_RL16(&p->buf[8]) <= 0x410)
+ return AVPROBE_SCORE_MAX;
+ else
+ return 0;
+}
+
+static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb)
+{
+ WVContext *wc = ctx->priv_data;
+ int ret;
+ int rate, bpp, chan;
+ uint32_t chmask, flags;
+
+ wc->pos = avio_tell(pb);
+
+ /* don't return bogus packets with the ape tag data */
+ if (wc->apetag_start && wc->pos >= wc->apetag_start)
+ return AVERROR_EOF;
+
+ ret = avio_read(pb, wc->block_header, WV_HEADER_SIZE);
+ if (ret != WV_HEADER_SIZE)
+ return (ret < 0) ? ret : AVERROR_EOF;
+
+ ret = ff_wv_parse_header(&wc->header, wc->block_header);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid block header.\n");
+ return ret;
+ }
+
+ if (wc->header.version < 0x402 || wc->header.version > 0x410) {
+ av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", wc->header.version);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /* Blocks with zero samples don't contain actual audio information
+ * and should be ignored */
+ if (!wc->header.samples)
+ return 0;
+ // parse flags
+ flags = wc->header.flags;
+ bpp = ((flags & 3) + 1) << 3;
+ chan = 1 + !(flags & WV_MONO);
+ chmask = flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+ rate = wv_rates[(flags >> 23) & 0xF];
+ wc->multichannel = !(wc->header.initial && wc->header.final);
+ if (wc->multichannel) {
+ chan = wc->chan;
+ chmask = wc->chmask;
+ }
+ if ((rate == -1 || !chan) && !wc->block_parsed) {
+ int64_t block_end = avio_tell(pb) + wc->header.blocksize;
+ if (!pb->seekable) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Cannot determine additional parameters\n");
+ return AVERROR_INVALIDDATA;
+ }
+ while (avio_tell(pb) < block_end) {
+ int id, size;
+ id = avio_r8(pb);
+ size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
+ size <<= 1;
+ if (id & 0x40)
+ size--;
+ switch (id & 0x3F) {
+ case 0xD:
+ if (size <= 1) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Insufficient channel information\n");
+ return AVERROR_INVALIDDATA;
+ }
+ chan = avio_r8(pb);
+ switch (size - 2) {
+ case 0:
+ chmask = avio_r8(pb);
+ break;
+ case 1:
+ chmask = avio_rl16(pb);
+ break;
+ case 2:
+ chmask = avio_rl24(pb);
+ break;
+ case 3:
+ chmask = avio_rl32(pb);
+ break;
+ case 5:
+ avio_skip(pb, 1);
+ chan |= (avio_r8(pb) & 0xF) << 8;
+ chmask = avio_rl24(pb);
+ break;
+ default:
+ av_log(ctx, AV_LOG_ERROR,
+ "Invalid channel info size %d\n", size);
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ case 0x27:
+ rate = avio_rl24(pb);
+ break;
+ default:
+ avio_skip(pb, size);
+ }
+ if (id & 0x40)
+ avio_skip(pb, 1);
+ }
+ if (rate == -1) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Cannot determine custom sampling rate\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avio_seek(pb, block_end - wc->header.blocksize, SEEK_SET);
+ }
+ if (!wc->bpp)
+ wc->bpp = bpp;
+ if (!wc->chan)
+ wc->chan = chan;
+ if (!wc->chmask)
+ wc->chmask = chmask;
+ if (!wc->rate)
+ wc->rate = rate;
+
+ if (flags && bpp != wc->bpp) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Bits per sample differ, this block: %i, header block: %i\n",
+ bpp, wc->bpp);
+ return AVERROR_INVALIDDATA;
+ }
+ if (flags && !wc->multichannel && chan != wc->chan) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Channels differ, this block: %i, header block: %i\n",
+ chan, wc->chan);
+ return AVERROR_INVALIDDATA;
+ }
+ if (flags && rate != -1 && rate != wc->rate) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Sampling rate differ, this block: %i, header block: %i\n",
+ rate, wc->rate);
+ return AVERROR_INVALIDDATA;
+ }
+ return 0;
+}
+
+static int wv_read_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ WVContext *wc = s->priv_data;
+ AVStream *st;
+ int ret;
+
+ wc->block_parsed = 0;
+ for (;;) {
+ if ((ret = wv_read_block_header(s, pb)) < 0)
+ return ret;
+ if (!wc->header.samples)
+ avio_skip(pb, wc->header.blocksize);
+ else
+ break;
+ }
+
+ /* now we are ready: build format streams */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = AV_CODEC_ID_WAVPACK;
+ st->codec->channels = wc->chan;
+ st->codec->channel_layout = wc->chmask;
+ st->codec->sample_rate = wc->rate;
+ st->codec->bits_per_coded_sample = wc->bpp;
+ avpriv_set_pts_info(st, 64, 1, wc->rate);
+ st->start_time = 0;
+ if (wc->header.total_samples != 0xFFFFFFFFu)
+ st->duration = wc->header.total_samples;
+
+ if (s->pb->seekable) {
+ int64_t cur = avio_tell(s->pb);
+ wc->apetag_start = ff_ape_parse_tag(s);
+ if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
+ ff_id3v1_read(s);
+ avio_seek(s->pb, cur, SEEK_SET);
+ }
+
+ return 0;
+}
+
+static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ WVContext *wc = s->priv_data;
+ int ret;
+ int off;
+ int64_t pos;
+ uint32_t block_samples;
+
+ if (url_feof(s->pb))
+ return AVERROR_EOF;
+ if (wc->block_parsed) {
+ if ((ret = wv_read_block_header(s, s->pb)) < 0)
+ return ret;
+ }
+
+ pos = wc->pos;
+ if (av_new_packet(pkt, wc->header.blocksize + WV_HEADER_SIZE) < 0)
+ return AVERROR(ENOMEM);
+ memcpy(pkt->data, wc->block_header, WV_HEADER_SIZE);
+ ret = avio_read(s->pb, pkt->data + WV_HEADER_SIZE, wc->header.blocksize);
+ if (ret != wc->header.blocksize) {
+ av_free_packet(pkt);
+ return AVERROR(EIO);
+ }
+ while (!(wc->header.flags & WV_FLAG_FINAL_BLOCK)) {
+ if ((ret = wv_read_block_header(s, s->pb)) < 0) {
+ av_free_packet(pkt);
+ return ret;
+ }
+
+ off = pkt->size;
+ if ((ret = av_grow_packet(pkt, WV_HEADER_SIZE + wc->header.blocksize)) < 0) {
+ av_free_packet(pkt);
+ return ret;
+ }
+ memcpy(pkt->data + off, wc->block_header, WV_HEADER_SIZE);
+
+ ret = avio_read(s->pb, pkt->data + off + WV_HEADER_SIZE, wc->header.blocksize);
+ if (ret != wc->header.blocksize) {
+ av_free_packet(pkt);
+ return (ret < 0) ? ret : AVERROR_EOF;
+ }
+ }
+ pkt->stream_index = 0;
+ wc->block_parsed = 1;
+ pkt->pts = wc->header.block_idx;
+ block_samples = wc->header.samples;
+ if (block_samples > INT32_MAX)
+ av_log(s, AV_LOG_WARNING,
+ "Too many samples in block: %"PRIu32"\n", block_samples);
+ else
+ pkt->duration = block_samples;
+
+ av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+ return 0;
+}
+
+static int wv_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ AVStream *st = s->streams[stream_index];
+ WVContext *wc = s->priv_data;
+ AVPacket pkt1, *pkt = &pkt1;
+ int ret;
+ int index = av_index_search_timestamp(st, timestamp, flags);
+ int64_t pos, pts;
+
+ /* if found, seek there */
+ if (index >= 0 &&
+ timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
+ wc->block_parsed = 1;
+ avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
+ return 0;
+ }
+ /* if timestamp is out of bounds, return error */
+ if (timestamp < 0 || timestamp >= s->duration)
+ return AVERROR(EINVAL);
+
+ pos = avio_tell(s->pb);
+ do {
+ ret = av_read_frame(s, pkt);
+ if (ret < 0) {
+ avio_seek(s->pb, pos, SEEK_SET);
+ return ret;
+ }
+ pts = pkt->pts;
+ av_free_packet(pkt);
+ } while(pts < timestamp);
+ return 0;
+}
+
+AVInputFormat ff_wv_demuxer = {
+ .name = "wv",
+ .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
+ .priv_data_size = sizeof(WVContext),
+ .read_probe = wv_probe,
+ .read_header = wv_read_header,
+ .read_packet = wv_read_packet,
+ .read_seek = wv_read_seek,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/wvenc.c b/chromium/third_party/ffmpeg/libavformat/wvenc.c
index c33d4309acf..b0d74caaec9 100644
--- a/chromium/third_party/ffmpeg/libavformat/wvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/wvenc.c
@@ -1,5 +1,6 @@
/*
* WavPack muxer
+ * Copyright (c) 2013 Konstantin Shishkov <kostya.shishkov@gmail.com>
* Copyright (c) 2012 Paul B Mahol
*
* This file is part of FFmpeg.
@@ -19,125 +20,72 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/intreadwrite.h"
-#include "avformat.h"
-#include "internal.h"
-#include "avio_internal.h"
-#include "apetag.h"
+#include "libavutil/attributes.h"
-#define WV_EXTRA_SIZE 12
-#define WV_END_BLOCK 0x1000
+#include "apetag.h"
+#include "avformat.h"
+#include "wv.h"
-typedef struct{
- uint32_t duration;
-} WVMuxContext;
+typedef struct WvMuxContext {
+ int64_t samples;
+} WvMuxContext;
-static int write_header(AVFormatContext *s)
+static av_cold int wv_write_header(AVFormatContext *ctx)
{
- AVCodecContext *codec = s->streams[0]->codec;
-
- if (s->nb_streams > 1) {
- av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
- return AVERROR(EINVAL);
- }
- if (codec->codec_id != AV_CODEC_ID_WAVPACK) {
- av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+ if (ctx->nb_streams > 1 ||
+ ctx->streams[0]->codec->codec_id != AV_CODEC_ID_WAVPACK) {
+ av_log(ctx, AV_LOG_ERROR, "This muxer only supports a single WavPack stream.\n");
return AVERROR(EINVAL);
}
- if (codec->extradata_size > 0) {
- avpriv_report_missing_feature(s, "remuxing from matroska container");
- return AVERROR_PATCHWELCOME;
- }
- avpriv_set_pts_info(s->streams[0], 64, 1, codec->sample_rate);
return 0;
}
-static int write_packet(AVFormatContext *s, AVPacket *pkt)
+static int wv_write_packet(AVFormatContext *ctx, AVPacket *pkt)
{
- WVMuxContext *wc = s->priv_data;
- AVCodecContext *codec = s->streams[0]->codec;
- AVIOContext *pb = s->pb;
- uint64_t size;
- uint32_t flags;
- uint32_t left = pkt->size;
- uint8_t *ptr = pkt->data;
- int off = codec->channels > 2 ? 4 : 0;
+ WvMuxContext *s = ctx->priv_data;
+ WvHeader header;
+ int ret;
- /* FIXME: Simplify decoder/demuxer so bellow code can support midstream
- * change of stream parameters */
- wc->duration += pkt->duration;
- ffio_wfourcc(pb, "wvpk");
- if (off) {
- size = AV_RL32(pkt->data);
- if (size <= 12)
- return AVERROR_INVALIDDATA;
- size -= 12;
- } else {
- size = pkt->size;
+ if (pkt->size < WV_HEADER_SIZE ||
+ (ret = ff_wv_parse_header(&header, pkt->data)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid WavPack packet.\n");
+ return AVERROR(EINVAL);
}
+ s->samples += header.samples;
- if (size + off > left)
- return AVERROR_INVALIDDATA;
-
- avio_wl32(pb, size + 12);
- avio_wl16(pb, 0x410);
- avio_w8(pb, 0);
- avio_w8(pb, 0);
- avio_wl32(pb, -1);
- avio_wl32(pb, pkt->pts);
- ptr += off; left -= off;
- flags = AV_RL32(ptr + 4);
- avio_write(pb, ptr, size);
- ptr += size; left -= size;
-
- while (!(flags & WV_END_BLOCK) &&
- (left >= 4 + WV_EXTRA_SIZE)) {
- ffio_wfourcc(pb, "wvpk");
- size = AV_RL32(ptr);
- ptr += 4; left -= 4;
- if (size < 24 || size - 24 > left)
- return AVERROR_INVALIDDATA;
- avio_wl32(pb, size);
- avio_wl16(pb, 0x410);
- avio_w8(pb, 0);
- avio_w8(pb, 0);
- avio_wl32(pb, -1);
- avio_wl32(pb, pkt->pts);
- flags = AV_RL32(ptr + 4);
- avio_write(pb, ptr, WV_EXTRA_SIZE);
- ptr += WV_EXTRA_SIZE; left -= WV_EXTRA_SIZE;
- avio_write(pb, ptr, size - 24);
- ptr += size - 24; left -= size - 24;
- }
+ avio_write(ctx->pb, pkt->data, pkt->size);
return 0;
}
-static int write_trailer(AVFormatContext *s)
+static av_cold int wv_write_trailer(AVFormatContext *ctx)
{
- WVMuxContext *wc = s->priv_data;
- AVIOContext *pb = s->pb;
-
- ff_ape_write(s);
-
- if (pb->seekable) {
- avio_seek(pb, 12, SEEK_SET);
- avio_wl32(pb, wc->duration);
- avio_flush(pb);
+ WvMuxContext *s = ctx->priv_data;
+
+ /* update total number of samples in the first block */
+ if (ctx->pb->seekable && s->samples &&
+ s->samples < UINT32_MAX) {
+ int64_t pos = avio_tell(ctx->pb);
+ avio_seek(ctx->pb, 12, SEEK_SET);
+ avio_wl32(ctx->pb, s->samples);
+ avio_seek(ctx->pb, pos, SEEK_SET);
}
+ ff_ape_write_tag(ctx);
return 0;
}
AVOutputFormat ff_wv_muxer = {
.name = "wv",
- .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
- .priv_data_size = sizeof(WVMuxContext),
+ .long_name = NULL_IF_CONFIG_SMALL("raw WavPack"),
+ .mime_type = "audio/x-wavpack",
.extensions = "wv",
+ .priv_data_size = sizeof(WvMuxContext),
.audio_codec = AV_CODEC_ID_WAVPACK,
.video_codec = AV_CODEC_ID_NONE,
- .write_header = write_header,
- .write_packet = write_packet,
- .write_trailer = write_trailer,
+ .write_header = wv_write_header,
+ .write_packet = wv_write_packet,
+ .write_trailer = wv_write_trailer,
+ .flags = AVFMT_NOTIMESTAMPS,
};
diff --git a/chromium/third_party/ffmpeg/libavformat/xa.c b/chromium/third_party/ffmpeg/libavformat/xa.c
index e3d36e61b5f..43661dea43c 100644
--- a/chromium/third_party/ffmpeg/libavformat/xa.c
+++ b/chromium/third_party/ffmpeg/libavformat/xa.c
@@ -59,7 +59,7 @@ static int xa_probe(AVProbeData *p)
if (!channels || channels > 8 || !srate || srate > 192000 ||
bits_per_sample < 4 || bits_per_sample > 32)
return 0;
- return AVPROBE_SCORE_MAX/2;
+ return AVPROBE_SCORE_EXTENSION;
}
static int xa_read_header(AVFormatContext *s)
@@ -84,6 +84,9 @@ static int xa_read_header(AVFormatContext *s)
avio_skip(pb, 2); /* Skip block align */
avio_skip(pb, 2); /* Skip bits-per-sample */
+ if (!st->codec->channels || !st->codec->sample_rate)
+ return AVERROR_INVALIDDATA;
+
st->codec->bit_rate = av_clip(15LL * st->codec->channels * 8 *
st->codec->sample_rate / 28, 0, INT_MAX);
diff --git a/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.c b/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.c
index bf48230bb3f..a6d83469ef2 100644
--- a/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.c
+++ b/chromium/third_party/ffmpeg/libavformat/yuv4mpeg.c
@@ -217,8 +217,8 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
// Adjust for smaller Cb and Cr planes
av_pix_fmt_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
&v_chroma_shift);
- width >>= h_chroma_shift;
- height >>= v_chroma_shift;
+ width = FF_CEIL_RSHIFT(width, h_chroma_shift);
+ height = FF_CEIL_RSHIFT(height, v_chroma_shift);
ptr1 = picture->data[1];
ptr2 = picture->data[2];