// File: /workspace/github_c_makefile_star2_O2/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_video_decode_sequence_header
int plm_video_decode_sequence_header(plm_video_t *self) {
	int max_header_size = 64 + 2 * 64 * 8; // 64 bit header + 2x 64 byte matrix
	if (!plm_buffer_has(self->buffer, max_header_size)) {
		return FALSE;
	}

	self->width = plm_buffer_read(self->buffer, 12);
	self->height = plm_buffer_read(self->buffer, 12);

	if (self->width <= 0 || self->height <= 0) {
		return FALSE;
	}

	// Get pixel aspect ratio
	int pixel_aspect_ratio_code;
	pixel_aspect_ratio_code = plm_buffer_read(self->buffer, 4);
	pixel_aspect_ratio_code -= 1;
	if (pixel_aspect_ratio_code < 0) {
		pixel_aspect_ratio_code = 0;
	}
	int par_last = (sizeof(PLM_VIDEO_PIXEL_ASPECT_RATIO) /
			sizeof(PLM_VIDEO_PIXEL_ASPECT_RATIO[0]) - 1);
	if (pixel_aspect_ratio_code > par_last) {
		pixel_aspect_ratio_code = par_last;
	}
	self->pixel_aspect_ratio =
		PLM_VIDEO_PIXEL_ASPECT_RATIO[pixel_aspect_ratio_code];

	// Get frame rate
	self->framerate = PLM_VIDEO_PICTURE_RATE[plm_buffer_read(self->buffer, 4)];

	// Skip bit_rate, marker, buffer_size and constrained bit
	plm_buffer_skip(self->buffer, 18 + 1 + 10 + 1);

	// Load custom intra quant matrix?
	if (plm_buffer_read(self->buffer, 1)) { 
		for (int i = 0; i < 64; i++) {
			int idx = PLM_VIDEO_ZIG_ZAG[i];
			self->intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8);
		}
	}
	else {
		memcpy(self->intra_quant_matrix, PLM_VIDEO_INTRA_QUANT_MATRIX, 64);
	}

	// Load custom non intra quant matrix?
	if (plm_buffer_read(self->buffer, 1)) { 
		for (int i = 0; i < 64; i++) {
			int idx = PLM_VIDEO_ZIG_ZAG[i];
			self->non_intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8);
		}
	}
	else {
		memcpy(self->non_intra_quant_matrix, PLM_VIDEO_NON_INTRA_QUANT_MATRIX, 64);
	}

	self->mb_width = (self->width + 15) >> 4;
	self->mb_height = (self->height + 15) >> 4;
	self->mb_size = self->mb_width * self->mb_height;

	self->luma_width = self->mb_width << 4;
	self->luma_height = self->mb_height << 4;

	self->chroma_width = self->mb_width << 3;
	self->chroma_height = self->mb_height << 3;


	// Allocate one big chunk of data for all 3 frames = 9 planes
	size_t luma_plane_size = self->luma_width * self->luma_height;
	size_t chroma_plane_size = self->chroma_width * self->chroma_height;
	size_t frame_data_size = (luma_plane_size + 2 * chroma_plane_size);

	self->frames_data = (uint8_t*)PLM_MALLOC(frame_data_size * 3);
	plm_video_init_frame(self, &self->frame_current, self->frames_data + frame_data_size * 0);
	plm_video_init_frame(self, &self->frame_forward, self->frames_data + frame_data_size * 1);
	plm_video_init_frame(self, &self->frame_backward, self->frames_data + frame_data_size * 2);

	self->has_sequence_header = TRUE;
	return TRUE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0xa0(%rdi), %rdi
movl $0x440, %esi            # imm = 0x440
callq 0x3b9d
xorl %ebp, %ebp
testl %eax, %eax
je 0x4286
movq 0xa0(%rbx), %rdi
pushq $0xc
popq %r14
movl %r14d, %esi
callq 0x3c08
movl %eax, 0x1c(%rbx)
movq 0xa0(%rbx), %rdi
movl %r14d, %esi
callq 0x3c08
movl %eax, 0x20(%rbx)
cmpl $0x0, 0x1c(%rbx)
setle %cl
testl %eax, %eax
setle %al
orb %cl, %al
jne 0x4286
movq 0xa0(%rbx), %rdi
pushq $0x4
popq %r14
movl %r14d, %esi
callq 0x3c08
cmpl $0x2, %eax
pushq $0x1
popq %rbp
movl %ebp, %ecx
cmovgel %eax, %ecx
decl %ecx
cmpl $0xf, %eax
pushq $0xd
popq %rax
cmovll %ecx, %eax
leaq 0x4190(%rip), %rcx      # 0x8250
cvtss2sd (%rcx,%rax,4), %xmm0
movsd %xmm0, 0x8(%rbx)
movq 0xa0(%rbx), %rdi
movl %r14d, %esi
callq 0x3c08
cltq
leaq 0x41ae(%rip), %rcx      # 0x8290
movsd (%rcx,%rax,8), %xmm0
movsd %xmm0, (%rbx)
movq 0xa0(%rbx), %rdi
pushq $0x1e
popq %rsi
callq 0x3c94
movq 0xa0(%rbx), %rdi
movl %ebp, %esi
callq 0x3c08
testl %eax, %eax
je 0x413f
xorl %r14d, %r14d
leaq 0x41fa(%rip), %r15      # 0x8310
pushq $0x8
popq %rbp
cmpq $0x40, %r14
je 0x4171
movzbl (%r14,%r15), %r12d
movq 0xa0(%rbx), %rdi
movl %ebp, %esi
callq 0x3c08
movb %al, 0x278(%rbx,%r12)
incq %r14
jmp 0x4119
leaq 0x278(%rbx), %rax
movaps 0x4233(%rip), %xmm0     # 0x8380
movups %xmm0, 0x30(%rax)
movaps 0x4218(%rip), %xmm0     # 0x8370
movups %xmm0, 0x20(%rax)
movaps 0x41fd(%rip), %xmm0     # 0x8360
movups %xmm0, 0x10(%rax)
movaps 0x41e2(%rip), %xmm0     # 0x8350
movups %xmm0, (%rax)
movq 0xa0(%rbx), %rdi
pushq $0x1
popq %rbp
movl %ebp, %esi
callq 0x3c08
testl %eax, %eax
je 0x41bb
xorl %r15d, %r15d
leaq 0x4180(%rip), %r12      # 0x8310
pushq $0x8
popq %r14
cmpq $0x40, %r15
je 0x41d8
movzbl (%r15,%r12), %r13d
movq 0xa0(%rbx), %rdi
movl %r14d, %esi
callq 0x3c08
movb %al, 0x2b8(%rbx,%r13)
incq %r15
jmp 0x4194
leaq 0x2b8(%rbx), %rax
movaps 0x3e57(%rip), %xmm0     # 0x8020
movups %xmm0, 0x30(%rax)
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movslq 0x1c(%rbx), %rax
addq $0xf, %rax
movl %eax, %ecx
sarl $0x4, %ecx
movl %ecx, 0x24(%rbx)
movslq 0x20(%rbx), %rdx
addq $0xf, %rdx
movl %edx, %esi
sarl $0x4, %esi
movl %esi, 0x28(%rbx)
movl %esi, %edi
imull %ecx, %edi
movl %edi, 0x2c(%rbx)
andq $-0x10, %rax
movl %eax, 0x30(%rbx)
andq $-0x10, %rdx
movl %edx, 0x34(%rbx)
shll $0x3, %ecx
movl %ecx, 0x38(%rbx)
shll $0x3, %esi
movl %esi, 0x3c(%rbx)
imulq %rax, %rdx
imull %ecx, %esi
movslq %esi, %rax
leaq (%rdx,%rax,2), %r14
leaq (%r14,%r14,2), %rdi
callq 0x2210
movq %rax, 0x170(%rbx)
leaq 0xb0(%rbx), %rsi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x448e
leaq 0xf0(%rbx), %rsi
movq 0x170(%rbx), %rdx
addq %r14, %rdx
movq %rbx, %rdi
callq 0x448e
leaq 0x130(%rbx), %rsi
addq %r14, %r14
addq 0x170(%rbx), %r14
movq %rbx, %rdi
movq %r14, %rdx
callq 0x448e
movl $0x1, 0x70(%rbx)
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq