Como faço para definir o libavcodec para usar o Chroma 4: 2: 2 ao codificar o perfil MPEG-2 4: 2: 2?

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

Pergunta

Eu tenho um projeto usando libavcodec (ffmpeg). Estou usando para codificar o vídeo MPEG-2 a 4: 2: 2 perfil, nível principal. Eu tenho o formato pixel pix_fmt_yuv422p selecionado no AvCodecContext, no entanto, a saída de vídeo que estou recebendo tem todas as cores erradas e me parece que o codificador está lendo incorretamente os buffers, como se ele pensasse que é 4: 2: 0 croma, antes que de 4: 2: 2. Aqui está minha configuração de codec:

// 
// 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;
}

Uma tela de tela do quadro de vídeo resultante pode ser vista em http://ftp.limeboy.com/images/screen_grab.png (A entrada era barras de cores padrão).

Eu verifiquei produzindo quadros de depuração para o formato TGA em vários pontos do processo, e posso confirmar que tudo está bem e dândi até o ponto em que o libavcodec codifica o quadro.

Qualquer assistência mais apreciada!

Saúde, Mike.

Foi útil?

Solução

Ok, isso é embaraçoso.

Na verdade, a maneira como eu a configurei está correta. Olhando através do código -fonte do FFMPEG, parece que tudo o que você precisa fazer para que ele codifique 4: 2: 2 e 4: 2: 2 Chroma é definir o formato de pixel de entrada para PIX_FMT_YUV422P.

A causa do problema? Eu estava assistindo o arquivo de vídeo de volta no VLC em uma máquina virtual, que em algum momento mudou sua resolução de vídeo de 32 bits para 16 bits.

Isso mesmo! Mudou. Eu não mudei - fez isso! Por si só, você me ouve !!

Desculpas se alguém perdeu o tempo perseguindo esse não problema.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top