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

Side by Side Diff: services/media/framework_ffmpeg/ffmpeg_video_decoder.cc

Issue 2077413003: Motown: Various fixes related to video playback support (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Comments and name changes for clarity. Created 4 years, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "mojo/services/media/common/cpp/timeline.h"
9 #include "mojo/services/media/common/cpp/timeline_rate.h"
8 #include "services/media/framework_ffmpeg/ffmpeg_formatting.h" 10 #include "services/media/framework_ffmpeg/ffmpeg_formatting.h"
9 #include "services/media/framework_ffmpeg/ffmpeg_video_decoder.h" 11 #include "services/media/framework_ffmpeg/ffmpeg_video_decoder.h"
10 extern "C" { 12 extern "C" {
11 #include "third_party/ffmpeg/libavutil/imgutils.h" 13 #include "third_party/ffmpeg/libavutil/imgutils.h"
12 } 14 }
13 15
14 namespace mojo { 16 namespace mojo {
15 namespace media { 17 namespace media {
16 18
17 FfmpegVideoDecoder::FfmpegVideoDecoder(AvCodecContextPtr av_codec_context) 19 FfmpegVideoDecoder::FfmpegVideoDecoder(AvCodecContextPtr av_codec_context)
18 : FfmpegDecoderBase(std::move(av_codec_context)) { 20 : FfmpegDecoderBase(std::move(av_codec_context)) {
19 DCHECK(context()); 21 DCHECK(context());
20 22
21 context()->opaque = this; 23 context()->opaque = this;
22 context()->get_buffer2 = AllocateBufferForAvFrame; 24 context()->get_buffer2 = AllocateBufferForAvFrame;
23 context()->refcounted_frames = 1; 25 context()->refcounted_frames = 1;
26
27 // Turn on multi-proc decoding by allowing the decoder to use three threads
28 // (the calling thread and the two specified here). FF_THREAD_FRAME means
29 // that threads are assigned an entire frame.
30 // TODO(dalesat): Consider using FF_THREAD_SLICE.
31 context()->thread_count = 2;
32 context()->thread_type = FF_THREAD_FRAME;
33
34 // Determine the frame rate in frames per nanosecond so we can translate pts
35 // values from frame index to nanoseconds.
36 frame_rate_in_frames_per_ns_ =
37 TimelineRate(context()->time_base.den,
38 Timeline::ns_from_seconds(context()->time_base.num));
24 } 39 }
25 40
26 FfmpegVideoDecoder::~FfmpegVideoDecoder() {} 41 FfmpegVideoDecoder::~FfmpegVideoDecoder() {}
27 42
28 int FfmpegVideoDecoder::Decode(const AVPacket& av_packet, 43 int FfmpegVideoDecoder::Decode(const AVPacket& av_packet,
29 const ffmpeg::AvFramePtr& av_frame_ptr, 44 const ffmpeg::AvFramePtr& av_frame_ptr,
30 PayloadAllocator* allocator, 45 PayloadAllocator* allocator,
31 bool* frame_decoded_out) { 46 bool* frame_decoded_out) {
32 DCHECK(allocator); 47 DCHECK(allocator);
33 DCHECK(frame_decoded_out); 48 DCHECK(frame_decoded_out);
(...skipping 22 matching lines...) Expand all
56 71
57 void FfmpegVideoDecoder::Flush() { 72 void FfmpegVideoDecoder::Flush() {
58 FfmpegDecoderBase::Flush(); 73 FfmpegDecoderBase::Flush();
59 next_pts_ = Packet::kUnknownPts; 74 next_pts_ = Packet::kUnknownPts;
60 } 75 }
61 76
62 PacketPtr FfmpegVideoDecoder::CreateOutputPacket(const AVFrame& av_frame, 77 PacketPtr FfmpegVideoDecoder::CreateOutputPacket(const AVFrame& av_frame,
63 PayloadAllocator* allocator) { 78 PayloadAllocator* allocator) {
64 DCHECK(allocator); 79 DCHECK(allocator);
65 80
66 // Recover the pts deposited in Decode. 81 // Recover the pts deposited in Decode and divide it by frames per nanosecond
67 next_pts_ = av_frame.reordered_opaque; 82 // to get the pts in nanoseconds.
83 next_pts_ = av_frame.reordered_opaque / frame_rate_in_frames_per_ns_;
68 84
69 AvBufferContext* av_buffer_context = 85 return DecoderPacket::Create(next_pts_, av_buffer_ref(av_frame.buf[0]));
70 reinterpret_cast<AvBufferContext*>(av_buffer_get_opaque(av_frame.buf[0]));
71
72 return Packet::Create(
73 next_pts_,
74 false, // The base class is responsible for end-of-stream.
75 av_buffer_context->size(), av_buffer_context->Release(), allocator);
76 } 86 }
77 87
78 PacketPtr FfmpegVideoDecoder::CreateOutputEndOfStreamPacket() { 88 PacketPtr FfmpegVideoDecoder::CreateOutputEndOfStreamPacket() {
79 return Packet::CreateEndOfStream(next_pts_); 89 return Packet::CreateEndOfStream(next_pts_);
80 } 90 }
81 91
82 int FfmpegVideoDecoder::AllocateBufferForAvFrame( 92 int FfmpegVideoDecoder::AllocateBufferForAvFrame(
83 AVCodecContext* av_codec_context, 93 AVCodecContext* av_codec_context,
84 AVFrame* av_frame, 94 AVFrame* av_frame,
85 int flags) { 95 int flags) {
(...skipping 28 matching lines...) Expand all
114 static_cast<size_t>(av_codec_context->coded_width)), 124 static_cast<size_t>(av_codec_context->coded_width)),
115 std::max(visible_size.height(), 125 std::max(visible_size.height(),
116 static_cast<size_t>(av_codec_context->coded_height))); 126 static_cast<size_t>(av_codec_context->coded_height)));
117 127
118 VideoStreamType::FrameLayout frame_layout; 128 VideoStreamType::FrameLayout frame_layout;
119 129
120 VideoStreamType::InfoForPixelFormat( 130 VideoStreamType::InfoForPixelFormat(
121 PixelFormatFromAVPixelFormat(av_codec_context->pix_fmt)) 131 PixelFormatFromAVPixelFormat(av_codec_context->pix_fmt))
122 .BuildFrameLayout(coded_size, &frame_layout); 132 .BuildFrameLayout(coded_size, &frame_layout);
123 133
124 AvBufferContext* av_buffer_context = 134 uint8_t* buffer = static_cast<uint8_t*>(
125 new AvBufferContext(frame_layout.size, self->allocator_); 135 self->allocator_->AllocatePayloadBuffer(frame_layout.size));
126 uint8_t* buffer = av_buffer_context->buffer();
127 136
128 // TODO(dalesat): For investigation purposes only...remove one day. 137 // TODO(dalesat): For investigation purposes only...remove one day.
129 if (self->first_frame_) { 138 if (self->first_frame_) {
130 self->first_frame_ = false; 139 self->first_frame_ = false;
131 self->colorspace_ = av_codec_context->colorspace; 140 self->colorspace_ = av_codec_context->colorspace;
132 self->coded_size_ = coded_size; 141 self->coded_size_ = coded_size;
133 } else { 142 } else {
134 if (av_codec_context->colorspace != self->colorspace_) { 143 if (av_codec_context->colorspace != self->colorspace_) {
135 LOG(WARNING) << " colorspace changed to " << av_codec_context->colorspace 144 LOG(WARNING) << " colorspace changed to " << av_codec_context->colorspace
136 << std::endl; 145 << std::endl;
(...skipping 24 matching lines...) Expand all
161 } 170 }
162 171
163 // TODO(dalesat): Do we need to attach colorspace info to the packet? 172 // TODO(dalesat): Do we need to attach colorspace info to the packet?
164 173
165 av_frame->width = coded_size.width(); 174 av_frame->width = coded_size.width();
166 av_frame->height = coded_size.height(); 175 av_frame->height = coded_size.height();
167 av_frame->format = av_codec_context->pix_fmt; 176 av_frame->format = av_codec_context->pix_fmt;
168 av_frame->reordered_opaque = av_codec_context->reordered_opaque; 177 av_frame->reordered_opaque = av_codec_context->reordered_opaque;
169 178
170 DCHECK(av_frame->data[0] == buffer); 179 DCHECK(av_frame->data[0] == buffer);
171 av_frame->buf[0] = 180 av_frame->buf[0] = av_buffer_create(buffer, frame_layout.size,
172 av_buffer_create(buffer, av_buffer_context->size(), 181 ReleaseBufferForAvFrame, self->allocator_,
173 ReleaseBufferForAvFrame, av_buffer_context, 182 0); // flags
174 0); // flags
175 183
176 return 0; 184 return 0;
177 } 185 }
178 186
179 void FfmpegVideoDecoder::ReleaseBufferForAvFrame(void* opaque, 187 void FfmpegVideoDecoder::ReleaseBufferForAvFrame(void* opaque,
180 uint8_t* buffer) { 188 uint8_t* buffer) {
181 AvBufferContext* av_buffer_context = 189 DCHECK(opaque);
182 reinterpret_cast<AvBufferContext*>(opaque); 190 DCHECK(buffer);
183 DCHECK(av_buffer_context); 191 PayloadAllocator* allocator = reinterpret_cast<PayloadAllocator*>(opaque);
184 // Either this buffer has already been released to someone else's ownership, 192 allocator->ReleasePayloadBuffer(buffer);
185 // or it's the same as the buffer parameter.
186 DCHECK(av_buffer_context->buffer() == nullptr ||
187 av_buffer_context->buffer() == buffer);
188 delete av_buffer_context;
189 } 193 }
190 194
191 } // namespace media 195 } // namespace media
192 } // namespace mojo 196 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/framework_ffmpeg/ffmpeg_video_decoder.h ('k') | services/media/framework_mojo/mojo_producer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698