gpt4 book ai didi

c++ - 使用媒体基础从 h.264 字节流(附件 B)创建 MP4 容器?

转载 作者:太空狗 更新时间:2023-10-29 21:00:29 24 4
gpt4 key购买 nike

基本上,我有一个采用 I 和 P 样本形式的整洁 H.264 字节流。我可以使用 MediaStreamSource 和 MediaElement 播放这些示例,它们播放效果很好。我还需要将它们保存为 MP4 文件,以便以后可以使用 Media Element 或 VLC 播放。这就是我尝试使用 Media Foundation 的方式;我从 MFCreateMPEG4MediaSink 创建了一个 IMFMediaSink;这是我的代码:

IMFMediaType *pMediaType = NULL;
IMFByteStream *pByteStream = NULL;
HRESULT hr = S_OK;
if (SUCCEEDED(hr))
{
hr = MFCreateMediaType(&pMediaType);
}

pSeqHdr = reinterpret_cast<UINT8 *>(mSamplesQueue.SequenceHeader());
if (SUCCEEDED(hr))
{
hr = pMediaType->SetBlob(MF_MT_MPEG_SEQUENCE_HEADER, pSeqHdr, 35);
}
UINT32 pcbBlobSize = {0};
hr = pMediaType->GetBlobSize(MF_MT_MPEG_SEQUENCE_HEADER, &pcbBlobSize);

/*if (SUCCEEDED(hr))
{
hr = pMediaType->SetUINT32(MF_MPEG4SINK_SPSPPS_PASSTHROUGH, TRUE);
}*/
if (SUCCEEDED(hr))
{
hr = pMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
}
if (SUCCEEDED(hr))
{
hr = pMediaType->SetGUID(MF_MT_SUBTYPE, VIDEO_INPUT_FORMAT);
}
if (SUCCEEDED(hr))
{
hr = MFSetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, VIDEO_FPS, 1);
}
if (SUCCEEDED(hr))
{
hr = pMediaType->SetUINT32(MF_MT_AVG_BITRATE, VIDEO_BIT_RATE);
}
if (SUCCEEDED(hr))
{
hr = pMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
}
if (SUCCEEDED(hr))
{
hr = MFSetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT);
}
if (SUCCEEDED(hr))
{
// Pixel aspect ratio
hr = MFSetAttributeRatio(pMediaType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
}
if (SUCCEEDED(hr))
{
hr = MFCreateFile(
MF_ACCESSMODE_READWRITE,
MF_OPENMODE_DELETE_IF_EXIST,
MF_FILEFLAGS_NONE,
L"output1.mp4",
&pByteStream);
}
if (SUCCEEDED(hr))
{
hr = MFCreateMPEG4MediaSink(
pByteStream,
pMediaType,
NULL,
&pMediaSink);
}

然后我使用 MFCreateSinkWriterFromMediaSink 从这个媒体接收器创建一个 IMFSinkWriter;这是我的代码:

if (SUCCEEDED(hr))
{
hr = MFCreateSinkWriterFromMediaSink(pMediaSink, NULL, &pSinkWriter);
}
// Tell the sink writer to start accepting data.
if (SUCCEEDED(hr))
{
hr = pSinkWriter->BeginWriting();
}

if (SUCCEEDED(hr))
{
pSinkWriter->AddRef();
}

然后我使用 IMFSinkWriter::WriteSample(0, IMFSample); 将每个样本写入接收器编写器;这是我的代码:IMFSample *pSample = NULL; IMFMediaBuffer *pBuffer = NULL;

const DWORD cbBuffer = mSamplesQueue.GetNextSampleSize();
UINT32 isIDR = mSamplesQueue.GetNextSampleIsIDR();
BYTE *pData = NULL;

// Create a new memory buffer.
HRESULT hr = MFCreateMemoryBuffer(cbBuffer, &pBuffer);

// Lock the buffer and copy the video frame to the buffer.
if (SUCCEEDED(hr))
{
DWORD buffLen = cbBuffer;
hr = pBuffer->Lock(&pData, &buffLen, 0);
}
if (SUCCEEDED(hr))
{
hr = mSamplesQueue.Dequeu(&pData);
}
if (pBuffer)
{
pBuffer->Unlock();
}

// Set the data length of the buffer.
if (SUCCEEDED(hr))
{
hr = pBuffer->SetCurrentLength(cbBuffer);
}

// Create a media sample and add the buffer to the sample.
if (SUCCEEDED(hr))
{
hr = MFCreateSample(&pSample);
}
if (SUCCEEDED(hr))
{
hr = pSample->AddBuffer(pBuffer);
}

// Set the time stamp and the duration.
if (SUCCEEDED(hr))
{
hr = pSample->SetSampleTime(rtStart);
}
if (SUCCEEDED(hr))
{
hr = pSample->SetSampleDuration(rtDuration);
}
if (SUCCEEDED(hr))
{
hr = pSample->SetUINT32(MFSampleExtension_CleanPoint, isIDR);
}
//pSample->
// Send the sample to the Sink Writer.
if (SUCCEEDED(hr))
{
hr = pSinkWriter->WriteSample(0, pSample);
}

SafeRelease(&pSample);
SafeRelease(&pBuffer);

样本的编写是从我拥有的每个样本中调用的迭代代码(我正在测试 1k I 和 P 样本)。现在,当我调用 IMFSinkWriter::Finalize() 时,它告诉我“0xc00d4a45:接收器无法创建有效的输出文件,因为所需的 header 未提供给接收器。”。它确实创建了一个非常有效大小的 MP4 文件(对于我的 1k 样本,4.6 MB)。 This is the link to the trace from MFTrace.如果它要求 MF_MT_MPEG_SEQUENCE_HEADER 那么我用 IMFMediaType::SetBlob(MF_MT_MPEG_SEQUENCE_HEADER, BYTE[], UINT32) 设置它们我用 Elecard Video Format Analyzer 检查了文件,标题似乎不完整。我可以得到一些帮助来找出我缺少的东西,或者是否有更好的/其他方法来做我想要实现的目标?谢谢!

最佳答案

对我来说,问题是 MF_MT_MPEG_SEQUENCE_HEADER blob 的格式。

与 dwSequenceHeader 和 H.264 上的 MSDN 文档相比,SPS 和 PPS 应该在前面加上起始代码 (0x00,0x00,0x01) 而不是 2 字节长度字段。

http://msdn.microsoft.com/en-us/library/dd757808%28VS.85%29.aspx

关于c++ - 使用媒体基础从 h.264 字节流(附件 B)创建 MP4 容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22057696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com