一个有趣的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
    评论
### 回答1: RS编码是一种重要的纠错编码技术,可以在数据传输或存储过程中实现数据的纠错和恢复。在MATLAB中,我们可以使用编程语言和相关的函数来实现RS编码器。 首先,我们需要定义RS编码的参数,包括码长(length)、信息位(k)、修正位(t)。然后我们可以使用MATLAB中的函数构建一个RS编码器,以下是一个示例: ```matlab function encoded_data = RS_encoder(data, length, k, t) % RS编码器函数 % 输入参数: % data: 待编码的数据 % length: 编码后的码长 % k: 信息位的数量 % t: 修正位的数量 % 输出参数: % encoded_data: 编码后的数据 % 创建RS编码器对象 rs_encoder = comm.RSEncoder(length, k, 'BitInput', true, 'PrimitivePolynomialSource', 'Property', 'PrimitivePolynomial', [1 0 0 0 1 1 0 1 0 0 1]); % 编码输入数据 encoded_data = step(rs_encoder, data); end ``` 在以上示例中,我们使用了MATLAB中提供的comm.RSEncoder函数创建了一个RS编码器对象,并传入了参数length、k以及定义的原始多项式(Primitive Polynomial)来初始化编码器。然后我们调用step函数来使用RS编码器进行编码操作,并返回编码后的数据。 使用以上的RS编码器函数,我们可以将数据传入并进行编码。例如: ```matlab data = [1 0 1 1 0 1 0]; % 待编码的数据 length = 15; % 编码后的码长 k = 7; % 信息位的数量 t = 4; % 修正位的数量 encoded_data = RS_encoder(data, length, k, t); % 调用RS编码器函数进行编码 disp(encoded_data); % 显示编码后的数据 ``` 以上示例中,我们定义了一个长度为15的RS编码,其中有7个信息位和4个修正位。然后我们传入一个长度为7的数据进行编码,并打印出编码后的数据。 通过以上方法,我们可以在MATLAB中实现一个RS编码器,并进行数据的纠错编码操作。 ### 回答2: RS编码是一种常用的纠错编码方法,在信息传输过程中能够有效地检测和纠正错误。在MATLAB中编写一个RS编码器可以完成以下步骤: 1. 定义RS编码器的参数:首先需要定义RS编码器的参数,包括信息位数和校验位数。通常情况下,信息位数加上校验位数等于总位数。例如,如果信息位数为k,校验位数为n,则总位数为n+k。 2. 生成生成多项式:RS编码器使用一个生成多项式来生成校验位。可以在MATLAB中使用poly2trellis函数生成生成多项式。生成多项式需要指定校验位数和生成多项式的指数形式。 3. 对输入数据进行编码:使用MATLAB的convenc函数对输入的数据进行编码。convenc函数需要输入一个二进制向量和生成多项式。 4. 输出编码结果:编码器将输入数据编码为输出数据。输出数据包括信息位和校验位。将数据进行二进制化输出。 5. 完成编码器的编写:以上步骤完成后,编码器已经实现了RS编码的功能。可以把代码保存为一个.m文件作为RS编码器的代码。 总的来说,使用MATLAB编写RS编码器需要确定参数、生成生成多项式、编码输入数据并输出编码结果。在编写代码的过程中,可以使用MATLAB的多项式函数和编码函数来实现RS编码的功能。 ### 回答3: RS编码器是一种在信息传输中常用的纠错编码方式。在MATLAB中,可以使用编程语言来实现RS编码器。 首先,需要定义RS编码的参数,包括码距(d)和生成多项式(G)。码距指的是两个不同编码之间的最小汉明距离,通常是通过RS码的纠错能力进行选择。生成多项式则是用于生成RS码的特定多项式,通常使用伽罗华域的特征多项式。 接下来,可以定义一个函数来实现RS编码器的功能。这个函数的输入参数可以是待编码的信息序列,输出参数则是RS编码后的序列。 在函数内部,首先需要将输入的信息序列换为伽罗华域的元素。然后,利用生成多项式和被编码信息计算出编码后的结果。最后,将编码结果换为二进制序列并返回。 可以使用MATLAB中的矩阵运算和多项式函数来实现这个函数。在完成RS编码器函数的编写后,可以调用这个函数来进行RS编码,输入待编码的信息序列,输出编码后的序列。 除了编写RS编码器函数,还可以编写其他辅助函数,如将信息序列换为伽罗华域元素,将编码结果换为二进制序列等,以便更好地实现RS编码的功能。 总之,在MATLAB中实现RS编码器,需要定义参数、编写编码器函数以及辅助函数,来完成RS编码的计算和换过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值