зеркало из https://github.com/mozilla/gecko-dev.git
Bug 504613 - Handle zero-byte first-frame packets in Theora. p=tterribe@vt.edu, r=chris.double
--HG-- extra : rebase_source : d2b18e88ddec3836e30b448f949657206a33f3fa
This commit is contained in:
Родитель
636b7e873a
Коммит
40780c2c4b
|
@ -125,6 +125,7 @@ _TEST_FILES += \
|
|||
bug500311.ogv \
|
||||
bug500311.ogv^headers^ \
|
||||
bug501279.ogg \
|
||||
bug504613.ogv \
|
||||
bug504644.ogv \
|
||||
bug506094.ogv \
|
||||
seek.ogv \
|
||||
|
|
Двоичный файл не отображается.
|
@ -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" }
|
||||
];
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
# HG changeset patch
|
||||
# User Matthew Gregan <kinetik@flim.org>
|
||||
# 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;
|
||||
}
|
|
@ -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)+
|
||||
|
|
|
@ -56,3 +56,4 @@ patch -p3 <455357_wince_local_variable_macro_clash_patch
|
|||
patch -p3 <bug498815.patch
|
||||
patch -p3 <bug498824.patch
|
||||
patch -p0 <bug498770.patch
|
||||
patch -p3 <bug504613.patch
|
||||
|
|
Загрузка…
Ссылка в новой задаче