c++ - 从 AVPacket 为 h264 视频填充 CMediaType 和 IMediaSample

标签 c++ directshow h.264 libav

我已经进行了搜索,但几乎什么也没找到,所以我非常感谢能为我的问题提供帮助。

我正在编写一个 DirectShow 源过滤器,它使用 libav 从 youtube 的 FLV 文件读取和发送下游 h264 数据包。但是我找不到合适的 libav 结构字段来正确实现过滤器的 GetMediType() 和 FillBuffer()。某些 libav 字段为空。结果,h264 解码器在尝试处理接收到的数据时崩溃。

我哪里错了?在使用 libav 或 DirectShow 接口(interface)时?也许 h264 在使用 libav 时需要额外的处理,或者我错误地填写了引用时间?有人有任何链接可用于使用 libav 编写 DirectShow h264 源过滤器吗?

GetMediaType() 的一部分:

VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*) toMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
pvi->AvgTimePerFrame = UNITS_PER_SECOND / m_pFormatContext->streams[m_streamNo]->codec->sample_rate; //sample_rate is 0
pvi->dwBitRate       = m_pFormatContext->bit_rate;
pvi->rcSource        = videoRect;
pvi->rcTarget        = videoRect;

//Bitmap
pvi->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth    = videoRect.right;
pvi->bmiHeader.biHeight   = videoRect.bottom;
pvi->bmiHeader.biPlanes   = 1;
pvi->bmiHeader.biBitCount = m_pFormatContext->streams[m_streamNo]->codec->bits_per_raw_sample;//or should here be bits_per_coded_sample
pvi->bmiHeader.biCompression = FOURCC_H264;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);

FillBuffer() 的一部分:

//Get buffer pointer
BYTE* pBuffer = NULL;
if (pSamp->GetPointer(&pBuffer) < 0)
   return S_FALSE;

//Get next packet
AVPacket* pPacket = m_mediaFile.getNextPacket();
if (pPacket->data == NULL)
   return S_FALSE;

//Check packet and buffer size
if (pSamp->GetSize() < pPacket->size)
   return S_FALSE;

//Copy from packet to sample buffer
memcpy(pBuffer, pPacket->data, pPacket->size);

//Set media sample time
REFERENCE_TIME start    = m_mediaFile.timeStampToReferenceTime(pPacket->pts);
REFERENCE_TIME duration = m_mediaFile.timeStampToReferenceTime(pPacket->duration);
REFERENCE_TIME end      = start + duration;
pSamp->SetTime(&start, &end);
pSamp->SetMediaTime(&start, &end);

附言我用 hax264 解码器调试了我的过滤器,它在调用 libav 弃用函数 img_convert() 时崩溃。

最佳答案

这是构建正确的 H.264 媒体类型所需的 MSDN 链接:H.264 Video Types

关于c++ - 从 AVPacket 为 h264 视频填充 CMediaType 和 IMediaSample,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7066768/

相关文章:

c++ - 使用函数从 C++ 中的数组中删除重复项

c++ - 使用 C++ 提取 .rar/.zip

来自函数的 c++ stacktrace 抛出异常?

c++ - DirectX pEnum->Next(1,&pPin,NULL) 返回 S_FALSE

video - 如何让屏幕录像机捕获基于DirectShow的视频?

ffmpeg - 使用管道而不是文件从原始 h264 创建 mp4 文件

C++11 从参数包创建静态数组

c++ - 从 directshow 获取音频/视频数据的最简单方法

Ubuntu ffmpeg 无法使用 libx264

c - h264 inside AVI、MP4 和 "Raw"h264 流。不同格式的 NAL 单元(或 ffmpeg 错误)