【问题标题】:C++ h264 ffmpeg/libav encode/decode(lossless) issuesC++ h264 ffmpeg/libav 编码/解码(无损)问题
【发布时间】:2016-11-10 09:05:28
【问题描述】:

使用 ffmpeg h264(无损)编码/解码视频的见解

所以我在编码部分做了一些工作,用 264 编码一个 avi,但是 VLC 不会播放它,但是 Totem 会。 解码同一个文件很麻烦。 (我希望输入与输出完全相同的数据/帧),我得到了这些;

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(&param, "qp", "0", 0);

然后打开...

所以我想我的问题是这些:

  • 无损编码的正确编解码器参数是什么(如果 h264 在这方面是一个糟糕的想法,请提供建议)。
  • 在追求无损时是否需要处理延迟帧?
  • 为什么 VLC 生我的气?

谢谢。

【问题讨论】:

    标签: c++ ffmpeg h.264 libav


    【解决方案1】:
    1. 实现无损:av_dict_set(&param, "crf", "0", 0);
    2. 延迟帧(B 帧)与无损无关。如果您需要低延迟,请不要使用 B 帧。

    您的编码中有严重错误。错误“I 帧中的 MV 错误”在这里很奇怪,I 帧中不应该有任何 MV。似乎解析自身的标头出错了。请分享 VLC 故障的比特流和更多详细信息

    【讨论】:

    • 谢谢,我会的。当我回到家时,我正在使用一台笔记本电脑,我以为它天生就内置了网络摄像头……我错了。
    • qp 0 更适合 10 位。
    【解决方案2】:

    您正在将原始附件b 帧写入文件而没有任何容器包装。使用像 mp4 或 matroska 这样的容器,VLC 应该会很高兴。

    【讨论】:

      猜你喜欢
      • 2012-05-11
      • 2011-10-05
      • 2015-12-30
      • 2011-11-24
      • 2011-08-24
      • 2015-06-07
      • 2014-02-24
      • 2013-11-24
      • 2015-08-11
      相关资源
      最近更新 更多