Additional clean ups on comments and TODOs

Also rename WebMStreamParser to WebMMediaParser.

Change-Id: I0defca481f9d7774dd84810a5abd52902d5f47b6
This commit is contained in:
KongQun Yang 2015-10-15 15:39:16 -07:00
parent 845766f69a
commit afbab86399
17 changed files with 170 additions and 217 deletions

View File

@ -29,8 +29,8 @@
'webm_info_parser.h', 'webm_info_parser.h',
'webm_parser.cc', 'webm_parser.cc',
'webm_parser.h', 'webm_parser.h',
'webm_stream_parser.cc', 'webm_media_parser.cc',
'webm_stream_parser.h', 'webm_media_parser.h',
'webm_tracks_parser.cc', 'webm_tracks_parser.cc',
'webm_tracks_parser.h', 'webm_tracks_parser.h',
'webm_video_client.cc', 'webm_video_client.cc',

View File

@ -16,21 +16,21 @@ namespace edash_packager {
namespace media { namespace media {
class AudioDecoderConfig; class AudioDecoderConfig;
// Helper class used to parse an Audio element inside a TrackEntry element. /// Helper class used to parse an Audio element inside a TrackEntry element.
class WebMAudioClient : public WebMParserClient { class WebMAudioClient : public WebMParserClient {
public: public:
WebMAudioClient(); WebMAudioClient();
~WebMAudioClient() override; ~WebMAudioClient() override;
// Reset this object's state so it can process a new audio track element. /// Reset this object's state so it can process a new audio track element.
void Reset(); void Reset();
// Create an AudioStreamInfo with the data in |track_num|, |codec_id|, /// Create an AudioStreamInfo with the data in |track_num|, |codec_id|,
// |codec_private|, |is_encrypted| and the fields parsed from the last audio /// |codec_private|, |is_encrypted| and the fields parsed from the last audio
// track element this object was used to parse. /// track element this object was used to parse.
// Returns an AudioStreamInfo scoped_refptr if successful. /// @return An AudioStreamInfo scoped_refptr if successful.
// Returns an empty scoped_refptr if there was unexpected values in the /// @return An empty scoped_refptr if there was unexpected values in the
// provided parameters or audio track element fields. /// provided parameters or audio track element fields.
scoped_refptr<AudioStreamInfo> GetAudioStreamInfo( scoped_refptr<AudioStreamInfo> GetAudioStreamInfo(
int64_t track_num, int64_t track_num,
const std::string& codec_id, const std::string& codec_id,

View File

@ -136,15 +136,15 @@ int64_t WebMClusterParser::TryGetEncodedAudioDuration(
// Duration is currently read assuming the *entire* stream is unencrypted. // Duration is currently read assuming the *entire* stream is unencrypted.
// The special "Signal Byte" prepended to Blocks in encrypted streams is // The special "Signal Byte" prepended to Blocks in encrypted streams is
// assumed to not be present. // assumed to not be present.
// TODO(chcunningham): Consider parsing "Signal Byte" for encrypted streams // TODO: Consider parsing "Signal Byte" for encrypted streams to return
// to return duration for any unencrypted blocks. // duration for any unencrypted blocks.
if (audio_codec_ == kCodecOpus) { if (audio_codec_ == kCodecOpus) {
return ReadOpusDuration(data, size); return ReadOpusDuration(data, size);
} }
// TODO(wolenetz/chcunningham): Implement duration reading for Vorbis. See // TODO: Implement duration reading for Vorbis. See motivations in
// motivations in http://crbug.com/396634. // http://crbug.com/396634.
return kNoTimestamp; return kNoTimestamp;
} }
@ -344,10 +344,10 @@ bool WebMClusterParser::OnBinary(int id, const uint8_t* data, int size) {
case kWebMIdBlockAdditional: { case kWebMIdBlockAdditional: {
uint64_t block_add_id = base::HostToNet64(block_add_id_); uint64_t block_add_id = base::HostToNet64(block_add_id_);
if (block_additional_data_) { if (block_additional_data_) {
// TODO(vigneshv): Technically, more than 1 BlockAdditional is allowed // TODO: Technically, more than 1 BlockAdditional is allowed as per
// as per matroska spec. But for now we don't have a use case to // matroska spec. But for now we don't have a use case to support
// support parsing of such files. Take a look at this again when such a // parsing of such files. Take a look at this again when such a case
// case arises. // arises.
LOG(ERROR) << "More than 1 BlockAdditional in a " LOG(ERROR) << "More than 1 BlockAdditional in a "
"BlockGroup is not supported."; "BlockGroup is not supported.";
return false; return false;
@ -395,8 +395,8 @@ bool WebMClusterParser::OnBlock(bool is_simple_block,
return false; return false;
} }
// TODO(acolwell): Should relative negative timecode offsets be rejected? Or // TODO: Should relative negative timecode offsets be rejected? Or only when
// only when the absolute timecode is negative? See http://crbug.com/271794 // the absolute timecode is negative? See http://crbug.com/271794
if (timecode < 0) { if (timecode < 0) {
LOG(ERROR) << "Got a block with negative timecode offset " << timecode; LOG(ERROR) << "Got a block with negative timecode offset " << timecode;
return false; return false;
@ -501,7 +501,7 @@ bool WebMClusterParser::OnBlock(bool is_simple_block,
// estimation may still apply in cases of encryption and codecs for which // estimation may still apply in cases of encryption and codecs for which
// we do not extract encoded duration. Within a cluster, estimates are applied // we do not extract encoded duration. Within a cluster, estimates are applied
// as Block Timecode deltas, or once the whole cluster is parsed in the case // as Block Timecode deltas, or once the whole cluster is parsed in the case
// of the last Block in the cluster. See Track::AddBuffer and // of the last Block in the cluster. See Track::EmitBuffer and
// ApplyDurationEstimateIfNeeded(). // ApplyDurationEstimateIfNeeded().
if (encoded_duration != kNoTimestamp) { if (encoded_duration != kNoTimestamp) {
DCHECK(encoded_duration != kInfiniteDuration); DCHECK(encoded_duration != kInfiniteDuration);
@ -529,7 +529,7 @@ bool WebMClusterParser::OnBlock(bool is_simple_block,
buffer->set_duration(track->default_duration()); buffer->set_duration(track->default_duration());
} }
return track->AddBuffer(buffer); return track->EmitBuffer(buffer);
} }
WebMClusterParser::Track::Track(int track_num, WebMClusterParser::Track::Track(int track_num,
@ -546,9 +546,9 @@ WebMClusterParser::Track::Track(int track_num,
WebMClusterParser::Track::~Track() {} WebMClusterParser::Track::~Track() {}
bool WebMClusterParser::Track::AddBuffer( bool WebMClusterParser::Track::EmitBuffer(
const scoped_refptr<MediaSample>& buffer) { const scoped_refptr<MediaSample>& buffer) {
DVLOG(2) << "AddBuffer() : " << track_num_ DVLOG(2) << "EmitBuffer() : " << track_num_
<< " ts " << buffer->pts() << " ts " << buffer->pts()
<< " dur " << buffer->duration() << " dur " << buffer->duration()
<< " kf " << buffer->is_key_frame() << " kf " << buffer->is_key_frame()
@ -559,7 +559,7 @@ bool WebMClusterParser::Track::AddBuffer(
buffer->pts() - last_added_buffer_missing_duration_->pts(); buffer->pts() - last_added_buffer_missing_duration_->pts();
last_added_buffer_missing_duration_->set_duration(derived_duration); last_added_buffer_missing_duration_->set_duration(derived_duration);
DVLOG(2) << "AddBuffer() : applied derived duration to held-back buffer : " DVLOG(2) << "EmitBuffer() : applied derived duration to held-back buffer : "
<< " ts " << " ts "
<< last_added_buffer_missing_duration_->pts() << last_added_buffer_missing_duration_->pts()
<< " dur " << " dur "
@ -569,17 +569,17 @@ bool WebMClusterParser::Track::AddBuffer(
scoped_refptr<MediaSample> updated_buffer = scoped_refptr<MediaSample> updated_buffer =
last_added_buffer_missing_duration_; last_added_buffer_missing_duration_;
last_added_buffer_missing_duration_ = NULL; last_added_buffer_missing_duration_ = NULL;
if (!QueueBuffer(updated_buffer)) if (!EmitBufferHelp(updated_buffer))
return false; return false;
} }
if (buffer->duration() == kNoTimestamp) { if (buffer->duration() == kNoTimestamp) {
last_added_buffer_missing_duration_ = buffer; last_added_buffer_missing_duration_ = buffer;
DVLOG(2) << "AddBuffer() : holding back buffer that is missing duration"; DVLOG(2) << "EmitBuffer() : holding back buffer that is missing duration";
return true; return true;
} }
return QueueBuffer(buffer); return EmitBufferHelp(buffer);
} }
void WebMClusterParser::Track::ApplyDurationEstimateIfNeeded() { void WebMClusterParser::Track::ApplyDurationEstimateIfNeeded() {
@ -611,7 +611,7 @@ void WebMClusterParser::Track::ApplyDurationEstimateIfNeeded() {
<< " size " << last_added_buffer_missing_duration_->data_size(); << " size " << last_added_buffer_missing_duration_->data_size();
// Don't use the applied duration as a future estimation (don't use // Don't use the applied duration as a future estimation (don't use
// QueueBuffer() here.) // EmitBufferHelp() here.)
new_sample_cb_.Run(track_num_, last_added_buffer_missing_duration_); new_sample_cb_.Run(track_num_, last_added_buffer_missing_duration_);
last_added_buffer_missing_duration_ = NULL; last_added_buffer_missing_duration_ = NULL;
} }
@ -643,7 +643,7 @@ bool WebMClusterParser::Track::IsKeyframe(const uint8_t* data, int size) const {
return true; return true;
} }
bool WebMClusterParser::Track::QueueBuffer( bool WebMClusterParser::Track::EmitBufferHelp(
const scoped_refptr<MediaSample>& buffer) { const scoped_refptr<MediaSample>& buffer) {
DCHECK(!last_added_buffer_missing_duration_.get()); DCHECK(!last_added_buffer_missing_duration_.get());
@ -660,8 +660,8 @@ bool WebMClusterParser::Track::QueueBuffer(
// so maximum is used and overlap is simply resolved by showing the // so maximum is used and overlap is simply resolved by showing the
// later of the overlapping frames at its given PTS, effectively trimming down // later of the overlapping frames at its given PTS, effectively trimming down
// the over-estimated duration of the previous frame. // the over-estimated duration of the previous frame.
// TODO(chcunningham): Use max for audio and disable splicing whenever // TODO: Use max for audio and disable splicing whenever estimated buffers are
// estimated buffers are encountered. // encountered.
if (duration > 0) { if (duration > 0) {
int64_t orig_duration_estimate = estimated_next_frame_duration_; int64_t orig_duration_estimate = estimated_next_frame_duration_;
if (estimated_next_frame_duration_ == kNoTimestamp) { if (estimated_next_frame_duration_ == kNoTimestamp) {

View File

@ -21,21 +21,21 @@ namespace media {
class WebMClusterParser : public WebMParserClient { class WebMClusterParser : public WebMParserClient {
public: public:
// Numbers chosen to estimate the duration of a buffer if none is set and /// Numbers chosen to estimate the duration of a buffer if none is set and
// there is not enough information to get a better estimate. /// there is not enough information to get a better estimate.
enum { enum {
// Common 1k samples @44.1kHz /// Common 1k samples @44.1kHz
kDefaultAudioBufferDurationInMs = 23, kDefaultAudioBufferDurationInMs = 23,
// Chosen to represent 16fps duration, which will prevent MSE stalls in /// Chosen to represent 16fps duration, which will prevent MSE stalls in
// videos with frame-rates as low as 8fps. /// videos with frame-rates as low as 8fps.
kDefaultVideoBufferDurationInMs = 63 kDefaultVideoBufferDurationInMs = 63
}; };
// Opus packets encode the duration and other parameters in the 5 most /// Opus packets encode the duration and other parameters in the 5 most
// significant bits of the first byte. The index in this array corresponds /// significant bits of the first byte. The index in this array corresponds
// to the duration of each frame of the packet in microseconds. See /// to the duration of each frame of the packet in microseconds. See
// https://tools.ietf.org/html/rfc6716#page-14 /// https://tools.ietf.org/html/rfc6716#page-14
static const uint16_t kOpusFrameDurationsMu[]; static const uint16_t kOpusFrameDurationsMu[];
private: private:
@ -51,21 +51,20 @@ class WebMClusterParser : public WebMParserClient {
int track_num() const { return track_num_; } int track_num() const { return track_num_; }
// If |last_added_buffer_missing_duration_| is set, updates its duration // If |last_added_buffer_missing_duration_| is set, updates its duration
// relative to |buffer|'s timestamp, and adds it to |buffers_| and unsets // relative to |buffer|'s timestamp, and emits it and unsets
// |last_added_buffer_missing_duration_|. Then, if |buffer| is missing // |last_added_buffer_missing_duration_|. Otherwise, if |buffer| is missing
// duration, saves |buffer| into |last_added_buffer_missing_duration_|, or // duration, saves |buffer| into |last_added_buffer_missing_duration_|.
// otherwise adds |buffer| to |buffers_|. bool EmitBuffer(const scoped_refptr<MediaSample>& buffer);
bool AddBuffer(const scoped_refptr<MediaSample>& buffer);
// If |last_added_buffer_missing_duration_| is set, updates its duration to // If |last_added_buffer_missing_duration_| is set, updates its duration to
// be non-kNoTimestamp() value of |estimated_next_frame_duration_| or a // be non-kNoTimestamp value of |estimated_next_frame_duration_| or a
// hard-coded default, then adds it to |buffers_| and unsets // hard-coded default, then emits it and unsets
// |last_added_buffer_missing_duration_|. (This method helps stream parser // |last_added_buffer_missing_duration_|. (This method helps stream parser
// emit all buffers in a media segment before signaling end of segment.) // emit all buffers in a media segment before signaling end of segment.)
void ApplyDurationEstimateIfNeeded(); void ApplyDurationEstimateIfNeeded();
// Clears all buffer state, including any possibly held-aside buffer that // Clears all buffer state, including any possibly held-aside buffer that
// was missing duration, and all contents of |buffers_|. // was missing duration.
void Reset(); void Reset();
// Helper function used to inspect block data to determine if the // Helper function used to inspect block data to determine if the
@ -78,10 +77,10 @@ class WebMClusterParser : public WebMParserClient {
private: private:
// Helper that sanity-checks |buffer| duration, updates // Helper that sanity-checks |buffer| duration, updates
// |estimated_next_frame_duration_|, and adds |buffer| to |buffers_|. // |estimated_next_frame_duration_|, and emits |buffer|.
// Returns false if |buffer| failed sanity check and therefore was not added // Returns false if |buffer| failed sanity check and therefore was not
// to |buffers_|. Returns true otherwise. // emitted. Returns true otherwise.
bool QueueBuffer(const scoped_refptr<MediaSample>& buffer); bool EmitBufferHelp(const scoped_refptr<MediaSample>& buffer);
// Helper that calculates the buffer duration to use in // Helper that calculates the buffer duration to use in
// ApplyDurationEstimateIfNeeded(). // ApplyDurationEstimateIfNeeded().
@ -95,19 +94,18 @@ class WebMClusterParser : public WebMParserClient {
bool is_video_; bool is_video_;
// Parsed track buffers, each with duration and in (decode) timestamp order, // Parsed track buffers, each with duration and in (decode) timestamp order,
// that have not yet been extracted into |ready_buffers_|. Note that up to // that have not yet been emitted. Note that up to one additional buffer
// one additional buffer missing duration may be tracked by // missing duration may be tracked by |last_added_buffer_missing_duration_|.
// |last_added_buffer_missing_duration_|.
scoped_refptr<MediaSample> last_added_buffer_missing_duration_; scoped_refptr<MediaSample> last_added_buffer_missing_duration_;
// If kNoTimestamp(), then |estimated_next_frame_duration_| will be used. // If kNoTimestamp, then |estimated_next_frame_duration_| will be used.
int64_t default_duration_; int64_t default_duration_;
// If kNoTimestamp(), then a default value will be used. This estimate is // If kNoTimestamp, then a default value will be used. This estimate is the
// the maximum (for video), or minimum (for audio) duration seen so far for // maximum (for video), or minimum (for audio) duration seen so far for this
// this track, and is used only if |default_duration_| is kNoTimestamp(). // track, and is used only if |default_duration_| is kNoTimestamp.
// TODO(chcunningham): Use maximum for audio too, adding checks to disable // TODO: Use maximum for audio too, adding checks to disable splicing when
// splicing when these estimates are observed in SourceBufferStream. // these estimates are observed in SourceBufferStream.
int64_t estimated_next_frame_duration_; int64_t estimated_next_frame_duration_;
MediaParser::NewSampleCB new_sample_cb_; MediaParser::NewSampleCB new_sample_cb_;
@ -129,19 +127,18 @@ class WebMClusterParser : public WebMParserClient {
const MediaParser::NewSampleCB& new_sample_cb); const MediaParser::NewSampleCB& new_sample_cb);
~WebMClusterParser() override; ~WebMClusterParser() override;
// Resets the parser state so it can accept a new cluster. /// Resets the parser state so it can accept a new cluster.
void Reset(); void Reset();
// Parses a WebM cluster element in |buf|. /// Parses a WebM cluster element in |buf|.
// /// @return -1 if the parse fails.
// Returns -1 if the parse fails. /// @return 0 if more data is needed.
// Returns 0 if more data is needed. /// @return The number of bytes parsed on success.
// Returns the number of bytes parsed on success.
int Parse(const uint8_t* buf, int size); int Parse(const uint8_t* buf, int size);
int64_t cluster_start_time() const { return cluster_start_time_; } int64_t cluster_start_time() const { return cluster_start_time_; }
// Returns true if the last Parse() call stopped at the end of a cluster. /// @return true if the last Parse() call stopped at the end of a cluster.
bool cluster_ended() const { return cluster_ended_; } bool cluster_ended() const { return cluster_ended_; }
private: private:
@ -177,21 +174,17 @@ class WebMClusterParser : public WebMParserClient {
Track* FindTextTrack(int track_num); Track* FindTextTrack(int track_num);
// Attempts to read the duration from the encoded audio data, returning as // Attempts to read the duration from the encoded audio data, returning as
// TimeDelta or kNoTimestamp() if duration cannot be retrieved. This obviously // kNoTimestamp if duration cannot be retrieved.
// violates layering rules, but is useful for MSE to know duration in cases // Avoid calling if encrypted; may produce unexpected output. See
// where it isn't explicitly given and cannot be calculated for Blocks at the // implementation for supported codecs.
// end of a Cluster (the next Cluster in playback-order may not be the next
// Cluster we parse, so we can't simply use the delta of the first Block in
// the next Cluster). Avoid calling if encrypted; may produce unexpected
// output. See implementation for supported codecs.
int64_t TryGetEncodedAudioDuration(const uint8_t* data, int size); int64_t TryGetEncodedAudioDuration(const uint8_t* data, int size);
// Reads Opus packet header to determine packet duration. Duration returned // Reads Opus packet header to determine packet duration. Duration returned
// as TimeDelta or kNoTimestamp() upon failure to read duration from packet. // as kNoTimestamp upon failure to read duration from packet.
int64_t ReadOpusDuration(const uint8_t* data, int size); int64_t ReadOpusDuration(const uint8_t* data, int size);
// Tracks the number of LOGs made in process of reading encoded // Tracks the number of LOGs made in process of reading encoded duration.
// duration. Useful to prevent log spam. // Useful to prevent log spam.
int num_duration_errors_ = 0; int num_duration_errors_ = 0;
double timecode_multiplier_; // Multiplier used to convert timecodes into double timecode_multiplier_; // Multiplier used to convert timecodes into

View File

@ -875,7 +875,7 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) {
// cluster. Duration for the last block in a cluster is estimated // cluster. Duration for the last block in a cluster is estimated
// independently for each track in the cluster. For video tracks we use the // independently for each track in the cluster. For video tracks we use the
// maximum seen so far. For audio we use the the minimum. // maximum seen so far. For audio we use the the minimum.
// TODO(chcunningham): Move audio over to use the maximum. // TODO: Move audio over to use the maximum.
const int kExpectedAudioEstimationInMs = 22; const int kExpectedAudioEstimationInMs = 22;
const int kExpectedVideoEstimationInMs = 34; const int kExpectedVideoEstimationInMs = 34;
@ -925,7 +925,7 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) {
ASSERT_TRUE(VerifyBuffers(kBlockInfo2, block_count2)); ASSERT_TRUE(VerifyBuffers(kBlockInfo2, block_count2));
} }
// TODO(wolenetz): Is parser behavior correct? See http://crbug.com/363433. // TODO: Is parser behavior correct? See http://crbug.com/363433.
TEST_F(WebMClusterParserTest, TEST_F(WebMClusterParserTest,
ParseWithDefaultDurationsBlockGroupsWithoutDurations) { ParseWithDefaultDurationsBlockGroupsWithoutDurations) {
InSequence s; InSequence s;

View File

@ -10,9 +10,9 @@
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
// WebM element IDs. /// WebM element IDs.
// This is a subset of the IDs in the Matroska spec. /// This is a subset of the IDs in the Matroska spec.
// http://www.matroska.org/technical/specs/index.html /// http://www.matroska.org/technical/specs/index.html
const int kWebMIdAESSettingsCipherMode = 0x47E8; const int kWebMIdAESSettingsCipherMode = 0x47E8;
const int kWebMIdAlphaMode = 0x53C0; const int kWebMIdAlphaMode = 0x53C0;
const int kWebMIdAspectRatioType = 0x54B3; const int kWebMIdAspectRatioType = 0x54B3;
@ -205,14 +205,14 @@ const int64_t kWebMUnknownSize = 0x00FFFFFFFFFFFFFFLL;
const uint8_t kWebMFlagKeyframe = 0x80; const uint8_t kWebMFlagKeyframe = 0x80;
// Current encrypted WebM request for comments specification is here /// Current encrypted WebM request for comments specification is here
// http://wiki.webmproject.org/encryption/webm-encryption-rfc /// http://wiki.webmproject.org/encryption/webm-encryption-rfc
const uint8_t kWebMFlagEncryptedFrame = 0x1; const uint8_t kWebMFlagEncryptedFrame = 0x1;
const int kWebMIvSize = 8; const int kWebMIvSize = 8;
const int kWebMSignalByteSize = 1; const int kWebMSignalByteSize = 1;
// Current specification for WebVTT embedded in WebM /// Current specification for WebVTT embedded in WebM
// http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm /// http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm
const int kWebMTrackTypeVideo = 1; const int kWebMTrackTypeVideo = 1;
const int kWebMTrackTypeAudio = 2; const int kWebMTrackTypeAudio = 2;

View File

@ -15,8 +15,8 @@ namespace media {
class ContentEncoding { class ContentEncoding {
public: public:
// The following enum definitions are based on the ContentEncoding element /// The following enum definitions are based on the ContentEncoding element
// specified in the Matroska spec. /// specified in the Matroska spec.
static const int kOrderInvalid = -1; static const int kOrderInvalid = -1;

View File

@ -18,7 +18,7 @@ namespace media {
typedef std::vector<ContentEncoding*> ContentEncodings; typedef std::vector<ContentEncoding*> ContentEncodings;
// Parser for WebM ContentEncodings element. /// Parser for WebM ContentEncodings element.
class WebMContentEncodingsClient : public WebMParserClient { class WebMContentEncodingsClient : public WebMParserClient {
public: public:
WebMContentEncodingsClient(); WebMContentEncodingsClient();
@ -26,7 +26,7 @@ class WebMContentEncodingsClient : public WebMParserClient {
const ContentEncodings& content_encodings() const; const ContentEncodings& content_encodings() const;
// WebMParserClient methods /// WebMParserClient methods
WebMParserClient* OnListStart(int id) override; WebMParserClient* OnListStart(int id) override;
bool OnListEnd(int id) override; bool OnListEnd(int id) override;
bool OnUInt(int id, int64_t val) override; bool OnUInt(int id, int64_t val) override;

View File

@ -4,49 +4,17 @@
#include "packager/media/formats/webm/webm_content_encodings_client.h" #include "packager/media/formats/webm/webm_content_encodings_client.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <string> #include <string>
#include "packager/base/bind.h"
#include "packager/base/strings/string_number_conversions.h" #include "packager/base/strings/string_number_conversions.h"
#include "packager/media/formats/webm/webm_constants.h" #include "packager/media/formats/webm/webm_constants.h"
#include "packager/media/formats/webm/webm_parser.h" #include "packager/media/formats/webm/webm_parser.h"
using ::testing::StrictMock;
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
// Matchers for verifying common media log entry strings.
MATCHER(MissingContentEncoding, "") {
return CONTAINS_STRING(arg, "Missing ContentEncoding.");
}
MATCHER(UnexpectedContentEncodingOrder, "") {
return CONTAINS_STRING(arg, "Unexpected ContentEncodingOrder.");
}
MATCHER(UnexpectedContentEncodingScope, "") {
return CONTAINS_STRING(arg, "Unexpected ContentEncodingScope.");
}
MATCHER(ContentCompressionNotSupported, "") {
return CONTAINS_STRING(arg, "ContentCompression not supported.");
}
MATCHER(MissingContentEncryption, "") {
return CONTAINS_STRING(
arg,
"ContentEncodingType is encryption but ContentEncryption is missing.");
}
MATCHER_P(UnexpectedContentEncAlgo, algo, "") {
return CONTAINS_STRING(
arg, "Unexpected ContentEncAlgo " + base::IntToString(algo) + ".");
}
class WebMContentEncodingsClientTest : public testing::Test { class WebMContentEncodingsClientTest : public testing::Test {
public: public:
WebMContentEncodingsClientTest() WebMContentEncodingsClientTest()

View File

@ -7,20 +7,20 @@
#include <stdint.h> #include <stdint.h>
#include "packager/base/macros.h"
#include "packager/base/memory/scoped_ptr.h" #include "packager/base/memory/scoped_ptr.h"
#include "packager/media/base/decrypt_config.h" #include "packager/media/base/decrypt_config.h"
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
// Fills an initialized DecryptConfig, which can be sent to the Decryptor if /// Fills an initialized DecryptConfig, which can be sent to the Decryptor if
// the stream has potentially encrypted frames. Also sets |data_offset| which /// the stream has potentially encrypted frames. Also sets |data_offset| which
// indicates where the encrypted data starts. Leaving the IV empty will tell /// indicates where the encrypted data starts. Leaving the IV empty will tell
// the decryptor that the frame is unencrypted. Returns true if |data| is valid, /// the decryptor that the frame is unencrypted.
// false otherwise, in which case |decrypt_config| and |data_offset| will not be /// Current encrypted WebM request for comments specification is here
// changed. Current encrypted WebM request for comments specification is here /// http://wiki.webmproject.org/encryption/webm-encryption-rfc
// http://wiki.webmproject.org/encryption/webm-encryption-rfc /// @return true if |data| is valid, false otherwise, in which case
/// |decrypt_config| and |data_offset| will not be changed.
bool WebMCreateDecryptConfig(const uint8_t* data, bool WebMCreateDecryptConfig(const uint8_t* data,
int data_size, int data_size,
const uint8_t* key_id, const uint8_t* key_id,

View File

@ -12,17 +12,16 @@
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
// Parser for WebM Info element. /// Parser for WebM Info element.
class WebMInfoParser : public WebMParserClient { class WebMInfoParser : public WebMParserClient {
public: public:
WebMInfoParser(); WebMInfoParser();
~WebMInfoParser() override; ~WebMInfoParser() override;
// Parses a WebM Info element in |buf|. /// Parses a WebM Info element in |buf|.
// /// @return -1 if the parse fails.
// Returns -1 if the parse fails. /// @return 0 if more data is needed.
// Returns 0 if more data is needed. /// @return The number of bytes parsed on success.
// Returns the number of bytes parsed on success.
int Parse(const uint8_t* buf, int size); int Parse(const uint8_t* buf, int size);
int64_t timecode_scale() const { return timecode_scale_; } int64_t timecode_scale() const { return timecode_scale_; }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "packager/media/formats/webm/webm_stream_parser.h" #include "packager/media/formats/webm/webm_media_parser.h"
#include <string> #include <string>
@ -19,18 +19,14 @@
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
WebMStreamParser::WebMStreamParser() WebMMediaParser::WebMMediaParser()
: state_(kWaitingForInit), : state_(kWaitingForInit), unknown_segment_size_(false) {}
unknown_segment_size_(false) {
}
WebMStreamParser::~WebMStreamParser() { WebMMediaParser::~WebMMediaParser() {}
}
void WebMStreamParser::Init( void WebMMediaParser::Init(const InitCB& init_cb,
const InitCB& init_cb, const NewSampleCB& new_sample_cb,
const NewSampleCB& new_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());
@ -43,7 +39,7 @@ void WebMStreamParser::Init(
ignore_text_tracks_ = true; ignore_text_tracks_ = true;
} }
void WebMStreamParser::Flush() { void WebMMediaParser::Flush() {
DCHECK_NE(state_, kWaitingForInit); DCHECK_NE(state_, kWaitingForInit);
byte_queue_.Reset(); byte_queue_.Reset();
@ -54,7 +50,7 @@ void WebMStreamParser::Flush() {
} }
} }
bool WebMStreamParser::Parse(const uint8_t* buf, int size) { bool WebMMediaParser::Parse(const uint8_t* buf, int size) {
DCHECK_NE(state_, kWaitingForInit); DCHECK_NE(state_, kWaitingForInit);
if (state_ == kError) if (state_ == kError)
@ -102,12 +98,12 @@ bool WebMStreamParser::Parse(const uint8_t* buf, int size) {
return true; return true;
} }
void WebMStreamParser::ChangeState(State new_state) { void WebMMediaParser::ChangeState(State new_state) {
DVLOG(1) << "ChangeState() : " << state_ << " -> " << new_state; DVLOG(1) << "ChangeState() : " << state_ << " -> " << new_state;
state_ = new_state; state_ = new_state;
} }
int WebMStreamParser::ParseInfoAndTracks(const uint8_t* data, int size) { int WebMMediaParser::ParseInfoAndTracks(const uint8_t* data, int size) {
DVLOG(2) << "ParseInfoAndTracks()"; DVLOG(2) << "ParseInfoAndTracks()";
DCHECK(data); DCHECK(data);
DCHECK_GT(size, 0); DCHECK_GT(size, 0);
@ -132,7 +128,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8_t* data, int size) {
case kWebMIdChapters: case kWebMIdChapters:
case kWebMIdTags: case kWebMIdTags:
case kWebMIdAttachments: case kWebMIdAttachments:
// TODO(matthewjheaney): Implement support for chapters. // TODO: Implement support for chapters.
if (cur_size < (result + element_size)) { if (cur_size < (result + element_size)) {
// We don't have the whole element yet. Signal we need more data. // We don't have the whole element yet. Signal we need more data.
return 0; return 0;
@ -213,7 +209,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8_t* data, int size) {
return bytes_parsed; return bytes_parsed;
} }
int WebMStreamParser::ParseCluster(const uint8_t* data, int size) { int WebMMediaParser::ParseCluster(const uint8_t* data, int size) {
if (!cluster_parser_) if (!cluster_parser_)
return -1; return -1;
@ -229,7 +225,7 @@ int WebMStreamParser::ParseCluster(const uint8_t* data, int size) {
return bytes_parsed; return bytes_parsed;
} }
void WebMStreamParser::OnEncryptedMediaInitData(const std::string& key_id) { void WebMMediaParser::OnEncryptedMediaInitData(const std::string& key_id) {
NOTIMPLEMENTED() << "WebM decryption is not implemented yet."; NOTIMPLEMENTED() << "WebM decryption is not implemented yet.";
} }

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef MEDIA_FORMATS_WEBM_WEBM_STREAM_PARSER_H_ #ifndef MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
#define MEDIA_FORMATS_WEBM_WEBM_STREAM_PARSER_H_ #define MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
#include "packager/base/callback_forward.h" #include "packager/base/callback_forward.h"
#include "packager/base/memory/ref_counted.h" #include "packager/base/memory/ref_counted.h"
@ -15,12 +15,12 @@ namespace media {
class WebMClusterParser; class WebMClusterParser;
class WebMStreamParser : public MediaParser { class WebMMediaParser : public MediaParser {
public: public:
WebMStreamParser(); WebMMediaParser();
~WebMStreamParser() override; ~WebMMediaParser() override;
// StreamParser implementation. /// StreamParser implementation.
void Init(const InitCB& init_cb, void Init(const InitCB& init_cb,
const NewSampleCB& new_sample_cb, const NewSampleCB& new_sample_cb,
KeySource* decryption_key_source) override; KeySource* decryption_key_source) override;
@ -70,10 +70,10 @@ class WebMStreamParser : public MediaParser {
scoped_ptr<WebMClusterParser> cluster_parser_; scoped_ptr<WebMClusterParser> cluster_parser_;
ByteQueue byte_queue_; ByteQueue byte_queue_;
DISALLOW_COPY_AND_ASSIGN(WebMStreamParser); DISALLOW_COPY_AND_ASSIGN(WebMMediaParser);
}; };
} // namespace media } // namespace media
} // namespace edash_packager } // namespace edash_packager
#endif // MEDIA_FORMATS_WEBM_WEBM_STREAM_PARSER_H_ #endif // MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_

View File

@ -15,18 +15,18 @@
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
// Interface for receiving WebM parser events. /// Interface for receiving WebM parser events.
// ///
// Each method is called when an element of the specified type is parsed. /// Each method is called when an element of the specified type is parsed.
// The ID of the element that was parsed is given along with the value /// The ID of the element that was parsed is given along with the value
// stored in the element. List elements generate calls at the start and /// stored in the element. List elements generate calls at the start and
// end of the list. Any pointers passed to these methods are only guaranteed /// end of the list. Any pointers passed to these methods are only guaranteed
// to be valid for the life of that call. Each method (except for OnListStart) /// to be valid for the life of that call. Each method (except for OnListStart)
// returns a bool that indicates whether the parsed data is valid. OnListStart /// returns a bool that indicates whether the parsed data is valid. OnListStart
// returns a pointer to a WebMParserClient object, which should be used to /// returns a pointer to a WebMParserClient object, which should be used to
// handle elements parsed out of the list being started. If false (or NULL by /// handle elements parsed out of the list being started. If false (or NULL by
// OnListStart) is returned then the parse is immediately terminated and an /// OnListStart) is returned then the parse is immediately terminated and an
// error is reported by the parser. /// error is reported by the parser.
class WebMParserClient { class WebMParserClient {
public: public:
virtual ~WebMParserClient(); virtual ~WebMParserClient();
@ -46,29 +46,28 @@ class WebMParserClient {
struct ListElementInfo; struct ListElementInfo;
// Parses a WebM list element and all of its children. This /// Parses a WebM list element and all of its children. This
// class supports incremental parsing of the list so Parse() /// class supports incremental parsing of the list so Parse()
// can be called multiple times with pieces of the list. /// can be called multiple times with pieces of the list.
// IsParsingComplete() will return true once the entire list has /// IsParsingComplete() will return true once the entire list has
// been parsed. /// been parsed.
class WebMListParser { class WebMListParser {
public: public:
// |id| - Element ID of the list we intend to parse. /// @param id Element ID of the list we intend to parse.
// |client| - Called as different elements in the list are parsed. /// @param client Called as different elements in the list are parsed.
WebMListParser(int id, WebMParserClient* client); WebMListParser(int id, WebMParserClient* client);
~WebMListParser(); ~WebMListParser();
// Resets the state of the parser so it can start parsing a new list. /// Resets the state of the parser so it can start parsing a new list.
void Reset(); void Reset();
// Parses list data contained in |buf|. /// Parses list data contained in |buf|.
// /// @return < 0 if the parse fails.
// Returns < 0 if the parse fails. /// @return 0 if more data is needed.
// Returns 0 if more data is needed. /// @return > 0 indicates success & the number of bytes parsed.
// Returning > 0 indicates success & the number of bytes parsed.
int Parse(const uint8_t* buf, int size); int Parse(const uint8_t* buf, int size);
// Returns true if the entire list has been parsed. /// @return true if the entire list has been parsed.
bool IsParsingComplete() const; bool IsParsingComplete() const;
private: private:
@ -146,14 +145,13 @@ class WebMListParser {
DISALLOW_COPY_AND_ASSIGN(WebMListParser); DISALLOW_COPY_AND_ASSIGN(WebMListParser);
}; };
// Parses an element header & returns the ID and element size. /// Parses an element header & returns the ID and element size.
// /// @param[out] id contains the element ID on success and is undefined otherwise.
// Returns < 0 if the parse fails. /// @param[out] element_size contains the element size on success and is
// Returns 0 if more data is needed. /// undefined otherwise.
// Returning > 0 indicates success & the number of bytes parsed. /// @return < 0 if the parse fails.
// |*id| contains the element ID on success and is undefined otherwise. /// @return 0 if more data is needed.
// |*element_size| contains the element size on success and is undefined /// @return > 0 indicates success & the number of bytes parsed.
// otherwise.
int WebMParseElementHeader(const uint8_t* buf, int WebMParseElementHeader(const uint8_t* buf,
int size, int size,
int* id, int* id,

View File

@ -24,26 +24,25 @@
namespace edash_packager { namespace edash_packager {
namespace media { namespace media {
// Parser for WebM Tracks element. /// Parser for WebM Tracks element.
class WebMTracksParser : public WebMParserClient { class WebMTracksParser : public WebMParserClient {
public: public:
explicit WebMTracksParser(bool ignore_text_tracks); explicit WebMTracksParser(bool ignore_text_tracks);
~WebMTracksParser() override; ~WebMTracksParser() override;
// Parses a WebM Tracks element in |buf|. /// Parses a WebM Tracks element in |buf|.
// /// @return -1 if the parse fails.
// Returns -1 if the parse fails. /// @return 0 if more data is needed.
// Returns 0 if more data is needed. /// @return The number of bytes parsed on success.
// Returns the number of bytes parsed on success.
int Parse(const uint8_t* buf, int size); int Parse(const uint8_t* buf, int size);
int64_t audio_track_num() const { return audio_track_num_; } int64_t audio_track_num() const { return audio_track_num_; }
int64_t video_track_num() const { return video_track_num_; } int64_t video_track_num() const { return video_track_num_; }
// If TrackEntry DefaultDuration field existed for the associated audio or /// If TrackEntry DefaultDuration field existed for the associated audio or
// video track, returns that value converted from ns to base::TimeDelta with /// video track, returns that value converted from ns to base::TimeDelta with
// precision not greater than |timecode_scale_in_us|. Defaults to /// precision not greater than |timecode_scale_in_us|. Defaults to
// kNoTimestamp(). /// kNoTimestamp.
int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const; int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const;
int64_t GetVideoDefaultDuration(const double timecode_scale_in_us) const; int64_t GetVideoDefaultDuration(const double timecode_scale_in_us) const;

View File

@ -16,21 +16,21 @@ namespace edash_packager {
namespace media { namespace media {
class VideoDecoderConfig; class VideoDecoderConfig;
// Helper class used to parse a Video element inside a TrackEntry element. /// Helper class used to parse a Video element inside a TrackEntry element.
class WebMVideoClient : public WebMParserClient { class WebMVideoClient : public WebMParserClient {
public: public:
WebMVideoClient(); WebMVideoClient();
~WebMVideoClient() override; ~WebMVideoClient() override;
// Reset this object's state so it can process a new video track element. /// Reset this object's state so it can process a new video track element.
void Reset(); void Reset();
// Create a VideoStreamInfo with the data in |track_num|, |codec_id|, /// Create a VideoStreamInfo with the data in |track_num|, |codec_id|,
// |codec_private|, |is_encrypted| and the fields parsed from the last video /// |codec_private|, |is_encrypted| and the fields parsed from the last video
// track element this object was used to parse. /// track element this object was used to parse.
// Returns a VideoStreamInfo scoped_refptr if successful. /// @return A VideoStreamInfo scoped_refptr if successful.
// Returns an empty scoped_refptr if there was unexpected values in the /// @return An empty scoped_refptr if there was unexpected values in the
// provided parameters or video track element fields. /// provided parameters or video track element fields.
scoped_refptr<VideoStreamInfo> GetVideoStreamInfo( scoped_refptr<VideoStreamInfo> GetVideoStreamInfo(
int64_t track_num, int64_t track_num,
const std::string& codec_id, const std::string& codec_id,

View File

@ -16,7 +16,7 @@ namespace media {
class WebMWebVTTParser { class WebMWebVTTParser {
public: public:
// Utility function to parse the WebVTT cue from a byte stream. /// Utility function to parse the WebVTT cue from a byte stream.
static void Parse(const uint8_t* payload, static void Parse(const uint8_t* payload,
int payload_size, int payload_size,
std::string* id, std::string* id,