SDL 简单学习

发布时间:2023年12月28日

MAC

//./configure --prefix=/usr/local/

//

使用SDL步骤

? 1.添加头文件#include<sdl.h>

? 2.初始化SDL

? 3.退出SDL

SDL渲染

SDL_INIT/SDL_Quit()

SDL_Createwindow()/SDL_DestroyWindow()

SDL_CreateRender()

sdl 窗口打开demo?

void sdl_test() {
    
    SDL_Window * window = NULL;
    SDL_Renderer *render = NULL;
    SDL_Event event;
    int quit = 1;

    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("SDL2 WINDOW", 100, 100,640, 480, SDL_WINDOW_ALWAYS_ON_TOP);
    
    if (!window) {
        SDL_LogInfo(1, "sdl window create failed");
        goto __ERROR;
    }
   render = SDL_CreateRenderer(window, -1, 0);
    if (!render) {
        SDL_Log("render create failed");
        goto __DWINDOW;
    }
    SDL_RenderClear(render);
    SDL_SetRenderDrawColor(render, 255, 0, 0, 0);
    SDL_RenderPresent(render);
    SDL_Event e;
//    while (!quit) {
//        while (SDL_PollEvent(&e)) {
//            if (e.type == SDL_QUIT) {
//                quit = 1;
//            }
//        }
//    }
    
    do{
        SDL_WaitEvent(&event);
        switch(event.type) {
            case SDL_QUIT:
                quit = 0;
                break;
            default:
                SDL_Log("EVENT TYPE = %d",event.type);
        }
    }while(quit);
__DWINDOW:
    SDL_DestroyWindow(window);
__ERROR:
    SDL_Quit();
    
}

sdl 渲染

// 内存图像->渲染器->纹理->交换->窗口展示
void sdl_texture(){
    //SDL_CreateTexture();
    //format:YUV RGB
    //access Texture Target stream
    //SDL_DestroyTexture();
    //    SDL_SetRenderTarget(<#SDL_Renderer *renderer#>, <#SDL_Texture *texture#>)
    //    SDL_RenderClear(<#SDL_Renderer *renderer#>)
    //    SDL_RenderCopy(<#SDL_Renderer *renderer#>, <#SDL_Texture *texture#>, <#const SDL_Rect *srcrect#>, <#const SDL_Rect *dstrect#>)
//    SDL_RenderPresent(<#SDL_Renderer *renderer#>)
        
        SDL_Window * window = NULL;
        SDL_Renderer *render = NULL;
        SDL_Texture *texture = NULL;
        SDL_Event event;
        int quit = 1;
        SDL_Rect rect;
        rect.w = 30;
        rect.h = 30;

        SDL_Init(SDL_INIT_VIDEO);
        window = SDL_CreateWindow("SDL2 WINDOW", 100, 100,640, 480, SDL_WINDOW_ALWAYS_ON_TOP);
        
        if (!window) {
            SDL_LogInfo(1, "sdl window create failed");
            goto __ERROR;
        }
       render = SDL_CreateRenderer(window, -1, 0);
        if (!render) {
            SDL_Log("render create failed");
            goto __DWINDOW;
        }
        SDL_RenderClear(render);
        SDL_SetRenderDrawColor(render, 255, 0, 0, 0);
        SDL_RenderPresent(render);
    
    
        texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, 640,480);
        if (!texture) {
            SDL_Log("texture create failed");
            goto __RENDER;
        }
    
        do{
            SDL_PollEvent(&event);
            switch(event.type) {
                case SDL_QUIT:
                    quit = 0;
                    break;
                default:
                    SDL_Log("EVENT TYPE = %d",event.type);
            }
            rect.x = rand() % 600;
            rect.y = rand() % 450;
            SDL_SetRenderTarget(render, texture);
            SDL_SetRenderDrawColor(render, 0, 0, 0, 0);
            SDL_RenderClear(render);
            
            SDL_RenderDrawRect(render, &rect);
            SDL_SetRenderDrawColor(render, 255.0, 0, 0, 0);
            SDL_RenderFillRect(render, &rect);
            SDL_SetRenderTarget(render, NULL);
            SDL_RenderCopy(render, texture, NULL, NULL);
            
            SDL_RenderPresent(render);
            
        }while(quit);
    SDL_DestroyTexture(texture);
__RENDER:
    SDL_DestroyRenderer(render);
__DWINDOW:
    SDL_DestroyWindow(window);
__ERROR:
    SDL_Quit();
}

sdl 播放yuv

#include <stdio.h>
#include <string.h>
#define BLOCK_SIZE 4096000

//event message
#define REFRESH_EVENT  (SDL_USEREVENT + 1)
#define QUIT_EVENT  (SDL_USEREVENT + 2)

int thread_exit=0;
int refresh_video_timer(void *udata){

    thread_exit=0;

    while (!thread_exit) {
        SDL_Event event;
        event.type = REFRESH_EVENT;
        SDL_PushEvent(&event);
        SDL_Delay(40);
    }

    thread_exit=0;

    //push quit event
    SDL_Event event;
    event.type = QUIT_EVENT;
    SDL_PushEvent(&event);

    return 0;
}

void sdl_yuv_player() {
    
    FILE *video_fd = NULL;

    SDL_Event event;
    SDL_Rect rect;

    Uint32 pixformat = 0;

    SDL_Window *win = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Texture *texture = NULL;

    SDL_Thread *timer_thread = NULL;

    int w_width = 640, w_height = 480;
    const int video_width = 608, video_height = 368;

    Uint8 *video_pos = NULL;
    Uint8 *video_end = NULL;

    unsigned int remain_len = 0;
    unsigned int video_buff_len = 0;
    unsigned int blank_space_len = 0;
    Uint8 video_buf[BLOCK_SIZE];

    const char *path = "/Users/king/Desktop/ffmpeg/video/01.yuv";

    const unsigned int yuv_frame_len = video_width * video_height * 12 / 8;

    //initialize SDL
    if(SDL_Init(SDL_INIT_VIDEO)) {
        fprintf( stderr, "Could not initialize SDL - %s\n", SDL_GetError());
        return;
    }

    //creat window from SDL
    win = SDL_CreateWindow("YUV Player",
                           SDL_WINDOWPOS_UNDEFINED,
                           SDL_WINDOWPOS_UNDEFINED,
                           w_width, w_height,
                           SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    if(!win) {
        fprintf(stderr, "Failed to create window, %s\n",SDL_GetError());
        goto __FAIL;
    }

    renderer = SDL_CreateRenderer(win, -1, 0);

    //IYUV: Y + U + V  (3 planes)
    //YV12: Y + V + U  (3 planes)
    pixformat= SDL_PIXELFORMAT_IYUV;

    //create texture for render
    texture = SDL_CreateTexture(renderer,
                                pixformat,
                                SDL_TEXTUREACCESS_STREAMING,
                                video_width,
                                video_height);

    //open yuv file
    video_fd = fopen(path, "r");
    if( !video_fd ){
        fprintf(stderr, "Failed to open yuv file\n");
        goto __FAIL;
    }

    //read block data
    if((video_buff_len = fread(video_buf, 1, BLOCK_SIZE, video_fd)) <= 0){
        fprintf(stderr, "Failed to read data from yuv file!\n");
        goto __FAIL;
    }

    //set video positon
    video_pos = video_buf;
    video_end = video_buf + video_buff_len;
    blank_space_len = BLOCK_SIZE - video_buff_len;

    timer_thread = SDL_CreateThread(refresh_video_timer,
                                    NULL,
                                    NULL);

    do {
        //Wait
        SDL_WaitEvent(&event);
        if(event.type==REFRESH_EVENT){
            //not enought data to render
            if((video_pos + yuv_frame_len) > video_end){

                //have remain data, but there isn't space
                remain_len = video_end - video_pos;
                if(remain_len && !blank_space_len) {
                    //copy data to header of buffer
                    memcpy(video_buf, video_pos, remain_len);

                    blank_space_len = BLOCK_SIZE - remain_len;
                    video_pos = video_buf;
                    video_end = video_buf + remain_len;
                }

                //at the end of buffer, so rotate to header of buffer
                if(video_end == (video_buf + BLOCK_SIZE)){
                    video_pos = video_buf;
                    video_end = video_buf;
                    blank_space_len = BLOCK_SIZE;
                }

                //read data from yuv file to buffer
                if((video_buff_len = fread(video_end, 1, blank_space_len, video_fd)) <= 0){
                    fprintf(stderr, "eof, exit thread!");
                    thread_exit = 1;
                    continue;// to wait event for exiting
                }

                //reset video_end
                video_end += video_buff_len;
                blank_space_len -= video_buff_len;
                printf("not enought data: pos:%p, video_end:%p, blank_space_len:%d\n", video_pos, video_end, blank_space_len);
            }

            SDL_UpdateTexture( texture, NULL, video_pos, video_width);

            //FIX: If window is resize
            rect.x = 0;
            rect.y = 0;
            rect.w = w_width;
            rect.h = w_height;

            SDL_RenderClear( renderer );
            SDL_RenderCopy( renderer, texture, NULL, &rect);
            SDL_RenderPresent( renderer );

            printf("not enought data: pos:%p, video_end:%p, blank_space_len:%d\n", video_pos, video_end, blank_space_len);
            video_pos += yuv_frame_len;

        }else if(event.type==SDL_WINDOWEVENT){
            //If Resize
            SDL_GetWindowSize(win, &w_width, &w_height);
        }else if(event.type==SDL_QUIT){
            thread_exit=1;
        }else if(event.type==QUIT_EVENT){
            break;
        }
    }while ( 1 );

__FAIL:

    //close file
    if(video_fd){
        fclose(video_fd);
    }

    SDL_Quit();
}

sdl播放pcm

#define BLOCK_SIZE 4096000
static Uint8 *audio_bufer = NULL;
static Uint8 *audio_pos   = NULL;
static size_t buffer_len  = 0;

void read_audio_data(void *data, Uint8 *stream, int len) {
    if(buffer_len == 0) {
        return;
    }
    SDL_memset(stream, 0, len);
    len = (len < buffer_len) ? len : buffer_len;
    SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
    audio_pos+=len;
    buffer_len-=len;
}
void audio_player() {
    char *path = "/Users/king/Desktop/ffmpeg/audio/test.pcm";
    FILE *audio_fd = NULL;
   int result = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER);
    if (result) {
        SDL_Log("init failed");
        return;
    }
    
    audio_fd = fopen(path, "rb+");
    if (!audio_fd) {
        SDL_Log("failed to pcm file");
        goto __FAIL;
    }
    
    audio_bufer = (Uint8 *)malloc(BLOCK_SIZE);
    if (!audio_bufer) {
        SDL_Log("dailed to alloc buffer");
    }
    SDL_AudioSpec spec;
    spec.freq = 44100;
    spec.channels = 2;
    spec.format = AUDIO_S16SYS;
    spec.callback = read_audio_data;
    spec.silence = 0;
    spec.userdata = NULL;
    if (SDL_OpenAudio(&spec, NULL)) {
        SDL_Log("Failed to open audio device");
        
        goto __FAIL;
    }
    SDL_PauseAudio(0);
    /// 从文件读取数据到buffer。声卡需要多少再从缓存中给多少
    do{
        buffer_len = fread(audio_bufer, 1, BLOCK_SIZE, audio_fd);
        audio_pos = audio_bufer;
        while (audio_pos < (audio_bufer + buffer_len)) {
            /// 这个时候buffer里面有数据 就先不读
            SDL_Delay(1);
        }
    } while(buffer_len != 0);
    SDL_CloseAudio();
__FAIL:
    if (audio_bufer) {
        free(audio_bufer);
    }
    if(audio_fd) {
        fclose(audio_fd);
    }
    SDL_Quit();
    
}

文章来源:https://blog.csdn.net/weixin_38432324/article/details/135129960
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。