내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. avcodec_find_encoder_by_name을 사용하여 인코더를 찾을 때,
libx264를 사용하여 avcodec_find_encoder_by_name을 찾습니다.
인코더 값은 다음과 같습니다.
아이디 AV_CODEC_ID_H264 (27)
long_name libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
이름 libx264
pix_fmts AV_PIX_FMT_YUV420P (0)
AVMEDIA_TYPE_VIDEO 유형 (0)
2. AVCodecContext *aacencodercontext = avcodec_alloc_context3(aacencoder);를 호출한 후.
인코더는 위와 동일하며 변경 사항이 없습니다.
인코더 컨텍스트의 콘텐츠는 다음과 같습니다.
인코더 컨텍스트의 codec_id 및 codec_type에는 값이 있으며 나머지는 기본값으로 다시 할당됩니다.
코덱_아이디 AV_CODEC_ID_H264 (27)
코덱 유형 AVMEDIA_TYPE_VIDEO (0)
기본값은 다음과 같습니다.
s->시간 기준 = (AVRational){0,1};
s->프레임 속도 = (AVRational){ 0, 1 };
s->pkt_timebase = (AVRational){ 0, 1 };
3. avcodec_open2(encoderAVCodecContext, EncoderAVCodec, NULL) 메소드가 호출되면 많은 매개변수가 설정됩니다.
인코더가 AAC라고 가정하면 어떤 매개변수가 설정될까요?
첫 번째는 avframe에 얼마나 많은 샘플 프레임이 있는지입니다.
3.1 처음에는 avcodec_find_encoder 또는 avcodec_find_decoder로 시작합니다.
메서드는 D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecallcodecs.c 파일에 있습니다.
const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
find_codec(id, av_codec_is_encoder)를 반환합니다.
}
const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
find_codec(id, av_codec_is_decoder)를 반환합니다.
}
3.2 find_codec 메소드의 핵심은 av_codec_iterate 메소드입니다
정적 const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
{
실험적 AVCodec = NULL;
무효 *i = 0;
id = remap_deprecated_codec_id(id);
((p = av_codec_iterate(&i))) 동안
만약 (!x(p))
계속하다;
if (p->id == id) {
if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
실험 = p;
} 또 다른
p를 반환합니다.
}
}
실험으로 돌아가다;
}
3.3 av_codec_iterate 메소드는 실제로 codec_list에서 해당 코덱을 찾습니다. 이 목록은 ffmepg 내의 모든 인코더 및 디코더의 이름을 포함하여 매우 깁니다.
const AVCodec *av_codec_iterate(void **opaque)
{
uintptr_t i = (uintptr_t)*불투명;
const FFCodec *c = 코덱 목록[i];
av_codec_init_static을 사용하여 스레드를 초기화합니다.
만약 (c) {
*불투명 = (void*)(i + 1);
&c->p로 돌아갑니다.
}
NULL을 반환합니다.
}
codec_list에 해당하는 여러 aac가 있음을 알 수 있으며 설명을 위해 ff_aac_encoder를 사용합니다.
코드를 검색한 결과 ff_aac_encoder의 정의가 aacenc.c에 있음을 발견했습니다.
다음 정보는 D:Ctoolyinshipinffmpeg-6.0sourcelibavcodecaacenc.c에서 볼 수 있습니다.
Field.init = aac_encode_init, 함수여야 하며,
aac_encode_init 함수에서 볼 수 있듯이, frame_size는 1024입니다.
avctx->프레임_크기 = 1024;
const FFCodec ff_aac_encoder = {
.p.name = "aac",
CODEC_LONG_NAME("AAC(고급 오디오 코딩)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.p.기능 = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SMALL_마지막_프레임,
.priv_data_size = AACEncContext의 크기,
.init = aac_인코딩_초기화,
FF_CODEC_ENCODE_CB(aac_인코딩_프레임),
.닫기 = aac_인코딩_끝,
.기본값 = aac_인코딩_기본값,
.p.지원되는_샘플링_레이트 = ff_mpeg4오디오_샘플_레이트,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (상수 열거형 AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_샘플_FMT_없음 },
.p.priv_class = &aacenc_class,
};
이 시점에서 여전히 질문이 있습니다. ff_aac_encoder는 언제 초기화되었습니까?
실제로 ret = avcodec_open2(avcodecContext,nullptr,nullptr);는 이 작업을 내부적으로 수행합니다.
핵심 코드는 다음과 같습니다.
if (코덱2->init) {
실제로는 다음과 같이 호출됩니다.
정적 av_cold int aac_encode_init(AVCodecContext *avctx)