mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Calculate track sizes and pregaps in media info.
This commit is contained in:
@@ -138,8 +138,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
// Check subchannels support
|
||||
supportsPqSubchannel = SupportsPqSubchannel();
|
||||
supportsRwSubchannel = SupportsRwSubchannel();
|
||||
supportsPqSubchannel = SupportsPqSubchannel(_dev, _dumpLog, UpdateStatus);
|
||||
supportsRwSubchannel = SupportsRwSubchannel(_dev, _dumpLog, UpdateStatus);
|
||||
|
||||
switch(_subchannel)
|
||||
{
|
||||
@@ -207,8 +207,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
if(!_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
|
||||
supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
if(_force ||
|
||||
_subchannel == DumpSubchannel.None)
|
||||
if(_force || _subchannel == DumpSubchannel.None)
|
||||
{
|
||||
_dumpLog.WriteLine("Output format does not support subchannels, continuing...");
|
||||
UpdateStatus?.Invoke("Output format does not support subchannels, continuing...");
|
||||
@@ -339,13 +338,13 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
blockSize = sectorSize + subSize;
|
||||
|
||||
tracks = GetCdTracks(ref blockSize, dskType, out lastSector, leadOutStarts, mediaTags, out toc, trackFlags,
|
||||
subType);
|
||||
tracks = GetCdTracks(ref blockSize, _dev, dskType, _dumpLog, _force, out lastSector, leadOutStarts,
|
||||
mediaTags, StoppingErrorMessage, subType, out toc, trackFlags, UpdateStatus);
|
||||
|
||||
if(tracks is null)
|
||||
return;
|
||||
|
||||
SolveTrackPregaps(tracks, supportsPqSubchannel, supportsRwSubchannel);
|
||||
SolveTrackPregaps(_dev, _dumpLog, UpdateStatus, tracks, supportsPqSubchannel, supportsRwSubchannel);
|
||||
|
||||
for(int t = 1; t < tracks.Length; t++)
|
||||
tracks[t - 1].TrackEndSector = tracks[t].TrackStartSector - 1;
|
||||
@@ -872,7 +871,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
ReadCdData(audioExtents, blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog,
|
||||
ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed,
|
||||
out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16,
|
||||
readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration, tracks);
|
||||
readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration,
|
||||
tracks);
|
||||
|
||||
// TODO: Enable when underlying images support lead-outs
|
||||
/*
|
||||
|
||||
@@ -35,6 +35,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Devices;
|
||||
|
||||
// ReSharper disable JoinDeclarationAndInitializer
|
||||
@@ -118,7 +119,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
firstTrackPregapMs.Close();
|
||||
}
|
||||
|
||||
void SolveTrackPregaps(Track[] tracks, bool supportsPqSubchannel, bool supportsRwSubchannel)
|
||||
public static void SolveTrackPregaps(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus,
|
||||
Track[] tracks, bool supportsPqSubchannel, bool supportsRwSubchannel)
|
||||
{
|
||||
bool sense; // Sense indicator
|
||||
byte[] cmdBuf; // Data buffer
|
||||
@@ -136,14 +138,14 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
while(lba > tracks[i - 1].TrackStartSector)
|
||||
{
|
||||
if(supportsPqSubchannel)
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, lba, 16, 1, MmcSectorTypes.AllTypes, false, false, false,
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Q16,
|
||||
_dev.Timeout, out _);
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 16, 1, MmcSectorTypes.AllTypes, false, false, false,
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Q16,
|
||||
dev.Timeout, out _);
|
||||
else
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 96, 1, MmcSectorTypes.AllTypes, false, false, false,
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Raw,
|
||||
_dev.Timeout, out _);
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Raw,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -229,8 +231,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
_dumpLog.WriteLine($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors");
|
||||
UpdateStatus?.Invoke($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors");
|
||||
dumpLog?.WriteLine($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors");
|
||||
updateStatus?.Invoke($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors");
|
||||
#endif
|
||||
|
||||
tracks[i].TrackPregap = (ulong)trackPregap;
|
||||
|
||||
@@ -30,31 +30,8 @@
|
||||
// Copyright © 2011-2019 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Extents;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
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;
|
||||
using DiscImageChef.Devices;
|
||||
using Schemas;
|
||||
using CdOffset = DiscImageChef.Database.Models.CdOffset;
|
||||
using MediaType = DiscImageChef.CommonTypes.MediaType;
|
||||
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
|
||||
using Session = DiscImageChef.Decoders.CD.Session;
|
||||
using TrackType = DiscImageChef.CommonTypes.Enums.TrackType;
|
||||
|
||||
// ReSharper disable JoinDeclarationAndInitializer
|
||||
// ReSharper disable InlineOutVariableDeclaration
|
||||
@@ -64,24 +41,24 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
partial class Dump
|
||||
{
|
||||
bool SupportsRwSubchannel()
|
||||
public static bool SupportsRwSubchannel(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus)
|
||||
{
|
||||
_dumpLog.WriteLine("Checking if drive supports full raw subchannel reading...");
|
||||
UpdateStatus?.Invoke("Checking if drive supports full raw subchannel reading...");
|
||||
dumpLog?.WriteLine("Checking if drive supports full raw subchannel reading...");
|
||||
updateStatus?.Invoke("Checking if drive supports full raw subchannel reading...");
|
||||
|
||||
return!_dev.ReadCd(out _, out _, 0, 2352 + 96, 1, MmcSectorTypes.AllTypes, false, false, true,
|
||||
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw,
|
||||
_dev.Timeout, out _);
|
||||
return!dev.ReadCd(out _, out _, 0, 2352 + 96, 1, MmcSectorTypes.AllTypes, false, false, true,
|
||||
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout,
|
||||
out _);
|
||||
}
|
||||
|
||||
bool SupportsPqSubchannel()
|
||||
public static bool SupportsPqSubchannel(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus)
|
||||
{
|
||||
_dumpLog.WriteLine("Checking if drive supports PQ subchannel reading...");
|
||||
UpdateStatus?.Invoke("Checking if drive supports PQ subchannel reading...");
|
||||
dumpLog?.WriteLine("Checking if drive supports PQ subchannel reading...");
|
||||
updateStatus?.Invoke("Checking if drive supports PQ subchannel reading...");
|
||||
|
||||
return!_dev.ReadCd(out _, out _, 0, 2352 + 16, 1, MmcSectorTypes.AllTypes, false, false, true,
|
||||
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16,
|
||||
_dev.Timeout, out _);
|
||||
return!dev.ReadCd(out _, out _, 0, 2352 + 16, 1, MmcSectorTypes.AllTypes, false, false, true,
|
||||
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, dev.Timeout,
|
||||
out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,9 @@ using System.Linq;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
using DiscImageChef.Devices;
|
||||
|
||||
// ReSharper disable JoinDeclarationAndInitializer
|
||||
// ReSharper disable InlineOutVariableDeclaration
|
||||
@@ -48,17 +50,25 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
/// <summary>Reads the TOC, processes it, returns the track list and last sector</summary>
|
||||
/// <param name="blockSize">Size of the read sector in bytes</param>
|
||||
/// <param name="dev">Device</param>
|
||||
/// <param name="dskType">Disc type</param>
|
||||
/// <param name="dumpLog">Dump log</param>
|
||||
/// <param name="force">Force dump enabled</param>
|
||||
/// <param name="lastSector">Last sector number</param>
|
||||
/// <param name="leadOutStarts">Lead-out starts</param>
|
||||
/// <param name="mediaTags">Media tags</param>
|
||||
/// <param name="stoppingErrorMessage">Stopping error message handler</param>
|
||||
/// <param name="subType">Track subchannel type</param>
|
||||
/// <param name="toc">Full CD TOC</param>
|
||||
/// <param name="trackFlags">Track flags</param>
|
||||
/// <param name="subType">Track subchannel type</param>
|
||||
/// <param name="updateStatus">Update status handler</param>
|
||||
/// <returns>List of tracks</returns>
|
||||
Track[] GetCdTracks(ref uint blockSize, MediaType dskType, out long lastSector,
|
||||
Dictionary<int, long> leadOutStarts, Dictionary<MediaTagType, byte[]> mediaTags,
|
||||
out FullTOC.CDFullTOC? toc, Dictionary<byte, byte> trackFlags, TrackSubchannelType subType)
|
||||
public static Track[] GetCdTracks(ref uint blockSize, Device dev, MediaType dskType, DumpLog dumpLog,
|
||||
bool force, out long lastSector, Dictionary<int, long> leadOutStarts,
|
||||
Dictionary<MediaTagType, byte[]> mediaTags,
|
||||
ErrorMessageHandler stoppingErrorMessage, TrackSubchannelType subType,
|
||||
out FullTOC.CDFullTOC? toc, Dictionary<byte, byte> trackFlags,
|
||||
UpdateStatusHandler updateStatus)
|
||||
{
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
@@ -71,9 +81,9 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
// We discarded all discs that falsify a TOC before requesting a real TOC
|
||||
// No TOC, no CD (or an empty one)
|
||||
_dumpLog.WriteLine("Reading full TOC");
|
||||
UpdateStatus?.Invoke("Reading full TOC");
|
||||
sense = _dev.ReadRawToc(out cmdBuf, out _, 0, _dev.Timeout, out _);
|
||||
dumpLog?.WriteLine("Reading full TOC");
|
||||
updateStatus?.Invoke("Reading full TOC");
|
||||
sense = dev.ReadRawToc(out cmdBuf, out _, 0, dev.Timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -83,12 +93,12 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
tmpBuf = new byte[cmdBuf.Length - 2];
|
||||
Array.Copy(cmdBuf, 2, tmpBuf, 0, cmdBuf.Length - 2);
|
||||
mediaTags.Add(MediaTagType.CD_FullTOC, tmpBuf);
|
||||
mediaTags?.Add(MediaTagType.CD_FullTOC, tmpBuf);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateStatus?.Invoke("Building track map...");
|
||||
_dumpLog.WriteLine("Building track map...");
|
||||
updateStatus?.Invoke("Building track map...");
|
||||
dumpLog?.WriteLine("Building track map...");
|
||||
|
||||
if(toc.HasValue)
|
||||
{
|
||||
@@ -113,7 +123,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
TrackSubchannelType = subType
|
||||
});
|
||||
|
||||
trackFlags.Add(trk.POINT, trk.CONTROL);
|
||||
trackFlags?.Add(trk.POINT, trk.CONTROL);
|
||||
}
|
||||
else if(trk.POINT == 0xA2)
|
||||
{
|
||||
@@ -154,7 +164,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
lastSector = ((phour * 3600 * 75) + (pmin * 60 * 75) + (psec * 75) + pframe) - 150;
|
||||
leadOutStarts.Add(trk.SessionNumber, lastSector + 1);
|
||||
leadOutStarts?.Add(trk.SessionNumber, lastSector + 1);
|
||||
}
|
||||
else if(trk.POINT == 0xA0 &&
|
||||
trk.ADR == 1)
|
||||
@@ -181,18 +191,18 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus?.Invoke("Cannot read RAW TOC, requesting processed one...");
|
||||
_dumpLog.WriteLine("Cannot read RAW TOC, requesting processed one...");
|
||||
sense = _dev.ReadToc(out cmdBuf, out _, false, 0, _dev.Timeout, out _);
|
||||
updateStatus?.Invoke("Cannot read RAW TOC, requesting processed one...");
|
||||
dumpLog?.WriteLine("Cannot read RAW TOC, requesting processed one...");
|
||||
sense = dev.ReadToc(out cmdBuf, out _, false, 0, dev.Timeout, out _);
|
||||
|
||||
TOC.CDTOC? oldToc = TOC.Decode(cmdBuf);
|
||||
|
||||
if((sense || !oldToc.HasValue) &&
|
||||
!_force)
|
||||
!force)
|
||||
{
|
||||
_dumpLog.WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
|
||||
dumpLog?.WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
|
||||
|
||||
StoppingErrorMessage?.
|
||||
stoppingErrorMessage?.
|
||||
Invoke("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
|
||||
|
||||
return null;
|
||||
@@ -214,7 +224,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
TrackRawBytesPerSector = (int)sectorSize, TrackSubchannelType = subType
|
||||
});
|
||||
|
||||
trackFlags.Add(trk.TrackNumber, trk.CONTROL);
|
||||
trackFlags?.Add(trk.TrackNumber, trk.CONTROL);
|
||||
}
|
||||
else if(trk.TrackNumber == 0xAA)
|
||||
{
|
||||
@@ -229,8 +239,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
if(trackList.Count == 0)
|
||||
{
|
||||
UpdateStatus?.Invoke("No tracks found, adding a single track from 0 to Lead-Out");
|
||||
_dumpLog.WriteLine("No tracks found, adding a single track from 0 to Lead-Out");
|
||||
updateStatus?.Invoke("No tracks found, adding a single track from 0 to Lead-Out");
|
||||
dumpLog?.WriteLine("No tracks found, adding a single track from 0 to Lead-Out");
|
||||
|
||||
trackList.Add(new Track
|
||||
{
|
||||
@@ -240,12 +250,12 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
TrackSubchannelType = subType
|
||||
});
|
||||
|
||||
trackFlags.Add(1, (byte)(leadoutTrackType == TrackType.Audio ? 0 : 4));
|
||||
trackFlags?.Add(1, (byte)(leadoutTrackType == TrackType.Audio ? 0 : 4));
|
||||
}
|
||||
|
||||
if(lastSector == 0)
|
||||
{
|
||||
sense = _dev.ReadCapacity16(out cmdBuf, out _, _dev.Timeout, out _);
|
||||
sense = dev.ReadCapacity16(out cmdBuf, out _, dev.Timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -258,7 +268,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
sense = _dev.ReadCapacity(out cmdBuf, out _, _dev.Timeout, out _);
|
||||
sense = dev.ReadCapacity(out cmdBuf, out _, dev.Timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -269,21 +279,21 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
if(lastSector <= 0)
|
||||
{
|
||||
if(!_force)
|
||||
if(!force)
|
||||
{
|
||||
StoppingErrorMessage?.
|
||||
stoppingErrorMessage?.
|
||||
Invoke("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");
|
||||
|
||||
_dumpLog.
|
||||
dumpLog?.
|
||||
WriteLine("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
UpdateStatus?.
|
||||
updateStatus?.
|
||||
Invoke("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
|
||||
|
||||
_dumpLog.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
|
||||
dumpLog?.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
|
||||
lastSector = 360000;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user