summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxav/Makefile.inc2
-rw-r--r--toxav/av_test.c149
2 files changed, 148 insertions, 3 deletions
diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc
index b61c1ea0..1dbabbcd 100644
--- a/toxav/Makefile.inc
+++ b/toxav/Makefile.inc
@@ -36,6 +36,7 @@ libtoxav_la_LIBADD = libtoxcore.la \
36 $(AV_LIBS) 36 $(AV_LIBS)
37 37
38 38
39
39noinst_PROGRAMS += av_test 40noinst_PROGRAMS += av_test
40 41
41av_test_SOURCES = ../toxav/av_test.c 42av_test_SOURCES = ../toxav/av_test.c
@@ -50,6 +51,7 @@ av_test_LDADD = $(LIBSODIUM_LDFLAGS) \
50 $(LIBSODIUM_LIBS) \ 51 $(LIBSODIUM_LIBS) \
51 $(NACL_OBJECTS) \ 52 $(NACL_OBJECTS) \
52 -lopenal \ 53 -lopenal \
54 -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab \
53 $(NACL_LIBS) 55 $(NACL_LIBS)
54 56
55 57
diff --git a/toxav/av_test.c b/toxav/av_test.c
index 7948445d..2323588a 100644
--- a/toxav/av_test.c
+++ b/toxav/av_test.c
@@ -13,6 +13,11 @@
13# endif /* ALC_ALL_DEVICES_SPECIFIER */ 13# endif /* ALC_ALL_DEVICES_SPECIFIER */
14#endif /* __APPLE__ */ 14#endif /* __APPLE__ */
15 15
16#include <opencv/cv.h>
17#include <opencv/highgui.h>
18
19#include <vpx/vpx_image.h>
20
16#include <assert.h> 21#include <assert.h>
17#include <stdio.h> 22#include <stdio.h>
18#include <stdlib.h> 23#include <stdlib.h>
@@ -26,7 +31,6 @@
26#define c_sleep(x) usleep(1000*x) 31#define c_sleep(x) usleep(1000*x)
27#endif 32#endif
28 33
29#define MIN(a,b) (((a)<(b))?(a):(b))
30 34
31/* Enable/disable tests */ 35/* Enable/disable tests */
32#define TEST_REGULAR_AV 0 36#define TEST_REGULAR_AV 0
@@ -35,7 +39,8 @@
35#define TEST_REJECT 0 39#define TEST_REJECT 0
36#define TEST_CANCEL 0 40#define TEST_CANCEL 0
37#define TEST_MUTE_UNMUTE 0 41#define TEST_MUTE_UNMUTE 0
38#define TEST_TRANSFER_A 1 42#define TEST_TRANSFER_A 0
43#define TEST_TRANSFER_V 1
39 44
40 45
41typedef struct { 46typedef struct {
@@ -44,6 +49,8 @@ typedef struct {
44 uint32_t output_source; 49 uint32_t output_source;
45} CallControl; 50} CallControl;
46 51
52const char* video_test_window = "AV Test";
53
47const char* stringify_state(TOXAV_CALL_STATE s) 54const char* stringify_state(TOXAV_CALL_STATE s)
48{ 55{
49 static const char* strings[] = 56 static const char* strings[] =
@@ -82,7 +89,36 @@ void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
82 uint8_t const *planes[], int32_t const stride[], 89 uint8_t const *planes[], int32_t const stride[],
83 void *user_data) 90 void *user_data)
84{ 91{
85 printf("Handling VIDEO FRAME callback\n"); 92 IplImage output_img;
93 const int bpl = stride[VPX_PLANE_Y];
94 const int cxbpl = stride[VPX_PLANE_V];
95
96 output_img.imageData = malloc(width * height * 3);
97 output_img.imageSize = width * height * 3;
98 output_img.width = width;
99 output_img.height = height;
100
101 /* FIXME: possible bug? */
102 const uint8_t* yData = planes[VPX_PLANE_Y];
103 const uint8_t* uData = planes[VPX_PLANE_V];
104 const uint8_t* vData = planes[VPX_PLANE_U];
105
106 // convert from planar to packed
107 for (int y = 0; y < height; ++y)
108 {
109 for (int x = 0; x < width; ++x)
110 {
111 uint8_t Y = planes[VPX_PLANE_Y][x + y * bpl];
112 uint8_t U = planes[VPX_PLANE_V][x/(1 << 1) + y/(1 << 1)*cxbpl];
113 uint8_t V = planes[VPX_PLANE_U][x/(1 << 1) + y/(1 << 1)*cxbpl];
114 output_img.imageData[width * 3 * y + x * 3 + 0] = Y;
115 output_img.imageData[width * 3 * y + x * 3 + 1] = U;
116 output_img.imageData[width * 3 * y + x * 3 + 2] = V;
117 }
118 }
119
120 cvShowImage(video_test_window, &output_img);
121 free(output_img.imageData);
86} 122}
87void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, 123void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
88 int16_t const *pcm, 124 int16_t const *pcm,
@@ -265,8 +301,84 @@ long get_device_idx(const char* arg)
265 return res; 301 return res;
266} 302}
267 303
304int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img)
305{
306 /* I use vpx image coz i'm noob TODO use opencv conversion */
307 vpx_image vpx_img;
308 vpx_img.w = vpx_img.h = vpx_img.d_w = vpx_img.d_h = 0;
309
310 const int w = img->width;
311 const int h = img->height;
312
313 vpx_img_alloc(&vpx_img, VPX_IMG_FMT_VPXI420, w, h, 1);
314
315 for (int y = 0; y < h; ++y)
316 {
317 for (int x = 0; x < w; ++x)
318 {
319 uint8_t b = img->imageData[(x + y * w) * 3 + 0];
320 uint8_t g = img->imageData[(x + y * w) * 3 + 1];
321 uint8_t r = img->imageData[(x + y * w) * 3 + 2];
322
323 vpx_img.planes[VPX_PLANE_Y][x + y * vpx_img.stride[VPX_PLANE_Y]] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
324
325 if (!(x % (1 << vpx_img.x_chroma_shift)) && !(y % (1 << vpx_img.y_chroma_shift)))
326 {
327 const int i = x / (1 << vpx_img.x_chroma_shift);
328 const int j = y / (1 << vpx_img.y_chroma_shift);
329 vpx_img.planes[VPX_PLANE_U][i + j * vpx_img.stride[VPX_PLANE_U]] = ((112 * r + -94 * g + -18 * b) >> 8) + 128;
330 vpx_img.planes[VPX_PLANE_V][i + j * vpx_img.stride[VPX_PLANE_V]] = ((-38 * r + -74 * g + 112 * b) >> 8) + 128;
331 }
332 }
333 }
334
335 int rc = toxav_send_video_frame(av, friend_number, w, h,
336 vpx_img.planes[VPX_PLANE_Y],
337 vpx_img.planes[VPX_PLANE_U],
338 vpx_img.planes[VPX_PLANE_V], NULL);
339
340 vpx_img_free(&vpx_img);
341 return rc;
342}
343
268int main (int argc, char** argv) 344int main (int argc, char** argv)
269{ 345{
346 /* AV files for testing */
347 const char* audio_in = "";
348 const char* video_in = "";
349 long audio_out_dev = 0;
350
351AGAIN:
352 switch (getopt(argc, argv, "a:v:o:"))
353 {
354 case 'a':
355 audio_in = optarg;
356 goto AGAIN;
357 break;
358 case 'v':
359 video_in = optarg;
360 goto AGAIN;
361 break;
362 case 'o':
363 char *d;
364 audio_out_dev = strtol(optarg, &d, 10);
365 if (*d) {
366 fprintf(stderr, "Invalid value for argument: 'o'");
367 return 1;
368 }
369 goto AGAIN;
370 break;
371 case '?':
372 return 1;
373 break;
374 case -1:
375 break;
376 }
377
378
379
380 return 0;
381
270 if (argc == 2) { 382 if (argc == 2) {
271 if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--devices") == 0) { 383 if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--devices") == 0) {
272 return print_devices(); 384 return print_devices();
@@ -675,6 +787,37 @@ int main (int argc, char** argv)
675 printf("Success!"); 787 printf("Success!");
676 } 788 }
677 789
790 if (TEST_TRANSFER_V) {
791 if (strlen(video_in) == 0) {
792 printf("Skipping video test...\n");
793 goto CONTINUE;
794 }
795
796 cvNamedWindow(video_test_window, CV_WINDOW_AUTOSIZE);
797
798 CvCapture* capture = cvCreateFileCapture(video_in);
799 if (!capture) {
800 printf("No file named: %s\n", video_in);
801 return 1;
802 }
803
804 IplImage* frame;
805 time_t start_time = time(NULL);
806
807 while(start_time + 10 > time(NULL)) {
808 frame = cvQueryFrame( capture );
809 if (!frame)
810 break;
811
812 }
813
814 cvReleaseCapture(&capture);
815 cvDestroyWindow(video_test_window);
816
817 CONTINUE:;
818 }
819
820
678 toxav_kill(BobAV); 821 toxav_kill(BobAV);
679 toxav_kill(AliceAV); 822 toxav_kill(AliceAV);
680 tox_kill(Bob); 823 tox_kill(Bob);