Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Unified Diff: services/media/framework_ffmpeg/ffmpeg_decoder_base.cc

Issue 1686363002: Motown: ffmpeg implementations of framework 'parts' (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Retype some const unique_ptr<T>& parameters to const T&. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/media/framework_ffmpeg/ffmpeg_decoder_base.cc
diff --git a/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc b/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc
new file mode 100644
index 0000000000000000000000000000000000000000..517cc7a2f2189e3a6a3c98556bcda911e7877fa4
--- /dev/null
+++ b/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc
@@ -0,0 +1,106 @@
+// 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.
+
+#include "base/logging.h"
+#include "services/media/framework_ffmpeg/ffmpeg_decoder_base.h"
+#include "services/media/framework_ffmpeg/ffmpeg_type_converters.h"
+
+namespace mojo {
+namespace media {
+
+FfmpegDecoderBase::FfmpegDecoderBase(AVCodecContext *av_codec_context) :
+ av_codec_context_(av_codec_context),
+ av_frame_(av_frame_alloc()),
+ next_presentation_time_(0) {
+ DCHECK(av_codec_context);
+}
+
+FfmpegDecoderBase::~FfmpegDecoderBase() {}
+
+Result FfmpegDecoderBase::Init(const StreamType& stream_type) {
+ return Result::kOk;
johngro 2016/03/01 01:31:38 Since this class is already abstract, why provide
dalesat 2016/03/01 20:43:01 AVCodecContext is established in the constructor a
+}
+
+std::unique_ptr<StreamType> FfmpegDecoderBase::output_stream_type() {
+ return StreamTypeFromAVCodecContext(av_codec_context_.get());
+}
+
+void FfmpegDecoderBase::Flush() {
+ avcodec_flush_buffers(av_codec_context_.get());
johngro 2016/03/01 01:31:38 avcodec_flush_buffers is not safe against being ca
dalesat 2016/03/01 20:43:01 Done.
+}
+
+bool FfmpegDecoderBase::TransformPacket(
+ const PacketPtr& input,
+ bool new_input,
+ PayloadAllocator* allocator,
+ PacketPtr* output) {
+ DCHECK(input);
+ DCHECK(allocator);
+ DCHECK(output);
+
+ *output = nullptr;
+
+ if (new_input) {
+ PrepareInputPacket(input);
+ }
+
+ bool frame_decoded = false;
+ int input_bytes_used = Decode(allocator, &frame_decoded);
johngro 2016/03/01 01:31:38 ssize_t instead of int?
dalesat 2016/03/01 20:43:01 Decode wraps one of two avcodec_decode_* functions
+ if (input_bytes_used < 0) {
+ // Decode failed.
+ return UnprepareInputPacket(input, output);
+ }
+
+ if (frame_decoded) {
+ *output = PacketFromAvFrame(allocator);
+ }
+
+ av_packet_.size -= input_bytes_used;
+ av_packet_.data += input_bytes_used;
johngro 2016/03/01 01:31:38 DCHECK(av_packet_.size >= input_bytes_used) and ru
dalesat 2016/03/01 20:43:01 Added a CHECK
+
+ if (av_packet_.size != 0 || (input->end_of_stream() && frame_decoded)) {
+ // The input packet is only partially decoded, or it's an end-of-stream
+ // packet and we're still draining. Let the caller know we want to see the
+ // input packet again.
+ return false;
+ }
+
+ // Used up the whole input packet, and, if we were draining, we're done with
+ // that too.
+ return UnprepareInputPacket(input, output);
+}
+
+void FfmpegDecoderBase::PrepareInputPacket(const PacketPtr& input) {
+ av_init_packet(&av_packet_);
+ av_packet_.data = reinterpret_cast<uint8_t*>(input->payload());
+ av_packet_.size = input->size();
+}
+
+bool FfmpegDecoderBase::UnprepareInputPacket(
+ const PacketPtr& input,
+ PacketPtr* output) {
+ if (input->end_of_stream()) {
+ // Indicate end of stream. This happens when we're draining for the last
+ // time, so there should be no output packet yet.
+ DCHECK(*output == nullptr);
+ *output = Packet::CreateEndOfStream(next_presentation_time_);
johngro 2016/03/01 01:31:38 what is the purpose of putting a PTS on an empty E
dalesat 2016/03/01 20:43:01 Design discussion.
+ }
+
+ av_packet_.size = 0;
+ av_packet_.data = nullptr;
+
+ return true;
+}
+
+PacketPtr FfmpegDecoderBase::PacketFromAvFrame(PayloadAllocator* allocator) {
+ DCHECK(allocator);
+
+ PacketPtr packet = CreateOutputPacket(allocator);
+ av_frame_unref(av_frame_.get());
+ next_presentation_time_ = packet->presentation_time() + packet->duration();
johngro 2016/03/01 01:31:38 either presentation_time or duration may be undefi
dalesat 2016/03/01 20:43:01 I've moved the next_presentation_time_ into the su
+ return packet;
+}
+
+} // namespace media
+} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698