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..c02f83bf1519b660e2157416d77b79de79f3ba79 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,36 +124,52 @@ 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; |
- return false; |
- } |
+ 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, |