我正在尝试使用ffmpeg库解码视频流,这就是我基本上这样做的方式:
void video_decode(const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int frame_count=0;
FILE *f;
AVFrame *frame;
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
av_init_packet(&avpkt);
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
printf("Decoding video file...\n");
/* find the h264 video decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
c = avcodec_alloc_context3(codec);
c->bit_rate = 400000;
c->width = 1920;
c->height = 1080;
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
frame = av_frame_alloc();
for (;;) {
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
if (avpkt.size == 0)
break;
avpkt.data = inbuf;
while(avpkt.size > 0){
int len, got_frame;
len = avcodec_decode_video2(c, frame, &got_frame, &avpkt);
if (len < 0) {
fprintf(stderr, "Errr while decding frame %d\n", frame_count);
exit (1);
}
if (got_frame) {
//Print out frame information..
}
if (avpkt.data) {
avpkt.size -= len;
avpkt.data += len;
}
}
}
}
但我得到了以下输出:
Decoding video file...
[h264 @ 0x303c040] decode_slice_header error
[h264 @ 0x303c040] decode_slice_header error
[h264 @ 0x303c040] decode_slice_header error
[h264 @ 0x303c040] no frame!
Errr while decding frame 0
显然,编解码器的启动是不完整的。你有h264 api的经验吗?任何帮助将不胜感激。
答案 0 :(得分:3)
您不能将随机数(INBUF_SIZE)的字节放入AV数据包。它应该是完整的AU或NALU,如果它不是附件B,则必须首先设置额外的数据字段。对于您的情况,我建议使用libavformat打开文件并阅读AVPackets。
答案 1 :(得分:0)
这个问题的答案在demuxing_decoding.c ffmpeg的例子中给出。
如果您的ffmpeg安装目录是默认的&#34; usr / local / &#34;
,可以单独编译此文件,如下所示。gcc -I/usr/local/include -c demuxing_decoding.c -o demuxing_decoding.o
gcc demuxing_decoding.o -pthread -L/usr/local/lib -lavdevice -lavfilter -lpostproc -lavformat -lavcodec -lva-x11 -lva -lxcb-xfixes -lxcb-render -lxcb-shape -lxcb -lX11 -lx264 -lpthread -ldl -lz -lswresample -lswscale -lavutil -lm -o demuxing_decoding
如果安装目录更改为&#34; ffmpeg_ins_dir &#34;替换&#34; usr / local / &#34;在上面的命令中使用&#34; 路径到ffmpef_ins_dir / &#34;。
运行二进制文件如下。
./demuxing_decoding test.h264 v_out.yuv a_out.yuv
注意:此示例包含许多您可能根本不需要的内容,删除不需要的内容并重新编译它。
答案 2 :(得分:0)
也许您应该尝试在fread()和avcodec_decode_video2()之间使用AVCODECPARSER; av_parser_parse2()。将您的原始数据从原始数据更改为h264,以提供给解码器。 像这样的C代码:
#while (1)
{
cur_size = fread(in_buffer, 1, in_buffer_size, fp_in);
cur_ptr = in_buffer;
while (cur_size > 0)
{
int len = av_parser_parse2(pCodecParserCtx, pCodecCtx, &packet.data, &packet.size, cur_ptr, cur_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
cur_ptr += len;
cur_size -= len;
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
if (ret < 0)
{
printf("Decode Error\n");
return ret;
}
if (got_picture)
{
printf("Succeed to decode 1 frame!\n");
}
}
受此启发: https://blog.csdn.net/leixiaohua1020/article/details/42181571