Advertisement
Guest User

Untitled

a guest
Jan 12th, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.73 KB | None | 0 0
  1. /*
  2. * boblight
  3. * Copyright (C) Bob 2009
  4. *
  5. * boblight is free software: you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * boblight is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. #define BOBLIGHT_DLOPEN
  20. #include "lib/boblight.h"
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #include <signal.h>
  27.  
  28. #include <fcntl.h>
  29. #include <errno.h>
  30. #include <sys/stat.h>
  31. #include <sys/poll.h>
  32. #include <sys/types.h>
  33. #include <sys/time.h>
  34. #include <sys/ioctl.h>
  35.  
  36. #include "config.h"
  37. #include "util/misc.h"
  38. #include "util/timeutils.h"
  39. #include "flagmanager-aml.h"
  40.  
  41. using namespace std;
  42.  
  43. //#include <linux/pivos/aml_snapshot.h>
  44.  
  45. //from linux/amlogic/amports/amvideocap.h
  46. #define AMVIDEOCAP_IOC_MAGIC 'V'
  47. #define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int)
  48. #define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int)
  49.  
  50.  
  51. struct aml_snapshot_t {
  52. unsigned int dst_width;
  53. unsigned int dst_height;
  54. unsigned int dst_stride;
  55. unsigned int dst_size;
  56. void *dst_vaddr;
  57. };
  58.  
  59. volatile bool g_stop = false;
  60. CFlagManagerAML g_flagmanager;
  61. /*********************************************************
  62. *********************************************************/
  63. static void SignalHandler(int signum)
  64. {
  65. if (signum == SIGTERM)
  66. {
  67. fprintf(stderr, "caught SIGTERM\n");
  68. g_stop = true;
  69. }
  70. else if (signum == SIGINT)
  71. {
  72. fprintf(stderr, "caught SIGTERM\n");
  73. g_stop = true;
  74. }
  75. }
  76.  
  77. #define VIDEO_PATH "/dev/amvideo"
  78. #define CAPTURE_PATH "/dev/amvideocap0"
  79. #define AMSTREAM_IOC_MAGIC 'S'
  80. #define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR(AMSTREAM_IOC_MAGIC, 0x48, unsigned long)
  81. static int amvideo_utils_video_playing()
  82. {
  83. int video_fd;
  84. int axis[4], video_disable;
  85.  
  86. video_fd = open(VIDEO_PATH, O_RDWR);
  87. if (video_fd < 0) {
  88. return -1;
  89. }
  90.  
  91. ioctl(video_fd, AMSTREAM_IOC_GET_VIDEO_DISABLE, &video_disable);
  92. if (video_disable)
  93. {
  94. close(video_fd);
  95. return 1;
  96. }
  97.  
  98. close(video_fd);
  99.  
  100. // fprintf(stderr, "pos x %d y %d w %d h %d\n",snapshot.src_x, snapshot.src_y,snapshot.src_width,snapshot.src_height);
  101. return 0;
  102. }
  103.  
  104. static int capture_frame(int fd, aml_snapshot_t &snapshot)
  105. {
  106. int ret = 0;
  107.  
  108. ssize_t readResult = pread(fd, snapshot.dst_vaddr, snapshot.dst_size, 0);
  109.  
  110. if (readResult < snapshot.dst_size)
  111. {
  112. fprintf(stderr, "frame read returned %d\n", readResult);
  113. }
  114. //fprintf(stderr, "requ: %d read %d \n", snapshot.dst_size, readResult);
  115. fprintf(stderr, ".");
  116. return ret;
  117. }
  118.  
  119. static int configure_capture(int fd, aml_snapshot_t &snapshot)
  120. {
  121. int ret = 0;
  122. int ioctlret = 0;
  123.  
  124. if ((ioctlret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, snapshot.dst_width)) != 0)
  125. {
  126. ret = 2;
  127. fprintf(stderr, "Error setting frame width (ret: %d errno: %d)\n", ioctlret, errno);
  128. }
  129.  
  130.  
  131. if ((ioctlret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, snapshot.dst_height)) != 0)
  132. {
  133. ret = 3;
  134. fprintf(stderr, "Error setting frame height (ret: %d errno: %d)\n", ioctlret, errno);
  135. }
  136.  
  137. return ret;
  138. }
  139.  
  140. static void frameToboblight(void *boblight, uint8_t* outputptr, int w, int h, int stride)
  141. {
  142. if (!boblight)
  143. {
  144. fprintf(stderr, "no boblight\n");
  145. return;
  146. }
  147. if (!outputptr)
  148. {
  149. fprintf(stderr, "no outputptr\n");
  150. return;
  151. }
  152. //read out pixels and hand them to libboblight
  153. uint8_t* buffptr;
  154. for (int y = h; y > 0; y--) {
  155. buffptr = outputptr + stride * y;
  156. for (int x = 0; x < w; x++) {
  157. int rgb[3];
  158. rgb[2] = *(buffptr++);
  159. rgb[1] = *(buffptr++);
  160. rgb[0] = *(buffptr++);
  161.  
  162. //fprintf(stdout, "frameToboblight: x(%d), y(%d)\n", x, y);
  163.  
  164. boblight_addpixelxy(boblight, x, y, rgb);
  165. }
  166. }
  167. }
  168.  
  169. static int Run(void* boblight)
  170. {
  171. int snapshot_fd = -1;
  172. aml_snapshot_t aml_snapshot = {0};
  173. int lastPriority = 255;
  174.  
  175. aml_snapshot.dst_width = 160;
  176. aml_snapshot.dst_height = 160;
  177.  
  178. // calc stride, size and alloc mem
  179. aml_snapshot.dst_stride = aml_snapshot.dst_width * 3;
  180. aml_snapshot.dst_size = aml_snapshot.dst_stride * aml_snapshot.dst_height;
  181. aml_snapshot.dst_vaddr = calloc(aml_snapshot.dst_size, 1);
  182.  
  183. fprintf(stdout, "Connection to boblightd config: width(%d), height(%d)\n",
  184. aml_snapshot.dst_width, aml_snapshot.dst_height);
  185. //tell libboblight how big our image is
  186. boblight_setscanrange(boblight, (int)aml_snapshot.dst_width, (int)aml_snapshot.dst_height);
  187.  
  188. while(!g_stop)
  189. {
  190. int64_t bgn = GetTimeUs();
  191.  
  192. if (snapshot_fd == -1) {
  193. snapshot_fd = open(CAPTURE_PATH, O_RDWR, 0);
  194. if (snapshot_fd == -1) {
  195. sleep(1);
  196. continue;
  197. } else {
  198. fprintf(stdout, "snapshot_fd(%d) \n", snapshot_fd);
  199. }
  200. }
  201.  
  202. // match source ratio if possible
  203. if (amvideo_utils_video_playing() != 0) {
  204. if ( lastPriority != 255)
  205. {
  206. boblight_setpriority(boblight, 255);
  207. lastPriority = 255;
  208. }
  209. sleep(1);
  210. continue;
  211. }
  212.  
  213. if (configure_capture(snapshot_fd, aml_snapshot) == 0)
  214. {
  215. if (capture_frame(snapshot_fd, aml_snapshot) == 0)
  216. {
  217. // image to boblight convert.
  218. frameToboblight(boblight, (uint8_t*)aml_snapshot.dst_vaddr,
  219. aml_snapshot.dst_width, aml_snapshot.dst_height, aml_snapshot.dst_stride);
  220.  
  221. if (lastPriority != g_flagmanager.m_priority)
  222. {
  223. boblight_setpriority(boblight, g_flagmanager.m_priority);
  224. lastPriority = g_flagmanager.m_priority;
  225. }
  226. if (!boblight_sendrgb(boblight, 1, NULL))
  227. {
  228. // some error happened, probably connection broken, so bitch and try again
  229. PrintError(boblight_geterror(boblight));
  230. boblight_destroy(boblight);
  231. continue;
  232. }
  233. }
  234. else
  235. {
  236. fprintf(stdout, "nap time\n");
  237. sleep(1);
  238. }
  239. }
  240. int64_t end = GetTimeUs();
  241. float calc_time_ms = (float)(end - bgn) / 1000.0;
  242. // throttle to 100ms max cycle rate
  243. calc_time_ms -= 100.0;
  244. if ((int)calc_time_ms < 0)
  245. usleep((int)(-calc_time_ms * 1000));
  246. }
  247.  
  248. // last image is black
  249. boblight_setpriority(boblight, 255);
  250. boblight_destroy(boblight);
  251. close(snapshot_fd);
  252. return 0;
  253. }
  254.  
  255. /*********************************************************
  256. *********************************************************/
  257. int main(int argc, char *argv[])
  258. {
  259. //load the boblight lib, if it fails we get a char* from dlerror()
  260. const char* boblight_error = boblight_loadlibrary(NULL);
  261. if (boblight_error)
  262. {
  263. PrintError(boblight_error);
  264. return 1;
  265. }
  266.  
  267. //try to parse the flags and bitch to stderr if there's an error
  268. try {
  269. g_flagmanager.ParseFlags(argc, argv);
  270. }
  271. catch (string error) {
  272. PrintError(error);
  273. g_flagmanager.PrintHelpMessage();
  274. return 1;
  275. }
  276.  
  277. if (g_flagmanager.m_printhelp) {
  278. g_flagmanager.PrintHelpMessage();
  279. return 1;
  280. }
  281.  
  282. if (g_flagmanager.m_printboblightoptions) {
  283. g_flagmanager.PrintBoblightOptions();
  284. return 1;
  285. }
  286.  
  287. //set up signal handlers
  288. signal(SIGINT, SignalHandler);
  289. signal(SIGTERM, SignalHandler);
  290.  
  291. //keep running until we want to quit
  292. while(!g_stop) {
  293. //init boblight
  294. void* boblight = boblight_init();
  295.  
  296. fprintf(stdout, "Connecting to boblightd(%p)\n", boblight);
  297.  
  298. //try to connect, if we can't then bitch to stderr and destroy boblight
  299. if (!boblight_connect(boblight, g_flagmanager.m_address, g_flagmanager.m_port, 5000000) ||
  300. !boblight_setpriority(boblight, 255)) {
  301. PrintError(boblight_geterror(boblight));
  302. fprintf(stdout, "Waiting 10 seconds before trying again\n");
  303. boblight_destroy(boblight);
  304. sleep(10);
  305. continue;
  306. }
  307.  
  308. fprintf(stdout, "Connection to boblightd opened\n");
  309.  
  310. //try to parse the boblight flags and bitch to stderr if we can't
  311. try {
  312. g_flagmanager.ParseBoblightOptions(boblight);
  313. }
  314. catch (string error) {
  315. PrintError(error);
  316. return 1;
  317. }
  318.  
  319. try {
  320. Run(boblight);
  321. }
  322. catch (string error) {
  323. PrintError(error);
  324. boblight_destroy(boblight);
  325. return 1;
  326. }
  327. }
  328. fprintf(stdout, "Exiting\n");
  329. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement