// File: /workspace/github_c_makefile_star2_O1/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_video_decode
plm_frame_t *plm_video_decode(plm_video_t *self) {
	if (!plm_video_has_header(self)) {
		return NULL;
	}
	
	plm_frame_t *frame = NULL;
	do {
		if (self->start_code != PLM_START_PICTURE) {
			self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_PICTURE);
			
			if (self->start_code == -1) {
				// If we reached the end of the file and the previously decoded
				// frame was a reference frame, we still have to return it.
				if (
					self->has_reference_frame &&
					!self->assume_no_b_frames &&
					plm_buffer_has_ended(self->buffer) && (
						self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA ||
						self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE
					)
				) {
					self->has_reference_frame = FALSE;
					frame = &self->frame_backward;
					break;
				}

				return NULL;
			}
		}

		// Make sure we have a full picture in the buffer before attempting to
		// decode it. Sadly, this can only be done by seeking for the start code
		// of the next picture. Also, if we didn't find the start code for the
		// next picture, but the source has ended, we assume that this last
		// picture is in the buffer.
		if (
			plm_buffer_has_start_code(self->buffer, PLM_START_PICTURE) == -1 &&
			!plm_buffer_has_ended(self->buffer)
		) {
			return NULL;
		}
		plm_buffer_discard_read_bytes(self->buffer);
		
		plm_video_decode_picture(self);

		if (self->assume_no_b_frames) {
			frame = &self->frame_backward;
		}
		else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
			frame = &self->frame_current;
		}
		else if (self->has_reference_frame) {
			frame = &self->frame_forward;
		}
		else {
			self->has_reference_frame = TRUE;
		}
	} while (!frame);
	
	frame->time = self->time;
	self->frames_decoded++;
	self->time = (double)self->frames_decoded / self->framerate;
	
	return frame;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
callq 0x2cd3
testl %eax, %eax
je 0x363a
leaq 0x130(%rbx), %r15
leaq 0xf0(%rbx), %rax
movq %rax, 0x8(%rsp)
leaq 0xb0(%rbx), %rax
movq %rax, 0x10(%rsp)
xorl %ebp, %ebp
cmpl $0x0, 0x40(%rbx)
je 0x3570
movq 0xa0(%rbx), %r14
movq %r14, %rdi
callq 0x4500
leal 0x1(%rax), %ecx
cmpl $0x1, %ecx
ja 0x3554
movl %eax, 0x40(%rbx)
cmpl $-0x1, %eax
je 0x3628
movq 0xa0(%rbx), %r14
movq (%r14), %r12
movl 0x20(%r14), %r13d
movl $0x0, 0x20(%r14)
movq %r14, %rdi
callq 0x4500
leal 0x1(%rax), %ecx
cmpl $0x1, %ecx
ja 0x3586
movq %r12, (%r14)
movl %r13d, 0x20(%r14)
cmpl $-0x1, %eax
jne 0x35b3
movq 0xa0(%rbx), %rax
cmpl $0x0, 0x24(%rax)
je 0x363a
movq 0xa0(%rbx), %rdi
callq 0x42b2
movq %rbx, %rdi
callq 0x4c48
cmpl $0x0, 0x2fc(%rbx)
movq %r15, %rax
jne 0x35f9
cmpl $0x3, 0x44(%rbx)
movq 0x10(%rsp), %rax
je 0x35f9
cmpl $0x0, 0x2f8(%rbx)
movq 0x8(%rsp), %rax
jne 0x35f9
movl $0x1, 0x2f8(%rbx)
movq %rbp, %rax
movq %rax, %rbp
testq %rax, %rax
je 0x3547
movsd 0x10(%rbx), %xmm0
movsd %xmm0, (%rax)
movl 0x18(%rbx), %ecx
incl %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
movl %ecx, 0x18(%rbx)
divsd (%rbx), %xmm0
movsd %xmm0, 0x10(%rbx)
jmp 0x363c
cmpl $0x0, 0x2f8(%rbx)
je 0x363a
cmpl $0x0, 0x2fc(%rbx)
je 0x364b
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xa0(%rbx), %rax
cmpl $0x0, 0x24(%rax)
je 0x363a
movl 0x44(%rbx), %eax
decl %eax
cmpl $0x1, %eax
ja 0x363a
movl $0x0, 0x2f8(%rbx)
leaq 0x130(%rbx), %rax
jmp 0x3605