[FFmpeg-devel] [PATCH] lavf/dashenc: add dash SegmentBase manifest generator

2020-03-11 Thread David Martin
Support to generate dash SegmentBase manifests, by adding
"use_segmentbase" option to dash muxer. SegmentBase manifest
is defined in ISO DASH Specification section 5.3.9.2 and has as
prerequisite the option "global_sidx" as players will use this box
to have a reference to all fragments in the media.
---
 doc/muxers.texi   |  5 +
 libavformat/dashenc.c | 35 ++-
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index d304181671..fbaa357f2d 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -309,6 +309,11 @@ escaped.
 @item global_sidx @var{global_sidx}
 Write global SIDX atom. Applicable only for single file, mp4 output, 
non-streaming mode.
 
+@item use_segmentbase @var{use_segmentbase}
+Generates a dash SegmentBase manifest as defined in section 5.3.9.2 of the ISO
+DASH specification. Only applicable when global sidx is enabled since the 
player
+uses it to have a reference of all the segments in the media
+
 @item dash_segment_type @var{dash_segment_type}
 Possible values:
 @table @option
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 94d463972a..e8b418e74c 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -193,6 +193,8 @@ typedef struct DASHContext {
 int profile;
 int64_t target_latency;
 int target_latency_refid;
+int use_segmentbase;
+int64_t sidx_size;
 } DASHContext;
 
 static struct codec_string {
@@ -696,16 +698,23 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 avio_printf(out, "\t\t\t\t\n");
 } else if (c->single_file) {
 avio_printf(out, "\t\t\t\t%s\n", os->initfile);
-avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
-avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, os->init_start_pos + 
os->init_range_length - 1);
-for (i = start_index; i < os->nb_segments; i++) {
-Segment *seg = os->segments[i];
-avio_printf(out, "\t\t\t\t\tstart_pos, seg->start_pos + 
seg->range_length - 1);
-if (seg->index_length)
-avio_printf(out, "indexRange=\"%"PRId64"-%"PRId64"\" ", 
seg->start_pos, seg->start_pos + seg->index_length - 1);
-avio_printf(out, "/>\n");
+int64_t init_segment_size = os->init_start_pos + os->init_range_length;
+if (c->use_segmentbase && final) {
+avio_printf(out, "\t\t\t\t\n", init_segment_size - c->sidx_size, init_segment_size - 1, 
AV_TIME_BASE);
+avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, init_segment_size - 
c->sidx_size - 1);
+avio_printf(out, "\t\t\t\t\n");
+} else {
+avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
+avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, init_segment_size - 1);
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+avio_printf(out, "\t\t\t\t\tstart_pos, seg->start_pos + 
seg->range_length - 1);
+if (seg->index_length)
+avio_printf(out, "indexRange=\"%"PRId64"-%"PRId64"\" ", 
seg->start_pos, seg->start_pos + seg->index_length - 1);
+avio_printf(out, "/>\n");
+}
+avio_printf(out, "\t\t\t\t\n");
 }
-avio_printf(out, "\t\t\t\t\n");
 } else {
 avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
 avio_printf(out, "\t\t\t\t\t\n", 
os->initfile);
@@ -1389,6 +1398,12 @@ static int dash_init(AVFormatContext *s)
 av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as 
streaming is enabled\n");
 c->global_sidx = 0;
 }
+
+if (c->use_segmentbase && !c->global_sidx) {
+av_log(s, AV_LOG_WARNING, "SegmentBase manifest signaling option will 
be ignored as global SIDX is not enabled\n");
+c->use_segmentbase = 0;
+}
+
 if (c->frag_type == FRAG_TYPE_NONE && c->streaming) {
 av_log(s, AV_LOG_VERBOSE, "Changing frag_type from none to every_frame 
as streaming is enabled\n");
 c->frag_type = FRAG_TYPE_EVERY_FRAME;
@@ -1981,6 +1996,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 if (c->global_sidx) {
 int j, start_index, start_number;
 int64_t sidx_size = avio_tell(os->ctx->pb) - file_size;
+c->sidx_size = sidx_size;
 get_start_index_number(os, c, &start_index, &start_number);
 if (start_index >= os->nb_segments ||
 os->segment_type != SEGMENT_TYPE_MP4)
@@ -2350,6 +2366,7 @@ static const AVOption options[] = {
 { "index_correction", "Enable/Disable segment index correction logic", 
OFFSET(index_correction), AV_OPT_T

[FFmpeg-devel] [PATCH] lavf/dashenc: add dash SegmentBase manifest generator

2020-03-11 Thread David Martin
Support to generate dash SegmentBase manifests, by adding
"use_segmentbase" option to dash muxer. SegmentBase manifest
is defined in ISO DASH Specification section 5.3.9.2 and has as
prerequisite the option "global_sidx" as players will use this box
to have a reference to all fragments in the media.
---
 doc/muxers.texi   |  5 +
 libavformat/dashenc.c | 35 ++-
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index d304181671..fbaa357f2d 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -309,6 +309,11 @@ escaped.
 @item global_sidx @var{global_sidx}
 Write global SIDX atom. Applicable only for single file, mp4 output, 
non-streaming mode.
 
+@item use_segmentbase @var{use_segmentbase}
+Generates a dash SegmentBase manifest as defined in section 5.3.9.2 of the ISO
+DASH specification. Only applicable when global sidx is enabled since the 
player
+uses it to have a reference of all the segments in the media
+
 @item dash_segment_type @var{dash_segment_type}
 Possible values:
 @table @option
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 94d463972a..e8b418e74c 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -193,6 +193,8 @@ typedef struct DASHContext {
 int profile;
 int64_t target_latency;
 int target_latency_refid;
+int use_segmentbase;
+int64_t sidx_size;
 } DASHContext;
 
 static struct codec_string {
@@ -696,16 +698,23 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 avio_printf(out, "\t\t\t\t\n");
 } else if (c->single_file) {
 avio_printf(out, "\t\t\t\t%s\n", os->initfile);
-avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
-avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, os->init_start_pos + 
os->init_range_length - 1);
-for (i = start_index; i < os->nb_segments; i++) {
-Segment *seg = os->segments[i];
-avio_printf(out, "\t\t\t\t\tstart_pos, seg->start_pos + 
seg->range_length - 1);
-if (seg->index_length)
-avio_printf(out, "indexRange=\"%"PRId64"-%"PRId64"\" ", 
seg->start_pos, seg->start_pos + seg->index_length - 1);
-avio_printf(out, "/>\n");
+int64_t init_segment_size = os->init_start_pos + os->init_range_length;
+if (c->use_segmentbase && final) {
+avio_printf(out, "\t\t\t\t\n", init_segment_size - c->sidx_size, init_segment_size - 1, 
AV_TIME_BASE);
+avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, init_segment_size - 
c->sidx_size - 1);
+avio_printf(out, "\t\t\t\t\n");
+} else {
+avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
+avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, init_segment_size - 1);
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+avio_printf(out, "\t\t\t\t\tstart_pos, seg->start_pos + 
seg->range_length - 1);
+if (seg->index_length)
+avio_printf(out, "indexRange=\"%"PRId64"-%"PRId64"\" ", 
seg->start_pos, seg->start_pos + seg->index_length - 1);
+avio_printf(out, "/>\n");
+}
+avio_printf(out, "\t\t\t\t\n");
 }
-avio_printf(out, "\t\t\t\t\n");
 } else {
 avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
 avio_printf(out, "\t\t\t\t\t\n", 
os->initfile);
@@ -1389,6 +1398,12 @@ static int dash_init(AVFormatContext *s)
 av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as 
streaming is enabled\n");
 c->global_sidx = 0;
 }
+
+if (c->use_segmentbase && !c->global_sidx) {
+av_log(s, AV_LOG_WARNING, "SegmentBase manifest signaling option will 
be ignored as global SIDX is not enabled\n");
+c->use_segmentbase = 0;
+}
+
 if (c->frag_type == FRAG_TYPE_NONE && c->streaming) {
 av_log(s, AV_LOG_VERBOSE, "Changing frag_type from none to every_frame 
as streaming is enabled\n");
 c->frag_type = FRAG_TYPE_EVERY_FRAME;
@@ -1981,6 +1996,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 if (c->global_sidx) {
 int j, start_index, start_number;
 int64_t sidx_size = avio_tell(os->ctx->pb) - file_size;
+c->sidx_size = sidx_size;
 get_start_index_number(os, c, &start_index, &start_number);
 if (start_index >= os->nb_segments ||
 os->segment_type != SEGMENT_TYPE_MP4)
@@ -2350,6 +2366,7 @@ static const AVOption options[] = {
 { "index_correction", "Enable/Disable segment index correction logic", 
OFFSET(index_correction), AV_OPT_T

[FFmpeg-devel] [PATCH v2] lavf/dashenc: add dash SegmentBase manifest generator

2020-03-12 Thread David Martin
Support to generate dash SegmentBase manifests, by adding
"use_segmentbase" option to dash muxer. SegmentBase manifest
is defined in ISO DASH Specification section 5.3.9.2 and has as
prerequisite the option "global_sidx" as players will use this
box to have a reference to all fragments in the media.

Signed-off-by: David Martin 
---
 doc/muxers.texi   |  5 +
 libavformat/dashenc.c | 16 
 2 files changed, 21 insertions(+)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index d304181671..fbaa357f2d 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -309,6 +309,11 @@ escaped.
 @item global_sidx @var{global_sidx}
 Write global SIDX atom. Applicable only for single file, mp4 output, 
non-streaming mode.
 
+@item use_segmentbase @var{use_segmentbase}
+Generates a dash SegmentBase manifest as defined in section 5.3.9.2 of the ISO
+DASH specification. Only applicable when global sidx is enabled since the 
player
+uses it to have a reference of all the segments in the media
+
 @item dash_segment_type @var{dash_segment_type}
 Possible values:
 @table @option
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 94d463972a..39286e9e11 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -193,6 +193,8 @@ typedef struct DASHContext {
 int profile;
 int64_t target_latency;
 int target_latency_refid;
+int use_segmentbase;
+int64_t sidx_size;
 } DASHContext;
 
 static struct codec_string {
@@ -694,6 +696,12 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 avio_printf(out, "\t\t\t\t\t\n");
 }
 avio_printf(out, "\t\t\t\t\n");
+} else if (c->single_file && c->use_segmentbase && final) {
+avio_printf(out, "\t\t\t\t%s\n", os->initfile);
+int64_t init_segment_size = os->init_start_pos + os->init_range_length;
+avio_printf(out, "\t\t\t\t\n", init_segment_size - 
c->sidx_size, init_segment_size - 1, AV_TIME_BASE);
+avio_printf(out, "\t\t\t\t\t\n", os->init_start_pos, init_segment_size - 
c->sidx_size - 1);
+avio_printf(out, "\t\t\t\t\n");
 } else if (c->single_file) {
 avio_printf(out, "\t\t\t\t%s\n", os->initfile);
 avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, 
FFMIN(os->seg_duration, os->last_duration), start_number);
@@ -1389,6 +1397,12 @@ static int dash_init(AVFormatContext *s)
 av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as 
streaming is enabled\n");
 c->global_sidx = 0;
 }
+
+if (c->use_segmentbase && !c->global_sidx) {
+av_log(s, AV_LOG_WARNING, "SegmentBase manifest signaling option will 
be ignored as global SIDX is not enabled\n");
+c->use_segmentbase = 0;
+}
+
 if (c->frag_type == FRAG_TYPE_NONE && c->streaming) {
 av_log(s, AV_LOG_VERBOSE, "Changing frag_type from none to every_frame 
as streaming is enabled\n");
 c->frag_type = FRAG_TYPE_EVERY_FRAME;
@@ -1981,6 +1995,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 if (c->global_sidx) {
 int j, start_index, start_number;
 int64_t sidx_size = avio_tell(os->ctx->pb) - file_size;
+c->sidx_size = sidx_size;
 get_start_index_number(os, c, &start_index, &start_number);
 if (start_index >= os->nb_segments ||
 os->segment_type != SEGMENT_TYPE_MP4)
@@ -2350,6 +2365,7 @@ static const AVOption options[] = {
 { "index_correction", "Enable/Disable segment index correction logic", 
OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
 { "format_options","set list of options for the container format 
(mp4/webm) used for dash", OFFSET(format_options), AV_OPT_TYPE_DICT, {.str = 
NULL},  0, 0, E},
 { "global_sidx", "Write global SIDX atom. Applicable only for single file, 
mp4 output, non-streaming mode", OFFSET(global_sidx), AV_OPT_TYPE_BOOL, { .i64 
= 0 }, 0, 1, E },
+{ "use_segmentbase", "Use SegmentBase in Representation", 
OFFSET(use_segmentbase), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
 { "dash_segment_type", "set dash segment files type", 
OFFSET(segment_type_option), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_AUTO }, 0, 
SEGMENT_TYPE_NB - 1, E, "segment_type"},
 { "auto", "select segment file format based on codec", 0, 
AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_AUTO }, 0, UINT_MAX,   E, 
"segment_type"},
 { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, 
{.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX,   E, "segment_type"},
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".