minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. Ao usar avcodec_find_encoder_by_name para encontrar o codificador,
const AVCodec * aacencoder = avcodec_find_encoder_by_name("libx264");
Os valores do codificador são:
id 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. Após chamar AVCodecContext *aacencodercontext = avcodec_alloc_context3(aacencoder);.
O codificador é o mesmo acima, sem alterações
O conteúdo no contexto do codificador é:
O codec_id e o codec_type no contexto do codificador possuem valores e os demais são reatribuídos aos seus valores padrão.
codec_id AV_CODEC_ID_H264 (27)
codec_type AVMEDIA_TYPE_VIDEO (0)
Os valores padrão são os seguintes:
s->base_de_tempo = (AVRacional){0,1};
s->taxa de quadros = (AVRational){ 0, 1 };
s->pkt_timebase = (AVRacional){ 0, 1 };
3. Quando o método avcodec_open2(encoderAVCodecContext, encoderAVCodec, NULL) é chamado, muitos parâmetros serão definidos.
Podemos imaginar que assumindo que o codificador seja AAC, quais parâmetros serão definidos?
A primeira é quantos quadros de amostra um avframe possui.
3.1 Comece com avcodec_find_encoder ou avcodec_find_decoder no início.
O método está no arquivo D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecallcodecs.c.
const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
retornar find_codec(id, av_codec_is_encoder);
}
const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
retornar find_codec(id, av_codec_is_decoder);
}
3.2 O núcleo do método find_codec é o método av_codec_iterate
estático const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
{
const AVCodec *p, *experimental = NULL;
vazio *i = 0;
id = remap_deprecated_codec_id(id);
enquanto ((p = av_codec_iterate(&i))) {
se (!x(p))
continuar;
se (p->id == id) {
se (p->capacidades & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
experimental = p;
} outro
retornar p;
}
}
retornar experimental;
}
3.3 O método av_codec_iterate realmente encontra o codec correspondente em codec_list. Esta lista é muito longa, incluindo os nomes de todos os codificadores e decodificadores dentro do ffmepg.
const AVCodec *av_codec_iterate(void **opaco)
{
uintptr_t i = (uintptr_t)*opaco;
const FFCodec *c = lista_de_codecs[i];
ff_thread_once(&init_estático_do_codec_av, init_estático_do_codec_av);
se (c) {
*opaco = (vazio*)(i + 1);
retornar &c->p;
}
retornar NULL;
}
Podemos ver que existem vários aacs correspondentes à codec_list e usamos ff_aac_encoder para ilustrar.
Depois de pesquisar o código, descobri que a definição de ff_aac_encoder está em aacenc.c, que contém
As informações a seguir podem ser vistas em D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecaacenc.c,
Field.init = aac_encode_init, deve ser uma função,
Como você pode ver na função aac_encode_init, frame_size é 1024
avctx->tamanho_do_quadro = 1024;
const FFCodec ff_aac_encoder = {
.p.nome = "aac",
CODEC_LONG_NAME("AAC (Codificação de Áudio Avançada)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.p.capacidades = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_PEQUENO_ÚLTIMO_QUADRO,
.priv_data_size = tamanho de (AACEncContext),
.init = aac_encode_init,
FF_CODEC_ENCODE_CB(quadro_codificação_aac),
.close = aac_encode_end,
.defaults = padrões_de_codificação_aac,
.p.supported_samplerates = ff_mpeg4audio_sample_rates,
.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,
};
Neste ponto, ainda há uma dúvida: quando o ff_aac_encoder foi inicializado?
Na verdade, ret = avcodec_open2(avcodecContext,nullptr,nullptr);
O código principal está em
se (codec2->init) {
Na verdade, será chamado:
estático av_cold int aac_encode_init(AVCodecContext *avctx)