Teknologian jakaminen

Kun ffmpeg löytää koodekin ja koodekkikontekstin, miten se alustaa tietyn koodekin? AAC-alustusprosessi on suunnilleen seuraava

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Kun käytät avcodec_find_encoder_by_name kooderin etsimiseen,
const AVCodec * aacencoder = avcodec_find_encoder_by_name("libx264");

Enkooderin arvot ovat:
tunnus AV_CODEC_ID_H264 (27)
long_name libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 osa 10
nimi libx264
pix_fmts AV_PIX_FMT_YUV420P (0)

tyyppi AVMEDIA_TYPE_VIDEO (0)


2. Kun AVCodecContext on kutsuttu *aacencodercontext = avcodec_alloc_context3(aacencoder);.
Enkooderi on sama kuin yllä, ei muutoksia


Enkooderin sisältö on:
Enkooderikontekstin koodeilla codec_id ja codec_type on arvot, ja muut määritetään uudelleen oletusarvoihinsa.
codec_id AV_CODEC_ID_H264 (27)
codec_type AVMEDIA_TYPE_VIDEO (0)
Oletusarvot ovat seuraavat:

s->aikakanta = (AVRational){0,1};
s->framerate = (AVRational){ 0, 1 };
s->pkt_timebase = (AVRational){ 0, 1 };


3. Kun avcodec_open2(encoderAVCodecContext, encoderAVCodec, NULL) -menetelmää kutsutaan, monet parametrit asetetaan.

Voimme kuvitella, että olettaen, että kooderi on AAC, mitkä parametrit asetetaan?
Ensimmäinen on kuinka monta näytekehystä avframessa on.

3.1 Aloita alussa avcodec_find_encoder tai avcodec_find_decoder.
Menetelmä on tiedostossa D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecallcodecs.c.


const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
return find_codec(id, av_codec_is_encoder);
}

const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
return find_codec(id, av_codec_is_dekooderi);
}


3.2 Find_codec-menetelmän ydin on av_codec_iterate-menetelmä

staattinen jatkuva AVCodec *find_codec(enum AVCodecID id, int (*x)(vakio AVCodec *))
{
const AVCodec *p, *kokeellinen = NULL;
tyhjä *i = 0;

id = remap_deprecated_codec_id(id);

while ((p = av_codec_iterate(&i))) {
jos (!x(p))
jatkaa;
if (p->id == id) {
if (p->ominaisuudet & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
kokeellinen = p;
} muuta
paluu p;
        }
    }

palauttaa kokeellinen;
}

3.3 Menetelmä av_codec_iterate löytää itse asiassa vastaavan koodekin codec_listista. Tämä luettelo on erittäin pitkä, ja se sisältää kaikkien ffmepg:n kooderien ja dekooderien nimet.
const AVCodec *av_codec_iterate(void **opasque)
{
uintptr_t i = (uintptr_t)*läpinäkymätön;
const FFCodec *c = koodekkiluettelo[i];

ff_thread_once(&av_codec_static_init, av_codec_init_static);

jos (c) {
*läpinäkymätön = (tyhjä*)(i + 1);
palauttaa &c->p;
    }
palauttaa NULL;
}


Voimme nähdä, että codec_list-luetteloa vastaavia aac-koodeja on useita, ja käytämme havainnollistamiseen ff_aac_encoder-koodia.
Etsittyäni koodia huomasin, että ff_aac_encoderin määritelmä on tiedostossa aacenc.c, joka sisältää


Seuraavat tiedot ovat nähtävissä osoitteesta D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecaacenc.c,
Field.init = aac_encode_init, pitäisi olla funktio,
Kuten näet aac_encode_init-funktiosta, frame_size on 1024
avctx->kehyksen_koko = 1024;


const FFCodec ff_aac_encoder = {
.p.name = "aac",
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.p.capabilities = 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(aac_encode_frame),
.close = aac_encode_end,
.defaults = aac_encode_defaults,
.p.supported_samplerates = ff_mpeg4audio_sample_rates,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (vakioluettelo AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &aacenc_class,
};

Tässä vaiheessa on edelleen kysymys: milloin ff_aac_encoder alustettiin?
Itse asiassa ret = avcodec_open2(avcodecContext,nullptr,nullptr);
Ydinkoodi on sisään

if (codec2->init) {
        
Itse asiassa sen nimi on:
static av_cold int aac_encode_init(AVCodecContext *avctx)