2013-05-04 162 views
0

我有我使用在此代码例C如何获得ffmpeg中所有可用编解码器的列表?

//#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 "libavcodec\avcodec.h" 
#include "libavutil\mathematics.h" 
//#include "libavcodec\avcodec.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 found\n"); 
     exit(1); 
    } 
    c = avcodec_alloc_context3(codec); 
    if (!c) { 
     fprintf(stderr, "Could not allocate video codec context\n"); 
     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; 
    } 

但我现在没有,因为没有3333编解码器我< 3333这样mayby的指数法是空的那么,如何获得/计算有多少的编解码器有在FFmpeg所以我会做这样的事情,例如:

我< codecs.Length 类似的东西,而不是3333

回答

3

AVCodecID是一个枚举。它定义了有限数量的值。然而,这些值中的很多值并不是连续的,值之间有几个间隙,并且还有值进入6位数字(最高为0x21000,即135168)。 libav的API没有找到最高可用值AVCodecID的机制,所以如果你想坚持一个ID循环,那么你需要增加你的循环计数器。此外,avcodec_get_name()返回"unknown_codec"未知的ID,所以你需要将它们过滤出来,然后再将它们添加到列表中。或者,您可以将switch声明合并到您的循环中,并使用已知ID值的硬编码case声明。

更好的方法是根本不循环ID,而是循环遍历注册的编解码器本身。调用av_codec_next()可以获得指向第一个注册的AVCodec结构体的指针。 AVCodecnamelong_name字段。然后再次调用av_codec_next()来获得下一个AVCodec,依此类推,直到它返回一个NULL指针。 The documentation状态:

avcodec中* av_codec_next(常量avcodec中* C)

如果c是NULL,则返回所述第一注册编解码器,如果c是非NULL, ℃后返回下一个注册的编解码器,或如果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; 
} 
5

的ffmpeg/avconv具有运行从cmdutils.c show_codecs()选项-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 
... 

你可以使用show_codecs()从cmdutils。c作为模板来获得你需要的东西

相关问题