El módulo libavcodec de FFmpeg completa el módulo de códec de audio y video multimedia.
FFmpeg en sí mismo no tiene funciones de codificación de audio y video y capacidades subyacentes , sino que solo encapsula y llama a varias API de codificador de terceros.
La versión anterior de FFmpeg utiliza avcodec_encode_video2() como API de función de decodificación de video y avcodec_encode_audio2() como API de función de decodificación de audio; desde la versión 3.4, las dos se han marcado como API obsoletas (atributo_obsoleto ) .
La nueva versión de FFmpeg usa avcodec_send_frame() y avcodec_receive_packet() como API de función de decodificación de audio y video, pero al mismo tiempo aún conserva la compatibilidad con las interfaces antiguas y llama a compat_decode() a través de avcodec_encode_video2() y avcodec_encode_audio2() para completar la empaquetado de las nuevas API.
//具体可以参考 FFmpeg 中 doc/APIchanges 中的记录.
2016-04-21 - 7fc329e - lavc 57.37.100 - avcodec.h
Add a new audio/video encoding and decoding API with decoupled input
and output -- avcodec_send_packet(), avcodec_receive_frame(),
avcodec_send_frame() and avcodec_receive_packet().
Puede usar la línea de comando ffmpeg configure -encoders para verificar qué formatos de codificador son compatibles, pero parece que la descripción en configure no es exactamente igual que el código fuente. El código fuente admite el codificador kvazaar (un codificador de código abierto que cumple al estándar de codificación h265), pero la configuración no se refleja.
Encoders:
V..... = Video
A..... = Audio
S..... = Subtitle
.F....= Frame-level multithreading
..S... = Slice-level multithreading
...X..= Codec is experimental
....B. = Supports draw_horiz_band
.....D = Supports direct rendering method 1
------
V....D a64multi Multicolor charset for Commodore 64(codec a64_multi)
V....D a64multi5 Multicolor charset for Commodore 64, extended with 5th color (colram)(codec a64_multi5)
V....D alias_pix Alias/Wavefront PIX image
V..... amv AMV Video
V....D apng APNG (Animated Portable Network Graphics) image
V....D asv1 ASUS V1
V....D asv2 ASUS V2
V....D libaom-av1 libaom AV1 (codec av1)
V....D librav1e librav1e AV1 (codec av1)
V..... libsvtav1 SVT-AV1(Scalable Video Technology for AV1) encoder (codec av1)
V....D avrp Avid 1:1 10-bit RGB Packer
V..X.D avui Avid Meridien Uncompressed
V....D ayuv Uncompressed packed MS 4:4:4:4
VF...D bitpacked Bitpacked
V....D bmp BMP (Windows and OS/2 bitmap)
VF...D cfhd GoPro CineForm HD
V....D cinepak Cinepak
V....D cljr Cirrus Logic AccuPak
V.S..D vc2 SMPTE VC-2 (codec dirac)
VFS..D dnxhd VC3/DNxHD
V....D dpx DPX (Digital Picture Exchange) image
VFS..D dvvideo DV (Digital Video)
VF...D exr OpenEXR image
V.S..D ffv1 FFmpeg video codec #1
VF...D ffvhuff Huffyuv FFmpeg variant
V....D fits Flexible Image Transport System
V....D flashsv Flash Screen Video
V....D flashsv2 Flash Screen Video Version 2
V..... flv FLV / Sorenson Spark / Sorenson H.263 (Flash Video)(codec flv1)
V....D gif GIF (Graphics Interchange Format)
V..... h261 H.261
V..... h263 H.263 / H.263-1996
V.S... h263p H.263+ / H.263-1998 / H.263 version 2
V....D libx264 libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10(codec h264)
V....D libx264rgb libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB (codec h264)
V....D h264_videotoolbox VideoToolbox H.264 Encoder (codec h264)
V.S..D hap Vidvox Hap
VF...D hdr HDR (Radiance RGBE format) image
V....D libx265 libx265 H.265 / HEVC (codec hevc)
V....D hevc_videotoolbox VideoToolbox H.265 Encoder (codec hevc)
VF...D huffyuv Huffyuv / HuffYUV
V....D jpeg2000 JPEG 2000
VF.... libopenjpeg OpenJPEG JPEG 2000(codec jpeg2000)
VF...D jpegls JPEG-LS
VF...D ljpeg Lossless JPEG
VF...D magicyuv MagicYUV video
VFS... mjpeg MJPEG (Motion JPEG)
V.S... mpeg1video MPEG-1 video
V.S... mpeg2video MPEG-2 video
V.S... mpeg4 MPEG-4 part 2
V....D libxvid libxvidcore MPEG-4 part 2(codec mpeg4)
V..... msmpeg4v2 MPEG-4 part 2 Microsoft variant version 2
V..... msmpeg4 MPEG-4 part 2 Microsoft variant version 3(codec msmpeg4v3)
V..... msvideo1 Microsoft Video-1
V....D pam PAM (Portable AnyMap) image
V....D pbm PBM (Portable BitMap) image
V....D pcx PC Paintbrush PCX image
V....D pfm PFM (Portable FloatMap) image
V....D pgm PGM (Portable GrayMap) image
V....D pgmyuv PGMYUV (Portable GrayMap YUV) image
V....D phm PHM (Portable HalfFloatMap) image
VF...D png PNG (Portable Network Graphics) image
V....D ppm PPM (Portable PixelMap) image
VF...D prores Apple ProRes
VF...D prores_aw Apple ProRes (codec prores)
VFS... prores_ks Apple ProRes (iCodec Pro)(codec prores)
V....D prores_videotoolbox VideoToolbox ProRes Encoder (codec prores)
VF...D qoi QOI (Quite OK Image format) image
V....D qtrle QuickTime Animation (RLE) video
V....D r10k AJA Kona 10-bit RGB Codec
V....D r210 Uncompressed RGB 10-bit
VF...D rawvideo raw video
V....D roqvideo id RoQ video (codec roq)
V....D rpza QuickTime video (RPZA)
V..... rv10 RealVideo 1.0
V..... rv20 RealVideo 2.0
V....D sgi SGI image
V....D smc QuickTime Graphics (SMC)
V....D snow Snow
V..... speedhq NewTek SpeedHQ
V....D sunrast Sun Rasterfile image
V....D svq1 Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1
V....D targa Truevision Targa image
V....D libtheora libtheora Theora (codec theora)
VF...D tiff TIFF image
VF...D utvideo Ut Video
VF...D v210 Uncompressed 4:2:2 10-bit
V....D v308 Uncompressed packed 4:4:4
V....D v408 Uncompressed packed QT 4:4:4:4
V....D v410 Uncompressed 4:4:4 10-bit
V.S..D vbn Vizrt Binary Image
V..... vnull null video
V....D libvpx libvpx VP8 (codec vp8)
V....D libvpx-vp9 libvpx VP9 (codec vp9)
VF...D wbmp WBMP (Wireless Application Protocol Bitmap) image
V....D libwebp_anim libwebp WebP image (codec webp)
V....D libwebp libwebp WebP image (codec webp)
V..... wmv1 Windows Media Video 7
V..... wmv2 Windows Media Video 8
V..... wrapped_avframe AVFrame to AVPacket passthrough
V....D xbm XBM (X BitMap) image
V....D xface X-face image
V....D xwd XWD (X Window Dump) image
V....D y41p Uncompressed YUV 4:1:1 12-bit
V....D yuv4 Uncompressed packed 4:2:0
VF...D zlib LCL (LossLess Codec Library) ZLIB
V....D zmbv Zip Motion Blocks Video
A....D aac AAC (Advanced Audio Coding)
A..... aac_at aac (AudioToolbox)(codec aac)
A....D ac3 ATSC A/52A (AC-3)
A....D ac3_fixed ATSC A/52A (AC-3)(codec ac3)
A....D adpcm_adx SEGA CRI ADX ADPCM
A....D adpcm_argo ADPCM Argonaut Games
A....D g722 G.722 ADPCM (codec adpcm_g722)
A....D g726 G.726 ADPCM (codec adpcm_g726)
A....D g726le G.726 little endian ADPCM ("right-justified")(codec adpcm_g726le)
A....D adpcm_ima_alp ADPCM IMA High Voltage Software ALP
A....D adpcm_ima_amv ADPCM IMA AMV
A....D adpcm_ima_apm ADPCM IMA Ubisoft APM
A....D adpcm_ima_qt ADPCM IMA QuickTime
A....D adpcm_ima_ssi ADPCM IMA Simon & Schuster Interactive
A....D adpcm_ima_wav ADPCM IMA WAV
A....D adpcm_ima_ws ADPCM IMA Westwood
A....D adpcm_ms ADPCM Microsoft
A....D adpcm_swf ADPCM Shockwave Flash
A....D adpcm_yamaha ADPCM Yamaha
A....D alac ALAC (Apple Lossless Audio Codec)
A..... alac_at alac (AudioToolbox)(codec alac)
A....D libopencore_amrnb OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)(codec amr_nb)
A..... anull null audio
A....D aptx aptX (Audio Processing Technology for Bluetooth)
A....D aptx_hd aptX HD (Audio Processing Technology for Bluetooth)
A....D comfortnoise RFC 3389 comfort noise generator
A....D dfpwm DFPWM1a audio
A..X.D dca DCA (DTS Coherent Acoustics)(codec dts)
A....D eac3 ATSC A/52 E-AC-3
A....D flac FLAC (Free Lossless Audio Codec)
A....D g723_1 G.723.1
A..... ilbc_at ilbc (AudioToolbox)(codec ilbc)
A..X.D mlp MLP (Meridian Lossless Packing)
A....D mp2 MP2 (MPEG audio layer 2)
A....D mp2fixed MP2 fixed point (MPEG audio layer 2)(codec mp2)
A....D libmp3lame libmp3lame MP3 (MPEG audio layer 3)(codec mp3)
A....D nellymoser Nellymoser Asao
A..X.D opus Opus
A....D libopus libopus Opus (codec opus)
A....D pcm_alaw PCM A-law / G.711 A-law
A..... pcm_alaw_at pcm_alaw (AudioToolbox)(codec pcm_alaw)
A....D pcm_bluray PCM signed 16|20|24-bit big-endian for Blu-ray media
A....D pcm_dvd PCM signed 16|20|24-bit big-endian for DVD media
A....D pcm_f32be PCM 32-bit floating point big-endian
A....D pcm_f32le PCM 32-bit floating point little-endian
A....D pcm_f64be PCM 64-bit floating point big-endian
A....D pcm_f64le PCM 64-bit floating point little-endian
A....D pcm_mulaw PCM mu-law / G.711 mu-law
A..... pcm_mulaw_at pcm_mulaw (AudioToolbox)(codec pcm_mulaw)
A....D pcm_s16be PCM signed 16-bit big-endian
A....D pcm_s16be_planar PCM signed 16-bit big-endian planar
A....D pcm_s16le PCM signed 16-bit little-endian
A....D pcm_s16le_planar PCM signed 16-bit little-endian planar
A....D pcm_s24be PCM signed 24-bit big-endian
A....D pcm_s24daud PCM D-Cinema audio signed 24-bit
A....D pcm_s24le PCM signed 24-bit little-endian
A....D pcm_s24le_planar PCM signed 24-bit little-endian planar
A....D pcm_s32be PCM signed 32-bit big-endian
A....D pcm_s32le PCM signed 32-bit little-endian
A....D pcm_s32le_planar PCM signed 32-bit little-endian planar
A....D pcm_s64be PCM signed 64-bit big-endian
A....D pcm_s64le PCM signed 64-bit little-endian
A....D pcm_s8 PCM signed 8-bit
A....D pcm_s8_planar PCM signed 8-bit planar
A....D pcm_u16be PCM unsigned 16-bit big-endian
A....D pcm_u16le PCM unsigned 16-bit little-endian
A....D pcm_u24be PCM unsigned 24-bit big-endian
A....D pcm_u24le PCM unsigned 24-bit little-endian
A....D pcm_u32be PCM unsigned 32-bit big-endian
A....D pcm_u32le PCM unsigned 32-bit little-endian
A....D pcm_u8 PCM unsigned 8-bit
A....D pcm_vidc PCM Archimedes VIDC
A....D real_144 RealAudio 1.0(14.4K)(codec ra_144)
A....D roq_dpcm id RoQ DPCM
A..X.D s302m SMPTE 302M
A....D sbc SBC (low-complexity subband codec)
A..X.D sonic Sonic
A..X.D sonicls Sonic lossless
A....D libspeex libspeex Speex (codec speex)
A..X.D truehd TrueHD
A....D tta TTA (True Audio)
A..X.D vorbis Vorbis
A....D libvorbis libvorbis (codec vorbis)
A....D wavpack WavPack
A....D wmav1 Windows Media Audio 1
A....D wmav2 Windows Media Audio 2
S..... ssa ASS (Advanced SubStation Alpha) subtitle (codec ass)
S..... ass ASS (Advanced SubStation Alpha) subtitle
S..... dvbsub DVB subtitles (codec dvb_subtitle)
S..... dvdsub DVD subtitles (codec dvd_subtitle)
S..... mov_text 3GPP Timed Text subtitle
S..... srt SubRip subtitle (codec subrip)
S..... subrip SubRip subtitle
S..... text Raw text subtitle
S..... ttml TTML subtitle
S..... webvtt WebVTT subtitle
S..... xsub DivX subtitles (XSUB)
Proceso detallado de codificación de video
Como puede verse en el proceso, la función central para completar la codificación es do_video_out(); la API central que implementa la codificación son las dos funciones avcodec_send_frame() y avcodec_receive_packet() ; las dos funciones son algo similares a la máquina de estado, Recibir el marco del marco al paquete de paquete de salida, para completar la codificación al juzgar si hay datos en el búfer.
Introducción a la API básica de codificación
avcodec_send_frame()
Introducción a la Declaración API
/**
* Supply a raw video or audio frame to the encoder. Use avcodec_receive_packet()
* to retrieve buffered output packets.
*
* @param avctx codec context
* @param[in] frame AVFrame containing the raw audio or video frame to be encoded.
* Ownership of the frame remains with the caller, and the
* encoder will not write to the frame. The encoder may create
* a reference to the frame data (or copy it if the frame is
* not reference-counted).
* It can be NULL, in which case it is considered a flush
* packet. This signals the end of the stream. If the encoder
* still has packets buffered, it will return them after this
* call. Once flushing mode has been entered, additional flush
* packets are ignored, and sending frames will return
* AVERROR_EOF.
*
* For audio:
* If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
* can have any number of samples.
* If it is not set, frame->nb_samples must be equal to
* avctx->frame_size for all frames except the last.
* The final frame may be smaller than avctx->frame_size.
* @return 0 on success, otherwise negative error code:
* AVERROR(EAGAIN): input is not accepted in the current state - user
* must read output with avcodec_receive_packet() (once
* all output is read, the packet should be resent, and
* the call will not fail with EAGAIN).
* AVERROR_EOF: the encoder has been flushed, and no new frames can
* be sent to it
* AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a
* decoder, or requires flush
* AVERROR(ENOMEM): failed to add packet to internal queue, or similar
* other errors: legitimate encoding errors
*/intavcodec_send_frame(AVCodecContext *avctx,const AVFrame *frame);
Análisis de definición avcodec_send_frame() llama internamente a encode_send_frame_internal() para comprobar si hay datos en el búfer de tramas. Cuando no hay datos en buffer_pkt, llamar a encode_receive_packet_internal() es la función principal para completar la codificación; en encode_receive_packet_internal(), la llamada principal es encode_simple_receive_packet() para completar la codificación de video; llame a encode_simple_internal () en encode_simple_receive_packet() para completar la codificación de video; en encode_simple_internal(), el puntero de función (*encode2)() se usa principalmente para llamar a varios codificadores de terceros; además, si se trata de una codificación de subprocesos múltiples, pasará ff_thread_video_encode_frame () por hacer.
(*encode2)() usa el puntero de función para apuntar a diferentes codificadores para completar el proceso de codificación específico, como x264, openh264, x265, avs2, videotoolbox, etc.;
/**
* Read encoded data from the encoder.
*
* @param avctx codec context
* @param avpkt This will be set to a reference-counted packet allocated by the
* encoder. Note that the function will always call
* av_packet_unref(avpkt) before doing anything else.
* @return 0 on success, otherwise negative error code:
* AVERROR(EAGAIN): output is not available in the current state - user
* must try to send input
* AVERROR_EOF: the encoder has been fully flushed, and there will be
* no more output packets
* AVERROR(EINVAL): codec not opened, or it is a decoder
* other errors: legitimate encoding errors
*/intavcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
Análisis de definición A partir de la lógica de implementación interna de la función avcode_receive_packet(), podemos ver que primero juzga si buffer_pkt tiene datos y, de ser así, llama a la función av_packet_move_ref() para completar el proceso de copia del paquete; si no hay datos en el buffer_pak, debe llamar a encode_receive_packet_internal() Para completar la codificación, el proceso es el mismo que en el módulo de marco de envío.
Ejemplo de codificación oficial
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*//**
* @file
* video encoding with libavcodec API example
*
* @example encode_video.c
*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<libavcodec/avcodec.h>#include<libavutil/opt.h>#include<libavutil/imgutils.h>staticvoidencode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
FILE *outfile){
int ret;/* send the frame to the encoder */if(frame)printf("Send frame %3"PRId64"\n", frame->pts);
ret =avcodec_send_frame(enc_ctx, frame);if(ret <0){
fprintf(stderr,"Error sending a frame for encoding\n");exit(1);}while(ret >=0){
ret =avcodec_receive_packet(enc_ctx, pkt);if(ret ==AVERROR(EAGAIN)|| ret == AVERROR_EOF)return;elseif(ret <0){
fprintf(stderr,"Error during encoding\n");exit(1);}printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);fwrite(pkt->data,1, pkt->size, outfile);av_packet_unref(pkt);}}intmain(int argc,char**argv){
constchar*filename,*codec_name;const AVCodec *codec;
AVCodecContext *c=NULL;int i, ret, x, y;
FILE *f;
AVFrame *frame;
AVPacket *pkt;uint8_t endcode[]={
0,0,1,0xb7};if(argc <=2){
fprintf(stderr,"Usage: %s <output file> <codec name>\n", argv[0]);exit(0);}
filename = argv[1];
codec_name = argv[2];/* find the mpeg1video encoder */
codec =avcodec_find_encoder_by_name(codec_name);if(!codec){
fprintf(stderr,"Codec '%s' not found\n", codec_name);exit(1);}
c =avcodec_alloc_context3(codec);if(!c){
fprintf(stderr,"Could not allocate video codec context\n");exit(1);}
pkt =av_packet_alloc();if(!pkt)exit(1);/* put sample parameters */
c->bit_rate =400000;/* resolution must be a multiple of two */
c->width =352;
c->height =288;/* frames per second */
c->time_base =(AVRational){
1,25};
c->framerate =(AVRational){
25,1};/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
c->gop_size =10;
c->max_b_frames =1;
c->pix_fmt = AV_PIX_FMT_YUV420P;if(codec->id == AV_CODEC_ID_H264)av_opt_set(c->priv_data,"preset","slow",0);/* open it */
ret =avcodec_open2(c, codec,NULL);if(ret <0){
fprintf(stderr,"Could not open codec: %s\n",av_err2str(ret));exit(1);}
f =fopen(filename,"wb");if(!f){
fprintf(stderr,"Could not open %s\n", filename);exit(1);}
frame =av_frame_alloc();if(!frame){
fprintf(stderr,"Could not allocate video frame\n");exit(1);}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret =av_frame_get_buffer(frame,0);if(ret <0){
fprintf(stderr,"Could not allocate the video frame data\n");exit(1);}/* encode 1 second of video */for(i =0; i <25; i++){
fflush(stdout);/* make sure the frame data is writable */
ret =av_frame_make_writable(frame);if(ret <0)exit(1);/* prepare a dummy image *//* Y */for(y =0; y < c->height; y++){
for(x =0; x < c->width; x++){
frame->data[0][y * frame->linesize[0]+ x]= x + y + i *3;}}/* Cb and Cr */for(y =0; y < c->height/2; y++){
for(x =0; x < c->width/2; x++){
frame->data[1][y * frame->linesize[1]+ x]=128+ y + i *2;
frame->data[2][y * frame->linesize[2]+ x]=64+ x + i *5;}}
frame->pts = i;/* encode the image */encode(c, frame, pkt, f);}/* flush the encoder */encode(c,NULL, pkt, f);/* add sequence end code to have a real MPEG file */if(codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)fwrite(endcode,1,sizeof(endcode), f);fclose(f);avcodec_free_context(&c);av_frame_free(&frame);av_packet_free(&pkt);return0;}