u32 RunSingleDec(void *ptr) { GF_Err e; u64 time_taken; CodecEntry *ce = (CodecEntry *) ptr; GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[MediaDecoder %d] Entering thread ID %d\n", ce->dec->odm->OD->objectDescriptorID, gf_th_id() )); while (ce->flags & GF_MM_CE_RUNNING) { time_taken = gf_sys_clock_high_res(); if (!ce->dec->force_cb_resize) { gf_mx_p(ce->mx); e = gf_codec_process(ce->dec, ce->dec->odm->term->frame_duration); if (e) gf_term_message(ce->dec->odm->term, ce->dec->odm->net_service->url, "Decoding Error", e); gf_mx_v(ce->mx); } time_taken = gf_sys_clock_high_res() - time_taken; /*no priority boost this way for systems codecs, priority is dynamically set by not releasing the graph when late and moving on*/ if (!ce->dec->CB || (ce->dec->CB->UnitCount == ce->dec->CB->Capacity)) ce->dec->PriorityBoost = 0; /*while on don't sleep*/ if (ce->dec->PriorityBoost) continue; if (time_taken<20) { gf_sleep(1); } } ce->flags |= GF_MM_CE_DEAD; return 0; }
/// <summary> /// Main processing function /// </summary> void CColorBasics::Update(DASHout* dasher, DWORD event_res) { u64 timeref = 0; //TODO fix/move this if (NULL == m_pNuiSensor) { return; } if ( WAIT_OBJECT_0 == WaitForSingleObject(m_hNextColorFrameEvent, INFINITE) ) { ProcessColor(dasher); } if (event_res == 1 && WAIT_OBJECT_0 == WaitForSingleObject(m_hNextSkeletonEvent, INFINITE) ) { //TODO add process skel function timeref = gf_sys_clock_high_res() - dasher->sys_start; ProcessSkeleton(dasher, timeref); } if(dasher->nextColourFrame){ int res = muxer_encode(dasher, (u8 *) dasher->nextColourFrame->kinectFrame, dasher->nextColourFrame->size,dasher->nextColourFrame->pts); if((res>=0)&&(!dasher->segment_started)){ res = muxer_open_segment(dasher, "x64/Debug/out", "seg", dasher->seg_num); timeref = gf_sys_clock_high_res() - dasher->sys_start; printf("\t\tOpening segment time : %llu\n", timeref); } if(res>=0){ res = muxer_write_frame(dasher, dasher->colFrameCount); dasher->colFrameCount++; } if(res==1){ res = muxer_close_segment(dasher); if(res==GF_OK){ dasher->seg_num = write_playlist_segment(dasher->seg_num, timeref); } } dasher->nextColourFrame = NULL; } }
u32 gf_sc_ar_get_clock(GF_AudioRenderer *ar) { if (ar->clock_use_audio_out) return ar->current_time; if (ar->Frozen) { return (u32) ((ar->freeze_time - ar->start_time) / 1000); } return (u32) ((gf_sys_clock_high_res() - ar->start_time) / 1000); }
static void gf_ar_pause(GF_AudioRenderer *ar, Bool DoFreeze, Bool for_reconfig, Bool reset_hw_buffer) { gf_mixer_lock(ar->mixer, GF_TRUE); if (DoFreeze) { if (!ar->Frozen) { ar->freeze_time = gf_sys_clock_high_res(); if (!for_reconfig && ar->audio_out && ar->audio_out->Play) ar->audio_out->Play(ar->audio_out, 0); ar->Frozen = GF_TRUE; GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[Audio] pausing master clock - time "LLD" (sys time "LLD")\n", ar->freeze_time, gf_sys_clock_high_res())); } } else { if (ar->Frozen) { if (!for_reconfig && ar->audio_out && ar->audio_out->Play) ar->audio_out->Play(ar->audio_out, reset_hw_buffer ? 2 : 1); ar->Frozen = GF_FALSE; ar->start_time += gf_sys_clock_high_res() - ar->freeze_time; GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[Audio] resuming master clock - new time "LLD" (sys time "LLD") \n", ar->start_time, gf_sys_clock_high_res())); } } gf_mixer_lock(ar->mixer, GF_FALSE); }
GF_AudioRenderer *gf_sc_ar_load(GF_User *user) { const char *sOpt; u32 i, count; u32 num_buffers, total_duration; GF_Err e; GF_AudioRenderer *ar; ar = (GF_AudioRenderer *) gf_malloc(sizeof(GF_AudioRenderer)); memset(ar, 0, sizeof(GF_AudioRenderer)); num_buffers = total_duration = 0; sOpt = gf_cfg_get_key(user->config, "Audio", "ForceConfig"); if (sOpt && !stricmp(sOpt, "yes")) { sOpt = gf_cfg_get_key(user->config, "Audio", "NumBuffers"); num_buffers = sOpt ? atoi(sOpt) : 6; sOpt = gf_cfg_get_key(user->config, "Audio", "TotalDuration"); total_duration = sOpt ? atoi(sOpt) : 400; } sOpt = gf_cfg_get_key(user->config, "Audio", "NoResync"); ar->disable_resync = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; sOpt = gf_cfg_get_key(user->config, "Audio", "DisableMultiChannel"); ar->disable_multichannel = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; ar->mixer = gf_mixer_new(ar); ar->user = user; sOpt = gf_cfg_get_key(user->config, "Audio", "Volume"); ar->volume = sOpt ? atoi(sOpt) : 75; sOpt = gf_cfg_get_key(user->config, "Audio", "Pan"); ar->pan = sOpt ? atoi(sOpt) : 50; if (! (user->init_flags & GF_TERM_NO_AUDIO) ) { /*get a prefered compositor*/ sOpt = gf_cfg_get_key(user->config, "Audio", "DriverName"); if (sOpt) { ar->audio_out = (GF_AudioOutput *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_AUDIO_OUTPUT_INTERFACE); if (!ar->audio_out) { ar->audio_out = NULL; sOpt = NULL; } } if (!ar->audio_out) { GF_AudioOutput *raw_out = NULL; count = gf_modules_get_count(ar->user->modules); for (i=0; i<count; i++) { ar->audio_out = (GF_AudioOutput *) gf_modules_load_interface(ar->user->modules, i, GF_AUDIO_OUTPUT_INTERFACE); if (!ar->audio_out) continue; //in enum mode, only use raw out if everything else failed ... if (!stricmp(ar->audio_out->module_name, "Raw Audio Output")) { raw_out = ar->audio_out; ar->audio_out = NULL; continue; } GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Audio output module %s loaded\n", ar->audio_out->module_name)); /*check that's a valid audio compositor*/ if ((ar->audio_out->SelfThreaded && ar->audio_out->SetPriority) || ar->audio_out->WriteAudio) { /*remember the module we use*/ gf_cfg_set_key(user->config, "Audio", "DriverName", ar->audio_out->module_name); break; } gf_modules_close_interface((GF_BaseInterface *)ar->audio_out); ar->audio_out = NULL; } if (raw_out) { if (ar->audio_out) gf_modules_close_interface((GF_BaseInterface *)raw_out); else ar->audio_out = raw_out; } } /*if not init we run with a NULL audio compositor*/ if (ar->audio_out) { ar->audio_out->FillBuffer = gf_ar_fill_output; ar->audio_out->audio_renderer = ar; GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Setting up audio module %s\n", ar->audio_out->module_name)); e = ar->audio_out->Setup(ar->audio_out, ar->user->os_window_handler, num_buffers, total_duration); /*load main audio filter*/ gf_afc_load(&ar->filter_chain, user, (char*)gf_cfg_get_key(user->config, "Audio", "Filter")); if (e != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("Could not setup audio out %s\n", ar->audio_out->module_name)); gf_modules_close_interface((GF_BaseInterface *)ar->audio_out); ar->audio_out = NULL; } else { if (!ar->audio_out->SelfThreaded) { ar->th = gf_th_new("AudioRenderer"); gf_th_run(ar->th, gf_ar_proc, ar); } else { gf_ar_setup_output_format(ar); if (ar->audio_out->SetPriority) ar->audio_out->SetPriority(ar->audio_out, GF_THREAD_PRIORITY_REALTIME); } } } if (!ar->audio_out) { gf_cfg_set_key(user->config, "Audio", "DriverName", "No Audio Output Available"); } else { if (user->init_flags & GF_TERM_USE_AUDIO_HW_CLOCK) ar->clock_use_audio_out = GF_TRUE; } } /*init compositor timer*/ ar->start_time = gf_sys_clock_high_res(); ar->current_time = 0; return ar; }
/// <summary> /// Handle new color data /// </summary> /// <returns>indicates success or failure</returns> void CColorBasics::ProcessColor(DASHout* dasher) { HRESULT hr; NUI_IMAGE_FRAME imageFrame; colourFrame *cFrame; // Attempt to get the color frame hr = m_pNuiSensor->NuiImageStreamGetNextFrame(m_pColorStreamHandle, 0, &imageFrame); if (FAILED(hr)) { printf("failed in processcolor \n "); return; } INuiFrameTexture * pTexture = imageFrame.pFrameTexture; NUI_LOCKED_RECT LockedRect; // Lock the frame data so the Kinect knows not to modify it while we're reading it pTexture->LockRect(0, &LockedRect, NULL, 0); // Make sure we've received valid data if (LockedRect.Pitch != 0) { //init the frame to be parsed in FFMPEG cFrame = init_cFrame(cColorWidth*cColorHeight*3); if(!cFrame){ printf("fudge!\n"); gf_free(cFrame); return; } //Frame number cFrame->number = imageFrame.dwFrameNumber; if (!dasher->sys_start) { dasher->sys_start = gf_sys_clock_high_res(); dasher->prev_pts = 0; cFrame->pts = 0; } else { //TODO: fix timing here and cFrame->pts = 30*(gf_sys_clock_high_res() - dasher->sys_start)/1000000; printf("CTS diff is %d ms\n", (u32) (cFrame->pts - dasher->prev_pts) / 1000); dasher->prev_pts = cFrame->pts; } //convert RGBA to RGB unsigned char * currFrame = (unsigned char *)LockedRect.pBits; int j = 0; for (int i = 0; i < cColorWidth * cColorHeight * 4; i += 4){ (cFrame->kinectFrame)[i - j] = currFrame[i + 2]; (cFrame->kinectFrame)[i - j + 1] = currFrame[i + 1]; (cFrame->kinectFrame)[i - j + 2] = currFrame[i]; j++; } dasher->nextColourFrame = cFrame; // Draw the data with Direct2D m_pDrawColor->Draw(static_cast<BYTE *>(LockedRect.pBits), LockedRect.size); #if 0 // If the user pressed the screenshot button, save a screenshot if (m_bSaveScreenshot) { WCHAR statusMessage[cStatusMessageMaxLen]; // Retrieve the path to My Photos WCHAR screenshotPath[MAX_PATH]; GetScreenshotFileName(screenshotPath, _countof(screenshotPath)); // Write out the bitmap to disk hr = SaveBitmapToFile(static_cast<BYTE *>(LockedRect.pBits), cColorWidth, cColorHeight, 32, screenshotPath); if (SUCCEEDED(hr)) { // Set the status bar to show where the screenshot was saved StringCchPrintf( statusMessage, cStatusMessageMaxLen, L"Screenshot saved to %s", screenshotPath); } else { StringCchPrintf( statusMessage, cStatusMessageMaxLen, L"Failed to write screenshot to %s", screenshotPath); } SetStatusMessage(statusMessage); // toggle off so we don't save a screenshot again next frame m_bSaveScreenshot = false; } #endif } // We're done with the texture so unlock it pTexture->UnlockRect(0); // Release the frame m_pNuiSensor->NuiImageStreamReleaseFrame(m_pColorStreamHandle, &imageFrame); }