gpt4 book ai didi

c - 增加视频 FFMPEG C++ 的持续时间

转载 作者:太空宇宙 更新时间:2023-11-04 03:39:52 26 4
gpt4 key购买 nike

我正在使用 FFmpeg 样本中的代码,将图片编码成视频。我想要做的就是给它一系列图片,它给了我一个视频,每张图片都需要一秒钟`下面的代码只是从我的文件系统中拍摄一张照片并从中创建视频

AVCodec *codec;
AVCodecContext *c = NULL;
int i, ret, x, y, got_output;
FILE *f;

AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };

printf("Encode video file %s\n", filename);

/* find the mpeg1 video encoder */
codec = avcodec_find_encoder((AVCodecID)codec_id);
if (!codec)
{
fprintf(stderr, "Codec not found\n");
exit(1);
}

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

/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 200;
c->height = 200;
/* frames per second */
AVRational rational;
rational.num = 1;
rational.den = 25;
c->time_base = rational;
/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
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 it */
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);
}
AVFrame *frame = OpenImage("..\\..\\..\\..\\..\\..\\1.jpg");
//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;
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */

int screenHeight = 200;
int screenWidth = 200;
for (i = 0; i < 25; i++)
{
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;

fflush(stdout);



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("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}

/* get the delayed frames */
for (got_output = 1; got_output; i++)
{
fflush(stdout);

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

if (got_output)
{
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}

/* add sequence end code to have a real mpeg file */
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);

avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
av_frame_free(&frame);
printf("\n");`

最佳答案

您正在尝试对 h264 视频进行编码,然后将编码后的数据按原样写入文件。我想你要做的是写一个 annexb h264 文件。寻找使用 libavformat 的写入文件,然后选择名为“h264”的文件(基本上是一个 annexb 写入器)。看这个link有关 muxing 的更多文档。

好的,现在你的问题是:1 fps。我不确定这在 annexb 中是否有效,但无论如何。参见ffmpeg的libavcodec/libx264.c中的如下代码:

x4->params.i_fps_num = avctx->time_base.den;
x4->params.i_fps_den = avctx->time_base.num * avctx->ticks_per_frame;

由于 annexb 只是按原样采用编解码器参数,在这种特殊情况下,更改 AVCodecContext.time_base 就足以表明您想要的帧速率。但是,通常情况下,容器会指定时间戳和帧率,并且您想在使用 libavformat 编写的 AVPacket 的 pts/dts 字段中设置适当的时间戳。也就是说,AVCodecContext.time_base只对annexb、AVPacket有效。 pts/dts 在 AV_TIME_BASE mp4 或 mkv 等容器格式需要单位。

关于c - 增加视频 FFMPEG C++ 的持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29535155/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com