[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