le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. Quando si utilizza avcodec_find_encoder_by_name per trovare il codificatore,
const AVCodec * aacencoder = avcodec_find_encoder_by_name("libx264");
I valori dell'encoder sono:
identificativo AV_CODEC_ID_H264 (27)
long_name libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 parte 10
nome libx264
pix_fmts AV_PIX_FMT_YUV420P (0)
tipo AVMEDIA_TYPE_VIDEO (0)
2. Dopo aver chiamato AVCodecContext *aacencodercontext = avcodec_alloc_context3(aacencoder);.
L'encoder è lo stesso di sopra, nessuna modifica
Il contenuto nel contesto del codificatore è:
Codec_id e codec_type nel contesto del codificatore hanno valori e gli altri vengono riassegnati ai rispettivi valori predefiniti.
codice_id AV_CODEC_ID_H264 (27)
tipo_codec AVMEDIA_TYPE_VIDEO (0)
I valori predefiniti sono i seguenti:
s->time_base = (AVRazionale){0,1};
s->framerate = (AVRazionale){ 0, 1 };
s->pkt_timebase = (AVRazionale){ 0, 1 };
3. Quando viene chiamato il metodo avcodec_open2(encoderAVCodecContext, encoderAVCodec, NULL), verranno impostati molti parametri.
Possiamo immaginare che supponendo che l'encoder sia AAC, quali parametri verranno impostati?
Il primo è quanti fotogrammi campione ha un avframe.
3.1 Inizia con avcodec_find_encoder o avcodec_find_decoder all'inizio.
Il metodo è nel file D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecallcodecs.c.
const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
restituisci find_codec(id, av_codec_is_encoder);
}
const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
restituisci find_codec(id, av_codec_is_decoder);
}
3.2 Il nucleo del metodo find_codec è il metodo av_codec_iterate
statico const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
{
const AVCodec *p, *sperimentale = NULL;
vuoto *i = 0;
id = remap_deprecated_codec_id(id);
mentre ((p = av_codec_iterate(&i))) {
se (!x(p))
Continua;
se (p->id == id) {
se (p->capacità & AV_CODEC_CAP_EXPERIMENTAL && !sperimentale) {
sperimentale = p;
} altro
restituisci p;
}
}
ritorno sperimentale;
}
3.3 Il metodo av_codec_iterate trova effettivamente il codec corrispondente da codec_list Questo elenco è molto lungo e include i nomi di tutti i codificatori e decodificatori all'interno di ffmepg.
const AVCodec *av_codec_iterate(void **opaco)
{
uintptr_t i = (uintptr_t)*opaco;
const FFCodec *c = codec_list[i];
ff_thread_once(&av_codec_static_init, av_codec_init_static);
se (c) {
*opaco = (vuoto*)(i + 1);
ritorno &c->p;
}
restituisci NULL;
}
Possiamo vedere che ci sono più aac corrispondenti a codec_list e utilizziamo ff_aac_encoder per illustrarlo.
Dopo aver cercato il codice, ho scoperto che la definizione di ff_aac_encoder è in aacenc.c, che contiene
Le seguenti informazioni possono essere visualizzate da D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecaacenc.c,
Field.init = aac_encode_init, dovrebbe essere una funzione,
Come puoi vedere dalla funzione aac_encode_init, frame_size è 1024
avctx->frame_size = 1024;
const FFCodec ff_aac_encoder = {
.p.name = "aac",
CODEC_LONG_NAME("AAC (codifica audio avanzata)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.p.capacità = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SMALL_LAST_FRAME,
.priv_data_size = sizeof(AACEncContext),
.init = aac_encode_init,
FF_CODEC_ENCODE_CB(frame di codifica aac),
.chiudi = aac_encode_end,
.defaults = aac_encode_defaults,
.p.supported_samplerates = frequenze di campionamento ff_mpeg4audio,
.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,
};
A questo punto c'è ancora una domanda: quando è stato inizializzato ff_aac_encoder?
In effetti, ret = avcodec_open2(avcodecContext,nullptr,nullptr);
Il codice principale è dentro
se (codec2->init) {
Si chiamerà infatti:
statico av_cold int aac_encode_init(AVCodecContext *avctx)