⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 268392 in webkit


Ignore:
Timestamp:
Oct 13, 2020, 5:08:31 AM (6 years ago)
Author:
Philippe Normand
Message:

[GStreamer] Crash in WebCore::GStreamerRegistryScanner::isAVC1CodecSupported
https://bugs.webkit.org/show_bug.cgi?id=217647

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

The registry scanner was assuming the avc1 codec field is always of the form
avc1.codecprofile, which is wrong.

Covered by test: media/media-can-play-mpeg4-video.html

  • platform/graphics/gstreamer/GStreamerRegistryScanner.cpp:

(WebCore::GStreamerRegistryScanner::isAVC1CodecSupported const): Check for '.' presence and
fallback to unconstrained check if no profile or level information was extracted.

LayoutTests:

  • media/media-can-play-mpeg4-video-expected.txt:
  • media/media-can-play-mpeg4-video.html: Add test for "avc1" codec.
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r268391 r268392  
     12020-10-13  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer] Crash in WebCore::GStreamerRegistryScanner::isAVC1CodecSupported
     4        https://bugs.webkit.org/show_bug.cgi?id=217647
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        * media/media-can-play-mpeg4-video-expected.txt:
     9        * media/media-can-play-mpeg4-video.html: Add test for "avc1" codec.
     10
    1112020-10-13  Adrian Perez de Castro  <aperez@igalia.com>
    212
  • trunk/LayoutTests/media/media-can-play-mpeg4-video-expected.txt

    r158743 r268392  
    66EXPECTED (video.canPlayType('video/x-m4v') == 'maybe') OK
    77EXPECTED (video.canPlayType('video/mp4') == 'maybe') OK
     8EXPECTED (video.canPlayType('video/mp4; Codecs="avc1"') == 'probably') OK
    89EXPECTED (video.canPlayType('video/mp4; Codecs="avc1.4D400C"') == 'probably') OK
    910EXPECTED (video.canPlayType(' Video/MP4 ; CODECS="mp4v.20.8, mp4a.40.2"') == 'probably') OK
  • trunk/LayoutTests/media/media-can-play-mpeg4-video.html

    r115798 r268392  
    1010                testExpected("video.canPlayType('video/x-m4v')", "maybe");
    1111                testExpected("video.canPlayType('video/mp4')", "maybe");
     12                testExpected("video.canPlayType('video/mp4; Codecs=\"avc1\"')", "probably");
    1213                testExpected("video.canPlayType('video/mp4; Codecs=\"avc1.4D400C\"')", "probably");
    1314                testExpected("video.canPlayType('        Video/MP4 ; CODECS=\"mp4v.20.8, mp4a.40.2\"')", "probably");
  • trunk/Source/WebCore/ChangeLog

    r268390 r268392  
     12020-10-13  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer] Crash in WebCore::GStreamerRegistryScanner::isAVC1CodecSupported
     4        https://bugs.webkit.org/show_bug.cgi?id=217647
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        The registry scanner was assuming the avc1 codec field is always of the form
     9        avc1.codecprofile, which is wrong.
     10
     11        Covered by test: media/media-can-play-mpeg4-video.html
     12
     13        * platform/graphics/gstreamer/GStreamerRegistryScanner.cpp:
     14        (WebCore::GStreamerRegistryScanner::isAVC1CodecSupported const): Check for '.' presence and
     15        fallback to unconstrained check if no profile or level information was extracted.
     16
    1172020-10-13  Adrian Perez de Castro  <aperez@igalia.com>
    218
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp

    r267474 r268392  
    365365bool GStreamerRegistryScanner::isAVC1CodecSupported(const String& codec, bool shouldCheckForHardwareUse) const
    366366{
    367     auto components = codec.split('.');
    368     long int spsAsInteger = strtol(components[1].utf8().data(), nullptr, 16);
    369     uint8_t sps[3];
    370     sps[0] = spsAsInteger >> 16;
    371     sps[1] = spsAsInteger >> 8;
    372     sps[2] = spsAsInteger;
    373 
    374     const char* profile = gst_codec_utils_h264_get_profile(sps, 3);
    375     const char* level = gst_codec_utils_h264_get_level(sps, 3);
    376 
    377     // To avoid going through a class hierarchy for such a simple
    378     // string conversion, we use a little trick here: See
    379     // https://bugs.webkit.org/show_bug.cgi?id=201870.
    380     char levelAsStringFallback[2] = { '\0', '\0' };
    381     if (!level && sps[2] > 0 && sps[2] <= 5) {
    382         levelAsStringFallback[0] = static_cast<char>('0' + sps[2]);
    383         level = levelAsStringFallback;
    384     }
    385 
    386     if (!profile || !level) {
    387         GST_ERROR("H.264 profile / level was not recognised in codec %s", codec.utf8().data());
    388         return false;
    389     }
    390 
    391     GST_DEBUG("Codec %s translates to H.264 profile %s and level %s", codec.utf8().data(), profile, level);
    392 
    393367    auto checkH264Caps = [&](const char* capsString) {
    394368        bool supported = false;
     
    400374        return supported;
    401375    };
     376
     377    if (codec.find('.') == notFound) {
     378        GST_DEBUG("Codec has no profile/level, falling back to unconstrained caps");
     379        return checkH264Caps("video/x-h264");
     380    }
     381
     382    auto components = codec.split('.');
     383    long int spsAsInteger = strtol(components[1].utf8().data(), nullptr, 16);
     384    uint8_t sps[3];
     385    sps[0] = spsAsInteger >> 16;
     386    sps[1] = spsAsInteger >> 8;
     387    sps[2] = spsAsInteger;
     388
     389    const char* profile = gst_codec_utils_h264_get_profile(sps, 3);
     390    const char* level = gst_codec_utils_h264_get_level(sps, 3);
     391
     392    // To avoid going through a class hierarchy for such a simple
     393    // string conversion, we use a little trick here: See
     394    // https://bugs.webkit.org/show_bug.cgi?id=201870.
     395    char levelAsStringFallback[2] = { '\0', '\0' };
     396    if (!level && sps[2] > 0 && sps[2] <= 5) {
     397        levelAsStringFallback[0] = static_cast<char>('0' + sps[2]);
     398        level = levelAsStringFallback;
     399    }
     400
     401    if (!profile || !level) {
     402        GST_ERROR("H.264 profile / level was not recognised in codec %s", codec.utf8().data());
     403        return false;
     404    }
     405
     406    GST_DEBUG("Codec %s translates to H.264 profile %s and level %s", codec.utf8().data(), profile, level);
    402407
    403408    if (const char* maxVideoResolution = g_getenv("WEBKIT_GST_MAX_AVC1_RESOLUTION")) {
Note: See TracChangeset for help on using the changeset viewer.