Hi,
a last little patch in the old year... ;-)
I implemented a Edit-menu entry for automated setting of chapter markers every
few minutes (as specified in the settings file via /chapters/interval as
number of frames). Normally I do this with the authoring tool, but if you
pipe the DVBcut output directly to dvdauthor and you are to lazy to set them
manually it may be convenient... ;-)
There is also a mode which looks for the next scene change inside a given
number of frames after the regular chapter markers, but that's rather slow,
so I disabled it by default (scanning the frames is much slower than
realtime!). To switch it on you have to set /chapters/tolerance>0
(with /chapters/threshold as the minimal averaged color distance between two
consecutive pictures to define a scene change).
Maybe someone has an Idea to speed this up...?
I guess the problem is the imageprovider...
Ciao and Happy New Yeay,
Ralph
BTW, I notice a bug when positioning frames via the output frame number input
field, which is fixed with this patch (in dvbcut.cpp/clickedgo2())!
--
------------------------------------------------------
Ralph Glasstetter
Rueppurrer Str. 62 0721 / 359166
76137 Karlsruhe [EMAIL PROTECTED]
------------------------------------------------------
diff -Naur svn/ChangeLog r110-autochapter/ChangeLog > r110-autochapter.diff
--- svn/ChangeLog 2007-12-15 17:43:14.000000000 +0100
+++ r110-autochapter/ChangeLog 2007-12-30 20:57:51.000000000 +0100
@@ -1,3 +1,13 @@
+2007-12-30 Ralph Glasstetter <[EMAIL PROTECTED]> (mr)
+
+ * src/dvbcutbase.ui
+ * src/dvbcut.cpp
+ * src/dvbcut.h
+ * src/settings.cpp
+ * src/settings.h
+ Automated setting of equidistant chapter markers
+ Fixed bug concerning positioning via output frames
+
2007-12-12 Ralph Glasstetter <[EMAIL PROTECTED]> (mr)
* src/dvbcutbase.ui:
diff -Naur svn/src/dvbcutbase.ui r110-autochapter/src/dvbcutbase.ui
--- svn/src/dvbcutbase.ui 2007-12-15 17:43:14.000000000 +0100
+++ r110-autochapter/src/dvbcutbase.ui 2007-12-30 14:33:53.000000000 +0100
@@ -376,6 +376,7 @@
<action name="editChapterAction"/>
<action name="editBookmarkAction"/>
<separator/>
+ <action name="editAutoChaptersAction"/>
<action name="editSuggestAction"/>
<action name="editImportAction"/>
</item>
@@ -653,6 +654,20 @@
</action>
<action>
<property name="name">
+ <cstring>editAutoChaptersAction</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Auto chapters</string>
+ </property>
+ <property name="accel">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
<cstring>editSuggestAction</cstring>
</property>
<property name="enabled">
@@ -926,6 +941,12 @@
<slot>editBookmark()</slot>
</connection>
<connection>
+ <sender>editAutoChaptersAction</sender>
+ <signal>activated()</signal>
+ <receiver>dvbcutbase</receiver>
+ <slot>editAutoChapters()</slot>
+ </connection>
+ <connection>
<sender>editSuggestAction</sender>
<signal>activated()</signal>
<receiver>dvbcutbase</receiver>
@@ -1082,6 +1103,7 @@
<slot>editStop()</slot>
<slot>editChapter()</slot>
<slot>editBookmark()</slot>
+ <slot>editAutoChapters()</slot>
<slot>editSuggest()</slot>
<slot>editImport()</slot>
<slot>editConvert(int)</slot>
diff -Naur svn/src/dvbcut.cpp r110-autochapter/src/dvbcut.cpp
--- svn/src/dvbcut.cpp 2007-12-15 17:43:14.000000000 +0100
+++ r110-autochapter/src/dvbcut.cpp 2007-12-30 20:44:48.000000000 +0100
@@ -148,7 +148,7 @@
connect( recentfilespopup, SIGNAL( aboutToShow() ), this, SLOT( abouttoshowrecentfiles() ) );
editconvertpopup=new QPopupMenu(this);
- editMenu->insertItem(QString("Convert bookmarks"),editconvertpopup,-1,7);
+ editMenu->insertItem(QString("Convert bookmarks"),editconvertpopup,-1,8);
connect( editconvertpopup, SIGNAL( activated(int) ), this, SLOT( editConvert(int) ) );
connect( editconvertpopup, SIGNAL( aboutToShow() ), this, SLOT( abouttoshoweditconvert() ) );
@@ -854,6 +854,71 @@
update_quick_picture_lookup_table();
}
+void dvbcut::editAutoChapters()
+{
+ int inpic, chapters = 0;
+ quick_picture_lookup_t::iterator it;
+ QImage p1, p2;
+
+ for(int outpic=settings().chapter_interval; outpic < quick_picture_lookup.back().outpicture-settings().chapter_interval; outpic+=settings().chapter_interval)
+ if (!quick_picture_lookup.empty()) {
+ // find the entry in the quick_picture_lookup table that corresponds to given output picture
+ it = std::upper_bound(quick_picture_lookup.begin(),quick_picture_lookup.end(),outpic,quick_picture_lookup_s::cmp_outpicture());
+ inpic = outpic - it->outpicture + it->stoppicture;
+
+ if(inpic+settings().chapter_tolerance>it->stoppicture) {
+ if(it == quick_picture_lookup.end()) break;
+ // take begin of next START/STOP range as chapter picture if to near at end of current range
+ it++;
+ inpic = it->startpicture;
+ } else if(settings().chapter_tolerance>0) {
+ // look for the next scene change inside specified frame tolerance (VERY SLOW!!!)
+ if (!imgp)
+ imgp = new imageprovider(*mpg, new dvbcutbusy(this), false, viewscalefactor, settings().chapter_tolerance);
+ p2 = imgp->getimage(inpic,fine);
+ for(int pic=inpic+1; pic<inpic+settings().chapter_tolerance && pic<pictures; pic++) {
+ // get next picture
+ p1 = p2;
+ p2 = imgp->getimage(pic,fine);
+ if (p2.size()!=p1.size())
+ p2=p2.scale(p1.size());
+
+ // calculate color distance between two consecutive frames
+ double dist=0.;
+ if (p2.depth()==32 && p1.depth()==32)
+ for (int y=0;y<p1.height();++y) {
+ QRgb *col1=(QRgb*)p1.scanLine(y);
+ QRgb *col2=(QRgb*)p2.scanLine(y);
+
+ for (int x=p1.width();x>0;--x) {
+ dist+=sqrt(pow(qRed(*col1)-qRed(*col2),2)+pow(qGreen(*col1)-qGreen(*col2),2)+pow(qBlue(*col1)-qBlue(*col2),2));
+ // that's maybe a bit faster... but neglectable compared to imageprovider!
+ //dist+=(abs(qRed(*col1)-qRed(*col2))+abs(qGreen(*col1)-qGreen(*col2))+abs(qBlue(*col1)-qBlue(*col2)));
+ ++col1;
+ ++col2;
+ }
+ }
+ dist/=(p1.height()*p1.width());
+
+ // 50. seems to be a good measure for the color distance at scene changes (about sqrt(3)*50. if sum of abs values)!
+ //fprintf(stderr,"%d, DIST=%f\n",pic,dist);
+ if(dist>settings().chapter_threshold) {
+ inpic=pic;
+ statusBar()->message(QString().sprintf("%d. Scene change @ %d, DIST=%f\n",chapters+1,inpic,dist));
+ break;
+ }
+ }
+ }
+
+ addEventListItem(inpic, EventListItem::chapter);
+ chapters++;
+ }
+
+ if (chapters)
+ update_quick_picture_lookup_table();
+
+}
+
void dvbcut::editSuggest()
{
int pic = 0, found=0;
@@ -1366,7 +1431,6 @@
// 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());
- --it;
inpic=outpic-it->outpicture+it->stoppicture;
fine=true;
linslider->setValue(inpic);
@@ -1600,6 +1664,7 @@
editStopAction->setEnabled(false);
editChapterAction->setEnabled(false);
editBookmarkAction->setEnabled(false);
+ editAutoChaptersAction->setEnabled(false);
editSuggestAction->setEnabled(false);
editImportAction->setEnabled(false);
//editConvertAction->setEnabled(false);
@@ -1931,6 +1996,7 @@
editStopAction->setEnabled(true);
editChapterAction->setEnabled(true);
editBookmarkAction->setEnabled(true);
+ editAutoChaptersAction->setEnabled(true);
editSuggestAction->setEnabled(true);
editImportAction->setEnabled(true);
//editConvertAction->setEnabled(true);
diff -Naur svn/src/dvbcut.h r110-autochapter/src/dvbcut.h
--- svn/src/dvbcut.h 2007-12-15 17:43:14.000000000 +0100
+++ r110-autochapter/src/dvbcut.h 2007-12-30 14:32:57.000000000 +0100
@@ -153,6 +153,7 @@
virtual void editChapter();
virtual void editStop();
virtual void editStart();
+ virtual void editAutoChapters();
virtual void editSuggest();
virtual void editImport();
virtual void editConvert(int);
diff -Naur svn/src/settings.cpp r110-autochapter/src/settings.cpp
--- svn/src/settings.cpp 2007-12-12 11:14:15.000000000 +0100
+++ r110-autochapter/src/settings.cpp 2007-12-30 19:30:47.000000000 +0100
@@ -58,13 +58,25 @@
#define DVBCUT_DEFAULT_PIPE_LABEL \
"DVD-Video titleset (dvdauthor)"
#define DVBCUT_DEFAULT_PIPE_FORMAT (0)
-/* ok,... for time consuming conversions one does not save any time processing the piped output... but just as an example. ;-)
-#define DVBCUT_DEFAULT_PIPE_COMMAND \
- "|ffmpeg -f mpeg2video -i - -f avi -vcodec mpeg4 -b 1200k -g 250 -bf 2 -acodec libmp3lame -ab 128k -ar 44100 %OUTPUT%"
-#define DVBCUT_DEFAULT_PIPE_POST ""
-#define DVBCUT_DEFAULT_PIPE_LABEL \
- "MPEG-4/ASP (ffmpeg)"
-#define DVBCUT_DEFAULT_PIPE_FORMAT (1)
+/*
+// SOME OTHER EXAMPLES for the settings file ~/.qt/dvbcut.sf.netrc
+// (ok, for time consuming conversions one does not save any time, but it may be convenient...)
+// 1. Conversion to mpeg4 avi-file with ffmpeg:
+// (to recode to a smaller MPEG2 File use "--target dvd -acodec copy"?)!
+pipe/1/command=|ffmpeg -f mpeg2video -i - -f avi -vcodec mpeg4 -b 1200k -g 250 -bf 2 -acodec libmp3lame -ab 128k -ar 44100 %OUTPUT%
+pipe/1/format=1
+pipe/1/label=MPEG-4/ASP (ffmpeg)
+pipe/1/post=
+// 2. Shrinking with vamps by 20%, before piping to dvdauthor:
+pipe/2/command=| vamps -E 1.2 -S 10000000000 -a 1,2,3 | dvdauthor -t -c '%CHAPTERS%' -v mpeg2 -o %OUTPUT% -
+pipe/2/format=0
+pipe/2/label=20% shrinked DVD-Video titleset (vamps & dvdauthor)
+pipe/2/post=dvdauthor -o %OUTPUT% -T
+// 3. Recoding to a (smaller?) MPEG2 file with DVD compliant resolution (ca. 3000kbps):
+pipe/3/command=|ffmpeg -f mpeg2video -i - -target dvd -qscale 3.0 -bf 2 -acodec copy %OUTPUT%"
+pipe/3/format=1
+pipe/3/label=recoded DVD compliant video (ffmpeg)
+pipe/3/post=
*/
dvbcut_settings::dvbcut_settings() {
@@ -189,6 +201,14 @@
endGroup(); // key
}
endGroup(); // pipe
+ beginGroup("/chapters");
+ chapter_interval = readNumEntry("/interval", 600*25);
+ // detection of scene changes is rather time comsuming...
+ //chapter_tolerance = readNumEntry("/tolerance", 10*25);
+ //... better switch it off per default!
+ chapter_tolerance = readNumEntry("/tolerance", 0);
+ chapter_threshold = readDoubleEntry("/threshold", 50.);
+ endGroup(); // auto chapters
}
void
@@ -266,6 +286,11 @@
endGroup(); // key
}
endGroup(); // pipe
+ beginGroup("/chapters");
+ writeEntry("/interval", chapter_interval);
+ writeEntry("/tolerance", chapter_tolerance);
+ writeEntry("/threshold", chapter_threshold);
+ endGroup(); // auto chapters
}
// private settings variable
diff -Naur svn/src/settings.h r110-autochapter/src/settings.h
--- svn/src/settings.h 2007-12-08 12:11:13.000000000 +0100
+++ r110-autochapter/src/settings.h 2007-12-30 18:59:09.000000000 +0100
@@ -79,6 +79,9 @@
std::vector<QString> pipe_post;
std::vector<QString> pipe_label;
std::vector<int> pipe_format;
+ int chapter_interval;
+ int chapter_tolerance;
+ double chapter_threshold;
};
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
DVBCUT-user mailing list
DVBCUT-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dvbcut-user