2013-05-04 163 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作爲模板來獲得你需要的東西

相關問題