(*************************************************************************
  vStrip: Unit for vStrip-DLL Interface
  Copyright (C) 2001 [maven] (maven@maven.de)

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*************************************************************************)

unit vStrip;

interface

uses
  SysUtils, Windows, ComCtrls;

const
  vs_DllName = 'vStrip.dll';
  inb_MAX_OUTPUT = 8;
  fio_BUFFER_SIZE = 65536;
  fio_SECTOR_SIZE = 2048;
  DVD_TIME_AND = $3f;

  vso_APPEND = 1;
  vso_SPLIT_VOBID = 2;
  vso_SPLIT_CELLID = 4;
  vso_DEMUX = 8;
  vso_KEEP_AC3_IDENT_BYTES = 16;
  vso_KEEP_PCM_IDENT_BYTES = 32;
  vso_ONLY_KEEP_GOPS = 64;
  vso_DVD2AVI = 128;

  vs_PRINT_SUMMARY = 1;
  vs_PRINT_INFO = 2;
  vs_PRINT_ERROR = 4;
  vs_IGNORE_UNKNOWN_CELLS = 8;
  vs_NO_VOB = 16;
  vs_USE_ASPI = 32;
  vs_DEMACRO = 64;
  vs_PREFER_ASPI = 128;
  vs_SUPPORT_1GB = 256;
{$IFDEF vs_DECRYPT}
  vs_DONT_CRACK = 512;
  vs_CRACK_EACH_VOB_ID = 1024;
  vs_CRACK_EACH_CELL_ID = 2048;
{$ENDIF}

  vsv_NONE = 0;
  vsv_DECRYPT = 1;

  udf_MAX_NAMELEN = 256;
  fio_APPEND = 1;
  fio_WRITEABLE = 2;
  fio_USE_ASPI = 4;
  fio_PREFER_ASPI = 8;
  fio_SUPPORT_1GB = 16;

type
  t_vs_streaminfo = packed record
    stream_id       : Cardinal;
    substream_id    : Cardinal;
    vob_id          : Cardinal;
    cell_id         : Cardinal;
    lba             : Cardinal;
    out_lba         : Cardinal;
    out_file_num    : Cardinal;
    out_flags       : Pointer;
    idx             : Cardinal;
    length          : Cardinal;
    encrypted       : Boolean;
  end;
  t_vs_streamflags = packed record
    user_func       : Cardinal; // ignore
    user_data       : Cardinal; // ignore
    packets         : Cardinal;
    bytes           : Cardinal;
    pts             : Double;
    remap_to        : Byte;
    save            : Byte; // bits 0-7 for each output file
    found           : Boolean;
  end;
  tp_vs_streamflags = ^t_vs_streamflags;
  ta_vs_streamflags = array[0..255] of t_vs_streamflags;
  tpa_vs_streamflags = ^ta_vs_streamflags;
  t_inb_buffer = packed record
    infp            : Cardinal;
    outfp           : array[0..inb_MAX_OUTPUT - 1] of Cardinal;
    bytes           : ^Byte;
    idx             : Cardinal;
    num_bytes       : Cardinal;
    buffer_size     : Cardinal;
    lba             : Cardinal;
    encrypted       : Boolean;
    has_system      : Boolean;
    is_vob          : Boolean;
    even            : Boolean;
    save            : Byte;
    // inb_status
  end;
  tp_inb_buffer = ^t_inb_buffer;
  t_vs_internal_data = packed record
    outfileprep     : array[0..inb_MAX_OUTPUT - 1, 0..255] of Char;
    outfileext      : array[0..inb_MAX_OUTPUT - 1, 0..255] of Char;
    buffer          : tp_inb_buffer;
    sti             : t_vs_streaminfo;
    cur_stream      : tp_vs_streamflags;
    framerate       : Cardinal;
    aspectratio     : Cardinal;
    pack_packets    : Cardinal;
    system_packets  : Cardinal;
    opened          : Pointer;
    dvd2avi         : Pointer;
    dvd2avi_idx     : Cardinal;
    only_gop_mask   : Byte;
    did_video_info  : Boolean;
    save_cell       : Boolean;
    init_ok         : Boolean;
{$IFDEF vs_DECRYPT}
    valid_key       : Boolean;
    vob_key         : Boolean;
    cell_key        : Boolean;
{$ENDIF}
  end;
  t_vs_output_data = packed record
    outfile         : array[0..255] of Char;
    split_output    : Cardinal;
    flags           : Cardinal;
  end;
  t_vs_data = packed record
    infile          : PChar;
    num_outputs     : Cardinal;
    outputs         : array[0..inb_MAX_OUTPUT - 1] of t_vs_output_data;
    framerate       : Cardinal;
    aspectratio     : Cardinal;
    max_sync_bytes  : Cardinal;
    start_lba       : Cardinal;
    end_lba         : Cardinal;
    flags           : Cardinal;
{$IFDEF vs_DECRYPT}
    same_guess      : Cardinal;
    pad_guess       : Cardinal;
    pc_guess        : Cardinal;
    key             : array[0..4] of Byte;
{$ENDIF}
    _in             : t_vs_internal_data;
  end;
  tp_vs_data        = ^t_vs_data;
  t_vs_vobcellid = packed record
    start_lba, end_lba: Cardinal;
    vob_id          : Word;
    cell_id         : Byte;
    angle           : Byte;
    chapter         : Byte;
    time            : array[0..3] of Byte;
  end;
  tp_vs_vobcellid = ^t_vs_vobcellid;
  TAVobCellID = array[0..65535] of t_vs_vobcellid;
  TPAVobCellID = ^TAVobCellID;
  t_vs_time = array[0..3] of Byte; //hh.mm.ss.ms
  t_vs_errorcode = (vse_OK, vse_DONE, vse_USER_FUNC_EXIT, vse_INIT_FAILED, vse_CANT_OPEN_INPUT,
                    vse_CANT_CREATE_OUTPUT, vse_CANT_WRITE_OUTPUT, vse_CANT_CRACK, vse_LOST_SYNC);
  t_udf_file = packed record
    name            : array[0..udf_MAX_NAMELEN - 1] of Char;
    is_dir          : Boolean;
    is_parent       : Boolean;
    // other stuff
  end;
  tp_udf_file = ^t_udf_file;
var
  aspi_ok: Boolean;

function vs_get_version(var flags: Cardinal): Cardinal; cdecl; external vs_DllName;
function vs_get_author(): PChar; cdecl; external vs_DllName;

function vs_init(var vsd: t_vs_data; var streams: ta_vs_streamflags; var substreams: ta_vs_streamflags): t_vs_errorcode;
  cdecl; external vs_DllName;
function vs_done(var vsd: t_vs_data; var streams: ta_vs_streamflags; var substreams: ta_vs_streamflags): t_vs_errorcode;
  cdecl; external vs_DllName;
function vs_strip_one_block(var vsd: t_vs_data; var streams: ta_vs_streamflags; var substreams: ta_vs_streamflags;
  num_idl: Cardinal; idl: tp_vs_vobcellid): t_vs_errorcode; cdecl; external vs_DllName;
function vs_get_time(const time: double): PChar; cdecl; external vs_DllName;

function ifoOpen(const name: PChar; const fio_flags: Cardinal): Cardinal; cdecl; external vs_DllName;
function ifoClose(const ifo: Cardinal): Boolean; cdecl; external vs_DllName;
function ifoGetNumPGCI(const ifo: Cardinal): Integer; cdecl; external vs_DllName;
function ifoGetPGCIInfo(const ifo: Cardinal; const title: Cardinal; var time_out: t_vs_time): Integer; cdecl; external vs_DllName;
function ifoGetPGCICells(const ifo: Cardinal; const title: Cardinal; cells: tp_vs_vobcellid): Boolean; cdecl; external vs_DllName;
function ifoGetVideoDesc(const ifo: Cardinal): PChar; cdecl; external vs_DllName;
function ifoGetNumAudio(const ifo: Cardinal): Integer; cdecl; external vs_DllName;
function ifoGetAudioDesc(const ifo: Cardinal; audio_idx: Integer): PChar; cdecl; external vs_DllName;
function ifoGetNumSubPic(const ifo: Cardinal): Integer; cdecl; external vs_DllName;
function ifoGetSubPicDesc(const ifo: Cardinal; subp_idx: Integer): PChar; cdecl; external vs_DllName;

function aspi_Init(): Boolean;  cdecl; external vs_DllName;
procedure aspi_Done();  cdecl; external vs_DllName;
function aspi_GetDriveAddress(drive_letter: Char; var address: Cardinal): Boolean; cdecl; external vs_DllName;
function aspi_GetSectorInfo(const address: Cardinal; var secSize, maxSec: Cardinal): Boolean; cdecl; external vs_DllName;
function aspi_SetTimeout(Const address, seconds: Cardinal): Boolean; cdecl; external vs_DllName;

function udf_get_root(const address: Cardinal; const partition_number: Word; const support_1gb: Boolean): tp_udf_file; cdecl; external vs_DllName;
function udf_get_next(const address: Cardinal; f: tp_udf_file): tp_udf_file; cdecl; external vs_DllName;
function udf_get_sub(const address: Cardinal; f: tp_udf_file): tp_udf_file; cdecl; external vs_DllName;
function udf_get_lba(const address: Cardinal; const f: tp_udf_file; var start_lba, end_lba: Cardinal): Boolean; cdecl; external vs_DllName;
procedure udf_free(f: tp_udf_file); cdecl; external vs_DllName;
function udf_find_file(const address: Cardinal; const partition_number: Word; const support_1gb: Boolean; const name: PChar): tp_udf_file; cdecl; external vs_DllName;

function uGetSize(Name: String): Cardinal;
function uFileExists(Name: String): Boolean;
function CreateStreamList(ListView: TListView; var total_lba: Int64): PChar;

implementation

function uGetSize(Name: String): Cardinal;
var
  i: Integer;
  address, slba, elba: Cardinal;
  f: tp_udf_file;
begin
  i := FileOpen(Name, fmOpenRead or fmShareDenyNone);
  if (i <> -1) then begin
    Result := GetFileSize(i, nil);
    FileClose(i);
  end else
    Result := 0;
  if ((Result = 0) and aspi_ok and aspi_GetDriveAddress(Name[1], address)) then begin
    f := udf_find_file(address, 0, True, PChar(Copy(Name, 3, Length(Name) - 2)));
    if (f <> Nil) then begin
      if (udf_get_lba(address, f, slba, elba)) then
        Result := (elba - slba + 1) shl 11;
      udf_free(f);
    end;
  end;
end;

function uFileExists(Name: String): Boolean;
var
  address: Cardinal;
  f: tp_udf_file;
begin
  Result := FileExists(Name);
  if (not Result and aspi_ok and aspi_GetDriveAddress(Name[1], address)) then begin
    f := udf_find_file(address, 0, False, PChar(Copy(Name, 3, Length(Name) - 2)));
    if (f <> Nil) then begin
      Result := True;
      udf_free(f);
    end;
  end;
end;

function CreateStreamList(ListView: TListView; var total_lba: Int64): PChar;
var
  i, j: Integer;
  s: String;
  list: PChar;
begin
  Result := nil;
  if (ListView.Items.Count > 0) then begin
    s := ':';
    total_lba := 0;
    for i := 0 to ListView.Items.Count - 1 do begin
      s := s + ListView.Items[i].Caption + #0;
      Inc(total_lba, uGetSize(ListView.Items[i].Caption) shr 11)
    end;
    s := s + #0;
    j := Length(s);
    GetMem(list, j);
    for i := 0 to j - 1 do
      list[i] := s[i + 1];
    Result := list;
  end;
end;

initialization
  aspi_ok := aspi_Init();
finalization
  if (aspi_ok) then
    aspi_Done();
end.


syntax highlighted by Code2HTML, v. 0.9.1