Кодирование с помощью ffmpeg: качество видео падает

Я пытаюсь закодировать набор картинок в видео с помощью 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;
}

Какие-нибудь советы? Большое спасибо!

1

Решение

400kb MPEG 1? Да, качество будет ужасным. Используйте более высокий битрейт или лучший кодек.

3

Другие решения


По вопросам рекламы [email protected]