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/>.
25 #include <sys/types.h>
29 #include <libexif/exif-loader.h>
30 #include "image_utils.h"
36 #include "tagutils/tagutils.h"
38 #include "upnpglobalvars.h"
39 #include "upnpreplyparse.h"
46 #ifndef FF_PROFILE_H264_BASELINE
47 #define FF_PROFILE_H264_BASELINE 66
49 #ifndef FF_PROFILE_H264_MAIN
50 #define FF_PROFILE_H264_MAIN 77
52 #ifndef FF_PROFILE_H264_HIGH
53 #define FF_PROFILE_H264_HIGH 100
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
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 */
81 PROFILE_AUDIO_UNKNOWN
,
84 PROFILE_AUDIO_WMA_BASE
,
85 PROFILE_AUDIO_WMA_FULL
,
86 PROFILE_AUDIO_WMA_PRO
,
90 PROFILE_AUDIO_AAC_MULT5
,
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 */
99 dlna_timestamp_is_present(const char * filename
, int * raw_packet_size
)
101 unsigned char buffer
[3*MPEG_TS_PACKET_LENGTH_DLNA
];
104 /* read file header */
105 fd
= open(filename
, O_RDONLY
);
106 read(fd
, buffer
, MPEG_TS_PACKET_LENGTH_DLNA
*3);
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)
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
;
130 *raw_packet_size
= 0;
136 is_tivo_file(const char * path
)
138 unsigned char buf
[5];
139 unsigned char hdr
[5] = { 'T','i','V','o','\0' };
142 /* read file header */
143 fd
= open(path
, O_RDONLY
);
147 return( !memcmp(buf
, hdr
, 5) );
152 check_for_captions(const char * path
, sqlite_int64 detailID
)
154 char *file
= malloc(PATH_MAX
);
157 sprintf(file
, "%s", path
);
160 /* If we weren't given a detail ID, look for one. */
163 id
= sql_get_text_field(db
, "SELECT ID from DETAILS where PATH glob '%q.*'"
164 " and MIME glob 'video/*' limit 1", file
);
167 //DEBUG DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like a caption file.\n", path);
168 detailID
= strtoll(id
, NULL
, 10);
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"
183 " (%lld, %Q)", detailID
, file
);
192 parse_nfo(const char * path
, metadata_t
* m
)
196 struct NameValueParserData xml
;
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
);
207 DPRINTF(E_DEBUG
, L_METADATA
, "Parsing .nfo file: %s\n", path
);
208 nfo
= fopen(path
, "r");
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");
219 val2
= GetValueFromNameValueList(&xml
, "episodetitle");
221 asprintf(&m
->title
, "%s - %s", val
, val2
);
223 m
->title
= strdup(val
);
226 val
= GetValueFromNameValueList(&xml
, "plot");
228 m
->comment
= strdup(val
);
230 val
= GetValueFromNameValueList(&xml
, "capturedate");
232 m
->date
= strdup(val
);
234 val
= GetValueFromNameValueList(&xml
, "genre");
236 m
->genre
= strdup(val
);
238 ClearNameValueList(&xml
);
243 free_metadata(metadata_t
* m
, uint32_t flags
)
245 if( flags
& FLAG_TITLE
)
247 if( flags
& FLAG_ARTIST
)
249 if( flags
& FLAG_ALBUM
)
251 if( flags
& FLAG_GENRE
)
253 if( flags
& FLAG_CREATOR
)
255 if( flags
& FLAG_DATE
)
257 if( flags
& FLAG_COMMENT
)
259 if( flags
& FLAG_DLNA_PN
)
261 if( flags
& FLAG_MIME
)
263 if( flags
& FLAG_DURATION
)
265 if( flags
& FLAG_RESOLUTION
)
267 if( flags
& FLAG_BITRATE
)
269 if( flags
& FLAG_FREQUENCY
)
271 if( flags
& FLAG_BPS
)
273 if( flags
& FLAG_CHANNELS
)
275 if( flags
& FLAG_ROTATION
)
280 GetFolderMetadata(const char * name
, const char * path
, const char * artist
, const char * genre
, sqlite3_int64 album_art
)
284 ret
= sql_exec(db
, "INSERT into DETAILS"
285 " (TITLE, PATH, CREATOR, ARTIST, GENRE, ALBUM_ART) "
287 " ('%q', %Q, %Q, %Q, %Q, %lld);",
288 name
, path
, artist
, artist
, genre
, album_art
);
289 if( ret
!= SQLITE_OK
)
292 ret
= sqlite3_last_insert_rowid(db
);
298 GetAudioMetadata(const char * path
, char * name
)
301 static char lang
[6] = { '\0' };
306 sqlite_int64 album_art
= 0;
307 struct song_metadata song
;
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 )
316 if( ends_with(path
, ".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") )
325 m
.mime
= strdup("audio/mp4");
327 else if( ends_with(path
, ".3gp") )
330 m
.mime
= strdup("audio/3gpp");
332 else if( ends_with(path
, ".wma") || ends_with(path
, ".asf") )
335 m
.mime
= strdup("audio/x-ms-wma");
337 else if( ends_with(path
, ".flac") || ends_with(path
, ".fla") || ends_with(path
, ".flc") )
340 m
.mime
= strdup("audio/x-flac");
342 else if( ends_with(path
, ".wav") )
345 m
.mime
= strdup("audio/x-wav");
347 else if( ends_with(path
, ".ogg") || ends_with(path
, ".oga") )
350 m
.mime
= strdup("audio/ogg");
352 else if( ends_with(path
, ".pcm") )
355 m
.mime
= strdup("audio/L16");
359 DPRINTF(E_WARN
, L_GENERAL
, "Unhandled file extension on %s\n", path
);
365 if( !getenv("LANG") )
366 strcpy(lang
, "en_US");
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
);
375 free_metadata(&m
, free_flags
);
380 m
.dlna_pn
= strdup(song
.dlna_pn
);
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
;
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)) )
414 free_flags
|= FLAG_CREATOR
;
416 m
.artist
= m
.creator
;
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
] )
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)) )
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
;
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
;
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
;
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) "
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
);
484 ret
= sqlite3_last_insert_rowid(db
);
487 free_metadata(&m
, free_flags
);
492 /* For libjpeg error handling */
493 jmp_buf setjmp_buffer
;
495 libjpeg_error_handler(j_common_ptr cinfo
)
497 cinfo
->err
->output_message (cinfo
);
498 longjmp(setjmp_buffer
, 1);
503 GetImageMetadata(const char * path
, char * name
)
508 struct jpeg_decompress_struct cinfo
;
509 struct jpeg_error_mgr jerr
;
511 int width
=0, height
=0, thumb
=0;
512 char make
[32], model
[64] = {'\0'};
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 )
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
);
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 )
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
);
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
);
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
);
577 switch( exif_get_short(e
->data
, exif_data_get_byte_order(ed
)) )
594 if( asprintf(&m
.rotation
, "%d", rotate
) < 0 )
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
);
607 if( (imsrc
->width
<= 160) && (imsrc
->height
<= 160) )
615 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb);
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");
626 cinfo
.err
= jpeg_std_error(&jerr
);
627 jerr
.error_exit
= libjpeg_error_handler
;
628 jpeg_create_decompress(&cinfo
);
629 if( setjmp(setjmp_buffer
) )
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
;
637 jpeg_destroy_decompress(&cinfo
);
641 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height);
643 if( !width
|| !height
)
645 free_metadata(&m
, free_flags
);
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) "
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
);
670 ret
= sqlite3_last_insert_rowid(db
);
672 free_metadata(&m
, free_flags
);
678 GetVideoMetadata(const char * path
, char * name
)
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
;
688 sqlite_int64 album_art
= 0;
689 char nfo
[PATH_MAX
], *ext
;
690 struct song_metadata video
;
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 )
701 //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
704 #if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(2<<8)+0)
705 if( avformat_open_input(&ctx
, path
, NULL
, NULL
) != 0 )
707 if( av_open_input_file(&ctx
, path
, NULL
, 0, NULL
) != 0 )
710 DPRINTF(E_WARN
, L_METADATA
, "Opening %s failed!\n", path
);
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
)
721 ac
= ctx
->streams
[audio_stream
]->codec
;
724 else if( video_stream
== -1 &&
725 ctx
->streams
[i
]->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
)
728 vc
= ctx
->streams
[video_stream
]->codec
;
732 /* This must not be a video file. */
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
));
742 ext
= strrchr(nfo
, '.');
745 strcpy(ext
+1, "nfo");
746 if( access(nfo
, F_OK
) == 0 )
755 modtime
= localtime(&file
.st_mtime
);
756 strftime(m
.date
, 20, "%FT%T", modtime
);
761 aac_object_type_t aac_type
= AAC_INVALID
;
762 switch( ac
->codec_id
)
765 audio_profile
= PROFILE_AUDIO_MP3
;
768 if( !ac
->extradata_size
||
771 DPRINTF(E_DEBUG
, L_METADATA
, "No AAC type\n");
776 memcpy(&data
, ac
->extradata
, 1);
777 aac_type
= data
>> 3;
781 /* AAC Low Complexity variants */
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",
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
;
799 DPRINTF(E_DEBUG
, L_METADATA
, "Unhandled AAC: %d channels, %d bitrate\n",
804 DPRINTF(E_DEBUG
, L_METADATA
, "Unhandled AAC type [%d]\n", aac_type
);
810 audio_profile
= PROFILE_AUDIO_AC3
;
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
;
821 #if LIBAVCODEC_VERSION_INT > ((51<<16)+(50<<8)+1)
822 case CODEC_ID_WMAPRO
:
823 audio_profile
= PROFILE_AUDIO_WMA_PRO
;
827 audio_profile
= PROFILE_AUDIO_MP2
;
829 case CODEC_ID_AMR_NB
:
830 audio_profile
= PROFILE_AUDIO_AMR
;
833 if( (ac
->codec_id
>= CODEC_ID_PCM_S16LE
) &&
834 (ac
->codec_id
< CODEC_ID_ADPCM_IMA_QT
) )
835 audio_profile
= PROFILE_AUDIO_PCM
;
837 DPRINTF(E_DEBUG
, L_METADATA
, "Unhandled audio codec [0x%X]\n", ac
->codec_id
);
840 asprintf(&m
.frequency
, "%u", ac
->sample_rate
);
841 #if LIBAVCODEC_VERSION_INT < (52<<16)
842 asprintf(&m
.bps
, "%u", ac
->bits_per_sample
);
844 asprintf(&m
.bps
, "%u", ac
->bits_per_coded_sample
);
846 asprintf(&m
.channels
, "%u", ac
->channels
);
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");
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");
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 )
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");
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");
928 off
+= sprintf(m
.dlna_pn
+off
, "NA");
930 if( raw_packet_size
== MPEG_TS_PACKET_LENGTH_DLNA
)
933 ts_timestamp
= VALID
;
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
));
944 switch( ts_timestamp
)
947 asprintf(&m
.mime
, "video/mpeg");
949 off
+= sprintf(m
.dlna_pn
+off
, "_ISO");
952 off
+= sprintf(m
.dlna_pn
+off
, "_T");
954 asprintf(&m
.mime
, "video/vnd.dlna.mpeg-tts");
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");
968 off
+= sprintf(m
.dlna_pn
+off
, "NTSC");
969 asprintf(&m
.mime
, "video/mpeg");
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
);
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
;
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
,
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_");
1034 else if( vc
->width
<= 352 &&
1035 vc
->height
<= 288 &&
1036 vc
->bit_rate
<= 3000000 )
1038 off
+= sprintf(m
.dlna_pn
+off
, "CIF30_");
1041 /* Fall back to Main Profile if it doesn't match a Baseline DLNA profile. */
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_");
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
));
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_");
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
));
1090 case FF_PROFILE_SKIP
:
1095 switch( audio_profile
)
1097 case PROFILE_AUDIO_MP3
:
1098 off
+= sprintf(m
.dlna_pn
+off
, "MPEG1_L3");
1100 case PROFILE_AUDIO_AC3
:
1101 off
+= sprintf(m
.dlna_pn
+off
, "AC3");
1103 case PROFILE_AUDIO_AAC
:
1104 case PROFILE_AUDIO_AAC_MULT5
:
1105 off
+= sprintf(m
.dlna_pn
+off
, "AAC_MULT5");
1108 DPRINTF(E_DEBUG
, L_METADATA
, "No DLNA profile found for %s file [%s]\n",
1109 m
.dlna_pn
, basename(path
));
1116 if( raw_packet_size
== MPEG_TS_PACKET_LENGTH_DLNA
)
1118 if( vc
->profile
== FF_PROFILE_H264_HIGH
||
1120 ts_timestamp
= VALID
;
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
));
1131 switch( ts_timestamp
)
1135 off
+= sprintf(m
.dlna_pn
+off
, "_ISO");
1138 off
+= sprintf(m
.dlna_pn
+off
, "_T");
1140 asprintf(&m
.mime
, "video/vnd.dlna.mpeg-tts");
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 &&
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_");
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");
1179 goto mp4_mp_fallback
;
1185 goto mp4_mp_fallback
;
1188 else if( vc
->width
<= 720 &&
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");
1200 goto mp4_mp_fallback
;
1202 else if( vc
->width
<= 1280 &&
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");
1214 goto mp4_mp_fallback
;
1217 goto mp4_mp_fallback
;
1219 case FF_PROFILE_H264_MAIN
:
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");
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
));
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");
1270 DPRINTF(E_DEBUG
, L_METADATA
, "AVC profile [%d] not recognized for file %s\n",
1271 vc
->profile
, basename(path
));
1282 DPRINTF(E_DEBUG
, L_METADATA
, "Stream %d of %s is h.264\n", video_stream
, basename(path
));
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] : '_',
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");
1310 case PROFILE_AUDIO_AMR
:
1311 off
+= sprintf(m
.dlna_pn
+off
, "3GPP_SP_L0B_AMR");
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
));
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 &&
1330 vc
->height
<= 480 &&
1331 audio_profile
== PROFILE_AUDIO_AAC
)
1333 off
+= sprintf(m
.dlna_pn
+off
, "MP4_SP_VGA_AAC");
1337 DPRINTF(E_DEBUG
, L_METADATA
, "Unsupported h.264 video profile! [%dx%d, %dbps]\n",
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) )
1353 if( !((vc
->extradata
[0] >> 6) & 1) )
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
);
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) &&
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");
1376 case PROFILE_AUDIO_WMA_BASE
:
1377 off
+= sprintf(m
.dlna_pn
+off
, "BASE");
1380 DPRINTF(E_DEBUG
, L_METADATA
, "No DLNA profile found for WMVSPLL/0x%X file %s\n",
1381 audio_profile
, basename(path
));
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");
1398 case PROFILE_AUDIO_WMA_BASE
:
1399 off
+= sprintf(m
.dlna_pn
+off
, "BASE");
1402 DPRINTF(E_DEBUG
, L_METADATA
, "No DLNA profile found for WMVSPML/0x%X file %s\n",
1403 audio_profile
, basename(path
));
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");
1419 case PROFILE_AUDIO_WMA_FULL
:
1420 off
+= sprintf(m
.dlna_pn
+off
, "FULL");
1422 case PROFILE_AUDIO_WMA_BASE
:
1423 off
+= sprintf(m
.dlna_pn
+off
, "BASE");
1426 DPRINTF(E_DEBUG
, L_METADATA
, "No DLNA profile found for WMVMED/0x%X file %s\n",
1427 audio_profile
, basename(path
));
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");
1443 case PROFILE_AUDIO_WMA_FULL
:
1444 off
+= sprintf(m
.dlna_pn
+off
, "FULL");
1447 DPRINTF(E_DEBUG
, L_METADATA
, "No DLNA profile found for WMVHIGH/0x%X file %s\n",
1448 audio_profile
, basename(path
));
1455 case CODEC_ID_MSMPEG4V3
:
1456 asprintf(&m
.mime
, "video/x-msvideo");
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
);
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");
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");
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);
1506 m
.creator
= m
.artist
;
1507 free_flags
&= ~FLAG_CREATOR
;
1512 #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
1513 else if( strcmp(ctx
->iformat
->name
, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
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);
1537 av_close_input_file(ctx
);
1540 if( ends_with(path
, ".TiVo") && is_tivo_file(path
) )
1547 m
.mime
= realloc(m
.mime
, 18);
1548 strcpy(m
.mime
, "video/x-tivo-mpeg");
1552 m
.title
= strdup(name
);
1554 album_art
= find_album_art(path
, video
.image
, video
.image_size
);
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) "
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
,
1566 if( ret
!= SQLITE_OK
)
1568 fprintf(stderr
, "Error inserting details for '%s'!\n", path
);
1573 ret
= sqlite3_last_insert_rowid(db
);
1574 check_for_captions(path
, ret
);
1576 free_metadata(&m
, free_flags
);