// File: /workspace/github_c_makefile_star2_O1/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_video_decode_macroblock
void plm_video_decode_macroblock(plm_video_t *self) {
	// Decode increment
	int increment = 0;
	int t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);

	while (t == 34) {
		// macroblock_stuffing
		t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
	}
	while (t == 35) {
		// macroblock_escape
		increment += 33;
		t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
	}
	increment += t;

	// Process any skipped macroblocks
	if (self->slice_begin) {
		// The first increment of each slice is relative to beginning of the
		// previous row, not the previous macroblock
		self->slice_begin = FALSE;
		self->macroblock_address += increment;
	}
	else {
		if (self->macroblock_address + increment >= self->mb_size) {
			return; // invalid
		}
		if (increment > 1) {
			// Skipped macroblocks reset DC predictors
			self->dc_predictor[0] = 128;
			self->dc_predictor[1] = 128;
			self->dc_predictor[2] = 128;

			// Skipped macroblocks in P-pictures reset motion vectors
			if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
				self->motion_forward.h = 0;
				self->motion_forward.v = 0;
			}
		}

		// Predict skipped macroblocks
		while (increment > 1) {
			self->macroblock_address++;
			self->mb_row = self->macroblock_address / self->mb_width;
			self->mb_col = self->macroblock_address % self->mb_width;

			plm_video_predict_macroblock(self);
			increment--;
		}
		self->macroblock_address++;
	}

	self->mb_row = self->macroblock_address / self->mb_width;
	self->mb_col = self->macroblock_address % self->mb_width;

	if (self->mb_col >= self->mb_width || self->mb_row >= self->mb_height) {
		return; // corrupt stream;
	}

	// Process the current macroblock
	const plm_vlc_t *table = PLM_VIDEO_MACROBLOCK_TYPE[self->picture_type];
	self->macroblock_type = plm_buffer_read_vlc(self->buffer, table);

	self->macroblock_intra = (self->macroblock_type & 0x01);
	self->motion_forward.is_set = (self->macroblock_type & 0x08);
	self->motion_backward.is_set = (self->macroblock_type & 0x04);

	// Quantizer scale
	if ((self->macroblock_type & 0x10) != 0) {
		self->quantizer_scale = plm_buffer_read(self->buffer, 5);
	}

	if (self->macroblock_intra) {
		// Intra-coded macroblocks reset motion vectors
		self->motion_backward.h = self->motion_forward.h = 0;
		self->motion_backward.v = self->motion_forward.v = 0;
	}
	else {
		// Non-intra macroblocks reset DC predictors
		self->dc_predictor[0] = 128;
		self->dc_predictor[1] = 128;
		self->dc_predictor[2] = 128;

		plm_video_decode_motion_vectors(self);
		plm_video_predict_macroblock(self);
	}

	// Decode blocks
	int cbp = ((self->macroblock_type & 0x02) != 0)
		? plm_buffer_read_vlc(self->buffer, PLM_VIDEO_CODE_BLOCK_PATTERN)
		: (self->macroblock_intra ? 0x3f : 0);

	for (int block = 0, mask = 0x20; block < 6; block++) {
		if ((cbp & mask) != 0) {
			plm_video_decode_block(self, block);
		}
		mask >>= 1;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
movq 0xa0(%rdi), %r14
xorl %eax, %eax
leaq 0x4263(%rip), %r15      # 0x91e0
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x43f5
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4f7d
jmp 0x4fc6
movq 0xa0(%rbx), %r14
xorl %eax, %eax
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x43f5
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4fa7
movzwl 0x2(%r15,%rcx,4), %eax
cmpw $0x22, %ax
je 0x4f9e
xorl %r12d, %r12d
cmpw $0x23, %ax
jne 0x5016
xorl %r12d, %r12d
movq 0xa0(%rbx), %r14
xorl %eax, %eax
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x43f5
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4fe7
addl $0x21, %r12d
movzwl 0x2(%r15,%rcx,4), %eax
cmpw $0x23, %ax
je 0x4fde
movswl %ax, %ecx
leal (%r12,%rcx), %eax
cmpl $0x0, 0x78(%rbx)
je 0x502c
movl $0x0, 0x78(%rbx)
jmp 0x509f
movl 0x7c(%rbx), %edx
addl %eax, %edx
cmpl 0x2c(%rbx), %edx
jge 0x51f1
cmpl $0x2, %eax
jl 0x5068
movabsq $0x8000000080, %rdx     # imm = 0x8000000080
movq %rdx, 0x90(%rbx)
movl $0x80, 0x98(%rbx)
cmpl $0x2, 0x44(%rbx)
jne 0x5068
movq $0x0, 0x54(%rbx)
cmpl $0x2, %eax
jl 0x509a
leal (%r12,%rcx), %ebp
incl %ebp
movl 0x7c(%rbx), %eax
incl %eax
movl %eax, 0x7c(%rbx)
cltd
idivl 0x24(%rbx)
movl %eax, 0x80(%rbx)
movl %edx, 0x84(%rbx)
movq %rbx, %rdi
callq 0x51fa
decl %ebp
cmpl $0x2, %ebp
jg 0x5073
movl $0x1, %eax
addl 0x7c(%rbx), %eax
movl %eax, 0x7c(%rbx)
movl 0x24(%rbx), %ecx
cltd
idivl %ecx
movl %eax, 0x80(%rbx)
movl %edx, 0x84(%rbx)
testl %ecx, %ecx
js 0x51f1
cmpl 0x28(%rbx), %eax
jge 0x51f1
movslq 0x44(%rbx), %rax
leaq 0x8cdd(%rip), %rcx      # 0xddb0
movq (%rcx,%rax,8), %r15
movq 0xa0(%rbx), %r14
xorl %eax, %eax
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x43f5
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x50e0
movswl 0x2(%r15,%rcx,4), %eax
movl %eax, 0x88(%rbx)
movl %eax, %ecx
andl $0x1, %ecx
movl %ecx, 0x8c(%rbx)
movl %eax, %ecx
andl $0x8, %ecx
movl %ecx, 0x4c(%rbx)
movl %eax, %ecx
andl $0x4, %ecx
movl %ecx, 0x60(%rbx)
testb $0x10, %al
je 0x513e
movq 0xa0(%rbx), %rdi
movl $0x5, %esi
callq 0x43f5
movl %eax, 0x74(%rbx)
cmpl $0x0, 0x8c(%rbx)
je 0x5153
xorl %eax, %eax
movq %rax, 0x54(%rbx)
movq %rax, 0x68(%rbx)
jmp 0x517e
movabsq $0x8000000080, %rax     # imm = 0x8000000080
movq %rax, 0x90(%rbx)
movl $0x80, 0x98(%rbx)
movq %rbx, %rdi
callq 0x528b
movq %rbx, %rdi
callq 0x51fa
testb $0x2, 0x88(%rbx)
jne 0x519b
movl 0x8c(%rbx), %eax
testl %eax, %eax
movl $0x3f, %r14d
cmovel %eax, %r14d
jmp 0x51d0
movq 0xa0(%rbx), %r14
xorl %eax, %eax
leaq 0x4175(%rip), %r15      # 0x9320
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x43f5
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x51ab
movzwl 0x2(%r15,%rcx,4), %r14d
xorl %ebp, %ebp
movl $0x20, %r15d
testl %r14d, %r15d
je 0x51e7
movq %rbx, %rdi
movl %ebp, %esi
callq 0x52fa
shrl %r15d
incl %ebp
cmpl $0x6, %ebp
jne 0x51d8
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq