X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fstream_out%2Ftranscode.c;h=2e675587428f31a14fbfb4fb2a23d8a2c6c0a492;hb=4f66b0775778c153c2a5445b5e603e2857d7a38f;hp=cc40e4b0c27062585a3e1cbca4d42ee9d7cff060;hpb=291e63dd10758db1bed1be3d54f926a9fbb2e284;p=vlc diff --git a/modules/stream_out/transcode.c b/modules/stream_out/transcode.c index cc40e4b0c2..2e67558742 100644 --- a/modules/stream_out/transcode.c +++ b/modules/stream_out/transcode.c @@ -285,9 +285,9 @@ static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * ); static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *, block_t *, block_t ** ); -static int EncoderThread( struct sout_stream_sys_t * p_sys ); +static void* EncoderThread( vlc_object_t * p_this ); -static int pi_channels_maps[6] = +static const int pi_channels_maps[6] = { 0, AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, @@ -1146,7 +1146,7 @@ static int transcode_audio_new( sout_stream_t *p_stream, id->p_decoder->fmt_out.i_codec ); id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec; - id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;//id->p_encoder->fmt_out.audio.i_rate; + id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate; id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_out.audio.i_physical_channels; id->p_encoder->fmt_in.audio.i_original_channels = @@ -1195,17 +1195,32 @@ static int transcode_audio_new( sout_stream_t *p_stream, (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) || (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) ) { - filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in ); + msg_Dbg( p_stream, "Looking for filter " + "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)", + (char *)&fmt_last.i_codec, + (char *)&id->p_encoder->fmt_in.i_codec, + fmt_last.audio.i_channels, + id->p_encoder->fmt_in.audio.i_channels, + fmt_last.audio.i_rate, + id->p_encoder->fmt_in.audio.i_rate ); + filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, + &fmt_last, &id->p_encoder->fmt_in ); fmt_last = *filter_chain_GetFmtOut( id->p_f_chain ); } + else break; } /* Final checks to see if conversions were successful */ if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec ) { - msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)", + msg_Err( p_stream, "no audio filter found " + "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)", (char *)&fmt_last.i_codec, - (char *)&id->p_encoder->fmt_in.i_codec ); + (char *)&id->p_encoder->fmt_in.i_codec, + fmt_last.audio.i_channels, + id->p_encoder->fmt_in.audio.i_channels, + fmt_last.audio.i_rate, + id->p_encoder->fmt_in.audio.i_rate ); transcode_audio_close( id ); return VLC_EGENERIC; } @@ -1217,6 +1232,7 @@ static int transcode_audio_new( sout_stream_t *p_stream, transcode_audio_filter_allocation_init, NULL, NULL ); filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in ); filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 ); + fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain ); } if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ) @@ -1245,8 +1261,15 @@ static int transcode_audio_new( sout_stream_t *p_stream, id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg; id->p_encoder->p_module = module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true ); - if( !id->p_encoder->p_module ) + if( !id->p_encoder->p_module || + fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels || + fmt_last.i_codec != id->p_encoder->fmt_in.i_codec ) { + if( id->p_encoder->p_module ) + { + module_Unneed( id->p_encoder, id->p_encoder->p_module ); + id->p_encoder->p_module = NULL; + } msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)", p_sys->psz_aenc ? p_sys->psz_aenc : "any", (char *)&p_sys->i_acodec ); @@ -1476,6 +1499,9 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) id->p_decoder->pf_picture_link = video_link_picture_decoder; id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder; id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) ); + if( !id->p_decoder->p_owner ) + return VLC_EGENERIC; + for( i = 0; i < PICTURE_RING_SIZE; i++ ) id->p_decoder->p_owner->pp_pics[i] = 0; id->p_decoder->p_owner->p_sys = p_sys; @@ -1487,6 +1513,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find video decoder" ); + free( id->p_decoder->p_owner ); return VLC_EGENERIC; } @@ -1525,6 +1552,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) (char *)&p_sys->i_vcodec ); module_Unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = 0; + free( id->p_decoder->p_owner ); return VLC_EGENERIC; } @@ -1545,7 +1573,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) VLC_THREAD_PRIORITY_VIDEO; p_sys->id_video = id; vlc_mutex_init( &p_sys->lock_out ); - vlc_cond_init( p_stream, &p_sys->cond ); + vlc_cond_init( &p_sys->cond ); memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) ); p_sys->i_first_pic = 0; p_sys->i_last_pic = 0; @@ -1557,6 +1585,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) msg_Err( p_stream, "cannot spawn encoder thread" ); module_Unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = 0; + free( id->p_decoder->p_owner ); return VLC_EGENERIC; } } @@ -1666,11 +1695,15 @@ static void transcode_video_encoder_init( sout_stream_t *p_stream, f_aspect = f_aspect * i_dst_width / i_dst_height; /* Store calculated values */ - id->p_encoder->fmt_out.video.i_width = i_dst_width; - id->p_encoder->fmt_out.video.i_height = i_dst_height; + id->p_encoder->fmt_out.video.i_width = + id->p_encoder->fmt_out.video.i_visible_width = i_dst_width; + id->p_encoder->fmt_out.video.i_height = + id->p_encoder->fmt_out.video.i_visible_height = i_dst_height; - id->p_encoder->fmt_in.video.i_width = i_dst_width; - id->p_encoder->fmt_in.video.i_height = i_dst_height; + id->p_encoder->fmt_in.video.i_width = + id->p_encoder->fmt_in.video.i_visible_width = i_dst_width; + id->p_encoder->fmt_in.video.i_height = + id->p_encoder->fmt_in.video.i_visible_height = i_dst_height; msg_Dbg( p_stream, "source %ix%i, destination %ix%i", i_src_width, i_src_height, @@ -1923,13 +1956,12 @@ static int transcode_video_process( sout_stream_t *p_stream, id->p_encoder->fmt_in.video.i_width; id->p_encoder->fmt_out.video.i_height = id->p_encoder->fmt_in.video.i_height; + id->p_encoder->fmt_out.video.i_aspect = + id->p_encoder->fmt_in.video.i_aspect; } if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS ) { - filter_chain_Delete( id->p_f_chain ); - if( id->p_uf_chain ) - filter_chain_Delete( id->p_uf_chain ); p_pic->pf_release( p_pic ); transcode_video_close( p_stream, id ); id->b_transcode = false; @@ -1949,7 +1981,7 @@ static int transcode_video_process( sout_stream_t *p_stream, if( p_sys->p_spu ) { p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date, - false /* Fixme: check if stream is paused */ ); + false /* Fixme: check if stream is paused */, false ); /* TODO: get another pic */ } @@ -1976,13 +2008,16 @@ static int transcode_video_process( sout_stream_t *p_stream, } } - fmt = filter_chain_GetFmtOut( id->p_f_chain )->video; + if( filter_chain_GetLength( id->p_f_chain ) > 0 ) + fmt = filter_chain_GetFmtOut( id->p_f_chain )->video; + else + fmt = id->p_decoder->fmt_out.video; /* FIXME (shouldn't have to be done here) */ fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width; fmt.i_sar_den = VOUT_ASPECT_FACTOR; - spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic, + spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_subpic, i_scale_width, i_scale_height ); } @@ -2071,12 +2106,14 @@ static int transcode_video_process( sout_stream_t *p_stream, return VLC_SUCCESS; } -static int EncoderThread( sout_stream_sys_t *p_sys ) +static void* EncoderThread( vlc_object_t* p_this ) { + sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this; sout_stream_id_t *id = p_sys->id_video; picture_t *p_pic; + int canc = vlc_savecancel (); - while( !p_sys->b_die && !p_sys->b_error ) + while( vlc_object_alive (p_sys) && !p_sys->b_error ) { block_t *p_block; @@ -2084,9 +2121,9 @@ static int EncoderThread( sout_stream_sys_t *p_sys ) while( p_sys->i_last_pic == p_sys->i_first_pic ) { vlc_cond_wait( &p_sys->cond, &p_sys->lock_out ); - if( p_sys->b_die || p_sys->b_error ) break; + if( !vlc_object_alive (p_sys) || p_sys->b_error ) break; } - if( p_sys->b_die || p_sys->b_error ) + if( !vlc_object_alive (p_sys) || p_sys->b_error ) { vlc_mutex_unlock( &p_sys->lock_out ); break; @@ -2115,7 +2152,8 @@ static int EncoderThread( sout_stream_sys_t *p_sys ) } block_ChainRelease( p_sys->p_buffers ); - return 0; + vlc_restorecancel (canc); + return NULL; } struct picture_sys_t @@ -2240,6 +2278,7 @@ static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic ) VLC_UNUSED(p_this); if( p_pic ) { + free( p_pic->p_q ); free( p_pic->p_data_orig ); free( p_pic->p_sys ); free( p_pic ); @@ -2251,6 +2290,7 @@ static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic ) VLC_UNUSED(p_decoder); p_pic->i_refcount = 0; p_pic->i_status = DESTROYED_PICTURE; + picture_CleanupQuant( p_pic ); } static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic ) @@ -2258,6 +2298,7 @@ static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic ) VLC_UNUSED(p_filter); p_pic->i_refcount = 0; p_pic->i_status = DESTROYED_PICTURE; + picture_CleanupQuant( p_pic ); } static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic ) @@ -2484,7 +2525,7 @@ static int transcode_osd_process( sout_stream_t *p_stream, /* Check if we have a subpicture to send */ if( p_sys->p_spu && in->i_dts > 0) { - p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false ); + p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false ); } else {