Friday, May 1, 2020

Cloud3D Bench 0.1

Overview

Cloud3D Bench is expected to be a standard and free benchmark suite for interactive graphics rendering research in the cloud. Cloud3D Bench 0.1 is our first attempt. To keep pace with the fast evolution of modern 3D workloads, we will keep enriching and updating this benchmark suite with more representative 3D applications on the Linux platform.

Benchmark Suite

Cloud3D bench currently has six 3D applications in total, which contains four computer games and two VR applications. All benchmarks are from real applications and cover popular game genres and usage cases. Table 1 lists these benchmarks. Among the six benchmarks, Dota2 and InMind are closed-source. 

Table 1. Applications included in Cloud3D Bench

Application Area BenchmarkGame
Game: Racing SuperTuxKart (STK)
Game: Real-time Strategy 0 A.D. (0AD)
Game: First-person Shoot Red Eclipse (RE)
Game: Online Battle Arena DoTA2 (D2)
VR: Education/Game InMind (IM)
VR: Health IMHOTEP (ITP)

Setups and Downloads

Setups: We use ubuntu 16.04, equipped with an 8-core Intel i7-7820x CPU, 16GB memory, and an NVIDIA GTX1080Ti GPU with 11GB GPU memory.

Downloads: STK, 0AD, RE, and ITP are open source and free to distribute, but InMind VR and DoTA2 are closed-source. So, we provide the following links to download these applications.

git clone https://github.com/cloud-graphics-rendering/cloud3dbench.git
cd cloud3dbench
./setup.sh

Then, it will take 1 to 2 hours to download the 3D applications.

For D2 and Inmind VR, you need to download these two applications from Steam on the Linux platform, after which, you need to copy all the files under "steam/steamapps/common/dota-2-beta/" to the path of dota2 in our benchmark suite directory. Similarly,  once you can play the InMind VR game in Steam, try to find the location of the InMindVR and copy the directory to our benchmark folder: cloud3dbench/inmindvr.

After copying, the folder of D2 and IM will be like this:
ll cloud3dbench/dota2
ll cloud3dbench/inmindvr

How to run the 3D applications?

-Run locally

Under each folder, you will find a script, named "start_game_real.sh", just run this one to launch applications locally.

Attention: If you encounter some errors when running DoTA2, please refer to this page.

-Run in the cloud / remotely

You will also find another script, named "start_game.sh", which is used to run 3D applications remotely (in the cloud) with the support of VirtualGL and TurboVNC. We have a docker image for you to use.

Description & Configuration

1. SuperTuxKart (STK) is an open-source 3D racing game. This game has specific implementations for different OS platforms. We use version 0.10 for the Linux platform. In this game, there are a variety of characters, tracks, and modes to select. In our evaluation, we choose "Sara" as the racer, use "abyss" track, and play in mode 0. Mode 0 is easy to play, and the "abyss" track involves intensive graphics rendering operations. 
2. 0 A.D. (0AD) is a real-time strategy 3D game, which is based on an ancient warfare story. This game also has specific implementations for three mainstream platforms. We use the version build in 2019 for the Linux platform. In this game, there are a variety of characters, maps, and modes to select. In our evaluation, we play "Matches" mode and choose the "Skirmish" map, with two players (Athenians and Britons). In the "Skirmish" map, there are some scenes for water rendering.
3. Red Eclipse (RE) is an open-source first-person shooting game. This game supports the three main platforms. We use the version of 1.6.0-nix64-stable on Linux. Similar to other games, we can select the game mode, game map, and characters. In our evaluation, we choose "deathmatch" mode, "area" map, and fight with bots from team "alpha". 
4. Dota 2 (D2) is a closed-source game, and it is an OnlineBattle Arena 3D game. This game is supported on windows platform and Linux platform with Steam. After downloading this free game on Linux, we can start Dota2 without Steam support. Since there are also lots of characters to choose and different modes to play. In our evaluation, we launched Dota2 without steam, and play with bots using "Luna".
5. InMind VR (IM) is a closed-source VR application, which brings players to experience the journey into the patient’s brain. This 3D application is available on different platforms and the version we use is for the Linux platform with Steam, which is released on July 9,2015. When we do the evaluation, we launched InMindVR without steam. 
6. IMHOTEP (ITP) is an immersive medical operation teaching and planning system. It is developed by the National Center for Tumor Disease and the University Hospital in Heidelberg. It is used to present patient data in a virtual reality setting. In our evaluation, we use a human liver model and visualize it using this software on the Linux platform.
All these 6 applications are real and they have different modes. You are free to use other configurations, but the above configurations are suggested.
 

Wednesday, April 29, 2020

Learning ffmpeg

How to install:

https://trac.ffmpeg.org/wiki/CompilationGuide/Centos

 Header

The ffmpeg header files:

extern "C"{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavutil/mem.h"
#include "libavutil/fifo.h"
#include "libswscale/swscale.h"
};

APIs

1. avcodec_init()
/*  Initialize libavcodec.
 *  This function must be called before any other libavcodec functions.
 *  This function is not thread-safe.
 *  # include "libavcodec/avcodec.h"
 *  Implementation: /ffmpeg/libavcodec/utils.c
*/

2. av_register_all()
/**
 * Initialize libavformat and register all the muxers, demuxers, and protocols. If you do not call this function, then you can select exactly which format you want to support.

* av_register_input_format()
* av_register_output_format()
* av_register_protocol()
*
* #include "libavformat/avformat.h"
* Implementation: /ffmpeg/libavformat/allformats.c
*/

3. avformat_alloc_context()
/** Allocate an AVFormatContext
 *  avformat_free_context() can be used to free the context and everything allocated by the framework within it.
*  #include "libavformat/avformat.h"
*  Implementation: /ffmpeg/libavformat/options.c
*/

4. avformat_free_context()
/** Free an AVFormatContext and all its streams.
*    void avformat_free_context(AVFormatContext *s)
*    #include "libavformat/avformat.h"
*    Implementation: /ffmpeg/libavformat/util.c
*
*/

5. avio_alloc_context()

AVIOContext *avio_alloc_context(
unsigned char *buffer,
int buffer_size,
int write_flag,
void *opaque,
int (*read_packet) (void *opaque, uint8_t * buf, int buf_size),
int (*write_packet)(void* opaque, uint8_t * buf, int buf_size),
int64_t(*seek)(void * opaque, int64_t offset, int whence));

6. av_open_input_file()

int av_open_input_file(
AVFormatContext **ic_ptr,
constchar * filename,
AVInputFormat *fmt,
int buf_size,
AVFormatParameters *ap);

7. av_close_input_file()

void av_close_input_file(AVFormatContext *s);

8. av_find_stream_info()

int av_find_stream_info(AVFormatContext* ic)

9. avcodec_find_decoder()
    avcodec_find_decoder_by_name()
    avcodec_find_encoder()
    avcodec_find_encoder_by_name()

10. avcodec_open()
int avcodec_open(AVCodecContext *avctx, AVCodec *codec);

AVOutputFormat *av_guess_format(constchar *short_name,
                                constchar *filename,
                                constchar *mime_type);
// 返回一个已经注册的最合适的输出格式

AVStream *av_new_stream(AVFormatContext *s, int id);
// 为媒体文件添加一个流,一般为作为输出的媒体文件容器添加音视频流

attribute_deprecated void dump_format(AVFormatContext *ic,
                                      int index,
                                      constchar *url,
                                      int is_output);
#endif
// 该函数的作用就是检查下初始化过程中设置的参数是否符合规范
// 有些版本中为 av_dump_format

attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
// 设置初始化参数
// 不赞成跳过该方法,直接调用 avformat_write_header/av_write_header
attribute_deprecated int av_write_header(AVFormatContext *s);
// 把流头信息写入到媒体文件中
// 返回0成功
1 AVPacket
typedef struct AVPacket {
    /**
     * Presentation timestamp in AVStream->time_base units; the time at which
     * the decompressed packet will be presented to the user.
     * Can be AV_NOPTS_VALUE if it is not stored in the file.
     * pts MUST be larger or equal to dts as presentation cannot happen before
     * decompression, unless one wants to view hex dumps. Some formats misuse
     * the terms dts and pts/cts to mean something different. Such timestamps
     * must be converted to true pts/dts before they are stored in AVPacket.
     */
    int64_t pts;
    /**
     * Decompression timestamp in AVStream->time_base units; the time at which
     * the packet is decompressed.
     * Can be AV_NOPTS_VALUE if it is not stored in the file.
     */
    int64_t dts;
    uint8_t *data;
    int   size;
    int   stream_index;
    int   flags;

int   duration;
...
} AVPacket

// AVPacket是个很重要的结构,该结构在读媒体源文件和写输出文件时都需要用到
// int64_t pts; 显示时间戳
// int64_t dts; 解码时间戳
// uint8_t *data; 包数据
// int   size; 包数据长度
// int   stream_index; 包所属流序号
// int   duration; 时长
// 以上信息,如果是在读媒体源文件那么avcodec会初始化,如果是输出文件,用户需要对以上信息赋值
void av_init_packet(AVPacket *pkt);
// 使用默认值初始化AVPacket
// 定义AVPacket对象后,请使用av_init_packet进行初始化
void av_free_packet(AVPacket *pkt);
// 释放AVPacket对象
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
// 从输入源文件容器中读取一个AVPacket数据包
// 该函数读出的包并不每次都是有效的,对于读出的包我们都应该进行相应的解码(视频解码/音频解码),
// 在返回值>=0时,循环调用该函数进行读取,循环调用之前请调用av_free_packet函数清理AVPacket
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,

                         int *got_picture_ptr,

                         AVPacket *avpkt);
// 解码视频流AVPacket
// 使用av_read_frame读取媒体流后需要进行判断,如果为视频流则调用该函数解码
// 返回结果<0时失败,此时程序应该退出检查原因
// 返回>=0时正常,假设 读取包为:AVPacket vPacket 返回值为 int vLen; 每次解码正常时,对vPacket做
// 如下处理:
//   vPacket.size -= vLen;
//   vPacket.data += vLen;
// 如果 vPacket.size==0,则继续读下一流包,否则继续调度该方法进行解码,直到vPacket.size==0
// 返回 got_picture_ptr > 0 时,表示解码到了AVFrame *picture,其后可以对picture进程处理
int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,

                         int *frame_size_ptr,

                         AVPacket *avpkt);

// 解码音频流AVPacket
// 使用av_read_frame读取媒体流后需要进行判断,如果为音频流则调用该函数解码
// 返回结果<0时失败,此时程序应该退出检查原因
// 返回>=0时正常,假设 读取包为:AVPacket vPacket 返回值为 int vLen; 每次解码正常时,对vPacket做
// 如下处理:
//   vPacket.size -= vLen;
//   vPacket.data += vLen;
// 如果 vPacket.size==0,则继续读下一流包,否则继续调度该方法进行解码,直到vPacket.size==0

Data Structures

1. AVFormatContext

typedef struct AVFormatContext{
    struct AVInputFormat        *iformat;
    struct AVOutputFormat     * oformat;
    AVIOContext                      *pb;
    unsigned int                       nb_streams;
    AVStream                          **streams;
    char                                   filename[1024];
    ...
}AVFormatContext;

2. AVIOContext

typedef struct AVIOContext{

}AVIOContext;

3. AVPacket

typedef struct AVPacket {
    /**
     * Presentation timestamp in AVStream->time_base units; the time at which
     * the decompressed packet will be presented to the user.
     * Can be AV_NOPTS_VALUE if it is not stored in the file.
     * pts MUST be larger or equal to dts as presentation cannot happen before
     * decompression, unless one wants to view hex dumps. Some formats misuse
     * the terms dts and pts/cts to mean something different. Such timestamps
     * must be converted to true pts/dts before they are stored in AVPacket.
     */
    int64_t pts;
    /**
     * Decompression timestamp in AVStream->time_base units; the time at which
     * the packet is decompressed.
     * Can be AV_NOPTS_VALUE if it is not stored in the file.
     */
    int64_t dts;
    uint8_t *data;
    int   size;
    int   stream_index;
    int   flags;

int   duration;
...
} AVPacket

Reference: 

https://blog.csdn.net/leixiaohua1020/article/details/15811977/