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

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

Issue 1515873002: change videotoolbox format from NV12 to I420 (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 30 matching lines...) Expand all
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 RTC_DCHECK(pixel_buffer); 50 RTC_DCHECK(pixel_buffer);
51 RTC_DCHECK(CVPixelBufferGetPixelFormatType(pixel_buffer) ==
52 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange);
53 size_t width = CVPixelBufferGetWidthOfPlane(pixel_buffer, 0); 51 size_t width = CVPixelBufferGetWidthOfPlane(pixel_buffer, 0);
54 size_t height = CVPixelBufferGetHeightOfPlane(pixel_buffer, 0); 52 size_t height = CVPixelBufferGetHeightOfPlane(pixel_buffer, 0);
55 // TODO(tkchin): Use a frame buffer pool. 53 // TODO(tkchin): Use a frame buffer pool.
56 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = 54 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
57 new rtc::RefCountedObject<webrtc::I420Buffer>(width, height); 55 new rtc::RefCountedObject<webrtc::I420Buffer>(width, height);
58 CVPixelBufferLockBaseAddress(pixel_buffer, kCVPixelBufferLock_ReadOnly); 56
59 const uint8_t* src_y = reinterpret_cast<const uint8_t*>( 57 OSType format = CVPixelBufferGetPixelFormatType(pixel_buffer);
60 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0)); 58 if (format == kCVPixelFormatType_420YpCbCr8Planar ||
61 int src_y_stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0); 59 format == kCVPixelFormatType_420YpCbCr8PlanarFullRange) {
62 const uint8_t* src_uv = reinterpret_cast<const uint8_t*>( 60 int stride;
63 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 1)); 61 CVPixelBufferLockBaseAddress(pixel_buffer, 0);
64 int src_uv_stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 1); 62 size_t height = CVPixelBufferGetHeight(pixel_buffer);
65 int ret = libyuv::NV12ToI420( 63 const int half_height = (height + 1) / 2;
66 src_y, src_y_stride, src_uv, src_uv_stride, 64 for (size_t planeIndex = 0;
67 buffer->MutableData(webrtc::kYPlane), buffer->stride(webrtc::kYPlane), 65 planeIndex < CVPixelBufferGetPlaneCount(pixel_buffer); planeIndex++) {
68 buffer->MutableData(webrtc::kUPlane), buffer->stride(webrtc::kUPlane), 66 void* baseAddress =
69 buffer->MutableData(webrtc::kVPlane), buffer->stride(webrtc::kVPlane), 67 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, planeIndex);
70 width, height); 68 stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, planeIndex);
71 CVPixelBufferUnlockBaseAddress(pixel_buffer, kCVPixelBufferLock_ReadOnly); 69 memcpy(buffer->MutableData((webrtc::PlaneType)planeIndex), baseAddress,
72 if (ret) { 70 (planeIndex == webrtc::kYPlane) ? stride * height
73 LOG(LS_ERROR) << "Error converting NV12 to I420: " << ret; 71 : stride * half_height);
72 }
73 CVPixelBufferUnlockBaseAddress(pixel_buffer, 0);
74 } else if (format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
75 format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
76 CVPixelBufferLockBaseAddress(pixel_buffer, kCVPixelBufferLock_ReadOnly);
77 const uint8_t* src_y = reinterpret_cast<const uint8_t*>(
78 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0));
79 int src_y_stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0);
80 const uint8_t* src_uv = reinterpret_cast<const uint8_t*>(
81 CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 1));
82 int src_uv_stride = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 1);
83 int ret = libyuv::NV12ToI420(
84 src_y, src_y_stride, src_uv, src_uv_stride,
85 buffer->MutableData(webrtc::kYPlane), buffer->stride(webrtc::kYPlane),
86 buffer->MutableData(webrtc::kUPlane), buffer->stride(webrtc::kUPlane),
87 buffer->MutableData(webrtc::kVPlane), buffer->stride(webrtc::kVPlane),
88 width, height);
89 CVPixelBufferUnlockBaseAddress(pixel_buffer, kCVPixelBufferLock_ReadOnly);
90 if (ret) {
91 LOG(LS_ERROR) << "Error converting NV12 to I420: " << ret;
92 return nullptr;
93 }
94 } else {
95 LOG(LS_ERROR) << "Unsupported pixel buffer format: " << format;
74 return nullptr; 96 return nullptr;
75 } 97 }
98
76 return buffer; 99 return buffer;
77 } 100 }
78 101
79 // This is the callback function that VideoToolbox calls when decode is 102 // This is the callback function that VideoToolbox calls when decode is
80 // complete. 103 // complete.
81 void VTDecompressionOutputCallback(void* decoder, 104 void VTDecompressionOutputCallback(void* decoder,
82 void* params, 105 void* params,
83 OSStatus status, 106 OSStatus status,
84 VTDecodeInfoFlags info_flags, 107 VTDecodeInfoFlags info_flags,
85 CVImageBufferRef image_buffer, 108 CVImageBufferRef image_buffer,
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 #if defined(WEBRTC_IOS) 219 #if defined(WEBRTC_IOS)
197 kCVPixelBufferOpenGLESCompatibilityKey, 220 kCVPixelBufferOpenGLESCompatibilityKey,
198 #elif defined(WEBRTC_MAC) 221 #elif defined(WEBRTC_MAC)
199 kCVPixelBufferOpenGLCompatibilityKey, 222 kCVPixelBufferOpenGLCompatibilityKey,
200 #endif 223 #endif
201 kCVPixelBufferIOSurfacePropertiesKey, 224 kCVPixelBufferIOSurfacePropertiesKey,
202 kCVPixelBufferPixelFormatTypeKey 225 kCVPixelBufferPixelFormatTypeKey
203 }; 226 };
204 CFDictionaryRef io_surface_value = 227 CFDictionaryRef io_surface_value =
205 internal::CreateCFDictionary(nullptr, nullptr, 0); 228 internal::CreateCFDictionary(nullptr, nullptr, 0);
206 int64_t nv12type = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; 229 OSType i420type = kCVPixelFormatType_420YpCbCr8Planar;
207 CFNumberRef pixel_format = 230 CFNumberRef pixel_format =
208 CFNumberCreate(nullptr, kCFNumberLongType, &nv12type); 231 CFNumberCreate(nullptr, kCFNumberSInt32Type, &i420type);
209 CFTypeRef values[attributes_size] = { 232 CFTypeRef values[attributes_size] = {
210 kCFBooleanTrue, 233 kCFBooleanTrue,
211 io_surface_value, 234 io_surface_value,
212 pixel_format 235 pixel_format
213 }; 236 };
214 CFDictionaryRef attributes = 237 CFDictionaryRef attributes =
215 internal::CreateCFDictionary(keys, values, attributes_size); 238 internal::CreateCFDictionary(keys, values, attributes_size);
216 if (io_surface_value) { 239 if (io_surface_value) {
217 CFRelease(io_surface_value); 240 CFRelease(io_surface_value);
218 io_surface_value = nullptr; 241 io_surface_value = nullptr;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 285 }
263 video_format_ = video_format; 286 video_format_ = video_format;
264 if (video_format_) { 287 if (video_format_) {
265 CFRetain(video_format_); 288 CFRetain(video_format_);
266 } 289 }
267 } 290 }
268 291
269 } // namespace webrtc 292 } // namespace webrtc
270 293
271 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) 294 #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED)
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698