fe170bb78a7e936116ef3da1a590f53f8230cbc0
[platform/core/api/video-util.git] / test / video_util_test.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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 <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <glib.h>
21 #include <dlog.h>
22 #include <video_util.h>
23
24 #define PACKAGE                 "video_util_test"
25 #define MAX_STRING_LEN  256
26
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #endif
30
31 #define LOG_TAG                 "VIDEO_UTIL_TEST"
32
33 enum {
34         CURRENT_STATUS_MAINMENU,
35         CURRENT_STATUS_FILENAME,
36         CURRENT_STATUS_SET_FORMAT,
37         CURRENT_STATUS_SET_VIDEO_CODEC,
38         CURRENT_STATUS_SET_AUDIO_CODEC,
39         CURRENT_STATUS_SET_ACCURATE_MODE,
40         CURRENT_STATUS_SET_RESOLUTION,
41         CURRENT_STATUS_SET_FPS,
42         CURRENT_STATUS_SET_TIME,
43         CURRENT_STATUS_SET_OUTFILENAME,
44         CURRENT_STATUS_MAX
45 };
46
47 static video_util_h video_h = NULL;
48 char g_uri[MAX_STRING_LEN] = { 0, };
49
50 int g_menu_state = CURRENT_STATUS_MAINMENU;
51 int g_handle_num = 1;
52 int format = VIDEO_UTIL_FILE_FORMAT_3GP;
53 int video_codec = VIDEO_UTIL_VIDEO_CODEC_MPEG4;
54 int audio_codec = VIDEO_UTIL_AUDIO_CODEC_AAC;
55 int accurate_mode = 0;
56 int width = 176;
57 int height = 144;
58 int fps = 10;
59 unsigned long start_position = 0;
60 unsigned long duration = 5000;
61 int make_video_cnt = 1;
62 char g_out[MAX_STRING_LEN] = { 0, };
63
64 typedef struct {
65         video_util_h video_h;
66         int idx;
67         unsigned long start_time;
68         unsigned long duration;
69 } test_util_s;
70
71 test_util_s *_util_s;
72
73
74 static void display_sub_basic();
75 void _video_util_start_transcoding(test_util_s *util_s);
76
77 void _quit_program(void)
78 {
79         exit(0);
80 }
81
82 bool test_transcode_spec_cb(int value, void *user_data)
83 {
84         if (!user_data) {
85                 LOGE("user_data is NULL");
86                 return FALSE;
87         }
88
89         if (!strcmp(user_data, "format_check")) {
90                 switch (value) {
91                 case 0:
92                         LOGI("[%s] --- [3gp]", user_data);
93                         break;
94                 case 1:
95                         LOGI("[%s] --- [mp4]", user_data);
96                         break;
97                 default:
98                         break;
99                 }
100         } else if (!strcmp(user_data, "video_codec_check")) {
101                 switch (value) {
102                 case 0:
103                         LOGI("[%s] --- [m4v]", user_data);
104                         break;
105                 case 1:
106                         LOGI("[%s] --- [h263]", user_data);
107                         break;
108                 case 2:
109                         LOGI("[%s] --- [h264]", user_data);
110                         break;
111                 default:
112                         break;
113                 }
114         } else if (!strcmp(user_data, "audio_codec_check")) {
115                 switch (value) {
116                 case 0:
117                         LOGI("[%s] --- [aac]", user_data);
118                         break;
119                 case 1:
120                         LOGI("[%s] --- [amrnb]", user_data);
121                         break;
122                 default:
123                         break;
124                 }
125         }
126
127         return true;
128 }
129
130 bool _supported_spec_check(video_util_h handle)
131 {
132         int ret = 0;
133         ret = video_util_foreach_supported_file_format(handle, (video_util_supported_file_format_cb)test_transcode_spec_cb, "format_check");
134         printf("video_util_foreach_supported_file_format [%d]\n", ret);
135         ret = video_util_foreach_supported_video_codec(handle, (video_util_supported_video_encoder_cb)test_transcode_spec_cb, "video_codec_check");
136         printf("video_util_foreach_supported_video_codec [%d]\n", ret);
137         ret = video_util_foreach_supported_audio_codec(handle, (video_util_supported_audio_encoder_cb)test_transcode_spec_cb, "audio_codec_check");
138         printf("video_util_foreach_supported_audio_codec [%d]\n", ret);
139
140         return true;
141 }
142
143 void _transcode_completed_cb(video_util_error_e error, void *user_data)
144 {
145         int idx = 0;
146         unsigned long ntn_start_position = 0;
147
148         test_util_s *_util_s = (test_util_s *)user_data;
149
150         if (!_util_s) {
151                 LOGE("completed_cb user data is NULL");
152                 return;
153         }
154
155         LOGI("transcode_completed_cb============= [%2d / %2d][%d]\n", _util_s->idx, make_video_cnt, error);
156         printf("transcode_completed_cb============= [%2d / %2d][%d]\n", _util_s->idx, make_video_cnt, error);
157
158         if (_util_s->idx == (make_video_cnt - 1)) {
159                 LOGI("End trascoding");
160                 return;
161         }
162
163         idx = _util_s->idx + 1;
164         ntn_start_position = _util_s->start_time + duration;
165         _util_s->idx = idx;
166         _util_s->start_time = ntn_start_position;
167
168         _video_util_start_transcoding(_util_s);
169
170         return;
171 }
172
173 void _transcode_progress_cb(unsigned long current_position, unsigned long duration, void *user_data)
174 {
175         test_util_s *_util_s = (test_util_s *)user_data;
176
177         LOGD("transcode_progress_cb-------------- [%2d][%ld][%ld]\n", _util_s->idx, current_position, duration);
178
179         return;
180 }
181
182 void _video_util_start_transcoding(test_util_s *util_s)
183 {
184         int ret = VIDEO_UTIL_ERROR_NONE;
185         char output_file_path[MAX_STRING_LEN] = { 0, };
186
187         if (!video_h) {
188                 LOGE("video_util handle is NULL, please set format after create");
189                 return;
190         }
191
192         LOGI("video_util set below");
193         LOGI("format: %d, video codec: %d, audio codec: %d, accurate mode: %d", format, video_codec, audio_codec, accurate_mode);
194         LOGI("width: %d, height: %d, fps: %d", width, height, fps);
195         LOGI("start time: %lu, durtation: %lu", start_position, duration);
196
197         ret = video_util_set_file_format(video_h, format);
198         if (ret != VIDEO_UTIL_ERROR_NONE) {
199                 LOGE("video_util_set_file_format is failed (%d)", ret);
200                 return;
201         }
202
203         ret = video_util_set_video_codec(video_h, video_codec);
204         if (ret != VIDEO_UTIL_ERROR_NONE) {
205                 LOGE("video_util_set_video_codec is failed (%d)", ret);
206                 return;
207         }
208
209         ret = video_util_set_audio_codec(video_h, audio_codec);
210         if (ret != VIDEO_UTIL_ERROR_NONE) {
211                 LOGE("video_util_set_audio_codec is failed (%d)", ret);
212                 return;
213         }
214
215         ret = video_util_set_accurate_mode(video_h, accurate_mode);
216         if (ret != VIDEO_UTIL_ERROR_NONE) {
217                 LOGE("video_util_set_accurate_mode is failed (%d)", ret);
218                 return;
219         }
220
221         ret = video_util_set_resolution(video_h, width, height);
222         if (ret != VIDEO_UTIL_ERROR_NONE) {
223                 LOGE("video_util_set_resolution is failed (%d)", ret);
224                 return;
225         }
226
227         ret = video_util_set_fps(video_h, fps);
228         if (ret != VIDEO_UTIL_ERROR_NONE) {
229                 LOGE("video_util_set_fps is failed (%d)", ret);
230                 return;
231         }
232
233         memset(output_file_path, 0x00, MAX_STRING_LEN);
234
235         snprintf(output_file_path, MAX_STRING_LEN, "%s_%d.%s", g_out, util_s->idx, format ? "mp4" : "3gp");
236
237         LOGI("input start_time: %lu, duration: %lu, output_file_path: %s", util_s->start_time, util_s->duration, output_file_path);
238         ret = video_util_start_transcoding(util_s->video_h, util_s->start_time, util_s->duration, output_file_path, _transcode_progress_cb, _transcode_completed_cb, util_s);
239
240         if (ret != VIDEO_UTIL_ERROR_NONE) {
241                 LOGE("video_util_start_transcoding is failed (%d)", ret);
242                 return;
243         }
244
245         return;
246 }
247
248 void _reset_var()
249 {
250         if (video_h) {
251                 video_util_destroy(video_h);
252                 video_h = NULL;
253         }
254         memset(g_uri, 0x00, MAX_STRING_LEN);
255         memset(g_out, 0x00, MAX_STRING_LEN);
256         g_menu_state = CURRENT_STATUS_MAINMENU;
257         g_handle_num = 1;
258         format = VIDEO_UTIL_FILE_FORMAT_3GP;
259         video_codec = VIDEO_UTIL_VIDEO_CODEC_MPEG4;
260         audio_codec = VIDEO_UTIL_AUDIO_CODEC_AAC;
261         accurate_mode = 0;
262         width = 176;
263         height = 144;
264         fps = 25;
265         start_position = 5000;
266         duration = 5000;
267         make_video_cnt = 3;
268 }
269
270 static void input_filename(char *filename)
271 {
272         int len = strlen(filename);
273         int ret = VIDEO_UTIL_ERROR_NONE;
274
275         if (len < 0 || len > MAX_STRING_LEN) {
276                 LOGE("Input file name is wrong");
277                 return;
278         }
279
280         _reset_var();
281
282         if (video_h) {
283                 ret = video_util_cancel_transcoding(video_h);
284                 ret = video_util_destroy(video_h);
285         }
286
287         video_h = NULL;
288
289         ret = video_util_create(&video_h);
290
291         if (ret != VIDEO_UTIL_ERROR_NONE) {
292                 LOGE("video_util create is failed (%d)", ret);
293                 return;
294         }
295
296         strncpy(g_uri, filename, len);
297
298         ret = video_util_set_file_path(video_h, g_uri);
299
300         if (ret != VIDEO_UTIL_ERROR_NONE) {
301                 LOGE("video_util_set_file_path is failed");
302                 return;
303         }
304
305         _supported_spec_check(video_h);
306 }
307
308 void reset_menu_state()
309 {
310         g_menu_state = CURRENT_STATUS_MAINMENU;
311         return;
312 }
313
314 void _interpret_main_menu(char *cmd)
315 {
316         int len = strlen(cmd);
317
318         if (len == 1) {
319                 if (strncmp(cmd, "a", 1) == 0) {
320                         g_menu_state = CURRENT_STATUS_FILENAME;
321                 } else if (strncmp(cmd, "s", 1) == 0) {
322                         if (!_util_s) {
323                                 _util_s = (test_util_s *)calloc(1, sizeof(test_util_s));
324                                 LOGE("_util_s malloc");
325                         }
326
327                         if (!_util_s) {
328                                 LOGE("test util calloc failed");
329                                 return;
330                         }
331
332                         _util_s->video_h = video_h;
333                         _util_s->idx = 0;
334                         _util_s->start_time = start_position;
335                         _util_s->duration = duration;
336
337                         _video_util_start_transcoding(_util_s);
338
339                 } else if (strncmp(cmd, "c", 1) == 0) {
340                         int ret = VIDEO_UTIL_ERROR_NONE;
341                         if (!video_h) {
342                                 g_print("video_util handle is NULL, please set format after create");
343                                 return;;
344                         }
345                         ret = video_util_cancel_transcoding(video_h);
346                         if (ret != VIDEO_UTIL_ERROR_NONE) {
347                                 g_print("video_util_cancel_transcoding is failed (%d)", ret);
348                                 return;
349                         }
350                 } else if (strncmp(cmd, "f", 1) == 0) {
351                         g_menu_state = CURRENT_STATUS_SET_FORMAT;
352                 } else if (strncmp(cmd, "m", 1) == 0) {
353                         g_menu_state = CURRENT_STATUS_SET_ACCURATE_MODE;
354                 } else if (strncmp(cmd, "t", 1) == 0) {
355                         g_menu_state = CURRENT_STATUS_SET_TIME;
356                 } else if (strncmp(cmd, "o", 1) == 0) {
357                         g_menu_state = CURRENT_STATUS_SET_OUTFILENAME;
358                 } else if (strncmp(cmd, "q", 1) == 0) {
359                         _quit_program();
360                 } else if (strncmp(cmd, "d", 1) == 0) {
361                         int ret = VIDEO_UTIL_ERROR_NONE;
362                         if (!video_h) {
363                                 g_print("video_util handle is NULL, please set format after create");
364                                 return;;
365                         }
366                         ret = video_util_destroy(video_h);
367                         if (ret != VIDEO_UTIL_ERROR_NONE) {
368                                 g_print("video_util_cancel_transcoding is failed (%d)", ret);
369                                 return;
370                         }
371                         free(_util_s);
372                         _util_s = NULL;
373                 } else {
374                         g_print("unknown menu \n");
375                 }
376         } else if (len == 2) {
377                 if (strncmp(cmd, "vc", 2) == 0)
378                         g_menu_state = CURRENT_STATUS_SET_VIDEO_CODEC;
379                 else if (strncmp(cmd, "ac", 2) == 0)
380                         g_menu_state = CURRENT_STATUS_SET_AUDIO_CODEC;
381                 else if (strncmp(cmd, "vr", 2) == 0)
382                         g_menu_state = CURRENT_STATUS_SET_RESOLUTION;
383                 else if (strncmp(cmd, "vf", 2) == 0)
384                         g_menu_state = CURRENT_STATUS_SET_FPS;
385                 else
386                         g_print("unknown menu \n");
387         } else {
388                 g_print("unknown menu \n");
389         }
390         return;
391 }
392
393 static void displaymenu(void)
394 {
395         if (g_menu_state == CURRENT_STATUS_MAINMENU) {
396                 display_sub_basic();
397         } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
398                 g_print("*** input mediapath.\n");
399         } else if (g_menu_state == CURRENT_STATUS_SET_FORMAT) {
400                 g_print("*** input file format.(0:3gp, 1:mp4)\n");
401         } else if (g_menu_state == CURRENT_STATUS_SET_VIDEO_CODEC) {
402                 g_print("*** input video codec.(0:m4v, 1:h263, 2:h264)\n");
403         } else if (g_menu_state == CURRENT_STATUS_SET_AUDIO_CODEC) {
404                 g_print("*** input audio codec.(0:aac, 1:amrnb)\n");
405         } else if (g_menu_state == CURRENT_STATUS_SET_ACCURATE_MODE) {
406                 g_print("*** input accurate mode.(0: OFF, 1: ON)\n");
407         } else if (g_menu_state == CURRENT_STATUS_SET_RESOLUTION) {
408                 g_print("*** input video resolution.(width, height)\n");
409         } else if (g_menu_state == CURRENT_STATUS_SET_FPS) {
410                 g_print("*** input video fps.(5<=fps<=30)\n");
411         } else if (g_menu_state == CURRENT_STATUS_SET_FPS) {
412                 g_print("*** input video fps.(5<=fps<=30)\n");
413         } else if (g_menu_state == CURRENT_STATUS_SET_TIME) {
414                 g_print("*** input transcode start/duration time(ms), run nth.(start time, duration, n)\n");
415         } else if (g_menu_state == CURRENT_STATUS_SET_OUTFILENAME) {
416                 g_print("*** input output filename.(defaunt path /opt/usr/media/)\n");
417         } else {
418                 g_print("*** unknown status.\n");
419                 _quit_program();
420         }
421         g_print(" >>> ");
422 }
423
424 gboolean timeout_menu_display(void *data)
425 {
426         displaymenu();
427         return FALSE;
428 }
429
430 static void interpret(char *cmd)
431 {
432         switch (g_menu_state) {
433
434         case CURRENT_STATUS_MAINMENU:
435                 {
436                         _interpret_main_menu(cmd);
437                         break;
438                 }
439         case CURRENT_STATUS_FILENAME:
440                 {
441                         input_filename(cmd);
442                         reset_menu_state();
443                         break;
444                 }
445         case CURRENT_STATUS_SET_FORMAT:
446                 {
447                         int ret = VIDEO_UTIL_ERROR_NONE;
448                         format = atoi(cmd);
449                         if (format < 0 || format >= VIDEO_UTIL_FILE_FORMAT_MAX) {
450                                 LOGE("input cmd is out of range.");
451                                 reset_menu_state();
452                                 break;
453                         }
454                         if (!video_h) {
455                                 LOGE("video_util handle is NULL, please set format after create");
456                                 reset_menu_state();
457                                 break;
458                         }
459                         ret = video_util_set_file_format(video_h, format);
460                         if (ret != VIDEO_UTIL_ERROR_NONE) {
461                                 LOGE("video_util_set_file_format is failed (%d)", ret);
462                                 reset_menu_state();
463                                 break;
464                         }
465
466                         reset_menu_state();
467                         break;
468                 }
469         case CURRENT_STATUS_SET_VIDEO_CODEC:
470                 {
471                         int ret = VIDEO_UTIL_ERROR_NONE;
472                         video_codec = atoi(cmd);
473                         if (video_codec < 0 || video_codec >= VIDEO_UTIL_VIDEO_CODEC_NONE) {
474                                 LOGE("input cmd is out of range");
475                                 reset_menu_state();
476                                 break;
477                         }
478                         if (!video_h) {
479                                 LOGE("video_util handle is NULL, please set format after create");
480                                 reset_menu_state();
481                                 break;
482                         }
483                         ret = video_util_set_video_codec(video_h, video_codec);
484                         if (ret != VIDEO_UTIL_ERROR_NONE) {
485                                 LOGE("video_util_set_video_codec is failed (%d)", ret);
486                                 reset_menu_state();
487                                 break;
488                         }
489
490                         reset_menu_state();
491                         break;
492                 }
493         case CURRENT_STATUS_SET_AUDIO_CODEC:
494                 {
495                         int ret = VIDEO_UTIL_ERROR_NONE;
496                         audio_codec = atoi(cmd);
497                         if (audio_codec < 0 || audio_codec >= VIDEO_UTIL_VIDEO_CODEC_NONE) {
498                                 LOGE("input cmd is out of range");
499                                 reset_menu_state();
500                                 break;
501                         }
502                         if (!video_h) {
503                                 LOGE("video_util handle is NULL, please set format after create");
504                                 reset_menu_state();
505                                 break;
506                         }
507                         ret = video_util_set_video_codec(video_h, audio_codec);
508                         if (ret != VIDEO_UTIL_ERROR_NONE) {
509                                 LOGE("video_util_set_video_codec is failed (%d)", ret);
510                                 reset_menu_state();
511                                 break;
512                         }
513
514                         reset_menu_state();
515                         break;
516                 }
517         case CURRENT_STATUS_SET_ACCURATE_MODE:
518                 {
519                         int ret = VIDEO_UTIL_ERROR_NONE;
520                         accurate_mode = atoi(cmd);
521
522                         if (!video_h) {
523                                 LOGE("video_util handle is NULL, please set format after create");
524                                 reset_menu_state();
525                                 break;
526                         }
527                         ret = video_util_set_accurate_mode(video_h, (bool)accurate_mode);
528                         if (ret != VIDEO_UTIL_ERROR_NONE) {
529                                 LOGE("video_util_set_video_codec is failed (%d)", ret);
530                                 reset_menu_state();
531                                 break;
532                         }
533
534                         reset_menu_state();
535                         break;
536                 }
537         case CURRENT_STATUS_SET_RESOLUTION:
538                 {
539                         int ret = VIDEO_UTIL_ERROR_NONE;
540                         int value = atoi(cmd);
541                         static int resolution_cnt = 0;
542
543                         if (!video_h) {
544                                 LOGE("video_util handle is NULL, please set format after create");
545                                 reset_menu_state();
546                                 break;
547                         }
548
549                         switch (resolution_cnt) {
550                         case 0:
551                                 width = value;
552                                 resolution_cnt++;
553                                 break;
554                         case 1:
555                                 resolution_cnt = 0;
556                                 height = value;
557
558                                 ret = video_util_set_resolution(video_h, width, height);
559                                 if (ret != VIDEO_UTIL_ERROR_NONE) {
560                                         LOGE("video_util_set_resolution is failed (%d)", ret);
561                                         reset_menu_state();
562                                         break;
563                                 }
564
565                                 reset_menu_state();
566                                 break;
567                         }
568                         break;
569                 }
570         case CURRENT_STATUS_SET_FPS:
571                 {
572                         int ret = VIDEO_UTIL_ERROR_NONE;
573                         fps = atoi(cmd);
574
575                         if (fps < 5 || fps > 30) {
576                                 LOGE("input cmd is out of range");
577                                 reset_menu_state();
578                                 break;
579                         }
580                         if (!video_h) {
581                                 LOGE("video_util handle is NULL, please set format after create");
582                                 reset_menu_state();
583                                 break;
584                         }
585                         ret = video_util_set_fps(video_h, fps);
586                         if (ret != VIDEO_UTIL_ERROR_NONE) {
587                                 LOGE("video_util_set_fps is failed (%d)", ret);
588                                 reset_menu_state();
589                                 break;
590                         }
591
592                         reset_menu_state();
593                         break;
594                 }
595         case CURRENT_STATUS_SET_TIME:
596                 {
597                         int value = atoi(cmd);
598                         static int set_time_cnt = 0;
599
600                         switch (set_time_cnt) {
601                         case 0:
602                                 start_position = value;
603                                 set_time_cnt++;
604                                 break;
605                         case 1:
606                                 duration = value;
607                                 set_time_cnt++;
608                                 break;
609                         case 2:
610                                 set_time_cnt = 0;
611                                 make_video_cnt = value;
612                                 reset_menu_state();
613                                 break;
614
615                         }
616                         break;
617                 }
618         case CURRENT_STATUS_SET_OUTFILENAME:
619                 {
620                         LOGI("output file is %s", g_out);
621                         snprintf(g_out, MAX_STRING_LEN, "/opt/usr/media/%s", cmd);
622                         g_out[MAX_STRING_LEN - 1] = '\0';
623                         LOGI("output file is %s", g_out);
624                         reset_menu_state();
625                         break;
626                 }
627         default:
628                 break;
629         }
630
631         g_timeout_add(100, timeout_menu_display, 0);
632 }
633
634 static void display_sub_basic()
635 {
636         g_print("\n");
637         g_print("=========================================================================================\n");
638         g_print("                                    video_util_test test\n");
639         g_print("-----------------------------------------------------------------------------------------\n");
640         g_print(" a. Create \t\t\t");
641         g_print(" s. Start transcoding \t");
642         g_print(" c. Cancel transcoding \n");
643         g_print(" f. Set file format\t\t");
644         g_print("vc. Set video codec\t");
645         g_print("ac. Set audio codec\n");
646         g_print(" m. Set accurate mode\t\t");
647         g_print("vr. Set resolution\t");
648         g_print("vf. Set video fps\n");
649         g_print(" t. Set start/duration time \t");
650         g_print(" o. Set output filename\t");
651         g_print(" q. quite test suite\t\n");
652         g_print(" d. Destroy\t");
653         g_print("\n");
654         g_print("=========================================================================================\n");
655 }
656
657 gboolean input(GIOChannel *channel)
658 {
659         gchar buf[MAX_STRING_LEN];
660         gsize read;
661         GError *error = NULL;
662
663         g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
664         buf[read] = '\0';
665         g_strstrip(buf);
666         interpret(buf);
667
668         return TRUE;
669 }
670
671 int main(int argc, char *argv[])
672 {
673         GIOChannel *stdin_channel;
674         GMainLoop *loop = g_main_loop_new(NULL, 0);
675         stdin_channel = g_io_channel_unix_new(0);
676         g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
677         g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
678
679         displaymenu();
680
681         g_main_loop_run(loop);
682         g_print("STOP main loop\n");
683
684         g_main_loop_unref(loop);
685         return 0;
686
687 }