diff --git a/content/media/test/Makefile.in b/content/media/test/Makefile.in index b441bfd97a8d..8d1657b84d36 100644 --- a/content/media/test/Makefile.in +++ b/content/media/test/Makefile.in @@ -125,6 +125,7 @@ _TEST_FILES += \ bug500311.ogv \ bug500311.ogv^headers^ \ bug501279.ogg \ + bug504613.ogv \ bug504644.ogv \ bug506094.ogv \ seek.ogv \ diff --git a/content/media/test/bug504613.ogv b/content/media/test/bug504613.ogv new file mode 100644 index 000000000000..5c7fd015e9ed Binary files /dev/null and b/content/media/test/bug504613.ogv differ diff --git a/content/media/test/manifest.js b/content/media/test/manifest.js index 6fd562996674..65bb3c94e791 100644 --- a/content/media/test/manifest.js +++ b/content/media/test/manifest.js @@ -34,6 +34,8 @@ var gPlayTests = [ { name:"small-shot.ogg", type:"video/ogg" }, // More audio in file than video. { name:"short-video.ogv", type:"video/ogg", duration:1.081 }, + // First Theora data packet is zero bytes. + { name:"bug504613.ogv", type:"video/ogg" }, { name:"bogus.duh", type:"bogus/duh" } ]; diff --git a/media/libtheora/README_MOZILLA b/media/libtheora/README_MOZILLA index 67577a366af4..94a92fd35269 100644 --- a/media/libtheora/README_MOZILLA +++ b/media/libtheora/README_MOZILLA @@ -15,3 +15,4 @@ Bug 455357 - WinCE LibTheora Pre-defined Macro usage in local variable bug498815.patch: Fix for this bug from libtheora svn r16143. bug498824.patch: Fix for this bug from libtheora thusnelda branch. +bug504613.patch: Fix for this bug from libtheora svn r16557. diff --git a/media/libtheora/bug504613.patch b/media/libtheora/bug504613.patch new file mode 100644 index 000000000000..b2d778e88666 --- /dev/null +++ b/media/libtheora/bug504613.patch @@ -0,0 +1,119 @@ +# HG changeset patch +# User Matthew Gregan +# Date 1252993590 -43200 +# Node ID 2fce745981185aecebad0366b4c2ff45e9f93e95 +# Parent 8dbe8de92cb46f64f8ff80d79f38961eb02e9cbd +imported patch bug504613 + +diff --git a/media/libtheora/lib/dec/decode.c b/media/libtheora/lib/dec/decode.c +--- a/media/libtheora/lib/dec/decode.c ++++ b/media/libtheora/lib/dec/decode.c +@@ -1846,16 +1846,40 @@ int th_decode_ctl(th_dec_ctx *_dec,int _ + _dec->stripe_cb.ctx=cb->ctx; + _dec->stripe_cb.stripe_decoded=cb->stripe_decoded; + return 0; + }break; + default:return TH_EIMPL; + } + } + ++/*We're decoding an INTER frame, but have no initialized reference ++ buffers (i.e., decoding did not start on a key frame). ++ We initialize them to a solid gray here.*/ ++static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){ ++ th_info *info; ++ size_t yplane_sz; ++ size_t cplane_sz; ++ int yhstride; ++ int yvstride; ++ int chstride; ++ int cvstride; ++ _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0; ++ _dec->state.ref_frame_idx[OC_FRAME_PREV]=0; ++ _dec->state.ref_frame_idx[OC_FRAME_SELF]=1; ++ info=&_dec->state.info; ++ yhstride=info->frame_width+2*OC_UMV_PADDING; ++ yvstride=info->frame_height+2*OC_UMV_PADDING; ++ chstride=yhstride>>!(info->pixel_fmt&1); ++ cvstride=yvstride>>!(info->pixel_fmt&2); ++ yplane_sz=(size_t)yhstride*yvstride; ++ cplane_sz=(size_t)chstride*cvstride; ++ memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz); ++} ++ + int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, + ogg_int64_t *_granpos){ + int ret; + if(_dec==NULL||_op==NULL)return TH_EFAULT; + /*A completely empty packet indicates a dropped frame and is treated exactly + like an inter frame with no coded blocks. + Only proceed if we have a non-empty packet.*/ + if(_op->bytes!=0){ +@@ -1869,37 +1893,19 @@ int th_decode_packetin(th_dec_ctx *_dec, + theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes); + ret=oc_dec_frame_header_unpack(_dec); + if(ret<0)return ret; + /*Select a free buffer to use for the reconstructed version of this + frame.*/ + if(_dec->state.frame_type!=OC_INTRA_FRAME&& + (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| + _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){ +- th_info *info; +- size_t yplane_sz; +- size_t cplane_sz; +- int yhstride; +- int yvstride; +- int chstride; +- int cvstride; +- /*We're decoding an INTER frame, but have no initialized reference +- buffers (i.e., decoding did not start on a key frame). +- We initialize them to a solid gray here.*/ +- _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0; +- _dec->state.ref_frame_idx[OC_FRAME_PREV]=0; +- _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi=1; +- info=&_dec->state.info; +- yhstride=info->frame_width+2*OC_UMV_PADDING; +- yvstride=info->frame_height+2*OC_UMV_PADDING; +- chstride=yhstride>>!(info->pixel_fmt&1); +- cvstride=yvstride>>!(info->pixel_fmt&2); +- yplane_sz=(size_t)yhstride*yvstride; +- cplane_sz=(size_t)chstride*cvstride; +- memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz); ++ /*No reference frames yet!*/ ++ oc_dec_init_dummy_frame(_dec); ++ refi=_dec->state.ref_frame_idx[OC_FRAME_SELF]; + } + else{ + for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]|| + refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++); + _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; + } + if(_dec->state.frame_type==OC_INTRA_FRAME){ + oc_dec_mark_all_intra(_dec); +@@ -2036,16 +2042,26 @@ int th_decode_packetin(th_dec_ctx *_dec, + } + #if defined(OC_DUMP_IMAGES) + /*Don't dump images for dropped frames.*/ + oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec"); + #endif + return 0; + } + else{ ++ if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| ++ _dec->state.ref_frame_idx[OC_FRAME_PREV]<0){ ++ int refi; ++ /*No reference frames yet!*/ ++ oc_dec_init_dummy_frame(_dec); ++ refi=_dec->state.ref_frame_idx[OC_FRAME_PREV]; ++ _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; ++ memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi], ++ sizeof(_dec->pp_frame_buf[0])*3); ++ } + /*Just update the granule position and return.*/ + _dec->state.granpos= + (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+ + (_dec->state.curframe_num-_dec->state.keyframe_num); + _dec->state.curframe_num++; + if(_granpos!=NULL)*_granpos=_dec->state.granpos; + return TH_DUPFRAME; + } diff --git a/media/libtheora/lib/dec/decode.c b/media/libtheora/lib/dec/decode.c index bedacd15a03d..7fa8dd96a1a8 100644 --- a/media/libtheora/lib/dec/decode.c +++ b/media/libtheora/lib/dec/decode.c @@ -1851,6 +1851,30 @@ int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, } } +/*We're decoding an INTER frame, but have no initialized reference + buffers (i.e., decoding did not start on a key frame). + We initialize them to a solid gray here.*/ +static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){ + th_info *info; + size_t yplane_sz; + size_t cplane_sz; + int yhstride; + int yvstride; + int chstride; + int cvstride; + _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0; + _dec->state.ref_frame_idx[OC_FRAME_PREV]=0; + _dec->state.ref_frame_idx[OC_FRAME_SELF]=1; + info=&_dec->state.info; + yhstride=info->frame_width+2*OC_UMV_PADDING; + yvstride=info->frame_height+2*OC_UMV_PADDING; + chstride=yhstride>>!(info->pixel_fmt&1); + cvstride=yvstride>>!(info->pixel_fmt&2); + yplane_sz=(size_t)yhstride*yvstride; + cplane_sz=(size_t)chstride*cvstride; + memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz); +} + int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, ogg_int64_t *_granpos){ int ret; @@ -1874,27 +1898,9 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, if(_dec->state.frame_type!=OC_INTRA_FRAME&& (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){ - th_info *info; - size_t yplane_sz; - size_t cplane_sz; - int yhstride; - int yvstride; - int chstride; - int cvstride; - /*We're decoding an INTER frame, but have no initialized reference - buffers (i.e., decoding did not start on a key frame). - We initialize them to a solid gray here.*/ - _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0; - _dec->state.ref_frame_idx[OC_FRAME_PREV]=0; - _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi=1; - info=&_dec->state.info; - yhstride=info->frame_width+2*OC_UMV_PADDING; - yvstride=info->frame_height+2*OC_UMV_PADDING; - chstride=yhstride>>!(info->pixel_fmt&1); - cvstride=yvstride>>!(info->pixel_fmt&2); - yplane_sz=(size_t)yhstride*yvstride; - cplane_sz=(size_t)chstride*cvstride; - memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz); + /*No reference frames yet!*/ + oc_dec_init_dummy_frame(_dec); + refi=_dec->state.ref_frame_idx[OC_FRAME_SELF]; } else{ for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]|| @@ -2041,6 +2047,16 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, return 0; } else{ + if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| + _dec->state.ref_frame_idx[OC_FRAME_PREV]<0){ + int refi; + /*No reference frames yet!*/ + oc_dec_init_dummy_frame(_dec); + refi=_dec->state.ref_frame_idx[OC_FRAME_PREV]; + _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; + memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi], + sizeof(_dec->pp_frame_buf[0])*3); + } /*Just update the granule position and return.*/ _dec->state.granpos= (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+ diff --git a/media/libtheora/update.sh b/media/libtheora/update.sh index a50172c38154..a959acc00e59 100644 --- a/media/libtheora/update.sh +++ b/media/libtheora/update.sh @@ -56,3 +56,4 @@ patch -p3 <455357_wince_local_variable_macro_clash_patch patch -p3