MediaCodec编码结合FFmpeg封装流
在Android平台上合成视频一般使用MediaCodec进行硬编码,使用MediaMuxer进行封装,但是因为MediaMuxer在某些机型上合成的视频在其他手机上播放会出现问题,而且只支持一个音频轨道,因此可以选用FFmpeg来封装编码后的音视频流。
创建FFmpeg AVFormatContext
AVFormatContext*ofmt_ctx=nullptr;
intret=avformat_alloc_output_context2(&ofmt_ctx, nullptr, "mp4", filePath);
AVOutputFormat*ofmt=ofmt_ctx->oformat;
ret=avio_open(&ofmt_ctx->pb, filePath, AVIO_FLAG_WRITE);
添加音视频流
这里以添加h264视频流为例
AVStream*stream=avformat_new_stream(ofmt_ctx, nullptr);
intvideo_stream=stream->index;
AVCodecParameters*codecpar=stream->codecpar;
codecpar->codec_type=AVMEDIA_TYPE_VIDEO;
codecpar->codec_id=AV_CODEC_ID_H264;
codecpar->width=width;
codecpar->height=height;
设置视频流sps和pps
sps和pps能在MediaCodec产生第一帧画面之前获取到,以java MediaCodec异步编码方式为例
@Override
publicvoidonOutputBufferAvailable(@NonNullMediaCodeccodec, intindex, @NonNullMediaCodec.BufferInfoinfo) {
ByteBufferbuffer=encoder.getOutputBuffer(index);
if ((info.flags&MediaCodec.BUFFER_FLAG_CODEC_CONFIG) !=0) {
// 传递 buffer和info.size到native
}
// ...
}
// native获取sps和pps数据地址
uint8_t*data=static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
// 复制给视频流extradata
AVCodecParameters*codecpar=ofmt_ctx->streams[video_stream]->codecpar;
codecpar->extradata= (uint8_t*) av_mallocz(size+AV_INPUT_BUFFER_PADDING_SIZE);
memcpy(codecpar->extradata, data, size);
codecpar->extradata_size=size;
写入视频文件头信息,放在文件开头位置
AVDictionary*dict=nullptr;
av_dict_set(&dict, "movflags", "faststart", 0);
intret=avformat_write_header(ofmt_ctx, &dict);
写入视频流和音频流已编码数据
同样以写入视频流数据为例,️注意视频流和音频流在不同线程写入时需要同步
// onOutputBufferAvailable回调中
booleanisKeyFrame= (info.flags&MediaCodec.BUFFER_FLAG_KEY_FRAME) !=0;
// 传递buffer, info.size, isKeyFrame, info.presentationTimeUs到native
// 获取视频编码数据地址
uint8_t *data = static_cast<uint8_t *>(env->GetDirectBufferAddress(buffer));
AVPacket *packet = av_packet_alloc();
av_init_packet(packet);
packet->stream_index = video_stream;
packet->data = data;
packet->size = size;
packet->pts = av_rescale_q(pts, { 1, 1000000 }, ofmt_ctx->streams[video_stream]->time_base);
if (isKeyFrame) packet->flags |= AV_PKT_FLAG_KEY;
int ret = av_interleaved_write_frame(ofmt_ctx, packet);
av_packet_unref(packet);
av_packet_free(&packet);
结束并关闭文件
至此,整个流程就结束了
av_write_trailer(ofmt_ctx);
avio_closep(&ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
MediaCodec编码结合FFmpeg封装流的更多相关文章
- FFmpeg封装格式处理3-复用例程
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10506653.html FFmpeg封装格式处理相关内容分为如下几篇文章: [1]. F ...
- FFmpeg封装格式处理2-解复用例程
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10506642.html FFmpeg封装格式处理相关内容分为如下几篇文章: [1]. F ...
- FFmpeg封装格式处理
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10506636.html FFmpeg封装格式处理相关内容分为如下几篇文章: [1]. F ...
- WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码
转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...
- FFmpeg封装格式处理4-转封装例程
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10506662.html FFmpeg封装格式处理相关内容分为如下几篇文章: [1]. F ...
- android系统中对ffmpeg封装最好的免费SDK
android系统中对ffmpeg封装最好的免费SDK; 无论个人还是公司,都免费商用, 欢迎下载. https://github.com/LanSoSdk/LanSoEditor_common 可能 ...
- 流媒体测试笔记记录之————阿里云监控、OBS、FFmpeg拉流和推流变化比较记录
OBS设置视频(512kbps)和音频(128kbps)比特率 阿里云监控结果: 使用FFmpeg拉流到Nginx 服务器测试比特率 第二次测试,修改视频和音频比特率 OBS设置 阿里云监控 Ngin ...
- Mediacodec编码后的h264视频出现马赛克问题
问题:在视频采集后,通过Mediacodec编码生成h264视频文件,播放时出现马赛克较多,无论调整帧率.码率.还是分辨率都不能解决问题 出现问题的原因:编码时传入的时间戳不对.时间戳是视频播放的标准 ...
- 音视频处理之FFmpeg封装格式20180510
一.FFMPEG的封装格式转换器(无编解码) 1.封装格式转换 所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(对应.avi,.flv,.mkv,.mp4文件). 需要注意的 ...
随机推荐
- Kubernets二进制安装(16)之安装部署traefik(ingress)
K8S的DNS实现了服务在集群"内"被自动发现,如何使得服务在Kuberneters集群"外"被使用和访问呢,有二种方法 1)使用NodePort型的Servi ...
- DDL 数据定义语言
目录 创建数据库(CREATE) 删除数据库(DROP) 修改数据库(ALTER) 创建数据表(CREATE) 数据表的数据属性 数据类型属性(Type) 其他属性(Null,Key,Default, ...
- 1054D Changing Array 【位运算+思维】
题目:戳这里 题意:两个数n,k,满足给的n个数小于2的k次方.每个数可以进行一次操作,即把a[i]换成a[i]^(1<<k-1);求最多的连续区间数使得 区间[L,R] (1<=L ...
- springboot(四) rabbitMQ demo
RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息中间件在互联网公司的使用中越来越多,刚才还看到新闻阿里将RocketMQ捐献给了apa ...
- springboot( 三)redis demo
redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Red ...
- 2019牛客多校第二场F Partition problem(暴搜)题解
题意:把2n个人分成相同两组,分完之后的价值是val(i, j),其中i属于组1, j属于组2,已知val表,n <= 14 思路:直接dfs暴力分组,新加的价值为当前新加的人与不同组所有人的价 ...
- AirPods Max 出厂激活是怎么回事
AirPods Max 出厂激活是怎么回事 话说出厂激活是怎么检测出来的 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问! 原创文 ...
- Mac 开机时为什么突然响一下,duang
Mac 开机时为什么突然响一下,duang duang 一下 https://zh.wikipedia.org/wiki/Duang refs xgqfrms 2012-2020 www.cnblog ...
- string logo(字符画),website,html5,css3,atom ide
1 <!DOCTYPE html> <!-- Powered by... _ _ ____. ______ ._______. _______ ___ ___ sssssssss \ ...
- JavaScript this All In One
JavaScript this All In One js, this, bind, call, apply, new, function, arrow function, constructor f ...