7.2. 视频编解码性能

本节我们列举了BM1684芯片对于视频编码、解码、转码的性能数据,此外,我们附上了每一个性能测试的测试命令,您可以按照表格中的测试命令进行验证。

注解

  1. sleep参数值是经验值,需要根据tpu型号和视频格式自行设置。

  2. 如发生”tail: write error: Broken pipe”的问题,是因为线程还没有完成编/解码,因此线程没有正常退出。解决办法是将sleep设置的时间长一点。

  3. 测试文件可从如下链接中获取: 测试脚本

7.2.1. 视频解码性能测试

测试命令

#!/bin/bash

video=jellyfish-3-mbps-hd-h264.mkv
tpu_id=0
thread_num=16
decode_type=h264_bm

rm -rf *.log
rm -rf fpssum.txt  fps.txt  framesum.txt  frame.txt  speed.txt  timeavg.txt  timesum.txt  time.txt
killall ffmpeg &> /dev/null

for ((thread=0; thread<$thread_num; thread++))
do
{
        nohup ffmpeg -benchmark -extra_frame_buffer_num 5 -output_format 0 -zero_copy 1 -sophon_idx ${tpu_id} -c:v ${decode_type} -i $video  -f null /dev/null >> ${video}_thread_${thread}_tpu_${tpu_id}.log 2>&1 &
} &
done

echo "Start Wait End..."

while true; do
    ffmpeg_num=$(ps aux | grep ffmpeg | grep -v "grep" | wc -l)
    echo "running ffmpeg num: ${ffmpeg_num}"
    if [[ "$ffmpeg_num" == "0" ]]; then
            break
    fi
    sleep 3
done

echo "Start Calc fps..."


for ((thread=0; thread<$thread_num; thread++))
do
    frame_index=0
    for((a=1; a<20; a++))
    do
        str=$(cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n ${a}|head -n 1)
        # echo $str
        keyword=$(echo $str |grep "frame=")
        # echo $keyword
        if [[ $keyword != "" ]];
        then
        frame_index=${a}
        break
        fi
    done
    time_index=0
    for((a=1; a<20; a++))
    do
            str=$(cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n ${a}|head -n 1)
            # echo $str
            keyword=$(echo $str |grep "rtime=")
            # echo $keyword
            if [[ $keyword != "" ]];
            then
                time_index=${a}
                break
            fi
    done

    cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n $frame_index|head -n 1| awk -F '=' '{print $3}'|tr -d 'a-z'|tr -d ' ' >> fps.txt    #fps
    cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n $frame_index|head -n 1| awk -F '=' '{print $2}'|tr -d 'a-z'|tr -d ' ' >> frame.txt    #frames
    cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n $time_index|head -n 1| awk -F '=' '{print $4}'|tr -d 'a-z'|tr -d ' ' >> time.txt    #frames
    cat fps.txt | awk '{sum+=$1} END {print sum}' > fpssum.txt
    cat frame.txt | awk '{sum+=$1} END {print sum}' > framesum.txt
    cat time.txt | awk '{sum+=$1} END {print sum}' > timesum.txt
done

echo "tpu_id: $tpu_id"
echo "total_frames: $(<framesum.txt)"
task_num=$(cat frame.txt | grep "." -c)
cat timesum.txt | awk '{print $1/'$task_num'}' > timeavg.txt
echo "avg_time: $(<timeavg.txt)"
f_sum=$(<framesum.txt)
time_avg=$(<timeavg.txt)
awk 'BEGIN{printf "%.2f\n",'$f_sum'/'$time_avg'}' > speed.txt
speed=$(<speed.txt)
echo "speed: ${speed}"

参数说明

  • tpu_id: 测试的tpu的编号,可以通过bm-smi查看。

  • thread_num: 解码线程数,一般可设置为16。

  • decode_type: 解码方式,如h264_bm,hevc_bm ,分别代表h264和h265。

典型测试结果

芯片

场景

测试结果

1684

decode

../_images/1684_decode.png

1684X

decode

../_images/1684x_decode.png

小技巧

测试脚本 中包含了多芯卡的测试程序’decode_multicard.sh’,通过修改里面的’tpu_ids’可实现对多芯卡的视频解码测试。

7.2.2. 视频编码性能测试

测试命令

video=jellyfish-3-mbps-hd-h264.mkv
tpu_id=0
thread_num=12
encode_type=h264_bm

rm -rf *.log
rm -rf fpssum.txt  fps.txt  framesum.txt  frame.txt  speed.txt  timeavg.txt  timesum.txt  time.txt
killall ffmpeg &> /dev/null

for ((thread=0; thread<$thread_num; thread++))
do
{
    nohup ffmpeg -benchmark -extra_frame_buffer_num 5 -output_format 0 -zero_copy 1 -sophon_idx ${tpu_id} -i $video -sophon_idx ${tpu_id} -c:v ${encode_type} -g 256 -is_dma_buffer 1 -b:v 3MB -enc-params "gop_preset=2:mb_rc=1:delta_qp=3:min_qp=35:max_qp=40" -f null /dev/null >> ${video}_thread_${thread}_tpu_${tpu_id}.log 2>&1 &
} &
done

echo "Start Wait End..."

while true; do
    ffmpeg_num=$(ps aux | grep ffmpeg | grep -v "grep" | wc -l)
    echo "running ffmpeg num: ${ffmpeg_num}"
    if [[ "$ffmpeg_num" == "0" ]]; then
            break
    fi
    sleep 3
done

echo "Start Calc fps..."

for ((thread=0; thread<$thread_num; thread++))
do
    frame_index=0
    for((a=1; a<20; a++))
    do
        str=$(cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n ${a}|head -n 1)
        # echo $str
        keyword=$(echo $str |grep "frame=")
        # echo $keyword
        if [[ $keyword != "" ]];
        then
        frame_index=${a}
        break
        fi
    done
    time_index=0
    for((a=1; a<20; a++))
    do
            str=$(cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n ${a}|head -n 1)
            # echo $str
            keyword=$(echo $str |grep "rtime=")
            # echo $keyword
            if [[ $keyword != "" ]];
            then
                time_index=${a}
                break
            fi
    done

    cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n $frame_index|head -n 1| awk -F '=' '{print $3}'|tr -d 'a-z'|tr -d ' ' >> fps.txt    #fps
    cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n $frame_index|head -n 1| awk -F '=' '{print $2}'|tr -d 'a-z'|tr -d ' ' >> frame.txt    #frames
    cat ${video}_thread_${thread}_tpu_${tpu_id}.log | tail -n $time_index|head -n 1| awk -F '=' '{print $4}'|tr -d 'a-z'|tr -d ' ' >> time.txt    #frames
    cat fps.txt | awk '{sum+=$1} END {print sum}' > fpssum.txt
    cat frame.txt | awk '{sum+=$1} END {print sum}' > framesum.txt
    cat time.txt | awk '{sum+=$1} END {print sum}' > timesum.txt
done

echo "tpu_id: $tpu_id"
echo "total_frames: $(<framesum.txt)"
task_num=$(cat frame.txt | grep "." -c)
cat timesum.txt | awk '{print $1/'$task_num'}' > timeavg.txt
echo "avg_time: $(<timeavg.txt)"
f_sum=$(<framesum.txt)
time_avg=$(<timeavg.txt)
awk 'BEGIN{printf "%.2f\n",'$f_sum'/'$time_avg'}' > speed.txt
speed=$(<speed.txt)
echo "speed: ${speed}"

参数说明

  • tpu_ids: 测试的tpu的编号,可以通过bm-smi查看。

  • thread_num: 编码线程数,典型的,一般在BM1684芯片上面设置为2,在BM1684X芯片上可设置为12。

  • encode_type: 编码方式,如h264_bm,h265_bm ,分别代表h264和h265。

典型测试结果

芯片

场景

测试结果

1684

encode

../_images/1684_encode.png

1684X

encode

../_images/1684x_encode.png

小技巧

测试脚本 中包含了多芯卡的测试程序’encode_multicard.sh’,通过修改里面的’tpu_ids’可实现对多芯卡的视频编码测试。

7.2.3. 视频转码性能测试

生成转码所需要的原始视频

ffmpeg -i jellyfish-3-mbps-hd-h264.mkv -c copy -bsf:v h264_mp4toannexb -f mpegts 1.264
ffmpeg -i "concat:1.264|1.264|1.264|1.264|1.264|1.264|1.264|1.264" -c copy -bsf:a aac_adtstoasc -movflags +faststart test.264

转32K低码流

ffmpeg -hwaccel bmcodec -hwaccel_device 0 -c:v h264_bm -output_format 101 -i test.264 -vf "scale_bm=352:288" -c:v h264_bm -g 256 -b:v 32K -y result.264

转1M高码流

ffmpeg -hwaccel bmcodec -hwaccel_device 0 -c:v h264_bm -output_format 101 -i test.264 -vf "scale_bm=352:288" -c:v h264_bm -g 256 -b:v 1M -y result.ts

参数说明

  • -hwaccel: 使用硬件API

  • -hwaccel_device: 指定设备,使用bm-smi查看

  • -c:v: 解码器

  • -output_format 输出数据的格式。设为0,则输出线性排列的未压缩数据;设为101,则输出压缩数据。缺省值为0。推荐设置为101,输出压缩数据。可以节省内存、节省带宽。输出的压缩数据,可以调用scale_bm filter解压缩成正常的YUV数据。

  • -i 输入

  • -vf ffmpeg过滤器,scale_bm将frame resize为目标宽高

  • -c:v 编码器

  • -g 关键帧间隔控制

  • -b:v 输出码流

  • -y 输出时覆盖原文件

  • result.ts 输出文件

典型测试结果

芯片

场景

测试结果

1684

转 32K 低码流

../_images/1684_transcode_1.png

转 1M 高码流

../_images/1684_transcode_2.png

1684X

转 32K 低码流

../_images/1684x_transcode_1.png

转 1M 高码流

../_images/1684x_transcode_2.png