2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. Lorsque vous utilisez avcodec_find_encoder_by_name pour trouver l'encodeur,
const AVCodec * aacencoder = avcodec_find_encoder_by_name("libx264");
Les valeurs du codeur sont :
identifiant AV_CODEC_ID_H264 (27)
nom_long libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 partie 10
nom libx264
pix_fmts AV_PIX_FMT_YUV420P (0)
tapez AVMEDIA_TYPE_VIDEO (0)
2. Après avoir appelé AVCodecContext *aacencodercontext = avcodec_alloc_context3(aacencoder);.
L'encodeur est le même que ci-dessus, aucun changement
Le contenu dans le contexte de l'encodeur est :
Les codec_id et codec_type dans le contexte de l'encodeur ont des valeurs, et les autres sont réaffectés à leurs valeurs par défaut.
codec_id AV_CODEC_ID_H264 (27)
codec_type AVMEDIA_TYPE_VIDEO (0)
Les valeurs par défaut sont les suivantes :
s->base_de_temps = (AVRational){0,1};
s->framerate = (AVRational){ 0, 1 };
s->pkt_timebase = (AVRational){ 0, 1 };
3. Lorsque la méthode avcodec_open2(encoderAVCodecContext, encoderAVCodec, NULL) est appelée, de nombreux paramètres seront définis.
On peut imaginer qu'en supposant que l'encodeur soit AAC, quels paramètres seront définis ?
Le premier est le nombre d’images d’échantillon dont dispose un avframe.
3.1 Commencez par avcodec_find_encoder ou avcodec_find_decoder au début.
La méthode est dans le fichier D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecallcodecs.c.
const AVCodec *avcodec_find_encoder(énumération AVCodecID id)
{
retourner find_codec(id, av_codec_is_encoder);
}
const AVCodec *avcodec_find_decoder(énumération AVCodecID id)
{
retourner find_codec(id, av_codec_is_decoder);
}
3.2 Le cœur de la méthode find_codec est la méthode av_codec_iterate
statique const AVCodec *find_codec(énumération AVCodecID id, int (*x)(const AVCodec *))
{
const AVCodec *p, *expérimental = NULL;
vide *i = 0;
id = remap_deprecated_codec_id(id);
tandis que ((p = av_codec_iterate(&i))) {
si (!x(p))
continuer;
si (p->id == id) {
si (p->capacités & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
expérimental = p;
} autre
retour p;
}
}
retour expérimental;
}
3.3 La méthode av_codec_iterate trouve en fait le codec correspondant dans la liste codec_list. Cette liste est très longue, comprenant les noms de tous les encodeurs et décodeurs dans ffmepg.
const AVCodec *av_codec_iterate(void **opaque)
{
uintptr_t i = (uintptr_t)*opaque;
const FFCodec *c = codec_list[i];
ff_thread_once(&av_codec_static_init, av_codec_init_static);
si (c) {
*opaque = (vide*)(i + 1);
retour &c->p;
}
retourner NULL;
}
Nous pouvons voir qu'il existe plusieurs aac correspondant à la codec_list, et nous utilisons ff_aac_encoder pour illustrer.
Après avoir recherché le code, j'ai trouvé que la définition de ff_aac_encoder se trouve dans aacenc.c, qui contient
Les informations suivantes peuvent être consultées à partir de D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecaacenc.c,
Field.init = aac_encode_init, devrait être une fonction,
Comme vous pouvez le voir grâce à la fonction aac_encode_init, frame_size est 1024
avctx->frame_size = 1024;
const FFCodec ff_aac_encoder = {
.p.name = "aac",
CODEC_LONG_NAME("AAC (codage audio avancé)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_PETIT_DERNIÈRE_IMAGE,
.priv_data_size = taille de(AACEncContext),
.init = aac_encode_init,
FF_CODEC_ENCODE_CB(trame_encodage_aac),
.close = aac_encode_end,
.defaults = aac_encode_defaults,
.p.supported_samplerates = taux_d'échantillonnage_audio_ff_mpeg4,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &aacenc_class,
};
À ce stade, une question subsiste : quand ff_aac_encoder a-t-il été initialisé ?
En fait, ret = avcodec_open2(avcodecContext,nullptr,nullptr); le fait en interne.
Le code de base est dans
si (codec2->init) {
En fait, il s'appellera :
statique av_cold int aac_encode_init(AVCodecContext *avctx)