Re: Restoring recordings from image

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
15 years ago I've accidently deleted an XFS drive full of recordings. And even in those (*.vdr) days foremost wasn't the most successful tool in order to recover recordings.

What I've done:

    1. I've made an (dd-) image
    2. I used a modified version of genindex to scan the image

The result where thousands of small video files (the number depends on the degree of fragmentation of your drive).
This was working fairly well, but most of the recordings were not worth recovering because I had to solve the puzzle of concatinating dozens of files (out of the thousands) in the correct order.

But if it helps you here is my patch:
diff -ur genindex-0.1.3.orig/file.c genindex-0.1.3/file.c
--- genindex-0.1.3.orig/file.c    2006-06-01 22:09:10.000000000 +0200
+++ genindex-0.1.3/file.c    2008-11-19 14:59:52.000000000 +0100
@@ -181,16 +181,20 @@
 
 cFileName::~cFileName()
 {
+  printf("====>close %s<====\n", filename);
   close(fd);
 }
 
-int cFileName::Open(void)
+int cFileName::Open(off64_t xxx = 0)
 {
   close(fd); fd=-1;
   cString filename;
   if(input) filename=input;
   else filename=cString::sprintf(FILENAME,fileno);
   fd=open64(filename,O_RDONLY);
+  if (xxx > 0) {
+    lseek64(fd,xxx,SEEK_SET);
+  }
   if(fd>=0) {
     struct stat64 st;
     if(fstat64(fd,&st)==0) {
diff -ur genindex-0.1.3.orig/file.h genindex-0.1.3/file.h
--- genindex-0.1.3.orig/file.h    2006-06-01 17:12:25.000000000 +0200
+++ genindex-0.1.3/file.h    2008-11-19 15:01:15.000000000 +0100
@@ -54,12 +54,13 @@
 public:
   cFileName(const char *Input, bool LargeOK);
   ~cFileName();
-  int Open(void);
+  int Open(off64_t);
   int NextFile(void);
   int OpenWrite(void);
   int NextWriteFile(void);
   int Skip(int nr, int off);
   int FileNumber(void) { return fileno; }
+  void SetFileNumber(int i) {fileno = i;}
   long long FileSize(void) { return size; }
   };
 
Only in genindex-0.1.3: file.o
Only in genindex-0.1.3: genindex
diff -ur genindex-0.1.3.orig/genindex.c genindex-0.1.3/genindex.c
--- genindex-0.1.3.orig/genindex.c    2006-06-02 15:44:31.000000000 +0200
+++ genindex-0.1.3/genindex.c    2008-11-19 15:00:58.000000000 +0100
@@ -41,6 +41,8 @@
 char *destdir=0;
 char *input=0;
 int splitsize=2000;
+long long startat=0;
+int firstnum=1;
 bool rewrite=false;
 bool quiet=false;
 
@@ -61,6 +63,7 @@
   //
   unsigned int sSize;
   int splitOffset;
+  long long startOffset;
   bool pstart;
   //
   unsigned char buff[KILOBYTE(256)];
@@ -77,7 +80,7 @@
 public:
   cGenIndex(void);
   ~cGenIndex();
-  void Work(void);
+  void Work(off64_t);
   void Skip(int type);
   };
 
@@ -86,6 +89,7 @@
   index=new cIndex(destdir);
   fileName=new cFileName(input,input && rewrite);
   writeName=new cFileName(destdir,true);
+  writeName->SetFileNumber(firstnum);
 
   if(rewrite) {
     SetDefaultRule(prSkip);
@@ -124,7 +128,7 @@
   return replayFile>=0;
 }
 
-void cGenIndex::Work(void)
+void cGenIndex::Work(off64_t startat = 0)
 {
   eof=error=pstart=false;
   memset(fileSize,0,sizeof(fileSize));
@@ -137,14 +141,16 @@
       }
     }
 
-  replayFile=fileName->Open();
+  readOffset=startat;
+
+  replayFile=fileName->Open(readOffset);
   readNo=fileName->FileNumber();
   fileSize[readNo]=fileName->FileSize();
-  readOffset=0;
 
   fileNo=rewrite ? 1 : readNo;
   fileOffset=0;
   splitOffset=splitsize*MEGABYTE(1);
+  startOffset=startat*MEGABYTE(1);
   sSize=0;
 
   if(replayFile>=0) {
@@ -236,7 +242,7 @@
     }
 
   if(rewrite) {
-    if(scan && fileOffset>=splitOffset && (pstart || sSize)) {
+    if(scan && (fileOffset>=splitOffset || nextFile) && (pstart || sSize)) {
       if(sSize+len>sizeof(store)) {
         printf("Oops! Packet buffer overflow\n");
         error=true;
@@ -246,7 +252,7 @@
       sSize+=len;
       }
     else {
-      if(fileOffset>=splitOffset && sSize && ftype==I_FRAME) {
+      if((fileOffset>=splitOffset || nextFile) && sSize && ftype==I_FRAME) {
         writeFile=writeName->NextWriteFile();
         if(writeFile<0) {
           printf("Failed to open output file(s)\n");
@@ -254,6 +260,7 @@
           return -1;
           }
         packetNo=fileNo=writeName->FileNumber();
+    nextFile=false;
         packetOffset=0;
         fileOffset=sSize;
         }
@@ -343,6 +350,8 @@
 {
   static struct option long_options[] = {
       { "rewrite",  no_argument,       NULL, 'r' },
+      { "startat",  required_argument, NULL, 'a' },
+      { "firstnum", required_argument, NULL, 'f' },
       { "quiet",    no_argument,       NULL, 'q' },
       { "dest",     required_argument, NULL, 'd' },
       { "split",    required_argument, NULL, 's' },
@@ -353,8 +362,14 @@
 
   int s=0, str[MAX_STR];
   int c;
-  while((c=getopt_long(argc,argv,"rqd:s:i:",long_options,NULL))!=-1) {
+  while((c=getopt_long(argc,argv,"rqd:s:i:a:f:",long_options,NULL))!=-1) {
     switch (c) {
+      case 'a':
+        startat=atoll(optarg);
+        break;
+      case 'f':
+        firstnum=atoi(optarg);
+        break;
       case 'r':
         rewrite=true;
         break;
@@ -396,6 +411,8 @@
         about();
         printf("\nUsage: genindex [-r] [-d DIR] [-s SIZE]\n\n"
                "  -i FILE, --input FILE  use a single input file\n"
+               "  -a,      --startat     start reading input file at position\n"
+               "  -f,      --firstnum    start numbering output file at num\n"
                "  -r,      --rewrite     rewrite video files\n"
                "  -d DIR,  --dest=DIR    set destination dir\n"
                "  -s SIZE, --split=SIZE  split files at megabyte count\n"
@@ -421,6 +438,6 @@
       }
     if(!quiet) printf("\n\n");
     }
-  gi.Work();
+  gi.Work(startat);
   return 0;
 }
Only in genindex-0.1.3: genindex.o
diff -ur genindex-0.1.3.orig/pes.c genindex-0.1.3/pes.c
--- genindex-0.1.3.orig/pes.c    2003-07-26 23:55:21.000000000 +0200
+++ genindex-0.1.3/pes.c    2008-10-26 23:32:44.000000000 +0100
@@ -11,7 +11,7 @@
 #include "pes.h"
 #include "ringbuffer.h"
 
-#define DEBUG(x...) printf(x)
+#define DEBUG(x...) fprintf(stderr, x)
 //#define DEBUG(x...)
 
 //#define PD(x...) printf(x)
@@ -23,6 +23,7 @@
 {
   rb=new cRingBufferFrame(KILOBYTE(50));
   defaultRule=ru;
+  nextFile=false;
   Reset();
 }
 
@@ -109,6 +110,7 @@
       }
     }
   else if(skipped) {
+   nextFile=true;
    totalSkipped+=skipped;
    if(skipped==zeros) totalZeros+=zeros;
    else DEBUG("PES: skipped %d bytes\n",skipped);
diff -ur genindex-0.1.3.orig/pes.h genindex-0.1.3/pes.h
--- genindex-0.1.3.orig/pes.h    2003-07-26 23:54:51.000000000 +0200
+++ genindex-0.1.3/pes.h    2008-10-26 18:59:26.000000000 +0100
@@ -25,6 +25,7 @@
 class cPES : public cMutex {
 protected:
   enum eRule { prPass, prSkip, prAct1, prAct2, prAct3, prAct4, prAct5, prAct6, prAct7, prAct8 };
+  bool nextFile;
 private:
   eRule rules[NUM_RULESETS][NUM_RULES], *currRules, currRule, defaultRule;
   int currNum;
Only in genindex-0.1.3: pes.o
Only in genindex-0.1.3: ringbuffer.o
Only in genindex-0.1.3: thread.o


Christian.



On 2023-07-03 14:34, Kartsa wrote:
Hi

I’ve had VDR running for almost 20 years now. Not continuously of course and occasionally I have updated the system and added more disk and new MB and CPU and so.

My problem is that I had an external disk for saving recordings which did not fit on the internal hard disk and now the external disk has failed. I had XFS on the disk and I have been able to create an image of the disk (probably with big chunks missing) but I have not been able to restore any of the recordings from the image. I have tried with foremost but the problem is the ts files. Foremost does not recognise them out of the box and I would need some header/footer information of the files. But to my understanding the ts files have no special footer which would indicate the ending of a file. Have tried to recognise from current recordings the header and tried with that. Foremost has been able to restore the info files but those are not a big help.

Anyway I was wondering if there are any tools that I could try to restore the recordings. I have tried a lot of different tools (including testdisk and photorec) but have not had any real luck. So any instructions and/or pointers would be appreciated :)

BR
\\Kartsa


_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux