Commit 4e3bdf72 authored by James Almer's avatar James Almer

avformat/matroskaenc: always use a dynamic buffer when writting clusters

Tested-by: 's avatarDave Rice <dave@dericed.com>
Tested-by: 's avatarJerome Martinez <jerome@mediaarea.net>
Reviewed-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
Signed-off-by: 's avatarJames Almer <jamrial@gmail.com>
parent d41aeea8
...@@ -1930,9 +1930,6 @@ static void mkv_flush_dynbuf(AVFormatContext *s) ...@@ -1930,9 +1930,6 @@ static void mkv_flush_dynbuf(AVFormatContext *s)
int bufsize; int bufsize;
uint8_t *dyn_buf; uint8_t *dyn_buf;
if (!mkv->dyn_bc)
return;
bufsize = avio_close_dyn_buf(mkv->dyn_bc, &dyn_buf); bufsize = avio_close_dyn_buf(mkv->dyn_bc, &dyn_buf);
avio_write(s->pb, dyn_buf, bufsize); avio_write(s->pb, dyn_buf, bufsize);
av_free(dyn_buf); av_free(dyn_buf);
...@@ -1942,14 +1939,11 @@ static void mkv_flush_dynbuf(AVFormatContext *s) ...@@ -1942,14 +1939,11 @@ static void mkv_flush_dynbuf(AVFormatContext *s)
static void mkv_start_new_cluster(AVFormatContext *s, AVPacket *pkt) static void mkv_start_new_cluster(AVFormatContext *s, AVPacket *pkt)
{ {
MatroskaMuxContext *mkv = s->priv_data; MatroskaMuxContext *mkv = s->priv_data;
AVIOContext *pb; AVIOContext *pb = mkv->dyn_bc;
if (s->pb->seekable) {
pb = s->pb;
} else {
pb = mkv->dyn_bc;
}
end_ebml_master(pb, mkv->cluster);
mkv->cluster_pos = -1;
mkv_flush_dynbuf(s);
if (s->pb->seekable) if (s->pb->seekable)
av_log(s, AV_LOG_DEBUG, av_log(s, AV_LOG_DEBUG,
"Starting new cluster at offset %" PRIu64 " bytes, " "Starting new cluster at offset %" PRIu64 " bytes, "
...@@ -1959,10 +1953,6 @@ static void mkv_start_new_cluster(AVFormatContext *s, AVPacket *pkt) ...@@ -1959,10 +1953,6 @@ static void mkv_start_new_cluster(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_DEBUG, "Starting new cluster, " av_log(s, AV_LOG_DEBUG, "Starting new cluster, "
"pts %" PRIu64 "dts %" PRIu64 "\n", "pts %" PRIu64 "dts %" PRIu64 "\n",
pkt->pts, pkt->dts); pkt->pts, pkt->dts);
end_ebml_master(pb, mkv->cluster);
mkv->cluster_pos = -1;
if (mkv->dyn_bc)
mkv_flush_dynbuf(s);
avio_flush(s->pb); avio_flush(s->pb);
} }
...@@ -1992,16 +1982,14 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ ...@@ -1992,16 +1982,14 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
} }
} }
if (!s->pb->seekable) { if (!mkv->dyn_bc) {
if (!mkv->dyn_bc) { ret = avio_open_dyn_buf(&mkv->dyn_bc);
ret = avio_open_dyn_buf(&mkv->dyn_bc); if (ret < 0) {
if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to open dynamic buffer\n");
av_log(s, AV_LOG_ERROR, "Failed to open dynamic buffer\n"); return ret;
return ret;
}
} }
pb = mkv->dyn_bc;
} }
pb = mkv->dyn_bc;
if (mkv->cluster_pos == -1) { if (mkv->cluster_pos == -1) {
mkv->cluster_pos = avio_tell(s->pb); mkv->cluster_pos = avio_tell(s->pb);
...@@ -2010,7 +1998,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ ...@@ -2010,7 +1998,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
mkv->cluster_pts = FFMAX(0, ts); mkv->cluster_pts = FFMAX(0, ts);
} }
relative_packet_pos = avio_tell(s->pb) - mkv->cluster.pos; relative_packet_pos = avio_tell(pb) - mkv->cluster.pos;
if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) { if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) {
mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe);
...@@ -2074,11 +2062,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2074,11 +2062,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
// start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
// after 4k and on a keyframe // after 4k and on a keyframe
if (s->pb->seekable) { cluster_size = avio_tell(mkv->dyn_bc);
cluster_size = avio_tell(s->pb) - mkv->cluster_pos;
} else {
cluster_size = avio_tell(mkv->dyn_bc);
}
if (mkv->is_dash && codec_type == AVMEDIA_TYPE_VIDEO) { if (mkv->is_dash && codec_type == AVMEDIA_TYPE_VIDEO) {
// WebM DASH specification states that the first block of every cluster // WebM DASH specification states that the first block of every cluster
...@@ -2134,23 +2118,18 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2134,23 +2118,18 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt) static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt)
{ {
MatroskaMuxContext *mkv = s->priv_data; MatroskaMuxContext *mkv = s->priv_data;
AVIOContext *pb; AVIOContext *pb = mkv->dyn_bc;
if (s->pb->seekable)
pb = s->pb;
else
pb = mkv->dyn_bc;
if (!pkt) { if (!pkt) {
if (mkv->cluster_pos != -1) { if (mkv->cluster_pos != -1) {
end_ebml_master(pb, mkv->cluster);
mkv->cluster_pos = -1;
mkv_flush_dynbuf(s);
if (s->pb->seekable) if (s->pb->seekable)
av_log(s, AV_LOG_DEBUG, av_log(s, AV_LOG_DEBUG,
"Flushing cluster at offset %" PRIu64 " bytes\n", "Flushing cluster at offset %" PRIu64 " bytes\n",
avio_tell(s->pb)); avio_tell(s->pb));
else else
av_log(s, AV_LOG_DEBUG, "Flushing cluster\n"); av_log(s, AV_LOG_DEBUG, "Flushing cluster\n");
end_ebml_master(pb, mkv->cluster);
mkv->cluster_pos = -1;
if (mkv->dyn_bc)
mkv_flush_dynbuf(s);
avio_flush(s->pb); avio_flush(s->pb);
} }
return 1; return 1;
...@@ -2179,8 +2158,6 @@ static int mkv_write_trailer(AVFormatContext *s) ...@@ -2179,8 +2158,6 @@ static int mkv_write_trailer(AVFormatContext *s)
if (mkv->dyn_bc) { if (mkv->dyn_bc) {
end_ebml_master(mkv->dyn_bc, mkv->cluster); end_ebml_master(mkv->dyn_bc, mkv->cluster);
mkv_flush_dynbuf(s); mkv_flush_dynbuf(s);
} else if (mkv->cluster_pos != -1) {
end_ebml_master(pb, mkv->cluster);
} }
if (mkv->mode != MODE_WEBM) { if (mkv->mode != MODE_WEBM) {
......
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