// File: /workspace/github_c_makefile_star2_O0/phoboslab[P]pl_mpeg/pl_mpeg_player_gl.c
// Function: app_create
app_t * app_create(const char *filename, int texture_mode) {
	app_t *self = (app_t *)malloc(sizeof(app_t));
	memset(self, 0, sizeof(app_t));
	
	self->texture_mode = texture_mode;
	
	// 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_OPENGL | SDL_WINDOW_RESIZABLE
	);
	self->gl = SDL_GL_CreateContext(self->window);
	
	SDL_GL_SetSwapInterval(1);

	#if defined(__APPLE__) && defined(__MACH__)
		// OSX
		// (nothing to do here)
	#else
		// Windows, Linux
		glewExperimental = GL_TRUE;
		glewInit();
	#endif
	
	
	// Setup OpenGL shaders and textures
	const char * fsh = self->texture_mode == APP_TEXTURE_MODE_YCRCB
		? APP_FRAGMENT_SHADER_YCRCB
		: APP_FRAGMENT_SHADER_RGB;
	
	self->fragment_shader = app_compile_shader(self, GL_FRAGMENT_SHADER, fsh);
	self->vertex_shader = app_compile_shader(self, GL_VERTEX_SHADER, APP_VERTEX_SHADER);
	
	self->shader_program = glCreateProgram();
	glAttachShader(self->shader_program, self->vertex_shader);
	glAttachShader(self->shader_program, self->fragment_shader);
	glLinkProgram(self->shader_program);
	glUseProgram(self->shader_program);
	
	// Create textures for YCrCb or RGB rendering
	if (self->texture_mode == APP_TEXTURE_MODE_YCRCB) {
		self->texture_y  = app_create_texture(self, 0, "texture_y");
		self->texture_cb = app_create_texture(self, 1, "texture_cb");
		self->texture_cr = app_create_texture(self, 2, "texture_cr");
	}
	else {
		self->texture_rgb = app_create_texture(self, 0, "texture_rgb");
		int num_pixels = plm_get_width(self->plm) * plm_get_height(self->plm);
		self->rgb_data = (uint8_t*)malloc(num_pixels * 3);
	}
	self->texture_crop_size = glGetUniformLocation(self->shader_program, "texture_crop_size");
	
	return self;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl $0x60, %edi
callq 0x2200
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
xorl %esi, %esi
movl $0x60, %edx
callq 0x20f0
movl -0xc(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x3c(%rax)
movq -0x8(%rbp), %rdi
callq 0x2390
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0xc0c0
movq -0x8(%rbp), %rsi
leaq 0x27d5(%rip), %rdi      # 0xe884
movb $0x0, %al
callq 0x21f0
movl $0x1, %edi
callq 0x21b0
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movl $0x4e2000, %esi         # imm = 0x4E2000
callq 0x3030
cmpl $0x0, %eax
jne 0xc0f2
movq -0x8(%rbp), %rsi
leaq 0x27b4(%rip), %rdi      # 0xe895
movb $0x0, %al
callq 0x21f0
movl $0x1, %edi
callq 0x21b0
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x35c0
movl %eax, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x3480
movsd %xmm0, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x35c0
movl %eax, -0x5c(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x36c0
movq -0x68(%rbp), %rsi
movl -0x5c(%rbp), %edx
movaps %xmm0, %xmm1
movsd -0x58(%rbp), %xmm0
leaq 0x2775(%rip), %rdi      # 0xe8c0
movb $0x2, %al
callq 0x21f0
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
leaq 0x32c(%rip), %rsi       # 0xc490
callq 0x3a80
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
leaq 0x475(%rip), %rsi       # 0xc5f0
callq 0x3ab0
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movl $0x1, %esi
callq 0x3a40
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movl $0x1, %esi
callq 0x3200
movq -0x18(%rbp), %rax
movq (%rax), %rdi
xorl %esi, %esi
callq 0x3270
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x35a0
cmpl $0x0, %eax
jle 0xc25f
movl $0x30, %edi
callq 0x2150
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x20e0
movl -0x1c(%rbp), %eax
movl %eax, -0x40(%rbp)
movw $0x8120, -0x3c(%rbp)    # imm = 0x8120
movb $0x2, -0x3a(%rbp)
movw $0x1000, -0x38(%rbp)    # imm = 0x1000
xorl %eax, %eax
movl %eax, %ecx
xorl %r8d, %r8d
leaq -0x40(%rbp), %rdx
movq %rcx, %rdi
movl %r8d, %esi
callq 0x21c0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0xc234
callq 0x2110
movq %rax, %rsi
leaq 0x26cb(%rip), %rdi      # 0xe8f8
movb $0x0, %al
callq 0x21f0
movq -0x18(%rbp), %rax
movl 0x20(%rax), %edi
xorl %esi, %esi
callq 0x21e0
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movzwl -0x38(%rbp), %eax
cvtsi2sd %eax, %xmm0
cvtsi2sdl -0x1c(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x3680
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x3360
movl %eax, -0x6c(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x33f0
movl -0x6c(%rbp), %ecx
movl %eax, %r8d
leaq 0x2691(%rip), %rdi      # 0xe918
movl $0x2fff0000, %edx       # imm = 0x2FFF0000
movl $0x26, %r9d
movl %edx, %esi
callq 0x2040
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2090
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movl $0x1, %edi
callq 0x20a0
movq 0x5ceb(%rip), %rax      # 0x11fb8
movb $0x1, (%rax)
callq 0x2130
movq -0x18(%rbp), %rax
movl 0x3c(%rax), %edx
leaq 0x2519(%rip), %rax      # 0xe7fc
leaq 0x2346(%rip), %rcx      # 0xe630
cmpl $0x1, %edx
cmoveq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rdx
movl $0x8b30, %esi           # imm = 0x8B30
callq 0xc640
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x38(%rax)
movq -0x18(%rbp), %rdi
movl $0x8b31, %esi           # imm = 0x8B31
leaq 0x2247(%rip), %rdx      # 0xe567
callq 0xc640
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x34(%rax)
movq 0x5c5b(%rip), %rax      # 0x11f90
callq *(%rax)
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x30(%rax)
movq 0x5ca1(%rip), %rax      # 0x11fe8
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movl 0x30(%rcx), %edi
movq -0x18(%rbp), %rcx
movl 0x34(%rcx), %esi
callq *%rax
movq 0x5c87(%rip), %rax      # 0x11fe8
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movl 0x30(%rcx), %edi
movq -0x18(%rbp), %rcx
movl 0x38(%rcx), %esi
callq *%rax
movq 0x5c55(%rip), %rax      # 0x11fd0
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movl 0x30(%rcx), %edi
callq *%rax
movq 0x5c4a(%rip), %rax      # 0x11fd8
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movl 0x30(%rcx), %edi
callq *%rax
movq -0x18(%rbp), %rax
cmpl $0x1, 0x3c(%rax)
jne 0xc3fd
movq -0x18(%rbp), %rdi
xorl %esi, %esi
leaq 0x256f(%rip), %rdx      # 0xe920
callq 0xc6f0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
leaq 0x255b(%rip), %rdx      # 0xe92a
callq 0xc6f0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x44(%rax)
movq -0x18(%rbp), %rdi
movl $0x2, %esi
leaq 0x2548(%rip), %rdx      # 0xe935
callq 0xc6f0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x48(%rax)
jmp 0xc455
movq -0x18(%rbp), %rdi
xorl %esi, %esi
leaq 0x2536(%rip), %rdx      # 0xe940
callq 0xc6f0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x50(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x3360
movl %eax, -0x70(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x33f0
movl %eax, %ecx
movl -0x70(%rbp), %eax
imull %ecx, %eax
movl %eax, -0x4c(%rbp)
imull $0x3, -0x4c(%rbp), %eax
movslq %eax, %rdi
callq 0x2200
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x58(%rax)
movq 0x5b04(%rip), %rax      # 0x11f60
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movl 0x30(%rcx), %edi
leaq 0x24df(%rip), %rsi      # 0xe94c
callq *%rax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x4c(%rax)
movq -0x18(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)