[10/12] movenc: Allow writing to a non-seekable output if using empty moov

Message ID 1327065643-34065-10-git-send-email-martin@martin.st
State Committed
Headers show

Commit Message

Martin Storsjö Jan. 20, 2012, 1:20 p.m.
In this mode, no seeks will be done except for within moov/moof
fragments, which should fit within the AVIOContext buffer.
---
 libavformat/movenc.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

Comments

Martin Storsjö Jan. 25, 2012, 10:11 p.m. | #1
On Fri, 20 Jan 2012, Martin Storsjö wrote:

> In this mode, no seeks will be done except for within moov/moof
> fragments, which should fit within the AVIOContext buffer.
> ---
> libavformat/movenc.c |   14 ++++++++++++--
> 1 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 4ff4b7e..98de1eb 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -2507,6 +2507,7 @@ static int mov_flush_fragment(AVFormatContext *s)
>                                              mov->tracks[i].cluster[0].dts;
>             mov->tracks[i].entry = 0;
>         }
> +        avio_flush(s->pb);
>         return 0;
>     }
>
> @@ -2546,6 +2547,7 @@ static int mov_flush_fragment(AVFormatContext *s)
>
>         if (write_moof) {
>             MOVFragmentInfo *info;
> +            avio_flush(s->pb);
>             track->nb_frag_info++;
>             track->frag_info = av_realloc(track->frag_info,
>                                           sizeof(*track->frag_info) *
> @@ -2578,6 +2580,7 @@ static int mov_flush_fragment(AVFormatContext *s)
>
>     mov->mdat_size = 0;
>
> +    avio_flush(s->pb);
>     return 0;
> }
>
> @@ -2591,7 +2594,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
>     int size= pkt ? pkt->size : 0;
>     uint8_t *reformatted_data = NULL;
>
> -    if (!s->pb->seekable) return 0; /* Can't handle that */
> +    if (!s->pb->seekable && !(mov->flags & FF_MOV_FLAG_EMPTY_MOOV))
> +        return 0; /* Can't handle that */
>
>     if (!pkt) {
>         mov_flush_fragment(s);
> @@ -2767,7 +2771,13 @@ static int mov_write_header(AVFormatContext *s)
>     AVDictionaryEntry *t;
>     int i, hint_track = 0;
>
> -    if (!s->pb->seekable) {
> +    /* Non-seekable output is ok if EMPTY_MOOV is set, or if using the ismv
> +     * format (which sets EMPTY_MOOV later in this function). If ism_lookahead
> +     * is enabled, we don't support non-seekable output at all. */
> +    if (!s->pb->seekable &&
> +        ((!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) &&
> +          !(s->oformat && !strcmp(s->oformat->name, "ismv")))
> +         || mov->ism_lookahead)) {
>         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
>         return -1;
>     }
> -- 
> 1.7.3.1

This patch is pending review. As explanation of why, I locally amended the 
commit message with this paragraph:

This allows pushing live smooth streaming format data to a live publishing 
point on IIS over http.

// Martin
Luca Barbato Jan. 27, 2012, 7:11 p.m. | #2
On 20/01/12 05:20, Martin Storsjö wrote:
> In this mode, no seeks will be done except for within moov/moof
> fragments, which should fit within the AVIOContext buffer.
> ---

Seems ok, make sure fate result doesn't change ^^;

lu

Patch

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 4ff4b7e..98de1eb 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2507,6 +2507,7 @@  static int mov_flush_fragment(AVFormatContext *s)
                                              mov->tracks[i].cluster[0].dts;
             mov->tracks[i].entry = 0;
         }
+        avio_flush(s->pb);
         return 0;
     }
 
@@ -2546,6 +2547,7 @@  static int mov_flush_fragment(AVFormatContext *s)
 
         if (write_moof) {
             MOVFragmentInfo *info;
+            avio_flush(s->pb);
             track->nb_frag_info++;
             track->frag_info = av_realloc(track->frag_info,
                                           sizeof(*track->frag_info) *
@@ -2578,6 +2580,7 @@  static int mov_flush_fragment(AVFormatContext *s)
 
     mov->mdat_size = 0;
 
+    avio_flush(s->pb);
     return 0;
 }
 
@@ -2591,7 +2594,8 @@  int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     int size= pkt ? pkt->size : 0;
     uint8_t *reformatted_data = NULL;
 
-    if (!s->pb->seekable) return 0; /* Can't handle that */
+    if (!s->pb->seekable && !(mov->flags & FF_MOV_FLAG_EMPTY_MOOV))
+        return 0; /* Can't handle that */
 
     if (!pkt) {
         mov_flush_fragment(s);
@@ -2767,7 +2771,13 @@  static int mov_write_header(AVFormatContext *s)
     AVDictionaryEntry *t;
     int i, hint_track = 0;
 
-    if (!s->pb->seekable) {
+    /* Non-seekable output is ok if EMPTY_MOOV is set, or if using the ismv
+     * format (which sets EMPTY_MOOV later in this function). If ism_lookahead
+     * is enabled, we don't support non-seekable output at all. */
+    if (!s->pb->seekable &&
+        ((!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) &&
+          !(s->oformat && !strcmp(s->oformat->name, "ismv")))
+         || mov->ism_lookahead)) {
         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
         return -1;
     }