DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
mpd_builder.h
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // This file contains the MpdBuilder, AdaptationSet, and Representation class
8 // declarations.
9 // http://goo.gl/UrsSlF
10 //
14 
15 #ifndef MPD_BASE_MPD_BUILDER_H_
16 #define MPD_BASE_MPD_BUILDER_H_
17 
18 #include <stdint.h>
19 
20 #include <list>
21 #include <map>
22 #include <set>
23 #include <string>
24 
25 #include "packager/base/atomic_sequence_num.h"
26 #include "packager/base/callback.h"
27 #include "packager/base/gtest_prod_util.h"
28 #include "packager/base/stl_util.h"
29 #include "packager/base/time/clock.h"
30 #include "packager/base/time/time.h"
31 #include "packager/mpd/base/bandwidth_estimator.h"
32 #include "packager/mpd/base/content_protection_element.h"
33 #include "packager/mpd/base/media_info.pb.h"
34 #include "packager/mpd/base/mpd_options.h"
35 #include "packager/mpd/base/segment_info.h"
36 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
37 
38 // TODO(rkuroiwa): For classes with |id_|, consider removing the field and let
39 // the MPD (XML) generation functions take care of assigning an ID to each
40 // element.
41 namespace edash_packager {
42 
43 namespace media {
44 class File;
45 } // namespace media
46 
47 class AdaptationSet;
48 class Representation;
49 
50 namespace xml {
51 
52 class XmlNode;
53 class RepresentationXmlNode;
54 
55 } // namespace xml
56 
58 class MpdBuilder {
59  public:
60  enum MpdType {
61  kStatic = 0,
62  kDynamic
63  };
64 
68  MpdBuilder(MpdType type, const MpdOptions& mpd_options);
69  virtual ~MpdBuilder();
70 
73  void AddBaseUrl(const std::string& base_url);
74 
79  virtual AdaptationSet* AddAdaptationSet(const std::string& lang);
80 
85  bool WriteMpdToFile(media::File* output_file);
86 
90  virtual bool ToString(std::string* output);
91 
93  MpdType type() const { return type_; }
94 
100  static void MakePathsRelativeToMpd(const std::string& mpd_path,
101  MediaInfo* media_info);
102 
103  // Inject a |clock| that returns the current time.
105  void InjectClockForTesting(scoped_ptr<base::Clock> clock) {
106  clock_ = clock.Pass();
107  }
108 
109  private:
110  // DynamicMpdBuilderTest needs to set availabilityStartTime so that the test
111  // doesn't need to depend on current time.
112  friend class DynamicMpdBuilderTest;
113 
114  bool ToStringImpl(std::string* output);
115 
116  // This is a helper method for writing out MPDs, called from WriteMpdToFile()
117  // and ToString().
118  template <typename OutputType>
119  bool WriteMpdToOutput(OutputType* output);
120 
121  // Returns the document pointer to the MPD. This must be freed by the caller
122  // using appropriate xmlDocPtr freeing function.
123  // On failure, this returns NULL.
124  xmlDocPtr GenerateMpd();
125 
126  // Set MPD attributes common to all profiles. Uses non-zero |mpd_options_| to
127  // set attributes for the MPD.
128  void AddCommonMpdInfo(xml::XmlNode* mpd_node);
129 
130  // Adds 'static' MPD attributes and elements to |mpd_node|. This assumes that
131  // the first child element is a Period element.
132  void AddStaticMpdInfo(xml::XmlNode* mpd_node);
133 
134  // Same as AddStaticMpdInfo() but for 'dynamic' MPDs.
135  void AddDynamicMpdInfo(xml::XmlNode* mpd_node);
136 
137  float GetStaticMpdDuration(xml::XmlNode* mpd_node);
138 
139  // Set MPD attributes for dynamic profile MPD. Uses non-zero |mpd_options_| as
140  // well as various calculations to set attributes for the MPD.
141  void SetDynamicMpdAttributes(xml::XmlNode* mpd_node);
142 
143  // Gets the earliest, normalized segment timestamp. Returns true if
144  // successful, false otherwise.
145  bool GetEarliestTimestamp(double* timestamp_seconds);
146 
147  MpdType type_;
148  MpdOptions mpd_options_;
149  std::list<AdaptationSet*> adaptation_sets_;
150  STLElementDeleter<std::list<AdaptationSet*> > adaptation_sets_deleter_;
151 
152  std::list<std::string> base_urls_;
153  std::string availability_start_time_;
154 
155  base::AtomicSequenceNumber adaptation_set_counter_;
156  base::AtomicSequenceNumber representation_counter_;
157 
158  // By default, this returns the current time. This can be injected for
159  // testing.
160  scoped_ptr<base::Clock> clock_;
161 
162  DISALLOW_COPY_AND_ASSIGN(MpdBuilder);
163 };
164 
168  public:
169  // The role for this AdaptationSet. These values are used to add a Role
170  // element to the AdaptationSet with schemeIdUri=urn:mpeg:dash:role:2011.
171  // See ISO/IEC 23009-1:2012 section 5.8.5.5.
172  enum Role {
173  kRoleCaption,
174  kRoleSubtitle,
175  kRoleMain,
176  kRoleAlternate,
177  kRoleSupplementary,
178  kRoleCommentary,
179  kRoleDub
180  };
181 
182  virtual ~AdaptationSet();
183 
190  virtual Representation* AddRepresentation(const MediaInfo& media_info);
191 
201  virtual void AddContentProtectionElement(
202  const ContentProtectionElement& element);
203 
215  virtual void UpdateContentProtectionPssh(const std::string& drm_uuid,
216  const std::string& pssh);
217 
222  virtual void AddRole(Role role);
223 
228  xml::scoped_xml_ptr<xmlNode> GetXml();
229 
235  virtual void ForceSetSegmentAlignment(bool segment_alignment);
236 
242  virtual void SetGroup(int group_number);
243 
245  virtual int Group() const;
246 
247  // Must be unique in the Period.
248  uint32_t id() const { return id_; }
249 
261  void OnNewSegmentForRepresentation(uint32_t representation_id,
262  uint64_t start_time,
263  uint64_t duration);
264 
277  void OnSetFrameRateForRepresentation(uint32_t representation_id,
278  uint32_t frame_duration,
279  uint32_t timescale);
280 
281  protected:
289  AdaptationSet(uint32_t adaptation_set_id,
290  const std::string& lang,
291  const MpdOptions& mpd_options,
292  MpdBuilder::MpdType mpd_type,
293  base::AtomicSequenceNumber* representation_counter);
294 
295  private:
296  friend class MpdBuilder;
297  template <MpdBuilder::MpdType type>
298  friend class MpdBuilderTest;
299 
300  // kSegmentAlignmentUnknown means that it is uncertain if the
301  // (sub)segments are aligned or not.
302  // kSegmentAlignmentTrue means that it is certain that the all the (current)
303  // segments added to the adaptation set are aligned.
304  // kSegmentAlignmentFalse means that it is it is certain that some segments
305  // are not aligned. This is useful to disable the computation for
306  // segment alignment, once it is certain that some segments are not aligned.
307  enum SegmentAligmentStatus {
308  kSegmentAlignmentUnknown,
309  kSegmentAlignmentTrue,
310  kSegmentAlignmentFalse
311  };
312 
313  // This maps Representations (IDs) to a list of start times of the segments.
314  // e.g.
315  // If Representation 1 has start time 0, 100, 200 and Representation 2 has
316  // start times 0, 200, 400, then the map contains:
317  // 1 -> [0, 100, 200]
318  // 2 -> [0, 200, 400]
319  typedef std::map<uint32_t, std::list<uint64_t> > RepresentationTimeline;
320 
321  // Gets the earliest, normalized segment timestamp. Returns true if
322  // successful, false otherwise.
323  bool GetEarliestTimestamp(double* timestamp_seconds);
324 
332  void CheckLiveSegmentAlignment(uint32_t representation_id,
333  uint64_t start_time,
334  uint64_t duration);
335 
336  // Checks representation_segment_start_times_ and sets segments_aligned_.
337  // Use this for VOD, do not use for Live.
338  void CheckVodSegmentAlignment();
339 
340  // Records the framerate of a Representation.
341  void RecordFrameRate(uint32_t frame_duration, uint32_t timescale);
342 
343  std::list<ContentProtectionElement> content_protection_elements_;
344  std::list<Representation*> representations_;
345  STLElementDeleter<std::list<Representation*> > representations_deleter_;
346 
347  base::AtomicSequenceNumber* const representation_counter_;
348 
349  const uint32_t id_;
350  const std::string lang_;
351  const MpdOptions& mpd_options_;
352  const MpdBuilder::MpdType mpd_type_;
353 
354  // The group attribute for the AdaptationSet. If the value is negative,
355  // no group number is specified.
356  // Note that group 0 is a special group number.
357  int group_;
358 
359  // Video widths and heights of Representations. Note that this is a set; if
360  // there is only 1 resolution, then @width & @height should be set, otherwise
361  // @maxWidth & @maxHeight should be set for DASH IOP.
362  std::set<uint32_t> video_widths_;
363  std::set<uint32_t> video_heights_;
364 
365  // Video representations' frame rates.
366  // The frame rate notation for MPD is <integer>/<integer> (where the
367  // denominator is optional). This means the frame rate could be non-whole
368  // rational value, therefore the key is of type double.
369  // Value is <integer>/<integer> in string form.
370  // So, key == CalculatedValue(value)
371  std::map<double, std::string> video_frame_rates_;
372 
373  // contentType attribute of AdaptationSet.
374  // Determined by examining the MediaInfo passed to AddRepresentation().
375  std::string content_type_;
376 
377  // This does not have to be a set, it could be a list or vector because all we
378  // really care is whether there is more than one entry.
379  // Contains one entry if all the Representations have the same picture aspect
380  // ratio (@par attribute for AdaptationSet).
381  // There will be more than one entry if there are multiple picture aspect
382  // ratios.
383  // The @par attribute should only be set if there is exactly one entry
384  // in this set.
385  std::set<std::string> picture_aspect_ratio_;
386 
387  // The roles of this AdaptationSet.
388  std::set<Role> roles_;
389 
390  // True iff all the segments are aligned.
391  SegmentAligmentStatus segments_aligned_;
392  bool force_set_segment_alignment_;
393 
394  // Keeps track of segment start times of Representations.
395  // For VOD, this will not be cleared, all the segment start times are
396  // stored in this. This should not out-of-memory for a reasonable length
397  // video and reasonable subsegment length.
398  // For Live, the entries are deleted (see CheckLiveSegmentAlignment()
399  // implementation comment) because storing the entire timeline is not
400  // reasonable and may cause an out-of-memory problem.
401  RepresentationTimeline representation_segment_start_times_;
402 
403  DISALLOW_COPY_AND_ASSIGN(AdaptationSet);
404 };
405 
407  public:
410 
415  virtual void OnNewSegmentForRepresentation(uint64_t start_time,
416  uint64_t duration) = 0;
417 
422  virtual void OnSetFrameRateForRepresentation(uint32_t frame_duration,
423  uint32_t timescale) = 0;
424 };
425 
429  public:
430  enum SuppressFlag {
431  kSuppressWidth = 1,
432  kSuppressHeight = 2,
433  kSuppressFrameRate = 4,
434  };
435 
436  virtual ~Representation();
437 
441  bool Init();
442 
453  virtual void AddContentProtectionElement(
454  const ContentProtectionElement& element);
455 
467  virtual void UpdateContentProtectionPssh(const std::string& drm_uuid,
468  const std::string& pssh);
469 
478  virtual void AddNewSegment(uint64_t start_time,
479  uint64_t duration,
480  uint64_t size);
481 
487  virtual void SetSampleDuration(uint32_t sample_duration);
488 
490  xml::scoped_xml_ptr<xmlNode> GetXml();
491 
500  void SuppressOnce(SuppressFlag flag);
501 
503  uint32_t id() const { return id_; }
504 
505  protected:
515  const MediaInfo& media_info,
516  const MpdOptions& mpd_options,
517  uint32_t representation_id,
518  scoped_ptr<RepresentationStateChangeListener> state_change_listener);
519 
520  private:
521  friend class AdaptationSet;
522  template <MpdBuilder::MpdType type>
523  friend class MpdBuilderTest;
524 
525  bool AddLiveInfo(xml::RepresentationXmlNode* representation);
526 
527  // Returns true if |media_info_| has required fields to generate a valid
528  // Representation. Otherwise returns false.
529  bool HasRequiredMediaInfoFields();
530 
531  // Return false if the segment should be considered a new segment. True if the
532  // segment is contiguous.
533  bool IsContiguous(uint64_t start_time,
534  uint64_t duration,
535  uint64_t size) const;
536 
537  // Remove elements from |segment_infos_| if
538  // mpd_options_.time_shift_buffer_depth is specified. Increments
539  // |start_number_| by the number of segments removed.
540  void SlideWindow();
541 
542  // Note: Because 'mimeType' is a required field for a valid MPD, these return
543  // strings.
544  std::string GetVideoMimeType() const;
545  std::string GetAudioMimeType() const;
546  std::string GetTextMimeType() const;
547 
548  // Gets the earliest, normalized segment timestamp. Returns true if
549  // successful, false otherwise.
550  bool GetEarliestTimestamp(double* timestamp_seconds);
551 
552  // Init() checks that only one of VideoInfo, AudioInfo, or TextInfo is set. So
553  // any logic using this can assume only one set.
554  MediaInfo media_info_;
555  std::list<ContentProtectionElement> content_protection_elements_;
556  std::list<SegmentInfo> segment_infos_;
557 
558  const uint32_t id_;
559  std::string mime_type_;
560  std::string codecs_;
561  BandwidthEstimator bandwidth_estimator_;
562  const MpdOptions& mpd_options_;
563 
564  // startNumber attribute for SegmentTemplate.
565  // Starts from 1.
566  uint32_t start_number_;
567 
568  // If this is not null, then Representation is responsible for calling the
569  // right methods at right timings.
570  scoped_ptr<RepresentationStateChangeListener> state_change_listener_;
571 
572  // Bit vector for tracking witch attributes should not be output.
573  int output_suppression_flags_;
574 
575  DISALLOW_COPY_AND_ASSIGN(Representation);
576 };
577 
578 } // namespace edash_packager
579 
580 #endif // MPD_BASE_MPD_BUILDER_H_
MpdType type() const
Definition: mpd_builder.h:93
virtual void AddNewSegment(uint64_t start_time, uint64_t duration, uint64_t size)
AdaptationSet(uint32_t adaptation_set_id, const std::string &lang, const MpdOptions &mpd_options, MpdBuilder::MpdType mpd_type, base::AtomicSequenceNumber *representation_counter)
Definition: mpd_builder.cc:669
Defines Mpd Options.
Definition: mpd_options.h:17
virtual int Group() const
Definition: mpd_builder.cc:841
virtual AdaptationSet * AddAdaptationSet(const std::string &lang)
Definition: mpd_builder.cc:413
xml::scoped_xml_ptr< xmlNode > GetXml()
Define an abstract file interface.
Definition: file.h:23
static void MakePathsRelativeToMpd(const std::string &mpd_path, MediaInfo *media_info)
Definition: mpd_builder.cc:641
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:58
virtual void ForceSetSegmentAlignment(bool segment_alignment)
Definition: mpd_builder.cc:831
virtual void SetSampleDuration(uint32_t sample_duration)
void AddBaseUrl(const std::string &base_url)
Definition: mpd_builder.cc:409
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
Representation(const MediaInfo &media_info, const MpdOptions &mpd_options, uint32_t representation_id, scoped_ptr< RepresentationStateChangeListener > state_change_listener)
virtual void SetGroup(int group_number)
Definition: mpd_builder.cc:837
virtual void OnNewSegmentForRepresentation(uint64_t start_time, uint64_t duration)=0
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
virtual void OnSetFrameRateForRepresentation(uint32_t frame_duration, uint32_t timescale)=0
RepresentationType in MPD.
Definition: xml_node.h:128
bool WriteMpdToFile(media::File *output_file)
Definition: mpd_builder.cc:423
void OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)
Definition: mpd_builder.cc:863
virtual Representation * AddRepresentation(const MediaInfo &media_info)
Definition: mpd_builder.cc:688
xml::scoped_xml_ptr< xmlNode > GetXml()
Definition: mpd_builder.cc:754
void SuppressOnce(SuppressFlag flag)
void InjectClockForTesting(scoped_ptr< base::Clock > clock)
This is for testing.
Definition: mpd_builder.h:105
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
Definition: mpd_builder.cc:738
virtual bool ToString(std::string *output)
Definition: mpd_builder.cc:428
virtual void AddRole(Role role)
Definition: mpd_builder.cc:744
MpdBuilder(MpdType type, const MpdOptions &mpd_options)
Definition: mpd_builder.cc:401
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
Definition: mpd_builder.cc:732
void OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)
Definition: mpd_builder.cc:852