Skip to content
Permalink
Browse files
Add support for AVC H264 WebCodecsVideoDecoder
https://bugs.webkit.org/show_bug.cgi?id=246141
rdar://problem/100844377

Reviewed by Eric Carlson.

Update RTCVideoDecoderH264 and RTCVideoDecoderH265 to support AVC.
To do so, we introduce setAVCFormat to setup the decoder and put it in AVC mode.
When receiving data to decode, we skip the AnnexB translation since VTB is AVC based.

Update WebKit layer to pass the AVC description data to GPUProcess.

Covered by layout tests.

* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoDecoder-codec-specific.https.any.worker_h264_avc-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoDecoder-codec-specific.https.any_h264_avc-expected.txt:
* Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp:
* Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp:
* Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp:
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.mm:
(-[WK_RTCLocalVideoH264H265VP9Decoder setFormat:size:width:height:]):
(webrtc::setDecodingFormat):
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderH264.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm:
(-[RTCVideoDecoderH264 init]):
(H264BufferToCMSampleBuffer):
(-[RTCVideoDecoderH264 decodeData:size:timeStamp:]):
(-[RTCVideoDecoderH264 setAVCFormat:size:width:height:]):
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderH265.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderH265.mm:
(-[RTCVideoDecoderH265 init]):
(H265BufferToCMSampleBuffer):
(-[RTCVideoDecoderH265 decodeData:size:timeStamp:]):
(-[RTCVideoDecoderH265 setAVCFormat:size:width:height:]):
* Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h:
* Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in:
* Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm:
(WebKit::LibWebRTCCodecsProxy::setDecoderFormatDescription):
* Source/WebKit/WebProcess/GPU/media/RemoteVideoCodecFactory.cpp:
(WebKit::RemoteVideoCodecFactory::createDecoder):
(WebKit::RemoteVideoDecoder::RemoteVideoDecoder):
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::LibWebRTCCodecs::setDecoderFormatDescription):
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h:

Canonical link: https://commits.webkit.org/255422@main
  • Loading branch information
youennf committed Oct 12, 2022
1 parent 416870d commit a248b493c70a5fcc281db4bff4b463b53650816a
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 39 deletions.
@@ -3,18 +3,18 @@ PASS Test isConfigSupported()
PASS Test isConfigSupported() with 1080p crop
PASS Test that isConfigSupported() returns a parsed configuration
PASS Test invalid configs
FAIL Test configure() assert_equals: state expected "configured" but got "closed"
FAIL Decode a key frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Decode a non key frame first fails assert_throws_dom: function "() => decoder.decode(CHUNKS[1], 'decode')" threw object "InvalidStateError: VideoDecoder is not configured" that is not a DOMException DataError: property "code" is equal to 11, expected 0
FAIL Verify reset() suppresses outputs promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
PASS Test configure()
PASS Decode a key frame
PASS Decode a non key frame first fails
PASS Verify reset() suppresses outputs
PASS Test unconfigured VideoDecoder operations
PASS Test closed VideoDecoder operations
FAIL Decode empty frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Decode corrupt frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Close while decoding corrupt frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test decoding after flush promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test decoding a with negative timestamp promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test reset during flush promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test low-latency decoding promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL VideoDecoder decodeQueueSize test promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Decode empty frame assert_unreached: Should have rejected: undefined Reached unreachable code
FAIL Decode corrupt frame assert_unreached: Should have rejected: undefined Reached unreachable code
PASS Close while decoding corrupt frame
PASS Test decoding after flush
FAIL Test decoding a with negative timestamp assert_equals: timestamp expected -42 but got 4294967254
PASS Test reset during flush
PASS Test low-latency decoding
PASS VideoDecoder decodeQueueSize test

@@ -3,18 +3,18 @@ PASS Test isConfigSupported()
PASS Test isConfigSupported() with 1080p crop
PASS Test that isConfigSupported() returns a parsed configuration
PASS Test invalid configs
FAIL Test configure() assert_equals: state expected "configured" but got "closed"
FAIL Decode a key frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Decode a non key frame first fails assert_throws_dom: function "() => decoder.decode(CHUNKS[1], 'decode')" threw object "InvalidStateError: VideoDecoder is not configured" that is not a DOMException DataError: property "code" is equal to 11, expected 0
FAIL Verify reset() suppresses outputs promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
PASS Test configure()
PASS Decode a key frame
PASS Decode a non key frame first fails
PASS Verify reset() suppresses outputs
PASS Test unconfigured VideoDecoder operations
PASS Test closed VideoDecoder operations
FAIL Decode empty frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Decode corrupt frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Close while decoding corrupt frame promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test decoding after flush promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test decoding a with negative timestamp promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test reset during flush promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Test low-latency decoding promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL VideoDecoder decodeQueueSize test promise_test: Unhandled rejection with value: object "InvalidStateError: VideoDecoder is not configured"
FAIL Decode empty frame assert_unreached: Should have rejected: undefined Reached unreachable code
FAIL Decode corrupt frame assert_unreached: Should have rejected: undefined Reached unreachable code
PASS Close while decoding corrupt frame
PASS Test decoding after flush
FAIL Test decoding a with negative timestamp assert_equals: timestamp expected -42 but got 4294967254
PASS Test reset during flush
PASS Test low-latency decoding
PASS VideoDecoder decodeQueueSize test

@@ -200,6 +200,7 @@ __ZN6webrtc22createLocalH265DecoderEU13block_pointerFvP10__CVBufferjjE
__ZN6webrtc21createLocalVP9DecoderEU13block_pointerFvP10__CVBufferjjE
__ZN6webrtc19releaseLocalDecoderEPv
__ZN6webrtc17flushLocalDecoderEPv
__ZN6webrtc17setDecodingFormatEPvPKhmtt
__ZN6webrtc11decodeFrameEPvjPKhm
__ZN6webrtc24videoDecoderTaskCompleteEPvjjP10__CVBuffer
__ZN6webrtc24videoDecoderTaskCompleteEPvjjS0_PFP10__CVBufferS0_EPFvS0_Eii
@@ -200,6 +200,7 @@ __ZN6webrtc22createLocalH265DecoderEU13block_pointerFvP10__CVBufferjjE
__ZN6webrtc21createLocalVP9DecoderEU13block_pointerFvP10__CVBufferjjE
__ZN6webrtc19releaseLocalDecoderEPv
__ZN6webrtc17flushLocalDecoderEPv
__ZN6webrtc17setDecodingFormatEPvPKhmtt
__ZN6webrtc11decodeFrameEPvjPKhm
__ZN6webrtc24videoDecoderTaskCompleteEPvjjP10__CVBuffer
__ZN6webrtc24videoDecoderTaskCompleteEPvjjS0_PFP10__CVBufferS0_EPFvS0_Eii
@@ -200,6 +200,7 @@ __ZN6webrtc22createLocalH265DecoderEU13block_pointerFvP10__CVBufferjjE
__ZN6webrtc21createLocalVP9DecoderEU13block_pointerFvP10__CVBufferjjE
__ZN6webrtc19releaseLocalDecoderEPv
__ZN6webrtc17flushLocalDecoderEPv
__ZN6webrtc17setDecodingFormatEPvPKhmtt
__ZN6webrtc11decodeFrameEPvjPKhm
__ZN6webrtc24videoDecoderTaskCompleteEPvjjP10__CVBuffer
__ZN6webrtc24videoDecoderTaskCompleteEPvjjS0_PFP10__CVBufferS0_EPFvS0_Eii
@@ -64,6 +64,7 @@ void* createLocalH265Decoder(LocalDecoderCallback);
void* createLocalVP9Decoder(LocalDecoderCallback);
void releaseLocalDecoder(LocalDecoder);
void flushLocalDecoder(LocalDecoder);
int32_t setDecodingFormat(LocalDecoder, const uint8_t*, size_t, uint16_t width, uint16_t height);
int32_t decodeFrame(LocalDecoder, uint32_t timeStamp, const uint8_t*, size_t);
void setDecoderFrameSize(LocalDecoder, uint16_t width, uint16_t height);

@@ -42,6 +42,7 @@
@interface WK_RTCLocalVideoH264H265VP9Decoder : NSObject
- (instancetype)initH264DecoderWithCallback:(webrtc::LocalDecoderCallback)callback;
- (instancetype)initH265DecoderWithCallback:(webrtc::LocalDecoderCallback)callback;
- (NSInteger)setFormat:(const uint8_t *)data size:(size_t)size width:(uint16_t)width height:(uint16_t)height;
- (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint32_t)timeStamp;
- (NSInteger)releaseDecoder;
- (void)flush;
@@ -86,6 +87,14 @@ - (instancetype)initVP9DecoderWithCallback:(webrtc::LocalDecoderCallback)callbac
return self;
}

- (NSInteger)setFormat:(const uint8_t *)data size:(size_t)size width:(uint16_t)width height:(uint16_t)height {
if (m_h264Decoder)
return [m_h264Decoder setAVCFormat:data size:size width:width height:height];
if (m_h265Decoder)
return [m_h265Decoder setAVCFormat:data size:size width:width height:height];
return 0;
}

- (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint32_t)timeStamp {
if (m_h264Decoder)
return [m_h264Decoder decodeData:data size:size timeStamp:timeStamp];
@@ -305,6 +314,12 @@ void flushLocalDecoder(LocalDecoder localDecoder)
[decoder flush];
}

int32_t setDecodingFormat(LocalDecoder localDecoder, const uint8_t* data, size_t size, uint16_t width, uint16_t height)
{
auto* decoder = (__bridge WK_RTCLocalVideoH264H265VP9Decoder *)(localDecoder);
return [decoder setFormat:data size:size width:width height:height];
}

int32_t decodeFrame(LocalDecoder localDecoder, uint32_t timeStamp, const uint8_t* data, size_t size)
{
auto* decoder = (__bridge WK_RTCLocalVideoH264H265VP9Decoder *)(localDecoder);
@@ -16,6 +16,7 @@
RTC_OBJC_EXPORT
__attribute__((objc_runtime_name("WK_RTCVideoDecoderH264")))
@interface RTCVideoDecoderH264 : NSObject <RTCVideoDecoder>
- (NSInteger)setAVCFormat:(const uint8_t *)data size:(size_t)size width:(uint16_t)width height:(uint16_t)height;
- (NSInteger)decodeData:(const uint8_t *)data
size:(size_t)size
timeStamp:(uint32_t)timeStamp;
@@ -85,12 +85,14 @@ @implementation RTCVideoDecoderH264 {
VTDecompressionSessionRef _decompressionSession;
RTCVideoDecoderCallback _callback;
OSStatus _error;
bool _useAVC;
}

- (instancetype)init {
self = [super init];
if (self) {
_memoryPool = CMMemoryPoolCreate(nil);
_useAVC = false;
}
return self;
}
@@ -106,6 +108,27 @@ - (NSInteger)startDecodeWithNumberOfCores:(int)numberOfCores {
return WEBRTC_VIDEO_CODEC_OK;
}

CMSampleBufferRef H264BufferToCMSampleBuffer(const uint8_t* buffer, size_t buffer_size, CMVideoFormatDescriptionRef video_format) {
CMBlockBufferRef new_block_buffer;
if (auto error = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, buffer_size, kCFAllocatorDefault, NULL, 0, buffer_size, kCMBlockBufferAssureMemoryNowFlag, &new_block_buffer)) {
RTC_LOG(LS_ERROR) << "H264BufferToCMSampleBuffer CMBlockBufferCreateWithMemoryBlock failed with: " << error;
return nullptr;
}
auto block_buffer = rtc::ScopedCF(new_block_buffer);

if (auto error = CMBlockBufferReplaceDataBytes(buffer, block_buffer.get(), 0, buffer_size)) {
RTC_LOG(LS_ERROR) << "H264BufferToCMSampleBuffer CMBlockBufferReplaceDataBytes failed with: " << error;
return nullptr;
}

CMSampleBufferRef sample_buffer = nullptr;
if (auto error = CMSampleBufferCreate(kCFAllocatorDefault, block_buffer.get(), true, nullptr, nullptr, video_format, 1, 0, nullptr, 0, nullptr, &sample_buffer)) {
RTC_LOG(LS_ERROR) << "H264BufferToCMSampleBuffer CMSampleBufferCreate failed with: " << error;
return nullptr;
}
return sample_buffer;
}

- (NSInteger)decode:(RTCEncodedImage *)inputImage
missingFrames:(BOOL)missingFrames
codecSpecificInfo:(nullable id<RTCCodecSpecificInfo>)info
@@ -133,7 +156,7 @@ - (NSInteger)decodeData:(const uint8_t *)data
rtc::ScopedCF(webrtc::CreateVideoFormatDescription(data, size));
if (inputFormat) {
// Check if the video format has changed, and reinitialize decoder if
// needed.
// needed.
if (!CMFormatDescriptionEqual(inputFormat.get(), _videoFormat)) {
[self setVideoFormat:inputFormat.get()];
int resetDecompressionSessionError = [self resetDecompressionSession];
@@ -152,7 +175,13 @@ - (NSInteger)decodeData:(const uint8_t *)data
return WEBRTC_VIDEO_CODEC_ERROR;
}
CMSampleBufferRef sampleBuffer = nullptr;
if (!webrtc::H264AnnexBBufferToCMSampleBuffer(data,
if (_useAVC) {
sampleBuffer = H264BufferToCMSampleBuffer(data, size, _videoFormat);
if (!sampleBuffer) {
RTC_LOG(LS_ERROR) << "Cannot create sample from data.";
return WEBRTC_VIDEO_CODEC_ERROR;
}
} else if (!webrtc::H264AnnexBBufferToCMSampleBuffer(data,
size,
_videoFormat,
&sampleBuffer,
@@ -185,6 +214,49 @@ - (NSInteger)decodeData:(const uint8_t *)data
return WEBRTC_VIDEO_CODEC_OK;
}

- (NSInteger)setAVCFormat:(const uint8_t *)data size:(size_t)size width:(uint16_t)width height:(uint16_t)height {
CFStringRef avcCString = (CFStringRef)@"avcC";
CFDataRef codecConfig = CFDataCreate(kCFAllocatorDefault, data, size);
CFDictionaryRef atomsDict = CFDictionaryCreate(NULL,
(const void **)&avcCString,
(const void **)&codecConfig,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryRef extensionsDict = CFDictionaryCreate(NULL,
(const void **)&kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
(const void **)&atomsDict,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);

CMVideoFormatDescriptionRef videoFormatDescription = nullptr;
auto err = CMVideoFormatDescriptionCreate(NULL, kCMVideoCodecType_H264, width, height, extensionsDict, &videoFormatDescription);
CFRelease(codecConfig);
CFRelease(atomsDict);
CFRelease(extensionsDict);

if (err) {
RTC_LOG(LS_ERROR) << "Cannot create fromat description.";
return err;
}

rtc::ScopedCFTypeRef<CMVideoFormatDescriptionRef> inputFormat = rtc::ScopedCF(videoFormatDescription);
if (inputFormat) {
// Check if the video format has changed, and reinitialize decoder if
// needed.
if (!CMFormatDescriptionEqual(inputFormat.get(), _videoFormat)) {
[self setVideoFormat:inputFormat.get()];
int resetDecompressionSessionError = [self resetDecompressionSession];
if (resetDecompressionSessionError != WEBRTC_VIDEO_CODEC_OK) {
return resetDecompressionSessionError;
}
}
}
_useAVC = true;
return 0;
}

- (void)setCallback:(RTCVideoDecoderCallback)callback {
_callback = callback;
}
@@ -16,6 +16,7 @@
RTC_OBJC_EXPORT
__attribute__((objc_runtime_name("WK_RTCVideoDecoderH265")))
@interface RTCVideoDecoderH265 : NSObject <RTCVideoDecoder>
- (NSInteger)setAVCFormat:(const uint8_t *)data size:(size_t)size width:(uint16_t)width height:(uint16_t)height;
- (NSInteger)decodeData:(const uint8_t *)data
size:(size_t)size
timeStamp:(uint32_t)timeStamp;
@@ -82,10 +82,12 @@ @implementation RTCVideoDecoderH265 {
VTDecompressionSessionRef _decompressionSession;
RTCVideoDecoderCallback _callback;
OSStatus _error;
bool _useAVC;
}

- (instancetype)init {
if (self = [super init]) {
_useAVC = false;
}

return self;
@@ -100,6 +102,27 @@ - (NSInteger)startDecodeWithNumberOfCores:(int)numberOfCores {
return WEBRTC_VIDEO_CODEC_OK;
}

CMSampleBufferRef H265BufferToCMSampleBuffer(const uint8_t* buffer, size_t buffer_size, CMVideoFormatDescriptionRef video_format) {
CMBlockBufferRef new_block_buffer;
if (auto error = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, buffer_size, kCFAllocatorDefault, NULL, 0, buffer_size, kCMBlockBufferAssureMemoryNowFlag, &new_block_buffer)) {
RTC_LOG(LS_ERROR) << "H265BufferToCMSampleBuffer CMBlockBufferCreateWithMemoryBlock failed with: " << error;
return nullptr;
}
auto block_buffer = rtc::ScopedCF(new_block_buffer);

if (auto error = CMBlockBufferReplaceDataBytes(buffer, block_buffer.get(), 0, buffer_size)) {
RTC_LOG(LS_ERROR) << "H265BufferToCMSampleBuffer CMBlockBufferReplaceDataBytes failed with: " << error;
return nullptr;
}

CMSampleBufferRef sample_buffer = nullptr;
if (auto error = CMSampleBufferCreate(kCFAllocatorDefault, block_buffer.get(), true, nullptr, nullptr, video_format, 1, 0, nullptr, 0, nullptr, &sample_buffer)) {
RTC_LOG(LS_ERROR) << "H265BufferToCMSampleBuffer CMSampleBufferCreate failed with: " << error;
return nullptr;
}
return sample_buffer;
}

- (NSInteger)decode:(RTCEncodedImage*)inputImage
missingFrames:(BOOL)missingFrames
codecSpecificInfo:(__nullable id<RTCCodecSpecificInfo>)info
@@ -124,7 +147,7 @@ - (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint3
RTC_LOG(LS_INFO) << "Resolution: " << dimensions.width << " x "
<< dimensions.height;
// Check if the video format has changed, and reinitialize decoder if
// needed.
// needed.
if (!CMFormatDescriptionEqual(inputFormat.get(), _videoFormat)) {
[self setVideoFormat:inputFormat.get()];
int resetDecompressionSessionError = [self resetDecompressionSession];
@@ -144,7 +167,11 @@ - (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint3
}

CMSampleBufferRef sampleBuffer = nullptr;
if (!webrtc::H265AnnexBBufferToCMSampleBuffer(
if (_useAVC) {
sampleBuffer = H265BufferToCMSampleBuffer(data, size, _videoFormat);
if (!sampleBuffer)
return WEBRTC_VIDEO_CODEC_ERROR;
} else if (!webrtc::H265AnnexBBufferToCMSampleBuffer(
(uint8_t*)data, size,
_videoFormat, &sampleBuffer)) {
return WEBRTC_VIDEO_CODEC_ERROR;
@@ -178,6 +205,49 @@ - (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint3
return WEBRTC_VIDEO_CODEC_OK;
}

- (NSInteger)setAVCFormat:(const uint8_t *)data size:(size_t)size width:(uint16_t)width height:(uint16_t)height {
CFStringRef avcCString = (CFStringRef)@"hvcC";
CFDataRef codecConfig = CFDataCreate(kCFAllocatorDefault, data, size);
CFDictionaryRef atomsDict = CFDictionaryCreate(NULL,
(const void **)&avcCString,
(const void **)&codecConfig,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryRef extensionsDict = CFDictionaryCreate(NULL,
(const void **)&kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
(const void **)&atomsDict,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);

CMVideoFormatDescriptionRef videoFormatDescription = nullptr;
auto err = CMVideoFormatDescriptionCreate(NULL, kCMVideoCodecType_H264, width, height, extensionsDict, &videoFormatDescription);
CFRelease(codecConfig);
CFRelease(atomsDict);
CFRelease(extensionsDict);

if (err) {
RTC_LOG(LS_ERROR) << "Cannot create fromat description.";
return err;
}

rtc::ScopedCFTypeRef<CMVideoFormatDescriptionRef> inputFormat = rtc::ScopedCF(videoFormatDescription);
if (inputFormat) {
// Check if the video format has changed, and reinitialize decoder if
// needed.
if (!CMFormatDescriptionEqual(inputFormat.get(), _videoFormat)) {
[self setVideoFormat:inputFormat.get()];
int resetDecompressionSessionError = [self resetDecompressionSession];
if (resetDecompressionSessionError != WEBRTC_VIDEO_CODEC_OK) {
return resetDecompressionSessionError;
}
}
}
_useAVC = true;
return 0;
}

- (void)setCallback:(RTCVideoDecoderCallback)callback {
_callback = callback;
}
@@ -83,6 +83,7 @@ class LibWebRTCCodecsProxy final : public IPC::WorkQueueMessageReceiver {
void createDecoder(VideoDecoderIdentifier, VideoCodecType, bool useRemoteFrames);
void releaseDecoder(VideoDecoderIdentifier);
void flushDecoder(VideoDecoderIdentifier);
void setDecoderFormatDescription(VideoDecoderIdentifier, const IPC::DataReference&, uint16_t width, uint16_t height);
void decodeFrame(VideoDecoderIdentifier, uint32_t timeStamp, const IPC::DataReference&);
void setFrameSize(VideoDecoderIdentifier, uint16_t width, uint16_t height);

@@ -27,6 +27,7 @@ messages -> LibWebRTCCodecsProxy NotRefCounted {
CreateDecoder(WebKit::VideoDecoderIdentifier id, enum:uint8_t WebKit::VideoCodecType codecType, bool useRemoteFrames)
ReleaseDecoder(WebKit::VideoDecoderIdentifier id)
FlushDecoder(WebKit::VideoDecoderIdentifier id)
SetDecoderFormatDescription(WebKit::VideoDecoderIdentifier id, IPC::DataReference description, uint16_t width, uint16_t height)
DecodeFrame(WebKit::VideoDecoderIdentifier id, uint32_t timeStamp, IPC::DataReference data)
SetFrameSize(WebKit::VideoDecoderIdentifier id, uint16_t width, uint16_t height)

0 comments on commit a248b49

Please sign in to comment.