直接将视频文件原码流转换成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/ 支持获取文件流到客户端 ...
随机推荐
- (转载)为啥我们要学习Linux
学习Linux也有一阵子了,这过程中磕磕撞撞的,遇到了问题,也解决了一些问题,学习的路子是曲折的,想总结点啥的,让刚刚学习Linux的不会望而生畏. 为啥我们要学习Linux 技术的价值不在于这个技术 ...
- (转载)关于ArrayList的5道面试题
我以面试官的身份参加过很多Java的面试,以下是五个比较有技巧的问题,我发现有些初级到中级的Java研发人员在这些问题上没有完全弄明白,似懂非懂.所以我写了一篇相关的文章,帮助初级Java研发人员弄清 ...
- java的一些程序
1.文件读取并打印 import java.io.*;public class readandprint{//*********Found********public static void main ...
- Java基础知识强化之网络编程笔记09:TCP之客户端键盘录入服务器写到文本文件中
1. TCP之客户端键盘录入服务器写到文本文件中 (1)客户端: package cn.itcast_09; import java.io.BufferedReader; import java.io ...
- a标签中的href="#"与href="javascript:void(0)"区别
转自http://blog.csdn.net/fightplane/article/details/5190037 <a href="#"> 点击链接后,页面会向上滚到 ...
- 卸载AMH 5.0面板的具体办法
安装AMH 5.0面板只有YES.NO和EXIT,和AMH 4.X的安装.卸载.退出有点不同,那么如何卸载AMH 5.0面板呢? 1.root登录ssh 2.输入如下命令: killall php-f ...
- sulime-text 3 安装以及使用
sublime-text 3 使用了有一段时间了,虽然不是很熟悉,但是已经爱上它了,但是对这个编辑器还是一知半解,所以现在记录下,希望以后能永久的使用这个编辑器. 一,调用 控制台 使用命令 ctrl ...
- 在github上搭建博客(使用Jekyll)
简单说,只需要三步,就可以在 Github 搭建起一个博客: 在 Github 上建一个名为 xxx.github.io 的库: 把看中了的 Jekyll 模板 clone 到本地: 把这个模板 pu ...
- js调用.net后台事件,和后台调用前台等方法以及js调用服务器控件的方法
http://blog.csdn.net/deepwishly/article/details/6670942 ajaxPro.dll基础教程(前台调用后台方法,后台调用前台方法) 1. javaS ...
- JavaScript学习总结【4】、JS深入
1.JS流程控制语句 (1).if 判断 if 语句是基于条件成立时才执行相应的代码. if...else 语句是在指定的条件成立时执行if后的代码,在条件不成立时执行else后的代码. if...e ...