Index: webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc |
diff --git a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc |
index d677f8b812fa771fd8385d7df4d86cd1a2dd99f2..de0a7765763d91107faa34eee293797aab62e912 100644 |
--- a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc |
+++ b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc |
@@ -124,34 +124,50 @@ struct FrameEncodeParams { |
bool CopyVideoFrameToPixelBuffer(const webrtc::VideoFrame& frame, |
CVPixelBufferRef pixel_buffer) { |
RTC_DCHECK(pixel_buffer); |
- RTC_DCHECK(CVPixelBufferGetPixelFormatType(pixel_buffer) == |
- kCVPixelFormatType_420YpCbCr8BiPlanarFullRange); |
RTC_DCHECK(CVPixelBufferGetHeightOfPlane(pixel_buffer, 0) == |
static_cast<size_t>(frame.height())); |
RTC_DCHECK(CVPixelBufferGetWidthOfPlane(pixel_buffer, 0) == |
static_cast<size_t>(frame.width())); |
- CVReturn cvRet = CVPixelBufferLockBaseAddress(pixel_buffer, 0); |
- if (cvRet != kCVReturnSuccess) { |
- LOG(LS_ERROR) << "Failed to lock base address: " << cvRet; |
- return false; |
- } |
- uint8_t* dst_y = reinterpret_cast<uint8_t*>( |
- CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0)); |
- int dst_stride_y = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0); |
- uint8_t* dst_uv = reinterpret_cast<uint8_t*>( |
- CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 1)); |
- int dst_stride_uv = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 1); |
- // Convert I420 to NV12. |
- int ret = libyuv::I420ToNV12( |
- frame.buffer(webrtc::kYPlane), frame.stride(webrtc::kYPlane), |
- frame.buffer(webrtc::kUPlane), frame.stride(webrtc::kUPlane), |
- frame.buffer(webrtc::kVPlane), frame.stride(webrtc::kVPlane), |
- dst_y, dst_stride_y, dst_uv, dst_stride_uv, |
- frame.width(), frame.height()); |
- CVPixelBufferUnlockBaseAddress(pixel_buffer, 0); |
- if (ret) { |
- LOG(LS_ERROR) << "Error converting I420 VideoFrame to NV12 :" << ret; |
+ OSType format = CVPixelBufferGetPixelFormatType(pixel_buffer); |
+ if (format == kCVPixelFormatType_420YpCbCr8Planar || |
+ format == kCVPixelFormatType_420YpCbCr8PlanarFullRange) { |
+ CVPixelBufferLockBaseAddress(pixel_buffer, 0); |
+ for (size_t planeIndex = 0; |
+ planeIndex < CVPixelBufferGetPlaneCount(pixel_buffer); planeIndex++) { |
+ void* baseAddress = |
+ CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, planeIndex); |
+ memcpy(baseAddress, frame.buffer((webrtc::PlaneType)planeIndex), |
+ frame.allocated_size((webrtc::PlaneType)planeIndex)); |
+ } |
+ CVPixelBufferUnlockBaseAddress(pixel_buffer, 0); |
+ } else if (format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange || |
+ format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) { |
+ CVReturn cvRet = CVPixelBufferLockBaseAddress(pixel_buffer, 0); |
+ if (cvRet != kCVReturnSuccess) { |
+ LOG(LS_ERROR) << "Failed to lock base address: " << cvRet; |
+ return false; |
+ } |
+ uint8_t* dst_y = reinterpret_cast<uint8_t*>( |
+ CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0)); |
+ int dst_stride_y = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0); |
+ uint8_t* dst_uv = reinterpret_cast<uint8_t*>( |
+ CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 1)); |
+ int dst_stride_uv = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 1); |
+ // Convert I420 to NV12. |
+ int ret = libyuv::I420ToNV12( |
+ frame.buffer(webrtc::kYPlane), frame.stride(webrtc::kYPlane), |
+ frame.buffer(webrtc::kUPlane), frame.stride(webrtc::kUPlane), |
+ frame.buffer(webrtc::kVPlane), frame.stride(webrtc::kVPlane), dst_y, |
+ dst_stride_y, dst_uv, dst_stride_uv, frame.width(), frame.height()); |
+ CVPixelBufferUnlockBaseAddress(pixel_buffer, 0); |
+ if (ret) { |
+ LOG(LS_ERROR) << "Error converting I420 VideoFrame to NV12 :" << ret; |
+ return false; |
+ } |
+ |
+ } else { |
+ LOG(LS_ERROR) << "Unsupported pixel format type :" << format; |
return false; |
} |
return true; |
@@ -356,9 +372,9 @@ int H264VideoToolboxEncoder::ResetCompressionSession() { |
}; |
CFDictionaryRef io_surface_value = |
internal::CreateCFDictionary(nullptr, nullptr, 0); |
- int64_t nv12type = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; |
+ OSType i420type = kCVPixelFormatType_420YpCbCr8Planar; |
CFNumberRef pixel_format = |
- CFNumberCreate(nullptr, kCFNumberLongType, &nv12type); |
+ CFNumberCreate(nullptr, kCFNumberSInt32Type, &i420type); |
CFTypeRef values[attributes_size] = { |
kCFBooleanTrue, |
io_surface_value, |