// File: /workspace/github_c_makefile_star2_O3/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 0x4607(%rip), %r15      # 0x93e0
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x4215
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4dd9
jmp 0x4e22
movq 0xa0(%rbx), %r14
xorl %eax, %eax
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x4215
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4e03
movzwl 0x2(%r15,%rcx,4), %eax
cmpw $0x22, %ax
je 0x4dfa
xorl %r12d, %r12d
cmpw $0x23, %ax
jne 0x4e72
xorl %r12d, %r12d
movq 0xa0(%rbx), %r14
xorl %eax, %eax
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x4215
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4e43
addl $0x21, %r12d
movzwl 0x2(%r15,%rcx,4), %eax
cmpw $0x23, %ax
je 0x4e3a
movswl %ax, %ecx
leal (%r12,%rcx), %edx
cmpl $0x0, 0x78(%rbx)
je 0x4e90
movl $0x0, 0x78(%rbx)
addl 0x7c(%rbx), %edx
movl %edx, 0x7c(%rbx)
movl %edx, %eax
jmp 0x4f02
movl 0x7c(%rbx), %eax
leal (%rax,%rdx), %esi
cmpl 0x2c(%rbx), %esi
jge 0x5050
cmpl $0x2, %edx
jl 0x4efd
movabsq $0x8000000080, %rax     # imm = 0x8000000080
movq %rax, 0x90(%rbx)
movl $0x80, 0x98(%rbx)
cmpl $0x2, 0x44(%rbx)
jne 0x4ecd
movq $0x0, 0x54(%rbx)
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 0x5059
decl %ebp
cmpl $0x2, %ebp
ja 0x4ed3
movl 0x7c(%rbx), %eax
incl %eax
movl %eax, 0x7c(%rbx)
movl 0x24(%rbx), %ecx
cltd
idivl %ecx
movl %eax, 0x80(%rbx)
movl %edx, 0x84(%rbx)
testl %ecx, %ecx
js 0x5050
cmpl 0x28(%rbx), %eax
jge 0x5050
movslq 0x44(%rbx), %rax
leaq 0x8e80(%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 0x4215
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x4f3d
movswl 0x2(%r15,%rcx,4), %ecx
movl %ecx, 0x88(%rbx)
movl %ecx, %eax
andl $0x1, %eax
movl %eax, 0x8c(%rbx)
movl %ecx, %edx
andl $0x8, %edx
movl %edx, 0x4c(%rbx)
movl %ecx, %edx
andl $0x4, %edx
movl %edx, 0x60(%rbx)
testb $0x10, %cl
je 0x4fa2
movq 0xa0(%rbx), %rdi
movl $0x5, %esi
callq 0x4215
movl %eax, 0x74(%rbx)
movl 0x8c(%rbx), %eax
testl %eax, %eax
je 0x4fb2
xorl %eax, %eax
movq %rax, 0x54(%rbx)
movq %rax, 0x68(%rbx)
jmp 0x4fdd
movabsq $0x8000000080, %rax     # imm = 0x8000000080
movq %rax, 0x90(%rbx)
movl $0x80, 0x98(%rbx)
movq %rbx, %rdi
callq 0x50ea
movq %rbx, %rdi
callq 0x5059
testb $0x2, 0x88(%rbx)
jne 0x4ffa
movl 0x8c(%rbx), %eax
testl %eax, %eax
movl $0x3f, %r14d
cmovel %eax, %r14d
jmp 0x502f
movq 0xa0(%rbx), %r14
xorl %eax, %eax
leaq 0x4516(%rip), %r15      # 0x9520
movzwl %ax, %ebp
movq %r14, %rdi
movl $0x1, %esi
callq 0x4215
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r15,%rcx,4), %eax
testw %ax, %ax
jg 0x500a
movzwl 0x2(%r15,%rcx,4), %r14d
xorl %ebp, %ebp
movl $0x20, %r15d
testl %r14d, %r15d
je 0x5046
movq %rbx, %rdi
movl %ebp, %esi
callq 0x5159
shrl %r15d
incl %ebp
cmpl $0x6, %ebp
jne 0x5037
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq