音视频编解码:使用X265编码视频

使用X265编码视频

环境准备

  1. 使用hg 下载x265源码
    https://www.videolan.org/developers/x265.html
  2. 如果电脑之前没有安装过 hg,yasm,nasm 可以使用 brew 安装一下
    brew install hg
    brew install yasm
    brew install nasm

3.进入到工程 …/x265/build/linux 目录下编译
即便是Mac,也可以在这个目录下进行编译(我使用xcode编译,在安装阶段报错找不到静态包,所以使用在linux目录下编译)

sh make-Makefiles.bash

可以将其中的 ENABLE_SHARED 开关打开
配置完成之后

make
make install

命令行使用

 x265 -o akiyo.265 --fps=24 --input-res=352x288 --input-csp=i420 --input-depth=8 akiyo_cif.yuv

更多使用方式可以参考

x265 --help

工程使用

我使用的是vscode + cmake
因为安装的时候将pkgconfig 安装到了这个路径
/usr/local/lib/pkgconfig/x265

同时使用
pkg-config 命令确保,pkgconfig能够搜索到

pkg-config --list-all | grep x265
x265                                x265 - H.265/HEVC video encoder

如搜索不到,可配置环境变量试试

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

pkgconfig 可以帮助我们简化依赖

资源准备

yuv 视频源: http://trace.eas.asu.edu/yuv/index.html

查看YUV视频源工具: https://files.cnblogs.com/littlejohnny/YUVviewer_src.rar

https://github.com/IENT/YUView/releases

我下载了一个资源名,名称为:akiyo_cif,是一个I420,8位深的资源

CMakeList.txt

cmake_minimum_required(VERSION 3.14)
project(x265_encoder)
set(CMAKE_CXX_STANDARD 11)            # Enable c++11 standard

set(CMAKE_BUILD_TYPE Debug)
set(SOURCE_FILES X265Encoder.cpp)

# https://cmake.org/cmake/help/latest/module/FindPkgConfig.html
# https://zhuanlan.zhihu.com/p/111155574
find_package(PkgConfig REQUIRED)
pkg_check_modules(x265 REQUIRED IMPORTED_TARGET x265 )


add_executable(x265_encoder ${SOURCE_FILES})

target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::x265)
  1. 代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <iomanip>
#include <x265.h>

// https://blog.csdn.net/leixiaohua1020/article/details/42079101
int main(int argv, const char *args[])
{
    FILE *fp_src = fopen("res/akiyo_cif.yuv", "rb");
    FILE *fp_dst = fopen("res/akiyo_cif_code.h265", "wb");

    // 352x288
    int width = 352;
    int height = 288;
    int csp = X265_CSP_I420;
    // 设置为0,会根据文件大小计算帧数
    // 如果帧数设置的太小,可能会造成没有编码后的结果
    int frameNum = 0;

    if (fp_src && fp_dst)
    {
        x265_param *pParam = x265_param_alloc();
        // 设置参数
        x265_param_default(pParam);
        pParam->bRepeatHeaders = 1;
        pParam->internalCsp = csp;
        pParam->sourceWidth = width;
        pParam->sourceHeight = height;
        pParam->fpsNum = 24;
        pParam->fpsDenom = 1;

        // 打开编码器
        x265_encoder *pHander = x265_encoder_open(pParam);
        if (pHander == nullptr)
        {
            std::cout << "open encoder error." << std::endl;
            return -1;
        }
        int ySize = width * height;
        // 根据资源的大小设置的尺寸
        x265_picture *pPic_in = x265_picture_alloc();
        x265_picture_init(pParam, pPic_in);
        char * buff = nullptr;
        switch (csp)
        {
        case X265_CSP_I420:
            buff = new char[ySize * 3];
            pPic_in -> planes[0] = buff;
            pPic_in -> planes[1] = buff + ySize;
            pPic_in -> planes[2] = buff + ySize* 5 /4;
            pPic_in -> stride[0] = width;
            pPic_in -> stride[1] = width/2;
            pPic_in -> stride[2] = width/2;
            break;
        
        default:
            break;
        }
        // 计算帧数
        if (frameNum == 0)
        {
            switch (csp)
            {
            case X265_CSP_I420:
                fseek(fp_src, 0, SEEK_END);
                frameNum = ftell(fp_src) / (ySize * 3 / 2);
                fseek(fp_src, 0, SEEK_SET);
                break;

            default:
                std::cout << "Colorespace are not support." << std::endl;
                return -1;
            }
        }

        x265_nal *pNals = nullptr;
        uint32_t iNal = 0;
        // Loop to encode
        for (int i = 0; i < frameNum; i++)
        {
            switch (csp)
            {
            case X265_CSP_I420:
                // https://www.cplusplus.com/reference/cstdio/fseek/
                fread(pPic_in->planes[0], ySize, 1, fp_src);     // Y
                fread(pPic_in->planes[1], ySize / 4, 1, fp_src); // U
                fread(pPic_in->planes[2], ySize / 4, 1, fp_src); // V
                break;

            default:
                std::cout << "Coloresapce are not support." << std::endl;
                return -1;
            }
            // PTS VS DTS
            // https://bitmovin.com/docs/encoding/faqs/why-is-an-timestamp-offset-for-ts-muxings-applied-by-default
            // pPic_in->i_pts = i;

            int ret = x265_encoder_encode(pHander, &pNals, &iNal, pPic_in,nullptr);
            if (ret < 0)
            {
                std::cout << "Error encode." << std::endl;
                return -1;
            }
            std::cout << "success encode frame" << std::setw(5) << i << std::endl;
            for (int j = 0; j < iNal; j++)
            {
                std::cout << "write nal to file" << std::setw(5) << j << std::endl;
                fwrite(pNals[j].payload, 1, pNals[j].sizeBytes, fp_dst);
            }
        }
        std::cout << "to flush" << std::endl;
        // flush
        while (true)
        {
            int ret = x265_encoder_encode(pHander, &pNals, &iNal, pPic_in,nullptr);
            if (ret == 0)
            {
                break;
            }
            else if (ret < 0)
            {
                std::cout << "Error encode ." << std::endl;
                break;
            }
            else
            {
                std::cout << "Flush 1 frame." << std::endl;
                for (int j = 0; j < iNal; j++)
                {
                    fwrite(pNals[j].payload, 1, pNals[j].sizeBytes, fp_dst);
                }
                break;
            }
        }

        // clean
        std::cout << "to clean resource" << std::endl;
        x265_encoder_close(pHander);
        x265_picture_free(pPic_in);
        x265_param_free(pParam);
        delete[] buff;
        pHander = nullptr;

        fclose(fp_src);
        fclose(fp_dst);
        return 0;
    }
    else
    {
        char *buffer;
        if ((buffer = getcwd(nullptr, 0)) == nullptr)
        {
            std::cout << "get cwd error." << std::endl;
            free(buffer);
        }
        else
        {
            std::cout << "Error open files. "
                      << "the current dir is "
                      << buffer
                      << std::endl
                      << "The fpSrc is"
                      << fp_src
                      << "the fpDst is "
                      << fp_dst
                      << std::endl;
        }
        return -1;
    }
}

粉丝福利, 免费领取C++音视频学习资料包+学习路线大纲、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Open Source (GPL) H.265/HEVC video encoder 下载网址:https://bitbucket.org/multicoreware/x265/src x265 developer wiki To compile x265 you must first install Mercurial (or TortoiseHg on Windows) and CMake. Then follow these easy steps: (for the most definitive instructions, consult our build README) Linux Instructions # ubuntu packages: $ sudo apt-get install mercurial cmake cmake-curses-gui build-essential yasm # Note: if the packaged yasm is older than 1.2, you must download yasm-1.2 and build it $ hg clone https://bitbucket.org/multicoreware/x265 $ cd x265/build/linux $ ./make-Makefiles.bash $ make Windows (Visual Studio) Instructions $ hg clone https://bitbucket.org/multicoreware/x265 Then run make-solutions.bat in the build\ folder that corresponds to your favorite compiler, configure your build options, click 'configure', click 'generate', then close cmake-gui. You will be rewarded with an x265.sln file. Also see cmake documentation. Intel Compiler Instructions On Windows, you should open an Intel Compiler command prompt and within it run one of the make-makefiles.bat scripts in build/icl32 or build/icl64, then run nmake. On Linux, you can tell cmake to build Makefiles for icpc directly. This requires you to have configured Intel's compiler environment (by sourcing the appropriate shell script). For example: $ source /opt/intel/composer_xe_2013/bin/compilervars.sh intel64 $ cd repos/x265/build/linux $ export CXX=icpc $ export CC=icc $ ./make-Makefiles $ make Command line interface The Makefile/solution builds a static encoder.lib library and a standalone x265 executable that aims to be similar to x264 in its command line interface. Running without arguments shows you the command line help. Info Mission Statement Road Map TODO HOWTO add a new encoder performance primitive HOWTO Contribute patches to x265 HOWTO cross compile from Linux to Windows Coding Style Helpful links

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值