[FFmpeg-devel] [PATCH] avformat/hls: add supporting fMP4(CMAF) format to seek on HLS demuxer

κΉ€λ™μ›λ‹˜(DK) dongwon.kim at sk.com
Thu Jul 16 08:57:06 EEST 2020


Signed-off-by: Dongwon Kim <dongwon.kim at sk.com>
---
 libavformat/hls.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/libavformat/hls.c b/libavformat/hls.c index ba17c4ed96..561b42ea6b 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2139,6 +2139,68 @@ static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a,
     return av_compare_mod(scaled_ts_a, scaled_ts_b, 1LL << 33);  }
 
+static int reopen_demux_for_component(AVFormatContext *s, struct 
+playlist *pls) {
+    ff_const59 AVInputFormat *in_fmt = NULL;
+    AVDictionary  *in_fmt_opts = NULL;
+    uint8_t *avio_ctx_buffer  = NULL;
+    int ret = 0;
+
+    if (pls->ctx) {
+        av_freep(&pls->pb.buffer);
+        memset(&pls->pb, 0x00, sizeof(AVIOContext));
+        pls->ctx->pb = NULL;
+        avformat_close_input(&pls->ctx);
+        pls->ctx = NULL;
+    }
+
+    if (ff_check_interrupt(&s->interrupt_callback)) {
+        ret = AVERROR_EXIT;
+        goto fail;
+    }
+
+    if (!(pls->ctx = avformat_alloc_context())) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    avio_ctx_buffer  = av_malloc(INITIAL_BUFFER_SIZE);
+    if (!avio_ctx_buffer ) {
+        ret = AVERROR(ENOMEM);
+        avformat_free_context(pls->ctx);
+        pls->ctx = NULL;
+        goto fail;
+    }
+    ffio_init_context(&pls->pb, avio_ctx_buffer , INITIAL_BUFFER_SIZE, 0, pls, read_data, NULL, NULL);
+    pls->pb.seekable = 0;
+
+    if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
+        goto fail;
+
+    pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
+    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Error when loading segment, playlist %d\n", pls->cur_seq_no);
+        avformat_free_context(pls->ctx);
+        pls->ctx = NULL;
+        goto fail;
+    }
+
+    pls->ctx->pb = &pls->pb;
+    pls->ctx->io_open  = nested_io_open;
+
+    ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts);
+    av_dict_free(&in_fmt_opts);
+    if (ret < 0)
+        goto fail;
+    ret = avformat_find_stream_info(pls->ctx, NULL);
+    if (ret < 0)
+        goto fail;
+
+fail:
+    return ret;
+}
+
 static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)  {
     HLSContext *c = s->priv_data;
@@ -2351,6 +2413,11 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
             pls->seek_stream_index = -1;
             pls->seek_flags |= AVSEEK_FLAG_ANY;
         }
+
+        if (pls->ctx && pls->ctx->iformat && strcmp(pls->ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0) {
+            pls->init_sec_buf_read_offset = 0;
+            reopen_demux_for_component(s, pls);
+        }
     }
 
     c->cur_timestamp = seek_timestamp;
--
2.25.1



More information about the ffmpeg-devel mailing list