Changeset 270884 in webkit


Ignore:
Timestamp:
Dec 16, 2020, 12:30:05 AM (5 years ago)
Author:
youenn@apple.com
Message:

Make sure to correctly initialize the vpcC configuration in RTCVideoDecoderVTBVP9
https://bugs.webkit.org/show_bug.cgi?id=219782

Reviewed by Eric Carlson.

We need to initialize the configuration record based on the frame header.
We do so for every key frame.

  • Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm:

(convertSubsamplingXYToChromaSubsampling):
(-[RTCVideoDecoderVTBVP9 startDecodeWithNumberOfCores:]):
(-[RTCVideoDecoderVTBVP9 decode:missingFrames:codecSpecificInfo:renderTimeMs:]):
(-[RTCVideoDecoderVTBVP9 decodeData:size:timeStamp:]):

Location:
trunk/Source/ThirdParty/libwebrtc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/ThirdParty/libwebrtc/ChangeLog

    r270758 r270884  
     12020-12-16  Youenn Fablet  <youenn@apple.com>
     2
     3        Make sure to correctly initialize the vpcC configuration in RTCVideoDecoderVTBVP9
     4        https://bugs.webkit.org/show_bug.cgi?id=219782
     5
     6        Reviewed by Eric Carlson.
     7
     8        We need to initialize the configuration record based on the frame header.
     9        We do so for every key frame.
     10
     11        * Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm:
     12        (convertSubsamplingXYToChromaSubsampling):
     13        (-[RTCVideoDecoderVTBVP9 startDecodeWithNumberOfCores:]):
     14        (-[RTCVideoDecoderVTBVP9 decode:missingFrames:codecSpecificInfo:renderTimeMs:]):
     15        (-[RTCVideoDecoderVTBVP9 decodeData:size:timeStamp:]):
     16
    1172020-12-13  Andy Estes  <aestes@apple.com>
    218
  • trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm

    r269306 r270884  
    4242
    4343#include "modules/video_coding/include/video_error_codes.h"
     44#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
    4445#include "rtc_base/checks.h"
    4546#include "rtc_base/logging.h"
     
    4748
    4849extern const CFStringRef kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms;
    49 #define VPCodecConfigurationContentsSize 12
     50
     51static uint8_t convertSubsampling(webrtc::vp9::YuvSubsampling value)
     52{
     53    switch (value) {
     54    case webrtc::vp9::YuvSubsampling::k444:
     55        return 3;
     56    case webrtc::vp9::YuvSubsampling::k440:
     57        return 1;
     58    case webrtc::vp9::YuvSubsampling::k422:
     59        return 2;
     60    case webrtc::vp9::YuvSubsampling::k420:
     61        return 1;
     62    }
     63}
     64
     65rtc::ScopedCFTypeRef<CMVideoFormatDescriptionRef> computeInputFormat(const uint8_t* data, size_t size, int32_t width, int32_t height)
     66{
     67  constexpr size_t VPCodecConfigurationContentsSize = 12;
     68
     69  auto result = webrtc::vp9::ParseIntraFrameInfo(data, size);
     70
     71  if (!result)
     72      return { };
     73  auto chromaSubsampling = convertSubsampling(result->sub_sampling);
     74  uint8_t bitDepthChromaAndRange = (0xF & (uint8_t)result->bit_detph) << 4 | (0x7 & chromaSubsampling) << 1 | (0x1 & (uint8_t)result->color_range);
     75
     76  uint8_t record[VPCodecConfigurationContentsSize];
     77  memset((void*)record, 0, VPCodecConfigurationContentsSize);
     78  // Version and flags (4 bytes)
     79  record[0] = 1;
     80  // profile
     81  record[4] = result->profile;
     82  // level
     83  record[5] = 10;
     84  // bitDepthChromaAndRange
     85  record[6] = bitDepthChromaAndRange;
     86  // colourPrimaries
     87  record[7] = 2; // Unspecified.
     88  // transferCharacteristics
     89  record[8] = 2; // Unspecified.
     90  // matrixCoefficients
     91  record[9] = 2; // Unspecified.
     92
     93  auto cfData = rtc::ScopedCF(CFDataCreate(kCFAllocatorDefault, record, VPCodecConfigurationContentsSize));
     94  auto configurationDict = @{ @"vpcC": (__bridge NSData *)cfData.get() };
     95  auto extensions = @{ (__bridge NSString *)kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms: configurationDict };
     96
     97  CMVideoFormatDescriptionRef formatDescription = nullptr;
     98  // Use kCMVideoCodecType_VP9 once added to CMFormatDescription.h
     99  if (noErr != CMVideoFormatDescriptionCreate(kCFAllocatorDefault, 'vp09', width, height, (__bridge CFDictionaryRef)extensions, &formatDescription))
     100      return { };
     101
     102  return rtc::ScopedCF(formatDescription);
     103}
    50104
    51105// Struct that we pass to the decoder per frame to decode. We receive it again
     
    118172  int32_t _width;
    119173  int32_t _height;
     174  bool _shouldCheckFormat;
     175}
     176
     177- (instancetype)init {
     178  self = [super init];
     179  if (self) {
     180    _shouldCheckFormat = true;
     181  }
     182  return self;
    120183}
    121184
     
    143206  _width = width;
    144207  _height = height;
     208  _shouldCheckFormat = true;
    145209}
    146210
     
    155219  }
    156220
    157   uint8_t record[VPCodecConfigurationContentsSize];
    158   // FIXME: Initialize properly the vpcC decoding configuration.
    159   memset((void*)record, 0, VPCodecConfigurationContentsSize);
    160   auto configurationDict = @{
    161     @"vpcC": (__bridge NSData *)CFDataCreate(kCFAllocatorDefault, record, VPCodecConfigurationContentsSize)
    162   };
    163   auto extensions = @{
    164     (__bridge NSString *)kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms: configurationDict
    165   };
    166 
    167   CMVideoFormatDescriptionRef formatDescription = nullptr;
    168   // Use kCMVideoCodecType_VP9 once added to CMFormatDescription.h
    169   if (noErr != CMVideoFormatDescriptionCreate(kCFAllocatorDefault, 'vp09', _width, _height, (__bridge CFDictionaryRef)extensions, &formatDescription))
    170     return WEBRTC_VIDEO_CODEC_ERROR;
    171 
    172   rtc::ScopedCFTypeRef<CMVideoFormatDescriptionRef> inputFormat = rtc::ScopedCF(formatDescription);
    173   if (inputFormat) {
    174     // Check if the video format has changed, and reinitialize decoder if
    175     // needed.
    176     if (!CMFormatDescriptionEqual(inputFormat.get(), _videoFormat)) {
    177       [self setVideoFormat:inputFormat.get()];
    178       int resetDecompressionSessionError = [self resetDecompressionSession];
    179       if (resetDecompressionSessionError != WEBRTC_VIDEO_CODEC_OK) {
    180         return resetDecompressionSessionError;
     221  if (_shouldCheckFormat || !_videoFormat) {
     222    auto inputFormat = computeInputFormat(data, size, _width, _height);
     223    if (inputFormat) {
     224      _shouldCheckFormat = false;
     225      // Check if the video format has changed, and reinitialize decoder if
     226      // needed.
     227      if (!CMFormatDescriptionEqual(inputFormat.get(), _videoFormat)) {
     228        [self setVideoFormat:inputFormat.get()];
     229        int resetDecompressionSessionError = [self resetDecompressionSession];
     230        if (resetDecompressionSessionError != WEBRTC_VIDEO_CODEC_OK) {
     231          [self setVideoFormat:nullptr];
     232          return resetDecompressionSessionError;
     233        }
    181234      }
    182235    }
Note: See TracChangeset for help on using the changeset viewer.