2011-12-13 75 views
9

Tôi muốn chuyển đổi hình ảnh YUV420P (nhận được từ H.264 luồng) thành RGB, đồng thời thay đổi kích thước hình ảnh bằng cách sử dụng sws_scale.
Kích thước của hình ảnh gốc là 480 × 800. Chỉ cần chuyển đổi với cùng kích thước hoạt động tốt.
Nhưng khi tôi cố gắng để thay đổi kích thước, tôi nhận được một hình ảnh méo mó, với mô hình sau:sws_scale YUV -> Hình ảnh bị méo RGB

  • thay đổi để 481 × 800 sẽ mang lại một B & ảnh W méo trông giống như nó cắt ở giữa
  • 482 × 800 sẽ được thậm chí nhiều hơn méo
  • 483 × 800 bị méo nhưng trong màu
  • 484 × 800 là ok (quy mô chính xác).

Bây giờ mô hình này sau - rộng sẽ chỉ làm việc tốt nếu sự khác biệt giữa phân chia bởi 4.

Dưới đây là một số mẫu mã của cách mà tôi giải mã và chuyển đổi hình ảnh. Tất cả các phương pháp đều cho thấy "thành công".

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

Trong hàm sws_getContext() bạn chuyển như tham số định danh định dạng PIX_FMT_BGR24 thay vì PIX_FMT_RGB24 như bạn làm trong avpicture_fill –

+0

, vui lòng đăng lỗi tại https://ffmpeg.org/trac/ffmpeg/newticket –

+0

bạn đã bao giờ có được điều này để làm việc? – sendmoreinfo

Trả lời

-1

Khi bạn thực hiện một hình ảnh bitmap, độ rộng của hình ảnh PHẢI là bội số của 4.

Vì vậy, bạn cần phải thay đổi chiều rộng như 480, 484, 488, 492 ...

đây là phương thức để thay đổi thành bội số của 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); 
} 

Tôi hy vọng bạn giải quyết được sự cố.

+0

Không, nó không phải là bội số của 4. Đoạn mã thậm chí còn xa hơn toàn bộ điều khi nó trình diễn cách sắp xếp chiều rộng, nó không liên quan đến câu hỏi. –