热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FFmpeg像素格式转换和尺寸转换

DemoFFmpeg可以实现像素格式转换和尺寸转换,但是性能开销非常大,对视频帧率影响比较大,实际开发中最好用Shader来实现

Demo

FFmpeg 可以实现像素格式转换和尺寸转换,但是性能开销非常大,对视频帧率影响比较大,实际开发中最好用 Shader来实现,FFmpeg的优势转换接口比较简单。

像素格式转换上下文 SwsContext

(1)sws_getContext
(2)sws_getCachedContext(
struct SwsContext *context,
int srcW, int srcH, 原宽高
enum AVPixelFormat srcFormat,原像素格式
int dstW, int dstH, 目标宽高
enum AVPixelFormat dstFormat,目标格式
int flags, 算法标签(性能差异 效果差异 针对尺寸变化)
SwsFilter *srcFilter,过滤器
SwsFilter *dstFilter,过滤器
const double *param 算法中默认值的设定 可以默认);
两个函数的差别是第一个参数:SwsContext
sws_getContext 会创建一个上下文空间,sws_getCachedContext会去缓冲中找,前后两次参数没变时返回同一个

//每一帧数据的处理
int sws_scale(struct SwsContext *c,
const uint8_t *const srcSlice[],具体数据的数组
const int srcStride[],一行数据的大小
int srcSliceY, 传0
int srcSliceH, 图形高度
uint8_t *const dst[], 目标的地址(指针数组)
const int dstStride[]) 输出的一行数据的大小;

void sws_freeContext(struct SwsContext *swsContext);//是否

 

for (; ; ) {//保证能搜到全部的解码数据re = avcodec_receive_frame(cc, frame);if (re != 0) {break;}if (cc == vc) {frameCount++;vctx = sws_getCachedContext(vctx, frame->width, frame->height, (AVPixelFormat)frame->format, outWidth, outHeight, AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR, 0, 0, 0);if (!vctx) {NSLog(@"sws_getCachedContext failed!");}else{uint8_t *data[AV_NUM_DATA_POINTERS] = {0};data[0] = (uint8_t *)rgb;int lines[AV_NUM_DATA_POINTERS] = {0};lines[0] = outWidth * 4;int h = sws_scale(vctx, frame->data, frame->linesize, 0, frame->height, data, lines);NSLog(@"sws_scale h :%d ",h);}}}//最后一针的时候 avcodec_send_packet(cc, NULL)av_packet_unref(pkt);

 

2018-08-03 19:16:54.397601+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.409398+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.417052+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.425106+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.440420+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.448448+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.457397+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.465670+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.473706+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.481495+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.489395+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.497006+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.504962+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.512761+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.520280+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.528375+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.543610+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.551972+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.559866+0800 FFmpeg402[611:176423] sws_scale h :720

音频冲采样 SwrContext

一般音频解码出来直播不能直接播放,需要经过冲采样

SwrContext *swr_alloc(void); 上下文

SwrContext *swr_alloc_set_opts(设置参数
struct SwrContext *s,
int64_t out_ch_layout,输出layout
AVSampleFormat out_sample_fmt,输出的样本格式
int out_sample_rate,输出样本率
int64_t in_ch_layout,输入layout
AVSampleFormat in_sample_fmt,输入的样本格式
int in_sample_rate, 输入样本率
int log_offset, 0
void *log_ctx);日志 0

int swr_init(struct SwrContext *s); 初始化

void swr_free(struct SwrContext **s);释放

转换函数swr_convert 对每一帧音频做重采样

• int swr_convert(struct SwrContext *s,
uint8_t **out,输出的数组
int out_count,样本的数量 单通道
• const uint8_t **in , 输入参数指针数组
int in_count);

 

//音频重采样上下文初始化SwrContext *actx = swr_alloc();//设置参数actx = swr_alloc_set_opts(actx,av_get_default_channel_layout(2),//2AV_SAMPLE_FMT_S16,ac->sample_rate,av_get_default_channel_layout(ac->channels),ac->sample_fmt,ac->sample_rate,0,0);re = swr_init(actx);if (re != 0) {NSLog(@"swr_init failed!");}else{NSLog(@"swr_init success!");}

 

uint8_t *outData[2] = {0};outData[0] = (uint8_t *)pcm;//重采样int len = swr_convert(actx,//上下文outData,frame->nb_samples,(const uint8_t **)frame->data,frame->nb_samples);NSLog(@"swr_convert len :%d ",len);

 

2018-08-03 19:45:47.054517+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.054560+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066537+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066658+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066744+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066872+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066932+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066977+0800 FFmpeg402[630:182386] swr_convert len :1024

 


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了一种图的存储和遍历方法——链式前向星法,该方法在存储带边权的图时时间效率比vector略高且节省空间。然而,链式前向星法存图的最大问题是对一个点的出边进行排序去重不容易,但在平行边无所谓的情况下选择这个方法是非常明智的。文章还提及了图中搜索树的父子关系一般不是很重要,同时给出了相应的代码示例。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
author-avatar
手机用户2502898863
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有