一个有趣的vc1编码器

这里分享一个vc1编码器,下载地址:
https://download.csdn.net/download/weixin_43360707/87791898

文件包在附件,打开文件夹,可以看到下面三个文件夹:
在这里插入图片描述
因为我们的系统试Linux,所以我们选择Linux(x64).

继续打开,可以看到以下文件夹:
在这里插入图片描述

cd bin

chmod +x sample_enc_vc1

执行

./sample_enc_vc1

在这里插入图片描述
根据提示我们输入:

./sample_enc_vc1 -v …/…/…/…/vc1-720-480.yuv -o my.vc1 -w 720 -h 480 -I420

编码后出现my.vc1,我们用mediainfo查看编码后的文件:
在这里插入图片描述
说明编码好了,如果想要更近一步了解,可以查看samples中的encoder/sample_enc_vc1/sample_enc_vc1.cpp:

从下图可以看出,对w,h有要求:
在这里插入图片描述
从下图可以看到,命令行其实还有很多其它选项:

在这里插入图片描述

在这里插入图片描述

想要更加详细的,可以查看下面代码:

/*
 Copyright (c) 2023 MainConcept GmbH or its affiliates.  All rights reserved.


 MainConcept and its logos are registered trademarks of MainConcept GmbH or its affiliates.
 This software is protected by copyright law and international treaties.  Unauthorized
 reproduction or distribution of any portion is prohibited by law.
 */

#include <stdio.h>
#include <stdlib.h>

#include "mctypes.h"
#include "mcfourcc.h"
#include "bufstrm.h"
#include "sample_common_args.h"
#include "sample_common_misc.h"

#include "buf_file.h"

#include "enc_vc1.h"
#include "enc_vc1_def.h"

#include "config_vc1.h"

const char * profile_names[] = {"Simple", "Main", "Reserved", "Advanced"};
const char * interlace_names[] = {"Progressive", "Field picture", "MBAFF", "PAFF"};
const char * ratectl_names[] = {"Const quant", "VBR", "CBR"};

// guess desired video_type
int get_video_type(int width, int height, double frame_rate)
{
    if ((width == 352) && ((height == 240) || (height == 288)))
    {
        return VC1_CIF;
    }
    else if ((width == 480) && ((height == 480) || (height == 576)))
    {
        return VC1_SVCD;
    }
    else if ((width == 720) && ((height == 480) || (height == 576)))
    {
        return VC1_D1;
    }
    else if (width < 288)
    {
        return VC1_BASELINE;
    }
    else if (width >= 1280)
    {
        return VC1_BD;
    }

    return VC1_MAIN;
}


int main(int argc, char* argv[])
{
    vc1_param_set param_set;
 
    struct vc1_v_settings * v_settings = &param_set.params;
    vc1venc_tt * v_encoder = NULL;

    unsigned char * input_video_buffer = NULL;

    bufstream_tt * videobs = NULL;

    char * in_file;
    char * out_file;

    char * cfg_file;

    int32_t width;
    int32_t height;
    int32_t fourcc;

    double  frame_rate;
    int32_t bit_rate;
    int32_t interlaced;

    int32_t perf_preset;

    arg_item_t params[] =
    {
        { IDS_VIDEO_FILE,    1,  &in_file},
        { IDS_OUTPUT_FILE,   1,  &out_file},
        { IDS_CONFIG_FILE,   0,  &cfg_file},
        { IDI_V_WIDTH,       1,  &width},
        { IDI_V_HEIGHT,      1,  &height},
        { IDN_V_FOURCC,      1,  &fourcc},
        { IDD_V_FRAMERATE,   0,  &frame_rate},
        { IDI_BITRATE,       0,  &bit_rate},
        { IDN_V_INTERLACED,  0,  &interlaced},
        { IDI_V_PERFORMANCE, 0,  &perf_preset}
    };

    int init_options = 0;
    void * opt_list[10];

    if (parse_args(argc - 1, argv + 1, sizeof(params) / sizeof(params[0]), params) >= 0)
    {
        int line_size, img_start;
        int video_frame_size = get_video_frame_size(width, height, fourcc, &line_size, &img_start);
        int video_type = get_video_type(width, height, frame_rate);

        vc1OutVideoDefaults(v_settings, video_type, 0);

        if (cfg_file)
        {
            APIEXTFUNC_LOADPARAMSET load_param_func = (APIEXTFUNC_LOADPARAMSET) VC1ConfigGetAPIExt(MCAPI_LoadParamSet);

            if (load_param_func(&param_set, cfg_file) != MCAPI_NOERROR)
            {
                printf("\nInvalid config file. Terminating...\n");
                return 0;
            }
        }


        v_settings->min_key_frame_interval   = 1;

        v_settings->bit_rate                 = bit_rate >= 0 ? bit_rate * 1000 : v_settings->bit_rate;
        v_settings->frame_rate               = frame_rate > 0.0 ? frame_rate : v_settings->frame_rate;
        v_settings->interlace_mode           = interlaced == 0 ? VC1_PROGRESSIVE : interlaced == 1 ? VC1_INTERLACE_MBAFF : v_settings->interlace_mode;

        // the encoder can't scale the picture
        v_settings->def_horizontal_size      = width;
        v_settings->def_vertical_size        = height;

        if (vc1OutVideoChkSettings(NULL, v_settings, VC1_CHECK_AND_ADJUST, NULL) == VC1ERROR_FAILED)
        {
            printf("\nInvalid settings, vc1OutVideoChkSettings failed. Terminating...\n");
            return 0;
        }

        printf(
            "\nVC-1 %s Profile @ Level%d, %s, %s @ %.1f kbit/s, GOP %d/%d\n",
            profile_names[v_settings->profile_id],
            v_settings->level_id,
            interlace_names[v_settings->interlace_mode],
            ratectl_names[v_settings->bit_rate_mode],
            v_settings->bit_rate / 1000.0,
            v_settings->key_frame_interval,
            v_settings->b_frame_distance);

        if (perf_preset >= 0 && perf_preset <= 15)
            vc1OutVideoPerformance(v_settings, 0, perf_preset, 0);

        v_encoder = vc1OutVideoNew(NULL, v_settings, 0, 0xFFFFFFFF, 0, 0);
        
        if(!v_encoder)
        {
            printf("vc1OutVideoNew failed\n");
            return 0;
        }

        videobs = open_file_buf_write(out_file, 65536, NULL);

        // save original auxinfo handler
        org_auxinfo = videobs->auxinfo;

        // in order to get encoding statistics
        videobs->auxinfo = auxinfo;

        if(vc1OutVideoInit(v_encoder, videobs, init_options, &opt_list[0]))
        {
            printf("vc1OutVideoInit fails.\n");
            return 0;
        }

        input_video_buffer = new unsigned char [video_frame_size];

        FILE * input_video_file = fopen(in_file, "rb");
        
        int aborted = 0;
        int frame_cnt = 0;

        const void * ext_info_stack[16] = {0};

        while (1)
        {
            unsigned int option_flags = 0;
            unsigned int option_cnt = 0;
            const void ** ext_info = &ext_info_stack[0];

            if (fread(input_video_buffer, sizeof(unsigned char), video_frame_size, input_video_file) != video_frame_size)
            {
                // end of the file
                break;
            }


            if (vc1OutVideoPutFrame(v_encoder, input_video_buffer + img_start, line_size, width, height, fourcc, option_flags, ext_info))
            {
                break;
            }

            frame_cnt++;

            if(has_pressed_key(NULL)){
                aborted = 1;
                break;
            }
        }

        if (v_encoder)
        {
            vc1OutVideoDone(v_encoder, aborted);
            vc1OutVideoFree(v_encoder);
        }

        if (videobs)
        {
            videobs->done(videobs, aborted);
            videobs->free(videobs);
        }

        if (input_video_buffer)
            delete [] input_video_buffer;

        if (input_video_file)
            fclose(input_video_file);
    }

  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值