首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ffmpeg编码原始nv12帧

使用ffmpeg编码原始nv12帧
EN

Stack Overflow用户
提问于 2012-07-31 15:41:06
回答 1查看 2.2K关注 0票数 1

我正在尝试以nv12格式编码原始帧。帧速率是15。我正在使用avcodec进行编码。我的捕获设备有一个回调函数,该函数在原始取景器帧可用时激活。我正在复制原始取景器帧,并从数据中制作AVFrame。然后,我将框架提供给avcodec_encode_video,如api示例中所述,但不知何故,我没有得到预期的结果。我使用的是posix线程。我将原始帧保存在缓冲区中。然后我的编码器线程从缓冲区中收集数据并对其进行编码。编码速度太慢(h264和mpeg1 -tested)。是我的线程有问题还是别的什么问题?我不知所措。输出结果令人费解。整个编码过程是一个单一的函数和单线程,但我发现一次编码了一堆帧。编码器到底是如何工作的呢?下面是编码的代码片段:

代码语言:javascript
复制
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;
            }
        }

*/

代码语言:javascript
复制
        for(y=0;y<c->height;y++) {
                    for(x=0;x<c->width;x++) {
                        picture->data[0][y * picture->linesize[0] + x] = x + y + i * 7;
                    }
                }

                /* Cb and Cr */
                for(y=0;y<c->height/2;y++) {
                    for(x=0;x<c->width/2;x++) {
                        picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                        picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
                    }
                }
        free(buf_source);
        fprintf(stderr,"Data ready\n");

        outbuf_size = 100000 + c->width*c->height*3/2;
        outbuf = (uint8_t*)malloc(outbuf_size);
        fprintf(stderr,"Preparation done!!!\n");
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
        had_output |= out_size;
        printf("encoding frame %3d (size=%5d)\n", i, out_size);
        fwrite(outbuf, 1, out_size, f);
        av_free(picture->data[0]);
        av_free(picture);

    }
    pthread_mutex_unlock(&lock_encoder);
}
EN

回答 1

Stack Overflow用户

发布于 2012-08-04 03:48:21

您可以在libswscale中使用sws_scale进行色彩空间转换。首先,创建一个SwsContext,使用sws_getContext指定源(NV12)和目标(YUV420P)。

代码语言:javascript
复制
m_pSwsCtx = sws_getContext(picture_width, 
               picture_height, 
               PIX_FMT_NV12, 
               picture_width, 
               picture_height,
               PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);

然后当你想对每一帧进行转换时,

代码语言:javascript
复制
sws_scale(m_pSwsCtx, frameData, frameLineSize, 0, frameHeight,
    outFrameData, outFrameLineSize);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11735399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档