2014-03-24 2 views
1

FFmpeg 라이브러리를 사용하여 언젠가 RGB-> YUV420 변환 작업을하고 있습니다. 이미 sws_scale 기능을 사용해 보았지만 제대로 작동하지 않습니다. 이제, 저는 각 픽셀을 색 공간 변환 공식을 사용하여 개별적으로 변환하기로 결정했습니다. 내가 RGB-> YUV420 또는 그 반대로 변환하는 online을 읽을개별 픽셀 값을 RGB에서 YUV420으로 변환하고 프레임을 저장하십시오. - C++

// Read frames and save first five frames to disk 
    i=0; 
    while((av_read_frame(pFormatCtx, &packet)>=0) && (i<5)) 
    { 
     // Is this a packet from the video stream? 
     if(packet.stream_index==videoStreamIdx) 
     { 
      /// Decode video frame    
      avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 

      // Did we get a video frame? 
      if(frameFinished) 
      { 
       i++; 
       sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, 
          pFrame->linesize, 0, pCodecCtx->height, 
          pFrameRGB->data, pFrameRGB->linesize); 

       int x, y, R, G, B; 
       uint8_t *p = pFrameRGB->data[0]; 
       for(y = 0; y < h; y++) 
       { 
        for(x = 0; x < w; x++) 
        { 
         R = *p++; 
         G = *p++; 
         B = *p++; 
         printf(" %d-%d-%d ",R,G,B); 
        } 
       } 

       SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); 
      } 
     } 

     // Free the packet that was allocated by av_read_frame 
     av_free_packet(&packet); 
    } 

, 하나 : 그래서, 다음 날 몇 프레임을 얻고 나 각 픽셀의 개별 R, G, B 값에 액세스 할 수 있습니다 코드입니다 먼저 YUV444 형식으로 변환해야합니다. 그래서, 그것의 유사 : RGB-> YUV444-> YUV420. 이 C++에서 어떻게 구현합니까?

또한 여기에 사용 된 SaveFrame() 기능이 있습니다. 나는 YUV420이 데이터를 다르게 저장하기 때문에 조금 바뀌어야한다고 생각합니다. 그것을 돌보는 방법?

void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) 
{ 
    FILE *pFile; 
    char szFilename[32]; 
    int y; 

    // Open file 
    sprintf(szFilename, "frame%d.ppm", iFrame); 
    pFile=fopen(szFilename, "wb"); 
    if(pFile==NULL) 
     return; 

    // Write header 
    fprintf(pFile, "P6\n%d %d\n255\n", width, height); 

    // Write pixel data 
    for(y=0; y<height; y++) 
     fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile); 

    // Close file 
    fclose(pFile); 
} 

누군가 제안 하시겠습니까? 많은 감사합니다 !!! Windows에서

+0

왜 바퀴를 다시 발명합니까? ffmpeg 기능에 대한 귀하의 문제는 무엇입니까? 일해야하기 때문에! – alexbuisson

+0

@alexbuisson 나는 그것을 시도했다. 그러나 그것은 색과 스케일 정보를 잃어 버렸다. 여기 있습니다 : http://stackoverflow.com/questions/21938674/ffmpeg-rgb-to-yuv-conversion-loses-color-and-scale 누군가가 해결책을 제안했지만 발생한 문제를 해결할 수 없습니다. – learner

+0

비행기를 YUV444로 수동으로 변환하더라도 YUV420을 달성하기 위해 U/V 평면의 해상도를 줄이기 위해 어떤 것을 사용할 예정입니까? 그 직업을위한 최고의 도구는 ... 당신은 그것을 추측 sws_scale! 귀하의 RGB/YUV444 구현 또한 훨씬 느려질 것입니다. sws_scale을 사용하는 법을 배워야합니다. 당신은 기본적으로이 시점에서 stackoverflow를 스팸하고 있습니다. – szatmary

답변

0
void SaveFrameYUV420P(AVFrame *pFrame, int width, int height, int iFrame) 
{ 
    FILE *pFile; 
    char szFilename[32]; 
    int y; 

    // Open file 
    sprintf(szFilename, "frame%d.yuv", iFrame); 
    pFile=fopen(szFilename, "wb"); 
    if(pFile==NULL) 
     return; 

    // Write pixel data 
    fwrite(pFrame->data[0], 1, width*height, pFile); 
    fwrite(pFrame->data[1], 1, width*height/4, pFile); 
    fwrite(pFrame->data[2], 1, width*height/4, pFile); 

    // Close file 
    fclose(pFile); 
} 

,이 방법으로 저장된 프레임을 볼 수 irfanview를 사용할 수 있습니다. 프레임을 RAW, 24bpp 형식으로 열고 폭과 높이를 제공하고 "yuv420"상자를 선택하십시오.