// File: /workspace/github_c_makefile_star2_O1/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_seek_frame
plm_frame_t *plm_seek_frame(plm_t *self, double time, int seek_exact) {
	if (!plm_init_decoders(self)) {
		return NULL;
	}

	if (!self->video_packet_type) {
		return NULL;
	}

	int type = self->video_packet_type;

	double start_time = plm_demux_get_start_time(self->demux, type);
	double duration = plm_demux_get_duration(self->demux, type);

	if (time < 0) {
		time = 0;
	}
	else if (time > duration) {
		time = duration;
	}
	
	plm_packet_t *packet = plm_demux_seek(self->demux, time, type, TRUE);
	if (!packet) {
		return NULL;
	}

	// Disable writing to the audio buffer while decoding video
	int previous_audio_packet_type = self->audio_packet_type;
	self->audio_packet_type = 0;

	// Clear video buffer and decode the found packet
	plm_video_rewind(self->video_decoder);
	plm_video_set_time(self->video_decoder, packet->pts - start_time);
	plm_buffer_write(self->video_buffer, packet->data, packet->length);
	plm_frame_t *frame = plm_video_decode(self->video_decoder);	

	// If we want to seek to an exact frame, we have to decode all frames
	// on top of the intra frame we just jumped to.
	if (seek_exact) {
		while (frame && frame->time < time) {
			frame = plm_video_decode(self->video_decoder);
		}
	}

	// Enable writing to the audio buffer again?
	self->audio_packet_type = previous_audio_packet_type;

	if (frame) {
		self->time = frame->time;
	}

	self->has_ended = FALSE;
	return frame;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %esi, %ebp
movsd %xmm0, 0x8(%rsp)
movq %rdi, %rbx
callq 0x267c
testl %eax, %eax
je 0x3b49
movl 0x20(%rbx), %r14d
testl %r14d, %r14d
je 0x3b49
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x3b5e
movsd %xmm0, 0x10(%rsp)
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x30d8
xorpd %xmm1, %xmm1
movsd 0x8(%rsp), %xmm2
ucomisd %xmm2, %xmm1
ja 0x3a5e
ucomisd %xmm0, %xmm2
movapd %xmm2, %xmm1
jbe 0x3a5e
movapd %xmm0, %xmm1
movq (%rbx), %rdi
movsd %xmm1, 0x8(%rsp)
movapd %xmm1, %xmm0
movl %r14d, %esi
movl $0x1, %edx
callq 0x3c2e
xorl %r14d, %r14d
testq %rax, %rax
je 0x3b4c
movq %rax, %r15
movl 0x40(%rbx), %r12d
movl %r14d, 0x40(%rbx)
movq 0x30(%rbx), %r13
movq 0xa0(%r13), %rdi
xorl %esi, %esi
callq 0x430a
movq $0x0, 0x10(%r13)
movl %r14d, 0x18(%r13)
movl %r14d, 0x2f8(%r13)
movl $0xffffffff, 0x40(%r13) # imm = 0xFFFFFFFF
movq 0x30(%rbx), %rax
movsd 0x8(%r15), %xmm0
subsd 0x10(%rsp), %xmm0
movsd (%rax), %xmm1
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %ecx
movl %ecx, 0x18(%rax)
movsd %xmm0, 0x10(%rax)
movq 0x28(%rbx), %rdi
movq 0x10(%r15), %rdx
movq 0x18(%r15), %rsi
callq 0x394d
movq 0x30(%rbx), %rdi
callq 0x3508
movq %rax, %r14
testl %ebp, %ebp
sete %al
testq %r14, %r14
sete %cl
orb %al, %cl
jne 0x3b2d
movsd 0x8(%rsp), %xmm0
ucomisd (%r14), %xmm0
jbe 0x3b2d
movq 0x30(%rbx), %rdi
callq 0x3508
movq %rax, %r14
testq %rax, %rax
jne 0x3b0c
xorl %r14d, %r14d
movl %r12d, 0x40(%rbx)
testq %r14, %r14
je 0x3b40
movsd (%r14), %xmm0
movsd %xmm0, 0x8(%rbx)
movl $0x0, 0x10(%rbx)
jmp 0x3b4c
xorl %r14d, %r14d
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq