// File: /workspace/github_c_makefile_star2_O0/xiane[P]libvphevcodec/AML_HEVCEncoder.cpp
// Function: Wave4VpuEncGetHeader(AMVHEVCEncHandle_s*, unsigned char*, unsigned int*)
AMVEnc_Status Wave4VpuEncGetHeader(AMVHEVCEncHandle *Handle, unsigned char *buffer, unsigned int *buf_nal_size) {
    Uint32 addr_report_buf = 0;    // [31:0]
    Uint32 report_buf_size = 0;    // [31:0]
    unsigned char report_endian = 0;    // [ 3:0]
    //Uint32 use_sec_axi = 0;    // [31:0]
    //Uint32 sec_axi_buf_size = 0x00012800;   // 74KB

    // Bitstream Buffer Setting
    VpuWriteReg(Handle->instance_id, W4_BS_START_ADDR, Handle->bs_vb.phys_addr);
    VpuWriteReg(Handle->instance_id, W4_BS_SIZE, Handle->bs_vb.size - 0x8000);
    VpuWriteReg(Handle->instance_id, W4_BS_PARAM, 0xf);
    VpuWriteReg(Handle->instance_id, W4_BS_OPTION, 0);

    uint32_t current_idx = 0;
    current_idx |= (0 << 24); // [27:24] codec_std_aux
    current_idx |= (1 << 16); // [23:16] codec_std
    current_idx |= (Handle->instance_id << 0);  // [15: 0] Handle->instance_id
    VpuWriteReg(Handle->instance_id, W4_INST_INDEX, current_idx);

    // Work Buffer Setting
    VpuWriteReg(Handle->instance_id, W4_ADDR_WORK_BASE, Handle->work_vb.phys_addr);
    VpuWriteReg(Handle->instance_id, W4_WORK_SIZE, Handle->work_vb.size);
    VpuWriteReg(Handle->instance_id, W4_WORK_PARAM, 0);

    // Temp Buffer Setting
    VpuWriteReg(Handle->instance_id, W4_ADDR_TEMP_BASE, Handle->temp_vb.phys_addr);
    VpuWriteReg(Handle->instance_id, W4_TEMP_SIZE, Handle->temp_vb.size);
    VpuWriteReg(Handle->instance_id, W4_TEMP_PARAM, gol_endian);

    VpuWriteReg(Handle->instance_id, W4_BS_RD_PTR, Handle->bs_vb.phys_addr);
    VpuWriteReg(Handle->instance_id, W4_BS_WR_PTR, Handle->bs_vb.phys_addr);

    /* Secondary AXI */
    VpuWriteReg(Handle->instance_id, W4_ADDR_SEC_AXI, 0);
    VpuWriteReg(Handle->instance_id, W4_SEC_AXI_SIZE, 0);
    VpuWriteReg(Handle->instance_id, W4_USE_SEC_AXI, 0);
    VpuWriteReg(Handle->instance_id, W4_CMD_ENC_ADDR_REPORT_BASE, addr_report_buf);
    VpuWriteReg(Handle->instance_id, W4_CMD_ENC_REPORT_SIZE, report_buf_size);
    VpuWriteReg(Handle->instance_id, W4_CMD_ENC_REPORT_PARAM, report_endian);

    VpuWriteReg(Handle->instance_id, W4_CMD_ENC_SRC_PIC_IDX, 0);
    VpuWriteReg(Handle->instance_id, W4_CMD_ENC_CODE_OPTION, 0x1c);

    VpuWriteReg(Handle->instance_id, W4_VPU_BUSY_STATUS, 1);
    VpuWriteReg(Handle->instance_id, W4_RET_SUCCESS, 0);  //for debug
    VpuWriteReg(Handle->instance_id, W4_CORE_INDEX, 0);
    VpuWriteReg(Handle->instance_id, W4_COMMAND, ENC_PIC);
    VpuWriteReg(Handle->instance_id, W4_VPU_HOST_INT_REQ, 1);

    uint32_t status = VpuReadReg(Handle->instance_id, W4_VPU_BUSY_STATUS);
    VLOG(DEBUG, "W4_VPU_BUSY_STATUS :0x%x\n", status);

    if (vdi_wait_interrupt(Handle->instance_id, VPU_BUSY_CHECK_TIMEOUT) == -1) {
        VLOG(ERR, "Wave4VpuEncGetHeader error time out\n");
        return AMVENC_TIMEOUT;
    }

    if (VpuReadReg(Handle->instance_id, W4_RET_SUCCESS) == 0) {
        uint32_t reasonCode = VpuReadReg(Handle->instance_id, W4_RET_FAIL_REASON);
        VLOG(ERR, "Wave4VpuEncGetHeader failedREASON CODE(%08x)\n", reasonCode);
        return AMVENC_HARDWARE;
    }
    uint32_t result = VpuReadReg(Handle->instance_id, W4_RET_SUCCESS);
    VLOG(DEBUG, "W4_RET_SUCCESS %x\n", result);

    {
        Uint32 rd_ptr, wr_ptr;

        rd_ptr = VpuReadReg(Handle->instance_id, W4_BS_RD_PTR);
        wr_ptr = VpuReadReg(Handle->instance_id, W4_BS_WR_PTR);
        uint32_t header_length = VpuReadReg(Handle->instance_id, W4_RET_ENC_PIC_BYTE);

        if (header_length > Handle->mOutputBufferLen) {
            VLOG(ERR, "nal size %d bigger than output buffer %d!\n", header_length, Handle->mOutputBufferLen);
            return AMVENC_OVERFLOW;
        }
        *buf_nal_size = header_length;
        vdi_read_memory(Handle->instance_id, rd_ptr, (unsigned char *) buffer, header_length);
        VpuWriteReg(Handle->instance_id, W4_BS_RD_PTR, wr_ptr);
        VLOG(DEBUG, "Wave4VpuEncGetHeader, rd:0x%x, wr:0x%x, ret bytes: %d, buffer size:%d\n", rd_ptr, wr_ptr, header_length, wr_ptr - rd_ptr);
    }
    return AMVENC_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rax
movl %eax, %edx
movl $0x120, %esi            # imm = 0x120
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movl 0x80(%rax), %edx
subl $0x8000, %edx           # imm = 0x8000
movl $0x124, %esi            # imm = 0x124
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x128, %esi            # imm = 0x128
movl $0xf, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x12c, %esi            # imm = 0x12C
xorl %edx, %edx
callq 0x2160
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
orl $0x0, %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
orl $0x10000, %eax          # imm = 0x10000
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
shll $0x0, %eax
orl -0x30(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl -0x30(%rbp), %edx
movl $0x108, %esi            # imm = 0x108
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movl %eax, %edx
movl $0x138, %esi            # imm = 0x138
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movl 0x40(%rax), %edx
movl $0x13c, %esi            # imm = 0x13C
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x140, %esi            # imm = 0x140
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
movl %eax, %edx
movl $0x144, %esi            # imm = 0x144
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %edx
movl $0x148, %esi            # imm = 0x148
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl 0x2bb41(%rip), %edx     # 0x331d8
movl $0x14c, %esi            # imm = 0x14C
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rax
movl %eax, %edx
movl $0x130, %esi            # imm = 0x130
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rax
movl %eax, %edx
movl $0x134, %esi            # imm = 0x134
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x150, %esi            # imm = 0x150
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x154, %esi            # imm = 0x154
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x158, %esi            # imm = 0x158
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl -0x24(%rbp), %edx
movl $0x15c, %esi            # imm = 0x15C
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl -0x28(%rbp), %edx
movl $0x160, %esi            # imm = 0x160
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movzbl -0x29(%rbp), %edx
movl $0x164, %esi            # imm = 0x164
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x170, %esi            # imm = 0x170
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x168, %esi            # imm = 0x168
movl $0x1c, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x70, %esi
movl $0x1, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x110, %esi            # imm = 0x110
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x104, %esi            # imm = 0x104
xorl %edx, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x100, %esi            # imm = 0x100
movl $0x8, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x38, %esi
movl $0x1, %edx
callq 0x2160
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x70, %esi
callq 0x2210
movl %eax, -0x34(%rbp)
jmp 0x77ea
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x1388, %esi           # imm = 0x1388
callq 0x2340
cmpl $-0x1, %eax
jne 0x7829
jmp 0x7801
leaq 0x289e2(%rip), %rdi     # 0x301ea
movb $0x0, %al
callq 0x2050
leaq 0x28a50(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0xffffffdc, -0x4(%rbp) # imm = 0xFFFFFFDC
jmp 0x7947
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x110, %esi            # imm = 0x110
callq 0x2210
cmpl $0x0, %eax
jne 0x787c
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x114, %esi            # imm = 0x114
callq 0x2210
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %esi
leaq 0x289b4(%rip), %rdi     # 0x3020f
movb $0x0, %al
callq 0x2050
leaq 0x289fd(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0xffffffdb, -0x4(%rbp) # imm = 0xFFFFFFDB
jmp 0x7947
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x110, %esi            # imm = 0x110
callq 0x2210
movl %eax, -0x3c(%rbp)
jmp 0x7891
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x130, %esi            # imm = 0x130
callq 0x2210
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x134, %esi            # imm = 0x134
callq 0x2210
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x1c8, %esi            # imm = 0x1C8
callq 0x2210
movl %eax, -0x48(%rbp)
movl -0x48(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x300(%rcx), %eax
jbe 0x790d
jmp 0x78db
movl -0x48(%rbp), %esi
movq -0x10(%rbp), %rax
movl 0x300(%rax), %edx
leaq 0x2894e(%rip), %rdi     # 0x3023d
movb $0x0, %al
callq 0x2050
leaq 0x28969(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0xffffffd9, -0x4(%rbp) # imm = 0xFFFFFFD9
jmp 0x7947
movl -0x48(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl -0x40(%rbp), %esi
movq -0x18(%rbp), %rdx
movl -0x48(%rbp), %ecx
callq 0x2110
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl -0x44(%rbp), %edx
movl $0x130, %esi            # imm = 0x130
callq 0x2160
jmp 0x7940
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq