Move DerivePixelWidthHeight to video_util.cc
Change-Id: I14df8b39fb58078635f08377f4177a45e341be79
This commit is contained in:
parent
c257113e08
commit
edd776eea2
|
@ -108,6 +108,8 @@
|
||||||
'timestamp.h',
|
'timestamp.h',
|
||||||
'video_stream_info.cc',
|
'video_stream_info.cc',
|
||||||
'video_stream_info.h',
|
'video_stream_info.h',
|
||||||
|
'video_util.cc',
|
||||||
|
'video_util.h',
|
||||||
'widevine_key_source.cc',
|
'widevine_key_source.cc',
|
||||||
'widevine_key_source.h',
|
'widevine_key_source.h',
|
||||||
'widevine_pssh_generator.cc',
|
'widevine_pssh_generator.cc',
|
||||||
|
@ -188,6 +190,7 @@
|
||||||
'test/fake_prng.h', # For rsa_key_unittest
|
'test/fake_prng.h', # For rsa_key_unittest
|
||||||
'test/rsa_test_data.cc', # For rsa_key_unittest
|
'test/rsa_test_data.cc', # For rsa_key_unittest
|
||||||
'test/rsa_test_data.h', # For rsa_key_unittest
|
'test/rsa_test_data.h', # For rsa_key_unittest
|
||||||
|
'video_util_unittest.cc',
|
||||||
'widevine_key_source_unittest.cc',
|
'widevine_key_source_unittest.cc',
|
||||||
],
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#include "packager/media/base/video_util.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
uint64_t CalculateGCD(uint64_t a, uint64_t b) {
|
||||||
|
while (b != 0) {
|
||||||
|
uint64_t temp = a;
|
||||||
|
a = b;
|
||||||
|
b = temp % b;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReducePixelWidthHeight(uint64_t* pixel_width, uint64_t* pixel_height) {
|
||||||
|
if (*pixel_width == 0 || *pixel_height == 0)
|
||||||
|
return;
|
||||||
|
const uint64_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
|
||||||
|
while (true) {
|
||||||
|
uint64_t gcd = CalculateGCD(*pixel_width, *pixel_height);
|
||||||
|
*pixel_width /= gcd;
|
||||||
|
*pixel_height /= gcd;
|
||||||
|
// Both width and height needs to be 32 bit or less.
|
||||||
|
if (*pixel_width <= kMaxUint32 && *pixel_height <= kMaxUint32)
|
||||||
|
break;
|
||||||
|
*pixel_width >>= 1;
|
||||||
|
*pixel_height >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
namespace media {
|
||||||
|
|
||||||
|
void DerivePixelWidthHeight(uint32_t frame_width,
|
||||||
|
uint32_t frame_height,
|
||||||
|
uint32_t display_width,
|
||||||
|
uint32_t display_height,
|
||||||
|
uint32_t* pixel_width,
|
||||||
|
uint32_t* pixel_height) {
|
||||||
|
// DAR = PAR * FAR => PAR = DAR / FAR.
|
||||||
|
// Thus:
|
||||||
|
// pixel_width display_width frame_width
|
||||||
|
// ----------- = ------------- / -----------
|
||||||
|
// pixel_height display_height frame_height
|
||||||
|
// So:
|
||||||
|
// pixel_width display_width x frame_height
|
||||||
|
// ----------- = ------------------------------
|
||||||
|
// pixel_height display_height x frame_width
|
||||||
|
uint64_t pixel_width_unreduced =
|
||||||
|
static_cast<uint64_t>(display_width) * frame_height;
|
||||||
|
uint64_t pixel_height_unreduced =
|
||||||
|
static_cast<uint64_t>(display_height) * frame_width;
|
||||||
|
ReducePixelWidthHeight(&pixel_width_unreduced, &pixel_height_unreduced);
|
||||||
|
*pixel_width = pixel_width_unreduced;
|
||||||
|
*pixel_height = pixel_height_unreduced;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace media
|
||||||
|
} // namespace shaka
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#ifndef PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
|
||||||
|
#define PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
namespace media {
|
||||||
|
|
||||||
|
// Derive pixel aspect ratio from Display Aspect Ratio and Frame Aspect Ratio.
|
||||||
|
void DerivePixelWidthHeight(uint32_t frame_width,
|
||||||
|
uint32_t frame_height,
|
||||||
|
uint32_t display_width,
|
||||||
|
uint32_t display_height,
|
||||||
|
uint32_t* pixel_width,
|
||||||
|
uint32_t* pixel_height);
|
||||||
|
|
||||||
|
} // namespace media
|
||||||
|
} // namespace shaka
|
||||||
|
|
||||||
|
#endif // PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#include "packager/media/base/video_util.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using ::testing::TestWithParam;
|
||||||
|
using ::testing::Values;
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
namespace media {
|
||||||
|
|
||||||
|
struct SarTestData {
|
||||||
|
uint32_t frame_width;
|
||||||
|
uint32_t frame_height;
|
||||||
|
uint32_t display_width;
|
||||||
|
uint32_t display_height;
|
||||||
|
uint32_t expected_pixel_width;
|
||||||
|
uint32_t expected_pixel_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VideoUtilSarTest : public TestWithParam<SarTestData> {};
|
||||||
|
|
||||||
|
TEST_P(VideoUtilSarTest, Test) {
|
||||||
|
const SarTestData& test_data = GetParam();
|
||||||
|
|
||||||
|
uint32_t pixel_width;
|
||||||
|
uint32_t pixel_height;
|
||||||
|
DerivePixelWidthHeight(test_data.frame_width, test_data.frame_height,
|
||||||
|
test_data.display_width, test_data.display_height,
|
||||||
|
&pixel_width, &pixel_height);
|
||||||
|
EXPECT_EQ(pixel_width, test_data.expected_pixel_width);
|
||||||
|
EXPECT_EQ(pixel_height, test_data.expected_pixel_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(VideoUtilSarTestInstance,
|
||||||
|
VideoUtilSarTest,
|
||||||
|
Values(SarTestData{1024, 768, 1024, 768, 1, 1},
|
||||||
|
SarTestData{1024, 384, 1024, 768, 1, 2},
|
||||||
|
SarTestData{512, 768, 1024, 768, 2, 1},
|
||||||
|
SarTestData{1024, 1024, 1024, 768, 4, 3},
|
||||||
|
SarTestData{123, 567, 1024, 768, 252, 41}));
|
||||||
|
|
||||||
|
} // namespace media
|
||||||
|
} // namespace shaka
|
|
@ -5,7 +5,6 @@
|
||||||
#include "packager/media/formats/mp4/mp4_media_parser.h"
|
#include "packager/media/formats/mp4/mp4_media_parser.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include "packager/base/callback.h"
|
#include "packager/base/callback.h"
|
||||||
#include "packager/base/callback_helpers.h"
|
#include "packager/base/callback_helpers.h"
|
||||||
|
@ -21,6 +20,7 @@
|
||||||
#include "packager/media/base/media_sample.h"
|
#include "packager/media/base/media_sample.h"
|
||||||
#include "packager/media/base/rcheck.h"
|
#include "packager/media/base/rcheck.h"
|
||||||
#include "packager/media/base/video_stream_info.h"
|
#include "packager/media/base/video_stream_info.h"
|
||||||
|
#include "packager/media/base/video_util.h"
|
||||||
#include "packager/media/codecs/ac3_audio_util.h"
|
#include "packager/media/codecs/ac3_audio_util.h"
|
||||||
#include "packager/media/codecs/av1_codec_configuration_record.h"
|
#include "packager/media/codecs/av1_codec_configuration_record.h"
|
||||||
#include "packager/media/codecs/avc_decoder_configuration_record.h"
|
#include "packager/media/codecs/avc_decoder_configuration_record.h"
|
||||||
|
@ -115,56 +115,6 @@ Codec ObjectTypeToCodec(ObjectType object_type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t CalculateGCD(uint64_t a, uint64_t b) {
|
|
||||||
while (b != 0) {
|
|
||||||
uint64_t temp = a;
|
|
||||||
a = b;
|
|
||||||
b = temp % b;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReducePixelWidthHeight(uint64_t* pixel_width, uint64_t* pixel_height) {
|
|
||||||
if (*pixel_width == 0 || *pixel_height == 0)
|
|
||||||
return;
|
|
||||||
const uint64_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
|
|
||||||
while (true) {
|
|
||||||
uint64_t gcd = CalculateGCD(*pixel_width, *pixel_height);
|
|
||||||
*pixel_width /= gcd;
|
|
||||||
*pixel_height /= gcd;
|
|
||||||
// Both width and height needs to be 32 bit or less.
|
|
||||||
if (*pixel_width <= kMaxUint32 && *pixel_height <= kMaxUint32)
|
|
||||||
break;
|
|
||||||
*pixel_width >>= 1;
|
|
||||||
*pixel_height >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derive pixel aspect ratio from Display Aspect Ratio and Frame Aspect Ratio.
|
|
||||||
// DAR = PAR * FAR => PAR = DAR / FAR.
|
|
||||||
// Thus:
|
|
||||||
// pixel_width display_width frame_width
|
|
||||||
// ----------- = ------------- / -----------
|
|
||||||
// pixel_height display_height frame_height
|
|
||||||
// So:
|
|
||||||
// pixel_width display_width x frame_width
|
|
||||||
// ----------- = ------------------------------
|
|
||||||
// pixel_height display_height x frame_height
|
|
||||||
void DerivePixelWidthHeight(uint32_t frame_width,
|
|
||||||
uint32_t frame_height,
|
|
||||||
uint32_t display_width,
|
|
||||||
uint32_t display_height,
|
|
||||||
uint32_t* pixel_width,
|
|
||||||
uint32_t* pixel_height) {
|
|
||||||
uint64_t pixel_width_unreduced =
|
|
||||||
static_cast<uint64_t>(display_width) * frame_height;
|
|
||||||
uint64_t pixel_height_unreduced =
|
|
||||||
static_cast<uint64_t>(display_height) * frame_width;
|
|
||||||
ReducePixelWidthHeight(&pixel_width_unreduced, &pixel_height_unreduced);
|
|
||||||
*pixel_width = pixel_width_unreduced;
|
|
||||||
*pixel_height = pixel_height_unreduced;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t kNanosecondsPerSecond = 1000000000ull;
|
const uint64_t kNanosecondsPerSecond = 1000000000ull;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "packager/media/formats/webm/webm_video_client.h"
|
#include "packager/media/formats/webm/webm_video_client.h"
|
||||||
|
|
||||||
#include "packager/base/logging.h"
|
#include "packager/base/logging.h"
|
||||||
|
#include "packager/media/base/video_util.h"
|
||||||
#include "packager/media/codecs/av1_codec_configuration_record.h"
|
#include "packager/media/codecs/av1_codec_configuration_record.h"
|
||||||
#include "packager/media/codecs/vp_codec_configuration_record.h"
|
#include "packager/media/codecs/vp_codec_configuration_record.h"
|
||||||
#include "packager/media/formats/webm/webm_constants.h"
|
#include "packager/media/formats/webm/webm_constants.h"
|
||||||
|
@ -14,15 +15,6 @@ namespace {
|
||||||
// Timestamps are represented in double in WebM. Convert to uint64_t in us.
|
// Timestamps are represented in double in WebM. Convert to uint64_t in us.
|
||||||
const uint32_t kWebMTimeScale = 1000000u;
|
const uint32_t kWebMTimeScale = 1000000u;
|
||||||
|
|
||||||
int64_t GetGreatestCommonDivisor(int64_t a, int64_t b) {
|
|
||||||
while (b) {
|
|
||||||
int64_t temp = b;
|
|
||||||
b = a % b;
|
|
||||||
a = temp;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
@ -118,12 +110,12 @@ std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
|
||||||
LOG(ERROR) << "Unsupported display unit type " << display_unit_;
|
LOG(ERROR) << "Unsupported display unit type " << display_unit_;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate sample aspect ratio.
|
// Calculate sample aspect ratio.
|
||||||
int64_t sar_x = display_width_ * height_after_crop;
|
uint32_t pixel_width;
|
||||||
int64_t sar_y = display_height_ * width_after_crop;
|
uint32_t pixel_height;
|
||||||
int64_t gcd = GetGreatestCommonDivisor(sar_x, sar_y);
|
DerivePixelWidthHeight(width_after_crop, height_after_crop, display_width_,
|
||||||
sar_x /= gcd;
|
display_height_, &pixel_width, &pixel_height);
|
||||||
sar_y /= gcd;
|
|
||||||
|
|
||||||
// |codec_private| may be overriden later for some codecs, e.g. VP9 since for
|
// |codec_private| may be overriden later for some codecs, e.g. VP9 since for
|
||||||
// VP9, the format for MP4 and WebM are different; MP4 format is used as the
|
// VP9, the format for MP4 and WebM are different; MP4 format is used as the
|
||||||
|
@ -131,8 +123,8 @@ std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
|
||||||
return std::make_shared<VideoStreamInfo>(
|
return std::make_shared<VideoStreamInfo>(
|
||||||
track_num, kWebMTimeScale, 0, video_codec, H26xStreamFormat::kUnSpecified,
|
track_num, kWebMTimeScale, 0, video_codec, H26xStreamFormat::kUnSpecified,
|
||||||
codec_string, codec_private.data(), codec_private.size(),
|
codec_string, codec_private.data(), codec_private.size(),
|
||||||
width_after_crop, height_after_crop, sar_x, sar_y, 0, 0, std::string(),
|
width_after_crop, height_after_crop, pixel_width, pixel_height, 0, 0,
|
||||||
is_encrypted);
|
std::string(), is_encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
VPCodecConfigurationRecord WebMVideoClient::GetVpCodecConfig(
|
VPCodecConfigurationRecord WebMVideoClient::GetVpCodecConfig(
|
||||||
|
|
Loading…
Reference in New Issue