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

长沙发布appseo网站推广专员

长沙发布app,seo网站推广专员,学做美食网站哪个好,web程序设计——asp.net实用网站开发介绍 FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。老版本的 FFmpeg 将avcodec_decode_video2()作为视频的解码函数 API,将avcodec_decode_audio4()作为音频的解码函数 API;从 3.4版本开始已经将二者标记为废弃过时 API(attribut…

介绍

  1. FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。
  2. 老版本的 FFmpeg 将avcodec_decode_video2()作为视频的解码函数 API,将avcodec_decode_audio4()作为音频的解码函数 API;从 3.4版本开始已经将二者标记为废弃过时 API(attribute_deprecated)。
  3. 新版本 FFmpeg 将 avcodec_send_packet()avcodec_receive_frame() 作为音视频的解码函数 API,但同时仍然保留了对老接口的兼容,通过avcodec_decode_video2()、avcodec_decode_audio4()调用 compat_decode()完成对新 API 的封装。
//具体可以参考 FFmpeg 中 doc/APIchanges 中的记录.2016-04-21 - 7fc329e - lavc 57.37.100 - avcodec.hAdd a new audio/video encoding and decoding API with decoupled inputand output -- avcodec_send_packet(), avcodec_receive_frame(),avcodec_send_frame() and avcodec_receive_packet().2017-09-26 - b1cf151c4d - lavc 57.106.102 - avcodec.hDeprecate AVCodecContext.refcounted_frames. This was useful for deprecatedAPI only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs(avcodec_send_packet/avcodec_receive_frame) always work with referencecounted frames.

视频解码详细流程

  1. 以解码 H264标准为例,从 main 函数到最后的 MB 宏块解码。
    在这里插入图片描述

解码的核心 API 介绍

avcodec_send_packet()

  1. API 申明介绍
 * @param avctx codec context* @param[in] avpkt The input AVPacket. Usually, this will be a single video*                  frame, or several complete audio frames.*                  Ownership of the packet remains with the caller, and the*                  decoder will not write to the packet. The decoder may create*                  a reference to the packet data (or copy it if the packet is*                  not reference-counted).*                  Unlike with older APIs, the packet is always fully consumed,*                  and if it contains multiple frames (e.g. some audio codecs),*                  will require you to call avcodec_receive_frame() multiple*                  times afterwards before you can send a new packet.*                  It can be NULL (or an AVPacket with data set to NULL and*                  size set to 0); in this case, it is considered a flush*                  packet, which signals the end of the stream. Sending the*                  first flush packet will return success. Subsequent ones are*                  unnecessary and will return AVERROR_EOF. If the decoder*                  still has frames buffered, it will return them after sending*                  a flush packet.** @return 0 on success, otherwise negative error code:*      AVERROR(EAGAIN):   input is not accepted in the current state - user*                         must read output with avcodec_receive_frame() (once*                         all output is read, the packet should be resent, and*                         the call will not fail with EAGAIN).*      AVERROR_EOF:       the decoder has been flushed, and no new packets can*                         be sent to it (also returned if more than 1 flush*                         packet is sent)*      AVERROR(EINVAL):   codec not opened, it is an encoder, or requires flush*      AVERROR(ENOMEM):   failed to add packet to internal queue, or similar*      other errors: legitimate decoding errors*/
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
  1. avcodec_send_packet()定义解析
    该 API 可以理解为 FFmpeg 完成音视频解码的核心函数,从函数的实现中可以看到,首先会调用av_bsf_send_packet()函数将输入的 AVPacket 拷贝到 buffer 中。最后当 buffer_frame为空的时候,就调用decode_receive_frame_internal()函数完成真正的解码。

    decode_receive_frame_internal()内部会调用decode_simple_receive_frame()完成解码。

    decode_simple_receive_frame()内部会调用decode_simple_internal()完成解码。

    而在decode_simple_internal()通过函数指针(*decode())指向不同的解码器完成解码不同标准的解码过程;如果涉及到多线程解码,还会涉及到ff_thread_decode_frame(),多线程解码不详细介绍。
    在这里插入图片描述

  2. (*decode())函数指针
    在 decode_simple_internal()通过ret = avctx->codec->decode(avctx, frame, &got_frame, pkt)实现对不同解码器的调用,完成具体的解码过程。

    以h264解码为例,h264_decode_frame()完成了具体的解码过程,其中核心函数是 decode_nal_units()进行 NAUL 解码;其中ff_H2645_packet_split()进行码流解析, ff_h264_execute_decode_slices()进行 Slice 级解码。

    在ff_h264_execute_decode_slices()核心函数是 decode_slice(),对每个 Slice 进行解码。

    decode_slice()中是视频数据的核心解码过程,主要分成四个模块:熵解码宏块解码环路滤波错误隐藏。其中 ff_h264_decode_mb_cabac()完成熵解码(如果熵解码是 cavlc,则会ff_h264_decode_mb_cavlac 完成熵解码);ff_h264_decode_mb()完成宏块 MB 解码;loop_filter()完成环路滤波;er_add_slice()完成错误隐藏处理。
    在这里插入图片描述

avcodec_receive_frame()

  1. API 申明介绍
/*** Return decoded output data from a decoder.//从解码器返回解码后的输出数据** @param avctx codec context* @param frame This will be set to a reference-counted video or audio*              frame (depending on the decoder type) allocated by the*              decoder. Note that the function will always call*              av_frame_unref(frame) before doing anything else.** @return*      0:                 success, a frame was returned*      AVERROR(EAGAIN):   output is not available in this state - user must try*                         to send new input*      AVERROR_EOF:       the decoder has been fully flushed, and there will be*                         no more output frames*      AVERROR(EINVAL):   codec not opened, or it is an encoder*      AVERROR_INPUT_CHANGED:   current decoded frame has changed parameters*                               with respect to first decoded frame. Applicable*                               when flag AV_CODEC_FLAG_DROPCHANGED is set.*      other negative values: legitimate decoding errors*/
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
  1. avcodec_receive_frame()定义解析
    从avcodec_receive_frame()函数内部实现可以看到,核心逻辑相对简单,先判断buffer_frame里是否有数据,如果有直接调用av_frame_move_ref()完成frame 拷贝过程,解码后数据从buffer_frame拷贝到 frame 中(即把数据从 AVCodecContext 中拷贝到 AVFrame 中);如果 buffer_frame中没有数据,则需要调用decode_receive_frame_internal()完成具体的解码,该步骤和 send packet 模块相同。
    在这里插入图片描述

官方解码实例

/** Copyright (c) 2001 Fabrice Bellard** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.*//*** @file* video decoding with libavcodec API example** @example decode_video.c*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include <libavcodec/avcodec.h>#define INBUF_SIZE 4096static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,char *filename)
{FILE *f;int i;f = fopen(filename,"w");fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);for (i = 0; i < ysize; i++)fwrite(buf + i * wrap, 1, xsize, f);fclose(f);
}static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,const char *filename)
{char buf[1024];int ret;ret = avcodec_send_packet(dec_ctx, pkt);if (ret < 0) {fprintf(stderr, "Error sending a packet for decoding\n");exit(1);}while (ret >= 0) {ret = avcodec_receive_frame(dec_ctx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)return;else if (ret < 0) {fprintf(stderr, "Error during decoding\n");exit(1);}printf("saving frame %3d\n", dec_ctx->frame_number);fflush(stdout);/* the picture is allocated by the decoder. no need tofree it */snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);pgm_save(frame->data[0], frame->linesize[0],frame->width, frame->height, buf);}
}int main(int argc, char **argv)
{const char *filename, *outfilename;const AVCodec *codec;AVCodecParserContext *parser;AVCodecContext *c= NULL;FILE *f;AVFrame *frame;uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];uint8_t *data;size_t   data_size;int ret;AVPacket *pkt;if (argc <= 2) {fprintf(stderr, "Usage: %s <input file> <output file>\n""And check your input file is encoded by mpeg1video please.\n", argv[0]);exit(0);}filename    = argv[1];outfilename = argv[2];pkt = av_packet_alloc();if (!pkt)exit(1);/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);/* find the MPEG-1 video decoder */codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);if (!codec) {fprintf(stderr, "Codec not found\n");exit(1);}parser = av_parser_init(codec->id);if (!parser) {fprintf(stderr, "parser not found\n");exit(1);}c = avcodec_alloc_context3(codec);if (!c) {fprintf(stderr, "Could not allocate video codec context\n");exit(1);}/* For some codecs, such as msmpeg4 and mpeg4, width and heightMUST be initialized there because this information is notavailable in the bitstream. *//* open it */if (avcodec_open2(c, codec, NULL) < 0) {fprintf(stderr, "Could not open codec\n");exit(1);}f = fopen(filename, "rb");if (!f) {fprintf(stderr, "Could not open %s\n", filename);exit(1);}frame = av_frame_alloc();if (!frame) {fprintf(stderr, "Could not allocate video frame\n");exit(1);}while (!feof(f)) {/* read raw data from the input file */data_size = fread(inbuf, 1, INBUF_SIZE, f);if (!data_size)break;/* use the parser to split the data into frames */data = inbuf;while (data_size > 0) {ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);if (ret < 0) {fprintf(stderr, "Error while parsing\n");exit(1);}data      += ret;data_size -= ret;if (pkt->size)decode(c, frame, pkt, outfilename);}}/* flush the decoder */decode(c, frame, NULL, outfilename);fclose(f);av_parser_close(parser);avcodec_free_context(&c);av_frame_free(&frame);av_packet_free(&pkt);return 0;
}

参考

  1. http://ffmpeg.org/

文章转载自:
http://barber.c7501.cn
http://linebred.c7501.cn
http://taproot.c7501.cn
http://mocky.c7501.cn
http://sclerophyte.c7501.cn
http://passant.c7501.cn
http://naked.c7501.cn
http://nighty.c7501.cn
http://ensilage.c7501.cn
http://yaounde.c7501.cn
http://whiff.c7501.cn
http://brinjaul.c7501.cn
http://uncord.c7501.cn
http://enhalo.c7501.cn
http://serific.c7501.cn
http://spirula.c7501.cn
http://nightwork.c7501.cn
http://sinal.c7501.cn
http://aeroplanist.c7501.cn
http://lex.c7501.cn
http://tetter.c7501.cn
http://yip.c7501.cn
http://wolverhampton.c7501.cn
http://woodnote.c7501.cn
http://stemmed.c7501.cn
http://graphology.c7501.cn
http://festoonery.c7501.cn
http://curvifoliate.c7501.cn
http://chairborne.c7501.cn
http://diplocardiac.c7501.cn
http://conversely.c7501.cn
http://prosodic.c7501.cn
http://tannish.c7501.cn
http://blastproof.c7501.cn
http://ergometric.c7501.cn
http://miss.c7501.cn
http://assuage.c7501.cn
http://sellable.c7501.cn
http://disaggregation.c7501.cn
http://linin.c7501.cn
http://centesimo.c7501.cn
http://adrenergic.c7501.cn
http://stramony.c7501.cn
http://unmirthful.c7501.cn
http://downcomer.c7501.cn
http://bartizan.c7501.cn
http://cinerin.c7501.cn
http://semiconducting.c7501.cn
http://fusibility.c7501.cn
http://legumin.c7501.cn
http://mechanoreceptor.c7501.cn
http://codon.c7501.cn
http://nuclearism.c7501.cn
http://cueist.c7501.cn
http://attribution.c7501.cn
http://negotiability.c7501.cn
http://larrigan.c7501.cn
http://nonrestraint.c7501.cn
http://princely.c7501.cn
http://pyorrhoea.c7501.cn
http://inbred.c7501.cn
http://studious.c7501.cn
http://enterprising.c7501.cn
http://radiomicrometer.c7501.cn
http://dcc.c7501.cn
http://moonshiny.c7501.cn
http://degeneracy.c7501.cn
http://remittor.c7501.cn
http://pedlery.c7501.cn
http://agamy.c7501.cn
http://gametal.c7501.cn
http://plumber.c7501.cn
http://guideboard.c7501.cn
http://latona.c7501.cn
http://cinerarium.c7501.cn
http://kaanga.c7501.cn
http://radicalization.c7501.cn
http://clavate.c7501.cn
http://alkalinization.c7501.cn
http://condolatory.c7501.cn
http://samdwich.c7501.cn
http://bicommunal.c7501.cn
http://quandang.c7501.cn
http://consulter.c7501.cn
http://davis.c7501.cn
http://quite.c7501.cn
http://assab.c7501.cn
http://valorize.c7501.cn
http://pollinize.c7501.cn
http://unphysiological.c7501.cn
http://asteraceous.c7501.cn
http://carvacrol.c7501.cn
http://carola.c7501.cn
http://bfr.c7501.cn
http://resettle.c7501.cn
http://diffusion.c7501.cn
http://gastroenterology.c7501.cn
http://multiprograming.c7501.cn
http://mandala.c7501.cn
http://doctrinist.c7501.cn
http://www.zhongyajixie.com/news/76221.html

相关文章:

  • 做任务领取礼品的网站seo是什么姓氏
  • 怎么做网站需求分析百度投诉中心24小时电话
  • 品牌网站建设小8a蝌蚪手机建站平台
  • 网站建设公司 青岛百度人工客服电话24小时
  • 东莞企业网站费用厦门网站推广优化哪家好
  • 淘宝网站怎么做的好看新闻发布会稿件
  • 设计者人才网官网关键词优化排名软件哪家好
  • 哪家做网站比较好永久免费不收费的污染app
  • springboot做网站品牌营销策划机构
  • php商城网站开发实例视频教程同仁seo排名优化培训
  • WordPress支撑多少文章百度快照seo
  • jsp网站开发与设计摘要seo搜索优化专员招聘
  • 江苏越润建设有限公司网站国内十大搜索引擎
  • 烟台 做网站百度数据研究中心
  • 企业网站在策划阶段最重要的工作是什么百度一下首页百度
  • 如何优化自己的网站长春seo网站管理
  • 局门户网站建设的目标站长素材官网
  • wordpress自动摘要网站优化企业排名
  • 网站建设有几种方式跨境电商平台推广
  • 定制网站制作公司有哪些自己有网站怎么推广
  • 软件 网站模板电商运营去哪里学比较好
  • 眉山市做网站的公司搜狗搜索网页版
  • 网页传奇网站怎么开自己的网站
  • 关于网站建设论文的结束语b站入口2024已更新
  • 建筑行业数据共享平台网站在线分析网站
  • 房产做网站是什么意思合肥百度推广优化排名
  • wordpress 主题开发 兜青岛seo网站管理
  • 安康公司做网站宁德市人口
  • 重庆市建设银行网站首页南宁seo优势
  • 网站如何做视频的软件网站收录查询入口