# transcode
**Repository Path**: cambricon/transcode
## Basic Information
- **Project Name**: transcode
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 1
- **Created**: 2023-02-14
- **Last Updated**: 2023-11-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 视频转码
- [视频转码](#视频转码)
- [1.介绍](#1介绍)
- [2.前提条件](#2前提条件)
- [3.转码流程介绍](#3转码流程介绍)
- [4.运行example](#4运行example)
- [4.1 编译](#41-编译)
- [4.2 下载测试数据](#42-下载测试数据)
- [4.2 h264转hevc](#42-h264转hevc)
- [4.3 hevc转h264](#43-hevc转h264)
- [4.4 多输入](#44-多输入)
- [4.5 多输出](#45-多输出)
- [5 编解码流程](#5-编解码流程)
- [6.FAQ](#6faq)
- [推送rtmp视频流说明](#推送rtmp视频流说明)
- [安装ffmpeg,提示nasm/yasm 找不到](#安装ffmpeg提示nasmyasm-找不到)
## 1.介绍
视频转码,即将视频信号从一种格式转换成另一种格式
## 2.前提条件
- Linux 常见操作系统版本(如 Ubuntu16.04,Ubuntu18.04,CentOS7.x 等),安装 docker(>=v18.00.0)应用程序;
- 服务器装配好寒武纪 300 系列及以上的智能加速卡,并安装好驱动(>=v4.20.6)和cntoolkit(>=vx.x.x);
- 若不具备以上软硬件条件,可前往[寒武纪开发者社区](https://developer.cambricon.com/)申请试用;
下载cntoolkit后,执行以下命令安装,请根据实际情况替换内容
```bash
apt install ./cntoolkit_3.x.x-x.ubuntu18.04_amd64.deb
```
安装cncodec3及依赖的软件包
```bash
apt update
apt install cncodec3 cndev cndrv cnrt
```
## 3.转码流程介绍
视频转码的流程,就是将源视频流解码,解码出视频帧后,重新编码为目标格式。以下为h264的视频流转hevc的流程。
```mermaid
flowchart LR
h264_stream("h264视频流")
hevc_stream("hevc视频流")
frame("视频帧")
h264_stream-->|"解码器"|frame
frame-->|"编码器"|hevc_stream
```
## 4.运行example
### 4.1 编译
```bash
./build.sh
```
### 4.2 下载测试数据
数据存放于码云,手动下载后,放至本仓库的根目录
下载地址:https://gitee.com/mldata/data/blob/master/videos/cars.mp4
此视频为h264,hevc格式视频,运行h264_to_hevc后,将保存的output.mp4改成cars2.mp4,即可
### 4.2 h264转hevc
视频文件(h264) --> 视频文件(hevc)
```bash
./bin/simple_h264_to_hevc
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cars.mp4':
Metadata:
major_brand : mp42
minor_version : 1
compatible_brands: mp41mp42isom
creation_time : 2018-06-26T08:39:41.000000Z
Duration: 00:00:40.07, start: 0.000000, bitrate: 12128 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 12127 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 50 tbc (default)
Metadata:
creation_time : 2018-06-26T08:39:41.000000Z
handler_name : Core Media Video
[INFO ][/workspace/transcode/src/video_dec.cpp:153] Dec start success.
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: hevc (Main) (hev1 / 0x31766568), nv12, 1280x720, q=2-31, 30k tbn
[INFO ][/workspace/transcode/src/video_enc.cpp:214] Enc create success.
[WARN ][/workspace/transcode/src/video_dec.cpp:218] ffmpeg read frame failed, End of file
[INFO ][/workspace/transcode/src/video_enc.cpp:244] Enc finish.
[INFO ][/workspace/transcode/src/video_dec.cpp:172] Dec finish.
```
### 4.3 hevc转h264
视频文件(hevc) --> 视频文件(h264)
```bash
./bin/simple_hevc_to_h264
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cars2.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf57.83.100
Duration: 00:00:39.97, start: 0.033000, bitrate: 9885 kb/s
Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv), 1280x720, 9884 kb/s, 30.03 fps, 30 tbr, 30k tbn, 30 tbc (default)
Metadata:
handler_name : VideoHandler
[INFO ][/workspace/transcode/src/video_dec.cpp:153] Dec start success.
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: h264 (Main) (avc1 / 0x31637661), nv12, 1280x720, q=2-31, 30k tbn
[INFO ][/workspace/transcode/src/video_enc.cpp:214] Enc create success.
[WARN ][/workspace/transcode/src/video_dec.cpp:218] ffmpeg read frame failed, End of file
[INFO ][/workspace/transcode/src/video_enc.cpp:244] Enc finish.
[INFO ][/workspace/transcode/src/video_dec.cpp:172] Dec finish.
```
### 4.4 多输入
```
视频文件(h264) ↘
视频帧拼接 --> 视频文件(h264)
视频文件(hevc) ↗
```
```bash
./bin/simple_multi_input
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cars.mp4':
Metadata:
major_brand : mp42
minor_version : 1
compatible_brands: mp41mp42isom
creation_time : 2018-06-26T08:39:41.000000Z
Duration: 00:00:40.07, start: 0.000000, bitrate: 12128 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 12127 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 50 tbc (default)
Metadata:
creation_time : 2018-06-26T08:39:41.000000Z
handler_name : Core Media Video
[INFO ][/workspace/transcode/src/video_dec.cpp:153] Dec start success.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cars.mp4':
Metadata:
major_brand : mp42
minor_version : 1
compatible_brands: mp41mp42isom
creation_time : 2018-06-26T08:39:41.000000Z
Duration: 00:00:40.07, start: 0.000000, bitrate: 12128 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 12127 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 50 tbc (default)
Metadata:
creation_time : 2018-06-26T08:39:41.000000Z
handler_name : Core Media Video
[INFO ][/workspace/transcode/src/video_dec.cpp:153] Dec start success.
Output #0, mp4, to 'concat.mp4':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: h264 (Main) (avc1 / 0x31637661), nv12, 1280x1440, q=2-31, 30k tbn
[INFO ][/workspace/transcode/src/video_enc.cpp:214] Enc create success.
[WARN ][/workspace/transcode/src/video_dec.cpp:218] ffmpeg read frame failed, End of file
[WARN ][/workspace/transcode/src/video_dec.cpp:218] ffmpeg read frame failed, End of file
[INFO ][/workspace/transcode/src/video_enc.cpp:244] Enc finish.
[INFO ][/workspace/transcode/src/video_dec.cpp:172] Dec finish.
[INFO ][/workspace/transcode/src/video_dec.cpp:172] Dec finish.
```
### 4.5 多输出
运行前,请确保流媒体服务器已启动,[参考](#推送rtmp视频流说明)
```
↗ 视频文件 (hevc)
h264的视频文件
↘ rtsp视频流(h264)
```
```bash
./bin/simple_multi_output
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cars.mp4':
Metadata:
major_brand : mp42
minor_version : 1
compatible_brands: mp41mp42isom
creation_time : 2018-06-26T08:39:41.000000Z
Duration: 00:00:40.07, start: 0.000000, bitrate: 12128 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 12127 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 50 tbc (default)
Metadata:
creation_time : 2018-06-26T08:39:41.000000Z
handler_name : Core Media Video
[INFO ][/workspace/transcode/src/video_dec.cpp:153] Dec start success.
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: hevc (Main) (hev1 / 0x31766568), nv12, 1280x720, q=2-31, 30k tbn
[INFO ][/workspace/transcode/src/video_enc.cpp:214] Enc create success.
Output #0, flv, to 'rtmp://10.3.69.28/live/livestream':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: h264 (Main) ([7][0][0][0] / 0x0007), nv12, 1280x720, q=2-31, 1k tbn
[INFO ][/workspace/transcode/src/video_enc.cpp:214] Enc create success.
[WARN ][/workspace/transcode/src/video_dec.cpp:218] ffmpeg read frame failed, End of file
[INFO ][/workspace/transcode/src/video_enc.cpp:244] Enc finish.
[INFO ][/workspace/transcode/src/video_enc.cpp:244] Enc finish.
[INFO ][/workspace/transcode/src/video_dec.cpp:172] Dec finish.
```
## 5 编解码流程
```mermaid
sequenceDiagram
autonumber
participant 解码线程
participant 解码器回调
participant 主线程
participant 编码线程
participant 编码器回调
Note over 主线程: 实例化解码器
Note over 主线程: 解码器参数设置
alt 启动解码器
主线程 ->> 解码线程: 启动解码线程
Note over 解码线程: 视频解封装
解码线程 ->> 解码器回调: 创建解码器
并启动回调函数
Note over 解码器回调: new_seq 事件
解码器回调 ->> 主线程: 通知主线程
收到new_seq事件
end
Note over 主线程: 实例化编码器
Note over 主线程: 编码器参数设置
alt 启动解码器
主线程 ->> 编码器回调: 创建编码器
并启动回调函数
主线程 ->> 编码线程: 创建编码线程
Note over 编码器回调: sps pps事件
编码器回调 ->> 编码线程: 通知编码线程
收到sps pps事件
Note over 编码线程: 创建视频输出流
end
loop 循环至视频结束
解码线程 ->> 解码器回调: 读取原视频流的帧
发送到解码器
Note over 解码器回调: new_frame 事件
解码器回调 ->> 主线程: 取出解码后的视频帧
主线程 ->> 编码器回调: 发送视频帧到编码器
Note over 编码器回调: new_frame 事件
编码器回调 ->> 编码线程: 编码后的数据,写入视频流
end
Note over 主线程: 结束解码器
Note over 主线程: 结束编码器
```
## 6.FAQ
### 推送rtmp视频流说明
推送rtmp视频流前,需要先启动流媒体服务器流媒体服务器,推荐使用docker版的srs
```bash
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 registry.cn-hangzhou.aliyuncs.com/ossrs/srs:4 ./objs/srs -c conf/docker.conf
```
推动视频流后,浏览器访问流媒体服务器的8080端口,点击SRS控制台->视频流->预览,即可观看视频流
### 安装ffmpeg,提示nasm/yasm 找不到
```bash
apt-get install nasm
```