用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”
FFMPEG的文档少,JavaCV的文档就更少了。从网上找到这篇100行代码实现最简单的基于FFMPEG+SDL的视频播放器。地址是http://blog.csdn.net/leixiaohua1020/article/details/8652605。
用JavaCV重新实现并使用opencv_highgui进行显示。
import com.googlecode.javacpp.IntPointer;
import com.googlecode.javacpp.Pointer;
import com.googlecode.javacv.cpp.avcodec;
import com.googlecode.javacv.cpp.avcodec.AVPacket;
import com.googlecode.javacv.cpp.avcodec.AVPicture;
import com.googlecode.javacv.cpp.avformat;
import com.googlecode.javacv.cpp.avutil;
import com.googlecode.javacv.cpp.avutil.AVDictionary;
import com.googlecode.javacv.cpp.opencv_core;
import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_8U;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_core.cvSize;
import com.googlecode.javacv.cpp.opencv_highgui;
import static com.googlecode.javacv.cpp.opencv_highgui.cvDestroyWindow;
import static com.googlecode.javacv.cpp.opencv_highgui.cvNamedWindow;
import com.googlecode.javacv.cpp.swscale;
import com.googlecode.javacv.cpp.swscale.SwsContext; /**
*
* @author cuizhenfu@gmail.com
*/
public class DecodingH264 { public static void main(String[] args) {
String filePath = "Images/butterfly.h264"; // Register all formats and codes
avformat.av_register_all();
avcodec.avcodec_register_all(); // Open video file
avformat.AVFormatContext formatCtx = avformat.avformat_alloc_context();
if (avformat.avformat_open_input(formatCtx, filePath, null, null) != 0) {
System.out.println("无法打开文件\n");
return;
} if (avformat.avformat_find_stream_info(formatCtx, (AVDictionary) null) < 0) {
System.out.println("Couldn't find stream information.\n");
return;
}
int videoIndex = -1;
for (int i = 0; i < formatCtx.nb_streams(); i++) {
if (formatCtx.streams(i).codec().codec_type() == avutil.AVMEDIA_TYPE_VIDEO) {
videoIndex = i;
break;
}
} if (videoIndex == -1) {
System.out.println("Didn't find a video stream.\n");
return;
} avcodec.AVCodecContext codecCtx = formatCtx.streams(videoIndex).codec();
avcodec.AVCodec codec = avcodec.avcodec_find_decoder(codecCtx.codec_id());
if (codec == null) {
System.out.println("Codec not found.\n");
return;
} if (avcodec.avcodec_open2(codecCtx, codec, (AVDictionary) null) < 0) {
System.out.println("Could not open codec.\n");
} avutil.AVFrame frame = avcodec.avcodec_alloc_frame();
avutil.AVFrame frameRGB = avcodec.avcodec_alloc_frame(); // 注意AVPicture的构造方法,参考http://blog.csdn.net/wahrlr/article/details/21970755
// 注意avutil.av_malloc的返回值(用Pointer代替uint8_t*)
int nunBytes = avcodec.avpicture_get_size(avutil.AV_PIX_FMT_RGB24, codecCtx.width(), codecCtx.height());
Pointer outBuffer = avutil.av_malloc(nunBytes);
avcodec.avpicture_fill(new AVPicture(frameRGB), outBuffer.asByteBuffer(), avutil.AV_PIX_FMT_RGB24, codecCtx.width(), codecCtx.height()); avformat.av_dump_format(formatCtx, 0, filePath, 0); SwsContext img_convert_ctx = swscale.sws_getContext(codecCtx.width(), codecCtx.height(), codecCtx.pix_fmt(), codecCtx.width(), codecCtx.height(), avutil.AV_PIX_FMT_RGB24, swscale.SWS_BICUBIC, null, null, (double[])null); AVPacket packet = new AVPacket();
int y_size = codecCtx.width() * codecCtx.height();
avcodec.av_new_packet(packet, y_size);
cvNamedWindow("butterfly.h264");
IplImage showImage = opencv_core.cvCreateImage(cvSize(codecCtx.width(),codecCtx.height()), IPL_DEPTH_8U, 3);
while(avformat.av_read_frame(formatCtx, packet) >= 0) {
if(packet.stream_index() == videoIndex) {
IntPointer ip = new IntPointer();
int ret = avcodec.avcodec_decode_video2(codecCtx, frame, ip, packet);
if(ret < 0) {
System.out.println("解码错误");
return;
}
if(ip.get() != 0) {
swscale.sws_scale(img_convert_ctx, frame.data(), frame.linesize(), 0, codecCtx.height(), frameRGB.data(), frameRGB.linesize()); showImage.imageData(frameRGB.data(0));
showImage.widthStep(frameRGB.linesize().get(0)); opencv_highgui.cvShowImage("butterfly.h264", showImage);
opencv_highgui.cvWaitKey(25);
}
}
avcodec.av_free_packet(packet);
} showImage.release();
cvDestroyWindow("butterfly.h264");
avutil.av_free(frameRGB);
avcodec.avcodec_close(codecCtx);
avformat.avformat_close_input(formatCtx);
} }
用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”的更多相关文章
- 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...
- 【转】100行代码实现最简单的基于FFMPEG+SDL的视频播放器
FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我把自己做项目过程中实现的一个非常简单的视频播放器 ...
- 100行代码实现现代版Router
原文:http://www.html-js.com/article/JavaScript-version-100-lines-of-code-to-achieve-a-modern-version ...
- 100行代码让您学会JavaScript原生的Proxy设计模式
面向对象设计里的设计模式之Proxy(代理)模式,相信很多朋友已经很熟悉了.比如我之前写过代理模式在Java中实现的两篇文章: Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理 J ...
- GuiLite 1.2 发布(希望通过这100+行代码来揭示:GuiLite的初始化,界面元素Layout,及消息映射的过程)
经过开发群的长期验证,我们发现:即使代码只有5千多行,也不意味着能够轻松弄懂代码意图.痛定思痛,我们发现:虽然每个函数都很简单(平均长度约为30行),可以逐个击破:但各个函数之间如何协作,却很难说明清 ...
- 【编程教室】PONG - 100行代码写一个弹球游戏
大家好,欢迎来到 Crossin的编程教室 ! 今天跟大家讲一讲:如何做游戏 游戏的主题是弹球游戏<PONG>,它是史上第一款街机游戏.因此选它作为我这个游戏开发系列的第一期主题. 游戏引 ...
- 100行代码实现HarmonyOS“画图”应用,eTS开发走起!
本期我们给大家带来的是"画图"应用开发者Rick的分享,希望能给你的HarmonyOS开发之旅带来启发~ 介绍 2021年的华为开发者大会(HDC2021)上,HarmonyOS ...
- 100 行代码实现的 JavaScript MVC 样式框架
介绍 使用过 JavaScript框架(如 AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现 ...
- 100行代码搞定抖音短视频App,终于可以和美女合唱了。
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由视频咖 发表于云+社区专栏 本文作者,shengcui,腾讯云高级开发工程师,负责移动客户端开发 最近抖音最近又带了一波合唱的节奏,老 ...
随机推荐
- ScrollView 和 ListView 冲突解决方案
网上说了很多阿,什么linearLayout 实现listView 什么的.还设置高什么的. 其实,你们可能忘记了,如果出现 ScrollView 和 ListView 同时出现,那就是设计错误了. ...
- js实现选择及复制粘贴
最近项目有个点击复制到粘贴板的需求,在这里做一个简单的例子分享给大家,没考虑兼容性,需要兼容的大家去查找下文档 //html<p id="element">测试测试&l ...
- gensim自然语言处理(续)
上一篇,已经实现了如何将一条语句在一个语料库中比较相似度, 发现运行的时候每次都要编译语料库,通过查找资料,可以一次性编译成预料库,存人文件 编译语料库代码 11_k.py import sysimp ...
- 【转】iBatis简单入门教程
1. iBatis 简介: iBatis 是apache 的一个开源项目,一个O/R Mapping 解决方案,iBatis 最大的特点就是小巧,上手很快.如果不需要太多复杂的功能,iBatis 是能 ...
- angular -- $resource 用法
安装 ngResource模块是一个可选的angularjs模块,如果需要使用,我们要单独引用js <script type="text/javascript" src=&q ...
- canvas贝济埃曲线
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- struts 防止重复提交表单
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC &qu ...
- C语言-数据结构(一)
1.动态创建多维数组 int ** createArray(int rows, int cols) { int **x, i; x = (int **)malloc(rows * sizeof(*x) ...
- jqplot使用小心得
这两天做一个项目,需要画饼图,所以在网上搜到jqplot这个插件.下面就说说我对他的简单的使用心得. 先说说我想要的效果:1.我需要修改饼图每个部分的背景色 2.我需要修改饼图里面文本的颜色和字体大小 ...
- VSCode开发工具下载
VSCode集成多语言和插件,方便开发和代码管理. 请到此处下载:https://code.visualstudio.com/Download