On 12/18/17 2:17 PM, Steven Liu wrote:
fix ticket id: 6888

Signed-off-by: Steven Liu <l...@chinaffmpeg.org>
---
  libavformat/hlsenc.c | 72 ++++++++++++++++++++++++++++++++++++++++++++--------
  1 file changed, 62 insertions(+), 10 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index e3442c368f..f51fec1030 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -352,6 +352,29 @@ static void write_styp(AVIOContext *pb)
      ffio_wfourcc(pb, "msix");
  }
+static int flush_dynbuf(VariantStream *vs, int *range_length)
+{
+    AVFormatContext *ctx = vs->avf;
+    uint8_t *buffer;
+
+    if (!ctx->pb) {
+        return AVERROR(EINVAL);
+    }
+
+    // flush
+    av_write_frame(ctx, NULL);
+    avio_flush(ctx->pb);
+
+    // write out to file
+    *range_length = avio_close_dyn_buf(ctx->pb, &buffer);
+    ctx->pb = NULL;
+    avio_write(vs->out, buffer, *range_length);
+    av_free(buffer);
+
+    // re-open buffer
+    return avio_open_dyn_buf(&ctx->pb);
+}
+
  static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls,
                                     VariantStream *vs) {
@@ -677,7 +700,9 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
          if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
              return ret;
- if ((ret = s->io_open(s, &vs->out, vs->base_output_dirname, AVIO_FLAG_WRITE, &options)) < 0) {
+        ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options);
+        av_dict_free(&options);
+        if (ret < 0) {
              av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", 
vs->fmp4_init_filename);
              return ret;
          }
@@ -1404,9 +1429,10 @@ static int hls_start(AVFormatContext *s, VariantStream 
*vs)
          av_dict_free(&options);
          if (err < 0)
              return err;
-    } else
+    } else if (c->segment_type != SEGMENT_TYPE_FMP4) {
          if ((err = hlsenc_io_open(s, &oc->pb, oc->filename, &options)) < 0)
              goto fail;
+    }
      if (vs->vtt_basename) {
          set_http_options(s, &options, c);
          if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->filename, &options)) 
< 0)
@@ -1414,9 +1440,7 @@ static int hls_start(AVFormatContext *s, VariantStream 
*vs)
      }
      av_dict_free(&options);
- if (c->segment_type == SEGMENT_TYPE_FMP4 && !(c->flags & HLS_SINGLE_FILE)) {
-            write_styp(oc->pb);
-    } else {
+    if (c->segment_type != SEGMENT_TYPE_FMP4) {
          /* We only require one PAT/PMT per segment. */
          if (oc->oformat->priv_class && oc->priv_data) {
              char period[21];
@@ -1780,7 +1804,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
          vs->size = new_start_pos - vs->start_pos;
if (!byterange_mode) {
-            if (hls->segment_type == SEGMENT_TYPE_FMP4 && 
!vs->init_range_length) {
+            if (hls->segment_type == SEGMENT_TYPE_FMP4) {
+                if (!vs->init_range_length) {
                  avio_flush(oc->pb);
                  range_length = avio_close_dyn_buf(oc->pb, &buffer);
                  avio_write(vs->out, buffer, range_length);
@@ -1789,6 +1814,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
                  vs->packets_written = 0;
                  ff_format_io_close(s, &vs->out);
                  hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
+                }
              } else {
                  hlsenc_io_close(s, &oc->pb, oc->filename);
              }
@@ -1807,7 +1833,20 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
              vs->number--;
          }
- if (!vs->fmp4_init_mode || byterange_mode)
+        if (hls->segment_type == SEGMENT_TYPE_FMP4) {
+            ret = hlsenc_io_open(s, &vs->out, vs->avf->filename, NULL);
Will it be better if you call "set_http_options()" here itself, instead of a separate patch 4/4? In that way this patch would be self contained.
+            if (ret < 0) {
+                av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n",
+                    vs->avf->filename);
+                return ret;
+            }
+            write_styp(vs->out);
+            ret = flush_dynbuf(vs, &range_length);
+            if (ret < 0) {
+                return ret;
+            }
+            ff_format_io_close(s, &vs->out);
Again is it better to call hlsenc_io_close() here itself instead of patch 3/4. Again just from self-containment perspective.
+        }
              ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, 
vs->size);
          vs->start_pos = new_start_pos;
          if (ret < 0) {
@@ -1861,6 +1900,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
      AVFormatContext *vtt_oc = NULL;
      char *old_filename = NULL;
      int i;
+    int ret = 0;
      VariantStream *vs = NULL;
for (i = 0; i < hls->nb_varstreams; i++) {
@@ -1873,11 +1913,25 @@ static int hls_write_trailer(struct AVFormatContext *s)
      if (!old_filename) {
          return AVERROR(ENOMEM);
      }
-
+    if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
+        int range_length = 0;
+        ret = hlsenc_io_open(s, &vs->out, vs->avf->filename, NULL);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n", 
vs->avf->filename);
+            return AVERROR(ENOENT);
+        }
+        write_styp(vs->out);
+        ret = flush_dynbuf(vs, &range_length);
+        if (ret < 0) {
+            return ret;
+        }
+        ff_format_io_close(s, &vs->out);
+    }
Will it make sense it make this code as a separate function in order to avoid code repetition?
av_write_trailer(oc);
      if (oc->pb) {
          vs->size = avio_tell(vs->avf->pb) - vs->start_pos;
+        if (hls->segment_type != SEGMENT_TYPE_FMP4)
          ff_format_io_close(s, &oc->pb);
if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {
@@ -2238,10 +2292,8 @@ static int hls_init(AVFormatContext *s)
              }
          }
- if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) {
              if ((ret = hls_start(s, vs)) < 0)
                  goto fail;
-        }
      }
fail:
Thanks,
Karthick
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to