parent
ab8485c5b7
commit
3afe761637
|
@ -21,6 +21,10 @@ if(MSVC)
|
|||
add_compile_options(/wd4251)
|
||||
# Silence a warning about constant conditional expressions.
|
||||
add_compile_options(/wd4127)
|
||||
# We use long-jumps in subtitle_composer.cc due to API of libpng
|
||||
add_compile_options(/wd4611)
|
||||
# need /bigobj for box definitions
|
||||
add_compile_options(/bigobj)
|
||||
|
||||
# Packager's macro for Windows-specific code.
|
||||
add_definitions(-DOS_WIN)
|
||||
|
|
|
@ -43,7 +43,14 @@ std::string TempFileName() {
|
|||
} // namespace
|
||||
|
||||
bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path) {
|
||||
auto temp_dir_path = std::filesystem::u8path(temp_dir);
|
||||
std::filesystem::path temp_dir_path;
|
||||
|
||||
if (temp_dir.empty()) {
|
||||
temp_dir_path = std::filesystem::temp_directory_path();
|
||||
} else {
|
||||
temp_dir_path = std::filesystem::u8path(temp_dir);
|
||||
}
|
||||
|
||||
*temp_file_path = (temp_dir_path / TempFileName()).string();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ bool LocalFile::Open() {
|
|||
// first if it needs to be created.
|
||||
auto parent_path = file_path.parent_path();
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::is_directory(parent_path, ec)) {
|
||||
if (parent_path != "" && !std::filesystem::is_directory(parent_path, ec)) {
|
||||
if (!std::filesystem::create_directories(parent_path, ec)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
|
||||
namespace shaka {
|
||||
|
||||
std::vector<KVPair> SplitStringIntoKeyValuePairs(std::string_view str) {
|
||||
std::vector<KVPair> SplitStringIntoKeyValuePairs(std::string_view str,
|
||||
char kv_separator,
|
||||
char list_separator) {
|
||||
std::vector<KVPair> kv_pairs;
|
||||
|
||||
// Edge case: 0 pairs.
|
||||
|
@ -18,9 +20,9 @@ std::vector<KVPair> SplitStringIntoKeyValuePairs(std::string_view str) {
|
|||
return kv_pairs;
|
||||
}
|
||||
|
||||
std::vector<std::string> kv_strings = absl::StrSplit(str, '&');
|
||||
std::vector<std::string> kv_strings = absl::StrSplit(str, list_separator);
|
||||
for (const auto& kv_string : kv_strings) {
|
||||
KVPair pair = absl::StrSplit(kv_string, absl::MaxSplits('=', 1));
|
||||
KVPair pair = absl::StrSplit(kv_string, absl::MaxSplits(kv_separator, 1));
|
||||
kv_pairs.push_back(pair);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
namespace shaka {
|
||||
|
||||
typedef std::pair<std::string, std::string> KVPair;
|
||||
std::vector<KVPair> SplitStringIntoKeyValuePairs(std::string_view str);
|
||||
std::vector<KVPair> SplitStringIntoKeyValuePairs(std::string_view str,
|
||||
char kv_separator = '=',
|
||||
char list_separator = '&');
|
||||
|
||||
} // namespace shaka
|
||||
|
|
|
@ -39,4 +39,7 @@
|
|||
/// AES block size in bytes, regardless of key size.
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
#define DVLOG_IF(verboselevel, condition) \
|
||||
static_cast<void>(0), !(condition) ? (void)0 : VLOG(verboselevel)
|
||||
|
||||
#endif // PACKAGER_MACROS_H_
|
||||
|
|
|
@ -64,6 +64,8 @@ target_link_libraries(media_base
|
|||
glog
|
||||
hex_parser
|
||||
mbedtls
|
||||
mpd_media_info_proto
|
||||
utils_clock
|
||||
status
|
||||
widevine_protos
|
||||
LibXml2)
|
||||
|
|
|
@ -41,7 +41,7 @@ class AesCryptor {
|
|||
virtual bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv) = 0;
|
||||
|
||||
virtual size_t RequiredCiphertextSize(size_t plaintext_size) {
|
||||
virtual size_t RequiredOutputSize(size_t plaintext_size) {
|
||||
return plaintext_size;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,11 @@ bool AesCbcDecryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
|||
return SetIv(iv);
|
||||
}
|
||||
|
||||
size_t AesCbcDecryptor::RequiredOutputSize(size_t plaintext_size) {
|
||||
// mbedtls requires a buffer large enough for one extra block.
|
||||
return plaintext_size + AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
|
||||
size_t ciphertext_size,
|
||||
uint8_t* plaintext,
|
||||
|
|
|
@ -46,6 +46,8 @@ class AesCbcDecryptor : public AesCryptor {
|
|||
/// @{
|
||||
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv) override;
|
||||
|
||||
size_t RequiredOutputSize(size_t plaintext_size) override;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
|
|
@ -125,7 +125,7 @@ bool AesCbcEncryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
|||
return SetIv(iv);
|
||||
}
|
||||
|
||||
size_t AesCbcEncryptor::RequiredCiphertextSize(size_t plaintext_size) {
|
||||
size_t AesCbcEncryptor::RequiredOutputSize(size_t plaintext_size) {
|
||||
// mbedtls requires a buffer large enough for one extra block.
|
||||
return plaintext_size + NumPaddingBytes(plaintext_size) + AES_BLOCK_SIZE;
|
||||
}
|
||||
|
@ -136,8 +136,7 @@ bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
|
|||
size_t* ciphertext_size) {
|
||||
const size_t residual_block_size = plaintext_size % AES_BLOCK_SIZE;
|
||||
const size_t num_padding_bytes = NumPaddingBytes(plaintext_size);
|
||||
const size_t required_ciphertext_size =
|
||||
RequiredCiphertextSize(plaintext_size);
|
||||
const size_t required_ciphertext_size = RequiredOutputSize(plaintext_size);
|
||||
|
||||
if (*ciphertext_size < required_ciphertext_size) {
|
||||
LOG(ERROR) << "Expecting output size of at least "
|
||||
|
|
|
@ -84,7 +84,7 @@ class AesCbcEncryptor : public AesCryptor {
|
|||
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv) override;
|
||||
|
||||
size_t RequiredCiphertextSize(size_t plaintext_size) override;
|
||||
size_t RequiredOutputSize(size_t plaintext_size) override;
|
||||
|
||||
private:
|
||||
bool CryptInternal(const uint8_t* plaintext,
|
||||
|
|
|
@ -20,12 +20,8 @@ const bool kInitialEncryptionInfo = true;
|
|||
const int64_t kStartTime = 0;
|
||||
} // namespace
|
||||
|
||||
uint64_t DefaultMuxerClock() {
|
||||
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
}
|
||||
|
||||
Muxer::Muxer(const MuxerOptions& options)
|
||||
: options_(options), clock_(DefaultMuxerClock) {
|
||||
: options_(options), clock_(new Clock) {
|
||||
// "$" is only allowed if the output file name is a template, which is used to
|
||||
// support one file per Representation per Period when there are Ad Cues.
|
||||
if (options_.output_file_name.find("$") != std::string::npos)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "packager/media/base/muxer_options.h"
|
||||
#include "packager/media/event/muxer_listener.h"
|
||||
#include "packager/media/event/progress_listener.h"
|
||||
#include "packager/mpd/base/mpd_builder.h"
|
||||
#include "packager/status/status.h"
|
||||
|
||||
namespace shaka {
|
||||
|
@ -23,9 +24,6 @@ namespace media {
|
|||
|
||||
class MediaSample;
|
||||
|
||||
/// Returns seconds since January 1, 1970, UTC.
|
||||
typedef uint64_t (*MuxerClock)();
|
||||
|
||||
/// Muxer is responsible for taking elementary stream samples and producing
|
||||
/// media containers. An optional KeySource can be provided to Muxer
|
||||
/// to generate encrypted outputs.
|
||||
|
@ -56,7 +54,7 @@ class Muxer : public MediaHandler {
|
|||
/// If no clock is injected, the code uses std::chrone::system_clock::now()
|
||||
/// to generate the time-stamps.
|
||||
/// @param clock is the Clock to be injected.
|
||||
void set_clock(MuxerClock clock) { clock_ = clock; }
|
||||
void set_clock(Clock* clock) { clock_.reset(clock); }
|
||||
|
||||
protected:
|
||||
/// @name MediaHandler implementation overrides.
|
||||
|
@ -69,7 +67,13 @@ class Muxer : public MediaHandler {
|
|||
const MuxerOptions& options() const { return options_; }
|
||||
MuxerListener* muxer_listener() { return muxer_listener_.get(); }
|
||||
ProgressListener* progress_listener() { return progress_listener_.get(); }
|
||||
uint64_t Now() const { return clock_(); }
|
||||
|
||||
uint64_t Now() const {
|
||||
auto duration = clock_->now().time_since_epoch();
|
||||
auto seconds =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(duration).count();
|
||||
return static_cast<uint64_t>(seconds);
|
||||
}
|
||||
|
||||
private:
|
||||
Muxer(const Muxer&) = delete;
|
||||
|
@ -108,8 +112,7 @@ class Muxer : public MediaHandler {
|
|||
|
||||
std::unique_ptr<MuxerListener> muxer_listener_;
|
||||
std::unique_ptr<ProgressListener> progress_listener_;
|
||||
// An external injected clock, can be NULL.
|
||||
MuxerClock clock_ = nullptr;
|
||||
std::unique_ptr<Clock> clock_;
|
||||
|
||||
// In VOD single segment case with Ad Cues, |output_file_name| is allowed to
|
||||
// be a template. In this case, there will be NumAdCues + 1 files generated.
|
||||
|
|
|
@ -300,7 +300,7 @@ Status EncryptionHandler::ProcessMediaSample(
|
|||
}
|
||||
|
||||
size_t ciphertext_size =
|
||||
encryptor_->RequiredCiphertextSize(clear_sample->data_size());
|
||||
encryptor_->RequiredOutputSize(clear_sample->data_size());
|
||||
|
||||
std::shared_ptr<uint8_t> cipher_sample_data(new uint8_t[ciphertext_size],
|
||||
std::default_delete<uint8_t[]>());
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
#include "packager/media/crypto/sample_aes_ec3_cryptor.h"
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "packager/media/base/buffer_reader.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -5,4 +5,11 @@
|
|||
# https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
# Subdirectories with their own CMakeLists.txt, all of whose targets are built.
|
||||
add_subdirectory(dvb)
|
||||
add_subdirectory(packed_audio)
|
||||
add_subdirectory(ttml)
|
||||
add_subdirectory(mp4)
|
||||
add_subdirectory(mp2t)
|
||||
add_subdirectory(webm)
|
||||
add_subdirectory(webvtt)
|
||||
add_subdirectory(wvm)
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2020 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
|
||||
|
||||
|
||||
# Copyright 2016 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
|
||||
|
||||
|
||||
add_library(dvb STATIC
|
||||
dvb_image.cc
|
||||
dvb_image.h
|
||||
dvb_sub_parser.cc
|
||||
dvb_sub_parser.h
|
||||
subtitle_composer.cc
|
||||
subtitle_composer.h
|
||||
)
|
||||
target_link_libraries(dvb
|
||||
file
|
||||
media_base
|
||||
widevine_protos
|
||||
manifest_base
|
||||
mpd_media_info_proto
|
||||
png_static
|
||||
absl::flags
|
||||
absl::strings
|
||||
absl::str_format
|
||||
glog
|
||||
)
|
||||
|
||||
add_executable(dvb_unittest
|
||||
dvb_image_unittest.cc
|
||||
dvb_sub_parser_unittest.cc
|
||||
subtitle_composer_unittest.cc
|
||||
)
|
||||
|
||||
target_link_libraries(dvb_unittest
|
||||
file
|
||||
file_test_util
|
||||
test_data_util
|
||||
absl::flags
|
||||
media_event
|
||||
dvb
|
||||
gmock
|
||||
gtest
|
||||
gtest_main)
|
||||
|
||||
add_test(NAME dvb_unittest COMMAND dvb_unittest)
|
|
@ -1,45 +0,0 @@
|
|||
# Copyright 2020 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
|
||||
|
||||
{
|
||||
'variables': {
|
||||
'shaka_code': 1,
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'dvb',
|
||||
'type': '<(component)',
|
||||
'sources': [
|
||||
'dvb_image.cc',
|
||||
'dvb_image.h',
|
||||
'dvb_sub_parser.cc',
|
||||
'dvb_sub_parser.h',
|
||||
'subtitle_composer.cc',
|
||||
'subtitle_composer.h',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../base/media_base.gyp:media_base',
|
||||
'../../../third_party/libpng/libpng.gyp:libpng',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'dvb_unittest',
|
||||
'type': '<(gtest_target_type)',
|
||||
'sources': [
|
||||
'dvb_image_unittest.cc',
|
||||
'dvb_sub_parser_unittest.cc',
|
||||
'subtitle_composer_unittest.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../../testing/gtest.gyp:gtest',
|
||||
'../../../testing/gmock.gyp:gmock',
|
||||
'../../event/media_event.gyp:mock_muxer_listener',
|
||||
'../../test/media_test.gyp:media_test_support',
|
||||
'dvb',
|
||||
]
|
||||
},
|
||||
],
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
#include <cstring>
|
||||
#include <tuple>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
@ -134,7 +134,7 @@ RgbaColor DvbImageColorSpace::GetColor(BitDepth bit_depth,
|
|||
break;
|
||||
default:
|
||||
// Windows can't detect that all enums are handled and doesn't like
|
||||
// NOTREACHED.
|
||||
// NOTIMPLEMENTED.
|
||||
return kNoColor;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ RgbaColor DvbImageColorSpace::GetColorRaw(BitDepth bit_depth,
|
|||
case BitDepth::k8Bit:
|
||||
return color_map_8_[entry_id];
|
||||
}
|
||||
// Not reached, but Windows doesn't like NOTREACHED.
|
||||
// Not reached, but Windows doesn't like NOTIMPLEMENTED.
|
||||
return kNoColor;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/formats/mp2t/mp2t_common.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <png.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/text_sample.h"
|
||||
#include "packager/media/formats/dvb/dvb_image.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
# Copyright 2014 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
|
||||
|
||||
add_library(mp2t STATIC
|
||||
ac3_header.cc
|
||||
ac3_header.h
|
||||
adts_header.cc
|
||||
adts_header.h
|
||||
audio_header.h
|
||||
continuity_counter.cc
|
||||
continuity_counter.h
|
||||
es_parser_audio.cc
|
||||
es_parser_audio.h
|
||||
es_parser_dvb.cc
|
||||
es_parser_dvb.h
|
||||
es_parser_h264.cc
|
||||
es_parser_h264.h
|
||||
es_parser_h265.cc
|
||||
es_parser_h265.h
|
||||
es_parser_h26x.cc
|
||||
es_parser_h26x.h
|
||||
es_parser.h
|
||||
mp2t_media_parser.cc
|
||||
mp2t_media_parser.h
|
||||
mpeg1_header.cc
|
||||
mpeg1_header.h
|
||||
pes_packet.cc
|
||||
pes_packet.h
|
||||
pes_packet_generator.cc
|
||||
pes_packet_generator.h
|
||||
program_map_table_writer.cc
|
||||
program_map_table_writer.h
|
||||
ts_muxer.cc
|
||||
ts_muxer.h
|
||||
ts_packet.cc
|
||||
ts_packet.h
|
||||
ts_packet_writer_util.cc
|
||||
ts_packet_writer_util.h
|
||||
ts_section_pat.cc
|
||||
ts_section_pat.h
|
||||
ts_section_pes.cc
|
||||
ts_section_pes.h
|
||||
ts_section_pmt.cc
|
||||
ts_section_pmt.h
|
||||
ts_section_psi.cc
|
||||
ts_section_psi.h
|
||||
ts_segmenter.cc
|
||||
ts_segmenter.h
|
||||
ts_stream_type.h
|
||||
ts_writer.cc
|
||||
ts_writer.h
|
||||
)
|
||||
|
||||
target_link_libraries(mp2t
|
||||
media_base
|
||||
glog
|
||||
media_crypto
|
||||
hex_parser
|
||||
media_codecs
|
||||
dvb
|
||||
)
|
||||
|
||||
add_executable(mp2t_unittest
|
||||
ac3_header_unittest.cc
|
||||
adts_header_unittest.cc
|
||||
es_parser_h264_unittest.cc
|
||||
es_parser_h26x_unittest.cc
|
||||
mp2t_media_parser_unittest.cc
|
||||
mpeg1_header_unittest.cc
|
||||
pes_packet_generator_unittest.cc
|
||||
program_map_table_writer_unittest.cc
|
||||
ts_segmenter_unittest.cc
|
||||
ts_writer_unittest.cc
|
||||
)
|
||||
|
||||
target_link_libraries(mp2t_unittest
|
||||
mp2t
|
||||
file
|
||||
file_test_util
|
||||
test_data_util
|
||||
absl::flags
|
||||
media_event
|
||||
media_handler_test_base
|
||||
mock_muxer_listener
|
||||
glog
|
||||
gmock
|
||||
gtest
|
||||
gtest_main)
|
||||
|
||||
add_test(NAME mp2t_unittest COMMAND mp2t_unittest)
|
||||
|
|
@ -44,9 +44,9 @@ const size_t kFrameSizeCodeTable[][3] = {
|
|||
// frame size code.
|
||||
// @return the size of the frame (header + payload).
|
||||
size_t CalcFrameSize(uint8_t fscod, uint8_t frmsizecod) {
|
||||
const size_t kNumFscode = arraysize(kAc3SampleRateTable);
|
||||
const size_t kNumFscode = std::size(kAc3SampleRateTable);
|
||||
DCHECK_LT(fscod, kNumFscode);
|
||||
DCHECK_LT(frmsizecod, arraysize(kFrameSizeCodeTable));
|
||||
DCHECK_LT(frmsizecod, std::size(kFrameSizeCodeTable));
|
||||
// The order of frequencies are reversed in |kFrameSizeCodeTable| compared to
|
||||
// |kAc3SampleRateTable|.
|
||||
const int index = kNumFscode - 1 - fscod;
|
||||
|
@ -85,16 +85,16 @@ bool Ac3Header::Parse(const uint8_t* audio_frame, size_t audio_frame_size) {
|
|||
uint16_t crc1;
|
||||
RCHECK(frame.ReadBits(16, &crc1));
|
||||
RCHECK(frame.ReadBits(2, &fscod_));
|
||||
RCHECK(fscod_ < arraysize(kAc3SampleRateTable));
|
||||
RCHECK(fscod_ < std::size(kAc3SampleRateTable));
|
||||
RCHECK(frame.ReadBits(6, &frmsizecod_));
|
||||
RCHECK(frmsizecod_ < arraysize(kFrameSizeCodeTable));
|
||||
RCHECK(frmsizecod_ < std::size(kFrameSizeCodeTable));
|
||||
|
||||
// bsi: bit stream information section.
|
||||
RCHECK(frame.ReadBits(5, &bsid_));
|
||||
RCHECK(frame.ReadBits(3, &bsmod_));
|
||||
|
||||
RCHECK(frame.ReadBits(3, &acmod_));
|
||||
RCHECK(acmod_ < arraysize(kAc3NumChannelsTable));
|
||||
RCHECK(acmod_ < std::size(kAc3NumChannelsTable));
|
||||
// If 3 front channels.
|
||||
if ((acmod_ & 0x01) && (acmod_ != 0x01))
|
||||
RCHECK(frame.SkipBits(2)); // cmixlev.
|
||||
|
@ -149,12 +149,12 @@ uint8_t Ac3Header::GetObjectType() const {
|
|||
}
|
||||
|
||||
uint32_t Ac3Header::GetSamplingFrequency() const {
|
||||
DCHECK_LT(fscod_, arraysize(kAc3SampleRateTable));
|
||||
DCHECK_LT(fscod_, std::size(kAc3SampleRateTable));
|
||||
return kAc3SampleRateTable[fscod_];
|
||||
}
|
||||
|
||||
uint8_t Ac3Header::GetNumChannels() const {
|
||||
DCHECK_LT(acmod_, arraysize(kAc3NumChannelsTable));
|
||||
DCHECK_LT(acmod_, std::size(kAc3NumChannelsTable));
|
||||
return kAc3NumChannelsTable[acmod_] + (lfeon_ ? 1 : 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include "packager/utils/hex_parser.h"
|
||||
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/formats/mp2t/ac3_header.h"
|
||||
|
||||
using ::testing::ElementsAreArray;
|
||||
|
@ -51,11 +53,11 @@ namespace mp2t {
|
|||
class Ac3HeaderTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(base::HexStringToBytes(kValidPartialAc3Frame44100Hz,
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kValidPartialAc3Frame44100Hz,
|
||||
&ac3_frame_44100_hz_));
|
||||
ASSERT_TRUE(
|
||||
base::HexStringToBytes(kValidPartialAc3Frame48kHz, &ac3_frame_48k_hz_));
|
||||
ASSERT_TRUE(base::HexStringToBytes(kValidPartialAc3FrameSixChannels,
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kValidPartialAc3Frame48kHz,
|
||||
&ac3_frame_48k_hz_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kValidPartialAc3FrameSixChannels,
|
||||
&ac3_frame_six_channels_));
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ const size_t kAdtsHeaderMinSize = 7;
|
|||
const int kAdtsFrequencyTable[] = {96000, 88200, 64000, 48000, 44100,
|
||||
32000, 24000, 22050, 16000, 12000,
|
||||
11025, 8000, 7350};
|
||||
const size_t kAdtsFrequencyTableSize = arraysize(kAdtsFrequencyTable);
|
||||
const size_t kAdtsFrequencyTableSize = std::size(kAdtsFrequencyTable);
|
||||
|
||||
// The following conversion table is extracted from ISO 14496 Part 3 -
|
||||
// Table 1.17 - Channel Configuration.
|
||||
const int kAdtsNumChannelsTable[] = {0, 1, 2, 3, 4, 5, 6, 8};
|
||||
const size_t kAdtsNumChannelsTableSize = arraysize(kAdtsNumChannelsTable);
|
||||
const size_t kAdtsNumChannelsTableSize = std::size(kAdtsNumChannelsTable);
|
||||
} // namespace
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/formats/mp2t/adts_header.h"
|
||||
#include "packager/utils/hex_parser.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -41,7 +42,7 @@ namespace mp2t {
|
|||
class AdtsHeaderTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(base::HexStringToBytes(kValidAdtsFrame, &adts_frame_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kValidAdtsFrame, &adts_frame_));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -65,11 +66,11 @@ TEST_F(AdtsHeaderTest, ParseSuccess) {
|
|||
EXPECT_EQ(kExpectedNumChannels, adts_header.GetNumChannels());
|
||||
std::vector<uint8_t> audio_specific_config;
|
||||
adts_header.GetAudioSpecificConfig(&audio_specific_config);
|
||||
EXPECT_EQ(arraysize(kExpectedAudioSpecificConfig),
|
||||
EXPECT_EQ(std::size(kExpectedAudioSpecificConfig),
|
||||
audio_specific_config.size());
|
||||
EXPECT_EQ(std::vector<uint8_t>(kExpectedAudioSpecificConfig,
|
||||
kExpectedAudioSpecificConfig +
|
||||
arraysize(kExpectedAudioSpecificConfig)),
|
||||
std::size(kExpectedAudioSpecificConfig)),
|
||||
audio_specific_config);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
|
||||
#define PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include <functional>
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
@ -20,9 +19,9 @@ namespace mp2t {
|
|||
|
||||
class EsParser {
|
||||
public:
|
||||
typedef base::Callback<void(std::shared_ptr<StreamInfo>)> NewStreamInfoCB;
|
||||
typedef base::Callback<void(std::shared_ptr<MediaSample>)> EmitSampleCB;
|
||||
typedef base::Callback<void(std::shared_ptr<TextSample>)> EmitTextSampleCB;
|
||||
typedef std::function<void(std::shared_ptr<StreamInfo>)> NewStreamInfoCB;
|
||||
typedef std::function<void(std::shared_ptr<MediaSample>)> EmitSampleCB;
|
||||
typedef std::function<void(std::shared_ptr<TextSample>)> EmitTextSampleCB;
|
||||
|
||||
EsParser(uint32_t pid) : pid_(pid) {}
|
||||
virtual ~EsParser() {}
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
#include <algorithm>
|
||||
#include <list>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include <absl/strings/escaping.h>
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/audio_timestamp_helper.h"
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
|
@ -102,7 +103,8 @@ EsParserAudio::EsParserAudio(uint32_t pid,
|
|||
} else if (stream_type == TsStreamType::kMpeg1Audio) {
|
||||
audio_header_.reset(new Mpeg1Header);
|
||||
} else {
|
||||
DCHECK_EQ(stream_type, TsStreamType::kAdtsAac);
|
||||
DCHECK_EQ(static_cast<int>(stream_type),
|
||||
static_cast<int>(TsStreamType::kAdtsAac));
|
||||
audio_header_.reset(new AdtsHeader);
|
||||
}
|
||||
}
|
||||
|
@ -135,8 +137,9 @@ bool EsParserAudio::Parse(const uint8_t* buf,
|
|||
DVLOG(LOG_LEVEL_ES) << "syncword @ pos=" << es_position
|
||||
<< " frame_size=" << audio_header_->GetFrameSize();
|
||||
DVLOG(LOG_LEVEL_ES) << "header: "
|
||||
<< base::HexEncode(frame_ptr,
|
||||
audio_header_->GetHeaderSize());
|
||||
<< absl::BytesToHexString(absl::string_view(
|
||||
reinterpret_cast<const char*>(frame_ptr),
|
||||
audio_header_->GetHeaderSize()));
|
||||
|
||||
// Do not process the frame if this one is a partial frame.
|
||||
int remaining_size = raw_es_size - es_position;
|
||||
|
@ -167,7 +170,7 @@ bool EsParserAudio::Parse(const uint8_t* buf,
|
|||
sample->set_pts(current_pts);
|
||||
sample->set_dts(current_pts);
|
||||
sample->set_duration(frame_duration);
|
||||
emit_sample_cb_.Run(sample);
|
||||
emit_sample_cb_(sample);
|
||||
|
||||
// Update the PTS of the next frame.
|
||||
audio_timestamp_helper_->AddFrames(audio_header_->GetSamplesPerFrame());
|
||||
|
@ -247,7 +250,7 @@ bool EsParserAudio::UpdateAudioConfiguration(const AudioHeader& audio_header) {
|
|||
}
|
||||
|
||||
// Audio config notification.
|
||||
new_stream_info_cb_.Run(last_audio_decoder_config_);
|
||||
new_stream_info_cb_(last_audio_decoder_config_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include <functional>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/audio_stream_info.h"
|
||||
#include "packager/media/base/byte_queue.h"
|
||||
#include "packager/media/formats/mp2t/es_parser.h"
|
||||
|
|
|
@ -76,7 +76,7 @@ bool EsParserDvb::Parse(const uint8_t* buf,
|
|||
info->AddSubStream(pair.first, {pair.second});
|
||||
}
|
||||
|
||||
new_stream_info_cb_.Run(info);
|
||||
new_stream_info_cb_(info);
|
||||
}
|
||||
|
||||
// TODO: Handle buffering and multiple reads? All content so far has been
|
||||
|
@ -91,7 +91,7 @@ bool EsParserDvb::Flush() {
|
|||
|
||||
for (auto sample : samples) {
|
||||
sample->set_sub_stream_index(pair.first);
|
||||
emit_sample_cb_.Run(sample);
|
||||
emit_sample_cb_(sample);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -127,7 +127,7 @@ bool EsParserDvb::ParseInternal(const uint8_t* data, size_t size, int64_t pts) {
|
|||
&samples));
|
||||
for (auto sample : samples) {
|
||||
sample->set_sub_stream_index(page_id);
|
||||
emit_sample_cb_.Run(sample);
|
||||
emit_sample_cb_(sample);
|
||||
}
|
||||
|
||||
RCHECK(reader.SkipBytes(segment_length));
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include <functional>
|
||||
#include "packager/media/base/byte_queue.h"
|
||||
#include "packager/media/formats/dvb/dvb_sub_parser.h"
|
||||
#include "packager/media/formats/mp2t/es_parser.h"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
#include "packager/media/base/video_stream_info.h"
|
||||
|
@ -57,7 +57,7 @@ bool EsParserH264::ProcessNalu(const Nalu& nalu,
|
|||
decoder_config_check_pending_ = true;
|
||||
else if (status == H264Parser::kUnsupportedStream)
|
||||
// Indicate the stream can't be parsed.
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
else
|
||||
return false;
|
||||
break;
|
||||
|
@ -70,7 +70,7 @@ bool EsParserH264::ProcessNalu(const Nalu& nalu,
|
|||
decoder_config_check_pending_ = true;
|
||||
} else if (status == H264Parser::kUnsupportedStream) {
|
||||
// Indicate the stream can't be parsed.
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
} else {
|
||||
// Allow PPS parsing to fail if waiting for SPS.
|
||||
if (last_video_decoder_config_)
|
||||
|
@ -91,7 +91,7 @@ bool EsParserH264::ProcessNalu(const Nalu& nalu,
|
|||
video_slice_info->pps_id = shdr.pic_parameter_set_id;
|
||||
} else if (status == H264Parser::kUnsupportedStream) {
|
||||
// Indicate the stream can't be parsed.
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
} else {
|
||||
// Only accept an invalid SPS/PPS at the beginning when the stream
|
||||
// does not necessarily start with an SPS/PPS/IDR.
|
||||
|
@ -179,7 +179,7 @@ bool EsParserH264::UpdateVideoDecoderConfig(int pps_id) {
|
|||
DVLOG(1) << "log2_max_frame_num_minus4: " << sps->log2_max_frame_num_minus4;
|
||||
|
||||
// Video config notification.
|
||||
new_stream_info_cb_.Run(last_video_decoder_config_);
|
||||
new_stream_info_cb_(last_video_decoder_config_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H264_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/media/formats/mp2t/es_parser_h26x.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/bind.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include <functional>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
#include "packager/media/base/video_stream_info.h"
|
||||
|
@ -170,8 +170,8 @@ void EsParserH264Test::ProcessPesPackets(
|
|||
|
||||
EsParserH264 es_parser(
|
||||
0,
|
||||
base::Bind(&EsParserH264Test::NewVideoConfig, base::Unretained(this)),
|
||||
base::Bind(&EsParserH264Test::EmitSample, base::Unretained(this)));
|
||||
std::bind(&EsParserH264Test::NewVideoConfig, this, std::placeholders::_1),
|
||||
std::bind(&EsParserH264Test::EmitSample, this, std::placeholders::_1));
|
||||
|
||||
size_t au_idx = 0;
|
||||
for (size_t k = 0; k < pes_packets.size(); k++) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/offset_byte_queue.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
|
@ -60,7 +60,7 @@ bool EsParserH265::ProcessNalu(const Nalu& nalu,
|
|||
decoder_config_check_pending_ = true;
|
||||
else if (status == H265Parser::kUnsupportedStream)
|
||||
// Indicate the stream can't be parsed.
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
else
|
||||
return false;
|
||||
break;
|
||||
|
@ -73,7 +73,7 @@ bool EsParserH265::ProcessNalu(const Nalu& nalu,
|
|||
decoder_config_check_pending_ = true;
|
||||
} else if (status == H265Parser::kUnsupportedStream) {
|
||||
// Indicate the stream can't be parsed.
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
} else {
|
||||
// Allow PPS parsing to fail if waiting for SPS.
|
||||
if (last_video_decoder_config_)
|
||||
|
@ -95,7 +95,7 @@ bool EsParserH265::ProcessNalu(const Nalu& nalu,
|
|||
video_slice_info->pps_id = shdr.pic_parameter_set_id;
|
||||
} else if (status == H265Parser::kUnsupportedStream) {
|
||||
// Indicate the stream can't be parsed.
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
} else {
|
||||
// Only accept an invalid SPS/PPS at the beginning when the stream
|
||||
// does not necessarily start with an SPS/PPS/IDR.
|
||||
|
@ -179,7 +179,7 @@ bool EsParserH265::UpdateVideoDecoderConfig(int pps_id) {
|
|||
nalu_length_size, std::string(), false);
|
||||
|
||||
// Video config notification.
|
||||
new_stream_info_cb_.Run(last_video_decoder_config_);
|
||||
new_stream_info_cb_(last_video_decoder_config_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include <functional>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp2t/es_parser_h26x.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/numerics/safe_conversions.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/offset_byte_queue.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
|
@ -103,7 +102,7 @@ bool EsParserH26x::Flush() {
|
|||
pending_sample_duration_ = CalculateSampleDuration(pending_sample_pps_id_);
|
||||
}
|
||||
pending_sample_->set_duration(pending_sample_duration_);
|
||||
emit_sample_cb_.Run(std::move(pending_sample_));
|
||||
emit_sample_cb_(std::move(pending_sample_));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -342,7 +341,7 @@ bool EsParserH26x::EmitFrame(int64_t access_unit_pos,
|
|||
|
||||
pending_sample_duration_ = sample_duration;
|
||||
}
|
||||
emit_sample_cb_.Run(std::move(pending_sample_));
|
||||
emit_sample_cb_(std::move(pending_sample_));
|
||||
}
|
||||
pending_sample_ = media_sample;
|
||||
pending_sample_pps_id_ = pps_id;
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include <functional>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/codecs/nalu_reader.h"
|
||||
#include "packager/media/formats/mp2t/es_parser.h"
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/bind.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include <functional>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/stream_info.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
|
@ -113,7 +113,7 @@ class TestableEsParser : public EsParserH26x {
|
|||
bool UpdateVideoDecoderConfig(int pps_id) override {
|
||||
if (decoder_config_check_pending_) {
|
||||
EXPECT_EQ(kTestPpsId, pps_id);
|
||||
new_stream_info_cb_.Run(nullptr);
|
||||
new_stream_info_cb_(nullptr);
|
||||
decoder_config_check_pending_ = false;
|
||||
}
|
||||
return true;
|
||||
|
@ -241,7 +241,7 @@ std::vector<std::vector<uint8_t>> EsParserH26xTest::BuildSamplesData(
|
|||
es_data.end());
|
||||
|
||||
es_data.insert(es_data.begin(), kStartCode,
|
||||
kStartCode + arraysize(kStartCode));
|
||||
kStartCode + std::size(kStartCode));
|
||||
annex_b_sample_data.insert(annex_b_sample_data.end(), es_data.begin(),
|
||||
es_data.end());
|
||||
}
|
||||
|
@ -262,8 +262,8 @@ void EsParserH26xTest::RunTest(Nalu::CodecType codec_type,
|
|||
|
||||
TestableEsParser es_parser(
|
||||
codec_type,
|
||||
base::Bind(&EsParserH26xTest::NewVideoConfig, base::Unretained(this)),
|
||||
base::Bind(&EsParserH26xTest::EmitSample, base::Unretained(this)));
|
||||
std::bind(&EsParserH26xTest::NewVideoConfig, this, std::placeholders::_1),
|
||||
std::bind(&EsParserH26xTest::EmitSample, this, std::placeholders::_1));
|
||||
|
||||
int64_t timestamp = 0;
|
||||
for (const auto& sample_data :
|
||||
|
@ -292,7 +292,7 @@ TEST_F(EsParserH26xTest, H265BasicSupport) {
|
|||
kSeparator, kH265Aud, kH265Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ TEST_F(EsParserH26xTest, H265DeterminesAccessUnitsWithoutAUD) {
|
|||
kSeparator, kH265Sei, kH265Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(4u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ TEST_F(EsParserH26xTest, H265DoesNotStartOnRsv) {
|
|||
kSeparator, kH265Sei, kH265Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ TEST_F(EsParserH26xTest, H265SupportsNonZeroNuhLayerId) {
|
|||
kSeparator, kH265Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(5u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ TEST_F(EsParserH26xTest, H265WaitsForKeyFrame) {
|
|||
kSeparator, kH265Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ TEST_F(EsParserH26xTest, H265EmitsFramesWithNoStreamInfo) {
|
|||
kSeparator, kH265Sei, kH265Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_FALSE(has_stream_info_);
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ TEST_F(EsParserH26xTest, H265EmitsLastFrameWithNuhLayerId) {
|
|||
kSeparator, kH265Vcl, kH265Sei, kH265VclWithNuhLayer, kH265Rsv,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_FALSE(has_stream_info_);
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ TEST_F(EsParserH26xTest, H264BasicSupport) {
|
|||
kSeparator, kH264Aud, kH264Vcl,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH264, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH264, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
EXPECT_EQ(3u, media_samples_.size());
|
||||
|
@ -412,12 +412,12 @@ TEST_F(EsParserH26xTest, H264AudInAccessUnit) {
|
|||
|
||||
TestableEsParser es_parser(
|
||||
Nalu::kH264,
|
||||
base::Bind(&EsParserH26xTest::NewVideoConfig, base::Unretained(this)),
|
||||
base::Bind(&EsParserH26xTest::EmitSample, base::Unretained(this)));
|
||||
std::bind(&EsParserH26xTest::NewVideoConfig, this, std::placeholders::_1),
|
||||
std::bind(&EsParserH26xTest::EmitSample, this, std::placeholders::_1));
|
||||
|
||||
size_t sample_index = 0;
|
||||
for (const auto& sample_data :
|
||||
BuildSamplesData(Nalu::kH264, kData, arraysize(kData))) {
|
||||
BuildSamplesData(Nalu::kH264, kData, std::size(kData))) {
|
||||
// Duration of one 25fps video frame in 90KHz clock units.
|
||||
const uint32_t kMpegTicksPerFrame = 3600;
|
||||
const int64_t timestamp = kMpegTicksPerFrame * sample_index;
|
||||
|
@ -447,7 +447,7 @@ TEST_F(EsParserH26xTest, H264DeterminesAccessUnitsWithoutAUD) {
|
|||
kSeparator, kH264Sei, kH264VclFrame3,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH264, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH264, kData, std::size(kData));
|
||||
EXPECT_EQ(4u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ TEST_F(EsParserH26xTest, H264DoesNotStartOnRsv) {
|
|||
kSeparator, kH264Sei, kH264VclFrame2,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH264, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH264, kData, std::size(kData));
|
||||
EXPECT_EQ(3u, sample_count_);
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ TEST_F(EsParserH26xTest, H264ContainsOnlyOneFrame) {
|
|||
kH264VclKeyFrame,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH264, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH264, kData, std::size(kData));
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
EXPECT_EQ(1u, sample_count_);
|
||||
EXPECT_EQ(1u, media_samples_.size());
|
||||
|
@ -484,7 +484,7 @@ TEST_F(EsParserH26xTest, H265ContainsOnlyOneFrame) {
|
|||
kSeparator, kH265Aud, kH265Sps, kH265VclKeyFrame,
|
||||
};
|
||||
|
||||
RunTest(Nalu::kH265, kData, arraysize(kData));
|
||||
RunTest(Nalu::kH265, kData, std::size(kData));
|
||||
EXPECT_TRUE(has_stream_info_);
|
||||
EXPECT_EQ(1u, sample_count_);
|
||||
EXPECT_EQ(1u, media_samples_.size());
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
# Copyright 2014 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
|
||||
|
||||
{
|
||||
'variables': {
|
||||
'shaka_code': 1,
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'mp2t',
|
||||
'type': '<(component)',
|
||||
'sources': [
|
||||
'ac3_header.cc',
|
||||
'ac3_header.h',
|
||||
'adts_header.cc',
|
||||
'adts_header.h',
|
||||
'audio_header.h',
|
||||
'continuity_counter.cc',
|
||||
'continuity_counter.h',
|
||||
'es_parser_audio.cc',
|
||||
'es_parser_audio.h',
|
||||
'es_parser_dvb.cc',
|
||||
'es_parser_dvb.h',
|
||||
'es_parser_h264.cc',
|
||||
'es_parser_h264.h',
|
||||
'es_parser_h265.cc',
|
||||
'es_parser_h265.h',
|
||||
'es_parser_h26x.cc',
|
||||
'es_parser_h26x.h',
|
||||
'es_parser.h',
|
||||
'mp2t_media_parser.cc',
|
||||
'mp2t_media_parser.h',
|
||||
'mpeg1_header.cc',
|
||||
'mpeg1_header.h',
|
||||
'pes_packet.cc',
|
||||
'pes_packet.h',
|
||||
'pes_packet_generator.cc',
|
||||
'pes_packet_generator.h',
|
||||
'program_map_table_writer.cc',
|
||||
'program_map_table_writer.h',
|
||||
'ts_muxer.cc',
|
||||
'ts_muxer.h',
|
||||
'ts_packet.cc',
|
||||
'ts_packet.h',
|
||||
'ts_packet_writer_util.cc',
|
||||
'ts_packet_writer_util.h',
|
||||
'ts_section_pat.cc',
|
||||
'ts_section_pat.h',
|
||||
'ts_section_pes.cc',
|
||||
'ts_section_pes.h',
|
||||
'ts_section_pmt.cc',
|
||||
'ts_section_pmt.h',
|
||||
'ts_section_psi.cc',
|
||||
'ts_section_psi.h',
|
||||
'ts_segmenter.cc',
|
||||
'ts_segmenter.h',
|
||||
'ts_stream_type.h',
|
||||
'ts_writer.cc',
|
||||
'ts_writer.h',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../base/media_base.gyp:media_base',
|
||||
'../../crypto/crypto.gyp:crypto',
|
||||
'../../codecs/codecs.gyp:codecs',
|
||||
'../dvb/dvb.gyp:dvb',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'mp2t_unittest',
|
||||
'type': '<(gtest_target_type)',
|
||||
'sources': [
|
||||
'ac3_header_unittest.cc',
|
||||
'adts_header_unittest.cc',
|
||||
'es_parser_h264_unittest.cc',
|
||||
'es_parser_h26x_unittest.cc',
|
||||
'mp2t_media_parser_unittest.cc',
|
||||
'mpeg1_header_unittest.cc',
|
||||
'pes_packet_generator_unittest.cc',
|
||||
'program_map_table_writer_unittest.cc',
|
||||
'ts_segmenter_unittest.cc',
|
||||
'ts_writer_unittest.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../../testing/gtest.gyp:gtest',
|
||||
'../../../testing/gmock.gyp:gmock',
|
||||
'../../codecs/codecs.gyp:codecs',
|
||||
'../../event/media_event.gyp:mock_muxer_listener',
|
||||
'../../test/media_test.gyp:media_test_support',
|
||||
'mp2t',
|
||||
]
|
||||
},
|
||||
],
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "packager/base/bind.h"
|
||||
#include <functional>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/stream_info.h"
|
||||
#include "packager/media/base/text_sample.h"
|
||||
|
@ -160,10 +160,10 @@ void Mp2tMediaParser::Init(const InitCB& init_cb,
|
|||
const NewTextSampleCB& new_text_sample_cb,
|
||||
KeySource* decryption_key_source) {
|
||||
DCHECK(!is_initialized_);
|
||||
DCHECK(init_cb_.is_null());
|
||||
DCHECK(!init_cb.is_null());
|
||||
DCHECK(!new_media_sample_cb.is_null());
|
||||
DCHECK(!new_text_sample_cb.is_null());
|
||||
DCHECK(init_cb_ == nullptr);
|
||||
DCHECK(init_cb != nullptr);
|
||||
DCHECK(new_media_sample_cb != nullptr);
|
||||
DCHECK(new_text_sample_cb != nullptr);
|
||||
|
||||
init_cb_ = init_cb;
|
||||
new_media_sample_cb_ = new_media_sample_cb;
|
||||
|
@ -229,7 +229,8 @@ bool Mp2tMediaParser::Parse(const uint8_t* buf, int size) {
|
|||
ts_packet->pid() == TsSection::kPidPat) {
|
||||
// Create the PAT state here if needed.
|
||||
std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat(
|
||||
base::Bind(&Mp2tMediaParser::RegisterPmt, base::Unretained(this))));
|
||||
std::bind(&Mp2tMediaParser::RegisterPmt, this, std::placeholders::_1,
|
||||
std::placeholders::_2)));
|
||||
std::unique_ptr<PidState> pat_pid_state(new PidState(
|
||||
ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser)));
|
||||
pat_pid_state->Enable();
|
||||
|
@ -266,8 +267,9 @@ void Mp2tMediaParser::RegisterPmt(int program_number, int pmt_pid) {
|
|||
|
||||
// Create the PMT state here if needed.
|
||||
DVLOG(1) << "Create a new PMT parser";
|
||||
std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind(
|
||||
&Mp2tMediaParser::RegisterPes, base::Unretained(this), pmt_pid)));
|
||||
std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(std::bind(
|
||||
&Mp2tMediaParser::RegisterPes, this, pmt_pid, std::placeholders::_1,
|
||||
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)));
|
||||
std::unique_ptr<PidState> pmt_pid_state(
|
||||
new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser)));
|
||||
pmt_pid_state->Enable();
|
||||
|
@ -288,12 +290,12 @@ void Mp2tMediaParser::RegisterPes(int pmt_pid,
|
|||
// Create a stream parser corresponding to the stream type.
|
||||
PidState::PidType pid_type = PidState::kPidVideoPes;
|
||||
std::unique_ptr<EsParser> es_parser;
|
||||
auto on_new_stream = base::Bind(&Mp2tMediaParser::OnNewStreamInfo,
|
||||
base::Unretained(this), pes_pid);
|
||||
auto on_emit_media = base::Bind(&Mp2tMediaParser::OnEmitMediaSample,
|
||||
base::Unretained(this), pes_pid);
|
||||
auto on_emit_text = base::Bind(&Mp2tMediaParser::OnEmitTextSample,
|
||||
base::Unretained(this), pes_pid);
|
||||
auto on_new_stream = std::bind(&Mp2tMediaParser::OnNewStreamInfo, this,
|
||||
pes_pid, std::placeholders::_1);
|
||||
auto on_emit_media = std::bind(&Mp2tMediaParser::OnEmitMediaSample, this,
|
||||
pes_pid, std::placeholders::_1);
|
||||
auto on_emit_text = std::bind(&Mp2tMediaParser::OnEmitTextSample, this,
|
||||
pes_pid, std::placeholders::_1);
|
||||
switch (stream_type) {
|
||||
case TsStreamType::kAvc:
|
||||
es_parser.reset(new EsParserH264(pes_pid, on_new_stream, on_emit_media));
|
||||
|
@ -385,7 +387,7 @@ bool Mp2tMediaParser::FinishInitializationIfNeeded() {
|
|||
if (num_es && (all_stream_info.size() == num_es)) {
|
||||
// All stream configurations have been received. Initialization can
|
||||
// be completed.
|
||||
init_cb_.Run(all_stream_info);
|
||||
init_cb_(all_stream_info);
|
||||
DVLOG(1) << "Mpeg2TS stream parser initialization done";
|
||||
is_initialized_ = true;
|
||||
}
|
||||
|
@ -439,12 +441,12 @@ bool Mp2tMediaParser::EmitRemainingSamples() {
|
|||
// Buffer emission.
|
||||
for (const auto& pid_pair : pids_) {
|
||||
for (auto sample : pid_pair.second->media_sample_queue_) {
|
||||
RCHECK(new_media_sample_cb_.Run(pid_pair.first, sample));
|
||||
RCHECK(new_media_sample_cb_(pid_pair.first, sample));
|
||||
}
|
||||
pid_pair.second->media_sample_queue_.clear();
|
||||
|
||||
for (auto sample : pid_pair.second->text_sample_queue_) {
|
||||
RCHECK(new_text_sample_cb_.Run(pid_pair.first, sample));
|
||||
RCHECK(new_text_sample_cb_(pid_pair.first, sample));
|
||||
}
|
||||
pid_pair.second->text_sample_queue_.clear();
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ class Mp2tMediaParser : public MediaParser {
|
|||
const NewMediaSampleCB& new_media_sample_cb,
|
||||
const NewTextSampleCB& new_text_sample_cb,
|
||||
KeySource* decryption_key_source) override;
|
||||
bool Flush() override WARN_UNUSED_RESULT;
|
||||
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool Flush() override;
|
||||
[[nodiscard]] bool Parse(const uint8_t* buf, int size) override;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "packager/base/bind.h"
|
||||
#include "packager/base/bind_helpers.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include <functional>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/stream_info.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
|
@ -111,10 +110,11 @@ class Mp2tMediaParserTest : public testing::Test {
|
|||
|
||||
void InitializeParser() {
|
||||
parser_->Init(
|
||||
base::Bind(&Mp2tMediaParserTest::OnInit, base::Unretained(this)),
|
||||
base::Bind(&Mp2tMediaParserTest::OnNewSample, base::Unretained(this)),
|
||||
base::Bind(&Mp2tMediaParserTest::OnNewTextSample,
|
||||
base::Unretained(this)),
|
||||
std::bind(&Mp2tMediaParserTest::OnInit, this, std::placeholders::_1),
|
||||
std::bind(&Mp2tMediaParserTest::OnNewSample, this,
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
std::bind(&Mp2tMediaParserTest::OnNewTextSample, this,
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ const uint32_t kMpeg1SampleRateTable[][3] = {
|
|||
{48000, 24000, 12000},
|
||||
{32000, 16000, 8000}};
|
||||
// clang-format on
|
||||
const size_t kMpeg1SampleRateTableSize = arraysize(kMpeg1SampleRateTable);
|
||||
const size_t kMpeg1SampleRateTableSize = std::size(kMpeg1SampleRateTable);
|
||||
|
||||
static inline uint32_t Mpeg1SampleRate(uint8_t sr_idx, uint8_t version) {
|
||||
static int sr_version_indexes[] = {2, -1, 1, 0}; // {V2.5, RESERVED, V2, V1}
|
||||
|
@ -55,7 +55,7 @@ const uint32_t kMpeg1BitrateTable[][5] = {
|
|||
{ 416, 320, 256, 224, 144},
|
||||
{ 448, 384, 320, 256, 160}};
|
||||
// clang-format on
|
||||
const size_t kMpeg1BitrateTableSize = arraysize(kMpeg1BitrateTable);
|
||||
const size_t kMpeg1BitrateTableSize = std::size(kMpeg1BitrateTable);
|
||||
|
||||
static inline uint32_t Mpeg1BitRate(uint8_t btr_idx,
|
||||
uint8_t version,
|
||||
|
@ -186,7 +186,7 @@ void Mpeg1Header::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
|
|||
96000, 88200, 64000, 48000, 44100, 32000, 24000,
|
||||
22050, 16000, 12000, 11025, 8000, 7350};
|
||||
static const size_t kConfigFrequencyTableSize =
|
||||
arraysize(kConfigFrequencyTable);
|
||||
std::size(kConfigFrequencyTable);
|
||||
uint8_t cft_idx;
|
||||
|
||||
for (cft_idx = 0; cft_idx < kConfigFrequencyTableSize; cft_idx++)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/formats/mp2t/mpeg1_header.h"
|
||||
#include "packager/utils/hex_parser.h"
|
||||
|
||||
using ::testing::ElementsAreArray;
|
||||
|
||||
|
@ -36,20 +37,23 @@ namespace mp2t {
|
|||
class Mpeg1HeaderTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(base::HexStringToBytes(kValidMp3SyncByte, &sync_valid_));
|
||||
ASSERT_TRUE(base::HexStringToBytes(kInvalidMp3SyncByte_1, &sync_inv_1_));
|
||||
ASSERT_TRUE(base::HexStringToBytes(kInvalidMp3SyncByte_2, &sync_inv_2_));
|
||||
ASSERT_TRUE(base::HexStringToBytes(kInvalidMp3SyncByte_3, &sync_inv_3_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kValidMp3SyncByte, &sync_valid_));
|
||||
ASSERT_TRUE(
|
||||
shaka::ValidHexStringToBytes(kInvalidMp3SyncByte_1, &sync_inv_1_));
|
||||
ASSERT_TRUE(
|
||||
shaka::ValidHexStringToBytes(kInvalidMp3SyncByte_2, &sync_inv_2_));
|
||||
ASSERT_TRUE(
|
||||
shaka::ValidHexStringToBytes(kInvalidMp3SyncByte_3, &sync_inv_3_));
|
||||
|
||||
ASSERT_TRUE(base::HexStringToBytes(kValidMp3Frame, &frame_valid_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kValidMp3Frame, &frame_valid_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kInvalidMp3FrameBadVersion,
|
||||
&frame_inv_1_));
|
||||
ASSERT_TRUE(
|
||||
base::HexStringToBytes(kInvalidMp3FrameBadVersion, &frame_inv_1_));
|
||||
ASSERT_TRUE(
|
||||
base::HexStringToBytes(kInvalidMp3FrameBadLayer, &frame_inv_2_));
|
||||
ASSERT_TRUE(
|
||||
base::HexStringToBytes(kInvalidMp3FrameBadBitrate, &frame_inv_3_));
|
||||
ASSERT_TRUE(
|
||||
base::HexStringToBytes(kInvalidMp3FrameBadSamepleRate, &frame_inv_4_));
|
||||
shaka::ValidHexStringToBytes(kInvalidMp3FrameBadLayer, &frame_inv_2_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kInvalidMp3FrameBadBitrate,
|
||||
&frame_inv_3_));
|
||||
ASSERT_TRUE(shaka::ValidHexStringToBytes(kInvalidMp3FrameBadSamepleRate,
|
||||
&frame_inv_4_));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -123,7 +123,7 @@ std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(Codec codec) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
||||
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
return stream_info;
|
||||
|
@ -132,7 +132,7 @@ std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(Codec codec) {
|
|||
std::shared_ptr<AudioStreamInfo> CreateAudioStreamInfo(Codec codec) {
|
||||
std::shared_ptr<AudioStreamInfo> stream_info(new AudioStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, codec, kCodecString, kAudioExtraData,
|
||||
arraysize(kAudioExtraData), kSampleBits, kNumChannels, kSamplingFrequency,
|
||||
std::size(kAudioExtraData), kSampleBits, kNumChannels, kSamplingFrequency,
|
||||
kSeekPreroll, kCodecDelay, kMaxBitrate, kAverageBitrate, kLanguage,
|
||||
kIsEncrypted));
|
||||
return stream_info;
|
||||
|
@ -197,18 +197,18 @@ TEST_F(PesPacketGeneratorTest, AddVideoSample) {
|
|||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
const int32_t kPts = 12345;
|
||||
const uint32_t kDts = 12300;
|
||||
sample->set_pts(kPts);
|
||||
sample->set_dts(kDts);
|
||||
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + std::size(kAnyData));
|
||||
|
||||
std::unique_ptr<MockNalUnitToByteStreamConverter> mock(
|
||||
new MockNalUnitToByteStreamConverter());
|
||||
EXPECT_CALL(*mock, ConvertUnitToByteStreamWithSubsamples(
|
||||
_, arraysize(kAnyData), kIsKeyFrame,
|
||||
_, std::size(kAnyData), kIsKeyFrame,
|
||||
kEscapeEncryptedNalu, _, Pointee(IsEmpty())))
|
||||
.WillOnce(DoAll(SetArgPointee<4>(expected_data), Return(true)));
|
||||
|
||||
|
@ -235,7 +235,7 @@ TEST_F(PesPacketGeneratorTest, AddEncryptedVideoSample) {
|
|||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
const int32_t kPts = 12345;
|
||||
const uint32_t kDts = 12300;
|
||||
sample->set_pts(kPts);
|
||||
|
@ -250,12 +250,12 @@ TEST_F(PesPacketGeneratorTest, AddEncryptedVideoSample) {
|
|||
sample->set_is_encrypted(true);
|
||||
sample->set_decrypt_config(std::move(decrypt_config));
|
||||
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + std::size(kAnyData));
|
||||
|
||||
std::unique_ptr<MockNalUnitToByteStreamConverter> mock(
|
||||
new MockNalUnitToByteStreamConverter());
|
||||
EXPECT_CALL(*mock, ConvertUnitToByteStreamWithSubsamples(
|
||||
_, arraysize(kAnyData), kIsKeyFrame,
|
||||
_, std::size(kAnyData), kIsKeyFrame,
|
||||
kEscapeEncryptedNalu, _, Pointee(Eq(subsamples))))
|
||||
.WillOnce(DoAll(SetArgPointee<4>(expected_data), Return(true)));
|
||||
|
||||
|
@ -282,13 +282,13 @@ TEST_F(PesPacketGeneratorTest, AddVideoSampleFailedToConvert) {
|
|||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + std::size(kAnyData));
|
||||
std::unique_ptr<MockNalUnitToByteStreamConverter> mock(
|
||||
new MockNalUnitToByteStreamConverter());
|
||||
EXPECT_CALL(*mock, ConvertUnitToByteStreamWithSubsamples(
|
||||
_, arraysize(kAnyData), kIsKeyFrame,
|
||||
_, std::size(kAnyData), kIsKeyFrame,
|
||||
kEscapeEncryptedNalu, _, Pointee(IsEmpty())))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
|
@ -306,9 +306,9 @@ TEST_F(PesPacketGeneratorTest, AddAudioSample) {
|
|||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
std::vector<uint8_t> expected_data(kAnyData, kAnyData + std::size(kAnyData));
|
||||
|
||||
std::unique_ptr<MockAACAudioSpecificConfig> mock(
|
||||
new MockAACAudioSpecificConfig());
|
||||
|
@ -336,7 +336,7 @@ TEST_F(PesPacketGeneratorTest, AddAudioSampleFailedToConvert) {
|
|||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
|
||||
std::unique_ptr<MockAACAudioSpecificConfig> mock(
|
||||
new MockAACAudioSpecificConfig());
|
||||
|
@ -356,7 +356,7 @@ TEST_F(PesPacketGeneratorTest, TimeStampScaling) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTestTimescale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
||||
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
EXPECT_TRUE(generator_.Initialize(*stream_info));
|
||||
|
@ -364,7 +364,7 @@ TEST_F(PesPacketGeneratorTest, TimeStampScaling) {
|
|||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
const int32_t kPts = 5000;
|
||||
const uint32_t kDts = 4000;
|
||||
sample->set_pts(kPts);
|
||||
|
@ -373,7 +373,7 @@ TEST_F(PesPacketGeneratorTest, TimeStampScaling) {
|
|||
std::unique_ptr<MockNalUnitToByteStreamConverter> mock(
|
||||
new MockNalUnitToByteStreamConverter());
|
||||
EXPECT_CALL(*mock, ConvertUnitToByteStreamWithSubsamples(
|
||||
_, arraysize(kAnyData), kIsKeyFrame,
|
||||
_, std::size(kAnyData), kIsKeyFrame,
|
||||
kEscapeEncryptedNalu, _, Pointee(IsEmpty())))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/codecs/hls_audio_util.h"
|
||||
|
|
|
@ -64,7 +64,7 @@ TEST_F(ProgramMapTableWriterTest, ClearH264) {
|
|||
0xA1, // Adaptation Field length.
|
||||
0x00, // All adaptation field flags 0.
|
||||
};
|
||||
const int kExpectedPmtPrefixSize = arraysize(kExpectedPmtPrefix);
|
||||
const int kExpectedPmtPrefixSize = std::size(kExpectedPmtPrefix);
|
||||
const uint8_t kPmtH264[] = {
|
||||
0x00, // pointer field
|
||||
0x02,
|
||||
|
@ -87,7 +87,7 @@ TEST_F(ProgramMapTableWriterTest, ClearH264) {
|
|||
ASSERT_EQ(kTsPacketSize, buffer.Size());
|
||||
EXPECT_NO_FATAL_FAILURE(
|
||||
ExpectTsPacketEqual(kExpectedPmtPrefix, kExpectedPmtPrefixSize, 160,
|
||||
kPmtH264, arraysize(kPmtH264), buffer.Buffer()));
|
||||
kPmtH264, std::size(kPmtH264), buffer.Buffer()));
|
||||
}
|
||||
|
||||
// Verify that PSI for encrypted segments after clear lead is generated
|
||||
|
@ -131,8 +131,8 @@ TEST_F(ProgramMapTableWriterTest, EncryptedSegmentsAfterClearLeadH264) {
|
|||
0xAF, 0xCC, 0x24, 0x21,
|
||||
};
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kPmtEncryptedH264Prefix, arraysize(kPmtEncryptedH264Prefix), 154,
|
||||
kPmtEncryptedH264, arraysize(kPmtEncryptedH264), buffer.Buffer()));
|
||||
kPmtEncryptedH264Prefix, std::size(kPmtEncryptedH264Prefix), 154,
|
||||
kPmtEncryptedH264, std::size(kPmtEncryptedH264), buffer.Buffer()));
|
||||
}
|
||||
|
||||
// Verify that PMT for encrypted segments can be generated (without clear lead).
|
||||
|
@ -174,8 +174,8 @@ TEST_F(ProgramMapTableWriterTest, EncryptedSegmentsH264Pmt) {
|
|||
0xA9, 0xC2, 0x95, 0x7C,
|
||||
};
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kPmtEncryptedH264Prefix, arraysize(kPmtEncryptedH264Prefix), 154,
|
||||
kPmtEncryptedH264, arraysize(kPmtEncryptedH264), buffer.Buffer()));
|
||||
kPmtEncryptedH264Prefix, std::size(kPmtEncryptedH264Prefix), 154,
|
||||
kPmtEncryptedH264, std::size(kPmtEncryptedH264), buffer.Buffer()));
|
||||
}
|
||||
|
||||
TEST_F(ProgramMapTableWriterTest, ClearAac) {
|
||||
|
@ -212,8 +212,8 @@ TEST_F(ProgramMapTableWriterTest, ClearAac) {
|
|||
0xE0, 0x6F, 0x1A, 0x31, // CRC32.
|
||||
};
|
||||
EXPECT_NO_FATAL_FAILURE(
|
||||
ExpectTsPacketEqual(kExpectedPmtPrefix, arraysize(kExpectedPmtPrefix),
|
||||
160, kPmtAac, arraysize(kPmtAac), buffer.Buffer()));
|
||||
ExpectTsPacketEqual(kExpectedPmtPrefix, std::size(kExpectedPmtPrefix),
|
||||
160, kPmtAac, std::size(kPmtAac), buffer.Buffer()));
|
||||
}
|
||||
|
||||
TEST_F(ProgramMapTableWriterTest, ClearAc3) {
|
||||
|
@ -250,8 +250,8 @@ TEST_F(ProgramMapTableWriterTest, ClearAc3) {
|
|||
};
|
||||
|
||||
EXPECT_NO_FATAL_FAILURE(
|
||||
ExpectTsPacketEqual(kExpectedPmtPrefix, arraysize(kExpectedPmtPrefix),
|
||||
160, kPmtAc3, arraysize(kPmtAc3), buffer.Buffer()));
|
||||
ExpectTsPacketEqual(kExpectedPmtPrefix, std::size(kExpectedPmtPrefix),
|
||||
160, kPmtAc3, std::size(kPmtAc3), buffer.Buffer()));
|
||||
}
|
||||
|
||||
// Verify that PSI for encrypted segments after clear lead is generated
|
||||
|
@ -308,9 +308,8 @@ TEST_F(ProgramMapTableWriterTest, EncryptedSegmentsAfterClearLeadAac) {
|
|||
};
|
||||
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kPmtEncryptedAacPrefix, arraysize(kPmtEncryptedAacPrefix), 138,
|
||||
kPmtEncryptedAac, arraysize(kPmtEncryptedAac),
|
||||
buffer.Buffer()));
|
||||
kPmtEncryptedAacPrefix, std::size(kPmtEncryptedAacPrefix), 138,
|
||||
kPmtEncryptedAac, std::size(kPmtEncryptedAac), buffer.Buffer()));
|
||||
}
|
||||
|
||||
// Verify that PMT for encrypted segments can be generated (without clear lead).
|
||||
|
@ -365,9 +364,8 @@ TEST_F(ProgramMapTableWriterTest, EncryptedSegmentsAacPmt) {
|
|||
};
|
||||
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kPmtEncryptedAacPrefix, arraysize(kPmtEncryptedAacPrefix), 138,
|
||||
kPmtEncryptedAac, arraysize(kPmtEncryptedAac),
|
||||
buffer.Buffer()));
|
||||
kPmtEncryptedAacPrefix, std::size(kPmtEncryptedAacPrefix), 138,
|
||||
kPmtEncryptedAac, std::size(kPmtEncryptedAac), buffer.Buffer()));
|
||||
}
|
||||
|
||||
TEST_F(ProgramMapTableWriterTest, EncryptedSegmentsAc3Pmt) {
|
||||
|
@ -420,8 +418,8 @@ TEST_F(ProgramMapTableWriterTest, EncryptedSegmentsAc3Pmt) {
|
|||
};
|
||||
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kPmtEncryptedAc3Prefix, arraysize(kPmtEncryptedAc3Prefix), 130,
|
||||
kPmtEncryptedAc3, arraysize(kPmtEncryptedAc3), buffer.Buffer()));
|
||||
kPmtEncryptedAc3Prefix, std::size(kPmtEncryptedAc3Prefix), 130,
|
||||
kPmtEncryptedAc3, std::size(kPmtEncryptedAc3), buffer.Buffer()));
|
||||
}
|
||||
|
||||
} // namespace mp2t
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
|
||||
#define PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/muxer.h"
|
||||
#include "packager/media/formats/mp2t/ts_segmenter.h"
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "packager/media/formats/mp2t/ts_packet.h"
|
||||
|
||||
#include <memory>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/formats/mp2t/mp2t_common.h"
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "packager/media/formats/mp2t/ts_packet_writer_util.h"
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/formats/mp2t/continuity_counter.h"
|
||||
|
||||
|
@ -53,7 +53,7 @@ const uint8_t kPaddingBytes[] = {
|
|||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
static_assert(arraysize(kPaddingBytes) >= kTsPacketMaximumPayloadSize,
|
||||
static_assert(std::size(kPaddingBytes) >= kTsPacketMaximumPayloadSize,
|
||||
"Padding array is not big enough.");
|
||||
|
||||
// |remaining_data_size| is the amount of data that has to be written. This may
|
||||
|
@ -106,7 +106,7 @@ void WriteAdaptationField(bool has_pcr,
|
|||
if (remaining_bytes == 0)
|
||||
return;
|
||||
|
||||
DCHECK_GE(static_cast<int>(arraysize(kPaddingBytes)), remaining_bytes);
|
||||
DCHECK_GE(static_cast<int>(std::size(kPaddingBytes)), remaining_bytes);
|
||||
writer->AppendArray(kPaddingBytes, remaining_bytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/formats/mp2t/mp2t_common.h"
|
||||
|
||||
|
@ -66,7 +66,6 @@ bool TsSectionPat::ParsePsiSection(BitReader* bit_reader) {
|
|||
std::vector<int> program_number_array(pmt_pid_count);
|
||||
std::vector<int> pmt_pid_array(pmt_pid_count);
|
||||
for (int k = 0; k < pmt_pid_count; k++) {
|
||||
int reserved;
|
||||
RCHECK(bit_reader->ReadBits(16, &program_number_array[k]));
|
||||
RCHECK(bit_reader->ReadBits(3, &reserved));
|
||||
RCHECK(bit_reader->ReadBits(13, &pmt_pid_array[k]));
|
||||
|
@ -103,7 +102,7 @@ bool TsSectionPat::ParsePsiSection(BitReader* bit_reader) {
|
|||
for (int k = 0; k < pmt_pid_count; k++) {
|
||||
if (program_number_array[k] != 0) {
|
||||
// Program numbers different from 0 correspond to PMT.
|
||||
register_pmt_cb_.Run(program_number_array[k], pmt_pid_array[k]);
|
||||
register_pmt_cb_(program_number_array[k], pmt_pid_array[k]);
|
||||
// Even if there are multiple programs, only one can be supported now.
|
||||
// HLS: "Transport Stream segments MUST contain a single MPEG-2 Program."
|
||||
break;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PAT_H_
|
||||
#define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PAT_H_
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include <functional>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp2t/ts_section_psi.h"
|
||||
|
||||
namespace shaka {
|
||||
|
@ -16,7 +16,7 @@ namespace mp2t {
|
|||
class TsSectionPat : public TsSectionPsi {
|
||||
public:
|
||||
// RegisterPmtCb::Run(int program_number, int pmt_pid);
|
||||
typedef base::Callback<void(int, int)> RegisterPmtCb;
|
||||
typedef std::function<void(int, int)> RegisterPmtCb;
|
||||
|
||||
explicit TsSectionPat(const RegisterPmtCb& register_pmt_cb);
|
||||
~TsSectionPat() override;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "packager/media/formats/mp2t/ts_section_pes.h"
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/base/timestamp.h"
|
||||
#include "packager/media/formats/mp2t/es_parser.h"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/byte_queue.h"
|
||||
#include "packager/media/formats/mp2t/ts_section.h"
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/formats/mp2t/mp2t_common.h"
|
||||
#include "packager/media/formats/mp2t/ts_stream_type.h"
|
||||
|
@ -122,7 +122,7 @@ bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
|
|||
|
||||
// Once the PMT has been proved to be correct, register the PIDs.
|
||||
for (auto& info : pid_info) {
|
||||
register_pes_cb_.Run(info.pid_es, info.stream_type, info.descriptor,
|
||||
register_pes_cb_(info.pid_es, info.stream_type, info.descriptor,
|
||||
info.descriptor_length);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PMT_H_
|
||||
#define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PMT_H_
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include <functional>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp2t/ts_section_psi.h"
|
||||
#include "packager/media/formats/mp2t/ts_stream_type.h"
|
||||
|
||||
|
@ -19,7 +19,7 @@ class TsSectionPmt : public TsSectionPsi {
|
|||
// RegisterPesCb::Run(int pes_pid, int stream_type);
|
||||
// Stream type is defined in
|
||||
// "Table 2-34 – Stream type assignments" in H.222
|
||||
typedef base::Callback<void(int, TsStreamType, const uint8_t*, size_t)>
|
||||
typedef std::function<void(int, TsStreamType, const uint8_t*, size_t)>
|
||||
RegisterPesCb;
|
||||
|
||||
explicit TsSectionPmt(const RegisterPesCb& register_pes_cb);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/formats/mp2t/mp2t_common.h"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PSI_H_
|
||||
#define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PSI_H_
|
||||
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/byte_queue.h"
|
||||
#include "packager/media/formats/mp2t/ts_section.h"
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include "packager/media/event/muxer_listener.h"
|
||||
#include "packager/media/formats/mp2t/pes_packet.h"
|
||||
#include "packager/media/formats/mp2t/program_map_table_writer.h"
|
||||
#include "packager/status.h"
|
||||
#include "packager/status_macros.h"
|
||||
#include "packager/status/status.h"
|
||||
#include "packager/status/status_macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "packager/media/base/muxer_options.h"
|
||||
#include "packager/media/formats/mp2t/pes_packet_generator.h"
|
||||
#include "packager/media/formats/mp2t/ts_writer.h"
|
||||
#include "packager/status.h"
|
||||
#include "packager/status/status.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packager/media/base/audio_stream_info.h"
|
||||
#include "packager/media/base/macros.h"
|
||||
#include "packager/media/base/video_stream_info.h"
|
||||
#include "packager/media/event/mock_muxer_listener.h"
|
||||
#include "packager/media/formats/mp2t/pes_packet.h"
|
||||
#include "packager/media/formats/mp2t/program_map_table_writer.h"
|
||||
#include "packager/media/formats/mp2t/ts_segmenter.h"
|
||||
#include "packager/status_test_util.h"
|
||||
#include "packager/media/base/macros.h"
|
||||
#include "packager/status/status_test_util.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
@ -90,7 +90,7 @@ class MockTsWriter : public TsWriter {
|
|||
BufferWriter* buffer_writer));
|
||||
bool AddPesPacket(std::unique_ptr<PesPacket> pes_packet,
|
||||
BufferWriter* buffer_writer) override {
|
||||
buffer_writer->AppendArray(kAnyData, arraysize(kAnyData));
|
||||
buffer_writer->AppendArray(kAnyData, std::size(kAnyData));
|
||||
// No need to keep the pes packet around for the current tests.
|
||||
return AddPesPacketMock(pes_packet.get(), buffer_writer);
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ TEST_F(TsSegmenterTest, Initialize) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
@ -133,7 +133,7 @@ TEST_F(TsSegmenterTest, AddSample) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
@ -144,7 +144,7 @@ TEST_F(TsSegmenterTest, AddSample) {
|
|||
.WillOnce(Return(true));
|
||||
|
||||
std::shared_ptr<MediaSample> sample =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
|
||||
Sequence writer_sequence;
|
||||
EXPECT_CALL(*mock_ts_writer_, NewSegment(_))
|
||||
|
@ -185,7 +185,7 @@ TEST_F(TsSegmenterTest, PassedSegmentDuration) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kInputTimescale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
@ -200,10 +200,10 @@ TEST_F(TsSegmenterTest, PassedSegmentDuration) {
|
|||
.WillOnce(Return(true));
|
||||
|
||||
std::shared_ptr<MediaSample> sample1 =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
sample1->set_duration(kInputTimescale * 11);
|
||||
std::shared_ptr<MediaSample> sample2 =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
// Doesn't really matter how long this is.
|
||||
sample2->set_duration(kInputTimescale * 7);
|
||||
|
||||
|
@ -276,7 +276,7 @@ TEST_F(TsSegmenterTest, InitializeThenFinalize) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
@ -304,7 +304,7 @@ TEST_F(TsSegmenterTest, FinalizeSegment) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
@ -331,7 +331,7 @@ TEST_F(TsSegmenterTest, EncryptedSample) {
|
|||
std::shared_ptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
std::size(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
@ -347,14 +347,11 @@ TEST_F(TsSegmenterTest, EncryptedSample) {
|
|||
.WillByDefault(Return(true));
|
||||
ON_CALL(*mock_pes_packet_generator_, Flush()).WillByDefault(Return(true));
|
||||
|
||||
const uint8_t kAnyData[] = {
|
||||
0x01, 0x0F, 0x3C,
|
||||
};
|
||||
std::shared_ptr<MediaSample> sample1 =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
sample1->set_duration(kTimeScale * 2);
|
||||
std::shared_ptr<MediaSample> sample2 =
|
||||
MediaSample::CopyFrom(kAnyData, arraysize(kAnyData), kIsKeyFrame);
|
||||
MediaSample::CopyFrom(kAnyData, std::size(kAnyData), kIsKeyFrame);
|
||||
sample2->set_duration(kTimeScale * 3);
|
||||
|
||||
EXPECT_CALL(*mock_pes_packet_generator_, PushSample(_))
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/formats/mp2t/pes_packet.h"
|
||||
|
@ -167,7 +167,7 @@ TsWriter::~TsWriter() {}
|
|||
|
||||
bool TsWriter::NewSegment(BufferWriter* buffer) {
|
||||
BufferWriter psi;
|
||||
WritePatToBuffer(kPat, arraysize(kPat), &pat_continuity_counter_, &psi);
|
||||
WritePatToBuffer(kPat, std::size(kPat), &pat_continuity_counter_, &psi);
|
||||
if (encrypted_) {
|
||||
if (!pmt_writer_->EncryptedSegmentPmt(&psi)) {
|
||||
return false;
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/optional.h"
|
||||
#include <optional>
|
||||
#include "packager/file/file.h"
|
||||
#include "packager/file/file_closer.h"
|
||||
#include "packager/media/formats/mp2t/continuity_counter.h"
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/formats/mp2t/continuity_counter.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packager/base/files/file_path.h"
|
||||
#include "packager/base/files/file_util.h"
|
||||
#include <filesystem>
|
||||
#include "packager/media/base/audio_stream_info.h"
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/base/video_stream_info.h"
|
||||
|
@ -68,14 +67,14 @@ const uint8_t kMockPmtWriterData[] = {
|
|||
|
||||
ACTION(WriteOnePmt) {
|
||||
BufferWriter* writer = arg0;
|
||||
writer->AppendArray(kMockPmtWriterData, arraysize(kMockPmtWriterData));
|
||||
writer->AppendArray(kMockPmtWriterData, std::size(kMockPmtWriterData));
|
||||
return true;
|
||||
}
|
||||
|
||||
ACTION(WriteTwoPmts) {
|
||||
BufferWriter* writer = arg0;
|
||||
writer->AppendArray(kMockPmtWriterData, arraysize(kMockPmtWriterData));
|
||||
writer->AppendArray(kMockPmtWriterData, arraysize(kMockPmtWriterData));
|
||||
writer->AppendArray(kMockPmtWriterData, std::size(kMockPmtWriterData));
|
||||
writer->AppendArray(kMockPmtWriterData, std::size(kMockPmtWriterData));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -133,7 +132,7 @@ TEST_F(TsWriterTest, ClearH264Psi) {
|
|||
0xA6, // Adaptation Field length.
|
||||
0x00, // All adaptation field flags 0.
|
||||
};
|
||||
const int kExpectedPatPrefixSize = arraysize(kExpectedPatPrefix);
|
||||
const int kExpectedPatPrefixSize = std::size(kExpectedPatPrefix);
|
||||
const uint8_t kExpectedPatPayload[] = {
|
||||
0x00, // pointer field
|
||||
0x00,
|
||||
|
@ -153,7 +152,7 @@ TEST_F(TsWriterTest, ClearH264Psi) {
|
|||
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kExpectedPatPrefix, kExpectedPatPrefixSize, 165, kExpectedPatPayload,
|
||||
arraysize(kExpectedPatPayload), buffer_writer.Buffer()));
|
||||
std::size(kExpectedPatPayload), buffer_writer.Buffer()));
|
||||
|
||||
EXPECT_EQ(0, memcmp(kMockPmtWriterData, buffer_writer.Buffer() + kTsPacketSize,
|
||||
kTsPacketSize));
|
||||
|
@ -300,7 +299,7 @@ TEST_F(TsWriterTest, AddPesPacket) {
|
|||
const uint8_t kAnyData[] = {
|
||||
0x12, 0x88, 0x4f, 0x4a,
|
||||
};
|
||||
pes->mutable_data()->assign(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
pes->mutable_data()->assign(kAnyData, kAnyData + std::size(kAnyData));
|
||||
|
||||
EXPECT_TRUE(ts_writer.AddPesPacket(std::move(pes), &buffer_writer));
|
||||
|
||||
|
@ -342,8 +341,8 @@ TEST_F(TsWriterTest, AddPesPacket) {
|
|||
0x12, 0x88, 0x4f, 0x4a, // Payload.
|
||||
};
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kExpectedOutputPrefix, arraysize(kExpectedOutputPrefix), 153,
|
||||
kExpectedPayload, arraysize(kExpectedPayload),
|
||||
kExpectedOutputPrefix, std::size(kExpectedOutputPrefix), 153,
|
||||
kExpectedPayload, std::size(kExpectedPayload),
|
||||
buffer_writer.Buffer() + kPesStartPosition));
|
||||
}
|
||||
|
||||
|
@ -393,7 +392,7 @@ TEST_F(TsWriterTest, PesPtsZeroNoDts) {
|
|||
const uint8_t kAnyData[] = {
|
||||
0x12, 0x88, 0x4F, 0x4A,
|
||||
};
|
||||
pes->mutable_data()->assign(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
pes->mutable_data()->assign(kAnyData, kAnyData + std::size(kAnyData));
|
||||
|
||||
EXPECT_TRUE(ts_writer.AddPesPacket(std::move(pes), &buffer_writer));
|
||||
|
||||
|
@ -429,8 +428,8 @@ TEST_F(TsWriterTest, PesPtsZeroNoDts) {
|
|||
0x12, 0x88, 0x4F, 0x4A, // Payload.
|
||||
};
|
||||
EXPECT_NO_FATAL_FAILURE(ExpectTsPacketEqual(
|
||||
kExpectedOutputPrefix, arraysize(kExpectedOutputPrefix), 158,
|
||||
kExpectedPayload, arraysize(kExpectedPayload),
|
||||
kExpectedOutputPrefix, std::size(kExpectedOutputPrefix), 158,
|
||||
kExpectedPayload, std::size(kExpectedPayload),
|
||||
buffer_writer.Buffer() + kPesStartPosition));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Copyright 2020 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
|
||||
|
||||
add_library(mp4 STATIC
|
||||
box.cc
|
||||
box.h
|
||||
box_buffer.h
|
||||
box_definitions.cc
|
||||
box_definitions.h
|
||||
box_reader.cc
|
||||
box_reader.h
|
||||
chunk_info_iterator.cc
|
||||
chunk_info_iterator.h
|
||||
composition_offset_iterator.cc
|
||||
composition_offset_iterator.h
|
||||
decoding_time_iterator.cc
|
||||
decoding_time_iterator.h
|
||||
fragmenter.cc
|
||||
fragmenter.h
|
||||
key_frame_info.h
|
||||
low_latency_segment_segmenter.cc
|
||||
low_latency_segment_segmenter.h
|
||||
mp4_media_parser.cc
|
||||
mp4_media_parser.h
|
||||
mp4_muxer.cc
|
||||
mp4_muxer.h
|
||||
multi_segment_segmenter.cc
|
||||
multi_segment_segmenter.h
|
||||
segmenter.cc
|
||||
segmenter.h
|
||||
single_segment_segmenter.cc
|
||||
single_segment_segmenter.h
|
||||
sync_sample_iterator.cc
|
||||
sync_sample_iterator.h
|
||||
track_run_iterator.cc
|
||||
track_run_iterator.h
|
||||
)
|
||||
target_link_libraries(mp4
|
||||
media_base
|
||||
mpd_builder
|
||||
mbedtls
|
||||
media_codecs
|
||||
media_event
|
||||
absl::flags
|
||||
ttml
|
||||
)
|
||||
|
||||
add_executable(mp4_unittest
|
||||
box_definitions_unittest.cc
|
||||
box_reader_unittest.cc
|
||||
chunk_info_iterator_unittest.cc
|
||||
composition_offset_iterator_unittest.cc
|
||||
decoding_time_iterator_unittest.cc
|
||||
mp4_media_parser_unittest.cc
|
||||
sync_sample_iterator_unittest.cc
|
||||
track_run_iterator_unittest.cc
|
||||
)
|
||||
target_link_libraries(mp4_unittest
|
||||
file
|
||||
file_test_util
|
||||
test_data_util
|
||||
absl::flags
|
||||
media_event
|
||||
mp4
|
||||
gmock
|
||||
gtest
|
||||
gtest_main
|
||||
)
|
||||
add_test(NAME mp4_unittest COMMAND mp4_unittest)
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "packager/media/formats/mp4/box.h"
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/formats/mp4/box_buffer.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/formats/mp4/box.h"
|
||||
#include "packager/media/formats/mp4/box_reader.h"
|
||||
|
|
|
@ -4,17 +4,18 @@
|
|||
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
#include <absl/flags/flag.h>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/bit_reader.h"
|
||||
#include "packager/media/base/macros.h"
|
||||
#include "packager/media/base/rcheck.h"
|
||||
#include "packager/media/formats/mp4/box_buffer.h"
|
||||
|
||||
DEFINE_bool(mvex_before_trak,
|
||||
ABSL_FLAG(bool,
|
||||
mvex_before_trak,
|
||||
false,
|
||||
"Android MediaExtractor requires mvex to be written before trak. "
|
||||
"Set the flag to true to comply with the requirement.");
|
||||
|
@ -377,19 +378,20 @@ size_t SampleEncryption::ComputeSizeInternal() {
|
|||
}
|
||||
|
||||
bool SampleEncryption::ParseFromSampleEncryptionData(
|
||||
uint8_t iv_size,
|
||||
std::vector<SampleEncryptionEntry>* sample_encryption_entries) const {
|
||||
DCHECK(IsIvSizeValid(iv_size));
|
||||
uint8_t l_iv_size,
|
||||
std::vector<SampleEncryptionEntry>* l_sample_encryption_entries) const {
|
||||
DCHECK(IsIvSizeValid(l_iv_size));
|
||||
|
||||
BufferReader reader(sample_encryption_data.data(),
|
||||
sample_encryption_data.size());
|
||||
uint32_t sample_count = 0;
|
||||
RCHECK(reader.Read4(&sample_count));
|
||||
|
||||
sample_encryption_entries->resize(sample_count);
|
||||
for (auto& sample_encryption_entry : *sample_encryption_entries) {
|
||||
l_sample_encryption_entries->resize(sample_count);
|
||||
for (auto& sample_encryption_entry : *l_sample_encryption_entries) {
|
||||
RCHECK(sample_encryption_entry.ParseFromBuffer(
|
||||
iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) != 0);
|
||||
l_iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) !=
|
||||
0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -555,7 +557,7 @@ bool MovieHeader::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
|
||||
|
||||
std::vector<uint8_t> matrix(kUnityMatrix,
|
||||
kUnityMatrix + arraysize(kUnityMatrix));
|
||||
kUnityMatrix + std::size(kUnityMatrix));
|
||||
RCHECK(buffer->ReadWriteInt32(&rate) && buffer->ReadWriteInt16(&volume) &&
|
||||
buffer->IgnoreBytes(10) && // reserved
|
||||
buffer->ReadWriteVector(&matrix, matrix.size()) &&
|
||||
|
@ -598,7 +600,7 @@ bool TrackHeader::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
volume = (width != 0 && height != 0) ? 0 : 0x100;
|
||||
}
|
||||
std::vector<uint8_t> matrix(kUnityMatrix,
|
||||
kUnityMatrix + arraysize(kUnityMatrix));
|
||||
kUnityMatrix + std::size(kUnityMatrix));
|
||||
RCHECK(buffer->IgnoreBytes(8) && // reserved
|
||||
buffer->ReadWriteInt16(&layer) &&
|
||||
buffer->ReadWriteInt16(&alternate_group) &&
|
||||
|
@ -1290,20 +1292,20 @@ bool HandlerReference::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
switch (handler_type) {
|
||||
case FOURCC_vide:
|
||||
handler_name.assign(kVideoHandlerName,
|
||||
kVideoHandlerName + arraysize(kVideoHandlerName));
|
||||
kVideoHandlerName + std::size(kVideoHandlerName));
|
||||
break;
|
||||
case FOURCC_soun:
|
||||
handler_name.assign(kAudioHandlerName,
|
||||
kAudioHandlerName + arraysize(kAudioHandlerName));
|
||||
kAudioHandlerName + std::size(kAudioHandlerName));
|
||||
break;
|
||||
case FOURCC_text:
|
||||
handler_name.assign(kTextHandlerName,
|
||||
kTextHandlerName + arraysize(kTextHandlerName));
|
||||
kTextHandlerName + std::size(kTextHandlerName));
|
||||
break;
|
||||
case FOURCC_subt:
|
||||
handler_name.assign(
|
||||
kSubtitleHandlerName,
|
||||
kSubtitleHandlerName + arraysize(kSubtitleHandlerName));
|
||||
kSubtitleHandlerName + std::size(kSubtitleHandlerName));
|
||||
break;
|
||||
case FOURCC_ID32:
|
||||
break;
|
||||
|
@ -1660,8 +1662,8 @@ size_t VideoSampleEntry::ComputeSizeInternal() {
|
|||
return size;
|
||||
}
|
||||
|
||||
FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format) const {
|
||||
switch (format) {
|
||||
FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC l_format) const {
|
||||
switch (l_format) {
|
||||
case FOURCC_av01:
|
||||
return FOURCC_av1C;
|
||||
case FOURCC_avc1:
|
||||
|
@ -1676,7 +1678,7 @@ FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format) const {
|
|||
case FOURCC_vp09:
|
||||
return FOURCC_vpcC;
|
||||
default:
|
||||
LOG(ERROR) << FourCCToString(format) << " is not supported.";
|
||||
LOG(ERROR) << FourCCToString(l_format) << " is not supported.";
|
||||
return FOURCC_NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2467,7 +2469,7 @@ bool Movie::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
// We do not care the content of metadata box in the source content, so just
|
||||
// skip reading the box.
|
||||
RCHECK(buffer->TryReadWriteChild(&metadata));
|
||||
if (FLAGS_mvex_before_trak) {
|
||||
if (absl::GetFlag(FLAGS_mvex_before_trak)) {
|
||||
// |extends| has to be written before |tracks| to workaround Android
|
||||
// MediaExtractor bug which requires |mvex| to be placed before |trak|.
|
||||
// See https://github.com/shaka-project/shaka-packager/issues/711 for
|
||||
|
@ -2476,7 +2478,7 @@ bool Movie::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
}
|
||||
for (uint32_t i = 0; i < tracks.size(); ++i)
|
||||
RCHECK(buffer->ReadWriteChild(&tracks[i]));
|
||||
if (!FLAGS_mvex_before_trak) {
|
||||
if (!absl::GetFlag(FLAGS_mvex_before_trak)) {
|
||||
RCHECK(buffer->TryReadWriteChild(&extends));
|
||||
}
|
||||
for (uint32_t i = 0; i < pssh.size(); ++i)
|
||||
|
|
|
@ -117,8 +117,8 @@ struct SampleEncryption : FullBox {
|
|||
/// entries.
|
||||
/// @return true on success, false otherwise.
|
||||
bool ParseFromSampleEncryptionData(
|
||||
uint8_t iv_size,
|
||||
std::vector<SampleEncryptionEntry>* sample_encryption_entries) const;
|
||||
uint8_t l_iv_size,
|
||||
std::vector<SampleEncryptionEntry>* l_sample_encryption_entries) const;
|
||||
|
||||
/// We may not know @a iv_size before reading this box. In this case, we will
|
||||
/// store sample encryption data for parsing later when @a iv_size is known.
|
||||
|
@ -293,7 +293,7 @@ struct VideoSampleEntry : Box {
|
|||
return format == FOURCC_encv ? sinf.format.format : format;
|
||||
}
|
||||
// Returns the box type of codec configuration box from video format.
|
||||
FourCC GetCodecConfigurationBoxType(FourCC format) const;
|
||||
FourCC GetCodecConfigurationBoxType(FourCC l_format) const;
|
||||
|
||||
// Convert |extra_codec_configs| to vector.
|
||||
std::vector<uint8_t> ExtraCodecConfigsAsVector() const;
|
||||
|
@ -735,6 +735,7 @@ struct TrackFragmentHeader : FullBox {
|
|||
};
|
||||
|
||||
enum SampleFlagsMasks {
|
||||
kUnset = 0x00000000,
|
||||
kReservedMask = 0xFC000000,
|
||||
kSampleDependsOnMask = 0x03000000,
|
||||
kSampleIsDependedOnMask = 0x00C00000,
|
||||
|
|
|
@ -147,7 +147,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
}
|
||||
|
||||
void Fill(ProtectionSystemSpecificHeader* pssh) {
|
||||
pssh->raw_box.assign(kPsshBox, kPsshBox + arraysize(kPsshBox));
|
||||
pssh->raw_box.assign(kPsshBox, kPsshBox + std::size(kPsshBox));
|
||||
}
|
||||
|
||||
void Modify(ProtectionSystemSpecificHeader* pssh) {
|
||||
|
@ -155,7 +155,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
}
|
||||
|
||||
void Fill(SampleAuxiliaryInformationOffset* saio) {
|
||||
saio->offsets.assign(kData32, kData32 + arraysize(kData32));
|
||||
saio->offsets.assign(kData32, kData32 + std::size(kData32));
|
||||
}
|
||||
|
||||
void Modify(SampleAuxiliaryInformationOffset* saio) {
|
||||
|
@ -164,8 +164,8 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Fill(SampleAuxiliaryInformationSize* saiz) {
|
||||
saiz->default_sample_info_size = 0;
|
||||
saiz->sample_info_sizes.assign(kData8, kData8 + arraysize(kData8));
|
||||
saiz->sample_count = arraysize(kData8);
|
||||
saiz->sample_info_sizes.assign(kData8, kData8 + std::size(kData8));
|
||||
saiz->sample_count = std::size(kData8);
|
||||
}
|
||||
|
||||
void Modify(SampleAuxiliaryInformationSize* saiz) {
|
||||
|
@ -178,7 +178,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
senc->flags = SampleEncryption::kUseSubsampleEncryption;
|
||||
senc->sample_encryption_entries.resize(2);
|
||||
senc->sample_encryption_entries[0].initialization_vector.assign(
|
||||
kData8Bytes, kData8Bytes + arraysize(kData8Bytes));
|
||||
kData8Bytes, kData8Bytes + std::size(kData8Bytes));
|
||||
senc->sample_encryption_entries[0].subsamples.resize(2);
|
||||
senc->sample_encryption_entries[0].subsamples[0].clear_bytes = 17;
|
||||
senc->sample_encryption_entries[0].subsamples[0].cipher_bytes = 3456;
|
||||
|
@ -212,7 +212,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
tenc->default_is_protected = 1;
|
||||
tenc->default_per_sample_iv_size = 8;
|
||||
tenc->default_kid.assign(kData16Bytes,
|
||||
kData16Bytes + arraysize(kData16Bytes));
|
||||
kData16Bytes + std::size(kData16Bytes));
|
||||
tenc->default_skip_byte_block = 2;
|
||||
tenc->default_crypt_byte_block = 8;
|
||||
tenc->version = 1;
|
||||
|
@ -349,7 +349,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
0x00, 0x06, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0};
|
||||
codec_configuration->data.assign(
|
||||
kCodecConfigurationData,
|
||||
kCodecConfigurationData + arraysize(kCodecConfigurationData));
|
||||
kCodecConfigurationData + std::size(kCodecConfigurationData));
|
||||
}
|
||||
|
||||
void Modify(CodecConfiguration* codec_configuration) {
|
||||
|
@ -360,7 +360,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
|
||||
codec_configuration->data.assign(
|
||||
kCodecConfigurationData,
|
||||
kCodecConfigurationData + arraysize(kCodecConfigurationData));
|
||||
kCodecConfigurationData + std::size(kCodecConfigurationData));
|
||||
}
|
||||
|
||||
void Fill(VideoSampleEntry* entry) {
|
||||
|
@ -409,7 +409,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
ddts->sampling_frequency = 48000;
|
||||
ddts->pcm_sample_depth = 16;
|
||||
ddts->extra_data.assign(kDdtsExtraData,
|
||||
kDdtsExtraData + arraysize(kDdtsExtraData));
|
||||
kDdtsExtraData + std::size(kDdtsExtraData));
|
||||
}
|
||||
|
||||
void Modify(DTSSpecific* ddts) {
|
||||
|
@ -418,22 +418,22 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Fill(AC3Specific* dac3) {
|
||||
const uint8_t kAc3Data[] = {0x50, 0x11, 0x60};
|
||||
dac3->data.assign(kAc3Data, kAc3Data + arraysize(kAc3Data));
|
||||
dac3->data.assign(kAc3Data, kAc3Data + std::size(kAc3Data));
|
||||
}
|
||||
|
||||
void Modify(AC3Specific* dac3) {
|
||||
const uint8_t kAc3Data[] = {0x50, 0x11, 0x40};
|
||||
dac3->data.assign(kAc3Data, kAc3Data + arraysize(kAc3Data));
|
||||
dac3->data.assign(kAc3Data, kAc3Data + std::size(kAc3Data));
|
||||
}
|
||||
|
||||
void Fill(EC3Specific* dec3) {
|
||||
const uint8_t kEc3Data[] = {0x08, 0x00, 0x20, 0x0f, 0x00};
|
||||
dec3->data.assign(kEc3Data, kEc3Data + arraysize(kEc3Data));
|
||||
dec3->data.assign(kEc3Data, kEc3Data + std::size(kEc3Data));
|
||||
}
|
||||
|
||||
void Modify(EC3Specific* dec3) {
|
||||
const uint8_t kEc3Data[] = {0x07, 0x00, 0x60, 0x04, 0x00};
|
||||
dec3->data.assign(kEc3Data, kEc3Data + arraysize(kEc3Data));
|
||||
dec3->data.assign(kEc3Data, kEc3Data + std::size(kEc3Data));
|
||||
}
|
||||
|
||||
void Fill(OpusSpecific* dops) {
|
||||
|
@ -442,7 +442,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x01, 0x11};
|
||||
dops->opus_identification_header.assign(
|
||||
kOpusIdentificationHeader,
|
||||
kOpusIdentificationHeader + arraysize(kOpusIdentificationHeader));
|
||||
kOpusIdentificationHeader + std::size(kOpusIdentificationHeader));
|
||||
dops->preskip = 0x0403;
|
||||
}
|
||||
|
||||
|
@ -559,8 +559,8 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Fill(SampleSize* stsz) {
|
||||
stsz->sample_size = 0;
|
||||
stsz->sizes.assign(kData8, kData8 + arraysize(kData8));
|
||||
stsz->sample_count = arraysize(kData8);
|
||||
stsz->sizes.assign(kData8, kData8 + std::size(kData8));
|
||||
stsz->sample_count = std::size(kData8);
|
||||
}
|
||||
|
||||
void Modify(SampleSize* stsz) {
|
||||
|
@ -570,28 +570,28 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Fill(CompactSampleSize* stz2) {
|
||||
stz2->field_size = 4;
|
||||
stz2->sizes.assign(kData4, kData4 + arraysize(kData4));
|
||||
stz2->sizes.assign(kData4, kData4 + std::size(kData4));
|
||||
}
|
||||
|
||||
void Modify(CompactSampleSize* stz2) {
|
||||
stz2->field_size = 8;
|
||||
stz2->sizes.assign(kData8, kData8 + arraysize(kData8));
|
||||
stz2->sizes.assign(kData8, kData8 + std::size(kData8));
|
||||
}
|
||||
|
||||
void Fill(ChunkLargeOffset* co64) {
|
||||
co64->offsets.assign(kData64, kData64 + arraysize(kData64));
|
||||
co64->offsets.assign(kData64, kData64 + std::size(kData64));
|
||||
}
|
||||
|
||||
void Modify(ChunkLargeOffset* co64) { co64->offsets.pop_back(); }
|
||||
|
||||
void Fill(ChunkOffset* stco) {
|
||||
stco->offsets.assign(kData32, kData32 + arraysize(kData32));
|
||||
stco->offsets.assign(kData32, kData32 + std::size(kData32));
|
||||
}
|
||||
|
||||
void Modify(ChunkOffset* stco) { stco->offsets.push_back(10); }
|
||||
|
||||
void Fill(SyncSample* stss) {
|
||||
stss->sample_number.assign(kData32, kData32 + arraysize(kData32));
|
||||
stss->sample_number.assign(kData32, kData32 + std::size(kData32));
|
||||
}
|
||||
|
||||
void Modify(SyncSample* stss) { stss->sample_number.pop_back(); }
|
||||
|
@ -602,7 +602,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
sgpd->cenc_sample_encryption_info_entries[0].is_protected = 1;
|
||||
sgpd->cenc_sample_encryption_info_entries[0].per_sample_iv_size = 8;
|
||||
sgpd->cenc_sample_encryption_info_entries[0].key_id.assign(
|
||||
kData16Bytes, kData16Bytes + arraysize(kData16Bytes));
|
||||
kData16Bytes, kData16Bytes + std::size(kData16Bytes));
|
||||
sgpd->cenc_sample_encryption_info_entries[0].crypt_byte_block = 3;
|
||||
sgpd->cenc_sample_encryption_info_entries[0].skip_byte_block = 7;
|
||||
sgpd->cenc_sample_encryption_info_entries[1].is_protected = 0;
|
||||
|
@ -616,7 +616,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
sgpd->cenc_sample_encryption_info_entries[0].is_protected = 1;
|
||||
sgpd->cenc_sample_encryption_info_entries[0].per_sample_iv_size = 0;
|
||||
sgpd->cenc_sample_encryption_info_entries[0].constant_iv.assign(
|
||||
kData16Bytes, kData16Bytes + arraysize(kData16Bytes));
|
||||
kData16Bytes, kData16Bytes + std::size(kData16Bytes));
|
||||
sgpd->cenc_sample_encryption_info_entries[0].key_id.resize(16);
|
||||
sgpd->version = 1;
|
||||
}
|
||||
|
@ -692,19 +692,19 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Fill(DataEntryUrl* url) {
|
||||
url->flags = 2;
|
||||
url->location.assign(kData8, kData8 + arraysize(kData8));
|
||||
url->location.assign(kData8, kData8 + std::size(kData8));
|
||||
}
|
||||
|
||||
void Modify(DataEntryUrl* url) {
|
||||
url->flags += 1;
|
||||
url->location.assign(kData4, kData4 + arraysize(kData4));
|
||||
url->location.assign(kData4, kData4 + std::size(kData4));
|
||||
}
|
||||
|
||||
void Fill(DataReference* dref) {
|
||||
dref->data_entry.resize(2);
|
||||
Fill(&dref->data_entry[0]);
|
||||
Fill(&dref->data_entry[1]);
|
||||
dref->data_entry[1].location.assign(kData4, kData4 + arraysize(kData4));
|
||||
dref->data_entry[1].location.assign(kData4, kData4 + std::size(kData4));
|
||||
}
|
||||
|
||||
void Modify(DataReference* dref) {
|
||||
|
@ -823,14 +823,14 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
TrackFragmentRun::kSampleFlagsPresentMask |
|
||||
TrackFragmentRun::kSampleCompTimeOffsetsPresentMask;
|
||||
trun->data_offset = 783246;
|
||||
trun->sample_count = arraysize(kData32);
|
||||
trun->sample_flags.assign(kData32, kData32 + arraysize(kData32));
|
||||
trun->sample_count = std::size(kData32);
|
||||
trun->sample_flags.assign(kData32, kData32 + std::size(kData32));
|
||||
trun->sample_sizes = trun->sample_flags;
|
||||
trun->sample_sizes[0] += 1000;
|
||||
trun->sample_durations = trun->sample_flags;
|
||||
trun->sample_durations[1] += 2343;
|
||||
trun->sample_composition_time_offsets.assign(kData32,
|
||||
kData32 + arraysize(kData32));
|
||||
kData32 + std::size(kData32));
|
||||
trun->sample_composition_time_offsets[2] = -89782;
|
||||
trun->version = 1;
|
||||
}
|
||||
|
@ -1327,7 +1327,7 @@ TEST_F(BoxDefinitionsTest, SampleEntryExtraCodecConfigs) {
|
|||
TEST_F(BoxDefinitionsTest, CompactSampleSize_FieldSize16) {
|
||||
CompactSampleSize stz2;
|
||||
stz2.field_size = 16;
|
||||
stz2.sizes.assign(kData16, kData16 + arraysize(kData16));
|
||||
stz2.sizes.assign(kData16, kData16 + std::size(kData16));
|
||||
stz2.Write(this->buffer_.get());
|
||||
|
||||
CompactSampleSize stz2_readback;
|
||||
|
@ -1337,7 +1337,7 @@ TEST_F(BoxDefinitionsTest, CompactSampleSize_FieldSize16) {
|
|||
|
||||
TEST_F(BoxDefinitionsTest, ChunkLargeOffsetSmallOffset) {
|
||||
ChunkLargeOffset co64;
|
||||
co64.offsets.assign(kData32, kData32 + arraysize(kData32));
|
||||
co64.offsets.assign(kData32, kData32 + std::size(kData32));
|
||||
co64.Write(this->buffer_.get());
|
||||
|
||||
// The data is stored in ChunkOffset box instead.
|
||||
|
@ -1376,9 +1376,9 @@ TEST_F(BoxDefinitionsTest, TrackEncryptionConstantIv) {
|
|||
TrackEncryption tenc;
|
||||
tenc.default_is_protected = 1;
|
||||
tenc.default_per_sample_iv_size = 0;
|
||||
tenc.default_kid.assign(kData16Bytes, kData16Bytes + arraysize(kData16Bytes));
|
||||
tenc.default_kid.assign(kData16Bytes, kData16Bytes + std::size(kData16Bytes));
|
||||
tenc.default_constant_iv.assign(kData16Bytes,
|
||||
kData16Bytes + arraysize(kData16Bytes));
|
||||
kData16Bytes + std::size(kData16Bytes));
|
||||
tenc.Write(buffer_.get());
|
||||
|
||||
TrackEncryption tenc_readback;
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/stringprintf.h"
|
||||
#include <absl/strings/str_format.h>
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/formats/mp4/box.h"
|
||||
|
||||
namespace shaka {
|
||||
|
@ -118,7 +118,7 @@ bool BoxReader::ReadHeader(bool* err) {
|
|||
|
||||
if (size == 0) {
|
||||
// Boxes that run to EOS are not supported.
|
||||
NOTIMPLEMENTED() << base::StringPrintf("Box '%s' run to EOS.",
|
||||
NOTIMPLEMENTED() << absl::StrFormat("Box '%s' run to EOS.",
|
||||
FourCCToString(type_).c_str());
|
||||
*err = true;
|
||||
return false;
|
||||
|
@ -129,10 +129,9 @@ bool BoxReader::ReadHeader(bool* err) {
|
|||
|
||||
// The box should have at least the size of what have been parsed.
|
||||
if (size < pos()) {
|
||||
LOG(ERROR) << base::StringPrintf("Box '%s' with size (%" PRIu64
|
||||
LOG(ERROR) << absl::StrFormat("Box '%s' with size (%" PRIu64
|
||||
") is invalid.",
|
||||
FourCCToString(type_).c_str(),
|
||||
size);
|
||||
FourCCToString(type_).c_str(), size);
|
||||
*err = true;
|
||||
return false;
|
||||
}
|
||||
|
@ -140,10 +139,8 @@ bool BoxReader::ReadHeader(bool* err) {
|
|||
// 'mdat' box could have a 64-bit size; other boxes should be very small.
|
||||
if (size > static_cast<uint64_t>(std::numeric_limits<int32_t>::max()) &&
|
||||
type_ != FOURCC_mdat) {
|
||||
LOG(ERROR) << base::StringPrintf("Box '%s' size (%" PRIu64
|
||||
") is too large.",
|
||||
FourCCToString(type_).c_str(),
|
||||
size);
|
||||
LOG(ERROR) << absl::StrFormat("Box '%s' size (%" PRIu64 ") is too large.",
|
||||
FourCCToString(type_).c_str(), size);
|
||||
*err = true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/base/buffer_reader.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/rcheck.h"
|
||||
|
@ -49,45 +49,45 @@ class BoxReader : public BufferReader {
|
|||
/// reading the box.
|
||||
/// @return true if there is enough data to read the header and the header is
|
||||
/// sane, which does not imply that the entire box is in the buffer.
|
||||
static bool StartBox(const uint8_t* buf,
|
||||
[[nodiscard]] static bool StartBox(const uint8_t* buf,
|
||||
const size_t buf_size,
|
||||
FourCC* type,
|
||||
uint64_t* box_size,
|
||||
bool* err) WARN_UNUSED_RESULT;
|
||||
bool* err);
|
||||
|
||||
/// Scan through all boxes within the current box, starting at the current
|
||||
/// buffer position. Must be called before any of the @b *Child functions
|
||||
/// work.
|
||||
/// @return true on success, false otherwise.
|
||||
bool ScanChildren() WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool ScanChildren();
|
||||
|
||||
/// @return true if child with type @a child.BoxType() exists.
|
||||
bool ChildExist(Box* child) WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool ChildExist(Box* child);
|
||||
|
||||
/// Read exactly one child box from the set of children. The type of the
|
||||
/// child will be determined by the BoxType() of @a child.
|
||||
/// @return true on success, false otherwise.
|
||||
bool ReadChild(Box* child) WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool ReadChild(Box* child);
|
||||
|
||||
/// Read one child if available.
|
||||
/// @return false on error, true on successful read or on child absent.
|
||||
bool TryReadChild(Box* child) WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool TryReadChild(Box* child);
|
||||
|
||||
/// Read at least one child.
|
||||
/// @return false on error or no child of type <T> present.
|
||||
template <typename T>
|
||||
bool ReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool ReadChildren(std::vector<T>* children);
|
||||
|
||||
/// Read any number of children.
|
||||
/// @return false on error.
|
||||
template <typename T>
|
||||
bool TryReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool TryReadChildren(std::vector<T>* children);
|
||||
|
||||
/// Read all children. It expects all children to be of type T.
|
||||
/// Note that this method is mutually exclusive with ScanChildren().
|
||||
/// @return true on success, false otherwise.
|
||||
template <typename T>
|
||||
bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool ReadAllChildren(std::vector<T>* children);
|
||||
|
||||
bool ReadFourCC(FourCC* fourcc) {
|
||||
uint32_t val;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/rcheck.h"
|
||||
#include "packager/media/formats/mp4/box_buffer.h"
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include "packager/media/formats/mp4/chunk_info_iterator.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/media/formats/mp4/chunk_info_iterator.h"
|
||||
|
||||
namespace {
|
||||
struct ChunkProperty {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "packager/media/formats/mp4/composition_offset_iterator.h"
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
#include "packager/media/formats/mp4/key_frame_info.h"
|
||||
#include "packager/status_macros.h"
|
||||
#include "packager/status/status_macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
@ -80,7 +80,8 @@ Status Fragmenter::AddSample(const MediaSample& sample) {
|
|||
static_cast<uint32_t>(sample.data_size()));
|
||||
traf_->runs[0].sample_durations.push_back(duration);
|
||||
traf_->runs[0].sample_flags.push_back(
|
||||
sample.is_key_frame() ? 0 : TrackFragmentHeader::kNonKeySampleMask);
|
||||
sample.is_key_frame() ? TrackFragmentHeader::kUnset
|
||||
: TrackFragmentHeader::kNonKeySampleMask);
|
||||
|
||||
if (sample.decrypt_config()) {
|
||||
NewSampleEncryptionEntry(
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/status.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/macros.h"
|
||||
#include "packager/status/status.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
#include "packager/media/formats/mp4/fragmenter.h"
|
||||
#include "packager/media/formats/mp4/key_frame_info.h"
|
||||
#include "packager/status_macros.h"
|
||||
#include "packager/status/status_macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
# Copyright 2014 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
|
||||
|
||||
{
|
||||
'variables': {
|
||||
'shaka_code': 1,
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'mp4',
|
||||
'type': '<(component)',
|
||||
'sources': [
|
||||
'box.cc',
|
||||
'box.h',
|
||||
'box_buffer.h',
|
||||
'box_definitions.cc',
|
||||
'box_definitions.h',
|
||||
'box_reader.cc',
|
||||
'box_reader.h',
|
||||
'chunk_info_iterator.cc',
|
||||
'chunk_info_iterator.h',
|
||||
'composition_offset_iterator.cc',
|
||||
'composition_offset_iterator.h',
|
||||
'decoding_time_iterator.cc',
|
||||
'decoding_time_iterator.h',
|
||||
'fragmenter.cc',
|
||||
'fragmenter.h',
|
||||
'key_frame_info.h',
|
||||
'low_latency_segment_segmenter.cc',
|
||||
'low_latency_segment_segmenter.h',
|
||||
'mp4_media_parser.cc',
|
||||
'mp4_media_parser.h',
|
||||
'mp4_muxer.cc',
|
||||
'mp4_muxer.h',
|
||||
'multi_segment_segmenter.cc',
|
||||
'multi_segment_segmenter.h',
|
||||
'segmenter.cc',
|
||||
'segmenter.h',
|
||||
'single_segment_segmenter.cc',
|
||||
'single_segment_segmenter.h',
|
||||
'sync_sample_iterator.cc',
|
||||
'sync_sample_iterator.h',
|
||||
'track_run_iterator.cc',
|
||||
'track_run_iterator.h',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../../third_party/boringssl/boringssl.gyp:boringssl',
|
||||
'../../../third_party/gflags/gflags.gyp:gflags',
|
||||
'../../base/media_base.gyp:media_base',
|
||||
'../../codecs/codecs.gyp:codecs',
|
||||
'../../event/media_event.gyp:media_event',
|
||||
'../../formats/ttml/ttml.gyp:ttml',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'mp4_unittest',
|
||||
'type': '<(gtest_target_type)',
|
||||
'sources': [
|
||||
'box_definitions_unittest.cc',
|
||||
'box_reader_unittest.cc',
|
||||
'chunk_info_iterator_unittest.cc',
|
||||
'composition_offset_iterator_unittest.cc',
|
||||
'decoding_time_iterator_unittest.cc',
|
||||
'mp4_media_parser_unittest.cc',
|
||||
'sync_sample_iterator_unittest.cc',
|
||||
'track_run_iterator_unittest.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../../file/file.gyp:file',
|
||||
'../../../testing/gtest.gyp:gtest',
|
||||
'../../../testing/gmock.gyp:gmock',
|
||||
'../../../third_party/gflags/gflags.gyp:gflags',
|
||||
'../../test/media_test.gyp:media_test_support',
|
||||
'mp4',
|
||||
]
|
||||
},
|
||||
],
|
||||
}
|
|
@ -7,10 +7,9 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "packager/base/callback.h"
|
||||
#include "packager/base/callback_helpers.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <glog/logging.h>
|
||||
#include <functional>
|
||||
#include "packager/file/file.h"
|
||||
#include "packager/file/file_closer.h"
|
||||
#include "packager/media/base/audio_stream_info.h"
|
||||
|
@ -23,11 +22,11 @@
|
|||
#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/ac4_audio_util.h"
|
||||
#include "packager/media/codecs/av1_codec_configuration_record.h"
|
||||
#include "packager/media/codecs/avc_decoder_configuration_record.h"
|
||||
#include "packager/media/codecs/dovi_decoder_configuration_record.h"
|
||||
#include "packager/media/codecs/ec3_audio_util.h"
|
||||
#include "packager/media/codecs/ac4_audio_util.h"
|
||||
#include "packager/media/codecs/es_descriptor.h"
|
||||
#include "packager/media/codecs/hevc_decoder_configuration_record.h"
|
||||
#include "packager/media/codecs/vp_codec_configuration_record.h"
|
||||
|
@ -188,9 +187,9 @@ void MP4MediaParser::Init(const InitCB& init_cb,
|
|||
const NewTextSampleCB& new_text_sample_cb,
|
||||
KeySource* decryption_key_source) {
|
||||
DCHECK_EQ(state_, kWaitingForInit);
|
||||
DCHECK(init_cb_.is_null());
|
||||
DCHECK(!init_cb.is_null());
|
||||
DCHECK(!new_media_sample_cb.is_null());
|
||||
DCHECK(init_cb_ == nullptr);
|
||||
DCHECK(init_cb != nullptr);
|
||||
DCHECK(new_media_sample_cb != nullptr);
|
||||
|
||||
ChangeState(kParsingBoxes);
|
||||
init_cb_ = init_cb;
|
||||
|
@ -742,7 +741,7 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
|
|||
}
|
||||
}
|
||||
|
||||
init_cb_.Run(streams);
|
||||
init_cb_(streams);
|
||||
if (!FetchKeysIfNecessary(moov_->pssh))
|
||||
return false;
|
||||
runs_.reset(new TrackRunIterator(moov_.get()));
|
||||
|
@ -892,7 +891,7 @@ bool MP4MediaParser::EnqueueSample(bool* err) {
|
|||
<< ", cts=" << runs_->cts()
|
||||
<< ", size=" << runs_->sample_size();
|
||||
|
||||
if (!new_sample_cb_.Run(runs_->track_id(), stream_sample)) {
|
||||
if (!new_sample_cb_(runs_->track_id(), stream_sample)) {
|
||||
*err = true;
|
||||
LOG(ERROR) << "Failed to process the sample.";
|
||||
return false;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/callback_forward.h"
|
||||
#include "packager/media/base/decryptor_source.h"
|
||||
#include "packager/media/base/media_parser.h"
|
||||
#include "packager/media/base/offset_byte_queue.h"
|
||||
|
@ -38,8 +37,8 @@ class MP4MediaParser : public MediaParser {
|
|||
const NewMediaSampleCB& new_media_sample_cb,
|
||||
const NewTextSampleCB& new_text_sample_cb,
|
||||
KeySource* decryption_key_source) override;
|
||||
bool Flush() override WARN_UNUSED_RESULT;
|
||||
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
||||
[[nodiscard]] bool Flush() override;
|
||||
[[nodiscard]] bool Parse(const uint8_t* buf, int size) override;
|
||||
/// @}
|
||||
|
||||
/// Handles ISO-BMFF containers which have the 'moov' box trailing the
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packager/base/bind.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include <functional>
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/raw_key_source.h"
|
||||
#include "packager/media/base/stream_info.h"
|
||||
|
@ -95,16 +95,18 @@ class MP4MediaParserTest : public testing::Test {
|
|||
|
||||
void InitializeParser(KeySource* decryption_key_source) {
|
||||
parser_->Init(
|
||||
base::Bind(&MP4MediaParserTest::InitF, base::Unretained(this)),
|
||||
base::Bind(&MP4MediaParserTest::NewSampleF, base::Unretained(this)),
|
||||
base::Bind(&MP4MediaParserTest::NewTextSampleF, base::Unretained(this)),
|
||||
std::bind(&MP4MediaParserTest::InitF, this, std::placeholders::_1),
|
||||
std::bind(&MP4MediaParserTest::NewSampleF, this, std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
std::bind(&MP4MediaParserTest::NewTextSampleF, this,
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
decryption_key_source);
|
||||
}
|
||||
|
||||
bool ParseMP4File(const std::string& filename, int append_bytes) {
|
||||
InitializeParser(NULL);
|
||||
|
||||
if (!parser_->LoadMoov(GetTestDataFilePath(filename).AsUTF8Unsafe()))
|
||||
if (!parser_->LoadMoov(GetTestDataFilePath(filename).string()))
|
||||
return false;
|
||||
|
||||
std::vector<uint8_t> buffer = ReadTestDataFile(filename);
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include "packager/base/time/clock.h"
|
||||
#include "packager/base/time/time.h"
|
||||
#include <absl/strings/escaping.h>
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <chrono>
|
||||
#include "packager/file/file.h"
|
||||
#include "packager/media/base/aes_encryptor.h"
|
||||
#include "packager/media/base/audio_stream_info.h"
|
||||
|
@ -26,7 +26,7 @@
|
|||
#include "packager/media/formats/mp4/multi_segment_segmenter.h"
|
||||
#include "packager/media/formats/mp4/single_segment_segmenter.h"
|
||||
#include "packager/media/formats/ttml/ttml_generator.h"
|
||||
#include "packager/status_macros.h"
|
||||
#include "packager/status/status_macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
@ -135,7 +135,7 @@ void GenerateSinf(FourCC old_type,
|
|||
track_encryption.version = 1;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED() << "Unexpected protection scheme "
|
||||
NOTIMPLEMENTED() << "Unexpected protection scheme "
|
||||
<< encryption_config.protection_scheme;
|
||||
}
|
||||
|
||||
|
@ -434,8 +434,10 @@ bool MP4Muxer::GenerateVideoTrak(const VideoStreamInfo* video_info,
|
|||
video.codec_configuration.data = video_info->codec_config();
|
||||
if (!video.ParseExtraCodecConfigsVector(video_info->extra_config())) {
|
||||
LOG(ERROR) << "Malformed extra codec configs: "
|
||||
<< base::HexEncode(video_info->extra_config().data(),
|
||||
video_info->extra_config().size());
|
||||
<< absl::BytesToHexString(
|
||||
absl::string_view(reinterpret_cast<const char*>(
|
||||
video_info->extra_config().data()),
|
||||
video_info->extra_config().size()));
|
||||
return false;
|
||||
}
|
||||
if (pixel_width != 1 || pixel_height != 1) {
|
||||
|
@ -627,26 +629,26 @@ bool MP4Muxer::GenerateTextTrak(const TextStreamInfo* text_info,
|
|||
return false;
|
||||
}
|
||||
|
||||
base::Optional<Range> MP4Muxer::GetInitRangeStartAndEnd() {
|
||||
std::optional<Range> MP4Muxer::GetInitRangeStartAndEnd() {
|
||||
size_t range_offset = 0;
|
||||
size_t range_size = 0;
|
||||
const bool has_range = segmenter_->GetInitRange(&range_offset, &range_size);
|
||||
|
||||
if (!has_range)
|
||||
return base::nullopt;
|
||||
return std::nullopt;
|
||||
|
||||
Range range;
|
||||
SetStartAndEndFromOffsetAndSize(range_offset, range_size, &range);
|
||||
return range;
|
||||
}
|
||||
|
||||
base::Optional<Range> MP4Muxer::GetIndexRangeStartAndEnd() {
|
||||
std::optional<Range> MP4Muxer::GetIndexRangeStartAndEnd() {
|
||||
size_t range_offset = 0;
|
||||
size_t range_size = 0;
|
||||
const bool has_range = segmenter_->GetIndexRange(&range_offset, &range_size);
|
||||
|
||||
if (!has_range)
|
||||
return base::nullopt;
|
||||
return std::nullopt;
|
||||
|
||||
Range range;
|
||||
SetStartAndEndFromOffsetAndSize(range_offset, range_size, &range);
|
||||
|
@ -684,8 +686,15 @@ void MP4Muxer::FireOnMediaEndEvent() {
|
|||
uint64_t MP4Muxer::IsoTimeNow() {
|
||||
// Time in seconds from Jan. 1, 1904 to epoch time, i.e. Jan. 1, 1970.
|
||||
const uint64_t kIsomTimeOffset = 2082844800l;
|
||||
return kIsomTimeOffset +
|
||||
(clock() ? clock()->Now() : base::Time::Now()).ToDoubleT();
|
||||
|
||||
// Get the current system time since January 1, 1970, in seconds.
|
||||
std::chrono::system_clock::duration duration =
|
||||
std::chrono::system_clock::now().time_since_epoch();
|
||||
std::int64_t secondsSince1970 =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(duration).count();
|
||||
|
||||
// Add the offset of seconds between January 1, 1970, and January 1, 1904.
|
||||
return secondsSince1970 + kIsomTimeOffset;
|
||||
}
|
||||
|
||||
} // namespace mp4
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/optional.h"
|
||||
#include <optional>
|
||||
#include "packager/media/base/muxer.h"
|
||||
|
||||
namespace shaka {
|
||||
|
@ -54,11 +54,11 @@ class MP4Muxer : public Muxer {
|
|||
|
||||
// Gets |start| and |end| initialization range. Returns true if there is an
|
||||
// init range and sets start-end byte-range-spec specified in RFC2616.
|
||||
base::Optional<Range> GetInitRangeStartAndEnd();
|
||||
std::optional<Range> GetInitRangeStartAndEnd();
|
||||
|
||||
// Gets |start| and |end| index range. Returns true if there is an index range
|
||||
// and sets start-end byte-range-spec specified in RFC2616.
|
||||
base::Optional<Range> GetIndexRangeStartAndEnd();
|
||||
std::optional<Range> GetIndexRangeStartAndEnd();
|
||||
|
||||
// Fire events if there are no errors and Muxer::muxer_listener() is not NULL.
|
||||
void FireOnMediaStartEvent();
|
||||
|
@ -69,7 +69,7 @@ class MP4Muxer : public Muxer {
|
|||
|
||||
// Assumes single stream (multiplexed a/v not supported yet).
|
||||
bool to_be_initialized_ = true;
|
||||
base::Optional<int64_t> edit_list_offset_;
|
||||
std::optional<int64_t> edit_list_offset_;
|
||||
|
||||
std::unique_ptr<Segmenter> segmenter_;
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include "packager/base/strings/string_util.h"
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <absl/strings/str_format.h>
|
||||
#include "packager/file/file.h"
|
||||
#include "packager/file/file_closer.h"
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
|
@ -18,7 +18,7 @@
|
|||
#include "packager/media/event/muxer_listener.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
#include "packager/media/formats/mp4/key_frame_info.h"
|
||||
#include "packager/status_macros.h"
|
||||
#include "packager/status/status_macros.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include <glog/logging.h>
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/base/id3_tag.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
|
@ -154,9 +154,9 @@ Status Segmenter::FinalizeSegment(size_t stream_id,
|
|||
}
|
||||
|
||||
DCHECK_LT(stream_id, fragmenters_.size());
|
||||
Fragmenter* fragmenter = fragmenters_[stream_id].get();
|
||||
DCHECK(fragmenter);
|
||||
Status status = fragmenter->FinalizeFragment();
|
||||
Fragmenter* specified_fragmenter = fragmenters_[stream_id].get();
|
||||
DCHECK(specified_fragmenter);
|
||||
Status status = specified_fragmenter->FinalizeFragment();
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
|
@ -228,14 +228,14 @@ Status Segmenter::FinalizeSegment(size_t stream_id,
|
|||
|
||||
if (segment_info.is_chunk) {
|
||||
// Finalize the completed chunk for the LL-DASH case.
|
||||
Status status = DoFinalizeChunk();
|
||||
status = DoFinalizeChunk();
|
||||
if (!status.ok())
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!segment_info.is_subsegment || segment_info.is_final_chunk_in_seg) {
|
||||
// Finalize the segment.
|
||||
Status status = DoFinalizeSegment();
|
||||
status = DoFinalizeSegment();
|
||||
// Reset segment information to initial state.
|
||||
sidx_->references.clear();
|
||||
key_frame_infos_.clear();
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/optional.h"
|
||||
#include <optional>
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/range.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
#include "packager/status.h"
|
||||
#include "packager/status/status.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
@ -77,7 +77,7 @@ class Segmenter {
|
|||
Status FinalizeSegment(size_t stream_id, const SegmentInfo& segment_info);
|
||||
|
||||
// TODO(rkuroiwa): Change these Get*Range() methods to return
|
||||
// base::Optional<Range> as well.
|
||||
// std::optional<Range> as well.
|
||||
/// @return true if there is an initialization range, while setting @a offset
|
||||
/// and @a size; or false if initialization range does not apply.
|
||||
virtual bool GetInitRange(size_t* offset, size_t* size) = 0;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/macros.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
|
||||
namespace shaka {
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
#include "packager/media/formats/mp4/track_run_iterator.h"
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
#include <absl/flags/flag.h>
|
||||
|
||||
DEFINE_bool(mp4_reset_initial_composition_offset_to_zero,
|
||||
ABSL_FLAG(bool,
|
||||
mp4_reset_initial_composition_offset_to_zero,
|
||||
true,
|
||||
"MP4 only. If it is true, reset the initial composition offset to "
|
||||
"zero, i.e. by assuming that there is a missing EditList.");
|
||||
|
@ -331,7 +332,7 @@ bool TrackRunIterator::Init(const MovieFragment& moof) {
|
|||
video_sample_entry = &stsd.video_entries[desc_idx];
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
NOTIMPLEMENTED();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -700,7 +701,7 @@ int64_t TrackRunIterator::GetTimestampAdjustment(const Movie& movie,
|
|||
LOG(WARNING) << "Seeing non-zero composition offset "
|
||||
<< composition_offset
|
||||
<< ". An EditList is probably missing.";
|
||||
if (FLAGS_mp4_reset_initial_composition_offset_to_zero) {
|
||||
if (absl::GetFlag(FLAGS_mp4_reset_initial_composition_offset_to_zero)) {
|
||||
LOG(WARNING)
|
||||
<< "Adjusting timestamps by " << -composition_offset
|
||||
<< ". Please file a bug to "
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue