yuv播放器

来源:互联网 发布:php模拟post请求接口 编辑:程序博客网 时间:2024/06/05 18:24

用sdl写个播放器, 播放yuv 

发现播放yuv的应用还很广,主要是测试时用到

基于sdl, 现在出了sdl2.0, 暂用1.2的, 这个比较熟悉


todo:

1. 支持size的改变

2. 读取yuv的信息

3. 截取其中的一帧

4. 支持yuv nv12 yuv444, yuv422 , rgb24等主流

5. 跨平台


先贴个1.0(暂且这么叫吧)

#include<stdio.h>#include<unistd.h>#include<SDL/SDL.h>FILE                   *fp;SDL_Surface            *screen;const int width  = 1920;const int height = 1080;void QuitSdl(SDL_Event event);SDL_Surface* SDL_ScaleSurface(SDL_Surface *Surface, Uint16 Width, Uint16 Height);void ApplySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination );int ThreadCallBack(void *para);int main(int argc, char **argv){    const SDL_VideoInfo    *monitor;    SDL_Surface            *background;    SDL_Surface            *ground;    SDL_Event              event;    SDL_Thread             *thread = NULL;    void                   *param;        if(SDL_Init(SDL_INIT_VIDEO))    {        printf("Coundnot init SDL\n");        exit(1);    }        monitor    = SDL_GetVideoInfo();    screen     = SDL_SetVideoMode(width, height, 24, SDL_SWSURFACE);        background = SDL_LoadBMP("background.bmp");    ground     = SDL_ScaleSurface(background, width, height);     SDL_BlitSurface(ground, NULL, screen, NULL);    ApplySurface(0, 0, ground, screen);    SDL_Flip(screen);    fp = fopen("a.yuv","r");    if(NULL == fp)    {        printf("open file error\n");        exit(1);    }    thread  = SDL_CreateThread(ThreadCallBack, (void*)¶m);    if(NULL == thread)    {        printf("Thread Cread error\n");        exit(1);    }    while(1)    {        SDL_WaitEvent(&event);        QuitSdl(event);    }    return 0;}void ApplySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination ){//Temporary rectangle to hold the offsetsSDL_Rect offset;//Get the offsetsoffset.x = x;offset.y = y;SDL_BlitSurface( source, NULL, destination, &offset );}void QuitSdl(SDL_Event event){    switch(event.type)    {        case SDL_QUIT:            SDL_Quit();            break;    }    return ;}Uint32 ReadPixel(SDL_Surface *surface, int x, int y){int bpp = surface->format->BytesPerPixel;/* Here p is the address to the pixel we want to retrieve */Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;switch(bpp) {case 1:return *p;break;case 2:return *(Uint16 *)p;break;case 3:if(SDL_BYTEORDER == SDL_BIG_ENDIAN)return p[0] << 16 | p[1] << 8 | p[2];elsereturn p[0] | p[1] << 8 | p[2] << 16;break;case 4:return *(Uint32 *)p;break;default:return 0;       /* shouldn't happen, but avoids warnings */}}void DrawPixel(SDL_Surface *surface, int x, int y, Uint32 pixel){int bpp = surface->format->BytesPerPixel;/* Here p is the address to the pixel we want to set */Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;switch(bpp) {case 1:*p = pixel;break;case 2:*(Uint16 *)p = pixel;break;case 3:if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {p[0] = (pixel >> 16) & 0xff;p[1] = (pixel >> 8) & 0xff;p[2] = pixel & 0xff;} else {p[0] = pixel & 0xff;p[1] = (pixel >> 8) & 0xff;p[2] = (pixel >> 16) & 0xff;}break;case 4:*(Uint32 *)p = pixel;break;}}SDL_Surface* SDL_ScaleSurface(SDL_Surface *Surface, Uint16 Width, Uint16 Height){          SDL_Surface *_ret = SDL_CreateRGBSurface(Surface->flags, Width, Height, Surface->format->BitsPerPixel,                                                          Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask, Surface->format->Amask);         double    _stretch_factor_x = ((double)Width / (double)(Surface->w)),            _stretch_factor_y = ((double)(Height) / (double)(Surface->h));        for(Sint32 y = 0; y < Surface->h; y++) //Run across all Y pixels.            for(Sint32 x = 0; x < Surface->w; x++) //Run across all X pixels.                for(Sint32 o_y = 0; o_y < _stretch_factor_y; ++o_y) //Draw _stretch_factor_y pixels for each Y pixel.                    for(Sint32 o_x = 0; o_x < _stretch_factor_x; ++o_x) //Draw _stretch_factor_x pixels for each X pixel.                        DrawPixel(_ret, (Sint32)(_stretch_factor_x * x) + o_x,                                                          (Sint32)(_stretch_factor_y * y) + o_y, ReadPixel(Surface, x, y));        return _ret;}int ThreadCallBack(void *para){    unsigned char buf[width*height*3/2];    unsigned char *py, *pu, *pv;    int  len, pyLen, puLen, pvLen;    SDL_Overlay *bmp;    SDL_Rect    rect;    bmp  = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, screen);//    buf = (unsigned char*)malloc(sizeof(unsigned char)*1920*1080*3/2);        py  = buf;    pu  = buf + width*height;    pv  = buf + width*height*5/4;    pyLen = width*height;    puLen = pvLen = width*height/4;    rect.x = 0;    rect.y = 0;    rect.w = width;    rect.h = height;        while(1)    {        len = fread(buf, 1, width*height*3/2, fp);        printf("len=%d\n",len);        SDL_LockYUVOverlay(bmp);        bmp->pixels[0] = py;        bmp->pixels[2] = pu;        bmp->pixels[1] = pv;                bmp->pitches[0] = pyLen;        bmp->pitches[2] = puLen;        bmp->pitches[1] = pvLen;        SDL_UnlockYUVOverlay(bmp);        SDL_DisplayYUVOverlay(bmp, &rect);        sleep(1);    }    return 0;}

里面有两个文件,一个yuv, 一个bmp

0 0
原创粉丝点击