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