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

Side by Side Diff: webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc

Issue 1639273002: H264: Thread-safe InitializeFFmpeg. Flag to control if InitializeFFmpeg should be called. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 * 9 *
10 */ 10 */
(...skipping 16 matching lines...) Expand all
27 27
28 namespace webrtc { 28 namespace webrtc {
29 29
30 namespace { 30 namespace {
31 31
32 const AVPixelFormat kPixelFormat = AV_PIX_FMT_YUV420P; 32 const AVPixelFormat kPixelFormat = AV_PIX_FMT_YUV420P;
33 const size_t kYPlaneIndex = 0; 33 const size_t kYPlaneIndex = 0;
34 const size_t kUPlaneIndex = 1; 34 const size_t kUPlaneIndex = 1;
35 const size_t kVPlaneIndex = 2; 35 const size_t kVPlaneIndex = 2;
36 36
37 #if !defined(WEBRTC_CHROMIUM_BUILD) 37 #if defined(WEBRTC_INITIALIZE_FFMPEG)
38 38
39 rtc::CriticalSection ffmpeg_init_lock;
hbos 2016/01/27 13:35:42 Is it OK to have a global variable that is a class
stefan-webrtc 2016/01/27 14:00:39 Hm, I'm not sure, but I think it should be OK. We
hbos 2016/01/28 10:31:09 If I expose it in the header then I have to make s
stefan-webrtc 2016/01/28 10:39:46 I just wanted to make sure we considered it. Agree
39 bool ffmpeg_initialized = false; 40 bool ffmpeg_initialized = false;
stefan-webrtc 2016/01/27 14:00:38 I guess an option could be to use atomics for this
hbos 2016/01/28 10:31:09 Don't think it matters since I have to use the loc
stefan-webrtc 2016/01/28 10:39:46 Leave as is.
40 41
41 // Called by FFmpeg to do mutex operations if initialized using 42 // Called by FFmpeg to do mutex operations if initialized using
42 // |InitializeFFmpeg|. 43 // |InitializeFFmpeg|.
43 int LockManagerOperation(void** lock, AVLockOp op) 44 int LockManagerOperation(void** lock, AVLockOp op)
44 EXCLUSIVE_LOCK_FUNCTION() UNLOCK_FUNCTION() { 45 EXCLUSIVE_LOCK_FUNCTION() UNLOCK_FUNCTION() {
45 switch (op) { 46 switch (op) {
46 case AV_LOCK_CREATE: 47 case AV_LOCK_CREATE:
47 *lock = new rtc::CriticalSection(); 48 *lock = new rtc::CriticalSection();
48 return 0; 49 return 0;
49 case AV_LOCK_OBTAIN: 50 case AV_LOCK_OBTAIN:
50 static_cast<rtc::CriticalSection*>(*lock)->Enter(); 51 static_cast<rtc::CriticalSection*>(*lock)->Enter();
51 return 0; 52 return 0;
52 case AV_LOCK_RELEASE: 53 case AV_LOCK_RELEASE:
53 static_cast<rtc::CriticalSection*>(*lock)->Leave(); 54 static_cast<rtc::CriticalSection*>(*lock)->Leave();
54 return 0; 55 return 0;
55 case AV_LOCK_DESTROY: 56 case AV_LOCK_DESTROY:
56 delete static_cast<rtc::CriticalSection*>(*lock); 57 delete static_cast<rtc::CriticalSection*>(*lock);
57 *lock = nullptr; 58 *lock = nullptr;
58 return 0; 59 return 0;
59 } 60 }
60 RTC_NOTREACHED() << "Unrecognized AVLockOp."; 61 RTC_NOTREACHED() << "Unrecognized AVLockOp.";
61 return -1; 62 return -1;
62 } 63 }
63 64
64 // TODO(hbos): Assumed to be called on a single thread. Should DCHECK that
65 // InitializeFFmpeg is only called on one thread or make it thread safe.
66 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=5427.
67 void InitializeFFmpeg() { 65 void InitializeFFmpeg() {
66 rtc::CritScope cs(&ffmpeg_init_lock);
68 if (!ffmpeg_initialized) { 67 if (!ffmpeg_initialized) {
69 if (av_lockmgr_register(LockManagerOperation) < 0) { 68 if (av_lockmgr_register(LockManagerOperation) < 0) {
70 RTC_NOTREACHED() << "av_lockmgr_register failed."; 69 RTC_NOTREACHED() << "av_lockmgr_register failed.";
71 return; 70 return;
72 } 71 }
73 av_register_all(); 72 av_register_all();
74 ffmpeg_initialized = true; 73 ffmpeg_initialized = true;
75 } 74 }
76 } 75 }
77 76
78 #endif // !defined(WEBRTC_CHROMIUM_BUILD) 77 #endif // defined(WEBRTC_INITIALIZE_FFMPEG)
79 78
80 // Called by FFmpeg when it is done with a frame buffer, see AVGetBuffer2. 79 // Called by FFmpeg when it is done with a frame buffer, see AVGetBuffer2.
81 void AVFreeBuffer2(void* opaque, uint8_t* data) { 80 void AVFreeBuffer2(void* opaque, uint8_t* data) {
82 VideoFrame* video_frame = static_cast<VideoFrame*>(opaque); 81 VideoFrame* video_frame = static_cast<VideoFrame*>(opaque);
83 delete video_frame; 82 delete video_frame;
84 } 83 }
85 84
86 // Called by FFmpeg when it needs a frame buffer to store decoded frames in. 85 // Called by FFmpeg when it needs a frame buffer to store decoded frames in.
87 // The VideoFrames returned by FFmpeg at |Decode| originate from here. They are 86 // The VideoFrames returned by FFmpeg at |Decode| originate from here. They are
88 // reference counted and freed by FFmpeg using |AVFreeBuffer2|. 87 // reference counted and freed by FFmpeg using |AVFreeBuffer2|.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 Release(); 171 Release();
173 } 172 }
174 173
175 int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings, 174 int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings,
176 int32_t number_of_cores) { 175 int32_t number_of_cores) {
177 if (codec_settings && 176 if (codec_settings &&
178 codec_settings->codecType != kVideoCodecH264) { 177 codec_settings->codecType != kVideoCodecH264) {
179 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 178 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
180 } 179 }
181 180
182 // In Chromium FFmpeg will be initialized outside of WebRTC and we should not 181 // FFmpeg must have been initialized (with |av_lockmgr_register| and
183 // attempt to do so ourselves or it will be initialized twice. 182 // |av_register_all|) before we proceed. |InitializeFFmpeg| does this, which
184 // TODO(hbos): Put behind a different flag in case non-chromium project wants 183 // makes sense for WebRTC standalone. In other cases, such as Chromium, FFmpeg
185 // to initialize externally. 184 // is initialized externally and calling |InitializeFFmpeg| would be
186 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=5427. 185 // thread-unsafe and result in FFmpeg being initialized twice, which could
187 #if !defined(WEBRTC_CHROMIUM_BUILD) 186 // break other FFmpeg usage. See the |rtc_skip_ffmpeg_init| flag.
stefan-webrtc 2016/01/27 14:00:39 How is it safe to do this in webrtc if Chrome can
hbos 2016/01/28 10:31:09 Calling InitializeFFmpeg multiple times won't init
187 #if defined(WEBRTC_INITIALIZE_FFMPEG)
188 // Make sure FFmpeg has been initialized. 188 // Make sure FFmpeg has been initialized.
189 InitializeFFmpeg(); 189 InitializeFFmpeg();
190 #endif 190 #endif
191 191
192 // Release necessary in case of re-initializing. 192 // Release necessary in case of re-initializing.
193 int32_t ret = Release(); 193 int32_t ret = Release();
194 if (ret != WEBRTC_VIDEO_CODEC_OK) 194 if (ret != WEBRTC_VIDEO_CODEC_OK)
195 return ret; 195 return ret;
196 RTC_DCHECK(!av_context_); 196 RTC_DCHECK(!av_context_);
197 197
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 return ret; 353 return ret;
354 } 354 }
355 return WEBRTC_VIDEO_CODEC_OK; 355 return WEBRTC_VIDEO_CODEC_OK;
356 } 356 }
357 357
358 bool H264DecoderImpl::IsInitialized() const { 358 bool H264DecoderImpl::IsInitialized() const {
359 return av_context_ != nullptr; 359 return av_context_ != nullptr;
360 } 360 }
361 361
362 } // namespace webrtc 362 } // namespace webrtc
OLDNEW
« webrtc/modules/video_coding/BUILD.gn ('K') | « webrtc/modules/video_coding/codecs/h264/h264.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698