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