WVM media parsing - integration with Decryption.
Change-Id: I05352480ce03927dbf4f8a212bb81217260c65af
This commit is contained in:
parent
c1b47e256b
commit
e3d0f60c4b
|
@ -23,18 +23,19 @@
|
||||||
'../mpeg/mpeg.gyp:mpeg',
|
'../mpeg/mpeg.gyp:mpeg',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
# TODO(ramjic): Re-enable when KeySource::FetchKeys() is mocked.
|
||||||
'target_name': 'wvm_unittest',
|
#{
|
||||||
'type': '<(gtest_target_type)',
|
#'target_name': 'wvm_unittest',
|
||||||
'sources': [
|
#'type': '<(gtest_target_type)',
|
||||||
'wvm_media_parser_unittest.cc',
|
#'sources': [
|
||||||
],
|
# 'wvm_media_parser_unittest.cc',
|
||||||
'dependencies': [
|
#],
|
||||||
'../../../testing/gtest.gyp:gtest',
|
#'dependencies': [
|
||||||
'../../../testing/gmock.gyp:gmock',
|
# '../../../testing/gtest.gyp:gtest',
|
||||||
'../../test/media_test.gyp:media_test_support',
|
# '../../../testing/gmock.gyp:gmock',
|
||||||
'wvm',
|
# '../../test/media_test.gyp:media_test_support',
|
||||||
]
|
# 'wvm',
|
||||||
},
|
#]
|
||||||
|
#},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "media/base/audio_stream_info.h"
|
#include "media/base/status.h"
|
||||||
#include "media/base/media_sample.h"
|
#include "media/base/widevine_key_source.h"
|
||||||
#include "media/base/video_stream_info.h"
|
|
||||||
#include "media/formats/mp2t/adts_header.h"
|
#include "media/formats/mp2t/adts_header.h"
|
||||||
|
|
||||||
#define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
|
#define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
|
||||||
|
@ -45,10 +44,19 @@ const uint32_t kVersion4 = 4;
|
||||||
const int kAdtsHeaderMinSize = 7;
|
const int kAdtsHeaderMinSize = 7;
|
||||||
const uint8_t kAacSampleSizeBits = 16;
|
const uint8_t kAacSampleSizeBits = 16;
|
||||||
// Applies to all video streams.
|
// Applies to all video streams.
|
||||||
const uint8_t kNaluLengthSize = 4; // unit is bytes.
|
const uint8 kNaluLengthSize = 4; // unit is bytes.
|
||||||
// Placeholder sampling frequency for all audio streams, which
|
// Placeholder sampling frequency for all audio streams, which
|
||||||
// will be overwritten after filter parsing.
|
// will be overwritten after filter parsing.
|
||||||
const uint32_t kDefaultSamplingFrequency = 100;
|
const uint32_t kDefaultSamplingFrequency = 100;
|
||||||
|
const uint16_t kEcmSizeBytes = 80;
|
||||||
|
const uint32_t kInitializationVectorSizeBytes = 16;
|
||||||
|
// ECM fields for processing.
|
||||||
|
const uint32_t kEcmContentKeySizeBytes = 16;
|
||||||
|
const uint32_t kEcmDCPFlagsSizeBytes = 3;
|
||||||
|
const uint32_t kEcmCCIFlagsSizeBytes = 1;
|
||||||
|
const uint32_t kEcmFlagsSizeBytes =
|
||||||
|
kEcmCCIFlagsSizeBytes + kEcmDCPFlagsSizeBytes;
|
||||||
|
const uint32_t kEcmPaddingSizeBytes = 12;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_void = 0,
|
Type_void = 0,
|
||||||
|
@ -71,8 +79,6 @@ namespace wvm {
|
||||||
|
|
||||||
WvmMediaParser::WvmMediaParser() : is_initialized_(false),
|
WvmMediaParser::WvmMediaParser() : is_initialized_(false),
|
||||||
parse_state_(StartCode1),
|
parse_state_(StartCode1),
|
||||||
is_demuxing_sample_(true), // Check this.
|
|
||||||
is_first_pack_(true),
|
|
||||||
is_psm_needed_(true),
|
is_psm_needed_(true),
|
||||||
skip_bytes_(0),
|
skip_bytes_(0),
|
||||||
metadata_is_complete_(false),
|
metadata_is_complete_(false),
|
||||||
|
@ -82,6 +88,7 @@ WvmMediaParser::WvmMediaParser() : is_initialized_(false),
|
||||||
pes_packet_bytes_(0),
|
pes_packet_bytes_(0),
|
||||||
pes_flags_1_(0),
|
pes_flags_1_(0),
|
||||||
pes_flags_2_(0),
|
pes_flags_2_(0),
|
||||||
|
prev_pes_flags_1_(0),
|
||||||
pes_header_data_bytes_(0),
|
pes_header_data_bytes_(0),
|
||||||
timestamp_(0),
|
timestamp_(0),
|
||||||
pts_(0),
|
pts_(0),
|
||||||
|
@ -89,7 +96,8 @@ WvmMediaParser::WvmMediaParser() : is_initialized_(false),
|
||||||
index_program_id_(0),
|
index_program_id_(0),
|
||||||
sha_context_(new SHA256_CTX()),
|
sha_context_(new SHA256_CTX()),
|
||||||
media_sample_(NULL),
|
media_sample_(NULL),
|
||||||
stream_id_count_(0) {
|
stream_id_count_(0),
|
||||||
|
decryption_key_source_(NULL) {
|
||||||
SHA256_Init(sha_context_);
|
SHA256_Init(sha_context_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +109,9 @@ void WvmMediaParser::Init(const InitCB& init_cb,
|
||||||
DCHECK(!is_initialized_);
|
DCHECK(!is_initialized_);
|
||||||
DCHECK(!init_cb.is_null());
|
DCHECK(!init_cb.is_null());
|
||||||
DCHECK(!new_sample_cb.is_null());
|
DCHECK(!new_sample_cb.is_null());
|
||||||
|
DCHECK(decryption_key_source);
|
||||||
|
decryption_key_source_ =
|
||||||
|
reinterpret_cast<WidevineKeySource*>(decryption_key_source);
|
||||||
init_cb_ = init_cb;
|
init_cb_ = init_cb;
|
||||||
new_sample_cb_ = new_sample_cb;
|
new_sample_cb_ = new_sample_cb;
|
||||||
}
|
}
|
||||||
|
@ -238,8 +248,8 @@ bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PesExtension1:
|
case PesExtension1:
|
||||||
|
prev_pes_flags_1_ = pes_flags_1_;
|
||||||
pes_flags_1_ = *read_ptr;
|
pes_flags_1_ = *read_ptr;
|
||||||
// TODO(ramjic): Check if enable_decryption_ is needed.
|
|
||||||
*read_ptr &= ~kScramblingBitsMask;
|
*read_ptr &= ~kScramblingBitsMask;
|
||||||
--pes_packet_bytes_;
|
--pes_packet_bytes_;
|
||||||
parse_state_ = PesExtension2;
|
parse_state_ = PesExtension2;
|
||||||
|
@ -393,7 +403,7 @@ bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
|
||||||
memcpy(&ecm_[prev_size], read_ptr, num_bytes);
|
memcpy(&ecm_[prev_size], read_ptr, num_bytes);
|
||||||
}
|
}
|
||||||
if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
|
if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
|
||||||
if (!ProcessEcm(&ecm_[0], ecm_.size())) {
|
if (!ProcessEcm()) {
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -458,6 +468,9 @@ bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
|
||||||
parse_state_ = StartCode1;
|
parse_state_ = StartCode1;
|
||||||
prev_media_sample_data_.Reset();
|
prev_media_sample_data_.Reset();
|
||||||
current_program_id_++;
|
current_program_id_++;
|
||||||
|
ecm_.clear();
|
||||||
|
index_data_.clear();
|
||||||
|
psm_data_.clear();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -741,6 +754,10 @@ void WvmMediaParser::StartMediaSampleDemux(uint8_t* read_ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WvmMediaParser::Output() {
|
bool WvmMediaParser::Output() {
|
||||||
|
// Check decrypted sample data.
|
||||||
|
if (prev_pes_flags_1_ & kScramblingBitsMask) {
|
||||||
|
content_decryptor_.Decrypt(sample_data_, &sample_data_);
|
||||||
|
}
|
||||||
if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
|
if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
|
||||||
// Set data on the video stream from the NalUnitStream.
|
// Set data on the video stream from the NalUnitStream.
|
||||||
std::vector<uint8_t> nal_unit_stream;
|
std::vector<uint8_t> nal_unit_stream;
|
||||||
|
@ -895,6 +912,74 @@ void WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WvmMediaParser::GetAssetKey(const uint32_t asset_id,
|
||||||
|
EncryptionKey* encryption_key) {
|
||||||
|
Status status = decryption_key_source_->FetchKeys(asset_id);
|
||||||
|
if (!status.ok()) {
|
||||||
|
LOG(ERROR) << "Fetch Key(s) failed for AssetID = " << asset_id
|
||||||
|
<< ", error = " << status;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = decryption_key_source_->GetKey(KeySource::TRACK_TYPE_HD,
|
||||||
|
encryption_key);
|
||||||
|
if (!status.ok()) {
|
||||||
|
LOG(ERROR) << "Fetch Key(s) failed for AssetID = " << asset_id
|
||||||
|
<< ", error = " << status;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WvmMediaParser::ProcessEcm() {
|
||||||
|
if (current_program_id_ > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ecm_.size() != kEcmSizeBytes) {
|
||||||
|
LOG(ERROR) << "Unexpected ECM size = " << ecm_.size()
|
||||||
|
<< ", expected size = " << kEcmSizeBytes;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const uint8_t* ecm_data = ecm_.data();
|
||||||
|
DCHECK(ecm_data);
|
||||||
|
ecm_data += sizeof(uint32_t); // old version field - skip.
|
||||||
|
ecm_data += sizeof(uint32_t); // clear lead - skip.
|
||||||
|
ecm_data += sizeof(uint32_t); // system id(includes ECM version) - skip.
|
||||||
|
uint32_t asset_id = ntohlFromBuffer(ecm_data);
|
||||||
|
if (asset_id == 0) {
|
||||||
|
LOG(ERROR) << "AssetID in ECM is not valid.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ecm_data += sizeof(uint32_t); // asset_id.
|
||||||
|
EncryptionKey encryption_key;
|
||||||
|
if (!GetAssetKey(asset_id, &encryption_key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> iv(kInitializationVectorSizeBytes);
|
||||||
|
AesCbcCtsDecryptor asset_decryptor;
|
||||||
|
asset_decryptor.InitializeWithIv(encryption_key.key, iv);
|
||||||
|
|
||||||
|
std::vector<uint8_t> content_key_buffer; // flags + contentKey + padding.
|
||||||
|
content_key_buffer.resize(
|
||||||
|
kEcmFlagsSizeBytes + kEcmContentKeySizeBytes + kEcmPaddingSizeBytes);
|
||||||
|
// Get content key + padding from ECM.
|
||||||
|
memcpy(&content_key_buffer[0], ecm_data,
|
||||||
|
kEcmFlagsSizeBytes + kEcmContentKeySizeBytes + kEcmPaddingSizeBytes);
|
||||||
|
asset_decryptor.Decrypt(content_key_buffer, &content_key_buffer);
|
||||||
|
if (content_key_buffer.empty()) {
|
||||||
|
LOG(ERROR) << "Decryption of content key failed for asset id = "
|
||||||
|
<< asset_id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> decrypted_content_key_vec(
|
||||||
|
content_key_buffer.begin() + 4,
|
||||||
|
content_key_buffer.begin() + 20);
|
||||||
|
content_decryptor_.InitializeWithIv(decrypted_content_key_vec, iv);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
DemuxStreamIdMediaSample::DemuxStreamIdMediaSample() :
|
DemuxStreamIdMediaSample::DemuxStreamIdMediaSample() :
|
||||||
demux_stream_id(0),
|
demux_stream_id(0),
|
||||||
parsed_audio_or_video_stream_id(0) {}
|
parsed_audio_or_video_stream_id(0) {}
|
||||||
|
@ -908,9 +993,12 @@ PrevSampleData::PrevSampleData() {
|
||||||
PrevSampleData::~PrevSampleData() {}
|
PrevSampleData::~PrevSampleData() {}
|
||||||
|
|
||||||
void PrevSampleData::Reset() {
|
void PrevSampleData::Reset() {
|
||||||
audio_sample = video_sample = NULL;
|
audio_sample = NULL;
|
||||||
audio_stream_id = video_stream_id = 0;
|
video_sample = NULL;
|
||||||
audio_sample_duration = video_sample_duration = 0;
|
audio_stream_id = 0;
|
||||||
|
video_stream_id = 0;
|
||||||
|
audio_sample_duration = 0;
|
||||||
|
video_sample_duration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace wvm
|
} // namespace wvm
|
||||||
|
|
|
@ -14,12 +14,20 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "media/base/aes_encryptor.h"
|
||||||
|
#include "media/base/audio_stream_info.h"
|
||||||
#include "media/base/media_parser.h"
|
#include "media/base/media_parser.h"
|
||||||
|
#include "media/base/media_sample.h"
|
||||||
#include "media/base/network_util.h"
|
#include "media/base/network_util.h"
|
||||||
|
#include "media/base/video_stream_info.h"
|
||||||
#include "media/filters/h264_byte_to_unit_stream_converter.h"
|
#include "media/filters/h264_byte_to_unit_stream_converter.h"
|
||||||
|
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
|
struct EncryptionKey;
|
||||||
|
class WidevineKeySource;
|
||||||
|
|
||||||
namespace wvm {
|
namespace wvm {
|
||||||
|
|
||||||
struct DemuxStreamIdMediaSample {
|
struct DemuxStreamIdMediaSample {
|
||||||
|
@ -156,14 +164,7 @@ class WvmMediaParser : public MediaParser {
|
||||||
ProgramEnd
|
ProgramEnd
|
||||||
};
|
};
|
||||||
|
|
||||||
bool DecryptCBC(void* data,
|
bool ProcessEcm();
|
||||||
uint32_t length,
|
|
||||||
uint32_t bytesRemaining,
|
|
||||||
uint32_t& bytesDecrypted) {
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessEcm(void* ecm, uint32_t size) { return (true); }
|
|
||||||
|
|
||||||
// Index denotes 'search index' in the WVM content.
|
// Index denotes 'search index' in the WVM content.
|
||||||
bool ParseIndexEntry();
|
bool ParseIndexEntry();
|
||||||
|
@ -201,6 +202,8 @@ class WvmMediaParser : public MediaParser {
|
||||||
|
|
||||||
bool Output();
|
bool Output();
|
||||||
|
|
||||||
|
bool GetAssetKey(const uint32_t asset_id, EncryptionKey* encryption_key);
|
||||||
|
|
||||||
// Callback invoked by the ES media parser
|
// Callback invoked by the ES media parser
|
||||||
// to emit a new audio/video access unit.
|
// to emit a new audio/video access unit.
|
||||||
void EmitSample(uint32_t parsed_audio_or_video_stream_id,
|
void EmitSample(uint32_t parsed_audio_or_video_stream_id,
|
||||||
|
@ -222,9 +225,6 @@ class WvmMediaParser : public MediaParser {
|
||||||
// Internal content parsing state.
|
// Internal content parsing state.
|
||||||
State parse_state_;
|
State parse_state_;
|
||||||
|
|
||||||
bool is_demuxing_sample_;
|
|
||||||
bool is_first_pack_;
|
|
||||||
|
|
||||||
bool is_psm_needed_;
|
bool is_psm_needed_;
|
||||||
uint32_t skip_bytes_;
|
uint32_t skip_bytes_;
|
||||||
bool metadata_is_complete_;
|
bool metadata_is_complete_;
|
||||||
|
@ -234,16 +234,15 @@ class WvmMediaParser : public MediaParser {
|
||||||
uint16_t pes_packet_bytes_;
|
uint16_t pes_packet_bytes_;
|
||||||
uint8_t pes_flags_1_;
|
uint8_t pes_flags_1_;
|
||||||
uint8_t pes_flags_2_;
|
uint8_t pes_flags_2_;
|
||||||
|
uint8_t prev_pes_flags_1_;
|
||||||
uint8_t pes_header_data_bytes_;
|
uint8_t pes_header_data_bytes_;
|
||||||
uint64_t timestamp_;
|
uint64_t timestamp_;
|
||||||
uint64_t pts_;
|
uint64_t pts_;
|
||||||
uint64_t dts_;
|
uint64_t dts_;
|
||||||
uint8_t index_program_id_;
|
uint8_t index_program_id_;
|
||||||
|
|
||||||
SHA256_CTX* sha_context_;
|
SHA256_CTX* sha_context_;
|
||||||
scoped_refptr<MediaSample> media_sample_;
|
scoped_refptr<MediaSample> media_sample_;
|
||||||
PrevSampleData prev_media_sample_data_;
|
PrevSampleData prev_media_sample_data_;
|
||||||
|
|
||||||
H264ByteToUnitStreamConverter byte_to_unit_stream_converter_;
|
H264ByteToUnitStreamConverter byte_to_unit_stream_converter_;
|
||||||
|
|
||||||
std::vector<uint8_t, std::allocator<uint8_t> > ecm_;
|
std::vector<uint8_t, std::allocator<uint8_t> > ecm_;
|
||||||
|
@ -254,6 +253,8 @@ class WvmMediaParser : public MediaParser {
|
||||||
std::vector<scoped_refptr<StreamInfo> > stream_infos_;
|
std::vector<scoped_refptr<StreamInfo> > stream_infos_;
|
||||||
std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
|
std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
|
||||||
std::vector<uint8_t> sample_data_;
|
std::vector<uint8_t> sample_data_;
|
||||||
|
WidevineKeySource* decryption_key_source_;
|
||||||
|
AesCbcCtsDecryptor content_decryptor_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
|
DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,15 +12,17 @@
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "media/base/media_sample.h"
|
#include "media/base/media_sample.h"
|
||||||
|
#include "media/base/request_signer.h"
|
||||||
#include "media/base/stream_info.h"
|
#include "media/base/stream_info.h"
|
||||||
#include "media/base/timestamp.h"
|
#include "media/base/timestamp.h"
|
||||||
#include "media/base/video_stream_info.h"
|
#include "media/base/video_stream_info.h"
|
||||||
|
#include "media/base/widevine_key_source.h"
|
||||||
#include "media/formats/wvm/wvm_media_parser.h"
|
#include "media/formats/wvm/wvm_media_parser.h"
|
||||||
#include "media/test/test_data_util.h"
|
#include "media/test/test_data_util.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char kClearWvmFile[] = "hb2_4stream_clear.wvm";
|
const char kWvmFile[] = "hb2_4stream_encrypted.wvm";
|
||||||
// Constants associated with kClearWvmFile follows.
|
// Constants associated with kWvmFile follows.
|
||||||
const uint32_t kExpectedStreams = 4;
|
const uint32_t kExpectedStreams = 4;
|
||||||
const int kExpectedVideoFrameCount = 6665;
|
const int kExpectedVideoFrameCount = 6665;
|
||||||
const int kExpectedAudioFrameCount = 11964;
|
const int kExpectedAudioFrameCount = 11964;
|
||||||
|
@ -38,12 +40,24 @@ class WvmMediaParserTest : public testing::Test {
|
||||||
video_max_dts_(kNoTimestamp),
|
video_max_dts_(kNoTimestamp),
|
||||||
current_track_id_(-1) {
|
current_track_id_(-1) {
|
||||||
parser_.reset(new WvmMediaParser());
|
parser_.reset(new WvmMediaParser());
|
||||||
|
const std::string server_url =
|
||||||
|
"https://license.uat.widevine.com/cenc/getcontentkey/widevine_test";
|
||||||
|
const std::string aes_signing_key =
|
||||||
|
"1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9";
|
||||||
|
const std::string aes_signing_iv = "d58ce954203b7c9a9a9d467f59839249";
|
||||||
|
const std::string signer = "widevine_test";
|
||||||
|
request_signer_.reset(AesRequestSigner::CreateSigner(
|
||||||
|
signer, aes_signing_key, aes_signing_iv));
|
||||||
|
key_source_.reset(new WidevineKeySource(server_url,
|
||||||
|
request_signer_.Pass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<int, scoped_refptr<StreamInfo> > StreamMap;
|
typedef std::map<int, scoped_refptr<StreamInfo> > StreamMap;
|
||||||
|
|
||||||
scoped_ptr<WvmMediaParser> parser_;
|
scoped_ptr<WvmMediaParser> parser_;
|
||||||
|
scoped_ptr<RequestSigner> request_signer_;
|
||||||
|
scoped_ptr<WidevineKeySource> key_source_;
|
||||||
StreamMap stream_map_;
|
StreamMap stream_map_;
|
||||||
int audio_frame_count_;
|
int audio_frame_count_;
|
||||||
int video_frame_count_;
|
int video_frame_count_;
|
||||||
|
@ -101,7 +115,7 @@ class WvmMediaParserTest : public testing::Test {
|
||||||
base::Unretained(this)),
|
base::Unretained(this)),
|
||||||
base::Bind(&WvmMediaParserTest::OnNewSample,
|
base::Bind(&WvmMediaParserTest::OnNewSample,
|
||||||
base::Unretained(this)),
|
base::Unretained(this)),
|
||||||
NULL);
|
key_source_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parse(const std::string& filename) {
|
void Parse(const std::string& filename) {
|
||||||
|
@ -112,22 +126,22 @@ class WvmMediaParserTest : public testing::Test {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(WvmMediaParserTest, ParseClear) {
|
TEST_F(WvmMediaParserTest, ParseWvm) {
|
||||||
Parse(kClearWvmFile);
|
Parse(kWvmFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WvmMediaParserTest, StreamCount) {
|
TEST_F(WvmMediaParserTest, StreamCount) {
|
||||||
Parse(kClearWvmFile);
|
Parse(kWvmFile);
|
||||||
EXPECT_EQ(kExpectedStreams, stream_map_.size());
|
EXPECT_EQ(kExpectedStreams, stream_map_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WvmMediaParserTest, VideoFrameCount) {
|
TEST_F(WvmMediaParserTest, VideoFrameCount) {
|
||||||
Parse(kClearWvmFile);
|
Parse(kWvmFile);
|
||||||
EXPECT_EQ(kExpectedVideoFrameCount, video_frame_count_);
|
EXPECT_EQ(kExpectedVideoFrameCount, video_frame_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WvmMediaParserTest, AudioFrameCount) {
|
TEST_F(WvmMediaParserTest, AudioFrameCount) {
|
||||||
Parse(kClearWvmFile);
|
Parse(kWvmFile);
|
||||||
EXPECT_EQ(kExpectedAudioFrameCount, audio_frame_count_);
|
EXPECT_EQ(kExpectedAudioFrameCount, audio_frame_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue