// File: /workspace/github_c_makefile_star2_O2/phoboslab[P]pl_mpeg/pl_mpeg_player_sdl.c
// Function: app_create
app_t * app_create(const char *filename) {
	app_t *self = (app_t *)malloc(sizeof(app_t));
	memset(self, 0, sizeof(app_t));
	
	// Initialize plmpeg, load the video file, install decode callbacks
	self->plm = plm_create_with_filename(filename);
	if (!self->plm) {
		SDL_Log("Couldn't open %s", filename);
		exit(1);
	}

	if (!plm_probe(self->plm, 5000 * 1024)) {
		SDL_Log("No MPEG video or audio streams found in %s", filename);
		exit(1);
	}

	int samplerate = plm_get_samplerate(self->plm);

	SDL_Log(
		"Opened %s - framerate: %f, samplerate: %d, duration: %f",
		filename, 
		plm_get_framerate(self->plm),
		plm_get_samplerate(self->plm),
		plm_get_duration(self->plm)
	);
	
	plm_set_video_decode_callback(self->plm, app_on_video, self);
	plm_set_audio_decode_callback(self->plm, app_on_audio, self);
	
	plm_set_loop(self->plm, TRUE);
	plm_set_audio_enabled(self->plm, TRUE);
	plm_set_audio_stream(self->plm, 0);

	if (plm_get_num_audio_streams(self->plm) > 0) {
		// Initialize SDL Audio
		SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
		SDL_AudioSpec audio_spec;
		SDL_memset(&audio_spec, 0, sizeof(audio_spec));
		audio_spec.freq = samplerate;
		audio_spec.format = AUDIO_F32;
		audio_spec.channels = 2;
		audio_spec.samples = 4096;

		self->audio_device = SDL_OpenAudioDevice(NULL, 0, &audio_spec, NULL, 0);
		if (self->audio_device == 0) {
			SDL_Log("Failed to open audio device: %s", SDL_GetError());
		}
		SDL_PauseAudioDevice(self->audio_device, 0);

		// Adjust the audio lead time according to the audio_spec buffer size
		plm_set_audio_lead_time(self->plm, (double)audio_spec.samples / (double)samplerate);
	}
	
	// Create SDL Window
	self->window = SDL_CreateWindow(
		"pl_mpeg",
		SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
		plm_get_width(self->plm), plm_get_height(self->plm),
		SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
	);

	// Create SDL Renderer with vsync
	self->renderer = SDL_CreateRenderer(
		self->window,
		-1,
		SDL_RENDERER_PRESENTVSYNC
	);

	// Create SDL texture with YUV format
	self->texture = SDL_CreateTexture(
		self->renderer,
		SDL_PIXELFORMAT_IYUV,
		SDL_TEXTUREACCESS_STREAMING,
		plm_get_width(self->plm),
 		plm_get_height(self->plm)
	);

	// Adjust rectangle to video size
	self->rectangle.w = plm_get_width(self->plm);
	self->rectangle.h = plm_get_height(self->plm);

	// Renderer will keep the aspect ratio of the video and center the content if the window is resized
	SDL_RenderSetLogicalSize(self->renderer, plm_get_width(self->plm), plm_get_height(self->plm));

	// Mouse position based on the renderer logical size
	SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SCALING, "1");

	// Best render scale quality
	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");

	return self;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x30, %rsp
movq %rdi, %r14
pushq $0x1
popq %rdi
pushq $0x48
popq %rsi
callq 0x2110
movq %rax, %rbx
movq %r14, %rdi
callq 0x23ac
movq %rax, (%rbx)
testq %rax, %rax
je 0x7cf1
movq %rax, %r15
movl $0x4e2000, %esi         # imm = 0x4E2000
movq %rax, %rdi
callq 0x29fc
testl %eax, %eax
je 0x7cfa
movq %r15, %rdi
callq 0x2c62
movl %eax, %ebp
movq %r15, %rdi
callq 0x2be7
movsd %xmm0, 0x8(%rsp)
movq %r15, %rdi
callq 0x2c62
movl %eax, %r12d
movq %r15, %rdi
callq 0x2cb6
movapd %xmm0, %xmm1
leaq 0x1bac(%rip), %rdi      # 0x96d7
movq %r14, %rsi
movsd 0x8(%rsp), %xmm0
movl %r12d, %edx
movb $0x2, %al
callq 0x2200
leaq 0x1ce(%rip), %rax       # 0x7d13
movq %rax, 0x60(%r15)
movq %rbx, 0x68(%r15)
leaq 0x1ea(%rip), %rax       # 0x7d3e
movq %rax, 0x70(%r15)
movq %rbx, 0x78(%r15)
movl $0x1, 0x14(%r15)
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x2af6
movq (%rbx), %rdi
xorl %esi, %esi
callq 0x2b2a
movq (%rbx), %rdi
callq 0x2c5a
testl %eax, %eax
jle 0x7c0e
pushq $0x30
popq %rdi
callq 0x2150
leaq 0x10(%rsp), %r14
pushq $0x20
popq %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x20d0
movl %ebp, (%r14)
movw $0x8120, 0x4(%r14)      # imm = 0x8120
movb $0x2, 0x6(%r14)
movw $0x1000, 0x8(%r14)      # imm = 0x1000
xorl %edi, %edi
xorl %esi, %esi
movq %r14, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x21e0
movl %eax, 0x40(%rbx)
testl %eax, %eax
jne 0x7bea
callq 0x2130
leaq 0x1b32(%rip), %rdi      # 0x970f
movq %rax, %rsi
xorl %eax, %eax
callq 0x2200
movl 0x40(%rbx), %eax
movl %eax, %edi
xorl %esi, %esi
callq 0x21f0
movq (%rbx), %rdi
movzwl 0x18(%rsp), %eax
cvtsi2sd %eax, %xmm0
cvtsi2sd %ebp, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rdi)
jmp 0x7c11
movq (%rbx), %rdi
callq 0x2b7b
movl %eax, %ebp
movq (%rbx), %rdi
callq 0x2bb1
leaq 0x1b08(%rip), %rdi      # 0x972f
pushq $0x24
popq %r9
movl $0x2fff0000, %esi       # imm = 0x2FFF0000
movl $0x2fff0000, %edx       # imm = 0x2FFF0000
movl %ebp, %ecx
movl %eax, %r8d
callq 0x2060
movq %rax, 0x18(%rbx)
pushq $-0x1
popq %rsi
pushq $0x4
popq %rdx
movq %rax, %rdi
callq 0x2050
movq %rax, %r14
movq %rax, 0x20(%rbx)
movq (%rbx), %rdi
callq 0x2b7b
movl %eax, %ebp
movq (%rbx), %rdi
callq 0x2bb1
pushq $0x1
popq %rdx
movq %r14, %rdi
movl $0x56555949, %esi       # imm = 0x56555949
movl %ebp, %ecx
movl %eax, %r8d
callq 0x2280
movq %rax, 0x28(%rbx)
movq (%rbx), %rdi
callq 0x2b7b
movl %eax, 0x38(%rbx)
movq (%rbx), %rdi
callq 0x2bb1
movl %eax, 0x3c(%rbx)
movq (%rbx), %rdi
movq 0x20(%rbx), %r14
callq 0x2b7b
movl %eax, %ebp
movq (%rbx), %rdi
callq 0x2bb1
movq %r14, %rdi
movl %ebp, %esi
movl %eax, %edx
callq 0x2090
leaq 0x1a75(%rip), %rdi      # 0x9737
leaq 0x1a89(%rip), %rsi      # 0x9752
callq 0x2270
leaq 0x1a7f(%rip), %rdi      # 0x9754
leaq 0x1a91(%rip), %rsi      # 0x976d
callq 0x2270
movq %rbx, %rax
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x19a3(%rip), %rdi      # 0x969b
jmp 0x7d01
leaq 0x19ab(%rip), %rdi      # 0x96ac
movq %r14, %rsi
xorl %eax, %eax
callq 0x2200
pushq $0x1
popq %rdi
callq 0x21d0