Comment puis-je configurer libavcodec utiliser 4: 2: 2 Chroma lors de l'encodage MPEG-2 4: profil 2: 2?
-
20-09-2019 - |
Question
J'ai un projet en utilisant libavcodec (ffmpeg). Je l'utilise pour encoder la vidéo MPEG-2 à 4: 2: 2 Profil, niveau principal. Je le format de pixel PIX_FMT_YUV422P sélectionné dans le AVCodecContext, mais la sortie vidéo je reçois a toutes les couleurs mal, et me semble que l'encodeur est lu de façon incorrecte les tampons comme si elle pense qu'il est 4: 2: 0 chroma plutôt à 4: 2: 2. Voici ma configuration 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;
}
A screengrab de l'image vidéo qui en résulte peut être vu à http: //ftp.limeboy. com / images / screen_grab.png (l'entrée était barres de couleur standard).
J'ai vérifié en sortant des cadres de débogage au format TGA à différents points dans le processus, et je peux confirmer qu'il est bien beau jusqu'au point que libavcodec code le cadre.
Toute aide la plus appréciée!
Cordialement, Mike.
La solution
OK, cela est embarrassant.
En fait, la façon dont je l'avais mis en place est correcte. En regardant à travers le code source pour ffmpeg, il semble que tout ce que vous devez faire pour l'obtenir pour coder 4: 2: 2 profil et 4: 2: 2. Chroma est de définir le format de pixel entrant PIX_FMT_YUV422P
La cause du problème? Je regardais le fichier vidéo de retour sur VLC dans une machine virtuelle, qui, à un certain stade avait changé sa résolution vidéo de 32 bits à 16 bits.
C'est vrai! IT a changé. Je n'ai pas changé - il l'a fait! PAR LUI-MÊME, VOUS ENTENDU ME !!
Toutes mes excuses si quelqu'un perdu leur temps à courir après dans cette non-question.