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

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: Changed the way AVBuffer allocation/deallocation is done in the ffmpeg audio decoder. 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..c0cb980906c7ed8f2d50034181e73c62b93b19bc
--- /dev/null
+++ b/services/media/framework_ffmpeg/ffmpeg_decoder_base.cc
@@ -0,0 +1,97 @@
+// 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(AvCodecContextPtr av_codec_context) :
+ av_codec_context_(std::move(av_codec_context)),
+ av_frame_(av_frame_alloc()) {
+ DCHECK(av_codec_context);
+}
+
+FfmpegDecoderBase::~FfmpegDecoderBase() {}
+
+std::unique_ptr<StreamType> FfmpegDecoderBase::output_stream_type() {
+ return StreamTypeFromAVCodecContext(*av_codec_context_);
+}
+
+void FfmpegDecoderBase::Flush() {
+ DCHECK(av_codec_context_);
+ avcodec_flush_buffers(av_codec_context_.get());
+}
+
+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);
+ if (input_bytes_used < 0) {
+ // Decode failed.
+ return UnprepareInputPacket(input, output);
+ }
+
+ if (frame_decoded) {
+ DCHECK(allocator);
+ *output = CreateOutputPacket(allocator);
+ av_frame_unref(av_frame_.get());
+ }
+
+ CHECK(input_bytes_used <= av_packet_.size)
+ << "Ffmpeg decoder read beyond end of packet";
+ av_packet_.size -= input_bytes_used;
+ av_packet_.data += input_bytes_used;
+
+ 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 = CreateOutputEndOfStreamPacket();
+ }
+
+ av_packet_.size = 0;
+ av_packet_.data = nullptr;
+
+ return true;
+}
+
+} // namespace media
+} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698