@ -647,9 +647,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
var videoStream = mediaInfo . MediaStreams . FirstOrDefault ( i = > i . Type = = MediaStreamType . Video ) ;
if ( videoStream ! = null )
if ( videoStream ! = null & & ! videoStream . IsInterlaced )
{
var isInterlaced = await DetectInterlaced ( mediaInfo , videoStream , inputPath , probeSizeArgument ) . ConfigureAwait ( false ) ;
var isInterlaced = DetectInterlaced ( mediaInfo , videoStream ) ;
if ( isInterlaced )
{
@ -672,7 +672,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
private async Task < bool > DetectInterlaced ( MediaSourceInfo video , MediaStream videoStream , string inputPath , string probeSizeArgument )
private bool DetectInterlaced ( MediaSourceInfo video , MediaStream videoStream )
{
var formats = ( video . Container ? ? string . Empty ) . Split ( ',' ) . ToList ( ) ;
var enableInterlacedDection = formats . Contains ( "vob" , StringComparer . OrdinalIgnoreCase ) | |
@ -698,165 +698,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
if ( video . Protocol ! = MediaProtocol . File )
{
return false ;
}
var args = "{0} -i {1} -map 0:v:{2} -an -filter:v idet -frames:v 500 -an -f null /dev/null" ;
var process = _processFactory . Create ( new ProcessOptions
{
CreateNoWindow = true ,
UseShellExecute = false ,
// Must consume both or ffmpeg may hang due to deadlocks. See comments below.
RedirectStandardError = true ,
FileName = FFMpegPath ,
Arguments = string . Format ( args , probeSizeArgument , inputPath , videoStream . Index . ToString ( CultureInfo . InvariantCulture ) ) . Trim ( ) ,
IsHidden = true ,
ErrorDialog = false ,
EnableRaisingEvents = true
} ) ;
_logger . Debug ( "{0} {1}" , process . StartInfo . FileName , process . StartInfo . Arguments ) ;
var idetFoundInterlaced = false ;
using ( var processWrapper = new ProcessWrapper ( process , this , _logger ) )
{
try
{
StartProcess ( processWrapper ) ;
}
catch ( Exception ex )
{
_logger . ErrorException ( "Error starting ffprobe" , ex ) ;
throw ;
}
try
{
//process.BeginOutputReadLine();
using ( var reader = new StreamReader ( process . StandardError . BaseStream ) )
{
while ( ! reader . EndOfStream )
{
var line = await reader . ReadLineAsync ( ) . ConfigureAwait ( false ) ;
if ( line . StartsWith ( "[Parsed_idet" , StringComparison . OrdinalIgnoreCase ) )
{
var idetResult = AnalyzeIdetResult ( line ) ;
if ( idetResult . HasValue )
{
if ( ! idetResult . Value )
{
return false ;
}
idetFoundInterlaced = true ;
}
}
}
}
}
catch
{
StopProcess ( processWrapper , 100 ) ;
throw ;
}
}
return idetFoundInterlaced ;
}
private bool? AnalyzeIdetResult ( string line )
{
// As you can see, the filter only guessed one frame as progressive.
// Results like this are pretty typical. So if less than 30% of the detections are in the "Undetermined" category, then I only consider the video to be interlaced if at least 65% of the identified frames are in either the TFF or BFF category.
// In this case (310 + 311)/(622) = 99.8% which is well over the 65% metric. I may refine that number with more testing but I honestly do not believe I will need to.
// http://awel.domblogger.net/videoTranscode/interlace.html
var index = line . IndexOf ( "detection:" , StringComparison . OrdinalIgnoreCase ) ;
if ( index = = - 1 )
{
return null ;
}
line = line . Substring ( index ) . Trim ( ) ;
var parts = line . Split ( ' ' ) . Where ( i = > ! string . IsNullOrWhiteSpace ( i ) ) . Select ( i = > i . Trim ( ) ) . ToList ( ) ;
if ( parts . Count < 2 )
{
return null ;
}
double tff = 0 ;
double bff = 0 ;
double progressive = 0 ;
double undetermined = 0 ;
double total = 0 ;
for ( var i = 0 ; i < parts . Count - 1 ; i + + )
{
var part = parts [ i ] ;
if ( string . Equals ( part , "tff:" , StringComparison . OrdinalIgnoreCase ) )
{
tff = GetNextPart ( parts , i ) ;
total + = tff ;
}
else if ( string . Equals ( part , "bff:" , StringComparison . OrdinalIgnoreCase ) )
{
bff = GetNextPart ( parts , i ) ;
total + = tff ;
}
else if ( string . Equals ( part , "progressive:" , StringComparison . OrdinalIgnoreCase ) )
{
progressive = GetNextPart ( parts , i ) ;
total + = progressive ;
}
else if ( string . Equals ( part , "undetermined:" , StringComparison . OrdinalIgnoreCase ) )
{
undetermined = GetNextPart ( parts , i ) ;
total + = undetermined ;
}
}
if ( total = = 0 )
{
return null ;
}
if ( ( undetermined / total ) > = . 3 )
{
return false ;
}
if ( ( ( tff + bff ) / total ) > = . 4 )
{
return true ;
}
return false ;
}
private int GetNextPart ( List < string > parts , int index )
{
var next = parts [ index + 1 ] ;
int value ;
if ( int . TryParse ( next , NumberStyles . Any , CultureInfo . InvariantCulture , out value ) )
{
return value ;
}
return 0 ;
}
/// <summary>
/// The us culture
/// </summary>