// Native NTLite Bink video player. // // This application intentionally uses the native syscall ABI directly. Do not // include here; Win32 compatibility belongs in the Win32 personality // layer, not in native apps. #include #include #include #include #include #include "bink.h" #define VIDEO_DEFAULT_PATH "video.bk2" static void print_span(const char* s, size_t len) { if (!s || !len) return; SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(s, len) }; SysWriteConsole(&req); } static void print(const char* s) { if (!s) return; SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); } static void print_u64(uint64_t v) { char buf[32]; int i = 0; if (v == 0) { print("0"); return; } while (v && i < (int)sizeof(buf)) { buf[i++] = (char)('0' + (v % 10)); v /= 10; } while (i) { char c = buf[--i]; print_span(&c, 1); } } static void fail_status(const char* what, uint32_t status) { print("video: "); print(what); print(" failed status="); print_u64(status); print("\n"); for (;;) SysExitProcess(1); } static void exit_now(int code) { for (;;) SysExitProcess(code); } static SYS_STRING_VIEW command_line_view(void) { SYS_PEB* peb = SysGetPeb(); if (!peb || peb->Magic != SYS_PEB_MAGIC) return SYS_SV_NULL; return peb->CommandLine; } static int sv_is_space(char c) { return c == ' ' || c == '\t'; } static SYS_STRING_VIEW skip_one_token(SYS_STRING_VIEW s) { size_t i = 0; while (i < s.Length && sv_is_space(s.Data[i])) i++; if (i < s.Length && s.Data[i] == '"') { i++; while (i < s.Length && s.Data[i] != '"') i++; if (i < s.Length && s.Data[i] == '"') i++; } else { while (i < s.Length && !sv_is_space(s.Data[i])) i++; } while (i < s.Length && sv_is_space(s.Data[i])) i++; return SysSvFromParts(s.Data + i, s.Length - i); } static SYS_STRING_VIEW command_line_second_token(SYS_STRING_VIEW cmdline) { SYS_STRING_VIEW rest = skip_one_token(cmdline); if (!rest.Data || rest.Length == 0) return SYS_SV_LITERAL(VIDEO_DEFAULT_PATH); size_t begin = 0; size_t end = 0; if (rest.Data[0] == '"') { begin = 1; end = begin; while (end < rest.Length && rest.Data[end] != '"') end++; } else { begin = 0; end = 0; while (end < rest.Length && !sv_is_space(rest.Data[end])) end++; } if (end <= begin) return SYS_SV_LITERAL(VIDEO_DEFAULT_PATH); return SysSvFromParts(rest.Data + begin, end - begin); } static const char* path_to_cstr(SYS_STRING_VIEW path, char* out, size_t outSize) { if (!out || outSize == 0) return VIDEO_DEFAULT_PATH; if (!path.Data || path.Length == 0) path = SYS_SV_LITERAL(VIDEO_DEFAULT_PATH); size_t n = path.Length; if (n + 1 > outSize) n = outSize - 1; memcpy(out, path.Data, n); out[n] = '\0'; return out; } static uint32_t open_file_view(SYS_STRING_VIEW path, uint32_t* handleOut) { SYS_PATH_HANDLE_REQUEST req = { path, handleOut }; return SysOpenFile(&req); } int main(void) { SYS_STRING_VIEW cmdline = command_line_view(); SYS_STRING_VIEW pathView = command_line_second_token(cmdline); print("video: starting\n"); if (cmdline.Data && cmdline.Length) { print_span(cmdline.Data, cmdline.Length); print("\n"); } uint32_t file = 0; uint32_t status = open_file_view(pathView, &file); if (status != SYS_STATUS_SUCCESS) { char pathBuf[260]; print("video: failed to open input file: "); print(path_to_cstr(pathView, pathBuf, sizeof(pathBuf))); print("\n"); fail_status("SysOpenFile", status); } uint64_t fileSize = SysGetFileSize(file); if (fileSize == 0) { SysCloseHandle(file); print("video: input file is empty\n"); exit_now(1); } uint32_t mapping = 0; status = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, fileSize, &mapping); if (status != SYS_STATUS_SUCCESS || !mapping) { SysCloseHandle(file); fail_status("SysCreateFileMapping", status); } void* buf = 0; status = SysMapFile(mapping, 0, (size_t)fileSize, SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &buf); if (status != SYS_STATUS_SUCCESS || !buf) { SysCloseHandle(mapping); SysCloseHandle(file); fail_status("SysMapFile", status); } // The mapped VAD owns the file reference now; keep only the mapped pointer // alive while Bink is open. This avoids a second whole-file heap allocation // and lets the VM fault file pages in on demand. SysCloseHandle(mapping); SysCloseHandle(file); print("video: input file mapped\n"); HBINK b = BinkOpen((const char*)buf, BINKFROMMEMORY); if (!b) { print("video: BinkOpen failed: "); const char* err = BinkGetError(); print(err ? err : "unknown"); print("\n"); SysFreeVm(buf); exit_now(1); } uint32_t width = b->Width; uint32_t height = b->Height; if (!width || !height) { print("video: invalid video dimensions\n"); BinkClose(b); SysFreeVm(buf); exit_now(1); } uint32_t surface = 0; status = SysCreateSurface(width, height, SYS_SURFACE_FORMAT_XRGB8888, SYS_SURFACE_FLAG_NONE, &surface); if (status != SYS_STATUS_SUCCESS || !surface) { BinkClose(b); SysFreeVm(buf); fail_status("SysCreateSurface", status); } void* surfaceBase = 0; uint32_t pitchBytes = 0; status = SysMapSurface(surface, &surfaceBase, &pitchBytes); if (status != SYS_STATUS_SUCCESS || !surfaceBase || pitchBytes < width * sizeof(uint32_t)) { SysCloseHandle(surface); BinkClose(b); SysFreeVm(buf); fail_status("SysMapSurface", status); } print("video: native surface ready\n"); DISPLAY_RECT fullFrame = { 0, 0, (int32_t)width, (int32_t)height }; while (1) { if (BinkWait(b)) { _mm_pause(); continue; } BinkDoFrame(b); if (BinkShouldSkip(b)) { BinkNextFrame(b); BinkDoFrame(b); continue; } BinkCopyToBuffer(b, surfaceBase, pitchBytes, height, 0, 0, BINKSURFACE32); status = SysPresentSurface(surface, &fullFrame, 1); if (status != SYS_STATUS_SUCCESS) { SysCloseHandle(surface); BinkClose(b); SysFreeVm(buf); fail_status("SysPresentSurface", status); } if (b->FrameNum == b->Frames) break; BinkNextFrame(b); } SysCloseHandle(surface); BinkClose(b); SysFreeVm(buf); print("video: goodbye\n"); exit_now(0); }