Android FFmpeg + OpenGL ES YUV Player

本文详细介绍了如何使用FFmpeg从封装的媒体流中提取YUV帧数据,包括打开封装格式上下文、初始化解码器、解码、重裁剪以及将解码后的帧数据送入OpenGL显示的过程。
摘要由CSDN通过智能技术生成

一、FFmpeg解出YUV帧数据

方法介绍

打开封装格式上下文

1)[avformat.h] avformat_open_input
打开媒体流(本地或者网络资源)得到封装格式上下文AVFormatContext
AVFormatContext包含了媒体的基本信息,如时长等

初始化解码器

2)[avformat.h] avformat_find_stream_info
从封装格式上下文中找到所有的媒体数据流AVStream,如音频流、视频流、字幕流等
AVStream中则包含了这些数据流的解码信息,如分辨率、采样率、解码器参数、帧率等等

3)[avcodec.h] avcodec_find_decoder
根据AVStream中的解码器id找到对应的解码器AVCodec,FFmpeg可以指定编译编解码器,因此实际编译的FFmpeg包中可能不包含流所对应的解码器;注意此时解码器还未打开,缺少相关的上下文信息

4)[avcodec.h] avcodec_alloc_context3、avcodec_parameters_to_context
avcodec_alloc_context3创建一个空的codec上下文结构体AVCodecContext
avcodec_parameters_to_context将AVStream中的codec参数信息导入到创建出来的AVCodecContext中

5)[avcodec.h] avcodec_open2
根据解码器上下文中所描述的解码器参数信息打开指定的解码器

6)[avformat.h] av_read_frame
从媒体上下文中读取一个数据包,这是一个压缩后的数据包AVPacket,需要经过解码器解码才能得到原始的媒体数据

解码

6)[avcodec.h] avcodec_send_packet
将av_read_frame读取到的数据压缩包送入解码器进行解码

7)[avcodec.h] avcodec_receive_frame
从解码去读取一帧媒体原始数据,注意(6)、(7)并不是一一对应的调用关系

重裁剪

8)[swscale.h] sws_getContext
由于我们送显时一般都是固定像素格式或者分辨率的,因此需要对解码出的视频原始数据进行重裁剪,将分辨率或者像素格式统一,这个方法主要是初始化重裁剪相关的上下文

9)[swscale.h] sws_scale
将(7)中的AVFrame视频原始数据进行重裁剪

二、Demo实现

2.1 流程简介

FFmpegVideoDecoder.jpg

2.2 代码示例

1)打开封装格式上下文

// 1、创建1个空的上下文对象
AVFormatContext* formatCtx = avformat_alloc_context();
// 2、打开指定资源地址的封装格式上下文
avformat_open_input(&formatCtx, sourcePath.c_str(), nullptr, nullptr);

2)找到视频流

// 3、从封装格式中解析出所有的流信息
avformat_find_stream_info(formatCtx, nullptr);
// 4、遍历流找到视频流
AVStream *videoStream = nullptr;
  for (int i = 0; i < formatCtx->nb_streams; i++) {
   
    if (formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
   
      videoStream = formatCtx->streams[i];
      videoStreamIndex = i;
    }
}

3)根据流信息打开对应的解码器

// 5、找到解码器,这个时候解码器对象还没有打开,不能用
AVCodec *codec = avcodec_find_decoder(videoStream->codecpar->codec_id);
//
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值