Как мне настроить libavcodec на использование цветности 4: 2: 2 при кодировании профиля MPEG-2 4: 2: 2?

StackOverflow https://stackoverflow.com/questions/2453732

Вопрос

У меня есть проект, использующий libavcodec (ffmpeg).Я использую его для кодирования видео в формате MPEG-2 в формате 4: 2: 2, основной уровень.У меня выбран формат пикселя PIX_FMT_YUV422P в AVCodecContext, однако в видеовыходе, который я получаю, все цвета неверны, и мне кажется, что кодировщик неправильно считывает буферы, как будто он думает, что это цветность 4: 2: 0, а не 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;
}

Скриншот полученного видеокадра можно увидеть на http://ftp.limeboy.com/images/screen_grab.png (входные данные представляли собой стандартные цветные полосы).

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

Любая помощь очень ценится!

Твое здоровье, Майк.

Это было полезно?

Решение

Ладно, это смущает.

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

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

Вот именно!ЭТО все изменило.Я не менял это - ОНО сделало это!САМО СОБОЙ, ТЫ МЕНЯ СЛЫШИШЬ!!

Приношу извинения, если кто-то потратил свое время на поиск этой не-проблемы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top