使用ffmpeg将视频解析为YUV420
2015-12-24 13:38
666 查看
使用ffmpeg解析视频文件为YUV420,下载最新的 ffmpeg-20151221-git-c0f67e1-win32-dev 版本的开发库,然后用里面的sample做熟悉测试,发现由不少问题,还以为在Win7+VS2010中无法编译呢。但是经过一天多的查找终于解决了,实现了avi和mp4视频的解析(只做了这两种格式的测试)为YUV420.下面的代码是在filtering_video.c例子上做了改进得到的。
参考链接:
http://www.cnblogs.com/lidabo/p/3326502.html http://m.blog.csdn.net/blog/sun6623518/8602372
#ifdef __cplusplus extern "C" { #endif #include<stdio.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/opt.h> #ifdef __cplusplus } #endif static AVFormatContext *fmt_ctx; static AVCodecContext *dec_ctx; static int video_stream_index = -1; static int open_input_file(const char *filename) { int ret; AVCodec *dec; if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n"); return ret; } if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n"); return ret; } /* select the video stream */ ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n"); return ret; } video_stream_index = ret; dec_ctx = fmt_ctx->streams[video_stream_index]->codec; av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0); /* init the video decoder */ if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n"); return ret; } return 0; } int main(int argc, char **argv) { int ret; int got_frame; AVPacket packet; AVFrame *frame = av_frame_alloc(); if (!frame) { perror("Could not allocate frame"); exit(1); } av_register_all(); if ((ret = open_input_file(argv[1])) < 0) { printf("open_input_file wrong\n"); exit(1); } clock_t start = 0; FILE *fp = fopen("video.yuv", "wb"); /* read all packets */ while (1) { if ((ret = av_read_frame(fmt_ctx, &packet)) < 0) { break; } if (packet.stream_index == video_stream_index) { got_frame = 0; start = clock(); ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding video\n"); break; } printf("Time: %d\n",(clock()-start)); if (got_frame) { //use to ouput 1920*1080 yuv420 video with faster speed, need data line alignment //fwrite(frame->data[0], sizeof(frame->data[0][0]), frame->width*frame->height, fp); //fwrite(frame->data[1], sizeof(frame->data[1][0]), frame->width*frame->height/4, fp); //fwrite(frame->data[2], sizeof(frame->data[2][0]), frame->width*frame->height/4, fp); //can be used to ouput any size yuv420 video with fast speed //int width = dec_ctx->width, height = dec_ctx->height; //int height_half = height / 2, width_half = width / 2; //int y_wrap = frame->linesize[0]; //int u_wrap = frame->linesize[1]; //int v_wrap = frame->linesize[2]; //unsigned char *y_buf = frame->data[0]; //unsigned char *u_buf = frame->data[1]; //unsigned char *v_buf = frame->data[2]; ////save y //for (int i = 0; i < height; i++) // fwrite(y_buf + i * y_wrap, 1, width, fp); ////save u //for (int i = 0; i < height_half; i++) // fwrite(u_buf + i * u_wrap, 1, width_half, fp); ////save v //for (int i = 0; i < height_half; i++) // fwrite(v_buf + i * v_wrap, 1, width_half, fp); //fflush(fp); av_frame_unref(frame); } } av_packet_unref(&packet); } fclose(fp); avcodec_close(dec_ctx); avformat_close_input(&fmt_ctx); av_frame_free(&frame); system("pause"); return 0; }
参考链接:
http://www.cnblogs.com/lidabo/p/3326502.html http://m.blog.csdn.net/blog/sun6623518/8602372
相关文章推荐
- UITextField
- SQL Server中的锁可以分为如下几类
- 将B表的字段内容插入到A表字段中
- 记下一些常用的帮助
- 写好JAVA代码的30条经验
- Android EventBus源代码解析 带你深入理解EventBus
- 六种流行的语言大餐---C、C++、python、Java、php、C#你更喜欢哪一个呢?
- VirtualBox复制一个Clone一个虚拟机
- Java NIO系列教程(三) Buffer
- 137,单例模式
- UVa 11352 - Crazy King
- TTL与COMS的区别
- 兄弟连猿代码less css 视频教程学习平台
- java静态代码分析工具FindBugs
- LESS CSS 框架简介
- 抽象类与接口的区别:
- spring+mybatis的事务配置
- Linux下相关查找文件命令(find locate which whereis type)
- HTTP Cookie 详解
- Java NIO学习笔记之二-图解ByteBuffer