使用ffmpeg将平面RGB图像组合成无损视频

时间:2017-03-22 22:59:20

标签: c++ image video ffmpeg video-encoding

我的内存中已有一系列图像。图像是RGB,但是是平面的,即非交错的。我希望使用ffmpeg将这些无损压缩成视频。

目前我有这个(注意:我已经排除了错误检查和清理):

integer

目前在av_register_all(); AVCodec* codec = avcodec_find_encoder_by_name("libx264rgb"); AVCodecContext* context = avcodec_alloc_context3(codec); context->width = width; context->height = paddedHeight;//height padded to a multiple of 8 context->time_base = AVRational { 1,25 }; context->gop_size = 10; context->max_b_frames = 1; context->pix_fmt = AV_PIX_FMT_RGB24; av_opt_set(context->priv_data, "preset", "ultrafast", 0); av_opt_set(context->priv_data, "crf", 0, 0);//lossless avcodec_open2(context, codec, NULL); AVFrame* avFrame = av_frame_alloc(); for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) { avFrame->data[i] = NULL; } avFrame->data[0] = new uint8_t[width*paddedHeight]; avFrame->data[1] = new uint8_t[width*paddedHeight]; avFrame->data[2] = new uint8_t[width*paddedHeight]; AVFormatContext* outputContext; avformat_alloc_output_context2(&outputContext, NULL, NULL, "filename.webm"); AVStream* outputStream = avformat_new_stream(outputContext, codec); outputStream->codecpar->width = width; outputStream->codecpar->height = paddedHeight; outputStream->codecpar->format = AV_PIX_FMT_GBRP; outputStream->time_base = AVRational { 1,25 }; outputContext->video_codec = codec; avio_open2(&outputContext->pb, "filepath\filename.webm", AVIO_FLAG_WRITE, NULL, NULL);//obviously a real filepath is being used avformat_write_header(outputContext, NULL); uint8_t* R, G, B; while(GetNextImageChannels(&R, &G, &B)){ memcpy(R, avFrame->data[0], width * height * sizeof(uint8_t)); memcpy(G, avFrame->data[1], width * height * sizeof(uint8_t)); memcpy(B, avFrame->data[2], width * height * sizeof(uint8_t)); avcodec_send_frame(context, avFrame); AVPacket encodedPacket; avcodec_receive_packet(context, &encodedPacket); av_interleaved_write_frame(outputContext, &encodedPacket); } av_write_trailer(outputContext); 失败了,给我一个错误代码-22,我相信这意味着某种无效的参数?

我已尝试使用avformat_write_header,但在filename.mkv失败,错误代码为-22

我已尝试使用avformat_alloc_output_context2格式,但在AV_PIX_FMT_GBRP失败但错误代码为-22。

我在ffmpeg上找到了各种资源,但大多数都在使用命令行应用程序。少数不是非常通用的,并且大部分过时(使用已弃用的函数),并且通常从一种视频格式转换为另一种视频格式,并且它们都不处理平面图像。

如果你能帮助我解决我的错误?

编辑:修复了数组索引中的拼写错误

1 个答案:

答案 0 :(得分:0)

终于有时间安装&amp;建立它。 所以我们走了:

1)激活调试日志记录。这非常有用。

av_log_set_level(AV_LOG_DEBUG);

你是否致电注册?

avcodec_register_all();
av_register_all();

2)看起来您要使用的编解码器不支持平面RGB格式 对我来说,AV_PIX_FMT_GBRP错误地带有“无效参数”错误 您需要指定一些打包的RGB格式(AV_PIX_FMT_RGB24会这样做),并将单独的颜色通道转换为单个数组。

avFrame->data[0] = new uint8_t[3*width*paddedHeight];
. . .
uint8_t* R, G, B;
uint8_t* row = avFrame->data[0];
while(GetNextImageChannels(&R, &G, &B)){
    for(int iy=0; iy<height; ++iy){
        for(int ix=0; ix<width; ++ix){
            row[3*ix+0] = R[ix];
            row[3*ix+1] = G[ix];
            row[3*ix+2] = B[ix];
        }
        R += width;
        G += width;
        B += width;
        row += 3*width;
    }

3)WebM不支持h264。所以它又回到了mkv 您需要创建视频流:

AVFormatContext* outputContext;
avformat_alloc_output_context2(&outputContext, NULL, "h264", "filename.mkv");
AVStream* video_stream = avformat_new_stream(outputContext, codec);
video_stream->codec = c;
avio_open(&outputContext->pb, "filename.mkv", AVIO_FLAG_WRITE);
avformat_write_header(outputContext, NULL);