* Fallback code for duplicate audio/video extensions (.mp4).

* Fix a couple potential very small memory leaks in the scanner.
This commit is contained in:
Justin Maggard 2009-03-03 08:14:01 +00:00
parent e6aa386f77
commit 9eb6f81a64
2 changed files with 340 additions and 328 deletions

View File

@ -169,7 +169,8 @@ GetAudioMetadata(const char * path, char * name)
if( readtags((char *)path, &song, &file, NULL, type) != 0 ) if( readtags((char *)path, &song, &file, NULL, type) != 0 )
{ {
DPRINTF(E_WARN, L_GENERAL, "Cannot extract tags from %s\n", path); DPRINTF(E_WARN, L_GENERAL, "Cannot extract tags from %s!\n", path);
freetags(&song);
return 0; return 0;
} }
@ -463,7 +464,7 @@ GetVideoMetadata(const char * path, char * name)
memset(&m, '\0', sizeof(m)); memset(&m, '\0', sizeof(m));
date[0] = '\0'; date[0] = '\0';
DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path); DPRINTF(E_DEBUG, L_METADATA, "Parsing video %s...\n", path);
if ( stat(path, &file) == 0 ) if ( stat(path, &file) == 0 )
{ {
modtime = localtime(&file.st_mtime); modtime = localtime(&file.st_mtime);
@ -474,366 +475,371 @@ GetVideoMetadata(const char * path, char * name)
//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %d\n", size); //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %d\n", size);
av_register_all(); av_register_all();
if( av_open_input_file(&ctx, path, NULL, 0, NULL) == 0 ) if( av_open_input_file(&ctx, path, NULL, 0, NULL) != 0 )
{ {
av_find_stream_info(ctx); DPRINTF(E_WARN, L_METADATA, "Opening %s failed!\n", path);
//dump_format(ctx, 0, NULL, 0); return 0;
for( i=0; i<ctx->nb_streams; i++) }
av_find_stream_info(ctx);
//dump_format(ctx, 0, NULL, 0);
for( i=0; i<ctx->nb_streams; i++)
{
if( audio_stream == -1 &&
ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO )
{ {
if( audio_stream == -1 && audio_stream = i;
ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO ) continue;
{
audio_stream = i;
continue;
}
else if( video_stream == -1 &&
ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
{
video_stream = i;
continue;
}
} }
if( audio_stream >= 0 ) else if( video_stream == -1 &&
ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
{ {
switch( ctx->streams[audio_stream]->codec->codec_id ) video_stream = i;
{ continue;
case CODEC_ID_MP3: }
audio_profile = MP3; }
break; /* This must not be a video file. */
case CODEC_ID_AAC: if( video_stream == -1 )
if( !ctx->streams[audio_stream]->codec->extradata_size || {
!ctx->streams[audio_stream]->codec->extradata ) av_close_input_file(ctx);
{ DPRINTF(E_WARN, L_METADATA, "File %s does not contain a video stream!\n", path);
DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n"); return 0;
} }
else if( audio_stream >= 0 )
{ {
uint8_t data; switch( ctx->streams[audio_stream]->codec->codec_id )
memcpy(&data, ctx->streams[audio_stream]->codec->extradata, 1); {
aac_type = data >> 3; case CODEC_ID_MP3:
} audio_profile = MP3;
switch( aac_type ) break;
{ case CODEC_ID_AAC:
/* AAC Low Complexity variants */ if( !ctx->streams[audio_stream]->codec->extradata_size ||
case AAC_LC: !ctx->streams[audio_stream]->codec->extradata )
case AAC_LC_ER: {
if( ctx->streams[audio_stream]->codec->sample_rate < 8000 || DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n");
ctx->streams[audio_stream]->codec->sample_rate > 48000 ) }
{ else
DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n", {
ctx->streams[audio_stream]->codec->sample_rate); uint8_t data;
break; memcpy(&data, ctx->streams[audio_stream]->codec->extradata, 1);
} aac_type = data >> 3;
/* AAC @ Level 1/2 */ }
if( ctx->streams[audio_stream]->codec->channels <= 2 && switch( aac_type )
ctx->streams[audio_stream]->codec->bit_rate <= 576000 ) {
audio_profile = AAC; /* AAC Low Complexity variants */
else if( ctx->streams[audio_stream]->codec->channels <= 6 && case AAC_LC:
ctx->streams[audio_stream]->codec->bit_rate <= 1440000 ) case AAC_LC_ER:
audio_profile = AAC_MULT5; if( ctx->streams[audio_stream]->codec->sample_rate < 8000 ||
else ctx->streams[audio_stream]->codec->sample_rate > 48000 )
DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n", {
ctx->streams[audio_stream]->codec->channels, DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n",
ctx->streams[audio_stream]->codec->bit_rate); ctx->streams[audio_stream]->codec->sample_rate);
break; break;
default: }
DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type); /* AAC @ Level 1/2 */
break; if( ctx->streams[audio_stream]->codec->channels <= 2 &&
} ctx->streams[audio_stream]->codec->bit_rate <= 576000 )
break; audio_profile = AAC;
case CODEC_ID_AC3: else if( ctx->streams[audio_stream]->codec->channels <= 6 &&
case CODEC_ID_DTS: ctx->streams[audio_stream]->codec->bit_rate <= 1440000 )
audio_profile = AC3; audio_profile = AAC_MULT5;
break; else
case CODEC_ID_WMAV1: DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n",
case CODEC_ID_WMAV2: ctx->streams[audio_stream]->codec->channels,
/* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */ ctx->streams[audio_stream]->codec->bit_rate);
if ( ctx->streams[audio_stream]->codec->bit_rate <= 193000 ) break;
audio_profile = WMA_BASE; default:
/* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */ DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type);
else if ( ctx->streams[audio_stream]->codec->bit_rate <= 385000 ) break;
audio_profile = WMA_FULL; }
break; break;
#ifdef CODEC_ID_WMAPRO case CODEC_ID_AC3:
case CODEC_ID_WMAPRO: case CODEC_ID_DTS:
audio_profile = WMA_PRO; audio_profile = AC3;
break; break;
#endif case CODEC_ID_WMAV1:
case CODEC_ID_MP2: case CODEC_ID_WMAV2:
audio_profile = MP2; /* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */
break; if ( ctx->streams[audio_stream]->codec->bit_rate <= 193000 )
default: audio_profile = WMA_BASE;
if( (ctx->streams[audio_stream]->codec->codec_id >= CODEC_ID_PCM_S16LE) && /* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */
(ctx->streams[audio_stream]->codec->codec_id < CODEC_ID_ADPCM_IMA_QT) ) else if ( ctx->streams[audio_stream]->codec->bit_rate <= 385000 )
audio_profile = PCM; audio_profile = WMA_FULL;
else break;
DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [%X]\n", ctx->streams[audio_stream]->codec->codec_id); #ifdef CODEC_ID_WMAPRO
break; case CODEC_ID_WMAPRO:
} audio_profile = WMA_PRO;
asprintf(&m.frequency, "%u", ctx->streams[audio_stream]->codec->sample_rate); break;
#if LIBAVCODEC_VERSION_MAJOR >= 52
asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_coded_sample);
#else
asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_sample);
#endif #endif
asprintf(&m.channels, "%u", ctx->streams[audio_stream]->codec->channels); case CODEC_ID_MP2:
audio_profile = MP2;
break;
default:
if( (ctx->streams[audio_stream]->codec->codec_id >= CODEC_ID_PCM_S16LE) &&
(ctx->streams[audio_stream]->codec->codec_id < CODEC_ID_ADPCM_IMA_QT) )
audio_profile = PCM;
else
DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [%X]\n", ctx->streams[audio_stream]->codec->codec_id);
break;
} }
if( video_stream >= 0 ) asprintf(&m.frequency, "%u", ctx->streams[audio_stream]->codec->sample_rate);
#if LIBAVCODEC_VERSION_MAJOR >= 52
asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_coded_sample);
#else
asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_sample);
#endif
asprintf(&m.channels, "%u", ctx->streams[audio_stream]->codec->channels);
}
if( video_stream >= 0 )
{
DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, path);
asprintf(&m.resolution, "%dx%d", ctx->streams[video_stream]->codec->width, ctx->streams[video_stream]->codec->height);
asprintf(&m.bitrate, "%u", ctx->bit_rate / 8);
if( ctx->duration > 0 ) {
duration = (int)(ctx->duration / AV_TIME_BASE);
hours = (int)(duration / 3600);
min = (int)(duration / 60 % 60);
sec = (int)(duration % 60);
ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000);
asprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms);
}
/* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers -- not AVI. */
switch( ctx->streams[video_stream]->codec->codec_id )
{ {
DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, path); case CODEC_ID_MPEG1VIDEO:
asprintf(&m.resolution, "%dx%d", ctx->streams[video_stream]->codec->width, ctx->streams[video_stream]->codec->height); if( strcmp(ctx->iformat->name, "mpeg") == 0 )
asprintf(&m.bitrate, "%u", ctx->bit_rate / 8); {
if( ctx->duration > 0 ) { asprintf(&m.dlna_pn, "MPEG1;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
duration = (int)(ctx->duration / AV_TIME_BASE); asprintf(&m.mime, "video/mpeg");
hours = (int)(duration / 3600); }
min = (int)(duration / 60 % 60); break;
sec = (int)(duration % 60); case CODEC_ID_MPEG2VIDEO:
ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000); if( strcmp(ctx->iformat->name, "mpegts") == 0 )
asprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms); {
} DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, path, m.resolution);
/* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers -- not AVI. */ char res;
switch( ctx->streams[video_stream]->codec->codec_id ) tsinfo_t * ts = ctx->priv_data;
{ if( ts->packet_size == 192 )
case CODEC_ID_MPEG1VIDEO:
if( strcmp(ctx->iformat->name, "mpeg") == 0 )
{ {
asprintf(&m.dlna_pn, "MPEG1;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); asprintf(&m.dlna_pn, "MPEG_TS_HD_NA;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
asprintf(&m.mime, "video/mpeg"); asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
} }
break; else if( ts->packet_size == 188 )
case CODEC_ID_MPEG2VIDEO:
if( strcmp(ctx->iformat->name, "mpegts") == 0 )
{ {
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, path, m.resolution); if( (ctx->streams[video_stream]->codec->width >= 1280) &&
char res; (ctx->streams[video_stream]->codec->height >= 720) )
tsinfo_t * ts = ctx->priv_data;
if( ts->packet_size == 192 )
{
asprintf(&m.dlna_pn, "MPEG_TS_HD_NA;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
}
else if( ts->packet_size == 188 )
{
if( (ctx->streams[video_stream]->codec->width >= 1280) &&
(ctx->streams[video_stream]->codec->height >= 720) )
res = 'H';
else
res = 'S';
asprintf(&m.dlna_pn, "MPEG_TS_%cD_NA_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0", res);
asprintf(&m.mime, "video/mpeg");
}
}
else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, path, m.resolution);
char region[5];
if( (ctx->streams[video_stream]->codec->height == 576) ||
(ctx->streams[video_stream]->codec->height == 288) )
strcpy(region, "PAL");
else
strcpy(region, "NTSC");
asprintf(&m.dlna_pn, "MPEG_PS_%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", region);
asprintf(&m.mime, "video/mpeg");
}
else
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [UNKNOWN CONTAINER] is %s MPEG2\n", video_stream, path, m.resolution);
}
break;
case CODEC_ID_H264:
if( strcmp(ctx->iformat->name, "mpegts") == 0 )
{
tsinfo_t * ts = ctx->priv_data;
if( ts->packet_size == 192 )
{
if( dlna_timestamp_is_present(path) )
ts_timestamp = VALID;
else
ts_timestamp = EMPTY;
}
char res = '\0';
if( ctx->streams[video_stream]->codec->width <= 720 &&
ctx->streams[video_stream]->codec->height <= 576 &&
ctx->streams[video_stream]->codec->bit_rate <= 10000000 )
res = 'S';
else if( ctx->streams[video_stream]->codec->width <= 1920 &&
ctx->streams[video_stream]->codec->height <= 1152 &&
ctx->streams[video_stream]->codec->bit_rate <= 20000000 )
res = 'H'; res = 'H';
if( res )
{
switch( audio_profile )
{
case MP3:
asprintf(&m.dlna_pn, "AVC_TS_MP_HD_MPEG1_L3%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0",
ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"");
break;
case AC3:
asprintf(&m.dlna_pn, "AVC_TS_MP_HD_AC3%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0",
ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"");
break;
case AAC_MULT5:
asprintf(&m.dlna_pn, "AVC_TS_MP_HD_AAC_MULT5%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0",
ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"");
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for TS/AVC/%cD file %s\n", res, path);
break;
}
if( m.dlna_pn && (ts_timestamp != NONE) )
asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
}
else else
{ res = 'S';
DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n", asprintf(&m.dlna_pn, "MPEG_TS_%cD_NA_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0", res);
ctx->streams[video_stream]->codec->width, asprintf(&m.mime, "video/mpeg");
ctx->streams[video_stream]->codec->height,
ctx->streams[video_stream]->codec->bit_rate);
}
}
else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
{
/* AVC wrapped in MP4 only has SD profiles - 10 Mbps max */
if( ctx->streams[video_stream]->codec->width <= 720 &&
ctx->streams[video_stream]->codec->height <= 576 &&
ctx->streams[video_stream]->codec->bit_rate <= 10000000 )
{
switch( audio_profile )
{
case AC3:
asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
case AAC_MULT5:
asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MP4/AVC/SD file %s\n", path);
break;
}
}
}
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, path);
break;
case CODEC_ID_MPEG4:
if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("XVID") )
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s XViD\n", video_stream, path, m.resolution);
asprintf(&m.mime, "video/divx");
}
else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DX50") )
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s DiVX5\n", video_stream, path, m.resolution);
asprintf(&m.mime, "video/divx");
}
else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DIVX") )
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is DiVX\n", video_stream, path);
asprintf(&m.mime, "video/divx");
} }
}
else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, path, m.resolution);
char region[5];
if( (ctx->streams[video_stream]->codec->height == 576) ||
(ctx->streams[video_stream]->codec->height == 288) )
strcpy(region, "PAL");
else else
strcpy(region, "NTSC");
asprintf(&m.dlna_pn, "MPEG_PS_%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", region);
asprintf(&m.mime, "video/mpeg");
}
else
{
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [UNKNOWN CONTAINER] is %s MPEG2\n", video_stream, path, m.resolution);
}
break;
case CODEC_ID_H264:
if( strcmp(ctx->iformat->name, "mpegts") == 0 )
{
tsinfo_t * ts = ctx->priv_data;
if( ts->packet_size == 192 )
{ {
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%X]\n", video_stream, path, ctx->streams[video_stream]->codec->codec_tag); if( dlna_timestamp_is_present(path) )
ts_timestamp = VALID;
else
ts_timestamp = EMPTY;
} }
break; char res = '\0';
case CODEC_ID_WMV3: if( ctx->streams[video_stream]->codec->width <= 720 &&
case CODEC_ID_VC1: ctx->streams[video_stream]->codec->height <= 576 &&
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, path); ctx->streams[video_stream]->codec->bit_rate <= 10000000 )
char profile[5]; profile[0] = '\0'; res = 'S';
asprintf(&m.mime, "video/x-ms-wmv"); else if( ctx->streams[video_stream]->codec->width <= 1920 &&
if( (ctx->streams[video_stream]->codec->width <= 352) && ctx->streams[video_stream]->codec->height <= 1152 &&
(ctx->streams[video_stream]->codec->height <= 288) && ctx->streams[video_stream]->codec->bit_rate <= 20000000 )
(ctx->bit_rate/8 <= 384000) ) res = 'H';
if( res )
{ {
switch( audio_profile ) switch( audio_profile )
{ {
case MP3: case MP3:
asprintf(&m.dlna_pn, "WMVSPML_MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); asprintf(&m.dlna_pn, "AVC_TS_MP_HD_MPEG1_L3%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0",
ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"");
break; break;
case WMA_BASE: case AC3:
asprintf(&m.dlna_pn, "WMVSPML_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); asprintf(&m.dlna_pn, "AVC_TS_MP_HD_AC3%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0",
ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"");
break;
case AAC_MULT5:
asprintf(&m.dlna_pn, "AVC_TS_MP_HD_AAC_MULT5%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0",
ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"");
break; break;
default: default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n", audio_profile, path); DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for TS/AVC/%cD file %s\n", res, path);
break; break;
} }
if( m.dlna_pn && (ts_timestamp != NONE) )
asprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
} }
else if( (ctx->streams[video_stream]->codec->width <= 720) && else
(ctx->streams[video_stream]->codec->height <= 576) && {
(ctx->bit_rate/8 <= 10000000) ) DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n",
ctx->streams[video_stream]->codec->width,
ctx->streams[video_stream]->codec->height,
ctx->streams[video_stream]->codec->bit_rate);
}
}
else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
{
/* AVC wrapped in MP4 only has SD profiles - 10 Mbps max */
if( ctx->streams[video_stream]->codec->width <= 720 &&
ctx->streams[video_stream]->codec->height <= 576 &&
ctx->streams[video_stream]->codec->bit_rate <= 10000000 )
{ {
switch( audio_profile ) switch( audio_profile )
{ {
case WMA_PRO: case AC3:
asprintf(&m.dlna_pn, "WMVMED_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break; break;
case WMA_FULL: case AAC_MULT5:
asprintf(&m.dlna_pn, "WMVMED_FULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
case WMA_BASE:
asprintf(&m.dlna_pn, "WMVMED_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break; break;
default: default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n", audio_profile, path); DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MP4/AVC/SD file %s\n", path);
break; break;
} }
} }
else if( (ctx->streams[video_stream]->codec->width <= 1920) && }
(ctx->streams[video_stream]->codec->height <= 1080) && DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, path);
(ctx->bit_rate/8 <= 20000000) ) break;
{ case CODEC_ID_MPEG4:
switch( audio_profile ) if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("XVID") )
{ {
case WMA_PRO: DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s XViD\n", video_stream, path, m.resolution);
asprintf(&m.dlna_pn, "WMVHIGH_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); asprintf(&m.mime, "video/divx");
break; }
case WMA_FULL: else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DX50") )
asprintf(&m.dlna_pn, "WMVHIGH_FULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); {
break; DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s DiVX5\n", video_stream, path, m.resolution);
default: asprintf(&m.mime, "video/divx");
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n", audio_profile, path); }
break; else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DIVX") )
} {
} DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is DiVX\n", video_stream, path);
break; asprintf(&m.mime, "video/divx");
case CODEC_ID_XVID: }
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s UNKNOWN XVID\n", video_stream, path, m.resolution); else
break; {
case CODEC_ID_MSMPEG4V1: DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%X]\n", video_stream, path, ctx->streams[video_stream]->codec->codec_tag);
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MS MPEG4 v1\n", video_stream, path, m.resolution); }
case CODEC_ID_MSMPEG4V3: break;
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MS MPEG4 v3\n", video_stream, path, m.resolution); case CODEC_ID_WMV3:
asprintf(&m.mime, "video/avi"); case CODEC_ID_VC1:
break; DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, path);
case CODEC_ID_H263I: char profile[5]; profile[0] = '\0';
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.263i\n", video_stream, path);
break;
case CODEC_ID_MJPEG:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MJPEG\n", video_stream, path);
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %d\n", video_stream, path, ctx->streams[video_stream]->codec->codec_id);
break;
}
}
if( !m.mime )
{
if( strcmp(ctx->iformat->name, "avi") == 0 )
asprintf(&m.mime, "video/x-msvideo");
else if( strcmp(ctx->iformat->name, "mpegts") == 0 )
asprintf(&m.mime, "video/mpeg");
else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
asprintf(&m.mime, "video/mpeg");
else if( strcmp(ctx->iformat->name, "asf") == 0 )
asprintf(&m.mime, "video/x-ms-wmv"); asprintf(&m.mime, "video/x-ms-wmv");
else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 ) if( (ctx->streams[video_stream]->codec->width <= 352) &&
asprintf(&m.mime, "video/mp4"); (ctx->streams[video_stream]->codec->height <= 288) &&
(ctx->bit_rate/8 <= 384000) )
{
switch( audio_profile )
{
case MP3:
asprintf(&m.dlna_pn, "WMVSPML_MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
case WMA_BASE:
asprintf(&m.dlna_pn, "WMVSPML_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n", audio_profile, path);
break;
}
}
else if( (ctx->streams[video_stream]->codec->width <= 720) &&
(ctx->streams[video_stream]->codec->height <= 576) &&
(ctx->bit_rate/8 <= 10000000) )
{
switch( audio_profile )
{
case WMA_PRO:
asprintf(&m.dlna_pn, "WMVMED_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
case WMA_FULL:
asprintf(&m.dlna_pn, "WMVMED_FULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
case WMA_BASE:
asprintf(&m.dlna_pn, "WMVMED_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n", audio_profile, path);
break;
}
}
else if( (ctx->streams[video_stream]->codec->width <= 1920) &&
(ctx->streams[video_stream]->codec->height <= 1080) &&
(ctx->bit_rate/8 <= 20000000) )
{
switch( audio_profile )
{
case WMA_PRO:
asprintf(&m.dlna_pn, "WMVHIGH_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
case WMA_FULL:
asprintf(&m.dlna_pn, "WMVHIGH_FULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0");
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n", audio_profile, path);
break;
}
}
break;
case CODEC_ID_XVID:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s UNKNOWN XVID\n", video_stream, path, m.resolution);
break;
case CODEC_ID_MSMPEG4V1:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MS MPEG4 v1\n", video_stream, path, m.resolution);
case CODEC_ID_MSMPEG4V3:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MS MPEG4 v3\n", video_stream, path, m.resolution);
asprintf(&m.mime, "video/avi");
break;
case CODEC_ID_H263I:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.263i\n", video_stream, path);
break;
case CODEC_ID_MJPEG:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MJPEG\n", video_stream, path);
break;
default:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %d\n", video_stream, path, ctx->streams[video_stream]->codec->codec_id);
break;
} }
av_close_input_file(ctx);
} }
else if( !m.mime )
{ {
DPRINTF(E_WARN, L_METADATA, "Opening %s failed!\n", path); if( strcmp(ctx->iformat->name, "avi") == 0 )
asprintf(&m.mime, "video/x-msvideo");
else if( strcmp(ctx->iformat->name, "mpegts") == 0 )
asprintf(&m.mime, "video/mpeg");
else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
asprintf(&m.mime, "video/mpeg");
else if( strcmp(ctx->iformat->name, "asf") == 0 )
asprintf(&m.mime, "video/x-ms-wmv");
else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
asprintf(&m.mime, "video/mp4");
} }
av_close_input_file(ctx);
sql = sqlite3_mprintf( "INSERT into DETAILS" sql = sqlite3_mprintf( "INSERT into DETAILS"
" (PATH, SIZE, DURATION, DATE, CHANNELS, BITRATE, SAMPLERATE, RESOLUTION," " (PATH, SIZE, DURATION, DATE, CHANNELS, BITRATE, SAMPLERATE, RESOLUTION,"

View File

@ -432,6 +432,7 @@ insert_file(char * name, const char * path, const char * parentID, int object)
char * typedir_parentID; char * typedir_parentID;
int typedir_objectID; int typedir_objectID;
char * baseid; char * baseid;
char * orig_name = NULL;
if( is_image(name) ) if( is_image(name) )
{ {
@ -439,18 +440,23 @@ insert_file(char * name, const char * path, const char * parentID, int object)
strcpy(class, "item.imageItem.photo"); strcpy(class, "item.imageItem.photo");
detailID = GetImageMetadata(path, name); detailID = GetImageMetadata(path, name);
} }
else if( is_audio(name) ) else if( is_video(name) )
{
orig_name = strdup(name);
strcpy(base, VIDEO_DIR_ID);
strcpy(class, "item.videoItem");
detailID = GetVideoMetadata(path, name);
if( !detailID )
strcpy(name, orig_name);
}
if( !detailID && is_audio(name) )
{ {
strcpy(base, MUSIC_DIR_ID); strcpy(base, MUSIC_DIR_ID);
strcpy(class, "item.audioItem.musicTrack"); strcpy(class, "item.audioItem.musicTrack");
detailID = GetAudioMetadata(path, name); detailID = GetAudioMetadata(path, name);
} }
if( !detailID && is_video(name) ) if( orig_name )
{ free(orig_name);
strcpy(base, VIDEO_DIR_ID);
strcpy(class, "item.videoItem");
detailID = GetVideoMetadata(path, name);
}
if( !detailID ) if( !detailID )
{ {
DPRINTF(E_WARN, L_SCANNER, "Unsuccessful getting details for %s!\n", path); DPRINTF(E_WARN, L_SCANNER, "Unsuccessful getting details for %s!\n", path);