Changeset 287249 in webkit


Ignore:
Timestamp:
Dec 19, 2021 4:03:00 PM (7 months ago)
Author:
Jean-Yves Avenard
Message:

Don't pack audio samples with discontinuity together
https://bugs.webkit.org/show_bug.cgi?id=234458
rdar://86659914

Reviewed by Eric Carlson.

Some webm content may have a data gap between frames. Normally audio frames
are packed in 2s block. When we pack the samples with discontinuities, those
discontinuities would all be accumulated at the 2s boundary which makes them
much more audible.
The CMSampleBufferCreateReady API should allow us to pack samples with
discontinuities as we can give a vector of CMSampleTimingInfo with the
exact information for all packets.
However, this data appears to be ignored and the discontinuities is still
heard at the 2s boundary.
So we no longer pack samples with discontinuities so that the frame
timestamps will be more accurate and no audible artefacts are heard on
small gaps.

Manually tested and verified manually. This is getting around an issue
in CoreMedia that inserts very audible artifacts when there's a gap between
samples.

  • platform/graphics/cocoa/SourceBufferParserWebM.cpp:

(WebCore::SourceBufferParserWebM::AudioTrackData::resetCompleted):
(WebCore::SourceBufferParserWebM::AudioTrackData::consumeFrameData):
(WebCore::SourceBufferParserWebM::AudioTrackData::createSampleBuffer):

  • platform/graphics/cocoa/SourceBufferParserWebM.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r287248 r287249  
     12021-12-19  Jean-Yves Avenard  <jya@apple.com>
     2
     3        Don't pack audio samples with discontinuity together
     4        https://bugs.webkit.org/show_bug.cgi?id=234458
     5        rdar://86659914
     6
     7        Reviewed by Eric Carlson.
     8
     9        Some webm content may have a data gap between frames. Normally audio frames
     10        are packed in 2s block. When we pack the samples with discontinuities, those
     11        discontinuities would all be accumulated at the 2s boundary which makes them
     12        much more audible.
     13        The CMSampleBufferCreateReady API should allow us to pack samples with
     14        discontinuities as we can give a vector of CMSampleTimingInfo with the
     15        exact information for all packets.
     16        However, this data appears to be ignored and the discontinuities is still
     17        heard at the 2s boundary.
     18        So we no longer pack samples with discontinuities so that the frame
     19        timestamps will be more accurate and no audible artefacts are heard on
     20        small gaps.
     21
     22        Manually tested and verified manually. This is getting around an issue
     23        in CoreMedia that inserts very audible artifacts when there's a gap between
     24        samples.
     25
     26        * platform/graphics/cocoa/SourceBufferParserWebM.cpp:
     27        (WebCore::SourceBufferParserWebM::AudioTrackData::resetCompleted):
     28        (WebCore::SourceBufferParserWebM::AudioTrackData::consumeFrameData):
     29        (WebCore::SourceBufferParserWebM::AudioTrackData::createSampleBuffer):
     30        * platform/graphics/cocoa/SourceBufferParserWebM.h:
     31
    1322021-12-19  Alan Bujtas  <zalan@apple.com>
    233
  • trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp

    r287232 r287249  
    13741374{
    13751375    mNumFramesInCompleteBlock = 0;
    1376     m_packetDescriptions.clear();
     1376    m_packetSizes.clear();
     1377    m_packetTimings.clear();
    13771378    m_currentPacketByteOffset = 0;
    13781379    TrackData::resetCompleted();
     
    13811382webm::Status SourceBufferParserWebM::AudioTrackData::consumeFrameData(webm::Reader& reader, const FrameMetadata& metadata, uint64_t* bytesRemaining, const CMTime& presentationTime, int sampleCount)
    13821383{
     1384    if (m_packetTimings.size()) {
     1385        auto& lastTiming = m_packetTimings.last();
     1386        if (PAL::CMTimeCompare(PAL::CMTimeAdd(lastTiming.duration, lastTiming.presentationTimeStamp), presentationTime)) {
     1387            // Discontinuity encountered, emit the previously demuxed samples.
     1388            createSampleBuffer(metadata.position);
     1389            reset();
     1390        }
     1391    }
     1392
    13831393    auto status = readFrameData(reader, metadata, bytesRemaining);
    13841394    if (!status.completed_ok())
     
    13901400        mMaxBlockBufferCapacity = mNumFramesInCompleteBlock;
    13911401
    1392     if (m_packetDescriptions.isEmpty())
     1402    if (m_packetSizes.isEmpty())
    13931403        m_samplePresentationTime = presentationTime;
    13941404
     
    14671477    }
    14681478
    1469     m_packetDescriptions.append({ static_cast<int64_t>(m_currentPacketByteOffset), 0, static_cast<UInt32>(*m_completePacketSize) });
     1479    m_packetSizes.append(*m_completePacketSize);
     1480    m_packetTimings.append({ m_packetDuration, presentationTime, PAL::kCMTimeInvalid });
    14701481    m_currentPacketByteOffset += *m_completePacketSize;
    14711482    m_completePacketSize = std::nullopt;
    14721483
    14731484    auto sampleDuration = PAL::CMTimeGetSeconds(PAL::CMTimeSubtract(presentationTime, m_samplePresentationTime)) + PAL::CMTimeGetSeconds(m_packetDuration) * sampleCount;
     1485
    14741486    if (sampleDuration >= m_minimumSampleDuration) {
    14751487        createSampleBuffer(metadata.position);
     
    14831495void SourceBufferParserWebM::AudioTrackData::createSampleBuffer(std::optional<size_t> latestByteRangeOffset)
    14841496{
    1485     if (m_packetDescriptions.isEmpty())
     1497    if (m_packetSizes.isEmpty())
    14861498        return;
    14871499
    14881500    CMSampleBufferRef rawSampleBuffer = nullptr;
    1489     auto err = PAL::CMAudioSampleBufferCreateReadyWithPacketDescriptions(kCFAllocatorDefault, m_completeBlockBuffer.get(), formatDescription().get(), m_packetDescriptions.size(), m_samplePresentationTime, m_packetDescriptions.data(), &rawSampleBuffer);
     1501    auto err = PAL::CMSampleBufferCreateReady(kCFAllocatorDefault, m_completeBlockBuffer.get(), formatDescription().get(), m_packetSizes.size(), m_packetTimings.size(), m_packetTimings.data(), m_packetSizes.size(), m_packetSizes.data(), &rawSampleBuffer);
    14901502    if (err) {
    14911503        PARSER_LOG_ERROR_IF_POSSIBLE("CMAudioSampleBufferCreateWithPacketDescriptions failed with %d", err);
  • trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h

    r287232 r287249  
    235235        uint8_t m_framesPerPacket { 0 };
    236236        Seconds m_frameDuration { 0_s };
    237         Vector<AudioStreamPacketDescription> m_packetDescriptions;
     237        Vector<size_t> m_packetSizes;
     238        Vector<CMSampleTimingInfo> m_packetTimings;
    238239        size_t mNumFramesInCompleteBlock { 0 };
    239240        // FIXME: 0.5 - 1.0 seconds is a better duration per sample buffer, but use 2 seconds so at least the first
Note: See TracChangeset for help on using the changeset viewer.