1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <iostream>
17 #include <surface.h>
18 #include <cinttypes>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <fstream>
22 #include <memory>
23 #include <securec.h>
24 #include <sstream>
25 #include <unistd.h>
26
27 #include "window.h"
28 #include "window_scene.h"
29
30 #include "transaction/rs_transaction.h"
31 #include "ui/rs_root_node.h"
32 #include "ui/rs_display_node.h"
33 #include "ui/rs_surface_node.h"
34 #include "ui/rs_surface_extractor.h"
35 #include "ui/rs_ui_director.h"
36
37 #include "media_callback.h"
38
39 #include "player.h"
40 #include "nocopyable.h"
41 #include "media_data_source.h"
42
43 const char* SURFACE_STRIDE_ALIGNMENT = "8";
44 constexpr int32_t SURFACE_QUEUE_SIZE = 3;
45
46 using namespace OHOS;
47 using namespace OHOS::Rosen;
48 using namespace std;
49
50 std::map<std::string, std::function<int32_t()>> playerTable;
51
52 // If you want compile this demo, please add
53 // "//foundation/graphic/graphic_2d/rosen/modules/render_service_client/test:render_service_client_surface_node_demo",
54 // to bundle.json.
55 // and add "multimedia_player_framework:media_client" to external_deps in BUILD.gn.
56 // Attention: Before use this demo, please push any mp4 file which must be renamed "H264_Main.mp4" to /data,
57 // otherwise the demo would stop unnormally.
58
RegisterTable(std::shared_ptr<OHOS::Media::Player> player)59 void RegisterTable(std::shared_ptr<OHOS::Media::Player> player)
60 {
61 (void)playerTable.emplace("prepare", std::bind(&OHOS::Media::Player::Prepare, player));
62 (void)playerTable.emplace("prepareasync", std::bind(&OHOS::Media::Player::PrepareAsync, player));
63 (void)playerTable.emplace("", std::bind(&OHOS::Media::Player::Play, player)); // ENTER -> play
64 (void)playerTable.emplace("play", std::bind(&OHOS::Media::Player::Play, player));
65 (void)playerTable.emplace("pause", std::bind(&OHOS::Media::Player::Pause, player));
66 (void)playerTable.emplace("stop", std::bind(&OHOS::Media::Player::Stop, player));
67 (void)playerTable.emplace("reset", std::bind(&OHOS::Media::Player::Reset, player));
68 (void)playerTable.emplace("release", std::bind(&OHOS::Media::Player::Release, player));
69 }
70
DoNext()71 void DoNext()
72 {
73 cout << "Enter your step:" << endl;
74 std::string cmd;
75 while (std::getline(std::cin, cmd)) {
76 auto iter = playerTable.find(cmd);
77 if (iter != playerTable.end()) {
78 auto func = iter->second;
79 if (func() != 0) {
80 cout << "Operation error" << endl;
81 }
82 continue;
83 } else if (cmd.find("quit") != std::string::npos || cmd == "q") {
84 break;
85 }
86 }
87 }
88
89
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)90 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
91 {
92 std::cout << "rs SurfaceNode demo Init Rosen Backend!" << std::endl;
93
94 if (!rsUiDirector) {
95 return;
96 }
97 rsUiDirector->Init();
98 std::cout << "Init Rosen Backend" << std::endl;
99
100 auto rootNode = RSRootNode::Create();
101 cout << "RootNode id = " << rootNode->GetId() << endl;
102 rootNode->SetFrame(0, 0, width, height);
103 rootNode->SetBackgroundColor(Drawing::Color::COLOR_WHITE);
104 rsUiDirector->SetRoot(rootNode->GetId());
105
106 auto canvasNode = RSCanvasNode::Create();
107 cout << "canvasNode id = " << canvasNode->GetId() << endl;
108 // SetFrame also can be (100, 100, 960, 1000)
109 canvasNode->SetFrame(10, 10, 100, 100);
110 rootNode->SetBackgroundColor(Drawing::Color::COLOR_RED);
111 rootNode->AddChild(canvasNode, -1);
112
113 struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
114
115 // Create surfaceView node
116 auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig, false);
117
118 // Create abilityView node
119 // "auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig);"
120 // "surfaceNode->CreateNodeInRenderThread();"
121
122 cout << "surfaceNode id = " << surfaceNode->GetId() << endl;
123 // SetBounds also can be (300, 300, 960, 540);
124 surfaceNode->SetBounds(30, 30, 512, 256);
125 surfaceNode->SetBufferAvailableCallback([]() {
126 cout << "SetBufferAvailableCallback" << endl;
127 });
128
129 canvasNode->AddChild(surfaceNode, -1);
130 rsUiDirector->SendMessages();
131 auto player = OHOS::Media::PlayerFactory::CreatePlayer();
132 if (player == nullptr) {
133 cout << "player is null" << endl;
134 return;
135 }
136 RegisterTable(player);
137 std::shared_ptr<OHOS::Ace::MediaCallback> cb = std::make_shared<OHOS::Ace::MediaCallback>();
138 int32_t media_ret = -1;
139 media_ret = player->SetPlayerCallback(cb);
140 if (media_ret != 0) {
141 cout << "SetPlayerCallback fail" << endl;
142 }
143 // Use Local file source here
144 // path is /data/H264_Main.mp4
145 media_ret = player->SetSource("/data/H264_Main.mp4");
146 if (media_ret != 0) {
147 cout << "SetSource fail" << endl;
148 return;
149 }
150 sptr<Surface> producerSurface = nullptr;
151 producerSurface = surfaceNode->GetSurface();
152 if (producerSurface != nullptr) {
153 producerSurface->SetQueueSize(SURFACE_QUEUE_SIZE);
154 producerSurface->SetUserData("SURFACE_STRIDE_ALIGNMENT", SURFACE_STRIDE_ALIGNMENT);
155 producerSurface->SetUserData("SURFACE_FORMAT", std::to_string(GRAPHIC_PIXEL_FMT_RGBA_8888));
156 media_ret = player->SetVideoSurface(producerSurface);
157 if (media_ret != 0) {
158 cout << "SetVideoSurface fail" << endl;
159 }
160 }
161
162 media_ret = player->PrepareAsync();
163 if (media_ret != 0) {
164 cout << "PrepareAsync fail" << endl;
165 return;
166 }
167 DoNext();
168 sleep(10);
169 }
170
main()171 int main()
172 {
173 std::cout << "rs SurfaceNode demo start!" << std::endl;
174
175 sptr<WindowOption> option = new WindowOption();
176 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
177 // SetWindowRect also can be {200, 200, 1501, 1200}
178 option->SetWindowRect({120, 120, 512, 512});
179
180 auto scene = new WindowScene();
181
182 std::shared_ptr<AbilityRuntime::Context> context = nullptr;
183 sptr<IWindowLifeCycle> listener = nullptr;
184 scene->Init(0, context, listener, option);
185 auto window = scene->GetMainWindow();
186 scene->GoForeground();
187
188 auto rect = window->GetRect();
189 std::cout << "rs SurfaceNode demo create window " << rect.width_ << " " << rect.height_ << std::endl;
190 auto windowSurfaceNode = window->GetSurfaceNode();
191 cout << "windowSurfaceNode id = " << windowSurfaceNode->GetId() << endl;
192
193 auto rsUiDirector = RSUIDirector::Create();
194 rsUiDirector->Init();
195 RSTransaction::FlushImplicitTransaction();
196 sleep(1);
197
198 rsUiDirector->SetRSSurfaceNode(windowSurfaceNode);
199 Init(rsUiDirector, rect.width_, rect.height_);
200 std::cout << "rs SurfaceNode demo end!" << std::endl;
201 window->Hide();
202 window->Destroy();
203 return 0;
204 }