接下来是解析影片的帧

/***
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图片。

最新文章

  1. MFC-简单的函数使用
  2. SpringBoot源码解析:AOP思想以及相应的应用
  3. android 获取当前系统时间
  4. hdu 2680 最短路径(dijkstra算法+多源最短路径单源化求最小值)这题有点意思
  5. When you’re nearly 40 and unmarried, and you realize you’re going to be okay
  6. 【转】C++及java在内存分配上的区别
  7. Cocos2d-x3.0TestCpp文件夹笔记(二)
  8. 清橙A1484
  9. 面试题19:包含min函数的栈
  10. 在centOS7.2安装配置zabbix监控
  11. VR全景智慧城市-VR大时代
  12. html加载和解析流程
  13. 201521123059 《Java程序设计》第十二周学习总结
  14. vue-axios基本用法
  15. [原创]FPGA JTAG工具设计(一)
  16. MongoDB系列----mongostat
  17. pycharm与python环境配置
  18. SQL server 多个字段设为主键
  19. web前端(9)—— CSS属性
  20. eolinker——添加项目成员

热门文章

  1. 关于VS2019使用Git时遇到的Bug
  2. NuGet包 安装相关指令
  3. nginx 反向代理Jenkins
  4. React生命周期中应该做什么事
  5. Vue笔记目录
  6. 英语fieldyellowstone田黄石fieldyellowstone单词
  7. Android 指定调用已安装的某个“相机”App
  8. java InputStream的使用
  9. php+js实现极验,拖动滑块验证码验证表单
  10. k8s几种pod的控制器