如何从 DirectShow 获取未压缩的字节数组?

Posted

技术标签:

【中文标题】如何从 DirectShow 获取未压缩的字节数组?【英文标题】:How to get uncompressed byte array from DirectShow? 【发布时间】:2020-11-18 12:07:25 【问题描述】:

我正在尝试使用 DirectShow https://docs.microsoft.com/en-us/windows/win32/directshow/directshow 为了从.mp3 流中获取未压缩的字节数组。我有一个可以播放.mp3字节流的实现

bool coAudioPlayer::LoadImp(SoundDataType dataType, std::string const & filename, unsigned char const * pData, int64_t dataLen, bool bOnlyIfFilenameChanged)

...
    m_pMemReader = new CMemReader(m_pMemStream, m_pMediaType, &hr);

    m_pMemReader->AddRef();


    hr = CoCreateInstance(CLSID_FilterGraph,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IGraphBuilder,
        (void **)&this->m_pigb);

    hr = m_pigb->AddFilter(m_pMemReader, NULL);
    if (FAILED(hr))
    
        return false;
    

    m_pigb->QueryInterface(IID_IMediaControl, (void **)&m_pimc);
    m_pigb->QueryInterface(IID_IMediaEventEx, (void **)&m_pimex);
    m_pigb->QueryInterface(IID_IBasicAudio, (void**)&m_piba);
    m_pigb->QueryInterface(IID_IMediaSeeking, (void**)&m_pims);

    /*  Render our output pin */
    hr = m_pigb->Render(m_pMemReader->GetPin(0));
    if (!SUCCEEDED(hr))
    
        return false;
    

    HRESULT hr = m_pimc->Run();

    return m_bReady;

但我需要扩展此功能并添加方法来获取未压缩的字节数组(声音帧)。据我了解,DirectShow 对其进行了解码,但我看不到任何方法可以检索这个解码后的数组。

有办法吗?

【问题讨论】:

编写一个自定义的 DirectShow 过滤器,对帧进行处理并将其附加到 memreader 的输出引脚。微软关于这方面的文档非常好。您可以从CBaseRenderer 过滤器开始。 @Botje 您如何看待docs.microsoft.com/en-us/windows/win32/api/strmif/… 这种方法?看起来相关,不是吗? 该接口与属于过滤器的输入引脚相关联; CBaseRenderer filter 公开一个或多个实现此接口的 CBaseRendererInputPin 引脚。 【参考方案1】:

“未压缩字节数组”是对所需数据的完全错误定义。不存在字节数组格式的媒体数据。 MP3 音频通常会通过 MP3 解码器媒体对象包装器解压缩到 DirectShow 过滤器中,转换为具有某些属性(采样率、通道数、每个样本的位数)的 MEDIASUBTYPE_PCM 格式的音频。具体来说,选定的位深度(并且此解码器确实支持多个位深度选项!)直接将音频数据的表示定义为字节数组。

您在构建播放管道时不需要或不想访问数据,例如在您提到的Render 方法的场景中,您是否没有数据。

访问内容的典型方法是围绕Sample Grabber Filter 构建管道。有大量的代码和问题解释了这种方法。相关关键字是SampleCB 代表ISampleGrabberCB::SampleCB 方法。例如:ffmpeg audio frame from directshow sampleCB imediasample。

【讨论】:

以上是关于如何从 DirectShow 获取未压缩的字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何提供 AddRange 以获取 C# 中的所有数据?

Python:如何从 4 字节字节数组中获取 4 字节大小的整数?

从压缩字节加载 numpy 数组

如何从字节数组中获取正确的温度值

如何从Java中的字节数组中获取数据?

如何从 HttpInputStream 获取 docx 文件的字节数组?