// File: /workspace/github_cpp_makefile_star2_O2/OtherCrashOverride[P]xu4enc/./M2M.h
// Function: M2M::M2M(int, int, int, int, int)
M2M(int width, int height, int fps, int bitrate, int gop)
		: width(width), height(height), fps(fps), bitrate(bitrate), gop(gop)
	{
		// O_NONBLOCK prevents deque operations from blocking if no buffers are ready
		mfc_fd = open(decoderName, O_RDWR | O_NONBLOCK, 0);
		if (mfc_fd < 0)
		{
			throw Exception("Failed to open MFC");
		}


		// Check device capabilities
		v4l2_capability cap = { 0 };

		int ret = ioctl(mfc_fd, VIDIOC_QUERYCAP, &cap);
		if (ret != 0)
		{
			throw Exception("VIDIOC_QUERYCAP failed.");
		}

		if ((cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) == 0 ||
			(cap.capabilities & V4L2_CAP_STREAMING) == 0)
		{
			printf("V4L2_CAP_VIDEO_M2M_MPLANE=%d\n", (cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) != 0);
			printf("V4L2_CAP_STREAMING=%d\n", (cap.capabilities & V4L2_CAP_STREAMING) != 0);

			throw Exception("Insufficient capabilities of MFC device.");
		}


		fprintf(stderr, "V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE formats:\n");
		EnumFormats(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
		
		fprintf(stderr, "-------------------------------------------\n");

		fprintf(stderr, "V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE formats:\n");
		EnumFormats(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);


#if 0	// only V4L2_CID_MIN_BUFFERS_FOR_OUTPUT is supported for MFC

		// Get the number of buffers required
		v4l2_control ctrl = { 0 };
		ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;

		ret = ioctl(mfc_fd, VIDIOC_G_CTRL, &ctrl);
		if (ret != 0)
		{
			fprintf(stderr, "V4L2_CID_MIN_BUFFERS_FOR_OUTPUT VIDIOC_G_CTRL failed.\n");
		}
		else
		{
			fprintf(stderr, "V4L2_CID_MIN_BUFFERS_FOR_OUTPUT=%d\n", ctrl.value);
		}

		ctrl = { 0 };
		ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;

		ret = ioctl(mfc_fd, VIDIOC_G_CTRL, &ctrl);
		if (ret != 0)
		{
			fprintf(stderr, "V4L2_CID_MIN_BUFFERS_FOR_CAPTURE VIDIOC_G_CTRL failed.\n");
		}
		else
		{
			fprintf(stderr, "V4L2_CID_MIN_BUFFERS_FOR_CAPTURE=%d\n", ctrl.value);
		}

#endif

		ApplyInputSettings();
		CreateInputBuffers();

		ApplyOutputSettings();
		CreateOutputBuffers();

		// Start output stream
		int val = (int)V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;

		ret = ioctl(mfc_fd, VIDIOC_STREAMON, &val);
		if (ret != 0)
		{
			throw Exception("VIDIOC_STREAMON failed.");
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdi, %rbx
leaq 0x1a98(%rip), %rax      # 0x412b
movq %rax, (%rdi)
movl %esi, 0xc(%rdi)
movl %edx, 0x10(%rdi)
movl %ecx, 0x14(%rdi)
movl %r8d, 0x18(%rdi)
movl %r9d, 0x1c(%rdi)
leaq 0x58(%rdi), %r14
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rdi)
movups %xmm0, 0x30(%rdi)
movups %xmm0, 0x40(%rdi)
movb $0x0, 0x50(%rdi)
movq %r14, %rdi
callq 0x2cf2
movq (%rbx), %rdi
movl $0x802, %esi            # imm = 0x802
xorl %edx, %edx
xorl %eax, %eax
callq 0x20c0
movl %eax, 0x8(%rbx)
testl %eax, %eax
js 0x27e7
xorps %xmm0, %xmm0
leaq -0xa0(%rbp), %rdx
movaps %xmm0, 0x50(%rdx)
movaps %xmm0, 0x40(%rdx)
movaps %xmm0, 0x30(%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, (%rdx)
andq $0x0, 0x60(%rdx)
movl $0x80685600, %esi       # imm = 0x80685600
movl %eax, %edi
xorl %eax, %eax
callq 0x2110
testl %eax, %eax
jne 0x281c
movl -0x4c(%rbp), %esi
movl %esi, %eax
notl %eax
testl $0x4004000, %eax        # imm = 0x4004000
jne 0x2825
movq 0x48a1(%rip), %r13      # 0x6fd8
movq (%r13), %rcx
leaq 0x1a7f(%rip), %rdi      # 0x41c1
pushq $0x2b
popq %rsi
pushq $0x1
popq %r15
movq %r15, %rdx
callq 0x21e0
pushq $0xa
popq %rsi
movq %rbx, %rdi
callq 0x2d12
movq (%r13), %rcx
leaq 0x1a86(%rip), %rdi      # 0x41ed
pushq $0x2c
popq %r12
movq %r12, %rsi
movq %r15, %rdx
callq 0x21e0
movq (%r13), %rcx
leaq 0x1a99(%rip), %rdi      # 0x421a
movq %r12, %rsi
movq %r15, %rdx
callq 0x21e0
pushq $0x9
popq %rsi
movq %rbx, %rdi
callq 0x2d12
movq %rbx, %rdi
callq 0x2e92
movq %rbx, %rdi
callq 0x3004
movq %rbx, %rdi
callq 0x3238
movq %rbx, %rdi
callq 0x3304
leaq -0x2c(%rbp), %rdx
movl $0x9, (%rdx)
movl 0x8(%rbx), %edi
movl $0x40045612, %esi       # imm = 0x40045612
xorl %eax, %eax
callq 0x2110
testl %eax, %eax
jne 0x2883
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x8
popq %rdi
callq 0x2090
movq %rax, %r15
leaq 0x193f(%rip), %rsi      # 0x4138
movq %rax, %rdi
callq 0x264e
leaq 0x4568(%rip), %rsi      # 0x6d70
movq 0x47d9(%rip), %rdx      # 0x6fe8
movq %r15, %rdi
callq 0x21b0
jmp 0x28b3
leaq 0x1928(%rip), %r15      # 0x414b
jmp 0x2857
shrl $0xe, %esi
andl $0x1, %esi
leaq 0x1931(%rip), %rdi      # 0x4163
xorl %eax, %eax
callq 0x2040
movl -0x4c(%rbp), %esi
shrl $0x1a, %esi
andl $0x1, %esi
leaq 0x1938(%rip), %rdi      # 0x4181
xorl %eax, %eax
callq 0x2040
leaq 0x1941(%rip), %r15      # 0x4198
pushq $0x8
popq %rdi
callq 0x2090
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x264e
leaq 0x44fc(%rip), %rsi      # 0x6d70
movq 0x476d(%rip), %rdx      # 0x6fe8
movq %r12, %rdi
callq 0x21b0
pushq $0x8
popq %rdi
callq 0x2090
movq %rax, %r15
leaq 0x19b2(%rip), %rsi      # 0x4247
movq %rax, %rdi
callq 0x264e
leaq 0x44cc(%rip), %rsi      # 0x6d70
movq 0x473d(%rip), %rdx      # 0x6fe8
movq %r15, %rdi
callq 0x21b0
jmp 0x28bc
movq %rax, %r15
jmp 0x28c7
jmp 0x28bc
movq %rax, %r15
movq %r14, %rdi
callq 0x3cbc
leaq 0x20(%rbx), %r14
addq $0x38, %rbx
movq %rbx, %rdi
callq 0x3cec
movq %r14, %rdi
callq 0x3cec
movq %r15, %rdi
callq 0x21c0
nop