Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / minidlna / metadata.c
blob3c196b211f37cce656a01dde3b4889b12d982fac
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
77 #define FLAG_ROTATION 0x00008000
79 /* Audio profile flags */
80 enum audio_profiles {
81 PROFILE_AUDIO_UNKNOWN,
82 PROFILE_AUDIO_MP3,
83 PROFILE_AUDIO_AC3,
84 PROFILE_AUDIO_WMA_BASE,
85 PROFILE_AUDIO_WMA_FULL,
86 PROFILE_AUDIO_WMA_PRO,
87 PROFILE_AUDIO_MP2,
88 PROFILE_AUDIO_PCM,
89 PROFILE_AUDIO_AAC,
90 PROFILE_AUDIO_AAC_MULT5,
91 PROFILE_AUDIO_AMR
94 /* This function shamelessly copied from libdlna */
95 #define MPEG_TS_SYNC_CODE 0x47
96 #define MPEG_TS_PACKET_LENGTH 188
97 #define MPEG_TS_PACKET_LENGTH_DLNA 192 /* prepends 4 bytes to TS packet */
98 int
99 dlna_timestamp_is_present(const char * filename, int * raw_packet_size)
101 unsigned char buffer[3*MPEG_TS_PACKET_LENGTH_DLNA];
102 int fd, i;
104 /* read file header */
105 fd = open(filename, O_RDONLY);
106 read(fd, buffer, MPEG_TS_PACKET_LENGTH_DLNA*3);
107 close(fd);
108 for( i=0; i < MPEG_TS_PACKET_LENGTH_DLNA; i++ )
110 if( buffer[i] == MPEG_TS_SYNC_CODE )
112 if (buffer[i + MPEG_TS_PACKET_LENGTH_DLNA] == MPEG_TS_SYNC_CODE &&
113 buffer[i + MPEG_TS_PACKET_LENGTH_DLNA*2] == MPEG_TS_SYNC_CODE)
115 *raw_packet_size = MPEG_TS_PACKET_LENGTH_DLNA;
116 if (buffer[i+MPEG_TS_PACKET_LENGTH] == 0x00 &&
117 buffer[i+MPEG_TS_PACKET_LENGTH+1] == 0x00 &&
118 buffer[i+MPEG_TS_PACKET_LENGTH+2] == 0x00 &&
119 buffer[i+MPEG_TS_PACKET_LENGTH+3] == 0x00)
120 return 0;
121 else
122 return 1;
123 } else if (buffer[i + MPEG_TS_PACKET_LENGTH] == MPEG_TS_SYNC_CODE &&
124 buffer[i + MPEG_TS_PACKET_LENGTH*2] == MPEG_TS_SYNC_CODE) {
125 *raw_packet_size = MPEG_TS_PACKET_LENGTH;
126 return 0;
130 *raw_packet_size = 0;
131 return 0;
134 #ifdef TIVO_SUPPORT
136 is_tivo_file(const char * path)
138 unsigned char buf[5];
139 unsigned char hdr[5] = { 'T','i','V','o','\0' };
140 int fd;
142 /* read file header */
143 fd = open(path, O_RDONLY);
144 read(fd, buf, 5);
145 close(fd);
147 return( !memcmp(buf, hdr, 5) );
149 #endif
151 void
152 check_for_captions(const char * path, sqlite_int64 detailID)
154 char *file = malloc(PATH_MAX);
155 char *id = NULL;
157 sprintf(file, "%s", path);
158 strip_ext(file);
160 /* If we weren't given a detail ID, look for one. */
161 if( !detailID )
163 id = sql_get_text_field(db, "SELECT ID from DETAILS where PATH glob '%q.*'"
164 " and MIME glob 'video/*' limit 1", file);
165 if( id )
167 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like a caption file.\n", path);
168 detailID = strtoll(id, NULL, 10);
170 else
172 //DPRINTF(E_DEBUG, L_METADATA, "No file found for caption %s.\n", path);
173 goto no_source_video;
177 strcat(file, ".srt");
178 if( access(file, R_OK) == 0 )
180 sql_exec(db, "INSERT into CAPTIONS"
181 " (ID, PATH) "
182 "VALUES"
183 " (%lld, %Q)", detailID, file);
185 no_source_video:
186 if( id )
187 sqlite3_free(id);
188 free(file);
191 void
192 parse_nfo(const char * path, metadata_t * m)
194 FILE *nfo;
195 char buf[65536];
196 struct NameValueParserData xml;
197 struct stat file;
198 size_t nread;
199 char *val, *val2;
201 if( stat(path, &file) != 0 ||
202 file.st_size > 65536 )
204 DPRINTF(E_INFO, L_METADATA, "Not parsing very large .nfo file %s\n", path);
205 return;
207 DPRINTF(E_DEBUG, L_METADATA, "Parsing .nfo file: %s\n", path);
208 nfo = fopen(path, "r");
209 if( !nfo )
210 return;
211 nread = fread(&buf, 1, sizeof(buf), nfo);
213 ParseNameValue(buf, nread, &xml);
215 //printf("\ttype: %s\n", GetValueFromNameValueList(&xml, "rootElement"));
216 val = GetValueFromNameValueList(&xml, "title");
217 if( val )
219 val2 = GetValueFromNameValueList(&xml, "episodetitle");
220 if( val2 )
221 asprintf(&m->title, "%s - %s", val, val2);
222 else
223 m->title = strdup(val);
226 val = GetValueFromNameValueList(&xml, "plot");
227 if( val )
228 m->comment = strdup(val);
230 val = GetValueFromNameValueList(&xml, "capturedate");
231 if( val )
232 m->date = strdup(val);
234 val = GetValueFromNameValueList(&xml, "genre");
235 if( val )
236 m->genre = strdup(val);
238 ClearNameValueList(&xml);
239 fclose(nfo);
242 void
243 free_metadata(metadata_t * m, uint32_t flags)
245 if( flags & FLAG_TITLE )
246 free(m->title);
247 if( flags & FLAG_ARTIST )
248 free(m->artist);
249 if( flags & FLAG_ALBUM )
250 free(m->album);
251 if( flags & FLAG_GENRE )
252 free(m->genre);
253 if( flags & FLAG_CREATOR )
254 free(m->creator);
255 if( flags & FLAG_DATE )
256 free(m->date);
257 if( flags & FLAG_COMMENT )
258 free(m->comment);
259 if( flags & FLAG_DLNA_PN )
260 free(m->dlna_pn);
261 if( flags & FLAG_MIME )
262 free(m->mime);
263 if( flags & FLAG_DURATION )
264 free(m->duration);
265 if( flags & FLAG_RESOLUTION )
266 free(m->resolution);
267 if( flags & FLAG_BITRATE )
268 free(m->bitrate);
269 if( flags & FLAG_FREQUENCY )
270 free(m->frequency);
271 if( flags & FLAG_BPS )
272 free(m->bps);
273 if( flags & FLAG_CHANNELS )
274 free(m->channels);
275 if( flags & FLAG_ROTATION )
276 free(m->rotation);
279 sqlite_int64
280 GetFolderMetadata(const char * name, const char * path, const char * artist, const char * genre, sqlite3_int64 album_art)
282 int ret;
284 ret = sql_exec(db, "INSERT into DETAILS"
285 " (TITLE, PATH, CREATOR, ARTIST, GENRE, ALBUM_ART) "
286 "VALUES"
287 " ('%q', %Q, %Q, %Q, %Q, %lld);",
288 name, path, artist, artist, genre, album_art);
289 if( ret != SQLITE_OK )
290 ret = 0;
291 else
292 ret = sqlite3_last_insert_rowid(db);
294 return ret;
297 sqlite_int64
298 GetAudioMetadata(const char * path, char * name)
300 char type[4];
301 static char lang[6] = { '\0' };
302 struct stat file;
303 sqlite_int64 ret;
304 char *esc_tag;
305 int i;
306 sqlite_int64 album_art = 0;
307 struct song_metadata song;
308 metadata_t m;
309 uint32_t free_flags = FLAG_MIME|FLAG_DURATION|FLAG_DLNA_PN|FLAG_DATE;
310 memset(&m, '\0', sizeof(metadata_t));
312 if ( stat(path, &file) != 0 )
313 return 0;
314 strip_ext(name);
316 if( ends_with(path, ".mp3") )
318 strcpy(type, "mp3");
319 m.mime = strdup("audio/mpeg");
321 else if( ends_with(path, ".m4a") || ends_with(path, ".mp4") ||
322 ends_with(path, ".aac") || ends_with(path, ".m4p") )
324 strcpy(type, "aac");
325 m.mime = strdup("audio/mp4");
327 else if( ends_with(path, ".3gp") )
329 strcpy(type, "aac");
330 m.mime = strdup("audio/3gpp");
332 else if( ends_with(path, ".wma") || ends_with(path, ".asf") )
334 strcpy(type, "asf");
335 m.mime = strdup("audio/x-ms-wma");
337 else if( ends_with(path, ".flac") || ends_with(path, ".fla") || ends_with(path, ".flc") )
339 strcpy(type, "flc");
340 m.mime = strdup("audio/x-flac");
342 else if( ends_with(path, ".wav") )
344 strcpy(type, "wav");
345 m.mime = strdup("audio/x-wav");
347 else if( ends_with(path, ".ogg") || ends_with(path, ".oga") )
349 strcpy(type, "ogg");
350 m.mime = strdup("audio/ogg");
352 else if( ends_with(path, ".pcm") )
354 strcpy(type, "pcm");
355 m.mime = strdup("audio/L16");
357 else
359 DPRINTF(E_WARN, L_GENERAL, "Unhandled file extension on %s\n", path);
360 return 0;
363 if( !(*lang) )
365 if( !getenv("LANG") )
366 strcpy(lang, "en_US");
367 else
368 strncpyt(lang, getenv("LANG"), sizeof(lang));
371 if( readtags((char *)path, &song, &file, lang, type) != 0 )
373 DPRINTF(E_WARN, L_GENERAL, "Cannot extract tags from %s!\n", path);
374 freetags(&song);
375 free_metadata(&m, free_flags);
376 return 0;
379 if( song.dlna_pn )
380 m.dlna_pn = strdup(song.dlna_pn);
381 if( song.year )
382 asprintf(&m.date, "%04d-01-01", song.year);
383 asprintf(&m.duration, "%d:%02d:%02d.%03d",
384 (song.song_length/3600000),
385 (song.song_length/60000%60),
386 (song.song_length/1000%60),
387 (song.song_length%1000));
388 if( song.title && *song.title )
390 m.title = trim(song.title);
391 if( (esc_tag = escape_tag(m.title, 0)) )
393 free_flags |= FLAG_TITLE;
394 m.title = esc_tag;
397 else
399 m.title = name;
401 for( i=ROLE_START; i<N_ROLE; i++ )
403 if( song.contributor[i] && *song.contributor[i] )
405 m.creator = trim(song.contributor[i]);
406 if( strlen(m.creator) > 48 )
408 m.creator = strdup("Various Artists");
409 free_flags |= FLAG_CREATOR;
411 else if( (esc_tag = escape_tag(m.creator, 0)) )
413 m.creator = esc_tag;
414 free_flags |= FLAG_CREATOR;
416 m.artist = m.creator;
417 break;
420 /* If there is a band associated with the album, use it for virtual containers. */
421 if( (i != ROLE_BAND) && (i != ROLE_ALBUMARTIST) )
423 if( song.contributor[ROLE_BAND] && *song.contributor[ROLE_BAND] )
425 i = ROLE_BAND;
426 m.artist = trim(song.contributor[i]);
427 if( strlen(m.artist) > 48 )
429 m.artist = strdup("Various Artists");
430 free_flags |= FLAG_ARTIST;
432 else if( (esc_tag = escape_tag(m.artist, 0)) )
434 m.artist = esc_tag;
435 free_flags |= FLAG_ARTIST;
439 if( song.album && *song.album )
441 m.album = trim(song.album);
442 if( (esc_tag = escape_tag(m.album, 0)) )
444 free_flags |= FLAG_ALBUM;
445 m.album = esc_tag;
448 if( song.genre && *song.genre )
450 m.genre = trim(song.genre);
451 if( (esc_tag = escape_tag(m.genre, 0)) )
453 free_flags |= FLAG_GENRE;
454 m.genre = esc_tag;
457 if( song.comment && *song.comment )
459 m.comment = trim(song.comment);
460 if( (esc_tag = escape_tag(m.comment, 0)) )
462 free_flags |= FLAG_COMMENT;
463 m.comment = esc_tag;
467 album_art = find_album_art(path, song.image, song.image_size);
469 ret = sql_exec(db, "INSERT into DETAILS"
470 " (PATH, SIZE, TIMESTAMP, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE,"
471 " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, DISC, TRACK, DLNA_PN, MIME, ALBUM_ART) "
472 "VALUES"
473 " (%Q, %lld, %ld, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, %d, %Q, '%s', %lld);",
474 path, (long long)file.st_size, file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date,
475 m.title, m.creator, m.artist, m.album, m.genre, m.comment, song.disc, song.track,
476 m.dlna_pn, song.mime?song.mime:m.mime, album_art);
477 if( ret != SQLITE_OK )
479 fprintf(stderr, "Error inserting details for '%s'!\n", path);
480 ret = 0;
482 else
484 ret = sqlite3_last_insert_rowid(db);
486 freetags(&song);
487 free_metadata(&m, free_flags);
489 return ret;
492 /* For libjpeg error handling */
493 jmp_buf setjmp_buffer;
494 static void
495 libjpeg_error_handler(j_common_ptr cinfo)
497 cinfo->err->output_message (cinfo);
498 longjmp(setjmp_buffer, 1);
499 return;
502 sqlite_int64
503 GetImageMetadata(const char * path, char * name)
505 ExifData *ed;
506 ExifEntry *e = NULL;
507 ExifLoader *l;
508 struct jpeg_decompress_struct cinfo;
509 struct jpeg_error_mgr jerr;
510 FILE *infile;
511 int width=0, height=0, thumb=0;
512 char make[32], model[64] = {'\0'};
513 char b[1024];
514 struct stat file;
515 sqlite_int64 ret;
516 image_s * imsrc;
517 metadata_t m;
518 uint32_t free_flags = 0xFFFFFFFF;
519 memset(&m, '\0', sizeof(metadata_t));
521 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path);
522 if ( stat(path, &file) != 0 )
523 return 0;
524 strip_ext(name);
525 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
527 /* MIME hard-coded to JPEG for now, until we add PNG support */
528 m.mime = strdup("image/jpeg");
530 l = exif_loader_new();
531 exif_loader_write_file(l, path);
532 ed = exif_loader_get_data(l);
533 exif_loader_unref(l);
534 if( !ed )
535 goto no_exifdata;
537 e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
538 if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) )
540 m.date = strdup(exif_entry_get_value(e, b, sizeof(b)));
541 if( strlen(m.date) > 10 )
543 m.date[4] = '-';
544 m.date[7] = '-';
545 m.date[10] = 'T';
547 else {
548 free(m.date);
549 m.date = NULL;
552 else {
553 /* One last effort to get the date from XMP */
554 image_get_jpeg_date_xmp(path, &m.date);
556 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", m.date);
558 e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
559 if( e )
561 strncpyt(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
562 e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
563 if( e )
565 strncpyt(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));
566 if( !strcasestr(model, make) )
567 snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b)));
568 m.creator = escape_tag(trim(model), 1);
571 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * model: %s\n", model);
573 e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION);
574 if( e )
576 int rotate;
577 switch( exif_get_short(e->data, exif_data_get_byte_order(ed)) )
579 case 3:
580 rotate = 180;
581 break;
582 case 6:
583 rotate = 90;
584 break;
585 case 8:
586 rotate = 270;
587 break;
588 default:
589 rotate = 0;
590 break;
592 if( rotate )
594 if( asprintf(&m.rotation, "%d", rotate) < 0 )
595 m.rotation = NULL;
599 if( ed->size )
601 /* We might need to verify that the thumbnail is 160x160 or smaller */
602 if( ed->size > 12000 )
604 imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1, ROTATE_NONE);
605 if( imsrc )
607 if( (imsrc->width <= 160) && (imsrc->height <= 160) )
608 thumb = 1;
609 image_free(imsrc);
612 else
613 thumb = 1;
615 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb);
617 exif_data_unref(ed);
619 no_exifdata:
620 /* If SOF parsing fails, then fall through to reading the JPEG data with libjpeg to get the resolution */
621 if( image_get_jpeg_resolution(path, &width, &height) != 0 || !width || !height )
623 infile = fopen(path, "r");
624 if( infile )
626 cinfo.err = jpeg_std_error(&jerr);
627 jerr.error_exit = libjpeg_error_handler;
628 jpeg_create_decompress(&cinfo);
629 if( setjmp(setjmp_buffer) )
630 goto error;
631 jpeg_stdio_src(&cinfo, infile);
632 jpeg_read_header(&cinfo, TRUE);
633 jpeg_start_decompress(&cinfo);
634 width = cinfo.output_width;
635 height = cinfo.output_height;
636 error:
637 jpeg_destroy_decompress(&cinfo);
638 fclose(infile);
641 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height);
643 if( !width || !height )
645 free_metadata(&m, free_flags);
646 return 0;
648 if( width <= 640 && height <= 480 )
649 m.dlna_pn = strdup("JPEG_SM");
650 else if( width <= 1024 && height <= 768 )
651 m.dlna_pn = strdup("JPEG_MED");
652 else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) )
653 m.dlna_pn = strdup("JPEG_LRG");
654 asprintf(&m.resolution, "%dx%d", width, height);
656 ret = sql_exec(db, "INSERT into DETAILS"
657 " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION,"
658 " ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) "
659 "VALUES"
660 " (%Q, '%q', %lld, %ld, %Q, %Q, %Q, %d, %Q, %Q, %Q);",
661 path, name, (long long)file.st_size, file.st_mtime, m.date, m.resolution,
662 m.rotation, thumb, m.creator, m.dlna_pn, m.mime);
663 if( ret != SQLITE_OK )
665 fprintf(stderr, "Error inserting details for '%s'!\n", path);
666 ret = 0;
668 else
670 ret = sqlite3_last_insert_rowid(db);
672 free_metadata(&m, free_flags);
674 return ret;
677 sqlite_int64
678 GetVideoMetadata(const char * path, char * name)
680 struct stat file;
681 int ret, i;
682 struct tm *modtime;
683 AVFormatContext *ctx = NULL;
684 AVCodecContext *ac = NULL, *vc = NULL;
685 int audio_stream = -1, video_stream = -1;
686 enum audio_profiles audio_profile = PROFILE_AUDIO_UNKNOWN;
687 char fourcc[4];
688 sqlite_int64 album_art = 0;
689 char nfo[PATH_MAX], *ext;
690 struct song_metadata video;
691 metadata_t m;
692 uint32_t free_flags = 0xFFFFFFFF;
694 memset(&m, '\0', sizeof(m));
695 memset(&video, '\0', sizeof(video));
697 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing video %s...\n", name);
698 if ( stat(path, &file) != 0 )
699 return 0;
700 strip_ext(name);
701 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
703 av_register_all();
704 #if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(2<<8)+0)
705 if( avformat_open_input(&ctx, path, NULL, NULL) != 0 )
706 #else
707 if( av_open_input_file(&ctx, path, NULL, 0, NULL) != 0 )
708 #endif
710 DPRINTF(E_WARN, L_METADATA, "Opening %s failed!\n", path);
711 return 0;
713 av_find_stream_info(ctx);
714 //dump_format(ctx, 0, NULL, 0);
715 for( i=0; i<ctx->nb_streams; i++)
717 if( audio_stream == -1 &&
718 ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
720 audio_stream = i;
721 ac = ctx->streams[audio_stream]->codec;
722 continue;
724 else if( video_stream == -1 &&
725 ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
727 video_stream = i;
728 vc = ctx->streams[video_stream]->codec;
729 continue;
732 /* This must not be a video file. */
733 if( !vc )
735 av_close_input_file(ctx);
736 if( !is_audio(path) )
737 DPRINTF(E_DEBUG, L_METADATA, "File %s does not contain a video stream.\n", basename(path));
738 return 0;
741 strcpy(nfo, path);
742 ext = strrchr(nfo, '.');
743 if( ext )
745 strcpy(ext+1, "nfo");
746 if( access(nfo, F_OK) == 0 )
748 parse_nfo(nfo, &m);
752 if( !m.date )
754 m.date = malloc(20);
755 modtime = localtime(&file.st_mtime);
756 strftime(m.date, 20, "%FT%T", modtime);
759 if( ac )
761 aac_object_type_t aac_type = AAC_INVALID;
762 switch( ac->codec_id )
764 case CODEC_ID_MP3:
765 audio_profile = PROFILE_AUDIO_MP3;
766 break;
767 case CODEC_ID_AAC:
768 if( !ac->extradata_size ||
769 !ac->extradata )
771 DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n");
773 else
775 uint8_t data;
776 memcpy(&data, ac->extradata, 1);
777 aac_type = data >> 3;
779 switch( aac_type )
781 /* AAC Low Complexity variants */
782 case AAC_LC:
783 case AAC_LC_ER:
784 if( ac->sample_rate < 8000 ||
785 ac->sample_rate > 48000 )
787 DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n",
788 ac->sample_rate);
789 break;
791 /* AAC @ Level 1/2 */
792 if( ac->channels <= 2 &&
793 ac->bit_rate <= 576000 )
794 audio_profile = PROFILE_AUDIO_AAC;
795 else if( ac->channels <= 6 &&
796 ac->bit_rate <= 1440000 )
797 audio_profile = PROFILE_AUDIO_AAC_MULT5;
798 else
799 DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n",
800 ac->channels,
801 ac->bit_rate);
802 break;
803 default:
804 DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type);
805 break;
807 break;
808 case CODEC_ID_AC3:
809 case CODEC_ID_DTS:
810 audio_profile = PROFILE_AUDIO_AC3;
811 break;
812 case CODEC_ID_WMAV1:
813 case CODEC_ID_WMAV2:
814 /* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */
815 if ( ac->bit_rate <= 193000 )
816 audio_profile = PROFILE_AUDIO_WMA_BASE;
817 /* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */
818 else if ( ac->bit_rate <= 385000 )
819 audio_profile = PROFILE_AUDIO_WMA_FULL;
820 break;
821 #if LIBAVCODEC_VERSION_INT > ((51<<16)+(50<<8)+1)
822 case CODEC_ID_WMAPRO:
823 audio_profile = PROFILE_AUDIO_WMA_PRO;
824 break;
825 #endif
826 case CODEC_ID_MP2:
827 audio_profile = PROFILE_AUDIO_MP2;
828 break;
829 case CODEC_ID_AMR_NB:
830 audio_profile = PROFILE_AUDIO_AMR;
831 break;
832 default:
833 if( (ac->codec_id >= CODEC_ID_PCM_S16LE) &&
834 (ac->codec_id < CODEC_ID_ADPCM_IMA_QT) )
835 audio_profile = PROFILE_AUDIO_PCM;
836 else
837 DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ac->codec_id);
838 break;
840 asprintf(&m.frequency, "%u", ac->sample_rate);
841 #if LIBAVCODEC_VERSION_INT < (52<<16)
842 asprintf(&m.bps, "%u", ac->bits_per_sample);
843 #else
844 asprintf(&m.bps, "%u", ac->bits_per_coded_sample);
845 #endif
846 asprintf(&m.channels, "%u", ac->channels);
848 if( vc )
850 int off;
851 int duration, hours, min, sec, ms;
852 ts_timestamp_t ts_timestamp = NONE;
853 DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename(path));
854 asprintf(&m.resolution, "%dx%d", vc->width, vc->height);
855 if( ctx->bit_rate > 8 )
856 asprintf(&m.bitrate, "%u", ctx->bit_rate / 8);
857 if( ctx->duration > 0 ) {
858 duration = (int)(ctx->duration / AV_TIME_BASE);
859 hours = (int)(duration / 3600);
860 min = (int)(duration / 60 % 60);
861 sec = (int)(duration % 60);
862 ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000);
863 asprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms);
866 /* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers.
867 * Skip DLNA parsing for everything else. */
868 if( strcmp(ctx->iformat->name, "avi") == 0 )
870 asprintf(&m.mime, "video/x-msvideo");
871 if( vc->codec_id == CODEC_ID_MPEG4 )
873 fourcc[0] = vc->codec_tag & 0xff;
874 fourcc[1] = vc->codec_tag>>8 & 0xff;
875 fourcc[2] = vc->codec_tag>>16 & 0xff;
876 fourcc[3] = vc->codec_tag>>24 & 0xff;
877 if( memcmp(fourcc, "XVID", 4) == 0 ||
878 memcmp(fourcc, "DX50", 4) == 0 ||
879 memcmp(fourcc, "DIVX", 4) == 0 )
880 asprintf(&m.creator, "DiVX");
883 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 &&
884 ends_with(path, ".mov") )
885 asprintf(&m.mime, "video/quicktime");
886 else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 )
887 asprintf(&m.mime, "video/x-matroska");
888 else if( strcmp(ctx->iformat->name, "flv") == 0 )
889 asprintf(&m.mime, "video/x-flv");
890 if( m.mime )
891 goto video_no_dlna;
893 switch( vc->codec_id )
895 case CODEC_ID_MPEG1VIDEO:
896 if( strcmp(ctx->iformat->name, "mpeg") == 0 )
898 if( (vc->width == 352) &&
899 (vc->height <= 288) )
901 m.dlna_pn = strdup("MPEG1");
903 asprintf(&m.mime, "video/mpeg");
905 break;
906 case CODEC_ID_MPEG2VIDEO:
907 m.dlna_pn = malloc(64);
908 off = sprintf(m.dlna_pn, "MPEG_");
909 if( strcmp(ctx->iformat->name, "mpegts") == 0 )
911 int raw_packet_size;
912 int dlna_ts_present = dlna_timestamp_is_present(path, &raw_packet_size);
913 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS packet size %d\n",
914 video_stream, basename(path), m.resolution, raw_packet_size);
915 off += sprintf(m.dlna_pn+off, "TS_");
916 if( (vc->width >= 1280) &&
917 (vc->height >= 720) )
919 off += sprintf(m.dlna_pn+off, "HD_NA");
921 else
923 off += sprintf(m.dlna_pn+off, "SD_");
924 if( (vc->height == 576) ||
925 (vc->height == 288) )
926 off += sprintf(m.dlna_pn+off, "EU");
927 else
928 off += sprintf(m.dlna_pn+off, "NA");
930 if( raw_packet_size == MPEG_TS_PACKET_LENGTH_DLNA )
932 if (dlna_ts_present)
933 ts_timestamp = VALID;
934 else
935 ts_timestamp = EMPTY;
937 else if( raw_packet_size != MPEG_TS_PACKET_LENGTH )
939 DPRINTF(E_DEBUG, L_METADATA, "Unsupported DLNA TS packet size [%d] (%s)\n",
940 raw_packet_size, basename(path));
941 free(m.dlna_pn);
942 m.dlna_pn = NULL;
944 switch( ts_timestamp )
946 case NONE:
947 asprintf(&m.mime, "video/mpeg");
948 if( m.dlna_pn )
949 off += sprintf(m.dlna_pn+off, "_ISO");
950 break;
951 case VALID:
952 off += sprintf(m.dlna_pn+off, "_T");
953 case EMPTY:
954 asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
955 default:
956 break;
959 else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
961 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n",
962 video_stream, basename(path), m.resolution);
963 off += sprintf(m.dlna_pn+off, "PS_");
964 if( (vc->height == 576) ||
965 (vc->height == 288) )
966 off += sprintf(m.dlna_pn+off, "PAL");
967 else
968 off += sprintf(m.dlna_pn+off, "NTSC");
969 asprintf(&m.mime, "video/mpeg");
971 else
973 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [%s] is %s non-DLNA MPEG2\n",
974 video_stream, basename(path), ctx->iformat->name, m.resolution);
975 free(m.dlna_pn);
976 m.dlna_pn = NULL;
978 break;
979 case CODEC_ID_H264:
980 m.dlna_pn = malloc(128);
981 off = sprintf(m.dlna_pn, "AVC_");
983 if( strcmp(ctx->iformat->name, "mpegts") == 0 )
985 AVRational display_aspect_ratio;
986 int fps, interlaced;
987 int raw_packet_size;
988 int dlna_ts_present = dlna_timestamp_is_present(path, &raw_packet_size);
990 off += sprintf(m.dlna_pn+off, "TS_");
991 if (vc->sample_aspect_ratio.num) {
992 av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
993 vc->width * vc->sample_aspect_ratio.num,
994 vc->height * vc->sample_aspect_ratio.den,
995 1024*1024);
997 fps = ctx->streams[video_stream]->r_frame_rate.num / ctx->streams[video_stream]->r_frame_rate.den;
998 interlaced = (ctx->streams[video_stream]->r_frame_rate.num / vc->time_base.den);
999 if( ((((vc->width == 1920 || vc->width == 1440) && vc->height == 1080) ||
1000 (vc->width == 720 && vc->height == 480)) && fps == 59 && interlaced) ||
1001 ((vc->width == 1280 && vc->height == 720) && fps == 59 && !interlaced) )
1003 if( (vc->profile == FF_PROFILE_H264_MAIN || vc->profile == FF_PROFILE_H264_HIGH) &&
1004 audio_profile == PROFILE_AUDIO_AC3 )
1006 off += sprintf(m.dlna_pn+off, "HD_60_");
1007 vc->profile = FF_PROFILE_SKIP;
1010 else if( ((vc->width == 1920 && vc->height == 1080) ||
1011 (vc->width == 1440 && vc->height == 1080) ||
1012 (vc->width == 1280 && vc->height == 720) ||
1013 (vc->width == 720 && vc->height == 576)) &&
1014 interlaced && fps == 50 )
1016 if( (vc->profile == FF_PROFILE_H264_MAIN || vc->profile == FF_PROFILE_H264_HIGH) &&
1017 audio_profile == PROFILE_AUDIO_AC3 )
1019 off += sprintf(m.dlna_pn+off, "HD_50_");
1020 vc->profile = FF_PROFILE_SKIP;
1023 switch( vc->profile )
1025 case FF_PROFILE_H264_BASELINE:
1026 off += sprintf(m.dlna_pn+off, "BL_");
1027 if( vc->width <= 352 &&
1028 vc->height <= 288 &&
1029 vc->bit_rate <= 384000 )
1031 off += sprintf(m.dlna_pn+off, "CIF15_");
1032 break;
1034 else if( vc->width <= 352 &&
1035 vc->height <= 288 &&
1036 vc->bit_rate <= 3000000 )
1038 off += sprintf(m.dlna_pn+off, "CIF30_");
1039 break;
1041 /* Fall back to Main Profile if it doesn't match a Baseline DLNA profile. */
1042 else
1043 off -= 3;
1044 default:
1045 case FF_PROFILE_H264_MAIN:
1046 off += sprintf(m.dlna_pn+off, "MP_");
1047 if( vc->profile != FF_PROFILE_H264_BASELINE &&
1048 vc->profile != FF_PROFILE_H264_MAIN )
1050 DPRINTF(E_DEBUG, L_METADATA, "Unknown AVC profile %d; assuming MP. [%s]\n",
1051 vc->profile, basename(path));
1053 if( vc->width <= 720 &&
1054 vc->height <= 576 &&
1055 vc->bit_rate <= 10000000 )
1057 off += sprintf(m.dlna_pn+off, "SD_");
1059 else if( vc->width <= 1920 &&
1060 vc->height <= 1152 &&
1061 vc->bit_rate <= 20000000 )
1063 off += sprintf(m.dlna_pn+off, "HD_");
1065 else
1067 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%s, %dx%d, %dbps : %s]\n",
1068 m.dlna_pn, vc->width, vc->height, vc->bit_rate, basename(path));
1069 free(m.dlna_pn);
1070 m.dlna_pn = NULL;
1072 break;
1073 case FF_PROFILE_H264_HIGH:
1074 off += sprintf(m.dlna_pn+off, "HP_");
1075 if( vc->width <= 1920 &&
1076 vc->height <= 1152 &&
1077 vc->bit_rate <= 30000000 &&
1078 audio_profile == PROFILE_AUDIO_AC3 )
1080 off += sprintf(m.dlna_pn+off, "HD_");
1082 else
1084 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 HP video profile! [%dbps, %d audio : %s]\n",
1085 vc->bit_rate, audio_profile, basename(path));
1086 free(m.dlna_pn);
1087 m.dlna_pn = NULL;
1089 break;
1090 case FF_PROFILE_SKIP:
1091 break;
1093 if( !m.dlna_pn )
1094 break;
1095 switch( audio_profile )
1097 case PROFILE_AUDIO_MP3:
1098 off += sprintf(m.dlna_pn+off, "MPEG1_L3");
1099 break;
1100 case PROFILE_AUDIO_AC3:
1101 off += sprintf(m.dlna_pn+off, "AC3");
1102 break;
1103 case PROFILE_AUDIO_AAC:
1104 case PROFILE_AUDIO_AAC_MULT5:
1105 off += sprintf(m.dlna_pn+off, "AAC_MULT5");
1106 break;
1107 default:
1108 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file [%s]\n",
1109 m.dlna_pn, basename(path));
1110 free(m.dlna_pn);
1111 m.dlna_pn = NULL;
1112 break;
1114 if( !m.dlna_pn )
1115 break;
1116 if( raw_packet_size == MPEG_TS_PACKET_LENGTH_DLNA )
1118 if( vc->profile == FF_PROFILE_H264_HIGH ||
1119 dlna_ts_present )
1120 ts_timestamp = VALID;
1121 else
1122 ts_timestamp = EMPTY;
1124 else if( raw_packet_size != MPEG_TS_PACKET_LENGTH )
1126 DPRINTF(E_DEBUG, L_METADATA, "Unsupported DLNA TS packet size [%d] (%s)\n",
1127 raw_packet_size, basename(path));
1128 free(m.dlna_pn);
1129 m.dlna_pn = NULL;
1131 switch( ts_timestamp )
1133 case NONE:
1134 if( m.dlna_pn )
1135 off += sprintf(m.dlna_pn+off, "_ISO");
1136 break;
1137 case VALID:
1138 off += sprintf(m.dlna_pn+off, "_T");
1139 case EMPTY:
1140 asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
1141 default:
1142 break;
1145 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1147 off += sprintf(m.dlna_pn+off, "MP4_");
1149 switch( vc->profile ) {
1150 case FF_PROFILE_H264_BASELINE:
1151 if( vc->width <= 352 &&
1152 vc->height <= 288 )
1154 if( ctx->bit_rate < 600000 )
1155 off += sprintf(m.dlna_pn+off, "BL_CIF15_");
1156 else if( ctx->bit_rate < 5000000 )
1157 off += sprintf(m.dlna_pn+off, "BL_CIF30_");
1158 else
1159 goto mp4_mp_fallback;
1161 if( audio_profile == PROFILE_AUDIO_AMR )
1163 off += sprintf(m.dlna_pn+off, "AMR");
1165 else if( audio_profile == PROFILE_AUDIO_AAC )
1167 off += sprintf(m.dlna_pn+off, "AAC_");
1168 if( ctx->bit_rate < 520000 )
1170 off += sprintf(m.dlna_pn+off, "520");
1172 else if( ctx->bit_rate < 940000 )
1174 off += sprintf(m.dlna_pn+off, "940");
1176 else
1178 off -= 13;
1179 goto mp4_mp_fallback;
1182 else
1184 off -= 9;
1185 goto mp4_mp_fallback;
1188 else if( vc->width <= 720 &&
1189 vc->height <= 576 )
1191 if( vc->level == 30 &&
1192 audio_profile == PROFILE_AUDIO_AAC &&
1193 ctx->bit_rate <= 5000000 )
1194 off += sprintf(m.dlna_pn+off, "BL_L3L_SD_AAC");
1195 else if( vc->level <= 31 &&
1196 audio_profile == PROFILE_AUDIO_AAC &&
1197 ctx->bit_rate <= 15000000 )
1198 off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC");
1199 else
1200 goto mp4_mp_fallback;
1202 else if( vc->width <= 1280 &&
1203 vc->height <= 720 )
1205 if( vc->level <= 31 &&
1206 audio_profile == PROFILE_AUDIO_AAC &&
1207 ctx->bit_rate <= 15000000 )
1208 off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC");
1209 else if( vc->level <= 32 &&
1210 audio_profile == PROFILE_AUDIO_AAC &&
1211 ctx->bit_rate <= 21000000 )
1212 off += sprintf(m.dlna_pn+off, "BL_L32_HD_AAC");
1213 else
1214 goto mp4_mp_fallback;
1216 else
1217 goto mp4_mp_fallback;
1218 break;
1219 case FF_PROFILE_H264_MAIN:
1220 mp4_mp_fallback:
1221 off += sprintf(m.dlna_pn+off, "MP_");
1222 /* AVC MP4 SD profiles - 10 Mbps max */
1223 if( vc->width <= 720 &&
1224 vc->height <= 576 &&
1225 vc->bit_rate <= 10000000 )
1227 sprintf(m.dlna_pn+off, "SD_");
1228 if( audio_profile == PROFILE_AUDIO_AC3 )
1229 off += sprintf(m.dlna_pn+off, "AC3");
1230 else if( audio_profile == PROFILE_AUDIO_AAC ||
1231 audio_profile == PROFILE_AUDIO_AAC_MULT5 )
1232 off += sprintf(m.dlna_pn+off, "AAC_MULT5");
1233 else if( audio_profile == PROFILE_AUDIO_MP3 )
1234 off += sprintf(m.dlna_pn+off, "MPEG1_L3");
1235 else
1236 m.dlna_pn[10] = '\0';
1238 else if( vc->width <= 1280 &&
1239 vc->height <= 720 &&
1240 vc->bit_rate <= 15000000 &&
1241 audio_profile == PROFILE_AUDIO_AAC )
1243 off += sprintf(m.dlna_pn+off, "HD_720p_AAC");
1245 else if( vc->width <= 1920 &&
1246 vc->height <= 1080 &&
1247 vc->bit_rate <= 21000000 &&
1248 audio_profile == PROFILE_AUDIO_AAC )
1250 off += sprintf(m.dlna_pn+off, "HD_1080i_AAC");
1252 if( strlen(m.dlna_pn) <= 11 )
1254 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file %s\n",
1255 m.dlna_pn, basename(path));
1256 free(m.dlna_pn);
1257 m.dlna_pn = NULL;
1259 break;
1260 case FF_PROFILE_H264_HIGH:
1261 if( vc->width <= 1920 &&
1262 vc->height <= 1080 &&
1263 vc->bit_rate <= 25000000 &&
1264 audio_profile == PROFILE_AUDIO_AAC )
1266 off += sprintf(m.dlna_pn+off, "HP_HD_AAC");
1268 break;
1269 default:
1270 DPRINTF(E_DEBUG, L_METADATA, "AVC profile [%d] not recognized for file %s\n",
1271 vc->profile, basename(path));
1272 free(m.dlna_pn);
1273 m.dlna_pn = NULL;
1274 break;
1277 else
1279 free(m.dlna_pn);
1280 m.dlna_pn = NULL;
1282 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename(path));
1283 break;
1284 case CODEC_ID_MPEG4:
1285 fourcc[0] = vc->codec_tag & 0xff;
1286 fourcc[1] = vc->codec_tag>>8 & 0xff;
1287 fourcc[2] = vc->codec_tag>>16 & 0xff;
1288 fourcc[3] = vc->codec_tag>>24 & 0xff;
1289 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%c%c%c%c/0x%X]\n",
1290 video_stream, basename(path),
1291 isprint(fourcc[0]) ? fourcc[0] : '_',
1292 isprint(fourcc[1]) ? fourcc[1] : '_',
1293 isprint(fourcc[2]) ? fourcc[2] : '_',
1294 isprint(fourcc[3]) ? fourcc[3] : '_',
1295 vc->codec_tag);
1297 if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1299 m.dlna_pn = malloc(128);
1300 off = sprintf(m.dlna_pn, "MPEG4_P2_");
1302 if( ends_with(path, ".3gp") )
1304 asprintf(&m.mime, "video/3gpp");
1305 switch( audio_profile )
1307 case PROFILE_AUDIO_AAC:
1308 off += sprintf(m.dlna_pn+off, "3GPP_SP_L0B_AAC");
1309 break;
1310 case PROFILE_AUDIO_AMR:
1311 off += sprintf(m.dlna_pn+off, "3GPP_SP_L0B_AMR");
1312 break;
1313 default:
1314 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n",
1315 ac->codec_id, basename(path));
1316 free(m.dlna_pn);
1317 m.dlna_pn = NULL;
1318 break;
1321 else
1323 if( ctx->bit_rate <= 1000000 &&
1324 audio_profile == PROFILE_AUDIO_AAC )
1326 off += sprintf(m.dlna_pn+off, "MP4_ASP_AAC");
1328 else if( ctx->bit_rate <= 4000000 &&
1329 vc->width <= 640 &&
1330 vc->height <= 480 &&
1331 audio_profile == PROFILE_AUDIO_AAC )
1333 off += sprintf(m.dlna_pn+off, "MP4_SP_VGA_AAC");
1335 else
1337 DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n",
1338 vc->width,
1339 vc->height,
1340 ctx->bit_rate);
1341 free(m.dlna_pn);
1342 m.dlna_pn = NULL;
1346 break;
1347 case CODEC_ID_WMV3:
1348 /* I'm not 100% sure this is correct, but it works on everything I could get my hands on */
1349 if( vc->extradata_size > 0 )
1351 if( !((vc->extradata[0] >> 3) & 1) )
1352 vc->level = 0;
1353 if( !((vc->extradata[0] >> 6) & 1) )
1354 vc->profile = 0;
1356 case CODEC_ID_VC1:
1357 if( strcmp(ctx->iformat->name, "asf") != 0 )
1359 DPRINTF(E_DEBUG, L_METADATA, "Skipping DLNA parsing for non-ASF VC1 file %s\n", path);
1360 break;
1362 m.dlna_pn = malloc(64);
1363 off = sprintf(m.dlna_pn, "WMV");
1364 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename(path));
1365 asprintf(&m.mime, "video/x-ms-wmv");
1366 if( (vc->width <= 176) &&
1367 (vc->height <= 144) &&
1368 (vc->level == 0) )
1370 off += sprintf(m.dlna_pn+off, "SPLL_");
1371 switch( audio_profile )
1373 case PROFILE_AUDIO_MP3:
1374 off += sprintf(m.dlna_pn+off, "MP3");
1375 break;
1376 case PROFILE_AUDIO_WMA_BASE:
1377 off += sprintf(m.dlna_pn+off, "BASE");
1378 break;
1379 default:
1380 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPLL/0x%X file %s\n",
1381 audio_profile, basename(path));
1382 free(m.dlna_pn);
1383 m.dlna_pn = NULL;
1384 break;
1387 else if( (vc->width <= 352) &&
1388 (vc->height <= 288) &&
1389 (vc->profile == 0) &&
1390 (ctx->bit_rate/8 <= 384000) )
1392 off += sprintf(m.dlna_pn+off, "SPML_");
1393 switch( audio_profile )
1395 case PROFILE_AUDIO_MP3:
1396 off += sprintf(m.dlna_pn+off, "MP3");
1397 break;
1398 case PROFILE_AUDIO_WMA_BASE:
1399 off += sprintf(m.dlna_pn+off, "BASE");
1400 break;
1401 default:
1402 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n",
1403 audio_profile, basename(path));
1404 free(m.dlna_pn);
1405 m.dlna_pn = NULL;
1406 break;
1409 else if( (vc->width <= 720) &&
1410 (vc->height <= 576) &&
1411 (ctx->bit_rate/8 <= 10000000) )
1413 off += sprintf(m.dlna_pn+off, "MED_");
1414 switch( audio_profile )
1416 case PROFILE_AUDIO_WMA_PRO:
1417 off += sprintf(m.dlna_pn+off, "PRO");
1418 break;
1419 case PROFILE_AUDIO_WMA_FULL:
1420 off += sprintf(m.dlna_pn+off, "FULL");
1421 break;
1422 case PROFILE_AUDIO_WMA_BASE:
1423 off += sprintf(m.dlna_pn+off, "BASE");
1424 break;
1425 default:
1426 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n",
1427 audio_profile, basename(path));
1428 free(m.dlna_pn);
1429 m.dlna_pn = NULL;
1430 break;
1433 else if( (vc->width <= 1920) &&
1434 (vc->height <= 1080) &&
1435 (ctx->bit_rate/8 <= 20000000) )
1437 off += sprintf(m.dlna_pn+off, "HIGH_");
1438 switch( audio_profile )
1440 case PROFILE_AUDIO_WMA_PRO:
1441 off += sprintf(m.dlna_pn+off, "PRO");
1442 break;
1443 case PROFILE_AUDIO_WMA_FULL:
1444 off += sprintf(m.dlna_pn+off, "FULL");
1445 break;
1446 default:
1447 DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n",
1448 audio_profile, basename(path));
1449 free(m.dlna_pn);
1450 m.dlna_pn = NULL;
1451 break;
1454 break;
1455 case CODEC_ID_MSMPEG4V3:
1456 asprintf(&m.mime, "video/x-msvideo");
1457 default:
1458 DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n",
1459 video_stream, basename(path), m.resolution, vc->codec_id);
1460 break;
1463 if( !m.mime )
1465 if( strcmp(ctx->iformat->name, "avi") == 0 )
1466 asprintf(&m.mime, "video/x-msvideo");
1467 else if( strncmp(ctx->iformat->name, "mpeg", 4) == 0 )
1468 asprintf(&m.mime, "video/mpeg");
1469 else if( strcmp(ctx->iformat->name, "asf") == 0 )
1470 asprintf(&m.mime, "video/x-ms-wmv");
1471 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1472 if( ends_with(path, ".mov") )
1473 asprintf(&m.mime, "video/quicktime");
1474 else
1475 asprintf(&m.mime, "video/mp4");
1476 else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 )
1477 asprintf(&m.mime, "video/x-matroska");
1478 else if( strcmp(ctx->iformat->name, "flv") == 0 )
1479 asprintf(&m.mime, "video/x-flv");
1480 else
1481 DPRINTF(E_WARN, L_METADATA, "%s: Unhandled format: %s\n", path, ctx->iformat->name);
1484 if( strcmp(ctx->iformat->name, "asf") == 0 )
1486 if( readtags((char *)path, &video, &file, "en_US", "asf") == 0 )
1488 if( video.title && *video.title )
1490 m.title = escape_tag(trim(video.title), 1);
1492 if( video.genre && *video.genre )
1494 m.genre = escape_tag(trim(video.genre), 1);
1496 if( video.contributor[ROLE_TRACKARTIST] && *video.contributor[ROLE_TRACKARTIST] )
1498 m.artist = escape_tag(trim(video.contributor[ROLE_TRACKARTIST]), 1);
1500 if( video.contributor[ROLE_ALBUMARTIST] && *video.contributor[ROLE_ALBUMARTIST] )
1502 m.creator = escape_tag(trim(video.contributor[ROLE_ALBUMARTIST]), 1);
1504 else
1506 m.creator = m.artist;
1507 free_flags &= ~FLAG_CREATOR;
1511 #ifndef NETGEAR
1512 #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
1513 else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
1515 if( ctx->metadata )
1517 AVMetadataTag *tag = NULL;
1519 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Metadata:\n");
1520 while( (tag = av_metadata_get(ctx->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX)) )
1522 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " %-16s: %s\n", tag->key, tag->value);
1523 if( strcmp(tag->key, "title") == 0 )
1524 m.title = escape_tag(trim(tag->value), 1);
1525 else if( strcmp(tag->key, "genre") == 0 )
1526 m.genre = escape_tag(trim(tag->value), 1);
1527 else if( strcmp(tag->key, "artist") == 0 )
1528 m.artist = escape_tag(trim(tag->value), 1);
1529 else if( strcmp(tag->key, "comment") == 0 )
1530 m.comment = escape_tag(trim(tag->value), 1);
1534 #endif
1535 #endif
1536 video_no_dlna:
1537 av_close_input_file(ctx);
1539 #ifdef TIVO_SUPPORT
1540 if( ends_with(path, ".TiVo") && is_tivo_file(path) )
1542 if( m.dlna_pn )
1544 free(m.dlna_pn);
1545 m.dlna_pn = NULL;
1547 m.mime = realloc(m.mime, 18);
1548 strcpy(m.mime, "video/x-tivo-mpeg");
1550 #endif
1551 if( !m.title )
1552 m.title = strdup(name);
1554 album_art = find_album_art(path, video.image, video.image_size);
1555 freetags(&video);
1557 ret = sql_exec(db, "INSERT into DETAILS"
1558 " (PATH, SIZE, TIMESTAMP, DURATION, DATE, CHANNELS, BITRATE, SAMPLERATE, RESOLUTION,"
1559 " TITLE, CREATOR, ARTIST, GENRE, COMMENT, DLNA_PN, MIME, ALBUM_ART) "
1560 "VALUES"
1561 " (%Q, %lld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, '%q', %Q, %Q, %Q, %Q, %Q, '%q', %lld);",
1562 path, (long long)file.st_size, file.st_mtime, m.duration,
1563 m.date, m.channels, m.bitrate, m.frequency, m.resolution,
1564 m.title, m.creator, m.artist, m.genre, m.comment, m.dlna_pn,
1565 m.mime, album_art);
1566 if( ret != SQLITE_OK )
1568 fprintf(stderr, "Error inserting details for '%s'!\n", path);
1569 ret = 0;
1571 else
1573 ret = sqlite3_last_insert_rowid(db);
1574 check_for_captions(path, ret);
1576 free_metadata(&m, free_flags);
1578 return ret;