Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于ffmpeg的平面RGB图像无损视频合成_C++_Image_Video_Ffmpeg_Video Encoding - Fatal编程技术网

C++ 基于ffmpeg的平面RGB图像无损视频合成

C++ 基于ffmpeg的平面RGB图像无损视频合成,c++,image,video,ffmpeg,video-encoding,C++,Image,Video,Ffmpeg,Video Encoding,我的记忆中已经有一系列的图像。图像为RGB,但为平面图像,即非交错图像。我希望使用ffmpeg无损地将这些压缩到视频中 目前我有以下问题(注意:我排除了错误检查和清理): av_register_all(); AVCodec*codec=AVCodec按名称查找编码器(“libx264rgb”); AVCodecContext*context=avcodec\u alloc\u context3(编解码器); 上下文->宽度=宽度; 上下文->高度=填充高度//高度填充为8的倍数 context

我的记忆中已经有一系列的图像。图像为RGB,但为平面图像,即非交错图像。我希望使用ffmpeg无损地将这些压缩到视频中

目前我有以下问题(注意:我排除了错误检查和清理):

av_register_all();
AVCodec*codec=AVCodec按名称查找编码器(“libx264rgb”);
AVCodecContext*context=avcodec\u alloc\u context3(编解码器);
上下文->宽度=宽度;
上下文->高度=填充高度//高度填充为8的倍数
context->time_base=AVRational{1,25};
上下文->gop_大小=10;
context->max_b_frames=1;
上下文->pix_fmt=AV_pix_fmt_RGB24;
av_opt_set(上下文->私有数据,“预设”,“超快”,0);
av_opt_集(上下文->私有数据,“crf”,0,0)//无损
avcodec_open2(上下文,编解码器,空);
AVFrame*AVFrame=av_frame_alloc();
for(int i=0;idata[i]=NULL;
}
avFrame->data[0]=新单元8_t[宽度*填充高度];
avFrame->data[1]=新单元8_t[宽度*填充高度];
avFrame->data[2]=新单元8_t[宽度*填充高度];
AVFormatContext*输出上下文;
avformat_alloc_output_context2(&outputContext,NULL,NULL,“filename.webm”);
AVStream*outputStream=avformat\U new\U stream(输出上下文,编解码器);
outputStream->codepar->width=width;
outputStream->codepar->height=填充高度;
输出流->编解码器->格式=AV\U PIX\U FMT\U GBRP;
outputStream->time_base=AVRational{1,25};
outputContext->video\u codec=编解码器;
avio_open2(&outputContext->pb,“filepath\filename.webm”,avio_标志_WRITE,NULL,NULL)//显然,正在使用一个真正的文件路径
avformat_write_头(outputContext,NULL);
uint8_t*R,G,B;
while(GetNextImageChannels&R&G&B)){
memcpy(R,avFrame->data[0],宽度*高度*大小(uint8_t));
memcpy(G,avFrame->data[1],宽度*高度*大小(uint8_t));
memcpy(B,avFrame->data[2],宽度*高度*大小(uint8_t));
avcodec_发送_帧(上下文,avFrame);
AVPacket-encodedPacket;
avcodec_接收_数据包(上下文和编码包);
av交织写入帧(outputContext和EncodedPack);
}
av_写入_预告片(outputContext);
这在
avformat\u write\u header
中失败,给了我一个错误代码-22,我认为这意味着某种类型的无效参数

我尝试过使用
filename.mkv
,但在
avformat\u alloc\u output\u context2时失败,错误代码为-22

我尝试过使用
AV\u PIX\u FMT\u GBRP
格式,但在
avcodec\u open2
中失败,错误代码为-22

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

如果你能帮我解决我的问题吗?


编辑:修复了数组索引中的一个键入错误。终于有时间安装和构建它了。 现在我们开始:

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;
    }

哦,天哪,是的,那是个打字错误。但是我刚把它修好,得到的结果和以前完全一样(两种格式都试过了)。填充呢?我刚试过,填充到8、16和32,高度和宽度都是。不幸的是,它没有工作。压缩RGB呢?记住,它在到达循环之前就出错了。我相信这与我设置整件事情的方式有关,比如我可能错过了一些设置,或者我没有将两个结构正确地连接在一起。为了确认这不是数据缓冲区的数量,我尝试了这个方法,但没有成功
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;
    }
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);