SDL2.0 播放YUV

/*
* =====================================================================================
*
*       Filename: main.cpp 
*
*    Description:  
*
*        Version:  1.0
*        Created:  2014年05月10日 14时22分38秒
*       Revision:  none
*       Compiler:  gcc
*
*         Author:  Wenxian Ni (Hello World~), niwenxianq@qq.com
*   Organization:  AMS/ICT
*
* =====================================================================================
*/

#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <SDL2/SDL.h>
#include <string.h>
using namespace std;

const int width  = 1920;
const int height = 1080;

SDL_Window *window = nullptr;
SDL_Renderer *ren  = nullptr;

SDL_Texture* LoadImage(string file);
void ApplySurface(int x, int y, SDL_Texture *tex, SDL_Renderer *rend);
void QuitSdl(SDL_Event event);

int main(int argc, char **argv)
{
    string filename = "background.bmp";
    SDL_Event        event;
	SDL_bool         done = SDL_FALSE;
	Uint32           pixel_format = SDL_PIXELFORMAT_IYUV;
	int frame_number = 0;
    FILE *fp = fopen("a.yuv","r");

    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    //if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
    if (SDL_Init(SDL_INIT_VIDEO) != 0){
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        return 3;
    }

    SDL_Window *win = SDL_CreateWindow("Hello",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height,SDL_WINDOW_SHOWN);
    if(win == nullptr)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError());
        return 1;
    }
    ren = SDL_CreateRenderer(win, 0, 0); //渲染器 底层,打底
    if(ren == nullptr)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError());
        return 1; 
    }


  //  SDL_Texture *tex = LoadImage(filename);
  //  if(tex == nullptr)
  //  {
  //      cout<<"SDL_CreateTextureFromeSurface Error"<<SDL_GetError()<<endl;
  //      return 1;
  //  }

  //  SDL_RenderClear(ren);
  //  SDL_RenderCopy(ren, tex, NULL, NULL);
  //  SDL_RenderPresent(ren);
    SDL_Texture *tex = SDL_CreateTexture(ren, pixel_format, SDL_TEXTUREACCESS_STREAMING, width, height);
    int len  = height*width;
    Uint8* buf = (Uint8*)malloc(len*2);
    int iPitch = width * SDL_BYTESPERPIXEL(pixel_format);
        printf("IPath %d\n",iPitch);
    SDL_Rect rec;
    rec.x = 0;
    rec.y = 0;
    rec.w = width;
    rec.h = height;
	while(!done)
	{
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_KEYDOWN:
                if (event.key.keysym.sym == SDLK_ESCAPE) {
                    done = SDL_TRUE;
                }
                break;
            case SDL_QUIT:
                done = SDL_TRUE;
                break;
            }
        }
        fread(buf,1,height*width*3/2,fp);
        //printf("lee = %d\n",lee);
        //    SDL_UpdateYUVTexture(tex,NULL,(const Uint8*)bufY,len,(const Uint8*)bufU,len/4,(const Uint8*)bufV,len/4);
        SDL_UpdateTexture(tex,NULL, buf,width);
        SDL_RenderClear(ren);
        SDL_RenderCopy(ren, tex, NULL, &rec);
        SDL_RenderPresent(ren);
		frame_number++;
    }
//  while(1)
//  {
//      SDL_WaitEvent(&event);
//      QuitSdl(event);
//  }
SDL_Delay(2000);
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
fclose(fp);
return 0;
}

SDL_Texture* LoadImage(string file){
    SDL_Surface *loadedImage = nullptr;
    SDL_Texture *texture = nullptr;

    loadedImage = SDL_LoadBMP(file.c_str());
    if (loadedImage != nullptr){
        texture = SDL_CreateTextureFromSurface(ren, loadedImage);
        SDL_FreeSurface(loadedImage);
    }
    else
    std::cout << SDL_GetError() << std::endl;
    return texture;
}
void ApplySurface(int x, int y, SDL_Texture *tex, SDL_Renderer *rend){
    SDL_Rect pos;
    pos.x = x;
    pos.y = y;
    SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
    SDL_RenderCopy(rend, tex, NULL, &pos);
}

void QuitSdl(SDL_Event event)
{
    switch(event.type)
    {
        case SDL_QUIT:
        SDL_Quit();
        break;
    }
    return ;
}
说明:
1. SDL2.0 相对于老版,有更新
2. YV12, IYUV注意区别,如是图片显红,则是此处错误


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SDL2.0 支持渲染 YUV4:2:0 格式的视频,需要使用 SDL_Texture 和 SDL_RenderCopy 函数来实现。 以下是一个简单的示例代码: ```c #include <SDL2/SDL.h> #include <stdio.h> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; int main(int argc, char* argv[]) { SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; SDL_Texture* texture = NULL; if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); return 1; } window = SDL_CreateWindow("YUV4:2:0 Video", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } renderer = SDL_CreateRenderer(window, -1, 0); if (renderer == NULL) { printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); if (texture == NULL) { printf("Texture could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } // YUV data Uint8* yPlane = NULL; Uint8* uPlane = NULL; Uint8* vPlane = NULL; int yPitch = 0; int uPitch = 0; int vPitch = 0; int w = 0; int h = 0; // read YUV file FILE* fp = fopen("video.yuv", "rb"); if (fp == NULL) { printf("Could not open YUV file!\n"); return 1; } // allocate memory for YUV data int bufferSize = SCREEN_WIDTH * SCREEN_HEIGHT * 3 / 2; Uint8* buffer = (Uint8*)malloc(bufferSize); // main loop SDL_Event event; bool quit = false; while (!quit) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { quit = true; } } // read YUV data if (fread(buffer, 1, bufferSize, fp) != bufferSize) { // end of file rewind(fp); } // set YUV data yPlane = buffer; uPlane = yPlane + SCREEN_WIDTH * SCREEN_HEIGHT; vPlane = uPlane + SCREEN_WIDTH * SCREEN_HEIGHT / 4; yPitch = SCREEN_WIDTH; uPitch = SCREEN_WIDTH / 2; vPitch = SCREEN_WIDTH / 2; w = SCREEN_WIDTH; h = SCREEN_HEIGHT; // update texture SDL_UpdateYUVTexture(texture, NULL, yPlane, yPitch, uPlane, uPitch, vPlane, vPitch); // clear screen SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(renderer); // render texture SDL_RenderCopy(renderer, texture, NULL, NULL); // update screen SDL_RenderPresent(renderer); } // free memory free(buffer); // cleanup SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } ``` 在代码中,我们首先创建一个 SDL 窗口和渲染器。然后,使用 SDL_CreateTexture 函数创建一个 YV12 格式的纹理。接下来,读取 YUV 文件,并将数据设置到纹理中。在主循环中,使用 SDL_RenderCopy 函数将纹理渲染到屏幕上。最后,记得在程序结束前释放所有内存和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值