读取视屏文件,保存帧图片为ppm文件
ffmpeg跟sdl的学习过程:
一、版本信息:
ffmpeg-3.0.2.tar.bz2
SDL2-2.0.4.tar.gz
二、编译过程:
1、ffmgeg的编译:
./configure --enable-shared --disable-yasm --prefix=/usr/local/ffmpeg
make
make install
2、sdl的编译:
./configure --prefix=/usr/local/sdl
make
make install
3、系统环境配置:
查看/etc/ld.so.conf,知道 ”系统共享库路径”
方法一:把编译好的sdl的动态库,ffmpeg的动态库,复制到 “系统共享库路径“ 中,复制完成后,创建好软连接。
(完成之后调用指令ldconfig ???)
方法二:修改/etc/ld.so.conf
把下面的两行追加到ld.so.conf文件中
/usr/local/ffmpeg/lib
/usr/local/sdl/lib
调用ldconfig指令。
ldconfig做的这些东西都与运行程序时有关,跟编译连接sdl库,编译连接ffmpeg库一点关系都没有。编译的时候还是该加-L就得加,不要混淆了
方法三:临时环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/ffmpeg/lib:/usr/local/sdl/lib
方法四:修改shell文件:
$ vi ~/.bash_profile
没有LD_LIBRARY_PATH的话,添加:
LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:/usr/local/sdl/lib
export LD_LIBRARY_PATH
有LD_LIBRARY_PATH的话,
在LD_LIBRARY_PATH之后进行路径添加即可。
LD_LIBRARY_PATH=.......:/usr/local/ffmpeg/lib:/usr/local/sdl/lib
修改完shell文件之后,然后运行
$ source ~/.bash_profile 就行了。
------------------------------------------------------------------
在shell下尝试设置LD_LIBRARY_PATH,以下面这种形式设置,老是报错bash: LD_LIBRARY_PATH: command not found,
LD_LIBRARY_PATH=/usr/local/lib
LD_LIBRARY_PATH = $ LD_LIBRARY_PATH:/usr/local/lib
可能是因为系统之前没有设置过LD_LIBRARY_PATH,于是改成这样:
export LD_LIBRARY_PATH=/usr/local/lib
然后用 echo $LD_LIBRARY_PATH检查一下是否真的设置成功
------------------------------------------------------------
三、编写代码,调用ffmpeg动态库。
代码,读取视屏文件,保存帧图片为ppm文件
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <stdio.h>
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
int y;
// Open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; y<height; y++)
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
// Close file
fclose(pFile);
}
int main(int argc, char* argv[])
{
AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,argv[1],NULL,NULL)!=0)
{
printf("open file error\n");
return -1;
}
if ( avformat_find_stream_info(pFormatCtx,NULL) < 0 )
{
return -1;
}
i = 0;
int videostream = -1;
printf("pFormatCtx->nb_streams=%d\n", pFormatCtx->nb_streams);
for(i=0;i<pFormatCtx->nb_streams;i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videostream = i;
break;
}
}
printf("videostream=%d\n", videostream);
if (-1 == videostream)
{
printf("error no video stream\n");
return;
}
pCodecCtx = pFormatCtx->streams[videostream]->codec;
pCodec = avcodec_find_decoder( pCodecCtx->codec_id );
if(NULL == pCodec)
{
printf("couldn't find the decode\n");
return -1;
}
if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
printf("open decode error\n");
return -1;
}
AVFrame *pFrame,*pFrameRGB;
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
uint8_t *out_buffer;
int num = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
printf("num=%d\n", num);
out_buffer = (uint8_t *)av_malloc(num*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameRGB, out_buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
AVPacket packet;
int ret = -1;
i = 0;
struct SwsContext *img_convert_ctx = NULL;
img_convert_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt , pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
while(av_read_frame(pFormatCtx, &packet)>=0)
{
//printf("i=%d, videoindex=%d, packet.stream_index=%d\n", i++, videoindex, packet.stream_index);
if(packet.stream_index == videostream)
{
//printf("111111\n");
int got_picture = -1;
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
if(ret < 0)
{
printf("decode error\n");
return -1;
}
//printf("got_picture:%d\n",got_picture);
if(got_picture)
{
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
if(++i<=20)
{
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
}
}
}
av_free_packet(&packet);
}
free(out_buffer);
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
avformat_close_input(&pFormatCtx);
return 0;
}
编译指令:
gcc -o test main.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavutil -lavformat -lavcodec -lswscale -lz
sdl,ffmpeg都调用的编译指令:
gcc -o test main.c -I/usr/local/ffmpeg/include -I/usr/local/sdl/include -L/usr/local/ffmpeg/lib -L/usr/local/sdl/lib -lavutil -lavformat -lavcodec -lswscale -lz -lSDL2
读取视屏文件,保存帧图片为ppm文件的更多相关文章
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...
- 读取.properties配置文件并保存到另一个.properties文件内
代码如下 import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileOutputSt ...
- PDF 补丁丁 0.4.1.804 测试版发布:合并文件夹的图片和PDF文件,自由生成多层次书签
新的测试版增强了合并文件的功能,可以合并文件夹内的图片和PDF文件,还可以在合并文件列表上直接指定与合并文件对应的PDF书签标题.通过拖放文件项目生成多层次的PDF书签.如下图所示: 另外,新的测试版 ...
- [R] 保存pheatmap图片对象到文件
一般我们使用pheatmap通过Rstudio交互得到的图片在plots的Export导出即可,如何保存对象到文件呢?这个需求在自动化流程中很常见,作者似乎也没说明. 生成示例数据: test = m ...
- python中读取mongodb数据并保存为csv格式的文件
import pandas as pd import matplotlib.pyplot as plt import pymongo %matplotlib inline # 连接mongodb数据库 ...
- arcengine 将地图文件保存为图片(包括各种图片格式)
1,最近做了个地图文件输出图片的功能,思想主要就是利用MapControl的ActiveView中的out方法: 2代码如下:欢迎交流指正 SaveFileDialog m_save = new Sa ...
- android中保存Bitmap图片到指定文件夹中的方法
/** 保存方法 */ public void saveBitmap() { Log.e(TAG, "保存图片"); File f = new File("/s ...
- logback配置每天生成一个日志文件,保存30天的日志文件
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 文件输出格 ...
- vue项目build 之后,css文件加载图片或者字体文件时404的解决。
ExtractTextWebpackPlugin 提供了一个 options.publicPath 的 api,可以为css单独配置 publicPath . 对于用 vue-cli 生成的项目,di ...
随机推荐
- jQuery学习之prop和attr的区别
1.attr() :默认保存的是浏览器的初始值 prop()保存的是更新的值 2.下面的是首用法,但是.attr()方法可以运行在所有的attributes情况下. 注意:一些DOM元素的prope ...
- JavaScript 闭包整合
初遇闭包感觉很困惑,上网查看了些许介绍,有很多没看懂,就想先对能懂的东西整整 首先觉得要了解闭包,要先对一.JavaScript的变量作用域和作用域链有基本了解 1.变量的作用域分为:全局变量和局部变 ...
- 161101、在Java中如何高效判断数组中是否包含某个元素
如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Overflow中也是一个非常热门的问题.在投票比较高的几个答案中给出了几种 ...
- linux设备树笔记__dts基本概念及语法【转】
转自:http://www.360doc.com/content/15/1113/11/15700426_512794532.shtml 设备树手册(Device Tree Usage)原文地址:ht ...
- How To Set Up Apache Virtual Hosts on CentOS 6
About Virtual Hosts 虚拟主机,用于在一个单一IP地址上,运行多个域.这对那些想在一个VPS上,运行多个网站的人,尤其有用.基于用户访问的不同网站,给访问者显示不同的信息.没有限制能 ...
- Qt实现停靠功能
- Oracle游标练手实例
--声明游标:CURSOR cursor_name IS select_statement --For循环游标 --(1)定义游标 --(2)定义游标变量 --(3)使用for循环来使用这个游标 de ...
- [ Laravel 5.3 文档 ] 安全 ―― API认证(Passport)保障安全性。
1.简介 Laravel通过传统的登录表单已经让用户认证变得很简单,但是API怎么办?API通常使用token进行认证并且在请求之间不维护session状态.Laravel使用LaravelPassp ...
- yii2通过foreach循环遍历在一个用户组中取出id去另一表里查寻信息并且带着信息合并原数组信息---案例
yii2通过foreach循环遍历在一个用户组中取出id去另一表里查寻信息并且带着信息合并元数组信息---案例 public function actionRandomLists(){ //查询到了所 ...
- SQLServer学习笔记<>日期和时间数据的处理(cast转化格式、日期截取、日期的加减)和 case表达式
日期和时间数据的处理. (1)字符串日期 ‘20080301’,这一串为字符串日期,但必须保证为四位的年份,两位的月份,两位的日期.例如,查询订单表日期大于‘20080301’.可以这样写: 1 se ...