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

在Android平台上利用FFmpeg的Swscale组件实现YUV与RGB格式互转

本文探讨了在Android平台上利用FFmpeg的Swscale组件实现YUV与RGB格式互转的技术细节。通过详细分析Swscale的工作原理和实际应用,展示了如何在Android环境中高效地进行图像格式转换。此外,还介绍了FFmpeg的全平台编译过程,包括x264和fdk-aac的集成,并在Ubuntu系统中配置Nginx和Nginx-RTMP-Module以支持直播推流服务。这些技术的结合为音视频处理提供了强大的支持。

音视频实践学习


  • android全平台编译ffmpeg以及x264与fdk-aac实践
  • ubuntu下使用nginx和nginx-rtmp-module配置直播推流服务器
  • android全平台编译ffmpeg合并为单个库实践
  • android-studio使用cmake编译ffmpeg实践
  • android全平台下基于ffmpeg解码MP4视频文件为YUV文件
  • android全平台编译ffmpeg支持命令行实践
  • android全平台基于ffmpeg解码本地MP4视频推流到RTMP服务器
  • android平台下音频编码之编译LAME库转码PCM为MP3
  • ubuntu平台下编译vlc-android视频播放器实践
  • 图解YU12、I420、YV12、NV12、NV21、YUV420P、YUV420SP、YUV422P、YUV444P的区别
  • 图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别
  • YUV420P、YUV420SP、NV12、NV21和RGB互相转换并存储为JPEG以及PNG图片
  • android全平台编译libyuv库实现YUV和RGB的转换
  • android平台下基于ffmpeg对相机采集的NV21数据编码为MP4视频文件
  • android平台下基于ffmpeg采集Camera数据编码成H.264推流到RTMP服务器
  • android平台下基于ffmpeg和ANativeWindow实现简单的视频播放器
  • android平台下基于ffmpeg实现对相机预览截图的功能(NV21数据编码为JPEG文件)
  • android平台下基于ffmpeg的swscale模块实现对YUV和RGB数据进行转换

概述

其实如果对YUV和RGB数据进行转换,更推荐使用libyuv库进行转换,效率更高一些,今天记录一下ffmpeg库自带的swscale模块进行转码工作。

环境配置

操作系统:ubuntu 16.05
ndk版本:android-ndk-r16b
ffmpeg版本:ffmpeg-3.3.8

流程分析

工程实践

核心的转码实现:Transform


#include "native_swscale.h"
#include "logger.h"int NativeSwscale::Transform(const char *videoPath, const char *outputPath) {// 1.注册所有组件av_register_all();// 2.创建AVFormatContext结构体pFormatCtx &#61; avformat_alloc_context();// 3.打开一个输入文件if (avformat_open_input(&pFormatCtx, videoPath, NULL, NULL) !&#61; 0) {LOGE("Could not open input stream");goto end_line;}// 4.获取媒体的信息if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {LOGE("Could not find stream information");goto end_line;}//获取视频轨的下标for (int i &#61; 0; i < pFormatCtx->nb_streams; i&#43;&#43;)if (pFormatCtx->streams[i]->codecpar->codec_type &#61;&#61; AVMEDIA_TYPE_VIDEO) {videoIndex &#61; i;break;}if (videoIndex &#61;&#61; -1) {LOGE("Could not find a video stream");goto end_line;}// 5.查找解码器pCodec &#61; avcodec_find_decoder(pFormatCtx->streams[videoIndex]->codecpar->codec_id);if (pCodec &#61;&#61; NULL) {LOGE("Could not find Codec");goto end_line;}// 6.配置解码器pCodecCtx &#61; avcodec_alloc_context3(pCodec);avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoIndex]->codecpar);pCodecCtx->thread_count &#61; 1;if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {LOGE("Could not open codec");goto end_line;}pFrame &#61; av_frame_alloc();vPacket &#61; (AVPacket *) av_malloc(sizeof(AVPacket));pFrameYUV &#61; av_frame_alloc();bufferSize &#61; av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height,1);out_buffer &#61; (uint8_t *) av_malloc(bufferSize * sizeof(uint8_t));av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer, AV_PIX_FMT_YUV420P,pCodecCtx->width, pCodecCtx->height, 1);//RGB24转换/*bufferSize &#61; av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);out_buffer &#61; (uint8_t *) av_malloc(bufferSize * sizeof(uint8_t));av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer, AV_PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height, 1);*///转换sws_ctx &#61; sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,AV_PIX_FMT_YUV420P, //AV_PIX_FMT_RGB24SWS_BICUBIC,NULL, NULL, NULL);outputFile &#61; fopen(outputPath, "wb&#43;");while (av_read_frame(pFormatCtx, vPacket) >&#61; 0) {if (vPacket->stream_index &#61;&#61; videoIndex) {if (avcodec_send_packet(pCodecCtx, vPacket) !&#61; 0) {return -1;}while (avcodec_receive_frame(pCodecCtx, pFrame) &#61;&#61; 0) {sws_scale(sws_ctx, (const uint8_t *const *) pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);//YUV420Pfwrite(pFrameYUV->data[0], (pCodecCtx->width) * (pCodecCtx->height), 1, outputFile);fwrite(pFrameYUV->data[1], (pCodecCtx->width) * (pCodecCtx->height) / 4, 1,outputFile);fwrite(pFrameYUV->data[2], (pCodecCtx->width) * (pCodecCtx->height) / 4, 1,outputFile);//RGB24//fwrite(pFrameYUV->data[0], (pCodecCtx->width) * (pCodecCtx->height) * 3, 1, outputFile);//UYVY//fwrite(pFrameYUV->data[0],(pCodecCtx->width)*(pCodecCtx->height),2,outputFile);}}av_packet_unref(vPacket);}if (outputFile !&#61; NULL) {fclose(outputFile);outputFile &#61; NULL;}sws_freeContext(sws_ctx);end_line:avcodec_close(pCodecCtx);avcodec_free_context(&pCodecCtx);av_free(pFrame);av_free(pFrameYUV);avformat_close_input(&pFormatCtx);avformat_free_context(pFormatCtx);return 0;
}

最终输出一个output.yuv文件&#xff0c;同步到本地电脑上&#xff0c;使用ffplay可以直接播放&#xff1a;

ffplay -f rawvideo -video_size 480x960 output.yuv

项目地址&#xff1a;ffmpeg-single-swscale
https://github.com/byhook/ffmpeg4android

参考&#xff1a;
https://blog.csdn.net/leixiaohua1020/article/details/14215391


推荐阅读
  • 本文深入探讨了NDK与JNI技术在实际项目中的应用及其学习路径。通过分析工程目录结构和关键代码示例,详细介绍了如何在Android开发中高效利用NDK和JNI,实现高性能计算和跨平台功能。同时,文章还提供了从基础概念到高级实践的系统学习指南,帮助开发者快速掌握这些关键技术。 ... [详细]
  • 表面缺陷检测数据集综述及GitHub开源项目推荐
    本文综述了表面缺陷检测领域的数据集,并推荐了多个GitHub上的开源项目。通过对现有文献和数据集的系统整理,为研究人员提供了全面的资源参考,有助于推动该领域的发展和技术进步。 ... [详细]
  • 利用PaddleSharp模块在C#中实现图像文字识别功能测试
    PaddleSharp 是 PaddleInferenceCAPI 的 C# 封装库,适用于 Windows (x64)、NVIDIA GPU 和 Linux (Ubuntu 20.04) 等平台。本文详细介绍了如何使用 PaddleSharp 在 C# 环境中实现图像文字识别功能,并进行了全面的功能测试,验证了其在多种硬件配置下的稳定性和准确性。 ... [详细]
  • 在Spring框架中,基于Schema的异常通知与环绕通知的实现方法具有重要的实践价值。首先,对于异常通知,需要创建一个实现ThrowsAdvice接口的通知类。尽管ThrowsAdvice接口本身不包含任何方法,但开发者需自定义方法来处理异常情况。此外,环绕通知则通过实现MethodInterceptor接口来实现,允许在方法调用前后执行特定逻辑,从而增强功能或进行必要的控制。这两种通知机制的结合使用,能够有效提升应用程序的健壮性和灵活性。 ... [详细]
  • 本文将介绍一种扩展的ASP.NET MVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。 ... [详细]
  • 深入解析Wget CVE-2016-4971漏洞的利用方法与安全防范措施
    ### 摘要Wget 是一个广泛使用的命令行工具,用于从 Web 服务器下载文件。CVE-2016-4971 漏洞涉及 Wget 在处理特定 HTTP 响应头时的缺陷,可能导致远程代码执行。本文详细分析了该漏洞的成因、利用方法以及相应的安全防范措施,包括更新 Wget 版本、配置防火墙规则和使用安全的 HTTP 头。通过这些措施,可以有效防止潜在的安全威胁。 ... [详细]
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 2019年斯坦福大学CS224n课程笔记:深度学习在自然语言处理中的应用——Word2Vec与GloVe模型解析
    本文详细解析了2019年斯坦福大学CS224n课程中关于深度学习在自然语言处理(NLP)领域的应用,重点探讨了Word2Vec和GloVe两种词嵌入模型的原理与实现方法。通过具体案例分析,深入阐述了这两种模型在提升NLP任务性能方面的优势与应用场景。 ... [详细]
  • APKAnalyzer(1):命令行操作体验与功能解析
    在对apkChecker进行深入研究后,自然而然地关注到了Android Studio中的APK分析功能。将APK文件导入IDE中,系统会自动解析并展示其中各类文件的详细信息。官方文档提供了详细的命令行工具使用指南,帮助开发者快速上手。本文以一个RecyclerView的Adapter代理开源库为例,探讨了如何利用这些工具进行高效的APK分析。 ... [详细]
  • 题目描述:小K不幸被LL邪教洗脑,洗脑程度之深使他决定彻底脱离这个邪教。在最终离开前,他计划再进行一次亚瑟王游戏。作为最后一战,他希望这次游戏能够尽善尽美。众所周知,亚瑟王游戏的结果很大程度上取决于运气,但通过合理的策略和算法优化,可以提高获胜的概率。本文将详细解析洛谷P3239 [HNOI2015] 亚瑟王问题,并提供具体的算法实现方法,帮助读者更好地理解和应用相关技术。 ... [详细]
  • 深入解析:RKHunter与AIDE在入侵检测中的应用与优势
    本文深入探讨了RKHunter与AIDE在入侵检测领域的应用及其独特优势。通过对比分析,详细阐述了这两种工具在系统完整性验证、恶意软件检测及日志文件监控等方面的技术特点和实际效果,为安全管理人员提供了有效的防护策略建议。 ... [详细]
  • 在Laravel中实现PHP对JSON数据的发布与处理 ... [详细]
  • 在单个图表中实现饼图与条形图的精准对齐 ... [详细]
  • 本文探讨了协同过滤算法在推荐系统中的应用,重点介绍了基于用户和基于物品的两种协同过滤方法。通过引入相似度评估技术和交替最小二乘优化技术,显著提升了推荐系统的准确性和鲁棒性。实验结果表明,该方法在处理大规模数据集时表现出色,能够有效提高用户满意度和系统性能。 ... [详细]
  • 使用Boost.Asio进行异步数据处理的应用程序主要依赖于两个核心概念:I/O服务和I/O对象。I/O服务抽象了操作系统接口,使得异步操作能够高效地执行。I/O对象则代表了具体的网络资源,如套接字和文件描述符,通过这些对象可以实现数据的读写操作。本文详细介绍了这两个概念在Boost.Asio中的应用及其在网络编程中的重要性。 ... [详细]
author-avatar
卟可爱頹廢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有