[xiph-commits] r7739 - experimental/derf/theora-exp/lib
tterribe at motherfish-iii.xiph.org
tterribe at motherfish-iii.xiph.org
Sat Sep 11 09:50:11 PDT 2004
Author: tterribe
Date: 2004-09-11 09:50:10 -0700 (Sat, 11 Sep 2004)
New Revision: 7739
Modified:
experimental/derf/theora-exp/lib/decode.c
Log:
Treat 0-length packets as dropped frames, like we've been planning to for ages.
Modified: experimental/derf/theora-exp/lib/decode.c
===================================================================
--- experimental/derf/theora-exp/lib/decode.c 2004-09-11 16:20:03 UTC (rev 7738)
+++ experimental/derf/theora-exp/lib/decode.c 2004-09-11 16:50:10 UTC (rev 7739)
@@ -1751,116 +1751,126 @@
ogg_int64_t *_granpos){
int ret;
if(_dec==NULL||_op==NULL)return OC_FAULT;
- oggpackB_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)){
- theora_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]=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);
- }
- else{
- int rfi;
- for(rfi=0;rfi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
- rfi==_dec->state.ref_frame_idx[OC_FRAME_PREV];rfi++);
- _dec->state.ref_frame_idx[OC_FRAME_SELF]=rfi;
- }
- if(_dec->state.frame_type==OC_INTRA_FRAME){
- oc_dec_mark_all_intra(_dec);
- _dec->state.keyframe_num=_dec->state.curframe_num;
- }
- else{
- oc_dec_coded_flags_unpack(_dec);
- oc_dec_mb_modes_unpack(_dec);
- oc_dec_mv_unpack_and_frag_modes_fill(_dec);
- }
- oc_dec_block_qis_unpack(_dec);
- oc_dec_residual_tokens_unpack(_dec);
- /*TODO: All of the rest of the operations -- reconstructing coded fragments,
- copying (coded or uncoded) fragments and post-processing -- should be
- pipelined.
- i.e., after sufficient numbers of super-block rows are reconstructed, copy
- back fragments, then after sufficient numbers of super-block rows are
- complete, post-process.
- This allows us to operate on the data while it is still in cache,
- resulting in big performance improvements.
- An application callback to allow it to process each super-block row as it
- is decoded is also a good idea.*/
- oc_dec_frags_recon(_dec);
- /*Right now the reconstructed frame has only the coded blocks in it.
- We either need to copy all the other blocks into it, or copy the
- reconstructed blocks back into the previous frame, whichever is faster.*/
- if(_dec->state.frame_type==OC_INTRA_FRAME){
- /*Intra frames always code all fragments, so there is nothing to copy.
- The new frame becomes both the previous and gold reference frames.*/
- _dec->state.keyframe_num=_dec->state.curframe_num;
- _dec->state.ref_frame_idx[OC_FRAME_GOLD]=
- _dec->state.ref_frame_idx[OC_FRAME_PREV]=
- _dec->state.ref_frame_idx[OC_FRAME_SELF];
- }
- else{
- int *plfragis[3];
- int ncoded;
- int nuncoded;
- ncoded=_dec->state.ncoded_fragis[0]+_dec->state.ncoded_fragis[1]+
- _dec->state.ncoded_fragis[2];
- nuncoded=_dec->state.nfrags-ncoded;
- if(ncoded<nuncoded&&
- _dec->state.ref_frame_idx[OC_FRAME_PREV]!=
- _dec->state.ref_frame_idx[OC_FRAME_GOLD]){
- plfragis[0]=_dec->state.coded_fragis;
- plfragis[1]=plfragis[0]+_dec->state.ncoded_fragis[0];
- plfragis[2]=plfragis[1]+_dec->state.ncoded_fragis[1];
- oc_state_frag_copy(&_dec->state,plfragis,_dec->state.ncoded_fragis,
- OC_FRAME_PREV,OC_FRAME_SELF);
- _dec->state.ref_frame_idx[OC_FRAME_SELF]=
- _dec->state.ref_frame_idx[OC_FRAME_PREV];
+ /*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){
+ oggpackB_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)){
+ theora_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]=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);
}
else{
- plfragis[0]=_dec->state.uncoded_fragis-_dec->state.nuncoded_fragis[0];
- plfragis[1]=plfragis[0]-_dec->state.nuncoded_fragis[1];
- plfragis[2]=plfragis[1]-_dec->state.nuncoded_fragis[2];
- oc_state_frag_copy(&_dec->state,plfragis,_dec->state.nuncoded_fragis,
- OC_FRAME_SELF,OC_FRAME_PREV);
- _dec->state.ref_frame_idx[OC_FRAME_PREV]=
+ int rfi;
+ for(rfi=0;rfi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
+ rfi==_dec->state.ref_frame_idx[OC_FRAME_PREV];rfi++);
+ _dec->state.ref_frame_idx[OC_FRAME_SELF]=rfi;
+ }
+ if(_dec->state.frame_type==OC_INTRA_FRAME){
+ oc_dec_mark_all_intra(_dec);
+ _dec->state.keyframe_num=_dec->state.curframe_num;
+ }
+ else{
+ oc_dec_coded_flags_unpack(_dec);
+ oc_dec_mb_modes_unpack(_dec);
+ oc_dec_mv_unpack_and_frag_modes_fill(_dec);
+ }
+ oc_dec_block_qis_unpack(_dec);
+ oc_dec_residual_tokens_unpack(_dec);
+ /*TODO: All of the rest of the operations -- reconstructing coded
+ fragments, copying (coded or uncoded) fragments and post-processing --
+ should be pipelined.
+ i.e., after sufficient numbers of super-block rows are reconstructed,
+ copy back fragments, then after sufficient numbers of super-block rows
+ are complete, post-process.
+ This allows us to operate on the data while it is still in cache,
+ resulting in big performance improvements.
+ An application callback to allow it to process each super-block row as it
+ is decoded is also a good idea.*/
+ oc_dec_frags_recon(_dec);
+ /*Right now the reconstructed frame has only the coded blocks in it.
+ We either need to copy all the other blocks into it, or copy the
+ reconstructed blocks back into the previous frame, whichever is
+ faster.*/
+ if(_dec->state.frame_type==OC_INTRA_FRAME){
+ /*Intra frames always code all fragments, so there is nothing to copy.
+ The new frame becomes both the previous and gold reference frames.*/
+ _dec->state.keyframe_num=_dec->state.curframe_num;
+ _dec->state.ref_frame_idx[OC_FRAME_GOLD]=
+ _dec->state.ref_frame_idx[OC_FRAME_PREV]=
_dec->state.ref_frame_idx[OC_FRAME_SELF];
}
+ else{
+ int *plfragis[3];
+ int ncoded;
+ int nuncoded;
+ ncoded=_dec->state.ncoded_fragis[0]+_dec->state.ncoded_fragis[1]+
+ _dec->state.ncoded_fragis[2];
+ nuncoded=_dec->state.nfrags-ncoded;
+ /*Pick which way the copy goes based on the number of fragments that have
+ to be copied, but make sure we don't overwrite the golden reference
+ frame.*/
+ if(ncoded<nuncoded&&
+ _dec->state.ref_frame_idx[OC_FRAME_PREV]!=
+ _dec->state.ref_frame_idx[OC_FRAME_GOLD]){
+ plfragis[0]=_dec->state.coded_fragis;
+ plfragis[1]=plfragis[0]+_dec->state.ncoded_fragis[0];
+ plfragis[2]=plfragis[1]+_dec->state.ncoded_fragis[1];
+ oc_state_frag_copy(&_dec->state,plfragis,_dec->state.ncoded_fragis,
+ OC_FRAME_PREV,OC_FRAME_SELF);
+ _dec->state.ref_frame_idx[OC_FRAME_SELF]=
+ _dec->state.ref_frame_idx[OC_FRAME_PREV];
+ }
+ else{
+ plfragis[0]=_dec->state.uncoded_fragis-_dec->state.nuncoded_fragis[0];
+ plfragis[1]=plfragis[0]-_dec->state.nuncoded_fragis[1];
+ plfragis[2]=plfragis[1]-_dec->state.nuncoded_fragis[2];
+ oc_state_frag_copy(&_dec->state,plfragis,_dec->state.nuncoded_fragis,
+ OC_FRAME_SELF,OC_FRAME_PREV);
+ _dec->state.ref_frame_idx[OC_FRAME_PREV]=
+ _dec->state.ref_frame_idx[OC_FRAME_SELF];
+ }
+ }
+ /*Filter block edges.*/
+ oc_state_loop_filter(&_dec->state,OC_FRAME_PREV);
+ /*Fill in the borders from the reconstructed version of the last encoded
+ frame.*/
+ if(_dec->state.ref_frame_idx[OC_FRAME_PREV]>=0){
+ oc_state_borders_fill(&_dec->state,
+ _dec->state.ref_frame_idx[OC_FRAME_PREV]);
+ }
+ /*Perform out-of-loop post-processing, if enabled.*/
+ if(oc_dec_postprocess(_dec)){
+ memcpy(_dec->pp_frame_buf,
+ _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]],
+ sizeof(_dec->pp_frame_buf[0])*3);
+ }
}
- /*Filter block edges.*/
- oc_state_loop_filter(&_dec->state,OC_FRAME_PREV);
- /*Fill in the borders from the reconstructed version of the last encoded
- frame.*/
- if(_dec->state.ref_frame_idx[OC_FRAME_PREV]>=0){
- oc_state_borders_fill(&_dec->state,
- _dec->state.ref_frame_idx[OC_FRAME_PREV]);
- }
- /*Perform out-of-loop post-processing, if enabled.*/
- if(oc_dec_postprocess(_dec)){
- memcpy(_dec->pp_frame_buf,
- _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]],
- sizeof(_dec->pp_frame_buf[0])*3);
- }
/*Update granule position.*/
_dec->state.granpos=
(_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
More information about the commits
mailing list