2012-07-31 111 views
1

我試圖編碼nv12格式的原始幀。幀率是15.我正在使用avcodec進行編碼。我的捕捉設備具有回調功能,當原始取景框可用時,該功能被激活。我正在複製原始取景器框架並根據數據製作AVFrame。然後我提供框架到api樣本中描述的avcodec_encode_video,但不知何故我沒有得到預期的結果。我正在使用posix線程。我將原始幀保存在緩衝區中。然後我的編碼器線程從緩衝區收集數據並對其進行編碼。編碼速度太慢(h264和mpeg1測試)。這是我的線程或其他問題嗎?我處於虧損狀態。輸出是神祕的。整個編碼過程是一個單一的函數和單線程,但我發現一次編碼一堆幀。 ?究竟怎樣的編碼器功能下面是代碼片段編碼:使用ffmpeg編碼原始nv12幀

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

*/

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

回答

0

您可以使用sws_scale在libswscale的色彩空間轉換。首先使用sws_getContext創建一個指定源(NV12)和目標(YUV420P)的SwsContext。

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