1 // Copyright (c) 2016 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 #ifndef SRC_VIDEO_PARSER_H_ 9 #define SRC_VIDEO_PARSER_H_ 10 11 #include <cassert> 12 #include <cstdint> 13 14 #include "src/bool_parser.h" 15 #include "src/colour_parser.h" 16 #include "src/float_parser.h" 17 #include "src/int_parser.h" 18 #include "src/master_value_parser.h" 19 #include "src/projection_parser.h" 20 #include "webm/callback.h" 21 #include "webm/dom_types.h" 22 #include "webm/id.h" 23 #include "webm/reader.h" 24 #include "webm/status.h" 25 26 namespace webm { 27 28 // Spec reference: 29 // http://matroska.org/technical/specs/index.html#Video 30 // http://www.webmproject.org/docs/container/#Video 31 class VideoParser : public MasterValueParser<Video> { 32 public: VideoParser()33 VideoParser() 34 : MasterValueParser<Video>( 35 MakeChild<IntParser<FlagInterlaced>>(Id::kFlagInterlaced, 36 &Video::interlaced), 37 MakeChild<IntParser<StereoMode>>(Id::kStereoMode, 38 &Video::stereo_mode), 39 MakeChild<UnsignedIntParser>(Id::kAlphaMode, &Video::alpha_mode), 40 MakeChild<UnsignedIntParser>(Id::kPixelWidth, &Video::pixel_width), 41 MakeChild<UnsignedIntParser>(Id::kPixelHeight, 42 &Video::pixel_height), 43 MakeChild<UnsignedIntParser>(Id::kPixelCropBottom, 44 &Video::pixel_crop_bottom), 45 MakeChild<UnsignedIntParser>(Id::kPixelCropTop, 46 &Video::pixel_crop_top), 47 MakeChild<UnsignedIntParser>(Id::kPixelCropLeft, 48 &Video::pixel_crop_left), 49 MakeChild<UnsignedIntParser>(Id::kPixelCropRight, 50 &Video::pixel_crop_right), 51 MakeChild<UnsignedIntParser>(Id::kDisplayWidth, 52 &Video::display_width) 53 .NotifyOnParseComplete(), 54 MakeChild<UnsignedIntParser>(Id::kDisplayHeight, 55 &Video::display_height) 56 .NotifyOnParseComplete(), 57 MakeChild<IntParser<DisplayUnit>>(Id::kDisplayUnit, 58 &Video::display_unit), 59 MakeChild<IntParser<AspectRatioType>>(Id::kAspectRatioType, 60 &Video::aspect_ratio_type), 61 MakeChild<FloatParser>(Id::kFrameRate, &Video::frame_rate), 62 MakeChild<ColourParser>(Id::kColour, &Video::colour), 63 MakeChild<ProjectionParser>(Id::kProjection, &Video::projection)) {} 64 Init(const ElementMetadata & metadata,std::uint64_t max_size)65 Status Init(const ElementMetadata& metadata, 66 std::uint64_t max_size) override { 67 display_width_has_value_ = false; 68 display_height_has_value_ = false; 69 70 return MasterValueParser::Init(metadata, max_size); 71 } 72 InitAfterSeek(const Ancestory & child_ancestory,const ElementMetadata & child_metadata)73 void InitAfterSeek(const Ancestory& child_ancestory, 74 const ElementMetadata& child_metadata) override { 75 display_width_has_value_ = false; 76 display_height_has_value_ = false; 77 78 return MasterValueParser::InitAfterSeek(child_ancestory, child_metadata); 79 } 80 Feed(Callback * callback,Reader * reader,std::uint64_t * num_bytes_read)81 Status Feed(Callback* callback, Reader* reader, 82 std::uint64_t* num_bytes_read) override { 83 const Status status = 84 MasterValueParser::Feed(callback, reader, num_bytes_read); 85 if (status.completed_ok()) { 86 FixMissingDisplaySize(); 87 } 88 return status; 89 } 90 91 protected: OnChildParsed(const ElementMetadata & metadata)92 void OnChildParsed(const ElementMetadata& metadata) override { 93 assert(metadata.id == Id::kDisplayWidth || 94 metadata.id == Id::kDisplayHeight); 95 96 if (metadata.id == Id::kDisplayWidth) { 97 display_width_has_value_ = metadata.size > 0; 98 } else { 99 display_height_has_value_ = metadata.size > 0; 100 } 101 } 102 103 private: 104 bool display_width_has_value_; 105 bool display_height_has_value_; 106 FixMissingDisplaySize()107 void FixMissingDisplaySize() { 108 if (!display_width_has_value_) { 109 *mutable_value()->display_width.mutable_value() = 110 value().pixel_width.value(); 111 } 112 113 if (!display_height_has_value_) { 114 *mutable_value()->display_height.mutable_value() = 115 value().pixel_height.value(); 116 } 117 } 118 }; 119 120 } // namespace webm 121 122 #endif // SRC_VIDEO_PARSER_H_ 123