直接将视频文件原码流转换成YUV,输出到屏幕显示
#include "stdafx.h"
#define inline _inline
#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#ifdef __cplusplus
}
#endif
#include <stdio.h>
#include "SDL.h"
#include "SDL_thread.h"
#include <windows.h>
static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
#define SDL_AUDIO_BUFFER_SIZE 1024
static int sws_flags = SWS_BICUBIC;
int main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream(-1);
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVPacket packet;
int frameFinished;
float aspect_ratio;
AVCodecContext *aCodecCtx;
SDL_Overlay *bmp;
SDL_Surface *screen;
SDL_Rect rect;
SDL_Event event;
av_register_all();
const char* filename = "D:\\Wildlife.wmv";
pFormatCtx = avformat_alloc_context();
if (!pFormatCtx)
{
fprintf(stderr, "Memory error/n");
exit(1);
}
//打开视频文件
if(avformat_open_input(&pFormatCtx, filename, NULL, NULL)!=0)
return -1;
//查找视频流信息
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information
// Dump information about file onto standard error
av_dump_format(pFormatCtx, 0, argv[1], 0);
// 查找视频帧
for(i=0; i<pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type== AVMEDIA_TYPE_VIDEO&& videoStream<0)
{
videoStream=i;
}
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// 查找解码器
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
fprintf(stderr, "Unsupported codec!/n");
return -1; // Codec not found
}
// 打开解码器
if(avcodec_open(pCodecCtx, pCodec)<0)
return -1; // Could not open codec
// 申请帧内存
pFrame=avcodec_alloc_frame();
uint8_t *buffer;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width,
pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
{
fprintf(stderr, "Could not initialize SDL - %s/n", SDL_GetError());
exit(1);
}
#ifndef __DARWIN__
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
#else
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0);
#endif
if(!screen)
{
fprintf(stderr, "SDL: could not set video mode - exiting/n");
exit(1);
}
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,
SDL_YV12_OVERLAY, screen);
static struct SwsContext *img_convert_ctx;
if (img_convert_ctx == NULL)
{
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height,
PIX_FMT_YUV420P,
sws_flags, NULL, NULL, NULL);
if (img_convert_ctx == NULL)
{
fprintf(stderr, "Cannot initialize the conversion context/n");
exit(1);
}
}
i=0;
//不停的从码流中提取帧数据
while(av_read_frame(pFormatCtx, &packet)>=0)
{
// 判定数据包是否来自视频流
if(packet.stream_index==videoStream)
{
// 解码
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
&packet);
// Did we get a video frame?
if(frameFinished)
{
// Convert the image from its native format to RGB
/*sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);*/
// Save the frame to disk
/*if(++i<=5)
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);*/
//创建一个覆盖,用于显示
SDL_LockYUVOverlay(bmp);
AVPicture pict;
pict.data[0] = bmp->pixels[0];
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[1];
pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[2];
pict.linesize[2] = bmp->pitches[1];
// Convert the image into YUV format that SDL uses
/*img_convert(&pict, PIX_FMT_YUV420P,
(AVPicture *)pFrame, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height);*/
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
0, pCodecCtx->height, pict.data, pict.linesize);
//解锁覆盖
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
//显示
SDL_DisplayYUVOverlay(bmp, &rect);
Sleep(20);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default: break;
}
};
// Free the YUV image
av_free(buffer);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
return 0;
}
直接将视频文件原码流转换成YUV,输出到屏幕显示的更多相关文章
- php将文件转换成二进制输出[转]
header( "Content-type: image/jpeg"); $PSize = filesize('1.jpg'); $picturedata = fread(fope ...
- 利用ffmpeg0.6.1把.h264纯码流打包成.mp4 .avi等格式 (转载)
转自:http://cache2.weidaohang.org/h/index.php?q=aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cWluZ183MzkvYXJ0aWNsZS ...
- 将一个读取流转换成bitmap对象
将一个读取流转换成bitmap对象: BitmapFactory:可以将文件,读取流,字节数组转换成一个Bitmap对象. Bitmap bitmap = Bitma ...
- go http 下载视频(TS码流文件)(推荐一个网站学习 go example)
视频 http下载代码 dn.go(注意:代码很ugly,没怎么花时间) 总体感觉特别简单,网上看了下 net/http ,io这2个库的使用, 几分钟就写完了,感觉cpp 在做工具这块 开发效率的 ...
- 用vlc SDK创建一个播放视频文件和RTSP流视频的Demo
#include <stdio.h> #include <tchar.h> #include <time.h> #include <windows.h> ...
- plupload分片上传视频文件源码展示
plupload分片上传视频文件目录结构如下: |- images//视频上传小图片 |-js// plupload js文件 |-uploads//视频文件存放文件夹 里面是按日期存放 |-ajax ...
- 控制台程序的中文输出乱码问题(export LC_CTYPE=zh_CN.GBK,或者修改/etc/sysconfig/i18n为zh_CN.GBK。使用setlocale(LC_CTYPE, "");会使用默认办法。编译器会将源码做转换成Unicode格式,或者指定gcc的输入文件的编码参数-finput-charset=GBK。Linux下应该用wprintf(L"%ls/n",wstr))
今天发现用securecrt登陆时,gcc编译出错时会出现乱码,但直接在主机的窗口界面下用Shell编译却没有乱码.查看了一下当时的错误描述,发现它的引号是中文引号,导致在SecureCRT中显示出错 ...
- java程序练习:输入数字转换成中文输出(金额相关)
//题目,做一个输入金额数字,输出转换成中文的金额名称.public class Test { public static void main(String[] args) { System.out. ...
- vue文件流转换成pdf预览(pdf.js+iframe)
参考文档:https://www.jianshu.com/p/242525315bf6 PDFJS: https://mozilla.github.io/pdf.js/ 支持获取文件流到客户端 ...
随机推荐
- Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View
最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面 ...
- ASP.NET性能优化之分布式Session
如果我们正在使用Session,那么构建高性能可扩展的ASP.NET网站,就必须解决分布式Session的架构,因为单服务器的SESSION处理能力会很快出现性能瓶颈,这类问题也被称之为Session ...
- ajax大数据排队导出+进度条
描述 :我们现在有很多数据,分表存放,现在需要有精度条的导出.最后面有完整源码. 效果图:
- 逻辑回归应用之Kaggle泰坦尼克之灾(转)
正文:14pt 代码:15px 1 初探数据 先看看我们的数据,长什么样吧.在Data下我们train.csv和test.csv两个文件,分别存着官方给的训练和测试数据. import pandas ...
- linux下安装svn(基于编码的方式)
svn是什么,相信能看到这里的同学应该不会有这个问题了,费话不多说,开始: 1.创建目录 mkdir /home/svn/ 2.获取安装svn所需源文件(svn的官方网址是http://subvers ...
- php文件锁(转)
bool flock ( int handle, int operation [, int &wouldblock] );flock() 操作的 handle 必须是一个已经打开的文件指针.o ...
- 对装饰模式(Decorator)的解读
看过好多对装饰模式的讲解,他们几乎都有一句相同的话:对现有类功能的扩展.不知道大家怎么理解这句话的,之前我把”对功能的扩展“理解成”加功能=加方法“,比如Person类本来有两个功能:Eat 和 Ru ...
- 配置nginx1.7.8支持pathinfo模式
vi nginx/conf/nginx.conf 1.修改正则 set $real_script_name $fastcgi_script_name; if ($fastcgi_script_name ...
- SSO单点登录的实现原理
单点登录在现在的系统架构中广泛存在,他将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登录实现方案来满足需求.我将以我所 ...
- svn服务器时间与本地时间不同步解决
在用svn的时候,由于svn的时间与本地不同步,导致每次看log总是需要对时间. 今天修改了svn服务器时间与本地同步.只需要修改svn服务器时间与本地时间相同即可,但要主要修改时区,不然会出现时间又 ...