源码地址:
Native源码:

native-lib.cpp

#include <jni.h>
#include <string>
#include <android/log.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>}#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,"testffmpeg",__VA_ARGS__)#define srcWidth 640
#define srcHeight 480#define outWidth 640
#define outHeight 480//extern "C" 是不能少的,同时需要正确的返回函数的返回值,否则会出错
extern "C"
JNIEXPORT void JNICALL
Java_com_sunmi_testffmpeg_UsbCamera_start_1preview(JNIEnv *env, jobject instance, jobject surface) {// TODOFILE *src_file =fopen("/sdcard/yuv420.yuv", "rb");if(src_file == NULL)LOGW("yuv420.yuv open failed !");//设置输入视频文件的大小和视频格式const int src_w=srcWidth,src_h=srcHeight;AVPixelFormat src_pixfmt=AV_PIX_FMT_YUV420P;//获取输入视频文件每个像素占有的BIT数int src_bpp=av_get_bits_per_pixel(av_pix_fmt_desc_get(src_pixfmt));//设置输出图像的大小和格式const int dst_w=outWidth,dst_h=outHeight;AVPixelFormat dst_pixfmt=AV_PIX_FMT_RGBA;//获取输出视频文件每个像素占有的BIT数int dst_bpp=av_get_bits_per_pixel(av_pix_fmt_desc_get(dst_pixfmt));//Structuresuint8_t *src_data[4];int src_linesize[4];uint8_t *dst_data[4];int dst_linesize[4];struct SwsContext *img_convert_ctx;//用于临时存放yuv420p文件的bufuint8_t *temp_buffer=(uint8_t *)new char[src_w*src_h*src_bpp/8];int frame_idx=0;int ret=0;/*通过输入宽和高以及像素格式分配输入缓冲,对于yuv420p的格式:* src_data[0]:代表Y通道;src_linesize[0]:对齐后的Y宽度,可能会大于输入的图像宽度* src_data[1]:代表U通道;src_linesize[1]:对齐后的U宽度* src_data[2]:代表V通道;src_linesize[2]:对齐后的V宽度* align:输入宽度需要对齐到多少*/ret= av_image_alloc(src_data, src_linesize,src_w, src_h, src_pixfmt, 1);if (ret< 0) {LOGW( "Could not allocate source image\n");return ;}/*通过输出宽和高以及像素格式分配输入缓冲,对于RGBA的格式:* dst_data[0]:代表RGBA通道;dst_linesize[0]:对齐后的RGBA宽度(W*H*4),可能会大于输入的图像宽度* dst_data[1]:RGBA是非平面数据* dst_data[2]:RGBA是非平面数据* align:输出宽度需要对齐到多少*/ret = av_image_alloc(dst_data, dst_linesize,dst_w, dst_h, dst_pixfmt, 1);if (ret< 0) {LOGW( "Could not allocate destination image\n");return ;}//-----------------------------//Init Method 1//分配图像转换的上下文img_convert_ctx =sws_alloc_context();//Set Value//SWS_BICUBIC代表的是图像转换的其中一种算法av_opt_set_int(img_convert_ctx,"sws_flags",SWS_BICUBIC|SWS_PRINT_INFO,0);//设置图像转换输入源的宽av_opt_set_int(img_convert_ctx,"srcw",src_w,0);//设置图像转换输入源的高av_opt_set_int(img_convert_ctx,"srch",src_h,0);//设置图像转换输入源的格式av_opt_set_int(img_convert_ctx,"src_format",src_pixfmt,0);//'0' for MPEG (Y:0-235);'1' for JPEG (Y:0-255)/** FFmpeg中可以通过使用av_opt_set()设置“src_range”和“dst_range”来设置输入和输出的YUV的取值范围。* 如果“dst_range”字段设置为“1”的话,则代表输出的YUV的取值范围遵循“jpeg”标准;* 如果“dst_range”字段设置为“0”的话,则代表输出的YUV的取值范围遵循“mpeg”标准。* 下面记录一下YUV的取值范围的概念。与RGB每个像素点的每个分量取值范围为0-255不同(每个分量占8bit),YUV取值范围有两种:* (1)以Rec.601为代表(还包括BT.709 / BT.2020)的广播电视标准中,Y的取值范围是16-235,U、V的取值范围是16-240。FFmpeg中称之为“mpeg”范围。* (2)以JPEG为代表的标准中,Y、U、V的取值范围都是0-255。FFmpeg中称之为“jpeg” 范围。*/av_opt_set_int(img_convert_ctx,"src_range",1,0);//设置图像转换输出图像的宽av_opt_set_int(img_convert_ctx,"dstw",dst_w,0);//设置图像转换输出图像的高av_opt_set_int(img_convert_ctx,"dsth",dst_h,0);//设置图像转换输出图像的目标格式av_opt_set_int(img_convert_ctx,"dst_format",dst_pixfmt,0);//同上设置输出图像遵循Mjpeg还是Jpegav_opt_set_int(img_convert_ctx,"dst_range",1,0);//初始化图像转换上下文sws_init_context(img_convert_ctx,NULL,NULL);//显示窗口初始化ANativeWindow *nwin = ANativeWindow_fromSurface(env,surface);//设置显示窗口的格式ANativeWindow_setBuffersGeometry(nwin,outWidth,outHeight,WINDOW_FORMAT_RGBA_8888);//定义窗口bufANativeWindow_Buffer wbuf;while(1){//从源图像中读取一帧的数据到temp_buffer中if (fread(temp_buffer, 1, src_w*src_h*src_bpp/8, src_file) != src_w*src_h*src_bpp/8){break;}switch(src_pixfmt){case AV_PIX_FMT_GRAY8:{memcpy(src_data[0],temp_buffer,src_w*src_h);break;}case AV_PIX_FMT_YUV420P:{//通道转换,YUV420P有三个通道需要转换memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Ymemcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h/4);      //Umemcpy(src_data[2],temp_buffer+src_w*src_h*5/4,src_w*src_h/4);  //Vbreak;}case AV_PIX_FMT_YUV422P:{//通道转换,YUV422P有三个通道需要转换memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Ymemcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h/2);      //Umemcpy(src_data[2],temp_buffer+src_w*src_h*3/2,src_w*src_h/2);  //Vbreak;}case AV_PIX_FMT_YUV444P:{memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Ymemcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h);        //Umemcpy(src_data[2],temp_buffer+src_w*src_h*2,src_w*src_h);      //Vbreak;}case AV_PIX_FMT_YUYV422:{memcpy(src_data[0],temp_buffer,src_w*src_h*2);                  //Packedbreak;}case AV_PIX_FMT_RGB24:{memcpy(src_data[0],temp_buffer,src_w*src_h*3);                  //Packedbreak;}default:{printf("Not Support Input Pixel Format.\n");break;}}//将数据转换,YUV420P转换为RGBA格式sws_scale(img_convert_ctx, src_data, src_linesize, 0, src_h, dst_data, dst_linesize);LOGW("Finish process frame %5d\n",frame_idx);frame_idx++;ANativeWindow_lock(nwin,&wbuf,0);//wbuf.bits:对应的就是surface的bufuint8_t *dst = (uint8_t*)wbuf.bits;//因为RGBA是非平面的数据,所以转换后数据是存放在dst_data[0]中的memcpy(dst,dst_data[0],outWidth*outHeight*4);ANativeWindow_unlockAndPost(nwin);}sws_freeContext(img_convert_ctx);free(temp_buffer);av_freep(&src_data[0]);av_freep(&dst_data[0]);return;
}extern "C"
JNIEXPORT jboolean JNICALL
Java_com_sunmi_testffmpeg_MainActivity_open(JNIEnv *env, jobject instance, jstring url_,jobject handle) {const char *url = env->GetStringUTFChars(url_, 0);// TODO//Parametersout:env->ReleaseStringUTFChars(url_, url);return JNI_TRUE;
}//extern "C" 是不能少的,同时需要正确的返回函数的返回值,否则会出错
extern "C"
jstring
Java_com_sunmi_testffmpeg_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {std::string hello = "Hello from C++";hello += avcodec_configuration();return env->NewStringUTF(hello.c_str());
}

JAVA端源码很简单:

package com.sunmi.testffmpeg;import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.view.SurfaceHolder;/*** Created by Administrator on 2018/12/14 0014.*/public class UsbCamera extends GLSurfaceView implements Runnable,SurfaceHolder.Callback{public UsbCamera(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic void run() {//不能阻塞主线程start_preview(getHolder().getSurface());}@Overridepublic void surfaceCreated(SurfaceHolder var1){new Thread(this).start();}@Overridepublic void surfaceChanged(SurfaceHolder var1, int var2, int var3, int var4){}@Overridepublic void surfaceDestroyed(SurfaceHolder var1){}public native void start_preview(Object surface);
}

演示图片:

Android下播放YUV视频文件相关推荐

  1. 【开源项目----Android OPenGLES渲染YUV视频文件】

    [开源项目----Android OPenGLES渲染YUV视频文件] OpenGLES对YUV渲染相关文章参考

  2. YUVPlayer: 基于Android平台的YUV视频原始数据播放器

    基于Android平台的YUV视频原始数据播放器 编译环境 FFmpeg版本: 4.2.2 NDK版本:r17c 运行环境 x86(模拟器) arm64-v8a(64位手机) 功能点 从文件中读取YU ...

  3. ubuntu 下播放 yuv 格式的文件预览Raw格式图片

    1.ubuntu 下播放 yuv 格式的文件 1)使用ffplay sudo apt-get install ffmpeg 查看图片 ffplay -f rawvideo -video_size 64 ...

  4. 实践:基于腾讯云播放器SDK,带您体验播放多场景下的 COS 视频文件

    一. 实践步骤 1. 准备您的 腾讯云COS 视频文件链接,您需要: 1.1 创建一个存储桶: 1.2 上传对象: 1.3 在对象信息详情里复制对象地址: 注意: 目前腾讯云有COS特惠活动,新人1元 ...

  5. 01 Qt6.2.3播放YUV视频,使用QOpenGLWidget

    Qt6.2.3播放YUV视频,使用QOpenGLWidget 作者 将狼才鲸 创建日期 2022-03-30 工程Gitee源码地址:qt_gui_simple2complex/ source / 0 ...

  6. 使用ffmpeg指令转换出yuv视频文件

    播放器播放的都是经过解码后的视频,也就是yuv格式的视频文件,因此在学习的过程中需要准备一下yuv格式的视频做实验素材,这里演示如何在电脑中使用ffmpeg指令将一个视频文件转换为.yuv格式. 1. ...

  7. web三件套(经验贴)Google里,video标签播放mkv视频文件

    video标签播放mkv视频文件 第一次: <embed src="咏春.mkv" hidden="no" loop="true" R ...

  8. Win10系统,用C++调用OpenCV接口,播放本地视频文件,播放本地和网络摄像头

    1 前言 前边2篇文章介绍了在WIN10系统上,分别用C++和Python调用OpenCV接口,加载和显示一张静态图片.本篇我们来看一下,用C++如何调用OpenCV接口,打开和播放本地视频文件,打开 ...

  9. Python调用OpenCV接口播放本地视频文件、本地和网络摄像头

    1 前言 上篇文章介绍了在WIN10系统上, C++调用OpenCV接口,播放本地视频文件.本地和网络摄像头视频.本篇我们来看一下,Python如何调用OpenCV接口,做同样的事情. 序号 视频来源 ...

  10. matlab显示YCrCb的图像,【Matlab系列】读取并显示YUV视频文件

    Date: 2019-5-12 1.读取并显示YUV视频文件Matlab代码 %% 1.读取视频内容并显示 fid = fopen('akiyo_cif.yuv','r'); %读入YUV文件 row ...

最新文章

  1. android 自定义模板下载,android studio 自定义模板
  2. POJ3468--A Simple Problem with Integers--线段树/树状数组 改段求段
  3. Windows CE下流驱动的动态加载
  4. LeetCode17——Letter Combinations of a Phone Number(手机几个按键对应的字母(符号)组合)
  5. Qt笔记-拖动文件到QWidget(获取拖动文件路径)
  6. CHIL-SQL-INNER JOIN 关键字
  7. 人与人之间交往最重要的是什么?
  8. linux同步某台服务器,linux 两台服务器之间开机自动同步指定目录下的文件
  9. 自然语言领域中图神经网络模型(GNN)应用现状(论文)
  10. Laravel 5.3 windows环境安装
  11. 如何按行政区划下载谷歌地图并裁剪
  12. 【硕博士推荐】国内有哪些不错的CV(计算机视觉)团队?
  13. 2022-2028全球针织捆包网行业调研及趋势分析报告
  14. 压缩文件下载后无法打开问题解决方法
  15. Redis 哨兵模式安装方法
  16. 软考中级-数据库系统工程师复习知识点汇总
  17. java构造块与静态块
  18. python修改图片尺寸和DPI
  19. 有关JAVA考试中数据库的题_全国2018年4月自考互联网数据库考试真题
  20. 深度学习(PyTorch)——librosa库的使用

热门文章

  1. php5.3 appache phpstudy win7win8win10下 运行速度慢
  2. (qsf文件 、 tcl文件 和 csv(txt)文件的区别) FPGA管脚分配文件保存、导入导出方法...
  3. 用微软makecert.exe生成一个自签名的证书
  4. 浅谈WebService的版本兼容性设计
  5. Python之路——Python3 入门教程
  6. NBA历史上50大巨星2
  7. 在B/S开发中经常用到的javaScript技术(转载)
  8. fd抓包数据类型_fiddler——抓包中的王者
  9. python按键按下改变数值_「正点原子NANO STM32开发板资料连载」第十六章电容触摸按键实验...
  10. 绘制自己组合的k线图_史上最全K线图大全:搞懂70种K线组合形态,轻松低买高卖不踏空...