FFmpeg 使用 avcodec_decode_video2 解码原始缓冲区
我收到一个 h264 流,其中我至少知道一帧的大小.流是正确的,因为我可以将它存储在一个文件中并使用 vlc 播放.播放文件对我来说没有问题,因为我包含了 libavformat.但是 libavformat 给了我一个 AVPacket,我可以直接将其提供给 avcodec_decode_video2.在这种情况下,我得到了一个字节流.如何将原始 h264 流提供给 avcodec_decode_video2?如何将我的数据包装到 AVPacket 中.VLC 不需要猜测任何数据.
I am receiving a h264 stream where I at least know the size of one frame. The stream is coming in right as I can store it in a file and playback with vlc. Playing back a file is no problem for me as I include the libavformat. But libavformat gives me back an AVPacket which I can directly give to avcodec_decode_video2. In this case I got a bytestream. How can I give the raw h264 stream to the avcodec_decode_video2? How can I wrap my data into a AVPacket. VLC does not need to guess any data.
推荐答案
解码流或多或少很容易.这段代码非常适合我:
It is more or less easy to decode a stream. This code is working perfect for me:
class ffmpegstreamdestination
{
public:
ffmpegstreamdestination(AVCodecID decoder):
{
m_pCodec= avcodec_find_decoder(decoder);
m_pCodecCtx = avcodec_alloc_context3(m_pCodec);
avcodec_open2(m_pCodecCtx,m_pCodec,0);
m_pFrame=avcodec_alloc_frame();
}
~ffmpegstreamdestination()
{
av_free(m_pFrame);
avcodec_close(m_pCodecCtx);
}
void decodeStreamData(unsigned char * pData, size_t sz)
{
AVPacket packet;
av_init_packet(&packet);
packet.data=pData;
packet.size=(int)sz;
int framefinished=0;
int nres=avcodec_decode_video2(m_pCodecCtx,m_pFrame,&framefinished,&packet);
if(framefinished)
{
// do the yuv magic and call a consumer
}
return;
}
protected:
AVCodecContext *m_pCodecCtx;
AVCodec *m_pCodec;
AVFrame *m_pFrame;
};
decodeStreamData 调用期望数据为帧.你必须在你的流中搜索 NAL(或多或少是一个标头幻数),它在 h264 案例 0x00000001 中.它是一帧的开始.填充 AVPacket 并没有我想象的那么麻烦.如果您没有该信息,您可以将其中的属性保留为由 av_init_packet 初始化.例如,只有当您有不同的帧率时才会出现问题.
the call decodeStreamData expect the data as frames. You have to search your stream for the NAL (more or less a header magic number) which is in h264 case 0x00000001 .Its the beginning of a frame. Filling the AVPacket is not as problematic as I thought. If you do not have the information, you can left the attributes in it as the are init by av_init_packet. There are only problems if you have a different framerate for example.
与往常一样,如果您发现错误或认为某些东西可以更好地工作,欢迎发送短消息.
As always, if you see a bug or think something would work otherwise better, a short message would be welcome.
相关文章