日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android FFMPEG 开发】FFMPEG 获取编解码器 ( 获取编解码参数 | 查找编解码器 | 获取编解码器上下文 | 设置上下文参数 | 打开编解码器 )

發(fā)布時間:2025/6/17 Android 34 豆豆

文章目錄

        • 博客簡介 . FFMPEG 編解碼器獲取流程
        • I . FFMPEG 獲取音視頻流的編解碼參數(shù) AVCodecParameters *codecpar
        • II . FFMPEG 查找解碼器 avcodec_find_decoder ( )
        • III . FFMPEG 獲取編解碼器上下文 avcodec_alloc_context3 ( )
        • IV . FFMPEG 設置編解碼器上下文參數(shù) avcodec_parameters_to_context ( )
        • V . FFMPEG 打開編解碼器 avcodec_open2 ( )
        • VI . FFMPEG 獲取編解碼器 代碼示例



博客簡介 . FFMPEG 編解碼器獲取流程



FFMPEG 編解碼器獲取流程 : 在獲取音視頻流 AVStream *stream 之后 , 執(zhí)行以下流程 ;


〇 獲取 AVStream * 音視頻流 ( 獲取編解碼器前提 ) : 參考博客 【Android FFMPEG 開發(fā)】FFMPEG 獲取 AVStream 音視頻流 ( AVFormatContext 結(jié)構(gòu)體 | 獲取音視頻流信息 | 獲取音視頻流個數(shù) | 獲取音視頻流 )


① 獲取音視頻流的編碼參數(shù) : AVStream *stream 結(jié)構(gòu)體的 AVCodecParameters *codecpar 元素是音視頻流的編解碼參數(shù) ; 包含 碼率 , 寬度 , 高度 , 采樣率 等參數(shù)信息 ;

//解碼這個媒體流的參數(shù)信息 , 包含 碼率 , 寬度 , 高度 , 采樣率 等參數(shù)信息 AVCodecParameters *codecParameters = stream->codecpar;

② 查找編解碼器 : 調(diào)用 avcodec_find_decoder ( ) 獲取當前音視頻流使用的編解碼器 ;

//① 查找 當前流 使用的編碼方式 , 進而查找編解碼器 ( 可能失敗 , 不支持的解碼方式 ) AVCodec *avCodec = avcodec_find_decoder(codecParameters->codec_id);

③ 獲取編解碼器上下文 : 調(diào)用 avcodec_alloc_context3 ( ) 方法 , 獲取編解碼器上下文 ;

//② 獲取編解碼器上下文 AVCodecContext *avCodecContext = avcodec_alloc_context3(avCodec);

④ 設置編解碼器上下文參數(shù) : 調(diào)用 avcodec_parameters_to_context ( ) 方法 , 設置編解碼器的上下文參數(shù) ;

//③ 設置 編解碼器上下文 參數(shù) // int avcodec_parameters_to_context(AVCodecContext *codec, // const AVCodecParameters *par); // 返回值 > 0 成功 , < 0 失敗 int parameters_to_context_result =avcodec_parameters_to_context(avCodecContext, codecParameters);

⑤ 打開編解碼器 : 調(diào)用 avcodec_open2 ( ) 方法 , 打開編解碼器 ;

//④ 打開編解碼器 // int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, // 返回 0 成功 , 其它失敗 int open_codec_result = avcodec_open2(avCodecContext, avCodec, 0);

I . FFMPEG 獲取音視頻流的編解碼參數(shù) AVCodecParameters *codecpar



1 . 編解碼參數(shù)封裝在 AVStream 結(jié)構(gòu)體中 : FFMPEG 音視頻流的編碼參數(shù) AVCodecParameters *codecpar 是 AVStream 結(jié)構(gòu)體的元素 ;

/*** Stream structure.* New fields can be added to the end with minor version bumps.* Removal, reordering and changes to existing fields require a major* version bump.* sizeof(AVStream) must not be used outside libav*.*/ typedef struct AVStream {.../*** Codec parameters associated with this stream. Allocated and freed by* libavformat in avformat_new_stream() and avformat_free_context()* respectively.** - demuxing: filled by libavformat on stream creation or in* avformat_find_stream_info()* - muxing: filled by the caller before avformat_write_header()*/AVCodecParameters *codecpar;... }AVStream;

2 . FFMPEG 獲取音視頻流的編碼參數(shù) 示例 : 其中 AVStream *stream 是之前獲取的音視頻流結(jié)構(gòu)體指針 ;

//解碼這個媒體流的參數(shù)信息 , 包含 碼率 , 寬度 , 高度 , 采樣率 等參數(shù)信息 AVCodecParameters *codecParameters = stream->codecpar;

3 . 編解碼參數(shù) AVCodecParameters *codecpar 中封裝的數(shù)據(jù) : 這里只列舉我們需要使用的 ;

① enum AVCodecID codec_id : 編解碼器使用的編碼數(shù)據(jù)的特定類型 , 需要使用該值獲取解碼器 ;

/*** This struct describes the properties of an encoded stream.** sizeof(AVCodecParameters) is not a part of the public ABI, this struct must* be allocated with avcodec_parameters_alloc() and freed with* avcodec_parameters_free().*/ typedef struct AVCodecParameters{.../*** Specific type of the encoded data (the codec used).*/enum AVCodecID codec_id;... }AVCodecParameters;

II . FFMPEG 查找解碼器 avcodec_find_decoder ( )



1 . avcodec_find_decoder ( ) 函數(shù)原型 : 根據(jù)編解碼器 ID , 查找被注冊的解碼器 ;


① enum AVCodecID id 參數(shù) : 代表了一個編碼數(shù)據(jù)的特定類型 ; ( 詳情查看 I . 3 . ① 小節(jié)內(nèi)容 )

② AVCodec *avCodec 返回值 : 返回值是 AVCodec * 結(jié)構(gòu)體指針類型變量 , 代表了獲取的解碼器 ;

/** avcodec.h* Find a registered decoder with a matching codec ID.** @param id AVCodecID of the requested decoder* @return A decoder if one was found, NULL otherwise.*/ AVCodec *avcodec_find_decoder(enum AVCodecID id);

2 . FFMPEG 查找解碼器 avcodec_find_decoder ( ) 使用示例 :

//① 查找 當前流 使用的編碼方式 , 進而查找編解碼器 ( 可能失敗 , 不支持的解碼方式 ) AVCodec *avCodec = avcodec_find_decoder(codecParameters->codec_id); //查找失敗處理 if(avCodec == NULL){//如果沒有找到編解碼器 , 回調(diào)失敗 , 方法直接返回 , 后續(xù)代碼不執(zhí)行callHelper->onError(pid, 2);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "查找 編解碼器 失敗");return; }

III . FFMPEG 獲取編解碼器上下文 avcodec_alloc_context3 ( )



avcodec_alloc_context3 ( ) 函數(shù)原型 : 獲取編解碼器上下文 ;


① const AVCodec *codec 參數(shù) : 要獲取上下文的編解碼器 ;

② AVCodecContext *avCodecContext 返回值 : 編解碼器上下文 , 封裝了很多編解碼器相關參數(shù) ; 如果為 NULL , 說明獲取失敗 ;

/** avcodec.h* Allocate an AVCodecContext and set its fields to default values. The* resulting struct should be freed with avcodec_free_context().** @param codec if non-NULL, allocate private data and initialize defaults* for the given codec. It is illegal to then call avcodec_open2()* with a different codec.* If NULL, then the codec-specific defaults won't be initialized,* which may result in suboptimal default settings (this is* important mainly for encoders, e.g. libx264).** @return An AVCodecContext filled with default values or NULL on failure.*/ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);

2 . FFMPEG 獲取編解碼器上下文 avcodec_alloc_context3 ( ) 使用示例 :

//② 獲取編解碼器上下文 AVCodecContext *avCodecContext = avcodec_alloc_context3(avCodec); //獲取編解碼器失敗處理 if(avCodecContext == NULL){callHelper->onError(pid, 3);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "創(chuàng)建編解碼器上下文 失敗");return; }

IV . FFMPEG 設置編解碼器上下文參數(shù) avcodec_parameters_to_context ( )



1 . avcodec_parameters_to_context ( ) 函數(shù)原型 : 基于編解碼器提供的編解碼參數(shù)設置編解碼器上下文參數(shù) ;


① AVCodecContext *codec 參數(shù) : 要設置參數(shù)的編解碼器上下文 , 這里當做返回值使用 , 這個值之后還要使用 ;

② const AVCodecParameters *par 參數(shù) : 媒體流的參數(shù)信息 , 包含 碼率 , 寬度 , 高度 , 采樣率 等參數(shù)信息 , 是 AVStream 結(jié)構(gòu)體封裝的元素 ;

③ 返回值 : 如果返回值 >= 0 , 說明設置編解碼器上下文參數(shù)操作成功 , 如果 < 0 , 設置失敗 ;

/*** Fill the codec context based on the values from the supplied codec* parameters. Any allocated fields in codec that have a corresponding field in* par are freed and replaced with duplicates of the corresponding field in par.* Fields in codec that do not have a counterpart in par are not touched.** @return >= 0 on success, a negative AVERROR code on failure.*/ int avcodec_parameters_to_context(AVCodecContext *codec,const AVCodecParameters *par);

2 . FFMPEG 設置編解碼器上下文參數(shù) avcodec_parameters_to_context ( ) 使用示例 :

//③ 設置 編解碼器上下文 參數(shù) // int avcodec_parameters_to_context(AVCodecContext *codec, // const AVCodecParameters *par); // 返回值 > 0 成功 , < 0 失敗 int parameters_to_context_result =avcodec_parameters_to_context(avCodecContext, codecParameters); //設置 編解碼器上下文 參數(shù) 失敗處理 if(parameters_to_context_result < 0){callHelper->onError(pid, 4);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "設置編解碼器上下文參數(shù) 失敗");return; }

V . FFMPEG 打開編解碼器 avcodec_open2 ( )



1 . avcodec_open2 ( ) 函數(shù)原型 : 打開編解碼器 , 之前必須先初始化編解碼器上下文 AVCodecContext ;


① AVCodecContext *avctx 參數(shù) : 之前根據(jù)編解碼器獲取上下文參數(shù) avcodec_alloc_context3(avCodec) , 并為其設置了音視頻流編解碼參數(shù) avcodec_parameters_to_context(avCodecContext, codecParameters) ;

② const AVCodec *codec 參數(shù) : 需要打開的編解碼上下文對應的編解碼器 ;

③ 返回值 : 返回 0 成功 , 其它值 失敗 ;

/*** Initialize the AVCodecContext to use the given AVCodec. Prior to using this* function the context has to be allocated with avcodec_alloc_context3().** The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),* avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for* retrieving a codec.** @warning This function is not thread safe!** @note Always call this function before using decoding routines (such as* @ref avcodec_receive_frame()).** @code* avcodec_register_all();* av_dict_set(&opts, "b", "2.5M", 0);* codec = avcodec_find_decoder(AV_CODEC_ID_H264);* if (!codec)* exit(1);** context = avcodec_alloc_context3(codec);** if (avcodec_open2(context, codec, opts) < 0)* exit(1);* @endcode** @param avctx The context to initialize.* @param codec The codec to open this context for. If a non-NULL codec has been* previously passed to avcodec_alloc_context3() or* for this context, then this parameter MUST be either NULL or* equal to the previously passed codec.* @param options A dictionary filled with AVCodecContext and codec-private options.* On return this object will be filled with options that were not found.** @return zero on success, a negative value on error* @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),* av_dict_set(), av_opt_find().*/ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);

2 . FFMPEG 打開編解碼器 avcodec_open2 ( ) 使用示例 :

//④ 打開編解碼器 // int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); // 返回 0 成功 , 其它失敗 int open_codec_result = avcodec_open2(avCodecContext, avCodec, 0); //打開編解碼器 失敗處理 if(open_codec_result != 0){callHelper->onError(pid, 5);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "打開 編解碼器 失敗");return; }

VI . FFMPEG 獲取編解碼器 代碼示例



//視頻 / 音頻 處理需要的操作 ( 獲取編解碼器 )//① 查找 當前流 使用的編碼方式 , 進而查找編解碼器 ( 可能失敗 , 不支持的解碼方式 )AVCodec *avCodec = avcodec_find_decoder(codecParameters->codec_id);//查找失敗處理if(avCodec == NULL){//如果沒有找到編解碼器 , 回調(diào)失敗 , 方法直接返回 , 后續(xù)代碼不執(zhí)行callHelper->onError(pid, 2);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "查找 編解碼器 失敗");return;}//② 獲取編解碼器上下文AVCodecContext *avCodecContext = avcodec_alloc_context3(avCodec);//獲取編解碼器失敗處理if(avCodecContext == NULL){callHelper->onError(pid, 3);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "創(chuàng)建編解碼器上下文 失敗");return;}//③ 設置 編解碼器上下文 參數(shù)// int avcodec_parameters_to_context(AVCodecContext *codec,// const AVCodecParameters *par);// 返回值 > 0 成功 , < 0 失敗int parameters_to_context_result =avcodec_parameters_to_context(avCodecContext, codecParameters);//設置 編解碼器上下文 參數(shù) 失敗處理if(parameters_to_context_result < 0){callHelper->onError(pid, 4);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "設置編解碼器上下文參數(shù) 失敗");return;}//④ 打開編解碼器// int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);// 返回 0 成功 , 其它失敗int open_codec_result = avcodec_open2(avCodecContext, avCodec, 0);//打開編解碼器 失敗處理if(open_codec_result != 0){callHelper->onError(pid, 5);__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "打開 編解碼器 失敗");return;} 《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的【Android FFMPEG 开发】FFMPEG 获取编解码器 ( 获取编解码参数 | 查找编解码器 | 获取编解码器上下文 | 设置上下文参数 | 打开编解码器 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。