This allows writing a moov with an edit list even before the first
packet has been written.
This allows doing random-access writing of fragments when the
start dts of the stream isn't zero, so that the edit list in the moov
is written based on timestamps from the nominal start time set via
an option, while the first packet written corresponds to a later
fragment.
This is incredibly ugly - is there any better way of achieving
the same (private avoptions per stream)?
---
libavformat/movenc.c | 29 ++++++++++++++++++++++++++++-
libavformat/movenc.h | 1 +
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 342679e..abdceb8 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -73,6 +73,7 @@ static const AVOption options[] = {
{ "brand", "Override major brand", offsetof(MOVMuxContext,
major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags =
AV_OPT_FLAG_ENCODING_PARAM },
{ "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
{ "fragment_index", "Fragment number of the next fragment",
offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
AV_OPT_FLAG_ENCODING_PARAM},
+ { "stream_start_times", "Set stream start times, semicolon separated as
dts,pts", offsetof(MOVMuxContext, stream_start_times), AV_OPT_TYPE_STRING,
{.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -3421,11 +3422,37 @@ err:
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
{
+ MOVMuxContext *mov = s->priv_data;
+ if (mov->stream_start_times) {
+ const char *ptr = mov->stream_start_times;
+ int i;
+ for (i = 0; i < s->nb_streams; i++) {
+ char *token = av_get_token(&ptr, ";");
+ MOVTrack *track = &mov->tracks[i];
+ if (!token)
+ break;
+ if (*token) {
+ char *end;
+ track->start_dts = strtod(token, &end);
+ track->start_cts = 0;
+ if (*end == ',')
+ track->start_cts = strtod(end + 1, NULL) -
track->start_dts;
+ }
+ track->frag_discont = 1;
+ av_free(token);
+ if (*ptr)
+ ptr++;
+ else
+ break;
+ }
+ mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT;
+ av_freep(&mov->stream_start_times);
+ }
+
if (!pkt) {
mov_flush_fragment(s);
return 1;
} else {
- MOVMuxContext *mov = s->priv_data;
MOVTrack *trk = &mov->tracks[pkt->stream_index];
AVCodecContext *enc = trk->enc;
int64_t frag_duration = 0;
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 682820e..198d97d 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -169,6 +169,7 @@ typedef struct MOVMuxContext {
AVFormatContext *fc;
int use_editlist;
+ char *stream_start_times;
} MOVMuxContext;
#define FF_MOV_FLAG_RTP_HINT (1 << 0)
--
1.9.3 (Apple Git-50)
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel