代码之家  ›  专栏  ›  技术社区  ›  Michel Feinstein

正确使用avcode_encode_video2()刷新

  •  4
  • Michel Feinstein  · 技术社区  · 8 年前

    我有一个相机将图片发送到回调函数,我想用这些图片制作一部电影 FFmpeg 。我已遵循 decoding_encoding 实例 here 但不确定如何使用 got_output 用于刷新编码器并获得延迟帧。

    1. 当我的相机的图片到达时,我是否应该对它们进行编码,然后当我想停止拍摄并关闭视频时,我会进行冲洗循环?

    1. 我是否应该定期刷新,比如说,每收到100张图片?

    我的视频捕获程序可能会运行几个小时,所以我担心这些延迟的帧在内存消耗中是如何工作的,如果它们堆积在那里直到刷新,这可能会占用我所有的内存。


    这是示例执行的编码,它使25个虚拟 Frames 一秒钟的视频,最后,它循环播放 avcodec_encode_video2() 寻找 获取输出(_O) 对于延迟帧:

    /////  Prepare the Frame, CodecContext and some aditional logic.....
    
    /* encode 1 second of video */
    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);
        /* prepare a dummy image */
        /* Y */
        for (y = 0; y < c->height; y++) {
            for (x = 0; x < c->width; x++) {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
            }
        }
        /* Cb and Cr */
        for (y = 0; y < c->height/2; y++) {
            for (x = 0; x < c->width/2; x++) {
                frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
                frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
            }
        }
        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);
        }
    }
    
    /////  Closes the file and finishes.....
    
    1 回复  |  直到 8 年前
        1
  •  4
  •   Ronald S. Bultje    8 年前

    延迟是固定的,因此编码器延迟永远不会超过 delay 帧。因此,内存消耗不会随着记录长度的增加而增加,因此没有问题,导致正确答案1:只在编码结束时刷新。