接下来是解析影片的帧

/***
project.c
***/
#include<stdio.h>
#include<libavcodec/avcodec.h>
#include<libavformat/avformat.h>
#include<libswscale/swscale.h> void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[];
int y; //open file
sprintf(szFilename,"frame%d.ppm",iFrame);
pFile = fopen(szFilename, "wb");
if (NULL == pFile)
return; //write header
fprintf(pFile, "P6\n%d %d\n255\n",width,height); //write pixel data
for (y = ; y < height; y++)
{
fwrite(pFrame->data[] + y * pFrame->linesize[],
, width * , pFile);
} //close file
fclose(pFile);
}
int main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = NULL;
AVFrame *pFrameRGB = NULL;
AVPacket packet;
int i,videoStream;
int frameFinished;
int numBytes;
uint8_t *buffer = NULL; AVDictionary *optionsDict = NULL;
struct SwsContext *sws_ctx = NULL; if (argc < )
{
printf("Please provide a movie file\n");
return -;
} //register all formats and codecs
av_register_all(); //open video file
if (avformat_open_input(&pFormatCtx,argv[], NULL, NULL) != )
{
return -; //couldn't open file
} //retrive stream information
if (avformat_find_stream_info(pFormatCtx, NULL) < )
{
return -; //couldn't find stream information
} //dump information about file onto standard error
av_dump_format(pFormatCtx, , argv[], ); //find the first video stream
videoStream = -;
for (i = ; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
break;
}
} if (videoStream == -)
{
return -; //Don't find a video stream
} //Get a pointer to the codec context for the video stream
pCodecCtx = pFormatCtx->streams[videoStream]->codec; //Find the decoder for the video stream
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
{
fprintf(stderr,"Unsupported codec!\n");
return -; //Codec not found
} //open codec
if (avcodec_open2(pCodecCtx, pCodec, &optionsDict) < )
{
return -; //Could not open codec
} //Allcocate an AVFrame structure
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
if (pFrameRGB == NULL)
{
return -;
} //Determine required buffer size and allocate buffer
numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height);
buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t)); sws_ctx = sws_getContext
(
pCodecCtx->width,
pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width,
pCodecCtx->height,
AV_PIX_FMT_RGB24,
SWS_BILINEAR,
NULL, NULL, NULL
); //Assign appropriate parts of buffer to image planes in pFrameRGB
//Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVFPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer,
AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); //Read frames and save first five frames to disk
i = ;
while (av_read_frame(pFormatCtx, &packet) >= )
{
//Is this a packet from video stream
if (packet.stream_index == videoStream)
{
//decode video frame
avcodec_decode_video2(pCodecCtx, pFrame,
&frameFinished, &packet); //Did wo get a video frame
if (frameFinished)
{
//Convert the image from its native format to RGB
sws_scale(sws_ctx,
(uint8_t const * const *)pFrame->data,
pFrame->linesize,
,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize
); //Save the frame to disk
SaveFrame(pFrameRGB,pCodecCtx->width,
pCodecCtx->height,i);
printf("decde %d frame\n",i);
i++;
}
} //Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
} //Free the RGB image
av_free(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 ;
}

makefile如下:

//makefile

DIR_INC = -I/usr/local/include
DIR_LIB = -L/usr/local/lib LIBS = -lavformat\
-lavcodec\
-lva-x11 \
-lva \
-lxcb-shm \
-lxcb-xfixes \
-lxcb-render \
-lxcb-shape \
-lxcb -lX11 \
-lasound \
-lz \
-lswresample \
-lswscale \
-lavutil \
-lm \
-pthread FLAGS = -Wall -ggdb project : project.c
gcc project.c ${FLAGS} ${DIR_INC} ${DIR_LIB} ${LIBS} -o project .PHONY:clean
clean:
rm project

运行结果:

完成后有很多ppm文件,可以将ppm转为jpg:

编写一个脚本转化,内容如下:

/***
1.sh
***/
#!/bin/bash ff=`ls *.ppm` for f in $ff
do
file=`echo ${f%.*}`
ffmpeg -i "$file".ppm "$file".jpg
done mkdir -p jpgs
mv *.jpg jpgs
rm *.ppm

运行脚本:

sh 1.sh

可以在当前文件夹下找到jpgs文件夹下找到所有转化的jpg图片。

ffmpeg结合SDL编写播放器(三)的更多相关文章

  1. ffmpeg结合SDL编写播放器(二)

    我们将对帧数据做一些处理,比如将每一帧的 图像转为jpg或者bmp或者ppm等格式保存下来. 举例:在ffmpeg-2.8.8文件夹下编写test.c程序 /* test.c */ #include& ...

  2. ffmpeg结合SDL编写播放器

    创建播放窗口 SDL_Surface *screen = NULL; screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->heig ...

  3. ffmpeg结合SDL编写播放器(一)

    ffmpeg 工具是一个高效快速的命令行工具,进行视音频不同格式之间的转换. ffmpeg命令行 ffmpeg可以读取任意数量的输入“文件”(可以是常规文件,管道,网络流,抓取设备等)读取,由 -i ...

  4. H.264:FFMpeg 实现简单的播放器

    H.264:FFMpeg 实现简单的播放器   FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我 ...

  5. H264-YUV通过RTP接收视频流ffmpeg解码SDL实时播放

    写在前面的话 写一个简单的播放器,通过RTP接收视频流,进行实时播放.最初,使用ffplay或者vlc接收按照SDP协议文件可以播放视频,但是视频中断后重启,不能正确的解包,时常会出现如下的错误信息. ...

  6. JavaCV 学习(二):使用 JavaCV + FFmpeg 制作拉流播放器

    一.前言 在 Android 音视频开发学习思路 中,我们不断的学习和了解音视频相关的知识,随着知识点不断的学习,我们现在应该做的事情,就是将知识点不断的串联起来.这样才能得到更深层次的领悟.通过整理 ...

  7. FFmpeg入门,简单播放器

    一个偶然的机缘,好像要做直播相关的项目 为了筹备,前期做一些只是储备,于是开始学习ffmpeg 这是学习的第一课 做一个简单的播放器,播放视频画面帧 思路是,将视频文件解码,得到帧,然后使用定时器,1 ...

  8. ffmpeg学习(三)——ffmpeg+SDL2 实现简单播放器

    本篇实现基于ffmpeg动态库用测试程序播放本地文件和RTSP视频流. 参考文章:http://blog.csdn.net/leixiaohua1020/article/details/8652605 ...

  9. 基于FFmpeg和Qt的播放器 QtAV库

    http://blog.csdn.net/ibingow/article/details/8144795

随机推荐

  1. .Net Core 获取应用物理路径的常见问题

    如果要得到传统的ASP.Net应用程序中的相对路径或虚拟路径对应的服务器物理路径,只需要使用使用Server.MapPath()方法来取得Asp.Net根目录的物理路径. 但是在Asp.Net Cor ...

  2. APS.NET MVC + EF (02)---ADO.NET Entity FrameWork

    2.1 Entity Framework简介 Ado.net Entity Framework 是Microsoft推出的ORM框架. 2.1.1 什么是ORM 对象关系映射(Object Relat ...

  3. Spring项目中的数据库加密

    有时候为了安全,我们需要对数据库密码进行加密: SpringDruid数据源加密数据库密码 当我们初步开始打造系统时,什么都没有一片空白,而数据源使用的是SpringDruid时,我们可以通过这篇博客 ...

  4. @Valid注解的使用springmvc pojo校验

    @Valid注解用于校验,所属包为:javax.validation.Valid. ① 首先需要在实体类的相应字段上添加用于充当校验条件的注解,如:@Min,如下代码(age属于User类中的属性): ...

  5. Java基础篇(下)

    6.Java面向对象的三个特征与含义 三大特征是:继承.封装和多态. (1)继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得 ...

  6. dubbo循序渐进 - 什么是RPC

    RPC的核心并不在于使用什么协议.RPC的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里.通过RPC能解耦服务,这才是使用RPC的真正目的.RPC的原理 ...

  7. selenium firefox 内存 速度优化

    selenium firefox 内存 速度优化 2 23 profile = webdriver.FirefoxProfile() 2 24 profile.set_preference(" ...

  8. 编写可维护的JavaScript-随笔(二)

    一.注释 1. 单行注释 a)      以两个斜线开始,以行位结束 b)      独占一行的注释,用来解释下一行的代码, c)      注释行之前总有一个空行 d)      缩进层级与下一行代 ...

  9. Java 面向对象—非静态代码块

    一.非静态代码块 1.声明格式 [修饰符] class 类名 { { 非静态代码块 } } 2.非静态代码块中的代码执行时机 (1)在"每次"创建对象的时候执行 (2)比构造方法早 ...

  10. Android源码分析(四)-----Android源码编译及刷机步骤

    一 : 获取源码: 每个公司服务器地址不同,以如下源码地址为例: http://10.1.14.6/android/Qualcomm/msm89xx/branches/msm89xx svn环境执行: ...