#include <iostream>
#include<stdio.h>
#include <SDL.h>
#include<SDL_thread.h>
#define SCREEN_W 640 //螢屏寬度
#define SCREEN_H 272 //螢屏高度
#define PIXEL_W 640 //紋理的寬度,像素
#define PIXEL_H 272 //紋理的高度,像素
using namespace std;
int RefreshVideo(void*data)
{
/*向事件佇列中添加事件,每40ms添加一個事件 40x25=1000 ------每秒25幀*/
//SDL_Delay(40);
//SDL_PushEvent(&event);
cout<<"RefreshVideo"<<endl;
}
//SDL播放模塊
void SdlThread()
{
cout<<"播放執行緒啟動"<<endl;
const int bpp = 12; //一個YUV420像素點的bit數
unsigned char buffer[PIXEL_W*PIXEL_H*bpp/8]; //用于存盤從test.yuv中讀取的資料
SDL_Rect rect; //矩形框,用于指定重繪渲染器的區域
rect.x=0;
rect.y=0;
rect.w=SCREEN_W;
rect.h=SCREEN_H;
//打開測驗檔案
FILE *fp = fopen("./test.yuv","rb");
if(fp == NULL){
cout<<" open test.yuv failure "<<endl;
return ;
}
//初始化SDL
if(SDL_Init(SDL_INIT_VIDEO)){
SDL_Log("Unable to initialize SDL:%s",SDL_GetError());
return ;
}
//創建視窗
SDL_Window *window;
window= SDL_CreateWindow("Person Network Player",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_W,SCREEN_H,
SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
// 檢查表單是否創建成功,如果不成功window 為NULL
if (window == NULL) {
// 如果表單沒有創建成功,后面的程式已經沒有執行的必要了。
SDL_Log("Could not create window: %s\n", SDL_GetError());
return;
}
//給視窗添加界面,獲取視窗surface
SDL_Surface*surface=SDL_GetWindowSurface(window);
//加載bmp圖片
SDL_Surface*backgroud=SDL_LoadBMP("./testyuv.bmp");
SDL_BlitSurface(backgroud,NULL,surface,NULL);
//重繪視窗
SDL_UpdateWindowSurface(window);
//第三步:SDL_CreateRenderer(): 基于視窗創建渲染器(Render)
//使用第一個驅動程式,硬體加速
SDL_Renderer *renderer= SDL_CreateRenderer(window,-1,SDL_RENDERER_PRESENTVSYNC);
if(renderer==NULL)
{
SDL_Log("Could not create renderer: %s\n", SDL_GetError());
return;
}
//第四步:SDL_CreateTexture(): 創建紋理(Texture)
struct SDL_Texture *texture=SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_IYUV,
SDL_TEXTUREACCESS_STREAMING,PIXEL_W,PIXEL_H);
if(texture==NULL)
{
SDL_Log("Could not create renderer: %s\n", SDL_GetError());
return;
}
//創建執行緒
// SDL_Thread *SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
//typedef int (SDLCALL * SDL_ThreadFunction) (void *data); //SDL_ThreadFunction 函式指標型別
//void 引數為執行緒傳參
SDL_Thread *refresh_thread = SDL_CreateThread(RefreshVideo,NULL,NULL);
//事件捕獲
SDL_Event event; //創建事件物件
while(true)
{
SDL_WaitEvent(&event); //當事件佇列為空程式阻塞,釋放CPU
//收到事件后處理事件
//按下enter鍵開始處理
if((event.type==SDL_KEYDOWN )&& (event.key.keysym.sym==13))
{
while(true)
{
cout<<"Event started"<<endl;
//讀取YUV420資料,這里需要了解YUV420的內部結構組成
//判斷是否讀取完畢
if(!fread(buffer, 1, PIXEL_W*PIXEL_H*bpp/8, fp))
{
//移動檔案指標,否則下一次無法播放
fseek(fp, 0, SEEK_SET);
break;
}
//更新紋理
SDL_UpdateTexture(texture,NULL,buffer,PIXEL_W); //傳NULL,更新整個紋理
//更新渲染器
SDL_RenderClear(renderer); //先清除渲染器,消除上一幀的影響
//將紋理中的資料拷貝到渲染器中
SDL_RenderCopy(renderer,texture,NULL,&rect);
//將渲染器背景關系中的資料,渲染到關聯表單上去
SDL_RenderPresent(renderer);
}
}
else if(event.type==SDL_QUIT)
{
break;
}
}
fclose(fp); //關閉檔案
//釋放記憶體資源
SDL_FreeSurface(backgroud);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
cout<<"SDLPlayer Exit"<<endl;
//退出
SDL_Quit();
}
int main(int argc, char * argv[])
{
cout<<"This is main Function! "<<endl;
SdlThread();
return 0;
}
uj5u.com熱心網友回復:
第一次發帖,還不知道格式
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/123784.html
標籤:多媒體/流媒體開發
上一篇:mvn site 顯示
