4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyunjun Ko <zzoon.ko@samsung.com>, Haejeong Kim <backto.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
25 * This file defines structure and functions related to database.
27 * @file audio-svc-utils.c
29 * @brief This file defines utilities for Audio Service.
37 #include <sys/types.h>
44 #include <glib/gstdio.h>
45 #include <drm-service-types.h>
46 #include <drm-service.h>
48 #include "audio-svc-debug.h"
49 #include "audio-svc-error.h"
50 #include "audio-svc-utils.h"
51 #include "audio-svc.h"
52 #include "audio-svc-types-priv.h"
53 #include "media-svc-hash.h"
55 #define AUDIO_SVC_PARENTAL_RATING_LEN 20
56 #define AUDIO_SVC_FILE_EXT_LEN_MAX 6 /**< Maximum file ext lenth*/
59 AUDIO_SVC_EXTRACTED_FIELD_NONE = 0x00000001,
60 AUDIO_SVC_EXTRACTED_FIELD_TITLE = AUDIO_SVC_EXTRACTED_FIELD_NONE << 1,
61 AUDIO_SVC_EXTRACTED_FIELD_DESC = AUDIO_SVC_EXTRACTED_FIELD_NONE << 2,
62 AUDIO_SVC_EXTRACTED_FIELD_COPYRIGHT = AUDIO_SVC_EXTRACTED_FIELD_NONE << 3,
63 AUDIO_SVC_EXTRACTED_FIELD_AUTHOR = AUDIO_SVC_EXTRACTED_FIELD_NONE << 4,
64 AUDIO_SVC_EXTRACTED_FIELD_ARTIST = AUDIO_SVC_EXTRACTED_FIELD_NONE << 5,
65 AUDIO_SVC_EXTRACTED_FIELD_GENRE = AUDIO_SVC_EXTRACTED_FIELD_NONE << 6,
66 AUDIO_SVC_EXTRACTED_FIELD_ALBUM = AUDIO_SVC_EXTRACTED_FIELD_NONE << 7,
67 AUDIO_SVC_EXTRACTED_FIELD_TRACKNUM = AUDIO_SVC_EXTRACTED_FIELD_NONE << 8,
68 AUDIO_SVC_EXTRACTED_FIELD_YEAR = AUDIO_SVC_EXTRACTED_FIELD_NONE << 9,
69 AUDIO_SVC_EXTRACTED_FIELD_CATEGORY = AUDIO_SVC_EXTRACTED_FIELD_NONE << 10,
70 } audio_svc_extracted_field_e;
72 static bool __audio_svc_get_file_ext (const char *file_path, char *file_ext);
73 static int __save_thumbnail(void *image, int size, char *thumb_path);
75 static bool __audio_svc_get_file_ext (const char *file_path, char *file_ext)
79 for (i = strlen(file_path); i >= 0; i--) {
80 if (file_path[i] == '.') {
81 _strncpy_safe(file_ext, &file_path[i+1], AUDIO_SVC_FILE_EXT_LEN_MAX);
85 if (file_path[i] == '/') {
92 static int __save_thumbnail(void *image, int size, char *thumb_path)
94 audio_svc_debug("start save thumbnail, path: %s", thumb_path);
96 audio_svc_error("invalid image..");
97 return AUDIO_SVC_ERROR_INVALID_PARAMETER;
101 if (-1 == statfs(AUDIO_SVC_THUMB_PATH_PREFIX, &fs)) {
102 audio_svc_error("error in statfs");
103 return AUDIO_SVC_ERROR_INTERNAL;
106 long bsize_kbytes = fs.f_bsize >> 10;
108 if ((bsize_kbytes * fs.f_bavail) < 1024) {
109 audio_svc_error("not enought space...");
110 return AUDIO_SVC_ERROR_INTERNAL;
115 if (image != NULL && size > 0) {
116 fp = fopen(thumb_path, "w");
119 audio_svc_error("failed to open file");
120 return AUDIO_SVC_ERROR_INTERNAL;
122 audio_svc_debug("image size = [%d]", size);
124 nwrite = fwrite(image, 1, size, fp);
125 if (nwrite != size) {
126 audio_svc_error("failed to write thumbnail");
128 return AUDIO_SVC_ERROR_INTERNAL;
133 audio_svc_debug("save thumbnail success!!");
135 return AUDIO_SVC_ERROR_NONE;
138 int _audio_svc_extract_metadata_audio(audio_svc_storage_type_e storage_type, const char *path, audio_svc_audio_item_s *item)
140 MMHandleType content = 0;
141 MMHandleType tag = 0;
145 int extracted_field = AUDIO_SVC_EXTRACTED_FIELD_NONE;
147 bool thumb_extracted_from_drm = FALSE;
148 char *err_attr_name = NULL;
151 bool extract_thumbnail = FALSE;
153 char *thumbnail_path = NULL;
155 int artwork_mime_size = -1;
157 _strncpy_safe(item->pathname, path, sizeof(item->pathname));
158 item->storage_type = storage_type;
160 if (drm_svc_is_drm_file(item->pathname)) {
161 bool invalid_file = FALSE;
163 DRM_FILE_TYPE type = drm_svc_get_drm_type(item->pathname);
165 if (type == DRM_FILE_TYPE_OMA) {
166 drm_dcf_header_t header_info;
167 memset(&header_info, 0, sizeof(drm_dcf_header_t));
168 audio_svc_debug("drm type is OMA");
170 if (drm_svc_get_dcf_header_info(item->pathname, &header_info) != DRM_RESULT_SUCCESS) {
171 audio_svc_debug("cannot get dcf header info. just get the title");
172 title = _audio_svc_get_title_from_filepath(item->pathname);
174 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
177 audio_svc_error("Can't extract title from filepath");
178 return AUDIO_SVC_ERROR_INTERNAL;
181 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
182 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
183 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
184 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
185 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
187 return AUDIO_SVC_ERROR_NONE;
190 if (drm_svc_has_valid_ro(item->pathname, DRM_PERMISSION_PLAY) != DRM_RESULT_SUCCESS) {
191 audio_svc_debug("no valid ro. can't extract meta data");
195 if (header_info.version == DRM_OMA_DRMV1_RIGHTS) {
196 audio_svc_debug("DRM V1");
199 if (strlen(header_info.headerUnion.headerV1.contentName) > 0) {
200 _strncpy_safe(item->audio.title, header_info.headerUnion.headerV1.contentName, sizeof(item->audio.title));
201 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_TITLE;
202 audio_svc_debug("extract title from DCF");
205 if (strlen(header_info.headerUnion.headerV1.contentDescription) > 0) {
206 _strncpy_safe(item->audio.description, header_info.headerUnion.headerV1.contentDescription, sizeof(item->audio.description));
207 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_DESC;
208 audio_svc_debug("extract description from DCF");
211 } else if (header_info.version == DRM_OMA_DRMV2_RIGHTS) {
212 drm_user_data_common_t metadata;
215 audio_svc_debug("DRM V2");
217 if (drm_svc_get_user_data_box_info(item->audio.title, DRM_UDTA_TITLE, &metadata) == DRM_RESULT_SUCCESS) {
218 _strncpy_safe(item->audio.title, metadata.subBox.title.str, sizeof(item->audio.title));
219 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_TITLE;
220 audio_svc_debug("extract title from odf");
223 if (drm_svc_get_user_data_box_info(item->audio.description, DRM_UDTA_DESCRIPTION, &metadata) == DRM_RESULT_SUCCESS) {
224 _strncpy_safe(item->audio.description, metadata.subBox.desc.str, sizeof(item->audio.description));
225 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_DESC;
228 if (drm_svc_get_user_data_box_info(item->audio.copyright, DRM_UDTA_COPYRIGHT, &metadata) == DRM_RESULT_SUCCESS) {
229 _strncpy_safe(item->audio.copyright, metadata.subBox.copyright.str, sizeof(item->audio.copyright));
230 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_COPYRIGHT;
233 if (drm_svc_get_user_data_box_info(item->audio.author, DRM_UDTA_AUTHOR, &metadata) == DRM_RESULT_SUCCESS) {
234 _strncpy_safe(item->audio.author, metadata.subBox.author.str, sizeof(item->audio.author));
235 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_AUTHOR;
238 if (drm_svc_get_user_data_box_info(item->audio.artist, DRM_UDTA_PERFORMER, &metadata) == DRM_RESULT_SUCCESS) {
239 _strncpy_safe(item->audio.artist, metadata.subBox.performer.str, sizeof(item->audio.artist));
240 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_ARTIST;
243 if (drm_svc_get_user_data_box_info(item->audio.genre, DRM_UDTA_GENRE, &metadata) == DRM_RESULT_SUCCESS) {
244 _strncpy_safe(item->audio.genre, metadata.subBox.genre.str, sizeof(item->audio.genre));
245 audio_svc_debug("genre : %s", item->audio.genre);
246 if ((strcasecmp("Ringtone", metadata.subBox.genre.str) == 0) | (strcasecmp("Alert tone", metadata.subBox.genre.str) == 0)) {
247 item->category = AUDIO_SVC_CATEGORY_SOUND;
249 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_GENRE;
252 if (drm_svc_get_user_data_box_info(item->audio.album, DRM_UDTA_ALBUM, &metadata) == DRM_RESULT_SUCCESS) {
253 _strncpy_safe(item->audio.album, metadata.subBox.album.albumTitle, sizeof(item->audio.album));
254 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_ALBUM;
255 item->audio.track = (int)metadata.subBox.album.trackNum;
258 if (drm_svc_get_user_data_box_info(item->audio.year, DRM_UDTA_RECODINGYEAR, &metadata) == DRM_RESULT_SUCCESS) {
259 _strncpy_safe(item->audio.year, _year_2_str(metadata.subBox.recodingYear.recodingYear), sizeof(item->audio.year));
260 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_YEAR;
263 if (drm_svc_get_index_of_relative_contents(item->thumbname, DRM_CONTENTS_INDEX_ALBUMJACKET, &type_index) == DRM_RESULT_SUCCESS) {
264 char thumb_path[AUDIO_SVC_PATHNAME_SIZE+1] = {0};
266 if (drm_svc_make_multipart_drm_full_path(item->pathname, type_index, AUDIO_SVC_PATHNAME_SIZE, thumb_path) == DRM_TRUE) {
268 DRM_FILE_HANDLE hFile = DRM_HANDLE_NULL;
270 audio_svc_debug("drm image path : %s", thumb_path);
272 if (drm_svc_open_file(thumb_path, DRM_PERMISSION_ANY, &hFile) == DRM_RESULT_SUCCESS) {
275 if (drm_svc_seek_file(hFile, 0, DRM_SEEK_END) != DRM_RESULT_SUCCESS) {
278 thumb_size = drm_svc_tell_file(hFile);
280 if (drm_svc_seek_file(hFile, 0, DRM_SEEK_SET) != DRM_RESULT_SUCCESS) {
283 /* remove thumbnail extract routine in db creating time.
284 audio_svc_debug("drm thumb size : %d", thumb_size);
285 if (thumb_size > 0) {
286 unsigned int readSize = 0;
288 thumb_buffer = malloc(thumb_size);
289 if (drm_svc_read_file(hFile, thumb_buffer,thumb_size, &readSize) != DRM_RESULT_SUCCESS) {
290 SAFE_FREE(thumb_buffer);
294 __save_thumbnail(thumb_buffer, readSize, 1, item);
295 SAFE_FREE(thumb_buffer);
296 thumb_extracted_from_drm = TRUE;
300 drm_svc_free_dcf_header_info(&header_info);
301 drm_svc_close_file(hFile);
306 audio_svc_debug("unsupported drm format");
307 drm_svc_free_dcf_header_info(&header_info);
308 title = _audio_svc_get_title_from_filepath(item->pathname);
310 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
313 audio_svc_error("Can't extract title from filepath");
314 return AUDIO_SVC_ERROR_INTERNAL;
317 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
318 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
319 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
320 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
321 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
323 return AUDIO_SVC_ERROR_NONE;
326 if (invalid_file == TRUE) {
327 if (!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_TITLE)) {
328 title = _audio_svc_get_title_from_filepath(item->pathname);
330 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
331 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_TITLE;
334 audio_svc_error("Can't extract title from filepath");
335 drm_svc_free_dcf_header_info(&header_info);
336 return AUDIO_SVC_ERROR_INTERNAL;
339 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
340 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
341 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
342 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
343 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
346 drm_svc_free_dcf_header_info(&header_info);
347 return AUDIO_SVC_ERROR_NONE;
349 } else if (type == DRM_FILE_TYPE_PLAYREADY) {
350 audio_svc_debug("drm type is PLAYREADY");
351 if (drm_svc_has_valid_ro(item->pathname, DRM_PERMISSION_PLAY) != DRM_RESULT_SUCCESS) {
352 audio_svc_debug("no valid ro. can't extract meta data");
353 title = _audio_svc_get_title_from_filepath(item->pathname);
355 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
358 audio_svc_error("Can't extract title from filepath");
359 return AUDIO_SVC_ERROR_INTERNAL;
362 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
363 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
364 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
365 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
366 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
368 return AUDIO_SVC_ERROR_NONE;
371 audio_svc_error("Not supported DRM type");
372 title = _audio_svc_get_title_from_filepath(item->pathname);
374 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
377 audio_svc_error("Can't extract title from filepath");
378 return AUDIO_SVC_ERROR_INTERNAL;
381 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
382 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
383 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
384 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
385 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
387 return AUDIO_SVC_ERROR_NONE;
391 mmf_error = mm_file_create_content_attrs(&content, item->pathname);
393 if (mmf_error == 0) {
397 mmf_error = mm_file_get_attrs(content, &err_attr_name, MM_FILE_CONTENT_AUDIO_BITRATE, &item->audio.bitrate, NULL);
398 if (mmf_error != 0) {
399 SAFE_FREE(err_attr_name);
400 audio_svc_debug("fail to get audio bitrate attr - err(%x)", mmf_error);
402 audio_svc_debug("bit rate : %d", item->audio.bitrate);
404 mmf_error = mm_file_get_attrs(content, &err_attr_name, MM_FILE_CONTENT_DURATION, &item->audio.duration, NULL);
405 if (mmf_error != 0) {
406 SAFE_FREE(err_attr_name);
407 audio_svc_debug("fail to get duration attr - err(%x)", mmf_error);
409 audio_svc_debug("duration : %d", item->audio.duration);
411 mmf_error = mm_file_get_attrs(content, &err_attr_name, MM_FILE_CONTENT_AUDIO_SAMPLERATE, &sample_rate, NULL);
412 if (mmf_error != 0) {
413 SAFE_FREE(err_attr_name);
414 audio_svc_debug("fail to get sample rate attr - err(%x)", mmf_error);
416 audio_svc_debug("sample rate : %d", sample_rate);
418 mmf_error = mm_file_get_attrs(content, &err_attr_name, MM_FILE_CONTENT_AUDIO_CHANNELS, &channels, NULL);
419 if (mmf_error != 0) {
420 SAFE_FREE(err_attr_name);
421 audio_svc_debug("fail to get audio channels attr - err(%x)", mmf_error);
423 audio_svc_debug("channel : %d", channels);
428 * example : 3GPP stereo HE-AAC 48kbps 44.1kHz
429 * example : 128kbps 44.1kHz 2 Channels
430 * example : 128kpbs 44.1kHz 2ch
433 if (item->audio.bitrate > 0 && sample_rate > 0) {
434 snprintf(item->audio.format, sizeof(item->audio.format) - 1,
435 "%dkbps %.1fkHz %dch",
436 item->audio.bitrate / 1000, sample_rate / 1000.0, channels);
437 } else if (item->audio.bitrate > 0) {
438 snprintf(item->audio.format, sizeof(item->audio.format) - 1,
440 item->audio.bitrate / 1000, channels);
441 } else if (sample_rate > 0) {
442 snprintf(item->audio.format, sizeof(item->audio.format) - 1,
444 sample_rate / 1000.0, channels);
447 audio_svc_debug("format : %s", item->audio.format);
448 mmf_error = mm_file_destroy_content_attrs(content);
449 if (mmf_error != 0) {
450 audio_svc_debug("fail to free content attr - err(%x)", mmf_error);
453 audio_svc_debug("no contents information");
456 mmf_error = mm_file_create_tag_attrs(&tag, item->pathname);
458 if (mmf_error == 0) {
459 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_ALBUM, &p, &size, NULL);
460 if ((!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_ALBUM)) && mmf_error == 0 && size > 0) {
461 _strncpy_safe(item->audio.album, p, sizeof(item->audio.album));
462 audio_svc_debug("album[%d] : %s", size, item->audio.album);
464 SAFE_FREE(err_attr_name);
465 audio_svc_debug("album - unknown");
466 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
469 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_ARTIST, &p, &size, NULL);
470 if ((!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_ARTIST)) && mmf_error == 0 && size > 0) {
471 _strncpy_safe(item->audio.artist, p, sizeof(item->audio.artist));
472 audio_svc_debug("artist[%d] : %s", size, item->audio.artist);
474 SAFE_FREE(err_attr_name);
475 audio_svc_debug("artist - unknown");
476 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
479 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_GENRE, &p, &size, NULL);
480 if ((!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_GENRE)) && mmf_error == 0 && size > 0) {
481 _strncpy_safe(item->audio.genre, p, sizeof(item->audio.genre));
482 audio_svc_debug("genre : %s", item->audio.genre);
483 if ((strcasecmp("Ringtone", p) == 0) | (strcasecmp("Alert tone", p) == 0)) {
484 item->category = AUDIO_SVC_CATEGORY_SOUND;
487 SAFE_FREE(err_attr_name);
488 audio_svc_debug("genre - unknown");
489 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
492 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_TITLE, &p, &size, NULL);
493 if ((!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_TITLE)) && mmf_error == 0 && size > 0 && (!isspace(*p))) {
494 _strncpy_safe(item->audio.title, p, sizeof(item->audio.title));
495 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_TITLE;
496 audio_svc_debug("extract title from content : %s", item->audio.title);
497 audio_svc_debug("^^^^^^^^^^^^^^^ path = %s, title = %s, size = %d ^^^^^^^^^^^^^^", path, item->audio.title, size);
499 SAFE_FREE(err_attr_name);
501 title = _audio_svc_get_title_from_filepath(item->pathname);
503 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
506 audio_svc_error("Can't extract title from filepath");
507 return AUDIO_SVC_ERROR_INTERNAL;
511 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_DESCRIPTION, &p, &size, NULL);
512 if ((!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_DESC)) && mmf_error == 0 && size > 0) {
513 _strncpy_safe(item->audio.description, p, sizeof(item->audio.description));
514 audio_svc_debug("desc : %s", item->audio.description);
516 SAFE_FREE(err_attr_name);
519 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_AUTHOR, &p, &size, NULL);
520 if ((!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_AUTHOR)) && mmf_error == 0 && size > 0) {
521 _strncpy_safe(item->audio.author, p, sizeof(item->audio.author));
522 extracted_field |= AUDIO_SVC_EXTRACTED_FIELD_AUTHOR;
523 audio_svc_debug("extract author from content : %s", item->audio.author);
525 audio_svc_debug("author - unknown");
526 SAFE_FREE(err_attr_name);
527 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
530 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_TRACK_NUM, &p, &size, NULL);
531 if (mmf_error == 0 && size > 0) {
532 item->audio.track = atoi(p);
534 SAFE_FREE(err_attr_name);
535 item->audio.track = -1;
537 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_DATE, &p, &size, NULL);
538 if (!(extracted_field & AUDIO_SVC_EXTRACTED_FIELD_YEAR)) {
539 if (mmf_error == 0 && size > 0) {
540 _strncpy_safe(item->audio.year, p, sizeof(item->audio.year));
542 SAFE_FREE(err_attr_name);
543 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
546 SAFE_FREE(err_attr_name);
549 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_RATING, &p, &size, NULL);
550 if (mmf_error == 0 && size > 0) {
551 _strncpy_safe(item->audio.parental_rating, p, sizeof(item->audio.parental_rating));
553 SAFE_FREE(err_attr_name);
556 /* extract thumbnail image */
557 /* remove thumbnail extract routine while db creating.*/
559 album_id = _audio_svc_get_album_id(item->audio.album);
561 audio_svc_debug("album does not exist. So start to make album art");
562 extract_thumbnail = TRUE;
564 audio_svc_debug("album already exists. don't need to make album art");
565 thumbnail_path = _audio_svc_get_thumbnail_path_by_album_id(album_id);
566 _strncpy_safe(item->thumbname, thumbnail_path, sizeof(item->thumbname));
567 SAFE_FREE(thumbnail_path);
570 if ((!thumb_extracted_from_drm)/* && (extract_thumbnail == TRUE)*/) {
571 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_ARTWORK, &image, &size, NULL);
572 if (mmf_error != 0) {
573 audio_svc_debug("fail to get tag artwork - err(%x)", mmf_error);
574 SAFE_FREE(err_attr_name);
576 audio_svc_debug("artwork size1 [%d]", size);
579 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_ARTWORK_SIZE, &size, NULL);
580 if (mmf_error != 0) {
581 audio_svc_debug("fail to get artwork size - err(%x)", mmf_error);
582 SAFE_FREE(err_attr_name);
584 audio_svc_debug("artwork size2 [%d]", size);
586 if (image != NULL && size > 0) {
588 int result = AUDIO_SVC_ERROR_NONE;
589 char thumb_path[AUDIO_SVC_PATHNAME_SIZE] = "\0";
590 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_ARTWORK_MIME, &p, &artwork_mime_size, NULL);
591 if (mmf_error == 0 && artwork_mime_size > 0) {
592 ret = _audio_svc_get_thumbnail_path(storage_type, thumb_path, item->pathname, p);
594 audio_svc_error("fail to get thumb path..");
595 mmf_error = mm_file_destroy_tag_attrs(tag);
596 if (mmf_error != 0) {
597 audio_svc_error("fail to free tag attr - err(%x)", mmf_error);
599 return AUDIO_SVC_ERROR_INTERNAL;
602 SAFE_FREE(err_attr_name);
605 if (!strlen(thumb_path)) {
606 audio_svc_error("fail to get thumb path..");
607 mmf_error = mm_file_destroy_tag_attrs(tag);
608 if (mmf_error != 0) {
609 audio_svc_error("fail to free tag attr - err(%x)", mmf_error);
611 return AUDIO_SVC_ERROR_INTERNAL;
614 result = __save_thumbnail(image, size, thumb_path);
615 if (result != AUDIO_SVC_ERROR_NONE) {
616 mmf_error = mm_file_destroy_tag_attrs(tag);
617 if (mmf_error != 0) {
618 audio_svc_error("fail to free tag attr - err(%x)", mmf_error);
623 _strncpy_safe(item->thumbname, thumb_path, sizeof(item->thumbname));
627 mmf_error = mm_file_destroy_tag_attrs(tag);
628 if (mmf_error != 0) {
629 audio_svc_error("fail to free tag attr - err(%x)", mmf_error);
633 audio_svc_error("no tag information");
635 title = _audio_svc_get_title_from_filepath(item->pathname);
637 _strncpy_safe(item->audio.title, title, sizeof(item->audio.title));
640 audio_svc_error("Can't extract title from filepath");
641 return AUDIO_SVC_ERROR_INTERNAL;
644 /* in case of file size 0, MMFW Can't parsting tag info but add it to Music DB. */
645 _strncpy_safe(item->audio.album, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.album));
646 _strncpy_safe(item->audio.artist, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.artist));
647 _strncpy_safe(item->audio.genre, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.genre));
648 _strncpy_safe(item->audio.author, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.author));
649 _strncpy_safe(item->audio.year, AUDIO_SVC_TAG_UNKNOWN, sizeof(item->audio.year));
652 return AUDIO_SVC_ERROR_NONE;
655 bool _audio_svc_possible_to_extract_title_from_file(const char *path)
657 MMHandleType tag = 0;
661 char *err_attr_name = NULL;
663 if (drm_svc_is_drm_file(path)) {
664 DRM_FILE_TYPE type = drm_svc_get_drm_type(path);
666 if (type == DRM_FILE_TYPE_OMA) {
667 drm_dcf_header_t header_info;
669 memset(&header_info, 0, sizeof(drm_dcf_header_t));
671 if (drm_svc_get_dcf_header_info(path, &header_info) == DRM_RESULT_SUCCESS) {
672 if (header_info.version == DRM_OMA_DRMV1_RIGHTS) {
674 if (drm_svc_has_valid_ro(path, DRM_PERMISSION_ANY) != DRM_RESULT_SUCCESS) {
675 if (strlen(header_info.headerUnion.headerV1.contentName) > 0) {
683 } else if (header_info.version == DRM_OMA_DRMV2_RIGHTS) {
685 drm_user_data_common_t metadata;
687 if (drm_svc_get_user_data_box_info(path, DRM_UDTA_TITLE, &metadata) == DRM_RESULT_SUCCESS) {
693 audio_svc_debug("unsupported drm format");
696 drm_svc_free_dcf_header_info(&header_info);
699 } else if (type == DRM_FILE_TYPE_PLAYREADY) {
700 audio_svc_debug("drm type is PLAYREADY");
701 if (drm_svc_has_valid_ro(path, DRM_PERMISSION_PLAY) != DRM_RESULT_SUCCESS) {
702 audio_svc_debug("no valid ro. can't extract meta data");
705 audio_svc_error("Not supported DRM type");
710 err = mm_file_create_tag_attrs(&tag, path);
713 err = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_TITLE, &p, &size, NULL);
714 if (err == 0 && size > 0) {
715 mm_file_destroy_tag_attrs(tag);
718 SAFE_FREE(err_attr_name);
719 mm_file_destroy_tag_attrs(tag);
726 char *_audio_svc_get_title_from_filepath (const char *path)
728 char *filename = NULL;
731 int filename_len = -1;
732 int new_title_len = -1;
734 audio_svc_debug("title tag doesn't exist, so get from file path");
737 audio_svc_error("path is NULL");
741 filename = g_path_get_basename(path);
742 if ((filename == NULL) || (strlen(filename) < 1)) {
743 audio_svc_error("wrong file name");
748 filename_len = strlen(filename);
750 ext = g_strrstr(filename, ".");
752 audio_svc_error("there is no file extention");
756 new_title_len = filename_len - strlen(ext);
757 if (new_title_len < 1) {
758 audio_svc_error("title length is zero");
763 title = g_strndup(filename, new_title_len < AUDIO_SVC_PATHNAME_SIZE ? new_title_len : AUDIO_SVC_PATHNAME_SIZE-1);
767 audio_svc_debug("extract title is [%s]", title);
772 void _audio_svc_get_parental_rating(const char *path, char *parental_rating)
774 MMHandleType tag = 0;
778 char *err_attr_name = NULL;
780 if (mm_file_create_tag_attrs(&tag, path) == 0) {
781 mmf_error = mm_file_get_attrs(tag, &err_attr_name, MM_FILE_TAG_RATING, &p, &size, NULL);
782 if (mmf_error == 0 && size > 1) {
783 _strncpy_safe(parental_rating, p, AUDIO_SVC_PARENTAL_RATING_LEN);
784 audio_svc_debug("parental rating : %s, %d", parental_rating, size);
786 SAFE_FREE(err_attr_name);
789 mm_file_destroy_tag_attrs(tag);
794 int _audio_svc_remove_all_files_in_dir(const char *dir_path)
796 struct dirent *entry = NULL;
798 char filename[AUDIO_SVC_PATHNAME_SIZE] = {0};
801 dir = opendir(dir_path);
803 audio_svc_error("%s is not exist", dir_path);
804 return AUDIO_SVC_ERROR_INVALID_PARAMETER;
807 while ((entry = readdir(dir)) != NULL) {
808 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
811 snprintf(filename, sizeof(filename), "%s/%s", dir_path, entry->d_name);
813 if (stat(filename, &st) != 0) {
816 if (S_ISDIR(st.st_mode)) {
819 if (unlink(filename) != 0) {
820 audio_svc_error("failed to remove : %s", filename);
822 return AUDIO_SVC_ERROR_INTERNAL;
827 return AUDIO_SVC_ERROR_NONE;
830 bool _audio_svc_get_thumbnail_path(audio_svc_storage_type_e storage_type, char *thumb_path, const char *pathname, const char *img_format)
832 char savename[AUDIO_SVC_PATHNAME_SIZE] = {0};
833 char file_ext[AUDIO_SVC_FILE_EXT_LEN_MAX + 1] = {0};
834 char *thumb_dir = NULL;
836 char *thumbfile_ext = NULL;
838 thumb_dir = (storage_type == AUDIO_SVC_STORAGE_PHONE) ? AUDIO_SVC_THUMB_PHONE_PATH : AUDIO_SVC_THUMB_MMC_PATH;
840 memset(file_ext, 0, sizeof(file_ext));
841 if (!__audio_svc_get_file_ext(pathname, file_ext)) {
842 audio_svc_error("get file ext fail");
847 err = mb_svc_generate_hash_code(pathname, hash, sizeof(hash));
849 audio_svc_error("mb_svc_generate_hash_code failed : %d", err);
853 audio_svc_debug("img format is [%s]", img_format);
855 if((strstr(img_format, "jpeg") != NULL) || (strstr(img_format, "jpg") != NULL)) {
856 thumbfile_ext = "jpg";
857 } else if(strstr(img_format, "png") != NULL) {
858 thumbfile_ext = "png";
859 } else if(strstr(img_format, "gif") != NULL) {
860 thumbfile_ext = "gif";
861 } else if(strstr(img_format, "bmp") != NULL) {
862 thumbfile_ext = "bmp";
864 audio_svc_error("Not proper img format");
868 snprintf(savename, sizeof(savename), "%s/.%s-%s.%s", thumb_dir, file_ext, hash, thumbfile_ext);
869 _strncpy_safe(thumb_path, savename, AUDIO_SVC_PATHNAME_SIZE);
870 audio_svc_debug("thumb_path is [%s]", thumb_path);
875 int _audio_svc_get_drm_mime_type(const char *path, char *mime_type)
877 drm_content_info_t contentInfo;
880 audio_svc_error("path is NULL");
881 return AUDIO_SVC_ERROR_INVALID_PARAMETER;
884 if (drm_svc_get_content_info(path, &contentInfo) == DRM_RESULT_SUCCESS) {
885 if (strlen(contentInfo.contentType) == 0) {
886 audio_svc_error("contentType is NULL");
887 return AUDIO_SVC_ERROR_INVALID_MEDIA;
889 snprintf(mime_type, sizeof(contentInfo.contentType), "%s", (char *)contentInfo.contentType);
892 audio_svc_error("Error in drm_service");
893 return AUDIO_SVC_ERROR_INVALID_MEDIA;
896 return AUDIO_SVC_ERROR_NONE;
899 char *_year_2_str(int year)
902 static char ret[AUDIO_SVC_METADATA_LEN_MAX];
903 if (year == -1 || year == 0) {
904 _strncpy_safe(ret, AUDIO_SVC_TAG_UNKNOWN, AUDIO_SVC_METADATA_LEN_MAX);
906 snprintf(ret, AUDIO_SVC_METADATA_LEN_MAX - 1, "%d", year);
911 void _strncpy_safe(char *x_dst, const char *x_src, int max_len)
913 if (!x_src || strlen(x_src) == 0) {
914 audio_svc_error("x_src is NULL");
919 audio_svc_error("length is Wrong");
923 strncpy(x_dst, x_src, max_len-1);
924 x_dst[max_len-1] = '\0';
927 void _strlcat_safe(char *x_dst, char *x_src, int max_len)
929 if (!x_src || strlen(x_src) == 0) {
930 audio_svc_error("x_src is NULL");
935 audio_svc_error("length is Wrong");
939 g_strlcat(x_dst, x_src, max_len-1);
940 x_dst[max_len-1] = '\0';
943 bool _audio_svc_copy_file(const char *srcPath, const char *destPath)
947 char buff[4096] = {0};
951 bool remove_dest = false;
953 fs = fopen(srcPath, "rb");
955 audio_svc_error("failed to open source file: %s", srcPath);
960 fd = fopen(destPath, "wb");
962 audio_svc_error("failed to open dest file: %s", destPath);
972 n = fread(buff, sizeof(char), sizeof(buff), fs);
973 if (n > 0 && n <= sizeof(buff)) {
974 m = fwrite(buff, sizeof(char), n, fd);
976 audio_svc_debug("fwrite = %d \n", m);
983 audio_svc_debug("fread = %d \n", n);
1004 audio_svc_debug("copying file is successful");
1008 bool _audio_svc_make_file(const char *path)
1012 fd = fopen(path, "w");
1014 audio_svc_error("failed to open file: [%s]", path);
1023 bool _audio_svc_remove_file(const char *path)
1027 result = remove(path);
1029 audio_svc_debug("success to remove file");
1032 audio_svc_error("fail to remove file result = %d", result);
1037 bool _audio_svc_make_directory(const char *path)
1041 /* Returns : 0 if the directory already exists, or was successfully created. Returns -1 if an error occurred, with errno set. */
1042 result = g_mkdir_with_parents(path, 0755);
1044 audio_svc_debug("success to make directory");
1047 audio_svc_error("fail to make directory result = %d", result);
1052 unsigned int _audio_svc_print_elapse_time(int start_time, const char *log_msg)
1055 unsigned int tval = 0;
1056 gettimeofday(&t, NULL);
1058 tval = t.tv_sec*1000000L + t.tv_usec;
1060 if (start_time == 0) {
1061 printf("[%s] start [%u]\n", log_msg, tval);
1063 printf("[%s] elapsed time [%u]\n", log_msg, tval - start_time);
1069 int _audio_svc_get_order_field_str(audio_svc_search_order_e order_field,
1073 if (output_str == NULL) {
1074 audio_svc_debug("output str is NULL");
1075 return AUDIO_SVC_ERROR_INTERNAL;
1078 switch(order_field) {
1079 case AUDIO_SVC_ORDER_BY_TITLE_DESC:
1080 _strncpy_safe(output_str, "title COLLATE NOCASE DESC", len);
1082 case AUDIO_SVC_ORDER_BY_TITLE_ASC:
1083 _strncpy_safe(output_str, "title COLLATE NOCASE ASC", len);
1085 case AUDIO_SVC_ORDER_BY_ALBUM_DESC:
1086 _strncpy_safe(output_str, "album COLLATE NOCASE DESC", len);
1088 case AUDIO_SVC_ORDER_BY_ALBUM_ASC:
1089 _strncpy_safe(output_str, "album COLLATE NOCASE ASC", len);
1091 case AUDIO_SVC_ORDER_BY_ARTIST_DESC:
1092 _strncpy_safe(output_str, "artist COLLATE NOCASE DESC", len);
1094 case AUDIO_SVC_ORDER_BY_ARTIST_ASC:
1095 _strncpy_safe(output_str, "artist COLLATE NOCASE ASC", len);
1097 case AUDIO_SVC_ORDER_BY_GENRE_DESC:
1098 _strncpy_safe(output_str, "genre COLLATE NOCASE DESC", len);
1100 case AUDIO_SVC_ORDER_BY_GENRE_ASC:
1101 _strncpy_safe(output_str, "genre COLLATE NOCASE ASC", len);
1103 case AUDIO_SVC_ORDER_BY_AUTHOR_DESC:
1104 _strncpy_safe(output_str, "author COLLATE NOCASE DESC", len);
1106 case AUDIO_SVC_ORDER_BY_AUTHOR_ASC:
1107 _strncpy_safe(output_str, "author COLLATE NOCASE ASC", len);
1109 case AUDIO_SVC_ORDER_BY_PLAY_COUNT_DESC:
1110 _strncpy_safe(output_str, "played_count DESC", len);
1112 case AUDIO_SVC_ORDER_BY_PLAY_COUNT_ASC:
1113 _strncpy_safe(output_str, "played_count ASC", len);
1115 case AUDIO_SVC_ORDER_BY_ADDED_TIME_DESC:
1116 _strncpy_safe(output_str, "added_time DESC", len);
1118 case AUDIO_SVC_ORDER_BY_ADDED_TIME_ASC:
1119 _strncpy_safe(output_str, "added_time ASC", len);
1124 return AUDIO_SVC_ERROR_NONE;
1127 int _audio_svc_get_file_dir_modified_date(const char *full_path)
1129 struct stat statbuf;
1132 memset(&statbuf, 0, sizeof(struct stat));
1133 fd = stat(full_path, &statbuf);
1135 audio_svc_debug("stat(%s) fails.", full_path);
1136 return AUDIO_SVC_ERROR_INTERNAL;
1139 return statbuf.st_mtime;