Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
e2382750
Commit
e2382750
authored
Mar 19, 2013
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove unmaintained switcher module
parent
edb2d3b0
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1 addition
and
988 deletions
+1
-988
NEWS
NEWS
+1
-0
configure.ac
configure.ac
+0
-15
extras/package/rpm/vlc.altlinux.spec
extras/package/rpm/vlc.altlinux.spec
+0
-2
modules/LIST
modules/LIST
+0
-1
modules/stream_out/Modules.am
modules/stream_out/Modules.am
+0
-2
modules/stream_out/switcher.c
modules/stream_out/switcher.c
+0
-967
po/POTFILES.in
po/POTFILES.in
+0
-1
No files found.
NEWS
View file @
e2382750
...
...
@@ -89,6 +89,7 @@ Stream Output:
* Livehttp places more accurate segments durations in playlist
* Livehttp allows setting cachin-variable in playlist
* Livehttp stream encryption support
* Unmaintained switcher has been removed
Interfaces:
* configurable password for the HTTP server.
...
...
configure.ac
View file @
e2382750
...
...
@@ -2390,21 +2390,6 @@ AS_IF([test "${enable_vda}" != "no"], [
])
AM_CONDITIONAL([HAVE_AVCODEC_VDA], [test "${have_avcodec_vda}" = "yes"])
dnl
dnl stream_out switcher needs libavcodec
dnl
AC_ARG_ENABLE(switcher,
[ --enable-switcher Stream-out switcher plugin (default disabled)])
AS_IF([test "${enable_switcher}" = "yes"], [
AS_IF([test "x${have_avcodec}" = "xyes"], [
VLC_ADD_PLUGIN([stream_out_switcher])
VLC_ADD_LIBS([stream_out_switcher],[$AVCODEC_LIBS $AVUTIL_LIBS $LIBM])
VLC_ADD_CFLAGS([stream_out_switcher],[$AVCODEC_CFLAGS $AVUTIL_CFLAGS])
],[AC_MSG_ERROR([Stream_out switcher depends on avcodec])
])
])
dnl
dnl avformat demuxer/muxer plugin
dnl
...
...
extras/package/rpm/vlc.altlinux.spec
View file @
e2382750
...
...
@@ -1175,7 +1175,6 @@ strfile %buildroot%_gamesdatadir/fortune/vlc %buildroot%_gamesdatadir/fortune/vl
%_vlc_pluginsdir/stream_out/libstream_out_gather_plugin.so*
%_vlc_pluginsdir/stream_out/libstream_out_mosaic_bridge_plugin.so*
%_vlc_pluginsdir/stream_out/libstream_out_rtp_plugin.so*
#%_vlc_pluginsdir/stream_out/libstream_out_switcher_plugin.so*
%_vlc_pluginsdir/stream_out/libstream_out_transcode_plugin.so*
%_vlc_pluginsdir/stream_out/libstream_out_autodel_plugin.so*
...
...
@@ -1374,7 +1373,6 @@ strfile %buildroot%_gamesdatadir/fortune/vlc %buildroot%_gamesdatadir/fortune/vl
%files plugin-ffmpeg
%_vlc_pluginsdir/codec/libffmpeg_plugin.so*
#%_vlc_pluginsdir/stream_out/libstream_out_switcher_plugin.so*
%files plugin-framebuffer
%_vlc_pluginsdir/video_output/libfb_plugin.so*
...
...
modules/LIST
View file @
e2382750
...
...
@@ -328,7 +328,6 @@ $Id$
* stream_out_setid: Set the ID/Lang of an ES when streaming
* stream_out_smem: stream output module to a memory buffer
* stream_out_standard: standard stream output module
* stream_out_switcher: stream output module to display backgrounds
* stream_out_transcode: audio & video transcoder
* subsdec: a codec to output textual subtitles
* subsdelay: subtitles delay filter
...
...
modules/stream_out/Modules.am
View file @
e2382750
...
...
@@ -6,8 +6,6 @@ SOURCES_stream_out_duplicate = duplicate.c
SOURCES_stream_out_es = es.c
SOURCES_stream_out_display = display.c
SOURCES_stream_out_gather = gather.c
SOURCES_stream_out_switcher = switcher.c ../codec/avcodec/cpu.c \
../codec/avcodec/avcommon_compat.h ../codec/avcodec/avcommon.h
SOURCES_stream_out_bridge = bridge.c
SOURCES_stream_out_mosaic_bridge = mosaic_bridge.c
SOURCES_stream_out_autodel = autodel.c
...
...
modules/stream_out/switcher.c
deleted
100644 → 0
View file @
edb2d3b0
/*****************************************************************************
* switcher.c: MPEG2 video switcher module
*****************************************************************************
* Copyright (C) 2004 the VideoLAN team
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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 <math.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_sout.h>
#include <vlc_avcodec.h>
#include <vlc_filter.h>
#include <vlc_cpu.h>
#include <vlc_block.h>
#include <vlc_fs.h>
#include <vlc_network.h>
#define HAVE_MMX
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
# include <libavcodec/avcodec.h>
#elif defined(HAVE_FFMPEG_AVCODEC_H)
# include <ffmpeg/avcodec.h>
#else
# include <avcodec.h>
#endif
#include "../codec/avcodec/avcodec.h"
#include "../codec/avcodec/avcommon.h"
#define SOUT_CFG_PREFIX "sout-switcher-"
#define MAX_PICTURES 10
#define MAX_AUDIO 30
#define MAX_THRESHOLD 99999999
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
sout_stream_id_t
*
Add
(
sout_stream_t
*
,
es_format_t
*
);
static
int
Del
(
sout_stream_t
*
,
sout_stream_id_t
*
);
static
int
Send
(
sout_stream_t
*
,
sout_stream_id_t
*
,
block_t
*
);
static
mtime_t
Process
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
mtime_t
i_max_dts
);
static
int
UnpackFromFile
(
sout_stream_t
*
p_stream
,
const
char
*
psz_file
,
int
i_width
,
int
i_height
,
picture_t
*
p_pic
);
static
void
NetCommand
(
sout_stream_t
*
p_stream
);
static
mtime_t
VideoCommand
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
);
static
block_t
*
VideoGetBuffer
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
block_t
*
p_buffer
);
static
block_t
*
AudioGetBuffer
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
block_t
*
p_buffer
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define FILES_TEXT N_("Files")
#define FILES_LONGTEXT N_( \
"Full paths of the files separated by colons." )
#define SIZES_TEXT N_("Sizes")
#define SIZES_LONGTEXT N_( \
"List of sizes separated by colons (720x576:480x576)." )
#define RATIO_TEXT N_("Aspect ratio")
#define RATIO_LONGTEXT N_( \
"Aspect ratio (4:3, 16:9)." )
#define PORT_TEXT N_("Command UDP port")
#define PORT_LONGTEXT N_( \
"UDP port to listen to for commands." )
#define COMMAND_TEXT N_("Command")
#define COMMAND_LONGTEXT N_( \
"Initial command to execute." )
#define GOP_TEXT N_("GOP size")
#define GOP_LONGTEXT N_( \
"Number of P frames between two I frames." )
#define QSCALE_TEXT N_("Quantizer scale")
#define QSCALE_LONGTEXT N_( \
"Fixed quantizer scale to use." )
#define AUDIO_TEXT N_("Mute audio")
#define AUDIO_LONGTEXT N_( \
"Mute audio when command is not 0." )
vlc_module_begin
()
set_description
(
N_
(
"MPEG2 video switcher stream output"
)
)
set_capability
(
"sout stream"
,
50
)
add_shortcut
(
"switcher"
)
set_callbacks
(
Open
,
Close
)
add_string
(
SOUT_CFG_PREFIX
"files"
,
""
,
FILES_TEXT
,
FILES_LONGTEXT
,
false
)
add_string
(
SOUT_CFG_PREFIX
"sizes"
,
""
,
SIZES_TEXT
,
SIZES_LONGTEXT
,
false
)
add_string
(
SOUT_CFG_PREFIX
"aspect-ratio"
,
"4:3"
,
RATIO_TEXT
,
RATIO_LONGTEXT
,
false
)
add_integer
(
SOUT_CFG_PREFIX
"port"
,
5001
,
PORT_TEXT
,
PORT_LONGTEXT
,
true
)
add_integer
(
SOUT_CFG_PREFIX
"command"
,
0
,
COMMAND_TEXT
,
COMMAND_LONGTEXT
,
true
)
add_integer
(
SOUT_CFG_PREFIX
"gop"
,
8
,
GOP_TEXT
,
GOP_LONGTEXT
,
true
)
add_integer
(
SOUT_CFG_PREFIX
"qscale"
,
5
,
QSCALE_TEXT
,
QSCALE_LONGTEXT
,
true
)
add_bool
(
SOUT_CFG_PREFIX
"mute-audio"
,
true
,
AUDIO_TEXT
,
AUDIO_LONGTEXT
,
true
)
#if LIBAVCODEC_VERSION_MAJOR >= 54
add_string
(
SOUT_CFG_PREFIX
"options"
,
NULL
,
AV_OPTIONS_TEXT
,
AV_OPTIONS_LONGTEXT
,
true
)
#endif
vlc_module_end
()
static
const
char
*
const
ppsz_sout_options
[]
=
{
"files"
,
"sizes"
,
"aspect-ratio"
,
"port"
,
"command"
,
"gop"
,
"qscale"
,
"mute-audio"
,
"options"
,
NULL
};
struct
sout_stream_sys_t
{
int
i_gop
;
int
i_qscale
;
int
i_aspect
;
sout_stream_id_t
*
pp_audio_ids
[
MAX_AUDIO
];
bool
b_audio
;
/* Pictures */
picture_t
p_pictures
[
MAX_PICTURES
];
int
i_nb_pictures
;
/* Command */
int
i_fd
;
int
i_cmd
,
i_old_cmd
;
#if LIBAVCODEC_VERSION_MAJOR >= 54
AVDictionary
*
options
;
#endif
};
struct
sout_stream_id_t
{
void
*
id
;
bool
b_switcher_video
;
bool
b_switcher_audio
;
es_format_t
f_src
;
block_t
*
p_queued
;
/* ffmpeg part */
AVCodec
*
ff_enc
;
AVCodecContext
*
ff_enc_c
;
AVFrame
*
p_frame
;
uint8_t
*
p_buffer_out
;
int
i_nb_pred
;
int16_t
*
p_samples
;
};
/*****************************************************************************
* Open:
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_this
;
sout_stream_sys_t
*
p_sys
;
vlc_value_t
val
;
char
*
psz_files
,
*
psz_sizes
;
int
i_height
=
0
,
i_width
=
0
;
vlc_init_avcodec
();
p_sys
=
calloc
(
1
,
sizeof
(
sout_stream_sys_t
)
);
if
(
!
p_sys
)
return
VLC_ENOMEM
;
if
(
!
p_stream
->
p_next
)
{
msg_Err
(
p_stream
,
"cannot create chain"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
config_ChainParse
(
p_stream
,
SOUT_CFG_PREFIX
,
ppsz_sout_options
,
p_stream
->
p_cfg
);
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"files"
,
&
val
);
psz_files
=
val
.
psz_string
;
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"sizes"
,
&
val
);
psz_sizes
=
val
.
psz_string
;
p_sys
->
i_nb_pictures
=
0
;
while
(
psz_files
&&
*
psz_files
)
{
char
*
psz_file
=
psz_files
;
char
*
psz_size
=
psz_sizes
;
while
(
*
psz_files
&&
*
psz_files
!=
':'
)
psz_files
++
;
if
(
*
psz_files
==
':'
)
*
psz_files
++
=
'\0'
;
if
(
*
psz_sizes
)
{
while
(
*
psz_sizes
&&
*
psz_sizes
!=
':'
)
psz_sizes
++
;
if
(
*
psz_sizes
==
':'
)
*
psz_sizes
++
=
'\0'
;
if
(
sscanf
(
psz_size
,
"%dx%d"
,
&
i_width
,
&
i_height
)
!=
2
)
{
msg_Err
(
p_stream
,
"bad size %s for file %s"
,
psz_size
,
psz_file
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
}
if
(
UnpackFromFile
(
p_stream
,
psz_file
,
i_width
,
i_height
,
&
p_sys
->
p_pictures
[
p_sys
->
i_nb_pictures
]
)
<
0
)
{
free
(
p_sys
);
return
VLC_EGENERIC
;
}
p_sys
->
i_nb_pictures
++
;
}
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"aspect-ratio"
,
&
val
);
if
(
val
.
psz_string
)
{
char
*
psz_parser
=
strchr
(
val
.
psz_string
,
':'
);
if
(
psz_parser
)
{
*
psz_parser
++
=
'\0'
;
p_sys
->
i_aspect
=
atoi
(
val
.
psz_string
)
*
VOUT_ASPECT_FACTOR
/
atoi
(
psz_parser
);
}
else
{
msg_Warn
(
p_stream
,
"bad aspect ratio %s"
,
val
.
psz_string
);
p_sys
->
i_aspect
=
4
*
VOUT_ASPECT_FACTOR
/
3
;
}
free
(
val
.
psz_string
);
}
else
{
p_sys
->
i_aspect
=
4
*
VOUT_ASPECT_FACTOR
/
3
;
}
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"port"
,
&
val
);
p_sys
->
i_fd
=
net_ListenUDP1
(
VLC_OBJECT
(
p_stream
),
NULL
,
val
.
i_int
);
if
(
p_sys
->
i_fd
<
0
)
{
free
(
p_sys
);
return
VLC_EGENERIC
;
}
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"command"
,
&
val
);
p_sys
->
i_cmd
=
val
.
i_int
;
p_sys
->
i_old_cmd
=
0
;
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"gop"
,
&
val
);
p_sys
->
i_gop
=
val
.
i_int
;
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"qscale"
,
&
val
);
p_sys
->
i_qscale
=
val
.
i_int
;
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"mute-audio"
,
&
val
);
p_sys
->
b_audio
=
val
.
b_bool
;
p_stream
->
pf_add
=
Add
;
p_stream
->
pf_del
=
Del
;
p_stream
->
pf_send
=
Send
;
p_stream
->
p_sys
=
p_sys
;
#if LIBAVCODEC_VERSION_MAJOR >= 54
char
*
psz_opts
=
var_InheritString
(
p_stream
,
SOUT_CFG_PREFIX
"options"
);
if
(
psz_opts
&&
*
psz_opts
)
{
p_sys
->
options
=
vlc_av_get_options
(
psz_opts
);
}
else
{
p_sys
->
options
=
NULL
;
}
free
(
psz_opts
);
#endif
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_this
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
#if LIBAVCODEC_VERSION_MAJOR >= 54
av_dict_free
(
&
p_sys
->
options
);
#endif
free
(
p_sys
);
}
/*****************************************************************************
* Add: Add an input elementary stream
*****************************************************************************/
static
sout_stream_id_t
*
Add
(
sout_stream_t
*
p_stream
,
es_format_t
*
p_fmt
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
sout_stream_id_t
*
id
;
id
=
calloc
(
1
,
sizeof
(
sout_stream_id_t
)
);
if
(
!
id
)
return
NULL
;
if
(
p_fmt
->
i_cat
==
VIDEO_ES
&&
p_fmt
->
i_codec
==
VLC_CODEC_MPGV
)
{
id
->
b_switcher_video
=
true
;
p_fmt
->
i_codec
=
VLC_CODEC_MPGV
;
msg_Dbg
(
p_stream
,
"creating video switcher for fcc=`%4.4s' cmd:%d"
,
(
char
*
)
&
p_fmt
->
i_codec
,
p_sys
->
i_cmd
);
}
else
if
(
p_fmt
->
i_cat
==
AUDIO_ES
&&
p_fmt
->
i_codec
==
VLC_CODEC_MPGA
&&
p_sys
->
b_audio
)
{
int
i_ff_codec
=
AV_CODEC_ID_MP2
;
int
i
;
id
->
b_switcher_audio
=
true
;
msg_Dbg
(
p_stream
,
"creating audio switcher for fcc=`%4.4s' cmd:%d"
,
(
char
*
)
&
p_fmt
->
i_codec
,
p_sys
->
i_cmd
);
/* Allocate the encoder right now. */
if
(
i_ff_codec
==
0
)
{
msg_Err
(
p_stream
,
"cannot find encoder"
);
free
(
id
);
return
NULL
;
}
id
->
ff_enc
=
avcodec_find_encoder
(
i_ff_codec
);
if
(
!
id
->
ff_enc
)
{
msg_Err
(
p_stream
,
"cannot find encoder (avcodec)"
);
free
(
id
);
return
NULL
;
}
id
->
ff_enc_c
=
avcodec_alloc_context3
(
id
->
ff_enc
);
id
->
ff_enc_c
->
dsp_mask
=
GetVlcDspMask
();
id
->
ff_enc_c
->
sample_rate
=
p_fmt
->
audio
.
i_rate
;
id
->
ff_enc_c
->
time_base
.
num
=
1
;
id
->
ff_enc_c
->
time_base
.
den
=
p_fmt
->
audio
.
i_rate
;
id
->
ff_enc_c
->
channels
=
p_fmt
->
audio
.
i_channels
;
id
->
ff_enc_c
->
bit_rate
=
p_fmt
->
i_bitrate
;
int
ret
;
#if LIBAVCODEC_VERSION_MAJOR >= 54
AVDictionary
*
options
=
NULL
;
if
(
p_sys
->
options
)
av_dict_copy
(
&
options
,
p_sys
->
options
,
0
);
vlc_avcodec_lock
();
ret
=
avcodec_open2
(
id
->
ff_enc_c
,
id
->
ff_enc
,
options
?
&
options
:
NULL
);
vlc_avcodec_unlock
();
AVDictionaryEntry
*
t
=
NULL
;
while
((
t
=
av_dict_get
(
options
,
""
,
t
,
AV_DICT_IGNORE_SUFFIX
)))
{
msg_Err
(
p_stream
,
"Unknown option
\"
%s
\"
"
,
t
->
key
);
}
av_dict_free
(
&
options
);
#else
vlc_avcodec_lock
();
ret
=
avcodec_open
(
id
->
ff_enc_c
,
id
->
ff_enc
);
vlc_avcodec_unlock
();
#endif
if
(
ret
)
{
msg_Err
(
p_stream
,
"cannot open encoder"
);
av_free
(
id
->
ff_enc_c
);
free
(
id
);
return
NULL
;
}
id
->
p_buffer_out
=
malloc
(
AVCODEC_MAX_AUDIO_FRAME_SIZE
*
2
);
id
->
p_samples
=
calloc
(
id
->
ff_enc_c
->
frame_size
*
p_fmt
->
audio
.
i_channels
,
sizeof
(
int16_t
)
);
if
(
!
id
->
p_buffer_out
||
!
id
->
p_samples
)
goto
error
;
for
(
i
=
0
;
i
<
MAX_AUDIO
;
i
++
)
{
if
(
p_sys
->
pp_audio_ids
[
i
]
==
NULL
)
{
p_sys
->
pp_audio_ids
[
i
]
=
id
;
break
;
}
}
if
(
i
==
MAX_AUDIO
)
{
msg_Err
(
p_stream
,
"too many audio streams!"
);
goto
error
;
}
}
else
{
msg_Dbg
(
p_stream
,
"do not know what to do when switching (fcc=`%4.4s')"
,
(
char
*
)
&
p_fmt
->
i_codec
);
}
/* src format */
memcpy
(
&
id
->
f_src
,
p_fmt
,
sizeof
(
es_format_t
)
);
/* open output stream */
id
->
id
=
p_stream
->
p_next
->
pf_add
(
p_stream
->
p_next
,
p_fmt
);
if
(
id
->
id
!=
NULL
)
return
id
;
error:
vlc_avcodec_lock
();
avcodec_close
(
id
->
ff_enc_c
);
vlc_avcodec_unlock
();
free
(
id
->
p_samples
);
free
(
id
->
p_buffer_out
);
av_free
(
id
->
ff_enc_c
);
free
(
id
);
return
NULL
;
}
/*****************************************************************************
* Del: Del an elementary stream
*****************************************************************************/
static
int
Del
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
if
(
id
->
b_switcher_audio
)
{
int
i
;
for
(
i
=
0
;
i
<
MAX_AUDIO
;
i
++
)
{
if
(
p_sys
->
pp_audio_ids
[
i
]
==
id
)
{
p_sys
->
pp_audio_ids
[
i
]
=
NULL
;
break
;
}
}
}
if
(
id
->
ff_enc
)
{
vlc_avcodec_lock
();
avcodec_close
(
id
->
ff_enc_c
);
vlc_avcodec_unlock
();
av_free
(
id
->
ff_enc_c
);
av_free
(
id
->
p_frame
);
free
(
id
->
p_buffer_out
);
}
if
(
id
->
id
)
{
p_stream
->
p_next
->
pf_del
(
p_stream
->
p_next
,
id
->
id
);
}
free
(
id
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Send: Process an input packet
*****************************************************************************/
static
int
Send
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
block_t
*
p_buffer
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
if
(
!
id
->
id
)
{
block_Release
(
p_buffer
);
return
VLC_EGENERIC
;
}
if
(
!
id
->
b_switcher_video
&&
!
id
->
b_switcher_audio
)
{
return
p_stream
->
p_next
->
pf_send
(
p_stream
->
p_next
,
id
->
id
,
p_buffer
);
}
block_ChainAppend
(
&
id
->
p_queued
,
p_buffer
);
if
(
id
->
b_switcher_video
)
{
/* Check for commands for every video frame. */
NetCommand
(
p_stream
);
while
(
id
->
p_queued
!=
NULL
)
{
mtime_t
i_dts
=
0
;
if
(
p_sys
->
i_old_cmd
!=
p_sys
->
i_cmd
)
{
i_dts
=
VideoCommand
(
p_stream
,
id
);
}
i_dts
=
Process
(
p_stream
,
id
,
i_dts
);
for
(
int
i
=
0
;
i
<
MAX_AUDIO
;
i
++
)
{
if
(
p_sys
->
pp_audio_ids
[
i
]
!=
NULL
)
Process
(
p_stream
,
p_sys
->
pp_audio_ids
[
i
],
i_dts
);
}
}
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Process: Process and dispatch buffers
*****************************************************************************/
static
mtime_t
Process
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
mtime_t
i_max_dts
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
mtime_t
i_dts
=
0
;
block_t
*
p_blocks
=
NULL
;
block_t
*
p_blocks_out
=
NULL
;
/* Find out the blocks we need. */
while
(
id
->
p_queued
!=
NULL
&&
(
!
i_max_dts
||
id
->
p_queued
->
i_dts
<=
i_max_dts
)
)
{
block_t
*
p_next
=
id
->
p_queued
->
p_next
;
id
->
p_queued
->
p_next
=
NULL
;
i_dts
=
id
->
p_queued
->
i_dts
;
block_ChainAppend
(
&
p_blocks
,
id
->
p_queued
);
id
->
p_queued
=
p_next
;
}
if
(
p_sys
->
i_old_cmd
==
0
)
{
/* Full forward */
if
(
p_blocks
!=
NULL
)
p_stream
->
p_next
->
pf_send
(
p_stream
->
p_next
,
id
->
id
,
p_blocks
);
return
i_dts
;
}
if
(
p_sys
->
i_old_cmd
==
-
1
)
{
/* No output at all */
while
(
p_blocks
!=
NULL
)
{
block_t
*
p_next
=
p_blocks
->
p_next
;
block_Release
(
p_blocks
);
p_blocks
=
p_next
;
}
return
i_dts
;
}
while
(
p_blocks
!=
NULL
)
{
block_t
*
p_next
=
p_blocks
->
p_next
;
block_t
*
p_out
;
if
(
id
->
b_switcher_video
)
{
p_out
=
VideoGetBuffer
(
p_stream
,
id
,
p_blocks
);
}
else
{
p_out
=
AudioGetBuffer
(
p_stream
,
id
,
p_blocks
);
}
p_blocks
=
p_next
;
if
(
p_out
!=
NULL
)
{
block_ChainAppend
(
&
p_blocks_out
,
p_out
);
}
}
if
(
p_blocks_out
!=
NULL
)
p_stream
->
p_next
->
pf_send
(
p_stream
->
p_next
,
id
->
id
,
p_blocks_out
);
return
i_dts
;
}
/*****************************************************************************
* UnpackFromFile: Read a YUV picture and store it in our format
*****************************************************************************/
static
int
UnpackFromFile
(
sout_stream_t
*
p_stream
,
const
char
*
psz_file
,
int
i_width
,
int
i_height
,
picture_t
*
p_pic
)
{
int
i
,
j
;
FILE
*
p_file
=
vlc_fopen
(
psz_file
,
"r"
);
if
(
p_file
==
NULL
)
{
msg_Err
(
p_stream
,
"file %s not found"
,
psz_file
);
return
-
1
;
}
if
(
picture_Setup
(
p_pic
,
VLC_CODEC_I420
,
i_width
,
i_height
,
1
,
1
)
)
{
msg_Err
(
p_stream
,
"unknown chroma"
);
return
-
1
;
}
for
(
i
=
0
;
i
<
p_pic
->
i_planes
;
i
++
)
{
p_pic
->
p
[
i
].
p_pixels
=
malloc
(
p_pic
->
p
[
i
].
i_lines
*
p_pic
->
p
[
i
].
i_pitch
);
memset
(
p_pic
->
p
[
i
].
p_pixels
,
0
,
p_pic
->
p
[
i
].
i_lines
*
p_pic
->
p
[
i
].
i_pitch
);
}
for
(
i
=
0
;
i
<
i_height
;
i
++
)
{
int
i_chroma
;
uint8_t
p_buffer
[
i_width
*
2
];
uint8_t
*
p_char
=
p_buffer
;
uint8_t
*
p_y
=
&
p_pic
->
p
[
0
].
p_pixels
[
i
*
p_pic
->
p
[
0
].
i_pitch
];
uint8_t
*
p_u
=
&
p_pic
->
p
[
1
].
p_pixels
[
i
/
2
*
p_pic
->
p
[
1
].
i_pitch
];
uint8_t
*
p_v
=
&
p_pic
->
p
[
2
].
p_pixels
[
i
/
2
*
p_pic
->
p
[
2
].
i_pitch
];
if
(
fread
(
p_buffer
,
2
,
i_width
,
p_file
)
!=
(
size_t
)
i_width
)
{
msg_Err
(
p_stream
,
"premature end of file %s"
,
psz_file
);
fclose
(
p_file
);
for
(
i
=
0
;
i
<
p_pic
->
i_planes
;
i
++
)
{
free
(
p_pic
->
p
[
i
].
p_pixels
);
}
return
-
1
;
}
i_chroma
=
0
;
for
(
j
=
0
;
j
<
i_width
;
j
++
)
{
uint8_t
**
pp_chroma
=
i_chroma
?
&
p_v
:
&
p_u
;
i_chroma
=
!
i_chroma
;
if
(
i
&
1
)
**
pp_chroma
=
(
**
pp_chroma
+
*
p_char
+
1
)
/
2
;
else
**
pp_chroma
=
*
p_char
;
(
*
pp_chroma
)
++
;
p_char
++
;
*
p_y
++
=
*
p_char
++
;
}
}
fclose
(
p_file
);
return
0
;
}
/*****************************************************************************
* NetCommand: Get a command from the network
*****************************************************************************/
static
void
NetCommand
(
sout_stream_t
*
p_stream
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
char
psz_buffer
[
11
];
int
i_len
=
recv
(
p_sys
->
i_fd
,
psz_buffer
,
sizeof
(
psz_buffer
)
-
1
,
0
);
if
(
i_len
>
0
)
{
psz_buffer
[
i_len
]
=
'\0'
;
int
i_cmd
=
strtol
(
psz_buffer
,
NULL
,
0
);
if
(
i_cmd
<
-
1
||
i_cmd
>
p_sys
->
i_nb_pictures
)
{
msg_Err
(
p_stream
,
"got a wrong command (%d)"
,
i_cmd
);
return
;
}
p_sys
->
i_cmd
=
i_cmd
;
msg_Dbg
(
p_stream
,
"new command: %d old:%d"
,
p_sys
->
i_cmd
,
p_sys
->
i_old_cmd
);
}
}
/*****************************************************************************
* VideoCommand: Create/Delete a video encoder
*****************************************************************************/
static
mtime_t
VideoCommand
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
if
(
p_sys
->
i_cmd
==
0
&&
!
(
id
->
p_queued
->
i_flags
&
BLOCK_FLAG_TYPE_I
)
)
{
mtime_t
i_dts
=
id
->
p_queued
->
i_dts
;
block_t
*
p_block
=
id
->
p_queued
->
p_next
;
while
(
p_block
!=
NULL
)
{
if
(
p_block
->
i_flags
&
BLOCK_FLAG_TYPE_I
)
return
i_dts
;
i_dts
=
p_block
->
i_dts
;
p_block
=
p_block
->
p_next
;
}
return
0
;
}
p_sys
->
i_old_cmd
=
p_sys
->
i_cmd
;
if
(
id
->
ff_enc
)
{
vlc_avcodec_lock
();
avcodec_close
(
id
->
ff_enc_c
);
vlc_avcodec_unlock
();
av_free
(
id
->
ff_enc_c
);
av_free
(
id
->
p_frame
);
free
(
id
->
p_buffer_out
);
id
->
ff_enc
=
NULL
;
}
if
(
p_sys
->
i_cmd
>
0
)
{
/* Create a new encoder. */
int
i_ff_codec
=
AV_CODEC_ID_MPEG2VIDEO
;
int
i_aspect_num
,
i_aspect_den
;
if
(
i_ff_codec
==
0
)
{
msg_Err
(
p_stream
,
"cannot find encoder"
);
return
0
;
}
id
->
ff_enc
=
avcodec_find_encoder
(
i_ff_codec
);
if
(
!
id
->
ff_enc
)
{
msg_Err
(
p_stream
,
"cannot find encoder (avcodec)"
);
return
0
;
}
id
->
ff_enc_c
=
avcodec_alloc_context3
(
id
->
ff_enc
);
id
->
ff_enc_c
->
dsp_mask
=
GetVlcDspMask
();
id
->
ff_enc_c
->
width
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
format
.
i_width
;
id
->
ff_enc_c
->
height
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
format
.
i_height
;
av_reduce
(
&
i_aspect_num
,
&
i_aspect_den
,
p_sys
->
i_aspect
,
VOUT_ASPECT_FACTOR
,
1
<<
30
/* something big */
);
av_reduce
(
&
id
->
ff_enc_c
->
sample_aspect_ratio
.
num
,
&
id
->
ff_enc_c
->
sample_aspect_ratio
.
den
,
i_aspect_num
*
(
int64_t
)
id
->
ff_enc_c
->
height
,
i_aspect_den
*
(
int64_t
)
id
->
ff_enc_c
->
width
,
1
<<
30
);
id
->
ff_enc_c
->
time_base
.
num
=
1
;
id
->
ff_enc_c
->
time_base
.
den
=
25
;
/* FIXME */
id
->
ff_enc_c
->
gop_size
=
200
;
id
->
ff_enc_c
->
max_b_frames
=
0
;
id
->
ff_enc_c
->
flags
|=
CODEC_FLAG_QSCALE
|
CODEC_FLAG_INPUT_PRESERVED
|
CODEC_FLAG_LOW_DELAY
;
id
->
ff_enc_c
->
mb_decision
=
FF_MB_DECISION_SIMPLE
;
id
->
ff_enc_c
->
pix_fmt
=
PIX_FMT_YUV420P
;
vlc_avcodec_lock
();
int
ret
;
#if LIBAVCODEC_VERSION_MAJOR >= 54
AVDictionary
*
options
=
NULL
;
if
(
p_sys
->
options
)
av_dict_copy
(
&
options
,
p_sys
->
options
,
0
);
#endif
ret
=
avcodec_open2
(
id
->
ff_enc_c
,
id
->
ff_enc
,
options
?
&
options
:
NULL
);
vlc_avcodec_unlock
();
#if LIBAVCODEC_VERSION_MAJOR >= 54
AVDictionaryEntry
*
t
=
NULL
;
while
((
t
=
av_dict_get
(
options
,
""
,
t
,
AV_DICT_IGNORE_SUFFIX
)))
{
msg_Err
(
p_stream
,
"Unknown option
\"
%s
\"
"
,
t
->
key
);
}
av_dict_free
(
&
options
);
#endif
if
(
ret
)
{
msg_Err
(
p_stream
,
"cannot open encoder"
);
return
0
;
}
id
->
p_buffer_out
=
malloc
(
id
->
ff_enc_c
->
width
*
id
->
ff_enc_c
->
height
*
3
);
id
->
p_frame
=
avcodec_alloc_frame
();
id
->
p_frame
->
linesize
[
0
]
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
p
[
0
].
i_pitch
;
id
->
p_frame
->
linesize
[
1
]
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
p
[
1
].
i_pitch
;
id
->
p_frame
->
linesize
[
2
]
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
p
[
2
].
i_pitch
;
id
->
p_frame
->
data
[
0
]
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
p
[
0
].
p_pixels
;
id
->
p_frame
->
data
[
1
]
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
p
[
1
].
p_pixels
;
id
->
p_frame
->
data
[
2
]
=
p_sys
->
p_pictures
[
p_sys
->
i_cmd
-
1
].
p
[
2
].
p_pixels
;
id
->
i_nb_pred
=
p_sys
->
i_gop
;
}
return
0
;
}
/*****************************************************************************
* VideoGetBuffer: Build an alternate video buffer
*****************************************************************************/
static
block_t
*
VideoGetBuffer
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
block_t
*
p_buffer
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
int
i_out
;
block_t
*
p_out
;
id
->
p_frame
->
quality
=
p_sys
->
i_qscale
*
powf
(
2
.
0
,
FF_LAMBDA_SHIFT
+
7
.
0
)
/
139
.
0
;
id
->
p_frame
->
interlaced_frame
=
0
;
id
->
p_frame
->
top_field_first
=
1
;
id
->
p_frame
->
pts
=
p_buffer
->
i_dts
;
if
(
id
->
i_nb_pred
>=
p_sys
->
i_gop
)
{
id
->
p_frame
->
pict_type
=
AV_PICTURE_TYPE_I
;
#if 0
id->p_frame->me_threshold = 0;
id->p_frame->mb_threshold = 0;
#endif
id
->
i_nb_pred
=
0
;
}
else
{
id
->
p_frame
->
pict_type
=
AV_PICTURE_TYPE_P
;
#if 0
if ( id->p_frame->mb_type != NULL )
{
id->p_frame->me_threshold = MAX_THRESHOLD;
id->p_frame->mb_threshold = MAX_THRESHOLD;
}
#endif
id
->
i_nb_pred
++
;
}
i_out
=
avcodec_encode_video
(
id
->
ff_enc_c
,
id
->
p_buffer_out
,
id
->
ff_enc_c
->
width
*
id
->
ff_enc_c
->
height
*
3
,
id
->
p_frame
);
if
(
i_out
<=
0
)
return
NULL
;
#if 0
if ( id->p_frame->mb_type == NULL
&& id->ff_enc_c->coded_frame->pict_type != AV_PICTURE_TYPE_I )
{
int mb_width = (id->ff_enc_c->width + 15) / 16;
int mb_height = (id->ff_enc_c->height + 15) / 16;
int h_chroma_shift, v_chroma_shift;
int i;
avcodec_get_chroma_sub_sample( id->ff_enc_c->pix_fmt, &h_chroma_shift,
&v_chroma_shift );
id->p_frame->motion_subsample_log2
= id->ff_enc_c->coded_frame->motion_subsample_log2;
id->p_frame->mb_type = malloc( ((mb_width + 1) * (mb_height + 1) + 1)
* sizeof(uint32_t) );
memcpy( id->p_frame->mb_type, id->ff_enc_c->coded_frame->mb_type,
(mb_width + 1) * mb_height * sizeof(id->p_frame->mb_type[0]));
for ( i = 0; i < 2; i++ )
{
int stride = ((16 * mb_width )
>> id->ff_enc_c->coded_frame->motion_subsample_log2) + 1;
int height = ((16 * mb_height)
>> id->ff_enc_c->coded_frame->motion_subsample_log2);
int b8_stride = mb_width * 2 + 1;
if ( id->ff_enc_c->coded_frame->motion_val[i] )
{
id->p_frame->motion_val[i] = malloc( 2 * stride * height
* sizeof(int16_t) );
memcpy( id->p_frame->motion_val[i],
id->ff_enc_c->coded_frame->motion_val[i],
2 * stride * height * sizeof(int16_t) );
}
if ( id->ff_enc_c->coded_frame->ref_index[i] )
{
id->p_frame->ref_index[i] = malloc( b8_stride * 2 * mb_height
* sizeof(int8_t) );
memcpy( id->p_frame->ref_index[i],
id->ff_enc_c->coded_frame->ref_index[i],
b8_stride * 2 * mb_height * sizeof(int8_t));
}
}
}
#endif
p_out
=
block_Alloc
(
i_out
);
memcpy
(
p_out
->
p_buffer
,
id
->
p_buffer_out
,
i_out
);
p_out
->
i_length
=
p_buffer
->
i_length
;
p_out
->
i_pts
=
p_buffer
->
i_dts
;
p_out
->
i_dts
=
p_buffer
->
i_dts
;
switch
(
id
->
ff_enc_c
->
coded_frame
->
pict_type
)
{
case
AV_PICTURE_TYPE_I
:
p_out
->
i_flags
|=
BLOCK_FLAG_TYPE_I
;
break
;
case
AV_PICTURE_TYPE_P
:
p_out
->
i_flags
|=
BLOCK_FLAG_TYPE_P
;
break
;
case
AV_PICTURE_TYPE_B
:
p_out
->
i_flags
|=
BLOCK_FLAG_TYPE_B
;
break
;
default:
break
;
}
block_Release
(
p_buffer
);
return
p_out
;
}
/*****************************************************************************
* AudioGetBuffer: Build an alternate audio buffer
*****************************************************************************/
static
block_t
*
AudioGetBuffer
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
block_t
*
p_buffer
)
{
int
i_out
;
block_t
*
p_out
;
(
void
)
p_stream
;
i_out
=
avcodec_encode_audio
(
id
->
ff_enc_c
,
id
->
p_buffer_out
,
2
*
AVCODEC_MAX_AUDIO_FRAME_SIZE
,
id
->
p_samples
);
if
(
i_out
<=
0
)
return
NULL
;
p_out
=
block_Alloc
(
i_out
);
memcpy
(
p_out
->
p_buffer
,
id
->
p_buffer_out
,
i_out
);
p_out
->
i_length
=
p_buffer
->
i_length
;
p_out
->
i_pts
=
p_buffer
->
i_dts
;
p_out
->
i_dts
=
p_buffer
->
i_dts
;
block_Release
(
p_buffer
);
return
p_out
;
}
po/POTFILES.in
View file @
e2382750
...
...
@@ -1014,7 +1014,6 @@ modules/stream_out/rtsp.c
modules/stream_out/setid.c
modules/stream_out/smem.c
modules/stream_out/standard.c
modules/stream_out/switcher.c
modules/stream_out/transcode/transcode.c
modules/text_renderer/freetype.c
modules/text_renderer/quartztext.c
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment