[MPlayer-users] Re: BUG - Garbled output playing realaudio

Bryan Alton balton at eircom.net
Tue Sep 27 01:38:02 CEST 2005


I think have a fix for this problem.  I have tested it with all the BBC live
real streams and it seems to work.  I haven't tested to see if it interferes
with other Real streams.  A few times Mplayer has stopped, I don't know if
this is as a result of my fix or just the network.  My tests were run on
SuSe 9.3 and I will be building a Windows version as soon as I setup a
compile environment.

The messages in the fix will be gewnerated with -v 1 so that you can see if
packet loss was detected.  I fill in the gaps with the previous packet which
result in a short burst of choppy audio.  If you get a burst of errors, then
you will hear a longer burst of choppy audio but the stream usually settles
down.  I can live with this but I can suggest a better solution if somebody
wants to do the work. 

My changes are to one file libmpdemux/demux_real.c.  A diff file is included
below.  I made the changed to a recent release but demux_real.c hasn't
changed much in months so the changes will work back to other versions.

The cut & paste may have messed some lines but I hope you use it.



*** demux_real.c        2005-09-26 15:53:26.000000000 +0100
--- demux_real.c.orig   2005-09-25 23:47:44.000000000 +0100
*************** typedef struct {
*** 92,105 ****
      int a_bitrate; ///< Audio bitrate
      int v_bitrate; ///< Video bitrate
      int stream_switch; ///< Flag used to switch audio/video demuxing
- 
-     /*  Variables to fix missing buffer in stream audio */
-     int live_stream;            // Flag to indicate that it is a live audio only stream
-     int ms_per_packet;          // millisec per pack - used to detect if a packet is missed
-     int ms_per_block;           // millsec per block (usually made up 16 packets)
-     int ms_per_packet_safety;  //  Since timing is not precise - a safety margin is needed - guess about 20% of packet time.
- 
- 
  } real_priv_t;
  
  /* originally from FFmpeg */
--- 92,97 ----
*************** got_audio:
*** 695,721 ****
                priv->audio_need_keyframe = 0;
            }else 
                dp->pts = (priv->a_pts==timestamp) ? 0 : (timestamp/1000.0f);
- /*************************/
-             
-             if ( (priv->live_stream == 1) && (((sh_audio_t*)ds->sh)->format == mmioFOURCC('c','o','o','k')) ){ // Not sure if missingpacket happen the same way for other formats
-             
-                 demux_packet_t *dp1;
-               if (((timestamp - priv->a_pts) > priv->ms_per_packet_safety)&& ((timestamp - priv->a_pts) < priv->ms_per_block))
-                      mp_msg(MSGT_DEMUX,MSGL_V, "Packet timestamp gap Actual %7d msec Expected %7d Flags %02X\n", timestamp-priv->a_pts,priv->ms_per_packet,dp->flags);
-               if (((timestamp - priv->a_pts) < priv->ms_per_packet))
-                      mp_msg(MSGT_DEMUX,MSGL_V, "Packet timestamp gap too short  Actual %7d msec Expected %7d Flags %02X\n", timestamp-priv->a_pts,priv->ms_per_packet,dp->flags);
- 
-                 while( ((timestamp - priv->a_pts) > priv->ms_per_packet_safety) && (timestamp - priv->a_pts) < priv->ms_per_block) {
-                    dp1 = new_demux_packet(len);
-                    memcpy(dp1->buffer,dp->buffer,len);
-                  priv->a_pts=priv->a_pts + priv->ms_per_packet;
-                  dp1->pos = demuxer->filepos;
-                  dp1->flags = 0;
-                  ds_add_packet(ds, dp1);
-                 }
-              }
- /**************************/
- 
            priv->a_pts=timestamp;
            dp->pos = demuxer->filepos;
            dp->flags = (flags & 0x2) ? 0x10 : 0;
--- 687,692 ----
*************** static demuxer_t* demux_open_real(demuxe
*** 1158,1169 ****
  
        if (!strncmp(mimet,"audio/",6)) {
          if (strstr(mimet,"x-pn-realaudio") || strstr(mimet,"x-pn-multirate-realaudio")) {
- 
-                 if (strstr(mimet,"x-pn-multirate-realaudio-live" )) {
-                   priv->live_stream = 1;                
-                 } else
-                   priv->live_stream = 0;
- 
                // skip unknown shit - FIXME: find a better/cleaner way!
                len=codec_data_size;
                tmp = stream_read_dword(demuxer->stream);
--- 1130,1135 ----
*************** static demuxer_t* demux_open_real(demuxe
*** 1392,1406 ****
                            ((short*)(sh->wf+1))[4]=codecdata_length;
  //                        stream_read(demuxer->stream, ((char*)(sh->wf+1))+6, 24); // extras
                            stream_read(demuxer->stream, ((char*)(sh->wf+1))+10, codecdata_length); // extras
-                           priv->ms_per_packet = (long) ((coded_frame_size*8*1000L)/(sh->wf->nAvgBytesPerSec)); // I think variable should be avgbits/sec
-                           priv->ms_per_packet_safety = priv->ms_per_packet + (priv->ms_per_packet/5) ; // Add 20% for the safety margin
-                           priv->ms_per_block = priv->ms_per_packet * sub_packet_h;
-                           priv->ms_per_packet--;  // Empircally - round down to suit observed actual gaps
-                             if (priv->live_stream == 1){
-                             mp_msg(MSGT_DEMUX,MSGL_V,"Live stream: Subpacksize %d sub packet h %d  Flavour %d coded frame size %d codecdatalength %d avg byte/sec %d channels %d\n",sub_packet_size,sub_packet_h,flavor,coded_frame_size,codecdata_length, sh->wf->nAvgBytesPerSec, sh->channels);
-                             mp_msg(MSGT_DEMUX,MSGL_V,"Live stream: Expected range ms/packet %d to %d     ms per block %d\n",priv->ms_per_packet,priv->ms_per_packet_safety, priv->ms_per_block);
-                             }
-       
                            break;
                        case MKTAG('r', 'a', 'a', 'c'):
                        case MKTAG('r', 'a', 'c', 'p'):
--- 1358,1363 ----






More information about the MPlayer-users mailing list