2011-12-13 4 views
9

Я хочу преобразовать YUV420P изображение (полученное от H.264 stream) до RGB, а также изменяя его размер, используя sws_scale.
Размер оригинального изображения 480 × 800. Простое преобразование с одинаковыми размерами прекрасно работает.
Но когда я пытаюсь изменить размеры, я получаю искаженное изображение, со следующей схемой:sws_scale YUV -> RGB искаженное изображение

  • изменения в 481 × 800 даст искаженную B & W изображение, которое выглядит как это вырезать в середине
  • 482 × 800 будет еще более искаженным
  • 483 × 800 искажается, но в цвете
  • 484 × 800 нормально (масштабируется правильно).

Теперь этот шаблон следующим образом - масштабирование будет работать только хорошо, если разница между водоразделами на 4.

Вот пример кода таким образом, что я дешифровать и преобразовать изображение. Все методы показывают «успех».

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

В sws_getContext() функции, которые вы передаете в качестве параметра формата идентификатора PIX_FMT_BGR24 вместо PIX_FMT_RGB24, как вы в avpicture_fill –

+0

не стесняйтесь отправлять ошибку в https://ffmpeg.org/trac/ffmpeg/newticket –

+0

вы когда-нибудь заставить это работать? – sendmoreinfo

ответ

-1

При создании растрового изображения, ширина изображения должна быть кратна 4.

Таким образом, вы должны изменить ширину, как 480, 484, 488, 492 ...

Здесь метод для изменения на несколько из 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); 
} 

Надеюсь, вы решите проблему.

+0

Нет, это не должно быть кратным 4. Фрагмент кода еще дальше от всего, поскольку он демонстрирует, как выравнивать ширину, это не имеет отношения к вопросу. –