Hi,

Am Montag, 29. Oktober 2007 10:32 schrieb Michael Riepe:
> > Supported input fields are the cut-list supplied with the
> > "-cut"-CLI-option, the <start>/<stop>-tags in project files and the
> > search boxes in the GUI (did I forget something?).
>
> I guess it's not necessary to support the format in the project file -
> unless you're going to create project files with a script.
That was, actually the idea behind that... when editing project files by hand 
or automatically by some script and you don't have a frame number
but a time and you are to lazy to calculate. ;-)

> > BTW, we now also have an "-exp"-CLI-switch to specify an export
> > file/location in addition to the (optional) <expfile>-projectfile-tag.
> > Nevertheless, the latter has still priority...
>
> It's usually the other way round: command line switches override
> configuration files.

Hey,... no problem with that! I also find it more logical to override a 
projectfile default with a CLI-option, since the latter is easier to 
change... ;-)

Also -idx is implemented that way... to be consistent CLI should overrule PRJ 
for all options!

And should I also override the start/stop-markers from the project file with 
the "-cut" the option? At the moment the -cut-markers are just added... 
(BUG-Alert!!! This causes strange behavoir, since when adding new  start/stop 
markers, the result won't be necessarily alternated anymore!!!).

So either I delete any old ones (also in GUI-mode with convert bookmarks!)
or always just insert/add new markers, sort the whole list and then alternate 
START/STOP... at the moment the appended patch will implement the first 
option.

Another option would be to replace only in batch mode and add in gui-mode...?

>
> [...]
> > -     if (it->export_flag)
> > +     if (it->export_flag && it!=quick_picture_lookup.end())
> I'm pretty sure this change is useless. `it' can't be at the end of the
> list because it has just been decremented (i.e. moved towards the front
> by one position).

Hmmm,... of course you are right... very strange,... I thought I tested
that...?!? :-| 

OK,... in the updated patch file it is now compared to 
"quick_picture_lookup.end()-1"!
A cleaner solution maybe would be to set the export_flag of a START-entry only 
to true, if there follows a STOP-entry...?

The appended patch also implements no strict CLI overrules PRJ and adds  a
few more context menu entries (hmmm..., quite a long list now!). 

ciao
Ralph

PS: Thanks for looking over my not always 100% tested patches... :)


--- svn/ChangeLog	2007-10-25 19:22:04.000000000 +0200
+++ r96-timestamp/ChangeLog	2007-10-29 12:39:00.000000000 +0100
@@ -1,3 +1,18 @@
+2007-10-28  	
+
+    * src/dvbcut.cpp:
+	* src/dvbcut.h:
+	* src/main.cpp:
+	* src/dvbcutbase.ui:
+        Allow timestamps in input fields, added -exp option. 
+        -exp/-cut/-idx options overrule project file defaults.
+        Add specific "Delete"-entries to marker context menu. 
+        Fixed bugs with quick_picture_lookuptable.
+
+	* src/pts.cpp:
+	* src/pts.h:
+        Function to convert formatted timestamps to pts_t
+
 2007-10-25  Michael Riepe  <[EMAIL PROTECTED]>
 
 	* SConstruct:
diff -Naur svn/src/dvbcutbase.ui r96-timestamp/src/dvbcutbase.ui
--- svn/src/dvbcutbase.ui	2007-10-25 19:22:04.000000000 +0200
+++ r96-timestamp/src/dvbcutbase.ui	2007-10-28 11:26:12.000000000 +0100
@@ -132,7 +132,7 @@
                                     </sizepolicy>
                                 </property>
                                 <property name="maxLength">
-                                    <number>7</number>
+                                    <number>16</number>
                                 </property>
                             </widget>
                             <widget class="QPushButton">
@@ -179,7 +179,7 @@
                                     </sizepolicy>
                                 </property>
                                 <property name="maxLength">
-                                    <number>7</number>
+                                    <number>16</number>
                                 </property>
                             </widget>
                             <widget class="QPushButton">
diff -Naur svn/src/dvbcut.cpp r96-timestamp/src/dvbcut.cpp
--- svn/src/dvbcut.cpp	2007-10-25 14:33:26.000000000 +0200
+++ r96-timestamp/src/dvbcut.cpp	2007-10-29 13:19:10.000000000 +0100
@@ -705,7 +705,19 @@
 
 void dvbcut::addStartStopItems(std::vector<int> cutlist)
 {
-   // take list of frame numbers and set alternating START/STOP markers
+  // take list of frame numbers and set alternating START/STOP markers
+
+  // make sure list is sorted... 
+  sort(cutlist.begin(),cutlist.end());
+
+  // ...AND there are no old START/STOP pairs!!!
+  for (QListBoxItem *item=eventlist->firstItem();item;item=item->next())
+    if (item->rtti()==EventListItem::RTTI()) {
+      EventListItem *eli=(EventListItem*)item;
+      if (eli->geteventtype()==EventListItem::start || eli->geteventtype()==EventListItem::stop) 
+         delete item;       
+    } 
+
   EventListItem::eventtype type=EventListItem::start;
   for (std::vector<int>::iterator it = cutlist.begin(); it != cutlist.end(); ++it) {   
     addEventListItem(*it, type);
@@ -714,6 +726,7 @@
     else 
       type=EventListItem::start;  
   }
+  
   update_quick_picture_lookup_table();
 }
 
@@ -995,15 +1008,18 @@
   popup.insertItem("Delete",2);
   popup.insertItem("Delete others",3);
   popup.insertItem("Delete all",4);
-  popup.insertItem("Delete all bookmarks",5);
-  popup.insertItem("Convert to start marker",6);
-  popup.insertItem("Convert to stop marker",7);
-  popup.insertItem("Convert to chapter marker",8);
-  popup.insertItem("Convert to bookmark",9);
-  popup.insertItem("Display difference from this picture",10);
+  popup.insertItem("Delete all start/stops",5);
+  popup.insertItem("Delete all chapters",6);
+  popup.insertItem("Delete all bookmarks",7);
+  popup.insertItem("Convert to start marker",8);
+  popup.insertItem("Convert to stop marker",9);
+  popup.insertItem("Convert to chapter marker",10);
+  popup.insertItem("Convert to bookmark",11);
+  popup.insertItem("Display difference from this picture",12);
 
   QListBox *lb=lbi->listBox();
   QListBoxItem *first=lb->firstItem(),*current,*next;
+  EventListItem::eventtype cmptype=EventListItem::none, cmptype2=EventListItem::none;
 
   switch (popup.exec(point)) {
     case 1:
@@ -1016,8 +1032,7 @@
       {
       EventListItem::eventtype type=eli.geteventtype();
       delete lbi;
-      
-      if (type==EventListItem::start or type==EventListItem::stop)
+      if (type==EventListItem::start || type==EventListItem::stop)
         update_quick_picture_lookup_table();
       }
       break;
@@ -1038,32 +1053,42 @@
       break;
 
     case 5:
+      cmptype=EventListItem::start;
+      cmptype2=EventListItem::stop;
+    case 6:
+      if(cmptype==EventListItem::none) cmptype=EventListItem::chapter;
+    case 7:
+      if(cmptype==EventListItem::none) cmptype=EventListItem::bookmark;
       current=first;
       while(current) {
         next=current->next();
         const EventListItem &eli_current=*static_cast<const EventListItem*>(current);
-        if(eli_current.geteventtype()==EventListItem::bookmark) delete current;
+        if(eli_current.geteventtype()==cmptype || eli_current.geteventtype()==cmptype2) 
+          delete current;
         current=next;
-      }   
+      }       
+      if (cmptype==EventListItem::start) update_quick_picture_lookup_table();
       break;
 
-    case 6:
+    case 8:
       eli.seteventtype(EventListItem::start);
+      update_quick_picture_lookup_table();
       break;
 
-    case 7: 
+    case 9: 
       eli.seteventtype(EventListItem::stop);
+      update_quick_picture_lookup_table();
       break; 
 
-    case 8:
+    case 10:
       eli.seteventtype(EventListItem::chapter);
       break;
 
-    case 9: 
+    case 11: 
       eli.seteventtype(EventListItem::bookmark);
       break; 
 
-    case 10:
+    case 12:
       if (imgp)
         delete imgp;
       imgp=new differenceimageprovider(*mpg,eli.getpicture(),new dvbcutbusy(this),false,viewscalefactor);
@@ -1081,7 +1106,13 @@
   QString text=goinput->text();
   text.stripWhiteSpace();
   bool okay=false;
-  int inpic=text.toInt(&okay,0);
+  int inpic;
+  if(text.contains(':') || text.contains('.')) {
+    okay=true;
+    inpic=string2pts(text)/getTimePerFrame();
+  }
+  else
+    inpic=text.toInt(&okay,0);
   if (okay) {
     fine=true;
     linslider->setValue(inpic);
@@ -1095,8 +1126,14 @@
   QString text=goinput2->text();
   text.stripWhiteSpace();
   bool okay=false;
-  int inpic, outpic=text.toInt(&okay,0);
-  if (okay) {
+  int inpic, outpic;
+  if(text.contains(':') || text.contains('.')) {
+    okay=true;
+    outpic=string2pts(text)/getTimePerFrame();
+  }
+  else
+    outpic=text.toInt(&okay,0);
+  if (okay && !quick_picture_lookup.empty()) {
     // find the entry in the quick_picture_lookup table that corresponds to given output picture
     quick_picture_lookup_t::iterator it=
       std::upper_bound(quick_picture_lookup.begin(),quick_picture_lookup.end(),outpic,quick_picture_lookup_s::cmp_outpicture());
@@ -1255,7 +1292,7 @@
 // **************************************************************************
 // ***  public functions
 
-void dvbcut::open(std::list<std::string> filenames, std::string idxfilename)
+void dvbcut::open(std::list<std::string> filenames, std::string idxfilename, std::string expfilename)
 {
   if (filenames.empty()) {
     QStringList fn = QFileDialog::getOpenFileNames(
@@ -1356,7 +1393,7 @@
   linslider->setEnabled(false);
   jogslider->setEnabled(false);
 
-  std::string prjfilename,expfilename;
+  std::string prjfilename;
   QDomDocument domdoc;
   {
     QFile infile(filename);
@@ -1382,7 +1419,11 @@
 	  // parse elements, new-style first
 	  QDomNode n;
           filenames.clear();
+      if(!nogui) {    
+          // in batch mode CLI-switches have priority!              
           idxfilename.clear();
+          expfilename.clear();
+      }    
 	  for (n = domdoc.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) {
 	    QDomElement e = n.toElement();
 	    if (e.isNull())
@@ -1392,12 +1433,12 @@
 	      if (!qs.isEmpty())
 		filenames.push_back((const char*)qs);
 	    }
-	    else if (e.tagName() == "idxfile") {
+	    else if (e.tagName() == "idxfile" && idxfilename.empty()) {
 	      QString qs = e.attribute("path");
 	      if (!qs.isEmpty())
 		idxfilename = (const char*)qs;
 	    }
-	    else if (e.tagName() == "expfile") {
+	    else if (e.tagName() == "expfile" && expfilename.empty()) {           
 	      QString qs = e.attribute("path");
 	      if (!qs.isEmpty())
 		expfilename = (const char*)qs;
@@ -1569,6 +1610,7 @@
     addtorecentfiles(prjfilen);
 
   firstpts=(*mpg)[0].getpts();
+  timeperframe=(*mpg)[1].getpts()-(*mpg)[0].getpts();
 
   double fps=27.e6/double(mpgfile::frameratescr[(*mpg)[0].getframerate()]);
   linslider->setMaxValue(pictures-1);
@@ -1617,7 +1659,14 @@
       else
         continue;
       bool okay=false;
-      int picnum=e.attribute("picture","-1").toInt(&okay,0);
+      int picnum;
+      QString str=e.attribute("picture","-1");
+      if(str.contains(':') || str.contains('.')) {
+        okay=true;
+        picnum=string2pts(str)/getTimePerFrame();
+      }
+      else
+        picnum=str.toInt(&okay,0);
       if (okay && picnum>=0 && picnum<pictures) {
         new EventListItem(eventlist,imgp->getimage(picnum),evt,picnum,(*mpg)[picnum].getpicturetype(),(*mpg)[picnum].getpts()-firstpts);
         qApp->processEvents();
@@ -1823,11 +1872,11 @@
    {
      // curpic is not before the first entry of the table
      --it;
-     if (it->export_flag)
+     if (it->export_flag && it!=(quick_picture_lookup.end()-1))
      {
        // the corresponding entry says export_flag==true,
        // so this pic is after a START entry and is going to
-       // be exported
+       // be exported (But ONLY if it's not the last entry!).
        
        outpic=curpic-it->picture+it->outpicture;
        outpts=pts-it->pts+it->outpts;
diff -Naur svn/src/dvbcut.h r96-timestamp/src/dvbcut.h
--- svn/src/dvbcut.h	2007-10-25 12:40:50.000000000 +0200
+++ r96-timestamp/src/dvbcut.h	2007-10-28 12:03:15.000000000 +0100
@@ -78,6 +78,7 @@
   int curpic;
   double alpha;
   pts_t firstpts;
+  int timeperframe;
   bool showimage;
   bool fine;
   bool jogsliding;
@@ -121,11 +122,13 @@
 public:
   ~dvbcut();
   dvbcut(QWidget *parent = 0, const char *name = 0, WFlags fl = WType_TopLevel|WDestructiveClose );
-  void open(std::list<std::string> filenames=std::list<std::string>(), std::string idxfilename=std::string());
+  void open(std::list<std::string> filenames=std::list<std::string>(), 
+            std::string idxfilename=std::string(), std::string expfilename=std::string());
   void setbusy(bool b=true);
   void batchmode(bool b=true) { nogui = b; }
   // static dvbcut *New(std::string filename=std::string(), std::string idxfilename=std::string());
   void addStartStopItems(std::vector<int>);
+  int getTimePerFrame() { return timeperframe>0 && timeperframe<5000 ? timeperframe : 3003; };
 
 public slots:
   virtual void fileNew();
diff -Naur svn/src/main.cpp r96-timestamp/src/main.cpp
--- svn/src/main.cpp	2007-10-25 19:22:04.000000000 +0200
+++ r96-timestamp/src/main.cpp	2007-10-28 20:52:06.000000000 +0100
@@ -53,8 +53,8 @@
 usage_exit(int rv=1) {
   fprintf(stderr,
     "Usage ("VERSION_STRING"):\n"
-    "  %s -generateidx [-idx <indexfilename>] [<mpgfilename> ...]\n"
-    "  %s -batch [ -cut AR|TS|<list> ] <prjfilename> | <mpgfilename> ...\n\n",
+    "  %s -generateidx [-idx <idxfilename>] [<mpgfilename> ...]\n"
+    "  %s -batch [-cut AR|TS|<list>] [-exp <expfilename>] <prjfilename> | <mpgfilename> ...\n\n",
     argv0, argv0);
   fprintf(stderr,
     "If no input files are specified, `dvbcut -generateidx' reads from\n"
@@ -64,7 +64,7 @@
     "In batch mode you can use `-cut' to create automatically alternating\n"
     "START/STOP cut markers for each found aspect ratio change (AR), for\n"
     "the bookmarks imported from the input transport stream (TS) or for\n"
-    "a given list of frame numbers (you can use ',-|;:/' as separators).\n" 
+    "a given list of frame numbers / time stamps (use ',-|;' as separators).\n" 
     "Without any (valid) cut markers the whole file will be converted!\n\n");
   fprintf(stderr,
     "Options may be abbreviated as long as they remain unambiguous.\n\n");
@@ -76,8 +76,8 @@
   argv0=argv[0];
   bool generateidx=false;
   bool batchmode=false;
-  std::string idxfilename, cut;
-  std::vector<int> cutlist;
+  std::string idxfilename, expfilename;
+  std::vector<std::string> cutlist;
   int i;
 
   setlocale(LC_ALL, "");
@@ -97,15 +97,17 @@
       generateidx = true;
     else if (strncmp(argv[i], "-idx", n) == 0 && ++i < argc)
       idxfilename = argv[i];
+    else if (strncmp(argv[i], "-exp", n) == 0 && ++i < argc)
+      expfilename = argv[i];
     else if (strncmp(argv[i], "-cut", n) == 0 && ++i < argc) {
-      cut=argv[i];
-      char *pch=strtok(argv[i],",-|;:/");     
+      char *pch = strtok(argv[i],",-|;");
       while(pch) {
-         cutlist.push_back(atoi(pch));  
-         pch=strtok(NULL,",-|;:/");                 
-      }
-    } else
-      usage_exit();
+        if(strlen(pch))
+          cutlist.push_back((std::string)pch);    
+        pch = strtok(NULL,",-|;");                 
+      } 
+    } else 
+      usage_exit(); 
   }
 
   /*
@@ -195,18 +197,24 @@
   if (batchmode) {
     if (filenames.empty())	// must provide at least one filename
       usage_exit();
-    main->open(filenames,idxfilename);
-    if(!cut.empty()) {
-      if(cut=="AR") {
+    main->open(filenames,idxfilename,expfilename);
+    if(!cutlist.empty()) {
+      if(cutlist.front()=="AR") {
           main->editSuggest();
           main->editConvert();             
-      } else if(cut=="TS") {
+      } else if(cutlist.front()=="TS") {
           main->editImport();     
           main->editConvert();             
       } else if(cutlist.size()>1) { 
-          // just one entry entry makes no sense and/or can be a typo (atoi() returned 0)! 
-          main->addStartStopItems(cutlist);
-          if(cutlist.size()%2) 
+          // just one entry makes no sense and/or can be a typo!
+          std::vector<int> piclist;
+          for (unsigned int j=0; j<cutlist.size(); j++)                   
+            if(cutlist[j].find(':')!=std::string::npos || cutlist[j].find('.')!=std::string::npos) 
+              piclist.push_back(string2pts(cutlist[j])/main->getTimePerFrame()); // pts divided by 3600(PAL) or 3003(NTSC)
+            else
+              piclist.push_back(atoi(cutlist[j].c_str()));                       // integers are treated as frame numbers!
+          main->addStartStopItems(piclist);
+          if(piclist.size()%2) 
             fprintf(stderr,"*** Cut list contained an odd number of entries, discarded last one! ***\n");    
       } else
         fprintf(stderr,"*** Problems parsing parameter provided with option `-cut'! ***\n");    
@@ -218,7 +226,7 @@
     main->show();
 
     if (!filenames.empty())
-      main->open(filenames,idxfilename);
+      main->open(filenames,idxfilename,expfilename);
 
     if (main) {
       a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
diff -Naur svn/src/pts.cpp r96-timestamp/src/pts.cpp
--- svn/src/pts.cpp	2007-10-14 01:19:43.000000000 +0200
+++ r96-timestamp/src/pts.cpp	2007-10-28 19:39:28.000000000 +0100
@@ -23,7 +23,9 @@
 #include <cstdio>
 #include <cstdlib>
 #include <string>
+#include <list>
 
+// convert a pts (1/90000 sec) to a readable timestamp string
 std::string ptsstring(pts_t pts)
   {
   char *str=0;
@@ -46,3 +48,53 @@
   free(str);
   return s;
   }
+
+// parse timestamp string (hh:mm:ss.frac/nn) and convert to pts (1/90000 of a second)
+pts_t string2pts(std::string str)
+  {
+  int hour=0,min=0,sec=0,ms=0,sub=0,sign=1;
+  double dsec;
+  std::list<std::string> tokens;
+
+  size_t from=0, pos;
+  while((pos=str.find(':',from))!=std::string::npos)  {
+    tokens.push_back(str.substr(from,pos-from));
+    from=pos+1;
+  }  
+  tokens.push_back(str.substr(from));
+ 
+  if(!tokens.empty()) {
+    std::string t=tokens.back(); 
+    pos=t.find('/');
+    dsec=atof(t.substr(0,pos).c_str());
+    if(dsec<0) {
+      dsec*=-1;
+      sign=-1;
+    }
+    sec=int(dsec);
+    ms=int(1000*(dsec-sec)+0.5);
+
+    if(pos!=std::string::npos) 
+      sub=atoi(t.substr(pos+1).c_str())%90; 
+    tokens.pop_back();
+
+    if(!tokens.empty()) {
+      min=atoi(tokens.back().c_str());
+      if(min<0) {
+        min*=-1;  
+        sign=-1;
+      }
+      tokens.pop_back();
+
+      if(!tokens.empty()) {
+        hour=atoi(tokens.back().c_str());
+        if(hour<0) {
+          hour*=-1;  
+          sign=-1;
+        }
+      }    
+    }  
+  }
+  
+  return sign*((((hour*60 + min)*60 + sec)*1000 + ms)*90 + sub);
+  }
diff -Naur svn/src/pts.h r96-timestamp/src/pts.h
--- svn/src/pts.h	2007-10-11 20:03:19.000000000 +0200
+++ r96-timestamp/src/pts.h	2007-10-27 14:21:14.000000000 +0200
@@ -38,5 +38,6 @@
   }
 
 std::string ptsstring(pts_t pts);
+pts_t string2pts(std::string);
 
 #endif
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
DVBCUT-user mailing list
DVBCUT-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dvbcut-user

Reply via email to