* Allow some DLNA AVC profile fallbacks.

This commit is contained in:
Justin Maggard 2011-04-07 23:15:56 +00:00
parent 25e7cb305d
commit 556678ce08

View File

@ -642,6 +642,7 @@ GetVideoMetadata(const char * path, char * name)
int ret, i; int ret, i;
struct tm *modtime; struct tm *modtime;
AVFormatContext *ctx; AVFormatContext *ctx;
AVCodecContext *ac, *vc;
int audio_stream = -1, video_stream = -1; int audio_stream = -1, video_stream = -1;
enum audio_profiles audio_profile = PROFILE_AUDIO_UNKNOWN; enum audio_profiles audio_profile = PROFILE_AUDIO_UNKNOWN;
tsinfo_t *ts; tsinfo_t *ts;
@ -678,12 +679,14 @@ GetVideoMetadata(const char * path, char * name)
ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO ) ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO )
{ {
audio_stream = i; audio_stream = i;
ac = ctx->streams[audio_stream]->codec;
continue; continue;
} }
else if( video_stream == -1 && else if( video_stream == -1 &&
ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO ) ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
{ {
video_stream = i; video_stream = i;
vc = ctx->streams[video_stream]->codec;
continue; continue;
} }
} }
@ -716,21 +719,21 @@ GetVideoMetadata(const char * path, char * name)
if( audio_stream >= 0 ) if( audio_stream >= 0 )
{ {
switch( ctx->streams[audio_stream]->codec->codec_id ) switch( ac->codec_id )
{ {
case CODEC_ID_MP3: case CODEC_ID_MP3:
audio_profile = PROFILE_AUDIO_MP3; audio_profile = PROFILE_AUDIO_MP3;
break; break;
case CODEC_ID_AAC: case CODEC_ID_AAC:
if( !ctx->streams[audio_stream]->codec->extradata_size || if( !ac->extradata_size ||
!ctx->streams[audio_stream]->codec->extradata ) !ac->extradata )
{ {
DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n"); DPRINTF(E_DEBUG, L_METADATA, "No AAC type\n");
} }
else else
{ {
uint8_t data; uint8_t data;
memcpy(&data, ctx->streams[audio_stream]->codec->extradata, 1); memcpy(&data, ac->extradata, 1);
aac_type = data >> 3; aac_type = data >> 3;
} }
switch( aac_type ) switch( aac_type )
@ -738,24 +741,24 @@ GetVideoMetadata(const char * path, char * name)
/* AAC Low Complexity variants */ /* AAC Low Complexity variants */
case AAC_LC: case AAC_LC:
case AAC_LC_ER: case AAC_LC_ER:
if( ctx->streams[audio_stream]->codec->sample_rate < 8000 || if( ac->sample_rate < 8000 ||
ctx->streams[audio_stream]->codec->sample_rate > 48000 ) ac->sample_rate > 48000 )
{ {
DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n", DPRINTF(E_DEBUG, L_METADATA, "Unsupported AAC: sample rate is not 8000 < %d < 48000\n",
ctx->streams[audio_stream]->codec->sample_rate); ac->sample_rate);
break; break;
} }
/* AAC @ Level 1/2 */ /* AAC @ Level 1/2 */
if( ctx->streams[audio_stream]->codec->channels <= 2 && if( ac->channels <= 2 &&
ctx->streams[audio_stream]->codec->bit_rate <= 576000 ) ac->bit_rate <= 576000 )
audio_profile = PROFILE_AUDIO_AAC; audio_profile = PROFILE_AUDIO_AAC;
else if( ctx->streams[audio_stream]->codec->channels <= 6 && else if( ac->channels <= 6 &&
ctx->streams[audio_stream]->codec->bit_rate <= 1440000 ) ac->bit_rate <= 1440000 )
audio_profile = PROFILE_AUDIO_AAC_MULT5; audio_profile = PROFILE_AUDIO_AAC_MULT5;
else else
DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n", DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n",
ctx->streams[audio_stream]->codec->channels, ac->channels,
ctx->streams[audio_stream]->codec->bit_rate); ac->bit_rate);
break; break;
default: default:
DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type); DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC type [%d]\n", aac_type);
@ -769,10 +772,10 @@ GetVideoMetadata(const char * path, char * name)
case CODEC_ID_WMAV1: case CODEC_ID_WMAV1:
case CODEC_ID_WMAV2: case CODEC_ID_WMAV2:
/* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */ /* WMA Baseline: stereo, up to 48 KHz, up to 192,999 bps */
if ( ctx->streams[audio_stream]->codec->bit_rate <= 193000 ) if ( ac->bit_rate <= 193000 )
audio_profile = PROFILE_AUDIO_WMA_BASE; audio_profile = PROFILE_AUDIO_WMA_BASE;
/* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */ /* WMA Full: stereo, up to 48 KHz, up to 385 Kbps */
else if ( ctx->streams[audio_stream]->codec->bit_rate <= 385000 ) else if ( ac->bit_rate <= 385000 )
audio_profile = PROFILE_AUDIO_WMA_FULL; audio_profile = PROFILE_AUDIO_WMA_FULL;
break; break;
#if LIBAVCODEC_VERSION_INT > ((51<<16)+(50<<8)+1) #if LIBAVCODEC_VERSION_INT > ((51<<16)+(50<<8)+1)
@ -787,25 +790,25 @@ GetVideoMetadata(const char * path, char * name)
audio_profile = PROFILE_AUDIO_AMR; audio_profile = PROFILE_AUDIO_AMR;
break; break;
default: default:
if( (ctx->streams[audio_stream]->codec->codec_id >= CODEC_ID_PCM_S16LE) && if( (ac->codec_id >= CODEC_ID_PCM_S16LE) &&
(ctx->streams[audio_stream]->codec->codec_id < CODEC_ID_ADPCM_IMA_QT) ) (ac->codec_id < CODEC_ID_ADPCM_IMA_QT) )
audio_profile = PROFILE_AUDIO_PCM; audio_profile = PROFILE_AUDIO_PCM;
else else
DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ctx->streams[audio_stream]->codec->codec_id); DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ac->codec_id);
break; break;
} }
asprintf(&m.frequency, "%u", ctx->streams[audio_stream]->codec->sample_rate); asprintf(&m.frequency, "%u", ac->sample_rate);
#if LIBAVCODEC_VERSION_INT < (52<<16) #if LIBAVCODEC_VERSION_INT < (52<<16)
asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_sample); asprintf(&m.bps, "%u", ac->bits_per_sample);
#else #else
asprintf(&m.bps, "%u", ctx->streams[audio_stream]->codec->bits_per_coded_sample); asprintf(&m.bps, "%u", ac->bits_per_coded_sample);
#endif #endif
asprintf(&m.channels, "%u", ctx->streams[audio_stream]->codec->channels); asprintf(&m.channels, "%u", ac->channels);
} }
if( video_stream >= 0 ) if( video_stream >= 0 )
{ {
DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename(path)); DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename(path));
asprintf(&m.resolution, "%dx%d", ctx->streams[video_stream]->codec->width, ctx->streams[video_stream]->codec->height); asprintf(&m.resolution, "%dx%d", vc->width, vc->height);
if( ctx->bit_rate > 8 ) if( ctx->bit_rate > 8 )
asprintf(&m.bitrate, "%u", ctx->bit_rate / 8); asprintf(&m.bitrate, "%u", ctx->bit_rate / 8);
if( ctx->duration > 0 ) { if( ctx->duration > 0 ) {
@ -821,12 +824,12 @@ GetVideoMetadata(const char * path, char * name)
if( strcmp(ctx->iformat->name, "avi") == 0 ) if( strcmp(ctx->iformat->name, "avi") == 0 )
{ {
asprintf(&m.mime, "video/x-msvideo"); asprintf(&m.mime, "video/x-msvideo");
if( ctx->streams[video_stream]->codec->codec_id == CODEC_ID_MPEG4 ) if( vc->codec_id == CODEC_ID_MPEG4 )
{ {
fourcc[0] = ctx->streams[video_stream]->codec->codec_tag & 0xff; fourcc[0] = vc->codec_tag & 0xff;
fourcc[1] = ctx->streams[video_stream]->codec->codec_tag>>8 & 0xff; fourcc[1] = vc->codec_tag>>8 & 0xff;
fourcc[2] = ctx->streams[video_stream]->codec->codec_tag>>16 & 0xff; fourcc[2] = vc->codec_tag>>16 & 0xff;
fourcc[3] = ctx->streams[video_stream]->codec->codec_tag>>24 & 0xff; fourcc[3] = vc->codec_tag>>24 & 0xff;
if( memcmp(fourcc, "XVID", 4) == 0 || if( memcmp(fourcc, "XVID", 4) == 0 ||
memcmp(fourcc, "DX50", 4) == 0 || memcmp(fourcc, "DX50", 4) == 0 ||
memcmp(fourcc, "DIVX", 4) == 0 ) memcmp(fourcc, "DIVX", 4) == 0 )
@ -843,13 +846,13 @@ GetVideoMetadata(const char * path, char * name)
if( m.mime ) if( m.mime )
goto video_no_dlna; goto video_no_dlna;
switch( ctx->streams[video_stream]->codec->codec_id ) switch( vc->codec_id )
{ {
case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG1VIDEO:
if( strcmp(ctx->iformat->name, "mpeg") == 0 ) if( strcmp(ctx->iformat->name, "mpeg") == 0 )
{ {
if( (ctx->streams[video_stream]->codec->width == 352) && if( (vc->width == 352) &&
(ctx->streams[video_stream]->codec->height <= 288) ) (vc->height <= 288) )
{ {
asprintf(&m.dlna_pn, "MPEG1;%s", dlna_no_conv); asprintf(&m.dlna_pn, "MPEG1;%s", dlna_no_conv);
} }
@ -863,16 +866,16 @@ GetVideoMetadata(const char * path, char * name)
{ {
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, basename(path), m.resolution); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, basename(path), m.resolution);
off += sprintf(m.dlna_pn+off, "TS_"); off += sprintf(m.dlna_pn+off, "TS_");
if( (ctx->streams[video_stream]->codec->width >= 1280) && if( (vc->width >= 1280) &&
(ctx->streams[video_stream]->codec->height >= 720) ) (vc->height >= 720) )
{ {
off += sprintf(m.dlna_pn+off, "HD_NA"); off += sprintf(m.dlna_pn+off, "HD_NA");
} }
else else
{ {
off += sprintf(m.dlna_pn+off, "SD_"); off += sprintf(m.dlna_pn+off, "SD_");
if( (ctx->streams[video_stream]->codec->height == 576) || if( (vc->height == 576) ||
(ctx->streams[video_stream]->codec->height == 288) ) (vc->height == 288) )
off += sprintf(m.dlna_pn+off, "EU"); off += sprintf(m.dlna_pn+off, "EU");
else else
off += sprintf(m.dlna_pn+off, "NA"); off += sprintf(m.dlna_pn+off, "NA");
@ -909,8 +912,8 @@ GetVideoMetadata(const char * path, char * name)
{ {
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, basename(path), m.resolution); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, basename(path), m.resolution);
off += sprintf(m.dlna_pn+off, "PS_"); off += sprintf(m.dlna_pn+off, "PS_");
if( (ctx->streams[video_stream]->codec->height == 576) || if( (vc->height == 576) ||
(ctx->streams[video_stream]->codec->height == 288) ) (vc->height == 288) )
off += sprintf(m.dlna_pn+off, "PAL"); off += sprintf(m.dlna_pn+off, "PAL");
else else
off += sprintf(m.dlna_pn+off, "NTSC"); off += sprintf(m.dlna_pn+off, "NTSC");
@ -932,29 +935,55 @@ GetVideoMetadata(const char * path, char * name)
if( strcmp(ctx->iformat->name, "mpegts") == 0 ) if( strcmp(ctx->iformat->name, "mpegts") == 0 )
{ {
off += sprintf(m.dlna_pn+off, "TS_"); off += sprintf(m.dlna_pn+off, "TS_");
switch( ctx->streams[video_stream]->codec->profile ) switch( vc->profile )
{ {
case FF_PROFILE_H264_BASELINE: case FF_PROFILE_H264_BASELINE:
off += sprintf(m.dlna_pn+off, "BL_"); off += sprintf(m.dlna_pn+off, "BL_");
if( ctx->streams[video_stream]->codec->width <= 352 && if( vc->width <= 352 &&
ctx->streams[video_stream]->codec->height <= 288 && vc->height <= 288 &&
ctx->streams[video_stream]->codec->bit_rate <= 384000 ) vc->bit_rate <= 384000 )
{ {
off += sprintf(m.dlna_pn+off, "CIF15_"); off += sprintf(m.dlna_pn+off, "CIF15_");
break;
} }
else if( ctx->streams[video_stream]->codec->width <= 352 && else if( vc->width <= 352 &&
ctx->streams[video_stream]->codec->height <= 288 && vc->height <= 288 &&
ctx->streams[video_stream]->codec->bit_rate <= 3000000 ) vc->bit_rate <= 3000000 )
{ {
off += sprintf(m.dlna_pn+off, "CIF30_"); off += sprintf(m.dlna_pn+off, "CIF30_");
break;
}
/* Fall back to Main Profile if it doesn't match a Baseline DLNA profile. */
else
off -= 3;
default:
case FF_PROFILE_H264_MAIN:
off += sprintf(m.dlna_pn+off, "MP_");
if( vc->profile != FF_PROFILE_H264_BASELINE &&
vc->profile != FF_PROFILE_H264_MAIN )
{
DPRINTF(E_DEBUG, L_METADATA, "Unknown AVC profile %d; assuming MP. [%s]\n",
vc->profile, basename(path));
}
if( vc->width <= 720 &&
vc->height <= 576 &&
vc->bit_rate <= 10000000 )
{
off += sprintf(m.dlna_pn+off, "SD_");
}
else if( vc->width <= 1920 &&
vc->height <= 1152 &&
vc->bit_rate <= 20000000 )
{
off += sprintf(m.dlna_pn+off, "HD_");
} }
else else
{ {
DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%s, %dx%d, %dbps : %s]\n", DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%s, %dx%d, %dbps : %s]\n",
m.dlna_pn, m.dlna_pn,
ctx->streams[video_stream]->codec->width, vc->width,
ctx->streams[video_stream]->codec->height, vc->height,
ctx->streams[video_stream]->codec->bit_rate, vc->bit_rate,
basename(path)); basename(path));
free(m.dlna_pn); free(m.dlna_pn);
m.dlna_pn = NULL; m.dlna_pn = NULL;
@ -962,9 +991,9 @@ GetVideoMetadata(const char * path, char * name)
break; break;
case FF_PROFILE_H264_HIGH: case FF_PROFILE_H264_HIGH:
off += sprintf(m.dlna_pn+off, "HP_"); off += sprintf(m.dlna_pn+off, "HP_");
if( ctx->streams[video_stream]->codec->width <= 1920 && if( vc->width <= 1920 &&
ctx->streams[video_stream]->codec->height <= 1152 && vc->height <= 1152 &&
ctx->streams[video_stream]->codec->bit_rate <= 30000000 && vc->bit_rate <= 30000000 &&
audio_profile == PROFILE_AUDIO_AC3 ) audio_profile == PROFILE_AUDIO_AC3 )
{ {
off += sprintf(m.dlna_pn+off, "HD_"); off += sprintf(m.dlna_pn+off, "HD_");
@ -972,41 +1001,12 @@ GetVideoMetadata(const char * path, char * name)
else else
{ {
DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 HP video profile! [%dbps, %d audio : %s]\n", DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 HP video profile! [%dbps, %d audio : %s]\n",
ctx->streams[video_stream]->codec->bit_rate, vc->bit_rate,
audio_profile, basename(path)); audio_profile, basename(path));
free(m.dlna_pn); free(m.dlna_pn);
m.dlna_pn = NULL; m.dlna_pn = NULL;
} }
break; break;
default:
DPRINTF(E_DEBUG, L_METADATA, "Unknown AVC profile %d; assuming MP. [%s]\n",
ctx->streams[video_stream]->codec->profile, basename(path));
case FF_PROFILE_H264_MAIN:
off += sprintf(m.dlna_pn+off, "MP_");
if( ctx->streams[video_stream]->codec->width <= 720 &&
ctx->streams[video_stream]->codec->height <= 576 &&
ctx->streams[video_stream]->codec->bit_rate <= 10000000 )
{
off += sprintf(m.dlna_pn+off, "SD_");
}
else if( ctx->streams[video_stream]->codec->width <= 1920 &&
ctx->streams[video_stream]->codec->height <= 1152 &&
ctx->streams[video_stream]->codec->bit_rate <= 20000000 )
{
off += sprintf(m.dlna_pn+off, "HD_");
}
else
{
DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%s, %dx%d, %dbps : %s]\n",
m.dlna_pn,
ctx->streams[video_stream]->codec->width,
ctx->streams[video_stream]->codec->height,
ctx->streams[video_stream]->codec->bit_rate,
basename(path));
free(m.dlna_pn);
m.dlna_pn = NULL;
}
break;
} }
if( !m.dlna_pn ) if( !m.dlna_pn )
break; break;
@ -1018,6 +1018,7 @@ GetVideoMetadata(const char * path, char * name)
case PROFILE_AUDIO_AC3: case PROFILE_AUDIO_AC3:
off += sprintf(m.dlna_pn+off, "AC3"); off += sprintf(m.dlna_pn+off, "AC3");
break; break;
case PROFILE_AUDIO_AAC:
case PROFILE_AUDIO_AAC_MULT5: case PROFILE_AUDIO_AAC_MULT5:
off += sprintf(m.dlna_pn+off, "AAC_MULT5"); off += sprintf(m.dlna_pn+off, "AAC_MULT5");
break; break;
@ -1055,26 +1056,18 @@ GetVideoMetadata(const char * path, char * name)
{ {
off += sprintf(m.dlna_pn+off, "MP4_"); off += sprintf(m.dlna_pn+off, "MP4_");
switch( ctx->streams[video_stream]->codec->profile ) { switch( vc->profile ) {
case FF_PROFILE_H264_BASELINE: case FF_PROFILE_H264_BASELINE:
if( ctx->streams[video_stream]->codec->width <= 352 && if( vc->width <= 352 &&
ctx->streams[video_stream]->codec->height <= 288 ) vc->height <= 288 )
{ {
if( ctx->bit_rate < 600000 ) if( ctx->bit_rate < 600000 )
{
off += sprintf(m.dlna_pn+off, "BL_CIF15_"); off += sprintf(m.dlna_pn+off, "BL_CIF15_");
}
else if( ctx->bit_rate < 5000000 ) else if( ctx->bit_rate < 5000000 )
{
off += sprintf(m.dlna_pn+off, "BL_CIF30_"); off += sprintf(m.dlna_pn+off, "BL_CIF30_");
}
else else
{ goto mp4_mp_fallback;
DPRINTF(E_DEBUG, L_METADATA, "Unhandled MP4_BL bit rate on %s\n", basename(path));
free(m.dlna_pn);
m.dlna_pn = NULL;
break;
}
if( audio_profile == PROFILE_AUDIO_AMR ) if( audio_profile == PROFILE_AUDIO_AMR )
{ {
off += sprintf(m.dlna_pn+off, "AMR"); off += sprintf(m.dlna_pn+off, "AMR");
@ -1092,89 +1085,76 @@ GetVideoMetadata(const char * path, char * name)
} }
else else
{ {
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file %s\n", off -= 13;
m.dlna_pn, basename(path)); goto mp4_mp_fallback;
free(m.dlna_pn);
m.dlna_pn = NULL;
break;
} }
} }
else else
{ {
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file %s\n", off -= 9;
m.dlna_pn, basename(path)); goto mp4_mp_fallback;
free(m.dlna_pn);
m.dlna_pn = NULL;
break;
} }
} }
else if( ctx->streams[video_stream]->codec->width <= 720 && else if( vc->width <= 720 &&
ctx->streams[video_stream]->codec->height <= 576 ) vc->height <= 576 )
{ {
if( ctx->streams[video_stream]->codec->level == 30 && if( vc->level == 30 &&
audio_profile == PROFILE_AUDIO_AAC && audio_profile == PROFILE_AUDIO_AAC &&
ctx->bit_rate <= 5000000 ) ctx->bit_rate <= 5000000 )
{
off += sprintf(m.dlna_pn+off, "BL_L3L_SD_AAC"); off += sprintf(m.dlna_pn+off, "BL_L3L_SD_AAC");
} else if( vc->level <= 31 &&
else if( ctx->streams[video_stream]->codec->level <= 31 &&
audio_profile == PROFILE_AUDIO_AAC && audio_profile == PROFILE_AUDIO_AAC &&
ctx->bit_rate <= 15000000 ) ctx->bit_rate <= 15000000 )
{
off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC"); off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC");
else
goto mp4_mp_fallback;
} }
} else if( vc->width <= 1280 &&
else if( ctx->streams[video_stream]->codec->width <= 1280 && vc->height <= 720 )
ctx->streams[video_stream]->codec->height <= 720 )
{ {
if( ctx->streams[video_stream]->codec->level <= 31 && if( vc->level <= 31 &&
audio_profile == PROFILE_AUDIO_AAC && audio_profile == PROFILE_AUDIO_AAC &&
ctx->bit_rate <= 15000000 ) ctx->bit_rate <= 15000000 )
{
off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC"); off += sprintf(m.dlna_pn+off, "BL_L31_HD_AAC");
} else if( vc->level <= 32 &&
else if( ctx->streams[video_stream]->codec->level <= 32 &&
audio_profile == PROFILE_AUDIO_AAC && audio_profile == PROFILE_AUDIO_AAC &&
ctx->bit_rate <= 21000000 ) ctx->bit_rate <= 21000000 )
{
off += sprintf(m.dlna_pn+off, "BL_L32_HD_AAC"); off += sprintf(m.dlna_pn+off, "BL_L32_HD_AAC");
else
goto mp4_mp_fallback;
} }
} else
if( strlen(m.dlna_pn) <= 8 ) goto mp4_mp_fallback;
{
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file %s\n",
m.dlna_pn, basename(path));
free(m.dlna_pn);
m.dlna_pn = NULL;
}
break; break;
case FF_PROFILE_H264_MAIN: case FF_PROFILE_H264_MAIN:
mp4_mp_fallback:
off += sprintf(m.dlna_pn+off, "MP_"); off += sprintf(m.dlna_pn+off, "MP_");
/* AVC MP4 SD profiles - 10 Mbps max */ /* AVC MP4 SD profiles - 10 Mbps max */
if( ctx->streams[video_stream]->codec->width <= 720 && if( vc->width <= 720 &&
ctx->streams[video_stream]->codec->height <= 576 && vc->height <= 576 &&
ctx->streams[video_stream]->codec->bit_rate <= 10000000 ) vc->bit_rate <= 10000000 )
{ {
sprintf(m.dlna_pn+off, "SD_"); sprintf(m.dlna_pn+off, "SD_");
if( audio_profile == PROFILE_AUDIO_AC3 ) if( audio_profile == PROFILE_AUDIO_AC3 )
off += sprintf(m.dlna_pn+off, "AC3"); off += sprintf(m.dlna_pn+off, "AC3");
else if( audio_profile == PROFILE_AUDIO_AAC_MULT5 ) else if( audio_profile == PROFILE_AUDIO_AAC ||
audio_profile == PROFILE_AUDIO_AAC_MULT5 )
off += sprintf(m.dlna_pn+off, "AAC_MULT5"); off += sprintf(m.dlna_pn+off, "AAC_MULT5");
else if( audio_profile == PROFILE_AUDIO_MP3 ) else if( audio_profile == PROFILE_AUDIO_MP3 )
off += sprintf(m.dlna_pn+off, "MPEG1_L3"); off += sprintf(m.dlna_pn+off, "MPEG1_L3");
else else
m.dlna_pn[10] = '\0'; m.dlna_pn[10] = '\0';
} }
else if( ctx->streams[video_stream]->codec->width <= 1280 && else if( vc->width <= 1280 &&
ctx->streams[video_stream]->codec->height <= 720 && vc->height <= 720 &&
ctx->streams[video_stream]->codec->bit_rate <= 15000000 && vc->bit_rate <= 15000000 &&
audio_profile == PROFILE_AUDIO_AAC ) audio_profile == PROFILE_AUDIO_AAC )
{ {
off += sprintf(m.dlna_pn+off, "HD_720p_AAC"); off += sprintf(m.dlna_pn+off, "HD_720p_AAC");
} }
else if( ctx->streams[video_stream]->codec->width <= 1920 && else if( vc->width <= 1920 &&
ctx->streams[video_stream]->codec->height <= 1080 && vc->height <= 1080 &&
ctx->streams[video_stream]->codec->bit_rate <= 21000000 && vc->bit_rate <= 21000000 &&
audio_profile == PROFILE_AUDIO_AAC ) audio_profile == PROFILE_AUDIO_AAC )
{ {
off += sprintf(m.dlna_pn+off, "HD_1080i_AAC"); off += sprintf(m.dlna_pn+off, "HD_1080i_AAC");
@ -1188,9 +1168,9 @@ GetVideoMetadata(const char * path, char * name)
} }
break; break;
case FF_PROFILE_H264_HIGH: case FF_PROFILE_H264_HIGH:
if( ctx->streams[video_stream]->codec->width <= 1920 && if( vc->width <= 1920 &&
ctx->streams[video_stream]->codec->height <= 1080 && vc->height <= 1080 &&
ctx->streams[video_stream]->codec->bit_rate <= 25000000 && vc->bit_rate <= 25000000 &&
audio_profile == PROFILE_AUDIO_AAC ) audio_profile == PROFILE_AUDIO_AAC )
{ {
off += sprintf(m.dlna_pn+off, "HP_HD_AAC"); off += sprintf(m.dlna_pn+off, "HP_HD_AAC");
@ -1198,7 +1178,7 @@ GetVideoMetadata(const char * path, char * name)
break; break;
default: default:
DPRINTF(E_DEBUG, L_METADATA, "AVC profile [%d] not recognized for file %s\n", DPRINTF(E_DEBUG, L_METADATA, "AVC profile [%d] not recognized for file %s\n",
ctx->streams[video_stream]->codec->profile, basename(path)); vc->profile, basename(path));
free(m.dlna_pn); free(m.dlna_pn);
m.dlna_pn = NULL; m.dlna_pn = NULL;
break; break;
@ -1214,17 +1194,17 @@ GetVideoMetadata(const char * path, char * name)
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename(path)); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename(path));
break; break;
case CODEC_ID_MPEG4: case CODEC_ID_MPEG4:
fourcc[0] = ctx->streams[video_stream]->codec->codec_tag & 0xff; fourcc[0] = vc->codec_tag & 0xff;
fourcc[1] = ctx->streams[video_stream]->codec->codec_tag>>8 & 0xff; fourcc[1] = vc->codec_tag>>8 & 0xff;
fourcc[2] = ctx->streams[video_stream]->codec->codec_tag>>16 & 0xff; fourcc[2] = vc->codec_tag>>16 & 0xff;
fourcc[3] = ctx->streams[video_stream]->codec->codec_tag>>24 & 0xff; fourcc[3] = vc->codec_tag>>24 & 0xff;
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%c%c%c%c/0x%X]\n", DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%c%c%c%c/0x%X]\n",
video_stream, basename(path), video_stream, basename(path),
isprint(fourcc[0]) ? fourcc[0] : '_', isprint(fourcc[0]) ? fourcc[0] : '_',
isprint(fourcc[1]) ? fourcc[1] : '_', isprint(fourcc[1]) ? fourcc[1] : '_',
isprint(fourcc[2]) ? fourcc[2] : '_', isprint(fourcc[2]) ? fourcc[2] : '_',
isprint(fourcc[3]) ? fourcc[3] : '_', isprint(fourcc[3]) ? fourcc[3] : '_',
ctx->streams[video_stream]->codec->codec_tag); vc->codec_tag);
if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 ) if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
{ {
@ -1244,7 +1224,7 @@ GetVideoMetadata(const char * path, char * name)
break; break;
default: default:
DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n", DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n",
ctx->streams[audio_stream]->codec->codec_id, basename(path)); ac->codec_id, basename(path));
free(m.dlna_pn); free(m.dlna_pn);
m.dlna_pn = NULL; m.dlna_pn = NULL;
break; break;
@ -1258,8 +1238,8 @@ GetVideoMetadata(const char * path, char * name)
off += sprintf(m.dlna_pn+off, "MP4_ASP_AAC"); off += sprintf(m.dlna_pn+off, "MP4_ASP_AAC");
} }
else if( ctx->bit_rate <= 4000000 && else if( ctx->bit_rate <= 4000000 &&
ctx->streams[video_stream]->codec->width <= 640 && vc->width <= 640 &&
ctx->streams[video_stream]->codec->height <= 480 && vc->height <= 480 &&
audio_profile == PROFILE_AUDIO_AAC ) audio_profile == PROFILE_AUDIO_AAC )
{ {
off += sprintf(m.dlna_pn+off, "MP4_SP_VGA_AAC"); off += sprintf(m.dlna_pn+off, "MP4_SP_VGA_AAC");
@ -1267,8 +1247,8 @@ GetVideoMetadata(const char * path, char * name)
else else
{ {
DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n", DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%dx%d, %dbps]\n",
ctx->streams[video_stream]->codec->width, vc->width,
ctx->streams[video_stream]->codec->height, vc->height,
ctx->bit_rate); ctx->bit_rate);
free(m.dlna_pn); free(m.dlna_pn);
m.dlna_pn = NULL; m.dlna_pn = NULL;
@ -1280,12 +1260,12 @@ GetVideoMetadata(const char * path, char * name)
break; break;
case CODEC_ID_WMV3: case CODEC_ID_WMV3:
/* I'm not 100% sure this is correct, but it works on everything I could get my hands on */ /* I'm not 100% sure this is correct, but it works on everything I could get my hands on */
if( ctx->streams[video_stream]->codec->extradata_size > 0 ) if( vc->extradata_size > 0 )
{ {
if( !((ctx->streams[video_stream]->codec->extradata[0] >> 3) & 1) ) if( !((vc->extradata[0] >> 3) & 1) )
ctx->streams[video_stream]->codec->level = 0; vc->level = 0;
if( !((ctx->streams[video_stream]->codec->extradata[0] >> 6) & 1) ) if( !((vc->extradata[0] >> 6) & 1) )
ctx->streams[video_stream]->codec->profile = 0; vc->profile = 0;
} }
case CODEC_ID_VC1: case CODEC_ID_VC1:
if( strcmp(ctx->iformat->name, "asf") != 0 ) if( strcmp(ctx->iformat->name, "asf") != 0 )
@ -1297,9 +1277,9 @@ GetVideoMetadata(const char * path, char * name)
off = sprintf(m.dlna_pn, "WMV"); off = sprintf(m.dlna_pn, "WMV");
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename(path)); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename(path));
asprintf(&m.mime, "video/x-ms-wmv"); asprintf(&m.mime, "video/x-ms-wmv");
if( (ctx->streams[video_stream]->codec->width <= 176) && if( (vc->width <= 176) &&
(ctx->streams[video_stream]->codec->height <= 144) && (vc->height <= 144) &&
(ctx->streams[video_stream]->codec->level == 0) ) (vc->level == 0) )
{ {
off += sprintf(m.dlna_pn+off, "SPLL_"); off += sprintf(m.dlna_pn+off, "SPLL_");
switch( audio_profile ) switch( audio_profile )
@ -1317,9 +1297,9 @@ GetVideoMetadata(const char * path, char * name)
break; break;
} }
} }
else if( (ctx->streams[video_stream]->codec->width <= 352) && else if( (vc->width <= 352) &&
(ctx->streams[video_stream]->codec->height <= 288) && (vc->height <= 288) &&
(ctx->streams[video_stream]->codec->profile == 0) && (vc->profile == 0) &&
(ctx->bit_rate/8 <= 384000) ) (ctx->bit_rate/8 <= 384000) )
{ {
off += sprintf(m.dlna_pn+off, "SPML_"); off += sprintf(m.dlna_pn+off, "SPML_");
@ -1338,8 +1318,8 @@ GetVideoMetadata(const char * path, char * name)
break; break;
} }
} }
else if( (ctx->streams[video_stream]->codec->width <= 720) && else if( (vc->width <= 720) &&
(ctx->streams[video_stream]->codec->height <= 576) && (vc->height <= 576) &&
(ctx->bit_rate/8 <= 10000000) ) (ctx->bit_rate/8 <= 10000000) )
{ {
off += sprintf(m.dlna_pn+off, "MED_"); off += sprintf(m.dlna_pn+off, "MED_");
@ -1361,8 +1341,8 @@ GetVideoMetadata(const char * path, char * name)
break; break;
} }
} }
else if( (ctx->streams[video_stream]->codec->width <= 1920) && else if( (vc->width <= 1920) &&
(ctx->streams[video_stream]->codec->height <= 1080) && (vc->height <= 1080) &&
(ctx->bit_rate/8 <= 20000000) ) (ctx->bit_rate/8 <= 20000000) )
{ {
off += sprintf(m.dlna_pn+off, "HIGH_"); off += sprintf(m.dlna_pn+off, "HIGH_");
@ -1387,7 +1367,7 @@ GetVideoMetadata(const char * path, char * name)
case CODEC_ID_MSMPEG4V3: case CODEC_ID_MSMPEG4V3:
asprintf(&m.mime, "video/x-msvideo"); asprintf(&m.mime, "video/x-msvideo");
default: default:
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); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n", video_stream, basename(path), m.resolution, vc->codec_id);
break; break;
} }
} }