4 详细设计
这章是FFMPEG C++封装库的详细设计。
(图片来源网络,侵删)
4.1 Init
该模块初始化FFMPEG库。
4.1.1 Init定义
namespace media { namespace sdk { void MEDIASDK_EXPORT Init(); } }
函数说明:
(图片来源网络,侵删)
- Init 初始化FFMPEG库,该函数可调用多次。
4.1.2 Init实现
namespace media { namespace sdk { void Init() { static bool isInit = false; if(isInit) return; isInit = true; avcodec_register_all(); avfilter_register_all(); av_register_all(); avformat_network_init(); Report(false); } } }
函数流程:
- 注册支持的全部编码器(codec)。
- 注册支持的全部过滤器(filter)。
- 注册支持的全部封包格式(format)。
- 初始化支持的网络。
- 默认关闭打印输出。
4.2 Utils
该模块提供FFMPEG库的工具函数。
4.2.1 Utils定义
namespace media { namespace sdk { void MEDIASDK_EXPORT Report(bool on); void MEDIASDK_EXPORT Formats(); void MEDIASDK_EXPORT Codecs(bool encoder); void MEDIASDK_EXPORT Bsfs(); void MEDIASDK_EXPORT Protocols(); void MEDIASDK_EXPORT Filters(); void MEDIASDK_EXPORT PixFmts(); void MEDIASDK_EXPORT SampleFmts(); int64_t MEDIASDK_EXPORT Time(); int64_t MEDIASDK_EXPORT NoPtsValue(); int64_t MEDIASDK_EXPORT ToTime(int64_t const& pts, Rational const& timebase); std::vector MEDIASDK_EXPORT DisplayCardNames(); } }
4.2.2 Utils实现
4.2.2.1 Report
void Report(bool on) { if(on) av_log_set_callback(log_callback_help); else av_log_set_callback(log_callback_null); }
函数说明:
- 如果需要打印,设置一个可打印新的callback.
- 如果不要打印,设置一个不可打印的callback.
4.2.2.2 Formats
void Formats() { AVInputFormat *ifmt = NULL; AVOutputFormat *ofmt = NULL; const char *last_name; printf("File formats:\n" " D. = Demuxing supported\n" " .E = Muxing supported\n" " --\n"); last_name = "000"; for (;;) { int decode = 0; int encode = 0; const char *name = NULL; const char *long_name = NULL; while ((ofmt = (AVOutputFormat *)av_oformat_next(ofmt))) { if ((name == NULL || strcmp(ofmt->name, name) name, last_name) > 0) { name = ofmt->name; long_name = ofmt->long_name; encode = 1; } } while ((ifmt = (AVInputFormat *)av_iformat_next(ifmt))) { if ((name == NULL || strcmp(ifmt->name, name) name, last_name) > 0) { name = ifmt->name; long_name = ifmt->long_name; encode = 0; } if (name && strcmp(ifmt->name, name) == 0) decode = 1; } if (name == NULL) break; last_name = name; printf(" %s%s %-15s %s\n", decode ? "D" : " ", encode ? "E" : " ", name, long_name ? long_name:" "); } }
函数流程:
- 遍历输出格式和输入格式
- 打印名字和长名字
- 输入格式作为解复用(Demux)打印
- 输出格式作为复用(Mux)打印
4.2.2.3 Codecs
void Codecs(bool encoder) { const AVCodecDescriptor **codecs; unsigned i, nb_codecs = get_codecs_sorted(&codecs); printf("%s:\n" " V..... = Video\n" " A..... = Audio\n" " S..... = Subtitle\n" " .F.... = Frame-level multithreading\n" " ..S... = Slice-level multithreading\n" " ...X.. = Codec is experimental\n" " ....B. = Supports draw_horiz_band\n" " .....D = Supports direct rendering method 1\n" " ------\n", encoder ? "Encoders" : "Decoders"); for (i = 0; i id, codec, encoder))) { printf(" %c", get_media_type_char(desc->type)); printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : "."); printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : "."); printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? "X" : "."); printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : "."); printf((codec->capabilities & AV_CODEC_CAP_DR1) ? "D" : "."); printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : ""); if (strcmp(codec->name, desc->name)) printf(" (codec %s)", desc->name); printf("\n"); } } av_free(codecs); }
函数流程:
- 遍历支持的编解码器
- 按照视频,音频,字幕,帧级多线程,切片级多线程,实验性,支持画横条,支持直接渲染等格式打印
4.2.2.4 Bsfs
void Bsfs() { const AVBitStreamFilter *bsf = 0; void *opaque = NULL; printf("Bitstream filters:\n"); while ((bsf = av_bsf_iterate(&opaque))) printf("%s\n", bsf->name); printf("\n"); }
函数流程:
- 遍历支持的Bitstream过滤器
- 打印过滤器名称
4.2.2.5 Protocols
void Protocols() { void *opaque = NULL; const char *name; printf("Supported file protocols:\n" "Input:\n"); while ((name = avio_enum_protocols(&opaque, 0))) printf("%s\n", name); printf("Output:\n"); while ((name = avio_enum_protocols(&opaque, 1))) printf("%s\n", name); }
函数流程:
- 遍历支持的输入/输出协议
- 打印协议名称
4.2.2.6 Filters
void Filters() { const AVFilter *filter = NULL; char descr[64], *descr_cur; void *opaque = NULL; int i, j; const AVFilterPad *pad; printf("Filters:\n" " T.. = Timeline support\n" " .S. = Slice threading\n" " ..C = Command support\n" " A = Audio input/output\n" " V = Video input/output\n" " N = Dynamic number and/or type of input/output\n" " | = Source or sink filter\n"); while ((filter = av_filter_iterate(&opaque))) { descr_cur = descr; for (i = 0; i '; } pad = i ? filter->outputs : filter->inputs; for (j = 0; pad && avfilter_pad_get_name(pad, j); j++) { if (descr_cur >= descr + sizeof(descr) - 4) break; *(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j)); } if (!j) *(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) || ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|'; } *descr_cur = 0; printf(" %c%c%c %-17s %-10s %s\n", filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.', filter->flags & AVFILTER_FLAG_SLICE_THREADS ? 'S' : '.', filter->process_command ? 'C' : '.', filter->name, descr, filter->description); } }
函数流程:
- 遍历支持的过滤器
- 按照时间线,切片线程,命令支持,音频输入/输出,视频输入/输出和源/显示类型打印。
4.2.2.7 PixFmts
void PixFmts() { const AVPixFmtDescriptor *pix_desc = NULL; printf("Pixel formats:\n" "I.... = Supported Input format for conversion\n" ".O... = Supported Output format for conversion\n" "..H.. = Hardware accelerated format\n" "...P. = Paletted format\n" "....B = Bitstream format\n" "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n" "-----\n"); #if !CONFIG_SWSCALE # define sws_isSupportedInput(x) 0 # define sws_isSupportedOutput(x) 0 #endif while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) { enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc); printf("%c%c%c%c%c %-16s %d %2d\n", sws_isSupportedInput (pix_fmt) ? 'I' : '.', sws_isSupportedOutput(pix_fmt) ? 'O' : '.', pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL ? 'H' : '.', pix_desc->flags & AV_PIX_FMT_FLAG_PAL ? 'P' : '.', pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.', pix_desc->name, pix_desc->nb_components, av_get_bits_per_pixel(pix_desc)); } }
函数流程:
- 遍历支持的像素格式
- 按照输入,输出,硬件支持,调色板和位流类型打印。
4.2.2.8 SampleFmts
void SampleFmts() { int i; char fmt_str[128]; for (i = -1; i
函数流程:
- 遍历支持的音频采样格式
- 打印音频采样格式
4.2.2.9 Time
int64_t Time() { return av_gettime(); }
4.2.2.10 NoPtsValue
int64_t NoPtsValue() { return AV_NOPTS_VALUE; }
函数说明:
- 返回无效时间戳
4.2.2.11 ToTime
int64_t ToTime(int64_t const& pts, Rational const& timebase) { AVRational tb1 = {timebase.num, timebase.den}; AVRational tb2 = {1, AV_TIME_BASE}; return av_rescale_q(pts, tb1, tb2); }
函数说明:
- 将以1/AV_TIME_BASE秒为单位的时间戳转换位以timebase为单位的时间戳
- AV_TIME_BASE值为1000000
4.2.2.12 DisplayCardNames
std::vector DisplayCardNames() { std::vector displayNames; IDXGIFactory * pFactory; HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory)); if(FAILED(hr)) return displayNames; IDXGIAdapter * pAdapter; int iAdapterNum = 0; while(pFactory->EnumAdapters(iAdapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND) { DXGI_ADAPTER_DESC desc; pAdapter->GetDesc(&desc); std::wstring aa(desc.Description); displayNames.push_back(WStringToString(aa)); ++iAdapterNum; } return displayNames; }
函数流程:
- 遍历系统中显卡名称
- 将显卡名称放入数组并返回
示例
namespace mediasdk = media::sdk; int main(int argc, char* argv[]) { mediasdk::Init(); mediasdk::Formats();//打印支持的文件格式(封包格式). mediasdk::Codecs(true);//打印支持编码器. mediasdk::Codecs(false);//打印支持的解码器. mediasdk::Protocols();//打印支持的协议. mediasdk::Filters();//打印支持过滤器. mediasdk::PixFmts();//打印支持像素格式. mediasdk::SampleFmts();//打印支持采样格式. std::vector names = media::sdk::DisplayCardNames(); for(name: names) std::cout
- 返回无效时间戳
还没有评论,来说两句吧...