Here is a new version of the mplayer patch for anyone that is
interested:

Code:
--------------------
    Index: demux_real.c
  ===================================================================
  RCS file: /cvsroot/mplayer/main/libmpdemux/demux_real.c,v
  retrieving revision 1.72
  diff -u -r1.72 demux_real.c
  --- demux_real.c        5 Aug 2005 19:57:46 -0000       1.72
  +++ demux_real.c        3 Oct 2005 06:59:31 -0000
  @@ -92,6 +92,13 @@
  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 suitable 
live audio only stream
  +    int ms_per_packet;          // estimated millisec per packet 
  +    int ms_per_block;           // estimated millisec per block which is a 
multiple of packets defined by stream parameters
  +    int ms_per_packet_safety;  //  estimated millisec per packet with a 
margin 
  +    char *previous_pkt,*previous_pkt2;         // Copy of previous packet
  } real_priv_t;
  
  /* originally from FFmpeg */
  @@ -687,6 +694,41 @@
  priv->audio_need_keyframe = 0;
  }else 
  dp->pts = (priv->a_pts==timestamp) ? 0 : (timestamp/1000.0f);
  +/*
  + *            Only use this method of packet loss detection & fix for live 
audio streams of cook V5 decoder - typically from BBC live streams  
  + */
  +            if ( (priv->live_stream == 1) && (((sh_audio_t *)ds->sh)->format 
== mmioFOURCC('c','o','o','k')) ){ 
  +                demux_packet_t *dp1;
  +                int toggle =0;
  +
  +               if (((timestamp - priv->a_pts) > priv->ms_per_packet_safety) 
&& ((timestamp - priv->a_pts) < priv->ms_per_block))
  +                     mp_msg(MSGT_DEMUX,MSGL_V, "Packets lost: timestamp gap  
Actual %d msec Expected %d Flags %02X\n", timestamp-priv->a_pts, 
priv->ms_per_packet,dp->flags);
  +               if ((timestamp - priv->a_pts) < (priv->ms_per_packet-2))   // 
This is a diagnostic msg - allow a margin of 2 based on observations of streams 
to reduce "noise"
  +                     mp_msg(MSGT_DEMUX,MSGL_V, "Packet timestamp gap too 
short  Actual %d msec Expected %d Flags %02X\n", timestamp-priv->a_pts, 
priv->ms_per_packet,dp->flags);
  +
  +/*              Detected some packets dropped by server by gap in the 
timestamp.  This loops fills in the missing packets with copies of previous 
packets 
  + *              as an empty buffer would be heard as a click. Packets are 
striped but also alternate - so previous packet is not the packet closest in 
time.
  + */
  +                if ((timestamp - priv->a_pts) < priv->ms_per_block)          
      // Only insert buffer if it is not a whole block missing 
  +                 while( ((timestamp - priv->a_pts) > 
priv->ms_per_packet_safety) ) {
  +                   dp1 = new_demux_packet(len);
  +                   if (toggle == 1) {                           // This 
chooses which previous packet to pick that is closest in time to the missing 
packet
  +                     memcpy(dp1->buffer,priv->previous_pkt,len);
  +                     toggle = 0;
  +                   }
  +                   else {                                       // When 
there is more than one missing packet toggle chooses which previous packet is 
most suitable.
  +                     memcpy(dp1->buffer,priv->previous_pkt2,len);
  +                     toggle = 1;
  +                  }    
  +                  priv->a_pts=priv->a_pts + priv->ms_per_packet;
  +                  dp1->pos = demuxer->filepos;
  +                  dp1->flags = 0;
  +                  ds_add_packet(ds, dp1);
  +                 }
  +            memcpy(priv->previous_pkt2,priv->previous_pkt,len);  // Ensure 
that the last two good packets are kept to use to replace missing packets
  +            memcpy(priv->previous_pkt,dp->buffer,len);
  +             }
  +
  priv->a_pts=timestamp;
  dp->pos = demuxer->filepos;
  dp->flags = (flags & 0x2) ? 0x10 : 0;
  @@ -1358,6 +1400,28 @@
  ((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
  +/*
  + *                      Initialise variables used for packet loss detection 
in live audio streams using cook V5        
  + *                       Although in case "cook" Test for cook format 
because 'sipr' & 'atrc' fall through into cook  
  + */
  +                           if ( (sh->format == MKTAG('c', 'o', 'o', 'k')) && 
(version == 5) && strstr(mimet,"x-pn-multirate-realaudio-live")) {
  +                             priv->live_stream = 1; 
  +                            priv->ms_per_packet = (long) ( 
(coded_frame_size*8*1000L)/(sh->wf->nAvgBytesPerSec)); // Variable name 
nAvgBitsPerSec would be more appropriate
  +                            priv->ms_per_packet_safety = priv->ms_per_packet 
+ (priv->ms_per_packet/5) ;          // Add 20% for the safety margin as packet 
timing based on AvgBitsPerSec is not accurate
  +                            priv->ms_per_block = priv->ms_per_packet * 
sub_packet_h;
  +
  +                            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);
  +
  +                            priv->previous_pkt  = malloc(coded_frame_size);
  +                            priv->previous_pkt2 = malloc(coded_frame_size);
  +                            if (!priv->previous_pkt || !priv->previous_pkt2){
  +                              mp_msg(MSGT_DEMUX,MSGL_V,"Couldn't allocate 
memory to a packet buffer\n");
  +                            memset(priv->previous_pkt, 0, coded_frame_size);
  +                            memset(priv->previous_pkt2, 0, coded_frame_size);
  +
  +                             }
  +                           }
  break;
  case MKTAG('r', 'a', 'a', 'c'):
  case MKTAG('r', 'a', 'c', 'p'):
  @@ -1742,6 +1806,10 @@
  for(i=0; i<MAX_STREAMS; i++)
  if(priv->index_table[i])
  free(priv->index_table[i]);
  +        if(priv->previous_pkt)
  +              free(priv->previous_pkt);
  +        if(priv->previous_pkt2)
  +               free(priv->previous_pkt2);
  free(priv);
  }
--------------------


Note: I couldn't get the patch to automatically patch the file so I had
to manualy patch it. I applied it to v1.73 of demux_real.c.

I have been running this on Windows this morning and it seems to be
better than the previous one as the glitches are a lot less noticable.

Neil


-- 
Neil Sleightholm
_______________________________________________
Discuss mailing list
[email protected]
http://lists.slimdevices.com/lists/listinfo/discuss

Reply via email to