Merge pull request #9126 from Bond-009/interlaced
Revert 'Fix interlace check for H.264 MBAFF coded MP4 files' (#6222)
This commit is contained in:
commit
491f1f88c7
|
@ -625,17 +625,6 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
return attachment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a stream code time base is double the frame rate.
|
||||
/// </summary>
|
||||
/// <param name="averageFrameRate">average frame rate.</param>
|
||||
/// <param name="codecTimeBase">codec time base string.</param>
|
||||
/// <returns>true if the codec time base is double the frame rate.</returns>
|
||||
internal static bool IsCodecTimeBaseDoubleTheFrameRate(float? averageFrameRate, string codecTimeBase)
|
||||
{
|
||||
return MathF.Abs(((averageFrameRate ?? 0) * (GetFrameRate(codecTimeBase) ?? 0)) - 0.5f) <= float.Epsilon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts ffprobe stream info to our MediaStream class.
|
||||
/// </summary>
|
||||
|
@ -748,22 +737,9 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate);
|
||||
stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate);
|
||||
|
||||
bool videoInterlaced = !string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
|
||||
stream.IsInterlaced = !string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
|
||||
&& !string.Equals(streamInfo.FieldOrder, "progressive", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// Some interlaced H.264 files in mp4 containers using MBAFF coding aren't flagged as being interlaced by FFprobe,
|
||||
// so for H.264 files we also calculate the frame rate from the codec time base and check if it is double the reported
|
||||
// frame rate to determine if the file is interlaced
|
||||
|
||||
bool h264MbaffCoded = string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase)
|
||||
&& string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
|
||||
&& IsCodecTimeBaseDoubleTheFrameRate(stream.AverageFrameRate, stream.CodecTimeBase);
|
||||
|
||||
if (videoInterlaced || h264MbaffCoded)
|
||||
{
|
||||
stream.IsInterlaced = true;
|
||||
}
|
||||
|
||||
if (isAudio
|
||||
|| string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(stream.Codec, "gif", StringComparison.OrdinalIgnoreCase)
|
||||
|
|
|
@ -31,16 +31,6 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
|
|||
public void GetFrameRate_Success(string value, float? expected)
|
||||
=> Assert.Equal(expected, ProbeResultNormalizer.GetFrameRate(value));
|
||||
|
||||
[Theory]
|
||||
[InlineData(0.5f, "0/1", false)]
|
||||
[InlineData(24.5f, "8/196", false)]
|
||||
[InlineData(63.5f, "1/127", true)]
|
||||
[InlineData(null, "1/60", false)]
|
||||
[InlineData(30f, "2/120", true)]
|
||||
[InlineData(59.999996f, "1563/187560", true)]
|
||||
public void IsCodecTimeBaseDoubleTheFrameRate_Success(float? frameRate, string codecTimeBase, bool expected)
|
||||
=> Assert.Equal(expected, ProbeResultNormalizer.IsCodecTimeBaseDoubleTheFrameRate(frameRate, codecTimeBase));
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_MetaData_Success()
|
||||
{
|
||||
|
@ -158,6 +148,99 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
|
|||
Assert.False(res.MediaStreams[5].IsHearingImpaired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_ProgressiveVideoNoFieldOrder_Success()
|
||||
{
|
||||
var bytes = File.ReadAllBytes("Test Data/Probing/video_progressive_no_field_order.json");
|
||||
|
||||
var internalMediaInfoResult = JsonSerializer.Deserialize<InternalMediaInfoResult>(bytes, _jsonOptions);
|
||||
MediaInfo res = _probeResultNormalizer.GetMediaInfo(internalMediaInfoResult, VideoType.VideoFile, false, "Test Data/Probing/video_progressive_no_field_order.mp4", MediaProtocol.File);
|
||||
|
||||
Assert.Equal(2, res.MediaStreams.Count);
|
||||
|
||||
Assert.NotNull(res.VideoStream);
|
||||
Assert.Equal(res.MediaStreams[0], res.VideoStream);
|
||||
Assert.Equal(0, res.VideoStream.Index);
|
||||
Assert.Equal("h264", res.VideoStream.Codec);
|
||||
Assert.Equal("Main", res.VideoStream.Profile);
|
||||
Assert.Equal(MediaStreamType.Video, res.VideoStream.Type);
|
||||
Assert.Equal(1080, res.VideoStream.Height);
|
||||
Assert.Equal(1920, res.VideoStream.Width);
|
||||
Assert.False(res.VideoStream.IsInterlaced);
|
||||
Assert.Equal("16:9", res.VideoStream.AspectRatio);
|
||||
Assert.Equal("yuv420p", res.VideoStream.PixelFormat);
|
||||
Assert.Equal(41d, res.VideoStream.Level);
|
||||
Assert.Equal(1, res.VideoStream.RefFrames);
|
||||
Assert.True(res.VideoStream.IsAVC);
|
||||
Assert.Equal(23.9760246f, res.VideoStream.RealFrameRate);
|
||||
Assert.Equal("1/24000", res.VideoStream.TimeBase);
|
||||
Assert.Equal(3948341, res.VideoStream.BitRate);
|
||||
Assert.Equal(8, res.VideoStream.BitDepth);
|
||||
Assert.True(res.VideoStream.IsDefault);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_ProgressiveVideoNoFieldOrder2_Success()
|
||||
{
|
||||
var bytes = File.ReadAllBytes("Test Data/Probing/video_progressive_no_field_order2.json");
|
||||
|
||||
var internalMediaInfoResult = JsonSerializer.Deserialize<InternalMediaInfoResult>(bytes, _jsonOptions);
|
||||
MediaInfo res = _probeResultNormalizer.GetMediaInfo(internalMediaInfoResult, VideoType.VideoFile, false, "Test Data/Probing/video_progressive_no_field_order2.mp4", MediaProtocol.File);
|
||||
|
||||
Assert.Single(res.MediaStreams);
|
||||
|
||||
Assert.NotNull(res.VideoStream);
|
||||
Assert.Equal(res.MediaStreams[0], res.VideoStream);
|
||||
Assert.Equal(0, res.VideoStream.Index);
|
||||
Assert.Equal("h264", res.VideoStream.Codec);
|
||||
Assert.Equal("High", res.VideoStream.Profile);
|
||||
Assert.Equal(MediaStreamType.Video, res.VideoStream.Type);
|
||||
Assert.Equal(720, res.VideoStream.Height);
|
||||
Assert.Equal(1280, res.VideoStream.Width);
|
||||
Assert.False(res.VideoStream.IsInterlaced);
|
||||
Assert.Equal("16:9", res.VideoStream.AspectRatio);
|
||||
Assert.Equal("yuv420p", res.VideoStream.PixelFormat);
|
||||
Assert.Equal(31d, res.VideoStream.Level);
|
||||
Assert.Equal(1, res.VideoStream.RefFrames);
|
||||
Assert.True(res.VideoStream.IsAVC);
|
||||
Assert.Equal(25f, res.VideoStream.RealFrameRate);
|
||||
Assert.Equal("1/12800", res.VideoStream.TimeBase);
|
||||
Assert.Equal(53288, res.VideoStream.BitRate);
|
||||
Assert.Equal(8, res.VideoStream.BitDepth);
|
||||
Assert.True(res.VideoStream.IsDefault);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_InterlacedVideo_Success()
|
||||
{
|
||||
var bytes = File.ReadAllBytes("Test Data/Probing/video_interlaced.json");
|
||||
|
||||
var internalMediaInfoResult = JsonSerializer.Deserialize<InternalMediaInfoResult>(bytes, _jsonOptions);
|
||||
MediaInfo res = _probeResultNormalizer.GetMediaInfo(internalMediaInfoResult, VideoType.VideoFile, false, "Test Data/Probing/video_interlaced.mp4", MediaProtocol.File);
|
||||
|
||||
Assert.Single(res.MediaStreams);
|
||||
|
||||
Assert.NotNull(res.VideoStream);
|
||||
Assert.Equal(res.MediaStreams[0], res.VideoStream);
|
||||
Assert.Equal(0, res.VideoStream.Index);
|
||||
Assert.Equal("h264", res.VideoStream.Codec);
|
||||
Assert.Equal("High", res.VideoStream.Profile);
|
||||
Assert.Equal(MediaStreamType.Video, res.VideoStream.Type);
|
||||
Assert.Equal(720, res.VideoStream.Height);
|
||||
Assert.Equal(1280, res.VideoStream.Width);
|
||||
Assert.True(res.VideoStream.IsInterlaced);
|
||||
Assert.Equal("16:9", res.VideoStream.AspectRatio);
|
||||
Assert.Equal("yuv420p", res.VideoStream.PixelFormat);
|
||||
Assert.Equal(40d, res.VideoStream.Level);
|
||||
Assert.Equal(1, res.VideoStream.RefFrames);
|
||||
Assert.True(res.VideoStream.IsAVC);
|
||||
Assert.Equal(25f, res.VideoStream.RealFrameRate);
|
||||
Assert.Equal("1/12800", res.VideoStream.TimeBase);
|
||||
Assert.Equal(56945, res.VideoStream.BitRate);
|
||||
Assert.Equal(8, res.VideoStream.BitDepth);
|
||||
Assert.True(res.VideoStream.IsDefault);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_MusicVideo_Success()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"streams": [
|
||||
{
|
||||
"index": 0,
|
||||
"codec_name": "h264",
|
||||
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
|
||||
"profile": "High",
|
||||
"codec_type": "video",
|
||||
"codec_tag_string": "avc1",
|
||||
"codec_tag": "0x31637661",
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"coded_width": 1280,
|
||||
"coded_height": 720,
|
||||
"closed_captions": 0,
|
||||
"film_grain": 0,
|
||||
"has_b_frames": 2,
|
||||
"pix_fmt": "yuv420p",
|
||||
"level": 40,
|
||||
"chroma_location": "left",
|
||||
"field_order": "tt",
|
||||
"refs": 1,
|
||||
"is_avc": "true",
|
||||
"nal_length_size": "4",
|
||||
"id": "0x1",
|
||||
"r_frame_rate": "25/1",
|
||||
"avg_frame_rate": "25/1",
|
||||
"time_base": "1/12800",
|
||||
"start_pts": 0,
|
||||
"start_time": "0.000000",
|
||||
"duration_ts": 3840000,
|
||||
"duration": "300.000000",
|
||||
"bit_rate": "56945",
|
||||
"bits_per_raw_sample": "8",
|
||||
"nb_frames": "7500",
|
||||
"extradata_size": 42,
|
||||
"disposition": {
|
||||
"default": 1,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0,
|
||||
"captions": 0,
|
||||
"descriptions": 0,
|
||||
"metadata": 0,
|
||||
"dependent": 0,
|
||||
"still_image": 0
|
||||
},
|
||||
"tags": {
|
||||
"language": "und",
|
||||
"handler_name": "VideoHandler",
|
||||
"vendor_id": "[0][0][0][0]"
|
||||
}
|
||||
}
|
||||
],
|
||||
"format": {
|
||||
"filename": "test-gray.720i.mp4",
|
||||
"nb_streams": 1,
|
||||
"nb_programs": 0,
|
||||
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
|
||||
"format_long_name": "QuickTime / MOV",
|
||||
"start_time": "0.000000",
|
||||
"duration": "300.000000",
|
||||
"size": "2223957",
|
||||
"bit_rate": "59305",
|
||||
"probe_score": 100,
|
||||
"tags": {
|
||||
"major_brand": "isom",
|
||||
"minor_version": "512",
|
||||
"compatible_brands": "isomiso2avc1mp41",
|
||||
"encoder": "Lavf58.20.100"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"streams": [
|
||||
{
|
||||
"index": 0,
|
||||
"codec_name": "h264",
|
||||
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
|
||||
"profile": "Main",
|
||||
"codec_type": "video",
|
||||
"codec_time_base": "1001/48000",
|
||||
"codec_tag_string": "avc1",
|
||||
"codec_tag": "0x31637661",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"coded_width": 1920,
|
||||
"coded_height": 1088,
|
||||
"closed_captions": 0,
|
||||
"has_b_frames": 1,
|
||||
"sample_aspect_ratio": "1:1",
|
||||
"display_aspect_ratio": "16:9",
|
||||
"pix_fmt": "yuv420p",
|
||||
"level": 41,
|
||||
"chroma_location": "left",
|
||||
"refs": 1,
|
||||
"is_avc": "true",
|
||||
"nal_length_size": "4",
|
||||
"r_frame_rate": "24000/1001",
|
||||
"avg_frame_rate": "24000/1001",
|
||||
"time_base": "1/24000",
|
||||
"start_pts": 1000,
|
||||
"start_time": "0.041667",
|
||||
"duration_ts": 29095066,
|
||||
"duration": "1212.294417",
|
||||
"bit_rate": "3948341",
|
||||
"bits_per_raw_sample": "8",
|
||||
"nb_frames": "29066",
|
||||
"disposition": {
|
||||
"default": 1,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0
|
||||
},
|
||||
"tags": {
|
||||
"creation_time": "2020-01-20T13:56:34.000000Z",
|
||||
"language": "eng",
|
||||
"handler_name": "\fVideoHandler",
|
||||
"encoder": "h264"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"codec_name": "ac3",
|
||||
"codec_long_name": "ATSC A/52A (AC-3)",
|
||||
"codec_type": "audio",
|
||||
"codec_time_base": "1/48000",
|
||||
"codec_tag_string": "ac-3",
|
||||
"codec_tag": "0x332d6361",
|
||||
"sample_fmt": "fltp",
|
||||
"sample_rate": "48000",
|
||||
"channels": 2,
|
||||
"channel_layout": "stereo",
|
||||
"bits_per_sample": 0,
|
||||
"dmix_mode": "-1",
|
||||
"ltrt_cmixlev": "-1.000000",
|
||||
"ltrt_surmixlev": "-1.000000",
|
||||
"loro_cmixlev": "-1.000000",
|
||||
"loro_surmixlev": "-1.000000",
|
||||
"r_frame_rate": "0/0",
|
||||
"avg_frame_rate": "0/0",
|
||||
"time_base": "1/48000",
|
||||
"start_pts": 0,
|
||||
"start_time": "0.000000",
|
||||
"duration_ts": 58232832,
|
||||
"duration": "1213.184000",
|
||||
"bit_rate": "224000",
|
||||
"nb_frames": "37912",
|
||||
"disposition": {
|
||||
"default": 1,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0
|
||||
},
|
||||
"tags": {
|
||||
"creation_time": "2020-01-20T13:56:34.000000Z",
|
||||
"language": "eng",
|
||||
"handler_name": "\fSoundHandler"
|
||||
},
|
||||
"side_data_list": [
|
||||
{
|
||||
"side_data_type": "Audio Service Type"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"format": {
|
||||
"filename": "The Big Bang Theory - S01E17.mp4",
|
||||
"nb_streams": 2,
|
||||
"nb_programs": 0,
|
||||
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
|
||||
"format_long_name": "QuickTime / MOV",
|
||||
"start_time": "0.000000",
|
||||
"duration": "1213.184000",
|
||||
"size": "633084606",
|
||||
"bit_rate": "4174698",
|
||||
"probe_score": 100,
|
||||
"tags": {
|
||||
"major_brand": "mp42",
|
||||
"minor_version": "512",
|
||||
"compatible_brands": "mp42",
|
||||
"creation_time": "2020-01-20T13:56:34.000000Z",
|
||||
"media_type": "9",
|
||||
"season_number": "0",
|
||||
"episode_sort": "0",
|
||||
"hd_video": "0",
|
||||
"iTunMOVI": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"><plist version=\"1.0\"><dict><key>studio</key><string>studio</string><key>cast</key><array><dict><key>name</key><string></string></dict></array><key>directors</key><array><dict><key>name</key><string></string></dict></array><key>producers</key><array><dict><key>name</key><string></string></dict></array><key>codirectors</key><array><dict><key>name</key><string>codirector</string></dict></array><key>screenwriters</key><array><dict><key>name</key><string></string></dict></array></dict></plist>"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"streams": [
|
||||
{
|
||||
"index": 0,
|
||||
"codec_name": "h264",
|
||||
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
|
||||
"profile": "High",
|
||||
"codec_type": "video",
|
||||
"codec_time_base": "1/50",
|
||||
"codec_tag_string": "avc1",
|
||||
"codec_tag": "0x31637661",
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"coded_width": 1280,
|
||||
"coded_height": 720,
|
||||
"closed_captions": 0,
|
||||
"has_b_frames": 2,
|
||||
"pix_fmt": "yuv420p",
|
||||
"level": 31,
|
||||
"chroma_location": "left",
|
||||
"refs": 1,
|
||||
"is_avc": "true",
|
||||
"nal_length_size": "4",
|
||||
"r_frame_rate": "25/1",
|
||||
"avg_frame_rate": "25/1",
|
||||
"time_base": "1/12800",
|
||||
"start_pts": 0,
|
||||
"start_time": "0.000000",
|
||||
"duration_ts": 3840000,
|
||||
"duration": "300.000000",
|
||||
"bit_rate": "53288",
|
||||
"bits_per_raw_sample": "8",
|
||||
"nb_frames": "7500",
|
||||
"disposition": {
|
||||
"default": 1,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0
|
||||
},
|
||||
"tags": {
|
||||
"language": "und",
|
||||
"handler_name": "VideoHandler"
|
||||
}
|
||||
}
|
||||
],
|
||||
"format": {
|
||||
"filename": "test-gray.720p.mp4",
|
||||
"nb_streams": 1,
|
||||
"nb_programs": 0,
|
||||
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
|
||||
"format_long_name": "QuickTime / MOV",
|
||||
"start_time": "0.000000",
|
||||
"duration": "300.000000",
|
||||
"size": "2086818",
|
||||
"bit_rate": "55648",
|
||||
"probe_score": 100,
|
||||
"tags": {
|
||||
"major_brand": "isom",
|
||||
"minor_version": "512",
|
||||
"compatible_brands": "isomiso2avc1mp41",
|
||||
"encoder": "Lavf58.20.100"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user