1/* MiniDLNA media server 2 * Copyright (C) 2008-2009 Justin Maggard 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18#include <stdio.h> 19#include <ctype.h> 20#include <string.h> 21#include <stdlib.h> 22#include <sys/stat.h> 23 24#include <unistd.h> 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <fcntl.h> 28 29#include <libexif/exif-loader.h> 30#include "image_utils.h" 31#include <jpeglib.h> 32#include <setjmp.h> 33#include <avutil.h> 34#include <avcodec.h> 35#include <avformat.h> 36#include "tagutils/tagutils.h" 37 38#include "upnpglobalvars.h" 39#include "upnpreplyparse.h" 40#include "metadata.h" 41#include "albumart.h" 42#include "utils.h" 43#include "sql.h" 44#include "log.h" 45 46#define FLAG_TITLE 0x00000001 47#define FLAG_ARTIST 0x00000002 48#define FLAG_ALBUM 0x00000004 49#define FLAG_GENRE 0x00000008 50#define FLAG_COMMENT 0x00000010 51#define FLAG_CREATOR 0x00000020 52#define FLAG_DATE 0x00000040 53#define FLAG_DLNA_PN 0x00000080 54#define FLAG_MIME 0x00000100 55#define FLAG_DURATION 0x00000200 56#define FLAG_RESOLUTION 0x00000400 57#define FLAG_BITRATE 0x00000800 58#define FLAG_FREQUENCY 0x00001000 59#define FLAG_BPS 0x00002000 60#define FLAG_CHANNELS 0x00004000 61 62/* Audio profile flags */ 63enum audio_profiles { 64 PROFILE_AUDIO_UNKNOWN, 65 PROFILE_AUDIO_MP3, 66 PROFILE_AUDIO_AC3, 67 PROFILE_AUDIO_WMA_BASE, 68 PROFILE_AUDIO_WMA_FULL, 69 PROFILE_AUDIO_WMA_PRO, 70 PROFILE_AUDIO_MP2, 71 PROFILE_AUDIO_PCM, 72 PROFILE_AUDIO_AAC, 73 PROFILE_AUDIO_AAC_MULT5, 74 PROFILE_AUDIO_AMR 75}; 76 77/* This function shamelessly copied from libdlna */ 78#define MPEG_TS_SYNC_CODE 0x47 79#define MPEG_TS_PACKET_LENGTH_DLNA 192 /* prepends 4 bytes to TS packet */ 80int 81dlna_timestamp_is_present(const char * filename) 82{ 83 unsigned char buffer[2*MPEG_TS_PACKET_LENGTH_DLNA+1]; 84 int fd, i; 85 86 /* read file header */ 87 fd = open(filename, O_RDONLY); 88 read(fd, buffer, MPEG_TS_PACKET_LENGTH_DLNA*2); 89 close(fd); 90 for( i=0; i < MPEG_TS_PACKET_LENGTH_DLNA; i++ ) 91 { 92 if( buffer[i] == MPEG_TS_SYNC_CODE ) 93 { 94 if (buffer[i + MPEG_TS_PACKET_LENGTH_DLNA] == MPEG_TS_SYNC_CODE) 95 { 96 if (buffer[i] == 0x00 && buffer [i+1] == 0x00 && 97 buffer [i+2] == 0x00 && buffer [i+3] == 0x00) 98 { 99 break; 100 } 101 else 102 { 103 return 1; 104 } 105 } 106 } 107 } 108 return 0; 109} 110 111#ifdef TIVO_SUPPORT 112int 113is_tivo_file(const char * path) 114{ 115 unsigned char buf[5]; 116 unsigned char hdr[5] = { 'T','i','V','o','\0' }; 117 int fd; 118 119 /* read file header */ 120 fd = open(path, O_RDONLY); 121 read(fd, buf, 5); 122 close(fd); 123 124 return( !memcmp(buf, hdr, 5) ); 125} 126#endif 127 128/* This function taken from libavutil (ffmpeg), because it's not included with all versions of libavutil. */ 129int 130get_fourcc(const char *s) 131{ 132 return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); 133} 134 135void 136check_for_captions(const char * path, sqlite_int64 detailID) 137{ 138 char * sql; 139 char * file = malloc(PATH_MAX); 140 char **result; 141 int ret, rows; 142 143 sprintf(file, "%s", path); 144 strip_ext(file); 145 146 /* If we weren't given a detail ID, look for one. */ 147 if( !detailID ) 148 { 149 sql = sqlite3_mprintf("SELECT ID from DETAILS where PATH glob '%q.*'" 150 " and MIME glob 'video/*' limit 1", file); 151 ret = sql_get_table(db, sql, &result, &rows, NULL); 152 if( ret == SQLITE_OK ) 153 { 154 if( rows ) 155 { 156 detailID = strtoll(result[1], NULL, 10); 157 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like a caption file.\n", path); 158 } 159 /*else 160 { 161 DPRINTF(E_DEBUG, L_METADATA, "No file found for caption %s.\n", path); 162 }*/ 163 sqlite3_free_table(result); 164 } 165 sqlite3_free(sql); 166 if( !detailID ) 167 goto no_source_video; 168 } 169 170 strcat(file, ".srt"); 171 if( access(file, R_OK) == 0 ) 172 { 173 sql_exec(db, "INSERT into CAPTIONS" 174 " (ID, PATH) " 175 "VALUES" 176 " (%lld, %Q)", detailID, file); 177 } 178no_source_video: 179 free(file); 180} 181 182void 183parse_nfo(const char * path, metadata_t * m) 184{ 185 FILE *nfo; 186 char buf[65536]; 187 struct NameValueParserData xml; 188 struct stat file; 189 size_t nread; 190 char *val, *val2; 191 192 if( stat(path, &file) != 0 || 193 file.st_size > 65536 ) 194 { 195 DPRINTF(E_INFO, L_METADATA, "Not parsing very large .nfo file %s\n", path); 196 return; 197 } 198 DPRINTF(E_DEBUG, L_METADATA, "Parsing .nfo file: %s\n", path); 199 nfo = fopen(path, "r"); 200 if( !nfo ) 201 return; 202 nread = fread(&buf, 1, sizeof(buf), nfo); 203 204 ParseNameValue(buf, nread, &xml); 205 206 //printf("\ttype: %s\n", GetValueFromNameValueList(&xml, "rootElement")); 207 val = GetValueFromNameValueList(&xml, "title"); 208 if( val ) 209 { 210 val2 = GetValueFromNameValueList(&xml, "episodetitle"); 211 if( val2 ) 212 asprintf(&m->title, "%s - %s", val, val2); 213 else 214 m->title = strdup(val); 215 } 216 217 val = GetValueFromNameValueList(&xml, "plot"); 218 if( val ) 219 m->comment = strdup(val); 220 221 val = GetValueFromNameValueList(&xml, "capturedate"); 222 if( val ) 223 m->date = strdup(val); 224 225 ClearNameValueList(&xml); 226 fclose(nfo); 227} 228 229void 230free_metadata(metadata_t * m, uint32_t flags) 231{ 232 if( m->title && (flags & FLAG_TITLE) ) 233 free(m->title); 234 if( m->artist && (flags & FLAG_ARTIST) ) 235 free(m->artist); 236 if( m->album && (flags & FLAG_ALBUM) ) 237 free(m->album); 238 if( m->genre && (flags & FLAG_GENRE) ) 239 free(m->genre); 240 if( m->creator && (flags & FLAG_CREATOR) ) 241 free(m->creator); 242 if( m->date && (flags & FLAG_DATE) ) 243 free(m->date); 244 if( m->comment && (flags & FLAG_COMMENT) ) 245 free(m->comment); 246 if( m->dlna_pn && (flags & FLAG_DLNA_PN) ) 247 free(m->dlna_pn); 248 if( m->mime && (flags & FLAG_MIME) ) 249 free(m->mime); 250 if( m->duration && (flags & FLAG_DURATION) ) 251 free(m->duration); 252 if( m->resolution && (flags & FLAG_RESOLUTION) ) 253 free(m->resolution); 254 if( m->bitrate && (flags & FLAG_BITRATE) ) 255 free(m->bitrate); 256 if( m->frequency && (flags & FLAG_FREQUENCY) ) 257 free(m->frequency); 258 if( m->bps && (flags & FLAG_BPS) ) 259 free(m->bps); 260 if( m->channels && (flags & FLAG_CHANNELS) ) 261 free(m->channels); 262} 263 264sqlite_int64 265GetFolderMetadata(const char * name, const char * path, const char * artist, const char * genre, const char * album_art) 266{ 267 int ret; 268 269 ret = sql_exec(db, "INSERT into DETAILS" 270 " (TITLE, PATH, CREATOR, ARTIST, GENRE, ALBUM_ART) " 271 "VALUES" 272 " ('%q', %Q, %Q, %Q, %Q, %lld);", 273 name, path, artist, artist, genre, 274 album_art ? strtoll(album_art, NULL, 10) : 0); 275 if( ret != SQLITE_OK ) 276 ret = 0; 277 else 278 ret = sqlite3_last_insert_rowid(db); 279 280 return ret; 281} 282 283sqlite_int64 284GetAudioMetadata(const char * path, char * name) 285{ 286 char type[4]; 287 static char lang[6] = { '\0' }; 288 struct stat file; 289 sqlite_int64 ret; 290 char *esc_tag; 291 int i; 292 sqlite_int64 album_art = 0; 293 struct song_metadata song; 294 metadata_t m; 295 uint32_t free_flags = FLAG_MIME|FLAG_DURATION|FLAG_DLNA_PN|FLAG_DATE; 296 memset(&m, '\0', sizeof(metadata_t)); 297 298 if ( stat(path, &file) != 0 ) 299 return 0; 300 strip_ext(name); 301 302 if( ends_with(path, ".mp3") ) 303 { 304 strcpy(type, "mp3"); 305 m.mime = strdup("audio/mpeg"); 306 } 307 else if( ends_with(path, ".m4a") || ends_with(path, ".mp4") || 308 ends_with(path, ".aac") || ends_with(path, ".m4p") ) 309 { 310 strcpy(type, "aac"); 311 m.mime = strdup("audio/mp4"); 312 } 313 else if( ends_with(path, ".3gp") ) 314 { 315 strcpy(type, "aac"); 316 m.mime = strdup("audio/3gpp"); 317 } 318 else if( ends_with(path, ".wma") || ends_with(path, ".asf") ) 319 { 320 strcpy(type, "asf"); 321 m.mime = strdup("audio/x-ms-wma"); 322 } 323 else if( ends_with(path, ".flac") || ends_with(path, ".fla") || ends_with(path, ".flc") ) 324 { 325 strcpy(type, "flc"); 326 m.mime = strdup("audio/x-flac"); 327 } 328 else if( ends_with(path, ".wav") ) 329 { 330 strcpy(type, "wav"); 331 m.mime = strdup("audio/x-wav"); 332 } 333 else if( ends_with(path, ".ogg") ) 334 { 335 strcpy(type, "ogg"); 336 m.mime = strdup("application/ogg"); 337 } 338 else if( ends_with(path, ".pcm") ) 339 { 340 strcpy(type, "pcm"); 341 m.mime = strdup("audio/L16"); 342 } 343 else 344 { 345 DPRINTF(E_WARN, L_GENERAL, "Unhandled file extension on %s\n", path); 346 return 0; 347 } 348 349 if( !(*lang) ) 350 { 351 if( !getenv("LANG") ) 352 strcpy(lang, "en_US"); 353 else 354 strncpy(lang, getenv("LANG"), 5); 355 lang[5] = '\0'; 356 } 357 358 if( readtags((char *)path, &song, &file, lang, type) != 0 ) 359 { 360 DPRINTF(E_WARN, L_GENERAL, "Cannot extract tags from %s!\n", path); 361 freetags(&song); 362 free_metadata(&m, free_flags); 363 return 0; 364 } 365 366 if( song.dlna_pn ) 367 asprintf(&m.dlna_pn, "%s;DLNA.ORG_OP=01", song.dlna_pn); 368 if( song.year ) 369 asprintf(&m.date, "%04d-01-01", song.year); 370 asprintf(&m.duration, "%d:%02d:%02d.%03d", 371 (song.song_length/3600000), 372 (song.song_length/60000%60), 373 (song.song_length/1000%60), 374 (song.song_length%1000)); 375 m.title = song.title; 376 if( m.title && *m.title ) 377 { 378 m.title = trim(m.title); 379 if( (esc_tag = escape_tag(m.title)) ) 380 { 381 free_flags |= FLAG_TITLE; 382 m.title = esc_tag; 383 } 384 } 385 else 386 { 387 m.title = name; 388 } 389 for( i=ROLE_START; i<N_ROLE; i++ ) 390 { 391 if( song.contributor[i] && *song.contributor[i] ) 392 { 393 m.artist = trim(song.contributor[i]); 394 if( strlen(m.artist) > 48 ) 395 { 396 free_flags |= FLAG_ARTIST; 397 m.artist = strdup("Various Artists"); 398 } 399 else if( (esc_tag = escape_tag(m.artist)) ) 400 { 401 free_flags |= FLAG_ARTIST; 402 m.artist = esc_tag; 403 } 404 m.creator = m.artist; 405 break; 406 } 407 } 408 /* If there is a band associated with the album, use it for virtual containers. */ 409 if( (i != ROLE_BAND) && song.contributor[ROLE_BAND] && *song.contributor[ROLE_BAND] ) 410 { 411 m.creator = trim(song.contributor[ROLE_BAND]); 412 if( strlen(m.creator) > 48 ) 413 { 414 free_flags |= FLAG_CREATOR; 415 m.creator = strdup("Various Artists"); 416 } 417 else if( (esc_tag = escape_tag(m.creator)) ) 418 { 419 free_flags |= FLAG_CREATOR; 420 m.creator = esc_tag; 421 } 422 } 423 if( song.album && *song.album ) 424 { 425 m.album = trim(song.album); 426 if( (esc_tag = escape_tag(m.album)) ) 427 { 428 free_flags |= FLAG_ALBUM; 429 m.album = esc_tag; 430 } 431 } 432 if( song.genre && *song.genre ) 433 { 434 m.genre = trim(song.genre); 435 if( (esc_tag = escape_tag(m.genre)) ) 436 { 437 free_flags |= FLAG_GENRE; 438 m.genre = esc_tag; 439 } 440 } 441 if( song.comment && *song.comment ) 442 { 443 m.comment = trim(song.comment); 444 if( (esc_tag = escape_tag(m.comment)) ) 445 { 446 free_flags |= FLAG_COMMENT; 447 m.comment = esc_tag; 448 } 449 } 450 451 album_art = find_album_art(path, song.image, song.image_size); 452 453 ret = sql_exec(db, "INSERT into DETAILS" 454 " (PATH, SIZE, TIMESTAMP, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE," 455 " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, DISC, TRACK, DLNA_PN, MIME, ALBUM_ART) " 456 "VALUES" 457 " (%Q, %lld, %ld, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, %d, %Q, '%s', %lld);", 458 path, file.st_size, file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date, 459 m.title, m.creator, m.artist, m.album, m.genre, m.comment, song.disc, song.track, 460 m.dlna_pn, song.mime?song.mime:m.mime, album_art); 461 if( ret != SQLITE_OK ) 462 { 463 fprintf(stderr, "Error inserting details for '%s'!\n", path); 464 ret = 0; 465 } 466 else 467 { 468 ret = sqlite3_last_insert_rowid(db); 469 } 470 freetags(&song); 471 free_metadata(&m, free_flags); 472 473 return ret; 474} 475 476/* For libjpeg error handling */ 477jmp_buf setjmp_buffer; 478static void 479libjpeg_error_handler(j_common_ptr cinfo) 480{ 481 cinfo->err->output_message (cinfo); 482 longjmp(setjmp_buffer, 1); 483 return; 484} 485 486sqlite_int64 487GetImageMetadata(const char * path, char * name) 488{ 489 ExifData *ed; 490 ExifEntry *e = NULL; 491 ExifLoader *l; 492 struct jpeg_decompress_struct cinfo; 493 struct jpeg_error_mgr jerr; 494 FILE *infile; 495 int width=0, height=0, thumb=0; 496 char make[32], model[64] = {'\0'}; 497 char b[1024]; 498 struct stat file; 499 sqlite_int64 ret; 500 image * imsrc; 501 metadata_t m; 502 uint32_t free_flags = 0xFFFFFFFF; 503 memset(&m, '\0', sizeof(metadata_t)); 504 505 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path); 506 if ( stat(path, &file) != 0 ) 507 return 0; 508 strip_ext(name); 509 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size); 510 511 /* MIME hard-coded to JPEG for now, until we add PNG support */ 512 asprintf(&m.mime, "image/jpeg"); 513 514 l = exif_loader_new(); 515 exif_loader_write_file(l, path); 516 ed = exif_loader_get_data(l); 517 exif_loader_unref(l); 518 if( !ed ) 519 goto no_exifdata; 520 521 e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL); 522 if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) ) { 523 m.date = strdup(exif_entry_get_value(e, b, sizeof(b))); 524 if( strlen(m.date) > 10 ) 525 { 526 m.date[4] = '-'; 527 m.date[7] = '-'; 528 m.date[10] = 'T'; 529 } 530 else { 531 free(m.date); 532 m.date = NULL; 533 } 534 } 535 else { 536 /* One last effort to get the date from XMP */ 537 image_get_jpeg_date_xmp(path, &m.date); 538 } 539 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", m.date); 540 541 e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE); 542 if( e ) 543 { 544 strncpy(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make)); 545 e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL); 546 if( e ) 547 { 548 strncpy(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model)); 549 if( !strcasestr(model, make) ) 550 snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b))); 551 m.creator = strdup(model); 552 } 553 } 554 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * model: %s\n", model); 555 556 if( ed->size ) 557 { 558 /* We might need to verify that the thumbnail is 160x160 or smaller */ 559 if( ed->size > 12000 ) 560 { 561 imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1); 562 if( imsrc ) 563 { 564 if( (imsrc->width <= 160) && (imsrc->height <= 160) ) 565 thumb = 1; 566 image_free(imsrc); 567 } 568 } 569 else 570 thumb = 1; 571 } 572 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb); 573 574 exif_data_unref(ed); 575 576no_exifdata: 577 /* If SOF parsing fails, then fall through to reading the JPEG data with libjpeg to get the resolution */ 578 if( image_get_jpeg_resolution(path, &width, &height) != 0 || !width || !height ) 579 { 580 infile = fopen(path, "r"); 581 cinfo.err = jpeg_std_error(&jerr); 582 jerr.error_exit = libjpeg_error_handler; 583 jpeg_create_decompress(&cinfo); 584 if( setjmp(setjmp_buffer) ) 585 goto error; 586 jpeg_stdio_src(&cinfo, infile); 587 jpeg_read_header(&cinfo, TRUE); 588 jpeg_start_decompress(&cinfo); 589 width = cinfo.output_width; 590 height = cinfo.output_height; 591 error: 592 jpeg_destroy_decompress(&cinfo); 593 fclose(infile); 594 } 595 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height); 596 597 if( !width || !height ) 598 { 599 free_metadata(&m, free_flags); 600 return 0; 601 } 602 if( width <= 640 && height <= 480 ) 603 asprintf(&m.dlna_pn, "JPEG_SM;%s", dlna_no_conv); 604 else if( width <= 1024 && height <= 768 ) 605 asprintf(&m.dlna_pn, "JPEG_MED;%s", dlna_no_conv); 606 else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) ) 607 asprintf(&m.dlna_pn, "JPEG_LRG;%s", dlna_no_conv); 608 asprintf(&m.resolution, "%dx%d", width, height); 609 610 ret = sql_exec(db, "INSERT into DETAILS" 611 " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION, THUMBNAIL, CREATOR, DLNA_PN, MIME) " 612 "VALUES" 613 " (%Q, '%q', %lld, %ld, %Q, %Q, %d, %Q, %Q, %Q);", 614 path, name, file.st_size, file.st_mtime, m.date, m.resolution, thumb, m.creator, m.dlna_pn, m.mime); 615 if( ret != SQLITE_OK ) 616 { 617 fprintf(stderr, "Error inserting details for '%s'!\n", path); 618 ret = 0; 619 } 620 else 621 { 622 ret = sqlite3_last_insert_rowid(db); 623 } 624 free_metadata(&m, free_flags); 625 626 return ret; 627} 628 629sqlite_int64 630GetVideoMetadata(const char * path, char * name) 631{ 632 struct stat file; 633 int ret, i; 634 struct tm *modtime; 635 AVFormatContext *ctx; 636 int audio_stream = -1, video_stream = -1; 637 enum audio_profiles audio_profile = PROFILE_AUDIO_UNKNOWN; 638 ts_timestamp_t ts_timestamp = NONE; 639 int duration, hours, min, sec, ms; 640 aac_object_type_t aac_type = AAC_INVALID; 641 sqlite_int64 album_art = 0; 642 char nfo[PATH_MAX], *ext; 643 metadata_t m; 644 uint32_t free_flags = 0xFFFFFFFF; 645 memset(&m, '\0', sizeof(m)); 646// memset(&free_flags, 0xFF, sizeof(free_flags)); 647 648 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing video %s...\n", name); 649 if ( stat(path, &file) != 0 ) 650 return 0; 651 strip_ext(name); 652 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size); 653 654 av_register_all(); 655 if( av_open_input_file(&ctx, path, NULL, 0, NULL) != 0 ) 656 { 657 DPRINTF(E_WARN, L_METADATA, "Opening %s failed!\n", path); 658 return 0; 659 } 660 av_find_stream_info(ctx); 661 //dump_format(ctx, 0, NULL, 0); 662 for( i=0; i<ctx->nb_streams; i++) 663 { 664 if( audio_stream == -1 && 665 ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO ) 666 { 667 audio_stream = i; 668 continue; 669 } 670 else if( video_stream == -1 && 671 ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO ) 672 { 673 video_stream = i; 674 continue; 675 } 676 } 677 /* This must not be a video file. */ 678 if( video_stream == -1 ) 679 { 680 av_close_input_file(ctx); 681 if( !is_audio(path) ) 682 DPRINTF(E_DEBUG, L_METADATA, "File %s does not contain a video stream.\n", basename(path)); 683 return 0; 684 } 685 686 strcpy(nfo, path); 687 ext = strrchr(nfo, '.'); 688 if( ext ) 689 { 690 strcpy(ext+1, "nfo"); 691 if( access(nfo, F_OK) == 0 ) 692 { 693 parse_nfo(nfo, &m); 694 } 695 } 696 697 if( !m.date ) 698 { 699 m.date = malloc(20); 700 modtime = localtime(&file.st_mtime); 701 strftime(m.date, 20, "%FT%T", modtime); 702 } 703 704 if( audio_stream >= 0 ) 705 { 706 switch( ctx->streams[audio_stream]->codec->codec_id ) 707 { 708 case CODEC_ID_MP3: 709 audio_profile = PROFILE_AUDIO_MP3; 710 break; 711 case CODEC_ID_AAC: 712 if( !ctx->streams[audio_stream]->codec->extradata_size || 713 !ctx->streams[audio_stream]->codec->extradata ) 714 { 715 DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n"); 716 } 717 else 718 { 719 uint8_t data; 720 memcpy(&data, ctx->streams[audio_stream]->codec->extradata, 1); 721 aac_type = data >> 3; 722 } 723 switch( aac_type ) 724 { 725 /* AAC Low Complexity variants */ 726 case AAC_LC: 727 case AAC_LC_ER: 728 if( ctx->streams[audio_stream]->codec->sample_rate < 8000 || 729 ctx->streams[audio_stream]->codec->sample_rate > 48000 ) 730 { 731 DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n", 732 ctx->streams[audio_stream]->codec->sample_rate); 733 break; 734 } 735 /* AAC @ Level 1/2 */ 736 if( ctx->streams[audio_stream]->codec->channels <= 2 && 737 ctx->streams[audio_stream]->codec->bit_rate <= 576000 ) 738 audio_profile = PROFILE_AUDIO_AAC; 739 else if( ctx->streams[audio_stream]->codec->channels <= 6 && 740 ctx->streams[audio_stream]->codec->bit_rate <= 1440000 ) 741 audio_profile = PROFILE_AUDIO_AAC_MULT5; 742 else 743 DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n", 744 ctx->streams[audio_stream]->codec->channels, 745 ctx->streams[audio_stream]->codec->bit_rate); 746 break; 747 default: 748 DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type); 749 break; 750 } 751 break; 752 case CODEC_ID_AC3: 753 case CODEC_ID_DTS: 754 audio_profile = PROFILE_AUDIO_AC3; 755 break; 756 case CODEC_ID_WMAV1: 757 case CODEC_ID_WMAV2: 758 /* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */ 759 if ( ctx->streams[audio_stream]->codec->bit_rate <= 193000 ) 760 audio_profile = PROFILE_AUDIO_WMA_BASE; 761 /* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */ 762 else if ( ctx->streams[audio_stream]->codec->bit_rate <= 385000 ) 763 audio_profile = PROFILE_AUDIO_WMA_FULL; 764 break; 765 #if LIBAVCODEC_VERSION_INT > ((51<<16)+(50<<8)+1) 766 case CODEC_ID_WMAPRO: 767 audio_profile = PROFILE_AUDIO_WMA_PRO; 768 break; 769 #endif 770 case CODEC_ID_MP2: 771 audio_profile = PROFILE_AUDIO_MP2; 772 break; 773 case CODEC_ID_AMR_NB: 774 audio_profile = PROFILE_AUDIO_AMR; 775 break; 776 default: 777 if( (ctx->streams[audio_stream]->codec->codec_id >= CODEC_ID_PCM_S16LE) && 778 (ctx->streams[audio_stream]->codec->codec_id < CODEC_ID_ADPCM_IMA_QT) ) 779 audio_profile = PROFILE_AUDIO_PCM; 780 else 781 DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ctx->streams[audio_stream]->codec->codec_id); 782 break; 783 } 784 asprintf(&m.frequency, "%u", ctx->streams[audio_stream]->codec->sample_rate); 785 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) 786 asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_sample); 787 #else 788 asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_coded_sample); 789 #endif 790 asprintf(&m.channels, "%u", ctx->streams[audio_stream]->codec->channels); 791 } 792 if( video_stream >= 0 ) 793 { 794 DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename(path)); 795 asprintf(&m.resolution, "%dx%d", ctx->streams[video_stream]->codec->width, ctx->streams[video_stream]->codec->height); 796 if( ctx->bit_rate > 8 ) 797 asprintf(&m.bitrate, "%u", ctx->bit_rate / 8); 798 if( ctx->duration > 0 ) { 799 duration = (int)(ctx->duration / AV_TIME_BASE); 800 hours = (int)(duration / 3600); 801 min = (int)(duration / 60 % 60); 802 sec = (int)(duration % 60); 803 ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000); 804 asprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms); 805 } 806 /* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers -- not AVI. */ 807 switch( ctx->streams[video_stream]->codec->codec_id ) 808 { 809 case CODEC_ID_MPEG1VIDEO: 810 if( strcmp(ctx->iformat->name, "mpeg") == 0 ) 811 { 812 if( (ctx->streams[video_stream]->codec->width == 352) && 813 (ctx->streams[video_stream]->codec->height <= 288) ) 814 { 815 asprintf(&m.dlna_pn, "MPEG1;%s", dlna_no_conv); 816 } 817 asprintf(&m.mime, "video/mpeg"); 818 } 819 break; 820 case CODEC_ID_MPEG2VIDEO: 821 if( strcmp(ctx->iformat->name, "mpegts") == 0 ) 822 { 823 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, basename(path), m.resolution); 824 char res; 825 tsinfo_t * ts = ctx->priv_data; 826 if( ts->packet_size == 192 ) 827 { 828 asprintf(&m.dlna_pn, "MPEG_TS_HD_NA;%s", dlna_no_conv); 829 asprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); 830 } 831 else if( ts->packet_size == 188 ) 832 { 833 if( (ctx->streams[video_stream]->codec->width >= 1280) && 834 (ctx->streams[video_stream]->codec->height >= 720) ) 835 res = 'H'; 836 else 837 res = 'S'; 838 asprintf(&m.dlna_pn, "MPEG_TS_%cD_NA_ISO;%s", res, dlna_no_conv); 839 asprintf(&m.mime, "video/mpeg"); 840 } 841 } 842 else if( strcmp(ctx->iformat->name, "mpeg") == 0 ) 843 { 844 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, basename(path), m.resolution); 845 char region[5]; 846 if( (ctx->streams[video_stream]->codec->height == 576) || 847 (ctx->streams[video_stream]->codec->height == 288) ) 848 strcpy(region, "PAL"); 849 else 850 strcpy(region, "NTSC"); 851 asprintf(&m.dlna_pn, "MPEG_PS_%s;%s", region, dlna_no_conv); 852 asprintf(&m.mime, "video/mpeg"); 853 } 854 else 855 { 856 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [UNKNOWN CONTAINER] is %s MPEG2\n", video_stream, basename(path), m.resolution); 857 } 858 break; 859 case CODEC_ID_H264: 860 if( strcmp(ctx->iformat->name, "mpegts") == 0 ) 861 { 862 tsinfo_t * ts = ctx->priv_data; 863 if( ts->packet_size == 192 ) 864 { 865 if( dlna_timestamp_is_present(path) ) 866 ts_timestamp = VALID; 867 else 868 ts_timestamp = EMPTY; 869 } 870 char res = '\0'; 871 if( ctx->streams[video_stream]->codec->width <= 720 && 872 ctx->streams[video_stream]->codec->height <= 576 && 873 ctx->streams[video_stream]->codec->bit_rate <= 10000000 ) 874 res = 'S'; 875 else if( ctx->streams[video_stream]->codec->width <= 1920 && 876 ctx->streams[video_stream]->codec->height <= 1152 && 877 ctx->streams[video_stream]->codec->bit_rate <= 20000000 ) 878 res = 'H'; 879 if( res ) 880 { 881 switch( audio_profile ) 882 { 883 case PROFILE_AUDIO_MP3: 884 asprintf(&m.dlna_pn, "AVC_TS_MP_HD_MPEG1_L3%s;%s", 885 ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"", dlna_no_conv); 886 break; 887 case PROFILE_AUDIO_AC3: 888 asprintf(&m.dlna_pn, "AVC_TS_MP_HD_AC3%s;%s", 889 ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"", dlna_no_conv); 890 break; 891 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02, 892 * no support for AVC_TS_MP_HD_AAC_MULT5. 893 */ 894 //case PROFILE_AUDIO_AAC_MULT5: 895 // asprintf(&m.dlna_pn, "AVC_TS_MP_HD_AAC_MULT5%s;%s", 896 // ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"", dlna_no_conv); 897 // break; 898 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02. */ 899 default: 900 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for TS/AVC/%cD file %s\n", res, basename(path)); 901 break; 902 } 903 if( m.dlna_pn && (ts_timestamp != NONE) ) 904 asprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); 905 } 906 else 907 { 908 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n", 909 ctx->streams[video_stream]->codec->width, 910 ctx->streams[video_stream]->codec->height, 911 ctx->streams[video_stream]->codec->bit_rate); 912 } 913 } 914 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 ) 915 { 916 /* AVC wrapped in MP4 only has SD profiles - 10 Mbps max */ 917 if( ctx->streams[video_stream]->codec->width <= 720 && 918 ctx->streams[video_stream]->codec->height <= 576 && 919 ctx->streams[video_stream]->codec->bit_rate <= 10000000 && 920 !ends_with(path, ".mov") ) 921 { 922 switch( audio_profile ) 923 { 924 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02, 925 * no support for AVC_MP4_MP_SD_AC3 & AVC_MP4_MP_SD_AAC_MULT5 . 926 */ 927 //case PROFILE_AUDIO_AC3: 928 // asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AC3;%s", dlna_no_conv); 929 // break; 930 //case PROFILE_AUDIO_AAC_MULT5: 931 // asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AAC_MULT5;%s", dlna_no_conv); 932 // break; 933 /* Ended by Michael Jiang, for DLNA CTT 1.56, 2010/08/02. */ 934 default: 935 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MP4/AVC/SD file %s\n", basename(path)); 936 break; 937 } 938 } 939 } 940 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename(path)); 941 break; 942 case CODEC_ID_MPEG4: 943 if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("XVID") ) 944 { 945 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s XViD\n", video_stream, basename(path), m.resolution); 946 asprintf(&m.artist, "DiVX"); 947 } 948 else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DX50") ) 949 { 950 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s DiVX5\n", video_stream, basename(path), m.resolution); 951 asprintf(&m.artist, "DiVX"); 952 } 953 else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DIVX") ) 954 { 955 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is DiVX\n", video_stream, basename(path)); 956 asprintf(&m.artist, "DiVX"); 957 } 958 else if( ends_with(path, ".3gp") && (strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0) ) 959 { 960 asprintf(&m.mime, "video/3gpp"); 961 switch( audio_profile ) 962 { 963 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02, 964 * no support for MPEG4_P2_3GPP_SP_L0B_AAC & MPEG4_P2_3GPP_SP_L0B_AMR. 965 */ 966 //case PROFILE_AUDIO_AAC: 967 // asprintf(&m.dlna_pn, "MPEG4_P2_3GPP_SP_L0B_AAC;%s", dlna_no_conv); 968 // break; 969 //case PROFILE_AUDIO_AMR: 970 // asprintf(&m.dlna_pn, "MPEG4_P2_3GPP_SP_L0B_AMR;%s", dlna_no_conv); 971 // break; 972 /* Ended by Michael Jiang, for DLNA CTT 1.56, 2010/08/02. */ 973 default: 974 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n", 975 ctx->streams[audio_stream]->codec->codec_id, basename(path)); 976 break; 977 } 978 } 979 else 980 { 981 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%X]\n", video_stream, basename(path), ctx->streams[video_stream]->codec->codec_tag); 982 } 983 break; 984 case CODEC_ID_WMV3: 985 case CODEC_ID_VC1: 986 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename(path)); 987 char profile[5]; profile[0] = '\0'; 988 asprintf(&m.mime, "video/x-ms-wmv"); 989 if( (ctx->streams[video_stream]->codec->width <= 352) && 990 (ctx->streams[video_stream]->codec->height <= 288) && 991 (ctx->bit_rate/8 <= 384000) ) 992 { 993 switch( audio_profile ) 994 { 995 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02, no support for WMVSPML_MP3 */ 996 //case PROFILE_AUDIO_MP3: 997 // asprintf(&m.dlna_pn, "WMVSPML_MP3;%s", dlna_no_conv); 998 // break; 999 /* Ended by Michael Jiang, for DLNA CTT 1.56, 2010/08/02. */ 1000 case PROFILE_AUDIO_WMA_BASE: 1001 asprintf(&m.dlna_pn, "WMVSPML_BASE;%s", dlna_no_conv); 1002 break; 1003 default: 1004 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n", audio_profile, basename(path)); 1005 break; 1006 } 1007 } 1008 else if( (ctx->streams[video_stream]->codec->width <= 720) && 1009 (ctx->streams[video_stream]->codec->height <= 576) && 1010 (ctx->bit_rate/8 <= 10000000) ) 1011 { 1012 switch( audio_profile ) 1013 { 1014 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02, no support for WMVMED_PRO */ 1015 //case PROFILE_AUDIO_WMA_PRO: 1016 // asprintf(&m.dlna_pn, "WMVMED_PRO;%s", dlna_no_conv); 1017 // break; 1018 /* Ended by Michael Jiang, for DLNA CTT 1.56, 2010/08/02. */ 1019 case PROFILE_AUDIO_WMA_FULL: 1020 asprintf(&m.dlna_pn, "WMVMED_FULL;%s", dlna_no_conv); 1021 break; 1022 case PROFILE_AUDIO_WMA_BASE: 1023 asprintf(&m.dlna_pn, "WMVMED_BASE;%s", dlna_no_conv); 1024 break; 1025 default: 1026 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n", audio_profile, basename(path)); 1027 break; 1028 } 1029 } 1030 else if( (ctx->streams[video_stream]->codec->width <= 1920) && 1031 (ctx->streams[video_stream]->codec->height <= 1080) && 1032 (ctx->bit_rate/8 <= 20000000) ) 1033 { 1034 switch( audio_profile ) 1035 { 1036 /* Marked by Michael Jiang, for DLNA CTT 1.56, 2010/08/02, no support for WMVHIGH_PRO */ 1037 //case PROFILE_AUDIO_WMA_PRO: 1038 // asprintf(&m.dlna_pn, "WMVHIGH_PRO;%s", dlna_no_conv); 1039 /* Ended by Michael Jiang, for DLNA CTT 1.56, 2010/08/02. */ 1040 break; 1041 case PROFILE_AUDIO_WMA_FULL: 1042 asprintf(&m.dlna_pn, "WMVHIGH_FULL;%s", dlna_no_conv); 1043 break; 1044 default: 1045 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n", audio_profile, basename(path)); 1046 break; 1047 } 1048 } 1049 break; 1050 case CODEC_ID_MSMPEG4V3: 1051 asprintf(&m.mime, "video/x-msvideo"); 1052 default: 1053 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n", video_stream, basename(path), m.resolution, ctx->streams[video_stream]->codec->codec_id); 1054 break; 1055 } 1056 } 1057 if( !m.mime ) 1058 { 1059 if( strcmp(ctx->iformat->name, "avi") == 0 ) 1060 asprintf(&m.mime, "video/x-msvideo"); 1061 else if( strcmp(ctx->iformat->name, "mpegts") == 0 ) 1062 asprintf(&m.mime, "video/mpeg"); 1063 else if( strcmp(ctx->iformat->name, "mpeg") == 0 ) 1064 asprintf(&m.mime, "video/mpeg"); 1065 else if( strcmp(ctx->iformat->name, "asf") == 0 ) 1066 asprintf(&m.mime, "video/x-ms-wmv"); 1067 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 ) 1068 if( ends_with(path, ".mov") ) 1069 asprintf(&m.mime, "video/quicktime"); 1070 else 1071 asprintf(&m.mime, "video/mp4"); 1072 else if( strcmp(ctx->iformat->name, "matroska") == 0 ) 1073 asprintf(&m.mime, "video/x-matroska"); 1074 else if( strcmp(ctx->iformat->name, "flv") == 0 ) 1075 asprintf(&m.mime, "video/x-flv"); 1076 else 1077 DPRINTF(E_WARN, L_METADATA, "%s: Unhandled format: %s\n", path, ctx->iformat->name); 1078 } 1079 av_close_input_file(ctx); 1080#ifdef TIVO_SUPPORT 1081 if( ends_with(path, ".TiVo") && is_tivo_file(path) ) 1082 { 1083 free(m.mime); 1084 asprintf(&m.mime, "video/x-tivo-mpeg"); 1085 } 1086#endif 1087 album_art = find_album_art(path, NULL, 0); 1088 1089 ret = sql_exec(db, "INSERT into DETAILS" 1090 " (PATH, SIZE, TIMESTAMP, DURATION, DATE, CHANNELS, BITRATE, SAMPLERATE, RESOLUTION," 1091 " CREATOR, TITLE, COMMENT, DLNA_PN, MIME, ALBUM_ART) " 1092 "VALUES" 1093 " (%Q, %lld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, '%q', %Q, %Q, '%q', %lld);", 1094 path, file.st_size, file.st_mtime, m.duration, 1095 m.date, m.channels, 1096 m.bitrate, m.frequency, m.resolution, m.artist, 1097 m.title ? m.title : name, m.comment, m.dlna_pn, 1098 m.mime, album_art); 1099 if( ret != SQLITE_OK ) 1100 { 1101 fprintf(stderr, "Error inserting details for '%s'!\n", path); 1102 ret = 0; 1103 } 1104 else 1105 { 1106 ret = sqlite3_last_insert_rowid(db); 1107 check_for_captions(path, ret); 1108 } 1109 free_metadata(&m, free_flags); 1110 1111 return ret; 1112} 1113