Mar*_*ott 6 c++ ffmpeg libavcodec
我收到一个h264流,我至少知道一帧的大小.流正好进入,因为我可以将其存储在文件中并使用vlc进行播放.回放文件对我来说没问题,因为我包含了libavformat.但是libavformat给了我一个AVPacket,我可以直接给avogramc_decode_video2.在这种情况下,我得到了一个字节流.如何将原始h264流提供给avcodec_decode_video2?如何将数据包装到AVPacket中.VLC不需要猜测任何数据.
解码流或多或少都很容易.这段代码对我来说非常合适:
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;
};
Run Code Online (Sandbox Code Playgroud)
调用decodeStreamData期望数据为帧.你必须在你的流中搜索NAL(或多或少的标题幻数),它在h264情况下为0x00000001.它是一个帧的开头.填充AVPacket并不像我想象的那样有问题.如果您没有这些信息,可以将其中的属性保留为av_init_packet中的init.例如,如果您具有不同的帧速率,则只会出现问题.
和往常一样,如果你看到一个错误或认为某些东西会更好地工作,那么欢迎发短信.