sdl,yuv,sdl androidd:sdl androidd,sdl显示yuv,问:SDL英文是什么,答:规

相关文章推荐:
android 視頻 顯示 yuv
SDL(Simple DirectMedia Layer)是个好东西!
要想开发一个自己的跨平台的媒体播放器(如ffplay等),它就大有武之地啦。
SDL的入门介绍有很多,比如中文的有“龙飞”的洋洋洒洒一个系列:
/lf426/archive//42161.aspx
当然,官方的教程是很有用:
http://lazyfoo.net/SDL_tutorials/index.php
官方的教程讲了SDL的各个方面,但是并没有讲播放器的具体设计。
而ffmpeg的教程(http://...
阅读(30) 回复(0)
其他文章推荐
音乐播放器是从MediaProvider中获取音乐和音乐信息的,在插入SD卡后,MediaProvider启动扫描服务,文件解析通过opencore操作,扫描到的媒体文件由MediaProvider来保存到数据库,数据库位于
/data/data/com.android.providers.media/databases/external-*.db
在扫描时,扫描到的专辑图片存放于
android/data/com.android.providers.media/albumthumbs/
专辑图片选用优先选择音乐内嵌专辑图片
Android平台
阅读(0) 回复(0)
转自: /jisheng/archive//2852553.html
android 3.0 sdk,引入了很多新api,比如Loader。和Fragment类似(编写兼容android1.6的fragment),该api也可在android 1.6以上版本执行。
以下介绍如何编写Loader,实现对ListView的异步加载。效果如图:
示例中有一个后台线程每隔3秒更新数据库的长江记录,将记录改为“长江”或“Long River”。ListView无需监控数据库变化,基于Loader...
Android平台
阅读(90) 回复(0)
http://blog.csdn.net/vblittleboy/article/details/
最近在搞视频分析类的项目,android默认视频采集格式是NV21,Y Cr Cb格式,4.2.0.方式采样
还有其他采样方式,默认使用NV21
Sets the image format for preview pictures.
If this is never called, the default format will be NV21, which uses the NV21 encoding format.
Android平台
阅读(0) 回复(0)
yuv是指亮度参量和色度参量分开表示的像素格式,而这样分开的好处就是不但可以避免相互干扰,还可以降低色度的采样率而不会对图像质量影响太大。yuv是一个比较笼统地说法,针对它的具体排列方式,可以分为很多种具体的格式。yuv格式解析1(播放器——project2)
根据板卡api设计实现yuv420格式的视频播放器
打开*.mp4;*.264类型的文件,实现其播放。
使用的视频格式是yuv420格式
yuv格式通常有两大类:打包(packed)格式和平面...
阅读(0) 回复(0)
申明:以下大部分步骤都是来自网络资料,由于某些网络资料的不全甚至错误问题,因此自己实践后并整理一下整个流程,便于作为学习笔记,非常感谢网友!
意图:做这个的意图主要是因为目前准备游戏2.0的版本开发,要用到引擎,而引擎是用c/c++实现的,目前正在准备移植该引擎,因此开始着手这方便的资料,之前一直做的是纯android的游戏,未考虑到!
下面开始一天的旅程【在开始这些之前,你应该有android开发的环境了】:
Android平台
阅读(0) 回复(0)
申明:以下大部分步骤都是来自网络资料,由于某些网络资料的不全甚至错误问题,因此自己实践后并整理一下整个流程,便于作为学习笔记,非常感谢网友!
意图:做这个的意图主要是因为目前准备游戏2.0的版本开发,要用到引擎,而引擎是用c/c++实现的,目前正在准备移植该引擎,因此开始着手这方便的资料,之前一直做的是纯android的游戏,未考虑到!
下面开始一天的旅程【在开始这些之前,你应该有android开发的环境了】:
Android平台
阅读(0) 回复(0)
  android之JNI实践一(环境搭建和简单示例)
  申明:以下大部分步骤都是来自网络资料,由于某些网络资料的不全甚至错误问题,因此自己实践后并整理一下整个流程,便于作为学习笔记,非常感谢网友!
  意图:做这个的意图主要是因为目前准备游戏2.0的版本开发,要用到引擎,而引擎是用c/c++实现的,目前正在准备移植该引擎,因此开始着手这方便的资料,之前一直做的是纯android的游戏,未考虑到!
  下面开始一天的...
Android平台
阅读(30) 回复(0)
申明:以下大部分步骤都是来自网络资料,由于某些网络资料的不全甚至错误问题,因此自己实践后并整理一下整个流程,便于作为学习笔记,非常感谢网友!
意图:做这个的意图主要是因为目前准备游戏2.0的版本开发,要用到引擎,而引擎是用c/c++实现的,目前正在准备移植该引擎,因此开始着手这方便的资料,之前一直做的是纯android的游戏,未考虑到!
下面开始一天的旅程【在开始这些之前,你应该有android开发的环境了】:
Android平台
阅读(330) 回复(0)
先上图·····
1.进入程序
2、向右滑动
3、点击图片
4、向右滑动
5、再次点击右边图片,出现循环效果
实现步骤:
一、main.layout布局文件
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&http://schemas.android.com/apk/res/android&
android:id=&@+id/main&
android:layout_width=&fill_parent&
Android平台
阅读(270) 回复(0)
正好看到进度条章节,就顺便配合下“线程队列”来试试效果啥的,也行!程序有毛病的,长按一次效果行,之后不能长按了,否则线程会一直跑,嘿嘿!
布局文件: acitivity_ui.xml
点击(此处)折叠或打开
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&http://schemas.android.com/apk/res/android&
android:layout_width=&fill_p...
Android平台
阅读(1020) 回复(0)
盛拓传媒:
北京皓辰网域网络信息技术有限公司. 版权所有
北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证:编号(京)字第1149号
ITPUB推荐文章解答你所有技术难题上一篇文章主要是参照AwesomePlayer直接用SoftwareRenderer类来显示yuv,为了能用到这个类,不惜依赖了libstagefright、libstagefright_color_conversion等动态静态库,从而造成程序具有很高的耦合度,也不便于我们理解yuv数据直接显示的深层次原因。于是我开始研究SoftwareRenderer的具体实现,我们来提取SoftwareRenderer的核心代码,自己来实现yuv的显示。SoftwareRenderer就只有三个方法,一个构造函数,一个析构函数,还有一个负责显示的render方法。构造方法里有个很重要的地方native_window_set_buffers_geometry这里是配置即将申请的图形缓冲区的宽高和颜色空间,忽略了这个地方,画面将用默认的值显示,将造成显示不正确。render函数里最重要的三个地方,一个的dequeBuffer,一个是mapper,一个是queue_buffer。native_window_set_buffers_//设置宽高以及颜色空间yuv420native_window_dequeue_buffer_and_//根据以上配置申请图形缓冲区mapper.lock(buf-&handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));//将申请到的图形缓冲区跨进程映射到用户空间memcpy(dst, data, dst_y_size + dst_c_size*2);//填充yuv数据到图形缓冲区mNativeWindow-&queueB//显示以上五步是surface显示图形必不可少的五步。有了以上分析,我们直接上代码:(yuv数据下载地址点击打开链接,放到sdcard)main.cpp#include &cutils/memory.h&#include &unistd.h&#include &utils/Log.h&#include &binder/IPCThreadState.h&#include &binder/ProcessState.h&#include &binder/IServiceManager.h&#include &media/stagefright/foundation/ADebug.h&#include &gui/Surface.h&#include &gui/SurfaceComposerClient.h&#include &gui/ISurfaceComposer.h&#include &ui/DisplayInfo.h&#include &android/native_window.h&#include &system/window.h&#include &ui/GraphicBufferMapper.h&//ANativeWindow 就是surface,对应surface.cpp里的codeusi//将x规整为y的倍数,也就是将x按y对齐static int ALIGN(int x, int y) { // y must be a power of 2. return (x + y - 1) & ~(y - 1);}void render(
const void *data, size_t size, const sp&ANativeWindow& &nativeWindow,int width,int height) { sp&ANativeWindow& mNativeWindow = nativeW
int mCropWidth = int mCropHeight =
int halFormat = HAL_PIXEL_FORMAT_YV12;//颜色空间 int bufWidth = (mCropWidth + 1) & ~1;//按2对齐 int bufHeight = (mCropHeight + 1) & ~1;
CHECK_EQ(0,
native_window_set_usage(
mNativeWindow.get(),
GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
| GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP)); CHECK_EQ(0,
native_window_set_scaling_mode(
mNativeWindow.get(),
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)); // Width must be multiple of 32??? //很重要,配置宽高和和指定颜色空间yuv420 //如果这里不配置好,下面deque_buffer只能去申请一个默认宽高的图形缓冲区 CHECK_EQ(0, native_window_set_buffers_geometry(
mNativeWindow.get(),
bufHeight,
halFormat));
ANativeWindowBuffer *//描述buffer //申请一块空闲的图形缓冲区 if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
&buf)) != 0) {
ALOGW(&Surface::dequeueBuffer returned error %d&, err);
} GraphicBufferMapper &mapper = GraphicBufferMapper::get(); Rect bounds(mCropWidth, mCropHeight); void * CHECK_EQ(0, mapper.lock(//用来锁定一个图形缓冲区并将缓冲区映射到用户进程
buf-&handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));//dst就指向图形缓冲区首地址 if (true){
size_t dst_y_size = buf-&stride * buf-&
size_t dst_c_stride = ALIGN(buf-&stride / 2, 16);//1行v/u的大小
size_t dst_c_size = dst_c_stride * buf-&height / 2;//u/v的大小
memcpy(dst, data, dst_y_size + dst_c_size*2);//将yuv数据copy到图形缓冲区 } CHECK_EQ(0, mapper.unlock(buf-&handle)); if ((err = mNativeWindow-&queueBuffer(mNativeWindow.get(), buf,
-1)) != 0) {
ALOGW(&Surface::queueBuffer returned error %d&, err); } buf = NULL;}bool getYV12Data(const char *path,unsigned char * pYUVData,int size){ FILE *fp = fopen(path,&rb&); if(fp == NULL){
printf(&read %s fail !!!!!!!!!!!!!!!!!!!/n&,path);
} fread(pYUVData,size,1,fp); fclose(fp); }int main(void){ // set up the thread-pool sp&ProcessState& proc(ProcessState::self()); ProcessState::self()-&startThreadPool();
// create a client to surfaceflinger sp&SurfaceComposerClient& client = new SurfaceComposerClient(); sp&IBinder& dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain)); DisplayI //获取屏幕的宽高等信息 status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo); printf(&w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f/n&,
dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density); if (status)
return -1; //创建surface sp&SurfaceControl& surfaceControl = client-&createSurface(String8(&testsurface&),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888, 0);
/*************************ge****************************************/
printf(&[%s][%d]/n&,__FILE__,__LINE__); int width, width = 320; height = 240; int size = width * height * 3/2; unsigned char *data = new unsigned char[size]; const char *path = &/mnt/sdcard/yuv_320_240.yuv&; getYV12Data(path,data,size);//ge /*********************配置surface*******************************************************************/ SurfaceComposerClient::openGlobalTransaction(); surfaceControl-&setLayer(100000);//设定Z坐标 surfaceControl-&setPosition(100, 100);//以左上角为(0,0)设定显示位置 surfaceControl-&setSize(width, height);//设定视频显示大小 SurfaceComposerClient::closeGlobalTransaction(); sp&Surface& surface = surfaceControl-&getSurface(); printf(&[%s][%d]/n&,__FILE__,__LINE__); /**********************显示yuv数据******************************************************************/
render(data,size,surface,width,height); printf(&[%s][%d]/n&,__FILE__,__LINE__);
IPCThreadState::self()-&joinThreadPool();//可以保证画面一直显示,否则瞬间消失 IPCThreadState::self()-&stopProcess(); return 0;}Android.mk (这次依赖的库少了很多)LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= / main.cpp LOCAL_SHARED_LIBRARIES := / libcutils / libutils / libbinder / libui / libgui / libstagefright_foundation LOCAL_MODULE:= MyShowYUVLOCAL_MODULE_TAGS := testsinclude $(BUILD_EXECUTABLE)转载请注明出处今天看啥 热点:
最简单的视音频播放示例9:SDL2播放PCM,sdl2pcm
本文记录SDL播放音频的技术。在这里使用的版本是SDL2。实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API。在Windows平台下,SDL封装了Direct3D这类的API用于播放视频;封装了DirectSound这类的API用于播放音频。因为SDL的编写目的就是简化视音频播放的开发难度,所以使用SDL播放视频(YUV/RGB)和音频(PCM)数据非常的容易。SDL简介SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。用下面这张图可以很明确地说明SDL的用途。&SDL实际上并不限于视音频的播放,它将功能分成下列数个子系统(subsystem):Video(图像):图像控制以及线程(thread)和事件管理(event)。Audio(声音):声音控制Joystick(摇杆):游戏摇杆控制CD-ROM(光盘驱动器):光盘媒体控制Window Management(视窗管理):与视窗程序设计集成Event(事件驱动):处理事件驱动在Windows下,SDL与DirectX的对应关系如下。
SDL_Video、SDL_Image
DirectDraw、Direct3D
SDL_Audio、SDL_Mixer
DirectSound
SDL_Joystick、SDL_Base
DirectInput
DirectPlay 注:上文内容在《使用SDL播放视频》的文章中已经介绍,这里再次重复贴一遍。SDL播放音频的流程SDL播放音频的流程狠简单,分为以下步骤。1. 初始化1) 初始化SDL。2) 根据参数(SDL_AudioSpec)打开音频设备2. 循环播放数据1) 播放音频数据。2) 延时等待播放完成。下面详细分析一下上文流程。1. 初始化1) 初始化SDL。使用SDL_Init()初始化SDL。该函数可以确定希望激活的子系统。SDL_Init()函数定义如下:int SDLCALL SDL_Init(Uint32 flags)其中,flags可以取下列值:SDL_INIT_TIMER:定时器SDL_INIT_AUDIO:音频SDL_INIT_VIDEO:视频SDL_INIT_JOYSTICK:摇杆SDL_INIT_HAPTIC:触摸屏SDL_INIT_GAMECONTROLLER:游戏控制器SDL_INIT_EVENTS:事件SDL_INIT_NOPARACHUTE:不捕获关键信号(这个不理解)SDL_INIT_EVERYTHING:包含上述所有选项有关SDL_Init()有一点需要注意:初始化的时候尽量做到“够用就好”,而不要用SDL_INIT_EVERYTHING。因为有些情况下使用SDL_INIT_EVERYTHING会出现一些不可预知的问题。例如,在MFC应用程序中播放纯音频,如果初始化SDL的时候使用SDL_INIT_EVERYTHING,那么就会出现听不到声音的情况。后来发现,去掉了SDL_INIT_VIDEO之后,问题才得以解决。2) 根据参数(SDL_AudioSpec)打开音频设备使用SDL_OpenAudio()打开音频设备。该函数需要传入一个SDL_AudioSpec的结构体。DL_OpenAudio()的定义如下。int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired,
SDL_AudioSpec * obtained);它的参数是两个SDL_AudioSpec结构体,它们的含义:desired:期望的参数。obtained:实际音频设备的参数,一般情况下设置为NULL即可。SDL_AudioSpec结构体的定义如下。typedef struct SDL_AudioSpec
/**& DSP frequency -- samples per second */
SDL_AudioF
/**& Audio data format */
/**& Number of channels: 1 mono, 2 stereo */
/**& Audio buffer silence value (calculated) */
/**& Audio buffer size in samples (power of 2) */
/**& Necessary for some compile environments */
/**& Audio buffer size in bytes (calculated) */
SDL_AudioC
} SDL_AudioS其中包含了关于音频各种参数:freq:音频数据的采样率。常用的有等。format:音频数据的格式。举例几种格式: AUDIO_U16SYS:Unsigned 16-bit samples AUDIO_S16SYS:Signed 16-bit samples AUDIO_S32SYS:32-bit integer samples AUDIO_F32SYS:32-bit floating point sampleschannels:声道数。例如单声道取值为1,立体声取值为2。silence:设置静音的值。samples:音频缓冲区中的采样个数,要求必须是2的n次方。padding:考虑到兼容性的一个参数。size:音频缓冲区的大小,以字节为单位。callback:填充音频缓冲区的回调函数。userdata:用户自定义的数据。在这里记录一下填充音频缓冲区的回调函数的作用。当音频设备需要更多数据的时候会调用该回调函数。回调函数的格式要求如下。void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream,
int len);回调函数的参数含义如下所示。userdata:SDL_AudioSpec结构中的用户自定义数据,一般情况下可以不用。stream:该指针指向需要填充的音频缓冲区。len:音频缓冲区的大小(以字节为单位)。在回调函数中可以使用SDL_MixAudio()完成混音等工作。众所周知SDL2和SDL1.x关于视频方面的API差别很大。但是SDL2和SDL1.x关于音频方面的API是一模一样的。唯独在回调函数中,SDL2有一个地方和SDL1.x不一样:SDL2中必须首先使用SDL_memset()将stream中的数据设置为0。2. 循环播放数据1) 播放音频数据。使用SDL_PauseAudio()可以播放音频数据。SDL_PauseAudio()的定义如下。void SDLCALL SDL_PauseAudio(int pause_on)当pause_on设置为0的时候即可开始播放音频数据。设置为1的时候,将会播放静音的值。2) 延时等待播放完成。这一步就是延时等待音频播放完毕了。使用像SDL_Delay()这样的延时函数即可。代码源代码如下所示。/**
* 最简单的SDL2播放音频的例子(SDL2播放PCM)
* Simplest Audio Play SDL2 (SDL2 play PCM)
* 雷霄骅 Lei Xiaohua
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
* 本程序使用SDL2播放PCM音频采样数据。SDL实际上是对底层绘图
* API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层
* 函数调用步骤如下:
* [初始化]
* SDL_Init(): 初始化SDL。
* SDL_OpenAudio(): 根据参数(存储于SDL_AudioSpec)打开音频设备。
* [循环播放数据]
* SDL_PauseAudio(): 播放音频数据。
* SDL_Delay(): 延时等待播放完成。
* This software plays PCM raw audio data using SDL2.
* SDL is a wrapper of low-level API (DirectSound).
* Use SDL is much easier than directly call these low-level API.
* The process is shown as follows:
* SDL_Init(): Init SDL.
* SDL_OpenAudio(): Opens the audio device with the desired
parameters (In SDL_AudioSpec).
* [Loop to play data]
* SDL_PauseAudio(): Play Audio.
* SDL_Delay(): Wait for completetion of playback.
#include &stdio.h&
#include &tchar.h&
extern &C&
#include &sdl/SDL.h&
//|-----------|-------------|
//chunk-------pos---len-----|
/* Audio Callback
* The audio function callback takes the following parameters:
* stream: A pointer to the audio buffer to be filled
* len: The length (in bytes) of the audio buffer
fill_audio(void *udata,Uint8 *stream,int len){
SDL_memset(stream, 0, len);
if(audio_len==0)
len=(len&audio_len?audio_len:len); /*
SDL_MixAudio(stream,audio_pos,len,SDL_MIX_MAXVOLUME);
audio_pos +=
audio_len -=
int main(int argc, char* argv[])
if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( &Could not initialize SDL - %s\n&, SDL_GetError());
return -1;
//SDL_AudioSpec
SDL_AudioSpec wanted_
wanted_spec.freq = 44100;
wanted_spec.format = AUDIO_S16SYS;
wanted_spec.channels = 2;
wanted_spec.silence = 0;
wanted_spec.samples = 1024;
wanted_spec.callback = fill_
if (SDL_OpenAudio(&wanted_spec, NULL)&0){
printf(&can't open audio.\n&);
return -1;
FILE *fp=fopen(&../NocturneNo2inEflat_44.1k_s16le.pcm&,&rb+&);
if(fp==NULL){
printf(&cannot open this file\n&);
return -1;
//For YUV420P
int pcm_buffer_size=4096;
char *pcm_buffer=(char *)malloc(pcm_buffer_size);
int data_count=0;
if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size){
fseek(fp, 0, SEEK_SET);
fread(pcm_buffer, 1, pcm_buffer_size, fp);
data_count=0;
printf(&Now Playing %10d Bytes data.\n&,data_count);
data_count+=pcm_buffer_
//Set audio buffer (PCM data)
audio_chunk = (Uint8 *) pcm_
//Audio buffer length
audio_len =pcm_buffer_
audio_pos = audio_
SDL_PauseAudio(0);
while(audio_len&0)//Wait until finish
SDL_Delay(1);
运行结果运行的结果如下图所示。运行的时候可以听见音乐播放的声音。&下载代码位于“Simplest Media Play”中SourceForge项目地址:https://sourceforge.net/projects/simplestmediaplay/CSDN下载地址:http://download.csdn.net/detail/leixiaohua上述工程包含了使用各种API(Direct3D,OpenGL,GDI,DirectSound,SDL2)播放多媒体例子。其中音频输入为PCM采样数据。输出至系统的声卡播放出来。视频输入为YUV/RGB像素数据。输出至显示器上的一个窗口播放出来。通过本工程的代码初学者可以快速学习使用这几个API播放视频和音频的技术。一共包括了如下几个子工程:simplest_audio_play_directsound:
使用DirectSound播放PCM音频采样数据。simplest_audio_play_sdl2:
使用SDL2播放PCM音频采样数据。simplest_video_play_direct3d:
使用Direct3D的Surface播放RGB/YUV视频像素数据。simplest_video_play_direct3d_texture:使用Direct3D的Texture播放RGB视频像素数据。simplest_video_play_gdi:
使用GDI播放RGB/YUV视频像素数据。simplest_video_play_opengl:
使用OpenGL播放RGB/YUV视频像素数据。simplest_video_play_opengl_texture: 使用OpenGL的Texture播放YUV视频像素数据。simplest_video_play_sdl2:
使用SDL2播放RGB/YUV视频像素数据。
PCM就是WAV,你VERYCD下载的APE用千千或者FOOBAR转换成WAVjiu可以了 现在大多数的WAV都是16/44.1的,PCM是无损的,但不一定是最高音质格式 因为现在开始流行高清格式的有24/192的,还有多音轨的,好像是DTS吧。 用E443播放WAV,没什么必要,容量太小,素质不够,一般320MP3就可以了。 效果嘛,怕是比不上NE20
pcm就是线性音频数据,任何支持44100hz解码速度的硬件都能硬解播放,即便是mp3等格式也会经过解码填充达到44100hz频率才将数据还原成波流,缺失的数据全部用0或1填充。说真的,这么好的数据源要进行有损压缩太可惜,不如转换成ape格式或flac格式,基本不损失数据。工具也多,很多播放器也支持直接转换。顺便说一句,不是1411kb/s,没有声音文件这么大,都可以播放1080p的高清了。应该是1411kbps,相当1411kb/s的八分之一。
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&
WEB编程教程最近更新//添加的库:avcodec.lib avdevice.lib avfilter.lib avformat.lib avutil.lib swscale.lib & SDL.lib&extern &C&{ #include &libavcodec/avcodec.h& #include &libavformat/avformat.h& #include &libswscale/swscale.h& #include &libsdl/SDL.h& #include &libsdl/SDL_thread.h&};void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)&{ FILE *pF char szFilename[32]; int &y;
// Open file sprintf(szFilename, &frame%d.ppm&, iFrame); pFile=fopen(szFilename, &wb&); if(pFile==NULL)
// Write header fprintf(pFile, &P6\n%d %d\n255\n&, width, height);
// Write pixel data for(y=0; y& y++) fwrite(pFrame-&data[0]+y*pFrame-&linesize[0], 1, width*3, pFile);
// Close file fclose(pFile);}void CTest0Dlg::OnButton1()&{ // TODO: Add your control notification handler code here &AVFormatContext *pFormatC& int & & & & & & i, videoS& AVCodecContext &*pCodecC& AVCodec & & & & *pC& AVFrame & & & & *pF&& AVFrame & & & & *pFrameRGB;& AVPacket & & & && int & & & & & & frameF& int & & & & & & numB& uint8_t & & & & *& static int sws_flags = SWS_BICUBIC;& struct SwsContext *img_convert_& &AVP &// &argc = 2;& char argv[100] = &d:\\temp\\VIDEO&;&// argv[1] = &d:\\temp\\ff.mpg&;&& // /*注册所有可用的格式和编解码器*/& av_register_all();&&& // Open video file /*以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息*/& if(av_open_input_file(&pFormatCtx, argv, NULL, 0, NULL)!=0)& & // Couldn't open file&&& // Retrieve stream information/*通过读取媒体文件的中的包来获取媒体文件中的流信息,对于没有头信息的文件如(mpeg)是非常有用的,// 该函数通常重算类似mpeg-2帧模式的真实帧率,该函数并未改变逻辑文件的position.*/& if(av_find_stream_info(pFormatCtx)&0)& & // Couldn't find stream information&&& // Dump information about file onto standard error//该函数的作用就是检查下初始化过程中设置的参数是否符合规范& dump_format(pFormatCtx, 0, argv, 0);&&& // Find the first video stream& videoStream=-1;& printf(&%d\n&,pFormatCtx-&nb_streams);& getchar();& for(i=0; i&pFormatCtx-&nb_ i++)& & if(pFormatCtx-&streams[i]-&codec-&codec_type==CODEC_TYPE_VIDEO&&videoStream & 0)&{& & & videoStream=i;& & && & }& if(videoStream==-1)& & // Didn't find a video stream&&& // Get a pointer to the codec context for the video stream& pCodecCtx=pFormatCtx-&streams[videoStream]-&&&& // Find the decoder for the video stream& pCodec=avcodec_find_decoder(pCodecCtx-&codec_id);/*通过code ID查找一个已经注册的音视频编码器,查找编码器之前,必须先调用av_register_all注册所有支持的编码器音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找*/& if(pCodec==NULL) {& & fprintf(stderr, &Unsupported codec!\n&);& & // Codec not found& }& // Open codec//使用给定的AVCodec初始化AVCodecContext& if(avcodec_open(pCodecCtx, pCodec)&0)& & // Could not open codec& //printf(&name %s\n&,pCodec-&name);& //getchar();& // Allocate video frame& pFrame=avcodec_alloc_frame();&&& // Allocate an AVFrame structure& pFrameRGB=avcodec_alloc_frame();& if(pFrameRGB==NULL)& &&&& // Determine required buffer size and allocate buffer& numBytes=avpicture_get_size(PIX_FMT_RGB32, pCodecCtx-&width,& & & & &pCodecCtx-&height);& buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));&&& // Assign appropriate parts of buffer to image planes in pFrameRGB& // Note that pFrameRGB is an AVFrame, but AVFrame is a superset& // of AVPicture& avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB32,& &pCodecCtx-&width, pCodecCtx-&height);&&& // Read frames and save first five frames to disk& i=0;& ////////////////////////////////////////////////////////////////& if (SDL_Init(SDL_INIT_VIDEO) & 0)& { &fprintf(stderr, &can not initialize SDL:%s\n&, SDL_GetError()); &exit(1);& &}& atexit(SDL_Quit);& SDL_Surface *& screen = SDL_SetVideoMode(720, 576, 32, SDL_SWSURFACE|SDL_ANYFORMAT);& if ( screen == NULL )&& { &exit(2);& }& SDL_Surface *& & Uint32 rmask, gmask, bmask,& & /* SDL interprets each pixel as a 32-bit number, so our masks must depend& & & &on the endianness (byte order) of the machine */#if 0//SDL_BYTEORDER == SDL_BIG_ENDIAN& & rmask = 0xff000000;& & gmask = 0x00ff0000;& & bmask = 0x0000ff00;& & amask = 0x000000#else& & rmask = 0x000000& & gmask = 0x0000ff00;& & bmask = 0x00ff0000;& & amask = 0xff000000;#endif image = SDL_CreateRGBSurface(SDL_SWSURFACE, 720, 576, 0, rmask, gmask, bmask, NULL);& & if(image == NULL)& {& & & & //fprintf(stderr, &CreateRGBSurface failed: %s\n&, SDL_GetError());& & & & exit(1);& & }& //////////////////////////////////////////////////////////////////& while(av_read_frame(pFormatCtx, &packet)&=0)&& {& & // Is this a packet from the video stream?& & if(packet.stream_index==videoStream)&&{& & // Decode video frame& & avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,&& & & &packet.data, packet.size);& & &&& & // Did we get a video frame?& & if(frameFinished)&& & {& // Convert the image from its native format to RGB& & & & img_convert_ctx = sws_getContext( pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &pCodecCtx-&pix_fmt,& & & & & & & &pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &PIX_FMT_RGB32,& & & & & & & &sws_flags, NULL, NULL, NULL);& & & & sws_scale(img_convert_ctx,pFrame-&data,pFrame-&linesize,0,pCodecCtx-&height,pFrameRGB-&data,pFrameRGB-&linesize); && & & & sws_freeContext(img_convert_ctx);& & &//////////////////////////////////////////////////////////////// memcpy(screen-&pixels,buffer,720*576*4);
SDL_UpdateRect(screen, 0, 0, image-&w, image-&h);
/* Free the allocated BMP surface */& & SDL_FreeSurface(image); /////////////////////////////////////////////////////////////////& & &// Save the frame to disk& & &if((++i&=5))& & & &SaveFrame(pFrameRGB, pCodecCtx-&width, pCodecCtx-&height, i);& & }}& &&& & // Free the packet that was allocated by av_read_frame& & av_free_packet(&packet);& }&&& // Free the RGB image& av_free(buffer);& av_free(pFrameRGB);&&& // Free the YUV frame& av_free(pFrame);&&& // Close the codec& avcodec_close(pCodecCtx);&&& // Close the video file& av_close_input_file(pFormatCtx);& MessageBox(&over&);}void CTest0Dlg::OnButton2()&{ // TODO: Add your control notification handler code here &AVFormatContext *pFormatC& int & & & & & & i, videoS& AVCodecContext &*pCodecC& AVCodec & & & & *pC& AVFrame & & & & *pF&& AVFrame & & & & *pFrameRGB;& AVPacket & & & && int & & & & & & frameF& int & & & & & & numB& uint8_t & & & & *& static int sws_flags = SWS_BICUBIC;& struct SwsContext *img_convert_& &AVP &// &argc = 2;& char argv[100] = &d:\\temp\\VIDEO&;&// argv[1] = &d:\\temp\\ff.mpg&;&& // /*注册所有可用的格式和编解码器*/& av_register_all();&&& // Open video file /*以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息*/& if(av_open_input_file(&pFormatCtx, argv, NULL, 0, NULL)!=0)& & // Couldn't open file&&& // Retrieve stream information/*通过读取媒体文件的中的包来获取媒体文件中的流信息,对于没有头信息的文件如(mpeg)是非常有用的,// 该函数通常重算类似mpeg-2帧模式的真实帧率,该函数并未改变逻辑文件的position.*/& if(av_find_stream_info(pFormatCtx)&0)& & // Couldn't find stream information&&& // Dump information about file onto standard error//该函数的作用就是检查下初始化过程中设置的参数是否符合规范& dump_format(pFormatCtx, 0, argv, 0);&&& // Find the first video stream& videoStream=-1;& printf(&%d\n&,pFormatCtx-&nb_streams);& getchar();& for(i=0; i&pFormatCtx-&nb_ i++)& & if(pFormatCtx-&streams[i]-&codec-&codec_type==CODEC_TYPE_VIDEO&&videoStream & 0)&{& & & videoStream=i;& & && & }& if(videoStream==-1)& & // Didn't find a video stream&&& // Get a pointer to the codec context for the video stream& pCodecCtx=pFormatCtx-&streams[videoStream]-&&&& // Find the decoder for the video stream& pCodec=avcodec_find_decoder(pCodecCtx-&codec_id);/*通过code ID查找一个已经注册的音视频编码器,查找编码器之前,必须先调用av_register_all注册所有支持的编码器音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找*/& if(pCodec==NULL) {& & fprintf(stderr, &Unsupported codec!\n&);& & // Codec not found& }& // Open codec//使用给定的AVCodec初始化AVCodecContext& if(avcodec_open(pCodecCtx, pCodec)&0)& & // Could not open codec& //printf(&name %s\n&,pCodec-&name);& //getchar();& // Allocate video frame& pFrame=avcodec_alloc_frame();&&& // Allocate an AVFrame structure& pFrameRGB=avcodec_alloc_frame();& if(pFrameRGB==NULL)& &&&& // Determine required buffer size and allocate buffer& numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx-&width,& & & & &pCodecCtx-&height);& buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));&&& // Assign appropriate parts of buffer to image planes in pFrameRGB& // Note that pFrameRGB is an AVFrame, but AVFrame is a superset& // of AVPicture& avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,& &pCodecCtx-&width, pCodecCtx-&height);&&& // Read frames and save first five frames to disk& i=0;& ////////////////////////////////////////////////////////////////& if (SDL_Init(SDL_INIT_VIDEO) & 0)& { &fprintf(stderr, &can not initialize SDL:%s\n&, SDL_GetError()); &exit(1);& &}& atexit(SDL_Quit);& SDL_Surface *& screen = SDL_SetVideoMode(720, 576, 24, SDL_SWSURFACE|SDL_ANYFORMAT);& if ( screen == NULL )&& { &exit(2);& }& SDL_Surface *& & Uint32 rmask, gmask, bmask,& & /* SDL interprets each pixel as a 32-bit number, so our masks must depend& & & &on the endianness (byte order) of the machine */#if 0//SDL_BYTEORDER == SDL_BIG_ENDIAN& & rmask = 0xff000000;& & gmask = 0x00ff0000;& & bmask = 0x0000ff00;& & amask = 0x000000#else& & rmask = 0x000000& & gmask = 0x0000ff00;& & bmask = 0x00ff0000;& & amask = 0xff000000;#endif image = SDL_CreateRGBSurface(SDL_SWSURFACE, 720, 576, 0, rmask, gmask, bmask, NULL);& & if(image == NULL)& {& & & & //fprintf(stderr, &CreateRGBSurface failed: %s\n&, SDL_GetError());& & & & exit(1);& & }& //////////////////////////////////////////////////////////////////& while(av_read_frame(pFormatCtx, &packet)&=0)&& {& & // Is this a packet from the video stream?& & if(packet.stream_index==videoStream)&&{& & // Decode video frame& & avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,&& & & &packet.data, packet.size);& & &&& & // Did we get a video frame?& & if(frameFinished)&& & {& // Convert the image from its native format to RGB& & & & img_convert_ctx = sws_getContext( pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &pCodecCtx-&pix_fmt,& & & & & & & &pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &PIX_FMT_BGR24,& & & & & & & &sws_flags, NULL, NULL, NULL);& & & & sws_scale(img_convert_ctx,pFrame-&data,pFrame-&linesize,0,pCodecCtx-&height,pFrameRGB-&data,pFrameRGB-&linesize); && & & & sws_freeContext(img_convert_ctx);& & &//////////////////////////////////////////////////////////////// memcpy(screen-&pixels,buffer,720*576*3);
SDL_UpdateRect(screen, 0, 0, image-&w, image-&h);
/* Free the allocated BMP surface */& & SDL_FreeSurface(image); /////////////////////////////////////////////////////////////////& & &// Save the frame to disk& & &if((++i&=5))& & & &SaveFrame(pFrameRGB, pCodecCtx-&width, pCodecCtx-&height, i);& & }}& &&& & // Free the packet that was allocated by av_read_frame& & av_free_packet(&packet);& }&&& // Free the RGB image& av_free(buffer);& av_free(pFrameRGB);&&& // Free the YUV frame& av_free(pFrame);&&& // Close the codec& avcodec_close(pCodecCtx);&&& // Close the video file& av_close_input_file(pFormatCtx);& MessageBox(&over&);}void CTest0Dlg::OnButton3()&{ // TODO: Add your control notification handler code here // TODO: Add your control notification handler code here &AVFormatContext *pFormatC& int & & & & & & i, videoS& AVCodecContext &*pCodecC& AVCodec & & & & *pC& AVFrame & & & & *pF&& AVFrame & & & & *pFrameYUV;& AVPacket & & & && int & & & & & & frameF& int & & & & & & numB& uint8_t & & & & *& &SDL_Rect & & & && static int sws_flags = SWS_BICUBIC;& struct SwsContext *img_convert_& &AVP &// &argc = 2;& char argv[100] = &d:\\temp\\VIDEO&;&// argv[1] = &d:\\temp\\ff.mpg&;&& // /*注册所有可用的格式和编解码器*/& av_register_all();&&& // Open video file /*以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息*/& if(av_open_input_file(&pFormatCtx, argv, NULL, 0, NULL)!=0)& & // Couldn't open file&&& // Retrieve stream information/*通过读取媒体文件的中的包来获取媒体文件中的流信息,对于没有头信息的文件如(mpeg)是非常有用的,// 该函数通常重算类似mpeg-2帧模式的真实帧率,该函数并未改变逻辑文件的position.*/& if(av_find_stream_info(pFormatCtx)&0)& & // Couldn't find stream information&&& // Dump information about file onto standard error//该函数的作用就是检查下初始化过程中设置的参数是否符合规范& dump_format(pFormatCtx, 0, argv, 0);&&& // Find the first video stream& videoStream=-1;& printf(&%d\n&,pFormatCtx-&nb_streams);& getchar();& for(i=0; i&pFormatCtx-&nb_ i++)& & if(pFormatCtx-&streams[i]-&codec-&codec_type==CODEC_TYPE_VIDEO&&videoStream & 0)&{& & & videoStream=i;& & && & }& if(videoStream==-1)& & // Didn't find a video stream&&& // Get a pointer to the codec context for the video stream& pCodecCtx=pFormatCtx-&streams[videoStream]-&&&& // Find the decoder for the video stream& pCodec=avcodec_find_decoder(pCodecCtx-&codec_id);/*通过code ID查找一个已经注册的音视频编码器,查找编码器之前,必须先调用av_register_all注册所有支持的编码器音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找*/& if(pCodec==NULL) {& & fprintf(stderr, &Unsupported codec!\n&);& & // Codec not found& }& // Open codec//使用给定的AVCodec初始化AVCodecContext& if(avcodec_open(pCodecCtx, pCodec)&0)& & // Could not open codec& //printf(&name %s\n&,pCodec-&name);& //getchar();& // Allocate video frame& pFrame=avcodec_alloc_frame();&&& // Allocate an AVFrame structure& pFrameYUV=avcodec_alloc_frame();& if(pFrameYUV==NULL)& &&&& // 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));&&& // Assign appropriate parts of buffer to image planes in pFrameRGB& // Note that pFrameRGB is an AVFrame, but AVFrame is a superset& // of AVPicture& avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P,& &pCodecCtx-&width, pCodecCtx-&height);&&& // Read frames and save first five frames to disk& i=0;& ////////////////////////////////////////////////////////////////& if (SDL_Init(SDL_INIT_VIDEO) & 0)& { &fprintf(stderr, &can not initialize SDL:%s\n&, SDL_GetError()); &exit(1);& &}& atexit(SDL_Quit);& SDL_Surface *& screen = SDL_SetVideoMode(720, 576, 24, SDL_SWSURFACE|SDL_ANYFORMAT);& if ( screen == NULL )&& { &exit(2);& }& SDL_Overlay * image = SDL_CreateYUVOverlay(pCodecCtx-&width, pCodecCtx-&height, SDL_YV12_OVERLAY, screen);& & if(image == NULL)& {& & & & //fprintf(stderr, &CreateRGBSurface failed: %s\n&, SDL_GetError());& & & & exit(1);& & }& //////////////////////////////////////////////////////////////////& while(av_read_frame(pFormatCtx, &packet)&=0)&& {& & // Is this a packet from the video stream?& & if(packet.stream_index==videoStream)&&{& & // Decode video frame& & avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,&& & & &packet.data, packet.size);& & &&& & // Did we get a video frame?& & if(frameFinished)&& & {& // Convert the image from its native format to RGB& & & & & SDL_LockYUVOverlay(image);// pFrameYUV-&data[0] = image-&pixels[0];//预先改变指针数据区,不用copy// pFrameYUV-&data[1] = image-&pixels[2];// pFrameYUV-&data[2] = image-&pixels[1];// // pFrameYUV-&linesize[0] = image-&pitches[0];// pFrameYUV-&linesize[1] = image-&pitches[2];// pFrameYUV-&linesize[2] = image-&pitches[1];& & & & img_convert_ctx = sws_getContext( pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &pCodecCtx-&pix_fmt,& & & & & & & &pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &PIX_FMT_YUV420P,& & & & & & & &sws_flags, NULL, NULL, NULL);& & & & sws_scale(img_convert_ctx,pFrame-&data,pFrame-&linesize,0,pCodecCtx-&height,pFrameYUV-&data,pFrameYUV-&linesize); && & & & sws_freeContext(img_convert_ctx);& & & &memcpy(image-&pixels[0], pFrameYUV-&data[0],720*576);//拷贝数据yuv420,也可预先改变指针 & memcpy(image-&pixels[2], pFrameYUV-&data[1],720*576/4); & memcpy(image-&pixels[1], pFrameYUV-&data[2],720*576/4); SDL_UnlockYUVOverlay(image); & rect.x = 0; rect.y = 0; rect.w = pCodecCtx-& rect.h = pCodecCtx-& SDL_DisplayYUVOverlay(image, &rect);& & }}& &&& & // Free the packet that was allocated by av_read_frame& & av_free_packet(&packet);& }&&& // Free the RGB image& av_free(buffer);& av_free(pFrameYUV);&&& // Free the YUV frame& av_free(pFrame);&&& // Close the codec& avcodec_close(pCodecCtx);&&& // Close the video file& av_close_input_file(pFormatCtx);& MessageBox(&over&);}void CTest0Dlg::OnButton4()&{ // TODO: Add your control notification handler code here // TODO: Add your control notification handler code here &AVFormatContext *pFormatC& int & & & & & & i, videoS& AVCodecContext &*pCodecC& AVCodec & & & & *pC& AVFrame & & & & *pF&& AVFrame & & & & *pFrameYUV;& AVPacket & & & && int & & & & & & frameF& int & & & & & & numB& uint8_t & & & & *& &SDL_Rect & & & && static int sws_flags = SWS_BICUBIC;& struct SwsContext *img_convert_& &AVP &// &argc = 2;& char argv[100] = &d:\\temp\\VIDEO&;&// argv[1] = &d:\\temp\\ff.mpg&;&& // /*注册所有可用的格式和编解码器*/& av_register_all();&&& // Open video file /*以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息*/& if(av_open_input_file(&pFormatCtx, argv, NULL, 0, NULL)!=0)& & // Couldn't open file&&& // Retrieve stream information/*通过读取媒体文件的中的包来获取媒体文件中的流信息,对于没有头信息的文件如(mpeg)是非常有用的,// 该函数通常重算类似mpeg-2帧模式的真实帧率,该函数并未改变逻辑文件的position.*/& if(av_find_stream_info(pFormatCtx)&0)& & // Couldn't find stream information&&& // Dump information about file onto standard error//该函数的作用就是检查下初始化过程中设置的参数是否符合规范& dump_format(pFormatCtx, 0, argv, 0);&&& // Find the first video stream& videoStream=-1;& printf(&%d\n&,pFormatCtx-&nb_streams);& getchar();& for(i=0; i&pFormatCtx-&nb_ i++)& & if(pFormatCtx-&streams[i]-&codec-&codec_type==CODEC_TYPE_VIDEO&&videoStream & 0)&{& & & videoStream=i;& & && & }& if(videoStream==-1)& & // Didn't find a video stream&&& // Get a pointer to the codec context for the video stream& pCodecCtx=pFormatCtx-&streams[videoStream]-&&&& // Find the decoder for the video stream& pCodec=avcodec_find_decoder(pCodecCtx-&codec_id);/*通过code ID查找一个已经注册的音视频编码器,查找编码器之前,必须先调用av_register_all注册所有支持的编码器音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找*/& if(pCodec==NULL) {& & fprintf(stderr, &Unsupported codec!\n&);& & // Codec not found& }& // Open codec//使用给定的AVCodec初始化AVCodecContext& if(avcodec_open(pCodecCtx, pCodec)&0)& & // Could not open codec& //printf(&name %s\n&,pCodec-&name);& //getchar();& // Allocate video frame& pFrame=avcodec_alloc_frame();&&& // Allocate an AVFrame structure& pFrameYUV=avcodec_alloc_frame();& if(pFrameYUV==NULL)& &&&& // Determine required buffer size and allocate buffer& numBytes=avpicture_get_size(PIX_FMT_YUV422, pCodecCtx-&width,& & & & &pCodecCtx-&height);& buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));&&& // Assign appropriate parts of buffer to image planes in pFrameRGB& // Note that pFrameRGB is an AVFrame, but AVFrame is a superset& // of AVPicture& avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV422,& &pCodecCtx-&width, pCodecCtx-&height);&&& // Read frames and save first five frames to disk& i=0;& ////////////////////////////////////////////////////////////////& if (SDL_Init(SDL_INIT_VIDEO) & 0)& { &fprintf(stderr, &can not initialize SDL:%s\n&, SDL_GetError()); &exit(1);& &}& atexit(SDL_Quit);& SDL_Surface *& screen = SDL_SetVideoMode(720, 576, 24, SDL_SWSURFACE|SDL_ANYFORMAT);& if ( screen == NULL )&& { &exit(2);& }& SDL_Overlay * image = SDL_CreateYUVOverlay(pCodecCtx-&width, pCodecCtx-&height, SDL_YUY2_OVERLAY, screen);& & if(image == NULL)& {& & & & //fprintf(stderr, &CreateRGBSurface failed: %s\n&, SDL_GetError());& & & & exit(1);& & }& //////////////////////////////////////////////////////////////////& while(av_read_frame(pFormatCtx, &packet)&=0)&& {& & // Is this a packet from the video stream?& & if(packet.stream_index==videoStream)&&{& & // Decode video frame& & avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,&& & & &packet.data, packet.size);& & &&& & // Did we get a video frame?& & if(frameFinished)&& & {& // Convert the image from its native format to RGB& & & & & SDL_LockYUVOverlay(image);// pFrameYUV-&data[0] = image-&pixels[0];// pFrameYUV-&data[1] = image-&pixels[2];// pFrameYUV-&data[2] = image-&pixels[1];// // pFrameYUV-&linesize[0] = image-&pitches[0];// pFrameYUV-&linesize[1] = image-&pitches[2];// pFrameYUV-&linesize[2] = image-&pitches[1];& & & & img_convert_ctx = sws_getContext( pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &pCodecCtx-&pix_fmt,& & & & & & & &pCodecCtx-&width,&& & & & & & & &pCodecCtx-&height,& & & & & & & &PIX_FMT_YUV422,& & & & & & & &sws_flags, NULL, NULL, NULL);& & & & sws_scale(img_convert_ctx,pFrame-&data,pFrame-&linesize,0,pCodecCtx-&height,pFrameYUV-&data,pFrameYUV-&linesize); && & & & sws_freeContext(img_convert_ctx);& & & &memcpy(image-&pixels[0], pFrameYUV-&data[0],720*576*2);//拷贝数据yuv422 SDL_UnlockYUVOverlay(image); & rect.x = 0; rect.y = 0; rect.w = pCodecCtx-& rect.h = pCodecCtx-& SDL_DisplayYUVOverlay(image, &rect);& & }}& &&& & // Free the packet that was allocated by av_read_frame& & av_free_packet(&packet);& }&&& // Free the RGB image& av_free(buffer);& av_free(pFrameYUV);&&& // Free the YUV frame& av_free(pFrame);&&& // Close the codec& avcodec_close(pCodecCtx);&&& // Close the video file& av_close_input_file(pFormatCtx);& MessageBox(&over&);}}

我要回帖

更多关于 sdl android 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信