//------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { ERROR_PRINT("platform_support::init %d,%d\n", width, height); m_window_flags = flags; int wflags = 0; if(m_specific->m_texture) SDL_DestroyTexture(m_specific->m_texture); if(m_specific->m_renderer) SDL_DestroyRenderer(m_specific->m_renderer); if(m_specific->m_surface) SDL_FreeSurface(m_specific->m_surface); //if(m_specific->m_mwindow) SDL_DestroyWindow(m_specific->m_mwindow); m_specific->m_texture = 0; m_specific->m_renderer = 0; m_specific->m_surface = 0; //m_specific->m_mwindow = 0; if(m_window_flags & window_resize) { wflags |= SDL_WINDOW_RESIZABLE; } if(m_window_flags & window_fullscreen) { wflags |= SDL_WINDOW_FULLSCREEN; #ifdef __ANDROID__DISABLED width = Android_ScreenWidth; height = Android_ScreenHeight; #endif #ifdef __ANDROID__ if (m_window_flags & window_keep_aspect_ratio) { width = (double)Android_ScreenWidth/Android_ScreenHeight*height; width_factor = (double)width/Android_ScreenWidth; hight_factor = (double)height/Android_ScreenHeight; } #endif } DEBUG_PRINT("platform_support::init %d,%d,%d", width, height, wflags); int numRendDrv = SDL_GetNumRenderDrivers(); DEBUG_PRINT("num rend drv %d\n", numRendDrv); for (int i = 0; i < numRendDrv; i++) { SDL_RendererInfo info; SDL_GetRenderDriverInfo(i, &info); DEBUG_PRINT("index %i, %s, flags %x, texture formats %x\n", i, info.name, info.flags, info.texture_formats[0]); } if (!m_specific->m_mwindow) { m_specific->m_mwindow = SDL_CreateWindow(m_caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, wflags); } if (m_specific->m_mwindow == 0) { ERROR_PRINT( "Unable to create %dx%d %d bpp window: %s\n", width, height, m_bpp, SDL_GetError()); return false; } m_specific->m_surface = SDL_CreateRGBSurface(0, width, height, m_bpp, m_specific->m_rmask, m_specific->m_gmask, m_specific->m_bmask, m_specific->m_amask); DEBUG_PRINT("surface at %p", m_specific->m_surface); if(m_specific->m_surface == 0) { ERROR_PRINT( "Unable to create image buffer %dx%d %d bpp: %s\n", width, height, m_bpp, SDL_GetError()); return false; } m_specific->m_renderer = SDL_CreateRenderer(m_specific->m_mwindow, -1, 0); if(m_specific->m_renderer == 0) { ERROR_PRINT( "Unable to create renderer: %s\n", SDL_GetError()); return false; } { SDL_RendererInfo info; SDL_GetRendererInfo(m_specific->m_renderer, &info); DEBUG_PRINT("Current, %s, flags %x, texture formats %x, %x\n", info.name, info.flags, SDL_PIXELFORMAT_ARGB8888, info.texture_formats[0]); } m_specific->m_texture = SDL_CreateTexture( m_specific->m_renderer, m_specific->m_pformat, SDL_TEXTUREACCESS_STREAMING, width, height); if(m_specific->m_renderer == 0) { ERROR_PRINT( "Unable to create texture: %s\n", SDL_GetError()); return false; } void* pixels; int pitch; if (SDL_LockTexture(m_specific->m_texture, NULL, &pixels, &pitch) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock texture: %s\n", SDL_GetError()); } m_rbuf_window.attach((unsigned char*)pixels, width, height, m_flip_y ? -pitch : pitch); if (!m_specific->m_initialized) { m_initial_width = width; m_initial_height = height; on_init(); m_specific->m_initialized = true; } on_resize(m_rbuf_window.width(), m_rbuf_window.height()); m_specific->m_update_flag = true; return true; }
int main(int argc, char* argv[]) { printf("Play simple video\n"); if(argc < 2) { printf("Miss input video"); return -1; } int ret = -1, i = -1, v_stream_idx = -1; char* vf_path = argv[1]; // f**k, fmt_ctx must be inited by NULL AVFormatContext* fmt_ctx = NULL; AVCodecContext* codec_ctx = NULL; AVCodec* codec; AVFrame * frame; AVPacket packet; av_register_all(); ret = avformat_open_input(&fmt_ctx, vf_path, NULL, NULL); if(ret < 0){ printf("Open video file %s failed \n", vf_path); goto end; } if(avformat_find_stream_info(fmt_ctx, NULL)<0) goto end; av_dump_format(fmt_ctx, 0, vf_path, 0); for(i = 0; i< fmt_ctx->nb_streams; i++) { if(fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { v_stream_idx = i; break; } } if(v_stream_idx == -1) { printf("Cannot find video stream\n"); goto end; } codec_ctx = avcodec_alloc_context3(NULL); avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[v_stream_idx]->codecpar); codec = avcodec_find_decoder(codec_ctx->codec_id); if(codec == NULL){ printf("Unsupported codec for video file\n"); goto end; } if(avcodec_open2(codec_ctx, codec, NULL) < 0){ printf("Can not open codec\n"); goto end; } if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { printf("Could not init SDL due to %s", SDL_GetError()); goto end; } SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *texture; SDL_Event event; SDL_Rect r; window = SDL_CreateWindow("SDL_CreateTexture", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, codec_ctx->width, codec_ctx->height, SDL_WINDOW_RESIZABLE); r.x = 0; r.y = 0; r.w = codec_ctx->width; r.h = codec_ctx->height; renderer = SDL_CreateRenderer(window, -1, 0); // texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, // codec_ctx->width, codec_ctx->height); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, codec_ctx->width, codec_ctx->height); struct SwsContext *sws_ctx = NULL; sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL); frame = av_frame_alloc(); int ret1, ret2; AVFrame* pict; pict = av_frame_alloc(); int numBytes; uint8_t *buffer = NULL; numBytes=avpicture_get_size(AV_PIX_FMT_YUV420P, codec_ctx->width, codec_ctx->height); buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); // required, or bad dst image pointers avpicture_fill((AVPicture *)pict, buffer, AV_PIX_FMT_YUV420P, codec_ctx->width, codec_ctx->height); i = 0; while (1) { SDL_PollEvent(&event); if(event.type == SDL_QUIT) break; ret = av_read_frame(fmt_ctx, &packet); if(ret <0){ continue; } if(packet.stream_index == v_stream_idx) { ret1 = avcodec_send_packet(codec_ctx, &packet); ret2 = avcodec_receive_frame(codec_ctx, frame); if(ret2 < 0 ){ continue; } sws_scale(sws_ctx, (uint8_t const * const *)frame->data, frame->linesize, 0, codec_ctx->height, pict->data, pict->linesize); // if(++i <=5 ){ // save_frame(pict, codec_ctx->width, codec_ctx->height, i); // } SDL_UpdateYUVTexture(texture, &r, pict->data[0], pict->linesize[0], pict->data[1], pict->linesize[1], pict->data[2], pict->linesize[2]); // SDL_UpdateTexture(texture, &r, pict->data[0], pict->linesize[0]); // r.x=rand()%500; // r.y=rand()%500; // SDL_SetRenderTarget(renderer, texture); // SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); SDL_RenderClear(renderer); // SDL_RenderDrawRect(renderer,&r); // SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00); // SDL_RenderFillRect(renderer, &r); // SDL_SetRenderTarget(renderer, NULL); SDL_RenderCopy(renderer, texture, NULL, NULL); // SDL_RenderCopy(renderer, texture, &r, &r); SDL_RenderPresent(renderer); // SDL_Delay(50); } av_packet_unref(&packet); } SDL_DestroyRenderer(renderer); SDL_Quit(); av_frame_free(&frame); avcodec_close(codec_ctx); avcodec_free_context(&codec_ctx); end: avformat_close_input(&fmt_ctx); printf("Shutdown\n"); return 0; }
/* * initialize sdl video * args: * width - video width * height - video height * flags - window flags: * 0- none * 1- fullscreen * 2- maximized * * asserts: * none * * returns: error code */ static int video_init(int width, int height, int flags) { int w = width; int h = height; int32_t my_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; switch(flags) { case 2: my_flags |= SDL_WINDOW_MAXIMIZED; break; case 1: my_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; break; case 0: default: break; } if(verbosity > 0) printf("RENDER: Initializing SDL2 render\n"); if (sdl_window == NULL) /*init SDL*/ { if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0) { fprintf(stderr, "RENDER: Couldn't initialize SDL2: %s\n", SDL_GetError()); return -1; } SDL_SetHint("SDL_HINT_RENDER_SCALE_QUALITY", "1"); sdl_window = SDL_CreateWindow( "Guvcview Video", // window title SDL_WINDOWPOS_UNDEFINED, // initial x position SDL_WINDOWPOS_UNDEFINED, // initial y position w, // width, in pixels h, // height, in pixels my_flags ); if(sdl_window == NULL) { fprintf(stderr, "RENDER: (SDL2) Couldn't open window: %s\n", SDL_GetError()); render_sdl2_clean(); return -2; } int display_index = SDL_GetWindowDisplayIndex(sdl_window); int err = SDL_GetDesktopDisplayMode(display_index, &display_mode); if(!err) { if(verbosity > 0) printf("RENDER: video display %i -> %dx%dpx @ %dhz\n", display_index, display_mode.w, display_mode.h, display_mode.refresh_rate); } else fprintf(stderr, "RENDER: Couldn't determine display mode for video display %i\n", display_index); if(w > display_mode.w) w = display_mode.w; if(h > display_mode.h) h = display_mode.h; if(verbosity > 0) printf("RENDER: setting window size to %ix%i\n", w, h); SDL_SetWindowSize(sdl_window, w, h); } if(verbosity > 2) { /* Allocate a renderer info struct*/ SDL_RendererInfo *rend_info = (SDL_RendererInfo *) malloc(sizeof(SDL_RendererInfo)); if (!rend_info) { fprintf(stderr, "RENDER: Couldn't allocate memory for the renderer info data structure\n"); render_sdl2_clean(); return -5; } /* Print the list of the available renderers*/ printf("\nRENDER: Available SDL2 rendering drivers:\n"); int i = 0; for (i = 0; i < SDL_GetNumRenderDrivers(); i++) { if (SDL_GetRenderDriverInfo(i, rend_info) < 0) { fprintf(stderr, " Couldn't get SDL2 render driver information: %s\n", SDL_GetError()); } else { printf(" %2d: %s\n", i, rend_info->name); printf(" SDL_RENDERER_TARGETTEXTURE [%c]\n", (rend_info->flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' '); printf(" SDL_RENDERER_SOFTWARE [%c]\n", (rend_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' '); printf(" SDL_RENDERER_ACCELERATED [%c]\n", (rend_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' '); printf(" SDL_RENDERER_PRESENTVSYNC [%c]\n", (rend_info->flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' '); } } free(rend_info); } main_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); if(main_renderer == NULL) { fprintf(stderr, "RENDER: (SDL2) Couldn't get a accelerated renderer: %s\n", SDL_GetError()); fprintf(stderr, "RENDER: (SDL2) trying with a software renderer\n"); main_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_SOFTWARE); if(main_renderer == NULL) { fprintf(stderr, "RENDER: (SDL2) Couldn't get a software renderer: %s\n", SDL_GetError()); fprintf(stderr, "RENDER: (SDL2) giving up...\n"); render_sdl2_clean(); return -3; } } if(verbosity > 2) { /* Allocate a renderer info struct*/ SDL_RendererInfo *rend_info = (SDL_RendererInfo *) malloc(sizeof(SDL_RendererInfo)); if (!rend_info) { fprintf(stderr, "RENDER: Couldn't allocate memory for the renderer info data structure\n"); render_sdl2_clean(); return -5; } /* Print the name of the current rendering driver */ if (SDL_GetRendererInfo(main_renderer, rend_info) < 0) { fprintf(stderr, "Couldn't get SDL2 rendering driver information: %s\n", SDL_GetError()); } printf("RENDER: rendering driver in use: %s\n", rend_info->name); printf(" SDL_RENDERER_TARGETTEXTURE [%c]\n", (rend_info->flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' '); printf(" SDL_RENDERER_SOFTWARE [%c]\n", (rend_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' '); printf(" SDL_RENDERER_ACCELERATED [%c]\n", (rend_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' '); printf(" SDL_RENDERER_PRESENTVSYNC [%c]\n", (rend_info->flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' '); free(rend_info); } SDL_RenderSetLogicalSize(main_renderer, width, height); SDL_SetRenderDrawBlendMode(main_renderer, SDL_BLENDMODE_NONE); rending_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_IYUV, /*yuv420p*/ SDL_TEXTUREACCESS_STREAMING, width, height); if(rending_texture == NULL) { fprintf(stderr, "RENDER: (SDL2) Couldn't get a texture for rending: %s\n", SDL_GetError()); render_sdl2_clean(); return -4; } return 0; }
SDL_Surface *ANDROID_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { SDL_PixelFormat format; int bpp1; __android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_SetVideoMode(): application requested mode %dx%d OpenGL %d HW %d", width, height, flags & SDL_OPENGL, flags & SDL_HWSURFACE); if( ! SDL_ANDROID_InsideVideoThread() ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Error: calling %s not from the main thread!", __PRETTY_FUNCTION__); return NULL; } sdl_opengl = (flags & SDL_OPENGL) ? 1 : 0; SDL_ANDROID_sFakeWindowWidth = width; SDL_ANDROID_sFakeWindowHeight = height; current->flags = (flags & SDL_FULLSCREEN) | (flags & SDL_OPENGL) | SDL_DOUBLEBUF | ( flags & SDL_HWSURFACE ); current->w = width; current->h = height; current->pitch = SDL_ANDROID_sFakeWindowWidth * ANDROID_BYTESPERPIXEL; current->pixels = NULL; current->hwdata = NULL; HwSurfaceCount = 0; HwSurfaceList = NULL; DEBUGOUT("ANDROID_SetVideoMode() HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList); if( ! sdl_opengl ) { SDL_DisplayMode mode; SDL_RendererInfo SDL_VideoRendererInfo; SDL_SelectVideoDisplay(0); SDL_VideoWindow = SDL_CreateWindow("", 0, 0, width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL); SDL_memset(&mode, 0, sizeof(mode)); mode.format = SDL_PIXELFORMAT_RGB565; SDL_SetWindowDisplayMode(SDL_VideoWindow, &mode); if (SDL_CreateRenderer(SDL_VideoWindow, -1, 0) < 0) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_SetVideoMode(): Error creating renderer"); return NULL; } SDL_GetRendererInfo(&SDL_VideoRendererInfo); current->hwdata = NULL; if( ! (flags & SDL_HWSURFACE) ) { current->pixels = SDL_malloc(width * height * ANDROID_BYTESPERPIXEL); if ( ! current->pixels ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate buffer for requested mode"); SDL_SetError("Couldn't allocate buffer for requested mode"); return(NULL); } SDL_memset(current->pixels, 0, width * height * ANDROID_BYTESPERPIXEL); current->hwdata = (struct private_hwdata *)SDL_CreateTexture(SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STATIC, width, height); if( !current->hwdata ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate texture for SDL_CurrentVideoSurface"); SDL_free(current->pixels); current->pixels = NULL; SDL_OutOfMemory(); return(NULL); } if( SDL_ANDROID_SmoothVideo ) SDL_SetTextureScaleMode((SDL_Texture *)current->hwdata, SDL_SCALEMODE_SLOW); // Register main video texture to be recreated when needed HwSurfaceCount++; HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) ); HwSurfaceList[HwSurfaceCount-1] = current; DEBUGOUT("ANDROID_SetVideoMode() HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList); } glViewport(0, 0, SDL_ANDROID_sRealWindowWidth, SDL_ANDROID_sRealWindowHeight); glOrthof(0.0, (GLfloat) SDL_ANDROID_sWindowWidth, (GLfloat) SDL_ANDROID_sWindowHeight, 0.0, 0.0, 1.0); } /* Allocate the new pixel format for the screen */ SDL_memset(&format, 0, sizeof(format)); SDL_PixelFormatEnumToMasks( SDL_PIXELFORMAT_RGB565, &bpp1, &format.Rmask, &format.Gmask, &format.Bmask, &format.Amask ); format.BitsPerPixel = bpp1; format.BytesPerPixel = ANDROID_BYTESPERPIXEL; if ( ! SDL_ReallocFormat(current, ANDROID_BITSPERPIXEL, format.Rmask, format.Gmask, format.Bmask, format.Amask) ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate new pixel format for requested mode"); SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } /* Set up the new mode framebuffer */ SDL_CurrentVideoSurface = current; /* We're done */ return(current); }
static int ANDROID_LockHWSurface(_THIS, SDL_Surface *surface) { if( !SDL_ANDROID_InsideVideoThread() ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Error: calling %s not from the main thread!", __PRETTY_FUNCTION__); return -1; } if( surface == SDL_CurrentVideoSurface ) { // Copy pixels from pixelbuffer to video surface - this is slow! Uint16 * row = NULL; int fakeH = SDL_ANDROID_sFakeWindowHeight, fakeW = SDL_ANDROID_sFakeWindowWidth; int realH = SDL_ANDROID_sWindowHeight, realW = SDL_ANDROID_sWindowWidth; int x, y; if( ! SDL_CurrentVideoSurface->pixels ) { glPixelStorei(GL_PACK_ALIGNMENT, 1); SDL_CurrentVideoSurface->pixels = SDL_malloc(SDL_ANDROID_sFakeWindowWidth * SDL_ANDROID_sFakeWindowHeight * ANDROID_BYTESPERPIXEL); if ( ! SDL_CurrentVideoSurface->pixels ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate buffer for SDL_CurrentVideoSurface"); SDL_SetError("Couldn't allocate buffer for SDL_CurrentVideoSurface"); return(-1); } } if( ! SDL_CurrentVideoSurface->hwdata ) { SDL_CurrentVideoSurface->hwdata = (struct private_hwdata *)SDL_CreateTexture(SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STATIC, SDL_ANDROID_sFakeWindowWidth, SDL_ANDROID_sFakeWindowHeight); if( !SDL_CurrentVideoSurface->hwdata ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate texture for SDL_CurrentVideoSurface"); SDL_OutOfMemory(); return(-1); } if( SDL_ANDROID_SmoothVideo ) SDL_SetTextureScaleMode((SDL_Texture *)SDL_CurrentVideoSurface->hwdata, SDL_SCALEMODE_SLOW); // Register main video texture to be recreated when needed HwSurfaceCount++; HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) ); HwSurfaceList[HwSurfaceCount-1] = SDL_CurrentVideoSurface; DEBUGOUT("ANDROID_SetVideoMode() HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList); } row = SDL_stack_alloc(Uint16, SDL_ANDROID_sWindowWidth); for(y=0; y<fakeH; y++) { glReadPixels(0, realH - 1 - (realH * y / fakeH), realW, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, row); for(x=0; x<fakeW; x++) ((Uint16 *)SDL_CurrentVideoSurface->pixels)[ fakeW * y + x ] = row[ x * fakeW / realW ]; } SDL_stack_free(row); } if( !surface->hwdata ) return(-1); // Extra check not necessary /* if( SDL_CurrentVideoSurface->format->BitsPerPixel == surface->format->BitsPerPixel && SDL_CurrentVideoSurface->format->Rmask == surface->format->Rmask && SDL_CurrentVideoSurface->format->Gmask == surface->format->Gmask && SDL_CurrentVideoSurface->format->Bmask == surface->format->Bmask && SDL_CurrentVideoSurface->format->Amask == surface->format->Amask ) return(0); if( this->displayformatalphapixel->BitsPerPixel == surface->format->BitsPerPixel && this->displayformatalphapixel->Rmask == surface->format->Rmask && this->displayformatalphapixel->Gmask == surface->format->Gmask && this->displayformatalphapixel->Bmask == surface->format->Bmask && this->displayformatalphapixel->Amask == surface->format->Amask ) return(0); return(-1); */ return(0); }
unsigned short int NLF_screen_add(unsigned short int sugestPosition, unsigned short int x, unsigned short int y, unsigned short int w, unsigned short int h, NLF_Alignment vAlign, NLF_Alignment hAlign, NLF_bool isStatic) { /* arguments: sugestPosition - the order, between the other screen, where to insert the new screen. x,y - the position where where this screen shall be prited in the APPLICATION WINDOW, understand, not the device screen. w,h - the screen's widh height. verticalAlign,verticalAlign - the alignment this screen will have retated to the appliaction window. isStatic - NLF_True if this screen changes rarely, NLF_False if it is. Note.: leave w or h 0 and the screen will have the size of the Windows, x and y will also be set to 0 and the alignment will be ignored. Note².: leave the alignment 0 or NLF_AlignmentNone to use no alignment. Note³.: any alignment but 0 lead the function to ignore x and y values. This fuction will: Create a new screen and try to put it at the position sugested returns the position where the screen was inserted, or 0 in error case the only way this function can fail is if any allocation errorc ocurrur, then it'll sets an error flag and msg */ unsigned short int aux, ret; NLF_Screen *ps, *psant, *stemp; int ww, hw; if(sugestPosition <= 0) { NLF_error_set_flag(NLF_ErrorCantCreateFile, 1, "in NLF_screen_add 1st argument must be > 0"); return 0; } stemp = (NLF_Screen*) malloc(sizeof(NLF_Screen)); if(stemp == NULL) { printf("Could not craete NLF_Screen\n"); printf("Out of memory\n"); NLF_error_set_flag(NLF_ErrorInsufficientMemory, 1, "Out of memory when creating new screen"); ret = 0; }else{ if(screens != NULL) { //fiding where to insert the screen ps = screens; psant = screens; for(aux = 1; aux < sugestPosition && ps != NULL; aux++) { psant = ps; ps = ps->next; } stemp->position = aux; //fixing the pointers if(aux == sugestPosition) stemp->next = ps; else stemp->next = NULL; if(ps != psant) psant->next = stemp; else screens = stemp; //return set ret = aux; //fixign the positions for(ps = stemp->next; ps != NULL; ps = ps->next) { ps->position++; } }else{ stemp->position = 1; stemp->next = NULL; screens = stemp; ret = 1; } //calculatting position in the windows SDL_GetWindowSize(window, &ww, &hw); if(w == 0 || h == 0) { stemp->dimetions.x = 0; stemp->dimetions.y = 0; stemp->vAlign = NLF_AlignmentNone; stemp->hAlign = NLF_AlignmentNone; stemp->dimetions.w = ww; stemp->dimetions.h = hw; }else{ stemp->dimetions.w = w; stemp->dimetions.h = h; if(vAlign == 0) { stemp->dimetions.x = x; stemp->vAlign = NLF_AlignmentNone; }else{ stemp->vAlign = vAlign; switch(vAlign) { case NLF_AlignmentCenter: stemp->dimetions.y = (hw - stemp->dimetions.h) / 2; break; case NLF_AlignmentUp: stemp->dimetions.y = 0; break; case NLF_AlignmentDown: stemp->dimetions.y = hw - stemp->dimetions.h; break; //Right and Left are not valid alignment for height default: stemp->vAlign = NLF_AlignmentNone; } } if(hAlign == 0) { stemp->dimetions.y = y; stemp->hAlign = NLF_AlignmentNone; }else{ stemp->hAlign = hAlign; switch(hAlign) { case NLF_AlignmentCenter: stemp->dimetions.x = (ww - stemp->dimetions.w) / 2; break; case NLF_AlignmentRight: stemp->dimetions.x = ww - stemp->dimetions.w; break; case NLF_AlignmentLeft: stemp->dimetions.x = 0; break; //Up and Down are not valid alignment for width default: stemp->vAlign = NLF_AlignmentNone; } } stemp->dimetions.w = w; stemp->dimetions.h = h; } //creating the SDL_Texutre stemp->scene = SDL_CreateTexture(window_rederer, SDL_PIXELFORMAT_UNKNOWN, (isStatic == NLF_True) ? SDL_TEXTUREACCESS_STATIC : SDL_TEXTUREACCESS_STREAMING, stemp->dimetions.w, stemp->dimetions.h); if(stemp->scene == NULL) { printf("Could not craete screen's texture\n"); printf("Out of memory\n"); NLF_error_set_flag(NLF_ErrorInsufficientMemory, 1, "Out of memory when creating new screen's texture"); NLF_screen_remove(stemp->position); ret = 0; }else{ } } return ret; }
int main(int argc, char *argv[]) { AVFormatContext *pFormatCtx = NULL; int i, videoStream; AVCodecContext *pCodecCtx = NULL; AVCodecParameters *pCodecParam = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; AVPacket packet; int send_packet, receive_frame; //float aspect_ratio; AVFrame *pict; /* std::unique_ptr<AVFrame, std::function<void(AVFrame*)>> frame_converted{ av_frame_alloc(), [](AVFrame* f){ av_free(f->data[0]); } }; if (av_frame_copy_props(frame_converted.get(), frame_decoded.get()) < 0) { throw std::runtime_error("Copying frame properties"); } if (av_image_alloc( frame_converted->data, frame_converted->linesize, video_decoder_->width(), video_decoder_->height(), video_decoder_->pixel_format(), 1) < 0) { throw std::runtime_error("Allocating picture"); } */ AVDictionary *optionsDict = NULL; struct SwsContext *sws_ctx = NULL; SDL_Texture* pTexture = nullptr; SDL_Window* pWindows = nullptr; SDL_Renderer* pRenderer = nullptr; SDL_Event event; if (argc < 2) { fprintf(stderr, "Usage: test <file>\n"); exit(1); } // Register all formats and codecs av_register_all(); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); exit(1); } // Open video file if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) return -1; // Couldn't open file // Retrieve stream information if (avformat_find_stream_info(pFormatCtx, NULL)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error av_dump_format(pFormatCtx, 0, argv[1], 0); // Find the first video stream videoStream = -1; for (i = 0; i<pFormatCtx->nb_streams; i++) if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { videoStream = i; break; } if (videoStream == -1) return -1; // Didn't find a video stream // Get a pointer to the codec context for the video stream //AVCodecContext *codec is deprecated,so use the codecpar struct (AVCodecParameters) instead. pCodecParam = pFormatCtx->streams[videoStream]->codecpar; //but function avcodec_open2() need pCodecCtx,so copy (AVCodecParameters) pCodecParam to (AVCodecContext) pCodecCtx pCodec = avcodec_find_decoder(pCodecParam->codec_id); // Find the decoder for the video stream if (pCodec == NULL) { fprintf(stderr, "Unsupported codec!\n"); return -1; // Codec not found } pCodecCtx = avcodec_alloc_context3(pCodec); avcodec_parameters_to_context(pCodecCtx, pCodecParam); // Open codec if (avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0) return -1; // Could not open codec // Allocate video frame pFrame = av_frame_alloc(); // Make a screen to put our video #ifndef __DARWIN__ pWindows = SDL_CreateWindow(argv[1],SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,pCodecParam->width, pCodecParam->height,SDL_WINDOW_BORDERLESS|SDL_WINDOW_RESIZABLE); #else screen = SDL_SetVideoMode(pCodecParam->width, pCodecParam->height, 24, 0); #endif if (!pWindows) { fprintf(stderr, "SDL: could not set video mode - exiting\n"); exit(1); } // Allocate a place to put our YUV image on that screen pRenderer = SDL_CreateRenderer(pWindows, -1, 0); if (!pRenderer) { fprintf(stderr, "SDL: could not create renderer - exiting\n"); exit(1); } pTexture = SDL_CreateTexture(pRenderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, pCodecParam->width, pCodecParam->height); sws_ctx = sws_getContext ( pCodecParam->width, pCodecParam->height, (AVPixelFormat)pCodecParam->format, pCodecParam->width, pCodecParam->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL ); pict = av_frame_alloc(); if (pict == nullptr){ exit(1); } if (av_image_alloc(pict->data, pict->linesize, pCodecParam->width, pCodecParam->height, (AVPixelFormat)pCodecParam->format, 1) < 0){ exit(1); } // Read frames and save first five frames to disk i = 0; while (av_read_frame(pFormatCtx, &packet) >= 0) { // Is this a packet from the video stream? if (packet.stream_index == videoStream) { // Decode video frame //avcodec_decode_video2 is deprecated Use avcodec_send_packet() and avcodec_receive_frame(). send_packet = avcodec_send_packet(pCodecCtx, &packet); receive_frame = avcodec_receive_frame(pCodecCtx, pFrame); // Did we get a video frame? if (send_packet == SEND_PACKET_SUCCESS && receive_frame == RECEIVE_FRAME_SUCCESS) { //SDL_LockYUVOverlay(bmp); //SDL_LockTexture(pTexture,NULL,); // Convert the image into YUV format that SDL uses if (av_frame_copy_props(pFrame, pict) < 0) { exit(1); } sws_scale ( sws_ctx, pFrame->data, pFrame->linesize, 0, pCodecParam->height, pict->data, pict->linesize ); //SDL_UnlockYUVOverlay(bmp); SDL_UpdateYUVTexture(pTexture, NULL, pict->data[0], pict->linesize[0], pict->data[1], pict->linesize[1], pict->data[2], pict->linesize[2]); SDL_RenderCopy(pRenderer, pTexture, NULL, NULL); SDL_RenderPresent(pRenderer); } } // Free the packet that was allocated by av_read_frame av_packet_unref(&packet); SDL_PollEvent(&event); switch (event.type) { case SDL_QUIT: SDL_DestroyRenderer(pRenderer); SDL_DestroyTexture(pTexture); SDL_DestroyWindow(pWindows); SDL_Quit(); exit(0); break; default: break; } } // Free the YUV frame av_frame_free(&pFrame); //free pict av_freep(&pict->data[0]); av_frame_free(&pict); // Close the codec avcodec_close(pCodecCtx); // Close the video file avformat_close_input(&pFormatCtx); return 0; }
static void SetVideoMode(void) { int w, h; int x, y; unsigned int rmask, gmask, bmask, amask; int unused_bpp; int window_flags = 0, renderer_flags = 0; SDL_DisplayMode mode; w = window_width; h = window_height; // In windowed mode, the window can be resized while the game is // running. window_flags = SDL_WINDOW_RESIZABLE; // Set the highdpi flag - this makes a big difference on Macs with // retina displays, especially when using small window sizes. window_flags |= SDL_WINDOW_ALLOW_HIGHDPI; if (fullscreen) { if (fullscreen_width == 0 && fullscreen_height == 0) { // This window_flags means "Never change the screen resolution! // Instead, draw to the entire screen by scaling the texture // appropriately". window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { w = fullscreen_width; h = fullscreen_height; window_flags |= SDL_WINDOW_FULLSCREEN; } } // Running without window decorations is potentially useful if you're // playing in three window mode and want to line up three game windows // next to each other on a single desktop. // Deliberately not documented because I'm not sure how useful this is yet. if (M_ParmExists("-borderless")) { window_flags |= SDL_WINDOW_BORDERLESS; } I_GetWindowPosition(&x, &y, w, h); // Create window and renderer contexts. We set the window title // later anyway and leave the window position "undefined". If // "window_flags" contains the fullscreen flag (see above), then // w and h are ignored. if (screen == NULL) { screen = SDL_CreateWindow(NULL, x, y, w, h, window_flags); if (screen == NULL) { I_Error("Error creating window for video startup: %s", SDL_GetError()); } pixel_format = SDL_GetWindowPixelFormat(screen); SDL_SetWindowMinimumSize(screen, SCREENWIDTH, actualheight); I_InitWindowTitle(); I_InitWindowIcon(); } // The SDL_RENDERER_TARGETTEXTURE flag is required to render the // intermediate texture into the upscaled texture. renderer_flags = SDL_RENDERER_TARGETTEXTURE; if (SDL_GetCurrentDisplayMode(video_display, &mode) != 0) { I_Error("Could not get display mode for video display #%d: %s", video_display, SDL_GetError()); } // Turn on vsync if we aren't in a -timedemo if (!singletics && mode.refresh_rate > 0) { renderer_flags |= SDL_RENDERER_PRESENTVSYNC; } if (force_software_renderer) { renderer_flags |= SDL_RENDERER_SOFTWARE; renderer_flags &= ~SDL_RENDERER_PRESENTVSYNC; } if (renderer != NULL) { SDL_DestroyRenderer(renderer); // all associated textures get destroyed texture = NULL; texture_upscaled = NULL; } renderer = SDL_CreateRenderer(screen, -1, renderer_flags); if (renderer == NULL) { I_Error("Error creating renderer for screen window: %s", SDL_GetError()); } // Important: Set the "logical size" of the rendering context. At the same // time this also defines the aspect ratio that is preserved while scaling // and stretching the texture into the window. if (aspect_ratio_correct || integer_scaling) { SDL_RenderSetLogicalSize(renderer, SCREENWIDTH, actualheight); } // Force integer scales for resolution-independent rendering. #if SDL_VERSION_ATLEAST(2, 0, 5) SDL_RenderSetIntegerScale(renderer, integer_scaling); #endif // Blank out the full screen area in case there is any junk in // the borders that won't otherwise be overwritten. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); // Create the 8-bit paletted and the 32-bit RGBA screenbuffer surfaces. if (screenbuffer != NULL) { SDL_FreeSurface(screenbuffer); screenbuffer = NULL; } if (screenbuffer == NULL) { screenbuffer = SDL_CreateRGBSurface(0, SCREENWIDTH, SCREENHEIGHT, 8, 0, 0, 0, 0); SDL_FillRect(screenbuffer, NULL, 0); } // Format of argbbuffer must match the screen pixel format because we // import the surface data into the texture. if (argbbuffer != NULL) { SDL_FreeSurface(argbbuffer); argbbuffer = NULL; } if (argbbuffer == NULL) { SDL_PixelFormatEnumToMasks(pixel_format, &unused_bpp, &rmask, &gmask, &bmask, &amask); argbbuffer = SDL_CreateRGBSurface(0, SCREENWIDTH, SCREENHEIGHT, 32, rmask, gmask, bmask, amask); SDL_FillRect(argbbuffer, NULL, 0); } if (texture != NULL) { SDL_DestroyTexture(texture); } // Set the scaling quality for rendering the intermediate texture into // the upscaled texture to "nearest", which is gritty and pixelated and // resembles software scaling pretty well. SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); // Create the intermediate texture that the RGBA surface gets loaded into. // The SDL_TEXTUREACCESS_STREAMING flag means that this texture's content // is going to change frequently. texture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, SCREENWIDTH, SCREENHEIGHT); // Initially create the upscaled texture for rendering to screen CreateUpscaledTexture(true); }
static void CreateUpscaledTexture(boolean force) { int w, h; int h_upscale, w_upscale; static int h_upscale_old, w_upscale_old; SDL_Texture *new_texture, *old_texture; // Get the size of the renderer output. The units this gives us will be // real world pixels, which are not necessarily equivalent to the screen's // window size (because of highdpi). if (SDL_GetRendererOutputSize(renderer, &w, &h) != 0) { I_Error("Failed to get renderer output size: %s", SDL_GetError()); } // When the screen or window dimensions do not match the aspect ratio // of the texture, the rendered area is scaled down to fit. Calculate // the actual dimensions of the rendered area. if (w * actualheight < h * SCREENWIDTH) { // Tall window. h = w * actualheight / SCREENWIDTH; } else { // Wide window. w = h * SCREENWIDTH / actualheight; } // Pick texture size the next integer multiple of the screen dimensions. // If one screen dimension matches an integer multiple of the original // resolution, there is no need to overscale in this direction. w_upscale = (w + SCREENWIDTH - 1) / SCREENWIDTH; h_upscale = (h + SCREENHEIGHT - 1) / SCREENHEIGHT; // Minimum texture dimensions of 320x200. if (w_upscale < 1) { w_upscale = 1; } if (h_upscale < 1) { h_upscale = 1; } LimitTextureSize(&w_upscale, &h_upscale); // Create a new texture only if the upscale factors have actually changed. if (h_upscale == h_upscale_old && w_upscale == w_upscale_old && !force) { return; } h_upscale_old = h_upscale; w_upscale_old = w_upscale; // Set the scaling quality for rendering the upscaled texture to "linear", // which looks much softer and smoother than "nearest" but does a better // job at downscaling from the upscaled texture to screen. SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); new_texture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_TARGET, w_upscale*SCREENWIDTH, h_upscale*SCREENHEIGHT); old_texture = texture_upscaled; texture_upscaled = new_texture; if (old_texture != NULL) { SDL_DestroyTexture(old_texture); } }
void * thread_routine(void *arg) { struct mypara *recv_para = (struct mypara *)arg;; //recv para data AVFormatContext *pFormatCtx; int i, videoindex; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame, *pFrameYUV; unsigned char *out_buffer; AVPacket *packet; int y_size; int ret, got_picture; struct SwsContext *img_convert_ctx; //char filepath[]="bigbuckbunny_480x272.h265"; char filepath[] = "rtsp://192.168.131.4/0"; //SDL--------------------------- int screen_w = 0, screen_h = 0; SDL_Window *screen; SDL_Renderer* sdlRenderer; SDL_Texture* sdlTexture; SDL_Rect sdlRect, sdlRect_tmp; FILE *fp_yuv; //av_register_all(); //avformat_network_init(); pFormatCtx = avformat_alloc_context(); if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0){ printf("Couldn't open input stream.\n"); return -1; } if (avformat_find_stream_info(pFormatCtx, NULL) < 0){ printf("Couldn't find stream information.\n"); return -1; } videoindex = -1; for (i = 0; i < pFormatCtx->nb_streams; i++) if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){ videoindex = i; break; } if (videoindex == -1){ printf("Didn't find a video stream.\n"); return -1; } pCodecCtx = pFormatCtx->streams[videoindex]->codec; pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL){ printf("Codec not found.\n"); return -1; } //pthread_mutex_lock(&mutex); if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){ printf("Could not open codec.\n"); return -1; } //pthread_mutex_unlock(&mutex); pFrame = av_frame_alloc(); pFrameYUV = av_frame_alloc(); out_buffer = (unsigned char *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1)); av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1); packet = (AVPacket *)av_malloc(sizeof(AVPacket)); //Output Info----------------------------- printf("--------------- File Information ----------------\n"); av_dump_format(pFormatCtx, 0, filepath, 0); printf("-------------------------------------------------\n"); img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); #if OUTPUT_YUV420P fp_yuv = fopen("output.yuv", "wb+"); #endif //if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { // printf( "Could not initialize SDL - %s\n", SDL_GetError()); // return -1; //} screen_w = pCodecCtx->width; screen_h = pCodecCtx->height; //SDL 2.0 Support for multiple windows //screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, // screen_w*2, screen_h, // SDL_WINDOW_OPENGL); screen = (*recv_para).screen; //get the screen if (!screen) { printf("SDL: could not create window - exiting:%s\n", SDL_GetError()); return -1; } //sdlRenderer = SDL_CreateRenderer(screen, -1, 0); sdlRenderer = (*recv_para).sdlRenderer;//get the sdlRenderer //IYUV: Y + U + V (3 planes) //YV12: Y + V + U (3 planes) pthread_mutex_lock(&mutex); sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height); pthread_mutex_unlock(&mutex); //temp sdlRect for render copy sdlRect_tmp.x = 0; sdlRect_tmp.y = 0; sdlRect_tmp.w = screen_w; sdlRect_tmp.h = screen_h; //four rect in one line // total 4*4 = 16 rect sdlRect.x = 0 + screen_w / 2 * ((*recv_para).id % 4); sdlRect.y = 0 + screen_h / 2 * ((*recv_para).id / 4); sdlRect.w = screen_w / 2; sdlRect.h = screen_h / 2; //SDL End---------------------- while (thread_exit && av_read_frame(pFormatCtx, packet) >= 0){ if (packet->stream_index == videoindex){ ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if (ret < 0){ printf("Decode Error.\n"); return -1; } if (got_picture){ //printf("id:%d\n",(*recv_para).id); //打印线程id //printf("x_pos:%d y_pos:%d\n",sdlRect.x,sdlRect.y); //print rect position sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); #if OUTPUT_YUV420P y_size = pCodecCtx->width*pCodecCtx->height; fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv); //Y fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv); //U fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv); //V #endif //SDL--------------------------- #if 0 SDL_UpdateTexture(sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]); #else pthread_mutex_lock(&mutex); //mutex or SEGFAULT SDL_UpdateYUVTexture(sdlTexture, &sdlRect_tmp,//sdl tmp pFrameYUV->data[0], pFrameYUV->linesize[0], pFrameYUV->data[1], pFrameYUV->linesize[1], pFrameYUV->data[2], pFrameYUV->linesize[2]); #endif //SDL_RenderClear( sdlRenderer ); SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); //SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect1); SDL_RenderPresent(sdlRenderer); pthread_mutex_unlock(&mutex); //SDL End----------------------- //Delay 40ms //SDL_Delay(40); } } av_free_packet(packet); } //flush decoder //FIX: Flush Frames remained in Codec while (1) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if (ret < 0) break; if (!got_picture) break; sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); #if OUTPUT_YUV420P int y_size = pCodecCtx->width*pCodecCtx->height; fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv); //Y fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv); //U fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv); //V #endif //SDL--------------------------- SDL_UpdateTexture(sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0]); SDL_RenderClear(sdlRenderer); SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); SDL_RenderPresent(sdlRenderer); //SDL End----------------------- //Delay 40ms //SDL_Delay(40); } sws_freeContext(img_convert_ctx); #if OUTPUT_YUV420P fclose(fp_yuv); #endif SDL_RenderClear(sdlRenderer); SDL_Quit(); av_frame_free(&pFrameYUV); av_frame_free(&pFrame); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); }
bool init() { //Initialization flag bool success = true; //Initialize SDL if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) { printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() ); success = false; } else { //Set texture filtering to linear if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) ) { printf( "Warning: Linear texture filtering not enabled!" ); } //Create window gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if( gWindow == nullptr ) { printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() ); success = false; } else { //Create renderer for window gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED ); if( gRenderer == nullptr ) { printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() ); success = false; } else { //Initialize renderer color SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); texture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, CHIP8_W,CHIP8_H); if (!texture) { printf("texture could not initialize!\n"); success = false; } else { //Initialize SDL_audio SDL_AudioSpec spec; spec.freq = 44100; spec.format = AUDIO_S16SYS; spec.channels = 2; spec.samples = spec.freq / 20; // 0.05 seconds of latency spec.callback = [] (void*, Uint8* stream, int len) { // Generate square wave short* target = (short*)stream; while(len > 0 && !AudioQueue.empty()) { auto& data = AudioQueue.front(); for(; len && data.first; target += 2, len -= 4, --data.first) target[0] = target[1] = data.second*300*((len&128)-64); if(!data.first) AudioQueue.pop_front(); } }; if(SDL_OpenAudio(&spec, &obtained) != 0 ) { printf( "SDL_audio could not initialize! SDL_mixer Error: %s\n", SDL_GetError()); success = false; } SDL_PauseAudio(0); } } } } return success; }
int init(int width, int height) { //Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); return 1; } //Create window SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN, &window, &renderer); //set up screen texture screen = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); //load image into surface SDL_Surface* tmp = SDL_LoadBMP("260.bmp"); if (tmp == NULL) { printf ("coild not load image file SDL_Error: %s\n", SDL_GetError()); return 1; } char_map = SDL_ConvertSurfaceFormat(tmp, SDL_PIXELFORMAT_RGBA8888, 0); SDL_FreeSurface(tmp); c_map = SDL_CreateTextureFromSurface(renderer, char_map); if (window == NULL) { printf ("Window could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } if (c_map == NULL) { printf ("Texture could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } if (screen == NULL) { printf ("Texture could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } if (char_map == NULL) { printf ("Error allocating surface %s\n", SDL_GetError()); return 1; } return 0; }
int main(int, char**) { if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL_Init Error: %s\n", SDL_GetError()); return 1; } SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 800, 400, SDL_WINDOW_SHOWN); if (win == nullptr) { printf("SDL_CreateWindow Error: %s\n", SDL_GetError()); SDL_Quit(); return 1; } SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); assert(ren); SDL_Texture* texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, WIDTH, HEIGHT); assert(texture); OledSim oled(WIDTH, HEIGHT); Renderer display; display.Attach(WIDTH, HEIGHT, oled.Buffer()); SDL_SetRenderDrawColor(ren, 128, 128, 128, 255); UIRenderData data; data.volume = 2; data.power = 3; data.mVolts = 3219; data.fontName = "Bespin"; DotStarUI::Test(); SDL_Event e; int scale = 4; int mode = 0; int count = 0; uint32_t lastUpdate = SDL_GetTicks(); const char* FONT_NAMES[8] = { "Bespin", "Vader", "Vader", "ObiAni", "Bespin", "JainaSw", "Maul", "MAUL" }; uint8_t COLORS[8] = { 0, 255, 100, 200, 255, 0, 20, 120 }; data.color.set(COLORS[0], COLORS[1], COLORS[2]); int palette = 0; while (true) { SDL_PollEvent(&e); if (e.type == SDL_QUIT) { break; } else if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym >= SDLK_1 && e.key.keysym.sym <= SDLK_8) { scale = e.key.keysym.sym - SDLK_0; } else if (e.key.keysym.sym == SDLK_SPACE) { mode = (mode + 1) % Sketcher::NUM_MODES; } else if (e.key.keysym.sym == SDLK_p) { data.power = (data.power + 1) % 5; data.mVolts = 3000 + data.power * 111; } else if (e.key.keysym.sym == SDLK_v) { data.volume = (data.volume + 1) % 5; } else if (e.key.keysym.sym == SDLK_c) { palette = (palette + 1) % 8; data.color.set(COLORS[(palette * 3 + 0) % 8], COLORS[(palette * 2 + 1) % 8], COLORS[(palette * 5 + 2) % 8]); data.fontName = FONT_NAMES[palette]; data.palette = palette; } } uint32_t t = SDL_GetTicks(); if (t - lastUpdate > 100) { lastUpdate = t; uint8_t value = int(127.8 * (sin(count * 0.2) + 1.0)); ++count; sketcher.Push(value); sketcher.Draw(&display, 100, mode, &data); } oled.Commit(); const SDL_Rect src = { 0, 0, WIDTH, HEIGHT }; SDL_Rect winRect; SDL_GetWindowSize(win, &winRect.w, &winRect.h); const int w = WIDTH * scale; const int h = HEIGHT * scale; SDL_Rect dst = { (winRect.w - w) / 2, (winRect.h - h) / 2, w, h }; SDL_UpdateTexture(texture, NULL, oled.Pixels(), WIDTH * 4); SDL_RenderClear(ren); SDL_RenderCopy(ren, texture, &src, &dst); SDL_RenderPresent(ren); } SDL_Quit(); return 0; }
void displayThread(void) { #ifdef LOCAL_DISPLAY SDL_Window *win = NULL; SDL_Renderer *renderer = NULL; SDL_Texture *texture = NULL; SDL_Event e; int kill = FALSE; char resolution[20] = {0}; #else FILE *fp = NULL; #endif char *lineseeker = NULL; int linecnt = 0; int prevline = 0; int prevframe = 0; int flag = 0; VIDEO_DATA *popped = NULL; int frame_cnt = 0; popped = (VIDEO_DATA *)calloc(1, sizeof(VIDEO_DATA)); popped->packetbuff = (char *)calloc(1, packetsize - VALID_DATA); #ifdef LOCAL_DISPLAY SDL_Init(SDL_INIT_VIDEO); snprintf(resolution, 20, "Receiver : %dx%d", g_capture_width, g_capture_height); win = SDL_CreateWindow(resolution, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, g_capture_width, g_capture_height, SDL_WINDOW_RESIZABLE); renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YUY2, SDL_TEXTUREACCESS_STREAMING, g_capture_width, g_capture_height); #else fp = fopen(g_filename, "wb"); #endif while(!KillDisplayThread) { if((sizeofqueue() > 0) && (g_displaybuff)) { poppacket(popped); } else { continue; } if(flag == 0) { g_skipframe = popped->frame_num; prevframe = popped->frame_num; pr_dbg("Frame %d is going to skip\n",g_skipframe); flag = 1; } #if 0 /* check SDL event if any */ if (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { break; } else if(e.key.type == SDL_KEYUP) { switch(e.key.keysym.sym) { case SDLK_ESCAPE: kill = TRUE; break; default: break; } if(kill) break; } } #endif if(g_skipframe == popped->frame_num) { continue; } if(popped->line_num == FIRST_LINE) { lineseeker = g_displaybuff; memcpy(lineseeker, popped->packetbuff, packetsize - VALID_DATA); lineseeker += (packetsize - VALID_DATA); linecnt ++; prevline = FIRST_LINE; } else if(popped->line_num == g_last_line) { memcpy(lineseeker, popped->packetbuff, packetsize - VALID_DATA); linecnt++; if(linecnt == g_last_line) { #ifdef LOCAL_DISPLAY /* display frame*/ SDL_UpdateTexture(texture, 0, g_displaybuff, g_capture_width*BPP); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); #else /* save frame */ fwrite(g_displaybuff, buffsize, 1, fp); if(frame_cnt++ > no_of_frames_to_save) { fclose(fp); exit(0); } #endif } lineseeker = g_displaybuff; linecnt = 0; prevline = 0; } else if(prevframe == popped->frame_num) { if(popped->line_num == prevline + 1) { memcpy(lineseeker, popped->packetbuff, packetsize - VALID_DATA); lineseeker += packetsize - VALID_DATA; linecnt ++; } prevline = popped->line_num; } else { memset(g_displaybuff, 0, buffsize); lineseeker = g_displaybuff; linecnt = 0; g_skipframe = popped->frame_num; prevline = popped->line_num; } if(prevframe != popped->frame_num) { prevframe = popped->frame_num; } } #ifdef LOCAL_DISPLAY SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(win); SDL_Quit(); #else fclose(fp); #endif free(popped->packetbuff); free(popped); pr_dbg("Exiting Application\n"); exit(0); }
int SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) { int w, h; Uint32 format; int access; void *pixels; int pitch; /* We can't resize something we don't have... */ if (!SDL_VideoWindow) { return -1; } /* We probably have to recreate the window in fullscreen mode */ if (flags & SDL_FULLSCREEN) { return -1; } /* I don't think there's any change we can gracefully make in flags */ if (flags != SDL_VideoFlags) { return -1; } /* Resize the window */ SDL_GetWindowSize(SDL_VideoWindow, &w, &h); if (w != width || h != height) { SDL_SetWindowSize(SDL_VideoWindow, width, height); } /* If we're in OpenGL mode, just resize the stub surface and we're done! */ if (flags & SDL_OPENGL) { SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; return 0; } /* Destroy the screen texture and recreate it */ SDL_QueryTexture(SDL_VideoTexture, &format, &access, &w, &h); SDL_DestroyTexture(SDL_VideoTexture); SDL_VideoTexture = SDL_CreateTexture(format, access, width, height); if (!SDL_VideoTexture) { return -1; } SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; if (SDL_QueryTexturePixels(SDL_VideoTexture, &pixels, &pitch) == 0) { SDL_VideoSurface->pixels = pixels; SDL_VideoSurface->pitch = pitch; } else { SDL_CalculatePitch(SDL_VideoSurface); SDL_VideoSurface->pixels = SDL_realloc(SDL_VideoSurface->pixels, SDL_VideoSurface->h * SDL_VideoSurface->pitch); } SDL_SetClipRect(SDL_VideoSurface, NULL); SDL_InvalidateMap(SDL_VideoSurface->map); if (SDL_ShadowSurface) { SDL_ShadowSurface->w = width; SDL_ShadowSurface->h = height; SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); SDL_ShadowSurface->pixels = SDL_realloc(SDL_ShadowSurface->pixels, SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); SDL_SetClipRect(SDL_ShadowSurface, NULL); SDL_InvalidateMap(SDL_ShadowSurface->map); } ClearVideoSurface(); return 0; }
static texture_info *texture_create(sdl_window_info *window, const render_texinfo *texsource, quad_setup_data *setup, UINT32 flags) { sdl_info *sdl = (sdl_info *) window->dxdata; texture_info *texture; // allocate a new texture texture = (texture_info *) osd_malloc(sizeof(*texture)); memset(texture, 0, sizeof(*texture)); // fill in the core data texture->hash = texture_compute_hash(texsource, flags); texture->flags = flags; texture->texinfo = *texsource; texture->texinfo.seqid = -1; // force set data texture->is_rotated = FALSE; texture->setup = *setup; texture->sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags)); switch (PRIMFLAG_GET_TEXFORMAT(flags)) { case TEXFORMAT_ARGB32: texture->format = SDL_TEXFORMAT_ARGB32; break; case TEXFORMAT_RGB32: texture->format = texsource->palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32; break; case TEXFORMAT_PALETTE16: texture->format = SDL_TEXFORMAT_PALETTE16; break; case TEXFORMAT_PALETTEA16: texture->format = SDL_TEXFORMAT_PALETTE16A; break; case TEXFORMAT_YUY16: texture->format = texsource->palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16; break; default: mame_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags)); } texture->rawwidth = texsource->width; texture->rawheight = texsource->height; if (setup->rotwidth != texture->rawwidth || setup->rotheight != texture->rawheight || setup->dudx < 0 ) texture->is_rotated = TRUE; else texture->is_rotated = FALSE; //texture->sdl_access = SDL_TEXTUREACCESS_STATIC; texture->sdl_access = SDL_TEXTUREACCESS_STREAMING; // Watch out for 0x0 textures ... if (!texture->setup.rotwidth || !texture->setup.rotheight) mame_printf_warning("Trying to create texture with zero dim\n"); // compute the size texture->copyinfo = texture_compute_size_type(sdl->sdl_renderer, texsource, texture, flags); texture->texture_id = SDL_CreateTexture(sdl->sdl_renderer, texture->copyinfo->dst_fmt, texture->sdl_access, texture->setup.rotwidth, texture->setup.rotheight); if (!texture->texture_id) mame_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", texture->setup.rotwidth, texture->setup.rotheight, texture->copyinfo->dstname, SDL_GetError()); if ( (texture->copyinfo->func != NULL) && (texture->sdl_access == SDL_TEXTUREACCESS_STATIC)) { texture->pixels = osd_malloc_array(texture->setup.rotwidth * texture->setup.rotheight * texture->copyinfo->dst_bpp); texture->pixels_own=TRUE; } /* add us to the texture list */ texture->next = sdl->texlist; sdl->texlist = texture; texture->last_access = osd_ticks(); return texture; }
SDL_Surface * SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) { SDL_DisplayMode desktop_mode; SDL_DisplayMode mode; int window_x = SDL_WINDOWPOS_UNDEFINED; int window_y = SDL_WINDOWPOS_UNDEFINED; Uint32 window_flags; Uint32 desktop_format; Uint32 desired_format; Uint32 surface_flags; if (!SDL_GetVideoDevice()) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { return NULL; } } /* See if we can simply resize the existing window and surface */ if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) { return SDL_PublicSurface; } /* Destroy existing window */ SDL_PublicSurface = NULL; if (SDL_ShadowSurface) { SDL_FreeSurface(SDL_ShadowSurface); SDL_ShadowSurface = NULL; } if (SDL_VideoSurface) { SDL_DelPaletteWatch(SDL_VideoSurface->format->palette, SDL_VideoPaletteChanged, NULL); SDL_FreeSurface(SDL_VideoSurface); SDL_VideoSurface = NULL; } if (SDL_VideoContext) { /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */ SDL_GL_DeleteContext(SDL_VideoContext); SDL_VideoContext = NULL; } if (SDL_VideoWindow) { SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y); SDL_DestroyWindow(SDL_VideoWindow); } /* Set up the event filter */ if (!SDL_GetEventFilter(NULL, NULL)) { SDL_SetEventFilter(SDL_CompatEventFilter, NULL); } /* Create a new window */ window_flags = SDL_WINDOW_SHOWN; if (flags & SDL_FULLSCREEN) { window_flags |= SDL_WINDOW_FULLSCREEN; } if (flags & SDL_OPENGL) { window_flags |= SDL_WINDOW_OPENGL; } if (flags & SDL_RESIZABLE) { window_flags |= SDL_WINDOW_RESIZABLE; } if (flags & SDL_NOFRAME) { window_flags |= SDL_WINDOW_BORDERLESS; } GetEnvironmentWindowPosition(width, height, &window_x, &window_y); SDL_SetFullscreenDisplayMode(NULL); SDL_VideoWindow = SDL_CreateWindow(wm_title, window_x, window_y, width, height, window_flags); if (!SDL_VideoWindow) { return NULL; } SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon); window_flags = SDL_GetWindowFlags(SDL_VideoWindow); surface_flags = 0; if (window_flags & SDL_WINDOW_FULLSCREEN) { surface_flags |= SDL_FULLSCREEN; } if (window_flags & SDL_WINDOW_OPENGL) { surface_flags |= SDL_OPENGL; } if (window_flags & SDL_WINDOW_RESIZABLE) { surface_flags |= SDL_RESIZABLE; } if (window_flags & SDL_WINDOW_BORDERLESS) { surface_flags |= SDL_NOFRAME; } /* Set up the desired display mode */ SDL_GetDesktopDisplayMode(&desktop_mode); desktop_format = desktop_mode.format; if (desktop_format && ((flags & SDL_ANYFORMAT) || (bpp == SDL_BITSPERPIXEL(desktop_format)))) { desired_format = desktop_format; } else { switch (bpp) { case 0: if (desktop_format) { desired_format = desktop_format; } else { desired_format = SDL_PIXELFORMAT_RGB888; } bpp = SDL_BITSPERPIXEL(desired_format); break; case 8: desired_format = SDL_PIXELFORMAT_INDEX8; break; case 15: desired_format = SDL_PIXELFORMAT_RGB555; break; case 16: desired_format = SDL_PIXELFORMAT_RGB565; break; case 24: desired_format = SDL_PIXELFORMAT_RGB24; break; case 32: desired_format = SDL_PIXELFORMAT_RGB888; break; default: SDL_SetError("Unsupported bpp in SDL_SetVideoMode()"); return NULL; } } mode.format = desired_format; mode.w = width; mode.h = height; mode.refresh_rate = 0; /* Set the desired display mode */ if (flags & SDL_FULLSCREEN) { if (SDL_SetFullscreenDisplayMode(&mode) < 0) { return NULL; } } /* If we're in OpenGL mode, just create a stub surface and we're done! */ if (flags & SDL_OPENGL) { SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow); if (!SDL_VideoContext) { return NULL; } if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) { return NULL; } SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0); if (!SDL_VideoSurface) { return NULL; } SDL_VideoSurface->flags |= surface_flags; SDL_PublicSurface = SDL_VideoSurface; return SDL_PublicSurface; } /* Create a renderer for the window */ if (SDL_CreateRenderer (SDL_VideoWindow, -1, SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0) { return NULL; } SDL_GetRendererInfo(&SDL_VideoRendererInfo); /* Create a texture for the screen surface */ SDL_VideoTexture = SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_STREAMING, width, height); if (!SDL_VideoTexture) { SDL_VideoTexture = SDL_CreateTexture(desktop_format, SDL_TEXTUREACCESS_STREAMING, width, height); } if (!SDL_VideoTexture) { return NULL; } /* Create the screen surface */ SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture); if (!SDL_VideoSurface) { return NULL; } SDL_VideoSurface->flags |= surface_flags; /* Set a default screen palette */ if (SDL_VideoSurface->format->palette) { SDL_VideoSurface->flags |= SDL_HWPALETTE; SDL_DitherColors(SDL_VideoSurface->format->palette->colors, SDL_VideoSurface->format->BitsPerPixel); SDL_AddPaletteWatch(SDL_VideoSurface->format->palette, SDL_VideoPaletteChanged, SDL_VideoSurface); SDL_SetPaletteColors(SDL_VideoSurface->format->palette, SDL_VideoSurface->format->palette->colors, 0, SDL_VideoSurface->format->palette->ncolors); } /* Create a shadow surface if necessary */ if ((bpp != SDL_VideoSurface->format->BitsPerPixel) && !(flags & SDL_ANYFORMAT)) { SDL_ShadowSurface = SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0); if (!SDL_ShadowSurface) { return NULL; } SDL_ShadowSurface->flags |= surface_flags; /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */ if (SDL_ShadowSurface->format->palette) { SDL_ShadowSurface->flags |= SDL_HWPALETTE; if (SDL_VideoSurface->format->palette) { SDL_SetSurfacePalette(SDL_ShadowSurface, SDL_VideoSurface->format->palette); } else { SDL_DitherColors(SDL_ShadowSurface->format->palette->colors, SDL_ShadowSurface->format->BitsPerPixel); } SDL_AddPaletteWatch(SDL_ShadowSurface->format->palette, SDL_VideoPaletteChanged, SDL_ShadowSurface); } } SDL_PublicSurface = (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface); SDL_VideoFlags = flags; ClearVideoSurface(); SetupScreenSaver(flags); /* We're finally done! */ return SDL_PublicSurface; }
bool yuv_set_video_mode_size(struct graphics_data *graphics, int width, int height, int depth, bool fullscreen, bool resize, int yuv_width, int yuv_height) { struct yuv_render_data *render_data = graphics->render_data; #if SDL_VERSION_ATLEAST(2,0,0) render_data->window = SDL_CreateWindow("MegaZeux", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, sdl_flags(depth, fullscreen, resize)); if(!render_data->window) { warn("Failed to create window: %s\n", SDL_GetError()); goto err_free; } render_data->renderer = SDL_CreateRenderer(render_data->window, -1, SDL_RENDERER_ACCELERATED); if(!render_data->renderer) { render_data->renderer = SDL_CreateRenderer(render_data->window, -1, SDL_RENDERER_SOFTWARE); if(!render_data->renderer) { warn("Failed to create renderer: %s\n", SDL_GetError()); goto err_destroy_window; } warn("Accelerated renderer not available. Overlay will be SLOW!\n"); } render_data->screen = SDL_GetWindowSurface(render_data->window); if(!render_data->screen) { /* Sometimes the accelerated renderer will be created, but doesn't * allow the surface to be returned. This seems like an SDL bug, but * we'll work around it here. */ SDL_DestroyRenderer(render_data->renderer); render_data->renderer = SDL_CreateRenderer(render_data->window, -1, SDL_RENDERER_SOFTWARE); if(!render_data->renderer) { warn("Failed to create renderer: %s\n", SDL_GetError()); goto err_destroy_window; } render_data->screen = SDL_GetWindowSurface(render_data->window); if(!render_data->screen) { warn("Failed to get window surface: %s\n", SDL_GetError()); goto err_destroy_renderer; } warn("Accelerated renderer not available. Overlay will be SLOW!\n"); } if(render_data->screen->format->BitsPerPixel != 32) { warn("Failed to get 32-bit window surface\n"); goto err_destroy_renderer; } render_data->is_yuy2 = true; render_data->texture = SDL_CreateTexture(render_data->renderer, SDL_PIXELFORMAT_YUY2, SDL_TEXTUREACCESS_STREAMING, yuv_width, yuv_height); if(!render_data->texture) { render_data->is_yuy2 = false; render_data->texture = SDL_CreateTexture(render_data->renderer, SDL_PIXELFORMAT_UYVY, SDL_TEXTUREACCESS_STREAMING, yuv_width, yuv_height); if(!render_data->texture) { warn("Failed to create YUV texture: %s\n", SDL_GetError()); goto err_destroy_renderer; } } #else // !SDL_VERSION_ATLEAST(2,0,0) // the YUV renderer _requires_ 32bit colour render_data->screen = SDL_SetVideoMode(width, height, 32, sdl_flags(depth, fullscreen, resize) | SDL_ANYFORMAT); if(!render_data->screen) goto err_free; // try with a YUY2 pixel format first render_data->overlay = SDL_CreateYUVOverlay(yuv_width, yuv_height, SDL_YUY2_OVERLAY, render_data->screen); // didn't work, try with a UYVY pixel format next if(!render_data->overlay) render_data->overlay = SDL_CreateYUVOverlay(yuv_width, yuv_height, SDL_UYVY_OVERLAY, render_data->screen); // failed to create an overlay if(!render_data->overlay) goto err_free; render_data->is_yuy2 = render_data->overlay->format == SDL_YUY2_OVERLAY; #endif // !SDL_VERSION_ATLEAST(2,0,0) return true; #if SDL_VERSION_ATLEAST(2,0,0) err_destroy_renderer: SDL_DestroyRenderer(render_data->renderer); render_data->renderer = NULL; err_destroy_window: SDL_DestroyWindow(render_data->window); render_data->window = NULL; #endif // SDL_VERSION_ATLEAST(2,0,0) err_free: free(render_data); return false; }
static int setup_sdl_video( consumer_sdl self ) { int error = 0; int sdl_flags = SDL_WINDOW_RESIZABLE; int texture_format = SDL_PIXELFORMAT_YUY2; // Skip this if video is disabled. int video_off = mlt_properties_get_int( self->properties, "video_off" ); int preview_off = mlt_properties_get_int( self->properties, "preview_off" ); if ( video_off || preview_off ) return error; if (!SDL_WasInit(SDL_INIT_VIDEO)) { pthread_mutex_lock( &mlt_sdl_mutex ); int ret = SDL_Init( SDL_INIT_VIDEO ); pthread_mutex_unlock( &mlt_sdl_mutex ); if ( ret < 0 ) { mlt_log_error( MLT_CONSUMER_SERVICE(&self->parent), "Failed to initialize SDL: %s\n", SDL_GetError() ); return -1; } } #ifdef MLT_IMAGE_FORMAT int image_format = mlt_properties_get_int( self->properties, "mlt_image_format" ); if ( image_format ) switch ( image_format ) { case mlt_image_rgb24: texture_format = SDL_PIXELFORMAT_RGB24; break; case mlt_image_rgb24a: texture_format = SDL_PIXELFORMAT_ABGR8888; break; case mlt_image_yuv420p: texture_format = SDL_PIXELFORMAT_IYUV; break; case mlt_image_yuv422: texture_format = SDL_PIXELFORMAT_YUY2; break; default: mlt_log_error( MLT_CONSUMER_SERVICE(&self->parent), "Invalid image format %s\n", mlt_image_format_name( image_format ) ); return -1; } #endif if ( mlt_properties_get_int( self->properties, "fullscreen" ) ) { self->window_width = self->width; self->window_height = self->height; sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; SDL_ShowCursor( SDL_DISABLE ); } pthread_mutex_lock( &mlt_sdl_mutex ); self->sdl_window = SDL_CreateWindow("MLT", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, self->window_width, self->window_height, sdl_flags); self->sdl_renderer = SDL_CreateRenderer(self->sdl_window, -1, SDL_RENDERER_ACCELERATED); if ( self->sdl_renderer ) { // Get texture width and height from the profile. int width = mlt_properties_get_int( self->properties, "width" ); int height = mlt_properties_get_int( self->properties, "height" ); self->sdl_texture = SDL_CreateTexture( self->sdl_renderer, texture_format, SDL_TEXTUREACCESS_STREAMING, width, height ); if ( self->sdl_texture ) { SDL_SetRenderDrawColor( self->sdl_renderer, 0, 0, 0, 255); } else { mlt_log_error( MLT_CONSUMER_SERVICE(&self->parent), "Failed to create SDL texture: %s\n", SDL_GetError() ); error = -1; } } else { mlt_log_error( MLT_CONSUMER_SERVICE(&self->parent), "Failed to create SDL renderer: %s\n", SDL_GetError() ); error = -1; } pthread_mutex_unlock( &mlt_sdl_mutex ); return error; }
struct twinterface*interface_init() { struct twinterface *twinterface; twinterface = (struct twinterface*) malloc(sizeof(struct twinterface)); twinterface->closeup = 0; twinterface->overview = 0; twinterface->btn_play = 0; twinterface->btn_reset = 0; twinterface->btn_reverse = 0; twinterface->btn_deck = 0; twinterface->btn_touch_mode = 0; twinterface->label_pitch = 0; twinterface->fader = 0; twinterface->redraw = 0; twinterface->volumeup_pressed = 0; twinterface->renderedFrames = 0; twinterface->last_track_length = tracks[0].length; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); /* Initialize SDL */ if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init fail : %s\n", SDL_GetError()); return twinterface; } /* Create window and renderer for given surface */ twinterface->window = SDL_CreateWindow(TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 747, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); if(!twinterface->window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Window creation fail : %s\n",SDL_GetError()); return twinterface; } twinterface->renderer = SDL_CreateRenderer(twinterface->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if(!twinterface->renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Render creation for surface fail : %s\n",SDL_GetError()); return twinterface; } /* Get the Size of drawing surface */ SDL_RenderGetViewport(twinterface->renderer, &twinterface->viewport); /* SDL interprets each pixel as a 32-bit number, so our masks must depend on the endianness (byte order) of the machine */ Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif twinterface->surface = SDL_CreateRGBSurface(0, twinterface->viewport.w, twinterface->viewport.h, 32, rmask, gmask, bmask, amask); if(!twinterface->surface) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Surface creation fail : %s\n",SDL_GetError()); return twinterface; } twinterface->texture = SDL_CreateTexture(twinterface->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, twinterface->viewport.w, twinterface->viewport.h); /* Clear the rendering surface with the specified color */ SDL_SetRenderDrawColor(twinterface->renderer, 0x0, 0x0, 0x0, 0); SDL_RenderClear(twinterface->renderer); /* Start timer to post ticker events */ twinterface->timer = SDL_AddTimer(REFRESH, ticker, NULL); /* Show deck 0 */ twinterface->current_deck = 0; /* Initialize widgets */ interface_widgets_init(twinterface); return twinterface; }
bool LTexture::loadFromFile( std::string path ) { //Get rid of preexisting texture free(); //The final texture SDL_Texture* newTexture = NULL; //Load image at specified path SDL_Surface* loadedSurface = IMG_Load( path.c_str() ); if( loadedSurface == NULL ) { printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() ); } else { //Convert surface to display format SDL_Surface* formattedSurface = SDL_ConvertSurfaceFormat( loadedSurface, SDL_PIXELFORMAT_RGBA8888, NULL ); if( formattedSurface == NULL ) { printf( "Unable to convert loaded surface to display format! %s\n", SDL_GetError() ); } else { //Create blank streamable texture newTexture = SDL_CreateTexture( gRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, formattedSurface->w, formattedSurface->h ); if( newTexture == NULL ) { printf( "Unable to create blank texture! SDL Error: %s\n", SDL_GetError() ); } else { //Enable blending on texture SDL_SetTextureBlendMode( newTexture, SDL_BLENDMODE_BLEND ); //Lock texture for manipulation SDL_LockTexture( newTexture, &formattedSurface->clip_rect, &mPixels, &mPitch ); //Copy loaded/formatted surface pixels memcpy( mPixels, formattedSurface->pixels, formattedSurface->pitch * formattedSurface->h ); //Get image dimensions mWidth = formattedSurface->w; mHeight = formattedSurface->h; //Get pixel data in editable format Uint32* pixels = (Uint32*)mPixels; int pixelCount = ( mPitch / 4 ) * mHeight; //Map colors Uint32 colorKey = SDL_MapRGB( formattedSurface->format, 0, 0xFF, 0xFF ); Uint32 transparent = SDL_MapRGBA( formattedSurface->format, 0x00, 0xFF, 0xFF, 0x00 ); //Color key pixels for( int i = 0; i < pixelCount; ++i ) { if( pixels[ i ] == colorKey ) { pixels[ i ] = transparent; } } //Unlock texture to update SDL_UnlockTexture( newTexture ); mPixels = NULL; } //Get rid of old formatted surface SDL_FreeSurface( formattedSurface ); } //Get rid of old loaded surface SDL_FreeSurface( loadedSurface ); } //Return success mTexture = newTexture; return mTexture != NULL; }
/* * BEE::Sprite::set_as_target() - Set up the sprite for use as a render target * @w: the width of the render texture * @h: the height of the render texture */ int BEE::Sprite::set_as_target(int w, int h) { if (is_loaded) { // If the sprite is already loaded, free the old data this->free(); } // Set the sprite dimensions and remove all cropping width = w; height = h; set_subimage_amount(1, width); crop = {0, 0, (int)width, (int)height}; if (game->options->renderer_type != BEE_RENDERER_SDL) { // Generate the vertex array object for the sprite glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Generate the four corner vertices of the rectangular sprite GLfloat vertices[] = { 0.0, 0.0, (GLfloat)width, 0.0, (GLfloat)width, (GLfloat)height, 0.0, (GLfloat)height, }; glGenBuffers(1, &vbo_vertices); glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Generate the indices of the two triangles which form the rectangular sprite GLushort elements[] = { 0, 1, 2, 2, 3, 0, }; glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); // Bind the vertices to the VAO's vertex buffer glEnableVertexAttribArray(game->vertex_location); glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices); glVertexAttribPointer( game->vertex_location, 2, GL_FLOAT, GL_FALSE, 0, 0 ); // Generate the framebuffer that will be used to render to this sprite glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); // Generate an empty texture glGenTextures(1, &gl_texture); glBindTexture(GL_TEXTURE_2D, gl_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr ); // Bind the framebuffer to the empty texture glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_texture, 0); GLenum buffer[1] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(framebuffer, buffer); // Enable drawing to the framebuffer // Check whether the framebuffer has been successfully initialized if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { // If not, reset the state game->messenger_send({"engine", "sprite"}, BEE_MESSAGE_WARNING, "Failed to create a new framebuffer."); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind the frame buffer to switch back to the default this->free(); // Free the old data return 0; // Return 0 on failure } glBindVertexArray(0); // Unbind VAO when done loading // Set the loaded booleans is_loaded = true; has_draw_failed = false; return (int)framebuffer; // Return the framebuffer index on success } else { texture = SDL_CreateTexture(game->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h); // Create an empty texture if (texture == nullptr) { // If the texture could not be created, output a warning game->messenger_send({"engine", "sprite"}, BEE_MESSAGE_WARNING, "Failed to create a blank texture: " + get_sdl_error()); return 0; // Return 0 on failure } SDL_SetRenderTarget(game->renderer, texture); // Set the SDL render target // Set the loaded booleans is_loaded = true; has_draw_failed = false; } return 1; // Return a positive integer on success }
static int ANDROID_AllocHWSurface(_THIS, SDL_Surface *surface) { if( !SDL_ANDROID_InsideVideoThread() ) { __android_log_print(ANDROID_LOG_INFO, "libSDL", "Error: calling %s not from the main thread!", __PRETTY_FUNCTION__); return -1; } if ( ! (surface->w && surface->h) ) return(-1); DEBUGOUT("ANDROID_AllocHWSurface() surface %p w %d h %d", surface, surface->w, surface->h); Uint32 format = SDL_PIXELFORMAT_RGBA5551; // 1-bit alpha for color key, every surface will have colorkey so it's easier for us if( surface->format->Amask ) { SDL_PixelFormat format1; int bpp; format = SDL_PIXELFORMAT_RGBA4444; DEBUGOUT("ANDROID_AllocHWSurface() SDL_PIXELFORMAT_RGBA4444"); SDL_memset(&format1, 0, sizeof(format1)); SDL_PixelFormatEnumToMasks( format, &bpp, &format1.Rmask, &format1.Gmask, &format1.Bmask, &format1.Amask ); if( surface->format->BitsPerPixel != bpp || surface->format->Rmask != format1.Rmask || surface->format->Gmask != format1.Gmask || surface->format->Bmask != format1.Bmask || surface->format->Amask != format1.Amask ) return(-1); // Do not allow alpha-surfaces with format other than RGBA4444 (it will be pain to lock/copy them) } else { DEBUGOUT("ANDROID_AllocHWSurface() SDL_PIXELFORMAT_RGBA5551"); // HW-accel surface should be RGB565 if( !( SDL_CurrentVideoSurface->format->BitsPerPixel == surface->format->BitsPerPixel && SDL_CurrentVideoSurface->format->Rmask == surface->format->Rmask && SDL_CurrentVideoSurface->format->Gmask == surface->format->Gmask && SDL_CurrentVideoSurface->format->Bmask == surface->format->Bmask && SDL_CurrentVideoSurface->format->Amask == surface->format->Amask ) ) return(-1); } surface->pitch = surface->w * surface->format->BytesPerPixel; surface->pixels = SDL_malloc(surface->h * surface->w * surface->format->BytesPerPixel); if ( surface->pixels == NULL ) { SDL_OutOfMemory(); return(-1); } SDL_memset(surface->pixels, 0, surface->h*surface->pitch); surface->hwdata = (struct private_hwdata *)SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w, surface->h); if( !surface->hwdata ) { SDL_free(surface->pixels); surface->pixels = NULL; SDL_OutOfMemory(); return(-1); } if( SDL_ANDROID_SmoothVideo ) SDL_SetTextureScaleMode((SDL_Texture *)surface->hwdata, SDL_SCALEMODE_SLOW); if( surface->format->Amask ) { SDL_SetTextureAlphaMod((struct SDL_Texture *)surface->hwdata, SDL_ALPHA_OPAQUE); SDL_SetTextureBlendMode((struct SDL_Texture *)surface->hwdata, SDL_BLENDMODE_BLEND); } surface->flags |= SDL_HWSURFACE | SDL_HWACCEL; HwSurfaceCount++; DEBUGOUT("ANDROID_AllocHWSurface() in HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList); HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) ); DEBUGOUT("ANDROID_AllocHWSurface() out HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList); HwSurfaceList[HwSurfaceCount-1] = surface; return 0; }
SdlRenderer *RENDERER_Initialize() { LOG("Creating and initializing SdlRenderer..."); if (SDL_Init(SDL_INIT_VIDEO) != 0) { LOGerr("Couldn't Initialize SDL_VIDEO, Error: %s", SDL_GetError()); return NULL; } SdlRenderer *newRend = (SdlRenderer*) malloc(sizeof(SdlRenderer)); if (newRend == NULL) { LOGerr("Couldn't allocate SdlRenderer"); return NULL; } newRend->window = SDL_CreateWindow("Chip8 Emulator",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH * 4, HEIGHT * 6, SDL_WINDOW_RESIZABLE); if (newRend->window == NULL) { LOGerr("Couldn't initialize SDL_Window, Error: %s",SDL_GetError()); free(newRend); return NULL; } newRend->renderer = SDL_CreateRenderer(newRend->window,-1, SDL_RENDERER_ACCELERATED); if (newRend->renderer == NULL) { LOGerr("Couldn't initialize SDL_Renderer, Error: %s", SDL_GetError()); SDL_DestroyWindow(newRend->window); free(newRend); return NULL; } newRend->texture = SDL_CreateTexture(newRend->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT); if (newRend->texture == NULL) { LOGerr("Couldn't allocate SDL_Texture, Error: %s", SDL_GetError()); SDL_DestroyRenderer(newRend->renderer); SDL_DestroyWindow(newRend->window); free(newRend); return NULL; } newRend->gfx = (uint32_t*) malloc(sizeof(uint32_t) * GFX_MAX); if(newRend->gfx == NULL) { LOGerr("Couldn't allocate GFX array..."); SDL_DestroyTexture(newRend->texture); SDL_DestroyRenderer(newRend->renderer); SDL_DestroyWindow(newRend->window); free(newRend); return NULL; } memset(newRend->gfx, 0, sizeof(uint32_t) * GFX_MAX); newRend->fps = FPS; newRend->pitch = WIDTH * 4; return newRend; }
void IO_SetMode (int w, int h, int bpp, int scale, int fullscreen) { int realw, realh; int bytes_pp = 0; int red = 0, green = 0, blue = 0; Uint32 flags; Uint32 format = 0; if (bpp != 16 && bpp != 24) F_Error ("invalid bpp %d", bpp); if (scale < 1 || scale > 6) F_Error ("invalid scale %d", scale); F_Log ("Setting mode %dx%dx%d (scale %dx)\n", w, h, bpp, scale); DestroyWindow (); /* window */ realw = w * scale; realh = h * scale; flags = (fullscreen) ? (SDL_WINDOW_FULLSCREEN_DESKTOP) : (0); if ((sdl_win = SDL_CreateWindow(APPNAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, realw, realh, flags)) == NULL) F_Error ("failed setting mode %dx%dx%d: %s", realw, realh, bpp, SDL_GetError()); /* renderer */ if ((sdl_render = SDL_CreateRenderer(sdl_win, -1, 0)) == NULL) F_Error ("failed creating renderer: %s", SDL_GetError()); /* rendering texture */ if (bpp == 16) { format = SDL_PIXELFORMAT_RGB565; bytes_pp = 2; red = 0xf800; green = 0x7e0; blue = 0x1f; } else if (bpp == 24) { format = SDL_PIXELFORMAT_RGB888; bytes_pp = 4; red = 0xff0000; green = 0xff00; blue = 0xff; } else { F_Error ("shouldn't happen, invalid bpp %d", bpp); } if ((sdl_tex = SDL_CreateTexture(sdl_render, format, SDL_TEXTUREACCESS_STREAMING, w, h)) == NULL) F_Error ("failed creating render texture: %s", SDL_GetError()); /* our draw buffer */ if ((video.buf = malloc(w * h * bytes_pp)) == NULL) F_Error ("failed allocating frame buffer"); /* row pointers */ if ((video.rows = malloc(sizeof(void *) * h)) == NULL) F_Error ("failed allocating row buffer"); video.w = w; video.h = h; video.bpp = bpp; video.bytes_pp = bytes_pp; video.red = red; video.green = green; video.blue = blue; /* set up row pointers */ int y; for (y = 0; y < video.h; y++) video.rows[y] = (char *)video.buf + y * (video.w * bytes_pp); }
int main(int argc, char* argv[]) { AVFormatContext *pFormatCtx; int i, videoindex; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame,*pFrameYUV; uint8_t *out_buffer; AVPacket *packet; int y_size; int ret, got_picture; struct SwsContext *img_convert_ctx; char filepath[]="bigbuckbunny_480x272.h265"; //SDL--------------------------- int screen_w=0,screen_h=0; SDL_Window *screen; SDL_Renderer* sdlRenderer; SDL_Texture* sdlTexture; SDL_Rect sdlRect; FILE *fp_yuv; av_register_all(); avformat_network_init(); pFormatCtx = avformat_alloc_context(); if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){ printf("Couldn't open input stream.\n"); return -1; } if(avformat_find_stream_info(pFormatCtx,NULL)<0){ printf("Couldn't find stream information.\n"); return -1; } videoindex=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){ videoindex=i; break; } if(videoindex==-1){ printf("Didn't find a video stream.\n"); return -1; } pCodecCtx=pFormatCtx->streams[videoindex]->codec; pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL){ printf("Codec not found.\n"); return -1; } if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){ printf("Could not open codec.\n"); return -1; } pFrame=av_frame_alloc(); pFrameYUV=av_frame_alloc(); out_buffer=(uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)); avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); packet=(AVPacket *)av_malloc(sizeof(AVPacket)); //Output Info----------------------------- printf("--------------- File Information ----------------\n"); av_dump_format(pFormatCtx,0,filepath,0); printf("-------------------------------------------------\n"); img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); #if OUTPUT_YUV420P fp_yuv=fopen("output.yuv","wb+"); #endif if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { printf( "Could not initialize SDL - %s\n", SDL_GetError()); return -1; } screen_w = pCodecCtx->width; screen_h = pCodecCtx->height; //SDL 2.0 Support for multiple windows screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_w, screen_h, SDL_WINDOW_OPENGL); if(!screen) { printf("SDL: could not create window - exiting:%s\n",SDL_GetError()); return -1; } sdlRenderer = SDL_CreateRenderer(screen, -1, 0); //IYUV: Y + U + V (3 planes) //YV12: Y + V + U (3 planes) sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height); sdlRect.x=0; sdlRect.y=0; sdlRect.w=screen_w; sdlRect.h=screen_h; //SDL End---------------------- while(av_read_frame(pFormatCtx, packet)>=0){ if(packet->stream_index==videoindex){ ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if(ret < 0){ printf("Decode Error.\n"); return -1; } if(got_picture){ sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); #if OUTPUT_YUV420P y_size=pCodecCtx->width*pCodecCtx->height; fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V #endif //SDL--------------------------- #if 0 SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] ); #else SDL_UpdateYUVTexture(sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0], pFrameYUV->data[1], pFrameYUV->linesize[1], pFrameYUV->data[2], pFrameYUV->linesize[2]); #endif SDL_RenderClear( sdlRenderer ); SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect); SDL_RenderPresent( sdlRenderer ); //SDL End----------------------- //Delay 40ms SDL_Delay(40); } } av_free_packet(packet); } //flush decoder //FIX: Flush Frames remained in Codec while (1) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if (ret < 0) break; if (!got_picture) break; sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); #if OUTPUT_YUV420P int y_size=pCodecCtx->width*pCodecCtx->height; fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V #endif //SDL--------------------------- SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] ); SDL_RenderClear( sdlRenderer ); SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect); SDL_RenderPresent( sdlRenderer ); //SDL End----------------------- //Delay 40ms SDL_Delay(40); } sws_freeContext(img_convert_ctx); #if OUTPUT_YUV420P fclose(fp_yuv); #endif SDL_Quit(); av_frame_free(&pFrameYUV); av_frame_free(&pFrame); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0; }
int main(int argc, char* argv[]) { AVFormatContext *pFormatCtx; int i, videoindex; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame,*pFrameYUV; uint8_t *out_buffer; AVPacket *packet; int ret, got_picture; //------------SDL---------------- int screen_w,screen_h; SDL_Window *screen; SDL_Renderer* sdlRenderer; SDL_Texture* sdlTexture; SDL_Rect sdlRect; SDL_Thread *video_tid; SDL_Event event; struct SwsContext *img_convert_ctx; char filepath[]="bigbuckbunny_480x272.h265"; av_register_all(); avformat_network_init(); pFormatCtx = avformat_alloc_context(); if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0) { printf("Couldn't open input stream.\n"); return -1; } if(avformat_find_stream_info(pFormatCtx,NULL)<0) { printf("Couldn't find stream information.\n"); return -1; } videoindex=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoindex=i; break; } if(videoindex==-1) { printf("Didn't find a video stream.\n"); return -1; } pCodecCtx=pFormatCtx->streams[videoindex]->codec; pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { printf("Codec not found.\n"); return -1; } if(avcodec_open2(pCodecCtx, pCodec,NULL)<0) { printf("Could not open codec.\n"); return -1; } pFrame=av_frame_alloc(); pFrameYUV=av_frame_alloc(); out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)); avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); //Output Info----------------------------- printf("---------------- File Information ---------------\n"); av_dump_format(pFormatCtx,0,filepath,0); printf("-------------------------------------------------\n"); img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { printf( "Could not initialize SDL - %s\n", SDL_GetError()); return -1; } //SDL 2.0 Support for multiple windows screen_w = pCodecCtx->width; screen_h = pCodecCtx->height; screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_w, screen_h,SDL_WINDOW_OPENGL); if(!screen) { printf("SDL: could not create window - exiting:%s\n",SDL_GetError()); return -1; } sdlRenderer = SDL_CreateRenderer(screen, -1, 0); //IYUV: Y + U + V (3 planes) //YV12: Y + V + U (3 planes) sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height); sdlRect.x=0; sdlRect.y=0; sdlRect.w=screen_w; sdlRect.h=screen_h; packet=(AVPacket *)av_malloc(sizeof(AVPacket)); video_tid = SDL_CreateThread(sfp_refresh_thread,NULL,NULL); //------------SDL End------------ //Event Loop for (;;) { //Wait SDL_WaitEvent(&event); if(event.type==SFM_REFRESH_EVENT) { //------------------------------ if(av_read_frame(pFormatCtx, packet)>=0) { if(packet->stream_index==videoindex) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if(ret < 0) { printf("Decode Error.\n"); return -1; } if(got_picture) { sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); //SDL--------------------------- SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] ); SDL_RenderClear( sdlRenderer ); //SDL_RenderCopy( sdlRenderer, sdlTexture, &sdlRect, &sdlRect ); SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, NULL); SDL_RenderPresent( sdlRenderer ); //SDL End----------------------- } } av_free_packet(packet); } else { //Exit Thread thread_exit=1; } } 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==SFM_BREAK_EVENT) { break; } } sws_freeContext(img_convert_ctx); SDL_Quit(); //-------------- av_frame_free(&pFrameYUV); av_frame_free(&pFrame); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0; }
int main(int argc, char**argv) { SDL_Window* win = NULL; SDL_Renderer* ren = NULL; SDL_Texture* tex = NULL; SDL_Event eve; char*smoothing="nearest"; //nearest or linear unsigned width = 3000; unsigned height = 4000; unsigned i,r,g,b,x,y; int sizew,sizeh; //actual window size uint32_t*buff=NULL; srand(time(NULL)); assert(buff = calloc(width*height,sizeof(uint32_t))); for(x=0; x<width; x++) { for(y=0; y<height; y++) { r = x % 256; g = y % 256; //i / 256; b = 0; //rand() % 256; //buff[y*width+x] = (r<<16)+(g<<8)+b; setpixel(buff,x,y,width,r,g,b); } } if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL_Init Error: %s\n",SDL_GetError()); return 1; } assert(win = SDL_CreateWindow("Hello World!", SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, 100, 100,SDL_WINDOW_SHOWN|SDL_WINDOW_MAXIMIZED|SDL_WINDOW_RESIZABLE)); //SDL_WINDOW_FULLSCREEN_DESKTOP)); assert(ren = SDL_CreateRenderer(win, -1, 0)); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, smoothing); //"linear" or "nearest" //SDL_RenderSetLogicalSize(ren, width, height);- assert(tex = SDL_CreateTexture(ren,SDL_PIXELFORMAT_ARGB8888,SDL_TEXTUREACCESS_STREAMING, width, height)); SDL_UpdateTexture(tex, NULL, buff, width * sizeof (uint32_t)); SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, NULL, NULL); SDL_RenderPresent(ren); SDL_PollEvent(&eve); SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, NULL, NULL); SDL_RenderPresent(ren); SDL_Rect src; SDL_Rect dst; double vx = (double)width / 2.0; double vy = (double)height / 2.0; double scl = 0.5; src.x = 0; src.y = 0; src.w = width; src.h = height; SDL_GetWindowSize(win,&sizew,&sizeh); printf("window size: %d,%d\n",sizew,sizeh); SDL_GetWindowMaximumSize(win,&sizew,&sizeh); printf("max window size: %d,%d\n",sizew,sizeh); SDL_GetRendererOutputSize(ren,&sizew,&sizeh); printf("renderer size: %d,%d\n",sizew,sizeh); while(1) { SDL_WaitEvent(&eve); if(eve.type == SDL_QUIT) break; if(eve.type == SDL_KEYDOWN) { //quit if(eve.key.keysym.sym == SDLK_q) break; if(eve.key.keysym.sym == SDLK_ESCAPE) break; //scaling method if(eve.key.keysym.sym == SDLK_n) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"nearest"); if(eve.key.keysym.sym == SDLK_l) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"linear"); //reset view if(eve.key.keysym.sym == SDLK_RETURN || eve.key.keysym.sym == SDLK_RETURN2) { vx = (double)width / 2.0; vy = (double)height / 2.0; scl = 0.5; } //zoom in / out if(eve.key.keysym.sym == SDLK_PLUS || eve.key.keysym.sym == SDLK_KP_PLUS) { scl /= 1.01; } if(eve.key.keysym.sym == SDLK_MINUS || eve.key.keysym.sym == SDLK_KP_MINUS) { scl *= 1.01; } } if(eve.type == SDL_MOUSEBUTTONDOWN) { printf("(%d,%d)\n",eve.button.x,eve.button.y); } dst.x = vx - scl * (double)width; dst.y = vy - scl * (double)height; dst.w = 2.0 * scl * (double)width; dst.h = 2.0 * scl * (double)height; SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, &src, &dst); SDL_RenderPresent(ren); } SDL_Quit(); return 0; }
SDL_Texture * SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h) { SDL_Texture *texture; CHECK_RENDERER_MAGIC(renderer, NULL); if (!format) { format = renderer->info.texture_formats[0]; } if (SDL_ISPIXELFORMAT_INDEXED(format)) { SDL_SetError("Palettized textures are not supported"); return NULL; } if (w <= 0 || h <= 0) { SDL_SetError("Texture dimensions can't be 0"); return NULL; } texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture)); if (!texture) { SDL_OutOfMemory(); return NULL; } texture->magic = &texture_magic; texture->format = format; texture->access = access; texture->w = w; texture->h = h; texture->r = 255; texture->g = 255; texture->b = 255; texture->a = 255; texture->renderer = renderer; texture->next = renderer->textures; if (renderer->textures) { renderer->textures->prev = texture; } renderer->textures = texture; if (IsSupportedFormat(renderer, format)) { if (renderer->CreateTexture(renderer, texture) < 0) { SDL_DestroyTexture(texture); return 0; } } else { texture->native = SDL_CreateTexture(renderer, GetClosestSupportedFormat(renderer, format), access, w, h); if (!texture->native) { SDL_DestroyTexture(texture); return NULL; } /* Swap textures to have texture before texture->native in the list */ texture->native->next = texture->next; if (texture->native->next) { texture->native->next->prev = texture->native; } texture->prev = texture->native->prev; if (texture->prev) { texture->prev->next = texture; } texture->native->prev = texture; texture->next = texture->native; renderer->textures = texture; if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { texture->yuv = SDL_SW_CreateYUVTexture(format, w, h); if (!texture->yuv) { SDL_DestroyTexture(texture); return NULL; } } else if (access == SDL_TEXTUREACCESS_STREAMING) { /* The pitch is 4 byte aligned */ texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3); texture->pixels = SDL_calloc(1, texture->pitch * h); if (!texture->pixels) { SDL_DestroyTexture(texture); return NULL; } } } return texture; }
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) { const SDL_PixelFormat *fmt; SDL_bool needAlpha; Uint32 i; Uint32 format; SDL_Texture *texture; CHECK_RENDERER_MAGIC(renderer, NULL); if (!surface) { SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); return NULL; } /* See what the best texture format is */ fmt = surface->format; if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) { needAlpha = SDL_TRUE; } else { needAlpha = SDL_FALSE; } format = renderer->info.texture_formats[0]; for (i = 0; i < renderer->info.num_texture_formats; ++i) { if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) && SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) { format = renderer->info.texture_formats[i]; break; } } texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, surface->w, surface->h); if (!texture) { return NULL; } if (format == surface->format->format) { if (SDL_MUSTLOCK(surface)) { SDL_LockSurface(surface); SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); SDL_UnlockSurface(surface); } else { SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); } } else { SDL_PixelFormat *dst_fmt; SDL_Surface *temp = NULL; /* Set up a destination surface for the texture update */ dst_fmt = SDL_AllocFormat(format); temp = SDL_ConvertSurface(surface, dst_fmt, 0); SDL_FreeFormat(dst_fmt); if (temp) { SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch); SDL_FreeSurface(temp); } else { SDL_DestroyTexture(texture); return NULL; } } { Uint8 r, g, b, a; SDL_BlendMode blendMode; SDL_GetSurfaceColorMod(surface, &r, &g, &b); SDL_SetTextureColorMod(texture, r, g, b); SDL_GetSurfaceAlphaMod(surface, &a); SDL_SetTextureAlphaMod(texture, a); if (SDL_GetColorKey(surface, NULL) == 0) { /* We converted to a texture with alpha format */ SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); } else { SDL_GetSurfaceBlendMode(surface, &blendMode); SDL_SetTextureBlendMode(texture, blendMode); } } return texture; }