// File: /workspace/github_c_makefile_star2_O3/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
subq $0x28, %rsp
movq %rdi, %rbx
movq 0xa0(%rdi), %rdi
movl $0x440, %esi            # imm = 0x440
callq 0x41a8
xorl %ebp, %ebp
testl %eax, %eax
je 0x4a45
movq 0xa0(%rbx), %rdi
movl $0xc, %esi
callq 0x4215
movl %eax, 0x1c(%rbx)
movq 0xa0(%rbx), %rdi
movl $0xc, %esi
callq 0x4215
movl %eax, 0x20(%rbx)
cmpl $0x0, 0x1c(%rbx)
setle %cl
testl %eax, %eax
setle %al
orb %cl, %al
jne 0x4a45
movq 0xa0(%rbx), %rdi
movl $0x4, %esi
callq 0x4215
cmpl $0x2, %eax
movl $0x1, %ecx
cmovgel %eax, %ecx
decl %ecx
cmpl $0xf, %eax
movl $0xd, %eax
cmovll %ecx, %eax
leaq 0x4b1c(%rip), %rcx      # 0x92a0
cvtss2sd (%rcx,%rax,4), %xmm0
movsd %xmm0, 0x8(%rbx)
movq 0xa0(%rbx), %rdi
movl $0x4, %esi
callq 0x4215
cltq
leaq 0x4b38(%rip), %rcx      # 0x92e0
movsd (%rcx,%rax,8), %xmm0
movsd %xmm0, (%rbx)
movq 0xa0(%rbx), %r14
movl $0x1e, %esi
movq %r14, %rdi
callq 0x41a8
testl %eax, %eax
je 0x47cd
addq $0x1e, (%r14)
movq 0xa0(%rbx), %rdi
movl $0x1, %esi
callq 0x4215
testl %eax, %eax
je 0x4815
xorl %r14d, %r14d
leaq 0x4b74(%rip), %r15      # 0x9360
movzbl (%r14,%r15), %r12d
movq 0xa0(%rbx), %rdi
movl $0x8, %esi
callq 0x4215
movb %al, 0x278(%rbx,%r12)
incq %r14
cmpq $0x40, %r14
jne 0x47ec
jmp 0x4847
leaq 0x278(%rbx), %rax
movaps 0x4bad(%rip), %xmm0     # 0x93d0
movups %xmm0, 0x30(%rax)
movaps 0x4b92(%rip), %xmm0     # 0x93c0
movups %xmm0, 0x20(%rax)
movaps 0x4b77(%rip), %xmm0     # 0x93b0
movups %xmm0, 0x10(%rax)
movaps 0x4b5c(%rip), %xmm0     # 0x93a0
movups %xmm0, (%rax)
movq 0xa0(%rbx), %rdi
movl $0x1, %esi
callq 0x4215
testl %eax, %eax
je 0x488f
xorl %r14d, %r14d
leaq 0x4afa(%rip), %r15      # 0x9360
movzbl (%r14,%r15), %r12d
movq 0xa0(%rbx), %rdi
movl $0x8, %esi
callq 0x4215
movb %al, 0x2b8(%rbx,%r12)
incq %r14
cmpq $0x40, %r14
jne 0x4866
jmp 0x48ac
leaq 0x2b8(%rbx), %rax
movaps 0x4783(%rip), %xmm0     # 0x9020
movups %xmm0, 0x30(%rax)
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movl 0x1c(%rbx), %eax
movq %rax, 0x20(%rsp)
movl 0x20(%rbx), %ecx
movq %rcx, 0x18(%rsp)
leal 0xf(%rax), %r13d
movl %r13d, %ebp
sarl $0x4, %ebp
movl %ebp, 0x24(%rbx)
leal 0xf(%rcx), %r15d
movl %r15d, %r14d
sarl $0x4, %r14d
movl %r14d, 0x28(%rbx)
movl %r14d, %eax
imull %ebp, %eax
movl %eax, 0x2c(%rbx)
andl $-0x10, %r13d
movl %r13d, 0x30(%rbx)
andl $-0x10, %r15d
movl %r15d, 0x34(%rbx)
shll $0x3, %ebp
movl %ebp, 0x38(%rbx)
shll $0x3, %r14d
movl %r14d, 0x3c(%rbx)
movl %r15d, %eax
imull %r13d, %eax
movslq %eax, %r12
movl %r14d, %eax
imull %ebp, %eax
cltq
movq %rax, 0x8(%rsp)
leaq (%r12,%rax,2), %rcx
movq %rcx, 0x10(%rsp)
leaq (%rcx,%rcx,2), %rdi
callq 0x2210
movq %rax, 0x170(%rbx)
movq 0x20(%rsp), %rsi
movl %esi, 0xb8(%rbx)
movq 0x18(%rsp), %rdx
movl %edx, 0xbc(%rbx)
movl %r13d, 0xc0(%rbx)
movl %r15d, 0xc4(%rbx)
movq %rax, 0xc8(%rbx)
movl %ebp, 0xd0(%rbx)
movl %r14d, 0xd4(%rbx)
leaq (%rax,%r12), %rcx
movq %rcx, 0xd8(%rbx)
movl %ebp, 0xe0(%rbx)
movl %r14d, 0xe4(%rbx)
movq 0x8(%rsp), %rdi
addq %rdi, %rcx
movq %rcx, 0xe8(%rbx)
movq 0x10(%rsp), %r8
leaq (%rax,%r8), %rcx
movl %esi, 0xf8(%rbx)
movl %edx, 0xfc(%rbx)
movl %r13d, 0x100(%rbx)
movl %r15d, 0x104(%rbx)
movq %rcx, 0x108(%rbx)
movl %ebp, 0x110(%rbx)
movl %r14d, 0x114(%rbx)
addq %r12, %rcx
movq %rcx, 0x118(%rbx)
movl %ebp, 0x120(%rbx)
movl %r14d, 0x124(%rbx)
addq %rdi, %rcx
movq %rcx, 0x128(%rbx)
leaq (%rax,%r8,2), %rax
movl %esi, 0x138(%rbx)
movl %edx, 0x13c(%rbx)
movl %r13d, 0x140(%rbx)
movl %r15d, 0x144(%rbx)
movq %rax, 0x148(%rbx)
movl %ebp, 0x150(%rbx)
movl %r14d, 0x154(%rbx)
addq %r12, %rax
movq %rax, 0x158(%rbx)
movl %ebp, 0x160(%rbx)
movl %r14d, 0x164(%rbx)
addq %rdi, %rax
movq %rax, 0x168(%rbx)
movl $0x1, 0x70(%rbx)
movl $0x1, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq