[FFmpeg-cvslog] Merge commit 'db7968bff4851c2be79b15b2cb2ae747424d2fca'
Matthieu Bouron
git at videolan.org
Thu Jun 23 17:40:50 CEST 2016
ffmpeg | branch: master | Matthieu Bouron <matthieu.bouron at stupeflix.com> | Thu Jun 23 15:27:00 2016 +0200| [5d75e4667742c851e21dcd6ce70154834fb7d22b] | committer: Matthieu Bouron
Merge commit 'db7968bff4851c2be79b15b2cb2ae747424d2fca'
* commit 'db7968bff4851c2be79b15b2cb2ae747424d2fca':
avio: Allow custom IO users to get labels for the output bytestream
Merged-by: Matthieu Bouron <matthieu.bouron at stupeflix.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5d75e4667742c851e21dcd6ce70154834fb7d22b
---
doc/APIchanges | 4 +++
libavformat/avio.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
libavformat/aviobuf.c | 52 ++++++++++++++++++++++++++++++++++++--
libavformat/mux.c | 9 ++++++-
libavformat/version.h | 2 +-
5 files changed, 129 insertions(+), 4 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index 5c7d21a..9ca71b7 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,10 @@ libavutil: 2015-08-28
API changes, most recent first:
+2016-xx-xx - xxxxxxx / db7968b - lavf 57.40.100 / 57.7.0 - avio.h
+ Add AVIODataMarkerType, write_data_type, ignore_boundary_point and
+ avio_write_marker.
+
2016-xx-xx - xxxxxxx / 0c4468d - lavu 55.26.100 / 55.12.0 - opt.h
Add av_stereo3d_type_name() and av_stereo3d_from_name().
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 5e86f7e..b1ce1d1 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -97,6 +97,42 @@ typedef struct AVIODirContext {
} AVIODirContext;
/**
+ * Different data types that can be returned via the AVIO
+ * write_data_type callback.
+ */
+enum AVIODataMarkerType {
+ /**
+ * Header data; this needs to be present for the stream to be decodeable.
+ */
+ AVIO_DATA_MARKER_HEADER,
+ /**
+ * A point in the output bytestream where a decoder can start decoding
+ * (i.e. a keyframe). A demuxer/decoder given the data flagged with
+ * AVIO_DATA_MARKER_HEADER, followed by any AVIO_DATA_MARKER_SYNC_POINT,
+ * should give decodeable results.
+ */
+ AVIO_DATA_MARKER_SYNC_POINT,
+ /**
+ * A point in the output bytestream where a demuxer can start parsing
+ * (for non self synchronizing bytestream formats). That is, any
+ * non-keyframe packet start point.
+ */
+ AVIO_DATA_MARKER_BOUNDARY_POINT,
+ /**
+ * This is any, unlabelled data. It can either be a muxer not marking
+ * any positions at all, it can be an actual boundary/sync point
+ * that the muxer chooses not to mark, or a later part of a packet/fragment
+ * that is cut into multiple write callbacks due to limited IO buffer size.
+ */
+ AVIO_DATA_MARKER_UNKNOWN,
+ /**
+ * Trailer data, which doesn't contain actual content, but only for
+ * finalizing the output file.
+ */
+ AVIO_DATA_MARKER_TRAILER
+};
+
+/**
* Bytestream IO Context.
* New fields can be added to the end with minor version bumps.
* Removal, reordering and changes to existing fields require a major
@@ -259,6 +295,24 @@ typedef struct AVIOContext {
* ',' separated list of disallowed protocols.
*/
const char *protocol_blacklist;
+
+ /**
+ * A callback that is used instead of write_packet.
+ */
+ int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,
+ enum AVIODataMarkerType type, int64_t time);
+ /**
+ * If set, don't call write_data_type separately for AVIO_DATA_MARKER_BOUNDARY_POINT,
+ * but ignore them and treat them as AVIO_DATA_MARKER_UNKNOWN (to avoid needlessly
+ * small chunks of data returned from the callback).
+ */
+ int ignore_boundary_point;
+
+ /**
+ * Internal, not meant to be used from outside of AVIOContext.
+ */
+ enum AVIODataMarkerType current_type;
+ int64_t last_time;
} AVIOContext;
/**
@@ -412,6 +466,18 @@ int avio_put_str16le(AVIOContext *s, const char *str);
int avio_put_str16be(AVIOContext *s, const char *str);
/**
+ * Mark the written bytestream as a specific type.
+ *
+ * Zero-length ranges are omitted from the output.
+ *
+ * @param time the stream time the current bytestream pos corresponds to
+ * (in AV_TIME_BASE units), or AV_NOPTS_VALUE if unknown or not
+ * applicable
+ * @param type the kind of data written starting at the current pos
+ */
+void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type);
+
+/**
* ORing this as the "whence" parameter to a seek function causes it to
* return the filesize without seeking anywhere. Supporting this is optional.
* If it is not supported then the seek function will return <0.
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index f02ae21..95793c9 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -115,6 +115,11 @@ int ffio_init_context(AVIOContext *s,
s->read_pause = NULL;
s->read_seek = NULL;
+ s->write_data_type = NULL;
+ s->ignore_boundary_point = 0;
+ s->current_type = AVIO_DATA_MARKER_UNKNOWN;
+ s->last_time = AV_NOPTS_VALUE;
+
return 0;
}
@@ -137,12 +142,24 @@ AVIOContext *avio_alloc_context(
static void writeout(AVIOContext *s, const uint8_t *data, int len)
{
- if (s->write_packet && !s->error) {
- int ret = s->write_packet(s->opaque, (uint8_t *)data, len);
+ if (!s->error) {
+ int ret = 0;
+ if (s->write_data_type)
+ ret = s->write_data_type(s->opaque, (uint8_t *)data,
+ len,
+ s->current_type,
+ s->last_time);
+ else if (s->write_packet)
+ ret = s->write_packet(s->opaque, (uint8_t *)data, len);
if (ret < 0) {
s->error = ret;
}
}
+ if (s->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
+ s->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
+ s->current_type = AVIO_DATA_MARKER_UNKNOWN;
+ }
+ s->last_time = AV_NOPTS_VALUE;
s->writeout_count ++;
s->pos += len;
}
@@ -450,6 +467,37 @@ void avio_wb24(AVIOContext *s, unsigned int val)
avio_w8(s, (uint8_t)val);
}
+void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
+{
+ if (!s->write_data_type)
+ return;
+ // If ignoring boundary points, just treat it as unknown
+ if (type == AVIO_DATA_MARKER_BOUNDARY_POINT && s->ignore_boundary_point)
+ type = AVIO_DATA_MARKER_UNKNOWN;
+ // Avoid unnecessary flushes if we are already in non-header/trailer
+ // data and setting the type to unknown
+ if (type == AVIO_DATA_MARKER_UNKNOWN &&
+ (s->current_type != AVIO_DATA_MARKER_HEADER &&
+ s->current_type != AVIO_DATA_MARKER_TRAILER))
+ return;
+
+ switch (type) {
+ case AVIO_DATA_MARKER_HEADER:
+ case AVIO_DATA_MARKER_TRAILER:
+ // For header/trailer, ignore a new marker of the same type;
+ // consecutive header/trailer markers can be merged.
+ if (type == s->current_type)
+ return;
+ break;
+ }
+
+ // If we've reached here, we have a new, noteworthy marker.
+ // Flush the previous data and mark the start of the new data.
+ avio_flush(s);
+ s->current_type = type;
+ s->last_time = time;
+}
+
/* Input stream */
static void fill_buffer(AVIOContext *s)
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 76db607..8488043 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -475,6 +475,8 @@ static int init_pts(AVFormatContext *s)
static int write_header_internal(AVFormatContext *s)
{
+ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+ avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);
if (s->oformat->write_header) {
int ret = s->oformat->write_header(s);
if (ret >= 0 && s->pb && s->pb->error < 0)
@@ -486,6 +488,8 @@ static int write_header_internal(AVFormatContext *s)
avio_flush(s->pb);
}
s->internal->header_written = 1;
+ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+ avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);
return 0;
}
@@ -1164,12 +1168,15 @@ int av_write_trailer(AVFormatContext *s)
}
fail:
- if (s->internal->header_written && s->oformat->write_trailer)
+ if (s->internal->header_written && s->oformat->write_trailer) {
+ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+ avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
if (ret >= 0) {
ret = s->oformat->write_trailer(s);
} else {
s->oformat->write_trailer(s);
}
+ }
if (s->oformat->deinit)
s->oformat->deinit(s);
diff --git a/libavformat/version.h b/libavformat/version.h
index 0293b48..543afbb 100644
--- a/libavformat/version.h
+++ b/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 belive might be affected here
#define LIBAVFORMAT_VERSION_MAJOR 57
-#define LIBAVFORMAT_VERSION_MINOR 39
+#define LIBAVFORMAT_VERSION_MINOR 40
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
======================================================================
diff --cc doc/APIchanges
index 5c7d21a,8f6cdca..9ca71b7
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@@ -15,17 -13,20 +15,21 @@@ libavutil: 2015-08-2
API changes, most recent first:
-2016-xx-xx - xxxxxxx - lavf 57.7.0 - avio.h
++2016-xx-xx - xxxxxxx / db7968b - lavf 57.40.100 / 57.7.0 - avio.h
+ Add AVIODataMarkerType, write_data_type, ignore_boundary_point and
+ avio_write_marker.
+
-2016-xx-xx - xxxxxxx - lavu 55.12.0 - opt.h
+2016-xx-xx - xxxxxxx / 0c4468d - lavu 55.26.100 / 55.12.0 - opt.h
Add av_stereo3d_type_name() and av_stereo3d_from_name().
-2016-xx-xx - xxxxxxx - lavu 55.11.0 - hwcontext_dxva2.h
+2016-06-22 - xxxxxxx - lavu 55.25.100 - hwcontext_dxva2.h
Add new installed header with DXVA2-specific hwcontext definitions.
-2016-xx-xx - xxxxxxx - lavu 55.10.0 - opt.h
- Add av_opt_copy().
+2016-04-27 - fb91871 - lavu 55.23.100 - log.h
+ Add a new function av_log_format_line2() which returns number of bytes
+ written to the target buffer.
-2016-xx-xx - xxxxxxx - lavc 57.16.0 - avcodec.h
+2016-04-21 - 7fc329e - lavc 57.37.100 - avcodec.h
Add a new audio/video encoding and decoding API with decoupled input
and output -- avcodec_send_packet(), avcodec_receive_frame(),
avcodec_send_frame() and avcodec_receive_packet().
diff --cc libavformat/avio.h
index 5e86f7e,4bd5cb1..b1ce1d1
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@@ -53,50 -54,42 +53,86 @@@ typedef struct AVIOInterruptCB
} AVIOInterruptCB;
/**
+ * Directory entry types.
+ */
+enum AVIODirEntryType {
+ AVIO_ENTRY_UNKNOWN,
+ AVIO_ENTRY_BLOCK_DEVICE,
+ AVIO_ENTRY_CHARACTER_DEVICE,
+ AVIO_ENTRY_DIRECTORY,
+ AVIO_ENTRY_NAMED_PIPE,
+ AVIO_ENTRY_SYMBOLIC_LINK,
+ AVIO_ENTRY_SOCKET,
+ AVIO_ENTRY_FILE,
+ AVIO_ENTRY_SERVER,
+ AVIO_ENTRY_SHARE,
+ AVIO_ENTRY_WORKGROUP,
+};
+
+/**
+ * Describes single entry of the directory.
+ *
+ * Only name and type fields are guaranteed be set.
+ * Rest of fields are protocol or/and platform dependent and might be unknown.
+ */
+typedef struct AVIODirEntry {
+ char *name; /**< Filename */
+ int type; /**< Type of the entry */
+ int utf8; /**< Set to 1 when name is encoded with UTF-8, 0 otherwise.
+ Name can be encoded with UTF-8 even though 0 is set. */
+ int64_t size; /**< File size in bytes, -1 if unknown. */
+ int64_t modification_timestamp; /**< Time of last modification in microseconds since unix
+ epoch, -1 if unknown. */
+ int64_t access_timestamp; /**< Time of last access in microseconds since unix epoch,
+ -1 if unknown. */
+ int64_t status_change_timestamp; /**< Time of last status change in microseconds since unix
+ epoch, -1 if unknown. */
+ int64_t user_id; /**< User ID of owner, -1 if unknown. */
+ int64_t group_id; /**< Group ID of owner, -1 if unknown. */
+ int64_t filemode; /**< Unix file mode, -1 if unknown. */
+} AVIODirEntry;
+
+typedef struct AVIODirContext {
+ struct URLContext *url_context;
+} AVIODirContext;
+
+/**
+ * Different data types that can be returned via the AVIO
+ * write_data_type callback.
+ */
+ enum AVIODataMarkerType {
+ /**
+ * Header data; this needs to be present for the stream to be decodeable.
+ */
+ AVIO_DATA_MARKER_HEADER,
+ /**
+ * A point in the output bytestream where a decoder can start decoding
+ * (i.e. a keyframe). A demuxer/decoder given the data flagged with
+ * AVIO_DATA_MARKER_HEADER, followed by any AVIO_DATA_MARKER_SYNC_POINT,
+ * should give decodeable results.
+ */
+ AVIO_DATA_MARKER_SYNC_POINT,
+ /**
+ * A point in the output bytestream where a demuxer can start parsing
+ * (for non self synchronizing bytestream formats). That is, any
+ * non-keyframe packet start point.
+ */
+ AVIO_DATA_MARKER_BOUNDARY_POINT,
+ /**
+ * This is any, unlabelled data. It can either be a muxer not marking
+ * any positions at all, it can be an actual boundary/sync point
+ * that the muxer chooses not to mark, or a later part of a packet/fragment
+ * that is cut into multiple write callbacks due to limited IO buffer size.
+ */
+ AVIO_DATA_MARKER_UNKNOWN,
+ /**
+ * Trailer data, which doesn't contain actual content, but only for
+ * finalizing the output file.
+ */
+ AVIO_DATA_MARKER_TRAILER
+ };
+
+ /**
* Bytestream IO Context.
* New fields can be added to the end with minor version bumps.
* Removal, reordering and changes to existing fields require a major
@@@ -207,58 -153,22 +243,76 @@@ typedef struct AVIOContext
int seekable;
/**
+ * max filesize, used to limit allocations
+ * This field is internal to libavformat and access from outside is not allowed.
+ */
+ int64_t maxsize;
+
+ /**
+ * avio_read and avio_write should if possible be satisfied directly
+ * instead of going through a buffer, and avio_seek will always
+ * call the underlying seek function directly.
+ */
+ int direct;
+
+ /**
+ * Bytes read statistic
+ * This field is internal to libavformat and access from outside is not allowed.
+ */
+ int64_t bytes_read;
+
+ /**
+ * seek statistic
+ * This field is internal to libavformat and access from outside is not allowed.
+ */
+ int seek_count;
+
+ /**
+ * writeout statistic
+ * This field is internal to libavformat and access from outside is not allowed.
+ */
+ int writeout_count;
+
+ /**
+ * Original buffer size
+ * used internally after probing and ensure seekback to reset the buffer size
+ * This field is internal to libavformat and access from outside is not allowed.
+ */
+ int orig_buffer_size;
+
+ /**
+ * Threshold to favor readahead over seek.
+ * This is current internal only, do not use from outside.
+ */
+ int short_seek_threshold;
+
+ /**
+ * ',' separated list of allowed protocols.
+ */
+ const char *protocol_whitelist;
+
+ /**
+ * ',' separated list of disallowed protocols.
+ */
+ const char *protocol_blacklist;
++
++ /**
+ * A callback that is used instead of write_packet.
+ */
+ int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,
+ enum AVIODataMarkerType type, int64_t time);
+ /**
+ * If set, don't call write_data_type separately for AVIO_DATA_MARKER_BOUNDARY_POINT,
+ * but ignore them and treat them as AVIO_DATA_MARKER_UNKNOWN (to avoid needlessly
+ * small chunks of data returned from the callback).
+ */
+ int ignore_boundary_point;
+
+ /**
+ * Internal, not meant to be used from outside of AVIOContext.
+ */
+ enum AVIODataMarkerType current_type;
+ int64_t last_time;
} AVIOContext;
/**
diff --cc libavformat/aviobuf.c
index f02ae21,706cf5d..95793c9
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@@ -135,22 -165,28 +140,34 @@@ AVIOContext *avio_alloc_context
return s;
}
-static void flush_buffer(AVIOContext *s)
+static void writeout(AVIOContext *s, const uint8_t *data, int len)
{
- if (s->write_packet && !s->error) {
- int ret = s->write_packet(s->opaque, (uint8_t *)data, len);
- if (s->buf_ptr > s->buffer) {
- if (!s->error) {
- int ret = 0;
- if (s->write_data_type)
- ret = s->write_data_type(s->opaque, s->buffer,
- s->buf_ptr - s->buffer,
- s->current_type,
- s->last_time);
- else if (s->write_packet)
- ret = s->write_packet(s->opaque, s->buffer,
- s->buf_ptr - s->buffer);
- if (ret < 0) {
- s->error = ret;
- }
++ if (!s->error) {
++ int ret = 0;
++ if (s->write_data_type)
++ ret = s->write_data_type(s->opaque, (uint8_t *)data,
++ len,
++ s->current_type,
++ s->last_time);
++ else if (s->write_packet)
++ ret = s->write_packet(s->opaque, (uint8_t *)data, len);
+ if (ret < 0) {
+ s->error = ret;
}
- if (s->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
- s->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
- s->current_type = AVIO_DATA_MARKER_UNKNOWN;
- }
- s->last_time = AV_NOPTS_VALUE;
+ }
++ if (s->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
++ s->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
++ s->current_type = AVIO_DATA_MARKER_UNKNOWN;
++ }
++ s->last_time = AV_NOPTS_VALUE;
+ s->writeout_count ++;
+ s->pos += len;
+}
+
+static void flush_buffer(AVIOContext *s)
+{
+ if (s->write_flag && s->buf_ptr > s->buffer) {
+ writeout(s, s->buffer, s->buf_ptr - s->buffer);
if (s->update_checksum) {
s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
s->buf_ptr - s->checksum_ptr);
@@@ -446,10 -415,41 +463,41 @@@ void avio_wl24(AVIOContext *s, unsigne
void avio_wb24(AVIOContext *s, unsigned int val)
{
- avio_wb16(s, val >> 8);
- avio_w8(s, val);
+ avio_wb16(s, (int)val >> 8);
+ avio_w8(s, (uint8_t)val);
}
+ void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
+ {
+ if (!s->write_data_type)
+ return;
+ // If ignoring boundary points, just treat it as unknown
+ if (type == AVIO_DATA_MARKER_BOUNDARY_POINT && s->ignore_boundary_point)
+ type = AVIO_DATA_MARKER_UNKNOWN;
+ // Avoid unnecessary flushes if we are already in non-header/trailer
+ // data and setting the type to unknown
+ if (type == AVIO_DATA_MARKER_UNKNOWN &&
+ (s->current_type != AVIO_DATA_MARKER_HEADER &&
+ s->current_type != AVIO_DATA_MARKER_TRAILER))
+ return;
+
+ switch (type) {
+ case AVIO_DATA_MARKER_HEADER:
+ case AVIO_DATA_MARKER_TRAILER:
+ // For header/trailer, ignore a new marker of the same type;
+ // consecutive header/trailer markers can be merged.
+ if (type == s->current_type)
+ return;
+ break;
+ }
+
+ // If we've reached here, we have a new, noteworthy marker.
+ // Flush the previous data and mark the start of the new data.
+ avio_flush(s);
+ s->current_type = type;
+ s->last_time = time;
+ }
+
/* Input stream */
static void fill_buffer(AVIOContext *s)
diff --cc libavformat/mux.c
index 76db607,49fe65c..8488043
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@@ -436,77 -249,24 +436,81 @@@ fail
return ret;
}
-int avformat_write_header(AVFormatContext *s, AVDictionary **options)
+static int init_pts(AVFormatContext *s)
{
- int ret = 0;
+ int i;
+ AVStream *st;
- if (ret = init_muxer(s, options))
- return ret;
+ /* init PTS generation */
+ for (i = 0; i < s->nb_streams; i++) {
+ int64_t den = AV_NOPTS_VALUE;
+ st = s->streams[i];
+
+ switch (st->codecpar->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ den = (int64_t)st->time_base.num * st->codecpar->sample_rate;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ den = (int64_t)st->time_base.num * st->time_base.den;
+ break;
+ default:
+ break;
+ }
+
+ if (!st->priv_pts)
+ st->priv_pts = av_mallocz(sizeof(*st->priv_pts));
+ if (!st->priv_pts)
+ return AVERROR(ENOMEM);
+
+ if (den != AV_NOPTS_VALUE) {
+ if (den <= 0)
+ return AVERROR_INVALIDDATA;
+ frac_init(st->priv_pts, 0, 0, den);
+ }
+ }
+
+ return 0;
+}
+
+static int write_header_internal(AVFormatContext *s)
+{
+ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+ avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);
if (s->oformat->write_header) {
- ret = s->oformat->write_header(s);
+ int ret = s->oformat->write_header(s);
+ if (ret >= 0 && s->pb && s->pb->error < 0)
+ ret = s->pb->error;
+ s->internal->write_header_ret = ret;
if (ret < 0)
return ret;
+ if (s->flush_packets && s->pb && s->pb->error >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
+ avio_flush(s->pb);
}
+ s->internal->header_written = 1;
+ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+ avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);
+ return 0;
+}
+
+int avformat_write_header(AVFormatContext *s, AVDictionary **options)
+{
+ int ret = 0;
+
+ if ((ret = init_muxer(s, options)) < 0)
+ return ret;
+
+ if (!s->oformat->check_bitstream) {
+ ret = write_header_internal(s);
+ if (ret < 0)
+ goto fail;
+ }
- if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO) {
+ if ((ret = init_pts(s)) < 0)
+ goto fail;
+
+ if (s->avoid_negative_ts < 0) {
+ av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
s->avoid_negative_ts = 0;
} else
@@@ -1153,31 -706,17 +1157,34 @@@ int av_write_trailer(AVFormatContext *s
if (ret < 0)
goto fail;
+ if(s->pb && s->pb->error)
+ goto fail;
}
- if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
- avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
- if (s->oformat->write_trailer)
+ if (!s->internal->header_written) {
+ ret = s->internal->write_header_ret ? s->internal->write_header_ret : write_header_internal(s);
+ if (ret < 0)
+ goto fail;
+ }
+
+fail:
- if (s->internal->header_written && s->oformat->write_trailer)
++ if (s->internal->header_written && s->oformat->write_trailer) {
++ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
++ avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
+ if (ret >= 0) {
ret = s->oformat->write_trailer(s);
+ } else {
+ s->oformat->write_trailer(s);
+ }
++ }
- if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
- avio_flush(s->pb);
+ if (s->oformat->deinit)
+ s->oformat->deinit(s);
-fail:
+ if (s->pb)
+ avio_flush(s->pb);
+ if (ret == 0)
+ ret = s->pb ? s->pb->error : 0;
for (i = 0; i < s->nb_streams; i++) {
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
diff --cc libavformat/version.h
index 0293b48,b2a1e05..543afbb
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@@ -29,11 -29,9 +29,11 @@@
#include "libavutil/version.h"
-#define LIBAVFORMAT_VERSION_MAJOR 57
-#define LIBAVFORMAT_VERSION_MINOR 7
-#define LIBAVFORMAT_VERSION_MICRO 0
+// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
+// Also please add any ticket numbers that you belive might be affected here
+#define LIBAVFORMAT_VERSION_MAJOR 57
- #define LIBAVFORMAT_VERSION_MINOR 39
++#define LIBAVFORMAT_VERSION_MINOR 40
+#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
More information about the ffmpeg-cvslog
mailing list