【问题标题】:Increase Duration of a video FFMPEG C++增加视频 FFMPEG C++ 的持续时间
【发布时间】:2015-06-14 14:54:58
【问题描述】:

我正在使用 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");`

【问题讨论】:

  • 现在我们知道您想要什么,但介意告诉我们问题出在哪里吗?
  • 这段代码运行良好我只想知道如何在 1 秒内增加当前 25 帧的视频持续时间。

标签: c ffmpeg video-encoding


【解决方案1】:

您正在尝试对 h264 视频进行编码,然后将编码数据按原样写入文件。我认为您要做的是编写一个附件b h264 文件。寻找使用 libavformat 写入文件,然后选择名为“h264”的文件(基本上是一个附件编写器)。有关多路复用的更多文档,请参阅此link

好的,现在你的问题是:1 fps。我不确定这是附件b中的有效值,但无论如何。在 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;

由于附件b 只是按原样采用编解码器参数,在这种特殊情况下,更改 AVCodecContext.time_base 将足以指示您所需的帧速率。但是,通常,容器将指定时间戳和帧速率,并且您希望在使用 libavformat 编写的 AVPacket 的 pts/dts 字段中设置适当的时间戳。换句话说,AVCodecContext.time_base 只适用于附件b,AVPacket.pts/dts in AV_TIME_BASE 单位对于像mp4 或mkv 这样的容器格式是必需的。

【讨论】:

    【解决方案2】:

    在这部分代码中

    /* frames per second */
    AVRational rational;
    rational.num = 1;
    rational.den = 25;
    c->time_base = rational;
    

    您将时基设置为 25FPS(每秒帧数),您只需将其更改为所需的 FPS。

    更多信息:AVCodecContext::time_base

    【讨论】:

      猜你喜欢
      • 2016-12-17
      • 2015-05-29
      • 2016-06-08
      • 2014-08-07
      • 1970-01-01
      • 2015-02-08
      • 2020-12-11
      • 2011-09-21
      • 1970-01-01
      相关资源
      最近更新 更多