OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |