Commit 3ea1b0e9 authored by Gildas Bazin's avatar Gildas Bazin

* ALL: Major rework of the subpictures architecture.

  (expect some breakage).
* modules/video_filter/blend.c: new alpha-blending module.
parent 327a8a92
......@@ -98,6 +98,7 @@ HEADERS_include = \
include/vlc_error.h \
include/vlc_es.h \
include/vlc_es_out.h \
include/vlc_filter.h \
include/vlc_help.h \
include/vlc_httpd.h \
include/vlc_input.h \
......
......@@ -952,7 +952,7 @@ VLC_ADD_PLUGINS([trivial_mixer spdif_mixer float32_mixer])
VLC_ADD_PLUGINS([aout_file equalizer])
VLC_ADD_PLUGINS([i420_rgb i420_yuy2 i422_yuy2 i420_ymga])
VLC_ADD_PLUGINS([m3u id3 playlist export sgimb])
VLC_ADD_PLUGINS([rawvideo])
VLC_ADD_PLUGINS([rawvideo blend])
VLC_ADD_PLUGINS([wav araw subtitle adpcm a52sys dtssys au])
VLC_ADD_PLUGINS([access_file access_udp access_tcp access_http ipv4 access_mms])
VLC_ADD_PLUGINS([access_ftp access_directory sap http])
......
......@@ -53,7 +53,7 @@ struct text_style_t
};
static const text_style_t default_text_style = { 22, 0xffffff, VLC_FALSE, VLC_FALSE, VLC_FALSE };
VLC_EXPORT( subpicture_t *, vout_ShowTextRelative, ( vout_thread_t *, int, char *, text_style_t *, int, int, int, mtime_t ) );
VLC_EXPORT( int, vout_ShowTextRelative, ( vout_thread_t *, int, char *, text_style_t *, int, int, int, mtime_t ) );
VLC_EXPORT( int, vout_ShowTextAbsolute, ( vout_thread_t *, int, char *, text_style_t *, int, int, int, mtime_t, mtime_t ) );
VLC_EXPORT( void, __vout_OSDMessage, ( vlc_object_t *, int, char *, ... ) );
/**
......
......@@ -123,14 +123,26 @@ struct vout_thread_t
vout_chroma_t chroma; /**< translation tables */
/**@}*/
/* Picture and subpicture heaps */
/* Picture heap */
picture_t p_picture[2*VOUT_MAX_PICTURES+1]; /**< pictures */
/* Subpicture properties */
subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /**< subpictures */
subpicture_t *p_default_channel; /**< subpicture in the default
channel */
int i_channel_count; /**< index of last subpicture
channel registered */
filter_t *p_blend; /**< alpha blending module */
filter_t *p_text; /**< text renderer module */
vlc_bool_t b_force_crop; /**< force cropping of subpicture */
int i_crop_x, i_crop_y, i_crop_width, i_crop_height; /**< cropping */
vlc_bool_t b_force_alpha; /**< force alpha palette of subpicture */
uint8_t pi_alpha[4]; /**< forced alpha palette */
/* Statistics */
count_t c_loops;
count_t c_pictures, c_late_pictures;
......@@ -144,15 +156,6 @@ struct vout_thread_t
/* Filter chain */
char *psz_filter_chain;
vlc_bool_t b_filter_change;
/* text renderer data */
text_renderer_sys_t * p_text_renderer_data; /**< private data for
the text renderer */
module_t * p_text_renderer_module; /**< text renderer module */
/** callback used when a new string needs to be shown on the vout */
subpicture_t * ( *pf_add_string ) ( vout_thread_t *, int, char *,
text_style_t *, int, int, int, mtime_t,
mtime_t );
};
#define I_OUTPUTPICTURES p_vout->output.i_pictures
......@@ -268,10 +271,16 @@ VLC_EXPORT( void, vout_DestroySubPicture, ( vout_thread_t *, subpict
VLC_EXPORT( void, vout_DisplaySubPicture, ( vout_thread_t *, subpicture_t * ) );
VLC_EXPORT( int, vout_RegisterOSDChannel, ( vout_thread_t * ) );
VLC_EXPORT( void, vout_ClearOSDChannel, ( vout_thread_t *, int ) );
subpicture_t * vout_SortSubPictures ( vout_thread_t *, mtime_t );
void vout_RenderSubPictures ( vout_thread_t *, picture_t *,
subpicture_t * );
#define spu_CreateRegion(a,b) __spu_CreateRegion(VLC_OBJECT(a),b)
VLC_EXPORT( subpicture_region_t *,__spu_CreateRegion, ( vlc_object_t *, video_format_t * ) );
#define spu_DestroyRegion(a,b) __spu_DestroyRegion(VLC_OBJECT(a),b)
VLC_EXPORT( void, __spu_DestroyRegion, ( vlc_object_t *, subpicture_region_t * ) );
void vout_InitSPU( vout_thread_t * );
void vout_DestroySPU( vout_thread_t * );
subpicture_t * vout_SortSubPictures ( vout_thread_t *, mtime_t );
void vout_RenderSubPictures( vout_thread_t *, picture_t *,
subpicture_t * );
/** @}*/
/**
* @}
......
......@@ -48,7 +48,7 @@ struct decoder_t
picture_t * ( * pf_decode_video )( decoder_t *, block_t ** );
aout_buffer_t * ( * pf_decode_audio )( decoder_t *, block_t ** );
void ( * pf_decode_sub) ( decoder_t *, block_t ** );
subpicture_t * ( * pf_decode_sub) ( decoder_t *, block_t ** );
block_t * ( * pf_packetize ) ( decoder_t *, block_t ** );
/* Some decoders only accept packetized data (ie. not truncated) */
......@@ -74,6 +74,9 @@ struct decoder_t
void ( * pf_picture_link) ( decoder_t *, picture_t * );
void ( * pf_picture_unlink) ( decoder_t *, picture_t * );
/* SPU output callbacks */
subpicture_t * ( * pf_spu_buffer_new) ( decoder_t * );
void ( * pf_spu_buffer_del) ( decoder_t *, subpicture_t * );
/* Private structure for the owner of the decoder */
decoder_owner_sys_t *p_owner;
......
......@@ -277,6 +277,7 @@ typedef struct picture_sys_t picture_sys_t;
typedef struct picture_heap_t picture_heap_t;
typedef struct subpicture_t subpicture_t;
typedef struct subpicture_sys_t subpicture_sys_t;
typedef struct subpicture_region_t subpicture_region_t;
typedef struct vout_synchro_t vout_synchro_t;
typedef struct text_renderer_sys_t text_renderer_sys_t;
typedef struct text_style_t text_style_t;
......@@ -314,6 +315,10 @@ typedef struct decoder_sys_t decoder_sys_t;
typedef struct encoder_t encoder_t;
typedef struct encoder_sys_t encoder_sys_t;
/* Filters */
typedef struct filter_t filter_t;
typedef struct filter_sys_t filter_sys_t;
/* Misc */
typedef struct data_packet_t data_packet_t;
typedef struct data_buffer_t data_buffer_t;
......
......@@ -36,10 +36,8 @@
*/
struct video_palette_t
{
int i_dummy; /**< to keep the compatibility with ffmpeg's palette */
uint32_t palette[256]; /**< 4-byte ARGB palette entries, stored in native
* byte order */
int i_dummy; /**< to keep the compatibility with ffmpeg's palette */
uint8_t palette[256][4]; /**< 4-byte RGBA/YUVA palette */
};
/**
......@@ -96,6 +94,7 @@ struct video_format_t
unsigned int i_frame_rate; /**< frame rate numerator */
unsigned int i_frame_rate_base; /**< frame rate denominator */
int i_rmask, i_rgmask, i_bmask; /**< color masks for RGB chroma */
video_palette_t *p_palette; /**< video palette from demuxer */
};
......
/*****************************************************************************
* vlc_codec.h: codec related structures
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* 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
* (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.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef _VLC_FILTER_H
#define _VLC_FILTER_H 1
/**
* \file
* This file defines the structure and types used by video and audio filters
*/
typedef struct filter_owner_sys_t filter_owner_sys_t;
/**
* \defgroup filter Filter
*
* The structure describing a filter
*
* @{
*/
struct filter_t
{
VLC_COMMON_MEMBERS
/* Module properties */
module_t * p_module;
filter_sys_t * p_sys;
void ( * pf_video_blend ) ( filter_t *, picture_t *,
picture_t *, picture_t *,
int, int );
picture_t * ( * pf_video_filter ) ( filter_t *, picture_t * );
subpicture_t * ( *pf_render_string ) ( filter_t *, block_t * );
/* Input format */
es_format_t fmt_in;
/* Output format of filter */
es_format_t fmt_out;
/*
* Buffers allocation
*/
/* Audio output callbacks */
aout_buffer_t * ( * pf_aout_buffer_new) ( filter_t *, int );
void ( * pf_aout_buffer_del) ( filter_t *, aout_buffer_t * );
/* Video output callbacks */
picture_t * ( * pf_vout_buffer_new) ( filter_t * );
void ( * pf_vout_buffer_del) ( filter_t *, picture_t * );
void ( * pf_picture_link) ( filter_t *, picture_t * );
void ( * pf_picture_unlink) ( filter_t *, picture_t * );
/* SPU output callbacks */
subpicture_t * ( * pf_spu_buffer_new) ( filter_t * );
void ( * pf_spu_buffer_del) ( filter_t *, subpicture_t * );
/* Private structure for the owner of the decoder */
filter_owner_sys_t *p_owner;
};
/**
* @}
*/
#endif /* _VLC_FILTER_H */
......@@ -175,6 +175,8 @@ struct picture_heap_t
#define U_PITCH p[U_PLANE].i_pitch
#define V_PIXELS p[V_PLANE].p_pixels
#define V_PITCH p[V_PLANE].i_pitch
#define A_PIXELS p[A_PLANE].p_pixels
#define A_PITCH p[A_PLANE].i_pitch
/**
* \defgroup subpicture Video Subpictures
......@@ -184,6 +186,28 @@ struct picture_heap_t
* @{
*/
/**
* Video subtitle region
*
* A subtitle region is defined by a picture (graphic) and its rendering
* coordinates.
* Subtitles contain a list of regions.
*/
struct subpicture_region_t
{
/** \name Region properties */
/**@{*/
video_format_t fmt; /**< format of the picture */
picture_t picture; /**< picture comprising this region */
int i_x; /**< position of region */
int i_y; /**< position of region */
subpicture_region_t *p_next; /**< next region in the list */
/**@}*/
};
/**
* Video subtitle
*
......@@ -216,6 +240,8 @@ struct subpicture_t
untill the next one appear */
/**@}*/
subpicture_region_t *p_region; /**< region list composing this subtitle */
/** \name Display properties
* These properties are only indicative and may be
* changed by the video output thread, or simply ignored depending of the
......@@ -225,13 +251,20 @@ struct subpicture_t
int i_y; /**< offset from alignment position */
int i_width; /**< picture width */
int i_height; /**< picture height */
/**@}*/
int b_absolute; /**< position is absolute */
int i_flags; /**< position flags */
/**@}*/
/** Pointer to function that renders this subtitle in a picture */
void ( *pf_render ) ( vout_thread_t *, picture_t *, const subpicture_t * );
/** Pointer to function that cleans up the private data of this subtitle */
void ( *pf_destroy ) ( subpicture_t * );
/** Pointer to functions for region management */
subpicture_region_t * ( *pf_create_region ) ( vlc_object_t *,
video_format_t * );
void ( *pf_destroy_region ) ( vlc_object_t *, subpicture_region_t * );
/** Private data - the subtitle plugin might want to put stuff here to
* keep track of the subpicture */
subpicture_sys_t *p_sys; /* subpicture data */
......
This diff is collapsed.
SOURCES_spudec = \
spudec.c \
parse.c \
render.c \
spudec.h \
$(NULL)
This diff is collapsed.
This diff is collapsed.
......@@ -26,7 +26,6 @@
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include "spudec.h"
......@@ -36,8 +35,7 @@
*****************************************************************************/
static int DecoderOpen ( vlc_object_t * );
static int PacketizerOpen( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Close ( vlc_object_t * );
vlc_module_begin();
set_description( _("DVD subtitles decoder") );
......@@ -53,12 +51,9 @@ vlc_module_end();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static vout_thread_t *FindVout( decoder_t *);
static block_t *Reassemble( decoder_t *, block_t ** );
static void Decode ( decoder_t *, block_t ** );
static block_t *Packetize( decoder_t *, block_t ** );
static block_t * Reassemble( decoder_t *, block_t ** );
static subpicture_t * Decode ( decoder_t *, block_t ** );
static block_t * Packetize ( decoder_t *, block_t ** );
/*****************************************************************************
* DecoderOpen
......@@ -83,7 +78,6 @@ static int DecoderOpen( vlc_object_t *p_this )
p_sys->i_spu_size = 0;
p_sys->i_spu = 0;
p_sys->p_block = NULL;
p_sys->p_vout = NULL;
es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 's','p','u',' ' ) );
......@@ -120,71 +114,39 @@ static void Close( vlc_object_t *p_this )
decoder_t *p_dec = (decoder_t*)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
if( !p_sys->b_packetizer )
{
/* FIXME check if it's ok to not lock vout */
if( p_sys->p_vout != NULL && p_sys->p_vout->p_subpicture != NULL )
{
subpicture_t * p_subpic;
int i_subpic;
for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
{
p_subpic = &p_sys->p_vout->p_subpicture[i_subpic];
if( p_subpic != NULL &&
( ( p_subpic->i_status == RESERVED_SUBPICTURE ) ||
( p_subpic->i_status == READY_SUBPICTURE ) ) )
{
vout_DestroySubPicture( p_sys->p_vout, p_subpic );
}
}
}
}
if( p_sys->p_block )
{
block_ChainRelease( p_sys->p_block );
}
if( p_sys->p_block ) block_ChainRelease( p_sys->p_block );
free( p_sys );
}
/*****************************************************************************
* Decode:
*****************************************************************************/
static void Decode( decoder_t *p_dec, block_t **pp_block )
static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_spu = Reassemble( p_dec, pp_block );
vout_thread_t *p_last_vout = p_dec->p_sys->p_vout;
block_t *p_spu_block;
if( p_spu )
if( (p_spu_block = Reassemble( p_dec, pp_block )) )
{
p_sys->i_spu = block_ChainExtract( p_spu, p_sys->buffer, 65536 );
p_sys->i_pts = p_spu->i_pts;
block_ChainRelease( p_spu );
subpicture_t *p_spu;
if( ( p_sys->p_vout = FindVout( p_dec ) ) )
{
if( p_last_vout != p_sys->p_vout )
{
p_sys->i_subpic_channel =
vout_RegisterOSDChannel( p_sys->p_vout );
}
p_sys->i_spu = block_ChainExtract( p_spu_block, p_sys->buffer, 65536 );
p_sys->i_pts = p_spu_block->i_pts;
block_ChainRelease( p_spu_block );
/* Parse and decode */
E_(ParsePacket)( p_dec );
vlc_object_release( p_sys->p_vout );
}
/* Parse and decode */
p_spu = E_(ParsePacket)( p_dec );
/* reinit context */
p_sys->i_spu_size = 0;
p_sys->i_rle_size = 0;
p_sys->i_spu = 0;
p_sys->p_block = NULL;
return p_spu;
}
return NULL;
}
/*****************************************************************************
......@@ -208,6 +170,7 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
return block_ChainGather( p_spu );
}
return NULL;
}
......@@ -219,17 +182,16 @@ static block_t *Reassemble( decoder_t *p_dec, block_t **pp_block )
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
if( pp_block == NULL || *pp_block == NULL )
{
return NULL;
}
if( pp_block == NULL || *pp_block == NULL ) return NULL;
p_block = *pp_block;
*pp_block = NULL;
if( p_sys->i_spu_size <= 0 && ( p_block->i_pts <= 0 || p_block->i_buffer < 4 ) )
if( p_sys->i_spu_size <= 0 &&
( p_block->i_pts <= 0 || p_block->i_buffer < 4 ) )
{
msg_Dbg( p_dec, "invalid starting packet (size < 4 or pts <=0)" );
msg_Dbg( p_dec, "spu size: %d, i_pts: "I64Fd" i_buffer: %d", p_sys->i_spu_size, p_block->i_pts, p_block->i_buffer );
msg_Dbg( p_dec, "spu size: %d, i_pts: "I64Fd" i_buffer: %d",
p_sys->i_spu_size, p_block->i_pts, p_block->i_buffer );
block_Release( p_block );
return NULL;
}
......@@ -239,11 +201,14 @@ static block_t *Reassemble( decoder_t *p_dec, block_t **pp_block )
if( p_sys->i_spu_size <= 0 )
{
p_sys->i_spu_size = ( p_block->p_buffer[0] << 8 )| p_block->p_buffer[1];
p_sys->i_rle_size = ( ( p_block->p_buffer[2] << 8 )| p_block->p_buffer[3] ) - 4;
p_sys->i_spu_size = ( p_block->p_buffer[0] << 8 )|
p_block->p_buffer[1];
p_sys->i_rle_size = ( ( p_block->p_buffer[2] << 8 )|
p_block->p_buffer[3] ) - 4;
/* msg_Dbg( p_dec, "i_spu_size=%d i_rle=%d",
p_sys->i_spu_size, p_sys->i_rle_size ); */
if( p_sys->i_spu_size <= 0 || p_sys->i_rle_size >= p_sys->i_spu_size )
{
p_sys->i_spu_size = 0;
......@@ -266,34 +231,3 @@ static block_t *Reassemble( decoder_t *p_dec, block_t **pp_block )
}
return NULL;
}
/* following functions are local */
/*****************************************************************************
* FindVout: Find a vout or wait for one to be created.
*****************************************************************************/
static vout_thread_t *FindVout( decoder_t *p_dec )
{
vout_thread_t *p_vout = NULL;
/* Find an available video output */
do
{
if( p_dec->b_die || p_dec->b_error )
{
break;
}
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( p_vout )
{
break;
}
msleep( VOUT_OUTMEM_SLEEP );
}
while( 1 );
return p_vout;
}
......@@ -30,16 +30,13 @@ struct decoder_sys_t
int i_rle_size;
int i_spu;
int i_subpic_channel;
block_t *p_block;
uint8_t buffer[65536 + 20 ]; /* we will never overflow more than 11 bytes if I'm right */
vout_thread_t *p_vout;
/* We will never overflow more than 11 bytes if I'm right */
uint8_t buffer[65536 + 20 ];
};
struct subpicture_sys_t
typedef struct subpicture_data_t
{
mtime_t i_pts; /* presentation timestamp */
......@@ -51,14 +48,7 @@ struct subpicture_sys_t
uint8_t pi_alpha[4];
uint8_t pi_yuv[4][3];
/* Link to our input */
vlc_object_t * p_input;
/* Cropping properties */
vlc_mutex_t lock;
vlc_bool_t b_crop;
unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
};
} subpicture_data_t;
/*****************************************************************************
* Amount of bytes we GetChunk() in one go
......@@ -80,7 +70,4 @@ struct subpicture_sys_t
/*****************************************************************************
* Prototypes
*****************************************************************************/
void E_(ParsePacket)( decoder_t * );
void E_(RenderSPU) ( vout_thread_t *, picture_t *, const subpicture_t * );
subpicture_t * E_(ParsePacket)( decoder_t * );
This diff is collapsed.
......@@ -23,22 +23,19 @@
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "vlc_block.h"
#include "vlc_filter.h"
static subpicture_t * AddText( vout_thread_t *, int, char *, text_style_t *,
int, int, int, mtime_t, mtime_t );
static subpicture_t *RenderText( filter_t *, block_t * );
int E_(OpenRenderer)( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
p_vout->pf_add_string = AddText;
filter_t *p_filter = (filter_t *)p_this;
p_filter->pf_render_string = RenderText;
return VLC_SUCCESS;
}
static subpicture_t * AddText( vout_thread_t *p_vout, int i_channel,
char *psz_string, text_style_t *p_style , int i_flags,
int i_x_margin, int i_y_margin, mtime_t i_start,
mtime_t i_stop )
static subpicture_t *RenderText( filter_t *p_filter, block_t *p_block )
{
return VLC_SUCCESS;
return NULL;
}
This diff is collapsed.
......@@ -8,4 +8,5 @@ SOURCES_crop = crop.c
SOURCES_motionblur = motionblur.c
SOURCES_logo = logo.c
SOURCES_deinterlace = deinterlace.c
SOURCES_blend = blend.c
noinst_HEADERS += filter_common.h
This diff is collapsed.
......@@ -51,6 +51,9 @@ static void vout_del_buffer( decoder_t *, picture_t * );
static void vout_link_picture( decoder_t *, picture_t * );
static void vout_unlink_picture( decoder_t *, picture_t * );
static subpicture_t *spu_new_buffer( decoder_t * );
static void spu_del_buffer( decoder_t *, subpicture_t * );
static es_format_t null_es_format = {0};
struct decoder_owner_sys_t
......@@ -64,6 +67,9 @@ struct decoder_owner_sys_t
vout_thread_t *p_vout;
vout_thread_t *p_spu_vout;
int i_spu_channel;
sout_instance_t *p_sout;
sout_packetizer_input_t *p_sout_input;
......@@ -387,17 +393,19 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
p_dec->p_owner->p_aout = NULL;
p_dec->p_owner->p_aout_input = NULL;
p_dec->p_owner->p_vout = NULL;
p_dec->p_owner->p_spu_vout = NULL;
p_dec->p_owner->i_spu_channel = 0;
p_dec->p_owner->p_sout = p_input->p_sout;
p_dec->p_owner->p_sout_input = NULL;
p_dec->p_owner->p_packetizer = NULL;
/* decoder fifo */
if( ( p_dec->p_owner->p_fifo = block_FifoNew( p_dec ) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return NULL;
}
/* Set buffers allocation callbacks for the decoders */
p_dec->pf_aout_buffer_new = aout_new_buffer;
p_dec->pf_aout_buffer_del = aout_del_buffer;
......@@ -405,6 +413,8 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
p_dec->pf_vout_buffer_del = vout_del_buffer;
p_dec->pf_picture_link = vout_link_picture;
p_dec->pf_picture_unlink = vout_unlink_picture;
p_dec->pf_spu_buffer_new = spu_new_buffer;
p_dec->pf_spu_buffer_del = spu_del_buffer;
vlc_object_attach( p_dec, p_input );
......@@ -618,7 +628,17 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
}
else if( p_dec->fmt_in.i_cat == SPU_ES )
{
p_dec->pf_decode_sub( p_dec, &p_block );
vout_thread_t *p_vout;
subpicture_t *p_spu;
while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) )
{
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( p_vout )
{
vout_DisplaySubPicture( p_vout, p_spu );
vlc_object_release( p_vout );
}
}
}
else
{
......@@ -677,6 +697,18 @@ static void DeleteDecoder( decoder_t * p_dec )
es_format_Clean( &p_dec->p_owner->sout );
}
if( p_dec->fmt_in.i_cat == SPU_ES )
{
vout_thread_t *p_vout;
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( p_vout )
{
vout_ClearOSDChannel( p_vout, p_dec->p_owner->i_spu_channel );
vlc_object_release( p_vout );
}
}
es_format_Clean( &p_dec->fmt_in );
es_format_Clean( &p_dec->fmt_out );
......@@ -840,3 +872,32 @@ static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
{
vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
}
static subpicture_t *spu_new_buffer( decoder_t *p_dec )
{
decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
vout_thread_t *p_vout;
subpicture_t *p_spu;
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( !p_vout ) return NULL;
if( p_sys->p_spu_vout != p_vout )
{
p_sys->i_spu_channel =
vout_RegisterOSDChannel( p_vout );
p_sys->p_spu_vout = p_vout;
}
p_spu = vout_CreateSubPicture( p_vout, p_sys->i_spu_channel,
MEMORY_SUBPICTURE );
vlc_object_release( p_vout );
return p_spu;
}
static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_spu )
{
vout_DestroySubPicture( p_dec->p_owner->p_vout, p_spu );
}
......@@ -1210,7 +1210,8 @@ char *stream_ReadLine( stream_t *s )
}
/* Remove trailing LF/CR */
while( i_line > 0 && ( p_line[i_line-1] == '\r' || p_line[i_line-1] == '\n') ) i_line--;
while( i_line > 0 && ( p_line[i_line-1] == '\r' ||
p_line[i_line-1] == '\n') ) i_line--;
if( i_read > 0 )
{
......@@ -1218,7 +1219,7 @@ char *stream_ReadLine( stream_t *s )
return p_line;
}
/* We failed to read any data, probably EOF*/
/* We failed to read any data, probably EOF */
if( p_line ) free( p_line );
return NULL;
}
......@@ -232,7 +232,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
return NULL;
}
/* Initialize pictures and subpictures - translation tables and functions
/* Initialize pictures - translation tables and functions
* will be initialized later in InitThread */
for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES + 1; i_index++)
{
......@@ -243,12 +243,6 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
p_vout->p_picture[i_index].b_slow = 0;
}
for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++)
{
p_vout->p_subpicture[i_index].i_status = FREE_SUBPICTURE;
p_vout->p_subpicture[i_index].i_type = EMPTY_SUBPICTURE;
}
/* No images in the heap */
p_vout->i_heap_size = 0;
......@@ -416,13 +410,8 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
return NULL;
}
p_vout->p_text_renderer_module =
module_Need( p_vout, "text renderer", NULL, 0 );
if( p_vout->p_text_renderer_module == NULL )
{
msg_Warn( p_vout, "no suitable text renderer module" );
p_vout->pf_add_string = NULL;
}
/* Initialize subpicture unit */
vout_InitSPU( p_vout );
/* Create a few object variables for interface interaction */
var_Create( p_vout, "deinterlace", VLC_VAR_STRING | VLC_VAR_HASCHOICE );
......@@ -489,10 +478,6 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
/* Make sure the thread is destroyed */
p_vout->b_die = VLC_TRUE;
if( p_vout->p_text_renderer_module )
{
module_Unneed( p_vout, p_vout->p_text_renderer_module );
}
vlc_thread_join( p_vout );
vlc_object_detach( p_vout );
......@@ -1127,18 +1112,8 @@ static void EndThread( vout_thread_t *p_vout )
}
}
/* Destroy all remaining subpictures */
for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++ )
{
if( p_vout->p_subpicture[i_index].i_status != FREE_SUBPICTURE )
{
vout_DestroySubPicture( p_vout,
&p_vout->p_subpicture[i_index] );
}
}
if( p_vout->p_text_renderer_module )
module_Unneed( p_vout, p_vout->p_text_renderer_module );
/* Destroy subpicture unit */
vout_DestroySPU( p_vout );
/* Destroy translation tables */
p_vout->pf_end( p_vout );
......
......@@ -21,7 +21,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vlc/vout.h>
#include <osd.h>
#include "vlc_block.h"
#include "vlc_filter.h"
#include "osd.h"
/**
* \brief Show text on the video for some time
......@@ -34,25 +36,44 @@
* \param i_vmargin vertical margin in pixels
* \param i_duration Amount of time the text is to be shown.
*/
subpicture_t *vout_ShowTextRelative( vout_thread_t *p_vout, int i_channel,
char *psz_string, text_style_t *p_style,
int i_flags, int i_hmargin, int i_vmargin,
mtime_t i_duration )
int vout_ShowTextRelative( vout_thread_t *p_vout, int i_channel,
char *psz_string, text_style_t *p_style,
int i_flags, int i_hmargin, int i_vmargin,
mtime_t i_duration )
{
subpicture_t *p_subpic = NULL;
mtime_t i_now = mdate();
if ( p_vout->pf_add_string )
if( p_vout->p_text && p_vout->p_text->p_module &&
p_vout->p_text->pf_render_string )
{
p_subpic = p_vout->pf_add_string( p_vout, i_channel, psz_string,
p_style, i_flags, i_hmargin, i_vmargin, i_now, i_now + i_duration );
block_t *p_block = block_New( p_vout, strlen(psz_string) + 1 );
if( p_block )
{
memcpy( p_block->p_buffer, psz_string, p_block->i_buffer );
p_block->i_pts = p_block->i_dts = i_now;
p_block->i_length = i_duration;
p_subpic = p_vout->p_text->pf_render_string( p_vout->p_text,
p_block );
if( p_subpic )
{
p_subpic->i_x = i_hmargin;
p_subpic->i_y = i_vmargin;
p_subpic->i_flags = i_flags;
p_subpic->i_channel = i_channel;
vout_DisplaySubPicture( p_vout, p_subpic );
return VLC_SUCCESS;
}
}
return VLC_EGENERIC;
}
else
{
msg_Warn( p_vout, "No text renderer found" );
return VLC_EGENERIC;
}
return p_subpic;
}
/**
......@@ -74,11 +95,32 @@ int vout_ShowTextAbsolute( vout_thread_t *p_vout, int i_channel,
int i_flags, int i_hmargin, int i_vmargin,
mtime_t i_start, mtime_t i_stop )
{
if ( p_vout->pf_add_string )
subpicture_t *p_subpic = NULL;
if( p_vout->p_text && p_vout->p_text->p_module &&
p_vout->p_text->pf_render_string )
{
p_vout->pf_add_string( p_vout, i_channel, psz_string, p_style, i_flags,
i_hmargin, i_vmargin, i_start, i_stop );
return VLC_SUCCESS;
block_t *p_block = block_New( p_vout, strlen(psz_string) + 1 );
if( p_block )
{
memcpy( p_block->p_buffer, psz_string, p_block->i_buffer );
p_block->i_pts = p_block->i_dts = i_start;
p_block->i_length = i_stop - i_start;
p_subpic = p_vout->p_text->pf_render_string( p_vout->p_text,
p_block );
if( p_subpic )
{
p_subpic->i_x = i_hmargin;
p_subpic->i_y = i_vmargin;
p_subpic->i_flags = i_flags;
p_subpic->i_channel = i_channel;
vout_DisplaySubPicture( p_vout, p_subpic );
return VLC_SUCCESS;
}
}
return VLC_EGENERIC;
}
else
{
......
......@@ -586,6 +586,9 @@ void vout_InitFormat( video_frame_format_t *p_format, vlc_fourcc_t i_chroma,
switch( i_chroma )
{
case FOURCC_YUVA:
p_format->i_bits_per_pixel = 32;
break;
case FOURCC_I444:
p_format->i_bits_per_pixel = 24;
break;
......@@ -608,6 +611,10 @@ void vout_InitFormat( video_frame_format_t *p_format, vlc_fourcc_t i_chroma,
case FOURCC_Y211:
p_format->i_bits_per_pixel = 8;
break;
case FOURCC_YUVP:
p_format->i_bits_per_pixel = 8;
break;
case FOURCC_RV32:
p_format->i_bits_per_pixel = 32;
break;
......@@ -731,6 +738,30 @@ void vout_InitPicture( vlc_object_t *p_this, picture_t *p_pic,
p_pic->i_planes = 3;
break;
case FOURCC_YUVA:
p_pic->p[ Y_PLANE ].i_lines = i_height;
p_pic->p[ Y_PLANE ].i_pitch = i_width;
p_pic->p[ Y_PLANE ].i_visible_pitch = p_pic->p[ Y_PLANE ].i_pitch;
p_pic->p[ U_PLANE ].i_lines = i_height;
p_pic->p[ U_PLANE ].i_pitch = i_width;
p_pic->p[ U_PLANE ].i_visible_pitch = p_pic->p[ U_PLANE ].i_pitch;
p_pic->p[ V_PLANE ].i_lines = i_height;
p_pic->p[ V_PLANE ].i_pitch = i_width;
p_pic->p[ V_PLANE ].i_visible_pitch = p_pic->p[ V_PLANE ].i_pitch;
p_pic->p[ A_PLANE ].i_lines = i_height;
p_pic->p[ A_PLANE ].i_pitch = i_width;
p_pic->p[ A_PLANE ].i_visible_pitch = p_pic->p[ A_PLANE ].i_pitch;
p_pic->i_planes = 4;
break;
case FOURCC_YUVP:
p_pic->p->i_lines = i_height;
p_pic->p->i_pitch = i_width;
p_pic->p->i_visible_pitch = p_pic->p->i_pitch;
p_pic->p->i_pixel_pitch = 8;
p_pic->i_planes = 1;
break;
case FOURCC_Y211:
p_pic->p->i_lines = i_height;
p_pic->p->i_pitch = i_width;
......@@ -811,20 +842,6 @@ void vout_InitPicture( vlc_object_t *p_this, picture_t *p_pic,
p_pic->p_heap->i_bmask = 0x0000ff; */
p_pic->i_planes = 1;
break;
case FOURCC_YUVA:
p_pic->p[ Y_PLANE ].i_lines = i_height;
p_pic->p[ Y_PLANE ].i_pitch = i_width;
p_pic->p[ Y_PLANE ].i_visible_pitch = p_pic->p[ Y_PLANE ].i_pitch;
p_pic->p[ U_PLANE ].i_lines = i_height;
p_pic->p[ U_PLANE ].i_pitch = i_width;
p_pic->p[ U_PLANE ].i_visible_pitch = p_pic->p[ U_PLANE ].i_pitch;
p_pic->p[ V_PLANE ].i_lines = i_height;
p_pic->p[ V_PLANE ].i_pitch = i_width;
p_pic->p[ V_PLANE ].i_visible_pitch = p_pic->p[ V_PLANE ].i_pitch;
p_pic->p[ A_PLANE ].i_lines = i_height;
p_pic->p[ A_PLANE ].i_pitch = i_width;
p_pic->p[ A_PLANE ].i_visible_pitch = p_pic->p[ A_PLANE ].i_pitch;
p_pic->i_planes = 4;
default:
msg_Err( p_this, "unknown chroma type 0x%.8x (%4.4s)",
......
......@@ -90,3 +90,6 @@
/* Planar 4:4:4:4 Y:U:V:A */
#define FOURCC_YUVA VLC_FOURCC('Y','U','V','A')
/* Palettized YUV with palette element Y:U:V:A */
#define FOURCC_YUVP VLC_FOURCC('Y','U','V','P')
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment