| Index: media/formats/webm/webm_cluster_parser.h
|
| diff --git a/media/formats/webm/webm_cluster_parser.h b/media/formats/webm/webm_cluster_parser.h
|
| index 2af102eaa0ce58b28909a6aa15fffd1bdbe4ed00..759fba9d6341800a6e58d1793435fdc03b11ef91 100644
|
| --- a/media/formats/webm/webm_cluster_parser.h
|
| +++ b/media/formats/webm/webm_cluster_parser.h
|
| @@ -11,6 +11,7 @@
|
| #include <string>
|
|
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "media/base/audio_decoder_config.h"
|
| #include "media/base/media_export.h"
|
| #include "media/base/media_log.h"
|
| #include "media/base/stream_parser.h"
|
| @@ -28,13 +29,17 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
|
|
|
| // Arbitrarily-chosen numbers to estimate the duration of a buffer if none is
|
| // set and there is not enough information to get a better estimate.
|
| - // TODO(wolenetz/acolwell): Parse audio codebook to determine missing audio
|
| - // frame durations. See http://crbug.com/351166.
|
| enum {
|
| kDefaultAudioBufferDurationInMs = 23, // Common 1k samples @44.1kHz
|
| kDefaultVideoBufferDurationInMs = 42 // Low 24fps to reduce stalls
|
| };
|
|
|
| + // Opus packets encode the duration and other parameters in the 5 most
|
| + // significant bits of the first byte. The index in this array corresponds
|
| + // to the duration of each frame of the packet in microseconds. See
|
| + // https://tools.ietf.org/html/rfc6716#page-14
|
| + static const uint16_t kOpusFrameDurationsMu[];
|
| +
|
| private:
|
| // Helper class that manages per-track state.
|
| class Track {
|
| @@ -87,7 +92,7 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
|
| // block is a keyframe.
|
| // |data| contains the bytes in the block.
|
| // |size| indicates the number of bytes in |data|.
|
| - bool IsKeyframe(const uint8* data, int size) const;
|
| + bool IsKeyframe(const uint8_t* data, int size) const;
|
|
|
| base::TimeDelta default_duration() const { return default_duration_; }
|
|
|
| @@ -143,6 +148,7 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
|
| const std::set<int64>& ignored_tracks,
|
| const std::string& audio_encryption_key_id,
|
| const std::string& video_encryption_key_id,
|
| + const AudioCodec audio_codec_,
|
| const LogCB& log_cb);
|
| ~WebMClusterParser() override;
|
|
|
| @@ -154,7 +160,7 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
|
| // Returns -1 if the parse fails.
|
| // Returns 0 if more data is needed.
|
| // Returns the number of bytes parsed on success.
|
| - int Parse(const uint8* buf, int size);
|
| + int Parse(const uint8_t* buf, int size);
|
|
|
| base::TimeDelta cluster_start_time() const { return cluster_start_time_; }
|
|
|
| @@ -194,14 +200,24 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
|
| WebMParserClient* OnListStart(int id) override;
|
| bool OnListEnd(int id) override;
|
| bool OnUInt(int id, int64 val) override;
|
| - bool OnBinary(int id, const uint8* data, int size) override;
|
| -
|
| - bool ParseBlock(bool is_simple_block, const uint8* buf, int size,
|
| - const uint8* additional, int additional_size, int duration,
|
| + bool OnBinary(int id, const uint8_t* data, int size) override;
|
| +
|
| + bool ParseBlock(bool is_simple_block,
|
| + const uint8_t* buf,
|
| + int size,
|
| + const uint8_t* additional,
|
| + int additional_size,
|
| + int duration,
|
| int64 discard_padding);
|
| - bool OnBlock(bool is_simple_block, int track_num, int timecode, int duration,
|
| - int flags, const uint8* data, int size,
|
| - const uint8* additional, int additional_size,
|
| + bool OnBlock(bool is_simple_block,
|
| + int track_num,
|
| + int timecode,
|
| + int duration,
|
| + int flags,
|
| + const uint8_t* data,
|
| + int size,
|
| + const uint8_t* additional,
|
| + int additional_size,
|
| int64 discard_padding);
|
|
|
| // Resets the Track objects associated with each text track.
|
| @@ -227,21 +243,40 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
|
| // if that track num is not a text track.
|
| Track* FindTextTrack(int track_num);
|
|
|
| + // Attempts to read the duration from the encoded audio data, returning as
|
| + // TimeDelta or kNoTimestamp() if duration cannot be retrieved. This obviously
|
| + // violates layering rules, but is useful for MSE to know duration in cases
|
| + // where it isn't explicitly given and cannot be calculated for Blocks at the
|
| + // 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.
|
| + base::TimeDelta TryGetEncodedAudioDuration(const uint8_t* data, int size);
|
| +
|
| + // Reads Opus packet header to determine packet duration. Duration returned
|
| + // as TimeDelta or kNoTimestamp() upon failure to read duration from packet.
|
| + base::TimeDelta ReadOpusDuration(const uint8_t* data, int size);
|
| +
|
| + // Tracks the number of MEDIA_LOGs made in process of reading encoded
|
| + // duration. Useful to prevent log spam.
|
| + int num_duration_errors_;
|
| +
|
| double timecode_multiplier_; // Multiplier used to convert timecodes into
|
| // microseconds.
|
| std::set<int64> ignored_tracks_;
|
| std::string audio_encryption_key_id_;
|
| std::string video_encryption_key_id_;
|
| + const AudioCodec audio_codec_;
|
|
|
| WebMListParser parser_;
|
|
|
| int64 last_block_timecode_;
|
| - scoped_ptr<uint8[]> block_data_;
|
| + scoped_ptr<uint8_t[]> block_data_;
|
| int block_data_size_;
|
| int64 block_duration_;
|
| int64 block_add_id_;
|
|
|
| - scoped_ptr<uint8[]> block_additional_data_;
|
| + scoped_ptr<uint8_t[]> block_additional_data_;
|
| // Must be 0 if |block_additional_data_| is null. Must be > 0 if
|
| // |block_additional_data_| is NOT null.
|
| int block_additional_data_size_;
|
|
|