2010-03-16 2 views
2

У меня есть проект с использованием libavcodec (ffmpeg). Я использую его для кодирования MPEG-2 видео в профиль 4: 2: 2, главный уровень. У меня есть формат пикселя PIX_FMT_YUV422P, выбранный в AVCodecContext, однако выход видео, который я получаю, имеет все цвета неправильно, и выглядит так, как будто кодер неправильно читает буферы, как будто он считает, что это 4: 2: 0. чем 4: 2: 2. Вот мой кодек установки:Как установить libavcodec для использования цветности 4: 2: 2 при кодировании профиля MPEG-2 4: 2: 2?

// 
// AVFormatContext* _avFormatContext previously defined as mpeg2video 
// 

// 
// Set up the video stream for output 
// 
AVVideoStream* _avVideoStream = av_new_stream(_avFormatContext, 0); 
if (!_avVideoStream) 
{ 
    err = ccErrWFFFmpegUnableToAllocateStream; 
    goto bail; 
} 
_avCodecContext = _avVideoStream->codec; 
_avCodecContext->codec_id = CODEC_ID_MPEG2VIDEO; 
_avCodecContext->codec_type = CODEC_TYPE_VIDEO; 

// 
// Set up required parameters 
// 
_avCodecContext->rc_max_rate = _avCodecContext->rc_min_rate = _avCodecContext->bit_rate = src->_avCodecContext->bit_rate; 
_avCodecContext->flags = CODEC_FLAG_INTERLACED_DCT; 
_avCodecContext->flags2 = CODEC_FLAG2_INTRA_VLC | CODEC_FLAG2_NON_LINEAR_QUANT; 
_avCodecContext->qmin = 1; 
_avCodecContext->qmax = 1; 
_avCodecContext->rc_buffer_size = _avCodecContext->rc_initial_buffer_occupancy = 2000000; 
_avCodecContext->rc_buffer_aggressivity = 0.25; 
_avCodecContext->profile = 0; 
_avCodecContext->level = 5; 
_avCodecContext->width = f->GetWidth(); // f is a private Frame class with width, height properties etc. 
_avCodecContext->height = f->GetHeight(); 
_avCodecContext->time_base.den = 25; 
_avCodecContext->time_base.num = 1; 
_avCodecContext->gop_size = 12; 
_avCodecContext->max_b_frames = 2; 
_avCodecContext->pix_fmt = PIX_FMT_YUV422P; 

if (_avFormatContext->oformat->flags & AVFMT_GLOBALHEADER) 
{ 
    _avCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER; 
} 

if (av_set_parameters(_avFormatContext, NULL) < 0) 
{ 
    err = ccErrWFFFmpegUnableToSetParameters; 
    goto bail; 
} 

// 
// Set up video codec for encoding 
// 
AVCodec* _avCodec = avcodec_find_encoder(_avCodecContext->codec_id); 
if (!_avCodec) 
{ 
    err = ccErrWFFFmpegUnableToFindCodecForOutput; 
    goto bail; 
} 
if (avcodec_open(_avCodecContext, _avCodec) < 0) 
{ 
    err = ccErrWFFFmpegUnableToOpenCodecForOutput; 
    goto bail; 
} 

Screengrab результирующего видеокадра можно увидеть на http://ftp.limeboy.com/images/screen_grab.png (вход был стандартный цвет баров).

Я проверил вывод кадров отладки в формат TGA в разных точках процесса, и я могу подтвердить, что все это нормально и dandy до момента, когда libavcodec кодирует кадр.

Любые помощь, которые вам очень понравились!

Cheers, Mike.

ответ

4

ОК, это неловко.

Собственно, способ, которым я был настроен, правильный. Просматривая исходный код для ffmpeg, кажется, что все, что вам нужно сделать, чтобы заставить его кодировать профиль 4: 2: 2 и цвет 4: 2: 2, - установить формат входящего пикселя в PIX_FMT_YUV422P.

Причина проблемы? Я смотрел видеофайлы на VLC на виртуальной машине, которая на каком-то этапе изменила разрешение видео с 32-битного на 16 бит.

Правильно! Это изменило его. Я не изменил его - это сделали! СЕБЯ, ВЫ ЗДЕСЬ МЕНЯ!

Извините, если кто-то потратил впустую свое время, преследуя эту проблему.