1da853ecaSopenharmony_ci/*
2da853ecaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License.
5da853ecaSopenharmony_ci * You may obtain a copy of the License at
6da853ecaSopenharmony_ci *
7da853ecaSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8da853ecaSopenharmony_ci *
9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and
13da853ecaSopenharmony_ci * limitations under the License.
14da853ecaSopenharmony_ci */
15da853ecaSopenharmony_ci
16da853ecaSopenharmony_ci#include <cstdio>
17da853ecaSopenharmony_ci#include <fcntl.h>
18da853ecaSopenharmony_ci#include <iostream>
19da853ecaSopenharmony_ci#include <malloc.h>
20da853ecaSopenharmony_ci#include <string>
21da853ecaSopenharmony_ci#include <thread>
22da853ecaSopenharmony_ci#include <sys/stat.h>
23da853ecaSopenharmony_ci#include <fstream>
24da853ecaSopenharmony_ci#include <chrono>
25da853ecaSopenharmony_ci
26da853ecaSopenharmony_ci#include "avcodec_common.h"
27da853ecaSopenharmony_ci#include "buffer/avsharedmemorybase.h"
28da853ecaSopenharmony_ci#include "media_description.h"
29da853ecaSopenharmony_ci#include "native_avcodec_base.h"
30da853ecaSopenharmony_ci#include "native_avformat.h"
31da853ecaSopenharmony_ci#include "native_avmagic.h"
32da853ecaSopenharmony_ci#include "native_avmemory.h"
33da853ecaSopenharmony_ci#include "native_avbuffer.h"
34da853ecaSopenharmony_ci
35da853ecaSopenharmony_ci#include "capi_demo/avdemuxer_demo.h"
36da853ecaSopenharmony_ci#include "capi_demo/avsource_demo.h"
37da853ecaSopenharmony_ci#include "demo_log.h"
38da853ecaSopenharmony_ci#include "inner_demo/inner_demuxer_demo.h"
39da853ecaSopenharmony_ci#include "inner_demo/inner_source_demo.h"
40da853ecaSopenharmony_ci#include "server_demo/file_server_demo.h"
41da853ecaSopenharmony_ci
42da853ecaSopenharmony_ci#include "avdemuxer_demo_runner.h"
43da853ecaSopenharmony_ci#include "media_data_source.h"
44da853ecaSopenharmony_ci
45da853ecaSopenharmony_ciusing namespace std;
46da853ecaSopenharmony_ciusing namespace OHOS::MediaAVCodec;
47da853ecaSopenharmony_ciusing namespace OHOS::Media;
48da853ecaSopenharmony_ci
49da853ecaSopenharmony_cistatic int64_t g_seekTime = 1000;
50da853ecaSopenharmony_cistatic int64_t g_startTime = 0;
51da853ecaSopenharmony_cistatic int64_t g_loopTime = 20;
52da853ecaSopenharmony_cistatic uint32_t g_maxThreadNum = 16;
53da853ecaSopenharmony_cistatic vector<string> g_filelist = {"AAC_44100hz_2c.aac",    "ALAC_44100hz_2c.m4a",
54da853ecaSopenharmony_ci                                    "FLAC_44100hz_2c.flac",  "h264_720x480_aac_44100hz_2c.mp4",
55da853ecaSopenharmony_ci                                    "h264_aac_moovlast.mp4", "h265_720x480_aac_44100hz_2c.mp4",
56da853ecaSopenharmony_ci                                    "MPEG_44100hz_2c.mp3",   "MPEGTS_V1920x1080_A44100hz_2c.ts",
57da853ecaSopenharmony_ci                                    "OGG_44100hz_2c.ogg",    "WAV_44100hz_2c.wav"};
58da853ecaSopenharmony_cistatic std::string g_filePath;
59da853ecaSopenharmony_ci
60da853ecaSopenharmony_cistatic int32_t AVSourceReadAt(OH_AVBuffer *data, int32_t length, int64_t pos)
61da853ecaSopenharmony_ci{
62da853ecaSopenharmony_ci    if (data == nullptr) {
63da853ecaSopenharmony_ci        printf("AVSourceReadAt : data is nullptr!\n");
64da853ecaSopenharmony_ci        return MediaDataSourceError::SOURCE_ERROR_IO;
65da853ecaSopenharmony_ci    }
66da853ecaSopenharmony_ci
67da853ecaSopenharmony_ci    std::ifstream infile(g_filePath, std::ofstream::binary);
68da853ecaSopenharmony_ci    if (!infile.is_open()) {
69da853ecaSopenharmony_ci        printf("AVSourceReadAt : open file failed! file:%s\n", g_filePath.c_str());
70da853ecaSopenharmony_ci        return MediaDataSourceError::SOURCE_ERROR_IO;  // 打开文件失败
71da853ecaSopenharmony_ci    }
72da853ecaSopenharmony_ci
73da853ecaSopenharmony_ci    infile.seekg(0, std::ios::end);
74da853ecaSopenharmony_ci    int64_t fileSize = infile.tellg();
75da853ecaSopenharmony_ci    if (pos >= fileSize) {
76da853ecaSopenharmony_ci        printf("AVSourceReadAt : pos over or equals file size!\n");
77da853ecaSopenharmony_ci        return MediaDataSourceError::SOURCE_ERROR_EOF;  // pos已经是文件末尾位置,无法读取
78da853ecaSopenharmony_ci    }
79da853ecaSopenharmony_ci
80da853ecaSopenharmony_ci    if (pos + length > fileSize) {
81da853ecaSopenharmony_ci        length = fileSize - pos;    // pos+length长度超过文件大小时,读取从pos到文件末尾的数据
82da853ecaSopenharmony_ci    }
83da853ecaSopenharmony_ci
84da853ecaSopenharmony_ci    infile.seekg(pos, std::ios::beg);
85da853ecaSopenharmony_ci    if (length <= 0) {
86da853ecaSopenharmony_ci        printf("AVSourceReadAt : raed length less than zero!\n");
87da853ecaSopenharmony_ci        return MediaDataSourceError::SOURCE_ERROR_IO;
88da853ecaSopenharmony_ci    }
89da853ecaSopenharmony_ci    char* buffer = new char[length];
90da853ecaSopenharmony_ci    infile.read(buffer, length);
91da853ecaSopenharmony_ci    infile.close();
92da853ecaSopenharmony_ci
93da853ecaSopenharmony_ci    errno_t result = memcpy_s(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)),
94da853ecaSopenharmony_ci        OH_AVBuffer_GetCapacity(data), buffer, length);
95da853ecaSopenharmony_ci    delete[] buffer;
96da853ecaSopenharmony_ci    if (result != 0) {
97da853ecaSopenharmony_ci        printf("memcpy_s failed!");
98da853ecaSopenharmony_ci        return MediaDataSourceError::SOURCE_ERROR_IO;
99da853ecaSopenharmony_ci    }
100da853ecaSopenharmony_ci
101da853ecaSopenharmony_ci    return length;
102da853ecaSopenharmony_ci}
103da853ecaSopenharmony_ci
104da853ecaSopenharmony_cistatic void TestNativeSeek(OH_AVMemory *sampleMem, int32_t trackCount, std::shared_ptr<AVDemuxerDemo> avDemuxerDemo)
105da853ecaSopenharmony_ci{
106da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_MODE_NEXT_SYNC\n");
107da853ecaSopenharmony_ci    avDemuxerDemo->SeekToTime(g_seekTime, OH_AVSeekMode::SEEK_MODE_NEXT_SYNC); // 测试seek功能
108da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
109da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_MODE_PREVIOUS_SYNC\n");
110da853ecaSopenharmony_ci    avDemuxerDemo->SeekToTime(g_seekTime, OH_AVSeekMode::SEEK_MODE_PREVIOUS_SYNC);
111da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
112da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_MODE_CLOSEST_SYNC\n");
113da853ecaSopenharmony_ci    avDemuxerDemo->SeekToTime(g_seekTime, OH_AVSeekMode::SEEK_MODE_CLOSEST_SYNC);
114da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
115da853ecaSopenharmony_ci    printf("seek to 0s,mode:SEEK_MODE_CLOSEST_SYNC\n");
116da853ecaSopenharmony_ci    avDemuxerDemo->SeekToTime(g_startTime, OH_AVSeekMode::SEEK_MODE_CLOSEST_SYNC);
117da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
118da853ecaSopenharmony_ci}
119da853ecaSopenharmony_ci
120da853ecaSopenharmony_cistatic void ShowSourceDescription(OH_AVFormat *oh_trackformat)
121da853ecaSopenharmony_ci{
122da853ecaSopenharmony_ci    int32_t trackType = -1;
123da853ecaSopenharmony_ci    int64_t duration = -1;
124da853ecaSopenharmony_ci    const char* mimeType = nullptr;
125da853ecaSopenharmony_ci    int64_t bitrate = -1;
126da853ecaSopenharmony_ci    int32_t width = -1;
127da853ecaSopenharmony_ci    int32_t height = -1;
128da853ecaSopenharmony_ci    int32_t audioSampleFormat = -1;
129da853ecaSopenharmony_ci    double keyFrameRate = -1;
130da853ecaSopenharmony_ci    int32_t profile = -1;
131da853ecaSopenharmony_ci    int32_t audioChannelCount = -1;
132da853ecaSopenharmony_ci    int32_t audioSampleRate = -1;
133da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_TRACK_TYPE, &trackType);
134da853ecaSopenharmony_ci    OH_AVFormat_GetLongValue(oh_trackformat, OH_MD_KEY_DURATION, &duration);
135da853ecaSopenharmony_ci    OH_AVFormat_GetStringValue(oh_trackformat, OH_MD_KEY_CODEC_MIME, &mimeType);
136da853ecaSopenharmony_ci    OH_AVFormat_GetLongValue(oh_trackformat, OH_MD_KEY_BITRATE, &bitrate);
137da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_WIDTH, &width);
138da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_HEIGHT, &height);
139da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, &audioSampleFormat);
140da853ecaSopenharmony_ci    OH_AVFormat_GetDoubleValue(oh_trackformat, OH_MD_KEY_FRAME_RATE, &keyFrameRate);
141da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_PROFILE, &profile);
142da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_AUD_CHANNEL_COUNT, &audioChannelCount);
143da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_trackformat, OH_MD_KEY_AUD_SAMPLE_RATE, &audioSampleRate);
144da853ecaSopenharmony_ci    printf("===>tracks:%d duration:%" PRId64 " mimeType:%s bitrate:%" PRId64 " width:%d height:%d audioSampleFormat:%d"
145da853ecaSopenharmony_ci        " keyFrameRate:%.2f profile:%d audioChannelCount:%d audioSampleRate:%d\n", trackType, duration, mimeType,
146da853ecaSopenharmony_ci        bitrate, width, height, audioSampleFormat, keyFrameRate, profile, audioChannelCount, audioSampleRate);
147da853ecaSopenharmony_ci}
148da853ecaSopenharmony_ci
149da853ecaSopenharmony_cistatic void RunNativeDemuxer(const std::string &filePath, const std::string &fileMode)
150da853ecaSopenharmony_ci{
151da853ecaSopenharmony_ci    auto avSourceDemo = std::make_shared<AVSourceDemo>();
152da853ecaSopenharmony_ci    int32_t fd = -1;
153da853ecaSopenharmony_ci    if (fileMode == "1") {
154da853ecaSopenharmony_ci        avSourceDemo->CreateWithURI((char *)(filePath.c_str()));
155da853ecaSopenharmony_ci    } else if (fileMode == "0" || fileMode == "2") {
156da853ecaSopenharmony_ci        if ((fd = open(filePath.c_str(), O_RDONLY)) < 0) {
157da853ecaSopenharmony_ci            printf("open file failed\n");
158da853ecaSopenharmony_ci            return;
159da853ecaSopenharmony_ci        }
160da853ecaSopenharmony_ci        int64_t fileSize = avSourceDemo->GetFileSize(filePath);
161da853ecaSopenharmony_ci        if (fileMode == "0") {
162da853ecaSopenharmony_ci            avSourceDemo->CreateWithFD(fd, 0, fileSize);
163da853ecaSopenharmony_ci        } else if (fileMode == "2") {
164da853ecaSopenharmony_ci            g_filePath = filePath;
165da853ecaSopenharmony_ci            OH_AVDataSource dataSource = {fileSize, AVSourceReadAt};
166da853ecaSopenharmony_ci            avSourceDemo->CreateWithDataSource(&dataSource);
167da853ecaSopenharmony_ci        }
168da853ecaSopenharmony_ci    }
169da853ecaSopenharmony_ci
170da853ecaSopenharmony_ci    auto avDemuxerDemo = std::make_shared<AVDemuxerDemo>();
171da853ecaSopenharmony_ci    OH_AVSource *av_source = avSourceDemo->GetAVSource();
172da853ecaSopenharmony_ci    avDemuxerDemo->CreateWithSource(av_source);
173da853ecaSopenharmony_ci    int32_t trackCount = 0;
174da853ecaSopenharmony_ci    int64_t duration = 0;
175da853ecaSopenharmony_ci    OH_AVFormat *oh_avformat = avSourceDemo->GetSourceFormat();
176da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_avformat, OH_MD_KEY_TRACK_COUNT, &trackCount); // 北向获取sourceformat
177da853ecaSopenharmony_ci    OH_AVFormat_GetLongValue(oh_avformat, OH_MD_KEY_DURATION, &duration);
178da853ecaSopenharmony_ci    printf("====>total tracks:%d duration:%" PRId64 "\n", trackCount, duration);
179da853ecaSopenharmony_ci    for (int32_t i = 0; i < trackCount; i++) {
180da853ecaSopenharmony_ci        OH_AVFormat *oh_trackformat = avSourceDemo->GetTrackFormat(i);
181da853ecaSopenharmony_ci        ShowSourceDescription(oh_trackformat);
182da853ecaSopenharmony_ci        avDemuxerDemo->SelectTrackByID(i); // 添加轨道
183da853ecaSopenharmony_ci    }
184da853ecaSopenharmony_ci    uint32_t buffersize = 10 * 1024 * 1024;
185da853ecaSopenharmony_ci    OH_AVMemory *sampleMem = OH_AVMemory_Create(buffersize); // 创建memory
186da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
187da853ecaSopenharmony_ci    TestNativeSeek(sampleMem, trackCount, avDemuxerDemo);
188da853ecaSopenharmony_ci    OH_AVMemory_Destroy(sampleMem);
189da853ecaSopenharmony_ci    OH_AVFormat_Destroy(oh_avformat);
190da853ecaSopenharmony_ci    avDemuxerDemo->Destroy();
191da853ecaSopenharmony_ci    avSourceDemo->Destroy();
192da853ecaSopenharmony_ci    if (fileMode == "0" && fd > 0) {
193da853ecaSopenharmony_ci        close(fd);
194da853ecaSopenharmony_ci    }
195da853ecaSopenharmony_ci}
196da853ecaSopenharmony_ci
197da853ecaSopenharmony_cistatic void RunDrmNativeDemuxer(const std::string &filePath, const std::string &fileMode)
198da853ecaSopenharmony_ci{
199da853ecaSopenharmony_ci    auto avSourceDemo = std::make_shared<AVSourceDemo>();
200da853ecaSopenharmony_ci    int32_t fd = -1;
201da853ecaSopenharmony_ci    if (fileMode == "0") {
202da853ecaSopenharmony_ci        fd = open(filePath.c_str(), O_RDONLY);
203da853ecaSopenharmony_ci        if (fd < 0) {
204da853ecaSopenharmony_ci            printf("open file failed\n");
205da853ecaSopenharmony_ci            return;
206da853ecaSopenharmony_ci        }
207da853ecaSopenharmony_ci        size_t filesize = avSourceDemo->GetFileSize(filePath);
208da853ecaSopenharmony_ci        avSourceDemo->CreateWithFD(fd, 0, filesize);
209da853ecaSopenharmony_ci    } else if (fileMode == "1") {
210da853ecaSopenharmony_ci        avSourceDemo->CreateWithURI((char *)(filePath.c_str()));
211da853ecaSopenharmony_ci    }
212da853ecaSopenharmony_ci    auto avDemuxerDemo = std::make_shared<AVDemuxerDemo>();
213da853ecaSopenharmony_ci    OH_AVSource *av_source = avSourceDemo->GetAVSource();
214da853ecaSopenharmony_ci    avDemuxerDemo->CreateWithSource(av_source);
215da853ecaSopenharmony_ci
216da853ecaSopenharmony_ci    // test drm event callback
217da853ecaSopenharmony_ci    avDemuxerDemo->SetDrmAppCallback();
218da853ecaSopenharmony_ci
219da853ecaSopenharmony_ci    int32_t trackCount = 0;
220da853ecaSopenharmony_ci    int64_t duration = 0;
221da853ecaSopenharmony_ci    OH_AVFormat *oh_avformat = avSourceDemo->GetSourceFormat();
222da853ecaSopenharmony_ci    OH_AVFormat_GetIntValue(oh_avformat, OH_MD_KEY_TRACK_COUNT, &trackCount); // 北向获取sourceformat
223da853ecaSopenharmony_ci    OH_AVFormat_GetLongValue(oh_avformat, OH_MD_KEY_DURATION, &duration);
224da853ecaSopenharmony_ci    printf("====>total tracks:%d duration:%" PRId64 "\n", trackCount, duration);
225da853ecaSopenharmony_ci    for (int32_t i = 0; i < trackCount; i++) {
226da853ecaSopenharmony_ci        avDemuxerDemo->SelectTrackByID(i); // 添加轨道
227da853ecaSopenharmony_ci    }
228da853ecaSopenharmony_ci    uint32_t buffersize = 10 * 1024 * 1024;
229da853ecaSopenharmony_ci    OH_AVMemory *sampleMem = OH_AVMemory_Create(buffersize); // 创建memory
230da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
231da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_MODE_NEXT_SYNC\n");
232da853ecaSopenharmony_ci    avDemuxerDemo->SeekToTime(g_seekTime, OH_AVSeekMode::SEEK_MODE_NEXT_SYNC); // 测试seek功能
233da853ecaSopenharmony_ci    avDemuxerDemo->ReadAllSamples(sampleMem, trackCount);
234da853ecaSopenharmony_ci
235da853ecaSopenharmony_ci    // test drm GetMediaKeySystemInfos
236da853ecaSopenharmony_ci    avDemuxerDemo->GetMediaKeySystemInfo();
237da853ecaSopenharmony_ci
238da853ecaSopenharmony_ci    OH_AVMemory_Destroy(sampleMem);
239da853ecaSopenharmony_ci    OH_AVFormat_Destroy(oh_avformat);
240da853ecaSopenharmony_ci    avDemuxerDemo->Destroy();
241da853ecaSopenharmony_ci    avSourceDemo->Destroy();
242da853ecaSopenharmony_ci    if (fileMode == "0" && fd > 0) {
243da853ecaSopenharmony_ci        close(fd);
244da853ecaSopenharmony_ci    }
245da853ecaSopenharmony_ci}
246da853ecaSopenharmony_ci
247da853ecaSopenharmony_cistatic void ConvertPtsFrameIndexDemo(std::shared_ptr<InnerDemuxerDemo> innerDemuxerDemo)
248da853ecaSopenharmony_ci{
249da853ecaSopenharmony_ci    uint32_t trackIndex = 0;
250da853ecaSopenharmony_ci    uint64_t relativePresentationTimeUs = 0;    // pts 0
251da853ecaSopenharmony_ci
252da853ecaSopenharmony_ci    using clock = std::chrono::high_resolution_clock;
253da853ecaSopenharmony_ci    auto start = clock::now();
254da853ecaSopenharmony_ci    auto end = clock::now();
255da853ecaSopenharmony_ci    std::chrono::duration<double> elapsed = end - start;
256da853ecaSopenharmony_ci
257da853ecaSopenharmony_ci    for (uint32_t index = 0; index < 10 ; ++index) { // get first 10 frames
258da853ecaSopenharmony_ci        start = clock::now();
259da853ecaSopenharmony_ci        int32_t ret = innerDemuxerDemo->GetRelativePresentationTimeUsByIndex(trackIndex,
260da853ecaSopenharmony_ci                                                                             index, relativePresentationTimeUs);
261da853ecaSopenharmony_ci        if (ret != 0) {
262da853ecaSopenharmony_ci            break;
263da853ecaSopenharmony_ci        }
264da853ecaSopenharmony_ci        end = clock::now();
265da853ecaSopenharmony_ci        elapsed = end - start;
266da853ecaSopenharmony_ci        printf("GetRelativePresentationTimeUsByIndex, relativePresentationTimeUs = %" PRId64 "\n",
267da853ecaSopenharmony_ci            relativePresentationTimeUs);
268da853ecaSopenharmony_ci        printf("Function took %f seconds to run.\n", elapsed.count());
269da853ecaSopenharmony_ci
270da853ecaSopenharmony_ci        start = clock::now();
271da853ecaSopenharmony_ci        ret = innerDemuxerDemo->GetIndexByRelativePresentationTimeUs(trackIndex, relativePresentationTimeUs, index);
272da853ecaSopenharmony_ci        if (ret != 0) {
273da853ecaSopenharmony_ci            break;
274da853ecaSopenharmony_ci        }
275da853ecaSopenharmony_ci        end = clock::now();
276da853ecaSopenharmony_ci        elapsed = end - start;
277da853ecaSopenharmony_ci        printf("GetIndexByRelativePresentationTimeUs, index = %u\n", index);
278da853ecaSopenharmony_ci        printf("Function took %f seconds to run.\n", elapsed.count());
279da853ecaSopenharmony_ci    }
280da853ecaSopenharmony_ci}
281da853ecaSopenharmony_ci
282da853ecaSopenharmony_cistatic void RunInnerSourceDemuxer(const std::string &filePath, const std::string &fileMode)
283da853ecaSopenharmony_ci{
284da853ecaSopenharmony_ci    auto innerSourceDemo = std::make_shared<InnerSourceDemo>();
285da853ecaSopenharmony_ci    int32_t fd = -1;
286da853ecaSopenharmony_ci    if (fileMode == "0") {
287da853ecaSopenharmony_ci        fd = open(filePath.c_str(), O_RDONLY);
288da853ecaSopenharmony_ci        if (fd < 0) {
289da853ecaSopenharmony_ci            printf("open file failed\n");
290da853ecaSopenharmony_ci            return;
291da853ecaSopenharmony_ci        }
292da853ecaSopenharmony_ci        size_t filesize = innerSourceDemo->GetFileSize(filePath);
293da853ecaSopenharmony_ci        innerSourceDemo->CreateWithFD(fd, 0, filesize);
294da853ecaSopenharmony_ci    } else if (fileMode == "1") {
295da853ecaSopenharmony_ci        innerSourceDemo->CreateWithURI(filePath);
296da853ecaSopenharmony_ci    }
297da853ecaSopenharmony_ci    auto innerDemuxerDemo = std::make_shared<InnerDemuxerDemo>();
298da853ecaSopenharmony_ci    innerDemuxerDemo->CreateWithSource(innerSourceDemo->avsource_);
299da853ecaSopenharmony_ci    int32_t trackCount = 0;
300da853ecaSopenharmony_ci    int64_t duration = 0;
301da853ecaSopenharmony_ci    Format source_format = innerSourceDemo->GetSourceFormat();
302da853ecaSopenharmony_ci    source_format.GetIntValue(MediaDescriptionKey::MD_KEY_TRACK_COUNT, trackCount);
303da853ecaSopenharmony_ci    source_format.GetLongValue(MediaDescriptionKey::MD_KEY_DURATION, duration);
304da853ecaSopenharmony_ci    printf("====>duration:%" PRId64 " total tracks:%d\n", duration, trackCount);
305da853ecaSopenharmony_ci    ConvertPtsFrameIndexDemo(innerDemuxerDemo);
306da853ecaSopenharmony_ci    for (int32_t i = 0; i < trackCount; i++) {
307da853ecaSopenharmony_ci        innerDemuxerDemo->SelectTrackByID(i); // 添加轨道
308da853ecaSopenharmony_ci    }
309da853ecaSopenharmony_ci    innerDemuxerDemo->UnselectTrackByID(0); // 去掉轨道
310da853ecaSopenharmony_ci    innerDemuxerDemo->SelectTrackByID(0);
311da853ecaSopenharmony_ci    uint32_t buffersize = 1024 * 1024;
312da853ecaSopenharmony_ci    std::shared_ptr<AVSharedMemoryBase> sharedMemory =
313da853ecaSopenharmony_ci        std::make_shared<AVSharedMemoryBase>(buffersize, AVSharedMemory::FLAGS_READ_WRITE, "userBuffer");
314da853ecaSopenharmony_ci    sharedMemory->Init();
315da853ecaSopenharmony_ci    innerDemuxerDemo->ReadAllSamples(sharedMemory, trackCount); // demuxer run
316da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_NEXT_SYNC\n");
317da853ecaSopenharmony_ci    innerDemuxerDemo->SeekToTime(g_seekTime, SeekMode::SEEK_NEXT_SYNC); // 测试seek功能
318da853ecaSopenharmony_ci    innerDemuxerDemo->ReadAllSamples(sharedMemory, trackCount);
319da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_PREVIOUS_SYNC\n");
320da853ecaSopenharmony_ci    innerDemuxerDemo->SeekToTime(g_seekTime, SeekMode::SEEK_PREVIOUS_SYNC);
321da853ecaSopenharmony_ci    innerDemuxerDemo->ReadAllSamples(sharedMemory, trackCount);
322da853ecaSopenharmony_ci    printf("seek to 1s,mode:SEEK_CLOSEST_SYNC\n");
323da853ecaSopenharmony_ci    innerDemuxerDemo->SeekToTime(g_seekTime, SeekMode::SEEK_CLOSEST_SYNC);
324da853ecaSopenharmony_ci    innerDemuxerDemo->ReadAllSamples(sharedMemory, trackCount);
325da853ecaSopenharmony_ci    printf("seek to 0s,mode:SEEK_CLOSEST_SYNC\n");
326da853ecaSopenharmony_ci    innerDemuxerDemo->SeekToTime(g_startTime, SeekMode::SEEK_CLOSEST_SYNC);
327da853ecaSopenharmony_ci    innerDemuxerDemo->ReadAllSamples(sharedMemory, trackCount);
328da853ecaSopenharmony_ci    innerDemuxerDemo->Destroy();
329da853ecaSopenharmony_ci    if (fileMode == "0" && fd > 0) {
330da853ecaSopenharmony_ci        close(fd);
331da853ecaSopenharmony_ci    }
332da853ecaSopenharmony_ci}
333da853ecaSopenharmony_ci
334da853ecaSopenharmony_cistatic void RunRefParserDemuxer(const std::string &filePath, const std::string &fileMode)
335da853ecaSopenharmony_ci{
336da853ecaSopenharmony_ci    auto innerSourceDemo = std::make_shared<InnerSourceDemo>();
337da853ecaSopenharmony_ci    int32_t fd = open(filePath.c_str(), O_RDONLY);
338da853ecaSopenharmony_ci    if (fd < 0) {
339da853ecaSopenharmony_ci        printf("open file failed\n");
340da853ecaSopenharmony_ci        return;
341da853ecaSopenharmony_ci    }
342da853ecaSopenharmony_ci    innerSourceDemo->CreateWithFD(fd, 0, innerSourceDemo->GetFileSize(filePath));
343da853ecaSopenharmony_ci    auto innerDemuxerDemo = std::make_shared<InnerDemuxerDemo>();
344da853ecaSopenharmony_ci    innerDemuxerDemo->CreateWithSource(innerSourceDemo->avsource_);
345da853ecaSopenharmony_ci    int32_t trackCount = 0;
346da853ecaSopenharmony_ci    int64_t duration = 0;
347da853ecaSopenharmony_ci    Format source_format = innerSourceDemo->GetSourceFormat();
348da853ecaSopenharmony_ci    source_format.GetIntValue(MediaDescriptionKey::MD_KEY_TRACK_COUNT, trackCount);
349da853ecaSopenharmony_ci    source_format.GetLongValue(MediaDescriptionKey::MD_KEY_DURATION, duration);
350da853ecaSopenharmony_ci    printf("====>duration:%" PRId64 " total tracks:%d\n", duration, trackCount);
351da853ecaSopenharmony_ci    int32_t trackType = 0;
352da853ecaSopenharmony_ci    int32_t videoTrackIdx = 0;
353da853ecaSopenharmony_ci    for (int32_t i = 0; i < trackCount; i++) {
354da853ecaSopenharmony_ci        Format trackFormat = innerSourceDemo->GetTrackFormat(i);
355da853ecaSopenharmony_ci        trackFormat.GetIntValue(MediaDescriptionKey::MD_KEY_TRACK_TYPE, trackType);
356da853ecaSopenharmony_ci        if (trackType == 1) {                     // 视频轨道
357da853ecaSopenharmony_ci            innerDemuxerDemo->SelectTrackByID(i); // 添加轨道
358da853ecaSopenharmony_ci            videoTrackIdx = i;
359da853ecaSopenharmony_ci        }
360da853ecaSopenharmony_ci    }
361da853ecaSopenharmony_ci    uint32_t buffersize = 1024 * 1024;
362da853ecaSopenharmony_ci    std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
363da853ecaSopenharmony_ci    std::shared_ptr<OHOS::Media::AVBuffer> avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
364da853ecaSopenharmony_ci    innerDemuxerDemo->StartReferenceParser(0);
365da853ecaSopenharmony_ci    FrameLayerInfo frameLayerInfo;
366da853ecaSopenharmony_ci    bool isEosFlag = true;
367da853ecaSopenharmony_ci    while (isEosFlag) {
368da853ecaSopenharmony_ci        innerDemuxerDemo->ReadSampleBuffer(videoTrackIdx, avBuffer);
369da853ecaSopenharmony_ci        if (avBuffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
370da853ecaSopenharmony_ci            cout << "read sample end" << endl;
371da853ecaSopenharmony_ci            isEosFlag = false;
372da853ecaSopenharmony_ci        }
373da853ecaSopenharmony_ci        cout << "size: " << avBuffer->memory_->GetSize() << ",pts: " << avBuffer->pts_ << ", dts: " << avBuffer->dts_
374da853ecaSopenharmony_ci             << endl;
375da853ecaSopenharmony_ci        innerDemuxerDemo->GetFrameLayerInfo(avBuffer, frameLayerInfo);
376da853ecaSopenharmony_ci        cout << "isDiscardable: " << frameLayerInfo.isDiscardable << ", gopId: " << frameLayerInfo.gopId
377da853ecaSopenharmony_ci             << ", layer: " << frameLayerInfo.layer << endl;
378da853ecaSopenharmony_ci    }
379da853ecaSopenharmony_ci    innerDemuxerDemo->Destroy();
380da853ecaSopenharmony_ci    if (fileMode == "0" && fd > 0) {
381da853ecaSopenharmony_ci        close(fd);
382da853ecaSopenharmony_ci        fd = -1;
383da853ecaSopenharmony_ci    }
384da853ecaSopenharmony_ci}
385da853ecaSopenharmony_ci
386da853ecaSopenharmony_cistatic void RunNativeDemuxerLoop(const std::string &filePath, const std::string &fileMode)
387da853ecaSopenharmony_ci{
388da853ecaSopenharmony_ci    time_t startTime = 0;
389da853ecaSopenharmony_ci    time_t curTime = 0;
390da853ecaSopenharmony_ci    (void)time(&startTime);
391da853ecaSopenharmony_ci    (void)time(&curTime);
392da853ecaSopenharmony_ci    while (difftime(curTime, startTime) < g_loopTime) {
393da853ecaSopenharmony_ci        RunNativeDemuxer(filePath, fileMode);
394da853ecaSopenharmony_ci        (void)time(&curTime);
395da853ecaSopenharmony_ci    }
396da853ecaSopenharmony_ci    return;
397da853ecaSopenharmony_ci}
398da853ecaSopenharmony_ci
399da853ecaSopenharmony_cistatic void RunInnerSourceDemuxerLoop(const std::string &filePath, const std::string &fileMode)
400da853ecaSopenharmony_ci{
401da853ecaSopenharmony_ci    time_t startTime = 0;
402da853ecaSopenharmony_ci    time_t curTime = 0;
403da853ecaSopenharmony_ci    (void)time(&startTime);
404da853ecaSopenharmony_ci    (void)time(&curTime);
405da853ecaSopenharmony_ci    while (difftime(curTime, startTime) < g_loopTime) {
406da853ecaSopenharmony_ci        RunInnerSourceDemuxer(filePath, fileMode);
407da853ecaSopenharmony_ci        (void)time(&curTime);
408da853ecaSopenharmony_ci    }
409da853ecaSopenharmony_ci    return;
410da853ecaSopenharmony_ci}
411da853ecaSopenharmony_ci
412da853ecaSopenharmony_cistatic void RunNativeDemuxerMulti(const std::string &filePath, const std::string &fileMode)
413da853ecaSopenharmony_ci{
414da853ecaSopenharmony_ci    vector<thread> vecThread;
415da853ecaSopenharmony_ci    for (uint32_t i = 0; i < g_maxThreadNum; ++i) {
416da853ecaSopenharmony_ci        vecThread.emplace_back(RunNativeDemuxerLoop, filePath, fileMode);
417da853ecaSopenharmony_ci    }
418da853ecaSopenharmony_ci    for (thread &val : vecThread) {
419da853ecaSopenharmony_ci        val.join();
420da853ecaSopenharmony_ci    }
421da853ecaSopenharmony_ci    return;
422da853ecaSopenharmony_ci}
423da853ecaSopenharmony_ci
424da853ecaSopenharmony_cistatic void RunInnerSourceDemuxerMulti(const std::string &filePath, const std::string &fileMode)
425da853ecaSopenharmony_ci{
426da853ecaSopenharmony_ci    vector<thread> vecThread;
427da853ecaSopenharmony_ci    for (uint32_t i = 0; i < g_maxThreadNum; ++i) {
428da853ecaSopenharmony_ci        vecThread.emplace_back(RunInnerSourceDemuxerLoop, filePath, fileMode);
429da853ecaSopenharmony_ci    }
430da853ecaSopenharmony_ci    for (thread &val : vecThread) {
431da853ecaSopenharmony_ci        val.join();
432da853ecaSopenharmony_ci    }
433da853ecaSopenharmony_ci    return;
434da853ecaSopenharmony_ci}
435da853ecaSopenharmony_ci
436da853ecaSopenharmony_cistatic void RunNativeDemuxerAllFormat(const std::string &fileMode)
437da853ecaSopenharmony_ci{
438da853ecaSopenharmony_ci    string pathRoot;
439da853ecaSopenharmony_ci    if (fileMode == "0") {
440da853ecaSopenharmony_ci        pathRoot = "/data/test/media/";
441da853ecaSopenharmony_ci    } else if (fileMode == "1") {
442da853ecaSopenharmony_ci        pathRoot = "http://127.0.0.1:46666/";
443da853ecaSopenharmony_ci    }
444da853ecaSopenharmony_ci    int64_t groupNum = g_filelist.size() / g_maxThreadNum;
445da853ecaSopenharmony_ci    groupNum = (g_loopTime % g_maxThreadNum) == 0 ? groupNum : (groupNum + 1);
446da853ecaSopenharmony_ci    int64_t looptime = g_loopTime / groupNum;
447da853ecaSopenharmony_ci    std::mutex mutexPrint;
448da853ecaSopenharmony_ci    auto loopfunc = [pathRoot, looptime, fileMode, &mutexPrint](uint32_t i) {
449da853ecaSopenharmony_ci        const string filePath = pathRoot + g_filelist[i];
450da853ecaSopenharmony_ci        time_t startTime = 0;
451da853ecaSopenharmony_ci        time_t curTime = 0;
452da853ecaSopenharmony_ci        (void)time(&startTime);
453da853ecaSopenharmony_ci        (void)time(&curTime);
454da853ecaSopenharmony_ci        while (difftime(curTime, startTime) < looptime) {
455da853ecaSopenharmony_ci            RunNativeDemuxer(filePath, fileMode);
456da853ecaSopenharmony_ci            (void)time(&curTime);
457da853ecaSopenharmony_ci        }
458da853ecaSopenharmony_ci        unique_lock<mutex> lock(mutexPrint);
459da853ecaSopenharmony_ci        cout << filePath << " loop done" << endl;
460da853ecaSopenharmony_ci    };
461da853ecaSopenharmony_ci    for (uint32_t index = 0; index < g_filelist.size(); index += g_maxThreadNum) {
462da853ecaSopenharmony_ci        vector<thread> vecThread;
463da853ecaSopenharmony_ci        for (uint32_t i = 0; (i < g_maxThreadNum) && ((index + i) < g_filelist.size()); ++i) {
464da853ecaSopenharmony_ci            vecThread.emplace_back(loopfunc, index + i);
465da853ecaSopenharmony_ci        }
466da853ecaSopenharmony_ci        for (thread &val : vecThread) {
467da853ecaSopenharmony_ci            val.join();
468da853ecaSopenharmony_ci        }
469da853ecaSopenharmony_ci    }
470da853ecaSopenharmony_ci    return;
471da853ecaSopenharmony_ci}
472da853ecaSopenharmony_ci
473da853ecaSopenharmony_civoid PrintPrompt()
474da853ecaSopenharmony_ci{
475da853ecaSopenharmony_ci    cout << "Please select a demuxer demo(default native demuxer demo): " << endl;
476da853ecaSopenharmony_ci    cout << "0:native_demuxer" << endl;
477da853ecaSopenharmony_ci    cout << "1:ffmpeg_demuxer" << endl;
478da853ecaSopenharmony_ci    cout << "2:native_demuxer loop" << endl;
479da853ecaSopenharmony_ci    cout << "3:ffmpeg_demuxer loop" << endl;
480da853ecaSopenharmony_ci    cout << "4:native_demuxer multithread" << endl;
481da853ecaSopenharmony_ci    cout << "5:ffmpeg_demuxer multithread" << endl;
482da853ecaSopenharmony_ci    cout << "6:native_demuxer all format" << endl;
483da853ecaSopenharmony_ci    cout << "7:native_demuxer drm test" << endl;
484da853ecaSopenharmony_ci    cout << "8:ffmpeg_demuxe ref test" << endl;
485da853ecaSopenharmony_ci}
486da853ecaSopenharmony_ci
487da853ecaSopenharmony_civoid AVSourceDemuxerDemoCase(void)
488da853ecaSopenharmony_ci{
489da853ecaSopenharmony_ci    PrintPrompt();
490da853ecaSopenharmony_ci    string mode;
491da853ecaSopenharmony_ci    string fileMode;
492da853ecaSopenharmony_ci    string filePath;
493da853ecaSopenharmony_ci    std::unique_ptr<FileServerDemo> server = nullptr;
494da853ecaSopenharmony_ci    (void)getline(cin, mode);
495da853ecaSopenharmony_ci    cout << "Please select file path (0) or uri (1) or dataSource (2)" << endl;
496da853ecaSopenharmony_ci    (void)getline(cin, fileMode);
497da853ecaSopenharmony_ci    if (fileMode == "1") {
498da853ecaSopenharmony_ci        server = std::make_unique<FileServerDemo>();
499da853ecaSopenharmony_ci        server->StartServer();
500da853ecaSopenharmony_ci    }
501da853ecaSopenharmony_ci    if (mode != "6") {
502da853ecaSopenharmony_ci        cout << "Please input file path or uri:" << endl;
503da853ecaSopenharmony_ci        (void)getline(cin, filePath);
504da853ecaSopenharmony_ci    }
505da853ecaSopenharmony_ci    if (mode >= "2" && mode <= "6") {
506da853ecaSopenharmony_ci        cout << "Please set the time spent:" << endl;
507da853ecaSopenharmony_ci        cin >> g_loopTime;
508da853ecaSopenharmony_ci    }
509da853ecaSopenharmony_ci    if (mode == "0" || mode == "") {
510da853ecaSopenharmony_ci        RunNativeDemuxer(filePath, fileMode);
511da853ecaSopenharmony_ci    } else if (mode == "1") {
512da853ecaSopenharmony_ci        RunInnerSourceDemuxer(filePath, fileMode);
513da853ecaSopenharmony_ci    } else if (mode == "2") {
514da853ecaSopenharmony_ci        RunNativeDemuxerLoop(filePath, fileMode);
515da853ecaSopenharmony_ci    } else if (mode == "3") {
516da853ecaSopenharmony_ci        RunInnerSourceDemuxerLoop(filePath, fileMode);
517da853ecaSopenharmony_ci    } else if (mode == "4") {
518da853ecaSopenharmony_ci        RunNativeDemuxerMulti(filePath, fileMode);
519da853ecaSopenharmony_ci    } else if (mode == "5") {
520da853ecaSopenharmony_ci        RunInnerSourceDemuxerMulti(filePath, fileMode);
521da853ecaSopenharmony_ci    } else if (mode == "6") {
522da853ecaSopenharmony_ci        RunNativeDemuxerAllFormat(fileMode);
523da853ecaSopenharmony_ci    } else if (mode == "7") {
524da853ecaSopenharmony_ci        RunDrmNativeDemuxer(filePath, fileMode);
525da853ecaSopenharmony_ci    } else if (mode == "8") {
526da853ecaSopenharmony_ci        if (fileMode == "0") {
527da853ecaSopenharmony_ci            RunRefParserDemuxer(filePath, fileMode);
528da853ecaSopenharmony_ci            return;
529da853ecaSopenharmony_ci        }
530da853ecaSopenharmony_ci        printf("only support local file\n");
531da853ecaSopenharmony_ci    } else {
532da853ecaSopenharmony_ci        printf("select 0 or 1\n");
533da853ecaSopenharmony_ci    }
534da853ecaSopenharmony_ci    if (fileMode == "1") {
535da853ecaSopenharmony_ci        server->StopServer();
536da853ecaSopenharmony_ci    }
537da853ecaSopenharmony_ci}
538