summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_mpeg_block.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index 8d6c0279d..8a08524d8 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_mpeg_block.c,v 1.147 2002/12/08 21:43:51 miguelfreitas Exp $
+ * $Id: demux_mpeg_block.c,v 1.148 2002/12/15 01:05:36 rockyb Exp $
*
* demultiplexer for mpeg 1/2 program streams
*
@@ -640,35 +640,55 @@ static int demux_mpeg_block_send_chunk (demux_plugin_t *this_gen) {
return this->status;
}
-/* estimate bitrate */
+/*!
+ Estimate bitrate by looking inside the MPEG file for presentation
+ time stamps (PTS) and computing how far apart these are
+ in bytes and in time.
+
+ On failure return 0.
+*/
+
+/* How many *sucessful* PTS samples do we take? */
+#define MAX_SAMPLES 5
+
+/* How many times we read blocks before giving up. */
+#define MAX_READS 30
+
+/* TRUNCATE x to the nearest multiple of y. */
+#define TRUNC(x,y) (((x) / (y)) * (y))
static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) {
buf_element_t *buf = NULL;
unsigned char *p;
int is_mpeg1=0;
- off_t pos, last_pos;
- off_t step;
- int64_t pts, last_pts;
- int rate;
- int count;
+ off_t pos, last_pos=0;
+ off_t step, mpeg_length;
+ off_t blocksize = this->blocksize;
+ int64_t pts, last_pts=0;
+ int reads=0 /* Number of blocks read so far */;
+ int count=0; /* Number of sucessful PTS found so far */
+ int rate=0; /* The return rate value */
int stream_id;
+ /* We can't estimate by sampling if we don't thave the ability to
+ randomly access the and more importantly reset after accessessing. */
if (!(this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE))
return 0;
- last_pos = 0;
- last_pts = 0;
- rate = 0;
- step = this->input->get_length (this->input) / 10;
- step = (step / this->blocksize) * this->blocksize;
- if (step <= 0) step = this->blocksize; /* avoid endless loop for tiny files */
- pos = step;
- count = 0;
+ mpeg_length= this->input->get_length (this->input);
+ step = TRUNC((mpeg_length/MAX_SAMPLES), blocksize);
+ if (step <= 0) step = blocksize; /* avoid endless loop for tiny files */
+ pos = step;
+
+ /* At this point "pos", and "step" are a multiple of blocksize and
+ they should continue to be so throughout.
+ */
this->input->seek (this->input, pos, SEEK_SET);
- while ((buf = this->input->read_block (this->input, this->video_fifo, this->blocksize)) ) {
+ while ( (buf = this->input->read_block (this->input, this->video_fifo, blocksize))
+ && count < MAX_SAMPLES && reads++ < MAX_READS ) {
p = buf->content; /* len = this->mnBlocksize; */
@@ -698,7 +718,7 @@ static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) {
pts = 0;
if ((stream_id < 0xbc) || ((stream_id & 0xf0) != 0xe0)) {
- pos += (off_t) this->blocksize;
+ pos += (off_t) blocksize;
buf->free_buffer (buf);
continue; /* only use video packets */
}
@@ -762,11 +782,11 @@ static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) {
last_pts = pts;
pos += step;
} else
- pos += (off_t) this->blocksize;
+ pos += blocksize;
buf->free_buffer (buf);
- if (this->input->seek (this->input, pos, SEEK_SET) == (off_t)-1)
+ if (pos > mpeg_length || this->input->seek (this->input, pos, SEEK_SET) == (off_t)-1)
break;
}