Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
7ea9a56d
Commit
7ea9a56d
authored
Apr 25, 2010
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split out interlacing/post-processing management from video_output.c (vout).
parent
72300186
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
531 additions
and
383 deletions
+531
-383
src/Makefile.am
src/Makefile.am
+4
-0
src/video_output/interlacing.c
src/video_output/interlacing.c
+294
-0
src/video_output/interlacing.h
src/video_output/interlacing.h
+39
-0
src/video_output/postprocessing.c
src/video_output/postprocessing.c
+143
-0
src/video_output/postprocessing.h
src/video_output/postprocessing.h
+37
-0
src/video_output/video_output.c
src/video_output/video_output.c
+14
-383
No files found.
src/Makefile.am
View file @
7ea9a56d
...
...
@@ -361,9 +361,13 @@ SOURCES_libvlc_common = \
video_output/event.h
\
video_output/inhibit.c
\
video_output/inhibit.h
\
video_output/interlacing.c
\
video_output/interlacing.h
\
video_output/snapshot.c
\
video_output/snapshot.h
\
video_output/statistic.h
\
video_output/postprocessing.c
\
video_output/postprocessing.h
\
video_output/video_output.c
\
video_output/vout_pictures.c
\
video_output/vout_pictures.h
\
...
...
src/video_output/interlacing.c
0 → 100644
View file @
7ea9a56d
/*****************************************************************************
* interlacing.c
*****************************************************************************
* Copyright (C) 2010 Laurent Aimar
* $Id$
*
* Authors: Laurent Aimar <fenrir _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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_vout.h>
#include "interlacing.h"
/*****************************************************************************
* Deinterlacing
*****************************************************************************/
/* XXX
* You can use the non vout filter if and only if the video properties stay the
* same (width/height/chroma/fps), at least for now.
*/
static
const
char
*
deinterlace_modes
[]
=
{
""
//"discard",
"blend"
,
//"mean",
//"bob",
//"linear",
"x"
,
//"yadif",
//"yadif2x",
NULL
};
static
bool
DeinterlaceIsModeValid
(
const
char
*
mode
)
{
for
(
unsigned
i
=
0
;
deinterlace_modes
[
i
];
i
++
)
{
if
(
!
strcmp
(
deinterlace_modes
[
i
],
mode
))
return
true
;
}
return
false
;
}
static
char
*
FilterFind
(
char
*
psz_filter_base
,
const
char
*
psz_module
)
{
const
size_t
i_module
=
strlen
(
psz_module
);
const
char
*
psz_filter
=
psz_filter_base
;
if
(
!
psz_filter
||
i_module
<=
0
)
return
NULL
;
for
(
;;
)
{
char
*
psz_find
=
strstr
(
psz_filter
,
psz_module
);
if
(
!
psz_find
)
return
NULL
;
if
(
psz_find
[
i_module
]
==
'\0'
||
psz_find
[
i_module
]
==
':'
)
return
psz_find
;
psz_filter
=
&
psz_find
[
i_module
];
}
}
static
bool
DeinterlaceIsPresent
(
vout_thread_t
*
p_vout
)
{
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
bool
b_found
=
FilterFind
(
psz_filter
,
"deinterlace"
)
!=
NULL
;
free
(
psz_filter
);
return
b_found
;
}
static
void
DeinterlaceRemove
(
vout_thread_t
*
p_vout
)
{
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
char
*
psz
=
FilterFind
(
psz_filter
,
"deinterlace"
);
if
(
!
psz
)
{
free
(
psz_filter
);
return
;
}
/* */
strcpy
(
&
psz
[
0
],
&
psz
[
strlen
(
"deinterlace"
)]
);
if
(
*
psz
==
':'
)
strcpy
(
&
psz
[
0
],
&
psz
[
1
]
);
var_SetString
(
p_vout
,
"video-filter"
,
psz_filter
);
free
(
psz_filter
);
}
static
void
DeinterlaceAdd
(
vout_thread_t
*
p_vout
)
{
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
if
(
FilterFind
(
psz_filter
,
"deinterlace"
)
)
{
free
(
psz_filter
);
return
;
}
/* */
if
(
psz_filter
)
{
char
*
psz_tmp
=
psz_filter
;
if
(
asprintf
(
&
psz_filter
,
"%s:%s"
,
psz_tmp
,
"deinterlace"
)
<
0
)
psz_filter
=
psz_tmp
;
else
free
(
psz_tmp
);
}
else
{
psz_filter
=
strdup
(
"deinterlace"
);
}
if
(
psz_filter
)
{
var_SetString
(
p_vout
,
"video-filter"
,
psz_filter
);
free
(
psz_filter
);
}
}
static
void
DeinterlaceSave
(
vout_thread_t
*
p_vout
,
int
i_deinterlace
,
const
char
*
psz_mode
)
{
/* We have to set input variable to ensure restart support
* FIXME to be removed when vout_Request does the right job.
*/
vlc_object_t
*
p_input
=
vlc_object_find
(
p_vout
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
if
(
!
p_input
)
return
;
var_Create
(
p_input
,
"deinterlace"
,
VLC_VAR_INTEGER
);
var_SetInteger
(
p_input
,
"deinterlace"
,
i_deinterlace
);
static
const
char
*
const
ppsz_variable
[]
=
{
"deinterlace-mode"
,
"sout-deinterlace-mode"
,
NULL
};
for
(
int
i
=
0
;
ppsz_variable
[
i
];
i
++
)
{
var_Create
(
p_input
,
ppsz_variable
[
i
],
VLC_VAR_STRING
);
var_SetString
(
p_input
,
ppsz_variable
[
i
],
psz_mode
);
}
vlc_object_release
(
p_input
);
}
static
int
DeinterlaceCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
newval
);
VLC_UNUSED
(
p_data
);
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
/* */
const
int
i_deinterlace
=
var_GetInteger
(
p_this
,
"deinterlace"
);
char
*
psz_mode
=
var_GetString
(
p_this
,
"deinterlace-mode"
);
const
bool
is_needed
=
var_GetBool
(
p_this
,
"deinterlace-needed"
);
if
(
!
psz_mode
||
!
DeinterlaceIsModeValid
(
psz_mode
)
)
return
VLC_EGENERIC
;
DeinterlaceSave
(
p_vout
,
i_deinterlace
,
psz_mode
);
/* */
char
*
psz_old
=
var_CreateGetString
(
p_vout
,
"sout-deinterlace-mode"
);
msg_Dbg
(
p_vout
,
"deinterlace %d, mode %s, is_needed %d"
,
i_deinterlace
,
psz_mode
,
is_needed
);
if
(
i_deinterlace
==
0
||
(
i_deinterlace
==
-
1
&&
!
is_needed
)
)
{
DeinterlaceRemove
(
p_vout
);
}
else
if
(
!
DeinterlaceIsPresent
(
p_vout
)
)
{
DeinterlaceAdd
(
p_vout
);
}
else
if
(
psz_old
&&
strcmp
(
psz_old
,
psz_mode
)
)
{
var_TriggerCallback
(
p_vout
,
"video-filter"
);
}
/* */
free
(
psz_old
);
free
(
psz_mode
);
return
VLC_SUCCESS
;
}
void
vout_InitInterlacingSupport
(
vout_thread_t
*
p_vout
,
bool
is_interlaced
)
{
vlc_value_t
val
,
text
;
msg_Dbg
(
p_vout
,
"Deinterlacing available"
);
/* Create the configuration variables */
/* */
var_Create
(
p_vout
,
"deinterlace"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
|
VLC_VAR_HASCHOICE
);
int
i_deinterlace
=
var_GetInteger
(
p_vout
,
"deinterlace"
);
text
.
psz_string
=
_
(
"Deinterlace"
);
var_Change
(
p_vout
,
"deinterlace"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
const
module_config_t
*
p_optd
=
config_FindConfig
(
VLC_OBJECT
(
p_vout
),
"deinterlace"
);
var_Change
(
p_vout
,
"deinterlace"
,
VLC_VAR_CLEARCHOICES
,
NULL
,
NULL
);
for
(
int
i
=
0
;
p_optd
&&
i
<
p_optd
->
i_list
;
i
++
)
{
val
.
i_int
=
p_optd
->
pi_list
[
i
];
text
.
psz_string
=
(
char
*
)
vlc_gettext
(
p_optd
->
ppsz_list_text
[
i
]);
var_Change
(
p_vout
,
"deinterlace"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
}
var_AddCallback
(
p_vout
,
"deinterlace"
,
DeinterlaceCallback
,
NULL
);
/* */
var_Create
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
|
VLC_VAR_HASCHOICE
);
char
*
psz_deinterlace
=
var_GetNonEmptyString
(
p_vout
,
"deinterlace-mode"
);
text
.
psz_string
=
_
(
"Deinterlace mode"
);
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
const
module_config_t
*
p_optm
=
config_FindConfig
(
VLC_OBJECT
(
p_vout
),
"deinterlace-mode"
);
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_CLEARCHOICES
,
NULL
,
NULL
);
for
(
int
i
=
0
;
p_optm
&&
i
<
p_optm
->
i_list
;
i
++
)
{
if
(
!
DeinterlaceIsModeValid
(
p_optm
->
ppsz_list
[
i
]
)
)
continue
;
val
.
psz_string
=
p_optm
->
ppsz_list
[
i
];
text
.
psz_string
=
(
char
*
)
vlc_gettext
(
p_optm
->
ppsz_list_text
[
i
]);
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
}
var_AddCallback
(
p_vout
,
"deinterlace-mode"
,
DeinterlaceCallback
,
NULL
);
/* */
var_Create
(
p_vout
,
"deinterlace-needed"
,
VLC_VAR_BOOL
);
var_AddCallback
(
p_vout
,
"deinterlace-needed"
,
DeinterlaceCallback
,
NULL
);
/* Override the initial value from filters if present */
char
*
psz_filter_mode
=
NULL
;
if
(
DeinterlaceIsPresent
(
p_vout
)
)
psz_filter_mode
=
var_CreateGetNonEmptyString
(
p_vout
,
"sout-deinterlace-mode"
);
if
(
psz_filter_mode
)
{
free
(
psz_deinterlace
);
if
(
i_deinterlace
>=
-
1
)
i_deinterlace
=
1
;
psz_deinterlace
=
psz_filter_mode
;
}
/* */
if
(
i_deinterlace
<
0
)
i_deinterlace
=
-
1
;
/* */
val
.
psz_string
=
psz_deinterlace
?
psz_deinterlace
:
p_optm
->
orig
.
psz
;
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
val
.
b_bool
=
is_interlaced
;
var_Change
(
p_vout
,
"deinterlace-needed"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_SetInteger
(
p_vout
,
"deinterlace"
,
i_deinterlace
);
free
(
psz_deinterlace
);
}
void
vout_SetInterlacingState
(
vout_thread_t
*
p_vout
,
vout_interlacing_support_t
*
state
,
bool
is_interlaced
)
{
/* Wait 30s before quiting interlacing mode */
const
int
interlacing_change
=
(
!!
is_interlaced
)
-
(
!!
state
->
is_interlaced
);
if
((
interlacing_change
==
1
)
||
(
interlacing_change
==
-
1
&&
state
->
date
+
30000000
<
mdate
()))
{
msg_Dbg
(
p_vout
,
"Detected %s video"
,
is_interlaced
?
"interlaced"
:
"progressive"
);
var_SetBool
(
p_vout
,
"deinterlace-needed"
,
is_interlaced
);
state
->
is_interlaced
=
is_interlaced
;
}
if
(
is_interlaced
)
state
->
date
=
mdate
();
}
src/video_output/interlacing.h
0 → 100644
View file @
7ea9a56d
/*****************************************************************************
* interlacing.h: Interlacing related helpers
*****************************************************************************
* Copyright (C) 2010 Laurent Aimar
* $Id$
*
* Authors: Laurent Aimar <fenrir _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.
*****************************************************************************/
#if defined(__PLUGIN__) || defined(__BUILTIN__) || !defined(__LIBVLC__)
# error This header file can only be included from LibVLC.
#endif
#ifndef _VOUT_INTERLACING_H
#define _VOUT_INTERLACING_H
typedef
struct
{
bool
is_interlaced
;
mtime_t
date
;
}
vout_interlacing_support_t
;
void
vout_InitInterlacingSupport
(
vout_thread_t
*
,
bool
is_interlaced
);
void
vout_SetInterlacingState
(
vout_thread_t
*
,
vout_interlacing_support_t
*
,
bool
is_interlaced
);
#endif
src/video_output/postprocessing.c
0 → 100644
View file @
7ea9a56d
/*****************************************************************************
* postprocessing.c
*****************************************************************************
* Copyright (C) 2010 Laurent Aimar
* $Id$
*
* Authors: Laurent Aimar <fenrir _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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_vout.h>
#include "postprocessing.h"
static
bool
PostProcessIsPresent
(
const
char
*
psz_filter
)
{
const
char
*
psz_pp
=
"postproc"
;
const
size_t
i_pp
=
strlen
(
psz_pp
);
return
psz_filter
&&
!
strncmp
(
psz_filter
,
psz_pp
,
strlen
(
psz_pp
)
)
&&
(
psz_filter
[
i_pp
]
==
'\0'
||
psz_filter
[
i_pp
]
==
':'
);
}
static
int
PostProcessCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
p_data
);
static
const
char
*
psz_pp
=
"postproc"
;
char
*
psz_vf2
=
var_GetString
(
p_vout
,
"video-filter"
);
if
(
newval
.
i_int
<=
0
)
{
if
(
PostProcessIsPresent
(
psz_vf2
)
)
{
strcpy
(
psz_vf2
,
&
psz_vf2
[
strlen
(
psz_pp
)]
);
if
(
*
psz_vf2
==
':'
)
strcpy
(
psz_vf2
,
&
psz_vf2
[
1
]
);
}
}
else
{
if
(
!
PostProcessIsPresent
(
psz_vf2
)
)
{
if
(
psz_vf2
)
{
char
*
psz_tmp
=
psz_vf2
;
if
(
asprintf
(
&
psz_vf2
,
"%s:%s"
,
psz_pp
,
psz_tmp
)
<
0
)
psz_vf2
=
psz_tmp
;
else
free
(
psz_tmp
);
}
else
{
psz_vf2
=
strdup
(
psz_pp
);
}
}
}
if
(
newval
.
i_int
>
0
)
var_SetInteger
(
p_vout
,
"postproc-q"
,
newval
.
i_int
);
if
(
psz_vf2
)
{
var_SetString
(
p_vout
,
"video-filter"
,
psz_vf2
);
free
(
psz_vf2
);
}
else
if
(
newval
.
i_int
>
0
)
{
var_TriggerCallback
(
p_vout
,
"video-filter"
);
}
return
VLC_SUCCESS
;
}
static
void
PostProcessEnable
(
vout_thread_t
*
p_vout
)
{
vlc_value_t
text
;
msg_Dbg
(
p_vout
,
"Post-processing available"
);
var_Create
(
p_vout
,
"postprocess"
,
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
);
text
.
psz_string
=
_
(
"Post processing"
);
var_Change
(
p_vout
,
"postprocess"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
for
(
int
i
=
0
;
i
<=
6
;
i
++
)
{
vlc_value_t
val
;
vlc_value_t
text
;
char
psz_text
[
1
+
1
];
val
.
i_int
=
i
;
snprintf
(
psz_text
,
sizeof
(
psz_text
),
"%d"
,
i
);
if
(
i
==
0
)
text
.
psz_string
=
_
(
"Disable"
);
else
text
.
psz_string
=
psz_text
;
var_Change
(
p_vout
,
"postprocess"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
}
var_AddCallback
(
p_vout
,
"postprocess"
,
PostProcessCallback
,
NULL
);
/* */
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
int
i_postproc_q
=
0
;
if
(
PostProcessIsPresent
(
psz_filter
)
)
i_postproc_q
=
var_CreateGetInteger
(
p_vout
,
"postproc-q"
);
var_SetInteger
(
p_vout
,
"postprocess"
,
i_postproc_q
);
free
(
psz_filter
);
}
static
void
PostProcessDisable
(
vout_thread_t
*
p_vout
)
{
msg_Dbg
(
p_vout
,
"Post-processing no more available"
);
var_Destroy
(
p_vout
,
"postprocess"
);
}
void
vout_SetPostProcessingState
(
vout_thread_t
*
vout
,
vout_postprocessing_support_t
*
state
,
int
qtype
)
{
const
int
postproc_change
=
(
qtype
!=
QTYPE_NONE
)
-
(
state
->
qtype
!=
QTYPE_NONE
);
if
(
postproc_change
==
1
)
PostProcessEnable
(
vout
);
else
if
(
postproc_change
==
-
1
)
PostProcessDisable
(
vout
);
if
(
postproc_change
)
state
->
qtype
=
qtype
;
}
src/video_output/postprocessing.h
0 → 100644
View file @
7ea9a56d
/*****************************************************************************
* postprocessing.h: Post processing related helpers
*****************************************************************************
* Copyright (C) 2010 Laurent Aimar
* $Id$
*
* Authors: Laurent Aimar <fenrir _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.
*****************************************************************************/
#if defined(__PLUGIN__) || defined(__BUILTIN__) || !defined(__LIBVLC__)
# error This header file can only be included from LibVLC.
#endif
#ifndef _VOUT_POSTPROCESSING_H
#define _VOUT_POSTPROCESSING_H
typedef
struct
{
int
qtype
;
}
vout_postprocessing_support_t
;
void
vout_SetPostProcessingState
(
vout_thread_t
*
,
vout_postprocessing_support_t
*
,
int
qtype
);
#endif
src/video_output/video_output.c
View file @
7ea9a56d
...
...
@@ -49,6 +49,8 @@
#include <vlc_input.h>
#include "vout_pictures.h"
#include "vout_internal.h"
#include "interlacing.h"
#include "postprocessing.h"
/*****************************************************************************
* Local prototypes
...
...
@@ -62,15 +64,6 @@ static int FilterCallback( vlc_object_t *, char const *,
static
int
VideoFilter2Callback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
/* */
static
void
PostProcessEnable
(
vout_thread_t
*
);
static
void
PostProcessDisable
(
vout_thread_t
*
);
static
int
PostProcessCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
/* */
static
void
DeinterlaceEnable
(
vout_thread_t
*
,
bool
is_interlaced
);
static
void
DeinterlaceNeeded
(
vout_thread_t
*
,
bool
);
/* Display media title in OSD */
static
void
DisplayTitleOnOSD
(
vout_thread_t
*
p_vout
);
...
...
@@ -384,7 +377,7 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
var_AddCallback
(
p_vout
,
"vout-filter"
,
FilterCallback
,
NULL
);
/* */
DeinterlaceEnable
(
p_vout
,
p_vout
->
p
->
displayed
.
is_interlaced
);
vout_InitInterlacingSupport
(
p_vout
,
p_vout
->
p
->
displayed
.
is_interlaced
);
if
(
p_vout
->
p
->
psz_filter_chain
&&
*
p_vout
->
p
->
psz_filter_chain
)
{
...
...
@@ -917,9 +910,13 @@ static void *Thread(void *object)
goto
exit_thread
;
/* */
bool
last_picture_interlaced
=
false
;
int
last_picture_qtype
=
QTYPE_NONE
;
mtime_t
last_picture_interlaced_date
=
mdate
();
vout_interlacing_support_t
interlacing
=
{
.
is_interlaced
=
false
,
.
date
=
mdate
(),
};
vout_postprocessing_support_t
postprocessing
=
{
.
qtype
=
QTYPE_NONE
,
};
/*
* Main loop - it is not executed if an error occurred during
...
...
@@ -971,24 +968,10 @@ static void *Thread(void *object)
}
/* Post processing */
const
int
postproc_change
=
(
picture_qtype
!=
QTYPE_NONE
)
-
(
last_picture_qtype
!=
QTYPE_NONE
);
if
(
postproc_change
==
1
)
PostProcessEnable
(
vout
);
else
if
(
postproc_change
==
-
1
)
PostProcessDisable
(
vout
);
if
(
postproc_change
)
last_picture_qtype
=
picture_qtype
;
/* Deinterlacing
* Wait 30s before quiting interlacing mode */
const
int
interlacing_change
=
(
!!
picture_interlaced
)
-
(
!!
last_picture_interlaced
);
if
((
interlacing_change
==
1
)
||
(
interlacing_change
==
-
1
&&
last_picture_interlaced_date
+
30000000
<
mdate
()))
{
DeinterlaceNeeded
(
vout
,
picture_interlaced
);
last_picture_interlaced
=
picture_interlaced
;
}
if
(
picture_interlaced
)
last_picture_interlaced_date
=
mdate
();
vout_SetPostProcessingState
(
vout
,
&
postprocessing
,
picture_qtype
);
/* Deinterlacing */
vout_SetInterlacingState
(
vout
,
&
interlacing
,
picture_interlaced
);
/* Check for "video filter2" changes */
vlc_mutex_lock
(
&
vout
->
p
->
vfilter_lock
);
...
...
@@ -1095,108 +1078,6 @@ static int VideoFilter2Callback( vlc_object_t *p_this, char const *psz_cmd,
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Post-processing
*****************************************************************************/
static
bool
PostProcessIsPresent
(
const
char
*
psz_filter
)
{
const
char
*
psz_pp
=
"postproc"
;
const
size_t
i_pp
=
strlen
(
psz_pp
);
return
psz_filter
&&
!
strncmp
(
psz_filter
,
psz_pp
,
strlen
(
psz_pp
)
)
&&
(
psz_filter
[
i_pp
]
==
'\0'
||
psz_filter
[
i_pp
]
==
':'
);
}
static
int
PostProcessCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
p_data
);
static
const
char
*
psz_pp
=
"postproc"
;
char
*
psz_vf2
=
var_GetString
(
p_vout
,
"video-filter"
);
if
(
newval
.
i_int
<=
0
)
{
if
(
PostProcessIsPresent
(
psz_vf2
)
)
{
strcpy
(
psz_vf2
,
&
psz_vf2
[
strlen
(
psz_pp
)]
);
if
(
*
psz_vf2
==
':'
)
strcpy
(
psz_vf2
,
&
psz_vf2
[
1
]
);
}
}
else
{
if
(
!
PostProcessIsPresent
(
psz_vf2
)
)
{
if
(
psz_vf2
)
{
char
*
psz_tmp
=
psz_vf2
;
if
(
asprintf
(
&
psz_vf2
,
"%s:%s"
,
psz_pp
,
psz_tmp
)
<
0
)
psz_vf2
=
psz_tmp
;
else
free
(
psz_tmp
);
}
else
{
psz_vf2
=
strdup
(
psz_pp
);
}
}
}
if
(
newval
.
i_int
>
0
)
var_SetInteger
(
p_vout
,
"postproc-q"
,
newval
.
i_int
);
if
(
psz_vf2
)
{
var_SetString
(
p_vout
,
"video-filter"
,
psz_vf2
);
free
(
psz_vf2
);
}
else
if
(
newval
.
i_int
>
0
)
{
var_TriggerCallback
(
p_vout
,
"video-filter"
);
}
return
VLC_SUCCESS
;
}
static
void
PostProcessEnable
(
vout_thread_t
*
p_vout
)
{
vlc_value_t
text
;
msg_Dbg
(
p_vout
,
"Post-processing available"
);
var_Create
(
p_vout
,
"postprocess"
,
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
);
text
.
psz_string
=
_
(
"Post processing"
);
var_Change
(
p_vout
,
"postprocess"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
for
(
int
i
=
0
;
i
<=
6
;
i
++
)
{
vlc_value_t
val
;
vlc_value_t
text
;
char
psz_text
[
1
+
1
];
val
.
i_int
=
i
;
snprintf
(
psz_text
,
sizeof
(
psz_text
),
"%d"
,
i
);
if
(
i
==
0
)
text
.
psz_string
=
_
(
"Disable"
);
else
text
.
psz_string
=
psz_text
;
var_Change
(
p_vout
,
"postprocess"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
}
var_AddCallback
(
p_vout
,
"postprocess"
,
PostProcessCallback
,
NULL
);
/* */
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
int
i_postproc_q
=
0
;
if
(
PostProcessIsPresent
(
psz_filter
)
)
i_postproc_q
=
var_CreateGetInteger
(
p_vout
,
"postproc-q"
);
var_SetInteger
(
p_vout
,
"postprocess"
,
i_postproc_q
);
free
(
psz_filter
);
}
static
void
PostProcessDisable
(
vout_thread_t
*
p_vout
)
{
msg_Dbg
(
p_vout
,
"Post-processing no more available"
);
var_Destroy
(
p_vout
,
"postprocess"
);
}
static
void
DisplayTitleOnOSD
(
vout_thread_t
*
p_vout
)
{
const
mtime_t
i_start
=
mdate
();
...
...
@@ -1221,256 +1102,6 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout )
p_vout
->
p
->
title
.
value
=
NULL
;
}
/*****************************************************************************
* Deinterlacing
*****************************************************************************/
/* XXX
* You can use the non vout filter if and only if the video properties stay the
* same (width/height/chroma/fps), at least for now.
*/
static
const
char
*
deinterlace_modes
[]
=
{
""
//"discard",
"blend"
,
//"mean",
//"bob",
//"linear",
"x"
,
//"yadif",
//"yadif2x",
NULL
};
static
bool
DeinterlaceIsModeValid
(
const
char
*
mode
)
{
for
(
unsigned
i
=
0
;
deinterlace_modes
[
i
];
i
++
)
{
if
(
!
strcmp
(
deinterlace_modes
[
i
],
mode
))
return
true
;
}
return
false
;
}
static
char
*
FilterFind
(
char
*
psz_filter_base
,
const
char
*
psz_module
)
{
const
size_t
i_module
=
strlen
(
psz_module
);
const
char
*
psz_filter
=
psz_filter_base
;
if
(
!
psz_filter
||
i_module
<=
0
)
return
NULL
;
for
(
;;
)
{
char
*
psz_find
=
strstr
(
psz_filter
,
psz_module
);
if
(
!
psz_find
)
return
NULL
;
if
(
psz_find
[
i_module
]
==
'\0'
||
psz_find
[
i_module
]
==
':'
)
return
psz_find
;
psz_filter
=
&
psz_find
[
i_module
];
}
}
static
bool
DeinterlaceIsPresent
(
vout_thread_t
*
p_vout
)
{
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
bool
b_found
=
FilterFind
(
psz_filter
,
"deinterlace"
)
!=
NULL
;
free
(
psz_filter
);
return
b_found
;
}
static
void
DeinterlaceRemove
(
vout_thread_t
*
p_vout
)
{
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
char
*
psz
=
FilterFind
(
psz_filter
,
"deinterlace"
);
if
(
!
psz
)
{
free
(
psz_filter
);
return
;
}
/* */
strcpy
(
&
psz
[
0
],
&
psz
[
strlen
(
"deinterlace"
)]
);
if
(
*
psz
==
':'
)
strcpy
(
&
psz
[
0
],
&
psz
[
1
]
);
var_SetString
(
p_vout
,
"video-filter"
,
psz_filter
);
free
(
psz_filter
);
}
static
void
DeinterlaceAdd
(
vout_thread_t
*
p_vout
)
{
char
*
psz_filter
=
var_GetNonEmptyString
(
p_vout
,
"video-filter"
);
if
(
FilterFind
(
psz_filter
,
"deinterlace"
)
)
{
free
(
psz_filter
);
return
;
}
/* */
if
(
psz_filter
)
{
char
*
psz_tmp
=
psz_filter
;
if
(
asprintf
(
&
psz_filter
,
"%s:%s"
,
psz_tmp
,
"deinterlace"
)
<
0
)
psz_filter
=
psz_tmp
;
else
free
(
psz_tmp
);
}
else
{
psz_filter
=
strdup
(
"deinterlace"
);
}
if
(
psz_filter
)
{
var_SetString
(
p_vout
,
"video-filter"
,
psz_filter
);
free
(
psz_filter
);
}
}
static
void
DeinterlaceSave
(
vout_thread_t
*
p_vout
,
int
i_deinterlace
,
const
char
*
psz_mode
)
{
/* We have to set input variable to ensure restart support
* FIXME to be removed when vout_Request does the right job.
*/
vlc_object_t
*
p_input
=
vlc_object_find
(
p_vout
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
if
(
!
p_input
)
return
;
var_Create
(
p_input
,
"deinterlace"
,
VLC_VAR_INTEGER
);
var_SetInteger
(
p_input
,
"deinterlace"
,
i_deinterlace
);
static
const
char
*
const
ppsz_variable
[]
=
{
"deinterlace-mode"
,
"sout-deinterlace-mode"
,
NULL
};
for
(
int
i
=
0
;
ppsz_variable
[
i
];
i
++
)
{
var_Create
(
p_input
,
ppsz_variable
[
i
],
VLC_VAR_STRING
);
var_SetString
(
p_input
,
ppsz_variable
[
i
],
psz_mode
);
}
vlc_object_release
(
p_input
);
}
static
int
DeinterlaceCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
newval
);
VLC_UNUSED
(
p_data
);
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
/* */
const
int
i_deinterlace
=
var_GetInteger
(
p_this
,
"deinterlace"
);
char
*
psz_mode
=
var_GetString
(
p_this
,
"deinterlace-mode"
);
const
bool
is_needed
=
var_GetBool
(
p_this
,
"deinterlace-needed"
);
if
(
!
psz_mode
||
!
DeinterlaceIsModeValid
(
psz_mode
)
)
return
VLC_EGENERIC
;
DeinterlaceSave
(
p_vout
,
i_deinterlace
,
psz_mode
);
/* */
char
*
psz_old
=
var_CreateGetString
(
p_vout
,
"sout-deinterlace-mode"
);
msg_Dbg
(
p_vout
,
"deinterlace %d, mode %s, is_needed %d"
,
i_deinterlace
,
psz_mode
,
is_needed
);
if
(
i_deinterlace
==
0
||
(
i_deinterlace
==
-
1
&&
!
is_needed
)
)
{
DeinterlaceRemove
(
p_vout
);
}
else
if
(
!
DeinterlaceIsPresent
(
p_vout
)
)
{
DeinterlaceAdd
(
p_vout
);
}
else
if
(
psz_old
&&
strcmp
(
psz_old
,
psz_mode
)
)
{
var_TriggerCallback
(
p_vout
,
"video-filter"
);
}
/* */
free
(
psz_old
);
free
(
psz_mode
);
return
VLC_SUCCESS
;
}
static
void
DeinterlaceEnable
(
vout_thread_t
*
p_vout
,
bool
is_interlaced
)
{
vlc_value_t
val
,
text
;
msg_Dbg
(
p_vout
,
"Deinterlacing available"
);
/* Create the configuration variables */
/* */
var_Create
(
p_vout
,
"deinterlace"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
|
VLC_VAR_HASCHOICE
);
int
i_deinterlace
=
var_GetInteger
(
p_vout
,
"deinterlace"
);
text
.
psz_string
=
_
(
"Deinterlace"
);
var_Change
(
p_vout
,
"deinterlace"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
const
module_config_t
*
p_optd
=
config_FindConfig
(
VLC_OBJECT
(
p_vout
),
"deinterlace"
);
var_Change
(
p_vout
,
"deinterlace"
,
VLC_VAR_CLEARCHOICES
,
NULL
,
NULL
);
for
(
int
i
=
0
;
p_optd
&&
i
<
p_optd
->
i_list
;
i
++
)
{
val
.
i_int
=
p_optd
->
pi_list
[
i
];
text
.
psz_string
=
(
char
*
)
vlc_gettext
(
p_optd
->
ppsz_list_text
[
i
]);
var_Change
(
p_vout
,
"deinterlace"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
}
var_AddCallback
(
p_vout
,
"deinterlace"
,
DeinterlaceCallback
,
NULL
);
/* */
var_Create
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
|
VLC_VAR_HASCHOICE
);
char
*
psz_deinterlace
=
var_GetNonEmptyString
(
p_vout
,
"deinterlace-mode"
);
text
.
psz_string
=
_
(
"Deinterlace mode"
);
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
const
module_config_t
*
p_optm
=
config_FindConfig
(
VLC_OBJECT
(
p_vout
),
"deinterlace-mode"
);
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_CLEARCHOICES
,
NULL
,
NULL
);
for
(
int
i
=
0
;
p_optm
&&
i
<
p_optm
->
i_list
;
i
++
)
{
if
(
!
DeinterlaceIsModeValid
(
p_optm
->
ppsz_list
[
i
]
)
)
continue
;
val
.
psz_string
=
p_optm
->
ppsz_list
[
i
];
text
.
psz_string
=
(
char
*
)
vlc_gettext
(
p_optm
->
ppsz_list_text
[
i
]);
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
}
var_AddCallback
(
p_vout
,
"deinterlace-mode"
,
DeinterlaceCallback
,
NULL
);
/* */
var_Create
(
p_vout
,
"deinterlace-needed"
,
VLC_VAR_BOOL
);
var_AddCallback
(
p_vout
,
"deinterlace-needed"
,
DeinterlaceCallback
,
NULL
);
/* Override the initial value from filters if present */
char
*
psz_filter_mode
=
NULL
;
if
(
DeinterlaceIsPresent
(
p_vout
)
)
psz_filter_mode
=
var_CreateGetNonEmptyString
(
p_vout
,
"sout-deinterlace-mode"
);
if
(
psz_filter_mode
)
{
free
(
psz_deinterlace
);
if
(
i_deinterlace
>=
-
1
)
i_deinterlace
=
1
;
psz_deinterlace
=
psz_filter_mode
;
}
/* */
if
(
i_deinterlace
<
0
)
i_deinterlace
=
-
1
;
/* */
val
.
psz_string
=
psz_deinterlace
?
psz_deinterlace
:
p_optm
->
orig
.
psz
;
var_Change
(
p_vout
,
"deinterlace-mode"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
val
.
b_bool
=
is_interlaced
;
var_Change
(
p_vout
,
"deinterlace-needed"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_SetInteger
(
p_vout
,
"deinterlace"
,
i_deinterlace
);
free
(
psz_deinterlace
);
}
static
void
DeinterlaceNeeded
(
vout_thread_t
*
p_vout
,
bool
is_interlaced
)
{
msg_Dbg
(
p_vout
,
"Detected %s video"
,
is_interlaced
?
"interlaced"
:
"progressive"
);
var_SetBool
(
p_vout
,
"deinterlace-needed"
,
is_interlaced
);
}
/* */
static
void
PrintVideoFormat
(
vout_thread_t
*
vout
,
const
char
*
description
,
...
...
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