Re: [DVBCUT-user] [PATCH] Fix audio framing in streamdata.cpp

2007-05-28 Thread Wolfram Gloger
Hi,

 Hmm... `bytes' is the distance between two items, and should be an
 integer multiple of the frame size.

But items also include the (sometime) non-aligned PES packet headers;
these are not deleted in audio_addpts.  For those, the distance is
arbitrary, see the log output below.

  By debugging :-)   I noticed audio frames were written with size
  1184 even though 576 should have been the size always.
 
 Is it always 1184, or does the value differ?

Ok, I have just applied

--- dvbcut-orig/src/mpgfile.cpp~Sun May 27 17:24:25 2007
+++ dvbcut-orig/src/mpgfile.cpp Mon May 28 12:15:51 2007
@@ -619,6 +619,7 @@
   if (bytes0)
   {
 pts_t pts=audiopts[a]-audiooffset[a];
+   fprintf(stderr, mux.put audio %d %lld\n, bytes, pts);
 
mux.putpacket(audiostream(a),sd-getdata(),bytes,pts,pts,MUXER_FLAG_KEY);
 
 sd-discard(bytes);

and I append the output for otherwise unchanged dvbcut-35
for a stream with unaligned audio.
Maybe you can make something out of it?
It doesn't include the case with false positive from mpaframe, though.

 No, if the error occurs once in a while, it must be something else.

I have two separate problems, but the one with false positive from
mpaframe() happens very rarely, and is handled by my patch.

 I think that should be handled inside the caller, i.e. audio_addpts().
 Actually, the whole syncing business should be handled there. ac3frame()
 and mpaframe() should just return the size of the frame, or 0 if there
 is no valid header.

Yes!  That is exactly what my patch does.

 There is, by the way, an indicator for the most likely next position:
 `bufferposition'. But there is also another bug: If audio_addpts() finds
 a valid frame, it will insert a new item. But it's not an item for the
 frame itself because `bufferposition' has already been updated and
 points *after* the frame just checked. :-(

Yes!  That is why I changed the {mpa,ac3}frame calling so this
can be handled correctly (in a followup patch).

 but I thought that the buffer shifts through the
 file with only the already framed data being discarded, so when
 audio_addpts is called _again_ the last frame (which is now the first
 frame) will be detected just fine?
 
 It should. Actually, it should be in sync as well. But it isn't :-(
  
  
  Ok, IMHO the root of the problem is that potentially unaligned items
  are used for framing the audio, and items with an artificial
  STREAM_ITEM_FLAG_DATA_ALIGNMENT_INDICATOR are mixed in.
 
 We don't care about that flag any longer. You could as well remove it.

Ok..

  Instead, we
  should abandon using the PES packet headers for framing and create a
  separate type of item (with a new flag STREAM_ITEM_FLAG_FRAME) for the
  parsed frame boundaries.  My next patch will do exactly this.
 
 Beware! The PES packet headers contain the PTS timestamps we need, and
 they're also required for file positioning.

I'm not deleting them, just not using them for audio output.

 Hmm. Doesn't that mean that your patch has no effect at all? Or, vice
 versa, that the original code worked fine even when there were sync
 problems now and then?

The patch just fixes the very rare false positive from mpaframe.  It
doesn't solve the sync problem.  I think I'll post my current complete
patch in another thread so maybe everything becomes clearer.

Regards,
Wolfram


mux.put audio 960 3721
mux.put audio 576 5881
mux.put audio 288 8041
mux.put audio 864 10201
mux.put audio 576 12361
mux.put audio 384 14521
mux.put audio 768 16681
mux.put audio 576 18841
mux.put audio 480 21001
mux.put audio 672 23161
mux.put audio 576 25321
mux.put audio 576 27481
mux.put audio 576 29641
mux.put audio 576 31801
mux.put audio 576 33961
mux.put audio 96 36121
mux.put audio 1056 38281
mux.put audio 576 40441
mux.put audio 192 42601
mux.put audio 960 44761
mux.put audio 576 46921
mux.put audio 288 49081
mux.put audio 864 51241
mux.put audio 576 53401
mux.put audio 384 55561
mux.put audio 768 57721
mux.put audio 576 59881
mux.put audio 480 62041
mux.put audio 672 64201
mux.put audio 576 66361
mux.put audio 576 68521
mux.put audio 576 70681
mux.put audio 576 72841
mux.put audio 576 75001
mux.put audio 96 77161
mux.put audio 1056 79321
mux.put audio 576 81481
mux.put audio 192 83641
mux.put audio 960 85801
mux.put audio 576 87961
mux.put audio 288 90121
mux.put audio 864 92281
mux.put audio 576 94441
mux.put audio 384 96601
mux.put audio 768 98761
mux.put audio 576 100921
mux.put audio 480 103081
mux.put audio 672 105241
mux.put audio 576 107401
mux.put audio 576 109561
mux.put audio 576 111721
mux.put audio 576 113881
mux.put audio 576 116041
mux.put audio 96 118201
mux.put audio 1056 120361
mux.put audio 576 122521
mux.put audio 192 124681
mux.put audio 960 126841
mux.put audio 576 129001
mux.put audio 288 131161
mux.put audio 864 133321
mux.put audio 576 135481
mux.put audio 384 137641
mux.put 

[DVBCUT-user] [PATCH] Fix audio framing in streamdata.cpp

2007-05-27 Thread Wolfram Gloger
Hi,

I still get false hits from streamdata.cpp:mpaframe() for audio
streams where MPEG audio frames aren't aligned to packet boundaries.

The reason is that mpaframe() simply looks for a possible MPA header,
and then looks for another MPA header at an offset of the framesize
_or anywhere later_.  So the following can happen:

Buffer Offset  Content 
===
x  MPA frame start
...
x+120  Packet boundary (Item points here)
...
x+129  Invalid MPA (is_mpa() returns true but it's
not really the start of a frame)
...
x+576  MPA frame start
...
x+2*576MPA frame start
...

mpaframe() in this case will happily detect an MPA frame between x+129
and x+2*576.  The correct frame, however, is between x+576 and
x+2*576.  With the current code, this means that the frame starting at
x+576 is missed.

The attached patch fixes this by only considering MPA headers which
are _exactly_ one frame size apart.  (All other MPEG parsers that I
know do this also.)  It also fixes a potential buffer overflow in
ac3frame().

I changed the interface for mpaframe() and ac3frame() so they return
the start _and_ size of valid audio frames.  This will be needed in
another patch which I will submit soon.

BTW the needsync code in audio_addpts() IMHO does absolutely nothing
and should be removed.  All items which have no pts are removed at
the start of the function, and only items which do have pts are added.
So, the following loop always terminates immediately:

if (needsync) {
  needsync=false;

  for(;it!=items.end();++it)
if (it-headerhaspts())
  // header carries PTS
  break;
...

Regards,
Wolfram.

dvbcut-frame0.diff
Description: Binary data
-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/___
DVBCUT-user mailing list
DVBCUT-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dvbcut-user


Re: [DVBCUT-user] [PATCH] Fix audio framing in streamdata.cpp

2007-05-27 Thread Michael Riepe
Hi!

Wolfram Gloger wrote:

 I still get false hits from streamdata.cpp:mpaframe() for audio
 streams where MPEG audio frames aren't aligned to packet boundaries.
 
 The reason is that mpaframe() simply looks for a possible MPA header,
 and then looks for another MPA header at an offset of the framesize
 _or anywhere later_.  So the following can happen:
 
 Buffer Offset  Content 
 ===
 x  MPA frame start
 ...
 x+120  Packet boundary (Item points here)
 ...
 x+129  Invalid MPA (is_mpa() returns true but it's
 not really the start of a frame)
 ...
 x+576  MPA frame start
 ...
 x+2*576MPA frame start
 ...
 
 mpaframe() in this case will happily detect an MPA frame between x+129
 and x+2*576.  The correct frame, however, is between x+576 and
 x+2*576.  With the current code, this means that the frame starting at
 x+576 is missed.

Yep. That's why there is the sync code. After a while, the program
should lock to the correct position automatically.

 The attached patch fixes this by only considering MPA headers which
 are _exactly_ one frame size apart.  (All other MPEG parsers that I
 know do this also.)  It also fixes a potential buffer overflow in
 ac3frame().

That will work fine in a perfect world where no transmission errors occur.

I noticed that you drop out of the loop in audio_addpts() (line 182 in
your version) when framesize == 0. Doesn't that mean that a single
missing frame header will stop audio pts processing prematurely?

 I changed the interface for mpaframe() and ac3frame() so they return
 the start _and_ size of valid audio frames.  This will be needed in
 another patch which I will submit soon.
 
 BTW the needsync code in audio_addpts() IMHO does absolutely nothing
 and should be removed.  All items which have no pts are removed at
 the start of the function, and only items which do have pts are added.
 So, the following loop always terminates immediately:
 
 if (needsync) {
   needsync=false;
 
   for(;it!=items.end();++it)
 if (it-headerhaspts())
   // header carries PTS
   break;

I agree that the for loop seems to terminate immediately and should be
removed. But what about the rest of the code? It used to be executed
whenever there was a frame synchronization problem. With your patch,
it's only executed once at the beginning of the outer (while) loop
because you deleted the assignment needsync=true later on (line 182 in
revision 35) and decided to leave the loop instead.

Besides that, your code will never return the length of the last frame
that begins in the buffer because {ac3,mpa}frame() can't access the
following frame header. But what happens if the frames are aligned?

I'm afraid you opened a big can of worms here.

-- 
Michael Tired Riepe [EMAIL PROTECTED]
X-Tired: Each morning I get up I die a little

-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
DVBCUT-user mailing list
DVBCUT-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dvbcut-user


Re: [DVBCUT-user] [PATCH] Fix audio framing in streamdata.cpp

2007-05-27 Thread Wolfram Gloger
 Delivery-Date: Sun, 27 May 2007 17:00:50 +0200
 Received-SPF: pass (mxeu11: domain of lists.sourceforge.net designates 
 66.35.250.225 as permitted sender) client-ip=66.35.250.225; [EMAIL 
 PROTECTED]; helo=lists-outbound.sourceforge.net;
Hi,

 Yep. That's why there is the sync code. After a while, the program
 should lock to the correct position automatically.

Sorry, I don't follow.  Whenever an unaligned item is encountered
(through
  it=nx;
  ++nx;
  pts=it-headerpts();
) at the end of the loop, the situation I described can
happen again.

I agree it wouldn't be a problem if the situation only occurred once
at the start of the stream, but we have already seem that for some
streams unaligned packets happen regularly.

 That will work fine in a perfect world where no transmission errors occur.
 
 I noticed that you drop out of the loop in audio_addpts() (line 182 in
 your version) when framesize == 0. Doesn't that mean that a single
 missing frame header will stop audio pts processing prematurely?

Indeed, that is a perhaps a mistake -- maybe I should have posted the
complete patch which I have in mind -- but I believe that doesn't
change anything compared to the original version, see below.

 I agree that the for loop seems to terminate immediately and should be
 removed. But what about the rest of the code? It used to be executed
 whenever there was a frame synchronization problem. With your patch,
 it's only executed once at the beginning of the outer (while) loop
 because you deleted the assignment needsync=true later on (line 182 in
 revision 35) and decided to leave the loop instead.

Yes that is perhaps a mistake.  But consider the original code.
How can needsync=true come about?
Only if ptsplus==0, and that means that mpaframe() or
ac3frame() has returned 0.  And I can see no way of that
happening without pos+2=len, which means that the condition

if (pos+2=len)
  break;

in audio_addpts() would already have left the loop!

 Besides that, your code will never return the length of the last frame
 that begins in the buffer because {ac3,mpa}frame() can't access the
 following frame header.

True (and I would argue you cannot be certain that what follows really
is a valid frame), but I thought that the buffer shifts through the
file with only the already framed data being discarded, so when
audio_addpts is called _again_ the last frame (which is now the first
frame) will be detected just fine?

 But what happens if the frames are aligned?

Sorry, I don't understand that question.

 I'm afraid you opened a big can of worms here.

I tested with several streams and can't see any change in behaviour.
Can you?

Regards,
Wolfram


-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
DVBCUT-user mailing list
DVBCUT-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dvbcut-user


Re: [DVBCUT-user] [PATCH] Fix audio framing in streamdata.cpp

2007-05-27 Thread Michael Riepe
Hi again!

Wolfram Gloger wrote:
Delivery-Date: Sun, 27 May 2007 17:00:50 +0200
Received-SPF: pass (mxeu11: domain of lists.sourceforge.net designates 
66.35.250.225 as permitted sender) client-ip=66.35.250.225; [EMAIL 
PROTECTED]; helo=lists-outbound.sourceforge.net;
 
 Hi,
 
 
Yep. That's why there is the sync code. After a while, the program
should lock to the correct position automatically.
 
 
 Sorry, I don't follow.  Whenever an unaligned item is encountered
 (through
   it=nx;
   ++nx;
   pts=it-headerpts();
 ) at the end of the loop, the situation I described can
 happen again.

This code really is confusing. And sometimes wrong.

I don't understand how dvbcut can actually encounter so many unaligned
frames at all. audio_addpts() operates on a single buffer that
(theoretically, i.e. if the file isn't damaged) contains a number of
consecutive frames, plus maybe a partial frame at the beginning and at
the end. And once it's in sync, it should stay in sync. Advancing to the
next item should not have any effect as long as `bufferposition' (the
index into the buffer) isn't updated as well.

By the way, how do you detect the sync failures? And how often do they
happen?

 I agree it wouldn't be a problem if the situation only occurred once
 at the start of the stream, but we have already seem that for some
 streams unaligned packets happen regularly.

Well, if they're unaligned, all of them usually are. The question is how
often dvbcut will run out of sync. Probably not with every single frame
or (PES) packet. Maybe once with every call to audio_addpts()?

That will work fine in a perfect world where no transmission errors occur.

I noticed that you drop out of the loop in audio_addpts() (line 182 in
your version) when framesize == 0. Doesn't that mean that a single
missing frame header will stop audio pts processing prematurely?
 
 
 Indeed, that is a perhaps a mistake -- maybe I should have posted the
 complete patch which I have in mind -- but I believe that doesn't
 change anything compared to the original version, see below.
 
 
I agree that the for loop seems to terminate immediately and should be
removed. But what about the rest of the code? It used to be executed
whenever there was a frame synchronization problem. With your patch,
it's only executed once at the beginning of the outer (while) loop
because you deleted the assignment needsync=true later on (line 182 in
revision 35) and decided to leave the loop instead.
 
 
 Yes that is perhaps a mistake.  But consider the original code.
 How can needsync=true come about?
 Only if ptsplus==0, and that means that mpaframe() or
 ac3frame() has returned 0.  And I can see no way of that
 happening without pos+2=len, which means that the condition
 
 if (pos+2=len)
   break;
 
 in audio_addpts() would already have left the loop!

Actually, testing for `pos+2=len' at that point was a bug. It should
have been `pos  len' because mpaframe updated pos to point at the end
of the frame (or even further). Therefore, it is possible that pos==len
and ptsplus!=0 if frames are aligned.

But you're right - after re-indenting the code I noticed that
{ac3,mpa}frame() will only return 0 when they reach the end of the buffer.

Besides that, your code will never return the length of the last frame
that begins in the buffer because {ac3,mpa}frame() can't access the
following frame header.
 
 
 True (and I would argue you cannot be certain that what follows really
 is a valid frame),

I could also argue that you can't claim a frame being invalid just
because it's not followed by another frame ;-)

 but I thought that the buffer shifts through the
 file with only the already framed data being discarded, so when
 audio_addpts is called _again_ the last frame (which is now the first
 frame) will be detected just fine?

It should. Actually, it should be in sync as well. But it isn't :-(

I guess we're currently barking at the wrong tree. The fact that
audio_addpts() obviously doesn't keep sync is not the fault auf
{ac3,mpa}frame(). It's the fault of audio_addpts(), or the functions
calling it, i.e. mpgfile::savempg() and mpgfile::playaudio(). You
probably can forget about the latter because it calls audio_addpts()
only once.

 I tested with several streams and can't see any change in behaviour.

How did you verify that - compare the output files?

-- 
Michael Tired Riepe [EMAIL PROTECTED]
X-Tired: Each morning I get up I die a little

-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
DVBCUT-user mailing list
DVBCUT-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dvbcut-user