diff --git a/media/BUILD.gn b/media/BUILD.gn index 2d62a1ec07b..2db427f9091 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -206,6 +206,7 @@ test("media_unittests") { # TODO(cobalt, b/379934658): add starboard_renderer_test. # TODO(cobalt, b/379936173): enable starboard_utils_test. # TODO(cobalt, b/379934533): enable bidirectional_fit_reuse_allocator_test. + # TODO(cobalt, b/380335617): enable progressive demuxer tests. # deps += ["//media/starboard:unit_tests"] } diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h index 27a87eb204e..c8d9057bfda 100644 --- a/media/base/decoder_buffer.h +++ b/media/base/decoder_buffer.h @@ -266,6 +266,7 @@ class MEDIA_EXPORT DecoderBuffer // If there's no data in this buffer, it represents end of stream. #if BUILDFLAG(USE_STARBOARD_MEDIA) bool end_of_stream() const { return !data_; } + void shrink_to(size_t size) { DCHECK_LE(size, size_); size_ = size; } #else // BUILDFLAG(USE_STARBOARD_MEDIA) bool end_of_stream() const { return !read_only_mapping_.IsValid() && !writable_mapping_.IsValid() && diff --git a/media/filters/demuxer_manager.cc b/media/filters/demuxer_manager.cc index 25db5bc3878..a3e90cc7463 100644 --- a/media/filters/demuxer_manager.cc +++ b/media/filters/demuxer_manager.cc @@ -25,6 +25,13 @@ #include "media/filters/manifest_demuxer.h" #endif // BUILDFLAG(ENABLE_HLS_DEMUXER) +#if BUILDFLAG(ENABLE_FFMPEG) +// ProgressDemuxer is enabled when is_cobalt=true and media_use_ffmpeg=false. +#elif BUILDFLAG(IS_COBALT) +#include "media/starboard/progressive/demuxer_extension_wrapper.h" +#include "media/starboard/progressive/progressive_demuxer.h" +#endif // BUILDFLAG(IS_COBALT) + namespace media { namespace { @@ -409,6 +416,8 @@ PipelineStatus DemuxerManager::CreateDemuxer( } else if (!load_media_source) { #if BUILDFLAG(ENABLE_FFMPEG) SetDemuxer(CreateFFmpegDemuxer()); +#elif BUILDFLAG(IS_COBALT) + SetDemuxer(CreateProgressiveDemuxer()); #else return DEMUXER_ERROR_COULD_NOT_OPEN; #endif @@ -576,6 +585,27 @@ std::unique_ptr DemuxerManager::CreateFFmpegDemuxer() { weak_factory_.GetWeakPtr())), media_log_.get(), IsLocalFile(loaded_url_)); } +#elif BUILDFLAG(IS_COBALT) +std::unique_ptr DemuxerManager::CreateDemuxerExtensionWrapper() { + DCHECK(data_source_); + return DemuxerExtensionWrapper::Create( + data_source_.get(), media_task_runner_); +} +std::unique_ptr DemuxerManager::CreateProgressiveDemuxer() { + DCHECK(data_source_); + std::unique_ptr progressive_demuxer_ = CreateDemuxerExtensionWrapper(); + if (progressive_demuxer_) { + LOG(INFO) << "Using DemuxerExtensionWrapper."; + return progressive_demuxer_; + } else { + // Either the demuxer Cobalt extension was not provided, or it failed to + // create a demuxer; fall back to the ProgressiveDemuxer. + LOG(INFO) << "Using ProgressiveDemuxer."; + return std::make_unique( + media_task_runner_, data_source_.get(), + media_log_.get()); + } +} #endif // BUILDFLAG(ENABLE_FFMPEG) #if BUILDFLAG(ENABLE_HLS_DEMUXER) diff --git a/media/filters/demuxer_manager.h b/media/filters/demuxer_manager.h index 435bce8989b..a6dcf723ba7 100644 --- a/media/filters/demuxer_manager.h +++ b/media/filters/demuxer_manager.h @@ -173,6 +173,9 @@ class MEDIA_EXPORT DemuxerManager { #if BUILDFLAG(ENABLE_FFMPEG) std::unique_ptr CreateFFmpegDemuxer(); +#elif BUILDFLAG(IS_COBALT) + std::unique_ptr CreateDemuxerExtensionWrapper(); + std::unique_ptr CreateProgressiveDemuxer(); #endif // BUILDFLAG(ENABLE_FFMPEG) #if BUILDFLAG(ENABLE_HLS_DEMUXER) diff --git a/media/starboard/BUILD.gn b/media/starboard/BUILD.gn index f1d176588fd..53a5d8d297d 100644 --- a/media/starboard/BUILD.gn +++ b/media/starboard/BUILD.gn @@ -14,6 +14,7 @@ assert(is_cobalt, "This file builds for cobalt builds, not Chromium builds") +import("//media/media_options.gni") import("//starboard/build/buildflags.gni") source_set("starboard") { @@ -55,6 +56,28 @@ source_set("starboard") { ] sources = [] + if (!media_use_ffmpeg) { + sources += [ + "progressive/avc_access_unit.cc", + "progressive/avc_access_unit.h", + "progressive/avc_parser.cc", + "progressive/avc_parser.h", + "progressive/data_source_reader.cc", + "progressive/data_source_reader.h", + "progressive/demuxer_extension_wrapper.cc", + "progressive/demuxer_extension_wrapper.h", + "progressive/mp4_map.cc", + "progressive/mp4_map.h", + "progressive/mp4_parser.cc", + "progressive/mp4_parser.h", + "progressive/progressive_demuxer.cc", + "progressive/progressive_demuxer.h", + "progressive/progressive_parser.cc", + "progressive/progressive_parser.h", + "progressive/rbsp_stream.cc", + "progressive/rbsp_stream.h", + ] + } if (use_starboard_media) { sources += [ @@ -91,12 +114,24 @@ source_set("starboard") { "//starboard/common", ] + if (!media_use_ffmpeg) { + deps += [ "//third_party/abseil-cpp:absl" ] + } + configs += [ "//media:subcomponent_config" ] } source_set("unit_tests") { testonly = true sources = [] + if (!media_use_ffmpeg) { + sources += [ + "progressive/demuxer_extension_wrapper_test.cc", + "progressive/mock_data_source_reader.h", + "progressive/mp4_map_unittest.cc", + "progressive/rbsp_stream_unittest.cc", + ] + } if (use_starboard_media) { sources += [ "bidirectional_fit_reuse_allocator_test.cc", diff --git a/media/starboard/progressive/avc_access_unit.cc b/media/starboard/progressive/avc_access_unit.cc index 80289eed4cc..9cab0b52d9e 100644 --- a/media/starboard/progressive/avc_access_unit.cc +++ b/media/starboard/progressive/avc_access_unit.cc @@ -12,24 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/avc_access_unit.h" +#include "media/starboard/progressive/avc_access_unit.h" #include -#include "cobalt/media/base/endian_util.h" -#include "cobalt/media/progressive/progressive_parser.h" #include "media/base/decoder_buffer.h" #include "media/base/timestamp_constants.h" +#include "media/starboard/progressive/endian_util.h" +#include "media/starboard/progressive/progressive_parser.h" -namespace cobalt { namespace media { namespace { -using ::media::DecoderBuffer; -using ::media::DemuxerStream; - -bool ReadBytes(uint64 offset, size_t size, uint8* buffer, +bool ReadBytes(uint64_t offset, + size_t size, + uint8_t* buffer, DataSourceReader* reader) { if (reader->BlockingRead(offset, size, buffer) != size) { LOG(ERROR) << "unable to download AU"; @@ -43,9 +41,7 @@ bool ReadBytes(uint64 offset, size_t size, uint8* buffer, class EndOfStreamAU : public AvcAccessUnit { public: EndOfStreamAU(Type type, TimeDelta timestamp) - : type_(type), - timestamp_(timestamp), - duration_(::media::kInfiniteDuration) {} + : type_(type), timestamp_(timestamp), duration_(kInfiniteDuration) {} private: bool IsEndOfStream() const override { return true; } @@ -79,13 +75,18 @@ class EndOfStreamAU : public AvcAccessUnit { class AudioAU : public AvcAccessUnit { public: - AudioAU(uint64 offset, size_t size, size_t prepend_size, bool is_keyframe, - TimeDelta timestamp, TimeDelta duration, ProgressiveParser* parser); + AudioAU(uint64_t offset, + size_t size, + size_t prepend_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, + ProgressiveParser* parser); private: bool IsEndOfStream() const override { return false; } bool IsValid() const override { - return offset_ != 0 && size_ != 0 && timestamp_ != ::media::kNoTimestamp; + return offset_ != 0 && size_ != 0 && timestamp_ != kNoTimestamp; } bool Read(DataSourceReader* reader, DecoderBuffer* buffer) override; Type GetType() const override { return DemuxerStream::AUDIO; } @@ -98,7 +99,7 @@ class AudioAU : public AvcAccessUnit { void SetDuration(TimeDelta duration) override { duration_ = duration; } void SetTimestamp(TimeDelta timestamp) override { timestamp_ = timestamp; } - uint64 offset_; + uint64_t offset_; size_t size_; size_t prepend_size_; bool is_keyframe_; @@ -107,8 +108,12 @@ class AudioAU : public AvcAccessUnit { ProgressiveParser* parser_; }; -AudioAU::AudioAU(uint64 offset, size_t size, size_t prepend_size, - bool is_keyframe, TimeDelta timestamp, TimeDelta duration, +AudioAU::AudioAU(uint64_t offset, + size_t size, + size_t prepend_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, ProgressiveParser* parser) : offset_(offset), size_(size), @@ -121,8 +126,9 @@ AudioAU::AudioAU(uint64 offset, size_t size, size_t prepend_size, bool AudioAU::Read(DataSourceReader* reader, DecoderBuffer* buffer) { DCHECK_LE(size_ + prepend_size_, buffer->data_size()); if (!ReadBytes(offset_, size_, buffer->writable_data() + prepend_size_, - reader)) + reader)) { return false; + } if (!parser_->Prepend(this, buffer)) { LOG(ERROR) << "prepend fail"; @@ -136,14 +142,19 @@ bool AudioAU::Read(DataSourceReader* reader, DecoderBuffer* buffer) { class VideoAU : public AvcAccessUnit { public: - VideoAU(uint64 offset, size_t size, size_t prepend_size, - uint8 length_of_nalu_size, bool is_keyframe, TimeDelta timestamp, - TimeDelta duration, ProgressiveParser* parser); + VideoAU(uint64_t offset, + size_t size, + size_t prepend_size, + uint8_t length_of_nalu_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, + ProgressiveParser* parser); private: bool IsEndOfStream() const override { return false; } bool IsValid() const override { - return offset_ != 0 && size_ != 0 && timestamp_ != ::media::kNoTimestamp; + return offset_ != 0 && size_ != 0 && timestamp_ != kNoTimestamp; } bool Read(DataSourceReader* reader, DecoderBuffer* buffer) override; Type GetType() const override { return DemuxerStream::VIDEO; } @@ -160,19 +171,23 @@ class VideoAU : public AvcAccessUnit { void SetDuration(TimeDelta duration) override { duration_ = duration; } void SetTimestamp(TimeDelta timestamp) override { timestamp_ = timestamp; } - uint64 offset_; + uint64_t offset_; size_t size_; size_t prepend_size_; - uint8 length_of_nalu_size_; + uint8_t length_of_nalu_size_; bool is_keyframe_; TimeDelta timestamp_; TimeDelta duration_; ProgressiveParser* parser_; }; -VideoAU::VideoAU(uint64 offset, size_t size, size_t prepend_size, - uint8 length_of_nalu_size, bool is_keyframe, - TimeDelta timestamp, TimeDelta duration, +VideoAU::VideoAU(uint64_t offset, + size_t size, + size_t prepend_size, + uint8_t length_of_nalu_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, ProgressiveParser* parser) : offset_(offset), size_(size), @@ -188,7 +203,7 @@ VideoAU::VideoAU(uint64 offset, size_t size, size_t prepend_size, bool VideoAU::Read(DataSourceReader* reader, DecoderBuffer* buffer) { size_t au_left = size_; // bytes left in the AU - uint64 au_offset = offset_; // offset to read in the reader + uint64_t au_offset = offset_; // offset to read in the reader size_t buf_left = buffer->data_size(); // bytes left in the buffer // The current write position in the buffer int64_t decoder_buffer_offset = prepend_size_; @@ -197,8 +212,8 @@ bool VideoAU::Read(DataSourceReader* reader, DecoderBuffer* buffer) { // transform it into [start code][data][start code][data].... // The length of size is indicated by length_of_nalu_size_ while (au_left >= length_of_nalu_size_ && buf_left >= kAnnexBStartCodeSize) { - uint8 size_buf[4]; - uint32 nal_size; + uint8_t size_buf[4]; + uint32_t nal_size; // Store [start code] memcpy(buffer->writable_data() + decoder_buffer_offset, kAnnexBStartCode, @@ -207,8 +222,9 @@ bool VideoAU::Read(DataSourceReader* reader, DecoderBuffer* buffer) { buf_left -= kAnnexBStartCodeSize; // Read [size] - if (!ReadBytes(au_offset, length_of_nalu_size_, size_buf, reader)) + if (!ReadBytes(au_offset, length_of_nalu_size_, size_buf, reader)) { return false; + } au_offset += length_of_nalu_size_; au_left -= length_of_nalu_size_; @@ -222,7 +238,9 @@ bool VideoAU::Read(DataSourceReader* reader, DecoderBuffer* buffer) { nal_size = endian_util::load_uint32_big_endian(size_buf); } - if (au_left < nal_size || buf_left < nal_size) break; + if (au_left < nal_size || buf_left < nal_size) { + break; + } // Read the [data] from reader into buf if (!ReadBytes(au_offset, nal_size, @@ -263,26 +281,36 @@ AvcAccessUnit::~AvcAccessUnit() {} // static scoped_refptr AvcAccessUnit::CreateEndOfStreamAU( - DemuxerStream::Type type, TimeDelta timestamp) { + DemuxerStream::Type type, + TimeDelta timestamp) { return new EndOfStreamAU(type, timestamp); } // static scoped_refptr AvcAccessUnit::CreateAudioAU( - uint64 offset, size_t size, size_t prepend_size, bool is_keyframe, - TimeDelta timestamp, TimeDelta duration, ProgressiveParser* parser) { + uint64_t offset, + size_t size, + size_t prepend_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, + ProgressiveParser* parser) { return new AudioAU(offset, size, prepend_size, is_keyframe, timestamp, duration, parser); } // static scoped_refptr AvcAccessUnit::CreateVideoAU( - uint64 offset, size_t size, size_t prepend_size, uint8 length_of_nalu_size, - bool is_keyframe, TimeDelta timestamp, TimeDelta duration, + uint64_t offset, + size_t size, + size_t prepend_size, + uint8_t length_of_nalu_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, ProgressiveParser* parser) { return new VideoAU(offset, size, prepend_size, length_of_nalu_size, is_keyframe, timestamp, duration, parser); } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/avc_access_unit.h b/media/starboard/progressive/avc_access_unit.h index fd4952748c9..086ddbb0fea 100644 --- a/media/starboard/progressive/avc_access_unit.h +++ b/media/starboard/progressive/avc_access_unit.h @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_AVC_ACCESS_UNIT_H_ -#define COBALT_MEDIA_PROGRESSIVE_AVC_ACCESS_UNIT_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_AVC_ACCESS_UNIT_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_AVC_ACCESS_UNIT_H_ #include "base/memory/ref_counted.h" -#include "cobalt/media/progressive/data_source_reader.h" #include "media/base/demuxer_stream.h" +#include "media/starboard/progressive/data_source_reader.h" -namespace cobalt { namespace media { class ProgressiveParser; @@ -33,24 +32,31 @@ static const uint8_t kAnnexBStartCode[] = {0, 0, 0, 1}; class AvcAccessUnit : public base::RefCountedThreadSafe { public: typedef base::TimeDelta TimeDelta; - typedef ::media::DemuxerStream::Type Type; + typedef DemuxerStream::Type Type; static scoped_refptr CreateEndOfStreamAU(Type type, TimeDelta timestamp); - static scoped_refptr CreateAudioAU( - uint64 offset, size_t size, size_t prepend_size, bool is_keyframe, - TimeDelta timestamp, TimeDelta duration, ProgressiveParser* parser); - static scoped_refptr CreateVideoAU( - uint64 offset, size_t size, size_t prepend_size, - uint8 length_of_nalu_size, bool is_keyframe, TimeDelta timestamp, - TimeDelta duration, ProgressiveParser* parser); + static scoped_refptr CreateAudioAU(uint64_t offset, + size_t size, + size_t prepend_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, + ProgressiveParser* parser); + static scoped_refptr CreateVideoAU(uint64_t offset, + size_t size, + size_t prepend_size, + uint8_t length_of_nalu_size, + bool is_keyframe, + TimeDelta timestamp, + TimeDelta duration, + ProgressiveParser* parser); virtual bool IsEndOfStream() const = 0; virtual bool IsValid() const = 0; // Read an AU from reader to buffer and also do all the necessary operations // like prepending head to make it ready to decode. - virtual bool Read(DataSourceReader* reader, - ::media::DecoderBuffer* buffer) = 0; + virtual bool Read(DataSourceReader* reader, DecoderBuffer* buffer) = 0; virtual Type GetType() const = 0; virtual bool IsKeyframe() const = 0; virtual bool AddPrepend() const = 0; @@ -71,6 +77,5 @@ class AvcAccessUnit : public base::RefCountedThreadSafe { }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_AVC_ACCESS_UNIT_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_AVC_ACCESS_UNIT_H_ diff --git a/media/starboard/progressive/avc_parser.cc b/media/starboard/progressive/avc_parser.cc index 4565ad4e6e5..d121ee39950 100644 --- a/media/starboard/progressive/avc_parser.cc +++ b/media/starboard/progressive/avc_parser.cc @@ -12,16 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/avc_parser.h" +#include "media/starboard/progressive/avc_parser.h" #include #include #include "base/logging.h" #include "base/strings/stringprintf.h" -#include "cobalt/media/base/endian_util.h" -#include "cobalt/media/progressive/avc_access_unit.h" -#include "cobalt/media/progressive/rbsp_stream.h" #include "media/base/audio_codecs.h" #include "media/base/decoder_buffer.h" #include "media/base/encryption_scheme.h" @@ -31,14 +28,16 @@ #include "media/base/video_transformation.h" #include "media/base/video_types.h" #include "media/formats/mp4/aac.h" +#include "media/starboard/progressive/avc_access_unit.h" +#include "media/starboard/progressive/endian_util.h" +#include "media/starboard/progressive/rbsp_stream.h" -namespace cobalt { namespace media { // what's the smallest meaningful AVC config we can parse? static const int kAVCConfigMinSize = 8; // lower five bits of first byte in SPS should be 7 -static const uint8 kSPSNALType = 7; +static const uint8_t kSPSNALType = 7; AVCParser::AVCParser(scoped_refptr reader, MediaLog* media_log) @@ -76,18 +75,18 @@ bool AVCParser::Prepend(scoped_refptr au, return false; } // audio, need to copy ADTS header and then add buffer size - uint32 buffer_size = au->GetSize() + audio_prepend_.size(); + uint32_t buffer_size = au->GetSize() + audio_prepend_.size(); // we can't express an AU size larger than 13 bits, something's bad here. if (buffer_size & 0xffffe000) { return false; } std::vector audio_prepend(audio_prepend_); // OR size into buffer, byte 3 gets 2 MSb of 13-bit size - audio_prepend[3] |= (uint8)((buffer_size & 0x00001800) >> 11); + audio_prepend[3] |= (uint8_t)((buffer_size & 0x00001800) >> 11); // byte 4 gets bits 10-3 of size - audio_prepend[4] = (uint8)((buffer_size & 0x000007f8) >> 3); + audio_prepend[4] = (uint8_t)((buffer_size & 0x000007f8) >> 3); // byte 5 gets bits 2-0 of size - audio_prepend[5] |= (uint8)((buffer_size & 0x00000007) << 5); + audio_prepend[5] |= (uint8_t)((buffer_size & 0x00000007) << 5); memcpy(buffer->writable_data(), audio_prepend.data(), audio_prepend.size()); } else { NOTREACHED() << "unsupported demuxer stream type."; @@ -97,13 +96,14 @@ bool AVCParser::Prepend(scoped_refptr au, return true; } -bool AVCParser::DownloadAndParseAVCConfigRecord(uint64 offset, uint32 size) { +bool AVCParser::DownloadAndParseAVCConfigRecord(uint64_t offset, + uint32_t size) { if (size == 0) { return false; } - std::vector record_buffer(size); + std::vector record_buffer(size); int bytes_read = reader_->BlockingRead(offset, size, &record_buffer[0]); - DCHECK_LE(size, static_cast(std::numeric_limits::max())); + DCHECK_LE(size, static_cast(std::numeric_limits::max())); if (bytes_read < static_cast(size)) { return false; } @@ -112,7 +112,8 @@ bool AVCParser::DownloadAndParseAVCConfigRecord(uint64 offset, uint32 size) { } // static -bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, +bool AVCParser::ParseSPS(const uint8_t* sps, + size_t sps_size, SPSRecord* record_out) { DCHECK(sps) << "no sps provided"; DCHECK(record_out) << "no output structure provided"; @@ -123,7 +124,7 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, } // convert SPS NALU to RBSP stream RBSPStream sps_rbsp(sps + 1, sps_size - 1); - uint8 profile_idc = 0; + uint8_t profile_idc = 0; if (!sps_rbsp.ReadByte(&profile_idc)) { LOG(ERROR) << "failure reading profile_idc from sps RBSP"; return false; @@ -132,15 +133,15 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, sps_rbsp.SkipBytes(2); // ReadUEV/ReadSEV require a value to be passed by reference but // there are many times in which we ignore this value. - uint32 disposable_uev = 0; - int32 disposable_sev = 0; + uint32_t disposable_uev = 0; + int32_t disposable_sev = 0; // seq_parameter_set_id sps_rbsp.ReadUEV(&disposable_uev); // skip profile-specific encoding information if there if (profile_idc == 100 || profile_idc == 103 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118) { - uint32 chroma_format_idc = 0; + uint32_t chroma_format_idc = 0; if (!sps_rbsp.ReadUEV(&chroma_format_idc)) { LOG(WARNING) << "failure reading chroma_format_idc from sps RBSP"; return false; @@ -156,7 +157,7 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, // qpprime_y_zero_transform_bypass_flag sps_rbsp.SkipBits(1); // seq_scaling_matrix_present_flag - uint8 seq_scaling_matrix_present_flag = 0; + uint8_t seq_scaling_matrix_present_flag = 0; if (!sps_rbsp.ReadBit(&seq_scaling_matrix_present_flag)) { LOG(ERROR) << "failure reading seq_scaling_matrix_present_flag from sps RBSP"; @@ -170,7 +171,7 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, // log2_max_frame_num_minus4 sps_rbsp.ReadUEV(&disposable_uev); // pic_order_cnt_type - uint32 pic_order_cnt_type = 0; + uint32_t pic_order_cnt_type = 0; if (!sps_rbsp.ReadUEV(&pic_order_cnt_type)) { LOG(ERROR) << "failure reading pic_order_cnt_type from sps RBSP"; return false; @@ -186,18 +187,18 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, // offset_for_top_to_bottom_field sps_rbsp.ReadSEV(&disposable_sev); // num_ref_frames_in_pic_order_cnt_cycle - uint32 num_ref_frames_in_pic_order_cnt_cycle = 0; + uint32_t num_ref_frames_in_pic_order_cnt_cycle = 0; if (!sps_rbsp.ReadUEV(&num_ref_frames_in_pic_order_cnt_cycle)) { LOG(ERROR) << "failure reading num_ref_frames_in_pic_order_cnt_cycle from sps"; return false; } - for (uint32 i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { + for (uint32_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { sps_rbsp.ReadSEV(&disposable_sev); } } // number of reference frames used to decode - uint32 num_ref_frames = 0; + uint32_t num_ref_frames = 0; if (!sps_rbsp.ReadUEV(&num_ref_frames)) { LOG(ERROR) << "failure reading number of ref frames from sps RBSP"; return false; @@ -205,34 +206,34 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, // gaps_in_frame_num_value_allowed_flag sps_rbsp.SkipBits(1); // width is calculated from pic_width_in_mbs_minus1 - uint32 pic_width_in_mbs_minus1 = 0; + uint32_t pic_width_in_mbs_minus1 = 0; if (!sps_rbsp.ReadUEV(&pic_width_in_mbs_minus1)) { LOG(WARNING) << "failure reading image width from sps RBSP"; return false; } // 16 pxs per macroblock - uint32 width = (pic_width_in_mbs_minus1 + 1) * 16; + uint32_t width = (pic_width_in_mbs_minus1 + 1) * 16; // pic_height_in_map_units_minus1 - uint32 pic_height_in_map_units_minus1 = 0; + uint32_t pic_height_in_map_units_minus1 = 0; if (!sps_rbsp.ReadUEV(&pic_height_in_map_units_minus1)) { LOG(ERROR) << "failure reading pic_height_in_map_uints_minus1 from sps RBSP"; return false; } - uint8 frame_mbs_only_flag = 0; + uint8_t frame_mbs_only_flag = 0; if (!sps_rbsp.ReadBit(&frame_mbs_only_flag)) { LOG(ERROR) << "failure reading frame_mbs_only_flag from sps RBSP"; return false; } - uint32 height = (2 - static_cast(frame_mbs_only_flag)) * - (pic_height_in_map_units_minus1 + 1) * 16; + uint32_t height = (2 - static_cast(frame_mbs_only_flag)) * + (pic_height_in_map_units_minus1 + 1) * 16; if (!frame_mbs_only_flag) { sps_rbsp.SkipBits(1); } // direct_8x8_inference_flag sps_rbsp.SkipBits(1); // frame cropping flag - uint8 frame_cropping_flag = 0; + uint8_t frame_cropping_flag = 0; if (!sps_rbsp.ReadBit(&frame_cropping_flag)) { LOG(ERROR) << "failure reading frame_cropping_flag from sps RBSP"; return false; @@ -258,10 +259,10 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, // | v | | // +------------------------------------------+ v // - uint32 crop_left = 0; - uint32 crop_right = 0; - uint32 crop_top = 0; - uint32 crop_bottom = 0; + uint32_t crop_left = 0; + uint32_t crop_right = 0; + uint32_t crop_top = 0; + uint32_t crop_bottom = 0; // cropping values are stored divided by two if (frame_cropping_flag) { if (!sps_rbsp.ReadUEV(&crop_left)) { @@ -297,7 +298,7 @@ bool AVCParser::ParseSPS(const uint8* sps, size_t sps_size, return true; } -bool AVCParser::ParseAVCConfigRecord(uint8* buffer, uint32 size) { +bool AVCParser::ParseAVCConfigRecord(uint8_t* buffer, uint32_t size) { if (size < kAVCConfigMinSize) { LOG(ERROR) << base::StringPrintf("AVC config record bad size: %d", size); return false; @@ -313,7 +314,7 @@ bool AVCParser::ParseAVCConfigRecord(uint8* buffer, uint32 size) { // (Sequence Parameter Set) (Network Abstraction Layer Units) // from which we can extract width, height, and cropping info. // That means we need at least 1 SPS NALU in this stream for extraction. - uint8 number_of_sps_nalus = buffer[5] & 0x1f; + uint8_t number_of_sps_nalus = buffer[5] & 0x1f; if (number_of_sps_nalus == 0) { LOG(WARNING) << "got AVCConfigRecord without any SPS NALUs!"; return false; @@ -325,9 +326,9 @@ bool AVCParser::ParseAVCConfigRecord(uint8* buffer, uint32 size) { int record_offset = 6; size_t usable_sps_size = 0; int usable_sps_offset = 0; - for (uint8 i = 0; i < number_of_sps_nalus; i++) { + for (uint8_t i = 0; i < number_of_sps_nalus; i++) { // make sure we haven't run out of record for the 2-byte size record - DCHECK_LE(size, static_cast(std::numeric_limits::max())); + DCHECK_LE(size, static_cast(std::numeric_limits::max())); if (record_offset + 2 > static_cast(size)) { LOG(WARNING) << "ran out of AVCConfig record while parsing SPS size."; return false; @@ -365,13 +366,14 @@ bool AVCParser::ParseAVCConfigRecord(uint8* buffer, uint32 size) { size_t usable_pps_size = 0; size_t usable_pps_offset = 0; bool have_valid_pps = false; - DCHECK_LE(size, static_cast(std::numeric_limits::max())); + DCHECK_LE(size, static_cast(std::numeric_limits::max())); if (record_offset + 1 < static_cast(size)) { - uint8 number_of_pps_nalus = buffer[record_offset]; + uint8_t number_of_pps_nalus = buffer[record_offset]; record_offset++; - for (uint8 i = 0; i < number_of_pps_nalus; i++) { + for (uint8_t i = 0; i < number_of_pps_nalus; i++) { // make sure we don't run out of room for 2-byte size record - DCHECK_LE(size, static_cast(std::numeric_limits::max())); + DCHECK_LE(size, + static_cast(std::numeric_limits::max())); if (record_offset + 2 >= static_cast(size)) { LOG(WARNING) << "ran out of AVCConfig record while parsing PPS size."; return false; @@ -401,21 +403,23 @@ bool AVCParser::ParseAVCConfigRecord(uint8* buffer, uint32 size) { return false; } // we can now initialize our video decoder config - video_config_.Initialize( - ::media::VideoCodec::kH264, - // profile is ignored currently - ::media::VideoCodecProfile::H264PROFILE_MAIN, - ::media::VideoDecoderConfig::AlphaMode::kIsOpaque, - ::media::VideoColorSpace::REC709(), ::media::VideoTransformation(), - sps_record.coded_size, sps_record.visible_rect, sps_record.natural_size, - ::media::EmptyExtraData(), ::media::EncryptionScheme::kUnencrypted); + video_config_.Initialize(VideoCodec::kH264, + // profile is ignored currently + VideoCodecProfile::H264PROFILE_MAIN, + VideoDecoderConfig::AlphaMode::kIsOpaque, + VideoColorSpace::REC709(), VideoTransformation(), + sps_record.coded_size, sps_record.visible_rect, + sps_record.natural_size, EmptyExtraData(), + EncryptionScheme::kUnencrypted); return BuildAnnexBPrepend(buffer + usable_sps_offset, usable_sps_size, buffer + usable_pps_offset, usable_pps_size); } -bool AVCParser::BuildAnnexBPrepend(uint8* sps, uint32 sps_size, uint8* pps, - uint32 pps_size) { +bool AVCParser::BuildAnnexBPrepend(uint8_t* sps, + uint32_t sps_size, + uint8_t* pps, + uint32_t pps_size) { // We will need to attach the sps and pps (if provided) to each keyframe // video packet, with the AnnexB start code in front of each. Start with // sps size and start code @@ -450,9 +454,9 @@ bool AVCParser::BuildAnnexBPrepend(uint8* sps, uint32 sps_size, uint8* pps, return true; } -void AVCParser::ParseAudioSpecificConfig(uint8 b0, uint8 b1) { - ::media::mp4::AAC aac; - std::vector aac_config(2); +void AVCParser::ParseAudioSpecificConfig(uint8_t b0, uint8_t b1) { + mp4::AAC aac; + std::vector aac_config(2); aac_config[0] = b0; aac_config[1] = b1; @@ -473,10 +477,9 @@ void AVCParser::ParseAudioSpecificConfig(uint8 b0, uint8 b1) { const bool kSbrInMimetype = false; audio_config_.Initialize( - ::media::AudioCodec::kAAC, ::media::kSampleFormatS16, - aac.GetChannelLayout(kSbrInMimetype), + AudioCodec::kAAC, kSampleFormatS16, aac.GetChannelLayout(kSbrInMimetype), aac.GetOutputSamplesPerSecond(kSbrInMimetype), aac.codec_specific_data(), - ::media::EncryptionScheme::kUnencrypted, base::TimeDelta(), 0); + EncryptionScheme::kUnencrypted, base::TimeDelta(), 0); audio_config_.set_aac_extra_data(aac.codec_specific_data()); } @@ -485,7 +488,9 @@ size_t AVCParser::CalculatePrependSize(DemuxerStream::Type type, size_t prepend_size = 0; if (type == DemuxerStream::VIDEO) { bool needs_prepend = is_keyframe; - if (needs_prepend) prepend_size = video_prepend_size_; + if (needs_prepend) { + prepend_size = video_prepend_size_; + } } else if (type == DemuxerStream::AUDIO) { prepend_size = audio_prepend_.size(); } else { @@ -495,4 +500,3 @@ size_t AVCParser::CalculatePrependSize(DemuxerStream::Type type, } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/avc_parser.h b/media/starboard/progressive/avc_parser.h index 9bc702cf654..a23cfc41b68 100644 --- a/media/starboard/progressive/avc_parser.h +++ b/media/starboard/progressive/avc_parser.h @@ -12,17 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_AVC_PARSER_H_ -#define COBALT_MEDIA_PROGRESSIVE_AVC_PARSER_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_AVC_PARSER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_AVC_PARSER_H_ #include -#include "cobalt/media/progressive/progressive_parser.h" #include "media/base/media_log.h" +#include "media/starboard/progressive/progressive_parser.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -namespace cobalt { namespace media { // Typical size of an annexB prepend will be around 60 bytes. We make more room @@ -35,10 +34,6 @@ static const int kAnnexBPrependMaxSize = 1024; // ProgressiveParser while leaving the rest for its children. class AVCParser : public ProgressiveParser { public: - typedef ::media::DecoderBuffer DecoderBuffer; - typedef ::media::DemuxerStream DemuxerStream; - typedef ::media::MediaLog MediaLog; - explicit AVCParser(scoped_refptr reader, MediaLog* media_log); virtual ~AVCParser(); @@ -47,9 +42,10 @@ class AVCParser : public ProgressiveParser { gfx::Size coded_size; gfx::Rect visible_rect; gfx::Size natural_size; - uint32 num_ref_frames; + uint32_t num_ref_frames; }; - static bool ParseSPS(const uint8* sps, size_t sps_size, + static bool ParseSPS(const uint8_t* sps, + size_t sps_size, SPSRecord* record_out); // GetNextAU we must pass on to FLV or MP4 children. @@ -59,28 +55,29 @@ class AVCParser : public ProgressiveParser { scoped_refptr buffer) override; protected: - virtual bool DownloadAndParseAVCConfigRecord(uint64 offset, uint32 size); - virtual bool ParseAVCConfigRecord(uint8* buffer, uint32 size); + virtual bool DownloadAndParseAVCConfigRecord(uint64_t offset, uint32_t size); + virtual bool ParseAVCConfigRecord(uint8_t* buffer, uint32_t size); // pps_size can be 0. Returns false on unable to construct. - virtual bool BuildAnnexBPrepend(uint8* sps, uint32 sps_size, uint8* pps, - uint32 pps_size); - virtual void ParseAudioSpecificConfig(uint8 b0, uint8 b1); + virtual bool BuildAnnexBPrepend(uint8_t* sps, + uint32_t sps_size, + uint8_t* pps, + uint32_t pps_size); + virtual void ParseAudioSpecificConfig(uint8_t b0, uint8_t b1); virtual size_t CalculatePrependSize(DemuxerStream::Type type, bool is_keyframe); MediaLog* media_log_; - uint8 nal_header_size_; + uint8_t nal_header_size_; // audio frames have a fixed-size small prepend that we attach to every // audio buffer created by DownloadBuffer() - std::vector audio_prepend_; + std::vector audio_prepend_; // video frames have a variable-size prepend that we limit to a reasonable // upper bound. We only need to attach it to keyframes, however, the rest // of the frames need only an AnnexB start code. - uint8 video_prepend_[kAnnexBPrependMaxSize]; - uint32 video_prepend_size_; + uint8_t video_prepend_[kAnnexBPrependMaxSize]; + uint32_t video_prepend_size_; }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_AVC_PARSER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_AVC_PARSER_H_ diff --git a/media/starboard/progressive/data_source_reader.cc b/media/starboard/progressive/data_source_reader.cc index fd4ff712da9..9ea2d028dc3 100644 --- a/media/starboard/progressive/data_source_reader.cc +++ b/media/starboard/progressive/data_source_reader.cc @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/data_source_reader.h" +#include "media/starboard/progressive/data_source_reader.h" #include "starboard/types.h" -namespace cobalt { namespace media { const int DataSourceReader::kReadError = DataSource::kReadError; @@ -37,7 +36,7 @@ void DataSourceReader::SetDataSource(DataSource* data_source) { } // currently only single-threaded reads supported -int DataSourceReader::BlockingRead(int64 position, int size, uint8* data) { +int DataSourceReader::BlockingRead(int64_t position, int size, uint8_t* data) { // read failures are unrecoverable, all subsequent reads will also fail if (read_has_failed_) { return kReadError; @@ -57,7 +56,7 @@ int DataSourceReader::BlockingRead(int64 position, int size, uint8* data) { } data_source_->Read( position, size, data, - base::Bind(&DataSourceReader::BlockingReadCompleted, this)); + base::BindRepeating(&DataSourceReader::BlockingReadCompleted, this)); } // wait for callback on read completion @@ -77,7 +76,9 @@ int DataSourceReader::BlockingRead(int64 position, int size, uint8* data) { } // Avoid entering an endless loop here. - if (last_bytes_read_ == 0) break; + if (last_bytes_read_ == 0) { + break; + } total_bytes_read += last_bytes_read_; position += last_bytes_read_; @@ -106,7 +107,7 @@ void DataSourceReader::BlockingReadCompleted(int bytes_read) { blocking_read_event_.Signal(); } -int64 DataSourceReader::FileSize() { +int64_t DataSourceReader::FileSize() { if (file_size_ == -1) { base::AutoLock auto_lock(lock_); if (data_source_ && !data_source_->GetSize(&file_size_)) { @@ -117,4 +118,3 @@ int64 DataSourceReader::FileSize() { } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/data_source_reader.h b/media/starboard/progressive/data_source_reader.h index 70e942bf44f..0ad73a03703 100644 --- a/media/starboard/progressive/data_source_reader.h +++ b/media/starboard/progressive/data_source_reader.h @@ -12,17 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_DATA_SOURCE_READER_H_ -#define COBALT_MEDIA_PROGRESSIVE_DATA_SOURCE_READER_H_ -#include "base/bind.h" -#include "base/callback.h" +#ifndef MEDIA_STARBOARD_PROGRESSIVE_DATA_SOURCE_READER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_DATA_SOURCE_READER_H_ + +#include "base/functional/bind.h" +#include "base/functional/callback.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/task/sequenced_task_runner.h" -#include "cobalt/media/base/data_source.h" +#include "media/base/data_source.h" -namespace cobalt { namespace media { // Allows sharing of a DataSource object between multiple objects on a single @@ -41,11 +41,11 @@ class DataSourceReader : public base::RefCountedThreadSafe { // Block the calling thread's task runner until read is complete. // returns number of bytes read or kReadError on error. // Currently only single-threaded support. - virtual int BlockingRead(int64 position, int size, uint8* data); + virtual int BlockingRead(int64_t position, int size, uint8_t* data); // returns size of file in bytes, or -1 if file size not known. If error will // retry getting file size on subsequent calls to FileSize(). - virtual int64 FileSize(); + virtual int64_t FileSize(); // abort any pending read, then stop the data source virtual void Stop(); @@ -59,12 +59,11 @@ class DataSourceReader : public base::RefCountedThreadSafe { base::Lock lock_; DataSource* data_source_; base::WaitableEvent blocking_read_event_; - int64 file_size_; + int64_t file_size_; bool read_has_failed_; int last_bytes_read_; // protected implicitly by blocking_read_event_ }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_DATA_SOURCE_READER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_DATA_SOURCE_READER_H_ diff --git a/media/starboard/progressive/demuxer_extension_wrapper.cc b/media/starboard/progressive/demuxer_extension_wrapper.cc index 1658a74c603..6833f610798 100644 --- a/media/starboard/progressive/demuxer_extension_wrapper.cc +++ b/media/starboard/progressive/demuxer_extension_wrapper.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/demuxer_extension_wrapper.h" +#include "media/starboard/progressive/demuxer_extension_wrapper.h" #include #include @@ -24,41 +24,18 @@ #include "media/base/audio_codecs.h" #include "media/base/encryption_scheme.h" #include "media/base/sample_format.h" -#include "media/base/starboard_utils.h" #include "media/base/video_types.h" #include "media/filters/h264_to_annex_b_bitstream_converter.h" #include "media/formats/mp4/box_definitions.h" +#include "media/starboard/starboard_utils.h" #include "starboard/extension/demuxer.h" #include "starboard/system.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -namespace cobalt { namespace media { -using ::media::AudioCodec; -using ::media::AudioDecoderConfig; -using ::media::ChannelLayout; -using ::media::DecoderBuffer; -using ::media::DemuxerHost; -using ::media::DemuxerStream; -using ::media::EncryptionScheme; -using ::media::H264ToAnnexBBitstreamConverter; -using ::media::MediaTrack; -using ::media::PipelineStatus; -using ::media::PipelineStatusCallback; -using ::media::PipelineStatusCB; -using ::media::Ranges; -using ::media::SampleFormat; -using ::media::VideoCodec; -using ::media::VideoCodecProfile; -using ::media::VideoColorSpace; -using ::media::VideoDecoderConfig; -using ::media::VideoPixelFormat; -using ::media::VideoTransformation; -using ::media::mp4::AVCDecoderConfigurationRecord; - // Used to convert a lambda to a pure C function. // |user_data| is a callback of type T, which takes a U*. template @@ -77,7 +54,7 @@ class DemuxerExtensionWrapper::H264AnnexBConverter { LOG(ERROR) << "Invalid inputs to H264AnnexBConverter::Create."; return nullptr; } - AVCDecoderConfigurationRecord config; + mp4::AVCDecoderConfigurationRecord config; std::unique_ptr converter( new H264ToAnnexBBitstreamConverter); if (!converter->ParseConfiguration( @@ -115,7 +92,7 @@ class DemuxerExtensionWrapper::H264AnnexBConverter { // The SPS and PPS NALUs -- generated from the config -- should only be // sent with the first real NALU. - config_ = base::nullopt; + config_ = absl::nullopt; // TODO(b/231994311): Add the buffer's side_data here, for HDR10+ support. return DecoderBuffer::CopyFrom(rewritten.data(), rewritten.size()); @@ -124,12 +101,12 @@ class DemuxerExtensionWrapper::H264AnnexBConverter { private: explicit H264AnnexBConverter( - AVCDecoderConfigurationRecord config, + mp4::AVCDecoderConfigurationRecord config, std::unique_ptr converter) : config_(std::move(config)), converter_(std::move(converter)) {} // This config data is only sent with the first NALU (as SPS and PPS NALUs). - base::Optional config_; + absl::optional config_; std::unique_ptr converter_; }; @@ -189,13 +166,16 @@ DemuxerExtensionStream::DemuxerExtensionStream( } void DemuxerExtensionStream::Read(uint32_t count, ReadCB read_cb) { - DCHECK(!read_cb.is_null()); base::AutoLock auto_lock(lock_); + DCHECK(!read_cb_); + + read_cb_ = base::BindPostTaskToCurrentDefault(std::move(read_cb)); + if (stopped_) { LOG(INFO) << "Already stopped."; std::vector> buffers; - buffers.push_back(std::move(DecoderBuffer::CreateEOSBuffer())); - std::move(read_cb).Run(DemuxerStream::kOk, buffers); + buffers.push_back(DecoderBuffer::CreateEOSBuffer()); + std::move(read_cb_).Run(DemuxerStream::kOk, buffers); return; } @@ -203,7 +183,7 @@ void DemuxerExtensionStream::Read(uint32_t count, ReadCB read_cb) { CHECK(buffer_queue_.empty() || read_queue_.empty()); if (buffer_queue_.empty()) { - read_queue_.push_back(std::move(read_cb)); + read_queue_.push_back(std::move(read_cb_)); return; } @@ -217,7 +197,7 @@ void DemuxerExtensionStream::Read(uint32_t count, ReadCB read_cb) { std::vector> buffers; buffers.push_back(std::move(buffer)); - std::move(read_cb).Run(DemuxerStream::kOk, buffers); + std::move(read_cb_).Run(DemuxerStream::kOk, buffers); } AudioDecoderConfig DemuxerExtensionStream::audio_decoder_config() { @@ -255,8 +235,8 @@ void DemuxerExtensionStream::EnqueueBuffer( if (buffer->end_of_stream()) { LOG(INFO) << "Received EOS"; - } else if (buffer->timestamp() != ::media::kNoTimestamp) { - if (last_buffer_timestamp_ != ::media::kNoTimestamp && + } else if (buffer->timestamp() != kNoTimestamp) { + if (last_buffer_timestamp_ != kNoTimestamp && last_buffer_timestamp_ < buffer->timestamp()) { buffered_ranges_.Add(last_buffer_timestamp_, buffer->timestamp()); } @@ -287,7 +267,7 @@ void DemuxerExtensionStream::FlushBuffers() { base::AutoLock auto_lock(lock_); buffer_queue_.clear(); total_buffer_size_ = 0; - last_buffer_timestamp_ = ::media::kNoTimestamp; + last_buffer_timestamp_ = kNoTimestamp; } void DemuxerExtensionStream::Stop() { @@ -296,11 +276,11 @@ void DemuxerExtensionStream::Stop() { base::AutoLock auto_lock(lock_); buffer_queue_.clear(); total_buffer_size_ = 0; - last_buffer_timestamp_ = ::media::kNoTimestamp; + last_buffer_timestamp_ = kNoTimestamp; // Fulfill any pending callbacks with EOS buffers set to end timestamp. for (auto& read_cb : read_queue_) { std::vector> buffers; - buffers.push_back(std::move(DecoderBuffer::CreateEOSBuffer())); + buffers.push_back(DecoderBuffer::CreateEOSBuffer()); std::move(read_cb).Run(DemuxerStream::kOk, buffers); } read_queue_.clear(); @@ -325,7 +305,9 @@ PositionalDataSource::PositionalDataSource( PositionalDataSource::~PositionalDataSource() = default; -void PositionalDataSource::Stop() { reader_->Stop(); } +void PositionalDataSource::Stop() { + reader_->Stop(); +} int PositionalDataSource::BlockingRead(uint8_t* data, int bytes_requested) { const int bytes_read = @@ -336,16 +318,24 @@ int PositionalDataSource::BlockingRead(uint8_t* data, int bytes_requested) { return bytes_read; } -void PositionalDataSource::SeekTo(int position) { position_ = position; } +void PositionalDataSource::SeekTo(int position) { + position_ = position; +} -int64_t PositionalDataSource::GetPosition() const { return position_; } +int64_t PositionalDataSource::GetPosition() const { + return position_; +} -int64_t PositionalDataSource::GetSize() { return reader_->FileSize(); } +int64_t PositionalDataSource::GetSize() { + return reader_->FileSize(); +} // Functions for converting a PositionalDataSource to // CobaltExtensionDemuxerDataSource. static int CobaltExtensionDemuxerDataSource_BlockingReadRead( - uint8_t* data, int bytes_requested, void* user_data) { + uint8_t* data, + int bytes_requested, + void* user_data) { return static_cast(user_data)->BlockingRead( data, bytes_requested); } @@ -472,7 +462,7 @@ void DemuxerExtensionWrapper::Initialize(DemuxerHost* host, // Start the blocking thread and have it download and parse the media config. if (!blocking_thread_.Start()) { LOG(ERROR) << "Unable to start blocking thread"; - std::move(status_cb).Run(::media::DEMUXER_ERROR_COULD_NOT_PARSE); + std::move(status_cb).Run(DEMUXER_ERROR_COULD_NOT_PARSE); return; } @@ -485,7 +475,8 @@ void DemuxerExtensionWrapper::Initialize(DemuxerHost* host, } void DemuxerExtensionWrapper::OnInitializeDone( - PipelineStatusCallback status_cb, CobaltExtensionDemuxerStatus status) { + PipelineStatusCallback status_cb, + CobaltExtensionDemuxerStatus status) { if (status == kCobaltExtensionDemuxerOk) { // Set up the stream(s) on this end. CobaltExtensionDemuxerAudioDecoderConfig audio_config = {}; @@ -495,7 +486,7 @@ void DemuxerExtensionWrapper::OnInitializeDone( // TODO(b/232957482): Determine whether we need to handle this case. LOG(ERROR) << "Encrypted audio is not supported for progressive playback."; - std::move(status_cb).Run(::media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS); + std::move(status_cb).Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); return; } audio_stream_.emplace(impl_, task_runner_, std::move(audio_config)); @@ -507,7 +498,7 @@ void DemuxerExtensionWrapper::OnInitializeDone( // TODO(b/232957482): Determine whether we need to handle this case. LOG(ERROR) << "Encrypted video is not supported for progressive playback."; - std::move(status_cb).Run(::media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS); + std::move(status_cb).Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); return; } if (video_config.extra_data && video_config.extra_data_size > 0 && @@ -528,12 +519,12 @@ void DemuxerExtensionWrapper::OnInitializeDone( // Even though initialization seems to have succeeded, something is wrong // if there are no streams. LOG(ERROR) << "No streams are present"; - std::move(status_cb).Run(::media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS); + std::move(status_cb).Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); return; } - host_->SetDuration(base::TimeDelta::FromMicroseconds( - impl_->GetDuration(impl_->user_data))); + host_->SetDuration( + base::Microseconds(impl_->GetDuration(impl_->user_data))); // Begin downloading data. Request(audio_stream_.has_value() ? DemuxerStream::AUDIO @@ -567,15 +558,19 @@ void DemuxerExtensionWrapper::SeekTask(base::TimeDelta time, CHECK(blocking_thread_.task_runner()->RunsTasksInCurrentSequence()); // clear any enqueued buffers on demuxer streams - if (video_stream_.has_value()) video_stream_->FlushBuffers(); - if (audio_stream_.has_value()) audio_stream_->FlushBuffers(); + if (video_stream_.has_value()) { + video_stream_->FlushBuffers(); + } + if (audio_stream_.has_value()) { + audio_stream_->FlushBuffers(); + } const CobaltExtensionDemuxerStatus status = impl_->Seek(time.InMicroseconds(), impl_->user_data); if (status != kCobaltExtensionDemuxerOk) { LOG(ERROR) << "Seek failed with status " << status; - std::move(status_cb).Run(::media::PIPELINE_ERROR_READ); + std::move(status_cb).Run(PIPELINE_ERROR_READ); return; } @@ -586,7 +581,7 @@ void DemuxerExtensionWrapper::SeekTask(base::TimeDelta time, audio_reached_eos_ = false; video_reached_eos_ = false; flushing_ = true; - std::move(status_cb).Run(::media::PIPELINE_OK); + std::move(status_cb).Run(PIPELINE_OK); if (issue_new_request) { IssueNextRequest(); @@ -616,13 +611,12 @@ void DemuxerExtensionWrapper::Stop() { } base::TimeDelta DemuxerExtensionWrapper::GetStartTime() const { - return base::TimeDelta::FromMicroseconds( - impl_->GetStartTime(impl_->user_data)); + return base::Microseconds(impl_->GetStartTime(impl_->user_data)); } base::Time DemuxerExtensionWrapper::GetTimelineOffset() const { - const base::TimeDelta reported_time = base::TimeDelta::FromMicroseconds( - impl_->GetTimelineOffset(impl_->user_data)); + const base::TimeDelta reported_time = + base::Microseconds(impl_->GetTimelineOffset(impl_->user_data)); return reported_time.is_zero() ? base::Time() : base::Time::FromDeltaSinceWindowsEpoch(reported_time); @@ -634,19 +628,21 @@ int64_t DemuxerExtensionWrapper::GetMemoryUsage() const { } void DemuxerExtensionWrapper::OnEnabledAudioTracksChanged( - const std::vector& track_ids, base::TimeDelta curr_time, + const std::vector& track_ids, + base::TimeDelta curr_time, TrackChangeCB change_completed_cb) { NOTREACHED(); } void DemuxerExtensionWrapper::OnSelectedVideoTrackChanged( - const std::vector& track_ids, base::TimeDelta curr_time, + const std::vector& track_ids, + base::TimeDelta curr_time, TrackChangeCB change_completed_cb) { NOTREACHED(); } void DemuxerExtensionWrapper::Request(DemuxerStream::Type type) { - static const auto kRequestDelay = base::TimeDelta::FromMilliseconds(100); + static const auto kRequestDelay = base::Milliseconds(100); if (type == DemuxerStream::AUDIO) { DCHECK(audio_stream_.has_value()); @@ -656,8 +652,8 @@ void DemuxerExtensionWrapper::Request(DemuxerStream::Type type) { if (!blocking_thread_.task_runner()->RunsTasksInCurrentSequence()) { blocking_thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&DemuxerExtensionWrapper::Request, - base::Unretained(this), type)); + FROM_HERE, base::BindRepeating(&DemuxerExtensionWrapper::Request, + base::Unretained(this), type)); return; } @@ -688,8 +684,8 @@ void DemuxerExtensionWrapper::Request(DemuxerStream::Type type) { // Retry after a delay. blocking_thread_.task_runner()->PostDelayedTask( FROM_HERE, - base::Bind(&DemuxerExtensionWrapper::Request, base::Unretained(this), - type), + base::BindRepeating(&DemuxerExtensionWrapper::Request, + base::Unretained(this), type), kRequestDelay); return; } @@ -717,10 +713,8 @@ void DemuxerExtensionWrapper::Request(DemuxerStream::Type type) { decoder_buffer = DecoderBuffer::CopyFrom(buffer->data, buffer->data_size); } - decoder_buffer->set_timestamp( - base::TimeDelta::FromMicroseconds(buffer->pts)); - decoder_buffer->set_duration( - base::TimeDelta::FromMicroseconds(buffer->duration)); + decoder_buffer->set_timestamp(base::Microseconds(buffer->pts)); + decoder_buffer->set_duration(base::Microseconds(buffer->duration)); decoder_buffer->set_is_key_frame(buffer->is_keyframe); }; impl_->Read(static_cast(type), @@ -730,12 +724,12 @@ void DemuxerExtensionWrapper::Request(DemuxerStream::Type type) { if (!called_cb) { LOG(ERROR) << "Demuxer extension implementation did not call the read callback."; - host_->OnDemuxerError(::media::PIPELINE_ERROR_READ); + host_->OnDemuxerError(PIPELINE_ERROR_READ); return; } if (!decoder_buffer) { LOG(ERROR) << "Received a null buffer from the demuxer."; - host_->OnDemuxerError(::media::PIPELINE_ERROR_READ); + host_->OnDemuxerError(PIPELINE_ERROR_READ); return; } @@ -786,9 +780,9 @@ void DemuxerExtensionWrapper::IssueNextRequest() { const base::TimeDelta audio_stamp = audio_stream_->GetLastBufferTimestamp(); const base::TimeDelta video_stamp = video_stream_->GetLastBufferTimestamp(); // If the audio demuxer stream is empty, always fill it first. - if (audio_stamp == ::media::kNoTimestamp) { + if (audio_stamp == kNoTimestamp) { type = DemuxerStream::AUDIO; - } else if (video_stamp == ::media::kNoTimestamp) { + } else if (video_stamp == kNoTimestamp) { // The video demuxer stream is empty; we need data for it. type = DemuxerStream::VIDEO; } else if (video_stamp < audio_stamp) { @@ -805,8 +799,8 @@ void DemuxerExtensionWrapper::IssueNextRequest() { // running in a tight loop and seek/stop requests would have no chance to kick // in. blocking_thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&DemuxerExtensionWrapper::Request, - base::Unretained(this), type)); + FROM_HERE, base::BindRepeating(&DemuxerExtensionWrapper::Request, + base::Unretained(this), type)); } bool DemuxerExtensionWrapper::HasStopped() { @@ -819,8 +813,10 @@ namespace { // Ensure that the demuxer extension's enums match up with the internal enums. // This doesn't affect any code, but prevents compilation if there's a mismatch // somewhere. -#define DEMUXER_EXTENSION_ENUM_EQ(a, b) \ - COMPILE_ASSERT(static_cast(a) == static_cast(b), mismatching_enums) +#define DEMUXER_EXTENSION_ENUM_EQ(a, b) \ + static_assert(static_cast(a) == static_cast(b), \ + "mismatching_" \ + "enums") // Pipeline status. DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerOk, ::media::PIPELINE_OK); @@ -877,7 +873,6 @@ DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerCodecALAC, DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerCodecAC3, ::media::AudioCodec::kAC3); - // Video codecs. DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerCodecUnknownVideo, ::media::VideoCodec::kUnknown); @@ -922,7 +917,6 @@ DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerSampleFormatPlanarS32, DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerSampleFormatS24, ::media::kSampleFormatS24); - // Channel layouts. DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerChannelLayoutNone, ::media::CHANNEL_LAYOUT_NONE); @@ -1118,4 +1112,3 @@ DEMUXER_EXTENSION_ENUM_EQ(kCobaltExtensionDemuxerEncryptionSchemeCbcs, } // namespace } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/demuxer_extension_wrapper.h b/media/starboard/progressive/demuxer_extension_wrapper.h index a2ec4ee2290..d6eeb841ddd 100644 --- a/media/starboard/progressive/demuxer_extension_wrapper.h +++ b/media/starboard/progressive/demuxer_extension_wrapper.h @@ -15,8 +15,8 @@ // Contains classes that wrap the Demuxer Cobalt Extension, providing an // implementation of a Cobalt demuxer. The main API is DemuxerExtensionWrapper. -#ifndef COBALT_MEDIA_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ -#define COBALT_MEDIA_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ #include #include @@ -24,24 +24,23 @@ #include #include "base/memory/scoped_refptr.h" -#include "base/optional.h" #include "base/sequence_checker.h" #include "base/threading/thread.h" -#include "cobalt/media/progressive/data_source_reader.h" #include "media/base/audio_decoder_config.h" #include "media/base/decoder_buffer.h" #include "media/base/demuxer.h" #include "media/base/pipeline_status.h" #include "media/base/ranges.h" #include "media/base/video_decoder_config.h" +#include "media/starboard/progressive/data_source_reader.h" #include "starboard/extension/demuxer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" -namespace cobalt { namespace media { // Represents an audio or video stream. Reads data via the demuxer Cobalt // Extension. -class DemuxerExtensionStream : public ::media::DemuxerStream { +class DemuxerExtensionStream : public DemuxerStream { public: // Represents a video stream. explicit DemuxerExtensionStream( @@ -61,8 +60,8 @@ class DemuxerExtensionStream : public ::media::DemuxerStream { ~DemuxerExtensionStream() = default; // Functions used by DemuxerExtensionWrapper. - ::media::Ranges GetBufferedRanges(); - void EnqueueBuffer(scoped_refptr<::media::DecoderBuffer> buffer); + Ranges GetBufferedRanges(); + void EnqueueBuffer(scoped_refptr buffer); void FlushBuffers(); void Stop(); base::TimeDelta GetLastBufferTimestamp() const; @@ -70,8 +69,8 @@ class DemuxerExtensionStream : public ::media::DemuxerStream { // DemuxerStream implementation: void Read(uint32_t count, ReadCB read_cb) override; - ::media::AudioDecoderConfig audio_decoder_config() override; - ::media::VideoDecoderConfig video_decoder_config() override; + AudioDecoderConfig audio_decoder_config() override; + VideoDecoderConfig video_decoder_config() override; Type type() const override; void EnableBitstreamConverter() override { NOTIMPLEMENTED(); } @@ -79,24 +78,25 @@ class DemuxerExtensionStream : public ::media::DemuxerStream { bool SupportsConfigChanges() override { return false; } private: - typedef std::deque> BufferQueue; + typedef std::deque> BufferQueue; typedef std::deque ReadQueue; CobaltExtensionDemuxer* demuxer_ = nullptr; // Not owned. - base::Optional<::media::VideoDecoderConfig> video_config_; - base::Optional<::media::AudioDecoderConfig> audio_config_; + std::optional video_config_; + std::optional audio_config_; // Protects everything below. mutable base::Lock lock_; + ReadCB read_cb_ GUARDED_BY(lock_); // Keeps track of all time ranges this object has seen since creation. // The demuxer uses these ranges to update the pipeline about what data // it has demuxed. - ::media::Ranges buffered_ranges_; + Ranges buffered_ranges_; // The last timestamp of buffer enqueued. This is used in two places: // 1. Used with the timestamp of the current frame to calculate the // buffer range. // 2. Used by the demuxer to deteminate what type of frame to get next. - base::TimeDelta last_buffer_timestamp_ = ::media::kNoTimestamp; + base::TimeDelta last_buffer_timestamp_ = kNoTimestamp; bool stopped_ = false; BufferQueue buffer_queue_; @@ -145,7 +145,7 @@ class PositionalDataSource { // Wraps the demuxer Cobalt Extension in the internal media::Demuxer API. // Instances should be created via the Create method. -class DemuxerExtensionWrapper : public ::media::Demuxer { +class DemuxerExtensionWrapper : public Demuxer { public: // Constructs a new DemuxerExtensionWrapper, returning null on failure. If // |data_source| or |task_runner| is null, or if a demuxer cannot be created, @@ -163,34 +163,32 @@ class DemuxerExtensionWrapper : public ::media::Demuxer { ~DemuxerExtensionWrapper() override; // Demuxer implementation: - std::vector<::media::DemuxerStream*> GetAllStreams() override; + std::vector GetAllStreams() override; std::string GetDisplayName() const override; - ::media::DemuxerType GetDemuxerType() const override { + DemuxerType GetDemuxerType() const override { // kFFmpegDemuxer is used in Chromium media for progressive demuxing. - return ::media::DemuxerType::kFFmpegDemuxer; + return DemuxerType::kFFmpegDemuxer; } - void Initialize(::media::DemuxerHost* host, - ::media::PipelineStatusCallback status_cb) override; + void Initialize(DemuxerHost* host, PipelineStatusCallback status_cb) override; void AbortPendingReads() override; void StartWaitingForSeek(base::TimeDelta seek_time) override; void CancelPendingSeek(base::TimeDelta seek_time) override; - void Seek(base::TimeDelta time, - ::media::PipelineStatusCallback status_cb) override; + void Seek(base::TimeDelta time, PipelineStatusCallback status_cb) override; bool IsSeekable() const override { return true; } void Stop() override; base::TimeDelta GetStartTime() const override; base::Time GetTimelineOffset() const override; int64_t GetMemoryUsage() const override; - void OnEnabledAudioTracksChanged( - const std::vector<::media::MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, TrackChangeCB change_completed_cb) override; - void OnSelectedVideoTrackChanged( - const std::vector<::media::MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, TrackChangeCB change_completed_cb) override; + void OnEnabledAudioTracksChanged(const std::vector& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; + void OnSelectedVideoTrackChanged(const std::vector& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; void SetPlaybackRate(double rate) override { NOTREACHED(); } - absl::optional<::media::container_names::MediaContainerName> - GetContainerForMetrics() const override { + absl::optional GetContainerForMetrics() + const override { NOTREACHED(); return absl::nullopt; } @@ -208,25 +206,24 @@ class DemuxerExtensionWrapper : public ::media::Demuxer { std::unique_ptr c_data_source, scoped_refptr task_runner); - void OnInitializeDone(::media::PipelineStatusCallback status_cb, + void OnInitializeDone(PipelineStatusCallback status_cb, CobaltExtensionDemuxerStatus status); - void Request(::media::DemuxerStream::Type type); + void Request(DemuxerStream::Type type); bool HasStopped(); void IssueNextRequest(); - void SeekTask(base::TimeDelta time, - ::media::PipelineStatusCallback status_cb); + void SeekTask(base::TimeDelta time, PipelineStatusCallback status_cb); // Returns the range of buffered data. If both audio and video streams are // present, this is the intersection of their buffered ranges; otherwise, it // is whatever range of data is buffered. - ::media::Ranges GetBufferedRanges(); + Ranges GetBufferedRanges(); const CobaltExtensionDemuxerApi* demuxer_api_ = nullptr; // Not owned. // Owned by this class. Construction/destruction is done via demuxer_api_. CobaltExtensionDemuxer* impl_ = nullptr; std::unique_ptr data_source_; std::unique_ptr c_data_source_; - ::media::DemuxerHost* host_ = nullptr; + DemuxerHost* host_ = nullptr; mutable base::Lock lock_for_stopped_; // Indicates whether Stop has been called. bool stopped_ = false; @@ -234,8 +231,8 @@ class DemuxerExtensionWrapper : public ::media::Demuxer { bool audio_reached_eos_ = false; bool flushing_ = false; - base::Optional video_stream_; - base::Optional audio_stream_; + absl::optional video_stream_; + absl::optional audio_stream_; std::unique_ptr h264_converter_; @@ -249,6 +246,5 @@ class DemuxerExtensionWrapper : public ::media::Demuxer { }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ diff --git a/media/starboard/progressive/endian_util.h b/media/starboard/progressive/endian_util.h index a8be522e029..1059db3b891 100644 --- a/media/starboard/progressive/endian_util.h +++ b/media/starboard/progressive/endian_util.h @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_BASE_ENDIAN_UTIL_H_ -#define COBALT_MEDIA_BASE_ENDIAN_UTIL_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_ENDIAN_UTIL_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_ENDIAN_UTIL_H_ #include "base/sys_byteorder.h" // TODO: Consider Starboardize functions in this file. -namespace cobalt { namespace media { namespace endian_util { @@ -138,6 +137,5 @@ inline void store_uint64_little_endian(uint64_t d, uint8_t* p) { } // namespace endian_util } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_BASE_ENDIAN_UTIL_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_ENDIAN_UTIL_H_ diff --git a/media/starboard/progressive/mock_data_source_reader.h b/media/starboard/progressive/mock_data_source_reader.h index 1ec8ba7cac9..bc1fb70ddad 100644 --- a/media/starboard/progressive/mock_data_source_reader.h +++ b/media/starboard/progressive/mock_data_source_reader.h @@ -1,26 +1,23 @@ -/* - * Copyright 2012 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2012 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_MOCK_DATA_SOURCE_READER_H_ -#define COBALT_MEDIA_PROGRESSIVE_MOCK_DATA_SOURCE_READER_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_MOCK_DATA_SOURCE_READER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_MOCK_DATA_SOURCE_READER_H_ -#include "cobalt/media/progressive/data_source_reader.h" +#include "media/starboard/progressive/data_source_reader.h" #include "testing/gmock/include/gmock/gmock.h" -namespace cobalt { namespace media { class MockDataSourceReader : public DataSourceReader { @@ -35,6 +32,5 @@ class MockDataSourceReader : public DataSourceReader { }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_MOCK_DATA_SOURCE_READER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_MOCK_DATA_SOURCE_READER_H_ diff --git a/media/starboard/progressive/mp4_map.cc b/media/starboard/progressive/mp4_map.cc index 0d308314e85..8460da0694a 100644 --- a/media/starboard/progressive/mp4_map.cc +++ b/media/starboard/progressive/mp4_map.cc @@ -12,21 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/mp4_map.h" +#include "media/starboard/progressive/mp4_map.h" #include #include "base/strings/stringprintf.h" -#include "cobalt/media/base/endian_util.h" -#include "cobalt/media/progressive/mp4_parser.h" +#include "media/starboard/progressive/endian_util.h" +#include "media/starboard/progressive/mp4_parser.h" -namespace cobalt { namespace media { // ==== TableCache ============================================================= -MP4Map::TableCache::TableCache(uint64 table_offset, uint32 entry_count, - uint32 entry_size, uint32 cache_size_entries, +MP4Map::TableCache::TableCache(uint64_t table_offset, + uint32_t entry_count, + uint32_t entry_size, + uint32_t cache_size_entries, scoped_refptr reader) : entry_size_(entry_size), entry_count_(entry_count), @@ -36,7 +37,7 @@ MP4Map::TableCache::TableCache(uint64 table_offset, uint32 entry_count, cache_first_entry_number_(-1), cache_entry_count_(0) {} -uint8* MP4Map::TableCache::GetBytesAtEntry(uint32 entry_number) { +uint8_t* MP4Map::TableCache::GetBytesAtEntry(uint32_t entry_number) { // don't fetch the unfetchable if (entry_number >= entry_count_) { return NULL; @@ -59,7 +60,7 @@ uint8* MP4Map::TableCache::GetBytesAtEntry(uint32 entry_number) { DCHECK_GE(cache_entry_count_, 0); int bytes_to_read = cache_entry_count_ * entry_size_; cache_.resize(bytes_to_read); - uint64 file_offset = + uint64_t file_offset = table_offset_ + (cache_first_entry_number_ * entry_size_); int bytes_read = reader_->BlockingRead(file_offset, bytes_to_read, &cache_[0]); @@ -72,12 +73,12 @@ uint8* MP4Map::TableCache::GetBytesAtEntry(uint32 entry_number) { DCHECK_GE(entry_number, cache_first_entry_number_); DCHECK_LT(entry_number, cache_first_entry_number_ + cache_entry_count_); - uint32 cache_offset = entry_number - cache_first_entry_number_; + uint32_t cache_offset = entry_number - cache_first_entry_number_; return &cache_[0] + (cache_offset * entry_size_); } -bool MP4Map::TableCache::ReadU32Entry(uint32 entry_number, uint32* entry) { - if (uint8* data = GetBytesAtEntry(entry_number)) { +bool MP4Map::TableCache::ReadU32Entry(uint32_t entry_number, uint32_t* entry) { + if (uint8_t* data = GetBytesAtEntry(entry_number)) { *entry = endian_util::load_uint32_big_endian(data); return true; } @@ -85,20 +86,25 @@ bool MP4Map::TableCache::ReadU32Entry(uint32 entry_number, uint32* entry) { return false; } -bool MP4Map::TableCache::ReadU32PairEntry(uint32 entry_number, uint32* first, - uint32* second) { - if (uint8* data = GetBytesAtEntry(entry_number)) { - if (first) *first = endian_util::load_uint32_big_endian(data); - if (second) *second = endian_util::load_uint32_big_endian(data + 4); +bool MP4Map::TableCache::ReadU32PairEntry(uint32_t entry_number, + uint32_t* first, + uint32_t* second) { + if (uint8_t* data = GetBytesAtEntry(entry_number)) { + if (first) { + *first = endian_util::load_uint32_big_endian(data); + } + if (second) { + *second = endian_util::load_uint32_big_endian(data + 4); + } return true; } return false; } -bool MP4Map::TableCache::ReadU32EntryIntoU64(uint32 entry_number, - uint64* entry) { - if (uint8* data = GetBytesAtEntry(entry_number)) { +bool MP4Map::TableCache::ReadU32EntryIntoU64(uint32_t entry_number, + uint64_t* entry) { + if (uint8_t* data = GetBytesAtEntry(entry_number)) { *entry = endian_util::load_uint32_big_endian(data); return true; } @@ -106,8 +112,8 @@ bool MP4Map::TableCache::ReadU32EntryIntoU64(uint32 entry_number, return false; } -bool MP4Map::TableCache::ReadU64Entry(uint32 entry_number, uint64* entry) { - if (uint8* data = GetBytesAtEntry(entry_number)) { +bool MP4Map::TableCache::ReadU64Entry(uint32_t entry_number, uint64_t* entry) { + if (uint8_t* data = GetBytesAtEntry(entry_number)) { *entry = endian_util::load_uint64_big_endian(data); return true; } @@ -161,7 +167,7 @@ bool MP4Map::IsComplete() { // The sample size is a lookup in the stsz table, which is indexed per sample // number. -bool MP4Map::GetSize(uint32 sample_number, uint32* size_out) { +bool MP4Map::GetSize(uint32_t sample_number, uint32_t* size_out) { DCHECK(size_out); DCHECK(stsz_ || stsz_default_size_); @@ -183,7 +189,7 @@ bool MP4Map::GetSize(uint32 sample_number, uint32* size_out) { // then use the stsz to sum samples to the byte offset with that chunk. The sum // of the chunk offset and the byte offset within the chunk is the offset of // the sample. -bool MP4Map::GetOffset(uint32 sample_number, uint64* offset_out) { +bool MP4Map::GetOffset(uint32_t sample_number, uint64_t* offset_out) { DCHECK(offset_out); DCHECK(stsc_); DCHECK(stco_ || co64_); @@ -204,9 +210,9 @@ bool MP4Map::GetOffset(uint32 sample_number, uint64* offset_out) { DCHECK_GE(sample_number, stsc_first_chunk_sample_); // calculate chunk number based on chunk sample size for this range - uint32 sample_offset = sample_number - stsc_first_chunk_sample_; - uint32 chunk_range_offset = sample_offset / stsc_samples_per_chunk_; - uint32 chunk_number = stsc_first_chunk_ + chunk_range_offset; + uint32_t sample_offset = sample_number - stsc_first_chunk_sample_; + uint32_t chunk_range_offset = sample_offset / stsc_samples_per_chunk_; + uint32_t chunk_number = stsc_first_chunk_ + chunk_range_offset; // should be within the range of chunks with this sample size DCHECK_LT(chunk_number, stsc_next_first_chunk_); // update first sample number contained within this chunk @@ -216,8 +222,9 @@ bool MP4Map::GetOffset(uint32 sample_number, uint64* offset_out) { next_chunk_sample_ = current_chunk_sample_ + stsc_samples_per_chunk_; // find offset of this chunk within the file from co64/stco if (co64_) { - if (!co64_->ReadU64Entry(chunk_number, ¤t_chunk_offset_)) + if (!co64_->ReadU64Entry(chunk_number, ¤t_chunk_offset_)) { return false; + } } else if (!stco_->ReadU32EntryIntoU64(chunk_number, ¤t_chunk_offset_)) { return false; @@ -236,7 +243,7 @@ bool MP4Map::GetOffset(uint32 sample_number, uint64* offset_out) { } else { // sum sample sizes within chunk to get to byte offset of sample while (current_chunk_sample_ < sample_number) { - uint32 sample_size = 0; + uint32_t sample_size = 0; if (!GetSize(current_chunk_sample_, &sample_size)) { return false; } @@ -254,7 +261,7 @@ bool MP4Map::GetOffset(uint32 sample_number, uint64* offset_out) { // durations to find the dts of that sample number. We then integrate sample // numbers through the ctts to find the composition time offset, which we add to // the dts to return the pts. -bool MP4Map::GetTimestamp(uint32 sample_number, uint64* timestamp_out) { +bool MP4Map::GetTimestamp(uint32_t sample_number, uint64_t* timestamp_out) { DCHECK(timestamp_out); if (sample_number > highest_valid_sample_number_) { return false; @@ -265,8 +272,8 @@ bool MP4Map::GetTimestamp(uint32 sample_number, uint64* timestamp_out) { } DCHECK_LT(sample_number, stts_next_first_sample_); DCHECK_GE(sample_number, stts_first_sample_); - uint64 dts = stts_first_sample_time_ + - (sample_number - stts_first_sample_) * stts_sample_duration_; + uint64_t dts = stts_first_sample_time_ + + (sample_number - stts_first_sample_) * stts_sample_duration_; if (ctts_) { if (!ctts_AdvanceToSample(sample_number)) { return false; @@ -279,7 +286,7 @@ bool MP4Map::GetTimestamp(uint32 sample_number, uint64* timestamp_out) { } // Sum through the stts to find the duration of the given sample_number. -bool MP4Map::GetDuration(uint32 sample_number, uint32* duration_out) { +bool MP4Map::GetDuration(uint32_t sample_number, uint32_t* duration_out) { DCHECK(duration_out); if (sample_number > highest_valid_sample_number_) { return false; @@ -294,7 +301,7 @@ bool MP4Map::GetDuration(uint32 sample_number, uint32* duration_out) { return true; } -bool MP4Map::GetIsKeyframe(uint32 sample_number, bool* is_keyframe_out) { +bool MP4Map::GetIsKeyframe(uint32_t sample_number, bool* is_keyframe_out) { DCHECK(is_keyframe_out); if (sample_number > highest_valid_sample_number_) { return false; @@ -335,14 +342,14 @@ bool MP4Map::GetIsKeyframe(uint32 sample_number, bool* is_keyframe_out) { return true; } -bool MP4Map::IsEOS(uint32 sample_number) { +bool MP4Map::IsEOS(uint32_t sample_number) { return (sample_number > highest_valid_sample_number_); } // First look up the sample number for the provided timestamp by integrating // timestamps through the stts. Then do a binary search on the stss to find the // keyframe nearest that sample number. -bool MP4Map::GetKeyframe(uint64 timestamp, uint32* sample_out) { +bool MP4Map::GetKeyframe(uint64_t timestamp, uint32_t* sample_out) { DCHECK(sample_out); // Advance stts to the provided timestamp range if (!stts_AdvanceToTime(timestamp)) { @@ -352,8 +359,8 @@ bool MP4Map::GetKeyframe(uint64 timestamp, uint32* sample_out) { DCHECK_LT(timestamp, stts_next_first_sample_time_); DCHECK_GE(timestamp, stts_first_sample_time_); // calculate sample number containing this timestamp - uint64 time_offset_within_range = timestamp - stts_first_sample_time_; - uint32 sample_number = + uint64_t time_offset_within_range = timestamp - stts_first_sample_time_; + uint32_t sample_number = stts_first_sample_ + (time_offset_within_range / stts_sample_duration_); // TODO: ctts? @@ -374,14 +381,17 @@ bool MP4Map::GetKeyframe(uint64 timestamp, uint32* sample_out) { // Set up map state and load first part of table, or entire table if it is small // enough, for each of the supported atoms. -bool MP4Map::SetAtom(uint32 four_cc, uint64 offset, uint64 size, - uint32 cache_size_entries, const uint8* atom) { +bool MP4Map::SetAtom(uint32_t four_cc, + uint64_t offset, + uint64_t size, + uint32_t cache_size_entries, + const uint8_t* atom) { // All map atoms are variable-length tables starting with 4 bytes of - // version/flag info followed by a uint32 indicating the number of items in + // version/flag info followed by a uint32_t indicating the number of items in // table. The stsz atom bucks tradition by putting an optional default value // at index 4. - uint32 count = 0; - uint64 table_offset = offset + 8; + uint32_t count = 0; + uint64_t table_offset = offset + 8; if (four_cc == kAtomType_stsz) { if (size < 12) { return false; @@ -392,7 +402,7 @@ bool MP4Map::SetAtom(uint32 four_cc, uint64 offset, uint64 size, std::min(count - 1, highest_valid_sample_number_); // if a non-zero default size is provided don't bother loading the table if (stsz_default_size_) { - stsz_ = NULL; + stsz_ = nullptr; return true; } @@ -415,43 +425,57 @@ bool MP4Map::SetAtom(uint32 four_cc, uint64 offset, uint64 size, case kAtomType_co64: co64_ = new TableCache(table_offset, count, kEntrySize_co64, cache_size_entries, reader_); - if (co64_) atom_init = co64_Init(); + if (co64_) { + atom_init = co64_Init(); + } break; case kAtomType_ctts: ctts_ = new TableCache(table_offset, count, kEntrySize_ctts, cache_size_entries, reader_); - if (ctts_) atom_init = ctts_Init(); + if (ctts_) { + atom_init = ctts_Init(); + } break; case kAtomType_stco: stco_ = new TableCache(table_offset, count, kEntrySize_stco, cache_size_entries, reader_); - if (stco_) atom_init = stco_Init(); + if (stco_) { + atom_init = stco_Init(); + } break; case kAtomType_stsc: stsc_ = new TableCache(table_offset, count, kEntrySize_stsc, cache_size_entries, reader_); - if (stsc_) atom_init = stsc_Init(); + if (stsc_) { + atom_init = stsc_Init(); + } break; case kAtomType_stss: stss_ = new TableCache(table_offset, count, kEntrySize_stss, cache_size_entries, reader_); - if (stss_) atom_init = stss_Init(); + if (stss_) { + atom_init = stss_Init(); + } break; case kAtomType_stts: stts_ = new TableCache(table_offset, count, kEntrySize_stts, cache_size_entries, reader_); - if (stts_) atom_init = stts_Init(); + if (stts_) { + atom_init = stts_Init(); + } break; case kAtomType_stsz: stsz_ = new TableCache(table_offset, count, kEntrySize_stsz, cache_size_entries, reader_); - if (stsz_) atom_init = stsz_Init(); + if (stsz_) { + atom_init = stsz_Init(); + } break; default: @@ -467,19 +491,19 @@ bool MP4Map::co64_Init() { // load offset of first chunk into current_chunk_offset_ if (co64_->GetEntryCount() > 0) { // can drop any stco table already allocated - stco_ = NULL; + stco_ = nullptr; // load initial value of current_chunk_offset_ for 0th chunk return co64_->ReadU64Entry(0, ¤t_chunk_offset_); } - co64_ = NULL; + co64_ = nullptr; return true; } // The ctts table has the following per-entry layout: -// uint32 sample count -// uint32 composition offset in ticks +// uint32_t sample count +// uint32_t composition offset in ticks // bool MP4Map::ctts_Init() { DCHECK(ctts_); @@ -497,7 +521,7 @@ bool MP4Map::ctts_Init() { &ctts_sample_offset_); } // drop empty ctts_ table - ctts_ = NULL; + ctts_ = nullptr; return true; } @@ -505,7 +529,7 @@ bool MP4Map::ctts_Init() { // To find the composition offset of a given sample number we must integrate // through the ctts to find the range of samples containing sample_number. Note // that the ctts is an optional table. -bool MP4Map::ctts_AdvanceToSample(uint32 sample_number) { +bool MP4Map::ctts_AdvanceToSample(uint32_t sample_number) { // ctts table is optional, so treat not having one as non-fatal if (!ctts_) { return true; @@ -550,10 +574,11 @@ bool MP4Map::ctts_AdvanceToSample(uint32 sample_number) { if (ctts_table_index_ < ctts_->GetEntryCount()) { // load the sample count to determine next first sample - uint32 sample_count; + uint32_t sample_count; if (!ctts_->ReadU32PairEntry(ctts_table_index_, &sample_count, - &ctts_sample_offset_)) + &ctts_sample_offset_)) { return false; + } ctts_next_first_sample_ = ctts_first_sample_ + sample_count; } else { // This means that the last entry in the table specified a sample range @@ -572,7 +597,7 @@ bool MP4Map::ctts_AdvanceToSample(uint32 sample_number) { return true; } -bool MP4Map::ctts_SlipCacheToSample(uint32 sample_number, +bool MP4Map::ctts_SlipCacheToSample(uint32_t sample_number, int starting_cache_index) { DCHECK_LT(starting_cache_index, ctts_samples_.size()); int cache_index = starting_cache_index; @@ -584,10 +609,11 @@ bool MP4Map::ctts_SlipCacheToSample(uint32 sample_number, ctts_first_sample_ = ctts_samples_[cache_index]; ctts_table_index_ = cache_index * ctts_->GetCacheSizeEntries(); // read sample count and duration to set next values - uint32 sample_count; + uint32_t sample_count; if (!ctts_->ReadU32PairEntry(ctts_table_index_, &sample_count, - &ctts_sample_offset_)) + &ctts_sample_offset_)) { return false; + } ctts_next_first_sample_ = ctts_first_sample_ + sample_count; return true; } @@ -596,19 +622,19 @@ bool MP4Map::stco_Init() { DCHECK(stco_); // load offset of first chunk into current_chunk_offset_ if (stco_->GetEntryCount() > 0) { - co64_ = NULL; + co64_ = nullptr; return stco_->ReadU32EntryIntoU64(0, ¤t_chunk_offset_); } - stco_ = NULL; + stco_ = nullptr; return true; } // The stsc table has the following per-entry layout: -// uint32 first chunk number with this sample count -// uint32 samples-per-chunk -// uint32 sample description id (unused) +// uint32_t first chunk number with this sample count +// uint32_t samples-per-chunk +// uint32_t sample description id (unused) bool MP4Map::stsc_Init() { DCHECK(stsc_); // set up vector to correct final size @@ -622,13 +648,13 @@ bool MP4Map::stsc_Init() { // first cached entry is always 0 stsc_sample_sums_.push_back(0); if (!stsc_->ReadU32PairEntry(0, NULL, &stsc_samples_per_chunk_)) { - stsc_ = NULL; + stsc_ = nullptr; return false; } // look up next first chunk at next index in table if (stsc_->GetEntryCount() > 1) { if (!stsc_->ReadU32PairEntry(1, &stsc_next_first_chunk_, NULL)) { - stsc_ = NULL; + stsc_ = nullptr; return false; } --stsc_next_first_chunk_; @@ -646,7 +672,7 @@ bool MP4Map::stsc_Init() { next_chunk_sample_ = stsc_samples_per_chunk_; } else { - stsc_ = NULL; + stsc_ = nullptr; } return true; @@ -659,7 +685,7 @@ bool MP4Map::stsc_Init() { // to be consumed incrementally and with minimal memory consumption we calculate // this integration step only when needed, and save results for each cached // piece of the table, to avoid having to recalculate needed data. -bool MP4Map::stsc_AdvanceToSample(uint32 sample_number) { +bool MP4Map::stsc_AdvanceToSample(uint32_t sample_number) { DCHECK(stsc_); // sample_number could be before first chunk, meaning that we are seeking // backwards and have left the current chunk. Find the closest part of the @@ -671,7 +697,7 @@ bool MP4Map::stsc_AdvanceToSample(uint32 sample_number) { } // sample_number could also be well head of our current piece of the - // cache, so see if we can re-use any previously calculated summations to + // cache, so see if we can reuse any previously calculated summations to // skip to the nearest cache entry int next_cache_index = (stsc_table_index_ / stsc_->GetCacheSizeEntries()) + 1; if ((next_cache_index < stsc_sample_sums_.size()) && @@ -735,7 +761,7 @@ bool MP4Map::stsc_AdvanceToSample(uint32 sample_number) { return true; } -bool MP4Map::stsc_SlipCacheToSample(uint32 sample_number, +bool MP4Map::stsc_SlipCacheToSample(uint32_t sample_number, int starting_cache_index) { DCHECK_LT(starting_cache_index, stsc_sample_sums_.size()); // look through old sample sums for the first entry that exceeds sample @@ -784,7 +810,7 @@ bool MP4Map::stss_Init() { if (stss_->GetEntryCount() > 0) { // identify first keyframe from first entry in stss if (!stss_->ReadU32Entry(0, &stss_last_keyframe_)) { - stss_ = NULL; + stss_ = nullptr; return false; } --stss_last_keyframe_; @@ -792,7 +818,7 @@ bool MP4Map::stss_Init() { stss_next_keyframe_ = stss_last_keyframe_; stss_table_index_ = 0; } else { - stss_ = NULL; + stss_ = nullptr; } return true; @@ -822,7 +848,7 @@ bool MP4Map::stss_AdvanceStep() { return true; } -bool MP4Map::stss_FindNearestKeyframe(uint32 sample_number) { +bool MP4Map::stss_FindNearestKeyframe(uint32_t sample_number) { DCHECK(stss_); // it is assumed that there's at least one cache entry created by // stss_Init(); @@ -872,7 +898,7 @@ bool MP4Map::stss_FindNearestKeyframe(uint32 sample_number) { // Use the first key frame in next cache as upper bound. int next_cached_entry_number = (cache_entry_number + 1) * stss_->GetCacheSizeEntries(); - uint32 next_cached_keyframe; + uint32_t next_cached_keyframe; if (!stss_->ReadU32Entry(next_cached_entry_number, &next_cached_keyframe)) { return false; @@ -887,7 +913,7 @@ bool MP4Map::stss_FindNearestKeyframe(uint32 sample_number) { cache_entry_number++; int first_table_entry_number = cache_entry_number * stss_->GetCacheSizeEntries(); - uint32 first_keyframe_in_cache_entry; + uint32_t first_keyframe_in_cache_entry; if (!stss_->ReadU32Entry(first_table_entry_number, &first_keyframe_in_cache_entry)) { return false; @@ -901,7 +927,7 @@ bool MP4Map::stss_FindNearestKeyframe(uint32 sample_number) { cache_entry_number == stss_keyframes_.size() - 1) { int next_cached_entry_number = ((cache_entry_number + 1) * stss_->GetCacheSizeEntries()); - uint32 next_cached_keyframe; + uint32_t next_cached_keyframe; if (!stss_->ReadU32Entry(next_cached_entry_number, &next_cached_keyframe)) { return false; @@ -952,8 +978,8 @@ bool MP4Map::stss_FindNearestKeyframe(uint32 sample_number) { } // The stts table has the following per-entry layout: -// uint32 sample count - number of sequential samples with this duration -// uint32 sample duration - duration in ticks of this sample range +// uint32_t sample count - number of sequential samples with this duration +// uint32_t sample duration - duration in ticks of this sample range bool MP4Map::stts_Init() { int cache_segments = (stts_->GetEntryCount() / stts_->GetCacheSizeEntries()) + 1; @@ -966,7 +992,7 @@ bool MP4Map::stts_Init() { stts_timestamps_.push_back(0); if (!stts_->ReadU32PairEntry(0, &stts_next_first_sample_, &stts_sample_duration_)) { - stts_ = NULL; + stts_ = nullptr; return false; } stts_first_sample_ = 0; @@ -975,13 +1001,13 @@ bool MP4Map::stts_Init() { stts_next_first_sample_ * stts_sample_duration_; stts_table_index_ = 0; } else { - stts_ = NULL; + stts_ = nullptr; } return true; } -bool MP4Map::stts_AdvanceToSample(uint32 sample_number) { +bool MP4Map::stts_AdvanceToSample(uint32_t sample_number) { DCHECK(stts_); // sample_number could be before our current sample range, in which case // we skip to the nearest table entry before sample_number and integrate @@ -1014,7 +1040,7 @@ bool MP4Map::stts_AdvanceToSample(uint32 sample_number) { // Move our integration steps to a previously saved entry in the cache tables. // Searches linearly through the vector of old cached values, so can accept a // starting index to do the search from. -bool MP4Map::stts_SlipCacheToSample(uint32 sample_number, +bool MP4Map::stts_SlipCacheToSample(uint32_t sample_number, int starting_cache_index) { DCHECK_LT(starting_cache_index, stts_samples_.size()); int cache_index = starting_cache_index; @@ -1026,7 +1052,7 @@ bool MP4Map::stts_SlipCacheToSample(uint32 sample_number, stts_first_sample_ = stts_samples_[cache_index]; stts_first_sample_time_ = stts_timestamps_[cache_index]; stts_table_index_ = cache_index * stts_->GetCacheSizeEntries(); - uint32 sample_count; + uint32_t sample_count; // read sample count and duration to set next values if (!stts_->ReadU32PairEntry(stts_table_index_, &sample_count, &stts_sample_duration_)) { @@ -1038,7 +1064,7 @@ bool MP4Map::stts_SlipCacheToSample(uint32 sample_number, return true; } -bool MP4Map::stts_AdvanceToTime(uint64 timestamp) { +bool MP4Map::stts_AdvanceToTime(uint64_t timestamp) { DCHECK(stts_); if (timestamp < stts_first_sample_time_) { @@ -1068,7 +1094,7 @@ bool MP4Map::stts_AdvanceToTime(uint64 timestamp) { bool MP4Map::stts_IntegrateStep() { // advance time to next sample range - uint32 range_size = stts_next_first_sample_ - stts_first_sample_; + uint32_t range_size = stts_next_first_sample_ - stts_first_sample_; stts_first_sample_time_ += (range_size * stts_sample_duration_); // advance sample counter to next range stts_first_sample_ = stts_next_first_sample_; @@ -1090,7 +1116,7 @@ bool MP4Map::stts_IntegrateStep() { } if (stts_table_index_ < stts_->GetEntryCount()) { // load next entry data - uint32 sample_count; + uint32_t sample_count; if (!stts_->ReadU32PairEntry(stts_table_index_, &sample_count, &stts_sample_duration_)) { return false; @@ -1110,7 +1136,8 @@ bool MP4Map::stts_IntegrateStep() { return true; } -bool MP4Map::stts_SlipCacheToTime(uint64 timestamp, int starting_cache_index) { +bool MP4Map::stts_SlipCacheToTime(uint64_t timestamp, + int starting_cache_index) { DCHECK_LT(starting_cache_index, stts_timestamps_.size()); int cache_index = starting_cache_index; for (; cache_index + 1 < stts_timestamps_.size(); cache_index++) { @@ -1122,7 +1149,7 @@ bool MP4Map::stts_SlipCacheToTime(uint64 timestamp, int starting_cache_index) { stts_first_sample_time_ = stts_timestamps_[cache_index]; stts_table_index_ = cache_index * stts_->GetCacheSizeEntries(); // read sample count and duration to set next values - uint32 sample_count; + uint32_t sample_count; if (!stts_->ReadU32PairEntry(stts_table_index_, &sample_count, &stts_sample_duration_)) { return false; @@ -1133,7 +1160,8 @@ bool MP4Map::stts_SlipCacheToTime(uint64 timestamp, int starting_cache_index) { return true; } -bool MP4Map::stsz_Init() { return stsz_->GetBytesAtEntry(0) != NULL; } +bool MP4Map::stsz_Init() { + return stsz_->GetBytesAtEntry(0) != NULL; +} } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/mp4_map.h b/media/starboard/progressive/mp4_map.h index 0678fc42bc5..626ff845803 100644 --- a/media/starboard/progressive/mp4_map.h +++ b/media/starboard/progressive/mp4_map.h @@ -12,16 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_MP4_MAP_H_ -#define COBALT_MEDIA_PROGRESSIVE_MP4_MAP_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_MP4_MAP_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_MP4_MAP_H_ #include -#include "base/callback.h" +#include "base/functional/callback.h" #include "base/memory/ref_counted.h" -#include "cobalt/media/progressive/data_source_reader.h" +#include "media/starboard/progressive/data_source_reader.h" -namespace cobalt { namespace media { // per-atom sizes of individual table entries @@ -45,57 +44,58 @@ class MP4Map : public base::RefCountedThreadSafe { // All Get() methods return true on success and save their values by // reference in the latter argument. - bool GetSize(uint32 sample_number, uint32* size_out); - bool GetOffset(uint32 sample_number, uint64* offset_out); + bool GetSize(uint32_t sample_number, uint32_t* size_out); + bool GetOffset(uint32_t sample_number, uint64_t* offset_out); // all time values in *ticks* as defined by the mp4 container - bool GetTimestamp(uint32 sample_number, uint64* timestamp_out); - bool GetDuration(uint32 sample_number, uint32* duration_out); - bool GetIsKeyframe(uint32 sample_number, bool* is_keyframe_out); + bool GetTimestamp(uint32_t sample_number, uint64_t* timestamp_out); + bool GetDuration(uint32_t sample_number, uint32_t* duration_out); + bool GetIsKeyframe(uint32_t sample_number, bool* is_keyframe_out); // Used to determine if the failure reported by any of the above methods // is due to EOS or other (fatal) error. The length of a mp4 file in samples // may not be known until iterating through almost the entire map, in the // case of a default sample size (rare in compressed media) - bool IsEOS(uint32 sample_number); + bool IsEOS(uint32_t sample_number); // Returns the keyframe sample number nearest the provided timestamp - bool GetKeyframe(uint64 timestamp, uint32* sample_out); + bool GetKeyframe(uint64_t timestamp, uint32_t* sample_out); // pass 0 as cache_size_entries to force caching of the entire map. - bool SetAtom(uint32 four_cc, // fourCC code ascii code as big-endian uint32 - uint64 offset, // offset of atom body in file - uint64 size, // total size of atom in bytes - uint32 cache_size_entries, // num of entries to cache in memory - const uint8* atom); // pointer to atom body start + bool SetAtom( + uint32_t four_cc, // fourCC code ascii code as big-endian uint32_t + uint64_t offset, // offset of atom body in file + uint64_t size, // total size of atom in bytes + uint32_t cache_size_entries, // num of entries to cache in memory + const uint8_t* atom); // pointer to atom body start private: bool co64_Init(); bool ctts_Init(); // advance the ctts cache and integration state to contain sample number. - bool ctts_AdvanceToSample(uint32 sample_number); - bool ctts_SlipCacheToSample(uint32 sample_number, int starting_cache_index); + bool ctts_AdvanceToSample(uint32_t sample_number); + bool ctts_SlipCacheToSample(uint32_t sample_number, int starting_cache_index); bool stco_Init(); bool stsc_Init(); // advance the stsc cache and integration state to contain sample number. - bool stsc_AdvanceToSample(uint32 sample_number); - // re-use previously calculated sums to jump through the table to get to the + bool stsc_AdvanceToSample(uint32_t sample_number); + // reuse previously calculated sums to jump through the table to get to the // nearest cache entry that contains given sample number. Starts the search // from the starting_cache_index. - bool stsc_SlipCacheToSample(uint32 sample_number, int starting_cache_index); + bool stsc_SlipCacheToSample(uint32_t sample_number, int starting_cache_index); bool stss_Init(); // step through table by one table entry, return false on error bool stss_AdvanceStep(); // search for nearest keyframe, update state to contain it - bool stss_FindNearestKeyframe(uint32 sample_number); + bool stss_FindNearestKeyframe(uint32_t sample_number); bool stts_Init(); - bool stts_AdvanceToSample(uint32 sample_number); - bool stts_SlipCacheToSample(uint32 sample_number, int starting_cache_index); - bool stts_AdvanceToTime(uint64 timestamp); - bool stts_SlipCacheToTime(uint64 timestamp, int starting_cache_index); + bool stts_AdvanceToSample(uint32_t sample_number); + bool stts_SlipCacheToSample(uint32_t sample_number, int starting_cache_index); + bool stts_AdvanceToTime(uint64_t timestamp); + bool stts_SlipCacheToTime(uint64_t timestamp, int starting_cache_index); // step through the stts table by one table entry, return false on error bool stts_IntegrateStep(); @@ -113,102 +113,106 @@ class MP4Map : public base::RefCountedThreadSafe { // calculated from entry_number / cache_size_entries. class TableCache : public base::RefCountedThreadSafe { public: - TableCache(uint64 table_offset, // byte offset of start of table in file - uint32 entry_count, // number of entries in table - uint32 entry_size, // size in bytes of each entry in table - uint32 cache_size_entries, // number of entries to cache in mem - scoped_refptr reader); // reader to use + TableCache( + uint64_t table_offset, // byte offset of start of table in file + uint32_t entry_count, // number of entries in table + uint32_t entry_size, // size in bytes of each entry in table + uint32_t cache_size_entries, // number of entries to cache in mem + scoped_refptr reader); // reader to use // The following Read* functions all read values in big endian. - bool ReadU32Entry(uint32 entry_number, uint32* entry); - bool ReadU32PairEntry(uint32 entry_number, uint32* first, uint32* second); - bool ReadU32EntryIntoU64(uint32 entry_number, uint64* entry); - bool ReadU64Entry(uint32 entry_number, uint64* entry); + bool ReadU32Entry(uint32_t entry_number, uint32_t* entry); + bool ReadU32PairEntry(uint32_t entry_number, + uint32_t* first, + uint32_t* second); + bool ReadU32EntryIntoU64(uint32_t entry_number, uint64_t* entry); + bool ReadU64Entry(uint32_t entry_number, uint64_t* entry); - uint8* GetBytesAtEntry(uint32 entry_number); + uint8_t* GetBytesAtEntry(uint32_t entry_number); // how many entries total in the table? - inline uint32 GetEntryCount() const { return entry_count_; } + inline uint32_t GetEntryCount() const { return entry_count_; } // how many entries are we caching in memory at once? - inline uint32 GetCacheSizeEntries() const { return cache_size_entries_; } + inline uint32_t GetCacheSizeEntries() const { return cache_size_entries_; } private: friend class base::RefCountedThreadSafe; - uint32 entry_size_; // size of entry in bytes - uint32 entry_count_; // size of table in entries - uint32 cache_size_entries_; // max number of entries to fit in memory - uint64 table_offset_; // offset of table in stream + uint32_t entry_size_; // size of entry in bytes + uint32_t entry_count_; // size of table in entries + uint32_t cache_size_entries_; // max number of entries to fit in memory + uint64_t table_offset_; // offset of table in stream scoped_refptr reader_; // means to read more table // current cache state - std::vector cache_; // the cached part of the table - uint32 cache_first_entry_number_; // first table entry number in cache - uint32 cache_entry_count_; // number of valid entries in cache + std::vector cache_; // the cached part of the table + uint32_t cache_first_entry_number_; // first table entry number in cache + uint32_t cache_entry_count_; // number of valid entries in cache }; scoped_refptr reader_; // current integration state for GetOffset(), we save the sum of sample sizes // within the current chunk. - uint32 current_chunk_sample_; // sample number last included in summation - uint32 next_chunk_sample_; // first sample number of next chunk - uint64 current_chunk_offset_; // file byte offset of current_chunk_sample_ + uint32_t current_chunk_sample_; // sample number last included in summation + uint32_t next_chunk_sample_; // first sample number of next chunk + uint64_t current_chunk_offset_; // file byte offset of current_chunk_sample_ // Can be set by a stsz entry count but an stsz may provide a default size, // in which case this number may not be known until iteration through // the ctts, or stts has completed. In the event that one of those tables // ends at a lower number than the others this number will be amended // to return the lower number. - uint32 highest_valid_sample_number_; + uint32_t highest_valid_sample_number_; // ==== c064 - per-chunk list of file offsets (64-bit) scoped_refptr co64_; // ==== ctts - run-length sample number to composition time offset scoped_refptr ctts_; - uint32 ctts_first_sample_; - uint32 ctts_sample_offset_; - uint32 ctts_next_first_sample_; - uint32 ctts_table_index_; - std::vector ctts_samples_; + uint32_t ctts_first_sample_; + uint32_t ctts_sample_offset_; + uint32_t ctts_next_first_sample_; + uint32_t ctts_table_index_; + std::vector ctts_samples_; // ==== stco - per-chunk list of chunk file offsets (32-bit) scoped_refptr stco_; // ==== stsc - chunk-number to samples-per-chunk scoped_refptr stsc_; - uint32 stsc_first_chunk_; // first chunk of the current sample size range - uint32 stsc_first_chunk_sample_; // sum of samples of all prev chunk ranges - uint32 stsc_samples_per_chunk_; // current samples-per-chunk in this range - uint32 stsc_next_first_chunk_; // the chunk number the next region begins in - uint32 stsc_next_first_chunk_sample_; // sample number next region begins in - uint32 stsc_table_index_; // the index in the table of the current range - std::vector stsc_sample_sums_; // saved sums of cache segments + uint32_t stsc_first_chunk_; // first chunk of the current sample size range + uint32_t stsc_first_chunk_sample_; // sum of samples of all prev chunk ranges + uint32_t stsc_samples_per_chunk_; // current samples-per-chunk in this range + uint32_t + stsc_next_first_chunk_; // the chunk number the next region begins in + uint32_t + stsc_next_first_chunk_sample_; // sample number next region begins in + uint32_t stsc_table_index_; // the index in the table of the current range + std::vector stsc_sample_sums_; // saved sums of cache segments // ==== stss - list of keyframe sample numbers scoped_refptr stss_; - uint32 stss_last_keyframe_; - uint32 stss_next_keyframe_; - uint32 stss_table_index_; // index of stss_next_keyframe_ in table - std::vector stss_keyframes_; + uint32_t stss_last_keyframe_; + uint32_t stss_next_keyframe_; + uint32_t stss_table_index_; // index of stss_next_keyframe_ in table + std::vector stss_keyframes_; // ==== stts - run-length sample number to time duration scoped_refptr stts_; - uint32 stts_first_sample_; // first sample of the current duration range - uint64 stts_first_sample_time_; // sum of all durations of previous ranges - uint32 stts_sample_duration_; // current duration of samples in this range - uint32 stts_next_first_sample_; // first sample number of next range - uint64 stts_next_first_sample_time_; // first timestamp of next range - uint32 stts_table_index_; // index in the table of the next entry - std::vector stts_samples_; - std::vector stts_timestamps_; + uint32_t stts_first_sample_; // first sample of the current duration range + uint64_t stts_first_sample_time_; // sum of all durations of previous ranges + uint32_t stts_sample_duration_; // current duration of samples in this range + uint32_t stts_next_first_sample_; // first sample number of next range + uint64_t stts_next_first_sample_time_; // first timestamp of next range + uint32_t stts_table_index_; // index in the table of the next entry + std::vector stts_samples_; + std::vector stts_timestamps_; // ==== stsz - per-sample list of sample sizes scoped_refptr stsz_; - uint32 stsz_default_size_; + uint32_t stsz_default_size_; }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_MP4_MAP_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_MP4_MAP_H_ diff --git a/media/starboard/progressive/mp4_map_unittest.cc b/media/starboard/progressive/mp4_map_unittest.cc index 38cf9ebc694..23ccbe1aa67 100644 --- a/media/starboard/progressive/mp4_map_unittest.cc +++ b/media/starboard/progressive/mp4_map_unittest.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/mp4_map.h" +#include "media/starboard/progressive/mp4_map.h" #include // for rand and srand @@ -22,33 +22,17 @@ #include #include -#include "cobalt/media/base/endian_util.h" -#include "cobalt/media/progressive/mock_data_source_reader.h" -#include "cobalt/media/progressive/mp4_parser.h" +#include "media/starboard/progressive/endian_util.h" +#include "media/starboard/progressive/mock_data_source_reader.h" +#include "media/starboard/progressive/mp4_parser.h" +#include "starboard/memory.h" #include "starboard/types.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using cobalt::media::endian_util::load_uint32_big_endian; -using cobalt::media::endian_util::store_uint32_big_endian; -using cobalt::media::endian_util::store_uint64_big_endian; - -using cobalt::media::kAtomType_co64; -using cobalt::media::kAtomType_ctts; -using cobalt::media::kAtomType_stco; -using cobalt::media::kAtomType_stsc; -using cobalt::media::kAtomType_stss; -using cobalt::media::kAtomType_stsz; -using cobalt::media::kAtomType_stts; -using cobalt::media::kEntrySize_co64; -using cobalt::media::kEntrySize_ctts; -using cobalt::media::kEntrySize_stco; -using cobalt::media::kEntrySize_stsc; -using cobalt::media::kEntrySize_stss; -using cobalt::media::kEntrySize_stsz; -using cobalt::media::kEntrySize_stts; -using cobalt::media::MockDataSourceReader; -using cobalt::media::MP4Map; +using endian_util::load_uint32_big_endian; +using endian_util::store_uint32_big_endian; +using endian_util::store_uint64_big_endian; using ::testing::_; using ::testing::AllOf; @@ -62,7 +46,9 @@ using ::testing::SetArrayArgument; namespace { -int RandomRange(int min, int max) { return min + rand() % (max - min + 1); } +int RandomRange(int min, int max) { + return min + rand() % (max - min + 1); +} // Data structure represent a sample inside stbl. It has redundant data for // easy access. @@ -82,10 +68,15 @@ class SampleTable { public: // All ranges are inclusive at both ends. // Set range of composition timestamp to [0, 0] to disable ctts. - SampleTable(unsigned int seed, int num_of_samples, int min_sample_size, - int max_sample_size, int min_samples_per_chunk, - int max_samples_per_chunk, int min_key_frame_gap, - int max_key_frame_gap, int min_sample_decode_timestamp_offset, + SampleTable(unsigned int seed, + int num_of_samples, + int min_sample_size, + int max_sample_size, + int min_samples_per_chunk, + int max_samples_per_chunk, + int min_key_frame_gap, + int max_key_frame_gap, + int min_sample_decode_timestamp_offset, int max_sample_decode_timestamp_offset, int min_sample_composition_timestamp_offset, int max_sample_composition_timestamp_offset) @@ -228,7 +219,9 @@ class SampleTable { const uint8_t* data = GetBoxData(boxes[i]); for (int64 j = 0; j < size; ++j) { ss << static_cast(data[j]) << ' '; - if (j != 0 && j % 32 == 0) ss << '\n'; + if (j != 0 && j % 32 == 0) { + ss << '\n'; + } } } LOG(INFO) << ss.str(); @@ -271,9 +264,15 @@ class SampleTable { for (SampleVector::const_iterator iter = samples_.begin(); iter != samples_.end(); ++iter) { - if (!iter->is_key_frame) all_key_frames = false; - if (iter->dts != iter->cts) all_ctts_offset_is_zero = false; - if (iter->size != samples_[0].size) all_sample_has_same_size = false; + if (!iter->is_key_frame) { + all_key_frames = false; + } + if (iter->dts != iter->cts) { + all_ctts_offset_is_zero = false; + } + if (iter->size != samples_[0].size) { + all_sample_has_same_size = false; + } } // populate the stsz box: 4 bytes flags + 4 bytes default size @@ -353,8 +352,9 @@ class SampleTable { } } store_uint32_big_endian((stts_.size() - 8) / kEntrySize_stts, &stts_[4]); - if (!all_ctts_offset_is_zero) + if (!all_ctts_offset_is_zero) { store_uint32_big_endian((ctts_.size() - 8) / kEntrySize_ctts, &ctts_[4]); + } // populate stss box // stss = 4 bytes count + (4 bytes sample index)* @@ -373,8 +373,9 @@ class SampleTable { const int kGarbageSize = 1024; std::vector garbage; garbage.reserve(kGarbageSize); - for (int i = 0; i < kGarbageSize; ++i) + for (int i = 0; i < kGarbageSize; ++i) { garbage.push_back(RandomRange(0xef, 0xfe)); + } combined_.insert(combined_.end(), garbage.begin(), garbage.end()); combined_.insert(combined_.end(), stsz_.begin(), stsz_.end()); combined_.insert(combined_.end(), garbage.begin(), garbage.end()); @@ -422,10 +423,13 @@ class MP4MapTest : public testing::Test { void ResetMap() { map_ = new MP4Map(reader_); } - void CreateTestSampleTable(unsigned int seed, int num_of_samples, - int min_sample_size, int max_sample_size, + void CreateTestSampleTable(unsigned int seed, + int num_of_samples, + int min_sample_size, + int max_sample_size, int min_samples_per_chunk, - int max_samples_per_chunk, int min_key_frame_gap, + int max_samples_per_chunk, + int min_key_frame_gap, int max_key_frame_gap, int min_sample_decode_timestamp_offset, int max_sample_decode_timestamp_offset, @@ -532,9 +536,10 @@ TEST_F(MP4MapTest, GetSizeIterationTinyCache) { } ASSERT_LE(sample_table_->read_count(), sample_table_->sample_count() / i + 1); - if (sample_table_->read_count()) + if (sample_table_->read_count()) { ASSERT_LE(sample_table_->read_bytes() / sample_table_->read_count(), (i + 1) * kEntrySize_stsz); + } // call to sample past the table size should still fail uint32 failed_size = 0; ASSERT_FALSE(map_->GetSize(sample_table_->sample_count(), &failed_size)); @@ -944,7 +949,9 @@ TEST_F(MP4MapTest, GetIsKeyframeRandomAccess) { // pick a keyframe about halfway uint32 sample_number = sample_table_->sample_count() / 2; - while (!GetTestSample(sample_number).is_key_frame) ++sample_number; + while (!GetTestSample(sample_number).is_key_frame) { + ++sample_number; + } // sample one past it should not be a keyframe bool map_is_keyframe_out = false; ASSERT_TRUE(map_->GetIsKeyframe(sample_number + 1, &map_is_keyframe_out)); @@ -958,7 +965,9 @@ TEST_F(MP4MapTest, GetIsKeyframeRandomAccess) { // first keyframe sample_number = 0; - while (!GetTestSample(sample_number).is_key_frame) ++sample_number; + while (!GetTestSample(sample_number).is_key_frame) { + ++sample_number; + } // next sample should not be a keyframe ASSERT_TRUE(map_->GetIsKeyframe(sample_number + 1, &map_is_keyframe_out)); ASSERT_FALSE(map_is_keyframe_out); @@ -1068,13 +1077,21 @@ TEST_F(MP4MapTest, GetKeyframe) { // find a first quarter keyframe in file uint32 qtr_keyframe = sample_table_->sample_count() / 4; - while (!GetTestSample(qtr_keyframe).is_key_frame) ++qtr_keyframe; + while (!GetTestSample(qtr_keyframe).is_key_frame) { + ++qtr_keyframe; + } uint32 next_keyframe = qtr_keyframe + 1; - while (!GetTestSample(next_keyframe).is_key_frame) ++next_keyframe; + while (!GetTestSample(next_keyframe).is_key_frame) { + ++next_keyframe; + } uint32 prev_keyframe = qtr_keyframe - 1; - while (!GetTestSample(prev_keyframe).is_key_frame) --prev_keyframe; + while (!GetTestSample(prev_keyframe).is_key_frame) { + --prev_keyframe; + } uint32 last_keyframe = sample_table_->sample_count() - 1; - while (!GetTestSample(last_keyframe).is_key_frame) --last_keyframe; + while (!GetTestSample(last_keyframe).is_key_frame) { + --last_keyframe; + } // midway between this keyframe and the next one uint32 test_frame = qtr_keyframe + ((next_keyframe - qtr_keyframe) / 2); // get time for this frame diff --git a/media/starboard/progressive/mp4_parser.cc b/media/starboard/progressive/mp4_parser.cc index bc05acf2515..bb07505a9a6 100644 --- a/media/starboard/progressive/mp4_parser.cc +++ b/media/starboard/progressive/mp4_parser.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/mp4_parser.h" +#include "media/starboard/progressive/mp4_parser.h" #include @@ -20,11 +20,10 @@ #include #include "base/strings/stringprintf.h" -#include "cobalt/media/base/endian_util.h" #include "media/formats/mp4/es_descriptor.h" +#include "media/starboard/progressive/endian_util.h" #include "starboard/types.h" -namespace cobalt { namespace media { // how many bytes to skip within an avc1 before the config atoms start? @@ -38,8 +37,8 @@ static const int kFullBoxHeaderAndFlagSize = 4; // how much to download of an hdlr to get the trak type? static const int kDesiredBytes_hdlr = 12; -static const uint32 kAudioSubtype_hdlr_soun = 0x736f756e; -static const uint32 kVideoSubtype_hdlr_vide = 0x76696465; +static const uint32_t kAudioSubtype_hdlr_soun = 0x736f756e; +static const uint32_t kVideoSubtype_hdlr_vide = 0x76696465; // how much to download of an mp4a to determine version number? static const int kDesiredBytes_mp4a = 2; @@ -68,34 +67,36 @@ static const int kMapTableAtomCacheEntries_co64 = 740212 / kEntrySize_co64; static const int kMapTableAtomCacheEntries_ctts = 51543 / kEntrySize_ctts; // static -::media::PipelineStatus MP4Parser::Construct( - scoped_refptr reader, const uint8* construction_header, - scoped_refptr* parser, MediaLog* media_log) { +PipelineStatus MP4Parser::Construct(scoped_refptr reader, + const uint8_t* construction_header, + scoped_refptr* parser, + MediaLog* media_log) { DCHECK(parser); DCHECK(media_log); - *parser = NULL; + *parser = nullptr; // detect mp4 stream by looking for ftyp atom at top of file - uint32 ftyp = endian_util::load_uint32_big_endian(construction_header + 4); + uint32_t ftyp = endian_util::load_uint32_big_endian(construction_header + 4); if (ftyp != kAtomType_ftyp) { // not an mp4 - return ::media::DEMUXER_ERROR_COULD_NOT_PARSE; + return DEMUXER_ERROR_COULD_NOT_PARSE; } // first 4 bytes will be the size of the ftyp atom - uint32 ftyp_atom_size = + uint32_t ftyp_atom_size = endian_util::load_uint32_big_endian(construction_header); if (ftyp_atom_size < kAtomMinSize) { - return ::media::DEMUXER_ERROR_COULD_NOT_PARSE; + return DEMUXER_ERROR_COULD_NOT_PARSE; } // construct new mp4 parser *parser = new MP4Parser(reader, ftyp_atom_size, media_log); - return ::media::PIPELINE_OK; + return PIPELINE_OK; } MP4Parser::MP4Parser(scoped_refptr reader, - uint32 ftyp_atom_size, MediaLog* media_log) + uint32_t ftyp_atom_size, + MediaLog* media_log) : AVCParser(reader, media_log), atom_offset_(ftyp_atom_size), // start at next atom, skipping over ftyp current_trak_is_video_(false), @@ -108,7 +109,7 @@ MP4Parser::MP4Parser(scoped_refptr reader, audio_sample_(0), video_sample_(0), first_audio_hole_ticks_(0), - first_audio_hole_(base::TimeDelta::FromSeconds(0)) {} + first_audio_hole_(base::Seconds(0)) {} MP4Parser::~MP4Parser() {} @@ -129,17 +130,17 @@ bool MP4Parser::ParseConfig() { } scoped_refptr MP4Parser::GetNextAU(DemuxerStream::Type type) { - uint32 size = 0; - uint32 duration_ticks = 0; - uint64 timestamp_ticks = 0; - uint64 offset = 0; + uint32_t size = 0; + uint32_t duration_ticks = 0; + uint64_t timestamp_ticks = 0; + uint64_t offset = 0; bool is_keyframe = false; base::TimeDelta timestamp; base::TimeDelta duration; if (type == DemuxerStream::AUDIO) { if (audio_time_scale_hz_ == 0) { LOG(ERROR) << "|audio_time_scale_hz_| cannot be 0."; - return NULL; + return nullptr; } if (!audio_map_->GetSize(audio_sample_, &size) || !audio_map_->GetOffset(audio_sample_, &offset) || @@ -151,7 +152,7 @@ scoped_refptr MP4Parser::GetNextAU(DemuxerStream::Type type) { audio_track_duration_); } else { LOG(ERROR) << "parsed bad audio AU"; - return NULL; + return nullptr; } } // all aac frames are random-access, so all are keyframes @@ -186,7 +187,7 @@ scoped_refptr MP4Parser::GetNextAU(DemuxerStream::Type type) { } else if (type == DemuxerStream::VIDEO) { if (video_time_scale_hz_ == 0) { LOG(ERROR) << "|video_time_scale_hz_| cannot be 0."; - return NULL; + return nullptr; } if (!video_map_->GetSize(video_sample_, &size) || !video_map_->GetOffset(video_sample_, &offset) || @@ -198,7 +199,7 @@ scoped_refptr MP4Parser::GetNextAU(DemuxerStream::Type type) { video_track_duration_); } else { LOG(ERROR) << "parsed bad video AU"; - return NULL; + return nullptr; } } video_sample_++; @@ -212,14 +213,15 @@ scoped_refptr MP4Parser::GetNextAU(DemuxerStream::Type type) { duration += one_video_tick_; } else { NOTREACHED() << "unsupported stream type"; - return NULL; + return nullptr; } size_t prepend_size = CalculatePrependSize(type, is_keyframe); - if (type == DemuxerStream::AUDIO) + if (type == DemuxerStream::AUDIO) { return AvcAccessUnit::CreateAudioAU(offset, size, prepend_size, is_keyframe, timestamp, duration, this); + } return AvcAccessUnit::CreateVideoAU(offset, size, prepend_size, nal_header_size_, is_keyframe, timestamp, duration, this); @@ -235,20 +237,20 @@ bool MP4Parser::SeekTo(base::TimeDelta timestamp) { } // get video timestamp in video time units - uint64 video_ticks = TimeToTicks(timestamp, video_time_scale_hz_); + uint64_t video_ticks = TimeToTicks(timestamp, video_time_scale_hz_); // find nearest keyframe from map, make it our next video sample if (!video_map_->GetKeyframe(video_ticks, &video_sample_)) { return false; } // get the timestamp for this video keyframe - uint64 video_keyframe_time_ticks = 0; + uint64_t video_keyframe_time_ticks = 0; if (!video_map_->GetTimestamp(video_sample_, &video_keyframe_time_ticks)) { return false; } base::TimeDelta video_keyframe_time = TicksToTime(video_keyframe_time_ticks, video_time_scale_hz_); // find the closest audio frame that bounds that timestamp - uint64 audio_ticks = TimeToTicks(video_keyframe_time, audio_time_scale_hz_); + uint64_t audio_ticks = TimeToTicks(video_keyframe_time, audio_time_scale_hz_); if (!audio_map_->GetKeyframe(audio_ticks, &audio_sample_)) { return false; } @@ -268,21 +270,22 @@ bool MP4Parser::SeekTo(base::TimeDelta timestamp) { // return false on fatal error. General structure of an MP4 atom is: // field | type | comment // ------------------+--------+--------- -// atom size | uint32 | if 0 means "rest of file", if 1 means extended -// fourCC code | ASCII | four-byte ASCII code we treat as uint32 -// extended size | uint64 | optional size field, only here if atom size is 1 +// atom size | uint32_t | if 0 means "rest of file", if 1 means extended +// fourCC code | ASCII | four-byte ASCII code we treat as uint32_t +// extended size | uint64_t | optional size field, only here if atom size is +// 1 // <--- rest of atom body starts here bool MP4Parser::ParseNextAtom() { - uint8 atom[kAtomDownload]; + uint8_t atom[kAtomDownload]; int bytes_read = reader_->BlockingRead(atom_offset_, kAtomDownload, atom); if (bytes_read < kAtomDownload) { return false; } - // first 4 bytes are size of atom uint32 - uint64 atom_size = - static_cast(endian_util::load_uint32_big_endian(atom)); + // first 4 bytes are size of atom uint32_t + uint64_t atom_size = + static_cast(endian_util::load_uint32_big_endian(atom)); // normally atom body starts just past fourCC code - uint32 atom_body = kAtomMinSize; + uint32_t atom_body = kAtomMinSize; // if 1 we need to load the extended size which will be appended just past // the fourCC code if (atom_size == 1) { @@ -292,8 +295,8 @@ bool MP4Parser::ParseNextAtom() { } else if (atom_size == 0) { // calculate size of this atom from remainder of file DCHECK_LE(atom_offset_, - static_cast(std::numeric_limits::max())); - if (reader_->FileSize() > static_cast(atom_offset_)) { + static_cast(std::numeric_limits::max())); + if (reader_->FileSize() > static_cast(atom_offset_)) { atom_size = reader_->FileSize() - atom_offset_; } } @@ -306,15 +309,15 @@ bool MP4Parser::ParseNextAtom() { return false; } - // extract fourCC code as big-endian uint32 - uint32 four_cc = endian_util::load_uint32_big_endian(atom + 4); + // extract fourCC code as big-endian uint32_t + uint32_t four_cc = endian_util::load_uint32_big_endian(atom + 4); LOG(INFO) << base::StringPrintf("four_cc: %c%c%c%c", atom[4], atom[5], atom[6], atom[7]); // advance read pointer to atom body atom_offset_ += atom_body; // adjust size of body of atom from size of header - uint64 atom_data_size = atom_size - atom_body; + uint64_t atom_data_size = atom_size - atom_body; bool atom_parse_success = true; @@ -336,7 +339,9 @@ bool MP4Parser::ParseNextAtom() { case kAtomType_avcC: atom_parse_success = DownloadAndParseAVCConfigRecord(atom_offset_, atom_data_size); - if (atom_parse_success) atom_offset_ += atom_data_size; + if (atom_parse_success) { + atom_offset_ += atom_data_size; + } break; // esds atoms contain actually usable audio configuration info for AAC. @@ -460,7 +465,7 @@ bool MP4Parser::ParseNextAtom() { return atom_parse_success; } -bool MP4Parser::ParseMP4_esds(uint64 atom_data_size) { +bool MP4Parser::ParseMP4_esds(uint64_t atom_data_size) { if (atom_data_size < kFullBoxHeaderAndFlagSize) { LOG(WARNING) << base::StringPrintf( "esds box should at least be %d bytes but now it is %" PRId64 " bytes", @@ -468,25 +473,25 @@ bool MP4Parser::ParseMP4_esds(uint64 atom_data_size) { return false; } - uint64 esds_offset = atom_offset_ + kFullBoxHeaderAndFlagSize; - uint64 esds_size = atom_data_size - kFullBoxHeaderAndFlagSize; + uint64_t esds_offset = atom_offset_ + kFullBoxHeaderAndFlagSize; + uint64_t esds_size = atom_data_size - kFullBoxHeaderAndFlagSize; if (esds_size == 0) { return false; } // we'll need to download entire esds, allocate buffer for it - std::vector esds_storage(esds_size); - uint8* esds = &esds_storage[0]; + std::vector esds_storage(esds_size); + uint8_t* esds = &esds_storage[0]; // download esds int bytes_read = reader_->BlockingRead(esds_offset, esds_size, esds); if (bytes_read < esds_size) { LOG(WARNING) << "failed to download esds"; return false; } - ::media::mp4::ESDescriptor es_descriptor; - std::vector data(esds, esds + esds_size); + mp4::ESDescriptor es_descriptor; + std::vector data(esds, esds + esds_size); if (es_descriptor.Parse(data)) { - const std::vector& dsi = es_descriptor.decoder_specific_info(); + const std::vector& dsi = es_descriptor.decoder_specific_info(); if (dsi.size() >= 2) { ParseAudioSpecificConfig(dsi[0], dsi[1]); atom_offset_ += atom_data_size; @@ -500,7 +505,7 @@ bool MP4Parser::ParseMP4_esds(uint64 atom_data_size) { return false; } -bool MP4Parser::ParseMP4_hdlr(uint64 atom_data_size, uint8* hdlr) { +bool MP4Parser::ParseMP4_hdlr(uint64_t atom_data_size, uint8_t* hdlr) { // ensure we're downloading enough of the hdlr to parse DCHECK_LE(kDesiredBytes_hdlr + 16, kAtomDownload); // sanity-check for minimum size @@ -511,7 +516,7 @@ bool MP4Parser::ParseMP4_hdlr(uint64 atom_data_size, uint8* hdlr) { } // last 4 bytes of the 12 we need are an ascii code for the trak type, we // want 'vide' for video or 'soun' for audio. ignore the rest. - uint32 hdlr_subtype = endian_util::load_uint32_big_endian(hdlr + 8); + uint32_t hdlr_subtype = endian_util::load_uint32_big_endian(hdlr + 8); // update state flags current_trak_is_video_ = (hdlr_subtype == kVideoSubtype_hdlr_vide); current_trak_is_audio_ = (hdlr_subtype == kAudioSubtype_hdlr_soun); @@ -520,8 +525,7 @@ bool MP4Parser::ParseMP4_hdlr(uint64 atom_data_size, uint8* hdlr) { video_time_scale_hz_ = current_trak_time_scale_; current_trak_time_scale_ = 0; video_track_duration_ = current_trak_duration_; - one_video_tick_ = - base::TimeDelta::FromMicroseconds(1000000 / video_time_scale_hz_); + one_video_tick_ = base::Microseconds(1000000 / video_time_scale_hz_); } if (current_trak_time_scale_ > 0 && current_trak_is_audio_) { audio_time_scale_hz_ = current_trak_time_scale_; @@ -533,20 +537,21 @@ bool MP4Parser::ParseMP4_hdlr(uint64 atom_data_size, uint8* hdlr) { return true; } -bool MP4Parser::ParseMP4_mdhd(uint64 atom_data_size, uint8* mdhd) { +bool MP4Parser::ParseMP4_mdhd(uint64_t atom_data_size, uint8_t* mdhd) { DCHECK_LE(kDesiredBytes_mdhd + 16, kAtomDownload); if (atom_data_size < kDesiredBytes_mdhd) { LOG(WARNING) << base::StringPrintf("bad size %" PRId64 " on mdhd", atom_data_size); return false; } - uint32 time_scale = endian_util::load_uint32_big_endian(mdhd + 12); + uint32_t time_scale = endian_util::load_uint32_big_endian(mdhd + 12); if (time_scale == 0) { LOG(WARNING) << "got 0 time scale for mvhd"; return false; } // double-check track duration, it may be different from the movie duration - uint32 track_duration_ticks = endian_util::load_uint32_big_endian(mdhd + 16); + uint32_t track_duration_ticks = + endian_util::load_uint32_big_endian(mdhd + 16); base::TimeDelta track_duration = TicksToTime(track_duration_ticks, time_scale); if (track_duration > duration_) { @@ -560,8 +565,7 @@ bool MP4Parser::ParseMP4_mdhd(uint64 atom_data_size, uint8* mdhd) { video_time_scale_hz_ = time_scale; current_trak_time_scale_ = 0; video_track_duration_ = track_duration; - one_video_tick_ = - base::TimeDelta::FromMicroseconds(1000000 / video_time_scale_hz_); + one_video_tick_ = base::Microseconds(1000000 / video_time_scale_hz_); } else if (current_trak_is_audio_) { audio_time_scale_hz_ = time_scale; current_trak_time_scale_ = 0; @@ -576,7 +580,7 @@ bool MP4Parser::ParseMP4_mdhd(uint64 atom_data_size, uint8* mdhd) { return true; } -bool MP4Parser::ParseMP4_mp4a(uint64 atom_data_size, uint8* mp4a) { +bool MP4Parser::ParseMP4_mp4a(uint64_t atom_data_size, uint8_t* mp4a) { DCHECK_LE(kDesiredBytes_mp4a + 16, kAtomDownload); // we only need the first two bytes of the header, which details the version // number of this atom, which tells us the size of the rest of the header, @@ -586,7 +590,7 @@ bool MP4Parser::ParseMP4_mp4a(uint64 atom_data_size, uint8* mp4a) { atom_data_size); return false; } - uint16 mp4a_version = endian_util::load_uint16_big_endian(mp4a); + uint16_t mp4a_version = endian_util::load_uint16_big_endian(mp4a); switch (mp4a_version) { case 0: atom_offset_ += kTotalSize_mp4a_v0; @@ -618,7 +622,7 @@ bool MP4Parser::ParseMP4_mp4a(uint64 atom_data_size, uint8* mp4a) { // 12 | time scale | 4 // 16 | duration: | 4 // -bool MP4Parser::ParseMP4_mvhd(uint64 atom_data_size, uint8* mvhd) { +bool MP4Parser::ParseMP4_mvhd(uint64_t atom_data_size, uint8_t* mvhd) { DCHECK_LE(kDesiredBytes_mvhd + 16, kAtomDownload); // it should be at least long enough for us to extract the parts we want if (atom_data_size < kDesiredBytes_mvhd) { @@ -626,13 +630,13 @@ bool MP4Parser::ParseMP4_mvhd(uint64 atom_data_size, uint8* mvhd) { atom_data_size); return false; } - uint32 time_scale_hz = endian_util::load_uint32_big_endian(mvhd + 12); + uint32_t time_scale_hz = endian_util::load_uint32_big_endian(mvhd + 12); if (time_scale_hz == 0) { LOG(WARNING) << "got 0 time scale for mvhd"; return false; } // duration is in units of the time scale we just extracted - uint64 duration_ticks = endian_util::load_uint32_big_endian(mvhd + 16); + uint64_t duration_ticks = endian_util::load_uint32_big_endian(mvhd + 16); // calculate actual duration from that and the time scale duration_ = TicksToTime(duration_ticks, time_scale_hz); // advance read position @@ -640,17 +644,16 @@ bool MP4Parser::ParseMP4_mvhd(uint64 atom_data_size, uint8* mvhd) { return true; } -base::TimeDelta MP4Parser::TicksToTime(uint64 ticks, uint32 time_scale_hz) { +base::TimeDelta MP4Parser::TicksToTime(uint64_t ticks, uint32_t time_scale_hz) { DCHECK_NE(time_scale_hz, 0); if (time_scale_hz == 0) { - return base::TimeDelta::FromSeconds(0); + return base::Seconds(0); } - return base::TimeDelta::FromMicroseconds((ticks * 1000000ULL) / - time_scale_hz); + return base::Microseconds((ticks * 1000000ULL) / time_scale_hz); } -uint64 MP4Parser::TimeToTicks(base::TimeDelta time, uint32 time_scale_hz) { +uint64_t MP4Parser::TimeToTicks(base::TimeDelta time, uint32_t time_scale_hz) { DCHECK_NE(time_scale_hz, 0); if (time_scale_hz == 0) { @@ -660,4 +663,3 @@ uint64 MP4Parser::TimeToTicks(base::TimeDelta time, uint32 time_scale_hz) { } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/mp4_parser.h b/media/starboard/progressive/mp4_parser.h index 49d6bd7d872..5ecf26adae4 100644 --- a/media/starboard/progressive/mp4_parser.h +++ b/media/starboard/progressive/mp4_parser.h @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_MP4_PARSER_H_ -#define COBALT_MEDIA_PROGRESSIVE_MP4_PARSER_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_MP4_PARSER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_MP4_PARSER_H_ -#include "cobalt/media/progressive/avc_parser.h" -#include "cobalt/media/progressive/mp4_map.h" #include "media/base/media_log.h" +#include "media/starboard/progressive/avc_parser.h" +#include "media/starboard/progressive/mp4_map.h" -namespace cobalt { namespace media { // How many bytes to download from the start of the atom? Should be large @@ -27,36 +26,36 @@ namespace media { // second download (typically), but no larger. This is currently set at 16 // bytes for the 8 byte header + optional 8 byte size extension plus 20 bytes // for the needed values within an mvhd header. We leave this is the header so -// that MP4Map can re-use, +// that MP4Map can reuse, static const int kAtomDownload = 36; // mp4 atom fourCC codes as big-endian unsigned ints -static const uint32 kAtomType_avc1 = 0x61766331; // skip in to subatom -static const uint32 kAtomType_avcC = 0x61766343; // download and parse -static const uint32 kAtomType_co64 = 0x636f3634; // cache in table -static const uint32 kAtomType_ctts = 0x63747473; // cache in table -static const uint32 kAtomType_dinf = 0x64696e66; // skip whole atom -static const uint32 kAtomType_dref = 0x64726566; // skip whole atom -static const uint32 kAtomType_esds = 0x65736473; // download and parse -static const uint32 kAtomType_ftyp = 0x66747970; // top of the file only -static const uint32 kAtomType_hdlr = 0x68646c72; // parse first 12 bytes -static const uint32 kAtomType_mdhd = 0x6d646864; // parse first 20 bytes -static const uint32 kAtomType_mdia = 0x6d646961; // container atom, no-op -static const uint32 kAtomType_minf = 0x6d696e66; // container atom, no-op -static const uint32 kAtomType_moov = 0x6d6f6f76; // container atom, no-op -static const uint32 kAtomType_mp4a = 0x6d703461; // parse first 10 bytes -static const uint32 kAtomType_mvhd = 0x6d766864; // parse first 20 bytes -static const uint32 kAtomType_smhd = 0x736d6862; // skip whole atom -static const uint32 kAtomType_stbl = 0x7374626c; // container atom, no-op -static const uint32 kAtomType_stco = 0x7374636f; // cache in table -static const uint32 kAtomType_stts = 0x73747473; // cache in table -static const uint32 kAtomType_stsc = 0x73747363; // cache in table -static const uint32 kAtomType_stsd = 0x73747364; // skip in to subatom -static const uint32 kAtomType_stss = 0x73747373; // cache in table -static const uint32 kAtomType_stsz = 0x7374737a; // cache in table -static const uint32 kAtomType_trak = 0x7472616b; // container atom, no-op -static const uint32 kAtomType_tkhd = 0x746b6864; // skip whole atom -static const uint32 kAtomType_vmhd = 0x766d6864; // skip whole atom +static const uint32_t kAtomType_avc1 = 0x61766331; // skip in to subatom +static const uint32_t kAtomType_avcC = 0x61766343; // download and parse +static const uint32_t kAtomType_co64 = 0x636f3634; // cache in table +static const uint32_t kAtomType_ctts = 0x63747473; // cache in table +static const uint32_t kAtomType_dinf = 0x64696e66; // skip whole atom +static const uint32_t kAtomType_dref = 0x64726566; // skip whole atom +static const uint32_t kAtomType_esds = 0x65736473; // download and parse +static const uint32_t kAtomType_ftyp = 0x66747970; // top of the file only +static const uint32_t kAtomType_hdlr = 0x68646c72; // parse first 12 bytes +static const uint32_t kAtomType_mdhd = 0x6d646864; // parse first 20 bytes +static const uint32_t kAtomType_mdia = 0x6d646961; // container atom, no-op +static const uint32_t kAtomType_minf = 0x6d696e66; // container atom, no-op +static const uint32_t kAtomType_moov = 0x6d6f6f76; // container atom, no-op +static const uint32_t kAtomType_mp4a = 0x6d703461; // parse first 10 bytes +static const uint32_t kAtomType_mvhd = 0x6d766864; // parse first 20 bytes +static const uint32_t kAtomType_smhd = 0x736d6862; // skip whole atom +static const uint32_t kAtomType_stbl = 0x7374626c; // container atom, no-op +static const uint32_t kAtomType_stco = 0x7374636f; // cache in table +static const uint32_t kAtomType_stts = 0x73747473; // cache in table +static const uint32_t kAtomType_stsc = 0x73747363; // cache in table +static const uint32_t kAtomType_stsd = 0x73747364; // skip in to subatom +static const uint32_t kAtomType_stss = 0x73747373; // cache in table +static const uint32_t kAtomType_stsz = 0x7374737a; // cache in table +static const uint32_t kAtomType_trak = 0x7472616b; // container atom, no-op +static const uint32_t kAtomType_tkhd = 0x746b6864; // skip whole atom +static const uint32_t kAtomType_vmhd = 0x766d6864; // skip whole atom // TODO: mp4v!! class MP4Parser : public AVCParser { @@ -66,9 +65,12 @@ class MP4Parser : public AVCParser { // MP4Parser initialized with some basic state. If it doesn't make sense // this returns an error status and |*parser| contains NULL. static ::media::PipelineStatus Construct( - scoped_refptr reader, const uint8* construction_header, - scoped_refptr* parser, MediaLog* media_log); - MP4Parser(scoped_refptr reader, uint32 ftyp_atom_size, + scoped_refptr reader, + const uint8_t* construction_header, + scoped_refptr* parser, + MediaLog* media_log); + MP4Parser(scoped_refptr reader, + uint32_t ftyp_atom_size, MediaLog* media_log); ~MP4Parser() override; @@ -79,34 +81,33 @@ class MP4Parser : public AVCParser { private: bool ParseNextAtom(); - bool ParseMP4_esds(uint64 atom_data_size); - bool ParseMP4_hdlr(uint64 atom_data_size, uint8* hdlr); - bool ParseMP4_mdhd(uint64 atom_data_size, uint8* mdhd); - bool ParseMP4_mp4a(uint64 atom_data_size, uint8* mp4a); - bool ParseMP4_mvhd(uint64 atom_data_size, uint8* mvhd); - base::TimeDelta TicksToTime(uint64 ticks, uint32 time_scale_hz); - uint64 TimeToTicks(base::TimeDelta time, uint32 time_scale_hz); + bool ParseMP4_esds(uint64_t atom_data_size); + bool ParseMP4_hdlr(uint64_t atom_data_size, uint8_t* hdlr); + bool ParseMP4_mdhd(uint64_t atom_data_size, uint8_t* mdhd); + bool ParseMP4_mp4a(uint64_t atom_data_size, uint8_t* mp4a); + bool ParseMP4_mvhd(uint64_t atom_data_size, uint8_t* mvhd); + base::TimeDelta TicksToTime(uint64_t ticks, uint32_t time_scale_hz); + uint64_t TimeToTicks(base::TimeDelta time, uint32_t time_scale_hz); - uint64 atom_offset_; + uint64_t atom_offset_; bool current_trak_is_video_; bool current_trak_is_audio_; - uint32 current_trak_time_scale_; + uint32_t current_trak_time_scale_; base::TimeDelta current_trak_duration_; - uint32 video_time_scale_hz_; + uint32_t video_time_scale_hz_; base::TimeDelta one_video_tick_; - uint32 audio_time_scale_hz_; + uint32_t audio_time_scale_hz_; base::TimeDelta audio_track_duration_; base::TimeDelta video_track_duration_; scoped_refptr audio_map_; scoped_refptr video_map_; - uint32 audio_sample_; - uint32 video_sample_; + uint32_t audio_sample_; + uint32_t video_sample_; // for keeping buffers continuous across time scales - uint64 first_audio_hole_ticks_; + uint64_t first_audio_hole_ticks_; base::TimeDelta first_audio_hole_; }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_MP4_PARSER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_MP4_PARSER_H_ diff --git a/media/starboard/progressive/progressive_demuxer.cc b/media/starboard/progressive/progressive_demuxer.cc index 0f1acb44951..1e0cdd95b53 100644 --- a/media/starboard/progressive/progressive_demuxer.cc +++ b/media/starboard/progressive/progressive_demuxer.cc @@ -12,55 +12,44 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/progressive_demuxer.h" +#include "media/starboard/progressive/progressive_demuxer.h" #include #include -#include "base/bind.h" -#include "base/callback.h" +#include "base/functional/bind.h" +#include "base/functional/callback.h" #include "base/functional/callback_helpers.h" #include "base/strings/stringprintf.h" #include "base/task/bind_post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" -#include "cobalt/media/base/data_source.h" -#include "media/base/starboard_utils.h" +#include "media/base/data_source.h" #include "media/base/timestamp_constants.h" +#include "media/starboard/starboard_utils.h" #include "starboard/types.h" -namespace cobalt { namespace media { -namespace { - -using ::media::AudioDecoderConfig; -using ::media::kNoTimestamp; -using ::media::VideoDecoderConfig; - -} // namespace ProgressiveDemuxerStream::ProgressiveDemuxerStream(ProgressiveDemuxer* demuxer, Type type) : demuxer_(demuxer), type_(type) { - TRACE_EVENT0("media_stack", - "ProgressiveDemuxerStream::ProgressiveDemuxerStream()"); DCHECK(demuxer_); } void ProgressiveDemuxerStream::Read(uint32_t count, ReadCB read_cb) { - TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::Read()"); - DCHECK(!read_cb.is_null()); - base::AutoLock auto_lock(lock_); + DCHECK(!read_cb_); + + read_cb_ = base::BindPostTaskToCurrentDefault(std::move(read_cb)); // Don't accept any additional reads if we've been told to stop. // The demuxer_ may have been destroyed in the pipeline thread. if (stopped_) { - TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::Read() EOS sent."); - std::move(read_cb).Run(DemuxerStream::kOk, - {DecoderBuffer::CreateEOSBuffer()}); + std::move(read_cb_).Run(DemuxerStream::kOk, + {DecoderBuffer::CreateEOSBuffer()}); return; } @@ -71,18 +60,16 @@ void ProgressiveDemuxerStream::Read(uint32_t count, ReadCB read_cb) { // Send the oldest buffer back. scoped_refptr buffer = buffer_queue_.front(); if (buffer->end_of_stream()) { - TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::Read() EOS sent."); + LOG(INFO) << "media_stack ProgressiveDemuxerStream::Read() EOS sent."; } else { // Do not pop EOS buffers, so that subsequent read requests also get EOS total_buffer_size_ -= buffer->data_size(); --total_buffer_count_; buffer_queue_.pop_front(); } - std::move(read_cb).Run(DemuxerStream::kOk, {buffer}); + std::move(read_cb_).Run(DemuxerStream::kOk, {buffer}); } else { - TRACE_EVENT0("media_stack", - "ProgressiveDemuxerStream::Read() request queued."); - read_queue_.push_back(std::move(read_cb)); + read_queue_.push_back(std::move(read_cb_)); } } @@ -94,22 +81,21 @@ VideoDecoderConfig ProgressiveDemuxerStream::video_decoder_config() { return demuxer_->VideoConfig(); } -::media::Ranges ProgressiveDemuxerStream::GetBufferedRanges() { +Ranges ProgressiveDemuxerStream::GetBufferedRanges() { base::AutoLock auto_lock(lock_); return buffered_ranges_; } -::media::DemuxerStream::Type ProgressiveDemuxerStream::type() const { +DemuxerStream::Type ProgressiveDemuxerStream::type() const { return type_; } -void ProgressiveDemuxerStream::EnableBitstreamConverter() { NOTIMPLEMENTED(); } +void ProgressiveDemuxerStream::EnableBitstreamConverter() { + NOTIMPLEMENTED(); +} void ProgressiveDemuxerStream::EnqueueBuffer( scoped_refptr buffer) { - TRACE_EVENT1( - "media_stack", "ProgressiveDemuxerStream::EnqueueBuffer()", "timestamp", - buffer->end_of_stream() ? -1 : buffer->timestamp().InMicroseconds()); base::AutoLock auto_lock(lock_); if (stopped_) { // it's possible due to pipelining both downstream and within the @@ -120,8 +106,8 @@ void ProgressiveDemuxerStream::EnqueueBuffer( } if (buffer->end_of_stream()) { - TRACE_EVENT0("media_stack", - "ProgressiveDemuxerStream::EnqueueBuffer() EOS received."); + LOG(INFO) << "media_stack ProgressiveDemuxerStream::EnqueueBuffer() EOS " + "received."; } else if (buffer->timestamp() != kNoTimestamp) { if (last_buffer_timestamp_ != kNoTimestamp && last_buffer_timestamp_ < buffer->timestamp()) { @@ -165,7 +151,6 @@ size_t ProgressiveDemuxerStream::GetTotalBufferCount() const { } void ProgressiveDemuxerStream::FlushBuffers() { - TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::FlushBuffers()"); base::AutoLock auto_lock(lock_); // TODO: Investigate if the following warning is valid. LOG_IF(WARNING, !read_queue_.empty()) << "Read requests should be empty"; @@ -176,7 +161,6 @@ void ProgressiveDemuxerStream::FlushBuffers() { } void ProgressiveDemuxerStream::Stop() { - TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::Stop()"); DCHECK(demuxer_->RunsTasksInCurrentSequence()); base::AutoLock auto_lock(lock_); buffer_queue_.clear(); @@ -186,7 +170,6 @@ void ProgressiveDemuxerStream::Stop() { // fulfill any pending callbacks with EOS buffers set to end timestamp for (ReadQueue::iterator it = read_queue_.begin(); it != read_queue_.end(); ++it) { - TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::Stop() EOS sent."); std::move(*it).Run(DemuxerStream::kOk, {DecoderBuffer::CreateEOSBuffer()}); } read_queue_.clear(); @@ -198,7 +181,8 @@ void ProgressiveDemuxerStream::Stop() { // ProgressiveDemuxer::ProgressiveDemuxer( const scoped_refptr& task_runner, - DataSource* data_source, MediaLog* const media_log) + DataSource* data_source, + MediaLog* const media_log) : task_runner_(task_runner), host_(NULL), blocking_thread_("ProgDemuxerBlk"), @@ -223,7 +207,6 @@ ProgressiveDemuxer::~ProgressiveDemuxer() { void ProgressiveDemuxer::Initialize(DemuxerHost* host, PipelineStatusCallback status_cb) { - TRACE_EVENT0("media_stack", "ProgressiveDemuxer::Initialize()"); DCHECK(RunsTasksInCurrentSequence()); DCHECK(reader_); DCHECK(!parser_); @@ -240,7 +223,7 @@ void ProgressiveDemuxer::Initialize(DemuxerHost* host, // start the blocking thread and have it download and parse the media config if (!blocking_thread_.Start()) { - std::move(status_cb).Run(::media::DEMUXER_ERROR_COULD_NOT_PARSE); + std::move(status_cb).Run(DEMUXER_ERROR_COULD_NOT_PARSE); return; } @@ -259,11 +242,11 @@ void ProgressiveDemuxer::ParseConfigBlocking(PipelineStatusCallback status_cb) { // if we can't construct a parser for this stream it's a fatal error, return // false so ParseConfigDone will notify the caller to Initialize() via // status_cb. - if (!parser_ || status != ::media::PIPELINE_OK) { + if (!parser_ || status != PIPELINE_OK) { DCHECK(!parser_); - DCHECK_NE(status, ::media::PIPELINE_OK); - if (status == ::media::PIPELINE_OK) { - status = ::media::DEMUXER_ERROR_COULD_NOT_PARSE; + DCHECK_NE(status, PIPELINE_OK); + if (status == PIPELINE_OK) { + status = DEMUXER_ERROR_COULD_NOT_PARSE; } ParseConfigDone(std::move(status_cb), status); return; @@ -271,25 +254,23 @@ void ProgressiveDemuxer::ParseConfigBlocking(PipelineStatusCallback status_cb) { // instruct the parser to extract audio and video config from the file if (!parser_->ParseConfig()) { - ParseConfigDone(std::move(status_cb), - ::media::DEMUXER_ERROR_COULD_NOT_PARSE); + ParseConfigDone(std::move(status_cb), DEMUXER_ERROR_COULD_NOT_PARSE); return; } // make sure we got a valid and complete configuration if (!parser_->IsConfigComplete()) { - ParseConfigDone(std::move(status_cb), - ::media::DEMUXER_ERROR_COULD_NOT_PARSE); + ParseConfigDone(std::move(status_cb), DEMUXER_ERROR_COULD_NOT_PARSE); return; } // IsConfigComplete() should guarantee we know the duration - DCHECK(parser_->Duration() != ::media::kInfiniteDuration); + DCHECK(parser_->Duration() != kInfiniteDuration); host_->SetDuration(parser_->Duration()); // successful parse of config data, inform the nonblocking demuxer thread - DCHECK_EQ(status, ::media::PIPELINE_OK); - ParseConfigDone(std::move(status_cb), ::media::PIPELINE_OK); + DCHECK_EQ(status, PIPELINE_OK); + ParseConfigDone(std::move(status_cb), PIPELINE_OK); } void ProgressiveDemuxer::ParseConfigDone(PipelineStatusCallback status_cb, @@ -301,7 +282,7 @@ void ProgressiveDemuxer::ParseConfigDone(PipelineStatusCallback status_cb, } // if the blocking parser thread cannot parse config we're done. - if (status != ::media::PIPELINE_OK) { + if (status != PIPELINE_OK) { std::move(status_cb).Run(status); return; } @@ -309,14 +290,14 @@ void ProgressiveDemuxer::ParseConfigDone(PipelineStatusCallback status_cb, // start downloading data Request(DemuxerStream::AUDIO); - std::move(status_cb).Run(::media::PIPELINE_OK); + std::move(status_cb).Run(PIPELINE_OK); } void ProgressiveDemuxer::Request(DemuxerStream::Type type) { if (!blocking_thread_.task_runner()->RunsTasksInCurrentSequence()) { blocking_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&ProgressiveDemuxer::Request, base::Unretained(this), type)); + FROM_HERE, base::BindRepeating(&ProgressiveDemuxer::Request, + base::Unretained(this), type)); return; } @@ -328,7 +309,7 @@ void ProgressiveDemuxer::Request(DemuxerStream::Type type) { if (!au || !au->IsValid()) { if (!HasStopCalled()) { LOG(ERROR) << "got back bad AU from parser"; - host_->OnDemuxerError(::media::DEMUXER_ERROR_COULD_NOT_PARSE); + host_->OnDemuxerError(DEMUXER_ERROR_COULD_NOT_PARSE); } return; } @@ -336,14 +317,10 @@ void ProgressiveDemuxer::Request(DemuxerStream::Type type) { // make sure we got back an AU of the correct type DCHECK(au->GetType() == type); - const char* ALLOW_UNUSED_TYPE event_type = - type == DemuxerStream::AUDIO ? "audio" : "video"; - TRACE_EVENT2("media_stack", "ProgressiveDemuxer::RequestTask()", "type", - event_type, "timestamp", au->GetTimestamp().InMicroseconds()); + const char* event_type = type == DemuxerStream::AUDIO ? "audio" : "video"; // don't issue allocation requests for EOS AUs if (au->IsEndOfStream()) { - TRACE_EVENT0("media_stack", "ProgressiveDemuxer::RequestTask() EOS sent"); // enqueue EOS buffer with correct stream scoped_refptr eos_buffer = DecoderBuffer::CreateEOSBuffer(); if (type == DemuxerStream::AUDIO) { @@ -381,20 +358,19 @@ void ProgressiveDemuxer::AllocateBuffer() { MediaVideoCodecToSbMediaVideoCodec(VideoConfig().codec()), VideoConfig().visible_rect().size().width(), VideoConfig().visible_rect().size().height(), kBitDepth); - base::TimeDelta progressive_duration_cap = - base::TimeDelta::FromMicroseconds( - SbMediaGetBufferGarbageCollectionDurationThreshold()); + base::TimeDelta progressive_duration_cap = base::Microseconds( + SbMediaGetBufferGarbageCollectionDurationThreshold()); const int kEstimatedBufferCountPerSeconds = 70; int progressive_buffer_count_cap = progressive_duration_cap.InSeconds() * kEstimatedBufferCountPerSeconds; if (total_buffer_size >= progressive_budget || total_buffer_count > progressive_buffer_count_cap) { // Retry after 100 milliseconds. - const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(100); + const base::TimeDelta kDelay = base::Milliseconds(100); blocking_thread_.task_runner()->PostDelayedTask( FROM_HERE, - base::Bind(&ProgressiveDemuxer::AllocateBuffer, - base::Unretained(this)), + base::BindRepeating(&ProgressiveDemuxer::AllocateBuffer, + base::Unretained(this)), kDelay); return; } @@ -414,11 +390,8 @@ void ProgressiveDemuxer::Download(scoped_refptr buffer) { // are buffering to a new location for this to make sense DCHECK(requested_au_); - const char* ALLOW_UNUSED_TYPE event_type = + const char* event_type = requested_au_->GetType() == DemuxerStream::AUDIO ? "audio" : "video"; - TRACE_EVENT2("media_stack", "ProgressiveDemuxer::Download()", "type", - event_type, "timestamp", - requested_au_->GetTimestamp().InMicroseconds()); // do nothing if stopped if (HasStopCalled()) { LOG(INFO) << "aborting download task, stopped"; @@ -430,14 +403,14 @@ void ProgressiveDemuxer::Download(scoped_refptr buffer) { // flushing_ will be reset by the next call to RequestTask() if (flushing_) { LOG(INFO) << "skipped AU download due to flush"; - requested_au_ = NULL; + requested_au_ = nullptr; IssueNextRequest(); return; } if (!requested_au_->Read(reader_.get(), buffer.get())) { LOG(ERROR) << "au read failed"; - host_->OnDemuxerError(::media::PIPELINE_ERROR_READ); + host_->OnDemuxerError(PIPELINE_ERROR_READ); return; } @@ -455,18 +428,18 @@ void ProgressiveDemuxer::Download(scoped_refptr buffer) { } // finished with this au, deref - requested_au_ = NULL; + requested_au_ = nullptr; // Calculate total range of buffered data for both audio and video. - ::media::Ranges buffered( + Ranges buffered( audio_demuxer_stream_->GetBufferedRanges().IntersectionWith( video_demuxer_stream_->GetBufferedRanges())); // Notify host of each disjoint range. host_->OnBufferedTimeRangesChanged(buffered); base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::Bind(&ProgressiveDemuxer::IssueNextRequest, - base::Unretained(this))); + FROM_HERE, base::BindRepeating(&ProgressiveDemuxer::IssueNextRequest, + base::Unretained(this))); } void ProgressiveDemuxer::IssueNextRequest() { @@ -517,8 +490,8 @@ void ProgressiveDemuxer::IssueNextRequest() { // |blocking_thread_| as otherwise it is possible that this function is // running in a tight loop and seek or stop request has no chance to kick in. base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::Bind(&ProgressiveDemuxer::Request, base::Unretained(this), type)); + FROM_HERE, base::BindRepeating(&ProgressiveDemuxer::Request, + base::Unretained(this), type)); } void ProgressiveDemuxer::Stop() { @@ -549,17 +522,14 @@ void ProgressiveDemuxer::Seek(base::TimeDelta time, PipelineStatusCallback cb) { // runs on blocking thread void ProgressiveDemuxer::SeekTask(base::TimeDelta time, PipelineStatusCallback cb) { - TRACE_EVENT1("media_stack", "ProgressiveDemuxer::SeekTask()", "timestamp", - time.InMicroseconds()); - LOG(INFO) << base::StringPrintf("seek to: %" PRId64 " ms", - time.InMilliseconds()); + LOG(ERROR) << base::StringPrintf("Cobalt seek to: %" PRId64 " ms", + time.InMilliseconds()); // clear any enqueued buffers on demuxer streams audio_demuxer_stream_->FlushBuffers(); video_demuxer_stream_->FlushBuffers(); // advance parser to new timestamp if (!parser_->SeekTo(time)) { - LOG(ERROR) << "parser seek failed."; - std::move(cb).Run(::media::PIPELINE_ERROR_READ); + std::move(cb).Run(PIPELINE_ERROR_READ); return; } // if both streams had finished downloading, we need to restart the request @@ -567,14 +537,13 @@ void ProgressiveDemuxer::SeekTask(base::TimeDelta time, audio_reached_eos_ = false; video_reached_eos_ = false; flushing_ = true; - std::move(cb).Run(::media::PIPELINE_OK); + std::move(cb).Run(PIPELINE_OK); if (issue_new_request) { - LOG(INFO) << "restarting stopped request loop"; Request(DemuxerStream::AUDIO); } } -std::vector<::media::DemuxerStream*> ProgressiveDemuxer::GetAllStreams() { +std::vector ProgressiveDemuxer::GetAllStreams() { return std::vector( {audio_demuxer_stream_.get(), video_demuxer_stream_.get()}); } @@ -593,4 +562,3 @@ const VideoDecoderConfig& ProgressiveDemuxer::VideoConfig() { } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/progressive_demuxer.h b/media/starboard/progressive/progressive_demuxer.h index f14580fd4dd..b306b3fcb45 100644 --- a/media/starboard/progressive/progressive_demuxer.h +++ b/media/starboard/progressive/progressive_demuxer.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ -#define COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ #include #include @@ -23,29 +23,23 @@ #include "base/logging.h" #include "base/task/sequenced_task_runner.h" #include "base/threading/thread.h" -#include "cobalt/media/progressive/progressive_parser.h" #include "media/base/decoder_buffer.h" #include "media/base/demuxer.h" #include "media/base/demuxer_stream.h" #include "media/base/media_log.h" #include "media/base/ranges.h" +#include "media/starboard/progressive/progressive_parser.h" -namespace media { -class DecoderBuffer; -} // namespace media - -namespace cobalt { namespace media { +class DecoderBuffer; class ProgressiveDemuxer; class ProgressiveDemuxerStream : public ::media::DemuxerStream { public: - typedef ::media::AudioDecoderConfig AudioDecoderConfig; - typedef ::media::DecoderBuffer DecoderBuffer; - typedef ::media::VideoDecoderConfig VideoDecoderConfig; - ProgressiveDemuxerStream(ProgressiveDemuxer* demuxer, Type type); + ProgressiveDemuxerStream(const ProgressiveDemuxerStream&) = delete; + ProgressiveDemuxerStream& operator=(const ProgressiveDemuxerStream&) = delete; // DemuxerStream implementation void Read(uint32_t count, ReadCB read_cb) override; @@ -76,6 +70,8 @@ class ProgressiveDemuxerStream : public ::media::DemuxerStream { // Used to protect everything below. mutable base::Lock lock_; + ReadCB read_cb_ GUARDED_BY(lock_); + // Keeps track of all time ranges this object has seen since creation. // The demuxer uses these ranges to update the pipeline about what data // it has demuxed. @@ -95,8 +91,6 @@ class ProgressiveDemuxerStream : public ::media::DemuxerStream { size_t total_buffer_size_ = 0; size_t total_buffer_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(ProgressiveDemuxerStream); }; class MEDIA_EXPORT ProgressiveDemuxer : public ::media::Demuxer { @@ -112,7 +106,8 @@ class MEDIA_EXPORT ProgressiveDemuxer : public ::media::Demuxer { ProgressiveDemuxer( const scoped_refptr& task_runner, - DataSource* data_source, MediaLog* const media_log); + DataSource* data_source, + MediaLog* const media_log); ~ProgressiveDemuxer() override; // Demuxer implementation. @@ -132,25 +127,26 @@ class MEDIA_EXPORT ProgressiveDemuxer : public ::media::Demuxer { base::TimeDelta GetStartTime() const override; base::Time GetTimelineOffset() const override { return base::Time(); } int64_t GetMemoryUsage() const override { - NOTREACHED(); + NOTIMPLEMENTED(); return 0; } absl::optional<::media::container_names::MediaContainerName> GetContainerForMetrics() const override { - NOTREACHED(); return absl::nullopt; } void OnEnabledAudioTracksChanged( const std::vector<::media::MediaTrack::Id>& track_ids, - base::TimeDelta currTime, TrackChangeCB change_completed_cb) override { - NOTREACHED(); + base::TimeDelta currTime, + TrackChangeCB change_completed_cb) override { + NOTIMPLEMENTED(); } void OnSelectedVideoTrackChanged( const std::vector<::media::MediaTrack::Id>& track_ids, - base::TimeDelta currTime, TrackChangeCB change_completed_cb) override { - NOTREACHED(); + base::TimeDelta currTime, + TrackChangeCB change_completed_cb) override { + NOTIMPLEMENTED(); } - void SetPlaybackRate(double rate) override { NOTREACHED(); } + void SetPlaybackRate(double rate) override { NOTIMPLEMENTED(); } // TODO: Consider move the following functions to private section. @@ -204,6 +200,5 @@ class MEDIA_EXPORT ProgressiveDemuxer : public ::media::Demuxer { }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ diff --git a/media/starboard/progressive/progressive_parser.cc b/media/starboard/progressive/progressive_parser.cc index 44707708c3c..b2c13aab7f1 100644 --- a/media/starboard/progressive/progressive_parser.cc +++ b/media/starboard/progressive/progressive_parser.cc @@ -12,13 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/progressive_parser.h" +#include "media/starboard/progressive/progressive_parser.h" #include "base/logging.h" -#include "cobalt/media/progressive/mp4_parser.h" #include "media/base/timestamp_constants.h" +#include "media/starboard/progressive/mp4_parser.h" -namespace cobalt { namespace media { // ==== ProgressiveParser @@ -28,19 +27,20 @@ namespace media { const int ProgressiveParser::kInitialHeaderSize = 9; // static -::media::PipelineStatus ProgressiveParser::Construct( +PipelineStatus ProgressiveParser::Construct( scoped_refptr reader, - scoped_refptr* parser, MediaLog* media_log) { + scoped_refptr* parser, + MediaLog* media_log) { DCHECK(parser); DCHECK(media_log); - *parser = NULL; + *parser = nullptr; // download first kInitialHeaderSize bytes of stream to determine file type // and extract basic container-specific stream configuration information - uint8 header[kInitialHeaderSize]; + uint8_t header[kInitialHeaderSize]; int bytes_read = reader->BlockingRead(0, kInitialHeaderSize, header); if (bytes_read != kInitialHeaderSize) { - return ::media::DEMUXER_ERROR_COULD_NOT_PARSE; + return DEMUXER_ERROR_COULD_NOT_PARSE; } // attempt to construct mp4 parser from this header @@ -48,14 +48,13 @@ ::media::PipelineStatus ProgressiveParser::Construct( } ProgressiveParser::ProgressiveParser(scoped_refptr reader) - : reader_(reader), duration_(::media::kInfiniteDuration) {} + : reader_(reader), duration_(kInfiniteDuration) {} ProgressiveParser::~ProgressiveParser() {} bool ProgressiveParser::IsConfigComplete() { return video_config_.IsValidConfig() && audio_config_.IsValidConfig() && - duration_ != ::media::kInfiniteDuration; + duration_ != kInfiniteDuration; } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/progressive_parser.h b/media/starboard/progressive/progressive_parser.h index caf94a9c05f..1631263f12d 100644 --- a/media/starboard/progressive/progressive_parser.h +++ b/media/starboard/progressive/progressive_parser.h @@ -12,32 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_PARSER_H_ -#define COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_PARSER_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_PROGRESSIVE_PARSER_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_PROGRESSIVE_PARSER_H_ #include "base/memory/ref_counted.h" -#include "cobalt/media/base/pipeline.h" -#include "cobalt/media/progressive/avc_access_unit.h" -#include "cobalt/media/progressive/data_source_reader.h" #include "media/base/audio_decoder_config.h" #include "media/base/demuxer_stream.h" #include "media/base/media_log.h" +#include "media/base/pipeline.h" #include "media/base/video_decoder_config.h" +#include "media/starboard/progressive/avc_access_unit.h" +#include "media/starboard/progressive/data_source_reader.h" -namespace cobalt { namespace media { // abstract base class to define a stream parser interface used by // ProgressiveDemuxer. class ProgressiveParser : public base::RefCountedThreadSafe { public: - typedef ::media::AudioDecoderConfig AudioDecoderConfig; - typedef ::media::DecoderBuffer DecoderBuffer; - typedef ::media::DemuxerStream DemuxerStream; - typedef ::media::MediaLog MediaLog; - typedef ::media::PipelineStatus PipelineStatus; - typedef ::media::VideoDecoderConfig VideoDecoderConfig; - static const int kInitialHeaderSize; // Determine stream type, construct appropriate parser object, and returns // PIPELINE_OK on success or error code. @@ -83,6 +75,5 @@ class ProgressiveParser : public base::RefCountedThreadSafe { }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_PARSER_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_PROGRESSIVE_PARSER_H_ diff --git a/media/starboard/progressive/rbsp_stream.cc b/media/starboard/progressive/rbsp_stream.cc index ea90f7a821f..0d167d49a8f 100644 --- a/media/starboard/progressive/rbsp_stream.cc +++ b/media/starboard/progressive/rbsp_stream.cc @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/rbsp_stream.h" +#include "media/starboard/progressive/rbsp_stream.h" +#include "base/check.h" #include "base/logging.h" -namespace cobalt { namespace media { -RBSPStream::RBSPStream(const uint8* nalu_buffer, size_t nalu_buffer_size) +RBSPStream::RBSPStream(const uint8_t* nalu_buffer, size_t nalu_buffer_size) : nalu_buffer_(nalu_buffer), nalu_buffer_size_(nalu_buffer_size), nalu_buffer_byte_offset_(0), @@ -28,10 +28,10 @@ RBSPStream::RBSPStream(const uint8* nalu_buffer, size_t nalu_buffer_size) rbsp_bit_offset_(0) {} // read unsigned Exp-Golomb coded integer, ISO 14496-10 Section 9.1 -bool RBSPStream::ReadUEV(uint32* uev_out) { - DCHECK(uev_out); +bool RBSPStream::ReadUEV(uint32_t* uev_out) { + CHECK(uev_out); int leading_zero_bits = -1; - for (uint8 b = 0; b == 0; leading_zero_bits++) { + for (uint8_t b = 0; b == 0; leading_zero_bits++) { if (!ReadRBSPBit(&b)) { return false; } @@ -40,8 +40,8 @@ bool RBSPStream::ReadUEV(uint32* uev_out) { if (leading_zero_bits >= 32) { return false; } - uint32 result = (1 << leading_zero_bits) - 1; - uint32 remainder = 0; + uint32_t result = (1 << leading_zero_bits) - 1; + uint32_t remainder = 0; if (!ReadBits(leading_zero_bits, &remainder)) { return false; } @@ -51,16 +51,16 @@ bool RBSPStream::ReadUEV(uint32* uev_out) { } // read signed Exp-Golomb coded integer, ISO 14496-10 Section 9.1 -bool RBSPStream::ReadSEV(int32* sev_out) { - DCHECK(sev_out); +bool RBSPStream::ReadSEV(int32_t* sev_out) { + CHECK(sev_out); // we start off by reading an unsigned Exp-Golomb coded number - uint32 uev = 0; + uint32_t uev = 0; if (!ReadUEV(&uev)) { return false; } // the LSb in this number is treated as the inverted sign bit bool is_negative = !(uev & 1); - int32 result = static_cast((uev + 1) >> 1); + int32_t result = static_cast((uev + 1) >> 1); if (is_negative) { result *= -1; } @@ -70,34 +70,34 @@ bool RBSPStream::ReadSEV(int32* sev_out) { // read and return up to 32 bits, filling from the right, meaning that // ReadBits(17) on a stream of all 1s would return 0x01ffff -bool RBSPStream::ReadBits(size_t bits, uint32* bits_out) { - DCHECK(bits_out); +bool RBSPStream::ReadBits(size_t bits, uint32_t* bits_out) { + CHECK(bits_out); if (bits > 32) { return false; } if (bits == 0) { return true; } - uint32 result = 0; + uint32_t result = 0; size_t bytes = bits >> 3; // read bytes first for (int i = 0; i < bytes; i++) { - uint8 new_byte = 0; + uint8_t new_byte = 0; if (!ReadRBSPByte(&new_byte)) { return false; } result = result << 8; - result = result | static_cast(new_byte); + result = result | static_cast(new_byte); } // scoot any leftover bits in bits = bits % 8; for (int i = 0; i < bits; i++) { - uint8 new_bit = 0; + uint8_t new_bit = 0; if (!ReadRBSPBit(&new_bit)) { return false; } result = result << 1; - result = result | static_cast(new_bit); + result = result | static_cast(new_bit); } *bits_out = result; return true; @@ -173,8 +173,8 @@ bool RBSPStream::ConsumeNALUByte() { // return single bit in the LSb from the RBSP stream. Bits are read from MSb // to LSb in the stream. -bool RBSPStream::ReadRBSPBit(uint8* bit_out) { - DCHECK(bit_out); +bool RBSPStream::ReadRBSPBit(uint8_t* bit_out) { + CHECK(bit_out); // check to see if we need to consume a fresh byte if (rbsp_bit_offset_ == 0) { if (!ConsumeNALUByte()) { @@ -182,15 +182,15 @@ bool RBSPStream::ReadRBSPBit(uint8* bit_out) { } } // since we read from MSb to LSb in stream we shift right - uint8 bit = (current_nalu_byte_ >> (7 - rbsp_bit_offset_)) & 1; + uint8_t bit = (current_nalu_byte_ >> (7 - rbsp_bit_offset_)) & 1; // increment bit offset rbsp_bit_offset_ = (rbsp_bit_offset_ + 1) % 8; *bit_out = bit; return true; } -bool RBSPStream::ReadRBSPByte(uint8* byte_out) { - DCHECK(byte_out); +bool RBSPStream::ReadRBSPByte(uint8_t* byte_out) { + CHECK(byte_out); // fast path for byte-aligned access if (rbsp_bit_offset_ == 0) { if (!ConsumeNALUByte()) { @@ -201,7 +201,7 @@ bool RBSPStream::ReadRBSPByte(uint8* byte_out) { } // at least some of the bits in the current byte will be included in this // next byte, absorb them - uint8 upper_part = current_nalu_byte_; + uint8_t upper_part = current_nalu_byte_; // read next byte from stream if (!ConsumeNALUByte()) { return false; @@ -213,4 +213,3 @@ bool RBSPStream::ReadRBSPByte(uint8* byte_out) { } } // namespace media -} // namespace cobalt diff --git a/media/starboard/progressive/rbsp_stream.h b/media/starboard/progressive/rbsp_stream.h index 26048202eda..f4b7a66f14d 100644 --- a/media/starboard/progressive/rbsp_stream.h +++ b/media/starboard/progressive/rbsp_stream.h @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef COBALT_MEDIA_PROGRESSIVE_RBSP_STREAM_H_ -#define COBALT_MEDIA_PROGRESSIVE_RBSP_STREAM_H_ +#ifndef MEDIA_STARBOARD_PROGRESSIVE_RBSP_STREAM_H_ +#define MEDIA_STARBOARD_PROGRESSIVE_RBSP_STREAM_H_ -#include "base/basictypes.h" +#include +#include -namespace cobalt { namespace media { // ISO 14496-10 describes a byte encoding format for NALUs (network abstraction @@ -29,19 +29,19 @@ class RBSPStream { public: // NON-OWNING pointer to buffer. It is assumed the client will dispose of // this buffer. - RBSPStream(const uint8* nalu_buffer, size_t nalu_buffer_size); + RBSPStream(const uint8_t* nalu_buffer, size_t nalu_buffer_size); // all Read/Skip methods return the value by reference and return true // on success, false on read error/EOB. Once the object has returned // false the consistency of the data is not guaranteed. // read unsigned Exp-Golomb coded integer, ISO 14496-10 Section 9.1 - bool ReadUEV(uint32* uev_out); + bool ReadUEV(uint32_t* uev_out); // read signed Exp-Golomb coded integer, ISO 14496-10 Section 9.1 - bool ReadSEV(int32* sev_out); + bool ReadSEV(int32_t* sev_out); // read and return up to 32 bits, filling from the right, meaning that // ReadBits(17) on a stream of all 1s would return 0x01ffff - bool ReadBits(size_t bits, uint32* bits_out); - bool ReadByte(uint8* byte_out) { return ReadRBSPByte(byte_out); } - bool ReadBit(uint8* bit_out) { return ReadRBSPBit(bit_out); } + bool ReadBits(size_t bits, uint32_t* bits_out); + bool ReadByte(uint8_t* byte_out) { return ReadRBSPByte(byte_out); } + bool ReadBit(uint8_t* bit_out) { return ReadRBSPBit(bit_out); } // jump over bytes in the RBSP stream bool SkipBytes(size_t bytes); // jump over bits in the RBSP stream @@ -55,19 +55,18 @@ class RBSPStream { bool ConsumeNALUByte(); // return single bit in the LSb from the RBSP stream. Bits are read from MSb // to LSb in the stream. - bool ReadRBSPBit(uint8* bit_out); - bool ReadRBSPByte(uint8* byte_out); + bool ReadRBSPBit(uint8_t* bit_out); + bool ReadRBSPByte(uint8_t* byte_out); - const uint8* nalu_buffer_; + const uint8_t* nalu_buffer_; size_t nalu_buffer_size_; size_t nalu_buffer_byte_offset_; - uint8 current_nalu_byte_; + uint8_t current_nalu_byte_; int number_consecutive_zeros_; // location of rbsp bit cursor within current_nalu_byte_ size_t rbsp_bit_offset_; }; } // namespace media -} // namespace cobalt -#endif // COBALT_MEDIA_PROGRESSIVE_RBSP_STREAM_H_ +#endif // MEDIA_STARBOARD_PROGRESSIVE_RBSP_STREAM_H_ diff --git a/media/starboard/progressive/rbsp_stream_unittest.cc b/media/starboard/progressive/rbsp_stream_unittest.cc index 89d1df55908..bb2130b351e 100644 --- a/media/starboard/progressive/rbsp_stream_unittest.cc +++ b/media/starboard/progressive/rbsp_stream_unittest.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cobalt/media/progressive/rbsp_stream.h" +#include "media/starboard/progressive/rbsp_stream.h" #include #include @@ -22,7 +22,6 @@ #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" -namespace cobalt { namespace media { class RBSPStreamTest : public testing::Test { @@ -634,4 +633,3 @@ TEST_F(RBSPStreamTest, SkipBits) { } } // namespace media -} // namespace cobalt