#ifndef FFMPEG_FILLPLUGINS_H #define FFMPEG_FILLPLUGINS_H #include "infotypes.h" #include "avm_fourcc.h" //#include "avcodec.h" #ifndef int64_t_C #define int64_t_C(c) (c ## LL) #define uint64_t_C(c) (c ## ULL) #endif #include "avformat.h" #include #include #include // remove AVM_BEGIN_NAMESPACE; #define FFCSTR(name) \ static const char* ffstr_ ## name = #name FFCSTR(dr1); static void libffmpeg_get_attr(avm::vector& a, AVCodec* codec) { if (!codec) return; const AVOption* c = codec->options; if (c) { const AVOption *stack[FF_OPT_MAX_DEPTH]; int depth = 0; for (;;) { //printf("NAME %s\n", c->name); if (!c->name) { if (c->help) { stack[depth++] = c; c = (const AVOption*)c->help; } else { if (depth == 0) break; // finished c = stack[--depth]; c++; } } else { int t = c->type & FF_OPT_TYPE_MASK; char* arr[100]; char* dealloc; #if 0 printf("Config %s %s\n", t == FF_OPT_TYPE_BOOL ? "bool " : t == FF_OPT_TYPE_DOUBLE ? "double " : t == FF_OPT_TYPE_INT ? "integer" : t == FF_OPT_TYPE_STRING ? "string " : "unknown??", c->name); #endif switch (t) { case FF_OPT_TYPE_BOOL: a.push_back(AttributeInfo(c->name, c->help, AttributeInfo::Integer, 0, 1, (int)c->defval)); break; case FF_OPT_TYPE_DOUBLE: a.push_back(AttributeInfo(c->name, c->help, c->defval, c->min,c->max)); break; case FF_OPT_TYPE_INT: a.push_back(AttributeInfo(c->name, c->help, AttributeInfo::Integer, (int)c->min, (int)c->max, (int)c->defval)); break; case FF_OPT_TYPE_STRING: t = 0; dealloc = 0; if (c->defstr) { char* tmp = dealloc = strdup(c->defstr); if (tmp) { char* semi; while (tmp && (semi = strchr(tmp, ';'))) { *semi++ = 0; arr[t++] = tmp; if (t > 97) break; // weird - too many string options ??? tmp = semi; } arr[t++] = tmp; } arr[t] = 0; } //printf("%d %s\n", i, cnf->name); a.push_back((t > 1) ? AttributeInfo(c->name, c->help, (const char**)arr, (int)c->defval) : AttributeInfo(c->name, c->help, AttributeInfo::String)); if (dealloc) free(dealloc); break; /* if (c->defstr) { char* d = av_strdup(c->defstr); char* f = strchr(d, ','); if (f) *f = 0; i += sprintf(def + i, "%s%s=%s", col, c->name, d); av_free(d); } break; */ } c++; } } } } static void libffmpeg_fill_decattr(avm::vector& a, const char* cd) { a.clear(); a.push_back(AttributeInfo(ffstr_dr1, "Direct Rendering 1", AttributeInfo::Integer, 0, 1, 1)); libffmpeg_get_attr(a, avcodec_find_decoder_by_name(cd)); } static void libffmpeg_fill_encattr(avm::vector& a, const char* cd) { a.clear(); libffmpeg_get_attr(a, avcodec_find_encoder_by_name(cd)); } static void libffmpeg_add_divx(avm::vector& ci) { static const char divx_about[] = "FFMPEG LGPL version of popular M$ MPEG-4 video codec v3. " "Advanced compression technologies allow it to " "compress 640x480x25 video with a perfect " "quality into 100-150 kbytes/s ( 3-4 times " "less than MPEG-2 )."; static const fourcc_t div3_codecs[] = { fccDIV3, fccdiv3, fccDIV4, fccdiv4, fccDIV5, fccdiv5, fccDIV6, fccdiv6, fccMP41, fccMP43, RIFFINFO_MPG3, RIFFINFO_mpg3, fccAP41, fccap41, fccAP42, fccap42, mmioFOURCC('C', 'O', 'L', '1'), // Cool codec mmioFOURCC('c', 'o', 'l', '1'), mmioFOURCC('C', 'O', 'L', '0'), mmioFOURCC('c', 'o', 'l', '0'), mmioFOURCC('3', 'I', 'V', 'D'), // 3ivx.com mmioFOURCC('3', 'i', 'v', 'd'), 0 }; avm::vector da; static const char* msmpeg4_str = "msmpeg4"; libffmpeg_fill_decattr(da, msmpeg4_str); //da.push_back(AttributeInfo("Hue", "Hue", AttributeInfo::Integer, 0, 100)); //da.push_back(AttributeInfo("Brightness", "Brightness", AttributeInfo::Integer, 0, 100)); //da.push_back(AttributeInfo("Contrast", "Contrast", AttributeInfo::Integer, 0, 100)); // for encoding ci.push_back(CodecInfo(div3_codecs, "FF DivX ;-)", msmpeg4_str, divx_about, CodecInfo::Plugin, "ffdivx", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t opendix_codecs[] = { fccDIVX, fccdivx, RIFFINFO_XVID, RIFFINFO_XviD, RIFFINFO_xvid, fccMP4S, fccmp4s, mmioFOURCC('m', 'p', '4', 'v'), mmioFOURCC('U', 'M', 'P', '4'), mmioFOURCC('3', 'I', 'V', '1'), mmioFOURCC('3', 'I', 'V', '2'), mmioFOURCC('3', 'i', 'v', '2'), 0x4, 0 }; static const char* mpeg4_str = "mpeg4"; libffmpeg_fill_decattr(da, mpeg4_str); ci.push_back(CodecInfo(opendix_codecs, "FF OpenDivX", mpeg4_str, "FF OpenDivX MPEG-4 codec", CodecInfo::Plugin, "ffodivx", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t codecs[] = { fccDX50, fccdx50, 0 }; //libffmpeg_fill_decattr(da, mpeg4_str); avm::vector va; libffmpeg_fill_encattr(va, mpeg4_str); ci.push_back(CodecInfo(codecs, "FF DivX5", mpeg4_str, "FF DivX 5.0 codec", CodecInfo::Plugin, "ffdx50", CodecInfo::Video, //CodecInfo::Decode, CodecInfo::Both, // working on 0, va, da)); static const fourcc_t wmv_codecs[] = { fccWMV1, fccwmv1, 0 }; static const char* wmv1_str = "wmv1"; libffmpeg_fill_decattr(da, wmv1_str); ci.push_back(CodecInfo(wmv_codecs, "FF Windows Media Video 7", wmv1_str, "FF Windows Media Video 7 codec", CodecInfo::Plugin, "ffwmv1", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t wmv2_codecs[] = { fccWMV2, fccwmv2, 0 }; static const char* wmv2_str = "wmv2"; libffmpeg_fill_decattr(da, wmv2_str); ci.push_back(CodecInfo(wmv2_codecs, "FF Windows Media Video 8", wmv2_str, "FF Windows Media Video 7 codec", CodecInfo::Plugin, "ffwmv2", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t mp41_codecs[] = { fccMPG4, fccmpg4, fccDIV1, fccdiv1, 0 }; static const char* msmpeg4v1 = "msmpeg4v1"; libffmpeg_fill_decattr(da, msmpeg4v1); ci.push_back(CodecInfo(mp41_codecs, "FF M$ MPEG-4 v1", msmpeg4v1, "FF M$ MPEG-4 v1 codec", CodecInfo::Plugin, "ffmp41", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t mp42_codecs[] = { fccMP42, fccmp42, fccDIV2, fccdiv2, 0 }; static const char* msmpeg4v2 = "msmpeg4v2"; libffmpeg_fill_decattr(da, msmpeg4v2); ci.push_back(CodecInfo(mp42_codecs, "FF M$ MPEG-4 v2", msmpeg4v2, "FF M$ MPEG-4 v2 codec", CodecInfo::Plugin, "ffmp42", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t mpeg12_codecs[] = { RIFFINFO_MPG1, RIFFINFO_MPG2, 0x10000001, 0x10000002, // mplayer's MPEG-PES 1/2 0 }; static const char* mpegvideo_str = "mpegvideo"; libffmpeg_fill_decattr(da, mpegvideo_str); ci.push_back(CodecInfo(mpeg12_codecs, "FF MPEG 1/2", mpegvideo_str, "FF MPEG1/2 decoder", CodecInfo::Plugin, "ffmpeg", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t pim_codecs[] = { fccPIM1, 0 }; ci.push_back(CodecInfo(pim_codecs, "FF PinnacleS PIM1", mpegvideo_str, "FF PinnacleS PIM1", CodecInfo::Plugin, "ffpim1", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); } static void libffmpeg_add_vdec(avm::vector& ci) { avm::vector da; //libffmpeg_fill_attr(da, false); static const fourcc_t mjpg_codecs[] = { fccMJPG, fccmjpg, mmioFOURCC('A', 'V', 'R', 'n'), mmioFOURCC('A', 'V', 'D', 'J'), mmioFOURCC('J', 'P', 'E', 'G'), mmioFOURCC('j', 'p', 'e', 'g'), mmioFOURCC('m', 'j', 'p', 'b'), 0 }; static const char* mjpeg_str = "mjpeg"; ci.push_back(CodecInfo(mjpg_codecs, "FF Motion JPEG", mjpeg_str, "FF Motion JPEG", CodecInfo::Plugin, "ffmjpeg", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t h264_codecs[] = { mmioFOURCC('H', '2', '6', '4'), mmioFOURCC('h', '2', '6', '4'), 0 }; static const char* h264_str = "h264"; ci.push_back(CodecInfo(h264_codecs, "FF H264", h264_str, "FF H263+ codec", CodecInfo::Plugin, "ffh263", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t h263_codecs[] = { fccH263, fcch263, fccU263, fccu263, mmioFOURCC('s', '2', '6', '3'), 0 }; static const char* h263_str = "h263"; ci.push_back(CodecInfo(h263_codecs, "FF H263+", h263_str, "FF H263+ codec", CodecInfo::Plugin, "ffh263", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t i263_codecs[] = { fccI263, fcci263, 0 }; static const char* h263i_str = "h263i"; ci.push_back(CodecInfo(i263_codecs, "FF I263", h263i_str, "FF I263 codec", CodecInfo::Plugin, "ffi263", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t dvsd_codecs[] = { fccDVSD, fccdvsd, fccdvhd, fccdvsl, mmioFOURCC('D', 'V', 'C', 'S'), mmioFOURCC('d', 'v', 'c', 's'), mmioFOURCC('d', 'v', 'c', 'p'), mmioFOURCC('d', 'v', 'c', ' '), 0 }; ci.push_back(CodecInfo(dvsd_codecs, "FF DV Video", "dvvideo", "FF DV Video decoder", CodecInfo::Plugin, "ffdv", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t huf_codecs[] = { fccHFYU, 0 }; ci.push_back(CodecInfo(huf_codecs, "FF Huffyuv", "huffyuv", "FF Huffyuv codec", CodecInfo::Plugin, "ffhuffyuv", CodecInfo::Video, CodecInfo::Both, 0, 0, da)); static const fourcc_t vp3_codecs[] = { fccVP31, fccvp31, fccVP30, fccVP30, 0 }; ci.push_back(CodecInfo(vp3_codecs, "FF VP3", "vp3", "FF VP3 codec", CodecInfo::Plugin, "ffvp3", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t svq1_codecs[] = { mmioFOURCC('S', 'V', 'Q', '1'), 0 }; ci.push_back(CodecInfo(svq1_codecs, "FF SVQ1", "svq1", "FF Sorenson1 decoder", CodecInfo::Plugin, "ffsvq1", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t svq3_codecs[] = { mmioFOURCC('S', 'V', 'Q', '3'), 0 }; ci.push_back(CodecInfo(svq3_codecs, "FF SVQ3", "svq3", "FF Sorenson3 decoder", CodecInfo::Plugin, "ffsvq3", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t indeo3_codecs[] = { RIFFINFO_IV31, RIFFINFO_iv31, RIFFINFO_IV32, RIFFINFO_iv31, 0 }; ci.push_back(CodecInfo(indeo3_codecs, "FF Indeo 3", "indeo3", "FF Indeo 3 decoder", CodecInfo::Plugin, "ffindeo3", CodecInfo::Video, CodecInfo::Decode)); static const fourcc_t asv1_codecs[] = { fccASV1, 0 }; ci.push_back(CodecInfo(asv1_codecs, "FF ASUSV1", "asv1", "FF ASUS V1 codec", CodecInfo::Plugin, "ffasv1", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); static const fourcc_t ffv1_codecs[] = { mmioFOURCC('F', 'F', 'V', '1'), 0 }; ci.push_back(CodecInfo(asv1_codecs, "FF FFV1", "ffv1", "FF FFV1 looseless codec", CodecInfo::Plugin, "ffv1", CodecInfo::Video, CodecInfo::Decode, 0, 0, da)); } static void libffmpeg_add_ac3dec(avm::vector& ci) { static const fourcc_t ac3_codecs[] = { 0x2000, 0 }; ci.push_back(CodecInfo(ac3_codecs, "FF AC3", "ac3", "AC3 audio codec", CodecInfo::Plugin, "ffac3", CodecInfo::Audio, CodecInfo::Decode)); } static void libffmpeg_add_adec(avm::vector& ci) { static const fourcc_t mpg_codecs[] = { 0x55, 0x50, mmioFOURCC('.', 'm', 'p', '3'), 0 }; ci.push_back(CodecInfo(mpg_codecs, "FF MPEG Layer-3", "mp2", "FF MPEG Layer-III audio decoder", CodecInfo::Plugin, "ffmp3", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t alaw_codecs[] = { 0x06, 0 }; ci.push_back(CodecInfo(alaw_codecs, "FF ALaw", "pcm_alaw", "FF ALaw audio decoder", CodecInfo::Plugin, "ffalaw", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t ulaw_codecs[] = { 0x07, 0 }; ci.push_back(CodecInfo(ulaw_codecs, "FF uLaw", "pcm_mulaw", "FF uLaw audio decoder", CodecInfo::Plugin, "ffmulaw", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t wmav1_codecs[] = { 0x160, 0 }; ci.push_back(CodecInfo(wmav1_codecs, "FF WMA v1", "wmav1", "FF Window Media Audio v1 decoder", CodecInfo::Plugin, "ffwmav1", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t wmav2_codecs[] = { 0x161, 0 }; ci.push_back(CodecInfo(wmav2_codecs, "FF WMA v2", "wmav2", "FF Window Media Audio v2 decoder", CodecInfo::Plugin, "ffwmav2", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t ms_codecs[] = { 0x02, 0 }; ci.push_back(CodecInfo(ms_codecs, "FF MS ADPCM", "adpcm_ms", "FF MS ADPCM audio decoder", CodecInfo::Plugin, "ffadpcmms", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t imaqt_codecs[] = { 0x11, 0x6d69, // ima4 0x34616d69 0 }; // unsure ci.push_back(CodecInfo(imaqt_codecs, "FF IMA Qt", "adpcm_ima_qt", "FF IMA Qt audio decoder", CodecInfo::Plugin, "ffimaqt", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t imawav_codecs[] = { 0x11, 0 }; // unsure ci.push_back(CodecInfo(imawav_codecs, "FF IMA WAV", "adpcm_ima_wav", "FF IMA WAV audio decoder", CodecInfo::Plugin, "ffimawav", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t dvaudio_codecs[] = { ('D' << 8) | 'A', 0 }; ci.push_back(CodecInfo(dvaudio_codecs, "FF DV Audio", "dvaudio", "FF DV Audio decoder", CodecInfo::Plugin, "ffdva", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t mace6_codecs[] = { ('M' << 8) | 'A', 0x414d, 0 }; // unsure ci.push_back(CodecInfo(mace6_codecs, "FF MACE6 Qt", "mace6", "FF Macintosh Audio Compression and Expansion 6:1", CodecInfo::Plugin, "ffmac6", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t ra144_codecs[] = { mmioFOURCC('1', '4', '_', '4'), 0x3431, 0 }; ci.push_back(CodecInfo(ra144_codecs, "FF Real 144", "real_144", "FF Real Audio 14.4kbps", CodecInfo::Plugin, "ffra144", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t ra288_codecs[] = { mmioFOURCC('2', '8', '_', '8'), 0x3431, 0 }; ci.push_back(CodecInfo(ra144_codecs, "FF Real 288", "real_288", "FF Real Audio 28.8kbps", CodecInfo::Plugin, "ffra288", CodecInfo::Audio, CodecInfo::Decode)); static const fourcc_t mpeg4aac_codecs[] = { (('p' << 8) | 'm'), (('P' << 8) | 'M'), mmioFOURCC('m', 'p', '4', 'a'), mmioFOURCC('M', 'P', '4', 'A'), 0 }; ci.push_back(CodecInfo(mpeg4aac_codecs, "FAAD (runtime)", "mpeg4aac", "FAAD - MPEG2/MPEG4 AAC" "Freeware Advanced Audio Decoder, " "http://www.audiocoding.com/" "Copyright (C) 2002 M. Bakker", CodecInfo::Plugin, "ffmpeg4aac", CodecInfo::Audio, CodecInfo::Decode)); } static void ffmpeg_FillPlugins(avm::vector& ci) { // video libffmpeg_add_divx(ci); libffmpeg_add_vdec(ci); // audio #ifdef HAVE_FFMPEG_A52 libffmpeg_add_ac3dec(ci); #endif libffmpeg_add_adec(ci); } AVM_END_NAMESPACE; #endif // FFMPEG_FILLPLUGINS_H