Infinite loop while MP3 encoding : mp3enc_bitsrteam.c

Infinite loop while MP3 encoding : mp3enc_bitsrteam.c

In the current implementation of mp3enc_writeFrame() inside the file mp3enc_bitstream.c, it is possible that we can encounter infinite loop while executing the code block below.

Whenever the code below gets called with resr_mod_slot = 1, we end up with an infinite loop.

Any suggestions on how to fix this ?

 do {

          Ipp32s left = resr_mod_slot;

          len = left < bytes ? left : bytes;

          for (i = 0; i < len; i++)
              *ptr_out++ = *ptr_main++;

          res += len;
          bytes -= len;
          resr_bytes -= len;
          resr_mod_slot -= len;
          if (resr_mod_slot < 0)
              resr_mod_slot += slot;

          if (len == left && si_num > 0) {
              for (i = 0; i < si_bytes; i++)
                  *ptr_out++ =
                      si_buf[si_beg][i];
              res += si_bytes;
              resr_bytes -= si_bytes;
              resr_mod_slot -= si_bytes;
              if (resr_mod_slot < 0)
                  resr_mod_slot += slot;
              si_num--;
              si_beg++;
              if (si_beg >= SI_MAX)
                  si_beg = 0;
          }
      } while(bytes)

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hi,

Could you specify more entry conditions to reproduce the issue? It is now visible from debugging session even with  resr_mod_slot = 1.

Regards,
Sergey

Hi Sergey,

Thanks for following up.  We have dug a bit further and here are some updates from us:

In the loop:

 do {
          Ipp32s left = resr_mod_slot;
          len = left < bytes ? left : bytes;
          for (i = 0; i < len; i++)
              *ptr_out++ = *ptr_main++;
          res += len;
          bytes -= len;
          resr_bytes -= len;
          resr_mod_slot -= len;
          if (resr_mod_slot < 0)
              resr_mod_slot += slot;
          if (len == left && si_num > 0) {
              for (i = 0; i < si_bytes; i++)
                  *ptr_out++ =
                      si_buf[si_beg][i];
              res += si_bytes;
              resr_bytes -= si_bytes;
              resr_mod_slot -= si_bytes;
              if (resr_mod_slot < 0)
                  resr_mod_slot += slot;
              si_num--;
              si_beg++;
              if (si_beg >= SI_MAX)
                  si_beg = 0;
          }
      } while(bytes)

si_num is set to 1 when we get to this loop, and len == left twice, and this leads to a loop.

So it is two conditions:

resr_mod_slot <  bytes and si_num=1

and

0 < slot_size – si_bytes  < bytes , in our case slot_size=144 and si_bytes=38 it is constant,

So our condition is 106 < bytes

First condition will cause first entrance into the second will cause infinite loop, because we will never come into if condition. Our resr_mod_slot will be 0, si_num=0 and bytes not 0 at this point, leading to an infinite loop.

Based on this, any thoughts?

We also are wondering if, to break free of the infinite loop, there could be changes to the while condition as follows:

while(bytes && (resr_mod_slot !=0 || si_num !=0));

Instead of what exists, but we are unsure of any ill side effects of doing this as of yet, as this "infinite loop" only happens after several hours (sometimes days) of many concurrent encoding sessions.

Any help is appreciated, including if this is a known issue in 6.1.6 that was fixed in a later version, but all I see in any later versions that *could* be involved in this, is the following line:

          resr_mod_slot -= len;
          if (resr_mod_slot < 0) // It is impossible to change! There will be an error!
              resr_mod_slot += slot;

Which is basically changed ONLY by a comment saying that resr_mod_slot < 0 cannot change, or there will be an error.

So to summarize:
- In general, any thoughts on solving this problem?
- Is our "solution" viable?
- Why was the above comment added?  Are there known issues fixed in later versions that involve infinite loops?

Also note we always pass in data.  Never do we pass in "NULL" values.

Cheers,
Paul

Leave a Comment

Please sign in to add a comment. Not a member? Join today