// File: /workspace/github_c_makefile_star2_O0/tvlabs[P]edge264/edge264.c
// Function: edge264_decode_NAL
int edge264_decode_NAL(Edge264Decoder *dec, const uint8_t *buf, const uint8_t *end, int non_blocking, void(*free_cb)(void*,int), void *free_arg, const uint8_t **next_NAL)
{
	static const char * const nal_unit_type_names[32] = {
		[0 ... 31] = "Unknown",
		[1] = "Coded slice of a non-IDR picture",
		[2] = "Coded slice data partition A",
		[3] = "Coded slice data partition B",
		[4] = "Coded slice data partition C",
		[5] = "Coded slice of an IDR picture",
		[6] = "Supplemental enhancement information (SEI)",
		[7] = "Sequence parameter set",
		[8] = "Picture parameter set",
		[9] = "Access unit delimiter",
		[10] = "End of sequence",
		[11] = "End of stream",
		[12] = "Filler data",
		[13] = "Sequence parameter set extension",
		[14] = "Prefix NAL unit",
		[15] = "Subset sequence parameter set",
		[16] = "Depth parameter set",
		[19] = "Coded slice of an auxiliary coded picture without partitioning",
		[20] = "Coded slice extension",
		[21] = "Coded slice extension for a depth view component or a 3D-AVC texture view component",
	};
	
	// initial checks before parsing
	if (dec == NULL || buf == NULL && end != NULL)
		return EINVAL;
	if (dec->n_threads)
		pthread_mutex_lock(&dec->lock);
	if (__builtin_expect((intptr_t)(end - buf) <= 0, 0)) {
		for (unsigned o = dec->output_flags; o; o &= o - 1)
			dec->dispPicOrderCnt = max(dec->dispPicOrderCnt, dec->FieldOrderCnt[0][__builtin_ctz(o)]);
		unsigned busy;
		while ((busy = dec->busy_tasks) && !non_blocking)
			pthread_cond_wait(&dec->task_complete, &dec->lock);
		if (dec->n_threads)
			pthread_mutex_unlock(&dec->lock);
		return busy ? EWOULDBLOCK : ENODATA;
	}
	dec->nal_ref_idc = buf[0] >> 5;
	dec->nal_unit_type = buf[0] & 0x1f;
	Parser parser = dec->parse_nal_unit[dec->nal_unit_type];
	if (dec->log_arg) { // no need to test log_cb since harmless otherwise
		dec->log_pos = snprintf(dec->log_buf, sizeof(dec->log_buf),
			"\n- nal_ref_idc: %u\n"
			"  nal_unit_type: %u # %s%s\n",
			dec->nal_ref_idc,
			dec->nal_unit_type, nal_unit_type_names[dec->nal_unit_type], unsup_if(!parser));
	}
	
	// initialize the parsing context if we can parse the current NAL
	int ret = ENOTSUP;
	if (parser != NULL) {
		// prefill the bitstream cache
		if ((intptr_t)(end - buf) >= 2) {
			dec->_gb.msb_cache = (size_t)buf[1] << (SIZE_BIT - 8) | (size_t)1 << (SIZE_BIT - 9);
			dec->_gb.CPB = buf + 2;
		} else {
			dec->_gb.msb_cache = (size_t)1 << (SIZE_BIT - 1);
			dec->_gb.CPB = buf + 1;
		}
		dec->_gb.lsb_cache = 0;
		dec->_gb.end = end;
		refill(&dec->_gb, 0);
		ret = parser(dec, non_blocking, free_cb, free_arg);
		// end may have been set to the next start code thanks to escape code detection in get_bytes
		buf = minp(dec->_gb.CPB - 2, dec->_gb.end);
	} else if (dec->log_arg) {
		dec->log_pos = 0;
		dec->log_cb(dec->log_buf, dec->log_arg);
	}
	// printf("nal_unit_type=%d, ret=%d\n\n", dec->nal_unit_type, ret);
	
	// for 0, ENOTSUP and EBADMSG we may free or advance the buffer pointer
	if (ret == 0 || ret == ENOTSUP || ret == EBADMSG) {
		if (free_cb && !(ret == 0 && 1048610 & 1 << dec->nal_unit_type)) // 1, 5 or 20
			free_cb(free_arg, ret);
		if (next_NAL)
			*next_NAL = edge264_find_start_code(buf, end, 0) + 3;
	}
	if (dec->n_threads)
		pthread_mutex_unlock(&dec->lock);
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x30(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdx, -0x40(%rbp)
movl %ecx, -0x44(%rbp)
movq %r8, -0x50(%rbp)
movq %r9, -0x58(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x1c68b
cmpq $0x0, -0x38(%rbp)
jne 0x1c697
cmpq $0x0, -0x40(%rbp)
je 0x1c697
movl $0x16, -0x24(%rbp)
jmp 0x1ca47
movq -0x30(%rbp), %rax
cmpb $0x0, 0x20(%rax)
je 0x1c6b1
movq -0x30(%rbp), %rdi
addq $0x1580, %rdi           # imm = 0x1580
callq 0x7160
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rcx, %rax
cmpq $0x0, %rax
setle %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x1c7b5
movq -0x30(%rbp), %rax
movl 0x54(%rax), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0x1c734
movq -0x30(%rbp), %rax
movl 0x48(%rax), %ecx
movq -0x30(%rbp), %rax
movl -0x5c(%rbp), %edx
tzcntl %edx, %edx
movslq %edx, %rdx
movl 0x3c0(%rax,%rdx,4), %eax
movl %ecx, -0x1c(%rbp)
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jle 0x1c716
movl -0x1c(%rbp), %eax
movl %eax, -0x70(%rbp)
jmp 0x1c71c
movl -0x20(%rbp), %eax
movl %eax, -0x70(%rbp)
movl -0x70(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x48(%rax)
movl -0x5c(%rbp), %eax
subl $0x1, %eax
andl -0x5c(%rbp), %eax
movl %eax, -0x5c(%rbp)
jmp 0x1c6de
jmp 0x1c736
movq -0x30(%rbp), %rax
movzwl 0x1638(%rax), %ecx
movl %ecx, -0x60(%rbp)
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x71(%rbp)
je 0x1c75a
cmpl $0x0, -0x44(%rbp)
setne %al
xorb $-0x1, %al
movb %al, -0x71(%rbp)
movb -0x71(%rbp), %al
testb $0x1, %al
jne 0x1c763
jmp 0x1c780
movq -0x30(%rbp), %rdi
addq $0x1608, %rdi           # imm = 0x1608
movq -0x30(%rbp), %rsi
addq $0x1580, %rsi           # imm = 0x1580
callq 0x7050
jmp 0x1c736
movq -0x30(%rbp), %rax
cmpb $0x0, 0x20(%rax)
je 0x1c79a
movq -0x30(%rbp), %rdi
addq $0x1580, %rdi           # imm = 0x1580
callq 0x70e0
movl -0x60(%rbp), %edx
movl $0x3d, %eax
movl $0xb, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x24(%rbp)
jmp 0x1ca47
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
sarl $0x5, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movb %cl, 0x21(%rax)
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
andl $0x1f, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movb %cl, 0x22(%rax)
movq -0x30(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbq 0x22(%rcx), %rcx
movq 0x278(%rax,%rcx,8), %rax
movq %rax, -0x68(%rbp)
movq -0x30(%rbp), %rax
cmpq $0x0, 0x7c98(%rax)
je 0x1c881
movq -0x30(%rbp), %rdi
addq $0x7ca2, %rdi           # imm = 0x7CA2
movq -0x30(%rbp), %rax
movsbl 0x21(%rax), %ecx
movq -0x30(%rbp), %rax
movsbl 0x22(%rax), %r8d
movq -0x30(%rbp), %rax
movsbq 0x22(%rax), %rdx
leaq 0xb8992(%rip), %rax     # 0xd51c0
movq (%rax,%rdx,8), %r9
cmpq $0x0, -0x68(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %esi
leaq 0xb3fe4(%rip), %rax     # 0xd0832
leaq 0xb152b(%rip), %rdx     # 0xcdd80
cmpl $0x0, %esi
cmovneq %rdx, %rax
movl $0x2542, %esi           # imm = 0x2542
leaq 0xb0f07(%rip), %rdx     # 0xcd76f
movq %rax, (%rsp)
movb $0x0, %al
callq 0x7070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0x7ca0(%rax)
movl $0x5f, -0x6c(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0x1c97c
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rcx, %rax
cmpq $0x2, %rax
jl 0x1c8d8
movq -0x38(%rbp), %rax
movzbl 0x1(%rax), %eax
movl %eax, %ecx
shlq $0x38, %rcx
movabsq $0x80000000000000, %rax # imm = 0x80000000000000
orq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rcx
addq $0x2, %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
jmp 0x1c8f9
movq -0x30(%rbp), %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rcx
addq $0x1, %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x30(%rbp), %rdi
xorl %esi, %esi
callq 0x1ca60
movq -0x68(%rbp), %rax
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x50(%rbp), %rdx
movq -0x58(%rbp), %rcx
callq *%rax
movl %eax, -0x6c(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rcx
addq $-0x2, %rcx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, -0x10(%rbp)
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
cmpq $0x0, %rax
jge 0x1c96a
movq -0x10(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x1c972
movq -0x18(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x1c9bc
movq -0x30(%rbp), %rax
cmpq $0x0, 0x7c98(%rax)
je 0x1c9ba
movq -0x30(%rbp), %rax
movw $0x0, 0x7ca0(%rax)
movq -0x30(%rbp), %rax
movq 0x7c90(%rax), %rax
movq -0x30(%rbp), %rdi
addq $0x7ca2, %rdi           # imm = 0x7CA2
movq -0x30(%rbp), %rcx
movq 0x7c98(%rcx), %rsi
callq *%rax
jmp 0x1c9bc
cmpl $0x0, -0x6c(%rbp)
je 0x1c9ce
cmpl $0x5f, -0x6c(%rbp)
je 0x1c9ce
cmpl $0x4a, -0x6c(%rbp)
jne 0x1ca27
cmpq $0x0, -0x50(%rbp)
je 0x1ca01
cmpl $0x0, -0x6c(%rbp)
jne 0x1c9f4
movq -0x30(%rbp), %rax
movsbl 0x22(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
andl $0x100022, %eax         # imm = 0x100022
cmpl $0x0, %eax
jne 0x1ca01
movq -0x50(%rbp), %rax
movq -0x58(%rbp), %rdi
movl -0x6c(%rbp), %esi
callq *%rax
cmpq $0x0, 0x10(%rbp)
je 0x1ca25
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
xorl %edx, %edx
callq 0x7150
movq %rax, %rcx
addq $0x3, %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
jmp 0x1ca27
movq -0x30(%rbp), %rax
cmpb $0x0, 0x20(%rax)
je 0x1ca41
movq -0x30(%rbp), %rdi
addq $0x1580, %rdi           # imm = 0x1580
callq 0x70e0
movl -0x6c(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)