X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fcodec%2Flibmpeg2.c;h=c8e1c493fb5b919e25e1155e0216a4c5e5213aad;hb=7307480b7a9b72d0f19a155216c608121a174a98;hp=39bde8dd09931cec15a5572a6b436c469970c245;hpb=be5d9107a6ba2160a0baa5ea51fc3c121265d5d2;p=vlc diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index 39bde8dd09..c8e1c493fb 100644 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -1,27 +1,35 @@ /***************************************************************************** * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2. ***************************************************************************** - * Copyright (C) 1999-2001 the VideoLAN team + * Copyright (C) 1999-2001 VLC authors and VideoLAN * $Id$ * * Authors: Gildas Bazin * Christophe Massiot * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +/***************************************************************************** + * NOTA BENE: this module requires the linking against a library which is + * known to require licensing under the GNU General Public License version 2 + * (or later). Therefore, the result of compiling this module will normally + * be subject to the terms of that later license. + *****************************************************************************/ + + /***************************************************************************** * Preamble *****************************************************************************/ @@ -83,7 +91,6 @@ struct decoder_sys_t * Output properties */ decoder_synchro_t *p_synchro; - int i_aspect; int i_sar_num; int i_sar_den; mtime_t i_last_frame_pts; @@ -127,7 +134,7 @@ static int DpbDisplayPicture( decoder_t *, picture_t * ); *****************************************************************************/ vlc_module_begin () set_description( N_("MPEG I/II video decoder (using libmpeg2)") ) - set_capability( "decoder", 150 ) + set_capability( "decoder", 50 ) set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_VCODEC ) set_callbacks( OpenDecoder, CloseDecoder ) @@ -173,7 +180,8 @@ static int OpenDecoder( vlc_object_t *p_this ) p_sys->i_previous_pts = 0; p_sys->i_current_dts = 0; p_sys->i_previous_dts = 0; - p_sys->i_aspect = 0; + p_sys->i_sar_num = 0; + p_sys->i_sar_den = 0; p_sys->b_garbage_pic = false; p_sys->b_slice_i = false; p_sys->b_second_field = false; @@ -192,30 +200,26 @@ static int OpenDecoder( vlc_object_t *p_this ) p_sys->i_gop_user_data = 0; #if defined( __i386__ ) || defined( __x86_64__ ) - if( vlc_CPU() & CPU_CAPABILITY_MMX ) - { + if( vlc_CPU_MMX() ) i_accel |= MPEG2_ACCEL_X86_MMX; - } - - if( vlc_CPU() & CPU_CAPABILITY_3DNOW ) - { + if( vlc_CPU_3dNOW() ) i_accel |= MPEG2_ACCEL_X86_3DNOW; - } - - if( vlc_CPU() & CPU_CAPABILITY_MMXEXT ) - { + if( vlc_CPU_MMXEXT() ) i_accel |= MPEG2_ACCEL_X86_MMXEXT; - } - #elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ ) - if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC ) - { + if( vlc_CPU_ALTIVEC() ) i_accel |= MPEG2_ACCEL_PPC_ALTIVEC; - } #elif defined(__arm__) +# ifdef MPEG2_ACCEL_ARM i_accel |= MPEG2_ACCEL_ARM; +# endif +# ifdef MPEG2_ACCEL_ARM_NEON + if( vlc_CPU_ARM_NEON() ) + i_accel |= MPEG2_ACCEL_ARM_NEON; +# endif + /* TODO: sparc */ #else /* If we do not know this CPU, trust libmpeg2's feature detection */ i_accel = MPEG2_ACCEL_DETECT; @@ -250,7 +254,6 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; mpeg2_state_t state; - picture_t *p_pic; block_t *p_block; @@ -276,7 +279,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 ); /* Set the first 2 reference frames */ - p_sys->i_aspect = 0; + p_sys->i_sar_num = 0; + p_sys->i_sar_den = 0; GetAR( p_dec ); for( int i = 0; i < 2; i++ ) { @@ -382,7 +386,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ); - bool b_skip = false; + picture_t *p_pic; + if( !p_dec->b_pace_control && !p_sys->b_preroll && !(p_sys->b_slice_i && ((p_current->flags @@ -392,12 +397,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) & PIC_MASK_CODING_TYPE, /*p_sys->p_vout->render_time*/ 0 /*FIXME*/, p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ) ) - { - b_skip = true; - } - - p_pic = NULL; - if( !b_skip ) + p_pic = NULL; + else { p_pic = DpbNewPicture( p_dec ); if( !p_pic ) @@ -414,28 +415,15 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) } } - if( b_skip || !p_pic ) - { - mpeg2_skip( p_sys->p_mpeg2dec, 1 ); - p_sys->b_skip = true; + mpeg2_skip( p_sys->p_mpeg2dec, p_pic == NULL ); + p_sys->b_skip = p_pic == NULL; + if( p_pic != NULL ) + decoder_SynchroDecode( p_sys->p_synchro ); + else decoder_SynchroTrash( p_sys->p_synchro ); - PutPicture( p_dec, NULL ); + PutPicture( p_dec, p_pic ); - if( !b_skip ) - { - block_Release( p_block ); - return NULL; - } - } - else - { - mpeg2_skip( p_sys->p_mpeg2dec, 0 ); - p_sys->b_skip = false; - decoder_SynchroDecode( p_sys->p_synchro ); - - PutPicture( p_dec, p_pic ); - } if( p_info->user_data_len > 2 || p_sys->i_gop_user_data > 2 ) { p_sys->i_cc_pts = i_pts; @@ -447,17 +435,21 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B ) p_sys->i_cc_flags = BLOCK_FLAG_TYPE_B; else p_sys->i_cc_flags = BLOCK_FLAG_TYPE_I; + bool b_top_field_first = p_sys->p_info->current_picture->flags + & PIC_FLAG_TOP_FIELD_FIRST; if( p_sys->i_gop_user_data > 2 ) { /* We now have picture info for any cached user_data out of the gop */ - cc_Extract( &p_sys->cc, &p_sys->p_gop_user_data[0], p_sys->i_gop_user_data ); + cc_Extract( &p_sys->cc, b_top_field_first, + &p_sys->p_gop_user_data[0], p_sys->i_gop_user_data ); p_sys->i_gop_user_data = 0; } /* Extract the CC from the user_data of the picture */ if( p_info->user_data_len > 2 ) - cc_Extract( &p_sys->cc, &p_info->user_data[0], p_info->user_data_len ); + cc_Extract( &p_sys->cc, b_top_field_first, + &p_info->user_data[0], p_info->user_data_len ); } } break; @@ -542,7 +534,9 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) case STATE_INVALID_END: case STATE_END: case STATE_SLICE: - p_pic = NULL; + { + picture_t *p_pic = NULL; + if( p_sys->p_info->display_fbuf && p_sys->p_info->display_fbuf->id ) { @@ -569,12 +563,11 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) DpbUnlinkPicture( p_dec, p_sys->p_info->discard_fbuf->id ); } - /* For still frames */ - if( state == STATE_END && p_pic ) - p_pic->b_force = true; - if( p_pic ) { + if( state == STATE_END ) + p_pic->b_force = true; /* For still frames */ + /* Avoid frames with identical timestamps. * Especially needed for still frames in DVD menus. */ if( p_sys->i_last_frame_pts == p_pic->date ) @@ -583,6 +576,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return p_pic; } break; + } case STATE_INVALID: { @@ -646,7 +640,6 @@ static picture_t *GetNewPicture( decoder_t *p_dec ) p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height; p_dec->fmt_out.video.i_visible_height = p_sys->p_info->sequence->picture_height; - p_dec->fmt_out.video.i_aspect = p_sys->i_aspect; p_dec->fmt_out.video.i_sar_num = p_sys->i_sar_num; p_dec->fmt_out.video.i_sar_den = p_sys->i_sar_den; @@ -695,7 +688,7 @@ static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] ) if( p_sys->cc.i_data <= 0 ) return NULL; - p_cc = block_New( p_dec, p_sys->cc.i_data); + p_cc = block_Alloc( p_sys->cc.i_data); if( p_cc ) { memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data ); @@ -714,24 +707,21 @@ static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] ) static void GetAR( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; - int i_old_aspect = p_sys->i_aspect; + int i_old_sar_num = p_sys->i_sar_num; + int i_old_sar_den = p_sys->i_sar_den; /* Check whether the input gave a particular aspect ratio */ - if( p_dec->fmt_in.video.i_aspect ) + if( p_dec->fmt_in.video.i_sar_num > 0 && + p_dec->fmt_in.video.i_sar_den > 0 ) { - p_sys->i_aspect = p_dec->fmt_in.video.i_aspect; + p_sys->i_sar_num = p_dec->fmt_in.video.i_sar_num; + p_sys->i_sar_den = p_dec->fmt_in.video.i_sar_den; } else { /* Use the value provided in the MPEG sequence header */ if( p_sys->p_info->sequence->pixel_height > 0 ) { - p_sys->i_aspect = - ((uint64_t)p_sys->p_info->sequence->picture_width) * - p_sys->p_info->sequence->pixel_width * - VOUT_ASPECT_FACTOR / - p_sys->p_info->sequence->picture_height / - p_sys->p_info->sequence->pixel_height; p_sys->i_sar_num = p_sys->p_info->sequence->pixel_width; p_sys->i_sar_den = p_sys->p_info->sequence->pixel_height; } @@ -740,23 +730,23 @@ static void GetAR( decoder_t *p_dec ) /* Invalid aspect, assume 4:3. * This shouldn't happen and if it does it is a bug * in libmpeg2 (likely triggered by an invalid stream) */ - p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3; p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 4; p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 3; } } - if( p_sys->i_aspect == i_old_aspect ) + if( p_sys->i_sar_num == i_old_sar_num && + p_sys->i_sar_den == i_old_sar_den ) return; if( p_sys->p_info->sequence->frame_period > 0 ) msg_Dbg( p_dec, - "%dx%d (display %d,%d), aspect %d, sar %i:%i, %u.%03u fps", + "%dx%d (display %d,%d), sar %i:%i, %u.%03u fps", p_sys->p_info->sequence->picture_width, p_sys->p_info->sequence->picture_height, p_sys->p_info->sequence->display_width, p_sys->p_info->sequence->display_height, - p_sys->i_aspect, p_sys->i_sar_num, p_sys->i_sar_den, + p_sys->i_sar_num, p_sys->i_sar_den, (uint32_t)((uint64_t)1001000000 * 27 / p_sys->p_info->sequence->frame_period / 1001), (uint32_t)((uint64_t)1001000000 * 27 / @@ -809,9 +799,9 @@ static void DpbClean( decoder_t *p_dec ) if( !p->p_picture ) continue; if( p->b_linked ) - decoder_UnlinkPicture( p_dec, p->p_picture ); + picture_Release( p->p_picture ); if( !p->b_displayed ) - decoder_DeletePicture( p_dec, p->p_picture ); + picture_Release( p->p_picture ); p->p_picture = NULL; } @@ -841,7 +831,7 @@ static picture_t *DpbNewPicture( decoder_t *p_dec ) p->p_picture = GetNewPicture( p_dec ); if( p->p_picture ) { - decoder_LinkPicture( p_dec, p->p_picture ); + picture_Hold( p->p_picture ); p->b_linked = true; p->b_displayed = false; @@ -878,11 +868,11 @@ static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture ) assert( p && p->b_linked ); - decoder_UnlinkPicture( p_dec, p->p_picture ); + picture_Release( p->p_picture ); p->b_linked = false; if( !p->b_displayed ) - decoder_DeletePicture( p_dec, p->p_picture ); + picture_Release( p->p_picture ); p->p_picture = NULL; } /**