当前位置: 首页 > news >正文

福建凭祥建设工程有限公司网站彩票系统网站开发

福建凭祥建设工程有限公司网站,彩票系统网站开发,做行业网站广告,物联网应用技术就业前景摘要:本文描述了FFmpeg中videotoobox解码器如何进行解码工作,如何将一个编码的码流解码为最终的裸流。   关键字:videotoobox,decoder,ffmpeg   VideoToolbox 是一个低级框架,提供对硬件编码器和解码器的直接访问。 它提供视频…

  摘要:本文描述了FFmpeg中videotoobox解码器如何进行解码工作,如何将一个编码的码流解码为最终的裸流。
  关键字:videotoobox,decoder,ffmpeg
  VideoToolbox 是一个低级框架,提供对硬件编码器和解码器的直接访问。 它提供视频压缩和解压缩服务,以及存储在 CoreVideo 像素缓冲区中的光栅图像格式之间的转换服务。 这些服务以会话对象(压缩、解压缩和像素传输)的形式提供,并作为 Core Foundation (CF) 类型输出。 VideoToolbox支持H.263, H.264, HEVC, MPEG-1, MPEG-2, MPEG-4 Part 2, ProRes解码,H.264, HEVC, ProRes编码,最新的版本似乎也支持了VP9解码。

1 主流程

1.1 涉及的Context

  FFmpeg中每个解码器都有自己的Context描述,该描述按照约定的格式描述对应的解码器参数和解码器的处理函数指针。FFmpeg中的VideoToolbox解码器主要实现代码在libavcodec/videotoobox.{h,c}中,其中针对每一种支持的解码格式定义了一个独立的Context,比如ff_h263_videotoolbox_hwaccel,ff_h263_videotoolbox_hwaccel,ff_h264_videotoolbox_hwaccel,...等,只是实现上有差异,我们主要关注其中一个即可,这里主要关注ff_h264_videotoolbox_hwaccel

const AVHWAccel ff_h264_videotoolbox_hwaccel = {.name           = "h264_videotoolbox",.type           = AVMEDIA_TYPE_VIDEO,.id             = AV_CODEC_ID_H264,.pix_fmt        = AV_PIX_FMT_VIDEOTOOLBOX,.alloc_frame    = ff_videotoolbox_alloc_frame,.start_frame    = ff_videotoolbox_h264_start_frame,.decode_slice   = ff_videotoolbox_h264_decode_slice,.decode_params  = videotoolbox_h264_decode_params,.end_frame      = videotoolbox_h264_end_frame,.frame_params   = ff_videotoolbox_frame_params,.init           = ff_videotoolbox_common_init,.uninit         = ff_videotoolbox_uninit,.priv_data_size = sizeof(VTContext),
};

  该结构中定义了:

  • 解码器的名称;
  • 解码数据的类型;
  • 解码器ID;
  • 硬件解码的格式;
  • 申请一个硬件相关的帧结构的函数指针;
  • 解码开始前针对帧进行内存拷贝之类的操作;
  • 解码数据;
  • 解析解码器需要的参数比如sps等;
  • 送帧结束后的后处理;
  • 初始化硬件解码器;
  • 销毁硬件解码器;
  • 当前硬件解码器的描述结构。

  ff_h264_videotoolbox_hwaccel是存储在hw_configs中的,运行时遍历该列表寻找期望的硬件解码器。所以解码工作是先经过FFmpeg内的ff_h264_decoder解码器再进入硬件解码器的。

const AVCodec ff_h264_decoder = {.name                  = "h264",.long_name             = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),.type                  = AVMEDIA_TYPE_VIDEO,.id                    = AV_CODEC_ID_H264,.priv_data_size        = sizeof(H264Context),.init                  = h264_decode_init,.close                 = h264_decode_end,.decode                = h264_decode_frame,.capabilities          = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |AV_CODEC_CAP_FRAME_THREADS,.hw_configs            = (const AVCodecHWConfigInternal *const []) {
#if CONFIG_H264_DXVA2_HWACCELHWACCEL_DXVA2(h264),
#endif
#if CONFIG_H264_D3D11VA_HWACCELHWACCEL_D3D11VA(h264),
#endif
#if CONFIG_H264_D3D11VA2_HWACCELHWACCEL_D3D11VA2(h264),
#endif
#if CONFIG_H264_NVDEC_HWACCELHWACCEL_NVDEC(h264),
#endif
#if CONFIG_H264_VAAPI_HWACCELHWACCEL_VAAPI(h264),
#endif
#if CONFIG_H264_VDPAU_HWACCELHWACCEL_VDPAU(h264),
#endif
#if CONFIG_H264_VIDEOTOOLBOX_HWACCELHWACCEL_VIDEOTOOLBOX(h264),
#endifNULL},.caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP,.flush                 = h264_decode_flush,.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),.update_thread_context_for_user = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context_for_user),.profiles              = NULL_IF_CONFIG_SMALL(ff_h264_profiles),.priv_class            = &h264_class,
};

  VTContextVT解码过程中描述VT的Context。

typedef struct VTContext {// The current bitstream buffer.uint8_t                     *bitstream;// The current size of the bitstream.int                         bitstream_size;// The reference size used for fast reallocation.int                         allocated_size;// The core video bufferCVImageBufferRef            frame;// Current dummy frames context (depends on exact CVImageBufferRef params).struct AVBufferRef         *cached_hw_frames_ctx;// Non-NULL if the new hwaccel API is used. This is only a separate struct// to ease compatibility with the old API.struct AVVideotoolboxContext *vt_ctx;// Current H264 parameters (used to trigger decoder restart on SPS changes).uint8_t                     sps[3];bool                        reconfig_needed;void *logctx;
} VTContext;

1.2 主要流程

在这里插入图片描述

2 每个步骤的具体实现

2.1ff_videotoolbox_common_init

  ff_videotoolbox_common_init在初始化解码器时调用,一般是在avcodec_open2时初始化硬件解码器。一般FFmpeg为了更加准确的探测当前视频的媒体信息,在avformat_find_stream_info时就会初始化解码器解码少部分的帧来进行流媒体信息探测。
  初始化时首先就时申请VT的Context内存,并设置一些参数,实际上只设置了VT的callback函数和PixFormat。之后及时根据需要初始化AVHWFramesContext,主要就是申请内存并设置帧格式比如宽高,格式等等。
  最后就是调用videotoolbox_start创建VT的Session,创建的过程比较简单就是直接调用Apple的API创建Session,需要重点关注的是如何设置的。具体的实现函数为videotoolbox_decoder_config_create,其中设置硬件加速的配置时写死的,无法进行配置。另外就是从当前的CodecCteonxt中取出sps等信息送给解码器,如果没有这些信息,解码器是无法准确识别出时间戳信息的。sps和pps的解析是由FFmpeg完成的。

    switch (codec_type) {case kCMVideoCodecType_MPEG4Video :if (avctx->extradata_size)data = videotoolbox_esds_extradata_create(avctx);if (data)CFDictionarySetValue(avc_info, CFSTR("esds"), data);break;case kCMVideoCodecType_H264 :data = ff_videotoolbox_avcc_extradata_create(avctx);if (data)CFDictionarySetValue(avc_info, CFSTR("avcC"), data);break;case kCMVideoCodecType_HEVC :data = ff_videotoolbox_hvcc_extradata_create(avctx);if (data)CFDictionarySetValue(avc_info, CFSTR("hvcC"), data);break;
#if CONFIG_VP9_VIDEOTOOLBOX_HWACCELcase kCMVideoCodecType_VP9 :data = ff_videotoolbox_vpcc_extradata_create(avctx);if (data)CFDictionarySetValue(avc_info, CFSTR("vpcC"), data);break;
#endifdefault:break;}

  解码callback的实现比较简单就是Retain一下CVPixelBuffer。

static void videotoolbox_decoder_callback(void *opaque,void *sourceFrameRefCon,OSStatus status,VTDecodeInfoFlags flags,CVImageBufferRef image_buffer,CMTime pts,CMTime duration)
{VTContext *vtctx = opaque;if (vtctx->frame) {CVPixelBufferRelease(vtctx->frame);vtctx->frame = NULL;}if (!image_buffer) {av_log(vtctx->logctx,  AV_LOG_DEBUG,"vt decoder cb: output image buffer is null: %i\n", status);return;}vtctx->frame = CVPixelBufferRetain(image_buffer);
}

2.2 videotoolbox_h264_decode_paramsff_videotoolbox_frame_params

 &esmp;videotoolbox_h264_decode_params主要的工作就是将上层解码出来额sps和pps信息拷贝到VTContext中。

case H264_NAL_SPS: {GetBitContext tmp_gb = nal->gb;if (avctx->hwaccel && avctx->hwaccel->decode_params) {ret = avctx->hwaccel->decode_params(avctx,nal->type,nal->raw_data,nal->raw_size);if (ret < 0)goto end;}if (ff_h264_decode_seq_parameter_set(&tmp_gb, avctx, &h->ps, 0) >= 0)break;av_log(h->avctx, AV_LOG_DEBUG,"SPS decoding failure, trying again with the complete NAL\n");init_get_bits8(&tmp_gb, nal->raw_data + 1, nal->raw_size - 1);if (ff_h264_decode_seq_parameter_set(&tmp_gb, avctx, &h->ps, 0) >= 0)break;ff_h264_decode_seq_parameter_set(&nal->gb, avctx, &h->ps, 1);break;

  ff_videotoolbox_frame_params比较简单就是将CodecContext中的参数传递给HWFramesContext。

ff_videotoolbox_alloc_frame,ff_videotoolbox_h264_start_frame,ff_videotoolbox_h264_decode_slice,videotoolbox_h264_end_frame

  这几个函数每一帧都会调用,顺序是alloc_frame->start_frame->decode_frame->end_frame
  ff_videotoolbox_alloc_frame用来申请一块内存,此时的内存只是一块儿裸内存只是将release函数指针设置成了VT的release指针,还未与CVPixelBuffer绑定,绑定是在解码器的Callback中进行的。
  ff_videotoolbox_h264_start_frame主要就是将上层传下来的stream数据流拷贝到VTContext中。
  videotoolbox_common_decode_slice也是拷贝数据流。
  videotoolbox_h264_end_frame才是具体将数据送给解码器的地方,核心的地方就是videotoolbox_session_decode_frame,这里送给解码器的数据流就上上面拷贝的数据流,需要注意的是在初始化时的callback中只是做了拷贝内存其他什么也没有做。这是因为在这里调用了VTDecompressionSessionWaitForAsynchronousFrames等待异步解码完成,能够保证上一帧解码完成后才送下一帧数据。

2.3 ff_videotoolbox_uninit

  ff_videotoolbox_uninit比较简单就是释放解码器的Context和缓存中的内存。

  • Apple Documentation——VideoToolbox
http://www.yayakq.cn/news/174258/

相关文章:

  • 深圳工厂网站建设公司淘宝客如何做淘宝客网站
  • 台州建设网站制作游戏型网站开发
  • 淘宝运营自学教程入门淄博网站排名优化
  • 赤峰住房城乡建设部网站常德网站优化推广
  • 安阳建设网站网站建设需要洽谈什么
  • 做网站的标签什么意思上海做关键词推广企业
  • 广东seo网站推广成都网站建设全平台
  • 国外做设计赚钱的网站django网站开发视频教程下载
  • 建设国家地质公园网站主要功能0建设营销型网站步骤介绍
  • 镇江网站建设推广查询网站备案密码是什么情况
  • 厦门网站建设公司网站后台中文模板
  • 成武菏泽网站建设百度有没有做游戏下载网站吗
  • 德阳网站建设熊掌号编程软件python下载
  • 建立网站要钱吗昆明的互联网公司有哪些
  • ftp网站备份在线培训系统软件
  • 站长工具seo综合查询下载安装短网址生成平台
  • ii6创建网站教育行业手机wap网站
  • 做网站和网页有区别吗电话销售的10个小技巧
  • 做网站上的在线支付怎么做万商天勤律师事务所
  • 一件代发48个货源网站杭州高瑞网站建设
  • 做的网站如何投入搜索引擎标准网站建设报价单
  • 国外的外贸网站微信软文怎么写
  • 广西建设工程造价管理协会网站网络服务器建设
  • 网站关键词优化难不难项目之家app
  • 网站年龄和域名年龄网站logo设计标准
  • 怎么提高网站关键词排名app推广渠道有哪些
  • 经济型网站建设windows 2008 wordpress
  • 网站开发运行环境做的好看的国内网站欣赏
  • 网站建设ui设计单位网站建设申请
  • 广州公司网站设计望牛墩仿做网站