用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”

FFMPEG的文档少,JavaCV的文档就更少了。从网上找到这篇100行代码实现最简单的基于FFMPEG+SDL的视频播放器。地址是http://blog.csdn.net/leixiaohua1020/article/details/8652605。

用JavaCV重新实现并使用opencv_highgui进行显示。


  1 import com.googlecode.javacpp.IntPointer;
2 import com.googlecode.javacpp.Pointer;

3 import com.googlecode.javacv.cpp.avcodec;
4 import com.googlecode.javacv.cpp.avcodec.AVPacket;
5 import com.googlecode.javacv.cpp.avcodec.AVPicture;
6 import com.googlecode.javacv.cpp.avformat;
7 import com.googlecode.javacv.cpp.avutil;
8 import com.googlecode.javacv.cpp.avutil.AVDictionary;
9 import com.googlecode.javacv.cpp.opencv_core;
10 import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_8U;
11 import com.googlecode.javacv.cpp.opencv_core.IplImage;
12 import static com.googlecode.javacv.cpp.opencv_core.cvSize;
13 import com.googlecode.javacv.cpp.opencv_highgui;
14 import static com.googlecode.javacv.cpp.opencv_highgui.cvDestroyWindow;
15 import static com.googlecode.javacv.cpp.opencv_highgui.cvNamedWindow;
16 import com.googlecode.javacv.cpp.swscale;
17 import com.googlecode.javacv.cpp.swscale.SwsContext;
18
19 /**
20 *
21 * @author [email protected]
22 */
23 public class DecodingH264 {
24
25 public static void main(String[] args) {
26 String filePath = "Images/butterfly.h264";
27
28 // Register all formats and codes
29 avformat.av_register_all();
30 avcodec.avcodec_register_all();
31
32 // Open video file
33 avformat.AVFormatContext formatCtx = avformat.avformat_alloc_context();
34 if (avformat.avformat_open_input(formatCtx, filePath, null, null) != 0) {
35 System.out.println("无法打开文件\n");
36 return;
37 }
38
39 if (avformat.avformat_find_stream_info(formatCtx, (AVDictionary) null) < 0) {
40 System.out.println("Couldn‘t find stream information.\n");
41 return;
42 }
43 int videoIndex = -1;
44 for (int i = 0; i < formatCtx.nb_streams(); i++) {
45 if (formatCtx.streams(i).codec().codec_type() == avutil.AVMEDIA_TYPE_VIDEO) {
46 videoIndex = i;
47 break;
48 }
49 }
50
51 if (videoIndex == -1) {
52 System.out.println("Didn‘t find a video stream.\n");
53 return;
54 }
55
56 avcodec.AVCodecContext codecCtx = formatCtx.streams(videoIndex).codec();
57 avcodec.AVCodec codec = avcodec.avcodec_find_decoder(codecCtx.codec_id());
58 if (codec == null) {
59 System.out.println("Codec not found.\n");
60 return;
61 }
62
63 if (avcodec.avcodec_open2(codecCtx, codec, (AVDictionary) null) < 0) {
64 System.out.println("Could not open codec.\n");
65 }
66
67 avutil.AVFrame frame = avcodec.avcodec_alloc_frame();
68 avutil.AVFrame frameRGB = avcodec.avcodec_alloc_frame();
69
70 // 注意AVPicture的构造方法,参考http://blog.csdn.net/wahrlr/article/details/21970755
71 // 注意avutil.av_malloc的返回值(用Pointer代替uint8_t*)
72 int nunBytes = avcodec.avpicture_get_size(avutil.AV_PIX_FMT_RGB24, codecCtx.width(), codecCtx.height());
73 Pointer outBuffer = avutil.av_malloc(nunBytes);
74 avcodec.avpicture_fill(new AVPicture(frameRGB), outBuffer.asByteBuffer(), avutil.AV_PIX_FMT_RGB24, codecCtx.width(), codecCtx.height());
75
76 avformat.av_dump_format(formatCtx, 0, filePath, 0);
77
78 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);
79
80 AVPacket packet = new AVPacket();
81 int y_size = codecCtx.width() * codecCtx.height();
82 avcodec.av_new_packet(packet, y_size);
83 cvNamedWindow("butterfly.h264");
84 IplImage showImage = opencv_core.cvCreateImage(cvSize(codecCtx.width(),codecCtx.height()), IPL_DEPTH_8U, 3);
85 while(avformat.av_read_frame(formatCtx, packet) >= 0) {
86 if(packet.stream_index() == videoIndex) {
87 IntPointer ip = new IntPointer();
88 int ret = avcodec.avcodec_decode_video2(codecCtx, frame, ip, packet);
89 if(ret < 0) {
90 System.out.println("解码错误");
91 return;
92 }
93 if(ip.get() != 0) {
94 swscale.sws_scale(img_convert_ctx, frame.data(), frame.linesize(), 0, codecCtx.height(), frameRGB.data(), frameRGB.linesize());
95
96 showImage.imageData(frameRGB.data(0));
97 showImage.widthStep(frameRGB.linesize().get(0));
98
99 opencv_highgui.cvShowImage("butterfly.h264", showImage);
100 opencv_highgui.cvWaitKey(25);
101 }
102 }
103 avcodec.av_free_packet(packet);
104 }
105
106 showImage.release();
107 cvDestroyWindow("butterfly.h264");
108 avutil.av_free(frameRGB);
109 avcodec.avcodec_close(codecCtx);
110 avformat.avformat_close_input(formatCtx);
111 }
112
113 }

用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”,码迷,mamicode.com

时间: 2024-08-05 07:09:35

用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”的相关文章

100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】

转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 简介 流程图 simplest_ffmpeg_player标准版代码 simplest_ffmpeg_player_suSU版代码 结果 FFMPEG相关学习资料 补充问题 ===================================================== 最简单的基于FFmp

不到100行代码实现一个简单的推荐系统

似乎咱的产品七,八年前就想做个推荐系统的,就是类似根据用户的喜好,自动的找到用户喜欢的电影或者节目,给用户做推荐.可是这么多年过去了,不知道是领导忘记了还是怎么了,连个影子还没见到. 而市场上各种产品的都有了推荐系统了.比如常见的各种购物网站京东,亚马逊,淘宝之类的商品推荐,视频网站优酷的的类似影片推荐,豆瓣音乐的音乐推荐...... 一个好的推荐系统推荐的精度必然很高,能够真的发现用户的潜在需求或喜好,提高购物网詀的销量,让视频网站发现用户喜欢的收费电影... 可是要实现一个高精度的推荐系统不

不到100行代码实现一个推荐系统

似乎咱的产品七,八年前就想做个推荐系统的,就是类似根据用户的喜好,自动的找到用户喜欢的电影或者节目,给用户做推荐.可是这么多年过去了,不知道是领导忘记了还是怎么了,连个影子还没见到. 而市场上各种产品的都有了推荐系统了.比如常见的各种购物网站京东,亚马逊,淘宝之类的商品推荐,视频网站优酷的的类似影片推荐,豆瓣音乐的音乐推荐...... 一个好的推荐系统推荐的精度必然很高,能够真的发现用户的潜在需求或喜好,提高购物网詀的销量,让视频网站发现用户喜欢的收费电影... 可是要实现一个高精度的推荐系统不

GameBuilder开发游戏应用系列之100行代码实现贪吃蛇

在线预览:http://osgames.duapp.com/apprun.html?appid=osgames1-801422234293697 在线编辑:http://osgames.duapp.com/gamebuilder.php?appid=osgames1-801422234293697 微信扫描: 运行截图: 除了重力感应游戏,GameBuilder开发传统的游戏也毫不逊色,作为一个怀旧的人,总是对这类游戏情有独钟. 贪吃蛇主要靠一个[UICanvas]来实现,前面一片博客GameB

100行代码教你教务系统自动抢课!

帮助广大学生解决抢课问题!自动抢课!! 100行代码帮你实现抢课! ? 本项目使用了python中splinter的API接口用来操作页面交互,用了twilio用来给手机发送短信通知抢课成功. ? 欢迎大家来全球最大同性交友网站Github:https://github.com/xubin97 来fork我的菜鸡代码,希望你能来继续增加更多功能,我也会不定期更新功能! ? 其中splinter API文档链接:https://splinter.readthedocs.io/en/latest/m

100行代码实现简单目录浏览器制作

给大家分享使用Lae软件开发工具开发小应用程序的过程,希望大家喜欢! 界面部分我们用lae软件开发工具实现,无需写代码,业务逻辑部分使用Lae软件开发平台自带的LuaIDE编辑器,使用100行lua代码完成简单目录浏览器的制作. lae软件下载地址: https://github.com/ouloba/laetool.git lae软件下载地址(国内):https://pan.baidu.com/s/1ckMy0Q 相关视频: http://www.tudou.com/listplay/aly7

基于zbus网络通讯模块实现的MySQL透明代理(&lt;100行代码)

项目地址 https://git.oschina.net/rushmore/zbus 我们上次讲到zbus网络通讯的核心API: Dispatcher -- 负责-NIO网络事件Selector引擎的管理,对Selector引擎负载均衡 IoAdaptor -- 网络事件的处理,服务器与客户端共用,负责读写,消息分包组包等 Session -- 代表网络链接,可以读写消息 实际的应用,我们几乎只需要做IoAdaptor的个性化实现就能完成高效的网络通讯服务,今天我们将举例说明如何个性化这个IoA

100 行代码实现的 JavaScript MVC 样式框架

介绍 使用过 JavaScript框架(如 AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现根据需要变化视图时更加轻松,而模型-视图-控制器(mvc)的核心概念就是:处理传入请求的控制器.显示信息的视图.表示业务规则和数据访问的模型. 因此,当需要创建这样一个需要在单个页面中实现切换出不同内容的应用时,我们通常选择使用上述框架之一.但是,如果我们仅仅需要一个在一个url中实现视图切换的框架

最简单的基于FFMPEG的转码程序分析 +ffmpga代码简析(转 +总结)

模块:  libavcodec    - 编码解码器         libavdevice   - 输入输出设备的支持         libavfilter   - 视音频滤镜支持         libavformat   - 视音频等格式的解析         libavutil     - 工具库         libpostproc   - 后期效果处理         libswscale    - 图像颜色.尺寸转换 1. ffmpga代码简析 1.1 av_log() av_