Advertisement
Guest User

Untitled

a guest
Jan 12th, 2023
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.41 KB | None | 0 0
  1. #include <errno.h>
  2.  
  3. #include <unistd.h>
  4.  
  5. #include <stdio.h>
  6.  
  7. #include <fcntl.h>
  8.  
  9. #include <stdlib.h>
  10.  
  11. #include <string.h>
  12.  
  13. #include <linux/fb.h>
  14.  
  15. #include <sys/ioctl.h>
  16.  
  17. #include <sys/mman.h>
  18.  
  19. #include <sys/wait.h>
  20.  
  21. #include <android/bitmap.h>
  22.  
  23. #include <binder/ProcessState.h>
  24.  
  25. #include <gui/ISurfaceComposer.h>
  26.  
  27. #include <gui/SurfaceComposerClient.h>
  28.  
  29. #include <gui/SyncScreenCaptureListener.h>
  30.  
  31. #include <ui/GraphicTypes.h>
  32.  
  33. #include <ui/PixelFormat.h>
  34.  
  35. #include <system/graphics.h>
  36.  
  37. #include <ws.h>
  38.  
  39. using namespace android;
  40.  
  41. static int32_t flinger2bitmapFormat(PixelFormat f) {
  42. switch (f) {
  43. case PIXEL_FORMAT_RGB_565:
  44. return ANDROID_BITMAP_FORMAT_RGB_565;
  45. default:
  46. return ANDROID_BITMAP_FORMAT_RGBA_8888;
  47. }
  48. }
  49.  
  50. void setResolution() {
  51. char const *binaryPath = "/system/bin/wm";
  52. char const *arg1 = "size";
  53. char const *arg2 = "1034x788";
  54.  
  55. pid_t pid;
  56. pid = fork();
  57. if (pid == -1) {
  58. perror("fork failed");
  59. exit(-1);
  60. } else if (pid == 0) {
  61. execlp(binaryPath, binaryPath, arg1, arg2 ,NULL);
  62. perror("execlp failed");
  63. exit(-1);
  64. }
  65. int status;
  66. wait(&status);
  67. printf("child exit status: %d\n", WEXITSTATUS(status));
  68. }
  69.  
  70. void webSocketOnConnectionOpened(ws_cli_conn_t *client) {
  71. char *cli;
  72. cli = ws_getaddress(client);
  73. printf("Connection opened, addr: %s\n", cli);
  74. }
  75.  
  76. void webSocketOnConnectionClosed(ws_cli_conn_t *client) {
  77. char *cli;
  78. cli = ws_getaddress(client);
  79. printf("Connection closed, addr: %s\n", cli);
  80. }
  81.  
  82. void webSocketOnMessage(ws_cli_conn_t *client,
  83. const unsigned char *msg, uint64_t size, int type)
  84. {
  85. char *cli;
  86. cli = ws_getaddress(client);
  87. printf("Message: %s (size: %" PRId64 ", type: %d), from: %s\n",
  88. msg, size, type, cli);
  89. }
  90.  
  91.  
  92. int main(__attribute__((unused)) int argc, __attribute__((unused)) char ** argv) {
  93. std::optional < PhysicalDisplayId > displayId = SurfaceComposerClient::getInternalDisplayId();
  94. if (!displayId) {
  95. fprintf(stderr, "Failed to get token for internal display\n");
  96. return 1;
  97. }
  98.  
  99. setResolution();
  100.  
  101. ProcessState::self() -> setThreadPoolMaxThreadCount(4);
  102. ProcessState::self() -> startThreadPool();
  103.  
  104.  
  105. struct ws_events evs;
  106. evs.onopen = &webSocketOnConnectionOpened;
  107. evs.onclose = &webSocketOnConnectionClosed;
  108. evs.onmessage = &webSocketOnMessage;
  109. ws_socket(&evs, 9090, 1, 1000);
  110.  
  111. while (true) {
  112. void * base = NULL;
  113.  
  114. sp < SyncScreenCaptureListener > captureListener = new SyncScreenCaptureListener();
  115. status_t result = ScreenshotClient::captureDisplay(*displayId, captureListener);
  116. if (result != NO_ERROR) {
  117. continue;
  118. }
  119.  
  120. ScreenCaptureResults captureResults = captureListener -> waitForResults();
  121. if (captureResults.result != NO_ERROR) {
  122. continue;
  123. }
  124. ui::Dataspace dataspace = captureResults.capturedDataspace;
  125. sp < GraphicBuffer > buffer = captureResults.buffer;
  126.  
  127. result = buffer -> lock(GraphicBuffer::USAGE_SW_READ_OFTEN, & base);
  128.  
  129. if (base == nullptr || result != NO_ERROR) {
  130. String8 reason;
  131. if (result != NO_ERROR) {
  132. reason.appendFormat(" Error Code: %d", result);
  133. } else {
  134. reason = "Failed to write to buffer";
  135. }
  136. fprintf(stderr, "Failed to take screenshot (%s)\n", reason.c_str());
  137. continue;
  138. }
  139.  
  140. AndroidBitmapInfo info;
  141. info.format = flinger2bitmapFormat(buffer -> getPixelFormat());
  142. info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
  143. info.width = buffer -> getWidth();
  144. info.height = buffer -> getHeight();
  145. info.stride = buffer -> getStride() * bytesPerPixel(buffer -> getPixelFormat());
  146.  
  147. std::string buff = "";
  148.  
  149. int compressionResult = AndroidBitmap_compress( & info, static_cast < int32_t > (dataspace), base,
  150. ANDROID_BITMAP_COMPRESS_FORMAT_JPEG, 80, & buff,
  151. [](void * fdPtr,
  152. const void * data, size_t size) -> bool {
  153. std::string * castedBuffer = (std::string * ) fdPtr;
  154. castedBuffer -> append((char * ) data, size);
  155. return true;
  156. });
  157.  
  158. if (compressionResult != ANDROID_BITMAP_RESULT_SUCCESS) {
  159. fprintf(stderr, "Failed to compress JPEG (error code: %d)\n", compressionResult);
  160. continue;
  161. }
  162.  
  163. ws_sendframe_bin(NULL, buff.c_str(), buff.length());
  164. //streamer.publish("/stream", buff);
  165. }
  166.  
  167. return 0;
  168. }
  169.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement