// File: /workspace/github_c_makefile_star2_O3/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_demux_get_duration
double plm_demux_get_duration(plm_demux_t *self, int type) {
	size_t file_size = plm_buffer_get_size(self->buffer);

	if (
		self->duration != PLM_PACKET_INVALID_TS &&
		self->last_file_size == file_size
	) {
		return self->duration;
	}

	size_t previous_pos = plm_buffer_tell(self->buffer);
	int previous_start_code = self->start_code;
	
	// Find last video PTS. Start searching 64kb from the end and go further 
	// back if needed.
	long start_range = 64 * 1024;
	long max_range = 4096 * 1024;
	for (long range = start_range; range <= max_range; range *= 2) {
		long seek_pos = file_size - range;
		if (seek_pos < 0) {
			seek_pos = 0;
			range = max_range; // Make sure to bail after this round
		}
		plm_demux_buffer_seek(self, seek_pos);
		self->current_packet.length = 0;

		double last_pts = PLM_PACKET_INVALID_TS;
		plm_packet_t *packet = NULL;
		while ((packet = plm_demux_decode(self))) {
			if (packet->pts != PLM_PACKET_INVALID_TS && packet->type == type) {
				last_pts = packet->pts;
			}
		}
		if (last_pts != PLM_PACKET_INVALID_TS) {
			self->duration = last_pts - plm_demux_get_start_time(self, type);
			break;
		}
	}

	plm_demux_buffer_seek(self, previous_pos);
	self->start_code = previous_start_code;
	self->last_file_size = file_size;
	return self->duration;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %esi, %ebp
movq %rdi, %rbx
movq (%rdi), %r15
xorl %eax, %eax
cmpl $0x0, 0x60(%r15)
sete %al
movq 0x10(%r15,%rax,8), %r14
movsd 0x30(%rdi), %xmm0
ucomisd 0x623b(%rip), %xmm0     # 0x9230
jne 0x2ff9
jnp 0x3003
cmpq %r14, 0x18(%rbx)
je 0x3126
movq 0x48(%r15), %rax
testq %rax, %rax
je 0x302a
movq 0x50(%r15), %rsi
movq %r15, %rdi
callq *%rax
movq (%r15), %rcx
shrq $0x3, %rcx
addq %rax, %rcx
subq 0x10(%r15), %rcx
movq %rcx, 0x10(%rsp)
jmp 0x3036
movq (%r15), %rax
shrq $0x3, %rax
movq %rax, 0x10(%rsp)
movl 0x38(%rbx), %eax
movl %eax, 0xc(%rsp)
movl $0x10000, %r15d         # imm = 0x10000
xorl %r13d, %r13d
movq %r14, %r12
subq %r15, %r12
testq %r12, %r12
movl $0x0, %esi
cmovgq %r12, %rsi
movq (%rbx), %rdi
callq 0x4120
movq %r13, 0x80(%rbx)
movl $0xffffffff, 0x38(%rbx) # imm = 0xFFFFFFFF
movq %r13, 0x60(%rbx)
movq %rbx, %rdi
callq 0x36fb
testq %rax, %rax
je 0x30c4
movsd 0x61a9(%rip), %xmm0     # 0x9230
movsd %xmm0, (%rsp)
movsd 0x8(%rax), %xmm0
ucomisd 0x6197(%rip), %xmm0     # 0x9230
jne 0x309d
jnp 0x30a6
cmpl %ebp, (%rax)
jne 0x30a6
movsd %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x36fb
testq %rax, %rax
jne 0x308c
movsd (%rsp), %xmm0
ucomisd 0x6170(%rip), %xmm0     # 0x9230
jne 0x30df
jp 0x30df
testq %r12, %r12
js 0x30fc
leaq (%r15,%r15), %rax
cmpq $0x200001, %r15         # imm = 0x200001
movq %rax, %r15
jb 0x3046
jmp 0x30fc
movq %rbx, %rdi
movl %ebp, %esi
movsd %xmm0, (%rsp)
callq 0x39d7
movsd (%rsp), %xmm1
subsd %xmm0, %xmm1
movsd %xmm1, 0x30(%rbx)
movq (%rbx), %rdi
movq 0x10(%rsp), %rsi
callq 0x4120
xorl %eax, %eax
movq %rax, 0x60(%rbx)
movq %rax, 0x80(%rbx)
movl 0xc(%rsp), %eax
movl %eax, 0x38(%rbx)
movq %r14, 0x18(%rbx)
movsd 0x30(%rbx), %xmm0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq