用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,腾讯云高级开发工程师,负责移动客户端开发 最近抖音最近又带了一波合唱的节奏,老 ...
随机推荐
- (转)Scala中协变(+)、逆变(-)、上界(<:)、下界(>:)简单介绍
看源码的时候看到: trait ExtensionId[T <: Extension] { 没见过这个符号啊<: Scala上界(<:)和下界(>:) 1) U >: T ...
- POJ 3122-Pie(二分+精度)
题目地址:id=3122">POJ 3122 题意:给出n个pie的直径.有F+1个人,假设给每人分的大小同样(形状能够不同),每一个人能够分多少.要求是分出来的每一份必须出自同一个p ...
- 南阳OJ 背包问题
/*背包问题 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描写叙述 如今有非常多物品(它们是能够切割的),我们知道它们每一个物品的单位重量的价值v和 重量w(1< ...
- JDBC:数据库操作:处理大对象CLOB数据
目标: 了解大对象处理基本原理, 掌握CLOB数据的读,写操作. 可以使用CLOB类处理大文本数据. 大对象处理主要指CLOB和BLOB两种类型字段.可以大量存储文字. 要想在程序中处理这样的大数据操 ...
- 【PHP】导入、导出Excel表格(有使用PHPExcel和不使用的两个版本)
------------ 首先,导出excel ---------------- 一.不使用PHPExcel的版本,很简单的一个方法,简洁.推荐 很简单的导出一个exc ...
- 学习-短信的上行(MO)和下行(MT)详解
基础知识: SP服务提供商: 通常是指在移动网内运营增值业务的社会合作单位, 它们建立与移动网络建立相连的服务平台, 为手机用户提供一系列信息服务, 如:娱乐.游戏.短信.彩信.WAP.彩铃.铃声下载 ...
- Nuget使用规范
- gitlab8.0 一键安装 经过自己测试 发送邮件部分最难搞 国内没有说明白的
邮件发送部分,弄了一天终于弄好啦,FQ过去查的资料,奶奶的无语 Gitlab搭建步骤 一:操作系统环境 CentOS: 6.5 –x86-64 二:安装方式 一种是自定义安装,一种是一键安装 三:自定 ...
- min-height clear
在编辑页面时,总是会遇到min-height的设置 但是设置min-height后下面的div总是 跟随min-height的高度有些漂浮,如果不想让下面的div没有漂浮的效果 可以用到样式 clea ...
- 1 bootstrap table null默认显示为 - 要查源码 2 记一个很无语的bug
本来返回的json 3个true 7个false的 结果显示10个true 因为本来是好的 结果判断的问题 给全部赋值true了