📄 schroedinger.c
字号:
} else if( p_sys->p_format->chroma_format == SCHRO_CHROMA_444 ) { p_schroframe->format = SCHRO_FRAME_FORMAT_U8_444; } p_schroframe->width = p_sys->p_format->width; p_schroframe->height = p_sys->p_format->height; p_free = malloc( sizeof( *p_free ) ); p_free->p_pic = p_pic; p_free->p_dec = p_dec; schro_frame_set_free_callback( p_schroframe, SchroFrameFree, p_free ); for( int i=0; i<3; i++ ) { p_schroframe->components[i].width = p_pic->p[i].i_visible_pitch; p_schroframe->components[i].stride = p_pic->p[i].i_pitch; p_schroframe->components[i].height = p_pic->p[i].i_visible_lines; p_schroframe->components[i].length = p_pic->p[i].i_pitch * p_pic->p[i].i_lines; p_schroframe->components[i].data = p_pic->p[i].p_pixels; if(i!=0) { p_schroframe->components[i].v_shift = SCHRO_FRAME_FORMAT_V_SHIFT( p_schroframe->format ); p_schroframe->components[i].h_shift = SCHRO_FRAME_FORMAT_H_SHIFT( p_schroframe->format ); } } p_pic->b_progressive = !p_sys->p_format->interlaced; p_pic->b_top_field_first = p_sys->p_format->top_field_first; p_pic->i_nb_fields = 2; return p_schroframe;}/***************************************************************************** * SchroBufferFree: schro_buffer callback to release the associated block_t *****************************************************************************/static void SchroBufferFree( SchroBuffer *buf, void *priv ){ block_t *p_block = priv; if( !p_block ) return; block_Release( p_block ); (void)buf;}/***************************************************************************** * CloseDecoder: decoder destruction *****************************************************************************/static void CloseDecoder( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys = p_dec->p_sys; schro_decoder_free( p_sys->p_schro ); free( p_sys );}/**************************************************************************** * DecodeBlock: the whole thing **************************************************************************** * Blocks must start with a Dirac parse unit. * Blocks must contain at least one Dirac parse unit. * Blocks must end with a picture parse unit. * Blocks must not contain more than one picture parse unit. * If a block has a PTS signaled, it applies to the first picture in p_block * - Schroedinger has no internal means to tag pictures with a PTS * - In this case, the picture number is extracted and stored in a TLB * When a picture is extracted from schro, it is looked up in the pts_tlb * - If the picture was never tagged with a PTS, a new one is calculated * based upon the frame rate and last output PTS. * * If this function returns a picture (!NULL), it is called again and the * same block is resubmitted. To avoid this, set *pp_block to NULL; * If this function returns NULL, the *pp_block is lost (and leaked). * This function must free all blocks when finished with them. ****************************************************************************/static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ){ decoder_sys_t *p_sys = p_dec->p_sys; int state; SchroBuffer *p_schrobuffer; SchroFrame *p_schroframe; picture_t *p_pic; block_t *p_block; uint32_t u_pnum; if( !pp_block ) return NULL; p_block = *pp_block; if ( p_block ) do { /* prepare block for submission */ if (p_sys->i_ts_resync_hack && p_sys->i_ts_resync_hack--) return NULL; if( !p_block->i_buffer ) { msg_Err( p_dec, "block is of zero size" ); break; } /* reset the decoder when seeking as the decode in progress is invalid */ /* discard the block as it is just a null magic block */ if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) {#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_RESET" );#endif schro_decoder_reset( p_sys->p_schro ); ResetPTStlb( p_dec ); p_sys->i_lastpts = -1; /* The ts layer manages to corrupt the next packet we are to receive * Since schro has no sync support, we need to drop it */ p_sys->i_ts_resync_hack = 1; block_Release( p_block ); *pp_block = NULL; return NULL; } /* Unsatisfactory, and will later be fixed in schro: * - Schro can only handle a single Dirac parse unit at a time * - Multiple parse units may exist in p_block * - All mapping specs so far guarantee that p_block would * not contain anything after a picture * So, we can not give the whole block to schro, but piecemeal */ size_t i_bufused = 0; while( schro_decoder_push_ready( p_sys->p_schro )) { if( p_block->i_buffer - i_bufused < 13 ) { *pp_block = NULL; block_Release( p_block ); msg_Err( p_dec, "not enough data left in block" ); break; } int b_bail = 0; size_t i_pulen = GetDWBE( p_block->p_buffer + i_bufused + 5 ); uint8_t *p_pu = p_block->p_buffer + i_bufused; if( 0 == i_pulen ) { i_pulen = 13; } /* blocks that do not start with the parse info prefix are invalid */ if( p_pu[0] != 'B' || p_pu[1] != 'B' || p_pu[2] != 'C' || p_pu[3] != 'D') { *pp_block = NULL; block_Release( p_block ); msg_Err( p_dec, "block does not start with dirac parse code" ); break; } if( i_bufused + i_pulen > p_block->i_buffer ) { *pp_block = NULL; block_Release( p_block ); break; } if( p_pu[4] & 0x08 ) StorePicturePTS( p_dec, p_block, i_bufused ); p_schrobuffer = schro_buffer_new_with_data( p_pu, i_pulen ); if( i_pulen + i_bufused < p_block->i_buffer ) { /* don't let schro free this block, more data still in it */ p_schrobuffer->free = 0; } else { p_schrobuffer->free = SchroBufferFree; p_schrobuffer->priv = p_block; b_bail = 1; }#ifdef TRACE msg_Dbg( p_dec, "Inserting bytes into decoder len=%zu of %zu pts=%"PRId64, i_pulen, p_block->i_buffer, p_block->i_pts);#endif /* this stops the same block being fed back into this function if * we were on the next iteration of this loop to output a picture */ *pp_block = NULL; state = schro_decoder_push( p_sys->p_schro, p_schrobuffer ); /* DO NOT refer to p_block after this point, it may have been freed */ i_bufused += i_pulen; if( state == SCHRO_DECODER_FIRST_ACCESS_UNIT ) {#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_FIRST_ACCESS_UNIT");#endif SetVideoFormat( p_dec ); ResetPTStlb( p_dec ); p_schroframe = CreateSchroFrameFromPic( p_dec ); if( p_schroframe ) { schro_decoder_add_output_picture( p_sys->p_schro, p_schroframe); } } if( b_bail ) break; } } while( 0 ); while( 1 ) { state = schro_decoder_wait( p_sys->p_schro ); switch( state ) { case SCHRO_DECODER_NEED_BITS:#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_NEED_BITS" );#endif return NULL; case SCHRO_DECODER_NEED_FRAME:#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_NEED_FRAME" );#endif p_schroframe = CreateSchroFrameFromPic( p_dec ); if( !p_schroframe ) { msg_Err( p_dec, "Could not allocate picture for decoder"); return NULL; } schro_decoder_add_output_picture( p_sys->p_schro, p_schroframe); break; case SCHRO_DECODER_OK: u_pnum = schro_decoder_get_picture_number( p_sys->p_schro ); p_schroframe = schro_decoder_pull( p_sys->p_schro ); p_pic = ((struct picture_free_t*) p_schroframe->priv)->p_pic; p_schroframe->priv = NULL; schro_frame_unref( p_schroframe ); /* solve presentation time stamp for picture. If this picture * was not tagged with a pts when presented to decoder, interpolate * one * This means no need to set p_pic->b_force, as we have a pts on * each picture */ p_pic->date = GetPicturePTS( p_dec, u_pnum ); if (p_sys->i_lastpts >= 0 && p_pic->date == 0) p_pic->date = p_sys->i_lastpts + p_sys->i_frame_pts_delta; p_sys->i_lastpts = p_pic->date;#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_OK num=%u date=%"PRId64, u_pnum, p_pic->date);#endif return p_pic; case SCHRO_DECODER_EOS:#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_EOS");#endif /* reset the decoder -- schro doesn't do this itself automatically */ /* there are no more pictures in the output buffer at this point */ schro_decoder_reset( p_sys->p_schro ); break; case SCHRO_DECODER_ERROR:#ifdef TRACE msg_Dbg( p_dec, "SCHRO_DECODER_ERROR");#endif return NULL; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -