mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add VideoNow Color detection.
This commit is contained in:
@@ -44,6 +44,7 @@ using DiscImageChef.CommonTypes.Metadata;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Core.Media.Detection;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Decoders.SCSI.MMC;
|
||||
@@ -239,6 +240,34 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add other detectors here
|
||||
dumpLog.WriteLine("Detecting disc type...");
|
||||
DicConsole.WriteLine("Detecting disc type...");
|
||||
byte[] videoNowColorFrame = new byte[9 * 2352];
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, 2352, 1, MmcSectorTypes.AllTypes, false, false,
|
||||
true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(sense || dev.Error)
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, 2352, 1, MmcSectorTypes.Cdda, false, false,
|
||||
true, MmcHeaderCodes.None, true, true, MmcErrorField.None, MmcSubchannel.None,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(sense || !dev.Error)
|
||||
{
|
||||
videoNowColorFrame = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Array.Copy(cmdBuf, 0, videoNowColorFrame, i * 2352, 2352);
|
||||
}
|
||||
|
||||
if(MMC.IsVideoNowColor(videoNowColorFrame)) dskType = MediaType.VideoNowColor;
|
||||
|
||||
MmcSubchannel supportedSubchannel = MmcSubchannel.Raw;
|
||||
dumpLog.WriteLine("Checking if drive supports full raw subchannel reading...");
|
||||
DicConsole.WriteLine("Checking if drive supports full raw subchannel reading...");
|
||||
|
||||
@@ -37,6 +37,37 @@ namespace DiscImageChef.Core.Media.Detection
|
||||
{
|
||||
public static class MMC
|
||||
{
|
||||
/// <summary>
|
||||
/// This is some kind of header. Every 10 bytes there's an audio byte.
|
||||
/// </summary>
|
||||
static readonly byte[] VideoNowColorFrameMarker =
|
||||
{
|
||||
0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81,
|
||||
0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7,
|
||||
0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81,
|
||||
0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3,
|
||||
0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7,
|
||||
0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3,
|
||||
0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7,
|
||||
0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81,
|
||||
0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3,
|
||||
0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00,
|
||||
0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81,
|
||||
0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7,
|
||||
0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81,
|
||||
0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3, 0xC7, 0x00, 0x81, 0xE3, 0xE3, 0xC7, 0xC7, 0x81, 0x81, 0xE3,
|
||||
0xC7, 0x00, 0x00, 0x00, 0x02, 0x01, 0x04, 0x02, 0x06, 0x03, 0xFF, 0x00, 0x08, 0x04, 0x0A, 0x05, 0x0C,
|
||||
0x06, 0x0E, 0x07, 0xFF, 0x00, 0x11, 0x08, 0x13, 0x09, 0x15, 0x0A, 0x17, 0x0B, 0xFF, 0x00, 0x19, 0x0C,
|
||||
0x1B, 0x0D, 0x1D, 0x0E, 0x1F, 0x0F, 0xFF, 0x00, 0x00, 0x28, 0x02, 0x29, 0x04, 0x2A, 0x06, 0x2B, 0xFF,
|
||||
0x00, 0x08, 0x2C, 0x0A, 0x2D, 0x0C, 0x2E, 0x0E, 0x2F, 0xFF, 0x00, 0x11, 0x30, 0x13, 0x31, 0x15, 0x32,
|
||||
0x17, 0x33, 0xFF, 0x00, 0x19, 0x34, 0x1B, 0x35, 0x1D, 0x36, 0x1F, 0x37, 0xFF, 0x00, 0x00, 0x38, 0x02,
|
||||
0x39, 0x04, 0x3A, 0x06, 0x3B, 0xFF, 0x00, 0x08, 0x3C, 0x0A, 0x3D, 0x0C, 0x3E, 0x0E, 0x3F, 0xFF, 0x00,
|
||||
0x11, 0x40, 0x13, 0x41, 0x15, 0x42, 0x17, 0x43, 0xFF, 0x00, 0x19, 0x44, 0x1B, 0x45, 0x1D, 0x46, 0x1F,
|
||||
0x47, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the media corresponds to CD-i.
|
||||
/// </summary>
|
||||
@@ -61,5 +92,24 @@ namespace DiscImageChef.Core.Media.Detection
|
||||
Array.Copy(sector16, 24, testMark, 0, 4);
|
||||
return cdiMark.SequenceEqual(testMark);
|
||||
}
|
||||
|
||||
public static bool IsVideoNowColor(byte[] videoFrame)
|
||||
{
|
||||
if(videoFrame is null || videoFrame.Length < VideoNowColorFrameMarker.Length) return false;
|
||||
|
||||
byte[] buffer = new byte[VideoNowColorFrameMarker.Length];
|
||||
for(int framePosition = 0; framePosition + buffer.Length < videoFrame.Length; framePosition++)
|
||||
{
|
||||
Array.Copy(videoFrame, framePosition, buffer, 0, buffer.Length);
|
||||
|
||||
for(int ab = 9; ab < buffer.Length; ab += 10) buffer[ab] = 0;
|
||||
|
||||
if(!VideoNowColorFrameMarker.SequenceEqual(buffer)) continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1253,6 +1253,7 @@ namespace DiscImageChef.Core.Media.Info
|
||||
byte[] secondDataSectorNotZero = null;
|
||||
byte[] firstTrackSecondSession = null;
|
||||
byte[] firstTrackSecondSessionAudio = null;
|
||||
byte[] videoNowColorFrame = null;
|
||||
|
||||
if(secondSessionFirstTrack != 0 && DecodedToc.HasValue &&
|
||||
DecodedToc.Value.TrackDescriptors.Any(t => t.TrackNumber == secondSessionFirstTrack))
|
||||
@@ -1291,6 +1292,29 @@ namespace DiscImageChef.Core.Media.Info
|
||||
}
|
||||
}
|
||||
|
||||
videoNowColorFrame = new byte[9 * 2352];
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, 2352, 1, MmcSectorTypes.AllTypes, false, false,
|
||||
true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(sense || dev.Error)
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, 2352, 1, MmcSectorTypes.Cdda, false, false,
|
||||
true, MmcHeaderCodes.None, true, true, MmcErrorField.None, MmcSubchannel.None,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(sense || !dev.Error)
|
||||
{
|
||||
videoNowColorFrame = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Array.Copy(cmdBuf, 0, videoNowColorFrame, i * 2352, 2352);
|
||||
}
|
||||
|
||||
// Check for hidden data before start of track 1
|
||||
if(DecodedToc.HasValue &&
|
||||
DecodedToc.Value.TrackDescriptors.FirstOrDefault(t => t.TrackNumber == 1).TrackStartAddress > 0)
|
||||
@@ -1728,6 +1752,10 @@ namespace DiscImageChef.Core.Media.Info
|
||||
if(Dreamcast.DecodeIPBin(milcd).HasValue) MediaType = MediaType.MilCD;
|
||||
}
|
||||
|
||||
// TODO: Detect black and white VideoNow
|
||||
// TODO: Detect VideoNow XP
|
||||
if(MMC.IsVideoNowColor(videoNowColorFrame)) MediaType = MediaType.VideoNowColor;
|
||||
|
||||
break;
|
||||
}
|
||||
// TODO: Check for CD-i Ready
|
||||
|
||||
Reference in New Issue
Block a user