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:
Matthew Gregan 2009-09-15 17:53:49 +12:00
Родитель 636b7e873a
Коммит 40780c2c4b
7 изменённых файлов: 161 добавлений и 21 удалений

Просмотреть файл

@ -125,6 +125,7 @@ _TEST_FILES += \
bug500311.ogv \
bug500311.ogv^headers^ \
bug501279.ogg \
bug504613.ogv \
bug504644.ogv \
bug506094.ogv \
seek.ogv \

Двоичные данные
content/media/test/bug504613.ogv Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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