Add TextSample to MediaParser.
In addition to the MediaSample handling of the MediaParser, this now adds callbacks for TextSample. This allows reading text streams from the media files. Change-Id: I6c00e286e98bc9aafe05b99cf2f7ce6f89d167a9
This commit is contained in:
parent
748e7e0056
commit
ba33a63693
|
@ -20,6 +20,7 @@ namespace media {
|
||||||
class KeySource;
|
class KeySource;
|
||||||
class MediaSample;
|
class MediaSample;
|
||||||
class StreamInfo;
|
class StreamInfo;
|
||||||
|
class TextSample;
|
||||||
|
|
||||||
class MediaParser {
|
class MediaParser {
|
||||||
public:
|
public:
|
||||||
|
@ -39,18 +40,31 @@ class MediaParser {
|
||||||
/// @return true if the sample is accepted, false if something was wrong
|
/// @return true if the sample is accepted, false if something was wrong
|
||||||
/// with the sample and a parsing error should be signaled.
|
/// with the sample and a parsing error should be signaled.
|
||||||
typedef base::Callback<bool(uint32_t track_id,
|
typedef base::Callback<bool(uint32_t track_id,
|
||||||
const std::shared_ptr<MediaSample>& media_sample)>
|
std::shared_ptr<MediaSample> media_sample)>
|
||||||
NewSampleCB;
|
NewMediaSampleCB;
|
||||||
|
|
||||||
|
/// Called when a new text sample has been parsed.
|
||||||
|
/// @param track_id is the track id of the new sample.
|
||||||
|
/// @param text_sample is the new text sample.
|
||||||
|
/// @return true if the sample is accepted, false if something was wrong
|
||||||
|
/// with the sample and a parsing error should be signaled.
|
||||||
|
typedef base::Callback<bool(uint32_t track_id,
|
||||||
|
std::shared_ptr<TextSample> text_sample)>
|
||||||
|
NewTextSampleCB;
|
||||||
|
|
||||||
/// Initialize the parser with necessary callbacks. Must be called before any
|
/// Initialize the parser with necessary callbacks. Must be called before any
|
||||||
/// data is passed to Parse().
|
/// data is passed to Parse().
|
||||||
/// @param init_cb will be called once enough data has been parsed to
|
/// @param init_cb will be called once enough data has been parsed to
|
||||||
/// determine the initial stream configurations.
|
/// determine the initial stream configurations.
|
||||||
/// @param new_sample_cb will be called each time a new media sample is
|
/// @param new_media_sample_cb will be called each time a new media sample is
|
||||||
/// available from the parser. May be NULL, and caller retains
|
/// available from the parser.
|
||||||
/// ownership.
|
/// @param new_text_sample_cb will be called each time a new text sample is
|
||||||
|
/// available from the parser.
|
||||||
|
/// @param decryption_key_source the key source to decrypt the frames. May be
|
||||||
|
/// NULL, and caller retains ownership.
|
||||||
virtual void Init(const InitCB& init_cb,
|
virtual void Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) = 0;
|
KeySource* decryption_key_source) = 0;
|
||||||
|
|
||||||
/// Flush data currently in the parser and put the parser in a state where it
|
/// Flush data currently in the parser and put the parser in a state where it
|
||||||
|
|
|
@ -147,12 +147,6 @@ void Demuxer::SetLanguageOverride(const std::string& stream_label,
|
||||||
language_overrides_[stream_index] = language_override;
|
language_overrides_[stream_index] = language_override;
|
||||||
}
|
}
|
||||||
|
|
||||||
Demuxer::QueuedSample::QueuedSample(uint32_t local_track_id,
|
|
||||||
std::shared_ptr<MediaSample> local_sample)
|
|
||||||
: track_id(local_track_id), sample(local_sample) {}
|
|
||||||
|
|
||||||
Demuxer::QueuedSample::~QueuedSample() {}
|
|
||||||
|
|
||||||
Status Demuxer::InitializeParser() {
|
Status Demuxer::InitializeParser() {
|
||||||
DCHECK(!media_file_);
|
DCHECK(!media_file_);
|
||||||
DCHECK(!all_streams_ready_);
|
DCHECK(!all_streams_ready_);
|
||||||
|
@ -213,9 +207,11 @@ Status Demuxer::InitializeParser() {
|
||||||
return Status(error::UNIMPLEMENTED, "Container not supported.");
|
return Status(error::UNIMPLEMENTED, "Container not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_->Init(base::Bind(&Demuxer::ParserInitEvent, base::Unretained(this)),
|
parser_->Init(
|
||||||
base::Bind(&Demuxer::NewSampleEvent, base::Unretained(this)),
|
base::Bind(&Demuxer::ParserInitEvent, base::Unretained(this)),
|
||||||
key_source_.get());
|
base::Bind(&Demuxer::NewMediaSampleEvent, base::Unretained(this)),
|
||||||
|
base::Bind(&Demuxer::NewTextSampleEvent, base::Unretained(this)),
|
||||||
|
key_source_.get());
|
||||||
|
|
||||||
// Handle trailing 'moov'.
|
// Handle trailing 'moov'.
|
||||||
if (container_name_ == CONTAINER_MOV &&
|
if (container_name_ == CONTAINER_MOV &&
|
||||||
|
@ -294,31 +290,56 @@ void Demuxer::ParserInitEvent(
|
||||||
all_streams_ready_ = true;
|
all_streams_ready_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Demuxer::NewSampleEvent(uint32_t track_id,
|
bool Demuxer::NewMediaSampleEvent(uint32_t track_id,
|
||||||
const std::shared_ptr<MediaSample>& sample) {
|
std::shared_ptr<MediaSample> sample) {
|
||||||
if (!all_streams_ready_) {
|
if (!all_streams_ready_) {
|
||||||
if (queued_samples_.size() >= kQueuedSamplesLimit) {
|
if (queued_media_samples_.size() >= kQueuedSamplesLimit) {
|
||||||
LOG(ERROR) << "Queued samples limit reached: " << kQueuedSamplesLimit;
|
LOG(ERROR) << "Queued samples limit reached: " << kQueuedSamplesLimit;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
queued_samples_.push_back(QueuedSample(track_id, sample));
|
queued_media_samples_.emplace_back(track_id, sample);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!init_event_status_.ok()) {
|
if (!init_event_status_.ok()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (!queued_samples_.empty()) {
|
|
||||||
if (!PushSample(queued_samples_.front().track_id,
|
while (!queued_media_samples_.empty()) {
|
||||||
queued_samples_.front().sample)) {
|
if (!PushMediaSample(queued_media_samples_.front().track_id,
|
||||||
|
queued_media_samples_.front().sample)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
queued_samples_.pop_front();
|
queued_media_samples_.pop_front();
|
||||||
}
|
}
|
||||||
return PushSample(track_id, sample);
|
return PushMediaSample(track_id, sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Demuxer::PushSample(uint32_t track_id,
|
bool Demuxer::NewTextSampleEvent(uint32_t track_id,
|
||||||
const std::shared_ptr<MediaSample>& sample) {
|
std::shared_ptr<TextSample> sample) {
|
||||||
|
if (!all_streams_ready_) {
|
||||||
|
if (queued_text_samples_.size() >= kQueuedSamplesLimit) {
|
||||||
|
LOG(ERROR) << "Queued samples limit reached: " << kQueuedSamplesLimit;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
queued_text_samples_.emplace_back(track_id, sample);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!init_event_status_.ok()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!queued_text_samples_.empty()) {
|
||||||
|
if (!PushTextSample(queued_text_samples_.front().track_id,
|
||||||
|
queued_text_samples_.front().sample)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
queued_text_samples_.pop_front();
|
||||||
|
}
|
||||||
|
return PushTextSample(track_id, sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Demuxer::PushMediaSample(uint32_t track_id,
|
||||||
|
std::shared_ptr<MediaSample> sample) {
|
||||||
auto stream_index_iter = track_id_to_stream_index_map_.find(track_id);
|
auto stream_index_iter = track_id_to_stream_index_map_.find(track_id);
|
||||||
if (stream_index_iter == track_id_to_stream_index_map_.end()) {
|
if (stream_index_iter == track_id_to_stream_index_map_.end()) {
|
||||||
LOG(ERROR) << "Track " << track_id << " not found.";
|
LOG(ERROR) << "Track " << track_id << " not found.";
|
||||||
|
@ -330,8 +351,27 @@ bool Demuxer::PushSample(uint32_t track_id,
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
LOG(ERROR) << "Failed to process sample " << stream_index_iter->second
|
LOG(ERROR) << "Failed to process sample " << stream_index_iter->second
|
||||||
<< " " << status;
|
<< " " << status;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return status.ok();
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Demuxer::PushTextSample(uint32_t track_id,
|
||||||
|
std::shared_ptr<TextSample> sample) {
|
||||||
|
auto stream_index_iter = track_id_to_stream_index_map_.find(track_id);
|
||||||
|
if (stream_index_iter == track_id_to_stream_index_map_.end()) {
|
||||||
|
LOG(ERROR) << "Track " << track_id << " not found.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (stream_index_iter->second == kInvalidStreamIndex)
|
||||||
|
return true;
|
||||||
|
Status status = DispatchTextSample(stream_index_iter->second, sample);
|
||||||
|
if (!status.ok()) {
|
||||||
|
LOG(ERROR) << "Failed to process sample " << stream_index_iter->second
|
||||||
|
<< " " << status;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Demuxer::Parse() {
|
Status Demuxer::Parse() {
|
||||||
|
|
|
@ -94,12 +94,15 @@ class Demuxer : public OriginHandler {
|
||||||
Demuxer(const Demuxer&) = delete;
|
Demuxer(const Demuxer&) = delete;
|
||||||
Demuxer& operator=(const Demuxer&) = delete;
|
Demuxer& operator=(const Demuxer&) = delete;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
struct QueuedSample {
|
struct QueuedSample {
|
||||||
QueuedSample(uint32_t track_id, std::shared_ptr<MediaSample> sample);
|
QueuedSample(uint32_t track_id, std::shared_ptr<T> sample)
|
||||||
~QueuedSample();
|
: track_id(track_id), sample(sample) {}
|
||||||
|
|
||||||
|
~QueuedSample() {}
|
||||||
|
|
||||||
uint32_t track_id;
|
uint32_t track_id;
|
||||||
std::shared_ptr<MediaSample> sample;
|
std::shared_ptr<T> sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize the parser. This method primes the demuxer by parsing portions
|
// Initialize the parser. This method primes the demuxer by parsing portions
|
||||||
|
@ -112,11 +115,13 @@ class Demuxer : public OriginHandler {
|
||||||
// Parser new sample event handler. Queues the samples if init event has not
|
// Parser new sample event handler. Queues the samples if init event has not
|
||||||
// been received, otherwise calls PushSample() to push the sample to
|
// been received, otherwise calls PushSample() to push the sample to
|
||||||
// corresponding stream.
|
// corresponding stream.
|
||||||
bool NewSampleEvent(uint32_t track_id,
|
bool NewMediaSampleEvent(uint32_t track_id,
|
||||||
const std::shared_ptr<MediaSample>& sample);
|
std::shared_ptr<MediaSample> sample);
|
||||||
|
bool NewTextSampleEvent(uint32_t track_id,
|
||||||
|
std::shared_ptr<TextSample> sample);
|
||||||
// Helper function to push the sample to corresponding stream.
|
// Helper function to push the sample to corresponding stream.
|
||||||
bool PushSample(uint32_t track_id,
|
bool PushMediaSample(uint32_t track_id, std::shared_ptr<MediaSample> sample);
|
||||||
const std::shared_ptr<MediaSample>& sample);
|
bool PushTextSample(uint32_t track_id, std::shared_ptr<TextSample> sample);
|
||||||
|
|
||||||
// Read from the source and send it to the parser.
|
// Read from the source and send it to the parser.
|
||||||
Status Parse();
|
Status Parse();
|
||||||
|
@ -126,7 +131,8 @@ class Demuxer : public OriginHandler {
|
||||||
// A stream is considered ready after receiving the stream info.
|
// A stream is considered ready after receiving the stream info.
|
||||||
bool all_streams_ready_ = false;
|
bool all_streams_ready_ = false;
|
||||||
// Queued samples received in NewSampleEvent() before ParserInitEvent().
|
// Queued samples received in NewSampleEvent() before ParserInitEvent().
|
||||||
std::deque<QueuedSample> queued_samples_;
|
std::deque<QueuedSample<MediaSample>> queued_media_samples_;
|
||||||
|
std::deque<QueuedSample<TextSample>> queued_text_samples_;
|
||||||
std::unique_ptr<MediaParser> parser_;
|
std::unique_ptr<MediaParser> parser_;
|
||||||
// TrackId -> StreamIndex map.
|
// TrackId -> StreamIndex map.
|
||||||
std::map<uint32_t, size_t> track_id_to_stream_index_map_;
|
std::map<uint32_t, size_t> track_id_to_stream_index_map_;
|
||||||
|
|
|
@ -149,17 +149,17 @@ Mp2tMediaParser::Mp2tMediaParser()
|
||||||
|
|
||||||
Mp2tMediaParser::~Mp2tMediaParser() {}
|
Mp2tMediaParser::~Mp2tMediaParser() {}
|
||||||
|
|
||||||
void Mp2tMediaParser::Init(
|
void Mp2tMediaParser::Init(const InitCB& init_cb,
|
||||||
const InitCB& init_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) {
|
KeySource* decryption_key_source) {
|
||||||
DCHECK(!is_initialized_);
|
DCHECK(!is_initialized_);
|
||||||
DCHECK(init_cb_.is_null());
|
DCHECK(init_cb_.is_null());
|
||||||
DCHECK(!init_cb.is_null());
|
DCHECK(!init_cb.is_null());
|
||||||
DCHECK(!new_sample_cb.is_null());
|
DCHECK(!new_media_sample_cb.is_null());
|
||||||
|
|
||||||
init_cb_ = init_cb;
|
init_cb_ = init_cb;
|
||||||
new_sample_cb_ = new_sample_cb;
|
new_sample_cb_ = new_media_sample_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mp2tMediaParser::Flush() {
|
bool Mp2tMediaParser::Flush() {
|
||||||
|
|
|
@ -34,7 +34,8 @@ class Mp2tMediaParser : public MediaParser {
|
||||||
/// @name MediaParser implementation overrides.
|
/// @name MediaParser implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
void Init(const InitCB& init_cb,
|
void Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) override;
|
KeySource* decryption_key_source) override;
|
||||||
bool Flush() override WARN_UNUSED_RESULT;
|
bool Flush() override WARN_UNUSED_RESULT;
|
||||||
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
||||||
|
@ -74,7 +75,7 @@ class Mp2tMediaParser : public MediaParser {
|
||||||
|
|
||||||
// List of callbacks.
|
// List of callbacks.
|
||||||
InitCB init_cb_;
|
InitCB init_cb_;
|
||||||
NewSampleCB new_sample_cb_;
|
NewMediaSampleCB new_sample_cb_;
|
||||||
|
|
||||||
bool sbr_in_mimetype_;
|
bool sbr_in_mimetype_;
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,7 @@ class Mp2tMediaParserTest : public testing::Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnNewSample(uint32_t track_id,
|
bool OnNewSample(uint32_t track_id, std::shared_ptr<MediaSample> sample) {
|
||||||
const std::shared_ptr<MediaSample>& sample) {
|
|
||||||
StreamMap::const_iterator stream = stream_map_.find(track_id);
|
StreamMap::const_iterator stream = stream_map_.find(track_id);
|
||||||
EXPECT_NE(stream_map_.end(), stream);
|
EXPECT_NE(stream_map_.end(), stream);
|
||||||
if (stream != stream_map_.end()) {
|
if (stream != stream_map_.end()) {
|
||||||
|
@ -97,11 +96,15 @@ class Mp2tMediaParserTest : public testing::Test {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OnNewTextSample(uint32_t track_id, std::shared_ptr<TextSample> sample) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeParser() {
|
void InitializeParser() {
|
||||||
parser_->Init(
|
parser_->Init(
|
||||||
base::Bind(&Mp2tMediaParserTest::OnInit,
|
base::Bind(&Mp2tMediaParserTest::OnInit, base::Unretained(this)),
|
||||||
base::Unretained(this)),
|
base::Bind(&Mp2tMediaParserTest::OnNewSample, base::Unretained(this)),
|
||||||
base::Bind(&Mp2tMediaParserTest::OnNewSample,
|
base::Bind(&Mp2tMediaParserTest::OnNewTextSample,
|
||||||
base::Unretained(this)),
|
base::Unretained(this)),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,16 +179,17 @@ MP4MediaParser::MP4MediaParser()
|
||||||
MP4MediaParser::~MP4MediaParser() {}
|
MP4MediaParser::~MP4MediaParser() {}
|
||||||
|
|
||||||
void MP4MediaParser::Init(const InitCB& init_cb,
|
void MP4MediaParser::Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) {
|
KeySource* decryption_key_source) {
|
||||||
DCHECK_EQ(state_, kWaitingForInit);
|
DCHECK_EQ(state_, kWaitingForInit);
|
||||||
DCHECK(init_cb_.is_null());
|
DCHECK(init_cb_.is_null());
|
||||||
DCHECK(!init_cb.is_null());
|
DCHECK(!init_cb.is_null());
|
||||||
DCHECK(!new_sample_cb.is_null());
|
DCHECK(!new_media_sample_cb.is_null());
|
||||||
|
|
||||||
ChangeState(kParsingBoxes);
|
ChangeState(kParsingBoxes);
|
||||||
init_cb_ = init_cb;
|
init_cb_ = init_cb;
|
||||||
new_sample_cb_ = new_sample_cb;
|
new_sample_cb_ = new_media_sample_cb;
|
||||||
decryption_key_source_ = decryption_key_source;
|
decryption_key_source_ = decryption_key_source;
|
||||||
if (decryption_key_source)
|
if (decryption_key_source)
|
||||||
decryptor_source_.reset(new DecryptorSource(decryption_key_source));
|
decryptor_source_.reset(new DecryptorSource(decryption_key_source));
|
||||||
|
|
|
@ -35,7 +35,8 @@ class MP4MediaParser : public MediaParser {
|
||||||
/// @name MediaParser implementation overrides.
|
/// @name MediaParser implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
void Init(const InitCB& init_cb,
|
void Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) override;
|
KeySource* decryption_key_source) override;
|
||||||
bool Flush() override WARN_UNUSED_RESULT;
|
bool Flush() override WARN_UNUSED_RESULT;
|
||||||
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
||||||
|
@ -82,7 +83,7 @@ class MP4MediaParser : public MediaParser {
|
||||||
|
|
||||||
State state_;
|
State state_;
|
||||||
InitCB init_cb_;
|
InitCB init_cb_;
|
||||||
NewSampleCB new_sample_cb_;
|
NewMediaSampleCB new_sample_cb_;
|
||||||
KeySource* decryption_key_source_;
|
KeySource* decryption_key_source_;
|
||||||
std::unique_ptr<DecryptorSource> decryptor_source_;
|
std::unique_ptr<DecryptorSource> decryptor_source_;
|
||||||
|
|
||||||
|
|
|
@ -82,18 +82,22 @@ class MP4MediaParserTest : public testing::Test {
|
||||||
num_samples_ = 0;
|
num_samples_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NewSampleF(uint32_t track_id,
|
bool NewSampleF(uint32_t track_id, std::shared_ptr<MediaSample> sample) {
|
||||||
const std::shared_ptr<MediaSample>& sample) {
|
|
||||||
DVLOG(2) << "Track Id: " << track_id << " "
|
DVLOG(2) << "Track Id: " << track_id << " "
|
||||||
<< sample->ToString();
|
<< sample->ToString();
|
||||||
++num_samples_;
|
++num_samples_;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NewTextSampleF(uint32_t track_id, std::shared_ptr<TextSample> sample) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeParser(KeySource* decryption_key_source) {
|
void InitializeParser(KeySource* decryption_key_source) {
|
||||||
parser_->Init(
|
parser_->Init(
|
||||||
base::Bind(&MP4MediaParserTest::InitF, base::Unretained(this)),
|
base::Bind(&MP4MediaParserTest::InitF, base::Unretained(this)),
|
||||||
base::Bind(&MP4MediaParserTest::NewSampleF, base::Unretained(this)),
|
base::Bind(&MP4MediaParserTest::NewSampleF, base::Unretained(this)),
|
||||||
|
base::Bind(&MP4MediaParserTest::NewTextSampleF, base::Unretained(this)),
|
||||||
decryption_key_source);
|
decryption_key_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ WebMClusterParser::WebMClusterParser(
|
||||||
const std::set<int64_t>& ignored_tracks,
|
const std::set<int64_t>& ignored_tracks,
|
||||||
const std::string& audio_encryption_key_id,
|
const std::string& audio_encryption_key_id,
|
||||||
const std::string& video_encryption_key_id,
|
const std::string& video_encryption_key_id,
|
||||||
const MediaParser::NewSampleCB& new_sample_cb,
|
const MediaParser::NewMediaSampleCB& new_sample_cb,
|
||||||
const MediaParser::InitCB& init_cb,
|
const MediaParser::InitCB& init_cb,
|
||||||
KeySource* decryption_key_source)
|
KeySource* decryption_key_source)
|
||||||
: timecode_multiplier_(timecode_scale /
|
: timecode_multiplier_(timecode_scale /
|
||||||
|
@ -482,10 +482,11 @@ bool WebMClusterParser::OnBlock(bool is_simple_block,
|
||||||
return track->EmitBuffer(buffer);
|
return track->EmitBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebMClusterParser::Track::Track(int track_num,
|
WebMClusterParser::Track::Track(
|
||||||
bool is_video,
|
int track_num,
|
||||||
int64_t default_duration,
|
bool is_video,
|
||||||
const MediaParser::NewSampleCB& new_sample_cb)
|
int64_t default_duration,
|
||||||
|
const MediaParser::NewMediaSampleCB& new_sample_cb)
|
||||||
: track_num_(track_num),
|
: track_num_(track_num),
|
||||||
is_video_(is_video),
|
is_video_(is_video),
|
||||||
default_duration_(default_duration),
|
default_duration_(default_duration),
|
||||||
|
|
|
@ -41,7 +41,7 @@ class WebMClusterParser : public WebMParserClient {
|
||||||
Track(int track_num,
|
Track(int track_num,
|
||||||
bool is_video,
|
bool is_video,
|
||||||
int64_t default_duration,
|
int64_t default_duration,
|
||||||
const MediaParser::NewSampleCB& new_sample_cb);
|
const MediaParser::NewMediaSampleCB& new_sample_cb);
|
||||||
~Track();
|
~Track();
|
||||||
|
|
||||||
int track_num() const { return track_num_; }
|
int track_num() const { return track_num_; }
|
||||||
|
@ -89,7 +89,7 @@ class WebMClusterParser : public WebMParserClient {
|
||||||
// only if |default_duration_| is kNoTimestamp.
|
// only if |default_duration_| is kNoTimestamp.
|
||||||
int64_t estimated_next_frame_duration_;
|
int64_t estimated_next_frame_duration_;
|
||||||
|
|
||||||
MediaParser::NewSampleCB new_sample_cb_;
|
MediaParser::NewMediaSampleCB new_sample_cb_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<int, Track> TextTrackMap;
|
typedef std::map<int, Track> TextTrackMap;
|
||||||
|
@ -129,7 +129,7 @@ class WebMClusterParser : public WebMParserClient {
|
||||||
const std::set<int64_t>& ignored_tracks,
|
const std::set<int64_t>& ignored_tracks,
|
||||||
const std::string& audio_encryption_key_id,
|
const std::string& audio_encryption_key_id,
|
||||||
const std::string& video_encryption_key_id,
|
const std::string& video_encryption_key_id,
|
||||||
const MediaParser::NewSampleCB& new_sample_cb,
|
const MediaParser::NewMediaSampleCB& new_sample_cb,
|
||||||
const MediaParser::InitCB& init_cb,
|
const MediaParser::InitCB& init_cb,
|
||||||
KeySource* decryption_key_source);
|
KeySource* decryption_key_source);
|
||||||
~WebMClusterParser() override;
|
~WebMClusterParser() override;
|
||||||
|
|
|
@ -377,8 +377,7 @@ class WebMClusterParserTest : public testing::Test {
|
||||||
streams_from_init_event_ = stream_info;
|
streams_from_init_event_ = stream_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NewSampleEvent(uint32_t track_id,
|
bool NewSampleEvent(uint32_t track_id, std::shared_ptr<MediaSample> sample) {
|
||||||
const std::shared_ptr<MediaSample>& sample) {
|
|
||||||
switch (track_id) {
|
switch (track_id) {
|
||||||
case kAudioTrackNum:
|
case kAudioTrackNum:
|
||||||
audio_buffers_.push_back(sample);
|
audio_buffers_.push_back(sample);
|
||||||
|
|
|
@ -26,16 +26,17 @@ WebMMediaParser::WebMMediaParser()
|
||||||
WebMMediaParser::~WebMMediaParser() {}
|
WebMMediaParser::~WebMMediaParser() {}
|
||||||
|
|
||||||
void WebMMediaParser::Init(const InitCB& init_cb,
|
void WebMMediaParser::Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) {
|
KeySource* decryption_key_source) {
|
||||||
DCHECK_EQ(state_, kWaitingForInit);
|
DCHECK_EQ(state_, kWaitingForInit);
|
||||||
DCHECK(init_cb_.is_null());
|
DCHECK(init_cb_.is_null());
|
||||||
DCHECK(!init_cb.is_null());
|
DCHECK(!init_cb.is_null());
|
||||||
DCHECK(!new_sample_cb.is_null());
|
DCHECK(!new_media_sample_cb.is_null());
|
||||||
|
|
||||||
ChangeState(kParsingHeaders);
|
ChangeState(kParsingHeaders);
|
||||||
init_cb_ = init_cb;
|
init_cb_ = init_cb;
|
||||||
new_sample_cb_ = new_sample_cb;
|
new_sample_cb_ = new_media_sample_cb;
|
||||||
decryption_key_source_ = decryption_key_source;
|
decryption_key_source_ = decryption_key_source;
|
||||||
ignore_text_tracks_ = true;
|
ignore_text_tracks_ = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ class WebMMediaParser : public MediaParser {
|
||||||
/// @name MediaParser implementation overrides.
|
/// @name MediaParser implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
void Init(const InitCB& init_cb,
|
void Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) override;
|
KeySource* decryption_key_source) override;
|
||||||
bool Flush() override WARN_UNUSED_RESULT;
|
bool Flush() override WARN_UNUSED_RESULT;
|
||||||
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
||||||
|
@ -64,7 +65,7 @@ class WebMMediaParser : public MediaParser {
|
||||||
|
|
||||||
State state_;
|
State state_;
|
||||||
InitCB init_cb_;
|
InitCB init_cb_;
|
||||||
NewSampleCB new_sample_cb_;
|
NewMediaSampleCB new_sample_cb_;
|
||||||
KeySource* decryption_key_source_;
|
KeySource* decryption_key_source_;
|
||||||
bool ignore_text_tracks_;
|
bool ignore_text_tracks_;
|
||||||
|
|
||||||
|
|
|
@ -112,14 +112,15 @@ WvmMediaParser::WvmMediaParser()
|
||||||
WvmMediaParser::~WvmMediaParser() {}
|
WvmMediaParser::~WvmMediaParser() {}
|
||||||
|
|
||||||
void WvmMediaParser::Init(const InitCB& init_cb,
|
void WvmMediaParser::Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) {
|
KeySource* decryption_key_source) {
|
||||||
DCHECK(!is_initialized_);
|
DCHECK(!is_initialized_);
|
||||||
DCHECK(!init_cb.is_null());
|
DCHECK(!init_cb.is_null());
|
||||||
DCHECK(!new_sample_cb.is_null());
|
DCHECK(!new_media_sample_cb.is_null());
|
||||||
decryption_key_source_ = decryption_key_source;
|
decryption_key_source_ = decryption_key_source;
|
||||||
init_cb_ = init_cb;
|
init_cb_ = init_cb;
|
||||||
new_sample_cb_ = new_sample_cb;
|
new_sample_cb_ = new_media_sample_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
|
bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
|
||||||
|
|
|
@ -56,7 +56,8 @@ class WvmMediaParser : public MediaParser {
|
||||||
/// @name MediaParser implementation overrides.
|
/// @name MediaParser implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
void Init(const InitCB& init_cb,
|
void Init(const InitCB& init_cb,
|
||||||
const NewSampleCB& new_sample_cb,
|
const NewMediaSampleCB& new_media_sample_cb,
|
||||||
|
const NewTextSampleCB& new_text_sample_cb,
|
||||||
KeySource* decryption_key_source) override;
|
KeySource* decryption_key_source) override;
|
||||||
bool Flush() override WARN_UNUSED_RESULT;
|
bool Flush() override WARN_UNUSED_RESULT;
|
||||||
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
|
||||||
|
@ -216,7 +217,7 @@ class WvmMediaParser : public MediaParser {
|
||||||
|
|
||||||
// List of callbacks.t
|
// List of callbacks.t
|
||||||
InitCB init_cb_;
|
InitCB init_cb_;
|
||||||
NewSampleCB new_sample_cb_;
|
NewMediaSampleCB new_sample_cb_;
|
||||||
|
|
||||||
// Whether |init_cb_| has been invoked.
|
// Whether |init_cb_| has been invoked.
|
||||||
bool is_initialized_;
|
bool is_initialized_;
|
||||||
|
|
|
@ -99,8 +99,7 @@ class WvmMediaParserTest : public testing::Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnNewSample(uint32_t track_id,
|
bool OnNewSample(uint32_t track_id, std::shared_ptr<MediaSample> sample) {
|
||||||
const std::shared_ptr<MediaSample>& sample) {
|
|
||||||
std::string stream_type;
|
std::string stream_type;
|
||||||
if (static_cast<int32_t>(track_id) != current_track_id_) {
|
if (static_cast<int32_t>(track_id) != current_track_id_) {
|
||||||
// onto next track.
|
// onto next track.
|
||||||
|
@ -138,11 +137,15 @@ class WvmMediaParserTest : public testing::Test {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OnNewTextSample(uint32_t track_id, std::shared_ptr<TextSample> sample) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeParser() {
|
void InitializeParser() {
|
||||||
parser_->Init(
|
parser_->Init(
|
||||||
base::Bind(&WvmMediaParserTest::OnInit,
|
base::Bind(&WvmMediaParserTest::OnInit, base::Unretained(this)),
|
||||||
base::Unretained(this)),
|
base::Bind(&WvmMediaParserTest::OnNewSample, base::Unretained(this)),
|
||||||
base::Bind(&WvmMediaParserTest::OnNewSample,
|
base::Bind(&WvmMediaParserTest::OnNewTextSample,
|
||||||
base::Unretained(this)),
|
base::Unretained(this)),
|
||||||
key_source_.get());
|
key_source_.get());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue