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 29 matching lines...) Expand all Loading... |
40 int64_t timestamp; | 40 int64_t timestamp; |
41 }; | 41 }; |
42 | 42 |
43 // On decode we receive a CVPixelBuffer, which we need to convert to a frame | 43 // On decode we receive a CVPixelBuffer, which we need to convert to a frame |
44 // buffer for use in the rest of WebRTC. Unfortunately this involves a frame | 44 // buffer for use in the rest of WebRTC. Unfortunately this involves a frame |
45 // copy. | 45 // copy. |
46 // TODO(tkchin): Stuff CVPixelBuffer into a TextureBuffer and pass that along | 46 // TODO(tkchin): Stuff CVPixelBuffer into a TextureBuffer and pass that along |
47 // instead once the pipeline supports it. | 47 // instead once the pipeline supports it. |
48 rtc::scoped_refptr<webrtc::VideoFrameBuffer> VideoFrameBufferForPixelBuffer( | 48 rtc::scoped_refptr<webrtc::VideoFrameBuffer> VideoFrameBufferForPixelBuffer( |
49 CVPixelBufferRef pixel_buffer) { | 49 CVPixelBufferRef pixel_buffer) { |
50 DCHECK(pixel_buffer); | 50 RTC_DCHECK(pixel_buffer); |
51 DCHECK(CVPixelBufferGetPixelFormatType(pixel_buffer) == | 51 RTC_DCHECK(CVPixelBufferGetPixelFormatType(pixel_buffer) == |
52 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange); | 52 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange); |
53 size_t width = CVPixelBufferGetWidthOfPlane(pixel_buffer, 0); | 53 size_t width = CVPixelBufferGetWidthOfPlane(pixel_buffer, 0); |
54 size_t height = CVPixelBufferGetHeightOfPlane(pixel_buffer, 0); | 54 size_t height = CVPixelBufferGetHeightOfPlane(pixel_buffer, 0); |
55 // TODO(tkchin): Use a frame buffer pool. | 55 // TODO(tkchin): Use a frame buffer pool. |
56 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = | 56 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = |
57 new rtc::RefCountedObject<webrtc::I420Buffer>(width, height); | 57 new rtc::RefCountedObject<webrtc::I420Buffer>(width, height); |
58 CVPixelBufferLockBaseAddress(pixel_buffer, kCVPixelBufferLock_ReadOnly); | 58 CVPixelBufferLockBaseAddress(pixel_buffer, kCVPixelBufferLock_ReadOnly); |
59 const uint8* src_y = reinterpret_cast<const uint8*>( | 59 const uint8* src_y = reinterpret_cast<const uint8*>( |
60 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0)); | 60 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0)); |
61 int src_y_stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0); | 61 int src_y_stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0); |
62 const uint8* src_uv = reinterpret_cast<const uint8*>( | 62 const uint8* src_uv = reinterpret_cast<const uint8*>( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 int number_of_cores) { | 118 int number_of_cores) { |
119 return WEBRTC_VIDEO_CODEC_OK; | 119 return WEBRTC_VIDEO_CODEC_OK; |
120 } | 120 } |
121 | 121 |
122 int H264VideoToolboxDecoder::Decode( | 122 int H264VideoToolboxDecoder::Decode( |
123 const EncodedImage& input_image, | 123 const EncodedImage& input_image, |
124 bool missing_frames, | 124 bool missing_frames, |
125 const RTPFragmentationHeader* fragmentation, | 125 const RTPFragmentationHeader* fragmentation, |
126 const CodecSpecificInfo* codec_specific_info, | 126 const CodecSpecificInfo* codec_specific_info, |
127 int64_t render_time_ms) { | 127 int64_t render_time_ms) { |
128 DCHECK(input_image._buffer); | 128 RTC_DCHECK(input_image._buffer); |
129 | 129 |
130 CMSampleBufferRef sample_buffer = nullptr; | 130 CMSampleBufferRef sample_buffer = nullptr; |
131 if (!H264AnnexBBufferToCMSampleBuffer(input_image._buffer, | 131 if (!H264AnnexBBufferToCMSampleBuffer(input_image._buffer, |
132 input_image._length, | 132 input_image._length, |
133 video_format_, | 133 video_format_, |
134 &sample_buffer)) { | 134 &sample_buffer)) { |
135 return WEBRTC_VIDEO_CODEC_ERROR; | 135 return WEBRTC_VIDEO_CODEC_ERROR; |
136 } | 136 } |
137 DCHECK(sample_buffer); | 137 RTC_DCHECK(sample_buffer); |
138 // Check if the video format has changed, and reinitialize decoder if needed. | 138 // Check if the video format has changed, and reinitialize decoder if needed. |
139 CMVideoFormatDescriptionRef description = | 139 CMVideoFormatDescriptionRef description = |
140 CMSampleBufferGetFormatDescription(sample_buffer); | 140 CMSampleBufferGetFormatDescription(sample_buffer); |
141 if (!CMFormatDescriptionEqual(description, video_format_)) { | 141 if (!CMFormatDescriptionEqual(description, video_format_)) { |
142 SetVideoFormat(description); | 142 SetVideoFormat(description); |
143 ResetDecompressionSession(); | 143 ResetDecompressionSession(); |
144 } | 144 } |
145 VTDecodeFrameFlags decode_flags = | 145 VTDecodeFrameFlags decode_flags = |
146 kVTDecodeFrame_EnableAsynchronousDecompression; | 146 kVTDecodeFrame_EnableAsynchronousDecompression; |
147 rtc::scoped_ptr<internal::FrameDecodeParams> frame_decode_params; | 147 rtc::scoped_ptr<internal::FrameDecodeParams> frame_decode_params; |
148 frame_decode_params.reset( | 148 frame_decode_params.reset( |
149 new internal::FrameDecodeParams(callback_, input_image._timeStamp)); | 149 new internal::FrameDecodeParams(callback_, input_image._timeStamp)); |
150 OSStatus status = VTDecompressionSessionDecodeFrame( | 150 OSStatus status = VTDecompressionSessionDecodeFrame( |
151 decompression_session_, sample_buffer, decode_flags, | 151 decompression_session_, sample_buffer, decode_flags, |
152 frame_decode_params.release(), nullptr); | 152 frame_decode_params.release(), nullptr); |
153 CFRelease(sample_buffer); | 153 CFRelease(sample_buffer); |
154 if (status != noErr) { | 154 if (status != noErr) { |
155 LOG(LS_ERROR) << "Failed to decode frame with code: " << status; | 155 LOG(LS_ERROR) << "Failed to decode frame with code: " << status; |
156 return WEBRTC_VIDEO_CODEC_ERROR; | 156 return WEBRTC_VIDEO_CODEC_ERROR; |
157 } | 157 } |
158 return WEBRTC_VIDEO_CODEC_OK; | 158 return WEBRTC_VIDEO_CODEC_OK; |
159 } | 159 } |
160 | 160 |
161 int H264VideoToolboxDecoder::RegisterDecodeCompleteCallback( | 161 int H264VideoToolboxDecoder::RegisterDecodeCompleteCallback( |
162 DecodedImageCallback* callback) { | 162 DecodedImageCallback* callback) { |
163 DCHECK(!callback_); | 163 RTC_DCHECK(!callback_); |
164 callback_ = callback; | 164 callback_ = callback; |
165 return WEBRTC_VIDEO_CODEC_OK; | 165 return WEBRTC_VIDEO_CODEC_OK; |
166 } | 166 } |
167 | 167 |
168 int H264VideoToolboxDecoder::Release() { | 168 int H264VideoToolboxDecoder::Release() { |
169 callback_ = nullptr; | 169 callback_ = nullptr; |
170 return WEBRTC_VIDEO_CODEC_OK; | 170 return WEBRTC_VIDEO_CODEC_OK; |
171 } | 171 } |
172 | 172 |
173 int H264VideoToolboxDecoder::Reset() { | 173 int H264VideoToolboxDecoder::Reset() { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 if (status != noErr) { | 231 if (status != noErr) { |
232 DestroyDecompressionSession(); | 232 DestroyDecompressionSession(); |
233 return WEBRTC_VIDEO_CODEC_ERROR; | 233 return WEBRTC_VIDEO_CODEC_ERROR; |
234 } | 234 } |
235 ConfigureDecompressionSession(); | 235 ConfigureDecompressionSession(); |
236 | 236 |
237 return WEBRTC_VIDEO_CODEC_OK; | 237 return WEBRTC_VIDEO_CODEC_OK; |
238 } | 238 } |
239 | 239 |
240 void H264VideoToolboxDecoder::ConfigureDecompressionSession() { | 240 void H264VideoToolboxDecoder::ConfigureDecompressionSession() { |
241 DCHECK(decompression_session_); | 241 RTC_DCHECK(decompression_session_); |
242 #if defined(WEBRTC_IOS) | 242 #if defined(WEBRTC_IOS) |
243 VTSessionSetProperty(decompression_session_, | 243 VTSessionSetProperty(decompression_session_, |
244 kVTDecompressionPropertyKey_RealTime, kCFBooleanTrue); | 244 kVTDecompressionPropertyKey_RealTime, kCFBooleanTrue); |
245 #endif | 245 #endif |
246 } | 246 } |
247 | 247 |
248 void H264VideoToolboxDecoder::DestroyDecompressionSession() { | 248 void H264VideoToolboxDecoder::DestroyDecompressionSession() { |
249 if (decompression_session_) { | 249 if (decompression_session_) { |
250 VTDecompressionSessionInvalidate(decompression_session_); | 250 VTDecompressionSessionInvalidate(decompression_session_); |
251 decompression_session_ = nullptr; | 251 decompression_session_ = nullptr; |
(...skipping 10 matching lines...) Expand all Loading... |
262 } | 262 } |
263 video_format_ = video_format; | 263 video_format_ = video_format; |
264 if (video_format_) { | 264 if (video_format_) { |
265 CFRetain(video_format_); | 265 CFRetain(video_format_); |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 } // namespace webrtc | 269 } // namespace webrtc |
270 | 270 |
271 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) | 271 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) |
OLD | NEW |