2011-12-13 23 views
9

Quiero convertir YUV420P imagen (recibida de H.264 corriente) a RGB, al tiempo que también lo cambio de tamaño, usando sws_scale.
El tamaño de la imagen original es 480 × 800. Solo convertir con las mismas dimensiones funciona bien.
Pero cuando trato de cambiar las dimensiones, consigo una imagen distorsionada, con el siguiente patrón:sws_scale YUV -> imagen distorsionada RGB

  • cambiar a 481 × 800 producirá una imagen distorsionada W B &, que parece que está cortada en el medio
  • 482 × 800 será aún más distorsionada
  • 483 × 800 está distorsionada pero en color
  • 484 × 800 es aceptable (escalado correctamente).

Ahora sigue este patrón - escalado sólo funcionará bien si la diferencia entre divide por 4.

Aquí hay un código de ejemplo de la forma en que decodificar y convertir la imagen. Todos los métodos muestran "éxito".

int srcX = 480; 
int srcY = 800; 
int dstX = 481; // or 482, 483 etc 
int dstY = 800; 

AVFrame* avFrameYUV = avcodec_alloc_frame(); 
avpicture_fill((AVPicture *)avFrameYUV, decoded_yuv_frame, PIX_FMT_YUV420P, srcX , srcY); 

AVFrame *avFrameRGB = avcodec_alloc_frame(); 

AVPacket avPacket; 
av_init_packet(&avPacket); 
avPacket.size = read; // size of raw data 
avPacket.data = raw_data; // raw data before decoding to YUV 

int frame_decoded = 0; 
int decoded_length = avcodec_decode_video2(g_avCodecContext, avFrameYUV, &frame_decoded, &avPacket); 
int size = dstX * dstY * 3; 

struct SwsContext *img_convert_ctx = sws_getContext(srcX, srcY, SOURCE_FORMAT, dstX, dstY, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); 

avpicture_fill((AVPicture *)avFrameRGB, rgb_frame, PIX_FMT_RGB24, dstX, dstY); 
sws_scale(img_convert_ctx, avFrameYUV->data, avFrameYUV->linesize, 0, srcY, avFrameRGB->data, avFrameRGB->linesize); 

// draws the resulting frame with windows BitBlt 
DrawBitmap(hdc, dstX, dstY, rgb_frame, size); 

sws_freeContext(img_convert_ctx); 
+0

En sws_getContext() función que está pasando como parámetro el identificador de formato PIX_FMT_BGR24 en lugar de PIX_FMT_RGB24 como lo hace en avpicture_fill –

+0

no dude en enviar un error al https://ffmpeg.org/trac/ffmpeg/newticket –

+0

¿alguna vez hacer que esto funcione? – sendmoreinfo

Respuesta

-1

Cuando se hace una imagen de mapa de bits, el ancho de la imagen debe ser múltiplo de 4.

Así que hay que cambiar el ancho como 480, 484, 488, 492 ...

Aquí es el método para cambiar a múltiplo de 4

#define WIDTHBYTES(bits) (((bits) + 31)/32 * 4) 

void main() 
{ 
    BITMAPFILEHEADER bmFileHeader; 
    BITMAPINFOHEADER bmInfoHeader; 

    // load image 
    // ... 

    // when you use the method, put parameter like this. 
    int tempWidth = WIDTHBYTES(width * bmInfoHeader.biBitCount); 
} 

Espero que resuelva el problema.

+0

No, no tiene que ser un múltiplo de 4. El fragmento de código está aún más lejos de todo, ya que muestra cómo alinear el ancho, es irrelevante para la pregunta. –

Cuestiones relacionadas