// File: /workspace/github_cpp_makefile_star2_O1/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 %r12
pushq %rbx
subq $0x70, %rsp
movq %rdi, %rbx
leaq 0x23e8(%rip), %rax      # 0x512b
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, 0x58(%rdi)
movups %xmm0, 0x68(%rdi)
movups %xmm0, 0x78(%rdi)
movups %xmm0, 0x88(%rdi)
movups %xmm0, 0x98(%rdi)
movups %xmm0, 0x20(%rdi)
movups %xmm0, 0x30(%rdi)
movups %xmm0, 0x40(%rdi)
movb $0x0, 0x50(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x39bc
movq (%rbx), %rdi
movl $0x802, %esi            # imm = 0x802
xorl %edx, %edx
xorl %eax, %eax
callq 0x20c0
movl %eax, 0x8(%rbx)
testl %eax, %eax
jns 0x2dfb
movl $0x8, %edi
callq 0x2090
movq %rax, %r15
leaq 0x4fda(%rip), %rax      # 0x7d98
movq %rax, (%r15)
movq 0x5210(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
leaq 0x2355(%rip), %rsi      # 0x5127
leaq 0x235f(%rip), %rdx      # 0x5138
xorl %eax, %eax
callq 0x2120
leaq 0x4f89(%rip), %rsi      # 0x7d70
movq 0x51fa(%rip), %rdx      # 0x7fe8
movq %r15, %rdi
callq 0x21b0
jmp 0x2fad
xorps %xmm0, %xmm0
leaq -0x90(%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)
movq $0x0, 0x60(%rdx)
movl $0x80685600, %esi       # imm = 0x80685600
movl %eax, %edi
xorl %eax, %eax
callq 0x2110
testl %eax, %eax
jne 0x2f05
movl -0x3c(%rbp), %edi
movl %edi, %eax
notl %eax
testl $0x4004000, %eax        # imm = 0x4004000
jne 0x2f0e
movq 0x5185(%rip), %r12      # 0x7fd8
movq (%r12), %rcx
leaq 0x2363(%rip), %rdi      # 0x51c1
movl $0x2b, %esi
movl $0x1, %edx
callq 0x21e0
movq %rbx, %rdi
movl $0xa, %esi
callq 0x223a
movq (%r12), %rcx
leaq 0x2368(%rip), %rdi      # 0x51ed
movl $0x2c, %esi
movl $0x1, %edx
callq 0x21e0
movq (%r12), %rcx
leaq 0x237b(%rip), %rdi      # 0x521a
movl $0x2c, %esi
movl $0x1, %edx
callq 0x21e0
movq %rbx, %rdi
movl $0x9, %esi
callq 0x223a
movq %rbx, %rdi
callq 0x33dc
movq %rbx, %rdi
callq 0x350e
movq %rbx, %rdi
callq 0x3748
movq %rbx, %rdi
callq 0x37e8
leaq -0x24(%rbp), %rdx
movl $0x9, (%rdx)
movl 0x8(%rbx), %edi
movl $0x40045612, %esi       # imm = 0x40045612
xorl %eax, %eax
callq 0x2110
testl %eax, %eax
jne 0x2f67
addq $0x70, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x223f(%rip), %r15      # 0x514b
jmp 0x2f1e
leaq -0x3c(%rbp), %rsi
callq 0x23f9
leaq 0x227a(%rip), %r15      # 0x5198
movl $0x8, %edi
callq 0x2090
movq %rax, %r12
leaq 0x4e66(%rip), %rax      # 0x7d98
movq %rax, (%r12)
movq 0x509b(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
leaq 0x21e0(%rip), %rsi      # 0x5127
movq %r15, %rdx
xorl %eax, %eax
callq 0x2120
leaq 0x4e18(%rip), %rsi      # 0x7d70
movq 0x5089(%rip), %rdx      # 0x7fe8
movq %r12, %rdi
callq 0x21b0
movl $0x8, %edi
callq 0x2090
movq %rax, %r15
leaq 0x4e1d(%rip), %rax      # 0x7d98
movq %rax, (%r15)
movq (%r12), %rdi
leaq 0x219e(%rip), %rsi      # 0x5127
leaq 0x22b7(%rip), %rdx      # 0x5247
xorl %eax, %eax
callq 0x2120
leaq 0x4dd2(%rip), %rsi      # 0x7d70
movq 0x5043(%rip), %rdx      # 0x7fe8
movq %r15, %rdi
callq 0x21b0
movq %rax, %r15
jmp 0x2fc1
jmp 0x2fb6
jmp 0x2fb6
movq %rax, %r15
movq %r14, %rdi
callq 0x3fe6
movq 0x38(%rbx), %rdi
addq $0x20, %rbx
testq %rdi, %rdi
je 0x2fd3
callq 0x20f0
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x2fe0
callq 0x20f0
movq %r15, %rdi
callq 0x21c0