我收到一个h264流,我至少知道一帧的大小。流正好进入,因为我可以将其存储在文件中并使用vlc进行播放。回放文件对我来说没问题,因为我包含了libavformat。但是libavformat给了我一个AVPacket,我可以直接给avogramc_decode_video2。在这种情况下,我得到了一个字节流。如何将原始h264流提供给avcodec_decode_video2?如何将数据包装到AVPacket中。 VLC不需要猜测任何数据。
答案 0 :(得分:6)
解码流或多或少都很容易。这段代码非常适合我:
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中的init。例如,如果您有不同的帧速率,则只会出现问题。
与往常一样,如果您发现错误或认为某些内容会更好,那么欢迎提供短信。