C++ h264 ffmpeg/libav encode/decode(无损)问题
C++ h264 ffmpeg/libav encode/decode(lossless) issues
使用 ffmpeg h264(无损)encode/decode 视频的见解
所以我在编码部分做了一些工作,将 avi 编码为 264,但 VLC 无法播放,但 Totem 可以。
解码同一个文件证明很麻烦。 (我想要完全相同的 data/frame 进出),我得到这些 ;
saving frame 5
Video decoding
[h264 @ 0x1d19880] decode_slice_header error
frame :6
saving frame 6
Video decoding
[h264 @ 0x1d19880] error while decoding MB 15 7, bytestream -27
[h264 @ 0x1d19880] concealing 194 DC, 194 AC, 194 MV errors in I frame
frame :7
saving frame 7
Video decoding
[h264 @ 0x1d19880] decode_slice_header error
最后就是这个
[H264 Decoder @ 0x7f1320766040] frame :11
Broken frame packetizing
[h264 @ 0x1d19880] SPS changed in the middle of the frame
[h264 @ 0x1d19880] decode_slice_header error
[h264 @ 0x1d19880] no frame!
Error while decoding frame 11
游戏结束。
现在我怀疑我必须回到 1. 编码部分,VLC 无法播放它可能有充分的理由!
我是这样编码的
void encode(char *Y,char *U,char *V){
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
fflush(stdout);
frame->data[0] = (uint8_t*)Y;
frame->data[1] = (uint8_t*)U;
frame->data[2] = (uint8_t*)V;
frame->pts = ++i;
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit (EXIT_FAILURE);
}
if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
编解码器设置如下:
AVCodecID dasd = AV_CODEC_ID_H264;
codec = avcodec_find_encoder(dasd);
c = avcodec_alloc_context3(codec);
c->bit_rate = 400000;
c->width = 320;
c->height = 240;
c->time_base= (AVRational){1,25};
c->gop_size = 10;
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
av_opt_set(c->priv_data, "preset", "slow", 0);
avcodec_open2(c, codec, NULL);
因为我要无损,所以我不处理延迟帧(这是正确的假设吗?)
我可能实际上并没有进行无损编码,看来我可能不得不使用
之类的东西
AVDictionary *param;
av_dict_set(¶m, "qp", "0", 0);
然后打开...
所以我想我的问题是这些:
- 无损编码的正确编解码器参数是什么(如果 h264 在这方面是个糟糕的主意,请提出建议)。
- 无损时是否需要处理延迟帧?
- 为什么 VLC 生我的气?
谢谢。
- 实现无损:av_dict_set(¶m, "crf", "0", 0);
- 延迟帧(B-frames)与无损无关。如果你需要low-delay,那么就不要使用B-frames。
您的编码出现严重错误。这里的错误"MV errors in I frame"是奇数,I-frame中不应该有任何MV。似乎 header 解析 it-self 出错了。请分享 bit-stream 以及 VLC 失败的更多详细信息
您正在将原始 annexb 帧写入一个没有任何容器包装的文件。使用像 mp4 或 matroska 这样的容器,VLC 应该很高兴。
使用 ffmpeg h264(无损)encode/decode 视频的见解
所以我在编码部分做了一些工作,将 avi 编码为 264,但 VLC 无法播放,但 Totem 可以。 解码同一个文件证明很麻烦。 (我想要完全相同的 data/frame 进出),我得到这些 ;
saving frame 5
Video decoding
[h264 @ 0x1d19880] decode_slice_header error
frame :6
saving frame 6
Video decoding
[h264 @ 0x1d19880] error while decoding MB 15 7, bytestream -27
[h264 @ 0x1d19880] concealing 194 DC, 194 AC, 194 MV errors in I frame
frame :7
saving frame 7
Video decoding
[h264 @ 0x1d19880] decode_slice_header error
最后就是这个
[H264 Decoder @ 0x7f1320766040] frame :11
Broken frame packetizing
[h264 @ 0x1d19880] SPS changed in the middle of the frame
[h264 @ 0x1d19880] decode_slice_header error
[h264 @ 0x1d19880] no frame!
Error while decoding frame 11
游戏结束。
现在我怀疑我必须回到 1. 编码部分,VLC 无法播放它可能有充分的理由!
我是这样编码的
void encode(char *Y,char *U,char *V){
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
fflush(stdout);
frame->data[0] = (uint8_t*)Y;
frame->data[1] = (uint8_t*)U;
frame->data[2] = (uint8_t*)V;
frame->pts = ++i;
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit (EXIT_FAILURE);
}
if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
编解码器设置如下:
AVCodecID dasd = AV_CODEC_ID_H264;
codec = avcodec_find_encoder(dasd);
c = avcodec_alloc_context3(codec);
c->bit_rate = 400000;
c->width = 320;
c->height = 240;
c->time_base= (AVRational){1,25};
c->gop_size = 10;
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
av_opt_set(c->priv_data, "preset", "slow", 0);
avcodec_open2(c, codec, NULL);
因为我要无损,所以我不处理延迟帧(这是正确的假设吗?) 我可能实际上并没有进行无损编码,看来我可能不得不使用
之类的东西AVDictionary *param;
av_dict_set(¶m, "qp", "0", 0);
然后打开...
所以我想我的问题是这些:
- 无损编码的正确编解码器参数是什么(如果 h264 在这方面是个糟糕的主意,请提出建议)。
- 无损时是否需要处理延迟帧?
- 为什么 VLC 生我的气?
谢谢。
- 实现无损:av_dict_set(¶m, "crf", "0", 0);
- 延迟帧(B-frames)与无损无关。如果你需要low-delay,那么就不要使用B-frames。
您的编码出现严重错误。这里的错误"MV errors in I frame"是奇数,I-frame中不应该有任何MV。似乎 header 解析 it-self 出错了。请分享 bit-stream 以及 VLC 失败的更多详细信息
您正在将原始 annexb 帧写入一个没有任何容器包装的文件。使用像 mp4 或 matroska 这样的容器,VLC 应该很高兴。