媒体基金会无法获取缩略图

Media Foundation cant get thumbnail

我正在尝试从两个 mp3 文件中获取缩略图并将它们保存到一个文件中
对于他们两个,我都能获得缩略图流,但对于其中一个,我无法创建具有 windows 成像组件和其他工作正常的解码器
我也试过 gdi+ 但结果是一样的

这是我可以获得解码器的文件

mp3 的缩略图流

这是我无法获得解码器的文件

mp3 的缩略图流

// How i get the thumbnail stream
comptr<IPropertyStore> properityStore;

hr = MFGetService(mediaSource.get(), MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(properityStore.put()));

PROPVARIANT thumbnail;
PropVariantInit(&thumbnail);

IStream* thumbnailStream;
properityStore->GetValue(PKEY_ThumbnailStream, &thumbnail);

thumbnailStream = thumbnail.pStream;

PropVariantClear(&thumbnail);

尝试用两种方式创建解码器

// Hresult is WINCODEC_ERR_BADHEADER
comptr<IWICBitmapDecoder> decoder;
factory->CreateDecoder(GUID_ContainerFormatPng, nullptr, decoder.put());
hr = decoder->Initialize(thumbnailStream, WICDecodeMetadataCacheOnLoad);
// Hresult is WINCODEC_ERR_COMPONENTNOTFOUND
comptr<IWICBitmapDecoder> decoder;
hr = factory->CreateDecoderFromStream(stream.get(), nullptr, WICDecodeMetadataCacheOnLoad, decoder.put());

有什么方法可以修复那个或另一个 api 以供使用吗?

我有点明白了
在我无法创建解码器的流中,开头有一个空字符,删除它解决了问题
但是媒体基金会为什么要这么给流量呢?

这里是修复缩略图的代码header

size_t FixHeader(BYTE* data)
{
    constexpr char pngHeader[] = "‰PNG";
    constexpr char jfifHeader[] = "ÿØÿà";

    size_t length = strlen((char*)data) + 1;
    BYTE* foundStrpng = (BYTE*)strstr((char*)data + length, pngHeader);
    BYTE* foundStrjfif = (BYTE*)strstr((char*)data + length, jfifHeader);

    if (foundStrjfif)
    {
        return foundStrjfif - data;
    }
    if (foundStrpng)
    {
        return foundStrpng - data;
    }

    return 0;
}

STATSTG stat;
thumbnailStream->Stat(&stat, NULL);

ULONG size = stat.cbSize.QuadPart;
BYTE* data = new BYTE[size];

ULONG read = -1;
thumbnailStream->Read(data, size, &read);

size_t offset = FixHeader(data);
size -= offset;

ULARGE_INTEGER newSize = { 0 };
newSize.QuadPart = size;
LARGE_INTEGER seekPos = { 0 };
seekPos.QuadPart = 0;
thumbnailStream->Seek(seekPos, STREAM_SEEK_SET, nullptr);
thumbnailStream->SetSize(newSize);
thumbnailStream->Seek(seekPos, STREAM_SEEK_SET, nullptr);
DWORD written = -1;
thumbnailStream->Write(data + offset, size, &written);
thumbnailStream->Seek(seekPos, STREAM_SEEK_SET, nullptr);