summaryrefslogtreecommitdiff
path: root/libavformat/aviobuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/aviobuf.c')
-rw-r--r--libavformat/aviobuf.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 29fccbea83..706cf5dd7f 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -140,6 +140,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;
}
@@ -163,13 +168,25 @@ AVIOContext *avio_alloc_context(
static void flush_buffer(AVIOContext *s)
{
if (s->buf_ptr > s->buffer) {
- if (s->write_packet && !s->error) {
- int ret = s->write_packet(s->opaque, 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->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->update_checksum) {
s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
s->buf_ptr - s->checksum_ptr);
@@ -402,6 +419,37 @@ void avio_wb24(AVIOContext *s, unsigned int val)
avio_w8(s, 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)