C++ FFMPEG错误:必须选择一种定标器算法

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

我目前正在从事一个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};
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);