FFmpeg源代碼簡單分析-架構圖-編碼

參考鏈接

  • FFmpeg源代碼結構圖 - 編碼_雷霄驊的博客-CSDN博客_ffmpeg 源碼

函數背景色

  • 函數在圖中以方框的形式表現出來。不同的背景色標志了該函數不同的作用:
    • 粉紅色背景函數:FFmpeg的API函數。
    • 白色背景的函數:FFmpeg的內部函數。
    • 黃色背景的函數:URLProtocol結構體中的函數,包含了讀寫各種協議的功能。
    • 綠色背景的函數:AVOutputFormat結構體中的函數,包含了讀寫各種封裝格式的功能。
    • 藍色背景的函數:AVCodec結構體中的函數,包含了編解碼的功能。

區域

  • 整個關系圖可以分為以下幾個區域:
    • 左邊區域——架構函數區域:這些函數并不針對某一特定的視頻格式。
    • 右上方黃色區域——協議處理函數區域:不同的協議(RTP,RTMP,FILE)會調用不同的協議處理函數。
    • 右邊中間綠色區域——封裝格式處理函數區域:不同的封裝格式(MKV,FLV,MPEG2TS,AVI)會調用不同的封裝格式處理函數。
    • 右邊下方藍色區域——編解碼函數區域:不同的編碼標準(HEVC,H.264,MPEG2)會調用不同的編解碼函數。

箭頭線

  • 為了把調用關系表示的更明顯,圖中的箭頭線也使用了不同的顏色:
    • 紅色的箭頭線:標志了編碼的流程。
    • 其他顏色的箭頭線:標志了函數之間的調用關系。其中:
      • 調用URLProtocol結構體中的函數用黃色箭頭線標識;
      • 調用AVOutputFormat結構體中的函數用綠色箭頭線標識;
      • 調用AVCodec結構體中的函數用藍色箭頭線標識。

函數所在的文件

  • 每個函數標識了它所在的文件路徑。

模塊介紹

  • 和解碼重合的內容,請參考下面的鏈接
  • ??????FFmpeg源代碼簡單分析-架構圖-解碼_MY CUP OF TEA的博客-CSDN博客

右中區域(AVOutputFormat封裝格式處理函數)

  • AVOutputFormat包含如下封裝格式處理函數指針:
    • write_header():寫文件頭
    • write_packet():寫一幀數據
    • write_trailer():寫文件尾
  • 參考鏈接:FFmpeg: AVOutputFormat Struct Reference
typedef struct AVOutputFormat {const char *name;/*** Descriptive name for the format, meant to be more human-readable* than name. You should use the NULL_IF_CONFIG_SMALL() macro* to define it.*/const char *long_name;const char *mime_type;const char *extensions; /**< comma-separated filename extensions *//* output support */enum AVCodecID audio_codec;    /**< default audio codec */enum AVCodecID video_codec;    /**< default video codec */enum AVCodecID subtitle_codec; /**< default subtitle codec *//*** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER,* AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,* AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,* AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE*/int flags;/*** List of supported codec_id-codec_tag pairs, ordered by "better* choice first". The arrays are all terminated by AV_CODEC_ID_NONE.*/const struct AVCodecTag * const *codec_tag;const AVClass *priv_class; ///< AVClass for the private context/****************************************************************** No fields below this line are part of the public API. They* may not be used outside of libavformat and can be changed and* removed at will.* New public fields should be added right above.******************************************************************//*** size of private data so that it can be allocated in the wrapper*/int priv_data_size;/*** Internal flags. See FF_FMT_FLAG_* in internal.h.*/int flags_internal;int (*write_header)(struct AVFormatContext *);/*** Write a packet. If AVFMT_ALLOW_FLUSH is set in flags,* pkt can be NULL in order to flush data buffered in the muxer.* When flushing, return 0 if there still is more data to flush,* or 1 if everything was flushed and there is no more buffered* data.*/int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);int (*write_trailer)(struct AVFormatContext *);/*** A format-specific function for interleavement.* If unset, packets will be interleaved by dts.** @param s           An AVFormatContext for output. pkt will be added to*                    resp. taken from its packet buffer.* @param[in,out] pkt A packet to be interleaved if has_packet is set;*                    also used to return packets. If no packet is returned*                    (e.g. on error), pkt is blank on return.* @param flush       1 if no further packets are available as input and*                    all remaining packets should be output.* @param has_packet  If set, pkt contains a packet to be interleaved*                    on input; otherwise pkt is blank on input.* @return 1 if a packet was output, 0 if no packet could be output,*         < 0 if an error occurred*/int (*interleave_packet)(struct AVFormatContext *s, AVPacket *pkt,int flush, int has_packet);/*** Test if the given codec can be stored in this container.** @return 1 if the codec is supported, 0 if it is not.*         A negative number if unknown.*         MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC*/int (*query_codec)(enum AVCodecID id, int std_compliance);void (*get_output_timestamp)(struct AVFormatContext *s, int stream,int64_t *dts, int64_t *wall);/*** Allows sending messages from application to device.*/int (*control_message)(struct AVFormatContext *s, int type,void *data, size_t data_size);/*** Write an uncoded AVFrame.** See av_write_uncoded_frame() for details.** The library will free *frame afterwards, but the muxer can prevent it* by setting the pointer to NULL.*/int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index,AVFrame **frame, unsigned flags);/*** Returns device list with it properties.* @see avdevice_list_devices() for more details.*/int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list);enum AVCodecID data_codec; /**< default data codec *//*** Initialize format. May allocate data here, and set any AVFormatContext or* AVStream parameters that need to be set before packets are sent.* This method must not write output.** Return 0 if streams were fully configured, 1 if not, negative AVERROR on failure** Any allocations made here must be freed in deinit().*/int (*init)(struct AVFormatContext *);/*** Deinitialize format. If present, this is called whenever the muxer is being* destroyed, regardless of whether or not the header has been written.** If a trailer is being written, this is called after write_trailer().** This is called if init() fails as well.*/void (*deinit)(struct AVFormatContext *);/*** Set up any necessary bitstream filtering and extract any extra data needed* for the global header.** @note pkt might have been directly forwarded by a meta-muxer; therefore*       pkt->stream_index as well as the pkt's timebase might be invalid.* Return 0 if more packets from this stream must be checked; 1 if not.*/int (*check_bitstream)(struct AVFormatContext *s, struct AVStream *st,const AVPacket *pkt);
} AVOutputFormat;

注意事項?

  • 【例子】不同的封裝格式對應著上述接口有不同的實現函數,舉幾個例子:
  • FLV封裝格式對應的AVOutputFormat結構體ff_flv_muxer:
    • write_header() -> flv_write_header()
    • write_packet() –> flv_write_packet()
    • write_trailer() -> flv_write_trailer()
  • 參考鏈接:FFmpeg: libavformat/flvenc.c File Reference
= {.name           = "flv",.long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),.mime_type      = "video/x-flv",.extensions     = "flv",.priv_data_size = sizeof(FLVContext),.audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,.video_codec    = AV_CODEC_ID_FLV1,.write_header   = flv_write_header,.write_packet   = flv_write_packet,.write_trailer  = flv_write_trailer,.codec_tag      = (const * const []) {flv_video_codec_ids, flv_audio_codec_ids, 0},.flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |AVFMT_TS_NONSTRICT,
}
  • MKV封裝格式對應的AVOutputFormat結構體ff_matroska_muxer:
    • write_header() -> mkv_write_header()
    • write_packet() –> mkv_write_flush_packet()
    • write_trailer() -> mkv_write_trailer()
  • 結構體ff_matroska_muxer 已經不存在
  • 參考鏈接:FFmpeg: libavformat/matroskaenc.c Source File
 const AVOutputFormat ff_matroska_muxer = {.name              = "matroska",.long_name         = NULL_IF_CONFIG_SMALL("Matroska"),.mime_type         = "video/x-matroska",.extensions        = "mkv",.priv_data_size    = sizeof(MatroskaMuxContext),.audio_codec       = CONFIG_LIBVORBIS_ENCODER ?AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3,.video_codec       = CONFIG_LIBX264_ENCODER ?AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,.init              = mkv_init,.deinit            = mkv_deinit,.write_header      = mkv_write_header,.write_packet      = mkv_write_flush_packet,.write_trailer     = mkv_write_trailer,.flags             = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,.codec_tag         = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags,additional_audio_tags, additional_video_tags, additional_subtitle_tags, 0},.subtitle_codec    = AV_CODEC_ID_ASS,.query_codec       = mkv_query_codec,.check_bitstream   = mkv_check_bitstream,.priv_class        = &matroska_webm_class,};#endif
  • MPEG2TS封裝格式對應的AVOutputFormat結構體ff_mpegts_muxer:
    • write_header() -> mpegts_write_header()
    • write_packet() –> mpegts_write_packet()
    • write_trailer() -> mpegts_write_end()
  • 參考鏈接:FFmpeg: libavformat/mpegtsenc.c File Reference
= {.name           = "mpegts",.long_name      = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),.mime_type      = "video/MP2T",.extensions     = "ts,m2t,m2ts,mts",.priv_data_size = sizeof(MpegTSWrite),.audio_codec    = AV_CODEC_ID_MP2,.video_codec    = AV_CODEC_ID_MPEG2VIDEO,.write_header   = mpegts_write_header,.write_packet   = mpegts_write_packet,.write_trailer  = mpegts_write_end,.flags          = AVFMT_ALLOW_FLUSH | AVFMT_VARIABLE_FPS,.priv_class     = &mpegts_muxer_class,
}
  • AVI封裝格式對應的AVOutputFormat結構體ff_avi_muxer:
    • write_header() -> avi_write_header()
    • write_packet() –> avi_write_packet()
    • write_trailer() -> avi_write_trailer()
  • 參考鏈接:FFmpeg: libavformat/avienc.c File Reference
= {.name           = "avi",.long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),.mime_type      = "video/x-msvideo",.extensions     = "avi",.priv_data_size = sizeof(AVIContext),.audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_AC3,.video_codec    = AV_CODEC_ID_MPEG4,.write_header   = avi_write_header,.write_packet   = avi_write_packet,.write_trailer  = avi_write_trailer,.codec_tag      = (const AVCodecTag * const []) {ff_codec_bmp_tags, ff_codec_wav_tags, 0},
}

右下區域(AVCodec編解碼函數)

  • AVCodec包含如下編解碼函數指針:
    • init():初始化
    • encode2():編碼一幀數據
    • close():關閉
  • 參考鏈接:FFmpeg: AVCodec Struct Reference
  • 上述參考鏈接里面包含的結構體包含上述編解碼函數指針
  • 但是新版本好像沒有了
typedef struct AVCodec {/*** Name of the codec implementation.* The name is globally unique among encoders and among decoders (but an* encoder and a decoder can share the same name).* This is the primary way to find a codec from the user perspective.*/const char *name;/*** Descriptive name for the codec, meant to be more human readable than name.* You should use the NULL_IF_CONFIG_SMALL() macro to define it.*/const char *long_name;enum AVMediaType type;enum AVCodecID id;/*** Codec capabilities.* see AV_CODEC_CAP_**/int capabilities;uint8_t max_lowres; ? ? ? ? ? ? ? ? ? ? ///< maximum value for lowres supported by the decoderconst AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}const enum AVPixelFormat *pix_fmts; ? ? ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1const int *supported_samplerates; ? ? ? ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
#if FF_API_OLD_CHANNEL_LAYOUT/*** @deprecated use ch_layouts instead*/attribute_deprecatedconst uint64_t *channel_layouts; ? ? ? ? ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
#endifconst AVClass *priv_class; ? ? ? ? ? ? ?///< AVClass for the private contextconst AVProfile *profiles; ? ? ? ? ? ? ?///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}/*** Group name of the codec implementation.* This is a short symbolic name of the wrapper backing this codec. A* wrapper uses some kind of external implementation for the codec, such* as an external library, or a codec implementation provided by the OS or* the hardware.* If this field is NULL, this is a builtin, libavcodec native codec.* If non-NULL, this will be the suffix in AVCodec.name in most cases* (usually AVCodec.name will be of the form "<codec_name>_<wrapper_name>").*/const char *wrapper_name;/*** Array of supported channel layouts, terminated with a zeroed layout.*/const AVChannelLayout *ch_layouts;
} AVCodec;

注意事項:

  • 【例子】不同的編解碼器對應著上述接口有不同的實現函數,舉幾個例子:
  • HEVC編碼器對應的AVCodec結構體ff_libx265_encoder:
    • init() -> libx265_encode_init() -> x265_param_alloc(), x265_param_default_preset(), x265_encoder_open()
    • encode2() -> libx265_encode_frame() -> x265_encoder_encode()
    • close() -> libx265_encode_close() -> x265_param_free(), x265_encoder_close()
  • 參考鏈接:FFmpeg: libavcodec/libx265.c File Reference
= {.name             = "libx265",.long_name        = NULL_IF_CONFIG_SMALL("libx265 H.265 / HEVC"),.type             = AVMEDIA_TYPE_VIDEO,.id               = AV_CODEC_ID_HEVC,.init             = libx265_encode_init,.init_static_data = libx265_encode_init_csp,.encode2          = libx265_encode_frame,.close            = libx265_encode_close,.priv_data_size   = sizeof(libx265Context),.priv_class       = &class,.defaults         = x265_defaults,.capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
}
  • H.264編碼器對應的AVCodec結構體ff_libx264_encoder:
    • init() -> X264_init() -> x264_param_default(), x264_encoder_open(), x264_encoder_headers()
    • encode2() -> X264_frame() -> x264_encoder_encode()
    • close() -> X264_close() -> x264_encoder_close()
  • 參考鏈接:FFmpeg: libavcodec/libx264.c File Reference
{.name           = "libx264",.type           = AVMEDIA_TYPE_VIDEO,.id             = CODEC_ID_H264,.priv_data_size = sizeof(X264Context),.init           = X264_init,.encode         = X264_frame,.close          = X264_close,.capabilities   = CODEC_CAP_DELAY,.pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_YUVJ420P, PIX_FMT_NONE },.long_name      = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),.priv_class     = &class,
}
  • VP8編碼器(libVPX)對應的AVCodec結構體ff_libvpx_vp8_encoder:
    • init() -> vpx_init() -> vpx_codec_enc_config_default()
    • encode2() -> vp8_encode() -> vpx_codec_enc_init(), vpx_codec_encode()
    • close() -> vp8_free() -> vpx_codec_destroy()
  • 參考鏈接:FFmpeg/libvpxenc.c at master · FFmpeg/FFmpeg · GitHub
const FFCodec ff_libvpx_vp8_encoder = {.p.name         = "libvpx",.p.long_name    = NULL_IF_CONFIG_SMALL("libvpx VP8"),.p.type         = AVMEDIA_TYPE_VIDEO,.p.id           = AV_CODEC_ID_VP8,.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |AV_CODEC_CAP_OTHER_THREADS,.priv_data_size = sizeof(VPxContext),.init           = vp8_init,FF_CODEC_ENCODE_CB(vpx_encode),.close          = vpx_free,.caps_internal  = FF_CODEC_CAP_AUTO_THREADS,.p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },.p.priv_class   = &class_vp8,.defaults       = defaults,.p.wrapper_name = "libvpx",
};
  • MPEG2編碼器對應的AVCodec結構體ff_mpeg2video_encoder:
    • init() -> encode_init()
    • encode2() -> ff_mpv_encode_picture()
    • close() -> ff_mpv_encode_end()
  • 參考鏈接:FFmpeg: libavcodec/mpeg12enc.c File Reference
= {.name                 = "mpeg2video",.long_name            = NULL_IF_CONFIG_SMALL("MPEG-2 video"),.type                 = AVMEDIA_TYPE_VIDEO,.id                   = AV_CODEC_ID_MPEG2VIDEO,.priv_data_size       = sizeof(MpegEncContext),.init                 = encode_init,.encode2              = ff_mpv_encode_picture,.close                = ff_mpv_encode_end,.supported_framerates = ff_mpeg2_frame_rate_tab,.pix_fmts             = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_NONE },.capabilities         = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,.priv_class           = &mpeg2_class,
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446008.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446008.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446008.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

為革命,保護視力——為Eclipse更換暗黑皮膚及編輯頁面的字體顏色主題

1.在Eclipse中的菜單欄的Help -> Eclipse Market 的 Search欄中輸入 Eclipse Moonrise UI Theme &#xff0c;之后自己執生啦&#xff08;確保上網配置正確&#xff09;。 2.與上面操作類似&#xff0c;輸入 Eclipse Color Theme&#xff0c;選擇安裝。 3.選擇菜單欄的Win…

python函數可以作為容器對象嗎_正確理解Python函數是第一類對象

正確理解 Python函數&#xff0c;能夠幫助我們更好地理解 Python 裝飾器、匿名函數(lambda)、函數式編程等高階技術。函數(Function)作為程序語言中不可或缺的一部分&#xff0c;太稀松平常了。但函數作為第一類對象(First-Class Object)卻是 Python 函數的一大特性。那到底什么…

FFmpeg源代碼簡單分析-通用- av_register_all()

參考鏈接 ffmpeg 源代碼簡單分析 &#xff1a; av_register_all()_雷霄驊的博客-CSDN博客_av_register_all()從學齡前開始解讀FFMPEG代碼 之 avcodec_register_all函數_zzyincsdn的博客-CSDN博客

@suppressWarnings(unchecked)及其相關屬性在Java中意思

首先suppressWarnings("unchecked")是JDK1.5中新加入的Annotation語法&#xff0c;用來壓制警告信息的。 編寫代碼時&#xff0c;有時會提示一些警告&#xff08;例如&#xff1a;使用已經廢棄的類&#xff0c;沒有加入泛型等&#xff09;&#xff0c;如果不想讓程序…

FFmpeg源代碼簡單分析-通用-avcodec_register_all()

參考鏈接 ffmpeg 源代碼簡單分析 &#xff1a; avcodec_register_all()_雷霄驊的博客-CSDN博客

pythonsklearn乳腺癌數據集_Python的Sklearn庫中的數據集

一、Sklearn介紹scikit-learn是Python語言開發的機器學習庫&#xff0c;一般簡稱為sklearn&#xff0c;目前算是通用機器學習算法庫中實現得比較完善的庫了。其完善之處不僅在于實現的算法多&#xff0c;還包括大量詳盡的文檔和示例。其文檔寫得通俗易懂&#xff0c;完全可以當…

FFmpeg源代碼簡單分析-通用- 內存的分配和釋放(av_malloc()、av_free()等)

參考鏈接 FFmpeg源代碼簡單分析&#xff1a;內存的分配和釋放&#xff08;av_malloc()、av_free()等&#xff09;_雷霄驊的博客-CSDN博客_av_malloc 內容介紹 內存操作的常見函數位于libavutil\mem.c中本文記錄最常使用的幾個函數&#xff1a; av_malloc()av_realloc()av_mal…

面試題——死鎖的實現

public class DeadLock {public static Object Chopstick_1 new Object();public static Object Chopstick_2 new Object();public static void main(String[] args) {final DeadLock deadLock new DeadLock();// 第一個線程 new Thread(new Runnable() {public void run()…

python回歸分析實驗_python線性回歸實驗

實驗算法python線性回歸實驗【實驗名稱】Python線性回歸實驗【實驗要求】掌握Python線性回歸模型應用過程&#xff0c;根據模型要求進行數據預處理&#xff0c;建模&#xff0c;評價與應用&#xff1b;【背景描述】線性回歸是利用數理統計中回歸分析&#xff0c;來確定兩種或兩…

FFmpeg源代碼簡單分析-通用-結構體分析-AVFormatContext

參考鏈接 FFMPEG結構體分析&#xff1a;AVFormatContext_雷霄驊的博客-CSDN博客_avformatcontext AVFormatContext AVFormatContext是包含碼流參數較多的結構體結構體的定義位于libavformat/avformat.h/*** Format I/O context.//格式化 I/O 上下文* New fields can be added…

log4j詳解與實戰

log4j詳解與實戰 http://www.iteye.com/topic/378077

plsql如何顯示表結構圖_【論文攻略】排版技巧——如何用 Word 編輯參考文獻

每個需要寫畢業論文的朋友都會發現&#xff0c;修改文獻是一件非常痛苦的事情&#xff0c;雖然現在也有很多軟件可以編排參考文獻&#xff0c;其實 word 本身就可以。采用合適的編輯方法會方便地做到整齊,規范, 自動排序和交叉引用。 1. 以尾注的方式插入第一個參考文獻將光標定…

FFmpeg源代碼簡單分析-通用-結構體分析-AVCodecContext

參考鏈接 FFMPEG結構體分析&#xff1a;AVCodecContext_雷霄驊的博客-CSDN博客_avcodeccontext AVCodecContext AVCodecContext是包含變量較多的結構體&#xff08;感覺差不多是變量最多的結構體&#xff09;結構體的定義位于avcodec.h關鍵的變量如下所示&#xff08;僅僅考慮…

Hello OpenGL——OpenGL在Visual c++6.0安裝和配置

1、下載并安裝glut庫opengl的glut庫 GLUT不是OpenGL所必須的&#xff0c;但它會給我們的學習帶來一定的方便&#xff0c;推薦安裝。 Windows環境下的GLUT下載地址&#xff1a;&#xff08;大小約為150k&#xff09; http://www.opengl.org/resources/libraries/glut/glutdlls37…

FFmpeg源代碼簡單分析-通用-結構體分析-AVIOContext

參考鏈接 FFMPEG結構體分析&#xff1a;AVIOContext_雷霄驊的博客-CSDN博客_aviocontext AVIOContext AVIOContext是FFMPEG管理輸入輸出數據的結構體結構體的定義位于位于avio.h關鍵的變量如下所示 unsigned char *buffer&#xff1a;緩存開始位置int buffer_size&#xff1…

初聞動態規劃

前言 本文以一道常見的算法面試題開篇&#xff0c;引入動態規劃的基礎概念&#xff0c; 介紹其思考過程。 正文 一、常見的一道算法面試題——上臺階 有一個樓梯總共n個臺階&#xff0c;只能往上走&#xff0c;每次只能上1個、2個臺階&#xff0c;總共有多少種走法。 解決…

FFmpeg源代碼簡單分析-通用-結構體分析-AVCodec

參考鏈接 FFMPEG結構體分析&#xff1a;AVCodec_雷霄驊的博客-CSDN博客_avcodec AVCodec AVCodec是存儲編解碼器信息的結構體結構體的定義位于avcodec.h文件中最主要的幾個變量 const char *name&#xff1a;編解碼器的名字&#xff0c;比較短const char *long_name&#xff…

SLF4J簡介與使用(整合log4j)

SLF4J簡介與使用(整合log4j) 一、概念 SLF4J的全稱是Simple Logging Facade for Java&#xff0c;即簡單日志門面。SLF4J并不是具體的日志框架&#xff0c;而是作為一個簡單門面服務于各類日志框架&#xff0c;如java.util.logging, logback和log4j。 SLF4J提供了統一的記錄…

multism中ui和uo應該怎么表示_王者榮耀:夢淚直播時談到體驗服大改動,表示裝備的改動很關鍵...

王者榮耀的主播夢淚&#xff0c;大家都很熟了&#xff0c;也是一個很強的主播&#xff0c;他對于王者榮耀的理解&#xff0c;還是非常深刻的&#xff0c;而最近王者榮耀的體驗服&#xff0c;進行了大改動&#xff0c;也是改變了很多的東西。對此&#xff0c;網友們也是非常的在…

FFmpeg源代碼簡單分析-通用-結構體分析-AVStream

參考鏈接 FFMPEG結構體分析&#xff1a;AVStream_雷霄驊的博客-CSDN博客_avstream AVStream AVStream是是存儲每一個視頻/音頻流信息的結構體結構體的定義位于avformat.h重要參數介紹 int index&#xff1a;標識該視頻/音頻流AVCodecContext *codec&#xff1a;指向該視頻/音…