[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"solution-scenes-menu":3,"tech-detail-2372":4},true,{"id":5,"title":6,"content":7,"picUrl":8,"tagIds":9,"keyWords":10,"htmlDescribe":11,"htmlUrl":12,"gmtCreate":13,"gmtModified":13,"articleInfoId":14},"2372","美畅物联丨如何通过 FFmpeg 解码视频","\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002F967be1dd-9dba-43e4-88fc-b18e1cf11e75.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">FFmpeg是一款功能强大、在多媒体处理领域广泛应用的开源工具。它可以处理多种音频和视频格式，包含编码、解码、转码、流媒体处理等众多功能。前两天，我们在《美畅物联丨如何通过FFmpeg排查视频问题》一文中介绍了借助FFmpeg程序来辅助判断视频播放异常的方法。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">实际上，在视频解码方面，FFmpeg同样提供了灵活且高效的解决方案，不管是将视频转换为可播放的格式，还是提取视频中的音频、图像等元素，都能够借助它得以实现。今日，我们借助代码实例来展示怎样运用FFmpeg对视频进行解码。\u003C\u002Fp>\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002Fc398bcba-bcc0-49b6-a623-db472c027a8f.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify;line-height:2\">首先引入FFmpeg库所需的头文件。\u003C\u002Fp>\u003Cp style=\"text-align:center;line-height:2\">\u003Cbr \u002F>\u003C\u002Fp>\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002Fab8fd809-503d-4797-b58e-3ec8c4879b31.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002F5e9f864d-c0c4-4868-a202-93c032793ebd.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">接着，我们需要打开解码器，并且初始化一系列必要的参数。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">当这一步成功完成之后，我们就能够通过FFmpeg对视频帧进行解码了。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">具体的代码如下：\u003C\u002Fp>\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002F5e39a27b-d281-4ccf-850e-2fcd40e199c6.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">借助avcodec_send_packet函数，将原始视频帧送入解码器；接着，利用avcodec_receive_frame函数获取解码后的视频帧。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">具体而言，解码过程能够被细化为如下几个关键步骤：\u003C\u002Fp>\u003Cp style=\"text-align:justify;line-height:2\">\u003Cstrong>1、创建AVCodecContext对象：\u003C\u002Fstrong>利用avcodec_alloc_context3函数，为解码器分配并初始化一个AVCodecContext对象。该对象涵盖了解码器所需的全部配置信息，包含视频的编码参数、像素格式、时间基准等，是解码工作的核心部分。\u003C\u002Fp>\u003Cp style=\"text-align:justify;line-height:2\">\u003Cstrong>2、开启解码器：\u003C\u002Fstrong>通过avcodec_open2函数开启解码器，从而让FFmpeg库能够运用针对特定视频编码格式的解码机制。在此过程中，需要将之前创建的AVCodecContext对象当作参数传入，这样解码器才能够获取到必要的信息。\u003C\u002Fp>\u003Cp style=\"text-align:justify;line-height:2\">\u003Cstrong>3、发送原始视频帧：\u003C\u002Fstrong>运用avcodec_send_packet函数，按照既定的规则和格式将原始视频数据递交给解码器进行处理。解码器在接收到视频帧之后，会对视频帧进行深度解析与转换。\u003C\u002Fp>\u003Cp style=\"text-align:justify;line-height:2\">\u003Cstrong>4、获取解码后的视频：\u003C\u002Fstrong>利用avcodec_receive_frame函数接收解码器输出的视频帧。这些帧数据已经转换为便于处理的格式，可用于后续的算法处理或者显示操作。\u003C\u002Fp>\u003Cp style=\"text-align:justify;line-height:2\">\u003Cstrong>5、释放资源：\u003C\u002Fstrong>在解码工作完成之后，需要调用avcodec_free_context函数来释放AVCodecContext对象，以免造成资源泄露。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify;line-height:2\">解码后的视频帧通常采用YUV420P格式。然而，在算法开发中，我们往往需要使用BGR格式的图像数据。为了解决这个问题，我们可以借助FFmpeg提供的SwsContext来进行格式转换。\u003C\u002Fp>\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002F3a8c1a7a-bb9e-408f-a5c7-a59a7fb15139.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">通过sws_getContext函数，我们创建了一个SwsContext对象。然后，利用sws_scale函数，我们将YUV420P格式的视频帧转换为BGR格式。这样，我们就可以轻松地将转换后的图像数据传递给算法库进行处理了。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">在实际应用中，我们可能还需要将BGR数据的指针地址传递给算法库的接口函数。例如，在调用某个目标检测算法的接口时，我们可以将转换后的BGR图像数据作为输入参数传递给算法库，从而进行后续的目标检测处理。代码如下：\u003C\u002Fp>\u003Cpre>\u003Ccode>_stDetIo.img_data = frame-&gt;get()-&gt;data[0];\n_iRet = aia_obj_det_process(x_pvDetHandle, &amp;_stDetIo);\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:left\">通过以上步骤，我们便能轻松运用FFmpeg来进行视频解码，且把解码后的视频转化为适合算法处理的格式。希望本文能够为大家的视频开发工作带来一些启示和帮助。\u003C\u002Fp>\u003Cp style=\"text-align:justify\">————————————————\u003C\u002Fp>\u003Cp>\u003Cspan style=\"color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);font-size:16px\">关注\u003C\u002Fspan>\u003Cspan style=\"color:rgb(66, 144, 247);background-color:rgb(255, 255, 255);font-size:16px\">\u003Cstrong>“美畅物联”\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);font-size:16px\">，了解更多视频汇聚及AIoT底座解决方案。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp>\u003Cbr \u002F>\u003C\u002Fp>","https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F02\u002Fdd490910-dac2-4d3b-ac8c-b59472a2a376.jpg","9","美畅，美畅物联，畅联，畅联云平台，视频监控云平台，云视频监控，视频云平台，视频开放平台，视频感知云，视频接入网关，AIoT综合接入网关，视频中台，物联网中台，无插件播放，H265播放，Ehome，ISUP， GB28181，GB35114，gat1400，JT808","原创技术分享丨美畅物联向工","http:\u002F\u002Fwww.24hlink.cn\u002Fweb-index\u002FLON93GO.html","2024-12-02 15:43:11","796"]