美文网首页
FFmpeg+SDL(雷神)-(4-进阶)

FFmpeg+SDL(雷神)-(4-进阶)

作者: Goning | 来源:发表于2019-01-08 17:20 被阅读8次

    (4) SDL视频显示-进阶
    代码记录


    #include <stdio.h>
    
    extern "C"
    {
    #include "sdl/SDL.h"
    };
    
    const int bpp=12;
    
    int screen_w=500,screen_h=500;
    const int pixel_w=320,pixel_h=180;
    
    unsigned char buffer[pixel_w*pixel_h*bpp/8];
    
    //Refresh Event
    #define REFRESH_EVENT  (SDL_USEREVENT + 1)
    //Break
    #define BREAK_EVENT  (SDL_USEREVENT + 2)
    
    int thread_exit=0;
    int thread_pause=0;
    
    int refresh_video(void *opaque){
        thread_exit=0;
        while (thread_exit==0) {
            if(thread_pause==0){
            SDL_Event event;
            event.type = REFRESH_EVENT;
            SDL_PushEvent(&event);
            }
            SDL_Delay(40);
        }
        thread_exit=0;
        //Break
        SDL_Event event;
        event.type = BREAK_EVENT;
        SDL_PushEvent(&event);
        return 0;
    }
    
    int writeY(FILE *i_file,FILE *o_file,const int w,const int h){
        //读取文件i_file
        FILE* fp_yuv=i_file;
        //写入文件o_file
        FILE* fp_frame=o_file;
        //开辟内存,与读取的文件的大小一致
        char* buffer_y=(char*)malloc(sizeof(char)*w*h);
        char* buffer_u=(char*)malloc(sizeof(char)*w*h/4);
        char* buffer_v=(char*)malloc(sizeof(char)*w*h/4);
        //读取函数,将i_file的第一帧存入buff指向的内存
        for(int i=0;i<50;i++)//50:i_file文件一共有50帧
        {
            fread(buffer_y,w*h,1,fp_yuv);
            fread(buffer_u,w*h/4,1,fp_yuv);
            fread(buffer_v,w*h/4,1,fp_yuv);
            /*memset():将buffer_u/buffer_v后面的w*h/4个字节用128替换*/
            memset(buffer_u,128,w*h/4);//128:色度的值,取值0~255
            memset(buffer_v,128,w*h/4);//128:饱和度的值,取值0~255
            fwrite(buffer_y,w*h,1,fp_frame);
            fwrite(buffer_u,w*h/4,1,fp_frame);
            fwrite(buffer_v,w*h/4,1,fp_frame);
        }
        free(buffer_y);
        free(buffer_u);
        free(buffer_v);
        return 0;
    }
    
    int main(int argc, char* argv[])
    {
        if(SDL_Init(SDL_INIT_VIDEO)) {  
            printf( "Could not initialize SDL - %s\n", SDL_GetError()); 
            return -1;
        } 
    
        SDL_Window *screen; 
        //SDL 2.0 Support for multiple windows
        screen = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
            screen_w, screen_h,SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
        if(!screen) {  
            printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  
            return -1;
        }
        SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  
    
        Uint32 pixformat=0;
        //IYUV: Y + U + V  (3 planes)
        //YV12: Y + V + U  (3 planes)
        pixformat= SDL_PIXELFORMAT_IYUV;  
    
        SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer,pixformat, SDL_TEXTUREACCESS_STREAMING,pixel_w,pixel_h);
    
        FILE *fp=NULL;
        fp=fopen("test_yuv420p_320x180.yuv","rb+");
        if(fp==NULL){
            printf("cannot open this file\n");
            return -1;
        }
    
        //写入文件frame.yuv(亮度数据)
        FILE* fp_frame=fopen("frame_320x180_out.yuv","wb");
        writeY(fp,fp_frame,pixel_w,pixel_h);
        fclose(fp_frame);
    
        SDL_Rect sdlRect;  
    
        SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video,NULL,NULL);
        SDL_Event event;
        while(1){
            //Wait
            SDL_WaitEvent(&event);
            if(event.type==REFRESH_EVENT){
                if (fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp) != pixel_w*pixel_h*bpp/8){
                    // Loop
                    fseek(fp, 0, SEEK_SET);
                    fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp);
                }
    
                SDL_UpdateTexture( sdlTexture, NULL, buffer, pixel_w);  
    
                //FIX: If window is resize
                sdlRect.x = 0;  
                sdlRect.y = 0;  
                sdlRect.w = screen_w;  
                sdlRect.h = screen_h;  
                
                SDL_RenderClear( sdlRenderer );   
                SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);  
                SDL_RenderPresent( sdlRenderer ); 
                
            }else if(event.type==SDL_WINDOWEVENT){
                //If Resize
                SDL_GetWindowSize(screen,&screen_w,&screen_h);
            }else if(event.type==SDL_KEYDOWN){
                //Pause
                if(event.key.keysym.sym==SDLK_SPACE)
                    thread_pause=!thread_pause;
            }else if(event.type==SDL_QUIT){
                thread_exit=1;
            }else if(event.type==BREAK_EVENT){
                break;
            }
        }
        SDL_Quit();
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:FFmpeg+SDL(雷神)-(4-进阶)

          本文链接:https://www.haomeiwen.com/subject/axuhrqtx.html