[MPlayer-dev-eng] [PATCH] Seeking in multirate RealMedia files.
Zuxy Meng
zuxy.meng at gmail.com
Mon Feb 9 16:53:38 CET 2009
Hi,
The attached implements seeking in multirate RM files, with some code
clean up. Now both normal (interleaved) and multirate RM files
maintain current_apacket and current_vpacket and use these counters in
seeking. Tested with several normal and multirate files and seemed to
work fine.
--
Zuxy
Beauty is truth,
While truth is beauty.
PGP KeyID: E8555ED6
-------------- next part --------------
Index: libmpdemux/demux_real.c
===================================================================
--- libmpdemux/demux_real.c ??? 28493?
+++ libmpdemux/demux_real.c ??????
@@ -95,8 +95,6 @@
int video_curpos; ///< Current file position for video demuxing
int a_num_of_packets; ///< Number of audio packets
int v_num_of_packets; ///< Number of video packets
- int a_idx_ptr; ///< Audio index position pointer
- int v_idx_ptr; ///< Video index position pointer
int a_bitrate; ///< Audio bitrate
int v_bitrate; ///< Video bitrate
int stream_switch; ///< Flag used to switch audio/video demuxing
@@ -558,9 +556,9 @@
/* Handle audio/video demxing switch for multirate files (non-interleaved) */
if (priv->is_multirate && priv->stream_switch) {
- if (priv->a_idx_ptr >= priv->index_table_size[demuxer->audio->id])
+ if (priv->current_apacket >= priv->index_table_size[demuxer->audio->id])
demuxer->audio->eof = 1;
- if (priv->v_idx_ptr >= priv->index_table_size[demuxer->video->id])
+ if (priv->current_vpacket >= priv->index_table_size[demuxer->video->id])
demuxer->video->eof = 1;
if (demuxer->audio->eof && demuxer->video->eof)
return 0;
@@ -568,8 +566,8 @@
stream_seek(demuxer->stream, priv->audio_curpos); // Get audio
else if (demuxer->audio->eof && !demuxer->video->eof)
stream_seek(demuxer->stream, priv->video_curpos); // Get video
- else if (priv->index_table[demuxer->audio->id][priv->a_idx_ptr].timestamp <
- priv->index_table[demuxer->video->id][priv->v_idx_ptr].timestamp)
+ else if (priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp <
+ priv->index_table[demuxer->video->id][priv->current_vpacket].timestamp)
stream_seek(demuxer->stream, priv->audio_curpos); // Get audio
else
stream_seek(demuxer->stream, priv->video_curpos); // Get video
@@ -601,7 +599,9 @@
if (len < 12){
mp_msg(MSGT_DEMUX, MSGL_V,"%08X: packet v%d len=%d \n",(int)demuxer->filepos,(int)version,(int)len);
mp_msg(MSGT_DEMUX, MSGL_WARN,"bad packet len (%d)\n", len);
- stream_skip(demuxer->stream, len);
+ if (!len)
+ while (!stream_read_char(demuxer->stream))
+ ;
continue; //goto loop;
}
@@ -804,18 +804,15 @@
} // codec_id check, codec default case
}
// we will not use audio index if we use -idx and have a video
- if(!demuxer->video->sh && index_mode == 2 && (unsigned)demuxer->audio->id < MAX_STREAMS)
+ if(((!demuxer->video->sh && index_mode == 2) || priv->is_multirate) && (unsigned)demuxer->audio->id < MAX_STREAMS) {
while (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id] &&
- timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp)
+ timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp) {
priv->current_apacket += 1;
-
- if(priv->is_multirate)
- while (priv->a_idx_ptr + 1 < priv->index_table_size[demuxer->audio->id] &&
- timestamp > priv->index_table[demuxer->audio->id][priv->a_idx_ptr + 1].timestamp) {
- priv->a_idx_ptr++;
- priv->audio_curpos = stream_tell(demuxer->stream);
priv->stream_switch = 1;
}
+ if (priv->stream_switch)
+ priv->audio_curpos = stream_tell(demuxer->stream);
+ }
// If we're reordering audio packets and we need more data get it
if (audioreorder_getnextpk)
@@ -1038,19 +1035,16 @@
if(len>0) stream_skip(demuxer->stream, len);
}
}
- if ((unsigned)demuxer->video->id < MAX_STREAMS)
+ if ((unsigned)demuxer->video->id < MAX_STREAMS) {
while (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id] &&
- timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp)
+ timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp) {
priv->current_vpacket += 1;
-
- if(priv->is_multirate)
- while (priv->v_idx_ptr + 1 < priv->index_table_size[demuxer->video->id] &&
- timestamp > priv->index_table[demuxer->video->id][priv->v_idx_ptr + 1].timestamp) {
- priv->v_idx_ptr++;
- priv->video_curpos = stream_tell(demuxer->stream);
priv->stream_switch = 1;
}
-
+ if (priv->stream_switch)
+ priv->video_curpos = stream_tell(demuxer->stream);
+ }
+
return 1;
}
@@ -1167,16 +1161,19 @@
case MKTAG('C', 'O', 'N', 'T'):
{
/* Content description header */
- char *buf;
+ char *buf, *tmp;
int len;
len = stream_read_word(demuxer->stream);
if (len > 0)
{
buf = malloc(len+1);
+ tmp = malloc(2*len+1);
stream_read(demuxer->stream, buf, len);
buf[len] = 0;
- demux_info_add(demuxer, "name", buf);
+ demux_info_add(demuxer, "name",
+ demux_legacy_recode(buf, tmp, 2*len));
+ free(tmp);
free(buf);
}
@@ -1184,9 +1181,12 @@
if (len > 0)
{
buf = malloc(len+1);
+ tmp = malloc(2*len+1);
stream_read(demuxer->stream, buf, len);
buf[len] = 0;
- demux_info_add(demuxer, "author", buf);
+ demux_info_add(demuxer, "author",
+ demux_legacy_recode(buf, tmp, 2*len));
+ free(tmp);
free(buf);
}
@@ -1194,9 +1194,12 @@
if (len > 0)
{
buf = malloc(len+1);
+ tmp = malloc(2*len+1);
stream_read(demuxer->stream, buf, len);
buf[len] = 0;
- demux_info_add(demuxer, "copyright", buf);
+ demux_info_add(demuxer, "copyright",
+ demux_legacy_recode(buf, tmp, 2*len));
+ free(tmp);
free(buf);
}
@@ -1204,9 +1207,12 @@
if (len > 0)
{
buf = malloc(len+1);
+ tmp = malloc(2*len+1);
stream_read(demuxer->stream, buf, len);
buf[len] = 0;
- demux_info_add(demuxer, "comment", buf);
+ demux_info_add(demuxer, "comment",
+ demux_legacy_recode(buf, tmp, 2*len));
+ free(tmp);
free(buf);
}
break;
@@ -1273,7 +1279,7 @@
int coded_frame_size;
int codecdata_length;
int i;
- char *buft;
+ char *buft, *tmp;
int hdr_size;
mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id);
mp_msg(MSGT_DEMUX,MSGL_V,"Found audio stream!\n");
@@ -1286,23 +1292,32 @@
// Name, author, (c) are also in CONT tag
if ((i = stream_read_char(demuxer->stream)) != 0) {
buft = malloc(i+1);
+ tmp = malloc(2*i+1);
stream_read(demuxer->stream, buft, i);
buft[i] = 0;
- demux_info_add(demuxer, "Name", buft);
+ demux_info_add(demuxer, "Name",
+ demux_legacy_recode(buft, tmp, 2*i));
+ free(tmp);
free(buft);
}
if ((i = stream_read_char(demuxer->stream)) != 0) {
buft = malloc(i+1);
+ tmp = malloc(2*i+1);
stream_read(demuxer->stream, buft, i);
buft[i] = 0;
- demux_info_add(demuxer, "Author", buft);
+ demux_info_add(demuxer, "Author",
+ demux_legacy_recode(buft, tmp, 2*i));
+ free(tmp);
free(buft);
}
if ((i = stream_read_char(demuxer->stream)) != 0) {
buft = malloc(i+1);
+ tmp = malloc(2*i+1);
stream_read(demuxer->stream, buft, i);
buft[i] = 0;
- demux_info_add(demuxer, "Copyright", buft);
+ demux_info_add(demuxer, "Copyright",
+ demux_legacy_recode(buft, tmp, 2*i));
+ free(tmp);
free(buft);
}
if ((i = stream_read_char(demuxer->stream)) != 0)
@@ -1731,9 +1746,6 @@
break;
}
- if(priv->is_multirate)
- demuxer->seekable = 0; // No seeking yet for multirate streams
-
// detect streams:
if(demuxer->video->id==-1 && v_streams>0){
// find the valid video stream:
@@ -1835,7 +1847,7 @@
break;
}
}
- else if (rel_seek_secs < 0)
+ else if (rel_seek_secs < 0) {
while ((cur_timestamp - priv->index_table[vid][priv->current_vpacket].timestamp) < - rel_seek_secs * 1000){
priv->current_vpacket -= 1;
if (priv->current_vpacket < 0) {
@@ -1843,12 +1855,16 @@
break;
}
}
- next_offset = priv->index_table[vid][priv->current_vpacket].offset;
- priv->audio_need_keyframe = 1;
+ }
+ priv->video_curpos = priv->index_table[vid][priv->current_vpacket].offset;
+ priv->audio_need_keyframe = !priv->is_multirate;
priv->video_after_seek = 1;
}
- else if (streams & 2) {
- cur_timestamp = priv->index_table[aid][priv->current_apacket].timestamp;
+ if (streams & 2) {
+ if (!(streams & 1)) {
+ cur_timestamp =
+ priv->index_table[aid][priv->current_apacket].timestamp;
+ }
if (rel_seek_secs > 0)
while ((priv->index_table[aid][priv->current_apacket].timestamp - cur_timestamp) < rel_seek_secs * 1000){
priv->current_apacket += 1;
@@ -1865,9 +1881,10 @@
break;
}
}
- next_offset = priv->index_table[aid][priv->current_apacket].offset;
+ priv->audio_curpos = priv->index_table[aid][priv->current_apacket].offset;
}
// }
+ next_offset = streams & 1 ? priv->video_curpos : priv->audio_curpos;
// printf("seek: pos: %d, current packets: a: %d, v: %d\n",
// next_offset, priv->current_apacket, priv->current_vpacket);
if (next_offset)
More information about the MPlayer-dev-eng
mailing list