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;