Motown: Improvements to packet definition - Removed duration field - Renamed various "PresentationTime" things to "Pts" - Now implementing Packet accessors in the base class. - Improved the way ffmpeg AVFrame and AVPacket structures are managed. R=johngro@google.com Review URL: https://codereview.chromium.org/1814553002 .
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart index b36f0f5..c8ffc41 100644 --- a/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart +++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_transport.mojom.dart
@@ -100,11 +100,10 @@ class MediaPacket extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ - const bindings.StructDataHeader(48, 0) + const bindings.StructDataHeader(40, 0) ]; static const int kNoTimestamp = 9223372036854775807; int pts = 9223372036854775807; - int duration = 0; bool endOfStream = false; MediaPacketRegion payload = null; List<MediaPacketRegion> extraPayload = null; @@ -150,20 +149,16 @@ } if (mainDataHeader.version >= 0) { - result.duration = decoder0.decodeUint64(16); + result.endOfStream = decoder0.decodeBool(16, 0); } if (mainDataHeader.version >= 0) { - result.endOfStream = decoder0.decodeBool(24, 0); - } - if (mainDataHeader.version >= 0) { - - var decoder1 = decoder0.decodePointer(32, false); + var decoder1 = decoder0.decodePointer(24, false); result.payload = MediaPacketRegion.decode(decoder1); } if (mainDataHeader.version >= 0) { - var decoder1 = decoder0.decodePointer(40, true); + var decoder1 = decoder0.decodePointer(32, true); if (decoder1 == null) { result.extraPayload = null; } else { @@ -189,21 +184,14 @@ rethrow; } try { - encoder0.encodeUint64(duration, 16); - } on bindings.MojoCodecError catch(e) { - e.message = "Error encountered while encoding field " - "duration of struct MediaPacket: $e"; - rethrow; - } - try { - encoder0.encodeBool(endOfStream, 24, 0); + encoder0.encodeBool(endOfStream, 16, 0); } on bindings.MojoCodecError catch(e) { e.message = "Error encountered while encoding field " "endOfStream of struct MediaPacket: $e"; rethrow; } try { - encoder0.encodeStruct(payload, 32, false); + encoder0.encodeStruct(payload, 24, false); } on bindings.MojoCodecError catch(e) { e.message = "Error encountered while encoding field " "payload of struct MediaPacket: $e"; @@ -211,9 +199,9 @@ } try { if (extraPayload == null) { - encoder0.encodeNullPointer(40, true); + encoder0.encodeNullPointer(32, true); } else { - var encoder1 = encoder0.encodePointerArray(extraPayload.length, 40, bindings.kUnspecifiedArrayLength); + var encoder1 = encoder0.encodePointerArray(extraPayload.length, 32, bindings.kUnspecifiedArrayLength); for (int i0 = 0; i0 < extraPayload.length; ++i0) { encoder1.encodeStruct(extraPayload[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false); } @@ -228,7 +216,6 @@ String toString() { return "MediaPacket(" "pts: $pts" ", " - "duration: $duration" ", " "endOfStream: $endOfStream" ", " "payload: $payload" ", " "extraPayload: $extraPayload" ")"; @@ -237,7 +224,6 @@ Map toJson() { Map map = new Map(); map["pts"] = pts; - map["duration"] = duration; map["endOfStream"] = endOfStream; map["payload"] = payload; map["extraPayload"] = extraPayload;
diff --git a/mojo/services/media/common/interfaces/media_transport.mojom b/mojo/services/media/common/interfaces/media_transport.mojom index b8d5ac4..da31dfd 100644 --- a/mojo/services/media/common/interfaces/media_transport.mojom +++ b/mojo/services/media/common/interfaces/media_transport.mojom
@@ -30,9 +30,6 @@ // according to the media timeline. int64 pts = kNoTimestamp; - // Duration represented by the packet. - uint64 duration; - // Indicates whether this is the last packet in the stream. bool end_of_stream;
diff --git a/services/media/factory_service/media_sink_impl.cc b/services/media/factory_service/media_sink_impl.cc index 36b3a22..b32121e 100644 --- a/services/media/factory_service/media_sink_impl.cc +++ b/services/media/factory_service/media_sink_impl.cc
@@ -240,12 +240,11 @@ // The media time corresponding to start_local_time. int64_t start_media_time; if (flushed_ && - producer_->GetFirstPresentationTimeSinceFlush() != - Packet::kUnknownPresentationTime) { + producer_->GetFirstPtsSinceFlush() != Packet::kUnknownPts) { // We're getting started initially or after a flush/prime, so the media // time corresponding to start_local_time should be the PTS of // the first packet. - start_media_time = producer_->GetFirstPresentationTimeSinceFlush(); + start_media_time = producer_->GetFirstPtsSinceFlush(); } else { // We're resuming, so the media time corresponding to start_local_time can // be calculated using the existing transform.
diff --git a/services/media/framework/formatting.cc b/services/media/framework/formatting.cc index cea3aaa..26c50bd 100644 --- a/services/media/framework/formatting.cc +++ b/services/media/framework/formatting.cc
@@ -57,8 +57,7 @@ } os << "&" << std::hex << uint64_t(value.get()) << std::dec; - os << "/pts:" << value->presentation_time(); - os << "/dur:" << value->duration(); + os << "/pts:" << value->pts(); os << "/eos:" << (value->end_of_stream() ? "t" : "f"); os << "/size:" << value->size(); os << "/payload:" << std::hex << uint64_t(value->payload()) << std::dec;
diff --git a/services/media/framework/packet.cc b/services/media/framework/packet.cc index 32204bc..e6b9155 100644 --- a/services/media/framework/packet.cc +++ b/services/media/framework/packet.cc
@@ -9,66 +9,57 @@ namespace mojo { namespace media { +Packet::Packet( + int64_t pts, + bool end_of_stream, + size_t size, + void* payload) : + pts_(pts), + end_of_stream_(end_of_stream), + size_(size), + payload_(payload) { + DCHECK((size == 0) == (payload == nullptr)); +} + class PacketImpl : public Packet { public: PacketImpl( - int64_t presentation_time, - uint64_t duration, + int64_t pts, bool end_of_stream, size_t size, void* payload, PayloadAllocator* allocator) : - presentation_time_(presentation_time), - duration_(duration), - end_of_stream_(end_of_stream), - size_(size), - payload_(payload), - allocator_(allocator) { - DCHECK((size == 0) == (payload == nullptr)); - } - - ~PacketImpl() override {}; - - int64_t presentation_time() const override { return presentation_time_; } - - uint64_t duration() const override { return duration_; } - - bool end_of_stream() const override { return end_of_stream_; } - - size_t size() const override { return size_; } - - void* payload() const override { return payload_; } + Packet(pts, end_of_stream, size, payload), + allocator_(allocator) {} protected: + ~PacketImpl() override {}; + void Release() override { - if (payload_ != nullptr && allocator_ != nullptr) { - DCHECK(allocator_); - allocator_->ReleasePayloadBuffer(size_, payload_); + // In the default implementation, payload() will be nullptr if and only if + // allocator_ is nullptr. Subclasses have the option of having a non-null + // payload() and handling deallocation themselves, so allocator_ can be + // nullptr even when payload() is not. + if (payload() != nullptr && allocator_ != nullptr) { + allocator_->ReleasePayloadBuffer(size(), payload()); } delete this; } private: - int64_t presentation_time_; - uint64_t duration_; - bool end_of_stream_; - size_t size_; - void* payload_; PayloadAllocator* allocator_; }; // static PacketPtr Packet::Create( - int64_t presentation_time, - uint64_t duration, + int64_t pts, bool end_of_stream, size_t size, void* payload, PayloadAllocator* allocator) { DCHECK(payload == nullptr || allocator != nullptr); return PacketPtr(new PacketImpl( - presentation_time, - duration, + pts, end_of_stream, size, payload, @@ -77,14 +68,12 @@ // static PacketPtr Packet::CreateNoAllocator( - int64_t presentation_time, - uint64_t duration, + int64_t pts, bool end_of_stream, size_t size, void* payload) { return PacketPtr(new PacketImpl( - presentation_time, - duration, + pts, end_of_stream, size, payload, @@ -92,10 +81,9 @@ } // static -PacketPtr Packet::CreateEndOfStream(int64_t presentation_time) { +PacketPtr Packet::CreateEndOfStream(int64_t pts) { return PacketPtr(new PacketImpl( - presentation_time, - 0, // duration + pts, true, // end_of_stream 0, // size nullptr, // payload
diff --git a/services/media/framework/packet.h b/services/media/framework/packet.h index d89d68b..952383c 100644 --- a/services/media/framework/packet.h +++ b/services/media/framework/packet.h
@@ -32,14 +32,12 @@ // 2) The relationship to the allocator could be clearer. class Packet { public: - static const int64_t kUnknownPresentationTime = - std::numeric_limits<int64_t>::min(); + static const int64_t kUnknownPts = std::numeric_limits<int64_t>::min(); // Creates a packet. If size is 0, payload must be nullptr and vice-versa. // If payload is not nullptr, an allocator must be provided. static PacketPtr Create( - int64_t presentation_time, - uint64_t duration, + int64_t pts, bool end_of_stream, size_t size, void* payload, @@ -49,30 +47,39 @@ // No allocator is provided, and the payload will not be released when the // packet is released. static PacketPtr CreateNoAllocator( - int64_t presentation_time, - uint64_t duration, + int64_t pts, bool end_of_stream, size_t size, void* payload); // Creates an end-of-stream packet with no payload. - static PacketPtr CreateEndOfStream(int64_t presentation_time); + static PacketPtr CreateEndOfStream(int64_t pts); - virtual int64_t presentation_time() const = 0; + int64_t pts() const { return pts_; } - virtual uint64_t duration() const = 0; + bool end_of_stream() const { return end_of_stream_; } - virtual bool end_of_stream() const = 0; + size_t size() const { return size_; } - virtual size_t size() const = 0; - - virtual void* payload() const = 0; + void* payload() const { return payload_; } protected: + Packet( + int64_t pts, + bool end_of_stream, + size_t size, + void* payload); + virtual ~Packet() {} virtual void Release() = 0; + private: + int64_t pts_; + bool end_of_stream_; + size_t size_; + void* payload_; + friend PacketDeleter; };
diff --git a/services/media/framework/parts/lpcm_reformatter.cc b/services/media/framework/parts/lpcm_reformatter.cc index 91c86f2..79b5458 100644 --- a/services/media/framework/parts/lpcm_reformatter.cc +++ b/services/media/framework/parts/lpcm_reformatter.cc
@@ -249,8 +249,7 @@ if (in_size == 0) { // Zero-sized input packet. Make a copy. *output = Packet::Create( - input->presentation_time(), - input->duration(), + input->pts(), input->end_of_stream(), 0, nullptr, @@ -258,7 +257,7 @@ return true; } - size_t frame_count = input->duration(); + size_t frame_count = in_type_.frame_count(in_size); uint64_t out_size = out_type_.min_buffer_size(frame_count); void* buffer = allocator->AllocatePayloadBuffer(out_size); @@ -285,8 +284,7 @@ } *output = Packet::Create( - input->presentation_time(), - frame_count, + input->pts(), input->end_of_stream(), out_size, buffer,
diff --git a/services/media/framework/stages/output.cc b/services/media/framework/stages/output.cc index e64d913..1180cf8 100644 --- a/services/media/framework/stages/output.cc +++ b/services/media/framework/stages/output.cc
@@ -65,8 +65,7 @@ } packet = Packet::Create( - packet->presentation_time(), - packet->duration(), + packet->pts(), packet->end_of_stream(), size, buffer,
diff --git a/services/media/framework/stream_type.h b/services/media/framework/stream_type.h index aaa3136..31021e2 100644 --- a/services/media/framework/stream_type.h +++ b/services/media/framework/stream_type.h
@@ -271,7 +271,13 @@ } uint64_t min_buffer_size(uint64_t frame_count) const { - return frame_count * sample_size_ * channels_; + return frame_count * bytes_per_frame(); + } + + uint64_t frame_count(uint64_t size) const { + DCHECK(bytes_per_frame() != 0); + DCHECK(size % bytes_per_frame() == 0); + return size / bytes_per_frame(); } static uint32_t SampleSizeFromFormat(SampleFormat sample_format);
diff --git a/services/media/framework_ffmpeg/BUILD.gn b/services/media/framework_ffmpeg/BUILD.gn index 8934bc5..0bb2492 100644 --- a/services/media/framework_ffmpeg/BUILD.gn +++ b/services/media/framework_ffmpeg/BUILD.gn
@@ -21,6 +21,8 @@ source_set("framework_ffmpeg") { sources = [ + "av_frame.h", + "av_packet.h", "ffmpeg_audio_decoder.cc", "ffmpeg_audio_decoder.h", "ffmpeg_decoder.cc",
diff --git a/services/media/framework_ffmpeg/av_frame.h b/services/media/framework_ffmpeg/av_frame.h new file mode 100644 index 0000000..8b02b66 --- /dev/null +++ b/services/media/framework_ffmpeg/av_frame.h
@@ -0,0 +1,34 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_MEDIA_FRAMEWORK_FFMPEG_AV_FRAME_H_ +#define SERVICES_MEDIA_FRAMEWORK_FFMPEG_AV_FRAME_H_ + +extern "C" { +#include "third_party/ffmpeg/libavutil/frame.h" +} + +namespace mojo { +namespace media { +namespace ffmpeg { + +struct AVFrameDeleter { + inline void operator()(AVFrame* ptr) const { + av_frame_free(&ptr); + } +}; + +using AvFramePtr = std::unique_ptr<AVFrame, AVFrameDeleter>; + +struct AvFrame{ + static AvFramePtr Create() { + return AvFramePtr(av_frame_alloc()); + } +}; + +} // namespace ffmpeg +} // namespace media +} // namespace mojo + +#endif // SERVICES_MEDIA_FRAMEWORK_FFMPEG_AV_FRAME_H_
diff --git a/services/media/framework_ffmpeg/av_packet.h b/services/media/framework_ffmpeg/av_packet.h new file mode 100644 index 0000000..f1d51b8 --- /dev/null +++ b/services/media/framework_ffmpeg/av_packet.h
@@ -0,0 +1,37 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_MEDIA_FRAMEWORK_FFMPEG_AV_PACKET_H_ +#define SERVICES_MEDIA_FRAMEWORK_FFMPEG_AV_PACKET_H_ + +extern "C" { +#include "third_party/ffmpeg/libavcodec/avcodec.h" +#include "third_party/ffmpeg/libavformat/avformat.h" +} + +namespace mojo { +namespace media { +namespace ffmpeg { + +struct AVPacketDeleter { + inline void operator()(AVPacket* ptr) const { + av_free_packet(ptr); + } +}; + +using AvPacketPtr = std::unique_ptr<AVPacket, AVPacketDeleter>; + +struct AvPacket{ + static AvPacketPtr Create() { + AVPacket* av_packet = new AVPacket(); + av_init_packet(av_packet); + return AvPacketPtr(av_packet); + } +}; + +} // namespace ffmpeg +} // namespace media +} // namespace mojo + +#endif // SERVICES_MEDIA_FRAMEWORK_FFMPEG_AV_PACKET_H_
diff --git a/services/media/framework_ffmpeg/ffmpeg_audio_decoder.cc b/services/media/framework_ffmpeg/ffmpeg_audio_decoder.cc index 11e2679..0d854c1 100644 --- a/services/media/framework_ffmpeg/ffmpeg_audio_decoder.cc +++ b/services/media/framework_ffmpeg/ffmpeg_audio_decoder.cc
@@ -28,12 +28,12 @@ void FfmpegAudioDecoder::Flush() { FfmpegDecoderBase::Flush(); - next_presentation_time_= Packet::kUnknownPresentationTime; + next_pts_= Packet::kUnknownPts; } int FfmpegAudioDecoder::Decode( const AVPacket& av_packet, - const AvFramePtr& av_frame_ptr, + const ffmpeg::AvFramePtr& av_frame_ptr, PayloadAllocator* allocator, bool* frame_decoded_out) { DCHECK(allocator); @@ -41,11 +41,11 @@ DCHECK(context()); DCHECK(av_frame_ptr); - if (next_presentation_time_ == Packet::kUnknownPresentationTime) { + if (next_pts_ == Packet::kUnknownPts) { if (av_packet.pts == AV_NOPTS_VALUE) { - next_presentation_time_ = 0; + next_pts_ = 0; } else { - next_presentation_time_ = av_packet.pts; + next_pts_ = av_packet.pts; } } @@ -74,10 +74,10 @@ PayloadAllocator* allocator) { DCHECK(allocator); - int64_t presentation_time = av_frame.pts; - if (presentation_time == AV_NOPTS_VALUE) { - presentation_time = next_presentation_time_; - next_presentation_time_ += av_frame.nb_samples; + int64_t pts = av_frame.pts; + if (pts == AV_NOPTS_VALUE) { + pts = next_pts_; + next_pts_ += av_frame.nb_samples; } uint64_t payload_size; @@ -110,8 +110,7 @@ } return Packet::Create( - presentation_time, - av_frame.nb_samples, + pts, false, // The base class is responsible for end-of-stream. payload_size, payload_buffer, @@ -119,7 +118,7 @@ } PacketPtr FfmpegAudioDecoder::CreateOutputEndOfStreamPacket() { - return Packet::CreateEndOfStream(next_presentation_time_); + return Packet::CreateEndOfStream(next_pts_); } int FfmpegAudioDecoder::AllocateBufferForAvFrame(
diff --git a/services/media/framework_ffmpeg/ffmpeg_audio_decoder.h b/services/media/framework_ffmpeg/ffmpeg_audio_decoder.h index 48503e6..9a8d6dc 100644 --- a/services/media/framework_ffmpeg/ffmpeg_audio_decoder.h +++ b/services/media/framework_ffmpeg/ffmpeg_audio_decoder.h
@@ -24,7 +24,7 @@ int Decode( const AVPacket& av_packet, - const AvFramePtr& av_frame_ptr, + const ffmpeg::AvFramePtr& av_frame_ptr, PayloadAllocator* allocator, bool* frame_decoded_out) override; @@ -112,7 +112,7 @@ std::unique_ptr<StreamType> stream_type_; // Used to supply missing PTS. - int64_t next_presentation_time_= Packet::kUnknownPresentationTime; + int64_t next_pts_= Packet::kUnknownPts; }; } // namespace media
diff --git a/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc b/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc index 8af9730..80bbe4f 100644 --- a/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc +++ b/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc
@@ -76,7 +76,7 @@ av_init_packet(&av_packet_); av_packet_.data = reinterpret_cast<uint8_t*>(input->payload()); av_packet_.size = input->size(); - av_packet_.pts = input->presentation_time(); + av_packet_.pts = input->pts(); } bool FfmpegDecoderBase::UnprepareInputPacket(
diff --git a/services/media/framework_ffmpeg/ffmpeg_decoder_base.h b/services/media/framework_ffmpeg/ffmpeg_decoder_base.h index 69faca7..ce3935b 100644 --- a/services/media/framework_ffmpeg/ffmpeg_decoder_base.h +++ b/services/media/framework_ffmpeg/ffmpeg_decoder_base.h
@@ -6,6 +6,8 @@ #define SERVICES_MEDIA_FRAMEWORK_FFMPEG_FFMPEG_DECODER_BASE_H_ #include "services/media/framework/parts/decoder.h" +#include "services/media/framework_ffmpeg/av_frame.h" +#include "services/media/framework_ffmpeg/av_packet.h" #include "services/media/framework_ffmpeg/ffmpeg_type_converters.h" extern "C" { #include "third_party/ffmpeg/libavcodec/avcodec.h" @@ -34,20 +36,12 @@ PacketPtr* output) override; protected: - struct AVFrameDeleter { - inline void operator()(AVFrame* ptr) const { - av_frame_free(&ptr); - } - }; - - using AvFramePtr = std::unique_ptr<AVFrame, AVFrameDeleter>; - // Decodes from av_packet into av_frame_ptr. The result indicates how many // bytes were consumed from av_packet_. *frame_decoded_out indicates whether // av_frame_ptr contains a complete frame. virtual int Decode( const AVPacket& av_packet, - const AvFramePtr& av_frame_ptr, + const ffmpeg::AvFramePtr& av_frame_ptr, PayloadAllocator* allocator, bool* frame_decoded_out) = 0; @@ -75,7 +69,7 @@ AvCodecContextPtr av_codec_context_; AVPacket av_packet_; - AvFramePtr av_frame_ptr_; + ffmpeg::AvFramePtr av_frame_ptr_; }; } // namespace media
diff --git a/services/media/framework_ffmpeg/ffmpeg_demux.cc b/services/media/framework_ffmpeg/ffmpeg_demux.cc index b882588..e71ebfa 100644 --- a/services/media/framework_ffmpeg/ffmpeg_demux.cc +++ b/services/media/framework_ffmpeg/ffmpeg_demux.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "services/media/framework/safe_clone.h" +#include "services/media/framework_ffmpeg/av_packet.h" #include "services/media/framework_ffmpeg/ffmpeg_demux.h" #include "services/media/framework_ffmpeg/ffmpeg_io.h" #include "services/media/framework_ffmpeg/ffmpeg_type_converters.h" @@ -54,36 +55,31 @@ // Specialized packet implementation. class DemuxPacket : public Packet { public: - DemuxPacket() { - av_init_packet(&av_packet_); - } - - // Packet implementation. - int64_t presentation_time() const override { return av_packet_.pts; }; - - uint64_t duration() const override { return av_packet_.duration; }; - - bool end_of_stream() const override { return false; } - - size_t size() const override { return size_t(av_packet_.size); } - - void* payload() const override { - return reinterpret_cast<void*>(av_packet_.data); + static PacketPtr Create(ffmpeg::AvPacketPtr av_packet) { + return PacketPtr(new DemuxPacket(std::move(av_packet))); } AVPacket& av_packet() { - return av_packet_; + return *av_packet_; } protected: - ~DemuxPacket() override { - av_free_packet(&av_packet_); - } + ~DemuxPacket() override {} void Release() override { delete this; } - private: - AVPacket av_packet_; + private: + DemuxPacket(ffmpeg::AvPacketPtr av_packet) : + Packet( + (av_packet->pts == AV_NOPTS_VALUE) ? kUnknownPts : av_packet->pts, + false, + static_cast<size_t>(av_packet->size), + av_packet->data), + av_packet_(std::move(av_packet)) { + DCHECK(av_packet->size >= 0); + } + + ffmpeg::AvPacketPtr av_packet_; }; struct AVFormatContextDeleter { @@ -105,7 +101,7 @@ AvioContextPtr io_context_; std::vector<DemuxStream*> streams_; std::unique_ptr<Metadata> metadata_; - int64_t next_presentation_time_; + int64_t next_pts_; int next_stream_to_end_ = -1; // -1: don't end, streams_.size(): stop. }; @@ -199,26 +195,23 @@ return PullEndOfStreamPacket(stream_index_out); } - FfmpegDemuxImpl::DemuxPacket* demux_packet = - new FfmpegDemuxImpl::DemuxPacket(); + ffmpeg::AvPacketPtr av_packet = ffmpeg::AvPacket::Create(); - demux_packet->av_packet().data = nullptr; - demux_packet->av_packet().size = 0; + av_packet->data = nullptr; + av_packet->size = 0; - if (av_read_frame(format_context_.get(), &demux_packet->av_packet()) < 0) { + if (av_read_frame(format_context_.get(), av_packet.get()) < 0) { // End of stream. Start producing end-of-stream packets for all the streams. - PacketPtr(demux_packet); // Deletes demux_packet. next_stream_to_end_ = 0; return PullEndOfStreamPacket(stream_index_out); } *stream_index_out = - static_cast<size_t>(demux_packet->av_packet().stream_index); + static_cast<size_t>(av_packet->stream_index); // TODO(dalesat): What if the packet has no PTS or duration? - next_presentation_time_ = - demux_packet->presentation_time() + demux_packet->duration(); + next_pts_ = av_packet->pts + av_packet->duration; - return PacketPtr(demux_packet); + return DemuxPacket::Create(std::move(av_packet)); } PacketPtr FfmpegDemuxImpl::PullEndOfStreamPacket(size_t* stream_index_out) { @@ -230,7 +223,7 @@ } *stream_index_out = next_stream_to_end_++; - return Packet::CreateEndOfStream(next_presentation_time_); + return Packet::CreateEndOfStream(next_pts_); } void FfmpegDemuxImpl::CopyMetadata(
diff --git a/services/media/framework_ffmpeg/ffmpeg_video_decoder.cc b/services/media/framework_ffmpeg/ffmpeg_video_decoder.cc index 8e84fb6..73fe12e 100644 --- a/services/media/framework_ffmpeg/ffmpeg_video_decoder.cc +++ b/services/media/framework_ffmpeg/ffmpeg_video_decoder.cc
@@ -17,7 +17,7 @@ int FfmpegVideoDecoder::Decode( const AVPacket& av_packet, - const AvFramePtr& av_frame_ptr, + const ffmpeg::AvFramePtr& av_frame_ptr, PayloadAllocator* allocator, bool* frame_decoded_out) { DCHECK(av_frame_ptr); @@ -45,7 +45,6 @@ // TODO(dalesat): This is just a copy of the audio version. return Packet::Create( av_frame.pts, - av_frame.pkt_duration, false, packet_size_, av_frame.data[0],
diff --git a/services/media/framework_ffmpeg/ffmpeg_video_decoder.h b/services/media/framework_ffmpeg/ffmpeg_video_decoder.h index e192804..3d3d4f7 100644 --- a/services/media/framework_ffmpeg/ffmpeg_video_decoder.h +++ b/services/media/framework_ffmpeg/ffmpeg_video_decoder.h
@@ -22,7 +22,7 @@ // FfmpegDecoderBase overrides. int Decode( const AVPacket& av_packet, - const AvFramePtr& av_frame_ptr, + const ffmpeg::AvFramePtr& av_frame_ptr, PayloadAllocator* allocator, bool* frame_decoded_out) override;
diff --git a/services/media/framework_mojo/mojo_consumer.cc b/services/media/framework_mojo/mojo_consumer.cc index 5c9d2c8..2efb5e3 100644 --- a/services/media/framework_mojo/mojo_consumer.cc +++ b/services/media/framework_mojo/mojo_consumer.cc
@@ -46,6 +46,7 @@ void MojoConsumer::SendPacket( MediaPacketPtr media_packet, const SendPacketCallback& callback) { + DCHECK(media_packet); DCHECK(supply_callback_); supply_callback_(PacketImpl::Create( media_packet.Pass(), @@ -77,7 +78,7 @@ } void MojoConsumer::set_allocator(PayloadAllocator* allocator) { - NOTREACHED(); + LOG(ERROR) << "set_allocator called on MojoConsumer"; } void MojoConsumer::SetSupplyCallback(const SupplyCallback& supply_callback) { @@ -91,10 +92,16 @@ const SendPacketCallback& callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner, const MappedSharedBuffer& buffer) : + Packet( + media_packet->pts, + media_packet->end_of_stream, + media_packet->payload->length, + media_packet->payload->length == 0 ? + nullptr : + buffer.PtrFromOffset(media_packet->payload->offset)), media_packet_(media_packet.Pass()), callback_(callback), - task_runner_(task_runner), - payload_(buffer.PtrFromOffset(media_packet_->payload->offset)) {} + task_runner_(task_runner) {} MojoConsumer::PacketImpl::~PacketImpl() {}
diff --git a/services/media/framework_mojo/mojo_consumer.h b/services/media/framework_mojo/mojo_consumer.h index f737405..076623e 100644 --- a/services/media/framework_mojo/mojo_consumer.h +++ b/services/media/framework_mojo/mojo_consumer.h
@@ -89,25 +89,6 @@ buffer)); } - // Packet implementation. - int64_t presentation_time() const override { - return media_packet_->pts; - } - - uint64_t duration() const override { - return media_packet_->duration; - } - - bool end_of_stream() const override { - return media_packet_->end_of_stream; - } - - size_t size() const override { - return media_packet_->payload->length; - } - - void* payload() const override { return payload_; } - protected: void Release() override; @@ -125,7 +106,6 @@ MediaPacketPtr media_packet_; const SendPacketCallback callback_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - void* payload_; }; BindingSet<MediaConsumer> bindings_;
diff --git a/services/media/framework_mojo/mojo_producer.cc b/services/media/framework_mojo/mojo_producer.cc index 4554ae5..744feed 100644 --- a/services/media/framework_mojo/mojo_producer.cc +++ b/services/media/framework_mojo/mojo_producer.cc
@@ -56,7 +56,7 @@ DCHECK(consumer_.is_bound()); consumer_->Flush(callback); - first_presentation_time_since_flush_ = Packet::kUnknownPresentationTime; + first_pts_since_flush_ = Packet::kUnknownPts; end_of_stream_= false; } @@ -65,8 +65,8 @@ status_callback_ = callback; } -int64_t MojoProducer::GetFirstPresentationTimeSinceFlush() { - return first_presentation_time_since_flush_; +int64_t MojoProducer::GetFirstPtsSinceFlush() { + return first_pts_since_flush_; } PayloadAllocator* MojoProducer::allocator() { @@ -80,9 +80,8 @@ Demand MojoProducer::SupplyPacket(PacketPtr packet) { DCHECK(packet); - if (first_presentation_time_since_flush_ == - Packet::kUnknownPresentationTime) { - first_presentation_time_since_flush_ = packet->presentation_time(); + if (first_pts_since_flush_ == Packet::kUnknownPts) { + first_pts_since_flush_ = packet->pts(); } // If we're no longer connected, throw the packet away. @@ -192,8 +191,7 @@ region->length = packet->size(); MediaPacketPtr media_packet = MediaPacket::New(); - media_packet->pts = packet->presentation_time(); - media_packet->duration = packet->duration(); + media_packet->pts = packet->pts(); media_packet->end_of_stream = packet->end_of_stream(); media_packet->payload = region.Pass();
diff --git a/services/media/framework_mojo/mojo_producer.h b/services/media/framework_mojo/mojo_producer.h index 2fb252e..5679b7c 100644 --- a/services/media/framework_mojo/mojo_producer.h +++ b/services/media/framework_mojo/mojo_producer.h
@@ -45,7 +45,7 @@ // Gets the first presentation time seen on any packet after the most recent // flush or, if there has never been a flush, the first packet supplied. - int64_t GetFirstPresentationTimeSinceFlush(); + int64_t GetFirstPtsSinceFlush(); // ActiveSink implementation. PayloadAllocator* allocator() override; @@ -89,8 +89,7 @@ bool end_of_stream_= false; DemandCallback demand_callback_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - int64_t first_presentation_time_since_flush_ = - Packet::kUnknownPresentationTime; + int64_t first_pts_since_flush_ = Packet::kUnknownPts; // TODO(dalesat): Base this logic on presentation time or duration. uint32_t max_pushes_outstanding_ = 0; uint32_t current_pushes_outstanding_ = 0;
diff --git a/services/media/framework_mojo/mojo_pull_mode_producer.cc b/services/media/framework_mojo/mojo_pull_mode_producer.cc index 141d6e1..b2c7dc8 100644 --- a/services/media/framework_mojo/mojo_pull_mode_producer.cc +++ b/services/media/framework_mojo/mojo_pull_mode_producer.cc
@@ -11,7 +11,7 @@ MojoPullModeProducer::MojoPullModeProducer() : state_(MediaState::UNPREPARED), demand_(Demand::kNegative), - presentation_time_(0), + pts_(0), cached_packet_(nullptr) {} MojoPullModeProducer::~MojoPullModeProducer() { @@ -157,7 +157,7 @@ // At end-of-stream. Respond with empty end-of-stream packet. HandlePullWithPacketUnsafe( callback, - Packet::CreateEndOfStream(presentation_time_)); + Packet::CreateEndOfStream(pts_)); return true; } @@ -190,11 +190,10 @@ region->length = packet->size(); MediaPacketPtr media_packet = MediaPacket::New(); - media_packet->pts = packet->presentation_time(); - media_packet->duration = packet->duration(); + media_packet->pts = packet->pts(); media_packet->end_of_stream = packet->end_of_stream(); media_packet->payload = region.Pass(); - presentation_time_ = packet->presentation_time() + packet->duration(); + pts_ = packet->pts(); return media_packet.Pass(); }
diff --git a/services/media/framework_mojo/mojo_pull_mode_producer.h b/services/media/framework_mojo/mojo_pull_mode_producer.h index 5ecf80e..8ba6fc6 100644 --- a/services/media/framework_mojo/mojo_pull_mode_producer.h +++ b/services/media/framework_mojo/mojo_pull_mode_producer.h
@@ -78,7 +78,7 @@ // THE FIELDS BELOW SHOULD ONLY BE ACCESSED WITH lock_ TAKEN. MediaState state_; Demand demand_; - int64_t presentation_time_; + int64_t pts_; // pending_pulls_ contains the callbacks for the pull requests that have yet // to be satisfied. unreleased_packets_ contains the packets that have been