Add support to decode VideoNow XP discs.

This commit is contained in:
2019-03-13 20:58:28 +00:00
parent 0a68e05f55
commit db75c6a8c7
4 changed files with 234 additions and 3 deletions

View File

@@ -26,6 +26,7 @@
<e p="Localization.sv.resx" t="Include" /> <e p="Localization.sv.resx" t="Include" />
</e> </e>
<e p="Swapping.cs" t="Include" /> <e p="Swapping.cs" t="Include" />
<e p="Xp.cs" t="Include" />
<e p="bin" t="ExcludeRecursive" /> <e p="bin" t="ExcludeRecursive" />
<e p="obj" t="ExcludeRecursive" /> <e p="obj" t="ExcludeRecursive" />
</e> </e>

View File

@@ -197,7 +197,7 @@ namespace DiscImageChef.VideoNow
: Localization.FirstFrameIsNotAtSectorBoundary); : Localization.FirstFrameIsNotAtSectorBoundary);
if(xp) if(xp)
Console.WriteLine("VideoNow XP discs are not yet supported"); Xp.Decode(args[0], fs, swapped, framePosition);
else else
Color.Decode(args[0], fs, swapped, framePosition); Color.Decode(args[0], fs, swapped, framePosition);

View File

@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.0")] [assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyFileVersion("2.0.0.0")]

View File

@@ -1,3 +1,9 @@
using System;
using System.IO;
using System.Linq;
using SharpAvi;
using SharpAvi.Output;
namespace DiscImageChef.VideoNow namespace DiscImageChef.VideoNow
{ {
public static class Xp public static class Xp
@@ -145,5 +151,229 @@ namespace DiscImageChef.VideoNow
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0xFF 0x00, 0xFF
}; };
public static void Decode(string filename, Stream fs, bool swapped, long framePosition)
{
char progress = ' ';
var aviWriter = new AviWriter(filename + ".avi")
{
EmitIndex1 = true, FramesPerSecond = 18
};
IAviVideoStream videoStream = aviWriter.AddVideoStream(144, 80, BitsPerPixel.Bpp24);
videoStream.Codec = KnownFourCCs.Codecs.Uncompressed;
IAviAudioStream audioStream = aviWriter.AddAudioStream(2, 17784, 8);
fs.Position = framePosition;
byte[] frameBuffer = new byte[19760];
fs.Read(frameBuffer, 0, frameBuffer.Length);
int audioStart = swapped ? 9 : 8;
byte[] frameMarkerToUse = swapped ? SwappedFrameMarker : FrameMarker;
byte[] frameMaskToUse = swapped ? SwappedFrameMask : FrameMask;
if(swapped)
frameBuffer = Swapping.SwapBuffer(frameBuffer);
var outFs = new MemoryStream();
for(int i = 9; i <= frameBuffer.Length; i += 10)
{
switch(i / 10 % 4)
{
case 0:
progress = '-';
break;
case 1:
progress = '\\';
break;
case 2:
progress = '|';
break;
case 3:
progress = '/';
break;
}
Console.Write($"\r{Localization.ExtractingAudio}", progress);
outFs.WriteByte(frameBuffer[i]);
}
byte[] videoFrame = Color.DecodeFrame(frameBuffer);
videoStream.WriteFrame(true, videoFrame, 0, videoFrame.Length);
audioStream.WriteBlock(outFs.ToArray(), 0, (int)outFs.Length);
int totalFrames = 1;
framePosition += 19760;
byte[] buffer = new byte[frameMarkerToUse.Length];
while(framePosition + 19760 < fs.Length)
{
switch(totalFrames % 4)
{
case 0:
progress = '-';
break;
case 1:
progress = '\\';
break;
case 2:
progress = '|';
break;
case 3:
progress = '/';
break;
}
Console.Write($"\r{Localization.LookingForMoreFrames}", progress);
for(int i = 0; i < buffer.Length; i++)
buffer[i] &= frameMaskToUse[i];
if(!buffer.SequenceEqual(frameMarkerToUse))
{
Console.Write("\r \r");
Console.WriteLine(Localization.FrameAndNextAreNotAligned, totalFrames);
long expectedFramePosition = framePosition;
while(framePosition < fs.Length)
{
fs.Position = framePosition;
fs.Read(buffer, 0, buffer.Length);
for(int i = 0; i < buffer.Length; i++)
buffer[i] &= frameMaskToUse[i];
if(buffer.SequenceEqual(frameMarkerToUse))
{
Console.Write("\r \r");
fs.Position = framePosition;
frameBuffer = new byte[19760];
fs.Read(frameBuffer, 0, frameBuffer.Length);
if(swapped)
frameBuffer = Swapping.SwapBuffer(frameBuffer);
outFs = new MemoryStream();
for(int i = 9; i <= frameBuffer.Length; i += 10)
{
switch(i / 10 % 4)
{
case 0:
progress = '-';
break;
case 1:
progress = '\\';
break;
case 2:
progress = '|';
break;
case 3:
progress = '/';
break;
}
Console.Write($"\r{Localization.ExtractingAudio}", progress);
outFs.WriteByte(frameBuffer[i]);
}
videoFrame = Color.DecodeFrame(frameBuffer);
videoStream.WriteFrame(true, videoFrame, 0, videoFrame.Length);
audioStream.WriteBlock(outFs.ToArray(), 0, (int)outFs.Length);
totalFrames++;
Console.Write("\r \r");
Console.WriteLine(Localization.FrameFoundAtPosition, framePosition, totalFrames,
framePosition - expectedFramePosition);
Console.
WriteLine(framePosition % 2352 == 0 ? Localization.FrameIsAtSectorBoundary : Localization.FrameIsNotAtSectorBoundary,
totalFrames);
framePosition += 19760;
break;
}
framePosition++;
}
continue;
}
if(framePosition % 2352 == 0)
{
Console.Write("\r \r");
Console.WriteLine(Localization.FrameIsAtSectorBoundary, totalFrames);
}
Console.Write("\r \r");
fs.Position = framePosition;
frameBuffer = new byte[19760];
fs.Read(frameBuffer, 0, frameBuffer.Length);
if(swapped)
frameBuffer = Swapping.SwapBuffer(frameBuffer);
outFs = new MemoryStream();
for(int i = 9; i <= frameBuffer.Length; i += 10)
{
switch(i / 10 % 4)
{
case 0:
progress = '-';
break;
case 1:
progress = '\\';
break;
case 2:
progress = '|';
break;
case 3:
progress = '/';
break;
}
Console.Write($"\r{Localization.ExtractingAudio}", progress);
outFs.WriteByte(frameBuffer[i]);
}
videoFrame = Color.DecodeFrame(frameBuffer);
videoStream.WriteFrame(true, videoFrame, 0, videoFrame.Length);
audioStream.WriteBlock(outFs.ToArray(), 0, (int)outFs.Length);
totalFrames++;
fs.Position = framePosition;
fs.Read(buffer, 0, buffer.Length);
framePosition += 19760;
}
Console.Write("\r \r");
Console.WriteLine(Localization.FramesFound, totalFrames);
outFs.Close();
aviWriter.Close();
}
} }
} }