IMFSourceReaderCallback::OnReadSample 函数
IMFSourceReaderCallback::OnReadSample Function
要从您的网络摄像头读取样本并将它们写入文件,您可以实现 IMFSourceReaderCallback 并且回调函数 OnReadSample 将发送 IMFSample *pSample 以及一些其他参数,例如时间戳,您可以将它们与 ISinkWriter 一起使用以将它们写入文件(您可以查看 MSDN 示例 MFCaptureToFile Sample )
STDMETHODIMP OnReadSample(
HRESULT hrStatus,
DWORD dwStreamIndex,
DWORD dwStreamFlags,
LONGLONG llTimestamp,
IMFSample *pSample
);
我已将我的编码参数设置为 H264。我将 pSample 转换为原始数据(字节集)并删除了 ISinkWriter。
我有一个棘手的问题 *"is IMFSample pSample encoded or they become encoded inside ISinkWriter as when I convert them to RawData I got a huge file so are they encoded?" 还有一个问题 将它们写入文件后如何测试它们(它们是原始格式)
示例将采用原始格式,例如 YUV 或 RGB。您不能在视频设备源 reader 上将输出媒体类型设置为 H264(除非该设备恰好本身支持 H264)。当您引入带有 .mp4 文件的 SinkWriter 作为目标时,媒体基础将负责解析拓扑,在这种情况下这意味着包括 H264 媒体基础转换。
我用来测试 SourceReader 原始输出的一种方法是指定 MFVideoFormat_IYUV 的输出格式,然后在写入文件流后使用 ffmpeg 提取 jpeg 或将其转换为 avi 视频文件。
std::ofstream outputBuffer("rawframes.yuv", std::ios::out | std::ios::binary);
IMFMediaBuffer *buf = NULL;
DWORD bufLength;
pSample->ConvertToContiguousBuffer(&buf);
buf->GetCurrentLength(&bufLength);
printf("Writing sample %i, sample time %i, sample duration %i, sample size .\n", sampleCount, llVideoTimeStamp, llSampleDuration);
byte *byteBuffer;
DWORD buffCurrLen = 0;
DWORD buffMaxLen = 0;
buf->Lock(&byteBuffer, &buffMaxLen, &buffCurrLen);
outputBuffer.write((char *)byteBuffer, bufLength);
outputBuffer.flush();
然后是 ffmpeg 命令:
ffmpeg -vcodec rawvideo -s 640x480 -pix_fmt yuv420p -i rawframes.yuv -vframes 1 output.jpeg
ffmpeg -vcodec rawvideo -s 640x480 -pix_fmt yuv420p -i rawframes.yuv out.avi
使用上述代码段的示例控制台应用程序可在 github.
要从您的网络摄像头读取样本并将它们写入文件,您可以实现 IMFSourceReaderCallback 并且回调函数 OnReadSample 将发送 IMFSample *pSample 以及一些其他参数,例如时间戳,您可以将它们与 ISinkWriter 一起使用以将它们写入文件(您可以查看 MSDN 示例 MFCaptureToFile Sample )
STDMETHODIMP OnReadSample(
HRESULT hrStatus,
DWORD dwStreamIndex,
DWORD dwStreamFlags,
LONGLONG llTimestamp,
IMFSample *pSample
);
我已将我的编码参数设置为 H264。我将 pSample 转换为原始数据(字节集)并删除了 ISinkWriter。 我有一个棘手的问题 *"is IMFSample pSample encoded or they become encoded inside ISinkWriter as when I convert them to RawData I got a huge file so are they encoded?" 还有一个问题 将它们写入文件后如何测试它们(它们是原始格式)
示例将采用原始格式,例如 YUV 或 RGB。您不能在视频设备源 reader 上将输出媒体类型设置为 H264(除非该设备恰好本身支持 H264)。当您引入带有 .mp4 文件的 SinkWriter 作为目标时,媒体基础将负责解析拓扑,在这种情况下这意味着包括 H264 媒体基础转换。
我用来测试 SourceReader 原始输出的一种方法是指定 MFVideoFormat_IYUV 的输出格式,然后在写入文件流后使用 ffmpeg 提取 jpeg 或将其转换为 avi 视频文件。
std::ofstream outputBuffer("rawframes.yuv", std::ios::out | std::ios::binary);
IMFMediaBuffer *buf = NULL;
DWORD bufLength;
pSample->ConvertToContiguousBuffer(&buf);
buf->GetCurrentLength(&bufLength);
printf("Writing sample %i, sample time %i, sample duration %i, sample size .\n", sampleCount, llVideoTimeStamp, llSampleDuration);
byte *byteBuffer;
DWORD buffCurrLen = 0;
DWORD buffMaxLen = 0;
buf->Lock(&byteBuffer, &buffMaxLen, &buffCurrLen);
outputBuffer.write((char *)byteBuffer, bufLength);
outputBuffer.flush();
然后是 ffmpeg 命令:
ffmpeg -vcodec rawvideo -s 640x480 -pix_fmt yuv420p -i rawframes.yuv -vframes 1 output.jpeg
ffmpeg -vcodec rawvideo -s 640x480 -pix_fmt yuv420p -i rawframes.yuv out.avi
使用上述代码段的示例控制台应用程序可在 github.