#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,输出到屏幕显示的更多相关文章

  1. php将文件转换成二进制输出[转]

    header( "Content-type: image/jpeg"); $PSize = filesize('1.jpg'); $picturedata = fread(fope ...

  2. 利用ffmpeg0.6.1把.h264纯码流打包成.mp4 .avi等格式 (转载)

    转自:http://cache2.weidaohang.org/h/index.php?q=aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cWluZ183MzkvYXJ0aWNsZS ...

  3. 将一个读取流转换成bitmap对象

     将一个读取流转换成bitmap对象:         BitmapFactory:可以将文件,读取流,字节数组转换成一个Bitmap对象.         Bitmap bitmap = Bitma ...

  4. go http 下载视频(TS码流文件)(推荐一个网站学习 go example)

    视频  http下载代码 dn.go(注意:代码很ugly,没怎么花时间) 总体感觉特别简单,网上看了下 net/http ,io这2个库的使用, 几分钟就写完了,感觉cpp 在做工具这块 开发效率的 ...

  5. 用vlc SDK创建一个播放视频文件和RTSP流视频的Demo

    #include <stdio.h> #include <tchar.h> #include <time.h> #include <windows.h> ...

  6. plupload分片上传视频文件源码展示

    plupload分片上传视频文件目录结构如下: |- images//视频上传小图片 |-js// plupload js文件 |-uploads//视频文件存放文件夹 里面是按日期存放 |-ajax ...

  7. 控制台程序的中文输出乱码问题(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中显示出错 ...

  8. java程序练习:输入数字转换成中文输出(金额相关)

    //题目,做一个输入金额数字,输出转换成中文的金额名称.public class Test { public static void main(String[] args) { System.out. ...

  9. vue文件流转换成pdf预览(pdf.js+iframe)

    参考文档:https://www.jianshu.com/p/242525315bf6 PDFJS: https://mozilla.github.io/pdf.js/     支持获取文件流到客户端 ...

随机推荐

  1. linux解压缩命令

    1.tar -cvf /data/sc2.tar /data (只打包,不压缩) 把/data下的文件打包成 sc.tar  上面两个都是绝对路径噢 tar -zcvf /data/sc2.tar.g ...

  2. magic_quotes_runtime(魔术引号开关)

    我们可以通过以下代码来探测php环境中magic_quotes_runtime是否开启: magic_runtime.php 源代码如下: <?php //当magic_quotes_runti ...

  3. Linux文件查找命令find用法整理(locate/find)

    Linux文件查找查找主要包括:locate和find 1.locate 用法简单,根据数据库查找,非实时,用法: locate FILENAME 手动更新数据库(时间可能较长) updatedb 2 ...

  4. Linux查看某个文件被哪些进程PID占用

    比如查看test.sh这个文件被哪些进程占用,可以用: lsof | grep test.sh 或者 fuser -v test.sh

  5. div随另一个div自动增高

    <script type="text/javascript"> document.getElementById("div1").style.heig ...

  6. SQL中存储过程的例子

    导读:sql存储是数据库操作过程中比较重要的一个环节,对于一些初学者来说也是比较抽象难理解的,本文我将通过几个实例来解析数据库中的sql存储过程,这样就将抽象的事物形象化,比较容易理解. 例1: cr ...

  7. ASP.NET 资料下载

    public void downloadfile(string s_fileName) { HttpContext.Current.Response.ContentType = "appli ...

  8. Unty3D动态加载图片

    试验动态加载图片,代码如下: using UnityEngine; using System.Collections; public class DynamicLoad : MonoBehaviour ...

  9. 【原创教程】虎咽CSS

      上节课我们讲了HTML基础,回顾的事我不干了,因为你可以回头看很多遍,这节课我们来学习下CSS这门艺术的基础知识,一直以来我们都是CSS,CSS那么CSS到底是什么呢,惯例,我又来一层一层把CSS ...

  10. XML--小结①