视频编解码示例

视频编解码示例主要展示了视频编解码的典型使用场景,具体包括以下内容:

  • 基于UCP编码结果的解码示例:演示如何使用UCP编码接口生成的码流进行解码,展示完整的编码-解码流程。
  • 基于UCP解码结果的编码示例:演示如何从提供的码流文件中进行解码,并在解码完成后使用UCP编码接口进行重新编码,适用于处理和转换已有视频数据的场景。

示例脚本允许配置编码参数,以优化视频质量、压缩率和性能,适应不同的应用场景。通过这个示例,您可以了解并实践如何使用UCP框架进行视频的编解码操作, 并根据具体需求调整编码参数,详细的实现方法请结合示例源码对比实践。

功能概述

基于UCP编码结果的解码示例

image

本示例实现了一个完整的视频编码-解码流程,输入视频序列为YUV420格式,经过H.265编码后,生成相应的码流。 在解码过程中,实时将每一帧码流输入解码器,经过H.265解码后,生成相应的YUV视频。 注意由于视频编码的过程是有损的,所以解码得到的YUV视频序列与输入的YUV视频序列不是完全等价的。

该示例的代码过程可以大致分为以下六个步骤,详细的实现请结合示例源码。

  1. 准备编码器和解码器参数。

  2. 创建编码器和解码器上下文。

  3. 准备编码器输入内存。

  4. 将输入的YUV420视频序列逐帧送入编码器进行编码,等待编码任务完成后,再将生成的H.265码流逐帧送入解码器。

  5. 视频编解码全部完成后,释放输入内存。

  6. 释放解码器和编码器上下文。

基于UCP解码结果的编码示例

image

本示例实现了一个如何从提供的码流文件中进行解码,并在解码完成后使用UCP编码接口进行重新编码,适用于处理和转换已有视频数据的场景。 输入视频序列为H.265格式的码流,首先通过H.265解码器将码流解码为YUV420格式的视频序列。 随后,将解码得到的YUV420视频序列逐帧送入编码器,重新编码为H.265码流。

该示例的代码过程可以大致分为以下六个步骤,详细的实现请结合示例源码。

  1. 准备解码器和编码器参数。

  2. 创建解码器和编码器上下文。

  3. 准备解码器输入内存。

  4. 调用avformat函数将H.265码流逐帧解析送入至解码器进行解码,等待编码任务完成后,再将生成的YUV数据逐帧送入编码器。

  5. 视频编解码全部完成后,释放输入内存。

  6. 释放编码器和解码器上下文。

运行指南

视频编解码示例执行脚本位于 ucp_tutorial/vp/vp_samples/script/06_codec 目录下,包含以下脚本:

06_codec
├── README.md
└── run_codec.sh 

run_codec.sh脚本中命令行内容如下:

bin=../aarch64/bin/codec_sample
lib=../aarch64/lib

export LD_LIBRARY_PATH=${lib}:${LD_LIBRARY_PATH}
export PATH=${bin}:${PATH}

${bin} $*

执行的时候,进入 vp_samples/script/06_codec 目录,然后直接执行run_codec.sh即可,执行方法及日志输出如下:

#!/bin/sh

root@j6dvb:/userdata/app/horizon/vp_samples/script/06_codec# sh run_codec.sh
[I][5282][08-13][10:57:14:937][codec_helper.cpp:72][codec_sample][VP_CODEC] Calling encode_decode_process and decode_encode_process with rc_mode: default, gop_preset: default
[I][5282][08-13][10:57:14:937][codec_helper.cpp:77][codec_sample][VP_CODEC] ******Encode and Decode process start******
[I][5282][08-13][10:57:14:940][codec_helper.cpp:42][codec_sample][VP_CODEC] Using default rate control mode: H265Cbr
[I][5282][08-13][10:57:14:940][codec_helper.cpp:65][codec_sample][VP_CODEC] Using default gopPresetIdx: 2
[I][5282][08-13][10:57:14:974][codec_helper.cpp:82][codec_sample][VP_CODEC] ******Encode and Decode process finish******
[I][5282][08-13][10:57:14:974][codec_helper.cpp:84][codec_sample][VP_CODEC] ******Decode and Encode process start******
[I][5282][08-13][10:57:14:974][codec_helper.cpp:42][codec_sample][VP_CODEC] Using default rate control mode: H265Cbr
[I][5282][08-13][10:57:14:974][codec_helper.cpp:65][codec_sample][VP_CODEC] Using default gopPresetIdx: 2
[I][5282][08-13][10:57:15:007][codec_helper.cpp:89][codec_sample][VP_CODEC] ******Decode and Encode process finish******
...

此示例中,直接执行示例脚本会使用H.265编码的默认参数。如果希望更改H.265编码的参数,可以在执行示例脚本时追加参数来控制执行流程,追加参数的规则如下:

sh run_codec.sh [rc_mode] [gop_preset_idx]

其中,rc_mode 为可选参数,用于指定H.265编码器的码率控制方式;gop_preset_idx 也是可选参数,用于指定H.265编码器的GOP结构预设方式。

此外还可以通过追加 -help 命令获取所有可用的追加参数列表。编码参数 rc_modegop_preset_idx 定义如下:

static const std::set<std::string> rc_mode_set = {"H265Cbr", "H265Vbr", "H265FixQp"};

static const std::set<std::string> gop_preset_idx_set = {"GOP_PRESET_IDX1", "GOP_PRESET_IDX2", "GOP_PRESET_IDX3"};

结果说明

示例执行后会在 vp_samples/script/06_codec 目录下保存图片处理结果,本示例的默认参数下生成物内容如下:

vp_samples
└── script                                                        // 图片数据目录
    └── 06_codec
      ├── encode_decode_640x480_yuv420p_default_default.h265      // 基于UCP编码结果的解码示例,编码器输出码流文件
      ├── encode_decode_640x480_yuv420p_default_default.yuv       // 基于UCP编码结果的解码示例,解码器输出YUV文件
      ├── decode_encode_640x480_yuv420p_default_default.yuv       // 基于外部码流文件的解码示例,解码器输出YUV文件
      └── decode_encode_640x480_yuv420p_default_default.h265      // 基于外部码流文件的解码示例,编码器输出码流文件

以解码为例,第一帧和第n帧的解码效果如下所示:

image