gecko/media/liboggplay/bug493224.patch
Viktor Gal 6a4baa404f Bug 493224. Handle non-increasing granule positions in Ogg files. r=doublec
--HG--
extra : rebase_source : d1efb6c38d22467fbb08e8781605c1b4d9552da2
2009-05-20 15:52:51 +12:00

107 lines
4.0 KiB
Diff

diff --git a/src/liboggplay/oggplay_callback.c b/src/liboggplay/oggplay_callback.c
index f3e2339..39380e7 100644
--- a/src/liboggplay/oggplay_callback.c
+++ b/src/liboggplay/oggplay_callback.c
@@ -109,6 +109,15 @@ oggplay_callback_theora (OGGZ * oggz, ogg_packet * op, long serialno,
int musec;
#endif
+ if ( (granulepos > 0) && (common->last_granulepos > granulepos)) {
+ /*
+ * the granule position is not monotonically increasing,
+ * something wrong with the page!
+ * skipping this page.....
+ */
+ return 0;
+ }
+
/*
* always decode headers
*/
@@ -174,10 +183,19 @@ oggplay_callback_theora (OGGZ * oggz, ogg_packet * op, long serialno,
#endif
if (granulepos != -1) {
+ /*
+ * save last granule position in order to be able to validate
+ * that it's monotonically increasing
+ */
+ common->last_granulepos = granulepos;
+
+ /* calculate the frame number */
granuleshift = oggz_get_granuleshift(oggz, serialno);
frame = (granulepos >> granuleshift);
frame += (granulepos & ((1 << granuleshift) - 1));
- common->current_loc = frame * common->granuleperiod;
+
+ /* calculate the current location in the stream */
+ common->current_loc = frame * common->granuleperiod;
} else {
common->current_loc = -1;
}
diff --git a/src/liboggplay/oggplay_private.h b/src/liboggplay/oggplay_private.h
index fb73f1d..1455c68 100644
--- a/src/liboggplay/oggplay_private.h
+++ b/src/liboggplay/oggplay_private.h
@@ -142,22 +142,22 @@ struct _OggPlayCallbackInfo {
* track
*/
typedef struct {
- long serialno;
- int content_type;
- const char * content_type_name;
- OggPlayDataType decoded_type;
- ogg_int64_t granuleperiod;
- ogg_int64_t last_granulepos;
- ogg_int64_t offset;
- ogg_int64_t current_loc;
- int active;
- ogg_int64_t final_granulepos;
- struct _OggPlay * player;
- OggPlayDataHeader * data_list;
- OggPlayDataHeader * end_of_data_list;
- OggPlayDataHeader * untimed_data_list;
- OggPlayStreamInfo stream_info;
- int preroll;
+ long serialno; /**< identifies the logical bit stream */
+ int content_type;
+ const char * content_type_name;
+ OggPlayDataType decoded_type; /**< type of the track @see OggPlayDataType */
+ ogg_int64_t granuleperiod;
+ ogg_int64_t last_granulepos; /**< last seen granule position */
+ ogg_int64_t offset; /**< */
+ ogg_int64_t current_loc; /**< current location in the stream (in ) */
+ int active; /**< indicates whether the track is active or not */
+ ogg_int64_t final_granulepos; /**< */
+ struct _OggPlay * player; /**< reference to the OggPlay handle */
+ OggPlayDataHeader * data_list;
+ OggPlayDataHeader * end_of_data_list;
+ OggPlayDataHeader * untimed_data_list;
+ OggPlayStreamInfo stream_info; /**< @see OggPlayStreamInfo */
+ int preroll; /**< num. of past content packets to take into account when decoding the current Ogg page */
} OggPlayDecode;
typedef struct {
@@ -190,6 +190,9 @@ typedef struct {
int granuleshift;
} OggPlayCmmlDecode;
+/**
+ * OggPlaySkeletonDecode
+ */
typedef struct {
OggPlayDecode decoder;
ogg_int64_t presentation_time;
diff --git a/src/liboggplay/oggplay_seek.c b/src/liboggplay/oggplay_seek.c
index e74c136..ef150b8 100644
--- a/src/liboggplay/oggplay_seek.c
+++ b/src/liboggplay/oggplay_seek.c
@@ -133,6 +133,7 @@ oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
track->data_list = track->end_of_data_list = NULL;
track->untimed_data_list = NULL;
track->current_loc = -1;
+ track->last_granulepos = -1;
track->stream_info = OGGPLAY_STREAM_JUST_SEEKED;
}