直接将视频文件原码流转换成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解压缩命令
1.tar -cvf /data/sc2.tar /data (只打包,不压缩) 把/data下的文件打包成 sc.tar 上面两个都是绝对路径噢 tar -zcvf /data/sc2.tar.g ...
- magic_quotes_runtime(魔术引号开关)
我们可以通过以下代码来探测php环境中magic_quotes_runtime是否开启: magic_runtime.php 源代码如下: <?php //当magic_quotes_runti ...
- Linux文件查找命令find用法整理(locate/find)
Linux文件查找查找主要包括:locate和find 1.locate 用法简单,根据数据库查找,非实时,用法: locate FILENAME 手动更新数据库(时间可能较长) updatedb 2 ...
- Linux查看某个文件被哪些进程PID占用
比如查看test.sh这个文件被哪些进程占用,可以用: lsof | grep test.sh 或者 fuser -v test.sh
- div随另一个div自动增高
<script type="text/javascript"> document.getElementById("div1").style.heig ...
- SQL中存储过程的例子
导读:sql存储是数据库操作过程中比较重要的一个环节,对于一些初学者来说也是比较抽象难理解的,本文我将通过几个实例来解析数据库中的sql存储过程,这样就将抽象的事物形象化,比较容易理解. 例1: cr ...
- ASP.NET 资料下载
public void downloadfile(string s_fileName) { HttpContext.Current.Response.ContentType = "appli ...
- Unty3D动态加载图片
试验动态加载图片,代码如下: using UnityEngine; using System.Collections; public class DynamicLoad : MonoBehaviour ...
- 【原创教程】虎咽CSS
上节课我们讲了HTML基础,回顾的事我不干了,因为你可以回头看很多遍,这节课我们来学习下CSS这门艺术的基础知识,一直以来我们都是CSS,CSS那么CSS到底是什么呢,惯例,我又来一层一层把CSS ...
- XML--小结①