| 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 |