c语言bmp2yuyv,SDL显示bmp,SDL播放yuv420P

SDL窗口能拖动的代码取自:[这里]

其他的SDL代码取自官网的[Demo]。

// sdl_test_console.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#define YUV420P_320240320*240*3/2//115200

void PrintHex(uint8_t *src, uint32_t size);

void display_bmp(char* file_name, SDL_Surface *screen);

int _tmain(int argc, _TCHAR* argv[])

{

if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1)) {

printf("Could not initialize SDL: %s.\n", SDL_GetError());

exit(-1);

}

atexit(SDL_Quit);

SDL_Surface *sdl_screen = NULL;

sdl_screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE|SDL_ANYFORMAT);

if (sdl_screen == NULL) {

exit(1);

}

display_bmp("./320_240.bmp", sdl_screen);

// main loop

bool bRun = true ;

while (bRun) {

//Update Screen

SDL_Flip(sdl_screen);

// delay, 50 for simple

SDL_Delay(50);

//While there's an event to handle

SDL_Event event;

while (SDL_PollEvent(&event)) {

if (event.type == SDL_QUIT) {

bRun = false ;

}

}

}

return 0;

}

void display_bmp(char* file_name, SDL_Surface *screen)

{

SDL_Surface* image = NULL;

/* Load the BMP file into a surface */

image = SDL_LoadBMP(file_name);

if (image == NULL) {

fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());

return;

}

/*

* Palettized screen modes will have a default palette (a standard

* 8*8*4 colour cube), but if the image is palettized as well we can

* use that palette for a nicer colour matching

*/

if (image->format->palette && screen->format->palette) {

SDL_SetColors(screen, image->format->palette->colors, 0, image->format->palette->ncolors);

}

/* Blit onto the screen surface */

if (SDL_BlitSurface(image, NULL, screen, NULL) < 0)

fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());

/* Update the modified region of the screen */

SDL_UpdateRect(screen, 0, 0, image->w, image->h);

/* Free the allocated BMP surface */

SDL_FreeSurface(image);

}

void PrintHex(uint8_t *src, uint32_t size)

{

for (uint32_t i = 0; i < size; ++i) {

if (i > 0 && i % 16 == 0) {

::OutputDebugStringA("\n");

}

AtlTrace("%02x ", src[i]);

}

::OutputDebugStringA("\n");

}

效果:

f243d0dacbc153dec70958e7ba9d1dee.png

==========================================================

2012 09-13 17:10更新:

SDL真是太棒了!接口清晰,这才是人类进步的希望。

实现的是播放yuv420P裸数据的代码,至于怎么得到yuv420P数据,用大家都喜欢的ffmpeg:

ffmpeg -i miku39.flv -pix_fmt yuv420p -s 320*240 -ss 60 -t 30 miku.yuv

SDL播放相关代码:

// sdl_test_console.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#define YUV420P_320240320*240*3/2//115200

void DisplayYUV420P(uint8_t *buf, uint32_t w, uint32_t h, SDL_Overlay *overlay);

int _tmain(int argc, _TCHAR* argv[])

{

uint8_t one_frame[YUV420P_320240] = {0};

std::fstream in_yuv420p;

in_yuv420p.open("yuv420p_320240.yuv", std::ios_base::in | std::ios_base::binary);

//PrintHex(one_frame, YUV420P_320240);

if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1)) {

printf("Could not initialize SDL: %s.\n", SDL_GetError());

exit(-1);

}

atexit(SDL_Quit);

SDL_Surface *sdl_screen = NULL;

sdl_screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE|SDL_ANYFORMAT);

if (sdl_screen == NULL) {

exit(1);

}

SDL_Overlay *sdl_overlay = SDL_CreateYUVOverlay(320, 240, SDL_IYUV_OVERLAY, sdl_screen);

if (sdl_overlay == NULL) {

exit(1);

}

SDL_Rect video_rect;

video_rect.x = 0;

video_rect.y = 0;

video_rect.w = 320;

video_rect.h = 240;

bool sdl_running = true;

while (sdl_running) {

//read yuv from file

if (!in_yuv420p.eof()) {

in_yuv420p.read((char *)one_frame, YUV420P_320240);

auto rel_size = in_yuv420p.gcount();

if (rel_size < YUV420P_320240) continue ;

DisplayYUV420P(one_frame, 320, 240, sdl_overlay);

SDL_DisplayYUVOverlay(sdl_overlay, &video_rect);

}

//Update Screen

SDL_Flip(sdl_screen);

// delay, 40 for sample (25 fps)

SDL_Delay(40);

//While there's an event to handle

SDL_Event sdl_event;

while (SDL_PollEvent(&sdl_event)) {

if (sdl_event.type == SDL_QUIT) {

sdl_running = false ;

}

}

}

SDL_FreeYUVOverlay(sdl_overlay);

return 0;

}

void DisplayYUV420P(uint8_t *buf, uint32_t w, uint32_t h, SDL_Overlay *overlay)

{

/* Fill in video data */

uint32_t yuv_size = (w*h) * 3/2;

auto y_video_data = buf;

auto u_video_data = buf + w * h;

auto v_video_data = u_video_data + (w * h / 4);

/* Fill in pixel data - the pitches array contains the length of a line in each plane */

SDL_LockYUVOverlay(overlay);

memcpy(overlay->pixels[0], y_video_data, w * h);

memcpy(overlay->pixels[1], u_video_data, w * h / 4);

memcpy(overlay->pixels[2], v_video_data, w * h / 4);

SDL_UnlockYUVOverlay(overlay);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值