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

Side by Side Diff: media/filters/ffmpeg_video_decoder.cc

Issue 2768713002: Pass a |media_log| to FFmpegVideoDecoder and roll ffmpeg (Closed)
Patch Set: Created 3 years, 9 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/filters/ffmpeg_video_decoder.h" 5 #include "media/filters/ffmpeg_video_decoder.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <string> 11 #include <string>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/sys_info.h" 19 #include "base/sys_info.h"
20 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
21 #include "media/base/bind_to_current_loop.h" 21 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/decoder_buffer.h" 22 #include "media/base/decoder_buffer.h"
23 #include "media/base/limits.h" 23 #include "media/base/limits.h"
24 #include "media/base/media_log.h"
24 #include "media/base/media_switches.h" 25 #include "media/base/media_switches.h"
25 #include "media/base/timestamp_constants.h" 26 #include "media/base/timestamp_constants.h"
26 #include "media/base/video_frame.h" 27 #include "media/base/video_frame.h"
27 #include "media/base/video_util.h" 28 #include "media/base/video_util.h"
28 #include "media/ffmpeg/ffmpeg_common.h" 29 #include "media/ffmpeg/ffmpeg_common.h"
29 #include "media/filters/ffmpeg_glue.h" 30 #include "media/filters/ffmpeg_glue.h"
30 31
31 namespace media { 32 namespace media {
32 33
34 namespace {
35
36 std::string AVErrorString(int errnum) {
wolenetz 2017/03/22 19:31:50 If the plan is to put similar into other ffmpeg us
sandersd (OOO until July 31) 2017/03/23 23:34:36 Done.
37 char errbuf[AV_ERROR_MAX_STRING_SIZE];
38 av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, errnum);
DaleCurtis 2017/03/22 00:43:16 Will need an ffmpeg roll to use this in component
sandersd (OOO until July 31) 2017/03/23 23:34:36 Done.
39 return std::string(errbuf);
40 }
41
42 } // namespace
43
33 // Always use 2 or more threads for video decoding. Most machines today will 44 // Always use 2 or more threads for video decoding. Most machines today will
34 // have 2-8 execution contexts. Using more cores generally doesn't seem to 45 // have 2-8 execution contexts. Using more cores generally doesn't seem to
35 // increase power usage and allows us to decode video faster. 46 // increase power usage and allows us to decode video faster.
36 // 47 //
37 // Handling decoding on separate threads also frees up the pipeline thread to 48 // Handling decoding on separate threads also frees up the pipeline thread to
38 // continue processing. Although it'd be nice to have the option of a single 49 // continue processing. Although it'd be nice to have the option of a single
39 // decoding thread, FFmpeg treats having one thread the same as having zero 50 // decoding thread, FFmpeg treats having one thread the same as having zero
40 // threads (i.e., avcodec_decode_video() will execute on the calling thread). 51 // threads (i.e., avcodec_decode_video() will execute on the calling thread).
41 // Yet another reason for having two threads :) 52 // Yet another reason for having two threads :)
42 static const int kDecodeThreads = 2; 53 static const int kDecodeThreads = 2;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 if (opaque) 116 if (opaque)
106 static_cast<VideoFrame*>(opaque)->Release(); 117 static_cast<VideoFrame*>(opaque)->Release();
107 } 118 }
108 119
109 // static 120 // static
110 bool FFmpegVideoDecoder::IsCodecSupported(VideoCodec codec) { 121 bool FFmpegVideoDecoder::IsCodecSupported(VideoCodec codec) {
111 FFmpegGlue::InitializeFFmpeg(); 122 FFmpegGlue::InitializeFFmpeg();
112 return avcodec_find_decoder(VideoCodecToCodecID(codec)) != nullptr; 123 return avcodec_find_decoder(VideoCodecToCodecID(codec)) != nullptr;
113 } 124 }
114 125
115 FFmpegVideoDecoder::FFmpegVideoDecoder() 126 FFmpegVideoDecoder::FFmpegVideoDecoder(scoped_refptr<MediaLog> media_log)
116 : state_(kUninitialized), decode_nalus_(false) { 127 : media_log_(std::move(media_log)),
128 state_(kUninitialized),
129 decode_nalus_(false) {
117 thread_checker_.DetachFromThread(); 130 thread_checker_.DetachFromThread();
118 } 131 }
119 132
120 int FFmpegVideoDecoder::GetVideoBuffer(struct AVCodecContext* codec_context, 133 int FFmpegVideoDecoder::GetVideoBuffer(struct AVCodecContext* codec_context,
121 AVFrame* frame, 134 AVFrame* frame,
122 int flags) { 135 int flags) {
123 // Don't use |codec_context_| here! With threaded decoding, 136 // Don't use |codec_context_| here! With threaded decoding,
124 // it will contain unsynchronized width/height/pix_fmt values, 137 // it will contain unsynchronized width/height/pix_fmt values,
125 // whereas |codec_context| contains the current threads's 138 // whereas |codec_context| contains the current threads's
126 // updated width/height/pix_fmt, which can change for adaptive 139 // updated width/height/pix_fmt, which can change for adaptive
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 codec_context_->reordered_opaque = buffer->timestamp().InMicroseconds(); 364 codec_context_->reordered_opaque = buffer->timestamp().InMicroseconds();
352 } 365 }
353 366
354 int frame_decoded = 0; 367 int frame_decoded = 0;
355 int result = avcodec_decode_video2(codec_context_.get(), 368 int result = avcodec_decode_video2(codec_context_.get(),
356 av_frame_.get(), 369 av_frame_.get(),
357 &frame_decoded, 370 &frame_decoded,
358 &packet); 371 &packet);
359 // Log the problem if we can't decode a video frame and exit early. 372 // Log the problem if we can't decode a video frame and exit early.
360 if (result < 0) { 373 if (result < 0) {
361 LOG(ERROR) << "Error decoding video: " << buffer->AsHumanReadableString(); 374 MEDIA_LOG(DEBUG, media_log_)
375 << "avcodec_decode_video2(): " << AVErrorString(result) << ", at "
376 << buffer->AsHumanReadableString();
362 return false; 377 return false;
363 } 378 }
364 379
365 // FFmpeg says some codecs might have multiple frames per packet. Previous 380 // FFmpeg says some codecs might have multiple frames per packet. Previous
366 // discussions with rbultje@ indicate this shouldn't be true for the codecs 381 // discussions with rbultje@ indicate this shouldn't be true for the codecs
367 // we use. 382 // we use.
368 DCHECK_EQ(result, packet.size); 383 DCHECK_EQ(result, packet.size);
369 384
370 // If no frame was produced then signal that more data is required to 385 // If no frame was produced then signal that more data is required to
371 // produce more frames. This can happen under two circumstances: 386 // produce more frames. This can happen under two circumstances:
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) { 443 if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
429 ReleaseFFmpegResources(); 444 ReleaseFFmpegResources();
430 return false; 445 return false;
431 } 446 }
432 447
433 av_frame_.reset(av_frame_alloc()); 448 av_frame_.reset(av_frame_alloc());
434 return true; 449 return true;
435 } 450 }
436 451
437 } // namespace media 452 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698