Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
// Copyright 2017 Google Inc. 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
|
|
|
|
|
2018-01-03 00:10:33 +00:00
|
|
|
#ifndef PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
|
|
|
|
#define PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
|
|
|
|
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
2017-03-11 02:48:04 +00:00
|
|
|
#include "packager/base/strings/string_number_conversions.h"
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
#include "packager/media/base/media_handler.h"
|
|
|
|
|
|
|
|
namespace shaka {
|
|
|
|
namespace media {
|
|
|
|
|
2018-01-03 00:10:33 +00:00
|
|
|
std::string StreamDataTypeToString(StreamDataType stream_data_type);
|
|
|
|
std::string BoolToString(bool value);
|
|
|
|
|
2017-09-18 15:43:21 +00:00
|
|
|
MATCHER_P(IsStreamInfo, stream_index, "") {
|
|
|
|
return arg->stream_index == stream_index &&
|
|
|
|
arg->stream_data_type == StreamDataType::kStreamInfo;
|
|
|
|
}
|
|
|
|
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
MATCHER_P3(IsStreamInfo, stream_index, time_scale, encrypted, "") {
|
2018-01-03 00:10:33 +00:00
|
|
|
if (arg->stream_data_type != StreamDataType::kStreamInfo) {
|
|
|
|
*result_listener << "which is "
|
|
|
|
<< StreamDataTypeToString(arg->stream_data_type);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result_listener << "which is (" << arg->stream_index << ","
|
|
|
|
<< arg->stream_info->time_scale() << ","
|
|
|
|
<< BoolToString(arg->stream_info->is_encrypted()) << ")";
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
return arg->stream_index == stream_index &&
|
|
|
|
arg->stream_info->time_scale() == time_scale &&
|
|
|
|
arg->stream_info->is_encrypted() == encrypted;
|
|
|
|
}
|
|
|
|
|
2018-02-08 02:28:51 +00:00
|
|
|
MATCHER_P4(IsStreamInfo, stream_index, time_scale, encrypted, language, "") {
|
|
|
|
if (arg->stream_data_type != StreamDataType::kStreamInfo) {
|
|
|
|
*result_listener << "which is "
|
|
|
|
<< StreamDataTypeToString(arg->stream_data_type);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result_listener << "which is (" << arg->stream_index << ","
|
|
|
|
<< arg->stream_info->time_scale() << ","
|
|
|
|
<< BoolToString(arg->stream_info->is_encrypted()) << ","
|
|
|
|
<< arg->stream_info->language() << ")";
|
|
|
|
return arg->stream_index == stream_index &&
|
|
|
|
arg->stream_info->time_scale() == time_scale &&
|
|
|
|
arg->stream_info->is_encrypted() == encrypted &&
|
|
|
|
arg->stream_info->language() == language;
|
|
|
|
}
|
|
|
|
|
2017-03-11 02:48:04 +00:00
|
|
|
MATCHER_P5(IsSegmentInfo,
|
|
|
|
stream_index,
|
|
|
|
start_timestamp,
|
|
|
|
duration,
|
|
|
|
subsegment,
|
|
|
|
encrypted,
|
|
|
|
"") {
|
2018-01-03 00:10:33 +00:00
|
|
|
if (arg->stream_data_type != StreamDataType::kSegmentInfo) {
|
|
|
|
*result_listener << "which is "
|
|
|
|
<< StreamDataTypeToString(arg->stream_data_type);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result_listener << "which is (" << arg->stream_index << ","
|
|
|
|
<< arg->segment_info->start_timestamp << ","
|
|
|
|
<< arg->segment_info->duration << ","
|
|
|
|
<< BoolToString(arg->segment_info->is_subsegment) << ","
|
|
|
|
<< BoolToString(arg->segment_info->is_encrypted) << ")";
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
return arg->stream_index == stream_index &&
|
2017-03-11 02:48:04 +00:00
|
|
|
arg->segment_info->start_timestamp == start_timestamp &&
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
arg->segment_info->duration == duration &&
|
2017-03-11 02:48:04 +00:00
|
|
|
arg->segment_info->is_subsegment == subsegment &&
|
|
|
|
arg->segment_info->is_encrypted == encrypted;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
}
|
|
|
|
|
2017-03-11 02:48:04 +00:00
|
|
|
MATCHER_P6(MatchEncryptionConfig,
|
|
|
|
protection_scheme,
|
|
|
|
crypt_byte_block,
|
|
|
|
skip_byte_block,
|
|
|
|
per_sample_iv_size,
|
|
|
|
constant_iv,
|
|
|
|
key_id,
|
|
|
|
"") {
|
2018-01-03 00:10:33 +00:00
|
|
|
*result_listener << "which is (" << FourCCToString(arg.protection_scheme)
|
|
|
|
<< "," << static_cast<int>(arg.crypt_byte_block) << ","
|
|
|
|
<< static_cast<int>(arg.skip_byte_block) << ","
|
|
|
|
<< static_cast<int>(arg.per_sample_iv_size) << ","
|
|
|
|
<< base::HexEncode(arg.constant_iv.data(),
|
|
|
|
arg.constant_iv.size())
|
|
|
|
<< ","
|
|
|
|
<< base::HexEncode(arg.key_id.data(), arg.key_id.size())
|
2017-03-11 02:48:04 +00:00
|
|
|
<< ")";
|
|
|
|
return arg.protection_scheme == protection_scheme &&
|
|
|
|
arg.crypt_byte_block == crypt_byte_block &&
|
|
|
|
arg.skip_byte_block == skip_byte_block &&
|
|
|
|
arg.per_sample_iv_size == per_sample_iv_size &&
|
|
|
|
arg.constant_iv == constant_iv && arg.key_id == key_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
MATCHER_P4(IsMediaSample, stream_index, timestamp, duration, encrypted, "") {
|
2018-01-03 00:10:33 +00:00
|
|
|
if (arg->stream_data_type != StreamDataType::kMediaSample) {
|
|
|
|
*result_listener << "which is "
|
|
|
|
<< StreamDataTypeToString(arg->stream_data_type);
|
|
|
|
return false;
|
|
|
|
}
|
2018-01-09 01:18:15 +00:00
|
|
|
*result_listener << "which is (" << arg->stream_index << ","
|
2018-01-03 00:10:33 +00:00
|
|
|
<< arg->media_sample->dts() << ","
|
|
|
|
<< arg->media_sample->duration() << ","
|
|
|
|
<< BoolToString(arg->media_sample->is_encrypted()) << ")";
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
return arg->stream_index == stream_index &&
|
|
|
|
arg->media_sample->dts() == timestamp &&
|
2017-03-11 02:48:04 +00:00
|
|
|
arg->media_sample->duration() == duration &&
|
|
|
|
arg->media_sample->is_encrypted() == encrypted;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
}
|
|
|
|
|
2017-09-18 15:47:00 +00:00
|
|
|
MATCHER_P5(IsTextSample, id, start_time, end_time, settings, payload, "") {
|
2018-01-03 00:10:33 +00:00
|
|
|
if (arg->stream_data_type != StreamDataType::kTextSample) {
|
|
|
|
*result_listener << "which is "
|
|
|
|
<< StreamDataTypeToString(arg->stream_data_type);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*result_listener << "which is (" << arg->text_sample->id() << ","
|
|
|
|
<< arg->text_sample->start_time() << ","
|
|
|
|
<< arg->text_sample->EndTime() << ","
|
|
|
|
<< arg->text_sample->settings() << ","
|
|
|
|
<< arg->text_sample->payload() << ")";
|
|
|
|
return arg->text_sample->id() == id &&
|
2017-09-18 15:47:00 +00:00
|
|
|
arg->text_sample->start_time() == start_time &&
|
|
|
|
arg->text_sample->EndTime() == end_time &&
|
|
|
|
arg->text_sample->settings() == settings &&
|
|
|
|
arg->text_sample->payload() == payload;
|
|
|
|
}
|
|
|
|
|
2018-03-15 23:01:47 +00:00
|
|
|
MATCHER_P2(IsCueEvent, stream_index, time_in_seconds, "") {
|
2018-01-03 00:10:33 +00:00
|
|
|
if (arg->stream_data_type != StreamDataType::kCueEvent) {
|
|
|
|
*result_listener << "which is "
|
|
|
|
<< StreamDataTypeToString(arg->stream_data_type);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*result_listener << "which is (" << arg->stream_index << ","
|
2018-03-15 23:01:47 +00:00
|
|
|
<< arg->cue_event->time_in_seconds << ")";
|
2018-01-03 00:10:33 +00:00
|
|
|
return arg->stream_index == stream_index &&
|
2018-03-15 23:01:47 +00:00
|
|
|
arg->cue_event->time_in_seconds == time_in_seconds;
|
2018-01-03 00:10:33 +00:00
|
|
|
}
|
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
class FakeInputMediaHandler : public MediaHandler {
|
|
|
|
public:
|
|
|
|
using MediaHandler::Dispatch;
|
|
|
|
using MediaHandler::FlushAllDownstreams;
|
|
|
|
using MediaHandler::FlushDownstream;
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool ValidateOutputStreamIndex(size_t index) const override;
|
|
|
|
Status InitializeInternal() override;
|
|
|
|
Status Process(std::unique_ptr<StreamData> stream_data) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class MockOutputMediaHandler : public MediaHandler {
|
|
|
|
public:
|
|
|
|
MOCK_METHOD1(OnProcess, void(const StreamData*));
|
|
|
|
MOCK_METHOD1(OnFlush, void(size_t index));
|
|
|
|
|
|
|
|
private:
|
|
|
|
Status InitializeInternal() override;
|
|
|
|
Status Process(std::unique_ptr<StreamData> stream_data) override;
|
|
|
|
Status OnFlushRequest(size_t index) override;
|
|
|
|
};
|
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
// TODO(vaage) : Remove this test handler and convert other tests to use
|
|
|
|
// FakeInputMediaHandler and MockOutputMediaHandler.
|
2017-03-21 23:14:46 +00:00
|
|
|
class FakeMediaHandler : public MediaHandler {
|
|
|
|
public:
|
|
|
|
const std::vector<std::unique_ptr<StreamData>>& stream_data_vector() const {
|
|
|
|
return stream_data_vector_;
|
|
|
|
}
|
|
|
|
void clear_stream_data_vector() { stream_data_vector_.clear(); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Status InitializeInternal() override;
|
|
|
|
Status Process(std::unique_ptr<StreamData> stream_data) override;
|
|
|
|
Status OnFlushRequest(size_t input_stream_index) override;
|
|
|
|
bool ValidateOutputStreamIndex(size_t stream_index) const override;
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<StreamData>> stream_data_vector_;
|
|
|
|
};
|
|
|
|
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
class MediaHandlerTestBase : public ::testing::Test {
|
|
|
|
public:
|
2017-09-14 16:23:29 +00:00
|
|
|
MediaHandlerTestBase() = default;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
protected:
|
2017-09-12 17:24:24 +00:00
|
|
|
bool IsVideoCodec(Codec codec) const;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale) const;
|
|
|
|
|
|
|
|
std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
|
|
|
|
uint32_t width,
|
|
|
|
uint64_t height) const;
|
2017-09-12 17:24:24 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
|
|
|
|
Codec codec) const;
|
2017-09-12 17:24:24 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
|
|
|
|
Codec codec,
|
|
|
|
uint32_t width,
|
|
|
|
uint64_t height) const;
|
2017-09-12 17:24:24 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
std::unique_ptr<StreamInfo> GetAudioStreamInfo(uint32_t time_scale) const;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
std::unique_ptr<StreamInfo> GetAudioStreamInfo(uint32_t time_scale,
|
|
|
|
Codec codec) const;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
|
2017-09-18 23:31:00 +00:00
|
|
|
std::shared_ptr<MediaSample> GetMediaSample(int64_t timestamp,
|
2017-09-14 16:23:29 +00:00
|
|
|
int64_t duration,
|
|
|
|
bool is_keyframe) const;
|
2017-09-12 17:24:24 +00:00
|
|
|
|
2017-09-18 23:31:00 +00:00
|
|
|
std::shared_ptr<MediaSample> GetMediaSample(int64_t timestamp,
|
2017-09-14 16:23:29 +00:00
|
|
|
int64_t duration,
|
|
|
|
bool is_keyframe,
|
|
|
|
const uint8_t* data,
|
|
|
|
size_t data_length) const;
|
2017-09-12 17:24:24 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
std::unique_ptr<SegmentInfo> GetSegmentInfo(int64_t start_timestamp,
|
|
|
|
int64_t duration,
|
|
|
|
bool is_subsegment) const;
|
2017-09-12 17:24:24 +00:00
|
|
|
|
2017-09-18 15:47:00 +00:00
|
|
|
std::unique_ptr<StreamInfo> GetTextStreamInfo() const;
|
|
|
|
|
|
|
|
std::unique_ptr<TextSample> GetTextSample(const std::string& id,
|
|
|
|
uint64_t start,
|
|
|
|
uint64_t end,
|
|
|
|
const std::string& payload) const;
|
|
|
|
|
2017-09-26 16:00:33 +00:00
|
|
|
// Connect and initialize all handlers.
|
|
|
|
Status SetUpAndInitializeGraph(std::shared_ptr<MediaHandler> handler,
|
|
|
|
size_t input_count,
|
|
|
|
size_t output_count);
|
|
|
|
|
|
|
|
// Get the input handler at |index|. The values of |index| will match the
|
|
|
|
// call to |AddInput|.
|
|
|
|
FakeInputMediaHandler* Input(size_t index);
|
|
|
|
|
|
|
|
// Get the output handler at |index|. The values of |index| will match the
|
|
|
|
// call to |AddOutput|.
|
|
|
|
MockOutputMediaHandler* Output(size_t index);
|
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
private:
|
|
|
|
MediaHandlerTestBase(const MediaHandlerTestBase&) = delete;
|
|
|
|
MediaHandlerTestBase& operator=(const MediaHandlerTestBase&) = delete;
|
2017-09-26 16:00:33 +00:00
|
|
|
|
|
|
|
std::shared_ptr<MediaHandler> handler_;
|
|
|
|
|
|
|
|
std::vector<std::shared_ptr<FakeInputMediaHandler>> inputs_;
|
|
|
|
std::vector<std::shared_ptr<MockOutputMediaHandler>> outputs_;
|
2017-09-14 16:23:29 +00:00
|
|
|
};
|
2017-03-11 02:48:04 +00:00
|
|
|
|
2017-09-14 16:23:29 +00:00
|
|
|
class MediaHandlerGraphTestBase : public MediaHandlerTestBase {
|
|
|
|
public:
|
|
|
|
MediaHandlerGraphTestBase();
|
|
|
|
|
|
|
|
protected:
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
/// Setup a graph using |handler| with |num_inputs| and |num_outputs|.
|
2017-03-28 06:04:29 +00:00
|
|
|
void SetUpGraph(size_t num_inputs,
|
|
|
|
size_t num_outputs,
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
std::shared_ptr<MediaHandler> handler);
|
|
|
|
|
2017-03-11 02:48:04 +00:00
|
|
|
/// @return the output stream data vector from handler.
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
const std::vector<std::unique_ptr<StreamData>>& GetOutputStreamDataVector()
|
|
|
|
const;
|
|
|
|
|
|
|
|
/// Clear the output stream data vector.
|
|
|
|
void ClearOutputStreamDataVector();
|
|
|
|
|
|
|
|
/// @return some random handler that can be used for testing.
|
|
|
|
std::shared_ptr<MediaHandler> some_handler() { return some_handler_; }
|
|
|
|
|
2017-03-21 23:14:46 +00:00
|
|
|
/// @return some a downstream handler that can be used for connecting.
|
|
|
|
std::shared_ptr<FakeMediaHandler> next_handler() { return next_handler_; }
|
|
|
|
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
private:
|
2017-09-14 16:23:29 +00:00
|
|
|
MediaHandlerGraphTestBase(const MediaHandlerTestBase&) = delete;
|
|
|
|
MediaHandlerGraphTestBase& operator=(const MediaHandlerTestBase&) = delete;
|
Implement ChunkingHandler
This handler is a multi-in multi-out handler. If more than one input is
provided, there should be one and only one video stream; also, all inputs
should come from the same thread and are synchronized.
There can be multiple chunking handler running in different threads or even
different processes, we use the "consistent chunking algorithm" to make sure
the chunks in different streams are aligned without explicit communcating
with each other - which is not efficient and often difficult.
Consistent Chunking Algorithm:
1. Find the consistent chunkable boundary
Let the timestamps for video frames be (t1, t2, t3, ...). Then a
consistent chunkable boundary is simply the first chunkable boundary after
(tk / N) != (tk-1 / N), where '/' denotes integer division, and N is the
intended chunk duration.
2. Chunk only at the consistent chunkable boundary
This algorithm will make sure the chunks from different video streams are
aligned if they have aligned GoPs. However, this algorithm will only work
for video streams. To be able to chunk non video streams at similar
positions as video streams, ChunkingHandler is designed to accept one video
input and multiple non video inputs, the non video inputs are chunked when
the video input is chunked. If the inputs are synchronized - which is true
if the inputs come from the same demuxer, the video and non video chunks
are aligned.
Change-Id: Id3bad51ab14f311efdb8713b6cd36d36cf9e4639
2017-02-07 18:58:47 +00:00
|
|
|
|
|
|
|
// Downstream handler used in testing graph.
|
|
|
|
std::shared_ptr<FakeMediaHandler> next_handler_;
|
|
|
|
// Some random handler which can be used for testing.
|
|
|
|
std::shared_ptr<MediaHandler> some_handler_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace media
|
|
|
|
} // namespace shaka
|
2018-01-03 00:10:33 +00:00
|
|
|
|
|
|
|
#endif // PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
|