最近关注的流媒体方向技术,FFMPEG学习是绕不过去的,不过网上关于FFMPEG的应用基本是基于2015年左右的版本,最新的FFMPEG视频解码部分变动还是挺大的,特此记录一下解码过程:

首先当然是FFMPEG的解码器等的初始化:

// 一定要先调用该注册FFMPEG,否则下面的都无法使用

av_register_all();

// 调用该初始化函数才能读取RTSP/RTMP等网络流的协议数据,否则干瞪眼,只解码本地文件的可以无视

avformat_network_init();

初始化完后需要申请一个AVFormatContext对象  *pFormatCtx = avformat_alloc_context();用于解码的上下文,有点FFMPEG基础的都明白这是老套路了。

然后呢还是老套路,调用以下两个函数:

// decodeUrl即为你要进行解码的链接,可以是本地文件路径,也可以是RTSP/RTMP等网络视频流的URL路径

avformat_open_input(&pFormatCtx, decodeUrl, NULL, NULL);

avformat_find_stream_info(pFormatCtx, NULL);

然后就在pFormatCtx->nb_streams找对应的解码类型为视频格式的解码器,这里跟老版本是有点不一样的,codecpar是新推荐的成员变量:

videoindex = -1;
    for (uint32_t i = 0; i < pFormatCtx->nb_streams; i++)
    {
        if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            videoindex = i;
            break;
        }

}

接下来还是有点区别的,不过一般人还是可以靠自己解决的

AVCodec  *pCodec = avcodec_find_decoder(pFormatCtx->streams[videoindex]->codecpar->codec_id);
    if (pCodec == NULL)
    {
        return -1;
    }

AVCodecContext  *pCodecCtx = avcodec_alloc_context3(pCodec);

获取视频解码器并创建解码器上下文,很好理解,套路一样就是细节改了改;

下面就开始打开解码器了,这个没变:

avcodec_open2(pCodecCtx, pCodec, NULL);

然后创建视频帧及YUV帧对象跟数据包对象

AVFrame *pFrame = av_frame_alloc();
AVFrame *pFrameYUV = av_frame_alloc();
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));

接下来就是循环读取数据并解码了

while (av_read_frame(pFormatCtx, packet) >= 0)
{if (packet->stream_index == videoindex)
{
// 视频帧进行解码,注意这里很不一样了,之前一个函数调用即可,现在需要自己再次写一个解码函数,具体看下面函数实现ret = Decode(pCodecCtx, pFrame, packet);if (ret < 0){printf("Decode Error.\n");av_packet_unref(packet);continue;}// 这里即为解码出来的数据进行YUV转换存储y_size = pCodecCtx->width*pCodecCtx->height;fwrite(pFrame->data[0], 1, y_size, fp_yuv);      //Y fwrite(pFrame->data[1], 1, y_size / 4, fp_yuv);  //Ufwrite(pFrame->data[2], 1, y_size / 4, fp_yuv);  //Vprintf("Write one frame...\n");}
// 用完了别忘了释放packetav_packet_unref(packet);
}

上面的没啥好说的,主要是Decode函数的实现不一样了,改动挺大的,下面贴出实现代码

int Decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
{int ret;// 先发送包数据到解码上下文中ret = avcodec_send_packet(dec_ctx, pkt);if (ret < 0){printf("Error sending a packet for decoding\n");return ret;}// 然后从解码上下文中读取帧数据到frame对象中return avcodec_receive_frame(dec_ctx, frame);
}

不知道官方基于何种意愿做此修改的,个人觉着麻烦多了,因为我要多写不少代码。。。

至此解码工作基本完成,当然用完了资源别忘了还给人家:

av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);

avformat_close_input(&pFormatCtx);

然后测试了下本地视频文件的解码,测试OK,做完后觉着很不错嘛,然而,然而真的那么如你所愿么?显然不是的。。。

在我一时兴起测试RTSP流的时候发现FFMPEG会报错,无法获取,提示什么FFMPEG编译没有添加-lpthread之类的选项,这是什么鬼?懵逼了,因为我是从官方下载的动态链接库,这是你会发现还是GG好使的。。。话不多说,贴解决办法:

在avformat_open_input函数调用中最后一个options参数进行设置RTSP传输基于TCP即可。。。

AVDictionary* options = NULL;
av_dict_set(&options, "rtsp_transport", "tcp", 0);

avformat_open_input(&pFormatCtx, c_TestFile, NULL, &options);

是的,这么设置过后就可以解码RTSP流数据了,知道了后是不是很简单,当然用完了资源记得一定要还:

av_dict_free(&options);

好的,想到的就这么多了。。。

使用FFMPEG3.4.2版本进行视频的解码为YUV格式相关推荐

  1. FFmpeg4入门07:解码视频并保存为YUV格式文件

    上一篇我们解码并保存了其中的几帧确保解码过程和结果是对的.本篇我们将解码整个视频并保存为标准的YUV格式(YUV格式具体信息详见YUV格式介绍),我们就选YUV420P(I420)作为输出格式. 保存 ...

  2. 视频与图像RGB/YUV格式详解

    计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...

  3. H.264/AVC视频编解码技术详解 第一章 视频信息与压缩编码

    H.264/AVC视频编解码技术详解系列笔记 是对 H.264/AVC视频编解码技术详解 课程的学习 文章目录 人与世界的交互 视频信号的表示方法 视频压缩编码 视频信息为什么可以被压缩? 视频压缩编 ...

  4. 深入浅出理解视频编解码技术

    导读:随着移动互联网技术的蓬勃发展,视频已无处不在.视频直播.视频点播.短视频.视频聊天,已经完全融入了每个人的生活.Cisco 发布的最新报告中写道,到 2022 年,在移动互联网流量中,视频数据占 ...

  5. 音视频-视频编/解码 实战

    先来简单看下 音视频的采集 . 一.音视频的采集 音视频采集的核心流程: 音/视频采集 用到的视频输出的类是AVCaptureVideoDataOutput,音频输出的类是AVCaptureAudio ...

  6. ffmpeg音视频编解码的封装

    //导入头文件 //核心库 #include "libavcodec/avcodec.h" //封装格式处理库 #include "libavformat/avforma ...

  7. FFMPEG总结 -- 音视频编解码和转码(全)

    在经过一周的学习后,现将其稍加总结下:附代码及详细注释. 简单分为如下六个部分 一.播放一个视频文件的流程 二.ffmpeg 视频编码 (YUV编码为H.264) 三.ffmpeg 视频解码 (解码为 ...

  8. 使用FFMPEG——4.2.2版本实现提取视频编码解码文件,ffmpeg基础学习。

    FFMPEG基础学习 视频解码,并且输出到文件. 我通过雷霄骅的博客学习FFMPEG,在学习过程中发现"雷神"的代码由于版本的问题,很多代码已经无法在FFMPEG--4.2.2版本 ...

  9. 音视频从入门到精通——ffmpeg3之打印多媒体文件音视频信息

    ffmpeg3之打印多媒体文件音视频信息 av_dump_format函数 /*** Print detailed information about the input or output form ...

  10. MediaCodec在Android视频硬解码组件的应用

    https://yq.aliyun.com/articles/632892 云栖社区> 博客列表> 正文 MediaCodec在Android视频硬解码组件的应用 cheenc 2018- ...

最新文章

  1. 有漏洞无作为才可怕、可耻!
  2. 动态代理之: com.sun.proxy.$Proxy0 cannot be cast to 问题
  3. CISCO 路由器(1)
  4. SCCM 2012系列13 操作系统播发②
  5. react学习笔记10:显示隐藏效果和tab切换效果
  6. 解决idea使用maven打自定义jar缺失
  7. 在linux内核中修改TCP MSS值
  8. Taro使用wxParse富文本组件
  9. UnionID与OpenID的区别【转自微信官方文档】
  10. 模拟退火算法求解超市布局问题
  11. 【数字IC】深入浅出理解UART协议
  12. iOS学习爬坑记录4:ios8中的搜索栏,使用UISearchController
  13. Squid缓存代理服务器
  14. unity中导入的角色没有Avatar
  15. C/C++ 机房预约系统
  16. 计算机用户域怎么删除,如何删除域内非活动计算机账号?
  17. 【Unity3D-Mirror多人坦克大战】坦克生成、移动和摄像机跟随(二)
  18. 大学生PHP简单网站制作方法 学生PHP网站作业 动态PHP毕业设计 PHP MYSQL在线留言板网站源码
  19. 设计模式之原型模式(C语言)
  20. 大唐天下平台模式开发

热门文章

  1. 大学计算机基础及应用课后题答案第二版,《大学计算机基础》课后题答案完整版...
  2. Swift之Attempting to badge the application icon but haven't received permission from the user to badg
  3. uniapp引入腾讯防水墙
  4. 卷积神经网络与机器视觉,卷积神经网络图像分类
  5. 卡内基梅隆大学计算机专业有哪些,卡内基梅隆大学计算机系统类大学排名最新资讯总结篇...
  6. Mybatis报错 :Error evaluating expression ‘condition.xxxx!= null ‘
  7. VISTA、Win7激活administrator用户
  8. DNA甲基化经CTCF和黏连蛋白复合体调节RNA可变剪切
  9. Matlab 网络通信(TCP IP)
  10. Microsoft buildup new website for open-source project