void MoSyncThread::start(int (SDLCALL * func)(void*), void* arg) { mThread = SDL_CreateThread(func, arg); _ASSERT(mThread); }
int video_thr(LPVOID lpParam) { int iRet = -1; AVFormatContext * pFmtCtx = NULL; AVFormatContext * pRtmpFmtCtx = NULL; AVInputFormat * pVideoInputFmt = NULL; AVOutputFormat * pVideoOutfmt = NULL; struct_stream_info * strct_streaminfo = NULL; AVCodecContext * pCodecContext = NULL; AVCodec * pCodec = NULL; int iVideoIndex = -1; int iVideo_Height = 0; int iVideo_Width = 0; int iVideoPic = 0; int64_t start_time = 0; int frame_index = 0; SDL_Event event; CLS_DlgStreamPusher* pThis = (CLS_DlgStreamPusher*)lpParam; if (pThis == NULL){ TRACE("video_thr--pThis == NULL\n"); return iRet; } pVideoInputFmt = av_find_input_format("dshow"); if (pVideoInputFmt == NULL){ TRACE("pVideoInputFmt == NULL\n"); return iRet; } char* psDevName = pThis->GetDeviceName(n_Video); if (psDevName == NULL){ TRACE("video_thr--psDevName == NULL"); return iRet; } while (1){ if (pThis->m_cstrPushAddr != ""){ break; } } //根据推流地址获取到AVFormatContext avformat_alloc_output_context2(&pRtmpFmtCtx, NULL, "flv", pThis->m_cstrPushAddr); if (NULL == pRtmpFmtCtx){ TRACE("NULL == pRtmpFmtCtx"); return iRet; } pVideoOutfmt = pRtmpFmtCtx->oformat; strct_streaminfo = pThis->m_pStreamInfo; if (NULL == strct_streaminfo){ TRACE("NULL == strct_streaminfo"); return iRet; } FILE *fp_yuv = fopen("output.yuv", "wb+"); pFmtCtx = avformat_alloc_context(); if (avformat_open_input(&pFmtCtx, psDevName, pVideoInputFmt, NULL) != 0){ TRACE("avformat_open_input err!\n"); goto END; } if (avformat_find_stream_info(pFmtCtx, NULL) < 0){ TRACE("avformat_find_stream_info(pFmtCtx, NULL) < 0\n"); goto END; } for (int i = 0; i < pFmtCtx->nb_streams; i++){ if (pFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){ iVideoIndex = i; break; } } if (iVideoIndex < 0){ TRACE("iVideoIndex < 0\n"); goto END; } pCodecContext = pFmtCtx->streams[iVideoIndex]->codec; if (NULL == pCodecContext){ TRACE("NULL == pCodecContext"); goto END; } pCodec = avcodec_find_decoder(pCodecContext->codec_id); if (pCodec == NULL){ TRACE("avcodec_find_decoder<0"); goto END; } if (avcodec_open2(pCodecContext, pCodec, NULL)<0){ TRACE("avcodec_open2<0"); goto END; } for (int i = 0; i < pFmtCtx->nb_streams; i++) { //根据输入流创建输出流(Create output AVStream according to input AVStream) AVStream *in_stream = pFmtCtx->streams[i]; AVStream *out_stream = avformat_new_stream(pRtmpFmtCtx, in_stream->codec->codec); if (!out_stream) { printf("Failed allocating output stream\n"); iRet = AVERROR_UNKNOWN; goto END; } //复制AVCodecContext的设置(Copy the settings of AVCodecContext) iRet = avcodec_copy_context(out_stream->codec, in_stream->codec); if (iRet < 0) { TRACE("Failed to copy context from input to output stream codec context\n"); goto END; } out_stream->codec->codec_tag = 0; if (pRtmpFmtCtx->oformat->flags & AVFMT_GLOBALHEADER) out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; } if (!(pVideoOutfmt->flags & AVFMT_NOFILE)) { iRet = avio_open(&pRtmpFmtCtx->pb, pThis->m_cstrPushAddr, AVIO_FLAG_WRITE); if (iRet < 0) { TRACE("Could not open output URL '%s'", pThis->m_cstrPushAddr); goto END; } } iRet = avformat_write_header(pRtmpFmtCtx, NULL); if (iRet < 0) { TRACE("Error occurred when opening output URL\n"); goto END; } start_time = av_gettime(); //获取视频的宽与高 iVideo_Height = pCodecContext->height;//strct_streaminfo->m_height;// iVideo_Width = pCodecContext->width;//strct_streaminfo->m_width;// TRACE("video_thr--video_height[%d],video_width[%d]", iVideo_Height , iVideo_Width); strct_streaminfo->m_pVideoPacket = (AVPacket*)av_malloc(sizeof(AVPacket)); strct_streaminfo->m_pVideoFrame = av_frame_alloc(); strct_streaminfo->m_pVideoFrameYUV = av_frame_alloc(); strct_streaminfo->m_pVideoOutBuffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, iVideo_Width, iVideo_Height)); avpicture_fill((AVPicture *)strct_streaminfo->m_pVideoFrameYUV, strct_streaminfo->m_pVideoOutBuffer, AV_PIX_FMT_YUV420P, iVideo_Width, iVideo_Height); strct_streaminfo->m_video_sws_ctx = sws_getContext(iVideo_Width, iVideo_Height, pCodecContext->pix_fmt, iVideo_Width, iVideo_Height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); if (NULL == strct_streaminfo->m_video_sws_ctx){ TRACE("NULL == strct_streaminfo->m_video_sws_ctx\n"); goto END; } strct_streaminfo->m_video_refresh_tid = SDL_CreateThread(video_refresh_thread, NULL, strct_streaminfo); //从摄像头获取数据 for (;;){ AVStream *in_stream, *out_stream; SDL_WaitEvent(&event); if (event.type == FF_VIDEO_REFRESH_EVENT){ if (av_read_frame(pFmtCtx, strct_streaminfo->m_pVideoPacket) >= 0){ if (strct_streaminfo->m_pVideoPacket->pts == AV_NOPTS_VALUE){ //Write PTS AVRational time_base1 = pFmtCtx->streams[iVideoIndex]->time_base; //Duration between 2 frames (us) int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(pFmtCtx->streams[iVideoIndex]->r_frame_rate); //Parameters strct_streaminfo->m_pVideoPacket->pts = (double)(frame_index*calc_duration) / (double)(av_q2d(time_base1)*AV_TIME_BASE); strct_streaminfo->m_pVideoPacket->dts = strct_streaminfo->m_pVideoPacket->pts; strct_streaminfo->m_pVideoPacket->duration = (double)calc_duration / (double)(av_q2d(time_base1)*AV_TIME_BASE); } if (strct_streaminfo->m_pVideoPacket->stream_index == iVideoIndex){ AVRational time_base = pFmtCtx->streams[iVideoIndex]->time_base; AVRational time_base_q = { 1, AV_TIME_BASE }; int64_t pts_time = av_rescale_q(strct_streaminfo->m_pVideoPacket->dts, time_base, time_base_q); int64_t now_time = av_gettime() - start_time; if (pts_time > now_time) av_usleep(pts_time - now_time); in_stream = pFmtCtx->streams[strct_streaminfo->m_pVideoPacket->stream_index]; out_stream = pRtmpFmtCtx->streams[strct_streaminfo->m_pVideoPacket->stream_index]; /* copy packet */ //转换PTS/DTS(Convert PTS/DTS) strct_streaminfo->m_pVideoPacket->pts = av_rescale_q_rnd(strct_streaminfo->m_pVideoPacket->pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); strct_streaminfo->m_pVideoPacket->dts = av_rescale_q_rnd(strct_streaminfo->m_pVideoPacket->dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); strct_streaminfo->m_pVideoPacket->duration = av_rescale_q(strct_streaminfo->m_pVideoPacket->duration, in_stream->time_base, out_stream->time_base); strct_streaminfo->m_pVideoPacket->pos = -1; TRACE("Send %8d video frames to output URL\n", frame_index); frame_index++; iRet = av_interleaved_write_frame(pRtmpFmtCtx, strct_streaminfo->m_pVideoPacket); if (iRet < 0) { TRACE("Error muxing packet\n"); break; } if (pThis->m_blVideoShow){ //解码显示 iRet = avcodec_decode_video2(pCodecContext, strct_streaminfo->m_pVideoFrame, &iVideoPic, strct_streaminfo->m_pVideoPacket); if (iRet < 0){ TRACE("Decode Error.\n"); av_free_packet(strct_streaminfo->m_pVideoPacket); goto END; } if (iVideoPic <= 0){ TRACE("iVideoPic <= 0"); av_free_packet(strct_streaminfo->m_pVideoPacket); goto END; } if (sws_scale(strct_streaminfo->m_video_sws_ctx, (const uint8_t* const*)strct_streaminfo->m_pVideoFrame->data, strct_streaminfo->m_pVideoFrame->linesize, 0, /*strct_streaminfo->m_height*/iVideo_Height, strct_streaminfo->m_pVideoFrameYUV->data, strct_streaminfo->m_pVideoFrameYUV->linesize) < 0){ TRACE("sws_scale < 0"); av_free_packet(strct_streaminfo->m_pVideoPacket); goto END; } if (pThis->m_blPushStream){ //进行推流操作 if (pThis->push_stream() < 0){ TRACE("pThis->push_stream() < 0"); goto END; } } if (SDL_UpdateTexture(strct_streaminfo->m_sdlTexture, NULL, strct_streaminfo->m_pVideoFrameYUV->data[0], strct_streaminfo->m_pVideoFrameYUV->linesize[0]) < 0){ TRACE("SDL_UpdateTexture < 0\n"); goto END; } if (SDL_RenderClear(strct_streaminfo->m_sdlRenderer) < 0){ TRACE("SDL_RenderClear<0\n"); goto END; } if (SDL_RenderCopy(strct_streaminfo->m_sdlRenderer, strct_streaminfo->m_sdlTexture, NULL, NULL) < 0){ TRACE("SDL_RenderCopy<0\n"); goto END; } SDL_RenderPresent(strct_streaminfo->m_sdlRenderer); } } av_free_packet(strct_streaminfo->m_pVideoPacket); } } else if (event.type == FF_BREAK_EVENT){ break; } } av_write_trailer(pRtmpFmtCtx); iRet = 1; END: //fclose(fp_yuv); if (strct_streaminfo->m_video_sws_ctx){ sws_freeContext(strct_streaminfo->m_video_sws_ctx); } if (strct_streaminfo->m_pVideoFrameYUV){ av_frame_free(&strct_streaminfo->m_pVideoFrameYUV); } avformat_close_input(&pFmtCtx); avformat_free_context(pRtmpFmtCtx); return iRet; }
int main( int argc, char* argv[] ) { SDL_Event event; Uint32 u; Uint32 v; int i; int w = W; int h = H; int multis = MULTIS; int threads = THREADS; int photons = PHOTONS; unsigned seed = (unsigned)-1; bool preview = true; NICEME; // Process cmd line args for(i=1; i<argc; i++) { if( argv[i][0]=='-' ) switch( argv[i][1] ) { case 'w': w = atoi(argv[i]+2); break; case 'h': h = atoi(argv[i]+2); break; case 'm': multis = atoi(argv[i]+2); break; case 't': threads = atoi(argv[i]+2); break; case 'p': photons = atoi(argv[i]+2); break; case '-': printf( "Usage: [OPTION]... [SEED]\nRender ray-traced 3D images generated randomly with seed number SEED.\n\n option default description\n -wNUM %7d Set image output width to NUM\n -hNUM %7d Set image output height to NUM\n -mNUM %7d Set multisampling level to NUM (level 2 recommended)\n -tNUM %7d Parallelize with NUM threads\n -pNUM %7d Simulate lighting with NUM million photons!\n",W,H,MULTIS,THREADS,PHOTONS ), exit(0); default: fprintf( stderr, "Halt! -%c isn't one of my options!\nUse --help for help.\n", argv[i][1] ), exit(-1); } else if( seed==(unsigned)-1 ) { seed = atoi(argv[i]); if( !seed ) fprintf( stderr, "Halt! SEED ought to be a positive number, not %s\n", argv[i] ), exit(-1); } else fprintf( stderr, "Halt! I'm confused by cmd line argument #%d: %s\n", i, argv[i] ), exit(-1); } if( w<1 ) w=W; if( h<1 ) h=H; if( multis<1 ) multis=MULTIS; if( threads<1 ) threads=THREADS; if( photons<1 ) photons=PHOTONS; // Use time as seed if not otherwise specified if( seed==(unsigned)-1 ) seed = (unsigned)time(NULL); // Init SDL if( SDL_Init( SDL_INIT_TIMER|SDL_INIT_AUDIO|SDL_INIT_VIDEO ) < 0 || !SDL_GetVideoInfo() ) return 0; // Create Window SetVideo( w, h ); SDL_WM_SetCaption("PixelMachine", NULL); pinfo = SDL_GetVideoInfo(); // font init SJF_Init(pinfo); //ui setup ui.init(); h_menu = ui.new_control(0,0,0,0); h_render = ui.new_control(h_menu,80,15,SJUIF_EXTENDSV); ui.set_caption(h_menu,"Click to render..."); ui.set_caption(h_render,"Loading"); //pm preview render setup pixelmachine = new PIXELMACHINE; pixelmachine->init(seed,100,75,1,threads,(photons?1:0)); thread = SDL_CreateThread(run_pixel_machine,NULL); // MAIN LOOP while( 1 ) { while( SDL_PollEvent(&event) ) switch(event.type) { case SDL_VIDEOEXPOSE: ; break; case SDL_VIDEORESIZE: SetVideo( event.resize.w, event.resize.h ); break; case SDL_MOUSEBUTTONDOWN: if( preview ) { //pm full render go! preview = false; pixelmachine->cancel = true; SDL_WaitThread(thread,NULL); //BUG: thread may not be valid? delete pixelmachine; pixelmachine = new PIXELMACHINE; pixelmachine->init(seed,w,h,multis,threads,photons); thread = SDL_CreateThread(run_pixel_machine,NULL); } break; case SDL_KEYDOWN: ; break; case SDL_QUIT: pixelmachine->cancel = true; SDL_WaitThread(thread,NULL); //BUG: thread may not be valid? delete pixelmachine; Cleanup(); break; } gutimenow = SDL_GetTicks(); if( (Uint32)(gutimenow-gutime)>50 ) { Render(); gutime = gutimenow; } // chill out for a bit SDL_Delay(10); } return 0; }
int main(int argc, char *argv[]) { enum { GAME_COMPUTER, GAME_NETWORK, GAME_UNKNOWN } game_type = GAME_UNKNOWN; char *remote_address = NULL; int remote_port; int i; if (argc < 2) { printf("Penguin Warrior\n"); printf("Usage: pw [ mode ] [ option ... ]\n"); printf(" Game modes (choose one):\n"); printf(" --computer\n"); printf(" --client <remote ip address>\n"); printf(" --server <port number>\n"); printf(" Display options, for tweaking and experimenting:\n"); printf(" --fullscreen\n"); printf(" --hwsurface (use an SDL hardware surface if possible)\n"); printf(" --doublebuf (use SDL double buffering if possible)\n"); printf(" The display options default to a windowed, software buffer.\n"); exit(EXIT_FAILURE); } /* Process command line arguments. There are plenty of libraries for command line processing, but our needs are simple in this case. */ for (i = 0; i < argc; i++) { /* Networked or scripted opponent? */ if (!strcmp(argv[i], "--computer")) { game_type = GAME_COMPUTER; continue; } else if (!strcmp(argv[i], "--client")) { game_type = GAME_NETWORK; if (i + 2 >= argc) { printf("You must supply an IP address "\ "and port number for network games.\n"); exit(EXIT_FAILURE); } remote_address = argv[i+1]; remote_port = atoi(argv[i+2]); i++; continue; } else if (!strcmp(argv[i], "--server")) { game_type = GAME_NETWORK; if (++i >= argc) { printf("You must supply a port number "\ "for --server.\n"); exit(EXIT_FAILURE); } remote_port = atoi(argv[i]); continue; /* Display-related options */ } else if (!strcmp(argv[i], "--hwsurface")) { hwsurface = 1; } else if (!strcmp(argv[i], "--doublebuf")) { doublebuf = 1; } else if (!strcmp(argv[i], "--fullscreen")) { fullscreen = 1; } } /* If this is a network game, make a connection. */ if (game_type == GAME_NETWORK) { /* If there's no remote address, the user selected server mode. */ if (remote_address == NULL) { if (WaitNetgameConnection(remote_port, &netlink) != 0) { printf("Unable to receive connection.\n"); exit(EXIT_FAILURE); } } else { if (ConnectToNetgame(remote_address, remote_port, &netlink) != 0) { printf("Unable to connect.\n"); exit(EXIT_FAILURE); } } opponent_type = OPP_NETWORK; printf("Playing in network game against %s.\n", netlink.dotted_ip); } else if (game_type == GAME_COMPUTER) { opponent_type = OPP_COMPUTER; printf("Playing against the computer.\n"); } else { printf("No game type selected.\n"); exit(EXIT_FAILURE); } /* Initialize our random number generator. */ initrandom(); /* Create a mutex to protect the player data. */ player_mutex = SDL_CreateMutex(); if (player_mutex == NULL) { fprintf(stderr, "Unable to create mutex: %s\n", SDL_GetError()); } /* Start our scripting engine. */ InitScripting(); if (LoadGameScript("pw.tcl") != 0) { fprintf(stderr, "Exiting due to script error.\n"); exit(EXIT_FAILURE); } /* Fire up SDL. */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("Unable to initialize SDL: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } atexit(SDL_Quit); /* Set an appropriate 16-bit video mode. */ if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) | (doublebuf ? SDL_DOUBLEBUF : 0) | (fullscreen ? SDL_FULLSCREEN : 0)) == NULL) { printf("Unable to set video mode: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } /* Save the screen pointer for later use. */ screen = SDL_GetVideoSurface(); /* Set the window caption to the name of the game. */ SDL_WM_SetCaption("Penguin Warrior", "Penguin Warrior"); /* Hide the mouse pointer. */ SDL_ShowCursor(0); /* Initialize the status display. */ if (InitStatusDisplay() < 0) { printf("Unable to initialize status display.\n"); exit(EXIT_FAILURE); } /* Start the OpenAL-based audio system. */ InitAudio(); /* Initialize music and give the music system a file. */ InitMusic(); if (LoadMusic("reflux.ogg") < 0) { /* If that failed, don't worry about it. */ printf("Unable to load reflux.ogg.\n"); } /* Load the game's data into globals. */ LoadGameData(); /* Initialize the background starfield. */ InitBackground(); /* Start the network thread. */ if (game_type == GAME_NETWORK) { network_thread = SDL_CreateThread(NetworkThread, NULL); if (network_thread == NULL) { printf("Unable to start network thread: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } } /* Play! */ InitPlayer(&player); InitPlayer(&opponent); PlayGame(); /* Kill the network thread. */ if (game_type == GAME_NETWORK) { SDL_KillThread(network_thread); } /* Close the network connection. */ if (game_type == GAME_NETWORK) CloseNetgameLink(&netlink); /* Unhide the mouse pointer. */ SDL_ShowCursor(1); /* Clean up the status display. */ CleanupStatusDisplay(); /* Unload data. */ UnloadGameData(); /* Shut down our scripting engine. */ CleanupScripting(); /* Get rid of the mutex. */ SDL_DestroyMutex(player_mutex); /* Shut down audio. */ CleanupMusic(); CleanupAudio(); return 0; }
Thread *CreateThread(int (*fn)(void *), void *data) { return SDL_CreateThread(fn, data); }
void GameScreen::Update(int delta) { if (!caseIsReady && gCaseFilePath.length() > 0) { SDL_CreateThread(GameScreen::LoadCaseStatic, "LoadCaseThread", new LoadCaseParameters(gCaseFilePath)); gCaseFilePath = ""; } if (isFinishing) { if (Case::GetInstance()->GetIsUnloaded()) { ResourceLoader::GetInstance()->SnapLoadStepQueue(); while (ResourceLoader::GetInstance()->HasLoadStep()) { ResourceLoader::GetInstance()->TryRunOneLoadStep(); } ResourceLoader::GetInstance()->UnloadCase(); Case::DestroyInstance(); caseIsReady = false; isFinishing = false; // If the case file path contains a path, then we're loading a new case, // so we only want to do go back to the title screen if it doesn't. if (gCaseFilePath.length() == 0) { Game::GetInstance()->PrepareMenuMode(); isFinished = true; nextScreenId = TITLE_SCREEN_ID; } } return; } if (!caseIsReady) { timeSinceLastLoadingDotsUpdate += delta; while (timeSinceLastLoadingDotsUpdate > LoadingDotsUpdateDelayMs) { timeSinceLastLoadingDotsUpdate -= LoadingDotsUpdateDelayMs; numLoadingDots++; if (numLoadingDots > 3) { numLoadingDots = 1; } } return; } else if (Case::GetInstance()->IsLoading()) { if (Case::GetInstance()->GetWantsToLoadResources()) { Case::GetInstance()->LoadResources(); startedLoadingResources = true; } else if (startedLoadingResources && !ResourceLoader::GetInstance()->HasLoadStep() && !ResourceLoader::GetInstance()->HasImageTexturesToLoad()) { Case::GetInstance()->SetIsLoadingSprites(false); startedLoadingResources = false; } return; } if (caseNeedsReset) { Case::GetInstance()->Reset(); Case::GetInstance()->Begin(); caseNeedsReset = false; } if (Case::GetInstance()->GetIsFinished()) { stopMusic(); isFinishing = true; SDL_CreateThread(GameScreen::UnloadCaseStatic, "UnloadCaseThread", this); return; } Case::GetInstance()->Update(delta); }
/* =============== GLimp_SpawnRenderThread =============== */ qboolean GLimp_SpawnRenderThread(void (*function) (void)) { static qboolean warned = qfalse; if(!warned) { Com_Printf("WARNING: You enable r_smp at your own risk!\n"); warned = qtrue; } #if !defined(MACOS_X) && !defined(WIN32) && !defined (SDL_VIDEO_DRIVER_X11) return qfalse; /* better safe than sorry for now. */ #endif if(renderThread != NULL) /* hopefully just a zombie at this point... */ { Com_Printf("Already a render thread? Trying to clean it up...\n"); GLimp_ShutdownRenderThread(); } smpMutex = SDL_CreateMutex(); if(smpMutex == NULL) { Com_Printf("smpMutex creation failed: %s\n", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } renderCommandsEvent = SDL_CreateCond(); if(renderCommandsEvent == NULL) { Com_Printf("renderCommandsEvent creation failed: %s\n", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } renderCompletedEvent = SDL_CreateCond(); if(renderCompletedEvent == NULL) { Com_Printf("renderCompletedEvent creation failed: %s\n", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } renderThreadFunction = function; renderThread = SDL_CreateThread(GLimp_RenderThreadWrapper, NULL); if(renderThread == NULL) { ri.Printf(PRINT_ALL, "SDL_CreateThread() returned %s", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } else { // tma 01/09/07: don't think this is necessary anyway? // // !!! FIXME: No detach API available in SDL! //ret = pthread_detach( renderThread ); //if ( ret ) { //ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) ); //} } return qtrue; }
void CImageClient::run(CRawImage *im) { image = im; codec = new CDecoder(imageSem,im); thread = SDL_CreateThread(StartThread,static_cast<void*>(this)); }
thread::thread(const std::string& name, boost::function<void()> fn) : fn_(fn), thread_(SDL_CreateThread(call_boost_function, name.c_str(), new boost::function<void()>(fn_))) {}
void Personaje::caminar(unsigned int destX, unsigned int destY){ if ( thrAccion ) SDL_KillThread(thrAccion); this->destX=destX; this->destY=destY; this->thrAccion = SDL_CreateThread(Personaje::entCaminar,this); }
int main(int argc, char *argv[]) { int success; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Simple MessageBox", "This is a simple error MessageBox", NULL); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); quit(1); } success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Simple MessageBox", "This is a simple MessageBox with a newline:\r\nHello world!", NULL); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); quit(1); } /* Google says this is Traditional Chinese for "beef with broccoli" */ success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "UTF-8 Simple MessageBox", "Unicode text: '牛肉西蘭花' ...", NULL); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); quit(1); } /* Google says this is Traditional Chinese for "beef with broccoli" */ success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "UTF-8 Simple MessageBox", "Unicode text and newline:\r\n'牛肉西蘭花'\n'牛肉西蘭花'", NULL); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); quit(1); } button_messagebox(NULL); /* Test showing a message box from a background thread. On Mac OS X, the video subsystem needs to be initialized for this to work, since the message box events are dispatched by the Cocoa subsystem on the main thread. */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video subsystem: %s\n", SDL_GetError()); return (1); } { int status = 0; SDL_Event event; intptr_t eventNumber = SDL_RegisterEvents(1); SDL_Thread* thread = SDL_CreateThread(&button_messagebox, "MessageBox", (void*)eventNumber); while (SDL_WaitEvent(&event)) { if (event.type == eventNumber) { break; } } SDL_WaitThread(thread, &status); SDL_Log("Message box thread return %i\n", status); } /* Test showing a message box with a parent window */ { SDL_Event event; SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0); success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Simple MessageBox", "This is a simple error MessageBox with a parent window", window); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); quit(1); } while (SDL_WaitEvent(&event)) { if (event.type == SDL_QUIT || event.type == SDL_KEYUP) { break; } } } SDL_Quit(); return (0); }
void Drawing::nonBlockingShowWindow() { SDL_Thread * thread = SDL_CreateThread( Drawing::showWindowThread, "show window", this); }
void Drawing::nonBlockRayTracingWorld(World * world_ptr) { SDL_Thread * thread = SDL_CreateThread( Drawing::realRayTracingThread, "ray tracing", world_ptr); }
void Drawing::nonBlockingRayTracing() { SDL_Thread * thread = SDL_CreateThread( Drawing::rayTracingThread, "ray tracing", this); }
int stream_component_open(VideoState *is, int stream_index) { AVFormatContext *pFormatCtx = is->pFormatCtx; AVCodecContext *codecCtx; AVCodec *codec; SDL_AudioSpec wanted_spec, spec; if(stream_index < 0 || stream_index >= pFormatCtx->nb_streams) { return -1; } // Get a pointer to the codec context for the video stream codecCtx = pFormatCtx->streams[stream_index]->codec; if(codecCtx->codec_type == CODEC_TYPE_AUDIO) { // Set audio settings from codec info wanted_spec.freq = codecCtx->sample_rate; wanted_spec.format = AUDIO_S16SYS; wanted_spec.channels = codecCtx->channels; wanted_spec.silence = 0; wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; wanted_spec.callback = audio_callback; wanted_spec.userdata = is; if(SDL_OpenAudio(&wanted_spec, &spec) < 0) { fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError()); return -1; } is->audio_hw_buf_size = spec.size; } codec = avcodec_find_decoder(codecCtx->codec_id); if(!codec || (avcodec_open(codecCtx, codec) < 0)) { fprintf(stderr, "Unsupported codec!\n"); return -1; } switch(codecCtx->codec_type) { case CODEC_TYPE_AUDIO: is->audioStream = stream_index; is->audio_st = pFormatCtx->streams[stream_index]; is->audio_buf_size = 0; is->audio_buf_index = 0; memset(&is->audio_pkt, 0, sizeof(is->audio_pkt)); packet_queue_init(&is->audioq); SDL_PauseAudio(0); break; case CODEC_TYPE_VIDEO: is->videoStream = stream_index; is->video_st = pFormatCtx->streams[stream_index]; is->frame_timer = (double)av_gettime() / 1000000.0; is->frame_last_delay = 40e-3; is->video_current_pts_time = av_gettime(); packet_queue_init(&is->videoq); is->video_tid = SDL_CreateThread(video_thread, is); codecCtx->get_buffer = our_get_buffer; codecCtx->release_buffer = our_release_buffer; break; default: break; } return 0; }
thread::thread(boost::function<void()> fn) : fn_(fn), thread_(SDL_CreateThread(call_boost_function, new boost::function<void()>(fn_))) {}
/* * This thread will read the buttons in an interrupt like fashion, and * also initializes SDL_INIT_VIDEO and the surfaces * * it must be done in the same thread (at least on windows) because events only * work in the thread which called SDL_Init(SubSystem) with SDL_INIT_VIDEO * * This is an SDL thread and relies on preemptive behavoir of the host **/ static int sdl_event_thread(void * param) { SDL_InitSubSystem(SDL_INIT_VIDEO); #if (CONFIG_PLATFORM & PLATFORM_MAEMO) SDL_sem *wait_for_maemo_startup; #endif SDL_Surface *picture_surface = NULL; int width, height; int depth; Uint32 flags; /* Try and load the background image. If it fails go without */ if (background) { picture_surface = SDL_LoadBMP("UI256.bmp"); if (picture_surface == NULL) { background = false; DEBUGF("warn: %s\n", SDL_GetError()); } } /* Set things up */ if (background) { width = UI_WIDTH; height = UI_HEIGHT; } else { #ifdef HAVE_REMOTE_LCD if (showremote) { width = SIM_LCD_WIDTH > SIM_REMOTE_WIDTH ? SIM_LCD_WIDTH : SIM_REMOTE_WIDTH; height = SIM_LCD_HEIGHT + SIM_REMOTE_HEIGHT; } else #endif { width = SIM_LCD_WIDTH; height = SIM_LCD_HEIGHT; } } depth = LCD_DEPTH; if (depth < 8) depth = 16; flags = SDL_HWSURFACE|SDL_DOUBLEBUF; #if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) /* Fullscreen mode for maemo app */ flags |= SDL_FULLSCREEN; #endif if ((gui_surface = SDL_SetVideoMode(width * display_zoom, height * display_zoom, depth, flags)) == NULL) { panicf("%s", SDL_GetError()); } #if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) /* Hide mouse cursor on real touchscreen device */ SDL_ShowCursor(SDL_DISABLE); #endif SDL_WM_SetCaption(UI_TITLE, NULL); if (background && picture_surface != NULL) SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL); /* let system_init proceed */ SDL_SemPost((SDL_sem *)param); #if (CONFIG_PLATFORM & PLATFORM_MAEMO) /* Start maemo thread: Listen to display on/off events and battery monitoring */ wait_for_maemo_startup = SDL_CreateSemaphore(0); /* 0-count so it blocks */ SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, wait_for_maemo_startup); #endif /* * finally enter the button loop */ gui_message_loop(); #if (CONFIG_PLATFORM & PLATFORM_MAEMO) /* Ensure maemo thread is up and running */ SDL_SemWait(wait_for_maemo_startup); SDL_DestroySemaphore(wait_for_maemo_startup); #if (CONFIG_PLATFORM & PLATFORM_MAEMO5) pcm_shutdown_gstreamer(); #endif g_main_loop_quit (maemo_main_loop); g_main_loop_unref(maemo_main_loop); SDL_WaitThread(maemo_thread, NULL); #endif if(picture_surface) SDL_FreeSurface(picture_surface); /* Order here is relevent to prevent deadlocks and use of destroyed sync primitives by kernel threads */ #ifdef HAVE_SDL_THREADS sim_thread_shutdown(); /* not needed for native threads */ #endif return 0; }
int main(int argc, char **argv) { optproc(argc, argv, &opts); if(audio_init(&opts) < 0) exit(1); SDL_Surface *screen = sdl_setup(&opts, IM_SIZE); im_w = screen->w - screen->w%16; im_h = screen->h - screen->h%16; printf("running with %dx%d bufs\n", im_w, im_h); if(strcmp(opts.map_name, "rational") == 0) { map_func = soft_map_rational_interp; if(opts.quality >= 1) map_func = soft_map_rational; } else if(strcmp(opts.map_name, "butterfly") == 0) { // map_func = soft_map_butterfly_interp; // if(opts.quality >= 1) map_func = soft_map_butterfly; } else if(opts.quality >= 1) map_func = soft_map; maxsrc = maxsrc_new(im_w, im_h); struct pal_ctx *pal_ctx = pal_ctx_new(screen->format->BitsPerPixel == 8); uint16_t *map_surf[3]; void *map_surf_mem = aligned_alloc(64, 3 * im_w * im_h * sizeof(uint16_t)); for(int i=0; i<3; i++) map_surf[i] = map_surf_mem + i * im_w * im_h * sizeof(uint16_t); memset(map_surf_mem, 0, 3 * im_w * im_h * sizeof(uint16_t)); tribuf *map_tb = tribuf_new((void **)map_surf, 1); int beats = 0; int frmcnt = 0; int lastdrawn=0; SDL_Thread *map_thread = SDL_CreateThread((void *)&run_map_thread, map_tb); SDL_Delay(100); uint32_t frametimes[FPS_HIST_LEN]; for(int i=1; i<FPS_HIST_LEN; i++) frametimes[i] = 0; uint32_t totframetime = frametimes[0] = MIN(1000/opts.draw_rate, 1); Uint32 tick0 = SDL_GetTicks(); Uint32 lastpalstep, lastupdate, fps_oldtime; fps_oldtime = lastpalstep = lastupdate = tick0; SDL_Event event; while(SDL_PollEvent(&event) >= 0) { if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) { break; } else if(tribuf_check_fresh(map_tb)) { Uint32 now = SDL_GetTicks(); if(now - lastpalstep >= 2048/256) { // want pallet switch to take ~2 seconds pal_ctx_step(pal_ctx, IMIN((now - lastpalstep)*256/2048, 64)); lastpalstep = now; } pallet_blit_SDL(screen, tribuf_get_read(map_tb), im_w, im_h, pal_ctx_get_active(pal_ctx)); tribuf_finish_read(map_tb); char buf[64]; sprintf(buf,"%6.1f FPS %6.1f UPS %6.1f", map_fps, FPS_HIST_LEN*1000.0f/totframetime, maxfrms*1000.0f/(now-tick0)); DrawText(screen, buf); SDL_Flip(screen); int newbeat = beat_get_count(); if(newbeat != beats) pal_ctx_start_switch(pal_ctx, newbeat); beats = newbeat; now = SDL_GetTicks(); int delay = (tick0 + frmcnt*1000/opts.draw_rate) - now; if(delay > 0) SDL_Delay(delay); totframetime -= frametimes[frmcnt%FPS_HIST_LEN]; totframetime += (frametimes[frmcnt%FPS_HIST_LEN] = now - fps_oldtime); fps_oldtime = now; frmcnt++; } else { SDL_Delay(1000/opts.draw_rate/2); // wait half a frame and hope we get a new buffer } } running = 0; int status; SDL_WaitThread(map_thread, &status); aligned_free(map_surf_mem); audio_shutdown(); SDL_Quit(); return 0; }
WZ_THREAD *wzThreadCreate(int (*threadFunc)(void *), void *data) { return (WZ_THREAD *)SDL_CreateThread(threadFunc, "wzThread", data); }
bool GameManager::init() { // success flag auto success = true; // init SDL video and audio 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 the window window.window = SDL_CreateWindow("Breakout", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if (window.window == nullptr) { printf("Window could not be created SDL ERROR: %s\n", SDL_GetError()); success = false; } else { // create the renderer for the window gRenderer = SDL_CreateRenderer(window.window, -1, SDL_RENDERER_ACCELERATED); if (gRenderer == nullptr) { printf("Renderer could not be created SDL ERROR %s\n", SDL_GetError()); success = false; } else { // init png loading int imgFlags = IMG_INIT_PNG; if (!(IMG_Init(imgFlags) & imgFlags)) { printf("SDL_Image could not be initalized, SDL_Image ERROR: %s\n", IMG_GetError()); success = false; } else { // init SDL_mixer success = bgMusic.init(); } } } } //Initialize SDL_ttf if (TTF_Init() == -1) { printf("SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError()); success = false; } // Initalizing default constructor of pieces, utilizing copy and move constructors Piece defaultInit; for (auto i = 0; i < PIECES; i++) { pieces.push_back(defaultInit); } // initialize the pieces level 0 initBlocks(pieces, level); threadID = SDL_CreateThread(threading_.threadedFunction, "PrintingThread", static_cast<void*>(&ball)); threadRunning = true; return success; }
static void PlayGame() { Uint8 *keystate; int quit = 0; int turn; int prev_ticks = 0, cur_ticks = 0; /* for keeping track of timing */ int awaiting_respawn = 0; /* framerate counter variables */ int start_time, end_time; int frames_drawn = 0; /* respawn timer */ int respawn_timer = -1; prev_ticks = SDL_GetTicks(); start_time = time(NULL); /* Reset the score counters. */ player.score = 0; opponent.score = 0; /* Start sound playback. */ StartAudio(); StartMusic(); /* Start the music update thread. */ music_update_thread = SDL_CreateThread(UpdateMusicThread, NULL); if (music_update_thread == NULL) { printf("Unable to start music update thread.\n"); } /* Start the game! */ while ((quit == 0) && network_ok) { /* Determine how many milliseconds have passed since the last frame, and update our motion scaling. */ prev_ticks = cur_ticks; cur_ticks = SDL_GetTicks(); time_scale = (double)(cur_ticks-prev_ticks)/30.0; /* Update SDL's internal input state information. */ SDL_PumpEvents(); /* Grab a snapshot of the keyboard. */ keystate = SDL_GetKeyState(NULL); /* Lock the mutex so we can access the player's data. */ SDL_LockMutex(player_mutex); /* If this is a network game, take note of variables set by the network thread. These are handled differently for a scripted opponent. */ if (opponent_type == OPP_NETWORK) { /* Has the opponent respawned? */ if (network_opponent_respawn) { printf("Remote player has respawned.\n"); opponent.shields = 100; network_opponent_respawn = 0; awaiting_respawn = 0; } /* Has the local player been hit? */ if (local_player_hit) { local_player_hit--; player.shields -= PHASER_DAMAGE; ShowPhaserHit(&player); /* No need to check for death, the other computer will tell us. */ } } /* Update phasers. */ player.firing -= time_scale; if (player.firing < 0) player.firing = 0; opponent.firing -= time_scale; if (opponent.firing < 0) opponent.firing = 0; ChargePhasers(&player); /* If the local player is destroyed, the respawn timer will start counting. During this time the controls are disabled and explosion sequence occurs. */ if (respawn_timer >= 0) { respawn_timer++; if (respawn_timer >= ((double)RESPAWN_TIME / time_scale)) { respawn_timer = -1; InitPlayer(&player); /* Set the local_player_respawn flag so the network thread will notify the opponent of the respawn. */ local_player_respawn = 1; SetStatusMessage("GOOD LUCK, WARRIOR!"); } } /* Respond to input and network events, but not if we're in a respawn. */ if (respawn_timer == -1) { if (keystate[SDLK_q] || keystate[SDLK_ESCAPE]) quit = 1; /* Left and right arrow keys control turning. */ turn = 0; if (keystate[SDLK_LEFT]) turn += 10; if (keystate[SDLK_RIGHT]) turn -= 10; /* Forward and back arrow keys activate thrusters. */ player.accel = 0; if (keystate[SDLK_UP]) player.accel = PLAYER_FORWARD_THRUST; if (keystate[SDLK_DOWN]) player.accel = PLAYER_REVERSE_THRUST; /* Spacebar fires phasers. */ if (keystate[SDLK_SPACE]) { if (CanPlayerFire(&player)) { FirePhasers(&player); /* If it's a hit, either notify the opponent or exact the damage. Create a satisfying particle burst. */ if (!awaiting_respawn && CheckPhaserHit(&player,&opponent)) { ShowPhaserHit(&opponent); DamageOpponent(); /* If that killed the opponent, set the "awaiting respawn" state, to prevent multiple kills. */ if (opponent.shields <= 0 && opponent_type == OPP_NETWORK) awaiting_respawn = 1; } } } /* Turn. */ player.angle += turn * time_scale; if (player.angle < 0) player.angle += 360; if (player.angle >= 360) player.angle -= 360; /* If this is a network game, the remote player will tell us if we've died. Otherwise we have to check for failed shields. */ if (((opponent_type == OPP_NETWORK) && local_player_dead) || (player.shields <= 0)) { printf("Local player has been destroyed.\n"); local_player_dead = 0; /* Kaboom! */ KillPlayer(); /* Respawn. */ respawn_timer = 0; } } /* If this is a player vs. computer game, give the computer a chance. */ if (opponent_type == OPP_COMPUTER) { if (RunGameScript() != 0) { fprintf(stderr, "Ending game due to script error.\n"); quit = 1; } /* Check for phaser hits against the player. */ if (opponent.firing) { if (CheckPhaserHit(&opponent,&player)) { ShowPhaserHit(&player); player.shields -= PHASER_DAMAGE; /* Did that destroy the player? */ if (respawn_timer < 0 && player.shields <= 0) { KillPlayer(); respawn_timer = 0; } } } ChargePhasers(&opponent); UpdatePlayer(&opponent); } /* Update the player's position. */ UpdatePlayer(&player); /* Update the status information. */ SetPlayerStatusInfo(player.score, player.shields, player.charge); SetOpponentStatusInfo(opponent.score, opponent.shields); /* Make the camera follow the player (but impose limits). */ camera_x = player.world_x - SCREEN_WIDTH/2; camera_y = player.world_y - SCREEN_HEIGHT/2; if (camera_x < 0) camera_x = 0; if (camera_x >= WORLD_WIDTH-SCREEN_WIDTH) camera_x = WORLD_WIDTH-SCREEN_WIDTH-1; if (camera_y < 0) camera_y = 0; if (camera_y >= WORLD_HEIGHT-SCREEN_HEIGHT) camera_y = WORLD_HEIGHT-SCREEN_HEIGHT-1; /* Update the particle system. */ UpdateParticles(); /* Keep OpenAL happy. */ UpdateAudio(&player, &opponent); /* Redraw everything. */ DrawBackground(screen, camera_x, camera_y); DrawParallax(screen, camera_x, camera_y); DrawParticles(screen, camera_x, camera_y); if (opponent.firing) DrawPhaserBeam(&opponent, screen, camera_x, camera_y); if (player.firing) DrawPhaserBeam(&player, screen, camera_x, camera_y); if (respawn_timer < 0) DrawPlayer(&player); if (!awaiting_respawn) DrawPlayer(&opponent); UpdateStatusDisplay(screen); /* Release the mutex so the networking system can get it. It doesn't stay unlocked for very long, but the networking system should still have plenty of time. */ SDL_UnlockMutex(player_mutex); /* Flip the page. */ SDL_Flip(screen); frames_drawn++; } end_time = time(NULL); if (start_time == end_time) end_time++; /* Display the average framerate. */ printf("Drew %i frames in %i seconds, for a framerate of %.2f fps.\n", frames_drawn, end_time-start_time, (float)frames_drawn/(float)(end_time-start_time)); /* Terminate the music update thread. */ if (music_update_thread != NULL) { SDL_KillThread(music_update_thread); music_update_thread = NULL; } /* Stop audio playback. */ StopAudio(); StopMusic(); }
int NET2_Init() { if (initialized) { return 0; } #ifndef WIN32 // SIGPIPE has to be ignored so that NET2 can handle broken // connections without raising a program wide exception. SDL_net // "should" do this so that it can handle exception properly, but it // doesn't. signal(SIGPIPE, SIG_IGN); // work around for bug in SDL_net #endif error = 0; errorSocket = -1; doneYet = 0; dataLock = SDL_CreateMutex(); if (NULL == dataLock) { setError("NET2: can't create a mutex", -1); return -1; } sdlNetLock = SDL_CreateMutex(); if (NULL == sdlNetLock) { setError("NET2: can't create a mutex", -1); return -1; } dataWait = SDL_CreateCond(); if (NULL == dataWait) { setError("NET2: can't create a condition variable", -1); return -1; } InitSockets(maxSockets); udpSendSocket = snUDPOpen(0); if (NULL == udpSendSocket) { setError("NET2: can't open the UDP send socket", -1); return -1; } processSockets = SDL_CreateThread(PumpNetworkEvents, NULL); if (NULL == processSockets) { setError("NET2: can't start the network thread", -1); return -1; } //printf("root=%d thread=%d\n", SDL_ThreadID(), SDL_GetThreadID(processSockets)); fflush(NULL); initialized = 1; return 0; }
bool Movie::Setup() { if (!IsRecording()) return false; if (!av) return false; bool success = true; std::string err_msg; alephone::Screen *scr = alephone::Screen::instance(); view_rect = scr->window_rect(); if (MainScreenIsOpenGL()) view_rect.y = scr->height() - (view_rect.y + view_rect.h); view_rect.x *= scr->pixel_scale(); view_rect.y *= scr->pixel_scale(); view_rect.w *= scr->pixel_scale(); view_rect.h *= scr->pixel_scale(); temp_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, view_rect.w, view_rect.h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0); success = (temp_surface != NULL); if (!success) err_msg = "Could not create SDL surface"; Mixer *mx = Mixer::instance(); av_register_all(); avcodec_register_all(); // Open output file AVOutputFormat *fmt; if (success) { fmt = av_guess_format("webm", NULL, NULL); success = fmt; if (!success) err_msg = "Could not find output format"; } if (success) { av->fmt_ctx = avformat_alloc_context(); success = av->fmt_ctx; if (!success) err_msg = "Could not allocate movie format context"; } if (success) { av->fmt_ctx->oformat = fmt; strncpy(av->fmt_ctx->filename, moviefile.c_str(), 1024); success = (0 <= avio_open(&av->fmt_ctx->pb, av->fmt_ctx->filename, AVIO_FLAG_WRITE)); if (!success) err_msg = "Could not open movie file for writing"; } // Open output video stream AVCodec *video_codec; AVStream *video_stream; if (success) { video_codec = avcodec_find_encoder(AV_CODEC_ID_VP8); success = video_codec; if (!success) err_msg = "Could not find VP8 encoder"; } if (success) { video_stream = avformat_new_stream(av->fmt_ctx, video_codec); success = video_stream; if (!success) err_msg = "Could not open output video stream"; } if (success) { video_stream->codec->codec_id = video_codec->id; video_stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; video_stream->codec->width = view_rect.w; video_stream->codec->height = view_rect.h; video_stream->codec->time_base = (AVRational){1, TICKS_PER_SECOND}; video_stream->codec->pix_fmt = AV_PIX_FMT_YUV420P; video_stream->codec->flags |= CODEC_FLAG_CLOSED_GOP; video_stream->codec->thread_count = get_cpu_count(); if (av->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) video_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; av->video_stream_idx = video_stream->index; // tuning options int vq = graphics_preferences->movie_export_video_quality; video_stream->codec->bit_rate = ScaleQuality(vq, 100*1024, 1024*1024, 10*1024*1024); video_stream->codec->qmin = ScaleQuality(vq, 10, 4, 0); video_stream->codec->qmax = ScaleQuality(vq, 63, 63, 50); std::string crf = boost::lexical_cast<std::string>(ScaleQuality(vq, 63, 10, 4)); av_opt_set(video_stream->codec->priv_data, "crf", crf.c_str(), 0); success = (0 <= avcodec_open2(video_stream->codec, video_codec, NULL)); if (!success) err_msg = "Could not open video codec"; } if (success) { av->video_bufsize = view_rect.w * view_rect.h * 4 + 10000; av->video_buf = static_cast<uint8_t *>(av_malloc(av->video_bufsize)); success = av->video_buf; if (!success) err_msg = "Could not allocate video buffer"; } if (success) { #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,0) av->video_frame = avcodec_alloc_frame(); #else av->video_frame = av_frame_alloc(); #endif success = av->video_frame; if (!success) err_msg = "Could not allocate video frame"; } if (success) { int numbytes = avpicture_get_size(video_stream->codec->pix_fmt, view_rect.w, view_rect.h); av->video_data = static_cast<uint8_t *>(av_malloc(numbytes)); success = av->video_data; if (!success) err_msg = "Could not allocate video data buffer"; } if (success) { avpicture_fill(reinterpret_cast<AVPicture *>(av->video_frame), av->video_data, video_stream->codec->pix_fmt, view_rect.w, view_rect.h); } // Open output audio stream AVCodec *audio_codec; AVStream *audio_stream; if (success) { audio_codec = avcodec_find_encoder(AV_CODEC_ID_VORBIS); success = audio_codec; if (!success) err_msg = "Could not find Vorbis encoder"; } if (success) { audio_stream = avformat_new_stream(av->fmt_ctx, audio_codec); success = audio_stream; if (!success) err_msg = "Could not open output audio stream"; } if (success) { audio_stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; audio_stream->codec->codec_id = audio_codec->id; audio_stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; audio_stream->codec->sample_rate = mx->obtained.freq; audio_stream->codec->time_base = (AVRational){1, mx->obtained.freq}; audio_stream->codec->channels = 2; if (av->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) audio_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; av->audio_stream_idx = audio_stream->index; // tuning options int aq = graphics_preferences->movie_export_audio_quality; audio_stream->codec->global_quality = FF_QP2LAMBDA * (aq / 10); audio_stream->codec->flags |= CODEC_FLAG_QSCALE; audio_stream->codec->sample_fmt = AV_SAMPLE_FMT_FLTP; success = (0 <= avcodec_open2(audio_stream->codec, audio_codec, NULL)); if (!success) err_msg = "Could not open audio codec"; } if (success) { #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,0) av->audio_frame = avcodec_alloc_frame(); #else av->audio_frame = av_frame_alloc(); #endif success = av->audio_frame; if (!success) err_msg = "Could not allocate audio frame"; } if (success) { av->audio_fifo = av_fifo_alloc(262144); success = av->audio_fifo; if (!success) err_msg = "Could not allocate audio fifo"; } if (success) { av->audio_data = reinterpret_cast<uint8_t *>(av_malloc(524288)); success = av->audio_data; if (!success) err_msg = "Could not allocate audio data buffer"; } if (success) { av->audio_data_conv = reinterpret_cast<uint8_t *>(av_malloc(524288)); success = av->audio_data_conv; if (!success) err_msg = "Could not allocate audio conversion buffer"; } // initialize conversion context if (success) { av->sws_ctx = sws_getContext(temp_surface->w, temp_surface->h, AV_PIX_FMT_RGB32, video_stream->codec->width, video_stream->codec->height, video_stream->codec->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL); success = av->sws_ctx; if (!success) err_msg = "Could not create video conversion context"; } // Start movie file if (success) { video_stream->time_base = (AVRational){1, TICKS_PER_SECOND}; audio_stream->time_base = (AVRational){1, mx->obtained.freq}; avformat_write_header(av->fmt_ctx, NULL); } // set up our threads and intermediate storage if (success) { videobuf.resize(av->video_bufsize); audiobuf.resize(2 * 2 * mx->obtained.freq / 30); } if (success) { encodeReady = SDL_CreateSemaphore(0); fillReady = SDL_CreateSemaphore(1); stillEncoding = true; success = encodeReady && fillReady; if (!success) err_msg = "Could not create movie thread semaphores"; } if (success) { encodeThread = SDL_CreateThread(Movie_EncodeThread, "MovieSetup_encodeThread", this); success = encodeThread; if (!success) err_msg = "Could not create movie encoding thread"; } if (!success) { StopRecording(); std::string full_msg = "Your movie could not be exported. ("; full_msg += err_msg; full_msg += ".)"; logError(full_msg.c_str()); alert_user(full_msg.c_str()); } av->inited = success; return success; }
//! starts the thread void ThreadSDL::Start(ThreadFunc threadFunc, void* pParam /*= 0*/) { typedef int SDLThreadFunc(void* pParam); m_pThread = SDL_CreateThread((SDLThreadFunc*)threadFunc, 0, pParam); }
int main(int argn, char** args) { srandom(time(NULL)); printf("main: STARTED\n"); printf("main: init SDL\n"); if(SDL_Init(SDL_INIT_EVENTTHREAD)!=0) { fprintf(stderr, "main: FATAL ERROR: SDL_Init fails: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } if(atexit(SDL_Quit)!=0) { fprintf(stderr, "main: FATAL ERROR: couldn't set exit function.\n"); exit(EXIT_FAILURE); } if(SDLNet_Init()!=0) { fprintf(stderr, "main: FATAL ERROR: SDLNet_Init fails: %s\n", SDLNet_GetError()); exit(EXIT_FAILURE); } FILE* file; char* path=new char[100]; /* // cyberspace_server_data.version_major=0; // cyberspace_server_data.version_minor=1; cyberspace_server_data.accounts=0; int filed; sprintf(path, "server_data.now"); if((file=fopen(path, "w+"))==NULL) { perror("perror:\n"); fprintf(stderr, "FATAL ERROR: unable to fopen file \"%s\"\n", path); exit(EXIT_FAILURE); } if(fwrite(&cyberspace_server_data, sizeof(cyberspace_server_data), 1, file)!=1) { fprintf(stderr, "FATAL ERROR: unable to fwrite file \"%s\"\n", path); exit(EXIT_FAILURE); } if((filed=fileno(file))==-1) { fprintf(stderr, "FATAL ERROR: unable to fileno file \"%s\"\n", path); exit(EXIT_FAILURE); } if(fdatasync(filed)!=0) { fprintf(stderr, "FATAL ERROR: unable to fdatasync file \"%s\"\n", path); exit(EXIT_FAILURE); } if(fclose(file)!=0) { fprintf(stderr, "FATAL ERROR: unable to fclose file \"%s\"\n", path); exit(EXIT_FAILURE); } printf("main: ONCE DONE\n"); exit(EXIT_FAILURE); */ sprintf(path, "server_data.now"); if((file=fopen(path, "r+"))==NULL) { perror("perror:\n"); fprintf(stderr, "FATAL ERROR: unable to fopen file \"%s\"\n", path); exit(EXIT_FAILURE); } if(fread(&cyberspace_server_data, sizeof(cyberspace_server_data), 1, file)!=1) { fprintf(stderr, "FATAL ERROR: unable to fread file \"%s\"\n", path); exit(EXIT_FAILURE); } if(fclose(file)!=0) { fprintf(stderr, "FATAL ERROR: unable to fclose file \"%s\"\n", path); exit(EXIT_FAILURE); } printf("main: server_data read\n"); delete[] path; cyberspace_mutex_server_data_sdl=SDL_CreateMutex(); /* pthread_attr_t thread_detached; pthread_attr_init(&thread_detached); pthread_attr_setdetachstate(&thread_detached, PTHREAD_CREATE_DETACHED); */ /* pthread_t physical_engine; if(pthread_create(&physical_engine, &thread_detached, cyberspace_physical_engine_tf, NULL)!=0) { fprintf(stderr, "FATAL ERROR: physical_engine thread creation fails.\n"); exit(EXIT_FAILURE); } */ SDL_Thread* physical_engine_thread_sdl; physical_engine_thread_sdl=SDL_CreateThread(cyberspace_physical_engine_tf_sdl, NULL); if(physical_engine_thread_sdl==NULL) { fprintf(stderr, "FATAL ERROR: physical_engine thread creation fails: %s.\n", SDL_GetError()); exit(EXIT_FAILURE); } /* pthread_t frontdoor; if(pthread_create(&frontdoor, &thread_detached, cyberspace_frontdoor_tf, NULL)!=0) { fprintf(stderr, "FATAL ERROR: frontdoor thread creation fails.\n"); exit(EXIT_FAILURE); } */ SDL_Thread* frontdoor_thread_sdl; frontdoor_thread_sdl=SDL_CreateThread(cyberspace_frontdoor_tf_sdl, NULL); if(frontdoor_thread_sdl==NULL) { fprintf(stderr, "FATAL ERROR: frontdoor thread creation fails: %s.\n", SDL_GetError()); exit(EXIT_FAILURE); } /* pthread_t frontdoor_inputchannel; if(pthread_create(&frontdoor_inputchannel, &thread_detached, cyberspace_frontdoor_inputchannel_tf, NULL)!=0) { fprintf(stderr, "FATAL ERROR: frontdoor_inputchannel thread creation fails.\n"); exit(EXIT_FAILURE); } */ SDL_Thread* frontdoor_inputchannel_thread_sdl; frontdoor_inputchannel_thread_sdl=SDL_CreateThread(cyberspace_frontdoor_inputchannel_tf_sdl, NULL); if(frontdoor_inputchannel_thread_sdl==NULL) { fprintf(stderr, "FATAL ERROR: frontdoor_inputchannel thread creation fails: %s.\n", SDL_GetError()); exit(EXIT_FAILURE); } /* pthread_t statistics; if(pthread_create(&statistics, &thread_detached, cyberspace_statistics_tf, NULL)!=0) { fprintf(stderr, "FATAL ERROR: statistics thread creation fails.\n"); exit(EXIT_FAILURE); } */ SDL_Thread* statistics_thread_sdl; statistics_thread_sdl=SDL_CreateThread(cyberspace_statistics_tf_sdl, NULL); if(statistics_thread_sdl==NULL) { fprintf(stderr, "FATAL ERROR: statistics thread creation fails: %s.\n", SDL_GetError()); exit(EXIT_FAILURE); } SDL_WaitThread(physical_engine_thread_sdl, NULL); SDL_WaitThread(frontdoor_thread_sdl, NULL); SDL_WaitThread(frontdoor_inputchannel_thread_sdl, NULL); SDL_WaitThread(statistics_thread_sdl, NULL); printf("main: ENDING\n"); // pthread_exit(NULL); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { if(pthread_mutex_init(&SimParams::Lock, NULL) != 0) Bug(true, "Failed to make mutex"); SimParams ¶ms = Initialize(); StartInfo *info = new StartInfo(argc, argv, params); SDL_Thread *guiThread = SDL_CreateThread(&StartGUI, info); TGRender render(0,0); TGResourceManager rec; TGResource vs = rec.CreateResource(TGResourceType::Shader, "water.vs"); TGResource fs = rec.CreateResource(TGResourceType::Shader, "water.fs"); TGResource bfs = rec.CreateResource(TGResourceType::Shader, "black.fs"); TGResource envvs = rec.CreateResource(TGResourceType::Shader, "envshader.vs"); TGResource envfs = rec.CreateResource(TGResourceType::Shader, "envshader.fs"); TGResource colvs = rec.CreateResource(TGResourceType::Shader, "colors.vs"); TGResource colfs = rec.CreateResource(TGResourceType::Shader, "colors.fs"); TGResource cvs = rec.CreateResource(TGResourceType::Shader, "cube.vs"); TGResource cfs = rec.CreateResource(TGResourceType::Shader, "cube.fs"); Debug("Got shaders"); Create(rec.GetData(vs).c_str(), rec.GetData(fs).c_str(), rec.GetData(bfs).c_str(), rec.GetData(envvs).c_str(), rec.GetData(envfs).c_str(), rec.GetData(colvs).c_str(), rec.GetData(colfs).c_str(), rec.GetData(cvs).c_str(), rec.GetData(cfs).c_str()); ChangeSize(render.GetSize().Width, render.GetSize().Height); bool running = true; bool mouse1Down = false; int clickMovement = 0; while(running) { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: running = false; break; case SDL_VIDEORESIZE: render.Resize(event.resize.w, event.resize.h); ChangeSize(event.resize.w, event.resize.h); break; case SDL_MOUSEMOTION: clickMovement += abs(event.motion.xrel) + abs(event.motion.yrel); //Debug("Got mouse move with dx=%d, dy=%d", event.motion.xrel, event.motion.yrel); if(mouse1Down) Orbit(event.motion.xrel, event.motion.yrel); break; case SDL_MOUSEBUTTONDOWN: Debug("Got mouse down on button %d", event.button.button); if(event.button.button == 1) { clickMovement = 0; mouse1Down = true; } break; case SDL_MOUSEBUTTONUP: //Debug("Got mouse up on button %d", event.button.button); if(event.button.button == 1) { if(clickMovement < 5) { Touch(event.button.x, event.button.y); } mouse1Down = false; } break; default: break; } } Draw(); render.Present(); } if(pthread_mutex_destroy(&SimParams::Lock) != 0) Bug(true, "Failed to destroy mutex"); return 0; }
int audio_thr(LPVOID lpParam) { int iRet = -1; //音频测试,播放文件显示波形 AVFormatContext * pFmtCtx = NULL; AVFormatContext * pFOutmtCtx = NULL; AVInputFormat * pAudioInputFmt = NULL; AVOutputFormat * pAudioOutputFmt = NULL; AVCodecContext * pOutputCodecCtx = NULL; AVPacket * pAudioPacket = NULL; int iAudioIndex = -1; int data_size = 0; int resampled_data_size = 0; uint8_t * out_buffer = 0; int64_t dec_channel_layout = 0; double pts; CLS_DlgStreamPusher* pThis = (CLS_DlgStreamPusher*)lpParam; if (pThis == NULL || pThis->m_pStreamInfo == NULL){ TRACE("audio_thr--pThis == NULL || pThis->m_pStreamInfo == NULL\n"); return iRet; } struct_stream_info* strct_stream_info = pThis->m_pStreamInfo; pAudioInputFmt = av_find_input_format("dshow"); if (pAudioInputFmt == NULL){ TRACE("pAudioInputFmt == NULL\n"); return iRet; } char* psDevName = pThis->GetDeviceName(n_Audio); if (psDevName == NULL){ TRACE("audio_thr--psDevName == NULL"); return iRet; } if (avformat_open_input(&pFmtCtx, psDevName, pAudioInputFmt, NULL) != 0){ TRACE("avformat_open_input err!\n"); goto END; } if (avformat_find_stream_info(pFmtCtx, NULL) < 0){ TRACE("avformat_find_stream_info(pFmtCtx, NULL) < 0\n"); goto END; } for (int i = 0; i < pFmtCtx->nb_streams; i++){ if (pFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){ iAudioIndex = i; AVCodec *tmpCodec = avcodec_find_decoder(pFmtCtx->streams[i]->codec->codec_id); if (0 > avcodec_open2(pFmtCtx->streams[i]->codec, tmpCodec, NULL)){ TRACE("can not find or open decoder!\n"); } break; } } //找到音频流信息 strct_stream_info->m_pAudioStream = pFmtCtx->streams[iAudioIndex]; if (strct_stream_info->m_pAudioStream == NULL){ TRACE("strct_stream_info->m_pAudioStream == NULL\n"); goto END; } AVCodecContext *pAudioDec = strct_stream_info->m_pAudioStream->codec; if (NULL == pAudioDec){ TRACE("NULL == pAudioDec\n"); goto END; } AVCodec* audio_encoder = avcodec_find_encoder(AV_CODEC_ID_AAC); if (audio_encoder == NULL){ TRACE("audio_encoder == NULL\r\n"); goto END; } pOutputCodecCtx = avcodec_alloc_context3(audio_encoder); if (pOutputCodecCtx == NULL){ TRACE("pOutputCodecCtx == NULL"); goto END; } pOutputCodecCtx->sample_rate = pFmtCtx->streams[0]->codec->sample_rate; pOutputCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO; pOutputCodecCtx->channels = av_get_channel_layout_nb_channels(pOutputCodecCtx->channel_layout); pOutputCodecCtx->sample_fmt = audio_encoder->sample_fmts[0]; pOutputCodecCtx->codec = audio_encoder; pOutputCodecCtx->codec_tag = 0; if (avcodec_open2(pOutputCodecCtx, pOutputCodecCtx->codec, 0) < 0){ //编码器打开失败,退出程序 TRACE("音频编码器打开失败!\n"); goto END; } //SDL_AudioSpec int out_nb_samples = AUDIO_BUF_SIZE; AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; int out_buffer_size = av_samples_get_buffer_size(NULL, pOutputCodecCtx->channels, out_nb_samples, out_sample_fmt, 1); SDL_AudioSpec wanted_spec, spec; wanted_spec.freq = pOutputCodecCtx->sample_rate; wanted_spec.format = AUDIO_S16SYS; wanted_spec.channels = pOutputCodecCtx->channels; wanted_spec.silence = 0; wanted_spec.samples = out_nb_samples; wanted_spec.callback = fill_audio;//&CLS_DlgStreamPusher:: wanted_spec.userdata = strct_stream_info; strct_stream_info->m_content_out_channels = pOutputCodecCtx->channels; if (SDL_OpenAudio(&wanted_spec, &spec)<0){ TRACE("can't open audio.\n"); goto END; } int audio_hw_buf_size = spec.size; if (audio_hw_buf_size < 0){ TRACE("audio_hw_buf_size < 0\n"); return -1; } strct_stream_info->m_audio_src.fmt = AV_SAMPLE_FMT_S16; strct_stream_info->m_audio_src.freq = spec.freq; strct_stream_info->m_audio_src.channel_layout = pOutputCodecCtx->channel_layout; strct_stream_info->m_audio_src.channels = spec.channels; strct_stream_info->m_audio_hw_buf_size = audio_hw_buf_size; strct_stream_info->m_audio_tgt = strct_stream_info->m_audio_src; AVPacket pkt; out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE * 2); strct_stream_info->m_audio_refresh_tid = SDL_CreateThread(audio_refresh_thread, NULL, strct_stream_info); while (av_read_frame(pFmtCtx, &pkt) == 0 && _kbhit() == 0){ if (!pThis->m_blAudioShow){ break; } if (pkt.stream_index != iAudioIndex){ continue; } if (!strct_stream_info->m_pAudioFrame) { if (!(strct_stream_info->m_pAudioFrame = avcodec_alloc_frame())){ TRACE("!(strct_stream_info->m_pAudioFrame = avcodec_alloc_frame())\n"); goto END; } } else{ avcodec_get_frame_defaults(strct_stream_info->m_pAudioFrame); } int gotframe = -1; strct_stream_info->m_pAudioFrame = av_frame_alloc(); if (avcodec_decode_audio4(pAudioDec, strct_stream_info->m_pAudioFrame, &gotframe, &pkt) < 0){ av_frame_free(&strct_stream_info->m_pAudioFrame); TRACE("can not decoder a frame\n"); break; } av_free_packet(&pkt); if (!gotframe){ //没有获取到数据,继续下一次 continue; } strct_stream_info->m_pAudioFrame->nb_samples = 1024;//这里暂时写死值 data_size = av_samples_get_buffer_size(NULL, pOutputCodecCtx->channels, strct_stream_info->m_pAudioFrame->nb_samples, pOutputCodecCtx->sample_fmt, 1); dec_channel_layout = (pOutputCodecCtx->channel_layout && pOutputCodecCtx->channels == av_get_channel_layout_nb_channels(pOutputCodecCtx->channel_layout)) ? pOutputCodecCtx->channel_layout : av_get_default_channel_layout(pOutputCodecCtx->channels); //wanted_nb_samples = SynAudio(strct_stream_info, strct_stream_info->m_pAudioFrame->nb_samples); /*if (pOutputCodecCtx->sample_fmt != strct_stream_info->m_audio_src.fmt || dec_channel_layout != strct_stream_info->m_audio_src.channel_layout || pOutputCodecCtx->sample_rate != strct_stream_info->m_audio_src.freq){*/ swr_free(&strct_stream_info->m_audio_swr_ctx); strct_stream_info->m_audio_swr_ctx = swr_alloc_set_opts(NULL, strct_stream_info->m_audio_tgt.channel_layout, strct_stream_info->m_audio_tgt.fmt, strct_stream_info->m_audio_tgt.freq, dec_channel_layout, pOutputCodecCtx->sample_fmt, pOutputCodecCtx->sample_rate, 0, NULL); if (!strct_stream_info->m_audio_swr_ctx || swr_init(strct_stream_info->m_audio_swr_ctx) < 0){ TRACE("!pThis->m_pStreamInfstrct_stream_infoo->m_audio_swr_ctx || swr_init(strct_stream_info->m_audio_swr_ctx) < 0"); break; } strct_stream_info->m_audio_src.channel_layout = dec_channel_layout; strct_stream_info->m_audio_src.channels = pOutputCodecCtx->channels; strct_stream_info->m_audio_src.freq = pOutputCodecCtx->sample_rate; strct_stream_info->m_audio_src.fmt = pOutputCodecCtx->sample_fmt; //} if (NULL != strct_stream_info->m_audio_swr_ctx){ const uint8_t **in = (const uint8_t **)strct_stream_info->m_pAudioFrame->extended_data; uint8_t *out[] = { strct_stream_info->m_audio_buf2 }; int out_count = sizeof(strct_stream_info->m_audio_buf2) / strct_stream_info->m_audio_tgt.channels / av_get_bytes_per_sample(strct_stream_info->m_audio_tgt.fmt); int iRet = swr_convert(strct_stream_info->m_audio_swr_ctx, out, out_count, in, strct_stream_info->m_pAudioFrame->nb_samples); if (iRet < 0){ TRACE("swr_convert < 0\n"); break; } if (iRet == out_count) { TRACE("warning: audio buffer is probably too small\n"); swr_init(strct_stream_info->m_audio_swr_ctx); } strct_stream_info->m_audio_buf = strct_stream_info->m_audio_buf2; resampled_data_size = iRet * strct_stream_info->m_audio_tgt.channels * av_get_bytes_per_sample(strct_stream_info->m_audio_tgt.fmt); } else{ strct_stream_info->m_audio_buf = strct_stream_info->m_pAudioFrame->data[0]; resampled_data_size = data_size; } /* if no pts, then compute it */ pts = strct_stream_info->m_audio_clock; //*pts_ptr = pts; strct_stream_info->m_audio_clock += (double)data_size / (pAudioDec->channels * pAudioDec->sample_rate * av_get_bytes_per_sample(pAudioDec->sample_fmt)); #ifdef DEBUG { static double last_clock; /*printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n", is->audio_clock - last_clock, is->audio_clock, pts);*/ last_clock = strct_stream_info->m_audio_clock; } #endif //FIX:FLAC,MP3,AAC Different number of samples /*if (wanted_spec.samples != strct_stream_info->m_pAudioFrame->nb_samples){ SDL_CloseAudio(); out_nb_samples = strct_stream_info->m_pAudioFrame->nb_samples; out_buffer_size = av_samples_get_buffer_size(NULL, pOutputCodecCtx->channels, out_nb_samples, out_sample_fmt, 1); wanted_spec.samples = out_nb_samples; SDL_OpenAudio(&wanted_spec, NULL); }*/ //设置PCM数据 TRACE("----out_buffer_size---is [%ld]\n",out_buffer_size); audio_chunk = (Uint8 *)out_buffer; audio_len = out_buffer_size; audio_pos = audio_chunk; strct_stream_info->m_aduio_pkt_size = resampled_data_size;//audio_len;// av_free_packet(&pkt); //写PCM进行test if (1){ FILE *p = NULL; fopen_s(&p, "test.pcm", "a+b"); if (p == NULL){ continue; } int tempLenght = 2 * strct_stream_info->m_pAudioFrame->nb_samples;//由于实验中知道这是16位深,所以才这么写 uint8_t *tmpPtr = strct_stream_info->m_pAudioFrame->data[0]; if (NULL != p) { while (tempLenght > 0) { size_t temp = fwrite(tmpPtr, 1, tempLenght, p); tmpPtr += temp; tempLenght = tempLenght - temp; } fclose(p); } } SDL_PauseAudio(0); //while (audio_len > 0){ // //Wait until finish // SDL_Delay(1); //} //if (pFmtCtx->streams[iAudioIndex]->codec->sample_fmt != pOutputCodecCtx->sample_fmt // || pFmtCtx->streams[iAudioIndex]->codec->channels != pOutputCodecCtx->channels // || pFmtCtx->streams[iAudioIndex]->codec->sample_rate != pOutputCodecCtx->sample_rate){ // //TODO如果输入和输出的音频格式不一样 需要重采样,这里是一样的就没做 //} //av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame->nb_samples); //av_audio_fifo_write(fifo, (void **)frame->data, frame->nb_samples); ////循环读取数据,直到buf里数据采样数不够 //while (av_audio_fifo_size(fifo) >= (pOutputCodecCtx->frame_size > 0 ? pOutputCodecCtx->frame_size : AUDIO_BUF_SIZE)) //{ // av_frame_free(&frame); // frame = av_frame_alloc(); // frame->nb_samples = pOutputCodecCtx->frame_size>0 ? pOutputCodecCtx->frame_size : AUDIO_BUF_SIZE; // frame->channel_layout = pOutputCodecCtx->channel_layout; // frame->format = pOutputCodecCtx->sample_fmt; // frame->sample_rate = pOutputCodecCtx->sample_rate; // av_frame_get_buffer(frame, 0); // av_audio_fifo_read(fifo, (void **)frame->data, (pOutputCodecCtx->frame_size > 0 ? pOutputCodecCtx->frame_size : AUDIO_BUF_SIZE)); // av_init_packet(&pkt_out); // //frame->pts = pFrame->pts; // int got_picture = -1; // pkt_out.data = NULL; // pkt_out.size = 0; // if (avcodec_encode_audio2(pOutputCodecCtx, &pkt_out, frame, &got_picture) < 0){ // printf("can not decoder a frame"); // } // av_frame_free(&frame); // if (got_picture) // { // pkt_out.pts = frameIndex * pOutputCodecCtx->frame_size; // pkt_out.dts = frameIndex * pOutputCodecCtx->frame_size; // pkt_out.duration = pOutputCodecCtx->frame_size; // //TODO将编码结果后续做合成处理[pkt_out] // if (pFile != NULL){ // /*fwrite((uint8_t *)pDlg->m_streamstate->audio_buf + pDlg->m_streamstate->audio_buf_index, 1, len1, pFile);*/ // } // frameIndex++; // } //} } iRet = 1; END: //swr_free(&au_convert_ctx); SDL_CloseAudio(); SDL_Quit(); av_free(out_buffer); avcodec_close(pOutputCodecCtx); return iRet; }
int main(int argc, char *argv[]) { SDL_Event event; VideoState *is; is = (VideoState *)av_mallocz(sizeof(VideoState)); 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); } // Make a screen to put our video #ifndef __DARWIN__ screen = SDL_SetVideoMode(1280, 720, 0, 0); #else screen = SDL_SetVideoMode(640, 480, 24, 0); #endif if(!screen) { fprintf(stderr, "SDL: could not set video mode - exiting\n"); exit(1); } //pstrcpy(is->filename, sizeof(is->filename), argv[1]); strcpy(is->filename,argv[1]); is->pictq_mutex = SDL_CreateMutex(); is->pictq_cond = SDL_CreateCond(); schedule_refresh(is, 40); is->av_sync_type = DEFAULT_AV_SYNC_TYPE; is->parse_tid = SDL_CreateThread(decode_thread, is); if(!is->parse_tid) { av_free(is); return -1; } for(;;) { double incr, pos; SDL_WaitEvent(&event); switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_LEFT: incr = -10.0; goto do_seek; case SDLK_RIGHT: incr = 10.0; goto do_seek; case SDLK_UP: incr = 60.0; goto do_seek; case SDLK_DOWN: incr = -60.0; goto do_seek; do_seek: if(global_video_state) { pos = get_master_clock(global_video_state); pos += incr; stream_seek(global_video_state, (int64_t)(pos * AV_TIME_BASE), incr); } break; default: break; } break; case FF_QUIT_EVENT: case SDL_QUIT: is->quit = 1; SDL_Quit(); exit(0); break; case FF_ALLOC_EVENT: alloc_picture(event.user.data1); break; case FF_REFRESH_EVENT: video_refresh_timer(event.user.data1); break; default: break; } } return 0; }
// For performance, we're using multiple threads so that the game state can // be updating in the background while openGL renders. // The general plan is: // 1. Vsync happens. Everything begins. // 2. Renderthread activates. (The update thread is currently blocked.) // 3. Renderthread dumps everything into opengl, via RenderAllEntities. (And // any other similar calls, such as calls to IMGUI) Updatethread is // still blocked. When this is complete, OpenGL now has its own copy of // everything, and we can safely change world state data. // 4. Renderthread signals updatethread to wake up. // 5a.Renderthread calls gl_flush, (via Renderer.advanceframe) and waits for // everything render. Once complete, it goes to sleep and waits for the // next vsync event. // 5b.Updatethread goes and updates the game state and gets us all ready for // next frame. Once complete, it also goes to sleep and waits for the next // vsync event. void Game::Run() { // Start the update thread: UpdateThreadData rt_data(&game_exiting_, &world_, &state_machine_, &renderer_, &input_, &audio_engine_, &sync_); input_.AdvanceFrame(&renderer_.window_size()); state_machine_.AdvanceFrame(16); SDL_Thread* update_thread = SDL_CreateThread(UpdateThread, "Zooshi Update Thread", &rt_data); if (!update_thread) { LogError("Error creating update thread."); assert(false); } #if DISPLAY_FRAMERATE_HISTOGRAM for (int i = 0; i < kHistogramSize; i++) { histogram[i] = 0; } last_printout = 0; #endif // DISPLAY_FRAMERATE_HISTOGRAM // variables used for regulating our framerate: // Total size of our history, in frames: const int kHistorySize = 60 * 5; // Max number of frames we can have dropped in our history, before we // switch to queue-stuffing mode, and ignore vsync pauses. const int kMaxDroppedFrames = 3; // Variable bool missed_frame_history[kHistorySize]; for (int i = 0; i < kHistorySize; i++) { missed_frame_history[i] = false; } int history_index = 0; int total_dropped_frames = 0; global_vsync_context = &sync_; #ifdef __ANDROID__ fplbase::RegisterVsyncCallback(HandleVsync); #else // We don't need this on android because we'll just get vsync events directly. SDL_Thread* vsync_simulator_thread = SDL_CreateThread( VsyncSimulatorThread, "Zooshi Simulated Vsync Thread", nullptr); if (!vsync_simulator_thread) { LogError("Error creating vsync simulator thread."); assert(false); } #endif // __ANDROID__ int last_frame_id = 0; // We basically own the lock all the time, except when we're waiting // for a vsync event. SDL_LockMutex(sync_.renderthread_mutex_); while (!game_exiting_) { #ifdef __ANDROID__ int current_frame_id = fplbase::GetVsyncFrameId(); #else int current_frame_id = 0; #endif // __ANDROID__ // Update our framerate history: // The oldest value falls off and is replaced with the most recent frame. // Also, we update our counts. if (missed_frame_history[history_index]) { total_dropped_frames--; } // We count it as a dropped frame if more than one vsync event passed since // we started rendering it. The check is implemented via equality // comparisons because current_frame_id will eventually wrap.) missed_frame_history[history_index] = (current_frame_id != last_frame_id + 1) && (current_frame_id != last_frame_id); if (missed_frame_history[history_index]) { total_dropped_frames++; } history_index = (history_index + 1) % kHistorySize; last_frame_id = current_frame_id; // ------------------------------------------- // Steps 1, 2. // Wait for start of frame. (triggered at vsync start on android.) // For performance, we only wait if we're not dropping frames. Otherwise, // we just keep rendering as fast as we can and stuff the render queue. if (total_dropped_frames <= kMaxDroppedFrames) { SDL_CondWait(sync_.start_render_cv_, sync_.renderthread_mutex_); } // Grab the lock to make sure the game isn't still updating. SDL_LockMutex(sync_.gameupdate_mutex_); SystraceBegin("RenderFrame"); // Input update must happen from the render thread. // From the SDL documentation on SDL_PollEvent(), // https://wiki.libsdl.org/SDL_PollEvent): // "As this function implicitly calls SDL_PumpEvents(), you can only call // this function in the thread that set the video mode." SystraceBegin("Input::AdvanceFrame()"); input_.AdvanceFrame(&renderer_.window_size()); game_exiting_ |= input_.exit_requested(); SystraceEnd(); // Milliseconds elapsed since last update. rt_data.frame_start = CurrentWorldTimeSubFrame(input_); // ------------------------------------------- // Step 3. // Render everything. // ------------------------------------------- SystraceBegin("StateMachine::Render()"); fplbase::RenderTarget::ScreenRenderTarget(renderer_).SetAsRenderTarget(); renderer_.ClearDepthBuffer(); renderer_.SetCulling(fplbase::Renderer::kCullBack); state_machine_.Render(&renderer_); SystraceEnd(); SDL_UnlockMutex(sync_.gameupdate_mutex_); SystraceBegin("StateMachine::HandleUI()"); state_machine_.HandleUI(&renderer_); SystraceEnd(); // ------------------------------------------- // Step 4. // Signal the update thread that it is safe to start messing with // data, now that we've already handed it all off to openGL. // ------------------------------------------- SDL_CondBroadcast(sync_.start_update_cv_); // ------------------------------------------- // Step 5a. // Start openGL actually rendering. AdvanceFrame will (among other things) // trigger a gl_flush. This thread will block until it is completed, // but that's ok because the update thread is humming in the background // preparing the worlds tate for next frame. // ------------------------------------------- SystraceBegin("AdvanceFrame"); renderer_.AdvanceFrame(input_.minimized(), input_.Time()); SystraceEnd(); // AdvanceFrame SystraceEnd(); // RenderFrame gpg_manager_.Update(); // Process input device messages since the last game loop. // Update render window size. if (input_.GetButton(fplbase::FPLK_BACKQUOTE).went_down()) { ToggleRelativeMouseMode(); } int new_time = CurrentWorldTimeSubFrame(input_); int frame_time = new_time - rt_data.frame_start; #if DISPLAY_FRAMERATE_HISTOGRAM UpdateProfiling(frame_time); #endif // DISPLAY_FRAMERATE_HISTOGRAM SystraceCounter("FrameTime", frame_time); } SDL_UnlockMutex(sync_.renderthread_mutex_); // Clean up asynchronous callbacks to prevent crashing on garbage data. #ifdef __ANDROID__ fplbase::RegisterVsyncCallback(nullptr); #endif // __ANDROID__ input_.AddAppEventCallback(nullptr); }
int XyEngine::CreateWindow(int width, int height, char* title, float frameRate) { double StartTime = Time::GetTime(); Log("XyEngine is Loading..."); this->m_windowWidth = width; this->m_windowHeight = height; this->m_middleWidth = m_windowWidth / 2; this->m_middleHeight = m_windowHeight / 2; this->m_FrameRate = frameRate; this->m_frameTime = 1.0 / this->m_FrameRate; if (SDL_Init(SDL_INIT_EVERYTHING) != 0) return ReturnWithError("SDL Failed To Init!"); m_Window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidth, m_windowHeight, SDL_WINDOW_OPENGL); if (m_Window == NULL) { SDL_Quit(); return ReturnWithError("SDL Failed To Create the Window!"); } glcontext = SDL_GL_CreateContext(m_Window); if (glewInit() != GLEW_OK) return ReturnWithError("GLEW Failed to Init!"); if (TTF_Init() != 0) return ReturnWithError("TTF Failed to Init!"); if (!IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG)) return ReturnWithError("IMG Failed to Init!"); m_running = true; double lastTime = Time::GetTime(); double unprocessedTime = 0; double frameCounter = 0; frames = 0; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_MULTISAMPLE_ARB); m_InitFunc(); m_pPhysicsThread = SDL_CreateThread(StaticPhysicsThread, "PhysicsThread", this); if (NULL == m_pPhysicsThread) { ReturnWithError("Physics Thread Failed to create"); } else { Log("Physics Thread Created"); } double EndTime = Time::GetTime() - StartTime; std::cout << "Time Taken to load XyEngine: " << EndTime << std::endl; SDL_Event event; while (m_running) { bool render = false; double startTime = Time::GetTime(); double passedTime = startTime - lastTime; lastTime = startTime; unprocessedTime += passedTime; frameCounter += passedTime; if (frameCounter >= 1.0) { fpsRate = frames; frames = 0; frameCounter = 0; } while (unprocessedTime > m_frameTime) { render = true; while (SDL_PollEvent(&event)) { m_InputFunc(event); switch (event.type) { case SDL_QUIT: m_running = false; break; case SDL_MOUSEBUTTONDOWN: mousein = true; SDL_ShowCursor(SDL_DISABLE); break; case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_ESCAPE: mousein = false; SDL_ShowCursor(SDL_ENABLE); break; } } } unprocessedTime -= m_frameTime; } if (render) { if (mousein) SDL_WarpMouseInWindow(m_Window, m_middleWidth, m_middleHeight); m_RenderFunc(); SDL_GL_SwapWindow(m_Window); frames++; } else { SDL_Delay(1); } } return EXIT_SUCCESS; }