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 "wm/window.h"
28 #include "wm/window_scene.h"
29
30 #include "include/core/SkCanvas.h"
31 #include "include/core/SkImageInfo.h"
32 #include "transaction/rs_transaction.h"
33 #include "ui/rs_root_node.h"
34 #include "ui/rs_display_node.h"
35 #include "ui/rs_surface_node.h"
36 #include "ui/rs_surface_extractor.h"
37 #include "ui/rs_ui_director.h"
38
39 #include "media_callback.h"
40
41 #include "player.h"
42 #include "nocopyable.h"
43 #include "media_data_source.h"
44
45 const char* SURFACE_STRIDE_ALIGNMENT = "8";
46 constexpr int32_t SURFACE_QUEUE_SIZE = 3;
47
48 using namespace OHOS;
49 using namespace OHOS::Rosen;
50 using namespace std;
51
52 std::map<std::string, std::function<int32_t()>> playerTable;
53
54 // If you want compile this demo, please add
55 // "//foundation/graphic/graphic_2d/rosen/modules/render_service_client/test:render_service_client_surface_node_demo",
56 // to bundle.json.
57 // and add "multimedia_player_framework:media_client" to external_deps in BUILD.gn.
58 // Attention: Before use this demo, please push any mp4 file which must be renamed "H264_Main.mp4" to /data,
59 // otherwise the demo would stop unnormally.
60
RegisterTable(std::shared_ptr<OHOS::Media::Player> player)61 void RegisterTable(std::shared_ptr<OHOS::Media::Player> player)
62 {
63 (void)playerTable.emplace("prepare", std::bind(&OHOS::Media::Player::Prepare, player));
64 (void)playerTable.emplace("prepareasync", std::bind(&OHOS::Media::Player::PrepareAsync, player));
65 (void)playerTable.emplace("", std::bind(&OHOS::Media::Player::Play, player)); // ENTER -> play
66 (void)playerTable.emplace("play", std::bind(&OHOS::Media::Player::Play, player));
67 (void)playerTable.emplace("pause", std::bind(&OHOS::Media::Player::Pause, player));
68 (void)playerTable.emplace("stop", std::bind(&OHOS::Media::Player::Stop, player));
69 (void)playerTable.emplace("reset", std::bind(&OHOS::Media::Player::Reset, player));
70 (void)playerTable.emplace("release", std::bind(&OHOS::Media::Player::Release, player));
71 }
72
DoNext()73 void DoNext()
74 {
75 cout << "Enter your step:" << endl;
76 std::string cmd;
77 while (std::getline(std::cin, cmd)) {
78 auto iter = playerTable.find(cmd);
79 if (iter != playerTable.end()) {
80 auto func = iter->second;
81 if (func() != 0) {
82 cout << "Operation error" << endl;
83 }
84 continue;
85 } else if (cmd.find("quit") != std::string::npos || cmd == "q") {
86 break;
87 }
88 }
89 }
90
91
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)92 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
93 {
94 std::cout << "rs SurfaceNode demo Init Rosen Backend!" << std::endl;
95
96 if (!rsUiDirector) {
97 return;
98 }
99 rsUiDirector->Init();
100 std::cout << "Init Rosen Backend" << std::endl;
101
102 auto rootNode = RSRootNode::Create();
103 cout << "RootNode id = " << rootNode->GetId() << endl;
104 rootNode->SetFrame(0, 0, width, height);
105 rootNode->SetBackgroundColor(SK_ColorWHITE);
106 rsUiDirector->SetRoot(rootNode->GetId());
107
108 auto canvasNode = RSCanvasNode::Create();
109 cout << "canvasNode id = " << canvasNode->GetId() << endl;
110 // SetFrame also can be (100, 100, 960, 1000)
111 canvasNode->SetFrame(10, 10, 100, 100);
112 canvasNode->SetBackgroundColor(SK_ColorRED);
113 rootNode->AddChild(canvasNode, -1);
114
115 struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
116
117 // Create surfaceView node
118 auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig, false);
119
120 // Create abilityView node
121 // "auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig);"
122 // "surfaceNode->CreateNodeInRenderThread();"
123
124 cout << "surfaceNode id = " << surfaceNode->GetId() << endl;
125 // SetBounds also can be (300, 300, 960, 540);
126 surfaceNode->SetBounds(30, 30, 512, 256);
127 surfaceNode->SetBufferAvailableCallback([]() {
128 cout << "SetBufferAvailableCallback" << endl;
129 });
130
131 canvasNode->AddChild(surfaceNode, -1);
132 rsUiDirector->SendMessages();
133 auto player = OHOS::Media::PlayerFactory::CreatePlayer();
134 if (player == nullptr) {
135 cout << "player is null" << endl;
136 return;
137 }
138 RegisterTable(player);
139 std::shared_ptr<OHOS::Ace::MediaCallback> cb = std::make_shared<OHOS::Ace::MediaCallback>();
140 int32_t media_ret = -1;
141 media_ret = player->SetPlayerCallback(cb);
142 if (media_ret != 0) {
143 cout << "SetPlayerCallback fail" << endl;
144 }
145 // Use Local file source here
146 // path is /data/H264_Main.mp4
147 media_ret = player->SetSource("/data/H264_Main.mp4");
148 if (media_ret != 0) {
149 cout << "SetSource fail" << endl;
150 return;
151 }
152 sptr<Surface> producerSurface = nullptr;
153 producerSurface = surfaceNode->GetSurface();
154 if (producerSurface != nullptr) {
155 producerSurface->SetQueueSize(SURFACE_QUEUE_SIZE);
156 producerSurface->SetUserData("SURFACE_STRIDE_ALIGNMENT", SURFACE_STRIDE_ALIGNMENT);
157 producerSurface->SetUserData("SURFACE_FORMAT", std::to_string(PIXEL_FMT_RGBA_8888));
158 media_ret = player->SetVideoSurface(producerSurface);
159 if (media_ret != 0) {
160 cout << "SetVideoSurface fail" << endl;
161 }
162 }
163
164 media_ret = player->PrepareAsync();
165 if (media_ret != 0) {
166 cout << "PrepareAsync fail" << endl;
167 return;
168 }
169 DoNext();
170 sleep(10);
171 }
172
main()173 int main()
174 {
175 std::cout << "rs SurfaceNode demo start!" << std::endl;
176
177 sptr<WindowOption> option = new WindowOption();
178 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
179 // SetWindowRect also can be {200, 200, 1501, 1200}
180 option->SetWindowRect({120, 120, 512, 512});
181
182 auto scene = new WindowScene();
183
184 std::shared_ptr<AbilityRuntime::Context> context = nullptr;
185 sptr<IWindowLifeCycle> listener = nullptr;
186 scene->Init(0, context, listener, option);
187 auto window = scene->GetMainWindow();
188 scene->GoForeground();
189
190 auto rect = window->GetRect();
191 std::cout << "rs SurfaceNode demo create window " << rect.width_ << " " << rect.height_ << std::endl;
192 auto windowSurfaceNode = window->GetSurfaceNode();
193 cout << "windowSurfaceNode id = " << windowSurfaceNode->GetId() << endl;
194
195 auto rsUiDirector = RSUIDirector::Create();
196 rsUiDirector->Init();
197 RSTransaction::FlushImplicitTransaction();
198 sleep(1);
199
200 rsUiDirector->SetRSSurfaceNode(windowSurfaceNode);
201 Init(rsUiDirector, rect.width_, rect.height_);
202 std::cout << "rs SurfaceNode demo end!" << std::endl;
203 window->Hide();
204 window->Destroy();
205 return 0;
206 }