X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fcsri.c;h=8e43d178fb4ace1685225c7d217673df422ce340;hb=ea93da268c6617a0c5c98a2125b9aa27eba19d6d;hp=1df576254a96aceb3885f1da60c5af438669c4e8;hpb=449fd28aaf007c6411251dae9d0dbfdc65b135d1;p=vlc diff --git a/modules/codec/csri.c b/modules/codec/csri.c index 1df576254a..8e43d178fb 100644 --- a/modules/codec/csri.c +++ b/modules/codec/csri.c @@ -24,47 +24,33 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include +#include -#include "config.h" -#include +#include +#include #include #include #include -#include -#include -#include -#include - -#include - -#ifdef HAVE_ERRNO_H -# include -#endif +#include #include #include /***************************************************************************** - * Local prototypes + * Module descriptor *****************************************************************************/ static int Create ( vlc_object_t * ); static void Destroy( vlc_object_t * ); -static subpicture_t *DecodeBlock( decoder_t *, block_t ** ); -static void DestroySubpicture( subpicture_t * ); -static void PreRender( video_format_t *, spu_t *, subpicture_t *, mtime_t ); -static subpicture_region_t *UpdateRegions( video_format_t *, spu_t *, - subpicture_t *, mtime_t ); - -/***************************************************************************** - * Module descriptor - *****************************************************************************/ - vlc_module_begin(); - set_shortname( _("Subtitles (advanced)")); - set_description( _("Wrapper for subtitle renderers using CSRI/asa") ); + set_shortname( N_("Subtitles (advanced)")); + set_description( N_("Wrapper for subtitle renderers using CSRI/asa") ); set_capability( "decoder", 60 ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_SCODEC ); @@ -72,13 +58,25 @@ vlc_module_begin(); vlc_module_end(); /***************************************************************************** - * decoder_sys_t: filter data + * Local prototypes + *****************************************************************************/ +static subpicture_t *DecodeBlock( decoder_t *, block_t ** ); +static void DestroySubpicture( subpicture_t * ); +static void PreRender( video_format_t *, spu_t *, subpicture_t * ); +static void UpdateRegions( video_format_t *, spu_t *, + subpicture_t *, mtime_t ); + +/***************************************************************************** + * decoder_sys_t: decoder data *****************************************************************************/ struct decoder_sys_t { subpicture_t *p_spu_final; video_format_t fmt_cached; csri_inst *p_instance; + + struct csri_stream_ext *p_stream_ext; + void (*pf_push_packet)(csri_inst *inst, const void *packet, size_t packetlen, double pts_start, double pts_end); @@ -101,12 +99,10 @@ static int Create( vlc_object_t *p_this ) decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys; csri_rend *p_render; - struct csri_stream_ext *p_streamext; + struct csri_stream_ext *p_stream_ext; if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') ) - { return VLC_EGENERIC; - } p_render = csri_renderer_default(); if (!p_render) @@ -114,8 +110,8 @@ static int Create( vlc_object_t *p_this ) msg_Err( p_dec, "can't load csri renderer" ); return VLC_EGENERIC; } - p_streamext = csri_query_ext(p_render, CSRI_EXT_STREAM_ASS); - if (!p_streamext) + p_stream_ext = csri_query_ext(p_render, CSRI_EXT_STREAM_ASS); + if (!p_stream_ext) { msg_Err( p_dec, "csri renderer does not support ASS streaming" ); return VLC_EGENERIC; @@ -125,17 +121,15 @@ static int Create( vlc_object_t *p_this ) p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) ); if( !p_sys ) - { - msg_Err( p_dec, "out of memory" ); return VLC_ENOMEM; - } - memset( &p_dec->p_sys->fmt_cached, 0, sizeof( p_dec->p_sys->fmt_cached ) ); - - p_sys->pf_push_packet = p_streamext->push_packet; - p_sys->p_instance = p_streamext->init_stream(p_render, - p_dec->fmt_in.p_extra, - p_dec->fmt_in.i_extra - 1, - NULL); + memset( &p_sys->fmt_cached, 0, sizeof( p_sys->fmt_cached ) ); + + p_sys->p_stream_ext = p_stream_ext; + p_sys->pf_push_packet = p_stream_ext->push_packet; + p_sys->p_instance = p_stream_ext->init_stream( p_render, + p_dec->fmt_in.p_extra, + p_dec->fmt_in.p_extra ? strnlen( p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra ) : 0, + NULL); return VLC_SUCCESS; } @@ -146,9 +140,11 @@ static int Create( vlc_object_t *p_this ) *****************************************************************************/ static void Destroy( vlc_object_t *p_this ) { - filter_t *p_filter = (filter_t *)p_this; - filter_sys_t *p_sys = p_filter->p_sys; + decoder_t *p_dec = (decoder_t *)p_this; + decoder_sys_t *p_sys = p_dec->p_sys; + if( p_sys->p_stream_ext->discard ) + p_sys->p_stream_ext->discard( p_sys->p_instance, true ); free( p_sys ); } @@ -159,30 +155,39 @@ static void Destroy( vlc_object_t *p_this ) ****************************************************************************/ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { + decoder_sys_t *p_sys = p_dec->p_sys; + subpicture_t *p_spu = NULL; block_t *p_block; - msg_Dbg( p_dec, "DecodeBlock %p", (void *)pp_block); - if( !pp_block || *pp_block == NULL ) return NULL; + //msg_Dbg( p_dec, "DecodeBlock %p", (void *)pp_block); + if( !pp_block || *pp_block == NULL ) + return NULL; + p_block = *pp_block; - if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' ) return NULL; + if( p_block->i_rate != 0 ) + p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT; + *pp_block = NULL; + + if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' ) + { + block_Release( p_block ); + return NULL; + } p_spu = p_dec->pf_spu_buffer_new( p_dec ); if( !p_spu ) { msg_Warn( p_dec, "can't get spu buffer" ); - block_Release( *pp_block ); - *pp_block = NULL; + block_Release( p_block ); return NULL; } p_spu->p_sys = malloc( sizeof( subpicture_sys_t )); if( !p_spu->p_sys ) { - msg_Err( p_dec, "out of memory" ); p_dec->pf_spu_buffer_del( p_dec, p_spu ); - block_Release( *pp_block ); - *pp_block = NULL; + block_Release( p_block ); return NULL; } p_spu->p_sys->p_dec = p_dec; @@ -191,11 +196,9 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_spu->p_sys->p_subs_data = malloc( p_block->i_buffer ); if( !p_spu->p_sys->p_subs_data ) { - msg_Err( p_dec, "out of memory" ); free( p_spu->p_sys ); p_dec->pf_spu_buffer_del( p_dec, p_spu ); - block_Release( *pp_block ); - *pp_block = NULL; + block_Release( p_block ); return NULL; } memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer, @@ -209,83 +212,109 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_spu->b_absolute = false; p_spu->b_pausable = true; - msg_Dbg( p_dec, "BS %lf..%lf", p_spu->i_start * 0.000001, p_spu->i_stop * 0.000001); - p_dec->p_sys->pf_push_packet(p_dec->p_sys->p_instance, - p_spu->p_sys->p_subs_data, p_block->i_buffer, - p_spu->i_start * 0.000001, - p_spu->i_stop * 0.000001); + //msg_Dbg( p_dec, "BS %lf..%lf", p_spu->i_start * 0.000001, p_spu->i_stop * 0.000001); + p_sys->pf_push_packet( p_sys->p_instance, + p_spu->p_sys->p_subs_data, p_spu->p_sys->i_subs_len, + p_spu->i_start * 0.000001, + p_spu->i_stop * 0.000001); p_spu->pf_pre_render = PreRender; p_spu->pf_update_regions = UpdateRegions; p_spu->pf_destroy = DestroySubpicture; - block_Release( *pp_block ); - *pp_block = NULL; + block_Release( p_block ); return p_spu; } static void DestroySubpicture( subpicture_t *p_subpic ) { - msg_Dbg( p_subpic->p_sys->p_dec, "drop spu %p", (void *)p_subpic ); + //msg_Dbg( p_subpic->p_sys->p_dec, "drop spu %p", (void *)p_subpic ); free( p_subpic->p_sys->p_subs_data ); free( p_subpic->p_sys ); } static void PreRender( video_format_t *p_fmt, spu_t *p_spu, - subpicture_t *p_subpic, mtime_t ts ) + subpicture_t *p_subpic ) { decoder_t *p_dec = p_subpic->p_sys->p_dec; p_dec->p_sys->p_spu_final = p_subpic; } -static subpicture_region_t *UpdateRegions( video_format_t *p_fmt, spu_t *p_spu, - subpicture_t *p_subpic, mtime_t ts ) +static void UpdateRegions( video_format_t *p_fmt, spu_t *p_spu, + subpicture_t *p_subpic, mtime_t ts ) { decoder_t *p_dec = p_subpic->p_sys->p_dec; + decoder_sys_t *p_sys = p_dec->p_sys; + subpicture_region_t *p_spu_region; video_format_t fmt; - struct csri_frame csri_frame; - if (p_subpic != p_dec->p_sys->p_spu_final) + /* TODO maybe checking if we really need redrawing */ + while( p_subpic->p_region ) { - return NULL; + subpicture_region_t *p_region = p_subpic->p_region; + p_subpic->p_region = p_region->p_next; + spu_DestroyRegion( p_spu, p_region ); } + p_subpic->p_region = NULL; - memcpy( &fmt, p_fmt, sizeof( fmt ) ); + /* FIXME check why this is needed */ + if( p_subpic != p_sys->p_spu_final ) + return; + +#if 0 + msg_Warn( p_dec, "---- fmt: %dx%d %dx%d chroma=%4.4s", + p_fmt->i_width, p_fmt->i_height, + p_fmt->i_visible_width, p_fmt->i_visible_height, + (const char*)&p_fmt->i_chroma ); +#endif + /* XXX On x86 at least our RGBA is mapped to their BGRA + * TODO confirm that is the same on big endian cpu */ + fmt = *p_fmt; fmt.i_chroma = VLC_FOURCC('R','G','B','A'); fmt.i_width = fmt.i_visible_width; fmt.i_height = fmt.i_visible_height; fmt.i_bits_per_pixel = 0; fmt.i_x_offset = fmt.i_y_offset = 0; + fmt.i_sar_num = 1; + fmt.i_sar_den = 1; - if (memcmp(&fmt, &p_dec->p_sys->fmt_cached, sizeof(fmt))) + if( memcmp(&fmt, &p_sys->fmt_cached, sizeof(fmt)) ) { + //msg_Warn( p_dec, "---- fmt: new %dx%d", fmt.i_width, fmt.i_height ); + struct csri_fmt csri_fmt; memset(&csri_fmt, 0, sizeof(csri_fmt)); - csri_fmt.pixfmt = CSRI_F_RGBA; + csri_fmt.pixfmt = CSRI_F_BGRA; csri_fmt.width = fmt.i_width; csri_fmt.height = fmt.i_height; - if( csri_request_fmt(p_dec->p_sys->p_instance, &csri_fmt) ) + if( csri_request_fmt( p_sys->p_instance, &csri_fmt ) ) msg_Dbg( p_dec, "csri error: format not supported" ); - memcpy(&p_dec->p_sys->fmt_cached, &fmt, sizeof(fmt)); + p_sys->fmt_cached = fmt; } - p_spu_region = p_subpic->pf_create_region( VLC_OBJECT(p_dec), &fmt ); - p_spu_region->i_align = SUBPICTURE_ALIGN_TOP; + p_subpic->i_original_picture_height = fmt.i_height; + p_subpic->i_original_picture_width = fmt.i_width; - csri_frame.pixfmt = CSRI_F_RGBA; - csri_frame.planes[0] = (unsigned char*)p_spu_region->picture.Y_PIXELS; - csri_frame.strides[0] = p_spu_region->picture.Y_PITCH; + p_spu_region = p_subpic->p_region = p_subpic->pf_create_region( VLC_OBJECT(p_dec), &fmt ); - msg_Dbg( p_dec, "TS %lf", ts * 0.000001 ); - csri_render( p_dec->p_sys->p_instance, &csri_frame, ts * 0.000001 ); - memset(p_spu_region->picture.Y_PIXELS, 0xff, fmt.i_width); - memset(p_spu_region->picture.Y_PIXELS + p_spu_region->picture.Y_PITCH - * (fmt.i_height - 1), 0x88, fmt.i_width); - - p_subpic->p_region = p_spu_region; - return p_spu_region; + if( p_spu_region ) + { + struct csri_frame csri_frame; + + /* */ + p_spu_region->i_align = SUBPICTURE_ALIGN_TOP | SUBPICTURE_ALIGN_LEFT; + memset( p_spu_region->picture.Y_PIXELS, 0x00, p_spu_region->picture.Y_PITCH * p_sys->fmt_cached.i_height ); + + /* */ + //msg_Dbg( p_dec, "TS %lf", ts * 0.000001 ); + memset( &csri_frame, 0, sizeof(csri_frame) ); + csri_frame.pixfmt = CSRI_F_BGRA; + csri_frame.planes[0] = (unsigned char*)p_spu_region->picture.Y_PIXELS; + csri_frame.strides[0] = p_spu_region->picture.Y_PITCH; + csri_render( p_sys->p_instance, &csri_frame, ts * 0.000001 ); + } }