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; }