From db418ab14e4d3071023fc9428168caddcabe5f9e Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Mon, 5 Mar 2018 09:44:22 -0800 Subject: [PATCH] Rewrite init segment in MultiSegmentSegmenter::DoFinalize This is called when reaching end of the file of the media. The duration of the media is updated. Fixes #340. Change-Id: I446f2d341b02125d4a7d8c958bda269b5403cb9c --- .../bear-640x360-a-live-cenc-golden-init.mp4 | Bin 951 -> 967 bytes ...0x360-a-live-cenc-rotation-golden-init.mp4 | Bin 899 -> 915 bytes ...live-cenc-rotation-no-pssh-golden-init.mp4 | Bin 899 -> 915 bytes .../bear-640x360-a-live-golden-init.mp4 | Bin 741 -> 757 bytes .../bear-640x360-v-live-cenc-golden-init.mp4 | Bin 1075 -> 1091 bytes ...0x360-v-live-cenc-rotation-golden-init.mp4 | Bin 1023 -> 1039 bytes ...live-cenc-rotation-no-pssh-golden-init.mp4 | Bin 1023 -> 1039 bytes .../bear-640x360-v-live-golden-init.mp4 | Bin 807 -> 823 bytes .../formats/mp4/multi_segment_segmenter.cc | 64 +++++++++--------- .../formats/mp4/multi_segment_segmenter.h | 1 + packager/media/formats/mp4/segmenter.cc | 2 +- 11 files changed, 34 insertions(+), 33 deletions(-) diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-init.mp4 index 8baf873921a6c10688b92cffc7912d25751f94a1..3292cd0e8d9c1a6c6eb00cd7dd4b80c70f91d173 100644 GIT binary patch delta 75 zcmdnaew=-RGWYV_{QNQo28Nv6vdI$|#WuP~G3!|5mZeqz#RPIwGg5#w0|Vn75UEg7 S1QrL2fJ7M>SSD97+X4Xis}M5) delta 59 zcmX@kzMXx7GWYb{{QNQo28Nv6vdI$|#WuP~G0SM=mZeqz#S}`4z%-D_zzD^YyO?bO D@+}R7 diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-init.mp4 index e0d23b00aea91625b31503fd5c0f7125d5beb63e..fd20d26f61e699abd2fe97d2664906a3fe788324 100644 GIT binary patch delta 80 zcmZo>pUgf%nY%bQKfjEDfgvZiZ1My~v5hWL%%&E(WvLZFF@fCFj1(Zvz`%G1L@JaN QfyKchAW;Se77!Z@01`D0Qvd(} delta 64 zcmbQt-poEhnL9Z*KfjEDfgvZiZ1My~v5hWL%&Ho>WvLZFF@=&MFb!lfFhVhi4F&)P C{0o!- diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-init.mp4 index e0d23b00aea91625b31503fd5c0f7125d5beb63e..fd20d26f61e699abd2fe97d2664906a3fe788324 100644 GIT binary patch delta 80 zcmZo>pUgf%nY%bQKfjEDfgvZiZ1My~v5hWL%%&E(WvLZFF@fCFj1(Zvz`%G1L@JaN QfyKchAW;Se77!Z@01`D0Qvd(} delta 64 zcmbQt-poEhnL9Z*KfjEDfgvZiZ1My~v5hWL%&Ho>WvLZFF@=&MFb!lfFhVhi4F&)P C{0o!- diff --git a/packager/app/test/testdata/bear-640x360-a-live-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-golden-init.mp4 index a703e29da80bc2d9624b870bf4fa644ead266d61..f725c309e7be284474af4512e9bb7e5445cffaae 100644 GIT binary patch delta 80 zcmaFL`jvHpGWXTo{QNQo28Nv6vdI$|#WuRsFqvB9mZeqz#RPIwGg5#w0|Vn75UEg7 R1QrL2fJ7M>SU_wr004fZ57qzx delta 64 zcmey$`jmBoGWXHk{QNQo28Nv6vdI$|#WuRsFsW+fmZeqz#S}`4z%-D_zzD@4HW&Z^ DTRROG diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-init.mp4 index 69d5615bdb50257047c3d8489cfcb60b36531da7..243f4297ec6fe2f7138ee4671d9a921f4880c830 100644 GIT binary patch delta 45 zcmdnYahPL*I-~qXjZMs=7P)1q6$}gv0=cOfDL|Tmfze^nWXjZMs=7P)1q6$}gv0=cOfDL|Tmfze^nZYjZMs~8o6bu6_ejHi*Yf)0RX(_2vGn4 diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-init.mp4 index cfbd64015fc99ac6f3e54c3024da8ac2f3d70af1..36cf45c94fffc9888d0e84b075b043f4e1700b34 100644 GIT binary patch delta 49 zcmey*-p?^Xo$>WXjZMs=7P)1q6$}gv0=cOfDL|Tmfze^nZYjZMs~8o6bu6_ejHi*Yf)0RX(_2vGn4 diff --git a/packager/app/test/testdata/bear-640x360-v-live-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-golden-init.mp4 index b183dc5d1cdf1af031460d6816acde6932500207..5ed12ec0532ac65e24a75bde8756e92456822e50 100644 GIT binary patch delta 66 zcmZ3^ww-N)I-~GLjay8n7P)1q6$}gv0=cOfDL|Tmfze?RkW?rs0*ix1K%xu`%r8M4 G5C8!D{tJ2l delta 50 pcmdnaww!H(IwSK&jay8r8o6bu6$}gv3MEBg8pvc|gklgI3;-t62h9Kg diff --git a/packager/media/formats/mp4/multi_segment_segmenter.cc b/packager/media/formats/mp4/multi_segment_segmenter.cc index 4d92f962fe..41d4ff723d 100644 --- a/packager/media/formats/mp4/multi_segment_segmenter.cc +++ b/packager/media/formats/mp4/multi_segment_segmenter.cc @@ -11,6 +11,7 @@ #include "packager/base/strings/string_number_conversions.h" #include "packager/base/strings/string_util.h" #include "packager/file/file.h" +#include "packager/file/file_closer.h" #include "packager/media/base/buffer_writer.h" #include "packager/media/base/muxer_options.h" #include "packager/media/base/muxer_util.h" @@ -55,28 +56,15 @@ std::vector MultiSegmentSegmenter::GetSegmentRanges() { } Status MultiSegmentSegmenter::DoInitialize() { - DCHECK(ftyp()); - DCHECK(moov()); - // Generate the output file with init segment. - File* file = File::Open(options().output_file_name.c_str(), "w"); - if (file == NULL) { - return Status(error::FILE_FAILURE, - "Cannot open file for write " + options().output_file_name); - } - std::unique_ptr buffer(new BufferWriter); - ftyp()->Write(buffer.get()); - moov()->Write(buffer.get()); - Status status = buffer->WriteToFile(file); - if (!file->Close()) { - LOG(WARNING) << "Failed to close the file properly: " - << options().output_file_name; - } - return status; + return WriteInitSegment(); } Status MultiSegmentSegmenter::DoFinalize() { - SetComplete(); - return Status::OK; + // Update init segment with media duration set. + Status status = WriteInitSegment(); + if (status.ok()) + SetComplete(); + return status; } Status MultiSegmentSegmenter::DoFinalizeSegment() { @@ -140,29 +128,44 @@ Status MultiSegmentSegmenter::DoFinalizeSegment() { return WriteSegment(); } +Status MultiSegmentSegmenter::WriteInitSegment() { + DCHECK(ftyp()); + DCHECK(moov()); + // Generate the output file with init segment. + std::unique_ptr file( + File::Open(options().output_file_name.c_str(), "w")); + if (!file) { + return Status(error::FILE_FAILURE, + "Cannot open file for write " + options().output_file_name); + } + std::unique_ptr buffer(new BufferWriter); + ftyp()->Write(buffer.get()); + moov()->Write(buffer.get()); + return buffer->WriteToFile(file.get()); +} + Status MultiSegmentSegmenter::WriteSegment() { DCHECK(sidx()); DCHECK(fragment_buffer()); DCHECK(styp_); std::unique_ptr buffer(new BufferWriter()); - File* file; + std::unique_ptr file; std::string file_name; if (options().segment_template.empty()) { // Append the segment to output file if segment template is not specified. file_name = options().output_file_name.c_str(); - file = File::Open(file_name.c_str(), "a"); - if (file == NULL) { - return Status( - error::FILE_FAILURE, - "Cannot open file for append " + options().output_file_name); + file.reset(File::Open(file_name.c_str(), "a")); + if (!file) { + return Status(error::FILE_FAILURE, "Cannot open file for append " + + options().output_file_name); } } else { file_name = GetSegmentName(options().segment_template, sidx()->earliest_presentation_time, num_segments_++, options().bandwidth); - file = File::Open(file_name.c_str(), "w"); - if (file == NULL) { + file.reset(File::Open(file_name.c_str(), "w")); + if (!file) { return Status(error::FILE_FAILURE, "Cannot open file for write " + file_name); } @@ -177,7 +180,7 @@ Status MultiSegmentSegmenter::WriteSegment() { const size_t segment_size = segment_header_size + fragment_buffer()->Size(); DCHECK_NE(segment_size, 0u); - Status status = buffer->WriteToFile(file); + Status status = buffer->WriteToFile(file.get()); if (status.ok()) { if (muxer_listener()) { for (const KeyFrameInfo& key_frame_info : key_frame_infos()) { @@ -187,12 +190,9 @@ Status MultiSegmentSegmenter::WriteSegment() { key_frame_info.size); } } - status = fragment_buffer()->WriteToFile(file); + status = fragment_buffer()->WriteToFile(file.get()); } - if (!file->Close()) - LOG(WARNING) << "Failed to close the file properly: " << file_name; - if (!status.ok()) return status; diff --git a/packager/media/formats/mp4/multi_segment_segmenter.h b/packager/media/formats/mp4/multi_segment_segmenter.h index 2309d24164..5fff12d6c3 100644 --- a/packager/media/formats/mp4/multi_segment_segmenter.h +++ b/packager/media/formats/mp4/multi_segment_segmenter.h @@ -49,6 +49,7 @@ class MultiSegmentSegmenter : public Segmenter { Status DoFinalizeSegment() override; // Write segment to file. + Status WriteInitSegment(); Status WriteSegment(); std::unique_ptr styp_; diff --git a/packager/media/formats/mp4/segmenter.cc b/packager/media/formats/mp4/segmenter.cc index 46345254f9..0df407d655 100644 --- a/packager/media/formats/mp4/segmenter.cc +++ b/packager/media/formats/mp4/segmenter.cc @@ -101,7 +101,7 @@ Status Segmenter::Initialize( Status Segmenter::Finalize() { // Set movie duration. Note that the duration in mvhd, tkhd, mdhd should not // be touched, i.e. kept at 0. The updated moov box will be written to output - // file for VOD case only. + // file for VOD and static live case only. moov_->extends.header.fragment_duration = 0; for (size_t i = 0; i < stream_durations_.size(); ++i) { uint64_t duration =