C++ FFMPEG错误:必须选择一种定标器算法
我目前正在从事一个FFMPEG项目。我正在尝试使用以下代码将RGB图像转换为YUV图像(我昨晚在互联网上找到):C++ FFMPEG错误:必须选择一种定标器算法,c++,ffmpeg,rgb,yuv,C++,Ffmpeg,Rgb,Yuv,我目前正在从事一个FFMPEG项目。我正在尝试使用以下代码将RGB图像转换为YUV图像(我昨晚在互联网上找到): void Decode::video\u encode\u示例(const char*filename,int codec\u id) { AVCodec*编解码器; AVCodecContext*c=NULL; int i,ret,x,y,got_输出; 文件*f; AVFrame*frame; AVPacket-pkt; uint8_t endcode[]={0,0,1,0xb7
void Decode::video\u encode\u示例(const char*filename,int codec\u id)
{
AVCodec*编解码器;
AVCodecContext*c=NULL;
int i,ret,x,y,got_输出;
文件*f;
AVFrame*frame;
AVPacket-pkt;
uint8_t endcode[]={0,0,1,0xb7};
printf(“编码视频文件%s\n”,文件名);
/*查找mpeg1视频编码器*/
codec=avcodec\u find\u编码器((枚举AVCodecID)codec\u id);
如果(!编解码器){
fprintf(stderr,“找不到编解码器”);
出口(1);
}
c=avcodec\u alloc\u context3(编解码器);
如果(!c){
fprintf(stderr,“无法分配视频编解码器上下文\n”);
出口(2);
}
/*输入样本参数*/
c->比特率=400000;
/*分辨率必须是2的倍数*/
c->宽度=352;
c->高度=288;
/*每秒帧数*/
c->time_base=(AVRational){1,25};
/*每十帧发射一帧内图像
*在通过机架前检查机架图片类型
*对于编码器,如果帧->图片类型是AV图片类型
*然后忽略gop_大小,编码器输出
*无论gop_的大小,都将始终是I帧
*/
c->gop_尺寸=10;
c->max_b_frames=1;
c->pix_fmt=AV_pix_fmt_YUV420P;
if(编解码器id==AV编解码器id\U H264)
av_opt_set(c->priv_数据,“预设”,“慢速”,0);
/*打开它*/
if(avcodec_open2(c,codec,NULL)<0){
fprintf(stderr,“无法打开编解码器”\n);
出口(3);
}
f=fopen(文件名,“wb”);
如果(!f){
fprintf(stderr,“无法打开%s\n”,文件名);
出口(4);
}
frame=avcodec_alloc_frame();//Dans une版本加上récente c'est av_frame_alloc
如果(!帧){
fprintf(stderr,“无法分配视频帧”\n);
出口(5);
}
帧->格式=c->pix\U fmt;
框架->宽度=c->宽度;
框架->高度=c->高度;
/*可以通过任何方式分配映像,并且av_image_alloc()是
*如果要使用av_malloc(),这是最方便的方法*/
ret=av\u image\u alloc(帧->数据,帧->线条尺寸,c->宽度,c->高度,
c->pix_fmt,32);
如果(ret<0){
fprintf(stderr,“无法分配原始图片缓冲区\n”);
出口(6);
}
//
//RGB至YUV:
// http://stackoverflow.com/questions/16667687/how-to-convert-rgb-from-yuv420p-for-ffmpeg-encoder
//
//创建一些虚拟RGB“帧”
uint8_t*rgba32Data=新的uint8_t[4*c->width*c->height];
SwsContext*ctx=sws_getContext(c->width,c->height,
AV_PIX_FMT_RGBA,c->宽度,c->高度,
AV_PIX_FMT_YUV420P,0,0,0);
/*编码1秒的视频*/
对于(i=0;i<25;i++){
av_初始_数据包(&pkt);
pkt.data=NULL;//数据包数据将由编码器分配
pkt.size=0;
fflush(stdout);
/*准备一个虚拟图像*/
/*Y*/
//对于(y=0;yheight;y++){
//对于(x=0;xwidth;x++){
//帧->数据[0][y*帧->线宽[0]+x]=x+y+i*3;
// }
// }
//
///*Cb和Cr*/
//对于(y=0;yheight/2;y++){
//对于(x=0;xwidth/2;x++){
//帧->数据[1][y*帧->线宽[1]+x]=128+y+i*2;
//帧->数据[2][y*帧->线宽[2]+x]=64+x+i*5;
// }
// }
uint8_t*pos=rgba32数据;
对于(y=0;yheight;y++)
{
对于(x=0;xwidth;x++)
{
pos[0]=i/(浮动)25*255;
pos[1]=0;
位置[2]=x/(浮动)(c->宽度)*255;
pos[3]=255;
pos+=4;
}
}
uint8_t*inData[1]={rgba32Data};//RGBA32有一个平面
//
//注意:在更一般的设置中,输入图像的行可能会
//可以填充;也就是说,每行的字节不能是4*宽。
//在这种情况下,应将inLineSize设置为填充宽度。
//
int inLinesize[1]={4*c->width};//RGBA步幅
sws_比例(ctx、inData、inLinesize、0、c->高度、帧->数据、帧->线宽);
帧->pts=i;
/*对图像进行编码*/
ret=avcodec_encode_video2(c、pkt、帧和got_输出);
如果(ret<0){
fprintf(stderr,“错误编码帧”);
出口(7);
}
如果(得到输出){
printf(“写入帧%3d(大小=%5d)\n”,i,pkt.size);
fwrite(包装数据,1,包装尺寸,f);
av_免费_数据包(&pkt);
}
}
/*获取延迟帧*/
for(got_output=1;got_output;i++){
fflush(stdout);
ret=avcodec_encode_video2(c,&pkt,NULL,&got_输出);
如果(ret<0){
fprintf(stderr,“错误编码帧”);
出口(8);
}
如果(得到输出){
printf(“写入帧%3d(大小=%5d)\n”,i,pkt.size);
fwrite(包装数据,1,包装尺寸,f);
av_免费_数据包(&pkt);
}
}
/*添加序列结束代码以获得真正的mpeg文件*/
fwrite(endcode,1,sizeof(endcode),f);
fclose(f);
avcodec_close(c);
无AVU(c);
av_freep(&frame->data[0]);
avcodec_free_frame(&frame);//Dans une版本加上récente c'est av_frame_alloc
printf(“\n”);
}
int main()
{
解码;
avcodec_寄存器_all();
d、 视频编码示例(“/home/Dave/Desktop/test.mpg”,AV编解码器ID\U MPEG2VIDEO);
}
当我运行这个应用程序时,我的Linux术语
void Decode::video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
FILE *f;
AVFrame *frame;
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((enum 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(2);
}
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base = (AVRational){1,25};
/* 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(3);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(4);
}
frame = avcodec_alloc_frame();// Dans une version plus récente c'est av_frame_alloc
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(5);
}
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 */
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
c->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "Could not allocate raw picture buffer\n");
exit(6);
}
//
// RGB to YUV:
// http://stackoverflow.com/questions/16667687/how-to-convert-rgb-from-yuv420p-for-ffmpeg-encoder
//
// Create some dummy RGB "frame"
uint8_t *rgba32Data = new uint8_t[4*c->width*c->height];
SwsContext * ctx = sws_getContext(c->width, c->height,
AV_PIX_FMT_RGBA, c->width, c->height,
AV_PIX_FMT_YUV420P, 0, 0, 0, 0);
/* 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;
// }
// }
uint8_t *pos = rgba32Data;
for (y = 0; y < c->height; y++)
{
for (x = 0; x < c->width; x++)
{
pos[0] = i / (float)25 * 255;
pos[1] = 0;
pos[2] = x / (float)(c->width) * 255;
pos[3] = 255;
pos += 4;
}
}
uint8_t * inData[1] = { rgba32Data }; // RGBA32 have one plane
//
// NOTE: In a more general setting, the rows of your input image may
// be padded; that is, the bytes per row may not be 4 * width.
// In such cases, inLineSize should be set to that padded width.
//
int inLinesize[1] = { 4*c->width }; // RGBA stride
sws_scale(ctx, inData, inLinesize, 0, c->height, frame->data, frame->linesize);
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(7);
}
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(8);
}
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]);
avcodec_free_frame(&frame);// Dans une version plus récente c'est av_frame_alloc
printf("\n");
}
int main()
{
Decode d;
avcodec_register_all();
d.video_encode_example("/home/Dave/Desktop/test.mpg",AV_CODEC_ID_MPEG2VIDEO);
}
SwsContext * ctx = sws_getContext(c->width, c->height,
AV_PIX_FMT_RGBA, c->width, c->height,
AV_PIX_FMT_YUV420P, 0, 0, 0, 0);