Décodage FLV - librairie libavcodec (ffmpeg)
Bonjour,
Je dois transcoder un extrait FLV en MJPEG avec les librairies ffmpeg mais il me reste quelques points obscurs et je ne trouve pas d'aides très explicites sur le net.
Je n'ai jamais fait de décodage avec ffmpeg, c'est donc la partie décodage FLV qui me pose problème.
(j'utilise libavcodec en version 51.7.0)
FLV : 570 ko, 480*360, pas d'audio, codec Sorenson H263
- Ai-je correctement initialisé la bibliothèque ?
- Ai-je correctement rempli les paramètres de l'AvCodecContext m_pCodecCtx ?
- Quel est le PixelFormat pour le FLV ? PIX_FMT_YUVJ420P ?
Le code suivant est un extrait de mon original mais devrait suffire à la compréhension de ma démarche.
Note : Initialement, je récupérais toutes les données de mon FLV pour les passer à avcodec_decode_video() que j'ai modifié ensuite pour le découper et passer seulement des paquets de 16384 octets.
- la fonction avcodec_find_decoder(CODEC_ID_FLV1) ne retourne pas d'erreur
- avcodec_decode_video() retourne -1
- si je remplace CODEC_ID_FLV1 par CODEC_ID_H263 dans avcodec_find_decoder(), avcodec_decode_video() ne retourne pas d'erreur mais got_picture reste à 0 !
Merci par avance si quelqu'un peut m'éclairer de son expérience dans ce domaine.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| avcodec_init();
av_register_all();
m_pCodecCtx = avcodec_alloc_context();
avcodec_get_context_defaults(m_pCodecCtx);
m_pCodecCtx->width=m_iWidth; // Width of the input FLV video: 480
m_pCodecCtx->height=m_iHeight; // Heigth of the input FLV video: 360
// RGB24 Context Init
m_pRGB24CodecCtx = avcodec_alloc_context();
m_pRGB24CodecCtx->width=m_iWidth;
m_pRGB24CodecCtx->height=m_iHeight;
m_pRGB24CodecCtx->pix_fmt = (PixelFormat)PIX_FMT_BGR24;
m_pRGB24Frame = avcodec_alloc_frame();
switch(m_iCodecID)
{
case CODEC_ID_FLV1 :
m_pCodec = avcodec_find_decoder(CODEC_ID_FLV1);
//CODEC_ID_H263);
if (!m_pCodec)
{
return false; // !!! !!! !!!
}
m_pCodecCtx->thread_count = 1;
m_pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
m_pCodecCtx->error_resilience = FF_ER_COMPLIANT;
m_pCodecCtx->error_concealment = 3;
m_pCodecCtx->idct_algo = FF_IDCT_AUTO;
m_pCodecCtx->debug = 0;
m_pCodecCtx->debug_mv = 0;
//m_pCodecCtx->codec_tag = 2;
// Inform the codec that we can handle truncated bitstreams -- i.e.,
// bitstreams where frame boundaries can fall in the middle of packets
if(m_pCodec->capabilities & CODEC_CAP_TRUNCATED)
m_pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
if (avcodec_open(m_pCodecCtx, m_pCodec) < 0)
{
return false; // !!! !!! !!!
}
m_pCodecCtx->pix_fmt = (PixelFormat) PIX_FMT_YUVJ420P; // or PIX_FMT_RGB24 ?
break;
default:
CString sMsg;
sMsg.Format(_T("[CVideoCodec::%d] ERROR not implemented"),int(this));
m_pSession->WriteLog(sMsg,1);
break;
}
m_iPixFmt = m_pCodecCtx->pix_fmt;
} else
{
m_pCodecCtx->pix_fmt = (PixelFormat) m_iPixFmt;
}
m_pInputFrame = avcodec_alloc_frame();
int numBytes=avpicture_get_size(m_iPixFmt, m_pCodecCtx->width, m_pCodecCtx->height);
m_buffer=new unsigned char[numBytes];
avpicture_fill((AVPicture *)m_pInputFrame, m_buffer, m_iPixFmt,
m_pCodecCtx->width, m_pCodecCtx->height);
m_pOutputFrame= avcodec_alloc_frame();
}
int got_picture = 0;
int iDecodedBytesCount = 0;
iDecodedBytesCount = avcodec_decode_video ( m_pCodecCtx,
m_pInputFrame,
//m_pOutputFrame,
&got_picture,
Buffer,
uiBufferUsed ); |