2012-06-05 8 views
1

FFmpeg를 사용하는 비디오를 jni의 OpenGL ES 텍스처로 변환하려고합니다.하지만 얻은 모든 것은 검은 색 텍스처입니다. OpenGL을 glGetError()과 함께 출력했지만 오류는 없습니다.FFmpeg 프레임을 OpenGL ES 텍스처로 변환

여기 내 코드입니다 : 나는 자바 비트 맵 pFrameRGB 변경에 성공했다

void* pixels; 
int err; 
int i; 
int frameFinished = 0; 
AVPacket packet; 
static struct SwsContext *img_convert_ctx; 
static struct SwsContext *scale_context = NULL; 
int64_t seek_target; 

int target_width = 320; 
int target_height = 240; 
GLenum error = GL_NO_ERROR; 
sws_freeContext(img_convert_ctx); 

i = 0; 
while((i==0) && (av_read_frame(pFormatCtx, &packet)>=0)) { 
     if(packet.stream_index==videoStream) { 
     avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 

     if(frameFinished) { 
      LOGI("packet pts %llu", packet.pts); 
      img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, 
        pCodecCtx->pix_fmt, 
        target_width, target_height, PIX_FMT_RGB24, SWS_BICUBIC, 
        NULL, NULL, NULL); 
      if(img_convert_ctx == NULL) { 
       LOGE("could not initialize conversion context\n"); 
       return; 
      } 
       sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); 
       LOGI("sws_scale"); 

       videoTextures = new Texture*[1]; 
       videoTextures[0]->mWidth = 256; //(unsigned)pCodecCtx->width; 
       videoTextures[0]->mHeight = 256; //(unsigned)pCodecCtx->height; 
       videoTextures[0]->mData = pFrameRGB->data[0]; 

       glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

       glGenTextures(1, &(videoTextures[0]->mTextureID)); 
       glBindTexture(GL_TEXTURE_2D, videoTextures[0]->mTextureID); 
       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

       if(0 == got_texture) 
       { 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, videoTextures[0]->mWidth, videoTextures[0]->mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)videoTextures[0]->mData); 

        glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, videoTextures[0]->mWidth, videoTextures[0]->mHeight, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)videoTextures[0]->mData); 
       }else 
       { 
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, videoTextures[0]->mWidth, videoTextures[0]->mHeight, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)videoTextures[0]->mData); 

       } 

       i = 1; 
       error = glGetError(); 
       if(error != GL_NO_ERROR) { 
        LOGE("couldn't create texture!!"); 
         switch (error) { 
         case GL_INVALID_ENUM: 
         LOGE("GL Error: Enum argument is out of range"); 
         break; 
         case GL_INVALID_VALUE: 
          LOGE("GL Error: Numeric value is out of range"); 
         break; 
         case GL_INVALID_OPERATION: 
          LOGE("GL Error: Operation illegal in current state"); 
         break; 
         case GL_OUT_OF_MEMORY: 
          LOGE("GL Error: Not enough memory to execute command"); 
         break; 
         default: 
          break; 
         } 
       } 
     } 
    } 
    av_free_packet(&packet); 
} 

,하지만 난 그냥 C 코드의 텍스처로 변경하고 싶습니다.

편집 1 텍스쳐 ID를 출력했습니다. 0입니다. 텍스처 ID가 0일까요? 내 코드 을 변경했지만 항상 0입니다.

편집 2 텍스처 디스플레이이지만 엉망입니다.

답변

0

디코더로 전달하기 전에 각 패킷에 16 바이트를 추가합니다. avcodec.h 에서

일부 의견 :

/* 
* @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than 
* the actual read bytes because some optimized bitstream readers read 32 or 64 
* bits at once and could read over the end. 
* @warning The end of the input buffer buf should be set to 0 to ensure that 
* no overreading happens for damaged MPEG streams. 
    */ 
2
GLES에 사용되지

하지만, GL. 거기 320에서 240은 2의 거듭 제곱에 대해 512,256을 계산하지 않습니다. 그렇지 않으면 texcoords가 0-1이 아닌 0-w/h 인 texture_rectangle 확장을 사용해야합니다. 텍스처 데이터를 업로드하는 경우, glTexImage (...)는 처음으로 (데이터 0에서도) 사용되어야하며, glTexSubImage이면 충분합니다. 크기 조정 등은 처음에 초기화되고, 두 번째는 그냥 고기를 보냅니다. 는 FFmpeg 사용에 관한

, 아마도 버전 문제가 있지만 CPU 사용량 대신 SWS_CUBIC의 문제 사용 SWS_LINEAR 경우 img_context이 더 가까운 sws_getContext로 이름이 변경 될, 한 번만 초기화, 또한 내가) avcodec_alloc_frame (pFrameRGB이 제대로되었습니다 가정 '에드, GL_RGBA를 사용하려고한다면 PIX_FMT_RGBA를 사용해야하고, PIX_FMT_RGB24는 GL_RGB 텍스쳐 파이핑이 될 것이고 마침내 패킷 스택이 없으므로 디스플레이를 동기화하여 늦지 않게 계속 읽을 수 있습니다.

언팩 정렬에 대한 의견을 읽었습니다. OpenGL/OpenAL 미디어 라이브러리에 대한 ffmpeg를 구현할 필요가 없었습니다. .com/p/openmedialibrary), 오디오 비트도 OpenAL 로더 (http://code.google.com/p/openalensions)에 ffmpeg로 추출되었습니다. 몇 가지 좋은 기능을 부수고 현재 나는 더 나은 성능을 발휘할 수 있는지 확인하기 위해 텍스처 압축 작업을 시도하고 있습니다. 튜토리얼을 고려하거나 심지어 gpl 코드를 사용할 준비가되었습니다.

OpenGL/AL 통합에 대한 ffmpeg의 모호한 (부족한) 예술에 대해 깨달을 수 있기를 바랍니다.

관련 문제