bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp, int &ctsOffset) { profileIn("ProcessEncodedFrame"); mfxU32 wait = 0; bool bMessageLogged = false; do { if(!packets.Num()) ProcessEncodedFrame(packets, packetTypes, outputTimestamp, ctsOffset, wait); CleanupLockedTasks(); if(idle_tasks.Num()) break; if(wait == INFINITE) { if(!bMessageLogged) Log(TEXT("Error: encoder is taking too long, consider decreasing your FPS/increasing your bitrate")); bMessageLogged = true; Sleep(1); //wait for locked tasks to unlock } else Log(TEXT("Error: all encode tasks in use, stalling pipeline")); wait = INFINITE; } while(!idle_tasks.Num()); profileOut; mfxFrameSurface1& pic = *(mfxFrameSurface1*)picInPtr; QueueEncodeTask(pic); profileIn("EncodeFrameAsync"); while(queued_tasks.Num()) { encode_task& task = encode_tasks[queued_tasks[0]]; mfxBitstream& bs = task.bs; mfxFrameSurface1& surf = task.surf; mfxSyncPoint& sp = task.sp; for(;;) { auto sts = enc->EncodeFrameAsync(task.keyframe ? &ctrl : nullptr, &surf, &bs, &sp); if(sts == MFX_ERR_NONE || (MFX_ERR_NONE < sts && sp)) break; if(sts == MFX_WRN_DEVICE_BUSY) { deferredFrames += 1; return false; } //if(!sp); //sts == MFX_ERR_MORE_DATA usually; retry the call (see MSDK examples) //Log(TEXT("returned status %i, %u"), sts, insert); } encoded_tasks << queued_tasks[0]; queued_tasks.Remove(0); } profileOut; return true; }
bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp) { if(!process_waiter.wait_timeout()) { int code = 0; if(!GetExitCodeProcess(process_waiter.list[0], (LPDWORD)&code)) CrashError(TEXT("QSVHelper.exe exited!")); switch(code) { case EXIT_INCOMPATIBLE_CONFIGURATION: CrashError(TEXT("QSVHelper.exe has exited because of an incompatible qsvimpl custom parameter")); default: CrashError(TEXT("QSVHelper.exe has exited with code %i"), code); } } profileIn("ProcessEncodedFrame"); do { ProcessEncodedFrame(packets, packetTypes, outputTimestamp, idle_tasks.Num() ? 0 : INFINITE); } while(!idle_tasks.Num()); profileOut; if(picInPtr) { profileSegment("QueueEncodeTask"); QueueEncodeTask(*(mfxFrameSurface1*)picInPtr); } return true; }