Reland of Injectable Obj-C video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2975963002/ )
Reason for revert: New CL for fixing the issues Original issue's description: > Revert of Injectable Obj-C video codecs (patchset #8 id:140001 of https://codereview.webrtc.org/2966023002/ ) > > Reason for revert: > Causes no video in certain scenarios. Please come up with a test plan or unit test to prevent such problems in the future. > > Original issue's description: > > Injectable Obj-C video codecs > > > > Initial CL for this effort, with a working RTCVideoEncoder/Decoder for H264 > > (wrapping the VideoToolbox codec). > > > > Some notes / things left to do: > > - There are some hard-coded references to codec types that are supported by > > webrtc::VideoCodec, cricket::VideoCodec, webrtc::CodecSpecificInfo etc > > since we need to convert to/from these types in ObjCVideoEncoder/Decoder. > > These types would need to be more codec agnostic to avoid this. > > - Most interfaces are borrowed from the design document for injectable > > codecs in Android. Some data in the corresponding C++ classes is discarded > > when converting to the Obj-C version, since it has fewer fields. I have not > > verified whether all data that we do keep is needed, or whether we might be > > losing anything useful in these conversions. > > - Implement the VideoToolbox codec code directly in the RTCVideoEncoderH264 > > classes, instead of wrapping webrtc::H264VideoToolboxEncoder / decoder. > > Eliminates converting between ObjC/C++ types outside the ObjCVideoEncoder/ > > Decoder wrapper classes. > > - List the injected codec factory's supported codecs in the list of codecs in > > AppRTCMobile. > > > > BUG=webrtc:7924 > > R=magjed@webrtc.org > > > > Review-Url: https://codereview.webrtc.org/2966023002 . > > Cr-Commit-Position: refs/heads/master@{#18928} > > Committed:a0349c138d> > TBR=magjed@webrtc.org,andersc@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=webrtc:7924 > NOTRY=true > > Review-Url: https://codereview.webrtc.org/2975963002 > Cr-Commit-Position: refs/heads/master@{#18979} > Committed:1095ada7adR=magjed@webrtc.org TBR=tkchin@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:7924 Review-Url: https://codereview.webrtc.org/2981583002 . Cr-Commit-Position: refs/heads/master@{#19002}
This commit is contained in:
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <OCMock/OCMock.h>
|
||||
|
||||
#include "webrtc/sdk/objc/Framework/Classes/PeerConnection/objc_video_decoder_factory.h"
|
||||
|
||||
#import "WebRTC/RTCVideoCodec.h"
|
||||
#import "WebRTC/RTCVideoCodecFactory.h"
|
||||
#include "webrtc/modules/include/module_common_types.h"
|
||||
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
||||
#include "webrtc/rtc_base/gunit.h"
|
||||
|
||||
id<RTCVideoDecoderFactory> CreateDecoderFactoryReturning(int return_code) {
|
||||
id decoderMock = OCMProtocolMock(@protocol(RTCVideoDecoder));
|
||||
OCMStub([decoderMock initDecodeWithSettings:[OCMArg any] numberOfCores:1]).andReturn(return_code);
|
||||
OCMStub([decoderMock decode:[OCMArg any]
|
||||
missingFrames:NO
|
||||
fragmentationHeader:[OCMArg any]
|
||||
codecSpecificInfo:[OCMArg any]
|
||||
renderTimeMs:0])
|
||||
.andReturn(return_code);
|
||||
OCMStub([decoderMock releaseDecode]).andReturn(return_code);
|
||||
|
||||
id decoderFactoryMock = OCMProtocolMock(@protocol(RTCVideoDecoderFactory));
|
||||
RTCVideoCodecInfo *supported =
|
||||
[[RTCVideoCodecInfo alloc] initWithPayload:0 name:@"H264" parameters:@{}];
|
||||
OCMStub([decoderFactoryMock supportedCodecs]).andReturn(@[ supported ]);
|
||||
OCMStub([decoderFactoryMock createDecoder:[OCMArg any]]).andReturn(decoderMock);
|
||||
return decoderFactoryMock;
|
||||
}
|
||||
|
||||
id<RTCVideoDecoderFactory> CreateOKDecoderFactory() {
|
||||
return CreateDecoderFactoryReturning(WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
id<RTCVideoDecoderFactory> CreateErrorDecoderFactory() {
|
||||
return CreateDecoderFactoryReturning(WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
webrtc::VideoDecoder *GetObjCDecoder(id<RTCVideoDecoderFactory> factory) {
|
||||
webrtc::ObjCVideoDecoderFactory decoder_factory(factory);
|
||||
return decoder_factory.CreateVideoDecoder(webrtc::kVideoCodecH264);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
TEST(ObjCVideoDecoderFactoryTest, InitDecodeReturnsOKOnSuccess) {
|
||||
webrtc::VideoDecoder *decoder = GetObjCDecoder(CreateOKDecoderFactory());
|
||||
|
||||
auto settings = new webrtc::VideoCodec();
|
||||
EXPECT_EQ(decoder->InitDecode(settings, 1), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoDecoderFactoryTest, InitDecodeReturnsErrorOnFail) {
|
||||
webrtc::VideoDecoder *decoder = GetObjCDecoder(CreateErrorDecoderFactory());
|
||||
|
||||
auto settings = new webrtc::VideoCodec();
|
||||
EXPECT_EQ(decoder->InitDecode(settings, 1), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoDecoderFactoryTest, DecodeReturnsOKOnSuccess) {
|
||||
webrtc::VideoDecoder *decoder = GetObjCDecoder(CreateOKDecoderFactory());
|
||||
|
||||
webrtc::EncodedImage encoded_image;
|
||||
webrtc::RTPFragmentationHeader header;
|
||||
webrtc::CodecSpecificInfo info;
|
||||
info.codecType = webrtc::kVideoCodecH264;
|
||||
|
||||
EXPECT_EQ(decoder->Decode(encoded_image, false, &header, &info, 0), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoDecoderFactoryTest, DecodeReturnsErrorOnFail) {
|
||||
webrtc::VideoDecoder *decoder = GetObjCDecoder(CreateErrorDecoderFactory());
|
||||
|
||||
webrtc::EncodedImage encoded_image;
|
||||
webrtc::RTPFragmentationHeader header;
|
||||
webrtc::CodecSpecificInfo info;
|
||||
info.codecType = webrtc::kVideoCodecH264;
|
||||
|
||||
EXPECT_EQ(decoder->Decode(encoded_image, false, &header, &info, 0), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoDecoderFactoryTest, ReleaseDecodeReturnsOKOnSuccess) {
|
||||
webrtc::VideoDecoder *decoder = GetObjCDecoder(CreateOKDecoderFactory());
|
||||
|
||||
EXPECT_EQ(decoder->Release(), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoDecoderFactoryTest, ReleaseDecodeReturnsErrorOnFail) {
|
||||
webrtc::VideoDecoder *decoder = GetObjCDecoder(CreateErrorDecoderFactory());
|
||||
|
||||
EXPECT_EQ(decoder->Release(), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <OCMock/OCMock.h>
|
||||
|
||||
#include "webrtc/sdk/objc/Framework/Classes/PeerConnection/objc_video_encoder_factory.h"
|
||||
|
||||
#import "WebRTC/RTCVideoCodec.h"
|
||||
#import "WebRTC/RTCVideoCodecFactory.h"
|
||||
#import "WebRTC/RTCVideoFrameBuffer.h"
|
||||
#include "webrtc/modules/include/module_common_types.h"
|
||||
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
||||
#include "webrtc/rtc_base/gunit.h"
|
||||
#include "webrtc/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
|
||||
|
||||
id<RTCVideoEncoderFactory> CreateEncoderFactoryReturning(int return_code) {
|
||||
id encoderMock = OCMProtocolMock(@protocol(RTCVideoEncoder));
|
||||
OCMStub([encoderMock initEncodeWithSettings:[OCMArg any] numberOfCores:1]).andReturn(return_code);
|
||||
OCMStub([encoderMock encode:[OCMArg any] codecSpecificInfo:[OCMArg any] frameTypes:[OCMArg any]])
|
||||
.andReturn(return_code);
|
||||
OCMStub([encoderMock releaseEncode]).andReturn(return_code);
|
||||
OCMStub([encoderMock setBitrate:0 framerate:0]).andReturn(return_code == WEBRTC_VIDEO_CODEC_OK);
|
||||
|
||||
id encoderFactoryMock = OCMProtocolMock(@protocol(RTCVideoEncoderFactory));
|
||||
RTCVideoCodecInfo *supported =
|
||||
[[RTCVideoCodecInfo alloc] initWithPayload:0 name:@"H264" parameters:@{}];
|
||||
OCMStub([encoderFactoryMock supportedCodecs]).andReturn(@[ supported ]);
|
||||
OCMStub([encoderFactoryMock createEncoder:[OCMArg any]]).andReturn(encoderMock);
|
||||
return encoderFactoryMock;
|
||||
}
|
||||
|
||||
id<RTCVideoEncoderFactory> CreateOKEncoderFactory() {
|
||||
return CreateEncoderFactoryReturning(WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
id<RTCVideoEncoderFactory> CreateErrorEncoderFactory() {
|
||||
return CreateEncoderFactoryReturning(WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
webrtc::VideoEncoder *GetObjCEncoder(id<RTCVideoEncoderFactory> factory) {
|
||||
webrtc::ObjCVideoEncoderFactory encoder_factory(factory);
|
||||
cricket::VideoCodec codec("H264");
|
||||
return encoder_factory.CreateVideoEncoder(codec);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsOKOnSuccess) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateOKEncoderFactory());
|
||||
|
||||
auto settings = new webrtc::VideoCodec();
|
||||
EXPECT_EQ(encoder->InitEncode(settings, 1, 0), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsErrorOnFail) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
||||
|
||||
auto settings = new webrtc::VideoCodec();
|
||||
EXPECT_EQ(encoder->InitEncode(settings, 1, 0), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, EncodeReturnsOKOnSuccess) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateOKEncoderFactory());
|
||||
|
||||
CVPixelBufferRef pixel_buffer;
|
||||
CVPixelBufferCreate(kCFAllocatorDefault, 640, 480, kCVPixelFormatType_32ARGB, nil, &pixel_buffer);
|
||||
rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
|
||||
new rtc::RefCountedObject<webrtc::ObjCFrameBuffer>(
|
||||
[[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixel_buffer]);
|
||||
webrtc::VideoFrame frame(buffer, webrtc::kVideoRotation_0, 0);
|
||||
webrtc::CodecSpecificInfo info;
|
||||
info.codecType = webrtc::kVideoCodecH264;
|
||||
info.codec_name = "H264";
|
||||
std::vector<webrtc::FrameType> frame_types;
|
||||
|
||||
EXPECT_EQ(encoder->Encode(frame, &info, &frame_types), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, EncodeReturnsErrorOnFail) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
||||
|
||||
CVPixelBufferRef pixel_buffer;
|
||||
CVPixelBufferCreate(kCFAllocatorDefault, 640, 480, kCVPixelFormatType_32ARGB, nil, &pixel_buffer);
|
||||
rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
|
||||
new rtc::RefCountedObject<webrtc::ObjCFrameBuffer>(
|
||||
[[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixel_buffer]);
|
||||
webrtc::VideoFrame frame(buffer, webrtc::kVideoRotation_0, 0);
|
||||
webrtc::CodecSpecificInfo info;
|
||||
info.codecType = webrtc::kVideoCodecH264;
|
||||
info.codec_name = "H264";
|
||||
std::vector<webrtc::FrameType> frame_types;
|
||||
|
||||
EXPECT_EQ(encoder->Encode(frame, &info, &frame_types), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, ReleaseEncodeReturnsOKOnSuccess) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateOKEncoderFactory());
|
||||
|
||||
EXPECT_EQ(encoder->Release(), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, ReleaseEncodeReturnsErrorOnFail) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
||||
|
||||
EXPECT_EQ(encoder->Release(), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, SetChannelParametersAlwaysReturnsOK) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
||||
|
||||
EXPECT_EQ(encoder->SetChannelParameters(1, 1), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, SetRatesReturnsOKOnSuccess) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateOKEncoderFactory());
|
||||
|
||||
EXPECT_EQ(encoder->SetRates(0, 0), WEBRTC_VIDEO_CODEC_OK);
|
||||
}
|
||||
|
||||
TEST(ObjCVideoEncoderFactoryTest, SetRatesReturnsErrorOnFail) {
|
||||
webrtc::VideoEncoder *encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
||||
|
||||
EXPECT_EQ(encoder->SetRates(0, 0), WEBRTC_VIDEO_CODEC_ERROR);
|
||||
}
|
||||
Reference in New Issue
Block a user