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