diff options
author | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:49:53 +0900 |
---|---|---|
committer | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:49:53 +0900 |
commit | b8ccdef0306cf19cde9511ec244fd43b4ae1d863 (patch) | |
tree | edfb6fbb5a168525e60cbcf918d84217bd667586 /server/thumb-server-internal.c | |
parent | 06e2dff413544d0e1465e0cb4897fe32e4de2c22 (diff) | |
download | libmedia-thumbnail-b8ccdef0306cf19cde9511ec244fd43b4ae1d863.tar.gz libmedia-thumbnail-b8ccdef0306cf19cde9511ec244fd43b4ae1d863.tar.bz2 libmedia-thumbnail-b8ccdef0306cf19cde9511ec244fd43b4ae1d863.zip |
Tizen 2.1 base
Diffstat (limited to 'server/thumb-server-internal.c')
-rwxr-xr-x | server/thumb-server-internal.c | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/server/thumb-server-internal.c b/server/thumb-server-internal.c new file mode 100755 index 0000000..3844fcb --- /dev/null +++ b/server/thumb-server-internal.c @@ -0,0 +1,412 @@ +/* + * media-thumbnail-server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hyunjun Ko <zzoon.ko@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "thumb-server-internal.h" + +#include <unistd.h> +#include <dirent.h> +#include <stdio.h> +#include <string.h> +#include <Ecore_Evas.h> + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "MEDIA_THUMBNAIL_SERVER" + +static __thread char **arr_path; +static __thread int g_idx = 0; +static __thread int g_cur_idx = 0; + +GMainLoop *g_thumb_server_mainloop; // defined in thumb-server.c as extern + +#ifdef _USE_MEDIA_UTIL_ +gboolean _thumb_server_send_msg_to_agent(int msg_type); +#endif + +gboolean _thumb_daemon_start_jobs(gpointer data) +{ + thumb_dbg(""); + /* Initialize ecore-evas to use evas library */ + ecore_evas_init(); + +#ifdef _USE_MEDIA_UTIL_ + _thumb_server_send_msg_to_agent(MS_MSG_THUMB_SERVER_READY); +#endif + return FALSE; +} + +void _thumb_daemon_finish_jobs() +{ + sqlite3 *sqlite_db_handle = _media_thumb_db_get_handle(); + + if (sqlite_db_handle != NULL) { + _media_thumb_db_disconnect(); + thumb_dbg("sqlite3 handle is alive. So disconnect to sqlite3"); + } + + /* Shutdown ecore-evas */ + ecore_evas_shutdown(); + + return; +} + +int _thumb_daemon_process_job(thumbMsg *req_msg, thumbMsg *res_msg) +{ + int err = -1; + + err = _media_thumb_process(req_msg, res_msg); + if (err < 0) { + if (req_msg->msg_type == THUMB_REQUEST_SAVE_FILE) { + thumb_err("_media_thumb_process is failed: %d", err); + res_msg->status = THUMB_FAIL; + } else { + thumb_warn("_media_thumb_process is failed: %d, So use default thumb", err); + res_msg->status = THUMB_SUCCESS; + } + } else { + res_msg->status = THUMB_SUCCESS; + } + + return err; +} + +int _thumb_daemon_all_extract() +{ + int err = -1; + int count = 0; + char query_string[MAX_PATH_SIZE + 1] = { 0, }; + char path[MAX_PATH_SIZE + 1] = { 0, }; + sqlite3 *sqlite_db_handle = NULL; + sqlite3_stmt *sqlite_stmt = NULL; + + err = _media_thumb_db_connect(); + if (err < 0) { + thumb_err("_media_thumb_db_connect failed: %d", err); + return MEDIA_THUMB_ERROR_DB; + } + + sqlite_db_handle = _media_thumb_db_get_handle(); + if (sqlite_db_handle == NULL) { + thumb_err("sqlite handle is NULL"); + return MEDIA_THUMB_ERROR_DB; + } + + snprintf(query_string, sizeof(query_string), SELECT_PATH_FROM_UNEXTRACTED_THUMB_MEDIA); + thumb_dbg("Query: %s", query_string); + + err = sqlite3_prepare_v2(sqlite_db_handle, query_string, strlen(query_string), &sqlite_stmt, NULL); + if (SQLITE_OK != err) { + thumb_err("prepare error [%s]\n", sqlite3_errmsg(sqlite_db_handle)); + _media_thumb_db_disconnect(); + return MEDIA_THUMB_ERROR_DB; + } + + while(1) { + err = sqlite3_step(sqlite_stmt); + if (err != SQLITE_ROW) { + thumb_dbg("end of row [%s]\n", sqlite3_errmsg(sqlite_db_handle)); + break; + } + + strncpy(path, (const char *)sqlite3_column_text(sqlite_stmt, 0), MAX_PATH_SIZE + 1); + count = sqlite3_column_int(sqlite_stmt, 1); + + thumb_dbg("Path : %s", path); + + if (g_idx == 0) { + arr_path = (char**)malloc(sizeof(char*)); + } else { + arr_path = (char**)realloc(arr_path, (g_idx + 1) * sizeof(char*)); + } + + arr_path[g_idx++] = strdup(path); + } + + sqlite3_finalize(sqlite_stmt); + _media_thumb_db_disconnect(); + + return MEDIA_THUMB_ERROR_NONE; +} + +int _thumb_daemon_process_queue_jobs(gpointer data) +{ + int err = -1; + char *path = NULL; + + if (g_cur_idx < g_idx) { + thumb_dbg("There are %d jobs in the queue", g_idx - g_cur_idx); + thumb_dbg("Current idx : [%d]", g_cur_idx); + path = arr_path[g_cur_idx++]; + + thumbMsg recv_msg, res_msg; + memset(&recv_msg, 0x00, sizeof(thumbMsg)); + memset(&res_msg, 0x00, sizeof(thumbMsg)); + + recv_msg.msg_type = THUMB_REQUEST_DB_INSERT; + recv_msg.thumb_type = MEDIA_THUMB_LARGE; + strncpy(recv_msg.org_path, path, sizeof(recv_msg.org_path)); + recv_msg.org_path[sizeof(recv_msg.org_path) - 1] = '\0'; + + _thumb_daemon_process_job(&recv_msg, &res_msg); + + if (res_msg.status == THUMB_SUCCESS) { + + err = _media_thumb_db_connect(); + if (err < 0) { + thumb_err("_media_thumb_mb_svc_connect failed: %d", err); + return TRUE; + } + + /* Need to update DB once generating thumb is done */ + err = _media_thumb_update_db(recv_msg.org_path, + res_msg.dst_path, + res_msg.origin_width, + res_msg.origin_height); + if (err < 0) { + thumb_err("_media_thumb_update_db failed : %d", err); + } + + _media_thumb_db_disconnect(); + } + + SAFE_FREE(path); + } else { + g_cur_idx = 0; + g_idx = 0; + thumb_warn("Deleting array"); + SAFE_FREE(arr_path); + //_media_thumb_db_disconnect(); + + _thumb_server_send_msg_to_agent(MS_MSG_THUMB_EXTRACT_ALL_DONE); // MS_MSG_THUMB_EXTRACT_ALL_DONE + + return FALSE; + } + + return TRUE; +} + +gboolean _thumb_server_read_socket(GIOChannel *src, + GIOCondition condition, + gpointer data) +{ + struct sockaddr_in client_addr; + unsigned int client_addr_len; +#ifndef _USE_MEDIA_UTIL_ + int client_sock; +#endif + + thumbMsg recv_msg; + thumbMsg res_msg; + + int sock = -1; + int header_size = 0; + + memset((void *)&recv_msg, 0, sizeof(recv_msg)); + memset((void *)&res_msg, 0, sizeof(res_msg)); + + sock = g_io_channel_unix_get_fd(src); + if (sock < 0) { + thumb_err("sock fd is invalid!"); + return TRUE; + } + + header_size = sizeof(thumbMsg) - MAX_PATH_SIZE*2; + +#ifndef _USE_MEDIA_UTIL_ + if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) { + thumb_err("accept failed : %s", strerror(errno)); + return TRUE; + } + + thumb_dbg("Client[%d] is accepted", client_sock); + + + if (_media_thumb_recv_msg(client_sock, header_size, &recv_msg) < 0) { + thumb_err("_media_thumb_recv_msg failed "); + close(client_sock); + return TRUE; + } +#else + + if (_media_thumb_recv_udp_msg(sock, header_size, &recv_msg, &client_addr, &client_addr_len) < 0) { + thumb_err("_media_thumb_recv_udp_msg failed"); + return FALSE; + } +#endif + + thumb_dbg("Received [%d] %s(%d) from PID(%d) \n", recv_msg.msg_type, recv_msg.org_path, strlen(recv_msg.org_path), recv_msg.pid); + + if (recv_msg.msg_type == THUMB_REQUEST_ALL_MEDIA) { + thumb_dbg("All thumbnails are being extracted now"); + _thumb_daemon_all_extract(); + g_idle_add(_thumb_daemon_process_queue_jobs, NULL); + } else if(recv_msg.msg_type == THUMB_REQUEST_KILL_SERVER) { + thumb_dbg("received KILL msg from thumbnail agent."); + } else { + long start = thumb_get_debug_time(); + + _thumb_daemon_process_job(&recv_msg, &res_msg); + + long end = thumb_get_debug_time(); + thumb_dbg("Time : %f (%s)", ((double)(end - start) / (double)CLOCKS_PER_SEC), recv_msg.org_path); + } + + res_msg.msg_type = recv_msg.msg_type; + strncpy(res_msg.org_path, recv_msg.org_path, recv_msg.origin_path_size); + res_msg.origin_path_size = recv_msg.origin_path_size; + res_msg.dest_path_size = strlen(res_msg.dst_path) + 1; + + int buf_size = 0; + unsigned char *buf = NULL; + _media_thumb_set_buffer(&res_msg, &buf, &buf_size); + + //thumb_dbg("buffer size : %d", buf_size); + +#ifndef _USE_MEDIA_UTIL_ + if (send(client_sock, buf, buf_size, 0) != buf_size) { + thumb_err("sendto failed : %s", strerror(errno)); + } else { + thumb_dbg("Sent %s(%d) \n", res_msg.dst_path, strlen(res_msg.dst_path)); + } + + close(client_sock); +#else + if (sendto(sock, buf, buf_size, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)) != buf_size) { + thumb_err("sendto failed: %s\n", strerror(errno)); + SAFE_FREE(buf); + return FALSE; + } +#endif + + thumb_dbg("Sent %s(%d)", res_msg.dst_path, strlen(res_msg.dst_path)); + + SAFE_FREE(buf); + + if(recv_msg.msg_type == THUMB_REQUEST_KILL_SERVER) { + thumb_dbg("Shutting down..."); + g_main_loop_quit(g_thumb_server_mainloop); + } + + return TRUE; +} + +#ifdef _USE_MEDIA_UTIL_ +gboolean _thumb_server_send_msg_to_agent(int msg_type) +{ + int sock; + const char *serv_ip = "127.0.0.1"; + struct sockaddr_in serv_addr; + ms_thumb_server_msg send_msg; +#if 0 + /* Creaete a UDP socket */ + if (_media_thumb_create_udp_socket(&sock) < 0) { + thumb_err("_media_thumb_create_udp_socket failed"); + return FALSE; + } +#endif + if (ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sock) < 0) { + thumb_err("ms_ipc_create_server_socket failed"); + return FALSE; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(serv_ip); + serv_addr.sin_port = htons(MS_THUMB_COMM_PORT); + + send_msg.msg_type = msg_type; + + if (sendto(sock, &send_msg, sizeof(ms_thumb_server_msg), 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != sizeof(ms_thumb_server_msg)) { + thumb_err("sendto failed: %s\n", strerror(errno)); + return FALSE; + } + + thumb_dbg("Sending msg to thumbnail agent[%d] is successful", send_msg.msg_type); + + return TRUE; +} +#endif + +gboolean _thumb_server_prepare_socket(int *sock_fd) +{ + int sock; + unsigned short serv_port; + + thumbMsg recv_msg; + thumbMsg res_msg; + + memset((void *)&recv_msg, 0, sizeof(recv_msg)); + memset((void *)&res_msg, 0, sizeof(res_msg)); +#ifdef _USE_MEDIA_UTIL_ + serv_port = MS_THUMB_DAEMON_PORT; + + if (ms_ipc_create_server_socket(MS_PROTOCOL_UDP, serv_port, &sock) < 0) { + thumb_err("ms_ipc_create_server_socket failed"); + return FALSE; + } +#if 0 + /* Creaete a UDP socket */ + if (_media_thumb_create_udp_socket(&sock) < 0) { + thumb_err("_media_thumb_create_udp_socket failed"); + return FALSE; + } +#endif +#else + char thumb_path[MAX_PATH_SIZE + 1]; + struct sockaddr_in serv_addr; + serv_port = THUMB_DAEMON_PORT; + + /* Creaete a TCP socket */ + if (_media_thumb_create_socket(SERVER_SOCKET, &sock) < 0) { + thumb_err("_media_thumb_create_socket failed"); + return FALSE; + } + + memset(thumb_path, 0, sizeof(thumb_path)); + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(serv_port); + + /* Bind to the local address */ + if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + thumb_err("bind failed : %s", strerror(errno)); + return FALSE; + } + + thumb_dbg("bind success"); + + /* Listening */ + if (listen(sock, SOMAXCONN) < 0) { + thumb_err("listen failed : %s", strerror(errno)); + } + + thumb_dbg("Listening..."); +#endif + + *sock_fd = sock; + + return TRUE; +} + |