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