MiniDLNA 1.0.22: cvs 2011-08-25
[tomato.git] / release / src / router / minidlna / metadata.c
blob0f698d0701a9833599067268adc6ea8b67fc77ea
1 /* MiniDLNA media server
2 * Copyright (C) 2008-2009 Justin Maggard
4 * This file is part of MiniDLNA.
6 * MiniDLNA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * MiniDLNA is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdio.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
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"
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"
46 #ifndef FF_PROFILE_H264_BASELINE
47 #define FF_PROFILE_H264_BASELINE 66
48 #endif
49 #ifndef FF_PROFILE_H264_MAIN
50 #define FF_PROFILE_H264_MAIN 77
51 #endif
52 #ifndef FF_PROFILE_H264_HIGH
53 #define FF_PROFILE_H264_HIGH 100
54 #endif
55 #define FF_PROFILE_SKIP -100
57 #if LIBAVCODEC_VERSION_MAJOR < 53
58 #define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
59 #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
60 #endif
62 #define FLAG_TITLE 0x00000001
63 #define FLAG_ARTIST 0x00000002
64 #define FLAG_ALBUM 0x00000004
65 #define FLAG_GENRE 0x00000008
66 #define FLAG_COMMENT 0x00000010
67 #define FLAG_CREATOR 0x00000020
68 #define FLAG_DATE 0x00000040
69 #define FLAG_DLNA_PN 0x00000080
70 #define FLAG_MIME 0x00000100
71 #define FLAG_DURATION 0x00000200
72 #define FLAG_RESOLUTION 0x00000400
73 #define FLAG_BITRATE 0x00000800
74 #define FLAG_FREQUENCY 0x00001000
75 #define FLAG_BPS 0x00002000
76 #define FLAG_CHANNELS 0x00004000
78 /* Audio profile flags */
79 enum audio_profiles {
80 PROFILE_AUDIO_UNKNOWN,
81 PROFILE_AUDIO_MP3,
82 PROFILE_AUDIO_AC3,
83 PROFILE_AUDIO_WMA_BASE,
84 PROFILE_AUDIO_WMA_FULL,
85 PROFILE_AUDIO_WMA_PRO,
86 PROFILE_AUDIO_MP2,
87 PROFILE_AUDIO_PCM,
88 PROFILE_AUDIO_AAC,
89 PROFILE_AUDIO_AAC_MULT5,
90 PROFILE_AUDIO_AMR
93 /* This function shamelessly copied from libdlna */
94 #define MPEG_TS_SYNC_CODE 0x47
95 #define MPEG_TS_PACKET_LENGTH 188
96 #define MPEG_TS_PACKET_LENGTH_DLNA 192 /* prepends 4 bytes to TS packet */
97 int
98 dlna_timestamp_is_present(const char * filename, int * raw_packet_size)
100 unsigned char buffer[3*MPEG_TS_PACKET_LENGTH_DLNA];
101 int fd, i;
103 /* read file header */
104 fd = open(filename, O_RDONLY);
105 read(fd, buffer, MPEG_TS_PACKET_LENGTH_DLNA*3);
106 close(fd);
107 for( i=0; i < MPEG_TS_PACKET_LENGTH_DLNA; i++ )
109 if( buffer[i] == MPEG_TS_SYNC_CODE )
111 if (buffer[i + MPEG_TS_PACKET_LENGTH_DLNA] == MPEG_TS_SYNC_CODE &&
112 buffer[i + MPEG_TS_PACKET_LENGTH_DLNA*2] == MPEG_TS_SYNC_CODE)
114 *raw_packet_size = MPEG_TS_PACKET_LENGTH_DLNA;
115 if (buffer[i+MPEG_TS_PACKET_LENGTH] == 0x00 &&
116 buffer[i+MPEG_TS_PACKET_LENGTH+1] == 0x00 &&
117 buffer[i+MPEG_TS_PACKET_LENGTH+2] == 0x00 &&
118 buffer[i+MPEG_TS_PACKET_LENGTH+3] == 0x00)
119 return 0;
120 else
121 return 1;
122 } else if (buffer[i + MPEG_TS_PACKET_LENGTH] == MPEG_TS_SYNC_CODE &&
123 buffer[i + MPEG_TS_PACKET_LENGTH*2] == MPEG_TS_SYNC_CODE) {
124 *raw_packet_size = MPEG_TS_PACKET_LENGTH;
125 return 0;
129 *raw_packet_size = 0;
130 return 0;
133 #ifdef TIVO_SUPPORT
135 is_tivo_file(const char * path)
137 unsigned char buf[5];
138 unsigned char hdr[5] = { 'T','i','V','o','\0' };
139 int fd;
141 /* read file header */
142 fd = open(path, O_RDONLY);
143 read(fd, buf, 5);
144 close(fd);
146 return( !memcmp(buf, hdr, 5) );
148 #endif
150 void
151 check_for_captions(const char * path, sqlite_int64 detailID)
153 char *file = malloc(PATH_MAX);
154 char *id = NULL;
156 sprintf(file, "%s", path);
157 strip_ext(file);
159 /* If we weren't given a detail ID, look for one. */
160 if( !detailID )
162 id = sql_get_text_field(db, "SELECT ID from DETAILS where PATH glob '%q.*'"
163 " and MIME glob 'video/*' limit 1", file);
164 if( id )
166 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like a caption file.\n", path);
167 detailID = strtoll(id, NULL, 10);
169 else
171 //DPRINTF(E_DEBUG, L_METADATA, "No file found for caption %s.\n", path);
172 goto no_source_video;
176 strcat(file, ".srt");
177 if( access(file, R_OK) == 0 )
179 sql_exec(db, "INSERT into CAPTIONS"
180 " (ID, PATH) "
181 "VALUES"
182 " (%lld, %Q)", detailID, file);
184 no_source_video:
185 if( id )
186 sqlite3_free(id);
187 free(file);
190 void
191 parse_nfo(const char * path, metadata_t * m)
193 FILE *nfo;
194 char buf[65536];
195 struct NameValueParserData xml;
196 struct stat file;
197 size_t nread;
198 char *val, *val2;
200 if( stat(path, &file) != 0 ||
201 file.st_size > 65536 )
203 DPRINTF(E_INFO, L_METADATA, "Not parsing very large .nfo file %s\n", path);
204 return;
206 DPRINTF(E_DEBUG, L_METADATA, "Parsing .nfo file: %s\n", path);
207 nfo = fopen(path, "r");
208 if( !nfo )
209 return;
210 nread = fread(&buf, 1, sizeof(buf), nfo);
212 ParseNameValue(buf, nread, &xml);
214 //printf("\ttype: %s\n", GetValueFromNameValueList(&xml, "rootElement"));
215 val = GetValueFromNameValueList(&xml, "title");
216 if( val )
218 val2 = GetValueFromNameValueList(&xml, "episodetitle");
219 if( val2 )
220 asprintf(&m->title, "%s - %s", val, val2);
221 else
222 m->title = strdup(val);
225 val = GetValueFromNameValueList(&xml, "plot");
226 if( val )
227 m->comment = strdup(val);
229 val = GetValueFromNameValueList(&xml, "capturedate");
230 if( val )
231 m->date = strdup(val);
233 val = GetValueFromNameValueList(&xml, "genre");
234 if( val )
235 m->genre = strdup(val);
237 ClearNameValueList(&xml);
238 fclose(nfo);
241 void
242 free_metadata(metadata_t * m, uint32_t flags)
244 if( m->title && (flags & FLAG_TITLE) )
245 free(m->title);
246 if( m->artist && (flags & FLAG_ARTIST) )
247 free(m->artist);
248 if( m->album && (flags & FLAG_ALBUM) )
249 free(m->album);
250 if( m->genre && (flags & FLAG_GENRE) )
251 free(m->genre);
252 if( m->creator && (flags & FLAG_CREATOR) )
253 free(m->creator);
254 if( m->date && (flags & FLAG_DATE) )
255 free(m->date);
256 if( m->comment && (flags & FLAG_COMMENT) )
257 free(m->comment);
258 if( m->dlna_pn && (flags & FLAG_DLNA_PN) )
259 free(m->dlna_pn);
260 if( m->mime && (flags & FLAG_MIME) )
261 free(m->mime);
262 if( m->duration && (flags & FLAG_DURATION) )
263 free(m->duration);
264 if( m->resolution && (flags & FLAG_RESOLUTION) )
265 free(m->resolution);
266 if( m->bitrate && (flags & FLAG_BITRATE) )
267 free(m->bitrate);
268 if( m->frequency && (flags & FLAG_FREQUENCY) )
269 free(m->frequency);
270 if( m->bps && (flags & FLAG_BPS) )
271 free(m->bps);
272 if( m->channels && (flags & FLAG_CHANNELS) )
273 free(m->channels);
276 sqlite_int64
277 GetFolderMetadata(const char * name, const char * path, const char * artist, const char * genre, sqlite3_int64 album_art)
279 int ret;
281 ret = sql_exec(db, "INSERT into DETAILS"
282 " (TITLE, PATH, CREATOR, ARTIST, GENRE, ALBUM_ART) "
283 "VALUES"
284 " ('%q', %Q, %Q, %Q, %Q, %lld);",
285 name, path, artist, artist, genre, album_art);
286 if( ret != SQLITE_OK )
287 ret = 0;
288 else
289 ret = sqlite3_last_insert_rowid(db);
291 return ret;
294 sqlite_int64
295 GetAudioMetadata(const char * path, char * name)
297 char type[4];
298 static char lang[6] = { '\0' };
299 struct stat file;
300 sqlite_int64 ret;
301 char *esc_tag;
302 int i;
303 sqlite_int64 album_art = 0;
304 struct song_metadata song;
305 metadata_t m;
306 uint32_t free_flags = FLAG_MIME|FLAG_DURATION|FLAG_DLNA_PN|FLAG_DATE;
307 memset(&m, '\0', sizeof(metadata_t));
309 if ( stat(path, &file) != 0 )
310 return 0;
311 strip_ext(name);
313 if( ends_with(path, ".mp3") )
315 strcpy(type, "mp3");
316 m.mime = strdup("audio/mpeg");
318 else if( ends_with(path, ".m4a") || ends_with(path, ".mp4") ||
319 ends_with(path, ".aac") || ends_with(path, ".m4p") )
321 strcpy(type, "aac");
322 m.mime = strdup("audio/mp4");
324 else if( ends_with(path, ".3gp") )
326 strcpy(type, "aac");
327 m.mime = strdup("audio/3gpp");
329 else if( ends_with(path, ".wma") || ends_with(path, ".asf") )
331 strcpy(type, "asf");
332 m.mime = strdup("audio/x-ms-wma");
334 else if( ends_with(path, ".flac") || ends_with(path, ".fla") || ends_with(path, ".flc") )
336 strcpy(type, "flc");
337 m.mime = strdup("audio/x-flac");
339 else if( ends_with(path, ".wav") )
341 strcpy(type, "wav");
342 m.mime = strdup("audio/x-wav");
344 else if( ends_with(path, ".ogg") || ends_with(path, ".oga") )
346 strcpy(type, "ogg");
347 m.mime = strdup("audio/ogg");
349 else if( ends_with(path, ".pcm") )
351 strcpy(type, "pcm");
352 m.mime = strdup("audio/L16");
354 else
356 DPRINTF(E_WARN, L_GENERAL, "Unhandled file extension on %s\n", path);
357 return 0;
360 if( !(*lang) )
362 if( !getenv("LANG") )
363 strcpy(lang, "en_US");
364 else
365 strncpy(lang, getenv("LANG"), 5);
366 lang[5] = '\0';
369 if( readtags((char *)path, &song, &file, lang, type) != 0 )
371 DPRINTF(E_WARN, L_GENERAL, "Cannot extract tags from %s!\n", path);
372 freetags(&song);
373 free_metadata(&m, free_flags);
374 return 0;
377 if( song.dlna_pn )
378 asprintf(&m.dlna_pn, "%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", song.dlna_pn);
379 if( song.year )
380 asprintf(&m.date, "%04d-01-01", song.year);
381 asprintf(&m.duration, "%d:%02d:%02d.%03d",
382 (song.song_length/3600000),
383 (song.song_length/60000%60),
384 (song.song_length/1000%60),
385 (song.song_length%1000));
386 if( song.title && *song.title )
388 m.title = trim(song.title);
389 if( (esc_tag = escape_tag(m.title, 0)) )
391 free_flags |= FLAG_TITLE;
392 m.title = esc_tag;
395 else
397 m.title = name;
399 for( i=ROLE_START; i<N_ROLE; i++ )
401 if( song.contributor[i] && *song.contributor[i] )
403 m.creator = trim(song.contributor[i]);
404 if( strlen(m.creator) > 48 )
406 m.creator = strdup("Various Artists");
407 free_flags |= FLAG_CREATOR;
409 else if( (esc_tag = escape_tag(m.creator, 0)) )
411 m.creator = esc_tag;
412 free_flags |= FLAG_CREATOR;
414 m.artist = m.creator;
415 break;
418 /* If there is a band associated with the album, use it for virtual containers. */
419 if( (i != ROLE_BAND) && (i != ROLE_ALBUMARTIST) )
421 if( song.contributor[ROLE_BAND] && *song.contributor[ROLE_BAND] )
423 i = ROLE_BAND;
424 m.artist = trim(song.contributor[i]);
425 if( strlen(m.artist) > 48 )
427 m.artist = strdup("Various Artists");
428 free_flags |= FLAG_ARTIST;
430 else if( (esc_tag = escape_tag(m.artist, 0)) )
432 m.artist = esc_tag;
433 free_flags |= FLAG_ARTIST;
437 if( song.album && *song.album )
439 m.album = trim(song.album);
440 if( (esc_tag = escape_tag(m.album, 0)) )
442 free_flags |= FLAG_ALBUM;
443 m.album = esc_tag;
446 if( song.genre && *song.genre )
448 m.genre = trim(song.genre);
449 if( (esc_tag = escape_tag(m.genre, 0)) )
451 free_flags |= FLAG_GENRE;
452 m.genre = esc_tag;
455 if( song.comment && *song.comment )
457 m.comment = trim(song.comment);
458 if( (esc_tag = escape_tag(m.comment, 0)) )
460 free_flags |= FLAG_COMMENT;
461 m.comment = esc_tag;
465 album_art = find_album_art(path, song.image, song.image_size);
467 ret = sql_exec(db, "INSERT into DETAILS"
468 " (PATH, SIZE, TIMESTAMP, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE,"
469 " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, DISC, TRACK, DLNA_PN, MIME, ALBUM_ART) "
470 "VALUES"
471 " (%Q, %lld, %ld, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, %d, %Q, '%s', %lld);",
472 path, file.st_size, file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date,
473 m.title, m.creator, m.artist, m.album, m.genre, m.comment, song.disc, song.track,
474 m.dlna_pn, song.mime?song.mime:m.mime, album_art);
475 if( ret != SQLITE_OK )
477 fprintf(stderr, "Error inserting details for '%s'!\n", path);
478 ret = 0;
480 else
482 ret = sqlite3_last_insert_rowid(db);
484 freetags(&song);
485 free_metadata(&m, free_flags);
487 return ret;
490 /* For libjpeg error handling */
491 jmp_buf setjmp_buffer;
492 static void
493 libjpeg_error_handler(j_common_ptr cinfo)
495 cinfo->err->output_message (cinfo);
496 longjmp(setjmp_buffer, 1);
497 return;
500 sqlite_int64
501 GetImageMetadata(const char * path, char * name)
503 ExifData *ed;
504 ExifEntry *e = NULL;
505 ExifLoader *l;
506 struct jpeg_decompress_struct cinfo;
507 struct jpeg_error_mgr jerr;
508 FILE *infile;
509 int width=0, height=0, thumb=0;
510 char make[32], model[64] = {'\0'};
511 char b[1024];
512 struct stat file;
513 sqlite_int64 ret;
514 image_s * imsrc;
515 metadata_t m;
516 uint32_t free_flags = 0xFFFFFFFF;
517 memset(&m, '\0', sizeof(metadata_t));
519 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path);
520 if ( stat(path, &file) != 0 )
521 return 0;
522 strip_ext(name);
523 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
525 /* MIME hard-coded to JPEG for now, until we add PNG support */
526 asprintf(&m.mime, "image/jpeg");
528 l = exif_loader_new();
529 exif_loader_write_file(l, path);
530 ed = exif_loader_get_data(l);
531 exif_loader_unref(l);
532 if( !ed )
533 goto no_exifdata;
535 e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
536 if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) ) {
537 m.date = strdup(exif_entry_get_value(e, b, sizeof(b)));
538 if( strlen(m.date) > 10 )
540 m.date[4] = '-';
541 m.date[7] = '-';
542 m.date[10] = 'T';
544 else {
545 free(m.date);
546 m.date = NULL;
549 else {
550 /* One last effort to get the date from XMP */
551 image_get_jpeg_date_xmp(path, &m.date);
553 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", m.date);
555 e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
556 if( e )
558 strncpy(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
559 e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
560 if( e )
562 strncpy(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));
563 if( !strcasestr(model, make) )
564 snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b)));
565 m.creator = strdup(model);
568 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * model: %s\n", model);
570 if( ed->size )
572 /* We might need to verify that the thumbnail is 160x160 or smaller */
573 if( ed->size > 12000 )
575 imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1);
576 if( imsrc )
578 if( (imsrc->width <= 160) && (imsrc->height <= 160) )
579 thumb = 1;
580 image_free(imsrc);
583 else
584 thumb = 1;
586 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb);
588 exif_data_unref(ed);
590 no_exifdata:
591 /* If SOF parsing fails, then fall through to reading the JPEG data with libjpeg to get the resolution */
592 if( image_get_jpeg_resolution(path, &width, &height) != 0 || !width || !height )
594 infile = fopen(path, "r");
595 if( infile )
597 cinfo.err = jpeg_std_error(&jerr);
598 jerr.error_exit = libjpeg_error_handler;
599 jpeg_create_decompress(&cinfo);
600 if( setjmp(setjmp_buffer) )
601 goto error;
602 jpeg_stdio_src(&cinfo, infile);
603 jpeg_read_header(&cinfo, TRUE);
604 jpeg_start_decompress(&cinfo);
605 width = cinfo.output_width;
606 height = cinfo.output_height;
607 error:
608 jpeg_destroy_decompress(&cinfo);
609 fclose(infile);
612 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height);
614 if( !width || !height )
616 free_metadata(&m, free_flags);
617 return 0;
619 if( width <= 640 && height <= 480 )
620 asprintf(&m.dlna_pn, "JPEG_SM;%s", dlna_no_conv);
621 else if( width <= 1024 && height <= 768 )
622 asprintf(&m.dlna_pn, "JPEG_MED;%s", dlna_no_conv);
623 else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) )
624 asprintf(&m.dlna_pn, "JPEG_LRG;%s", dlna_no_conv);
625 asprintf(&m.resolution, "%dx%d", width, height);
627 ret = sql_exec(db, "INSERT into DETAILS"
628 " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION, THUMBNAIL, CREATOR, DLNA_PN, MIME) "
629 "VALUES"
630 " (%Q, '%q', %lld, %ld, %Q, %Q, %d, %Q, %Q, %Q);",
631 path, name, file.st_size, file.st_mtime, m.date, m.resolution, thumb, m.creator, m.dlna_pn, m.mime);
632 if( ret != SQLITE_OK )
634 fprintf(stderr, "Error inserting details for '%s'!\n", path);
635 ret = 0;
637 else
639 ret = sqlite3_last_insert_rowid(db);
641 free_metadata(&m, free_flags);
643 return ret;
646 sqlite_int64
647 GetVideoMetadata(const char * path, char * name)
649 struct stat file;
650 int ret, i;
651 struct tm *modtime;
652 AVFormatContext *ctx = NULL;
653 AVCodecContext *ac = NULL, *vc = NULL;
654 int audio_stream = -1, video_stream = -1;
655 enum audio_profiles audio_profile = PROFILE_AUDIO_UNKNOWN;
656 char fourcc[4];
657 sqlite_int64 album_art = 0;
658 char nfo[PATH_MAX], *ext;
659 struct song_metadata video;
660 metadata_t m;
661 uint32_t free_flags = 0xFFFFFFFF;
663 memset(&m, '\0', sizeof(m));
664 memset(&video, '\0', sizeof(video));
666 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing video %s...\n", name);
667 if ( stat(path, &file) != 0 )
668 return 0;
669 strip_ext(name);
670 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
672 av_register_all();
673 #if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(2<<8)+0)
674 if( avformat_open_input(&ctx, path, NULL, NULL) != 0 )
675 #else
676 if( av_open_input_file(&ctx, path, NULL, 0, NULL) != 0 )
677 #endif
679 DPRINTF(E_WARN, L_METADATA, "Opening %s failed!\n", path);
680 return 0;
682 av_find_stream_info(ctx);
683 //dump_format(ctx, 0, NULL, 0);
684 for( i=0; i<ctx->nb_streams; i++)
686 if( audio_stream == -1 &&
687 ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
689 audio_stream = i;
690 ac = ctx->streams[audio_stream]->codec;
691 continue;
693 else if( video_stream == -1 &&
694 ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
696 video_stream = i;
697 vc = ctx->streams[video_stream]->codec;
698 continue;
701 /* This must not be a video file. */
702 if( !vc )
704 av_close_input_file(ctx);
705 if( !is_audio(path) )
706 DPRINTF(E_DEBUG, L_METADATA, "File %s does not contain a video stream.\n", basename(path));
707 return 0;
710 strcpy(nfo, path);
711 ext = strrchr(nfo, '.');
712 if( ext )
714 strcpy(ext+1, "nfo");
715 if( access(nfo, F_OK) == 0 )
717 parse_nfo(nfo, &m);
721 if( !m.date )
723 m.date = malloc(20);
724 modtime = localtime(&file.st_mtime);
725 strftime(m.date, 20, "%FT%T", modtime);
728 if( ac )
730 aac_object_type_t aac_type = AAC_INVALID;
731 switch( ac->codec_id )
733 case CODEC_ID_MP3:
734 audio_profile = PROFILE_AUDIO_MP3;
735 break;
736 case CODEC_ID_AAC:
737 if( !ac->extradata_size ||
738 !ac->extradata )
740 DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n");
742 else
744 uint8_t data;
745 memcpy(&data, ac->extradata, 1);
746 aac_type = data >> 3;
748 switch( aac_type )
750 /* AAC Low Complexity variants */
751 case AAC_LC:
752 case AAC_LC_ER:
753 if( ac->sample_rate < 8000 ||
754 ac->sample_rate > 48000 )
756 DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n",
757 ac->sample_rate);
758 break;
760 /* AAC @ Level 1/2 */
761 if( ac->channels <= 2 &&
762 ac->bit_rate <= 576000 )
763 audio_profile = PROFILE_AUDIO_AAC;
764 else if( ac->channels <= 6 &&
765 ac->bit_rate <= 1440000 )
766 audio_profile = PROFILE_AUDIO_AAC_MULT5;
767 else
768 DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n",
769 ac->channels,
770 ac->bit_rate);
771 break;
772 default:
773 DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type);
774 break;
776 break;
777 case CODEC_ID_AC3:
778 case CODEC_ID_DTS:
779 audio_profile = PROFILE_AUDIO_AC3;
780 break;
781 case CODEC_ID_WMAV1:
782 case CODEC_ID_WMAV2:
783 /* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */
784 if ( ac->bit_rate <= 193000 )
785 audio_profile = PROFILE_AUDIO_WMA_BASE;
786 /* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */
787 else if ( ac->bit_rate <= 385000 )
788 audio_profile = PROFILE_AUDIO_WMA_FULL;
789 break;
790 #if LIBAVCODEC_VERSION_INT > ((51<<16)+(50<<8)+1)
791 case CODEC_ID_WMAPRO:
792 audio_profile = PROFILE_AUDIO_WMA_PRO;
793 break;
794 #endif
795 case CODEC_ID_MP2:
796 audio_profile = PROFILE_AUDIO_MP2;
797 break;
798 case CODEC_ID_AMR_NB:
799 audio_profile = PROFILE_AUDIO_AMR;
800 break;
801 default:
802 if( (ac->codec_id >= CODEC_ID_PCM_S16LE) &&
803 (ac->codec_id < CODEC_ID_ADPCM_IMA_QT) )
804 audio_profile = PROFILE_AUDIO_PCM;
805 else
806 DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ac->codec_id);
807 break;
809 asprintf(&m.frequency, "%u", ac->sample_rate);
810 #if LIBAVCODEC_VERSION_INT < (52<<16)
811 asprintf(&m.bps, "%u", ac->bits_per_sample);
812 #else
813 asprintf(&m.bps, "%u", ac->bits_per_coded_sample);
814 #endif
815 asprintf(&m.channels, "%u", ac->channels);
817 if( vc )
819 int off;
820 int duration, hours, min, sec, ms;
821 ts_timestamp_t ts_timestamp = NONE;
822 DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename(path));
823 asprintf(&m.resolution, "%dx%d", vc->width, vc->height);
824 if( ctx->bit_rate > 8 )
825 asprintf(&m.bitrate, "%u", ctx->bit_rate / 8);
826 if( ctx->duration > 0 ) {
827 duration = (int)(ctx->duration / AV_TIME_BASE);
828 hours = (int)(duration / 3600);
829 min = (int)(duration / 60 % 60);
830 sec = (int)(duration % 60);
831 ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000);
832 asprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms);
835 /* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers.
836 * Skip DLNA parsing for everything else. */
837 if( strcmp(ctx->iformat->name, "avi") == 0 )
839 asprintf(&m.mime, "video/x-msvideo");
840 if( vc->codec_id == CODEC_ID_MPEG4 )
842 fourcc[0] = vc->codec_tag & 0xff;
843 fourcc[1] = vc->codec_tag>>8 & 0xff;
844 fourcc[2] = vc->codec_tag>>16 & 0xff;
845 fourcc[3] = vc->codec_tag>>24 & 0xff;
846 if( memcmp(fourcc, "XVID", 4) == 0 ||
847 memcmp(fourcc, "DX50", 4) == 0 ||
848 memcmp(fourcc, "DIVX", 4) == 0 )
849 asprintf(&m.creator, "DiVX");
852 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 &&
853 ends_with(path, ".mov") )
854 asprintf(&m.mime, "video/quicktime");
855 else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 )
856 asprintf(&m.mime, "video/x-matroska");
857 else if( strcmp(ctx->iformat->name, "flv") == 0 )
858 asprintf(&m.mime, "video/x-flv");
859 if( m.mime )
860 goto video_no_dlna;
862 switch( vc->codec_id )
864 case CODEC_ID_MPEG1VIDEO:
865 if( strcmp(ctx->iformat->name, "mpeg") == 0 )
867 if( (vc->width == 352) &&
868 (vc->height <= 288) )
870 asprintf(&m.dlna_pn, "MPEG1;%s", dlna_no_conv);
872 asprintf(&m.mime, "video/mpeg");
874 break;
875 case CODEC_ID_MPEG2VIDEO:
876 m.dlna_pn = malloc(64);
877 off = sprintf(m.dlna_pn, "MPEG_");
878 if( strcmp(ctx->iformat->name, "mpegts") == 0 )
880 int raw_packet_size;
881 int dlna_ts_present = dlna_timestamp_is_present(path, &raw_packet_size);
882 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS packet size %d\n",
883 video_stream, basename(path), m.resolution, raw_packet_size);
884 off += sprintf(m.dlna_pn+off, "TS_");
885 if( (vc->width >= 1280) &&
886 (vc->height >= 720) )
888 off += sprintf(m.dlna_pn+off, "HD_NA");
890 else
892 off += sprintf(m.dlna_pn+off, "SD_");
893 if( (vc->height == 576) ||
894 (vc->height == 288) )
895 off += sprintf(m.dlna_pn+off, "EU");
896 else
897 off += sprintf(m.dlna_pn+off, "NA");
899 if( raw_packet_size == MPEG_TS_PACKET_LENGTH_DLNA )
901 if (dlna_ts_present)
902 ts_timestamp = VALID;
903 else
904 ts_timestamp = EMPTY;
906 else if( raw_packet_size != MPEG_TS_PACKET_LENGTH )
908 DPRINTF(E_DEBUG, L_METADATA, "Unsupported DLNA TS packet size [%d] (%s)\n",
909 raw_packet_size, basename(path));
910 free(m.dlna_pn);
911 m.dlna_pn = NULL;
913 switch( ts_timestamp )
915 case NONE:
916 asprintf(&m.mime, "video/mpeg");
917 if( m.dlna_pn )
918 off += sprintf(m.dlna_pn+off, "_ISO");
919 break;
920 case VALID:
921 off += sprintf(m.dlna_pn+off, "_T");
922 case EMPTY:
923 asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
924 default:
925 break;
928 else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
930 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n",
931 video_stream, basename(path), m.resolution);
932 off += sprintf(m.dlna_pn+off, "PS_");
933 if( (vc->height == 576) ||
934 (vc->height == 288) )
935 off += sprintf(m.dlna_pn+off, "PAL");
936 else
937 off += sprintf(m.dlna_pn+off, "NTSC");
938 asprintf(&m.mime, "video/mpeg");
940 else
942 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [%s] is %s non-DLNA MPEG2\n",
943 video_stream, basename(path), ctx->iformat->name, m.resolution);
944 free(m.dlna_pn);
945 m.dlna_pn = NULL;
947 if( m.dlna_pn )
948 sprintf(m.dlna_pn+off, ";%s", dlna_no_conv);
949 break;
950 case CODEC_ID_H264:
951 m.dlna_pn = malloc(128);
952 off = sprintf(m.dlna_pn, "AVC_");
954 if( strcmp(ctx->iformat->name, "mpegts") == 0 )
956 AVRational display_aspect_ratio;
957 int fps, interlaced;
958 int raw_packet_size;
959 int dlna_ts_present = dlna_timestamp_is_present(path, &raw_packet_size);
961 off += sprintf(m.dlna_pn+off, "TS_");
962 if (vc->sample_aspect_ratio.num) {
963 av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
964 vc->width * vc->sample_aspect_ratio.num,
965 vc->height * vc->sample_aspect_ratio.den,
966 1024*1024);
968 fps = ctx->streams[video_stream]->r_frame_rate.num / ctx->streams[video_stream]->r_frame_rate.den;
969 interlaced = (ctx->streams[video_stream]->r_frame_rate.num / vc->time_base.den);
970 if( ((((vc->width == 1920 || vc->width == 1440) && vc->height == 1080) ||
971 (vc->width == 720 && vc->height == 480)) && fps == 59 && interlaced) ||
972 ((vc->width == 1280 && vc->height == 720) && fps == 59 && !interlaced) )
974 if( (vc->profile == FF_PROFILE_H264_MAIN || vc->profile == FF_PROFILE_H264_HIGH) &&
975 audio_profile == PROFILE_AUDIO_AC3 )
977 off += sprintf(m.dlna_pn+off, "HD_60_");
978 vc->profile = FF_PROFILE_SKIP;
981 else if( ((vc->width == 1920 && vc->height == 1080) ||
982 (vc->width == 1440 && vc->height == 1080) ||
983 (vc->width == 1280 && vc->height == 720) ||
984 (vc->width == 720 && vc->height == 576)) &&
985 interlaced && fps == 50 )
987 if( (vc->profile == FF_PROFILE_H264_MAIN || vc->profile == FF_PROFILE_H264_HIGH) &&
988 audio_profile == PROFILE_AUDIO_AC3 )
990 off += sprintf(m.dlna_pn+off, "HD_50_");
991 vc->profile = FF_PROFILE_SKIP;
994 switch( vc->profile )
996 case FF_PROFILE_H264_BASELINE:
997 off += sprintf(m.dlna_pn+off, "BL_");
998 if( vc->width <= 352 &&
999 vc->height <= 288 &&
1000 vc->bit_rate <= 384000 )
1002 off += sprintf(m.dlna_pn+off, "CIF15_");
1003 break;
1005 else if( vc->width <= 352 &&
1006 vc->height <= 288 &&
1007 vc->bit_rate <= 3000000 )
1009 off += sprintf(m.dlna_pn+off, "CIF30_");
1010 break;
1012 /* Fall back to Main Profile if it doesn't match a Baseline DLNA profile. */
1013 else
1014 off -= 3;
1015 default:
1016 case FF_PROFILE_H264_MAIN:
1017 off += sprintf(m.dlna_pn+off, "MP_");
1018 if( vc->profile != FF_PROFILE_H264_BASELINE &&
1019 vc->profile != FF_PROFILE_H264_MAIN )
1021 DPRINTF(E_DEBUG, L_METADATA, "Unknown AVC profile %d; assuming MP. [%s]\n",
1022 vc->profile, basename(path));
1024 if( vc->width <= 720 &&
1025 vc->height <= 576 &&
1026 vc->bit_rate <= 10000000 )
1028 off += sprintf(m.dlna_pn+off, "SD_");
1030 else if( vc->width <= 1920 &&
1031 vc->height <= 1152 &&
1032 vc->bit_rate <= 20000000 )
1034 off += sprintf(m.dlna_pn+off, "HD_");
1036 else
1038 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%s, %dx%d, %dbps : %s]\n",
1039 m.dlna_pn, vc->width, vc->height, vc->bit_rate, basename(path));
1040 free(m.dlna_pn);
1041 m.dlna_pn = NULL;
1043 break;
1044 case FF_PROFILE_H264_HIGH:
1045 off += sprintf(m.dlna_pn+off, "HP_");
1046 if( vc->width <= 1920 &&
1047 vc->height <= 1152 &&
1048 vc->bit_rate <= 30000000 &&
1049 audio_profile == PROFILE_AUDIO_AC3 )
1051 off += sprintf(m.dlna_pn+off, "HD_");
1053 else
1055 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 HP video profile! [%dbps, %d audio : %s]\n",
1056 vc->bit_rate, audio_profile, basename(path));
1057 free(m.dlna_pn);
1058 m.dlna_pn = NULL;
1060 break;
1061 case FF_PROFILE_SKIP:
1062 break;
1064 if( !m.dlna_pn )
1065 break;
1066 switch( audio_profile )
1068 case PROFILE_AUDIO_MP3:
1069 off += sprintf(m.dlna_pn+off, "MPEG1_L3");
1070 break;
1071 case PROFILE_AUDIO_AC3:
1072 off += sprintf(m.dlna_pn+off, "AC3");
1073 break;
1074 case PROFILE_AUDIO_AAC:
1075 case PROFILE_AUDIO_AAC_MULT5:
1076 off += sprintf(m.dlna_pn+off, "AAC_MULT5");
1077 break;
1078 default:
1079 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file [%s]\n",
1080 m.dlna_pn, basename(path));
1081 free(m.dlna_pn);
1082 m.dlna_pn = NULL;
1083 break;
1085 if( !m.dlna_pn )
1086 break;
1087 if( raw_packet_size == MPEG_TS_PACKET_LENGTH_DLNA )
1089 if( vc->profile == FF_PROFILE_H264_HIGH ||
1090 dlna_ts_present )
1091 ts_timestamp = VALID;
1092 else
1093 ts_timestamp = EMPTY;
1095 else if( raw_packet_size != MPEG_TS_PACKET_LENGTH )
1097 DPRINTF(E_DEBUG, L_METADATA, "Unsupported DLNA TS packet size [%d] (%s)\n",
1098 raw_packet_size, basename(path));
1099 free(m.dlna_pn);
1100 m.dlna_pn = NULL;
1102 switch( ts_timestamp )
1104 case NONE:
1105 if( m.dlna_pn )
1106 off += sprintf(m.dlna_pn+off, "_ISO");
1107 break;
1108 case VALID:
1109 off += sprintf(m.dlna_pn+off, "_T");
1110 case EMPTY:
1111 asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
1112 default:
1113 break;
1116 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1118 off += sprintf(m.dlna_pn+off, "MP4_");
1120 switch( vc->profile ) {
1121 case FF_PROFILE_H264_BASELINE:
1122 if( vc->width <= 352 &&
1123 vc->height <= 288 )
1125 if( ctx->bit_rate < 600000 )
1126 off += sprintf(m.dlna_pn+off, "BL_CIF15_");
1127 else if( ctx->bit_rate < 5000000 )
1128 off += sprintf(m.dlna_pn+off, "BL_CIF30_");
1129 else
1130 goto mp4_mp_fallback;
1132 if( audio_profile == PROFILE_AUDIO_AMR )
1134 off += sprintf(m.dlna_pn+off, "AMR");
1136 else if( audio_profile == PROFILE_AUDIO_AAC )
1138 off += sprintf(m.dlna_pn+off, "AAC_");
1139 if( ctx->bit_rate < 520000 )
1141 off += sprintf(m.dlna_pn+off, "520");
1143 else if( ctx->bit_rate < 940000 )
1145 off += sprintf(m.dlna_pn+off, "940");
1147 else
1149 off -= 13;
1150 goto mp4_mp_fallback;
1153 else
1155 off -= 9;
1156 goto mp4_mp_fallback;
1159 else if( vc->width <= 720 &&
1160 vc->height <= 576 )
1162 if( vc->level == 30 &&
1163 audio_profile == PROFILE_AUDIO_AAC &&
1164 ctx->bit_rate <= 5000000 )
1165 off += sprintf(m.dlna_pn+off, "BL_L3L_SD_AAC");
1166 else if( vc->level <= 31 &&
1167 audio_profile == PROFILE_AUDIO_AAC &&
1168 ctx->bit_rate <= 15000000 )
1169 off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC");
1170 else
1171 goto mp4_mp_fallback;
1173 else if( vc->width <= 1280 &&
1174 vc->height <= 720 )
1176 if( vc->level <= 31 &&
1177 audio_profile == PROFILE_AUDIO_AAC &&
1178 ctx->bit_rate <= 15000000 )
1179 off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC");
1180 else if( vc->level <= 32 &&
1181 audio_profile == PROFILE_AUDIO_AAC &&
1182 ctx->bit_rate <= 21000000 )
1183 off += sprintf(m.dlna_pn+off, "BL_L32_HD_AAC");
1184 else
1185 goto mp4_mp_fallback;
1187 else
1188 goto mp4_mp_fallback;
1189 break;
1190 case FF_PROFILE_H264_MAIN:
1191 mp4_mp_fallback:
1192 off += sprintf(m.dlna_pn+off, "MP_");
1193 /* AVC MP4 SD profiles - 10 Mbps max */
1194 if( vc->width <= 720 &&
1195 vc->height <= 576 &&
1196 vc->bit_rate <= 10000000 )
1198 sprintf(m.dlna_pn+off, "SD_");
1199 if( audio_profile == PROFILE_AUDIO_AC3 )
1200 off += sprintf(m.dlna_pn+off, "AC3");
1201 else if( audio_profile == PROFILE_AUDIO_AAC ||
1202 audio_profile == PROFILE_AUDIO_AAC_MULT5 )
1203 off += sprintf(m.dlna_pn+off, "AAC_MULT5");
1204 else if( audio_profile == PROFILE_AUDIO_MP3 )
1205 off += sprintf(m.dlna_pn+off, "MPEG1_L3");
1206 else
1207 m.dlna_pn[10] = '\0';
1209 else if( vc->width <= 1280 &&
1210 vc->height <= 720 &&
1211 vc->bit_rate <= 15000000 &&
1212 audio_profile == PROFILE_AUDIO_AAC )
1214 off += sprintf(m.dlna_pn+off, "HD_720p_AAC");
1216 else if( vc->width <= 1920 &&
1217 vc->height <= 1080 &&
1218 vc->bit_rate <= 21000000 &&
1219 audio_profile == PROFILE_AUDIO_AAC )
1221 off += sprintf(m.dlna_pn+off, "HD_1080i_AAC");
1223 if( strlen(m.dlna_pn) <= 11 )
1225 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file %s\n",
1226 m.dlna_pn, basename(path));
1227 free(m.dlna_pn);
1228 m.dlna_pn = NULL;
1230 break;
1231 case FF_PROFILE_H264_HIGH:
1232 if( vc->width <= 1920 &&
1233 vc->height <= 1080 &&
1234 vc->bit_rate <= 25000000 &&
1235 audio_profile == PROFILE_AUDIO_AAC )
1237 off += sprintf(m.dlna_pn+off, "HP_HD_AAC");
1239 break;
1240 default:
1241 DPRINTF(E_DEBUG, L_METADATA, "AVC profile [%d] not recognized for file %s\n",
1242 vc->profile, basename(path));
1243 free(m.dlna_pn);
1244 m.dlna_pn = NULL;
1245 break;
1248 else
1250 free(m.dlna_pn);
1251 m.dlna_pn = NULL;
1253 if( m.dlna_pn )
1254 sprintf(m.dlna_pn+off, ";%s", dlna_no_conv);
1255 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename(path));
1256 break;
1257 case CODEC_ID_MPEG4:
1258 fourcc[0] = vc->codec_tag & 0xff;
1259 fourcc[1] = vc->codec_tag>>8 & 0xff;
1260 fourcc[2] = vc->codec_tag>>16 & 0xff;
1261 fourcc[3] = vc->codec_tag>>24 & 0xff;
1262 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%c%c%c%c/0x%X]\n",
1263 video_stream, basename(path),
1264 isprint(fourcc[0]) ? fourcc[0] : '_',
1265 isprint(fourcc[1]) ? fourcc[1] : '_',
1266 isprint(fourcc[2]) ? fourcc[2] : '_',
1267 isprint(fourcc[3]) ? fourcc[3] : '_',
1268 vc->codec_tag);
1270 if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1272 m.dlna_pn = malloc(128);
1273 off = sprintf(m.dlna_pn, "MPEG4_P2_");
1275 if( ends_with(path, ".3gp") )
1277 asprintf(&m.mime, "video/3gpp");
1278 switch( audio_profile )
1280 case PROFILE_AUDIO_AAC:
1281 off += sprintf(m.dlna_pn+off, "3GPP_SP_L0B_AAC");
1282 break;
1283 case PROFILE_AUDIO_AMR:
1284 off += sprintf(m.dlna_pn+off, "3GPP_SP_L0B_AMR");
1285 break;
1286 default:
1287 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n",
1288 ac->codec_id, basename(path));
1289 free(m.dlna_pn);
1290 m.dlna_pn = NULL;
1291 break;
1294 else
1296 if( ctx->bit_rate <= 1000000 &&
1297 audio_profile == PROFILE_AUDIO_AAC )
1299 off += sprintf(m.dlna_pn+off, "MP4_ASP_AAC");
1301 else if( ctx->bit_rate <= 4000000 &&
1302 vc->width <= 640 &&
1303 vc->height <= 480 &&
1304 audio_profile == PROFILE_AUDIO_AAC )
1306 off += sprintf(m.dlna_pn+off, "MP4_SP_VGA_AAC");
1308 else
1310 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n",
1311 vc->width,
1312 vc->height,
1313 ctx->bit_rate);
1314 free(m.dlna_pn);
1315 m.dlna_pn = NULL;
1318 if( m.dlna_pn )
1319 sprintf(m.dlna_pn+off, ";%s", dlna_no_conv);
1321 break;
1322 case CODEC_ID_WMV3:
1323 /* I'm not 100% sure this is correct, but it works on everything I could get my hands on */
1324 if( vc->extradata_size > 0 )
1326 if( !((vc->extradata[0] >> 3) & 1) )
1327 vc->level = 0;
1328 if( !((vc->extradata[0] >> 6) & 1) )
1329 vc->profile = 0;
1331 case CODEC_ID_VC1:
1332 if( strcmp(ctx->iformat->name, "asf") != 0 )
1334 DPRINTF(E_DEBUG, L_METADATA, "Skipping DLNA parsing for non-ASF VC1 file %s\n", path);
1335 break;
1337 m.dlna_pn = malloc(64);
1338 off = sprintf(m.dlna_pn, "WMV");
1339 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename(path));
1340 asprintf(&m.mime, "video/x-ms-wmv");
1341 if( (vc->width <= 176) &&
1342 (vc->height <= 144) &&
1343 (vc->level == 0) )
1345 off += sprintf(m.dlna_pn+off, "SPLL_");
1346 switch( audio_profile )
1348 case PROFILE_AUDIO_MP3:
1349 off += sprintf(m.dlna_pn+off, "MP3");
1350 break;
1351 case PROFILE_AUDIO_WMA_BASE:
1352 off += sprintf(m.dlna_pn+off, "BASE");
1353 break;
1354 default:
1355 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPLL/0x%X file %s\n",
1356 audio_profile, basename(path));
1357 free(m.dlna_pn);
1358 m.dlna_pn = NULL;
1359 break;
1362 else if( (vc->width <= 352) &&
1363 (vc->height <= 288) &&
1364 (vc->profile == 0) &&
1365 (ctx->bit_rate/8 <= 384000) )
1367 off += sprintf(m.dlna_pn+off, "SPML_");
1368 switch( audio_profile )
1370 case PROFILE_AUDIO_MP3:
1371 off += sprintf(m.dlna_pn+off, "MP3");
1372 break;
1373 case PROFILE_AUDIO_WMA_BASE:
1374 off += sprintf(m.dlna_pn+off, "BASE");
1375 break;
1376 default:
1377 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n",
1378 audio_profile, basename(path));
1379 free(m.dlna_pn);
1380 m.dlna_pn = NULL;
1381 break;
1384 else if( (vc->width <= 720) &&
1385 (vc->height <= 576) &&
1386 (ctx->bit_rate/8 <= 10000000) )
1388 off += sprintf(m.dlna_pn+off, "MED_");
1389 switch( audio_profile )
1391 case PROFILE_AUDIO_WMA_PRO:
1392 off += sprintf(m.dlna_pn+off, "PRO");
1393 break;
1394 case PROFILE_AUDIO_WMA_FULL:
1395 off += sprintf(m.dlna_pn+off, "FULL");
1396 break;
1397 case PROFILE_AUDIO_WMA_BASE:
1398 off += sprintf(m.dlna_pn+off, "BASE");
1399 break;
1400 default:
1401 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n",
1402 audio_profile, basename(path));
1403 free(m.dlna_pn);
1404 m.dlna_pn = NULL;
1405 break;
1408 else if( (vc->width <= 1920) &&
1409 (vc->height <= 1080) &&
1410 (ctx->bit_rate/8 <= 20000000) )
1412 off += sprintf(m.dlna_pn+off, "HIGH_");
1413 switch( audio_profile )
1415 case PROFILE_AUDIO_WMA_PRO:
1416 off += sprintf(m.dlna_pn+off, "PRO");
1417 break;
1418 case PROFILE_AUDIO_WMA_FULL:
1419 off += sprintf(m.dlna_pn+off, "FULL");
1420 break;
1421 default:
1422 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n",
1423 audio_profile, basename(path));
1424 free(m.dlna_pn);
1425 m.dlna_pn = NULL;
1426 break;
1429 if( m.dlna_pn )
1430 sprintf(m.dlna_pn+off, ";%s", dlna_no_conv);
1431 break;
1432 case CODEC_ID_MSMPEG4V3:
1433 asprintf(&m.mime, "video/x-msvideo");
1434 default:
1435 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n",
1436 video_stream, basename(path), m.resolution, vc->codec_id);
1437 break;
1440 if( !m.mime )
1442 if( strcmp(ctx->iformat->name, "avi") == 0 )
1443 asprintf(&m.mime, "video/x-msvideo");
1444 else if( strncmp(ctx->iformat->name, "mpeg", 4) == 0 )
1445 asprintf(&m.mime, "video/mpeg");
1446 else if( strcmp(ctx->iformat->name, "asf") == 0 )
1447 asprintf(&m.mime, "video/x-ms-wmv");
1448 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1449 if( ends_with(path, ".mov") )
1450 asprintf(&m.mime, "video/quicktime");
1451 else
1452 asprintf(&m.mime, "video/mp4");
1453 else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 )
1454 asprintf(&m.mime, "video/x-matroska");
1455 else if( strcmp(ctx->iformat->name, "flv") == 0 )
1456 asprintf(&m.mime, "video/x-flv");
1457 else
1458 DPRINTF(E_WARN, L_METADATA, "%s: Unhandled format: %s\n", path, ctx->iformat->name);
1461 if( strcmp(ctx->iformat->name, "asf") == 0 )
1463 if( readtags((char *)path, &video, &file, "en_US", "asf") == 0 )
1465 if( video.title && *video.title )
1467 m.title = escape_tag(trim(video.title), 1);
1469 if( video.genre && *video.genre )
1471 m.genre = escape_tag(trim(video.genre), 1);
1473 if( video.contributor[ROLE_TRACKARTIST] && *video.contributor[ROLE_TRACKARTIST] )
1475 m.artist = escape_tag(trim(video.contributor[ROLE_TRACKARTIST]), 1);
1477 if( video.contributor[ROLE_ALBUMARTIST] && *video.contributor[ROLE_ALBUMARTIST] )
1479 m.creator = escape_tag(trim(video.contributor[ROLE_ALBUMARTIST]), 1);
1481 else
1483 m.creator = m.artist;
1484 free_flags &= ~FLAG_CREATOR;
1488 #ifndef NETGEAR
1489 #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
1490 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1492 if( ctx->metadata )
1494 AVMetadataTag *tag = NULL;
1496 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Metadata:\n");
1497 while( (tag = av_metadata_get(ctx->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX)) )
1499 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " %-16s: %s\n", tag->key, tag->value);
1500 if( strcmp(tag->key, "title") == 0 )
1501 m.title = escape_tag(trim(tag->value), 1);
1502 else if( strcmp(tag->key, "genre") == 0 )
1503 m.genre = escape_tag(trim(tag->value), 1);
1504 else if( strcmp(tag->key, "artist") == 0 )
1505 m.artist = escape_tag(trim(tag->value), 1);
1506 else if( strcmp(tag->key, "comment") == 0 )
1507 m.comment = escape_tag(trim(tag->value), 1);
1511 #endif
1512 #endif
1513 video_no_dlna:
1514 av_close_input_file(ctx);
1516 #ifdef TIVO_SUPPORT
1517 if( ends_with(path, ".TiVo") && is_tivo_file(path) )
1519 if( m.dlna_pn )
1521 free(m.dlna_pn);
1522 m.dlna_pn = NULL;
1524 m.mime = realloc(m.mime, 18);
1525 strcpy(m.mime, "video/x-tivo-mpeg");
1527 #endif
1528 if( !m.title )
1529 m.title = strdup(name);
1531 album_art = find_album_art(path, video.image, video.image_size);
1532 freetags(&video);
1534 ret = sql_exec(db, "INSERT into DETAILS"
1535 " (PATH, SIZE, TIMESTAMP, DURATION, DATE, CHANNELS, BITRATE, SAMPLERATE, RESOLUTION,"
1536 " TITLE, CREATOR, ARTIST, GENRE, COMMENT, DLNA_PN, MIME, ALBUM_ART) "
1537 "VALUES"
1538 " (%Q, %lld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, '%q', %Q, %Q, %Q, %Q, %Q, '%q', %lld);",
1539 path, file.st_size, file.st_mtime, m.duration,
1540 m.date, m.channels, m.bitrate, m.frequency, m.resolution,
1541 m.title, m.creator, m.artist, m.genre, m.comment, m.dlna_pn,
1542 m.mime, album_art);
1543 if( ret != SQLITE_OK )
1545 fprintf(stderr, "Error inserting details for '%s'!\n", path);
1546 ret = 0;
1548 else
1550 ret = sqlite3_last_insert_rowid(db);
1551 check_for_captions(path, ret);
1553 free_metadata(&m, free_flags);
1555 return ret;