• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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