// File: /workspace/github_c_makefile_star2_O3/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 %r12
pushq %rbx
movq %rdi, %rbx
callq 0x2bb6
testl %eax, %eax
je 0x34be
xorl %r14d, %r14d
cmpl $0x0, 0x40(%rbx)
je 0x3427
movq 0xa0(%rbx), %r15
movq %r15, %rdi
callq 0x4320
leal 0x1(%rax), %ecx
cmpl $0x1, %ecx
ja 0x340b
movl %eax, 0x40(%rbx)
cmpl $-0x1, %eax
je 0x34ac
movq 0xa0(%rbx), %r15
movq (%r15), %r12
movl 0x20(%r15), %ebp
movl $0x0, 0x20(%r15)
movq %r15, %rdi
callq 0x4320
leal 0x1(%rax), %ecx
cmpl $0x1, %ecx
ja 0x343d
movq %r12, (%r15)
movl %ebp, 0x20(%r15)
movq 0xa0(%rbx), %rdi
cmpl $-0x1, %eax
jne 0x346a
cmpl $0x0, 0x24(%rdi)
je 0x350f
callq 0x40c8
movq %rbx, %rdi
callq 0x4a68
cmpl $0x0, 0x2fc(%rbx)
jne 0x34e4
cmpl $0x3, 0x44(%rbx)
je 0x349e
cmpl $0x0, 0x2f8(%rbx)
jne 0x34a5
movl $0x1, 0x2f8(%rbx)
jmp 0x33fe
movl $0xb0, %eax
jmp 0x34e9
movl $0xf0, %eax
jmp 0x34e9
cmpl $0x0, 0x2f8(%rbx)
je 0x34be
cmpl $0x0, 0x2fc(%rbx)
je 0x34c3
xorl %r14d, %r14d
jmp 0x350f
movq 0xa0(%rbx), %rax
cmpl $0x0, 0x24(%rax)
je 0x34be
movl 0x44(%rbx), %eax
decl %eax
cmpl $0x1, %eax
ja 0x34be
movl $0x0, 0x2f8(%rbx)
movl $0x130, %eax            # imm = 0x130
leaq (%rbx,%rax), %r14
movsd 0x10(%rbx), %xmm0
movsd %xmm0, (%rbx,%rax)
movl 0x18(%rbx), %eax
incl %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movl %eax, 0x18(%rbx)
divsd (%rbx), %xmm0
movsd %xmm0, 0x10(%rbx)
movq %r14, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq