I added a patch which should work with the actual release 0.5 of the
OggVideoTools, which can be found here: http://dev.streamnik.de/files.html
Please let me know, if it there is any trouble with it.
- Yorn
> I haven't been on this list until now, so I wasn't aware of this
problem
> until last night ;-) - sorry for that. 
> 
> I am working on a patch for oggCut for that issue (looks good actually but
> I would like to do some testing befor I can release a patch.)
> 
> Normal players are not effected by the page time misordering, so I took
> this issue as "minor". The reason for the misordering is that
oggCut works on
> per-packet basis. Therefor there is usually a small time offset between
> the audio and video.
> The packet are delivered to the muxer in the way they are received from
> the demuxer, so in some cases, the packets will not be in the right order
any
> more and therefor the packets are not ordered correctly.
> 
> I give an additional buffer (500ms) to oggCut, so that packets can be
> reordered. I think this will solve the problem.
> 
> BTW oggCut cuts at keyframes, if you want to cut a video 100% perfect, I
> would suggest to use a video cut program.
> 
> - Yorn
> 
> 
> _______________________________________________
> ogg-dev mailing list
> ogg-dev at xiph.org
> http://lists.xiph.org/mailman/listinfo/ogg-dev
-------------- next part --------------
Index: oggCut.cpp
==================================================================RCS file:
/home/CVS/OggVideoTools/src/oggCut.cpp,v
retrieving revision 1.2
diff -r1.2 oggCut.cpp
31a32,43> struct ListElement {
>   double time;
>   OggPacket packet;
>   ListElement(double _time, OggPacket _packet) :
>     time(_time), packet(_packet)
>   {
>   }
> };
> 
> static std::list<ListElement> packetList;
> static double bufferTime(0.5); // buffer 500 ms
> 
34,43c46,77
<   std::cerr << "usage: " << progName <<
"[options]\n"
<             << "Options are:\n"
<             << " -i input    : Input file\n"
<             << " -o output   : Output file\n"
<             << " -s time     : Start time in milliseconds from
start\n"
<             << "               if no start time is given, 0 is
assumed\n"
<             << " -e time     : End time in milliseconds\n"
<             << "               if no end time or -1 is given,
the end of the\n"
<             << "               file is assumed as the
end\n"
<             << " -l length   : Length of the cut area\n";
--->   std::cerr << "usage: "<< progName <<
"[options]\n"<< "Options are:\n"
>       << " -i input    : Input file\n"<< " -o
output   : Output file\n"
>       << " -s time     : Start time in milliseconds from
start\n"
>       << "               if no start time is given, 0 is
assumed\n"
>       << " -e time     : End time in milliseconds\n"
>       << "               if no end time or -1 is given, the end
of the\n"
>       << "               file is assumed as the end\n"
>       << " -l length   : Length of the cut area\n";
> }
> 
> void bufferedOutput(StreamMux& streamMux, double time, OggPacket
packet)
> {
>   ListElement elem(time, packet);
> 
>   std::list<ListElement>::iterator iter(packetList.begin());
>   while ((iter != packetList.end()) && (elem.time <
iter->time))
>     ++iter;
>   packetList.insert(iter, elem);
> 
>   double lastTime(packetList.front().time);
>   while ((lastTime - packetList.back().time) > bufferTime) {
>     streamMux << packetList.back().packet;
>     packetList.pop_back();
>   }
> }
> 
> void flushBuffer(StreamMux& streamMux)
> {
>   while (!packetList.empty()) {
>     streamMux << packetList.back().packet;
>     packetList.pop_back();
>   }
59c93
<   switch (opt) {
--->     switch (opt) {
62,63c96,97
<     printHelpScreen(programName);
<     exit(-1);
--->       printHelpScreen(programName);
>       exit(-1);
66,67c100,101
<     inputFile = std::string(optarg);
<     break;
--->       inputFile = std::string(optarg);
>       break;
70,71c104,105
<     outputFile = std::string(optarg);
<     break;
--->       outputFile = std::string(optarg);
>       break;
74,75c108,109
<     startTime = atoi(optarg);
<     break;
--->       startTime = atoi(optarg);
>       break;
78,79c112,113
<     endTime = atoi(optarg);
<     break;
--->       endTime = atoi(optarg);
>       break;
82,83c116,117
<     length = atoi(optarg); // yes, I know the atoi bug
<     break;
--->       length = atoi(optarg); // yes, I know the atoi bug
>       break;
85c119
<   }
--->     }
90,91c124,126
<     std::cerr << "Error: please define an input and output file
with -i and -o\n\n";
<     return(-1);
--->     std::cerr
>         << "Error: please define an input and output file with
-i and -o\n\n";
>     return (-1);
96c131
<     return(-1);
--->     return (-1);
102,103c137
<     }
<     else {
--->     } else {
106c140
<         return(-1);
--->         return (-1);
123c157
<     return(-1);
--->     return (-1);
132a167,170>   /* create the time synchronizer */
>   std::vector<double> offset;
>   offset.resize(streamConfigList.size());
> 
135c173,176
<     std::cerr << streamConfigList[i].parameter->toString();
--->     StreamConfig& conf(streamConfigList[i]);
>     std::cerr << "Stream No:
"<<(int)conf.streamNo<<"(0x"<<std::hex
>         << conf.serialNo<<std::dec<<")\n"
>         << streamConfigList[i].parameter->toString();
137a179>     offset[i] = -1;
143a186>   double beginTime(0);
148c191
<   while(1==1) {
--->   while (streamSerializer.available()) {
155,158c198,205
<       if ((!foundTheora) || ((packet.getStreamType() == ogg_theora)
&&
<           (!(packet.data()[0] & 0x40))))
<         startMarker = true;
< 
--->       if (!startMarker) {
>         if ((!foundTheora) || ((packet.getStreamType() == ogg_theora)
>             &&(!(packet.data()[0] & 0x40)))) {
>           startMarker = true;
>           beginTime = time;
>           offset[packet.getStreamNo()] = time;
>         }
>       }
161,162c208,217
<         // std::cerr << packet.print(2);
<         streamMux << packet;
---> 
>         /* if this stream has no offset calculated, do it now */
>         if (offset[packet.getStreamNo()] < 0) {
>           offset[packet.getStreamNo()] = time;
>           /*          std::cout << "offset for stream
<"<<(int)packet.getStreamNo()
>            <<"> is "<<offset[packet.getStreamNo()]
- beginTime <<std::endl;
>            */
>         }
> 
>         bufferedOutput(streamMux, (time - offset[packet.getStreamNo()]),
packet);
167a223>       flushBuffer(streamMux);
Index: streamMux.cpp
==================================================================RCS file:
/home/CVS/OggVideoTools/src/streamMux.cpp,v
retrieving revision 1.3
diff -r1.3 streamMux.cpp
49c49
<  : repository(_repository)
--->  : timeOfLastPage(0.0), repository(_repository)
133c133
<     OggPage nextPage = outputPageList.front();
--->     OggPage nextPage = outputPageList.back().page;
146a147>     outputPageList.pop_back();
148d148
<     outputPageList.pop_front();
156d155
< 
163c162
<     OggPage nextPage = outputPageList.front();
--->     OggPage nextPage = outputPageList.back().page;
171d169
< //      std::cout << nextPage.print(3);
180c178
<     outputPageList.pop_front();
--->     outputPageList.pop_back();
220,221d217
< //  std::cout << "write page <" <<
streamList[nextID].nextPage.serialno() << "> with time
<"<<nextTime<<">\n";
< 
223c219,229
<   outputPageList.push_back(streamList[nextID].nextPage);
--->   OutputElement elem(streamList[nextID].nextPage,
streamList[nextID].nextTime);
> 
>   std::list<OutputElement>::iterator iter(outputPageList.begin());
> 
>   // -1 is a problem!
>   if (elem.time < 0) {
>       elem.time = timeOfLastPage; // should we care for the stream No?
>   }
> 
>   while((iter != outputPageList.end()) && (elem.time <
iter->time))
>     ++iter;
225c231,235
<   // mark the entry as free
--->   outputPageList.insert(iter, elem);
> 
>   timeOfLastPage = elem.time;
> 
>   // page has been added to the output list, mark the entry as free
267,268d276
< //    std::cerr << "configuring stream <" << i
<<">\n";
< 
303,307d310
< 
< //  std::cout << "inserting packet to stream
<"<<(int)packet.getStreamNo()<<"> with time "
< //            <<
entry.posInterpreter->getActTime()<<"\n";
< 
< 
Index: streamMux.h
==================================================================RCS file:
/home/CVS/OggVideoTools/src/streamMux.h,v
retrieving revision 1.2
diff -r1.2 streamMux.h
72a73,81>     struct OutputElement {
>       OggPage page;
>       double  time;
>       OutputElement(OggPage _page, double _time)
>         : page(_page), time(_time) {}
>     };
> 
>     double           timeOfLastPage;
> 
77c86,87
<     std::list<OggPage> outputPageList;
--->     //std::list<OggPage> outputPageList;
>     std::list<OutputElement> outputPageList;