From 10daa399019c9d766d820e48e559a7e445cd60d7 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Mon, 7 Dec 2020 00:09:04 -0800 Subject: [PATCH] [MP4] Allow not to generate 'sidx' box for single-segment too I.e. the flag --generate_sidx_in_media_segments, --nogenerate_sidx_in_media_segments work for both single-segment and multi-segment mode with this change. Related to #862. Change-Id: Icd27fd00e8e036ba0c4709b48650372429cc0351 --- docs/source/options/mp4_output_options.rst | 8 +++++--- packager/app/muxer_flags.cc | 6 +++--- .../formats/mp4/single_segment_segmenter.cc | 17 ++++++++++++----- .../formats/mp4/single_segment_segmenter.h | 3 +-- packager/packager.cc | 8 ++++++++ 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/docs/source/options/mp4_output_options.rst b/docs/source/options/mp4_output_options.rst index 582f4cb5d6..e0fc2dcec5 100644 --- a/docs/source/options/mp4_output_options.rst +++ b/docs/source/options/mp4_output_options.rst @@ -12,6 +12,8 @@ MP4 output options --generate_sidx_in_media_segments --nogenerate_sidx_in_media_segments - For MP4 with DASH live profile only: Indicates whether to generate 'sidx' - box in media segments. Note that it is reuqired by spec if segment template - contains $Time$ specifier. + Indicates whether to generate 'sidx' box in media segments. Note + that it is required for DASH on-demand profile (not using segment + template). + + Default enabled. diff --git a/packager/app/muxer_flags.cc b/packager/app/muxer_flags.cc index e688e5c2a5..1475e75b3a 100644 --- a/packager/app/muxer_flags.cc +++ b/packager/app/muxer_flags.cc @@ -36,9 +36,9 @@ DEFINE_bool(fragment_sap_aligned, "implies segment_sap_aligned."); DEFINE_bool(generate_sidx_in_media_segments, true, - "For ISO BMFF with DASH live profile only. Indicates whether to " - "generate 'sidx' box in media segments. Note that it is required " - "by spec if segment template contains $Time$ specifier."); + "Indicates whether to generate 'sidx' box in media segments. Note " + "that it is required for DASH on-demand profile (not using segment " + "template)."); DEFINE_string(temp_dir, "", "Specify a directory in which to store temporary (intermediate) " diff --git a/packager/media/formats/mp4/single_segment_segmenter.cc b/packager/media/formats/mp4/single_segment_segmenter.cc index 7c54d9235a..88e0c40a1a 100644 --- a/packager/media/formats/mp4/single_segment_segmenter.cc +++ b/packager/media/formats/mp4/single_segment_segmenter.cc @@ -45,15 +45,19 @@ bool SingleSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) { // Index range is right after init range so the offset must be the size of // ftyp and moov. *offset = ftyp()->ComputeSize() + moov()->ComputeSize(); - *size = vod_sidx_->ComputeSize(); + *size = options().mp4_params.generate_sidx_in_media_segments + ? vod_sidx_->ComputeSize() + : 0; return true; } std::vector SingleSegmentSegmenter::GetSegmentRanges() { std::vector ranges; - uint64_t next_offset = - ftyp()->ComputeSize() + moov()->ComputeSize() + vod_sidx_->ComputeSize() + - vod_sidx_->first_offset; + uint64_t next_offset = ftyp()->ComputeSize() + moov()->ComputeSize() + + (options().mp4_params.generate_sidx_in_media_segments + ? vod_sidx_->ComputeSize() + : 0) + + vod_sidx_->first_offset; for (const SegmentReference& segment_reference : vod_sidx_->references) { Range r; r.start = next_offset; @@ -111,7 +115,10 @@ Status SingleSegmentSegmenter::DoFinalize() { std::unique_ptr buffer(new BufferWriter()); ftyp()->Write(buffer.get()); moov()->Write(buffer.get()); - vod_sidx_->Write(buffer.get()); + + if (options().mp4_params.generate_sidx_in_media_segments) + vod_sidx_->Write(buffer.get()); + Status status = buffer->WriteToFile(file.get()); if (!status.ok()) return status; diff --git a/packager/media/formats/mp4/single_segment_segmenter.h b/packager/media/formats/mp4/single_segment_segmenter.h index 4659f35435..c70dc8e6fb 100644 --- a/packager/media/formats/mp4/single_segment_segmenter.h +++ b/packager/media/formats/mp4/single_segment_segmenter.h @@ -24,8 +24,7 @@ namespace mp4 { /// may not match the requested duration exactly, but will be approximated. That /// is, the Segmenter tries to end subsegment/fragment at the first sample with /// overall subsegment/fragment duration not smaller than defined duration and -/// yet meet SAP requirements. SingleSegmentSegmenter ignores @b -/// MuxerOptions.mp4_params.generate_sidx_in_media_segments. +/// yet meet SAP requirements. class SingleSegmentSegmenter : public Segmenter { public: SingleSegmentSegmenter(const MuxerOptions& options, diff --git a/packager/packager.cc b/packager/packager.cc index 9e9a1b6cb6..e7618632cb 100644 --- a/packager/packager.cc +++ b/packager/packager.cc @@ -351,6 +351,14 @@ Status ValidateParams(const PackagingParams& packaging_params, "(not using segment_template)."); } + if (on_demand_dash_profile && + !packaging_params.mpd_params.mpd_output.empty() && + !packaging_params.mp4_output_params.generate_sidx_in_media_segments) { + return Status(error::UNIMPLEMENTED, + "--generate_sidx_in_media_segments is required for DASH " + "on-demand profile (not using segment_template)."); + } + return Status::OK; }