VodMediaInfoDumpMuxerListener unit tests
Change-Id: Ib9ff3737f084fc835457fc931162c9a2e9c441bc
This commit is contained in:
parent
0170d0530e
commit
d07007a5d2
|
@ -22,6 +22,7 @@ class MuxerOptions;
|
||||||
namespace event {
|
namespace event {
|
||||||
|
|
||||||
class VodMediaInfoDumpMuxerListener : public MuxerListener {
|
class VodMediaInfoDumpMuxerListener : public MuxerListener {
|
||||||
|
public:
|
||||||
// This object does not own |output_file|. The file has to be open and be
|
// This object does not own |output_file|. The file has to be open and be
|
||||||
// ready for Write(). This will Flush() the file on write but it does not
|
// ready for Write(). This will Flush() the file on write but it does not
|
||||||
// Close() the file.
|
// Close() the file.
|
||||||
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/file_util.h"
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
#include "media/event/vod_media_info_dump_muxer_listener.h"
|
||||||
|
#include "media/file/file.h"
|
||||||
|
#include "media/base/muxer_options.h"
|
||||||
|
#include "media/base/video_stream_info.h"
|
||||||
|
#include "mpd/base/media_info.pb.h"
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
#include "third_party/protobuf/src/google/protobuf/text_format.h"
|
||||||
|
|
||||||
|
using dash_packager::MediaInfo;
|
||||||
|
|
||||||
|
namespace media {
|
||||||
|
namespace event {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct VideoStreamInfoParameters {
|
||||||
|
int track_id;
|
||||||
|
uint32 time_scale;
|
||||||
|
uint64 duration;
|
||||||
|
VideoCodec codec;
|
||||||
|
std::string codec_string;
|
||||||
|
std::string language;
|
||||||
|
uint16 width;
|
||||||
|
uint16 height;
|
||||||
|
uint8 nalu_length_size;
|
||||||
|
std::vector<uint8> extra_data;
|
||||||
|
bool is_encrypted;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note that this does not have vector of StreamInfo pointer.
|
||||||
|
struct OnMediaEndParameters {
|
||||||
|
bool has_init_range;
|
||||||
|
uint64 init_range_start;
|
||||||
|
uint64 init_range_end;
|
||||||
|
bool has_index_range;
|
||||||
|
uint64 index_range_start;
|
||||||
|
uint64 index_range_end;
|
||||||
|
float duration_seconds;
|
||||||
|
uint64 file_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
scoped_refptr<StreamInfo> CreateVideoStreamInfo(
|
||||||
|
const VideoStreamInfoParameters& param) {
|
||||||
|
return scoped_refptr<StreamInfo>(
|
||||||
|
new VideoStreamInfo(param.track_id,
|
||||||
|
param.time_scale,
|
||||||
|
param.duration,
|
||||||
|
param.codec,
|
||||||
|
param.codec_string,
|
||||||
|
param.language,
|
||||||
|
param.width,
|
||||||
|
param.height,
|
||||||
|
param.nalu_length_size,
|
||||||
|
¶m.extra_data[0],
|
||||||
|
param.extra_data.size(),
|
||||||
|
param.is_encrypted));
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoStreamInfoParameters GetDefaultVideoStreamInfoParams() {
|
||||||
|
const int kTrackId = 0;
|
||||||
|
const uint32 kTimeScale = 10;
|
||||||
|
const uint64 kVideoStreamDuration = 200;
|
||||||
|
const VideoCodec kH264Codec = kCodecH264;
|
||||||
|
const uint8 kH264Profile = 1;
|
||||||
|
const uint8 kH264CompatibleProfile = 1;
|
||||||
|
const uint8 kH264Level = 1;
|
||||||
|
const char* kLanuageUndefined = "und";
|
||||||
|
const uint16 kWidth = 720;
|
||||||
|
const uint16 kHeight = 480;
|
||||||
|
const uint8 kNaluLengthSize = 1;
|
||||||
|
const std::vector<uint8> kExtraData;
|
||||||
|
const bool kEncryptedFlag = false;
|
||||||
|
|
||||||
|
return {kTrackId, kTimeScale, kVideoStreamDuration, kH264Codec,
|
||||||
|
VideoStreamInfo::GetCodecString(
|
||||||
|
kCodecH264, kH264Profile, kH264CompatibleProfile, kH264Level),
|
||||||
|
kLanuageUndefined, kWidth, kHeight, kNaluLengthSize, kExtraData,
|
||||||
|
kEncryptedFlag};
|
||||||
|
}
|
||||||
|
|
||||||
|
OnMediaEndParameters GetDefaultOnMediaEndParams() {
|
||||||
|
// Values for {init, index} range {start, end} are arbitrary, but makes sure
|
||||||
|
// that it is monotonically increasing and contiguous.
|
||||||
|
const bool kHasInitRange = true;
|
||||||
|
const uint64 kInitRangeStart = 0;
|
||||||
|
const uint64 kInitRangeEnd = kInitRangeStart + 120;
|
||||||
|
const uint64 kHasIndexRange = true;
|
||||||
|
const uint64 kIndexRangeStart = kInitRangeEnd + 1;
|
||||||
|
const uint64 kIndexRangeEnd = kIndexRangeStart + 100;
|
||||||
|
const float kMediaDuration = 10.5f;
|
||||||
|
const uint64 kFileSize = 10000;
|
||||||
|
return {kHasInitRange, kInitRangeStart, kInitRangeEnd, kHasIndexRange,
|
||||||
|
kIndexRangeStart, kIndexRangeEnd, kMediaDuration, kFileSize};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDefaultMuxerOptionsValues(MuxerOptions* muxer_options) {
|
||||||
|
muxer_options->single_segment = false;
|
||||||
|
muxer_options->segment_duration = 10.0;
|
||||||
|
muxer_options->fragment_duration = 10.0;
|
||||||
|
muxer_options->segment_sap_aligned = true;
|
||||||
|
muxer_options->fragment_sap_aligned = true;
|
||||||
|
muxer_options->num_subsegments_per_sidx = 0;
|
||||||
|
muxer_options->output_file_name = "test_output_file_name.mp4";
|
||||||
|
muxer_options->segment_template.clear();
|
||||||
|
muxer_options->temp_file_name.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpectMediaInfoEqual(const MediaInfo& expect, const MediaInfo& actual) {
|
||||||
|
// I found out here
|
||||||
|
// https://groups.google.com/forum/#!msg/protobuf/5sOExQkB2eQ/ZSBNZI0K54YJ
|
||||||
|
// that the best way to check equality is to serialize and check equality.
|
||||||
|
std::string expect_serialized;
|
||||||
|
std::string actual_serialized;
|
||||||
|
ASSERT_TRUE(expect.SerializeToString(&expect_serialized));
|
||||||
|
ASSERT_TRUE(actual.SerializeToString(&actual_serialized));
|
||||||
|
ASSERT_EQ(expect_serialized, actual_serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpectTextFormatMediaInfoEqual(const std::string& expect,
|
||||||
|
const std::string& actual) {
|
||||||
|
MediaInfo expect_media_info;
|
||||||
|
MediaInfo actual_media_info;
|
||||||
|
typedef ::google::protobuf::TextFormat TextFormat;
|
||||||
|
ASSERT_TRUE(TextFormat::ParseFromString(expect, &expect_media_info))
|
||||||
|
<< "Failed to parse " << std::endl << expect;
|
||||||
|
ASSERT_TRUE(TextFormat::ParseFromString(actual, &actual_media_info))
|
||||||
|
<< "Failed to parse " << std::endl << actual;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
|
ExpectMediaInfoEqual(expect_media_info, actual_media_info))
|
||||||
|
<< "Expect:" << std::endl << expect << std::endl
|
||||||
|
<< "Actual:" << std::endl << actual;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class VodMediaInfoDumpMuxerListenerTest : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
VodMediaInfoDumpMuxerListenerTest() {}
|
||||||
|
virtual ~VodMediaInfoDumpMuxerListenerTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() OVERRIDE {
|
||||||
|
ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path_));
|
||||||
|
DLOG(INFO) << "Created temp file: " << temp_file_path_.value();
|
||||||
|
|
||||||
|
temp_file_ = File::Open(temp_file_path_.value().c_str(), "w");
|
||||||
|
ASSERT_TRUE(temp_file_);
|
||||||
|
listener_.reset(new VodMediaInfoDumpMuxerListener(temp_file_));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() OVERRIDE {
|
||||||
|
base::DeleteFile(temp_file_path_, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireOnMediaStartWithDefaultValues(
|
||||||
|
const std::vector<StreamInfo*> stream_infos) {
|
||||||
|
MuxerOptions muxer_options;
|
||||||
|
SetDefaultMuxerOptionsValues(&muxer_options);
|
||||||
|
const uint32 kReferenceTimeScale = 1000;
|
||||||
|
listener_->OnMediaStart(muxer_options,
|
||||||
|
stream_infos,
|
||||||
|
kReferenceTimeScale,
|
||||||
|
MuxerListener::kContainerMp4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireOnMediaEndWithParams(const std::vector<StreamInfo*> stream_infos,
|
||||||
|
const OnMediaEndParameters& params) {
|
||||||
|
// On success, this writes the result to |temp_file_|.
|
||||||
|
listener_->OnMediaEnd(stream_infos,
|
||||||
|
params.has_init_range,
|
||||||
|
params.init_range_start,
|
||||||
|
params.init_range_end,
|
||||||
|
params.has_index_range,
|
||||||
|
params.index_range_start,
|
||||||
|
params.index_range_end,
|
||||||
|
params.duration_seconds,
|
||||||
|
params.file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpectTempFileToEqual(const std::string& expected_protobuf) {
|
||||||
|
std::string temp_file_media_info_str;
|
||||||
|
ASSERT_TRUE(File::ReadFileToString(temp_file_path_.value().c_str(),
|
||||||
|
&temp_file_media_info_str));
|
||||||
|
ASSERT_TRUE(!temp_file_media_info_str.empty());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE((ExpectTextFormatMediaInfoEqual(
|
||||||
|
expected_protobuf, temp_file_media_info_str)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
File* temp_file_;
|
||||||
|
base::FilePath temp_file_path_;
|
||||||
|
scoped_ptr<VodMediaInfoDumpMuxerListener> listener_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListenerTest);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO(rkuroiwa): Enable these when implemented.
|
||||||
|
TEST_F(VodMediaInfoDumpMuxerListenerTest, DISABLED_UnencryptedStream_Normal) {
|
||||||
|
VideoStreamInfoParameters params = GetDefaultVideoStreamInfoParams();
|
||||||
|
params.is_encrypted = false;
|
||||||
|
|
||||||
|
std::vector<StreamInfo*> stream_infos;
|
||||||
|
scoped_refptr<StreamInfo> stream_info = CreateVideoStreamInfo(params);
|
||||||
|
stream_infos.push_back(stream_info.get());
|
||||||
|
|
||||||
|
FireOnMediaStartWithDefaultValues(stream_infos);
|
||||||
|
FireOnMediaEndWithParams(stream_infos,
|
||||||
|
GetDefaultOnMediaEndParams());
|
||||||
|
ASSERT_TRUE(temp_file_->Close());
|
||||||
|
|
||||||
|
const char* kExpectedProtobufOutput = "\
|
||||||
|
bandwidth: 7620\n\
|
||||||
|
video_info {\n\
|
||||||
|
codec: \"avc1.010101\"\n\
|
||||||
|
width: 720\n\
|
||||||
|
height: 480\n\
|
||||||
|
time_scale: 10\n\
|
||||||
|
}\n\
|
||||||
|
init_range {\n\
|
||||||
|
begin: 0\n\
|
||||||
|
end: 120\n\
|
||||||
|
}\n\
|
||||||
|
index_range {\n\
|
||||||
|
begin: 121\n\
|
||||||
|
end: 221\n\
|
||||||
|
}\n\
|
||||||
|
reference_time_scale: 1000\n\
|
||||||
|
container_type: 1\n\
|
||||||
|
media_file_name: \"test_output_file_name.mp4\"\n\
|
||||||
|
media_duration_seconds: 10.5\n";
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ExpectTempFileToEqual(kExpectedProtobufOutput));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(VodMediaInfoDumpMuxerListenerTest, DISABLED_EncryptedStream_Normal) {
|
||||||
|
listener_->SetContentProtectionSchemeIdUri("http://foo.com/bar");
|
||||||
|
|
||||||
|
VideoStreamInfoParameters params = GetDefaultVideoStreamInfoParams();
|
||||||
|
params.is_encrypted = true;
|
||||||
|
|
||||||
|
std::vector<StreamInfo*> stream_infos;
|
||||||
|
scoped_refptr<StreamInfo> stream_info = CreateVideoStreamInfo(params);
|
||||||
|
stream_infos.push_back(stream_info.get());
|
||||||
|
|
||||||
|
FireOnMediaStartWithDefaultValues(stream_infos);
|
||||||
|
FireOnMediaEndWithParams(stream_infos,
|
||||||
|
GetDefaultOnMediaEndParams());
|
||||||
|
ASSERT_TRUE(temp_file_->Close());
|
||||||
|
|
||||||
|
const char* kExpectedProtobufOutput = "\
|
||||||
|
bandwidth: 7620\n\
|
||||||
|
video_info {\n\
|
||||||
|
codec: \"avc1.010101\"\n\
|
||||||
|
width: 720\n\
|
||||||
|
height: 480\n\
|
||||||
|
time_scale: 10\n\
|
||||||
|
}\n\
|
||||||
|
content_protections {\n\
|
||||||
|
scheme_id_uri: \"http://foo.com/bar\"\n\
|
||||||
|
}\n\
|
||||||
|
init_range {\n\
|
||||||
|
begin: 0\n\
|
||||||
|
end: 120\n\
|
||||||
|
}\n\
|
||||||
|
index_range {\n\
|
||||||
|
begin: 121\n\
|
||||||
|
end: 221\n\
|
||||||
|
}\n\
|
||||||
|
reference_time_scale: 1000\n\
|
||||||
|
container_type: 1\n\
|
||||||
|
media_file_name: \"test_output_file_name.mp4\"\n\
|
||||||
|
media_duration_seconds: 10.5\n";
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ExpectTempFileToEqual(kExpectedProtobufOutput));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace event
|
||||||
|
} // namespace media
|
55
packager.gyp
55
packager.gyp
|
@ -191,25 +191,6 @@
|
||||||
'media_base',
|
'media_base',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
'target_name': 'media_event',
|
|
||||||
'type': 'static_library',
|
|
||||||
'sources': [
|
|
||||||
'media/event/muxer_listener.h',
|
|
||||||
'media/event/vod_media_info_dump_muxer_listener.cc',
|
|
||||||
'media/event/vod_media_info_dump_muxer_listener.h',
|
|
||||||
'media/event/vod_mpd_notify_muxer_listener.cc',
|
|
||||||
'media/event/vod_mpd_notify_muxer_listener.h',
|
|
||||||
'media/event/vod_muxer_listener_internal.cc',
|
|
||||||
'media/event/vod_muxer_listener_internal.h',
|
|
||||||
],
|
|
||||||
'dependencies': [
|
|
||||||
'media_base',
|
|
||||||
'mpd/mpd.gyp:media_info_proto',
|
|
||||||
# Depends on full protobuf to read/write with TextFormat.
|
|
||||||
'third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'target_name': 'mp4_unittest',
|
'target_name': 'mp4_unittest',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
@ -272,6 +253,42 @@
|
||||||
'testing/gtest.gyp:gtest',
|
'testing/gtest.gyp:gtest',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'media_event',
|
||||||
|
'type': '<(component)',
|
||||||
|
'sources': [
|
||||||
|
'media/event/muxer_listener.h',
|
||||||
|
'media/event/vod_media_info_dump_muxer_listener.cc',
|
||||||
|
'media/event/vod_media_info_dump_muxer_listener.h',
|
||||||
|
'media/event/vod_mpd_notify_muxer_listener.cc',
|
||||||
|
'media/event/vod_mpd_notify_muxer_listener.h',
|
||||||
|
'media/event/vod_muxer_listener_internal.cc',
|
||||||
|
'media/event/vod_muxer_listener_internal.h',
|
||||||
|
],
|
||||||
|
'dependencies': [
|
||||||
|
'media_base',
|
||||||
|
'mpd/mpd.gyp:media_info_proto',
|
||||||
|
# Depends on full protobuf to read/write with TextFormat.
|
||||||
|
'third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'media_event_unittest',
|
||||||
|
'type': '<(gtest_target_type)',
|
||||||
|
'sources': [
|
||||||
|
'media/event/vod_media_info_dump_muxer_listener_unittest.cc',
|
||||||
|
],
|
||||||
|
'dependencies': [
|
||||||
|
'base/base.gyp:base',
|
||||||
|
'base/base.gyp:run_all_unittests',
|
||||||
|
'file',
|
||||||
|
'media_event',
|
||||||
|
'mpd/mpd.gyp:media_info_proto',
|
||||||
|
'testing/gtest.gyp:gtest',
|
||||||
|
# Depends on full protobuf to read/write with TextFormat.
|
||||||
|
'third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'target_name': 'packager_main',
|
'target_name': 'packager_main',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
|
Loading…
Reference in New Issue