1 // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 // 3 // Use of this source code is governed by a BSD-style license 4 // that can be found in the LICENSE file in the root of the source 5 // tree. An additional intellectual property rights grant can be found 6 // in the file PATENTS. All contributing project authors may 7 // be found in the AUTHORS file in the root of the source tree. 8 9 #ifndef SAMPLE_MUXER_METADATA_H_ // NOLINT 10 #define SAMPLE_MUXER_METADATA_H_ 11 12 #include <stdint.h> 13 14 #include <list> 15 #include <set> 16 #include <string> 17 18 #include "webvtt/webvttparser.h" 19 20 namespace mkvmuxer { 21 class Chapter; 22 class Frame; 23 class Segment; 24 class Track; 25 } // namespace mkvmuxer 26 27 class SampleMuxerMetadata { 28 public: 29 enum Kind { kSubtitles, kCaptions, kDescriptions, kMetadata, kChapters }; 30 31 SampleMuxerMetadata(); 32 33 // Bind this metadata object to the muxer instance. Returns false 34 // if segment equals NULL, or Init has already been called. 35 bool Init(mkvmuxer::Segment* segment); 36 37 // Parse the WebVTT file |filename| having the indicated |kind|, and 38 // create a corresponding track (or chapters element) in the 39 // segment. Returns false on error. 40 bool Load(const char* filename, Kind kind); 41 42 bool AddChapters(); 43 44 // Write any WebVTT cues whose time is less or equal to |time_ns| as 45 // a metadata block in its corresponding track. If |time_ns| is 46 // negative, write all remaining cues. Returns false on error. 47 bool Write(int64_t time_ns); 48 49 private: 50 typedef libwebvtt::Cue cue_t; 51 52 // Used to sort cues as they are loaded. 53 struct SortableCue { 54 bool operator>(int64_t time_ns) const { 55 // Cue start time expressed in milliseconds 56 const int64_t start_ms = cue.start_time.presentation(); 57 58 // Cue start time expressed in nanoseconds (MKV time) 59 const int64_t start_ns = start_ms * 1000000; 60 61 return (start_ns > time_ns); 62 } 63 64 bool operator<(const SortableCue& rhs) const { 65 if (cue.start_time < rhs.cue.start_time) 66 return true; 67 68 if (cue.start_time > rhs.cue.start_time) 69 return false; 70 71 return (track_num < rhs.track_num); 72 } 73 74 // Write this cue as a metablock to |segment|. Returns false on 75 // error. 76 bool Write(mkvmuxer::Segment* segment) const; 77 78 uint64_t track_num; 79 cue_t cue; 80 }; 81 82 typedef std::multiset<SortableCue> cues_set_t; 83 typedef std::list<cue_t> cue_list_t; 84 85 // Parse the WebVTT cues in the named |file|, returning false on 86 // error. We handle chapters as a special case, because they are 87 // stored in their own, dedicated level-1 element. 88 bool LoadChapters(const char* file); 89 90 // Parse the WebVTT chapters in |file| to populate |cues|. Returns 91 // false on error. 92 static bool ParseChapters(const char* file, cue_list_t* cues); 93 94 // Adds WebVTT cue |chapter| to the chapters element of the output 95 // file's segment element. Returns false on error. 96 bool AddChapter(const cue_t& chapter); 97 98 // Add a metadata track to the segment having the indicated |kind|, 99 // returning the |track_num| that has been chosen for this track. 100 // Returns false on error. 101 bool AddTrack(Kind kind, uint64_t* track_num); 102 103 // Parse the WebVTT |file| having the indicated |kind| and 104 // |track_num|, adding each parsed cue to cues set. Returns false 105 // on error. 106 bool Parse(const char* file, Kind kind, uint64_t track_num); 107 108 // Converts a WebVTT cue to a Matroska metadata block. 109 static void MakeFrame(const cue_t& cue, std::string* frame); 110 111 // Populate the cue identifier part of the metadata block. 112 static void WriteCueIdentifier(const std::string& identifier, 113 std::string* frame); 114 115 // Populate the cue settings part of the metadata block. 116 static void WriteCueSettings(const cue_t::settings_t& settings, 117 std::string* frame); 118 119 // Populate the payload part of the metadata block. 120 static void WriteCuePayload(const cue_t::payload_t& payload, 121 std::string* frame); 122 123 mkvmuxer::Segment* segment_; 124 125 // Set of cues ordered by time and then by track number. 126 cues_set_t cues_set_; 127 128 // The cues that will be used to populate the Chapters level-1 129 // element of the output file. 130 cue_list_t chapter_cues_; 131 132 // Disable copy ctor and copy assign. 133 SampleMuxerMetadata(const SampleMuxerMetadata&); 134 SampleMuxerMetadata& operator=(const SampleMuxerMetadata&); 135 }; 136 137 #endif // SAMPLE_MUXER_METADATA_H_ // NOLINT 138