1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd.
3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License.
5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at
6fa7767c5Sopenharmony_ci *
7fa7767c5Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fa7767c5Sopenharmony_ci *
9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and
13fa7767c5Sopenharmony_ci * limitations under the License.
14fa7767c5Sopenharmony_ci */
15fa7767c5Sopenharmony_ci#ifdef OHOS_LITE
16fa7767c5Sopenharmony_ci#define HST_LOG_TAG "LiteStreamPlayer"
17fa7767c5Sopenharmony_ci
18fa7767c5Sopenharmony_ci#define LOG_TAG "main"
19fa7767c5Sopenharmony_ci
20fa7767c5Sopenharmony_ci#include <chrono>
21fa7767c5Sopenharmony_ci#include <cstring>
22fa7767c5Sopenharmony_ci#include <cstdio>
23fa7767c5Sopenharmony_ci#include <fstream>
24fa7767c5Sopenharmony_ci#include <iostream>
25fa7767c5Sopenharmony_ci#include <memory>
26fa7767c5Sopenharmony_ci#include <sstream>
27fa7767c5Sopenharmony_ci#include <string>
28fa7767c5Sopenharmony_ci#include <thread>
29fa7767c5Sopenharmony_ci#include <vector>
30fa7767c5Sopenharmony_ci
31fa7767c5Sopenharmony_ci#include "scene/lite/hiplayer.h"
32fa7767c5Sopenharmony_ci#include "securec.h"
33fa7767c5Sopenharmony_ci#include "foundation/log.h"
34fa7767c5Sopenharmony_ci#include "foundation/multimedia/media_utils_lite/interfaces/kits/data_stream.h"
35fa7767c5Sopenharmony_ci#include "foundation/osal/utils/util.h"
36fa7767c5Sopenharmony_ci#include "foundation/osal/thread/task.h"
37fa7767c5Sopenharmony_ci
38fa7767c5Sopenharmony_ciusing namespace OHOS::Media;
39fa7767c5Sopenharmony_ci
40fa7767c5Sopenharmony_ci#define INPUT_BUFFER_SIZE           10 * 1024
41fa7767c5Sopenharmony_ci#define INPUT_BUFFER_ITEM           3
42fa7767c5Sopenharmony_ci
43fa7767c5Sopenharmony_cistatic uint32_t readPos = 0;
44fa7767c5Sopenharmony_cistd::vector<uint32_t> testData;
45fa7767c5Sopenharmony_ciuint32_t testDataSize = 0;
46fa7767c5Sopenharmony_cistd::shared_ptr<DataStream> stream = nullptr;
47fa7767c5Sopenharmony_cistd::shared_ptr<OSAL::Task> task = nullptr;
48fa7767c5Sopenharmony_ci
49fa7767c5Sopenharmony_cienum SourceFlag {
50fa7767c5Sopenharmony_ci    SOURCE_EOS,
51fa7767c5Sopenharmony_ci};
52fa7767c5Sopenharmony_ci
53fa7767c5Sopenharmony_ciuint8_t *GetDataFromSource(int8_t *flag, uint32_t *getDataSize)
54fa7767c5Sopenharmony_ci{
55fa7767c5Sopenharmony_ci    uint32_t inputSize = INPUT_BUFFER_SIZE;
56fa7767c5Sopenharmony_ci    MEDIA_LOG_I("testDataSize:" PUBLIC_LOG_U32 " ,readPos:" PUBLIC_LOG_U32, testDataSize, readPos);
57fa7767c5Sopenharmony_ci    uint8_t *outDataPtr = nullptr;
58fa7767c5Sopenharmony_ci    if (readPos == testDataSize) {
59fa7767c5Sopenharmony_ci        *flag = SOURCE_EOS;
60fa7767c5Sopenharmony_ci        *getDataSize = 0;
61fa7767c5Sopenharmony_ci        return outDataPtr;
62fa7767c5Sopenharmony_ci    }
63fa7767c5Sopenharmony_ci    outDataPtr = reinterpret_cast<uint8_t*>(malloc(inputSize));
64fa7767c5Sopenharmony_ci    auto ret = memset_s(outDataPtr, INPUT_BUFFER_SIZE, 0, inputSize);
65fa7767c5Sopenharmony_ci    FALSE_RETURN(ret == 0);
66fa7767c5Sopenharmony_ci    if (readPos + INPUT_BUFFER_SIZE > testDataSize) {
67fa7767c5Sopenharmony_ci        inputSize = testDataSize - readPos;
68fa7767c5Sopenharmony_ci    }
69fa7767c5Sopenharmony_ci    (void)memcpy_s(outDataPtr, INPUT_BUFFER_SIZE, &testData[0] + readPos / sizeof(uint32_t), inputSize);
70fa7767c5Sopenharmony_ci    readPos += inputSize;
71fa7767c5Sopenharmony_ci    MEDIA_LOG_I("readPo:" PUBLIC_LOG_U32, readPos);
72fa7767c5Sopenharmony_ci    *getDataSize = inputSize;
73fa7767c5Sopenharmony_ci    return outDataPtr;
74fa7767c5Sopenharmony_ci}
75fa7767c5Sopenharmony_ci
76fa7767c5Sopenharmony_cibool g_playFinished = false;
77fa7767c5Sopenharmony_ci
78fa7767c5Sopenharmony_civoid DataProcessThread()
79fa7767c5Sopenharmony_ci{
80fa7767c5Sopenharmony_ci    MEDIA_LOG_I("DataProcessThread in");
81fa7767c5Sopenharmony_ci    while (!g_playFinished) {
82fa7767c5Sopenharmony_ci        int8_t sourceFlag = -1;
83fa7767c5Sopenharmony_ci        uint32_t realGetSize = 0;
84fa7767c5Sopenharmony_ci        uint8_t *sourceData = GetDataFromSource(&sourceFlag, &realGetSize);
85fa7767c5Sopenharmony_ci        std::shared_ptr<DataBuffer> buffer;
86fa7767c5Sopenharmony_ci        (void) stream->GetEmptyBuffer(buffer);
87fa7767c5Sopenharmony_ci        if (buffer == nullptr) {
88fa7767c5Sopenharmony_ci            MEDIA_LOG_E("buffer null error.");
89fa7767c5Sopenharmony_ci            if (sourceData != nullptr) {
90fa7767c5Sopenharmony_ci                free(sourceData);
91fa7767c5Sopenharmony_ci            }
92fa7767c5Sopenharmony_ci            return;
93fa7767c5Sopenharmony_ci        } else {
94fa7767c5Sopenharmony_ci            MEDIA_LOG_I("realGetSize:" PUBLIC_LOG_U32, realGetSize);
95fa7767c5Sopenharmony_ci            if (sourceData != nullptr) { // get data
96fa7767c5Sopenharmony_ci                (void) memcpy_s(buffer->GetAddress(), buffer->GetCapacity(), sourceData, realGetSize);
97fa7767c5Sopenharmony_ci                buffer->SetSize(realGetSize);
98fa7767c5Sopenharmony_ci                free(sourceData);
99fa7767c5Sopenharmony_ci            } else { // not get data, must be eos
100fa7767c5Sopenharmony_ci                buffer->SetSize(0);
101fa7767c5Sopenharmony_ci                FALSE_LOG(sourceFlag == SOURCE_EOS);
102fa7767c5Sopenharmony_ci                MEDIA_LOG_I("SourceEos");
103fa7767c5Sopenharmony_ci                buffer->SetEos(true);
104fa7767c5Sopenharmony_ci                stream->QueueDataBuffer(buffer);
105fa7767c5Sopenharmony_ci                break;
106fa7767c5Sopenharmony_ci            }
107fa7767c5Sopenharmony_ci            stream->QueueDataBuffer(buffer);
108fa7767c5Sopenharmony_ci        }
109fa7767c5Sopenharmony_ci    }
110fa7767c5Sopenharmony_ci    task->StopAsync();
111fa7767c5Sopenharmony_ci}
112fa7767c5Sopenharmony_ci
113fa7767c5Sopenharmony_ciclass PlayerCallbackImpl : public PlayerCallback {
114fa7767c5Sopenharmony_ci    void OnPlaybackComplete() override
115fa7767c5Sopenharmony_ci    {
116fa7767c5Sopenharmony_ci        g_playFinished = true;
117fa7767c5Sopenharmony_ci        MEDIA_LOG_I("OnPlaybackComplete called, g_playFinished is true now.");
118fa7767c5Sopenharmony_ci    }
119fa7767c5Sopenharmony_ci    void OnError(int32_t errorType, int32_t errorCode) override
120fa7767c5Sopenharmony_ci    {
121fa7767c5Sopenharmony_ci    }
122fa7767c5Sopenharmony_ci    void OnInfo(int type, int extra) override
123fa7767c5Sopenharmony_ci    {
124fa7767c5Sopenharmony_ci    }
125fa7767c5Sopenharmony_ci    void OnVideoSizeChanged(int width, int height) override
126fa7767c5Sopenharmony_ci    {
127fa7767c5Sopenharmony_ci    }
128fa7767c5Sopenharmony_ci    void OnRewindToComplete() override
129fa7767c5Sopenharmony_ci    {
130fa7767c5Sopenharmony_ci    }
131fa7767c5Sopenharmony_ci};
132fa7767c5Sopenharmony_ci
133fa7767c5Sopenharmony_ciint ReadDataFromFile(std::string dataPath)
134fa7767c5Sopenharmony_ci{
135fa7767c5Sopenharmony_ci    std::string dataFullPath;
136fa7767c5Sopenharmony_ci    if (OSAL::ConvertFullPath(dataPath, dataFullPath) && !dataFullPath.empty()) {
137fa7767c5Sopenharmony_ci        dataPath = dataFullPath;
138fa7767c5Sopenharmony_ci    }
139fa7767c5Sopenharmony_ci    std::fstream fs(dataPath);
140fa7767c5Sopenharmony_ci    if (!fs.is_open()) {
141fa7767c5Sopenharmony_ci        std::cout << "failed to open " << dataPath << '\n';
142fa7767c5Sopenharmony_ci        return 0;
143fa7767c5Sopenharmony_ci    }
144fa7767c5Sopenharmony_ci    std::stringstream ss;
145fa7767c5Sopenharmony_ci    while (!fs.eof()) {
146fa7767c5Sopenharmony_ci        std::string s;
147fa7767c5Sopenharmony_ci        fs >> s;
148fa7767c5Sopenharmony_ci        ss << s;
149fa7767c5Sopenharmony_ci    }
150fa7767c5Sopenharmony_ci    std::string data = ss.str();
151fa7767c5Sopenharmony_ci    const char* split = ",";
152fa7767c5Sopenharmony_ci    char* s_input = data.c_str();
153fa7767c5Sopenharmony_ci    char* p = strtok(s_input, split);
154fa7767c5Sopenharmony_ci    while (p != nullptr) {
155fa7767c5Sopenharmony_ci        uint32_t dataValue;
156fa7767c5Sopenharmony_ci        auto ret = sscanf_s(p, "%x", &dataValue);
157fa7767c5Sopenharmony_ci        FALSE_LOG_MSG_W(ret == 0, "sscanf_s failed.");
158fa7767c5Sopenharmony_ci        testData.push_back(dataValue);
159fa7767c5Sopenharmony_ci        p=strtok(nullptr, split);
160fa7767c5Sopenharmony_ci    }
161fa7767c5Sopenharmony_ci    return testData.size() * 4; // 4
162fa7767c5Sopenharmony_ci}
163fa7767c5Sopenharmony_ci
164fa7767c5Sopenharmony_ciint StartLiteStreamPlayer(const std::string& dataPath)
165fa7767c5Sopenharmony_ci{
166fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Use media_lite interface player.");
167fa7767c5Sopenharmony_ci    g_playFinished = false;
168fa7767c5Sopenharmony_ci    auto player = OHOS::Media::CreateHiPlayer();
169fa7767c5Sopenharmony_ci    player->Init();
170fa7767c5Sopenharmony_ci    auto callback = std::make_shared<PlayerCallbackImpl>();
171fa7767c5Sopenharmony_ci    player->SetPlayerCallback(callback);
172fa7767c5Sopenharmony_ci    stream = CreateDataStream(INPUT_BUFFER_SIZE, INPUT_BUFFER_ITEM);
173fa7767c5Sopenharmony_ci    if (stream == nullptr) {
174fa7767c5Sopenharmony_ci        MEDIA_LOG_E("Create data stream fail.");
175fa7767c5Sopenharmony_ci        return -1;
176fa7767c5Sopenharmony_ci    }
177fa7767c5Sopenharmony_ci    OHOS::Media::Source source(stream);
178fa7767c5Sopenharmony_ci    player->SetSource(source);
179fa7767c5Sopenharmony_ci    player->SetLoop(false);
180fa7767c5Sopenharmony_ci    testDataSize = ReadDataFromFile(dataPath);
181fa7767c5Sopenharmony_ci    if (!testDataSize) {
182fa7767c5Sopenharmony_ci        MEDIA_LOG_E("Get data size fail.");
183fa7767c5Sopenharmony_ci        return -1;
184fa7767c5Sopenharmony_ci    }
185fa7767c5Sopenharmony_ci    MEDIA_LOG_I("testDataSize:" PUBLIC_LOG_U32, testDataSize);
186fa7767c5Sopenharmony_ci    task = std::make_shared<OSAL::Task>("DataProcessThread");
187fa7767c5Sopenharmony_ci    task->RegisterHandler(DataProcessThread);
188fa7767c5Sopenharmony_ci    task->Start();
189fa7767c5Sopenharmony_ci    player->Prepare();
190fa7767c5Sopenharmony_ci    player->Play();
191fa7767c5Sopenharmony_ci    while (!g_playFinished) {
192fa7767c5Sopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 100
193fa7767c5Sopenharmony_ci        MEDIA_LOG_I("stream player thread running...");
194fa7767c5Sopenharmony_ci    }
195fa7767c5Sopenharmony_ci    readPos = 0;
196fa7767c5Sopenharmony_ci    stream = nullptr;
197fa7767c5Sopenharmony_ci    return 0;
198fa7767c5Sopenharmony_ci}
199fa7767c5Sopenharmony_ci#endif