5#include <packager/media/formats/webm/webm_video_client.h>
14#include <absl/log/log.h>
16#include <packager/macros/logging.h>
17#include <packager/media/base/buffer_writer.h>
18#include <packager/media/base/fourccs.h>
19#include <packager/media/base/stream_info.h>
20#include <packager/media/base/video_stream_info.h>
21#include <packager/media/base/video_util.h>
22#include <packager/media/codecs/av1_codec_configuration_record.h>
23#include <packager/media/codecs/vp_codec_configuration_record.h>
24#include <packager/media/formats/webm/webm_constants.h>
25#include <packager/media/formats/webm/webm_parser.h>
30const int32_t kWebMTimeScale = 1000000;
37WebMVideoClient::WebMVideoClient() {}
39WebMVideoClient::~WebMVideoClient() {}
53 matrix_coefficients_ = -1;
54 bits_per_channel_ = -1;
55 chroma_subsampling_horz_ = -1;
56 chroma_subsampling_vert_ = -1;
57 chroma_siting_horz_ = -1;
58 chroma_siting_vert_ = -1;
60 transfer_characteristics_ = -1;
61 color_primaries_ = -1;
66 const std::string& codec_id,
67 const std::vector<uint8_t>& codec_private,
69 std::string codec_string;
70 Codec video_codec = kUnknownCodec;
71 if (codec_id ==
"V_AV1") {
72 video_codec = kCodecAV1;
77 if (!av1_config.
Parse(codec_private)) {
78 LOG(ERROR) <<
"Failed to parse AV1 codec_private.";
82 }
else if (codec_id ==
"V_VP8") {
83 video_codec = kCodecVP8;
85 }
else if (codec_id ==
"V_VP9") {
86 video_codec = kCodecVP9;
89 LOG(ERROR) <<
"Unsupported video codec_id " << codec_id;
93 if (pixel_width_ <= 0 || pixel_height_ <= 0)
97 if (crop_bottom_ == -1)
103 if (crop_left_ == -1)
106 if (crop_right_ == -1)
109 if (display_unit_ == -1)
112 uint16_t width_after_crop = pixel_width_ - (crop_left_ + crop_right_);
113 uint16_t height_after_crop = pixel_height_ - (crop_top_ + crop_bottom_);
115 if (display_unit_ == 0) {
116 if (display_width_ <= 0)
117 display_width_ = width_after_crop;
118 if (display_height_ <= 0)
119 display_height_ = height_after_crop;
120 }
else if (display_unit_ == 3) {
121 if (display_width_ <= 0 || display_height_ <= 0)
124 LOG(ERROR) <<
"Unsupported display unit type " << display_unit_;
129 uint32_t pixel_width;
130 uint32_t pixel_height;
131 DerivePixelWidthHeight(width_after_crop, height_after_crop, display_width_,
132 display_height_, &pixel_width, &pixel_height);
137 auto video_stream_info = std::make_shared<VideoStreamInfo>(
138 track_num, kWebMTimeScale, 0, video_codec, H26xStreamFormat::kUnSpecified,
139 codec_string, codec_private.data(), codec_private.size(),
140 width_after_crop, height_after_crop, pixel_width, pixel_height, 0, 0, 0,
141 0, 0, std::string(), is_encrypted);
144 if ((video_codec == kCodecVP8 || video_codec == kCodecVP9) &&
147 if (!colr_data.empty()) {
148 video_stream_info->set_colr_data(colr_data.data(), colr_data.size());
152 return video_stream_info;
156 const std::vector<uint8_t>& codec_private) {
159 if (matrix_coefficients_ != -1) {
160 vp_config.set_matrix_coefficients(matrix_coefficients_);
162 if (bits_per_channel_ != -1) {
163 vp_config.set_bit_depth(bits_per_channel_);
165 if (chroma_subsampling_horz_ != -1 && chroma_subsampling_vert_ != -1) {
166 vp_config.SetChromaSubsampling(chroma_subsampling_horz_,
167 chroma_subsampling_vert_);
169 if (chroma_siting_horz_ != -1 && chroma_siting_vert_ != -1) {
170 vp_config.SetChromaLocation(chroma_siting_horz_, chroma_siting_vert_);
172 if (color_range_ != -1) {
173 vp_config.set_video_full_range_flag(color_range_ == 2);
175 if (transfer_characteristics_ != -1) {
176 vp_config.set_transfer_characteristics(transfer_characteristics_);
178 if (color_primaries_ != -1) {
179 vp_config.set_color_primaries(color_primaries_);
185 return id == kWebMIdColor ||
id == kWebMIdProjection
187 : WebMParserClient::OnListStart(
id);
190bool WebMVideoClient::OnListEnd(
int id) {
191 return id == kWebMIdColor ||
id == kWebMIdProjection
193 : WebMParserClient::OnListEnd(
id);
196bool WebMVideoClient::OnUInt(
int id, int64_t val) {
197 int64_t* dst =
nullptr;
200 case kWebMIdPixelWidth:
203 case kWebMIdPixelHeight:
204 dst = &pixel_height_;
206 case kWebMIdPixelCropTop:
209 case kWebMIdPixelCropBottom:
212 case kWebMIdPixelCropLeft:
215 case kWebMIdPixelCropRight:
218 case kWebMIdDisplayWidth:
219 dst = &display_width_;
221 case kWebMIdDisplayHeight:
222 dst = &display_height_;
224 case kWebMIdDisplayUnit:
225 dst = &display_unit_;
227 case kWebMIdAlphaMode:
230 case kWebMIdColorMatrixCoefficients:
231 dst = &matrix_coefficients_;
233 case kWebMIdColorBitsPerChannel:
234 dst = &bits_per_channel_;
236 case kWebMIdColorChromaSubsamplingHorz:
237 dst = &chroma_subsampling_horz_;
239 case kWebMIdColorChromaSubsamplingVert:
240 dst = &chroma_subsampling_vert_;
242 case kWebMIdColorChromaSitingHorz:
243 dst = &chroma_siting_horz_;
245 case kWebMIdColorChromaSitingVert:
246 dst = &chroma_siting_vert_;
248 case kWebMIdColorRange:
251 case kWebMIdColorTransferCharacteristics:
252 dst = &transfer_characteristics_;
254 case kWebMIdColorPrimaries:
255 dst = &color_primaries_;
257 case kWebMIdColorMaxCLL:
258 case kWebMIdColorMaxFALL:
259 NOTIMPLEMENTED() <<
"HDR is not supported yet.";
261 case kWebMIdProjectionType:
262 LOG(WARNING) <<
"Ignoring ProjectionType with value " << val;
269 LOG(ERROR) <<
"Multiple values for id " << std::hex <<
id <<
" specified ("
270 << *dst <<
" and " << val <<
")";
278bool WebMVideoClient::OnBinary(
int ,
285bool WebMVideoClient::OnFloat(
int ,
double ) {
291 return color_range_ != -1 || color_primaries_ != -1 ||
292 transfer_characteristics_ != -1 || matrix_coefficients_ != -1;
298 writer.
AppendInt(
static_cast<uint32_t
>(0));
304 (color_primaries_ != -1) ?
static_cast<uint16_t
>(color_primaries_) : 1;
305 uint16_t transfer = (transfer_characteristics_ != -1)
306 ?
static_cast<uint16_t
>(transfer_characteristics_)
308 uint16_t matrix = (matrix_coefficients_ != -1)
309 ?
static_cast<uint16_t
>(matrix_coefficients_)
317 uint8_t full_range_flag = 0;
318 if (color_range_ != -1) {
319 full_range_flag = (color_range_ == 2) ? 1 : 0;
323 const uint8_t* buffer = writer.
Buffer();
324 size_t buffer_size = writer.Size();
326 std::vector<uint8_t> data(buffer, buffer + buffer_size);
327 uint32_t box_size =
static_cast<uint32_t
>(data.size());
330 data[0] = (box_size >> 24) & 0xFF;
331 data[1] = (box_size >> 16) & 0xFF;
332 data[2] = (box_size >> 8) & 0xFF;
333 data[3] = box_size & 0xFF;
All the methods that are virtual are virtual for mocking.