用ffmpeg编码原始nv12帧

用ffmpeg编码原始nv12帧,ffmpeg,Ffmpeg,我正在尝试用nv12格式对原始帧进行编码。帧速率是15。我正在使用avcodec进行编码。我的拍摄设备有一个回调函数,当原始取景器框架可用时,该函数被激活。我正在复制原始取景器帧,并根据数据制作AVFrame。然后,我将帧提供给avcodec_encode_视频,如api示例中所述,但不知何故,我没有得到预期的结果。我正在使用posix线程。我将原始帧保存在缓冲区上。然后,我的编码器线程从缓冲区收集数据并对其进行编码。编码速度太慢(h264和mpeg1测试)。是我的线程问题还是其他问题?我不知所

我正在尝试用nv12格式对原始帧进行编码。帧速率是15。我正在使用avcodec进行编码。我的拍摄设备有一个回调函数,当原始取景器框架可用时,该函数被激活。我正在复制原始取景器帧,并根据数据制作AVFrame。然后,我将帧提供给avcodec_encode_视频,如api示例中所述,但不知何故,我没有得到预期的结果。我正在使用posix线程。我将原始帧保存在缓冲区上。然后,我的编码器线程从缓冲区收集数据并对其进行编码。编码速度太慢(h264和mpeg1测试)。是我的线程问题还是其他问题?我不知所措。输出是神秘的。整个编码过程是一个单一的函数和单线程,但我发现一次编码了一堆帧。编码器究竟是如何工作的?以下是用于编码的代码段:

while(cameraRunning)
{
    pthread_mutex_lock(&lock_encoder);
    if(vr->buffer->getTotalData()>0)
    {
        i++;
        fprintf(stderr,"Encoding %d\n",i);
        AVFrame *picture;
        int y = 0,x;
        picture = avcodec_alloc_frame();
        av_image_alloc(picture->data, picture->linesize,c->width, c->height,c->pix_fmt, 1);
        uint8_t* buf_source = new uint8_t[vr->width*vr->height*3/2];
        uint8_t* data = vr->buffer->Read(vr->width*vr->height*3/2);
        memcpy(buf_source,data,vr->width*vr->height*3/2);
        //free(&vr->buffer->Buffer[vr->buffer->getRead()-1][0]);
        /*for (y = 0; y < vr->height*vr->width; y++)
        {
            picture->data[0][(y/vr->width) * picture->linesize[0] + (y%vr->width)] = buf_source[(y/vr->width)+(y%vr->width)]x + y + i * 7;
            if(y<vr->height*vr->width/4)
            {
                picture->data[1][(y/vr->width) * picture->linesize[1] + (y%vr->width)] = buf_source[vr->width*vr->height + 2 * ((y/vr->width)+(y%vr->width))]128 + y + i * 2;
                picture->data[2][(y/vr->width) * picture->linesize[2] + (y%vr->width)] = buf_source[vr->width*vr->height +  2 * ((y/vr->width)+(y%vr->width)) + 1]64 + x + i * 5;
            }
        }
while(摄影机运行)
{
pthread_mutex_lock(&lock_编码器);
如果(vr->buffer->getTotalData()>0)
{
i++;
fprintf(stderr,“编码%d\n”,i);
AVFrame*图片;
int y=0,x;
picture=avcodec_alloc_frame();
av_image_alloc(图片->数据,图片->线条尺寸,c->宽度,c->高度,c->pix_fmt,1);
uint8_t*buf_source=新的uint8_t[vr->width*vr->height*3/2];
uint8_t*data=vr->buffer->Read(vr->width*vr->height*3/2);
memcpy(buf_源,数据,vr->width*vr->height*3/2);
//空闲(&vr->buffer->buffer[vr->buffer->getRead()-1][0]);
/*对于(y=0;y高度*vr->宽度;y++)
{
图片->数据[0][(y/vr->宽度)*图片->线宽[0]+(y%vr->宽度)]=buf_源[(y/vr->宽度)+(y%vr->宽度)]x+y+i*7;
如果(Y高*vr->宽度/4)
{
图片->数据[1][(y/vr->宽度)*图片->线宽[1]+(y%vr->宽度)]=buf_源[vr->宽度*vr->高度+2*((y/vr->宽度)+(y%vr->宽度))]128+y+i*2;
图片->数据[2][(y/vr->宽度)*图片->线条尺寸[2]+(y%vr->宽度)]=buf_源[vr->宽度*vr->高度+2*((y/vr->宽度)+(y%vr->宽度))+1]64+x+i*5;
}
}
*/

(y=0;yheight;y++)的
{
对于(x=0;xwidth;x++){
图片->数据[0][y*图片->线宽[0]+x]=x+y+i*7;
}
}
/*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;
}
}
免费(buf_来源);
fprintf(stderr,“数据就绪\n”);
突出尺寸=100000+c->宽度*c->高度*3/2;
EXBUFF=(uint8_t*)malloc(EXBUF_尺寸);
fprintf(标准“准备完成!!!\n”);
out_size=avcodec_encode_视频(c、EXBUF、EXBUF_size、图片);
had|u输出|=输出尺寸;
printf(“编码帧%3d(大小=%5d)\n”,i,out\u大小);
fwrite(f,1,out_size,f);
无AVU(图片->数据[0]);
av_免费(图片);
}
pthread_mutex_unlock(&lock_编码器);
}

您可以使用libswscale中的sws\u scale进行颜色空间转换。首先创建一个SwsContext,使用sws_getContext指定源(NV12)和目标(YUV420P)

m_pSwsCtx = sws_getContext(picture_width, 
               picture_height, 
               PIX_FMT_NV12, 
               picture_width, 
               picture_height,
               PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
然后当你想对每一帧进行转换时

sws_scale(m_pSwsCtx, frameData, frameLineSize, 0, frameHeight,
    outFrameData, outFrameLineSize);

编码器可能会在输出帧之前缓冲帧…我假设颜色通过了,好吗?
sws_scale(m_pSwsCtx, frameData, frameLineSize, 0, frameHeight,
    outFrameData, outFrameLineSize);