Commit 5d75e466 authored by Matthieu Bouron's avatar Matthieu Bouron

Merge commit 'db7968bf'

* commit 'db7968bf':
  avio: Allow custom IO users to get labels for the output bytestream
Merged-by: 's avatarMatthieu Bouron <matthieu.bouron@stupeflix.com>
parents 55816c92 db7968bf
......@@ -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().
......
......@@ -96,6 +96,42 @@ 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.
......@@ -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;
/**
......@@ -411,6 +465,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.
......
......@@ -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)
......
......@@ -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);
......
......@@ -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, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment