// File: /workspace/github_c_makefile_star2_O2/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_video_decode_picture
void plm_video_decode_picture(plm_video_t *self) {
	plm_buffer_skip(self->buffer, 10); // skip temporalReference
	self->picture_type = plm_buffer_read(self->buffer, 3);
	plm_buffer_skip(self->buffer, 16); // skip vbv_delay

	// D frames or unknown coding type
	if (self->picture_type <= 0 || self->picture_type > PLM_VIDEO_PICTURE_TYPE_B) {
		return;
	}

	// Forward full_px, f_code
	if (
		self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE ||
		self->picture_type == PLM_VIDEO_PICTURE_TYPE_B
	) {
		self->motion_forward.full_px = plm_buffer_read(self->buffer, 1);
		int f_code = plm_buffer_read(self->buffer, 3);
		if (f_code == 0) {
			// Ignore picture with zero f_code
			return;
		}
		self->motion_forward.r_size = f_code - 1;
	}

	// Backward full_px, f_code
	if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
		self->motion_backward.full_px = plm_buffer_read(self->buffer, 1);
		int f_code = plm_buffer_read(self->buffer, 3);
		if (f_code == 0) {
			// Ignore picture with zero f_code
			return;
		}
		self->motion_backward.r_size = f_code - 1;
	}

	plm_frame_t frame_temp = self->frame_forward;
	if (
		self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA ||
		self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE
	) {
		self->frame_forward = self->frame_backward;
	}


	// Find first slice start code; skip extension and user data
	do {
		self->start_code = plm_buffer_next_start_code(self->buffer);
	} while (
		self->start_code == PLM_START_EXTENSION || 
		self->start_code == PLM_START_USER_DATA
	);

	// Decode all slices
	while (PLM_START_IS_SLICE(self->start_code)) {
		plm_video_decode_slice(self, self->start_code & 0x000000FF);
		if (self->macroblock_address >= self->mb_size - 2) {
			break;
		}
		self->start_code = plm_buffer_next_start_code(self->buffer);
	}

	// If this is a reference picture rotate the prediction pointers
	if (
		self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA ||
		self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE
	) {
		self->frame_backward = self->frame_current;
		self->frame_current = frame_temp;
	}
}

// Assembly:
pushq %rbx
subq $0x40, %rsp
movq %rdi, %rbx
movq 0xa0(%rdi), %rdi
pushq $0xa
popq %rsi
callq 0x3c94
movq 0xa0(%rbx), %rdi
pushq $0x3
popq %rsi
callq 0x3c08
movl %eax, 0x44(%rbx)
movq 0xa0(%rbx), %rdi
pushq $0x10
popq %rsi
callq 0x3c94
movl 0x44(%rbx), %eax
leal -0x4(%rax), %ecx
cmpl $-0x3, %ecx
jb 0x4488
cmpl $0x2, %eax
jae 0x42fa
pushq $0x1
popq %rax
jmp 0x4361
movq 0xa0(%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x3c08
movl %eax, 0x48(%rbx)
movq 0xa0(%rbx), %rdi
pushq $0x3
popq %rsi
callq 0x3c08
testl %eax, %eax
je 0x4488
decl %eax
movl %eax, 0x50(%rbx)
movl 0x44(%rbx), %eax
cmpl $0x3, %eax
jne 0x4361
movq 0xa0(%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x3c08
movl %eax, 0x5c(%rbx)
movq 0xa0(%rbx), %rdi
pushq $0x3
popq %rsi
callq 0x3c08
testl %eax, %eax
je 0x4488
decl %eax
movl %eax, 0x64(%rbx)
movl 0x44(%rbx), %eax
movups 0xf0(%rbx), %xmm0
movups 0x100(%rbx), %xmm1
movups 0x110(%rbx), %xmm2
movups 0x120(%rbx), %xmm3
movaps %xmm3, 0x30(%rsp)
movaps %xmm2, 0x20(%rsp)
movaps %xmm1, 0x10(%rsp)
movaps %xmm0, (%rsp)
decl %eax
cmpl $0x1, %eax
ja 0x43c9
leaq 0xf0(%rbx), %rax
movups 0x130(%rbx), %xmm0
movups 0x140(%rbx), %xmm1
movups 0x150(%rbx), %xmm2
movups 0x160(%rbx), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
movq 0xa0(%rbx), %rdi
callq 0x3d0c
movl %eax, 0x40(%rbx)
cmpl $0xb2, %eax
je 0x43c9
cmpl $0xb5, %eax
je 0x43c9
jmp 0x440c
movq %rbx, %rdi
movl %eax, %esi
callq 0x44e3
movl 0x2c(%rbx), %eax
addl $-0x2, %eax
cmpl %eax, 0x7c(%rbx)
jge 0x4417
movq 0xa0(%rbx), %rdi
callq 0x3d0c
movl %eax, 0x40(%rbx)
leal -0x1(%rax), %ecx
cmpl $0xae, %ecx
jbe 0x43e8
movl 0x44(%rbx), %eax
decl %eax
cmpl $0x1, %eax
ja 0x4488
movups 0xb0(%rbx), %xmm0
movups 0xc0(%rbx), %xmm1
movups 0xd0(%rbx), %xmm2
movups 0xe0(%rbx), %xmm3
movups %xmm3, 0x160(%rbx)
movups %xmm2, 0x150(%rbx)
movups %xmm1, 0x140(%rbx)
movups %xmm0, 0x130(%rbx)
movaps (%rsp), %xmm0
movaps 0x10(%rsp), %xmm1
movaps 0x20(%rsp), %xmm2
movaps 0x30(%rsp), %xmm3
movups %xmm0, 0xb0(%rbx)
movups %xmm1, 0xc0(%rbx)
movups %xmm2, 0xd0(%rbx)
movups %xmm3, 0xe0(%rbx)
addq $0x40, %rsp
popq %rbx
retq