繁体   English   中英

使用ffmpeg进行编码:视频质量下降

[英]Encoding with ffmpeg: video quality drops

我正在尝试使用ffmpeg将一组图片编码为视频。 我是新手,但我设法让它发挥作用。 我只有一个问题:第一或第二视频看起来不错,但随着时间的推移,视频质量不断下降。 最后(这是一段约16秒的视频),质量非常差,我无法理解为什么。

我正在使用AV_CODEC_ID_MPEG1VIDEO作为视频编解码器(坦率地说,它是我唯一可以工作的),这是我的代码示例:

c = avcodec_alloc_context3(codec);
if (!c) {
    fprintf(stderr, "Could not allocate video codec context\n");
    exit(1);
}

c->bit_rate = 400000;
c->width = width;
c->height = height;
struct AVRational time_base = {1, 25};
c->time_base = time_base;
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;

if (codec_id == AV_CODEC_ID_H264)
    av_opt_set(c->priv_data, "preset", "slow", 0);

// Open the codec
if (avcodec_open2(c, codec, NULL) < 0) {
    fprintf(stderr, "Could not open codec\n");
    exit(1);
}

fopen_s(&f, filename, "wb");
if (!f) {
    fprintf(stderr, "Could not open %s\n", filename);
    exit(1);
}

frame = av_frame_alloc();
if (!frame) {
    fprintf(stderr, "Could not allocate video frame\n");
    exit(1);
}
frame->format = c->pix_fmt;
frame->width  = c->width;
frame->height = c->height;

ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
                     c->pix_fmt, 32);
if (ret < 0) {
    fprintf(stderr, "Could not allocate raw picture buffer\n");
    exit(1);
}

struct SwsContext *frameConvertContext = sws_getContext(width, height,
      PIX_FMT_RGB24,
      c->width, c->height,
      c->pix_fmt,
      SWS_LANCZOS | SWS_ACCURATE_RND, NULL, NULL, NULL);

for (i = 0; i < framesNr; i++) {
    // Read an image
    std::stringstream filename;
    filename << "input/image-" << (i+1) << ".jpg";
    Image* img;
    img = Image::fromJpeg((char*) filename.str().c_str());
    int srcSliceY[1] = { img->getWidth() * 3 };
    const uint8_t* imgbuf[1] = { (uint8_t*) img->getData(sizeof(uint8_t)) };

    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;

    fflush(stdout);
    frameConvertContext = sws_getCachedContext(frameConvertContext, width, height,
      PIX_FMT_RGB24,
      c->width, c->height,
      c->pix_fmt,
      SWS_LANCZOS | SWS_ACCURATE_RND, NULL, NULL, NULL);

    sws_scale(frameConvertContext, imgbuf, srcSliceY, 0, img->getHeight(), frame->data, frame->linesize);

    frame->pts = i;

    /* encode the image */
    ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
    if (ret < 0) {
        fprintf(stderr, "Error encoding frame\n");
        exit(1);
    }

    if (got_output) {
        printf(".");
        fwrite(pkt.data, 1, pkt.size, f);
        av_free_packet(&pkt);
    }

    // Free the memory
    delete img;
}

有小费吗? 非常感谢!

400kb mpeg 1? 是的质量将是糟糕的。 使用更高的比特率或更好的编解码器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM