如何获取 ffmpeg 中可用的所有编解码器的列表
How do i get a list of all codecs available in ffmpeg?
我有这个代码示例,我在C中使用:
//#define UINT64_C (uint64_t);
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "gdiplus.lib")
#include <windows.h>
#include <gdiplus.h>
#include <GdiPlusEnums.h>
using namespace Gdiplus;
extern "C" {
#include "libavcodecavcodec.h"
#include "libavutilmathematics.h"
//#include "libavcodecavcodec.h"
WCHAR *fname;
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
int total_frame_counter;
FILE *f;
AVFrame *frame;
AVPacket pkt;
int codec_id;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
int errn;
void Encoder_init()
{
avcodec_register_all();
/* find the mpeg1 video encoder */
codec_id = CODEC_ID_MPEG1VIDEO;
codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
if (!codec) {
fprintf(stderr, "Codec not foundn");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec contextn");
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->time_base.num=1;c->time_base.den=25;
c->gop_size = 10; /* emit one intra frame every ten frames */
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);
*/
}
const char *Encoder_GetCodecName( int id )
{
return avcodec_get_name( (AVCodecID)id );
}
然后我有一个 c++ 的头文件:
const char *Encoder_GetCodecName( int id );
然后我有另一个C++头文件,我正在使用GetCodecName()
来获取列表:
List<String^> ^GetCodecs()
{
List<String^> ^l = gcnew List<String^>;
String ^s;
for (int i=0;i<3333;i++)
{
s = gcnew String(Encoder_GetCodecName( i ));
l->Add(s);
}
return l;
}
但是我现在确实i<3333
所以也许其中一个索引是空的,因为编解码器少于 3333 个?
那么我如何获取/计算 ffmpeg 库中有多少编解码器,所以我将做一些类似的事情,例如:
i < codecs.Length
而不是使用3333
?
ffmpeg/avconv 有一个选项 -codecs,它从 cmdutils.c 运行 show_codecs((
它按以下格式列出所有内容:
Codecs:
D..... = Decoding supported
.E.... = Encoding supported
..V... = Video codec
..A... = Audio codec
..S... = Subtitle codec
...S.. = Supports draw_horiz_band
....D. = Supports direct rendering method 1
.....T = Supports weird frame truncation
------
D V D 4xm 4X Movie
D V D 8bps QuickTime 8BPS video
D A D 8svx_exp 8SVX exponential
D A D 8svx_fib 8SVX fibonacci
D V D FRWU Forward Uncompressed
EV a64multi Multicolor charset for Commodore 64
EV a64multi5 Multicolor charset for Commodore 64, extended with 5th color (colram)
DEA D aac Advanced Audio Coding
D A D aac_latm AAC LATM (Advanced Audio Codec LATM syntax)
D V D aasc Autodesk RLE
DEA D ac3 ATSC A/52A (AC-3)
EA ac3_fixed ATSC A/52A (AC-3)
D A D adpcm_4xm ADPCM 4X Movie
DEA D adpcm_adx SEGA CRI ADX ADPCM
D A D adpcm_ct ADPCM Creative Technology
...
您可以使用 cmdutils.c 中的 show_codecs(( 作为模板来获取所需的内容
AVCodecID
是一个枚举。 它具有有限数量的值。 但是,这些值中的许多不是连续的,值之间有几个间隙,并且还有一些值很好地进入 6 位数字(最高的是 0x21000 即 135168(。 libav 的 API 中没有机制来找出最高的可用AVCodecID
值,所以如果你想坚持使用 ID 循环,那么你需要增加你的循环计数器。 此外,avcodec_get_name()
会返回未知 ID 的"unknown_codec"
,因此您需要先将其过滤掉,然后再将它们添加到列表中。 或者,您可以使用已知 ID 值的硬编码case
语句将 switch
语句合并到循环中。
ID,而是遍历已注册的编解码器本身。 调用 av_codec_next()
以获取指向第一个已注册的 AVCodec
结构的指针。 AVCodec
有name
和long_name
领域。 然后再次调用 av_codec_next()
以获取下一个AVCodec
,依此类推,直到它返回 NULL 指针。 文档指出:
AVCodec* av_codec_next ( const AVCodec * c (
如果 c 为 NULL,则返回第一个注册的编解码器,如果 c 为非 NULL,返回 C 之后的下一个注册编解码器,如果 c 是最后一个,则返回 NULL。一。
通过直接访问AVCodec
结构,您的循环将运行得更快、更准确,它还允许您区分编码器和解码器,它们可能共享通用名称。
尝试这样的事情:
__declspec(thread) AVCodec* current_codec = NULL;
const char* Encoder_GetNextCodecName()
{
current_codec = av_codec_next(current_codec);
while (current_codec != NULL)
{
/* this is optional...
if (!av_codec_is_encoder(current_codec))
{
current_codec = av_codec_next(current_codec);
continue;
}
*/
return current_codec->name;
}
return "";
}
const char* Encoder_GetFirstCodecName()
{
current_codec = NULL;
return Encoder_GetNextCodecName();
}
List<String^> ^GetCodecs()
{
List<String^> ^l = gcnew List<String^>;
String ^s = gcnew String(Encoder_GetFirstCodecName());
while (!String.IsNullOrEmpty(s))
{
l->Add(s);
s = gcnew String(Encoder_GetNextCodecName());
}
return l;
}
更新:由于av_codec_next()
几年前已被弃用,因此您可以使用av_codec_iterate()
,例如:
__declspec(thread) void* iterate_data = NULL;
const char* Encoder_GetNextCodecName()
{
AVCodec* current_codec = av_codec_iterate(&iterate_data);
while (current_codec != NULL)
{
/* this is optional...
if (!av_codec_is_encoder(current_codec))
{
current_codec = av_codec_iterate(&iterate_data);
continue;
}
*/
return current_codec->name;
}
return "";
}
const char* Encoder_GetFirstCodecName()
{
iterate_data = NULL;
return Encoder_GetNextCodecName();
}
- h264_cuvid编解码器未找到
- C++17 编解码器在将标准::字符串转换为标准::字符串时抛出"bad conversion"
- 如何使用 ffmpeg 将 3840 nb_samples编码为请求 1024 的编解码器
- FFMPEG:为什么当我调用av_codec_next()时,我所有的编解码器都没有显示出来
- OpenCV 检查计算机上是否安装了视频编解码器 (C++)
- OpenCV:FFMPEG:编解码器 ID 12 和格式 'mp4 / MP4 不支持标记
- 带有 H264 编解码器的 libav 错误消息。"非严格单调PTS"
- 为什么编解码器X264/X265忽略了输入框架的PT和DTS
- 如何修复"UnicodeDecodeError:"utf-8"编解码器无法解码字节时使用Python C扩展?
- C++ avformat_open_input返回空编解码器、宽度和高度
- 如何为 OpenCV 的视频编写器动态选择可用的编解码器?
- 将FFMPEG命令行转换为C 编解码器设置
- codecvt_utf8<wchar_t>被转换为本机编解码器<wchar_t,字符>
- 寻求使用 FFmpeg 在 mp4 容器中 h264 编解码器的视频帧.数据包 pts 始终为 0
- C++ 无法实例化编解码器以在 txt 文件中写入 unicode
- 警告:找不到编解码器参数(././modules/higgui/src/cap_ffmpeg_impl.hpp:540)
- OpenCV videoWriter编解码器问题
- 编解码器在 gcc 中不起作用
- Qt5 QMediaPlayer使用随程序一起提供的编解码器
- 如何获取 ffmpeg 中可用的所有编解码器的列表