Commit 25fd8c34 authored by Rafaël Carré's avatar Rafaël Carré

Split stream_out_transcode in specific files

parent 8fb9c70f
......@@ -5301,6 +5301,7 @@ AC_CONFIG_FILES([
modules/services_discovery/Makefile
modules/stream_filter/Makefile
modules/stream_out/Makefile
modules/stream_out/transcode/Makefile
modules/video_chroma/Makefile
modules/video_filter/Makefile
modules/video_filter/dynamicoverlay/Makefile
......
SUBDIRS = transcode
SOURCES_stream_out_dummy = dummy.c
SOURCES_stream_out_description = description.c
SOURCES_stream_out_standard = standard.c
SOURCES_stream_out_transcode = transcode.c
SOURCES_stream_out_duplicate = duplicate.c
SOURCES_stream_out_es = es.c
SOURCES_stream_out_display = display.c
......@@ -18,7 +19,6 @@ libvlc_LTLIBRARIES += \
libstream_out_dummy_plugin.la \
libstream_out_description_plugin.la \
libstream_out_standard_plugin.la \
libstream_out_transcode_plugin.la \
libstream_out_duplicate_plugin.la \
libstream_out_es_plugin.la \
libstream_out_display_plugin.la \
......
SOURCES_stream_out_transcode = transcode.c transcode.h \
osd.c \
spu.c \
audio.c \
video.c
libvlc_LTLIBRARIES += libstream_out_transcode_plugin.la
This diff is collapsed.
/*****************************************************************************
* osd.c: transcoding stream output module (osd)
*****************************************************************************
* Copyright (C) 2003-2009 the VideoLAN team
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org>
* Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
* Antoine Cellerier <dionoea at videolan dot 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "transcode.h"
/*
* * OSD menu
* */
int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
id->p_decoder->fmt_in.i_cat = SPU_ES;
id->p_encoder->fmt_out.psz_language = strdup( "osd" );
if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
{
msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
"to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
(char*)&p_sys->i_osdcodec );
/* Complete destination format */
id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
/* Open encoder */
es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
VLC_CODEC_YUVA );
id->p_encoder->fmt_in.psz_language = strdup( "osd" );
id->p_encoder->p_cfg = p_sys->p_osd_cfg;
id->p_encoder->p_module =
module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
if( !id->p_encoder->p_module )
{
msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
goto error;
}
/* open output stream */
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
id->b_transcode = true;
if( !id->id ) goto error;
}
else
{
msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
(char*)&id->p_decoder->fmt_out.i_codec );
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
id->b_transcode = false;
if( !id->id ) goto error;
}
if( !p_sys->p_spu )
{
p_sys->p_spu = spu_Create( p_stream );
spu_Init( p_sys->p_spu );
}
return VLC_SUCCESS;
error:
msg_Err( p_stream, "starting osd encoding thread failed" );
if( id->p_encoder->p_module )
module_unneed( id->p_encoder, id->p_encoder->p_module );
p_sys->b_osd = false;
return VLC_EGENERIC;
}
void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
/* Close encoder */
if( id )
{
if( id->p_encoder->p_module )
module_unneed( id->p_encoder, id->p_encoder->p_module );
}
p_sys->b_osd = false;
}
int transcode_osd_process( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in, block_t **out )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
subpicture_t *p_subpic = NULL;
/* 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 );
}
else
{
msg_Warn( p_stream, "spu channel not initialized, doing it now" );
if( !p_sys->p_spu )
{
p_sys->p_spu = spu_Create( p_stream );
spu_Init( p_sys->p_spu );
}
}
if( p_subpic )
{
block_t *p_block = NULL;
if( p_sys->b_master_sync && p_sys->i_master_drift )
{
p_subpic->i_start -= p_sys->i_master_drift;
if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
}
p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
subpicture_Delete( p_subpic );
if( p_block )
{
p_block->i_dts = p_block->i_pts = in->i_dts;
block_ChainAppend( out, p_block );
return VLC_SUCCESS;
}
}
return VLC_EGENERIC;
}
bool transcode_osd_add( sout_stream_t *p_stream, es_format_t *p_fmt,
sout_stream_id_t *id)
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
"to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
(char*)&p_sys->i_scodec );
id->b_transcode = true;
/* Create a fake OSD menu elementary stream */
if( transcode_osd_new( p_stream, id ) )
{
msg_Err( p_stream, "cannot create osd chain" );
return false;
}
p_sys->b_osd = true;
return true;
}
/*****************************************************************************
* spu.c: transcoding stream output module (spu)
*****************************************************************************
* Copyright (C) 2003-2009 the VideoLAN team
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org>
* Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
* Antoine Cellerier <dionoea at videolan dot 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "transcode.h"
#include <vlc_meta.h>
#include <assert.h>
static subpicture_t *spu_new_buffer( decoder_t *p_dec )
{
VLC_UNUSED( p_dec );
return subpicture_New();
}
static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
{
VLC_UNUSED( p_dec );
subpicture_Delete( p_subpic );
}
int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
/*
* Open decoder
*/
/* Initialization of decoder structures */
id->p_decoder->pf_decode_sub = NULL;
id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
/* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
id->p_decoder->p_module =
module_need( id->p_decoder, "decoder", "$codec", false );
if( !id->p_decoder->p_module )
{
msg_Err( p_stream, "cannot find spu decoder" );
return VLC_EGENERIC;
}
if( !p_sys->b_soverlay )
{
/* Open encoder */
/* Initialization of encoder format structures */
es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
id->p_decoder->fmt_in.i_codec );
id->p_encoder->p_cfg = p_sys->p_spu_cfg;
id->p_encoder->p_module =
module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
if( !id->p_encoder->p_module )
{
module_unneed( id->p_decoder, id->p_decoder->p_module );
msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
return VLC_EGENERIC;
}
}
if( !p_sys->p_spu )
{
p_sys->p_spu = spu_Create( p_stream );
spu_Init( p_sys->p_spu );
}
return VLC_SUCCESS;
}
void transcode_spu_close( sout_stream_id_t *id)
{
/* Close decoder */
if( id->p_decoder->p_module )
module_unneed( id->p_decoder, id->p_decoder->p_module );
if( id->p_decoder->p_description )
vlc_meta_Delete( id->p_decoder->p_description );
/* Close encoder */
if( id->p_encoder->p_module )
module_unneed( id->p_encoder, id->p_encoder->p_module );
}
int transcode_spu_process( sout_stream_t *p_stream,
sout_stream_id_t *id,
block_t *in, block_t **out )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
subpicture_t *p_subpic;
*out = NULL;
p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
if( !p_subpic )
return VLC_EGENERIC;
sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
if( p_sys->b_master_sync && p_sys->i_master_drift )
{
p_subpic->i_start -= p_sys->i_master_drift;
if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
}
if( p_sys->b_soverlay )
{
spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
}
else
{
block_t *p_block;
p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
spu_del_buffer( id->p_decoder, p_subpic );
if( p_block )
{
block_ChainAppend( out, p_block );
return VLC_SUCCESS;
}
}
return VLC_EGENERIC;
}
bool transcode_spu_add( sout_stream_t *p_stream, es_format_t *p_fmt,
sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
if( p_sys->i_scodec || p_sys->psz_senc )
{
msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
"to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
(char*)&p_sys->i_scodec );
/* Complete destination format */
id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
/* build decoder -> filter -> encoder */
if( transcode_spu_new( p_stream, id ) )
{
msg_Err( p_stream, "cannot create subtitles chain" );
return false;
}
/* open output stream */
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
id->b_transcode = true;
if( !id->id )
{
transcode_spu_close( id );
return false;
}
}
else
{
assert( p_sys->b_soverlay );
msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
(char*)&p_fmt->i_codec );
id->b_transcode = true;
/* Build decoder -> filter -> overlaying chain */
if( transcode_spu_new( p_stream, id ) )
{
msg_Err( p_stream, "cannot create subtitles chain" );
return false;
}
}
return true;
}
This diff is collapsed.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_sout.h>
#include <vlc_filter.h>
#include <vlc_es.h>
#include <vlc_codec.h>
#include <vlc_osd.h>
#define PICTURE_RING_SIZE 64
#define SUBPICTURE_RING_SIZE 20
#define MASTER_SYNC_MAX_DRIFT 100000
struct sout_stream_sys_t
{
VLC_COMMON_MEMBERS
sout_stream_t *p_out;
sout_stream_id_t *id_video;
block_t *p_buffers;
vlc_mutex_t lock_out;
vlc_cond_t cond;
picture_t * pp_pics[PICTURE_RING_SIZE];
int i_first_pic, i_last_pic;
/* Audio */
vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
char *psz_aenc;
char *psz_alang;
config_chain_t *p_audio_cfg;
uint32_t i_sample_rate;
uint32_t i_channels;
int i_abitrate;
char *psz_af;
/* Video */
vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
char *psz_venc;
config_chain_t *p_video_cfg;
int i_vbitrate;
double f_scale;
double f_fps;
unsigned int i_width, i_maxwidth;
unsigned int i_height, i_maxheight;
bool b_deinterlace;
char *psz_deinterlace;
config_chain_t *p_deinterlace_cfg;
int i_threads;
bool b_high_priority;
bool b_hurry_up;
char *psz_vf2;
/* SPU */
vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
char *psz_senc;
bool b_soverlay;
config_chain_t *p_spu_cfg;
spu_t *p_spu;
/* OSD Menu */
vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
char *psz_osdenc;
config_chain_t *p_osd_cfg;
bool b_osd; /* true when osd es is registered */
/* Sync */
bool b_master_sync;
mtime_t i_master_drift;
};
struct sout_stream_id_t
{
bool b_transcode;
/* id of the out stream */
void *id;
/* Decoder */
decoder_t *p_decoder;
/* Filters */
filter_chain_t *p_f_chain;
/* User specified filters */
filter_chain_t *p_uf_chain;
/* Encoder */
encoder_t *p_encoder;
/* Sync */
date_t interpolated_pts;
};
/* OSD */
int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id );
void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id);
int transcode_osd_process( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in, block_t **out );
bool transcode_osd_add ( sout_stream_t *, es_format_t *, sout_stream_id_t *);
/* SPU */
int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
void transcode_spu_close ( sout_stream_id_t * );
int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
block_t *, block_t ** );
bool transcode_spu_add ( sout_stream_t *, es_format_t *, sout_stream_id_t *);
/* AUDIO */
int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
void transcode_audio_close ( sout_stream_id_t * );
int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
block_t *, block_t ** );
bool transcode_audio_add ( sout_stream_t *, es_format_t *,
sout_stream_id_t *);
/* VIDEO */
int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );
void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );
int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
block_t *, block_t ** );
bool transcode_video_add ( sout_stream_t *, es_format_t *,
sout_stream_id_t *);
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