summaryrefslogtreecommitdiff
path: root/chromium/third_party/ffmpeg/libavformat
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-05 17:15:33 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-11 07:47:18 +0000
commit7324afb043a0b1e623d8e8eb906cdc53bdeb4685 (patch)
treea3fe2d74ea9c9e142c390dac4ca0e219382ace46 /chromium/third_party/ffmpeg/libavformat
parent6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (diff)
downloadqtwebengine-chromium-7324afb043a0b1e623d8e8eb906cdc53bdeb4685.tar.gz
BASELINE: Update Chromium to 58.0.3029.54
Change-Id: I67f57065a7afdc8e4614adb5c0230281428df4d1 Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat')
-rw-r--r--chromium/third_party/ffmpeg/libavformat/Makefile5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aadec.c23
-rw-r--r--chromium/third_party/ffmpeg/libavformat/allformats.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avformat.h3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avidec.c17
-rw-r--r--chromium/third_party/ffmpeg/libavformat/avio.h12
-rw-r--r--chromium/third_party/ffmpeg/libavformat/aviobuf.c17
-rw-r--r--chromium/third_party/ffmpeg/libavformat/caf.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/dss.c17
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flacdec.c3
-rw-r--r--chromium/third_party/ffmpeg/libavformat/flvenc.c16
-rw-r--r--chromium/third_party/ffmpeg/libavformat/hlsenc.c411
-rw-r--r--chromium/third_party/ffmpeg/libavformat/id3v2.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/img2dec.c7
-rw-r--r--chromium/third_party/ffmpeg/libavformat/isom.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/libopenmpt.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroska.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskadec.c14
-rw-r--r--chromium/third_party/ffmpeg/libavformat/matroskaenc.c45
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mov.c13
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegenc.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mpegtsenc.c30
-rw-r--r--chromium/third_party/ffmpeg/libavformat/mxf.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/omadec.c4
-rw-r--r--chromium/third_party/ffmpeg/libavformat/riff.c15
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rmdec.c1
-rw-r--r--chromium/third_party/ffmpeg/libavformat/rtmphttp.c2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/sdsdec.c165
-rw-r--r--chromium/third_party/ffmpeg/libavformat/segment.c5
-rw-r--r--chromium/third_party/ffmpeg/libavformat/tee.c87
-rw-r--r--chromium/third_party/ffmpeg/libavformat/version.h2
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wavdec.c17
32 files changed, 815 insertions, 134 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/Makefile b/chromium/third_party/ffmpeg/libavformat/Makefile
index 119e46bd8e2..f30bc94562d 100644
--- a/chromium/third_party/ffmpeg/libavformat/Makefile
+++ b/chromium/third_party/ffmpeg/libavformat/Makefile
@@ -83,7 +83,7 @@ OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o
OBJS-$(CONFIG_AFC_DEMUXER) += afc.o
OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o \
mov_chan.o
-OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o isom.o id3v2enc.o
+OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o id3v2enc.o
OBJS-$(CONFIG_AIX_DEMUXER) += aixdec.o
OBJS-$(CONFIG_AMR_DEMUXER) += amr.o
OBJS-$(CONFIG_AMR_MUXER) += amr.o
@@ -123,7 +123,7 @@ OBJS-$(CONFIG_BRSTM_DEMUXER) += brstm.o
OBJS-$(CONFIG_C93_DEMUXER) += c93.o voc_packet.o vocdec.o voc.o
OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \
replaygain.o
-OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o isom.o
+OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o
OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o
OBJS-$(CONFIG_CAVSVIDEO_MUXER) += rawenc.o
OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o
@@ -436,6 +436,7 @@ OBJS-$(CONFIG_SAP_MUXER) += sapenc.o
OBJS-$(CONFIG_SBG_DEMUXER) += sbgdec.o
OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o
OBJS-$(CONFIG_SDR2_DEMUXER) += sdr2.o
+OBJS-$(CONFIG_SDS_DEMUXER) += sdsdec.o
OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o
OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o
OBJS-$(CONFIG_SHORTEN_DEMUXER) += shortendec.o rawdec.o
diff --git a/chromium/third_party/ffmpeg/libavformat/aadec.c b/chromium/third_party/ffmpeg/libavformat/aadec.c
index cf5f3d107ad..39dea40b80b 100644
--- a/chromium/third_party/ffmpeg/libavformat/aadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/aadec.c
@@ -25,6 +25,7 @@
#include "avformat.h"
#include "internal.h"
+#include "libavutil/dict.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/tea.h"
#include "libavutil/opt.h"
@@ -101,25 +102,15 @@ static int aa_read_header(AVFormatContext *s)
avio_skip(pb, 1); // unidentified integer
nkey = avio_rb32(pb); // key string length
nval = avio_rb32(pb); // value string length
- if (nkey > sizeof(key)) {
- avio_skip(pb, nkey);
- } else {
- avio_read(pb, key, nkey); // key string
- }
- if (nval > sizeof(val)) {
- avio_skip(pb, nval);
- } else {
- avio_read(pb, val, nval); // value string
- }
+ avio_get_str(pb, nkey, key, sizeof(key));
+ avio_get_str(pb, nval, val, sizeof(val));
if (!strcmp(key, "codec")) {
av_log(s, AV_LOG_DEBUG, "Codec is <%s>\n", val);
strncpy(codec_name, val, sizeof(codec_name) - 1);
- }
- if (!strcmp(key, "HeaderSeed")) {
+ } else if (!strcmp(key, "HeaderSeed")) {
av_log(s, AV_LOG_DEBUG, "HeaderSeed is <%s>\n", val);
header_seed = atoi(val);
- }
- if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890"
+ } else if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890"
av_log(s, AV_LOG_DEBUG, "HeaderKey is <%s>\n", val);
sscanf(val, "%u%u%u%u", &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]);
for (idx = 0; idx < 4; idx++) {
@@ -129,6 +120,8 @@ static int aa_read_header(AVFormatContext *s)
for (i = 0; i < 16; i++)
av_log(s, AV_LOG_DEBUG, "%02x", header_key[i]);
av_log(s, AV_LOG_DEBUG, "\n");
+ } else {
+ av_dict_set(&s->metadata, key, val, 0);
}
}
@@ -184,11 +177,13 @@ static int aa_read_header(AVFormatContext *s)
st->codecpar->block_align = 19;
st->codecpar->channels = 1;
st->codecpar->sample_rate = 8500;
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
} else if (!strcmp(codec_name, "acelp16")) {
st->codecpar->codec_id = AV_CODEC_ID_SIPR;
st->codecpar->block_align = 20;
st->codecpar->channels = 1;
st->codecpar->sample_rate = 16000;
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
}
/* determine, and jump to audio start offset */
diff --git a/chromium/third_party/ffmpeg/libavformat/allformats.c b/chromium/third_party/ffmpeg/libavformat/allformats.c
index 6a79b75d78c..e30305b92b3 100644
--- a/chromium/third_party/ffmpeg/libavformat/allformats.c
+++ b/chromium/third_party/ffmpeg/libavformat/allformats.c
@@ -275,6 +275,7 @@ void av_register_all(void)
REGISTER_DEMUXER (SBG, sbg);
REGISTER_DEMUXER (SDP, sdp);
REGISTER_DEMUXER (SDR2, sdr2);
+ REGISTER_DEMUXER (SDS, sds);
#if CONFIG_RTPDEC
ff_register_rtp_dynamic_payload_handlers();
ff_register_rdt_dynamic_payload_handlers();
diff --git a/chromium/third_party/ffmpeg/libavformat/avformat.h b/chromium/third_party/ffmpeg/libavformat/avformat.h
index af257e43c4e..ebb0e05c042 100644
--- a/chromium/third_party/ffmpeg/libavformat/avformat.h
+++ b/chromium/third_party/ffmpeg/libavformat/avformat.h
@@ -930,6 +930,9 @@ typedef struct AVStream {
* Decoding: duration of the stream, in stream time base.
* If a source file does not specify a duration, but does specify
* a bitrate, this value will be estimated from bitrate and file size.
+ *
+ * Encoding: May be set by the caller before avformat_write_header() to
+ * provide a hint to the muxer about the estimated duration.
*/
int64_t duration;
diff --git a/chromium/third_party/ffmpeg/libavformat/avidec.c b/chromium/third_party/ffmpeg/libavformat/avidec.c
index d4659657c3a..abe8c988f16 100644
--- a/chromium/third_party/ffmpeg/libavformat/avidec.c
+++ b/chromium/third_party/ffmpeg/libavformat/avidec.c
@@ -160,11 +160,11 @@ static int get_riff(AVFormatContext *s, AVIOContext *pb)
return 0;
}
-static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
+static int read_odml_index(AVFormatContext *s, int frame_num)
{
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
- int longs_pre_entry = avio_rl16(pb);
+ int longs_per_entry = avio_rl16(pb);
int index_sub_type = avio_r8(pb);
int index_type = avio_r8(pb);
int entries_in_use = avio_rl32(pb);
@@ -179,9 +179,9 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
int64_t filesize = avi->fsize;
av_log(s, AV_LOG_TRACE,
- "longs_pre_entry:%d index_type:%d entries_in_use:%d "
+ "longs_per_entry:%d index_type:%d entries_in_use:%d "
"chunk_id:%X base:%16"PRIX64" frame_num:%d\n",
- longs_pre_entry,
+ longs_per_entry,
index_type,
entries_in_use,
chunk_id,
@@ -198,7 +198,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
avio_rl32(pb);
- if (index_type && longs_pre_entry != 2)
+ if (index_type && longs_per_entry != 2)
return AVERROR_INVALIDDATA;
if (index_type > 1)
return AVERROR_INVALIDDATA;
@@ -253,7 +253,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
return -1;
avi->odml_depth++;
- read_braindead_odml_indx(s, frame_num);
+ read_odml_index(s, frame_num);
avi->odml_depth--;
frame_num += duration;
@@ -950,7 +950,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
pos = avio_tell(pb);
if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
avi->use_odml &&
- read_braindead_odml_indx(s, 0) < 0 &&
+ read_odml_index(s, 0) < 0 &&
(s->error_recognition & AV_EF_EXPLODE))
goto fail;
avio_seek(pb, pos + size, SEEK_SET);
@@ -1211,7 +1211,8 @@ start_sync:
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')) {
+ (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1') ||
+ (d[0] == 'i' && d[1] == 'n' && d[2] == 'd' && d[3] == 'x')) {
avio_skip(pb, size);
goto start_sync;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/avio.h b/chromium/third_party/ffmpeg/libavformat/avio.h
index b1ce1d1c72e..e2cb4af7a27 100644
--- a/chromium/third_party/ffmpeg/libavformat/avio.h
+++ b/chromium/third_party/ffmpeg/libavformat/avio.h
@@ -704,6 +704,18 @@ int avio_closep(AVIOContext **s);
int avio_open_dyn_buf(AVIOContext **s);
/**
+ * Return the written size and a pointer to the buffer.
+ * The AVIOContext stream is left intact.
+ * The buffer must NOT be freed.
+ * No padding is added to the buffer.
+ *
+ * @param s IO context
+ * @param pbuffer pointer to a byte buffer
+ * @return the length of the byte buffer
+ */
+int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
+
+/**
* Return the written size and a pointer to the buffer. The buffer
* must be freed with av_free().
* Padding of AV_INPUT_BUFFER_PADDING_SIZE is added to the buffer.
diff --git a/chromium/third_party/ffmpeg/libavformat/aviobuf.c b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
index 134d627a6e0..bf7e5f85a00 100644
--- a/chromium/third_party/ffmpeg/libavformat/aviobuf.c
+++ b/chromium/third_party/ffmpeg/libavformat/aviobuf.c
@@ -1277,6 +1277,23 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
return url_open_dyn_buf_internal(s, max_packet_size);
}
+int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
+{
+ DynBuffer *d;
+
+ if (!s) {
+ *pbuffer = NULL;
+ return 0;
+ }
+
+ avio_flush(s);
+
+ d = s->opaque;
+ *pbuffer = d->buffer;
+
+ return d->size;
+}
+
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
{
DynBuffer *d;
diff --git a/chromium/third_party/ffmpeg/libavformat/caf.c b/chromium/third_party/ffmpeg/libavformat/caf.c
index c05fb8087c6..8d394157946 100644
--- a/chromium/third_party/ffmpeg/libavformat/caf.c
+++ b/chromium/third_party/ffmpeg/libavformat/caf.c
@@ -33,6 +33,7 @@
*/
const AVCodecTag ff_codec_caf_tags[] = {
{ AV_CODEC_ID_AAC, MKTAG('a','a','c',' ') },
+ { AV_CODEC_ID_AAC, MKTAG('a','a','c','l') },
{ AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
{ AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
{ AV_CODEC_ID_ADPCM_IMA_WAV, MKTAG('m','s', 0, 17 ) },
diff --git a/chromium/third_party/ffmpeg/libavformat/dss.c b/chromium/third_party/ffmpeg/libavformat/dss.c
index 2f7f20d1348..083eb4ad43b 100644
--- a/chromium/third_party/ffmpeg/libavformat/dss.c
+++ b/chromium/third_party/ffmpeg/libavformat/dss.c
@@ -42,7 +42,6 @@
#define DSS_COMMENT_SIZE 64
#define DSS_BLOCK_SIZE 512
-#define DSS_HEADER_SIZE (DSS_BLOCK_SIZE * 2)
#define DSS_AUDIO_BLOCK_HEADER_SIZE 6
#define DSS_FRAME_SIZE 42
@@ -56,11 +55,13 @@ typedef struct DSSDemuxContext {
int8_t *dss_sp_buf;
int packet_size;
+ int dss_header_size;
} DSSDemuxContext;
static int dss_probe(AVProbeData *p)
{
- if (AV_RL32(p->buf) != MKTAG(0x2, 'd', 's', 's'))
+ if ( AV_RL32(p->buf) != MKTAG(0x2, 'd', 's', 's')
+ && AV_RL32(p->buf) != MKTAG(0x3, 'd', 's', 's'))
return 0;
return AVPROBE_SCORE_MAX;
@@ -120,12 +121,15 @@ static int dss_read_header(AVFormatContext *s)
DSSDemuxContext *ctx = s->priv_data;
AVIOContext *pb = s->pb;
AVStream *st;
- int ret;
+ int ret, version;
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
+ version = avio_r8(pb);
+ ctx->dss_header_size = version * DSS_BLOCK_SIZE;
+
ret = dss_read_metadata_string(s, DSS_HEAD_OFFSET_AUTHOR,
DSS_AUTHOR_SIZE, "author");
if (ret)
@@ -164,7 +168,7 @@ static int dss_read_header(AVFormatContext *s)
/* Jump over header */
- if (avio_seek(pb, DSS_HEADER_SIZE, SEEK_SET) != DSS_HEADER_SIZE)
+ if (avio_seek(pb, ctx->dss_header_size, SEEK_SET) != ctx->dss_header_size)
return AVERROR(EIO);
ctx->counter = 0;
@@ -261,9 +265,6 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt)
goto error_eof;
}
- if (pkt->data[0] == 0xff)
- return AVERROR_INVALIDDATA;
-
return pkt->size;
error_eof:
@@ -361,7 +362,7 @@ static int dss_read_seek(AVFormatContext *s, int stream_index,
if (seekto < 0)
seekto = 0;
- seekto += DSS_HEADER_SIZE;
+ seekto += ctx->dss_header_size;
ret = avio_seek(s->pb, seekto, SEEK_SET);
if (ret < 0)
diff --git a/chromium/third_party/ffmpeg/libavformat/flacdec.c b/chromium/third_party/ffmpeg/libavformat/flacdec.c
index 3060dc45fd7..66baba59225 100644
--- a/chromium/third_party/ffmpeg/libavformat/flacdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/flacdec.c
@@ -65,7 +65,8 @@ static int flac_read_header(AVFormatContext *s)
/* process metadata blocks */
while (!avio_feof(s->pb) && !metadata_last) {
- avio_read(s->pb, header, 4);
+ if (avio_read(s->pb, header, 4) != 4)
+ return AVERROR(AVERROR_INVALIDDATA);
flac_parse_block_header(header, &metadata_last, &metadata_type,
&metadata_size);
switch (metadata_type) {
diff --git a/chromium/third_party/ffmpeg/libavformat/flvenc.c b/chromium/third_party/ffmpeg/libavformat/flvenc.c
index 62d406a0316..d7506c56fbe 100644
--- a/chromium/third_party/ffmpeg/libavformat/flvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/flvenc.c
@@ -626,13 +626,15 @@ static int shift_data(AVFormatContext *s)
avio_seek(read_pb, flv->keyframes_info_offset, SEEK_SET);
pos = avio_tell(read_pb);
- /* shift data by chunk of at most keyframe *filepositions* and *times* size */
+#define READ_BLOCK do { \
read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], metadata_size); \
- read_buf_id ^= 1;
- do {
+ read_buf_id ^= 1; \
+} while (0)
- read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], metadata_size); \
- read_buf_id ^= 1;
+ /* shift data by chunk of at most keyframe *filepositions* and *times* size */
+ READ_BLOCK;
+ do {
+ READ_BLOCK;
n = read_size[read_buf_id];
if (n < 0)
break;
@@ -890,6 +892,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
av_free(par->extradata);
par->extradata = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!par->extradata) {
+ par->extradata_size = 0;
+ return AVERROR(ENOMEM);
+ }
memcpy(par->extradata, side, side_size);
par->extradata_size = side_size;
flv_write_codec_header(s, par);
diff --git a/chromium/third_party/ffmpeg/libavformat/hlsenc.c b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
index acf3a301afc..bd1e684954e 100644
--- a/chromium/third_party/ffmpeg/libavformat/hlsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/hlsenc.c
@@ -39,8 +39,15 @@
#include "internal.h"
#include "os_support.h"
+typedef enum {
+ HLS_START_SEQUENCE_AS_START_NUMBER = 0,
+ HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH = 1,
+ HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2, // YYYYMMDDhhmmss
+} StartSequenceSourceType;
+
#define KEYSIZE 16
#define LINE_BUFFER_SIZE 1024
+#define HLS_MICROSECOND_UNIT 1000000
typedef struct HLSSegment {
char filename[1024];
@@ -66,6 +73,9 @@ typedef enum HLSFlags {
HLS_SPLIT_BY_TIME = (1 << 5),
HLS_APPEND_LIST = (1 << 6),
HLS_PROGRAM_DATE_TIME = (1 << 7),
+ HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime e.g.: %%03d
+ HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t
+ HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s
} HLSFlags;
typedef enum {
@@ -80,6 +90,7 @@ typedef struct HLSContext {
unsigned number;
int64_t sequence;
int64_t start_sequence;
+ uint32_t start_sequence_source_type; // enum StartSequenceSourceType
AVOutputFormat *oformat;
AVOutputFormat *vtt_oformat;
@@ -100,6 +111,8 @@ typedef struct HLSContext {
int64_t recording_time;
int has_video;
int has_subtitle;
+ int new_start;
+ double dpp; // duration per packet
int64_t start_pts;
int64_t end_pts;
double duration; // last segment duration computed so far, in seconds
@@ -133,8 +146,14 @@ typedef struct HLSContext {
char *method;
double initial_prog_date_time;
+ char current_segment_final_filename_fmt[1024]; // when renaming segments
} HLSContext;
+static int get_int_from_double(double val)
+{
+ return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
+}
+
static int mkdir_p(const char *path) {
int ret = 0;
char *temp = av_strdup(path);
@@ -168,6 +187,58 @@ static int mkdir_p(const char *path) {
return ret;
}
+static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number)
+{
+ const char *p;
+ char *q, buf1[20], c;
+ int nd, len, addchar_count;
+ int found_count = 0;
+
+ q = buf;
+ p = filename;
+ for (;;) {
+ c = *p;
+ if (c == '\0')
+ break;
+ if (c == '%' && *(p+1) == '%') // %%
+ addchar_count = 2;
+ else if (c == '%' && (av_isdigit(*(p+1)) || *(p+1) == placeholder)) {
+ nd = 0;
+ addchar_count = 1;
+ while (av_isdigit(*(p + addchar_count))) {
+ nd = nd * 10 + *(p + addchar_count) - '0';
+ addchar_count++;
+ }
+
+ if (*(p + addchar_count) == placeholder) {
+ len = snprintf(buf1, sizeof(buf1), "%0*"PRId64, (number < 0) ? nd : nd++, number);
+ if (len < 1) // returned error or empty buf1
+ goto fail;
+ if ((q - buf + len) > buf_size - 1)
+ goto fail;
+ memcpy(q, buf1, len);
+ q += len;
+ p += (addchar_count + 1);
+ addchar_count = 0;
+ found_count++;
+ }
+
+ } else
+ addchar_count = 1;
+
+ while (addchar_count--)
+ if ((q - buf) < buf_size - 1)
+ *q++ = *p++;
+ else
+ goto fail;
+ }
+ *q = '\0';
+ return found_count;
+fail:
+ *q = '\0';
+ return -1;
+}
+
static int hls_delete_old_segments(HLSContext *hls) {
HLSSegment *segment, *previous_segment = NULL;
@@ -175,6 +246,8 @@ static int hls_delete_old_segments(HLSContext *hls) {
int ret = 0, path_size, sub_path_size;
char *dirname = NULL, *p, *sub_path;
char *path = NULL;
+ AVDictionary *options = NULL;
+ AVIOContext *out = NULL;
segment = hls->segments;
while (segment) {
@@ -185,7 +258,6 @@ static int hls_delete_old_segments(HLSContext *hls) {
segment = hls->old_segments;
while (segment) {
playlist_duration -= segment->duration;
- hls->initial_prog_date_time += segment->duration;
previous_segment = segment;
segment = previous_segment->next;
if (playlist_duration <= -previous_segment->duration) {
@@ -194,7 +266,7 @@ static int hls_delete_old_segments(HLSContext *hls) {
}
}
- if (segment) {
+ if (segment && !hls->use_localtime_mkdir) {
if (hls->segment_filename) {
dirname = av_strdup(hls->segment_filename);
} else {
@@ -211,22 +283,32 @@ static int hls_delete_old_segments(HLSContext *hls) {
while (segment) {
av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n",
segment->filename);
- path_size = strlen(dirname) + strlen(segment->filename) + 1;
+ path_size = (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1;
path = av_malloc(path_size);
if (!path) {
ret = AVERROR(ENOMEM);
goto fail;
}
- av_strlcpy(path, dirname, path_size);
- av_strlcat(path, segment->filename, path_size);
- if (unlink(path) < 0) {
+ if (hls->use_localtime_mkdir)
+ av_strlcpy(path, segment->filename, path_size);
+ else { // segment->filename contains basename only
+ av_strlcpy(path, dirname, path_size);
+ av_strlcat(path, segment->filename, path_size);
+ }
+
+ if (hls->method) {
+ av_dict_set(&options, "method", "DELETE", 0);
+ if ((ret = hls->avf->io_open(hls->avf, &out, path, AVIO_FLAG_WRITE, &options)) < 0)
+ goto fail;
+ ff_format_io_close(hls->avf, &out);
+ } else if (unlink(path) < 0) {
av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
path, strerror(errno));
}
- if (segment->sub_filename[0] != '\0') {
- sub_path_size = strlen(dirname) + strlen(segment->sub_filename) + 1;
+ if ((segment->sub_filename[0] != '\0')) {
+ sub_path_size = strlen(segment->sub_filename) + 1 + (dirname ? strlen(dirname) : 0);
sub_path = av_malloc(sub_path_size);
if (!sub_path) {
ret = AVERROR(ENOMEM);
@@ -235,7 +317,15 @@ static int hls_delete_old_segments(HLSContext *hls) {
av_strlcpy(sub_path, dirname, sub_path_size);
av_strlcat(sub_path, segment->sub_filename, sub_path_size);
- if (unlink(sub_path) < 0) {
+
+ if (hls->method) {
+ av_dict_set(&options, "method", "DELETE", 0);
+ if ((ret = hls->avf->io_open(hls->avf, &out, sub_path, AVIO_FLAG_WRITE, &options)) < 0) {
+ av_free(sub_path);
+ goto fail;
+ }
+ ff_format_io_close(hls->avf, &out);
+ } else if (unlink(sub_path) < 0) {
av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
sub_path, strerror(errno));
}
@@ -358,10 +448,21 @@ static int hls_mux_init(AVFormatContext *s)
st->time_base = s->streams[i]->time_base;
}
hls->start_pos = 0;
+ hls->new_start = 1;
return 0;
}
+static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename)
+{
+ while (segment) {
+ if (!av_strcasecmp(segment->filename,filename))
+ return segment;
+ segment = segment->next;
+ }
+ return (HLSSegment *) NULL;
+}
+
/* Create a new segment and append it to the segment list */
static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration,
int64_t pos, int64_t size)
@@ -373,11 +474,57 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double
if (!en)
return AVERROR(ENOMEM);
+ if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
+ strlen(hls->current_segment_final_filename_fmt)) {
+ av_strlcpy(hls->avf->filename, hls->current_segment_final_filename_fmt, sizeof(hls->avf->filename));
+ if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
+ char * filename = av_strdup(hls->avf->filename); // %%s will be %s after strftime
+ if (!filename) {
+ av_free(en);
+ return AVERROR(ENOMEM);
+ }
+ if (replace_int_data_in_filename(hls->avf->filename, sizeof(hls->avf->filename),
+ filename, 's', pos + size) < 1) {
+ av_log(hls, AV_LOG_ERROR,
+ "Invalid second level segment filename template '%s', "
+ "you can try to remove second_level_segment_size flag\n",
+ filename);
+ av_free(filename);
+ av_free(en);
+ return AVERROR(EINVAL);
+ }
+ av_free(filename);
+ }
+ if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
+ char * filename = av_strdup(hls->avf->filename); // %%t will be %t after strftime
+ if (!filename) {
+ av_free(en);
+ return AVERROR(ENOMEM);
+ }
+ if (replace_int_data_in_filename(hls->avf->filename, sizeof(hls->avf->filename),
+ filename, 't', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
+ av_log(hls, AV_LOG_ERROR,
+ "Invalid second level segment filename template '%s', "
+ "you can try to remove second_level_segment_time flag\n",
+ filename);
+ av_free(filename);
+ av_free(en);
+ return AVERROR(EINVAL);
+ }
+ av_free(filename);
+ }
+ }
+
+
filename = av_basename(hls->avf->filename);
if (hls->use_localtime_mkdir) {
filename = hls->avf->filename;
}
+ if (find_segment_by_filename(hls->segments, filename)
+ || find_segment_by_filename(hls->old_segments, filename)) {
+ av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);
+ }
av_strlcpy(en->filename, filename, sizeof(en->filename));
if(hls->has_subtitle)
@@ -414,6 +561,7 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double
if (hls->max_nb_segments && hls->nb_entries >= hls->max_nb_segments) {
en = hls->segments;
+ hls->initial_prog_date_time += en->duration;
hls->segments = en->next;
if (en && hls->flags & HLS_DELETE_SEGMENTS &&
!(hls->flags & HLS_SINGLE_FILE || hls->wrap)) {
@@ -458,7 +606,16 @@ static int parse_playlist(AVFormatContext *s, const char *url)
while (!avio_feof(in)) {
read_chomp_line(in, line, sizeof(line));
if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
- hls->sequence = atoi(ptr);
+ int64_t tmp_sequence = strtoll(ptr, NULL, 10);
+ if (tmp_sequence < hls->sequence)
+ av_log(hls, AV_LOG_VERBOSE,
+ "Found playlist sequence number was smaller """
+ "than specified start sequence number: %"PRId64" < %"PRId64", "
+ "omitting\n", tmp_sequence, hls->start_sequence);
+ else {
+ av_log(hls, AV_LOG_DEBUG, "Found playlist sequence number: %"PRId64"\n", tmp_sequence);
+ hls->sequence = tmp_sequence;
+ }
} else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
is_segment = 1;
hls->discontinuity = 1;
@@ -503,6 +660,19 @@ static void set_http_options(AVDictionary **options, HLSContext *c)
av_dict_set(options, "method", c->method, 0);
}
+static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int version,
+ int target_duration, int64_t sequence)
+{
+ avio_printf(out, "#EXTM3U\n");
+ avio_printf(out, "#EXT-X-VERSION:%d\n", version);
+ if (hls->allowcache == 0 || hls->allowcache == 1) {
+ avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? "NO" : "YES");
+ }
+ avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
+ avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
+ av_log(hls, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
+}
+
static int hls_window(AVFormatContext *s, int last)
{
HLSContext *hls = s->priv_data;
@@ -537,26 +707,18 @@ static int hls_window(AVFormatContext *s, int last)
goto fail;
for (en = hls->segments; en; en = en->next) {
- if (target_duration < en->duration)
- target_duration = ceil(en->duration);
+ if (target_duration <= en->duration)
+ target_duration = get_int_from_double(en->duration);
}
hls->discontinuity_set = 0;
- avio_printf(out, "#EXTM3U\n");
- avio_printf(out, "#EXT-X-VERSION:%d\n", version);
- if (hls->allowcache == 0 || hls->allowcache == 1) {
- avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? "NO" : "YES");
- }
- avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
- avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
+ write_m3u8_head_block(hls, out, version, target_duration, sequence);
if (hls->pl_type == PLAYLIST_TYPE_EVENT) {
avio_printf(out, "#EXT-X-PLAYLIST-TYPE:EVENT\n");
} else if (hls->pl_type == PLAYLIST_TYPE_VOD) {
avio_printf(out, "#EXT-X-PLAYLIST-TYPE:VOD\n");
}
- av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n",
- sequence);
if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && hls->discontinuity_set==0 ){
avio_printf(out, "#EXT-X-DISCONTINUITY\n");
hls->discontinuity_set = 1;
@@ -618,16 +780,7 @@ static int hls_window(AVFormatContext *s, int last)
if( hls->vtt_m3u8_name ) {
if ((ret = s->io_open(s, &sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE, &options)) < 0)
goto fail;
- avio_printf(sub_out, "#EXTM3U\n");
- avio_printf(sub_out, "#EXT-X-VERSION:%d\n", version);
- if (hls->allowcache == 0 || hls->allowcache == 1) {
- avio_printf(sub_out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? "NO" : "YES");
- }
- avio_printf(sub_out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
- avio_printf(sub_out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
-
- av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n",
- sequence);
+ write_m3u8_head_block(hls, sub_out, version, target_duration, sequence);
for (en = hls->segments; en; en = en->next) {
avio_printf(sub_out, "#EXTINF:%f,\n", en->duration);
@@ -669,9 +822,8 @@ static int hls_start(AVFormatContext *s)
av_strlcpy(vtt_oc->filename, c->vtt_basename,
sizeof(vtt_oc->filename));
} else if (c->max_seg_size > 0) {
- if (av_get_frame_filename2(oc->filename, sizeof(oc->filename),
- c->basename, c->wrap ? c->sequence % c->wrap : c->sequence,
- AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
+ if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
+ c->basename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -use_localtime 1 with it\n", c->basename);
return AVERROR(EINVAL);
}
@@ -685,7 +837,53 @@ static int hls_start(AVFormatContext *s)
av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n");
return AVERROR(EINVAL);
}
-
+ if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
+ char * filename = av_strdup(oc->filename); // %%d will be %d after strftime
+ if (!filename)
+ return AVERROR(ENOMEM);
+ if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
+ filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
+ av_log(c, AV_LOG_ERROR,
+ "Invalid second level segment filename template '%s', "
+ "you can try to remove second_level_segment_index flag\n",
+ filename);
+ av_free(filename);
+ return AVERROR(EINVAL);
+ }
+ av_free(filename);
+ }
+ if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
+ av_strlcpy(c->current_segment_final_filename_fmt, oc->filename,
+ sizeof(c->current_segment_final_filename_fmt));
+ if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
+ char * filename = av_strdup(oc->filename); // %%s will be %s after strftime
+ if (!filename)
+ return AVERROR(ENOMEM);
+ if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) {
+ av_log(c, AV_LOG_ERROR,
+ "Invalid second level segment filename template '%s', "
+ "you can try to remove second_level_segment_size flag\n",
+ filename);
+ av_free(filename);
+ return AVERROR(EINVAL);
+ }
+ av_free(filename);
+ }
+ if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
+ char * filename = av_strdup(oc->filename); // %%t will be %t after strftime
+ if (!filename)
+ return AVERROR(ENOMEM);
+ if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) {
+ av_log(c, AV_LOG_ERROR,
+ "Invalid second level segment filename template '%s', "
+ "you can try to remove second_level_segment_time flag\n",
+ filename);
+ av_free(filename);
+ return AVERROR(EINVAL);
+ }
+ av_free(filename);
+ }
+ }
if (c->use_localtime_mkdir) {
const char *dir;
char *fn_copy = av_strdup(oc->filename);
@@ -700,16 +898,14 @@ static int hls_start(AVFormatContext *s)
}
av_free(fn_copy);
}
- } else if (av_get_frame_filename2(oc->filename, sizeof(oc->filename),
- c->basename, c->wrap ? c->sequence % c->wrap : c->sequence,
- AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
+ } else if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
+ c->basename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -use_localtime 1 with it\n", c->basename);
return AVERROR(EINVAL);
}
if( c->vtt_basename) {
- if (av_get_frame_filename2(vtt_oc->filename, sizeof(vtt_oc->filename),
- c->vtt_basename, c->wrap ? c->sequence % c->wrap : c->sequence,
- AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
+ if (replace_int_data_in_filename(vtt_oc->filename, sizeof(vtt_oc->filename),
+ c->vtt_basename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->vtt_basename);
return AVERROR(EINVAL);
}
@@ -775,21 +971,48 @@ fail:
return err;
}
+static const char * get_default_pattern_localtime_fmt(void)
+{
+ char b[21];
+ time_t t = time(NULL);
+ struct tm *p, tmbuf;
+ p = localtime_r(&t, &tmbuf);
+ // no %s support when strftime returned error or left format string unchanged
+ return (!strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts";
+}
+
static int hls_write_header(AVFormatContext *s)
{
HLSContext *hls = s->priv_data;
int ret, i;
char *p;
const char *pattern = "%d.ts";
- const char *pattern_localtime_fmt = "-%s.ts";
+ const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt();
const char *vtt_pattern = "%d.vtt";
AVDictionary *options = NULL;
int basename_size;
int vtt_basename_size;
+ if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH || hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
+ time_t t = time(NULL); // we will need it in either case
+ if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
+ hls->start_sequence = (int64_t)t;
+ } else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
+ char b[15];
+ struct tm *p, tmbuf;
+ if (!(p = localtime_r(&t, &tmbuf)))
+ return AVERROR(ENOMEM);
+ if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
+ return AVERROR(ENOMEM);
+ hls->start_sequence = strtoll(b, NULL, 10);
+ }
+ av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
+ }
+
hls->sequence = hls->start_sequence;
hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
hls->start_pts = AV_NOPTS_VALUE;
+ hls->current_segment_final_filename_fmt[0] = '\0';
if (hls->flags & HLS_PROGRAM_DATE_TIME) {
time_t now0;
@@ -864,7 +1087,42 @@ static int hls_write_header(AVFormatContext *s)
av_strlcat(hls->basename, pattern, basename_size);
}
}
-
+ if (!hls->use_localtime) {
+ if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
+ av_log(hls, AV_LOG_ERROR,
+ "second_level_segment_duration hls_flag requires use_localtime to be true\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
+ av_log(hls, AV_LOG_ERROR,
+ "second_level_segment_size hls_flag requires use_localtime to be true\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
+ av_log(hls, AV_LOG_ERROR,
+ "second_level_segment_index hls_flag requires use_localtime to be true\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ } else {
+ const char *proto = avio_find_protocol_name(hls->basename);
+ int segment_renaming_ok = proto && !strcmp(proto, "file");
+
+ if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
+ av_log(hls, AV_LOG_ERROR,
+ "second_level_segment_duration hls_flag works only with file protocol segment names\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
+ av_log(hls, AV_LOG_ERROR,
+ "second_level_segment_size hls_flag works only with file protocol segment names\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ }
if(hls->has_subtitle) {
if (hls->flags & HLS_SINGLE_FILE)
@@ -996,21 +1254,36 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
if (pkt->pts == AV_NOPTS_VALUE)
is_ref_pkt = can_split = 0;
- if (is_ref_pkt)
- hls->duration = (double)(pkt->pts - hls->end_pts)
- * st->time_base.num / st->time_base.den;
+ if (is_ref_pkt) {
+ if (hls->new_start) {
+ hls->new_start = 0;
+ hls->duration = (double)(pkt->pts - hls->end_pts)
+ * st->time_base.num / st->time_base.den;
+ hls->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;
+ } else {
+ hls->duration += (double)(pkt->duration) * 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) {
int64_t new_start_pos;
+ char *old_filename = av_strdup(hls->avf->filename);
+
+ if (!old_filename) {
+ return AVERROR(ENOMEM);
+ }
+
av_write_frame(oc, NULL); /* Flush any buffered data */
new_start_pos = avio_tell(hls->avf->pb);
hls->size = new_start_pos - hls->start_pos;
ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size);
hls->start_pos = new_start_pos;
- if (ret < 0)
+ if (ret < 0) {
+ av_free(old_filename);
return ret;
+ }
hls->end_pts = pkt->pts;
hls->duration = 0;
@@ -1025,6 +1298,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
if (hls->start_pos >= hls->max_seg_size) {
hls->sequence++;
ff_format_io_close(s, &oc->pb);
+ if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
+ strlen(hls->current_segment_final_filename_fmt)) {
+ ff_rename(old_filename, hls->avf->filename, hls);
+ }
if (hls->vtt_avf)
ff_format_io_close(s, &hls->vtt_avf->pb);
ret = hls_start(s);
@@ -1036,22 +1313,25 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
hls->number++;
} else {
ff_format_io_close(s, &oc->pb);
+ if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
+ strlen(hls->current_segment_final_filename_fmt)) {
+ ff_rename(old_filename, hls->avf->filename, hls);
+ }
if (hls->vtt_avf)
ff_format_io_close(s, &hls->vtt_avf->pb);
ret = hls_start(s);
}
- if (ret < 0)
+ if (ret < 0) {
+ av_free(old_filename);
return ret;
+ }
- if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE )
- oc = hls->vtt_avf;
- else
- oc = hls->avf;
-
- if ((ret = hls_window(s, 0)) < 0)
+ if ((ret = hls_window(s, 0)) < 0) {
+ av_free(old_filename);
return ret;
+ }
}
ret = ff_write_chained(oc, stream_index, pkt, s, 0);
@@ -1064,12 +1344,24 @@ static int hls_write_trailer(struct AVFormatContext *s)
HLSContext *hls = s->priv_data;
AVFormatContext *oc = hls->avf;
AVFormatContext *vtt_oc = hls->vtt_avf;
+ char *old_filename = av_strdup(hls->avf->filename);
+
+ if (!old_filename) {
+ return AVERROR(ENOMEM);
+ }
+
av_write_trailer(oc);
if (oc->pb) {
hls->size = avio_tell(hls->avf->pb) - hls->start_pos;
ff_format_io_close(s, &oc->pb);
- hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size);
+ /* after av_write_trailer, then duration + 1 duration per packet */
+ hls_append_segment(s, hls, hls->duration + hls->dpp, hls->start_pos, hls->size);
+ }
+
+ if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
+ strlen(hls->current_segment_final_filename_fmt)) {
+ ff_rename(old_filename, hls->avf->filename, hls);
}
if (vtt_oc) {
@@ -1092,6 +1384,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
hls_free_segments(hls->segments);
hls_free_segments(hls->old_segments);
+ av_free(old_filename);
return 0;
}
@@ -1120,13 +1413,19 @@ static const AVOption options[] = {
{"split_by_time", "split the hls segment by time which user set by hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX, E, "flags"},
{"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX, E, "flags"},
{"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX, E, "flags"},
+ {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, "flags"},
+ {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"},
+ {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"},
{"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" },
{"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
{"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
{"method", "set the HTTP method", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
-
+ {"hls_start_number_source", "set source of first number in sequence", OFFSET(start_sequence_source_type), AV_OPT_TYPE_INT, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, 0, HLS_START_SEQUENCE_AS_FORMATTED_DATETIME, E, "start_sequence_source_type" },
+ {"generic", "start_number value (default)", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
+ {"epoch", "seconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
+ {"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
{ NULL },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/id3v2.c b/chromium/third_party/ffmpeg/libavformat/id3v2.c
index 9969d7a6ca6..b3036d2f87e 100644
--- a/chromium/third_party/ffmpeg/libavformat/id3v2.c
+++ b/chromium/third_party/ffmpeg/libavformat/id3v2.c
@@ -688,9 +688,9 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const cha
}
if (decode_str(s, pb, 0, &dst, &len) < 0)
- return;
+ goto end;
if (len < 16)
- return;
+ goto end;
start = avio_rb32(pb);
end = avio_rb32(pb);
diff --git a/chromium/third_party/ffmpeg/libavformat/img2dec.c b/chromium/third_party/ffmpeg/libavformat/img2dec.c
index f1a0e7fa546..321189f38fa 100644
--- a/chromium/third_party/ffmpeg/libavformat/img2dec.c
+++ b/chromium/third_party/ffmpeg/libavformat/img2dec.c
@@ -755,6 +755,8 @@ static int jpeg_probe(AVProbeData *p)
if (state == EOI)
return AVPROBE_SCORE_EXTENSION + 1;
+ if (state == SOS)
+ return AVPROBE_SCORE_EXTENSION / 2 + 1;
return AVPROBE_SCORE_EXTENSION / 8;
}
@@ -847,10 +849,7 @@ static int psd_probe(AVProbeData *p)
if ((color_mode <= 9) && (color_mode != 5) && (color_mode != 6))
ret += 1;
- if (ret)
- return AVPROBE_SCORE_EXTENSION + ret;
-
- return 0;
+ return AVPROBE_SCORE_EXTENSION + ret;
}
static int sgi_probe(AVProbeData *p)
diff --git a/chromium/third_party/ffmpeg/libavformat/isom.c b/chromium/third_party/ffmpeg/libavformat/isom.c
index ae10cb7d3fd..13ceef0fb5d 100644
--- a/chromium/third_party/ffmpeg/libavformat/isom.c
+++ b/chromium/third_party/ffmpeg/libavformat/isom.c
@@ -296,6 +296,8 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '6') },
{ AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '7') },
+ { AV_CODEC_ID_PIXLET, MKTAG('p', 'x', 'l', 't') },
+
{ AV_CODEC_ID_NONE, 0 },
};
diff --git a/chromium/third_party/ffmpeg/libavformat/libopenmpt.c b/chromium/third_party/ffmpeg/libavformat/libopenmpt.c
index e7091ef9fc5..35fd28f5f4d 100644
--- a/chromium/third_party/ffmpeg/libavformat/libopenmpt.c
+++ b/chromium/third_party/ffmpeg/libavformat/libopenmpt.c
@@ -82,6 +82,11 @@ static int read_header_openmpt(AVFormatContext *s)
if (!buf)
return AVERROR(ENOMEM);
size = avio_read(s->pb, buf, size);
+ if (size < 0) {
+ av_log(s, AV_LOG_ERROR, "Reading input buffer failed.\n");
+ av_freep(&buf);
+ return size;
+ }
openmpt->module = openmpt_module_create_from_memory(buf, size, openmpt_logfunc, s, NULL);
av_freep(&buf);
diff --git a/chromium/third_party/ffmpeg/libavformat/matroska.c b/chromium/third_party/ffmpeg/libavformat/matroska.c
index f3e1be796df..c8e53416d34 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroska.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroska.c
@@ -35,7 +35,7 @@ const CodecTags ff_mkv_codec_tags[]={
{"A_FLAC" , AV_CODEC_ID_FLAC},
{"A_MLP" , AV_CODEC_ID_MLP},
{"A_MPEG/L2" , AV_CODEC_ID_MP2},
- {"A_MPEG/L1" , AV_CODEC_ID_MP2},
+ {"A_MPEG/L1" , AV_CODEC_ID_MP1},
{"A_MPEG/L3" , AV_CODEC_ID_MP3},
{"A_OPUS" , AV_CODEC_ID_OPUS},
{"A_OPUS/EXPERIMENTAL",AV_CODEC_ID_OPUS},
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskadec.c b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
index 908c86bb5dc..3bb8d4aee27 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskadec.c
@@ -93,6 +93,7 @@ typedef const struct EbmlSyntax {
int list_elem_size;
int data_offset;
union {
+ int64_t i;
uint64_t u;
double f;
const char *s;
@@ -700,7 +701,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_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock, discard_padding) },
- { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference) },
+ { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference), { .i = INT64_MIN } },
{ MATROSKA_ID_CODECSTATE, EBML_NONE },
{ 1, EBML_UINT, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } },
{ 0 }
@@ -1075,6 +1076,9 @@ static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
for (i = 0; syntax[i].id; i++)
switch (syntax[i].type) {
+ case EBML_SINT:
+ *(int64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.i;
+ break;
case EBML_UINT:
*(uint64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.u;
break;
@@ -3247,9 +3251,11 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE &&
timecode < track->end_timecode)
is_keyframe = 0; /* overlapping subtitles are not key frame */
- if (is_keyframe)
+ if (is_keyframe) {
+ ff_reduce_index(matroska->ctx, st->index);
av_add_index_entry(st, cluster_pos, timecode, 0, 0,
AVINDEX_KEYFRAME);
+ }
}
if (matroska->skip_to_keyframe &&
@@ -3378,7 +3384,7 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
matroska->current_cluster_num_blocks = blocks_list->nb_elem;
i = blocks_list->nb_elem - 1;
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
- int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+ int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
uint8_t* additional = blocks[i].additional.size > 0 ?
blocks[i].additional.data : NULL;
if (!blocks[i].non_simple)
@@ -3416,7 +3422,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
blocks = blocks_list->elem;
for (i = 0; i < blocks_list->nb_elem; i++)
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
- int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+ int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
res = matroska_parse_block(matroska, blocks[i].bin.data,
blocks[i].bin.size, blocks[i].bin.pos,
cluster.timecode, blocks[i].duration,
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
index 827d7550c2d..f731b678b9d 100644
--- a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c
@@ -367,6 +367,22 @@ static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, Matrosk
*dyn_cp = NULL;
}
+/**
+* Complete ebml master whithout destroying the buffer, allowing for later updates
+*/
+static void end_ebml_master_crc32_preliminary(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv,
+ ebml_master master)
+{
+ if (pb->seekable) {
+
+ uint8_t *buf;
+ int size = avio_get_dyn_buf(*dyn_cp, &buf);
+
+ avio_write(pb, buf, size);
+ end_ebml_master(pb, master);
+ }
+}
+
static void put_xiph_size(AVIOContext *pb, int size)
{
ffio_fill(pb, 255, size / 255);
@@ -1103,14 +1119,15 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
} 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 == par->codec_id) {
- put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
- native_id = 1;
- break;
+ if (par->codec_id != AV_CODEC_ID_RAWVIDEO || par->codec_tag) {
+ for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
+ if (ff_mkv_codec_tags[j].id == par->codec_id) {
+ put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
+ native_id = 1;
+ break;
+ }
}
- }
- if (par->codec_id == AV_CODEC_ID_RAWVIDEO && !par->codec_tag) {
+ } else {
if (mkv->allow_raw_vfw) {
native_id = 0;
} else {
@@ -1231,11 +1248,9 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
uint32_t color_space = av_le2ne32(par->codec_tag);
put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space));
}
- if (s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
- ret = mkv_write_video_color(pb, par, st);
- if (ret < 0)
- return ret;
- }
+ ret = mkv_write_video_color(pb, par, st);
+ if (ret < 0)
+ return ret;
end_ebml_master(pb, subinfo);
break;
@@ -1309,7 +1324,7 @@ static int mkv_write_tracks(AVFormatContext *s)
}
if (pb->seekable && !mkv->is_live)
- put_ebml_void(pb, avio_tell(mkv->tracks_bc));
+ end_ebml_master_crc32_preliminary(pb, &mkv->tracks_bc, mkv, mkv->tracks_master);
else
end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, mkv->tracks_master);
@@ -1554,7 +1569,7 @@ static int mkv_write_tags(AVFormatContext *s)
if (mkv->tags.pos) {
if (s->pb->seekable && !mkv->is_live)
- put_ebml_void(s->pb, avio_tell(mkv->tags_bc));
+ end_ebml_master_crc32_preliminary(s->pb, &mkv->tags_bc, mkv, mkv->tags);
else
end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, mkv->tags);
}
@@ -1811,7 +1826,7 @@ static int mkv_write_header(AVFormatContext *s)
}
}
if (s->pb->seekable && !mkv->is_live)
- put_ebml_void(s->pb, avio_tell(pb));
+ end_ebml_master_crc32_preliminary(s->pb, &mkv->info_bc, mkv, mkv->info);
else
end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv, mkv->info);
pb = s->pb;
diff --git a/chromium/third_party/ffmpeg/libavformat/mov.c b/chromium/third_party/ffmpeg/libavformat/mov.c
index 612e8da469a..7f3e7ac2a43 100644
--- a/chromium/third_party/ffmpeg/libavformat/mov.c
+++ b/chromium/third_party/ffmpeg/libavformat/mov.c
@@ -411,7 +411,7 @@ retry:
key = c->meta_keys[index];
} else {
av_log(c->fc, AV_LOG_WARNING,
- "The index of 'data' is out of range: %d >= %d.\n",
+ "The index of 'data' is out of range: %d < 1 or >= %d.\n",
index, c->meta_keys_count);
}
}
@@ -742,7 +742,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
title_size = atom.size - 24;
if (title_size > 0) {
- if (title_size >= UINT_MAX)
+ if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
return AVERROR_INVALIDDATA;
title_str = av_malloc(title_size + 1); /* Add null terminator */
if (!title_str)
@@ -4600,7 +4600,7 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
};
- if (atom.size < sizeof(uuid) || atom.size == INT64_MAX)
+ if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
return AVERROR_INVALIDDATA;
if (c->fc->nb_streams < 1)
@@ -4661,9 +4661,6 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
} else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
uint8_t *buffer;
size_t len = atom.size - sizeof(uuid);
- if (len >= UINT_MAX)
- return AVERROR_INVALIDDATA;
-
if (c->export_xmp) {
buffer = av_mallocz(len + 1);
if (!buffer) {
@@ -4782,7 +4779,7 @@ static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_rb32(pb); /* entries */
- if (atom.size < 8 || atom.size > UINT_MAX) {
+ if (atom.size < 8 || atom.size > FFMIN(INT_MAX, SIZE_MAX)) {
av_log(c->fc, AV_LOG_ERROR, "senc atom size %"PRId64" invalid\n", atom.size);
return AVERROR_INVALIDDATA;
}
@@ -4851,7 +4848,7 @@ static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
- if (atom.size > UINT_MAX) {
+ if (atom.size > FFMIN(INT_MAX, SIZE_MAX)) {
av_log(c->fc, AV_LOG_ERROR, "saiz atom auxiliary_info_sizes size %"PRId64" invalid\n", atom.size);
return AVERROR_INVALIDDATA;
}
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegenc.c b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
index 878fa6381f1..c77c3dfe414 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegenc.c
@@ -1146,6 +1146,8 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
stream->next_packet = &stream->premux_packet;
*stream->next_packet =
pkt_desc = av_mallocz(sizeof(PacketDesc));
+ if (!pkt_desc)
+ return AVERROR(ENOMEM);
pkt_desc->pts = pts;
pkt_desc->dts = dts;
pkt_desc->unwritten_size =
diff --git a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
index cdd7e37a1f5..0f394c5fe0e 100644
--- a/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/mpegtsenc.c
@@ -1619,9 +1619,39 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
}
}
} else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ const uint8_t *p = buf, *buf_end = p + size;
+ uint32_t state = -1;
+ int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0;
int ret = check_hevc_startcode(s, st, pkt);
if (ret < 0)
return ret;
+
+ if (extradd && AV_RB24(st->codecpar->extradata) > 1)
+ extradd = 0;
+
+ do {
+ p = avpriv_find_start_code(p, buf_end, &state);
+ av_log(s, AV_LOG_TRACE, "nal %d\n", (state & 0x7e)>>1);
+ if ((state & 0x7e) == 2*32)
+ extradd = 0;
+ } while (p < buf_end && (state & 0x7e) != 2*35 &&
+ (state & 0x7e) >= 2*32);
+
+ if ((state & 0x7e) < 2*16 && (state & 0x7e) >= 2*24)
+ extradd = 0;
+ if ((state & 0x7e) != 2*35) { // AUD NAL
+ data = av_malloc(pkt->size + 7 + extradd);
+ if (!data)
+ return AVERROR(ENOMEM);
+ memcpy(data + 7, st->codecpar->extradata, extradd);
+ memcpy(data + 7 + extradd, pkt->data, pkt->size);
+ AV_WB32(data, 0x00000001);
+ data[4] = 2*35;
+ data[5] = 1;
+ data[6] = 0x50; // any slice type (0x4) + rbsp stop one bit
+ buf = data;
+ size = pkt->size + 7 + extradd;
+ }
} else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
if (pkt->size < 2) {
av_log(s, AV_LOG_ERROR, "Opus packet too short\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/mxf.c b/chromium/third_party/ffmpeg/libavformat/mxf.c
index e9c48e8d7fd..bfc3218b815 100644
--- a/chromium/third_party/ffmpeg/libavformat/mxf.c
+++ b/chromium/third_party/ffmpeg/libavformat/mxf.c
@@ -61,6 +61,7 @@ const MXFCodecUL ff_mxf_codec_uls[] = {
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x31,0x11,0x01 }, 14, AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC SPS/PPS in-band */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x01 }, 16, AV_CODEC_ID_V210 }, /* V210 */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0E,0x04,0x02,0x01,0x02,0x11,0x00,0x00 }, 14, AV_CODEC_ID_PRORES }, /* Avid MC7 ProRes */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x03,0x06,0x00,0x00 }, 14, AV_CODEC_ID_PRORES }, /* Apple ProRes */
/* SoundEssenceCompression */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14, AV_CODEC_ID_AAC }, /* MPEG-2 AAC ADTS (legacy) */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16LE }, /* uncompressed */
diff --git a/chromium/third_party/ffmpeg/libavformat/omadec.c b/chromium/third_party/ffmpeg/libavformat/omadec.c
index 6e476dbf25b..757ae5371a9 100644
--- a/chromium/third_party/ffmpeg/libavformat/omadec.c
+++ b/chromium/third_party/ffmpeg/libavformat/omadec.c
@@ -365,7 +365,7 @@ static int oma_read_header(AVFormatContext *s)
st->codecpar->channels = 2;
st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
st->codecpar->sample_rate = samplerate;
- st->codecpar->bit_rate = st->codecpar->sample_rate * framesize * 8 / 1024;
+ st->codecpar->bit_rate = st->codecpar->sample_rate * framesize / (1024 / 8);
/* fake the ATRAC3 extradata
* (wav format, makes stream copy to wav work) */
@@ -398,7 +398,7 @@ static int oma_read_header(AVFormatContext *s)
return AVERROR_INVALIDDATA;
}
st->codecpar->sample_rate = samplerate;
- st->codecpar->bit_rate = samplerate * framesize * 8 / 2048;
+ st->codecpar->bit_rate = samplerate * framesize / (2048 / 8);
avpriv_set_pts_info(st, 64, 1, samplerate);
break;
case OMA_CODECID_MP3:
diff --git a/chromium/third_party/ffmpeg/libavformat/riff.c b/chromium/third_party/ffmpeg/libavformat/riff.c
index e4e394d6135..d44b908f8be 100644
--- a/chromium/third_party/ffmpeg/libavformat/riff.c
+++ b/chromium/third_party/ffmpeg/libavformat/riff.c
@@ -428,11 +428,26 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_M101, MKTAG('M', '1', '0', '1') },
{ AV_CODEC_ID_M101, MKTAG('M', '1', '0', '2') },
{ AV_CODEC_ID_MAGICYUV, MKTAG('M', 'A', 'G', 'Y') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'R', 'G') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'R', 'A') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'G', '0') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '0') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '2') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '4') },
+ { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', 'A') },
{ AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', 'A') },
{ AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', 'G') },
{ AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'G', '0') },
{ AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '2') },
{ AV_CODEC_ID_YLC, MKTAG('Y', 'L', 'C', '0') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '0') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '1') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '2') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '3') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '4') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '5') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '7') },
+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '9') },
{ AV_CODEC_ID_NONE, 0 }
};
diff --git a/chromium/third_party/ffmpeg/libavformat/rmdec.c b/chromium/third_party/ffmpeg/libavformat/rmdec.c
index 4d565291af2..c8035889390 100644
--- a/chromium/third_party/ffmpeg/libavformat/rmdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/rmdec.c
@@ -236,6 +236,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
return -1;
}
st->codecpar->block_align = ff_sipr_subpk_size[flavor];
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
} else {
if(sub_packet_size <= 0){
av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
diff --git a/chromium/third_party/ffmpeg/libavformat/rtmphttp.c b/chromium/third_party/ffmpeg/libavformat/rtmphttp.c
index e5ce10ca4f0..ef6146ca864 100644
--- a/chromium/third_party/ffmpeg/libavformat/rtmphttp.c
+++ b/chromium/third_party/ffmpeg/libavformat/rtmphttp.c
@@ -208,7 +208,7 @@ static int rtmp_http_open(URLContext *h, const char *uri, int flags)
}
/* alloc the http context */
- if ((ret = ffurl_alloc(&rt->stream, url, AVIO_FLAG_READ_WRITE, NULL)) < 0)
+ if ((ret = ffurl_alloc(&rt->stream, url, AVIO_FLAG_READ_WRITE, &h->interrupt_callback)) < 0)
goto fail;
/* set options */
diff --git a/chromium/third_party/ffmpeg/libavformat/sdsdec.c b/chromium/third_party/ffmpeg/libavformat/sdsdec.c
new file mode 100644
index 00000000000..081bb4ca2d8
--- /dev/null
+++ b/chromium/third_party/ffmpeg/libavformat/sdsdec.c
@@ -0,0 +1,165 @@
+/*
+ * MIDI Sample Dump Standard format demuxer
+ * Copyright (c) 2017 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/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct SDSContext {
+ uint8_t data[120];
+ int bit_depth;
+ int size;
+ void (*read_block)(const uint8_t *src, uint32_t *dst);
+} SDSContext;
+
+static int sds_probe(AVProbeData *p)
+{
+ if (AV_RB32(p->buf) == 0xF07E0001 && p->buf[20] == 0xF7 &&
+ p->buf[6] >= 8 && p->buf[6] <= 28)
+ return AVPROBE_SCORE_EXTENSION;
+ return 0;
+}
+
+static void byte2_read(const uint8_t *src, uint32_t *dst)
+{
+ int i;
+
+ for (i = 0; i < 120; i += 2) {
+ unsigned sample = (src[i + 0] << 25) + (src[i + 1] << 18);
+
+ dst[i / 2] = sample;
+ }
+}
+
+static void byte3_read(const uint8_t *src, uint32_t *dst)
+{
+ int i;
+
+ for (i = 0; i < 120; i += 3) {
+ unsigned sample;
+
+ sample = (src[i + 0] << 25) | (src[i + 1] << 18) | (src[i + 2] << 11);
+ dst[i / 3] = sample;
+ }
+}
+
+static void byte4_read(const uint8_t *src, uint32_t *dst)
+{
+ int i;
+
+ for (i = 0; i < 120; i += 4) {
+ unsigned sample;
+
+ sample = (src[i + 0] << 25) | (src[i + 1] << 18) | (src[i + 2] << 11) | (src[i + 3] << 4);
+ dst[i / 4] = sample;
+ }
+}
+
+#define SDS_3BYTE_TO_INT_DECODE(x) (((x) & 0x7F) | (((x) & 0x7F00) >> 1) | (((x) & 0x7F0000) >> 2))
+
+static int sds_read_header(AVFormatContext *ctx)
+{
+ SDSContext *s = ctx->priv_data;
+ unsigned sample_period;
+ AVIOContext *pb = ctx->pb;
+ AVStream *st;
+
+ st = avformat_new_stream(ctx, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ avio_skip(pb, 4);
+ avio_skip(pb, 2);
+
+ s->bit_depth = avio_r8(pb);
+ if (s->bit_depth < 8 || s->bit_depth > 28)
+ return AVERROR_INVALIDDATA;
+
+ if (s->bit_depth < 14) {
+ s->read_block = byte2_read;
+ s->size = 60 * 4;
+ } else if (s->bit_depth < 21) {
+ s->read_block = byte3_read;
+ s->size = 40 * 4;
+ } else {
+ s->read_block = byte4_read;
+ s->size = 30 * 4;
+ }
+ st->codecpar->codec_id = AV_CODEC_ID_PCM_U32LE;
+
+ sample_period = avio_rl24(pb);
+ sample_period = SDS_3BYTE_TO_INT_DECODE(sample_period);
+ avio_skip(pb, 11);
+
+ st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codecpar->channels = 1;
+ st->codecpar->sample_rate = sample_period ? 1000000000 / sample_period : 16000;
+ st->duration = (avio_size(pb) - 21) / (127) * s->size / 4;
+
+ avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
+
+ return 0;
+}
+
+static int sds_read_packet(AVFormatContext *ctx, AVPacket *pkt)
+{
+ SDSContext *s = ctx->priv_data;
+ AVIOContext *pb = ctx->pb;
+ int64_t pos;
+ int ret;
+
+ if (avio_feof(pb))
+ return AVERROR_EOF;
+
+ pos = avio_tell(pb);
+ if (avio_rb16(pb) != 0xF07E)
+ return AVERROR_INVALIDDATA;
+ avio_skip(pb, 3);
+
+ ret = av_new_packet(pkt, s->size);
+ if (ret < 0)
+ return ret;
+
+ ret = avio_read(pb, s->data, 120);
+
+ s->read_block(s->data, (uint32_t *)pkt->data);
+
+ avio_skip(pb, 1); // checksum
+ if (avio_r8(pb) != 0xF7)
+ return AVERROR_INVALIDDATA;
+
+ pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
+ pkt->stream_index = 0;
+ pkt->pos = pos;
+
+ return ret;
+}
+
+AVInputFormat ff_sds_demuxer = {
+ .name = "sds",
+ .long_name = NULL_IF_CONFIG_SMALL("MIDI Sample Dump Standard"),
+ .priv_data_size = sizeof(SDSContext),
+ .read_probe = sds_probe,
+ .read_header = sds_read_header,
+ .read_packet = sds_read_packet,
+ .extensions = "sds",
+ .flags = AVFMT_GENERIC_INDEX,
+};
diff --git a/chromium/third_party/ffmpeg/libavformat/segment.c b/chromium/third_party/ffmpeg/libavformat/segment.c
index 9b3dc178ebb..9d471483b38 100644
--- a/chromium/third_party/ffmpeg/libavformat/segment.c
+++ b/chromium/third_party/ffmpeg/libavformat/segment.c
@@ -354,6 +354,9 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
int i;
int err;
+ if (!oc || !oc->pb)
+ return AVERROR(EINVAL);
+
av_write_frame(oc, NULL); /* Flush any buffered data (fragmented mp4) */
if (write_trailer)
ret = av_write_trailer(oc);
@@ -850,7 +853,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
int64_t usecs;
int64_t wrapped_val;
- if (!seg->avf)
+ if (!seg->avf || !seg->avf->pb)
return AVERROR(EINVAL);
calc_times:
diff --git a/chromium/third_party/ffmpeg/libavformat/tee.c b/chromium/third_party/ffmpeg/libavformat/tee.c
index d59ad4d183b..dd1844ac0e1 100644
--- a/chromium/third_party/ffmpeg/libavformat/tee.c
+++ b/chromium/third_party/ffmpeg/libavformat/tee.c
@@ -40,6 +40,8 @@ typedef struct {
AVBSFContext **bsfs; ///< bitstream filters per stream
SlaveFailurePolicy on_fail;
+ int use_fifo;
+ AVDictionary *fifo_options;
/** map from input to output streams indexes,
* disabled output streams are set to -1 */
@@ -52,15 +54,28 @@ typedef struct TeeContext {
unsigned nb_slaves;
unsigned nb_alive;
TeeSlave *slaves;
+ int use_fifo;
+ AVDictionary *fifo_options;
+ char *fifo_options_str;
} TeeContext;
static const char *const slave_delim = "|";
static const char *const slave_bsfs_spec_sep = "/";
static const char *const slave_select_sep = ",";
+#define OFFSET(x) offsetof(TeeContext, x)
+static const AVOption options[] = {
+ {"use_fifo", "Use fifo pseudo-muxer to separate actual muxers from encoder",
+ OFFSET(use_fifo), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ {"fifo_options", "fifo pseudo-muxer options", OFFSET(fifo_options_str),
+ AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM},
+ {NULL}
+};
+
static const AVClass tee_muxer_class = {
.class_name = "Tee muxer",
.item_name = av_default_item_name,
+ .option = options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -81,6 +96,29 @@ static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *t
return AVERROR(EINVAL);
}
+static int parse_slave_fifo_options(const char *use_fifo,
+ const char *fifo_options, TeeSlave *tee_slave)
+{
+ int ret = 0;
+
+ if (use_fifo) {
+ /*TODO - change this to use proper function for parsing boolean
+ * options when there is one */
+ if (av_match_name(use_fifo, "true,y,yes,enable,enabled,on,1")) {
+ tee_slave->use_fifo = 1;
+ } else if (av_match_name(use_fifo, "false,n,no,disable,disabled,off,0")) {
+ tee_slave->use_fifo = 0;
+ } else {
+ return AVERROR(EINVAL);
+ }
+ }
+
+ if (fifo_options)
+ ret = av_dict_parse_string(&tee_slave->fifo_options, fifo_options, "=", ":", 0);
+
+ return ret;
+}
+
static int close_slave(TeeSlave *tee_slave)
{
AVFormatContext *avf;
@@ -125,6 +163,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
AVDictionaryEntry *entry;
char *filename;
char *format = NULL, *select = NULL, *on_fail = NULL;
+ char *use_fifo = NULL, *fifo_options_str = NULL;
AVFormatContext *avf2 = NULL;
AVStream *st, *st2;
int stream_count;
@@ -145,6 +184,8 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
STEAL_OPTION("f", format);
STEAL_OPTION("select", select);
STEAL_OPTION("onfail", on_fail);
+ STEAL_OPTION("use_fifo", use_fifo);
+ STEAL_OPTION("fifo_options", fifo_options_str);
ret = parse_slave_failure_policy_option(on_fail, tee_slave);
if (ret < 0) {
@@ -153,7 +194,39 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
goto end;
}
- ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
+ ret = parse_slave_fifo_options(use_fifo, fifo_options_str, tee_slave);
+ if (ret < 0) {
+ av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n", av_err2str(ret));
+ goto end;
+ }
+
+ if (tee_slave->use_fifo) {
+
+ if (options) {
+ char *format_options_str = NULL;
+ ret = av_dict_get_string(options, &format_options_str, '=', ':');
+ if (ret < 0)
+ goto end;
+
+ ret = av_dict_set(&tee_slave->fifo_options, "format_opts", format_options_str,
+ AV_DICT_DONT_STRDUP_VAL);
+ if (ret < 0)
+ goto end;
+ }
+
+ if (format) {
+ ret = av_dict_set(&tee_slave->fifo_options, "fifo_format", format,
+ AV_DICT_DONT_STRDUP_VAL);
+ format = NULL;
+ if (ret < 0)
+ goto end;
+ }
+
+ av_dict_free(&options);
+ options = tee_slave->fifo_options;
+ }
+ ret = avformat_alloc_output_context2(&avf2, NULL,
+ tee_slave->use_fifo ? "fifo" :format, filename);
if (ret < 0)
goto end;
tee_slave->avf = avf2;
@@ -394,6 +467,12 @@ static int tee_write_header(AVFormatContext *avf)
filename++;
}
+ if (tee->fifo_options_str) {
+ ret = av_dict_parse_string(&tee->fifo_options, tee->fifo_options_str, "=", ":", 0);
+ if (ret < 0)
+ goto fail;
+ }
+
if (!(tee->slaves = av_mallocz_array(nb_slaves, sizeof(*tee->slaves)))) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -401,6 +480,12 @@ static int tee_write_header(AVFormatContext *avf)
tee->nb_slaves = tee->nb_alive = nb_slaves;
for (i = 0; i < nb_slaves; i++) {
+
+ tee->slaves[i].use_fifo = tee->use_fifo;
+ ret = av_dict_copy(&tee->slaves[i].fifo_options, tee->fifo_options, 0);
+ if (ret < 0)
+ goto fail;
+
if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0) {
ret = tee_process_slave_failure(avf, i, ret);
if (ret < 0)
diff --git a/chromium/third_party/ffmpeg/libavformat/version.h b/chromium/third_party/ffmpeg/libavformat/version.h
index 65e6a4ccb7f..402e4c138c5 100644
--- a/chromium/third_party/ffmpeg/libavformat/version.h
+++ b/chromium/third_party/ffmpeg/libavformat/version.h
@@ -32,7 +32,7 @@
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
// Also please add any ticket numbers that you believe might be affected here
#define LIBAVFORMAT_VERSION_MAJOR 57
-#define LIBAVFORMAT_VERSION_MINOR 61
+#define LIBAVFORMAT_VERSION_MINOR 63
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
diff --git a/chromium/third_party/ffmpeg/libavformat/wavdec.c b/chromium/third_party/ffmpeg/libavformat/wavdec.c
index 69857ba5a2c..903d4f49fad 100644
--- a/chromium/third_party/ffmpeg/libavformat/wavdec.c
+++ b/chromium/third_party/ffmpeg/libavformat/wavdec.c
@@ -558,6 +558,22 @@ break_loop:
if (sample_count)
st->duration = sample_count;
+ if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S32LE &&
+ st->codecpar->block_align == st->codecpar->channels * 4 &&
+ st->codecpar->bits_per_coded_sample == 32 &&
+ st->codecpar->extradata_size == 2 &&
+ AV_RL16(st->codecpar->extradata) == 1) {
+ st->codecpar->codec_id = AV_CODEC_ID_PCM_F16LE;
+ st->codecpar->bits_per_coded_sample = 16;
+ } else if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE &&
+ st->codecpar->block_align == st->codecpar->channels * 4 &&
+ st->codecpar->bits_per_coded_sample == 24) {
+ st->codecpar->codec_id = AV_CODEC_ID_PCM_F24LE;
+ } else if (st->codecpar->codec_id == AV_CODEC_ID_XMA1 ||
+ st->codecpar->codec_id == AV_CODEC_ID_XMA2) {
+ st->codecpar->block_align = 2048;
+ }
+
ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
@@ -709,6 +725,7 @@ static int wav_read_seek(AVFormatContext *s,
case AV_CODEC_ID_MP3:
case AV_CODEC_ID_AC3:
case AV_CODEC_ID_DTS:
+ case AV_CODEC_ID_XMA2:
/* use generic seeking with dynamically generated indexes */
return -1;
default: