summaryrefslogtreecommitdiff
path: root/libavformat/matroskaenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/matroskaenc.c')
-rw-r--r--libavformat/matroskaenc.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index baf851f481..9bbec1c027 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -158,6 +158,8 @@ typedef struct mkv_cues {
int num_entries;
} mkv_cues;
+struct MatroskaMuxContext;
+
typedef struct mkv_track {
int write_dts;
int has_cue;
@@ -171,6 +173,13 @@ typedef struct mkv_track {
int64_t duration_offset;
int64_t codecpriv_offset;
int64_t ts_offset;
+ /* This callback will be called twice: First with a NULL AVIOContext
+ * to return the size of the (Simple)Block's data via size
+ * and a second time with the AVIOContext set when the data
+ * shall be written.
+ * The callback shall not return an error on the second call. */
+ int (*reformat)(struct MatroskaMuxContext *, AVIOContext *,
+ const AVPacket *, int *size);
} mkv_track;
typedef struct MatroskaMuxContext {
@@ -2433,6 +2442,8 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
#endif
if (par->codec_id == AV_CODEC_ID_AV1) {
err = ff_av1_filter_obus_buf(pkt->data, &data, &size, &offset);
+ } else if (track->reformat) {
+ err = track->reformat(mkv, NULL, pkt, &size);
} else
data = pkt->data;
@@ -2483,9 +2494,13 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
put_ebml_num(pb, track_number, track->track_num_size);
avio_wb16(pb, ts - mkv->cluster_pts);
avio_w8(pb, (blockid == MATROSKA_ID_SIMPLEBLOCK && keyframe) ? (1 << 7) : 0);
+ if (track->reformat) {
+ track->reformat(mkv, pb, pkt, &size);
+ } else {
avio_write(pb, data + offset, size);
if (data != pkt->data)
av_free(data);
+ }
if (blockid == MATROSKA_ID_BLOCK && !keyframe)
put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp - ts);