// File: zhangk145[P]video_envalue/Decoder.cpp
// Function: Decoder::open_codec_context(int*, AVCodecContext**, AVFormatContext*, AVMediaType)
int Decoder::open_codec_context(int *stream_idx,
                              AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type)
{
    int ret, stream_index;
    AVStream *st;
    AVCodec *dec = NULL;
    AVDictionary *opts = NULL;

    ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not find %s stream\n",
                av_get_media_type_string(type));
        return ret;
    } else {
        stream_index = ret;
        st = fmt_ctx->streams[stream_index];

        /* find decoder for the stream */
        dec = avcodec_find_decoder(st->codecpar->codec_id);
        if (!dec) {
            fprintf(stderr, "Failed to find %s codec\n",
                    av_get_media_type_string(type));
            return AVERROR(EINVAL);
        }

        /* Allocate a codec context for the decoder */
        *dec_ctx = avcodec_alloc_context3(dec);
        if (!*dec_ctx) {
            fprintf(stderr, "Failed to allocate the %s codec context\n",
                    av_get_media_type_string(type));
            return AVERROR(ENOMEM);
        }

        /* Copy codec parameters from input stream to output codec context */
        if ((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) {
            fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
                    av_get_media_type_string(type));
            return ret;
        }

        /* Init the decoders, with or without reference counting */
        // av_dict_set(&opts, "refcounted_frames", mRefcount ? "1" : "0", 0);
        if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) {
            fprintf(stderr, "Failed to open %s codec\n",
                    av_get_media_type_string(type));
            return ret;
        }
        *stream_idx = stream_index;
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %esi
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
movl %ecx, %edx
callq 0x20a0
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jge 0x26d9
movq 0x4936(%rip), %rax      # 0x6fe0
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movl -0x2c(%rbp), %edi
callq 0x22a0
movq -0x58(%rbp), %rdi
movq %rax, %rdx
leaq 0x29ae(%rip), %rsi      # 0x5075
movb $0x0, %al
callq 0x2090
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x284d
movl -0x30(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq 0xd0(%rax), %rax
movl 0x4(%rax), %edi
callq 0x22f0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x2748
movq 0x48c8(%rip), %rax      # 0x6fe0
movq (%rax), %rax
movq %rax, -0x60(%rbp)
movl -0x2c(%rbp), %edi
callq 0x22a0
movq -0x60(%rbp), %rdi
movq %rax, %rdx
leaq 0x295a(%rip), %rsi      # 0x508f
movb $0x0, %al
callq 0x2090
movl $0xffffffea, -0x4(%rbp) # imm = 0xFFFFFFEA
jmp 0x284d
movq -0x48(%rbp), %rdi
callq 0x2230
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x279c
movq 0x4874(%rip), %rax      # 0x6fe0
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movl -0x2c(%rbp), %edi
callq 0x22a0
movq -0x68(%rbp), %rdi
movq %rax, %rdx
leaq 0x291f(%rip), %rsi      # 0x50a8
movb $0x0, %al
callq 0x2090
movl $0xfffffff4, -0x4(%rbp) # imm = 0xFFFFFFF4
jmp 0x284d
movq -0x20(%rbp), %rax
movq (%rax), %rdi
movq -0x40(%rbp), %rax
movq 0xd0(%rax), %rsi
callq 0x22b0
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
jge 0x27ee
movq 0x481e(%rip), %rax      # 0x6fe0
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movl -0x2c(%rbp), %edi
callq 0x22a0
movq -0x70(%rbp), %rdi
movq %rax, %rdx
leaq 0x28f2(%rip), %rsi      # 0x50d1
movb $0x0, %al
callq 0x2090
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x284d
movq -0x20(%rbp), %rax
movq (%rax), %rdi
movq -0x48(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x2160
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
jge 0x283d
movq 0x47cf(%rip), %rax      # 0x6fe0
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movl -0x2c(%rbp), %edi
callq 0x22a0
movq -0x78(%rbp), %rdi
movq %rax, %rdx
leaq 0x28da(%rip), %rsi      # 0x5108
movb $0x0, %al
callq 0x2090
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x284d
movl -0x34(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)