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: 1095ada7ad

R=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:
Anders Carlsson
2017-07-13 16:03:55 +02:00
parent a8a3515997
commit a5f1de1e65
21 changed files with 1443 additions and 10 deletions

View File

@ -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);
}

View File

@ -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);
}