Bring CSRI into the repository fully, I'm not an advocate of this! but it's the
best 'solution' for now. Originally committed to SVN as r1915.
This commit is contained in:
parent
20f0f52cec
commit
cdd49b02b4
43 changed files with 5074 additions and 0 deletions
22
csri/Doxyfile
Normal file
22
csri/Doxyfile
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
PROJECT_NAME = CSRI
|
||||||
|
PROJECT_NUMBER = 0.1
|
||||||
|
OUTPUT_DIRECTORY = doc
|
||||||
|
|
||||||
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
PREDEFINED = DOXYGEN
|
||||||
|
ENUM_VALUES_PER_LINE = 1
|
||||||
|
EXPAND_AS_DEFINED = _CSRI_H _CSRI_HELPER_H
|
||||||
|
|
||||||
|
INPUT = include/csri include/subhelp.h
|
||||||
|
FILE_PATTERNS = *.h
|
||||||
|
RECURSIVE = YES
|
||||||
|
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
|
||||||
|
GENERATE_MAN = YES
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
MAN_LINKS = NO
|
||||||
|
|
31
csri/LICENSE
Normal file
31
csri/LICENSE
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
Copyright (c) 2007, David Lamparter
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* The name of the author may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
|
12
csri/Makefile.am
Normal file
12
csri/Makefile.am
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
EXTRA_DIST = csri.pc.in acinclude.m4
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = csri.pc
|
||||||
|
|
||||||
|
SUBDIRS = ac \
|
||||||
|
include \
|
||||||
|
subhelp \
|
||||||
|
lib \
|
||||||
|
backends \
|
||||||
|
frontends
|
3
csri/ac/Makefile.am
Normal file
3
csri/ac/Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
EXTRA_DIST = \
|
||||||
|
csri.sln \
|
||||||
|
subhelp.vcproj
|
20
csri/ac/csri.sln
Normal file
20
csri/ac/csri.sln
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "subhelp", "subhelp.vcproj", "{870552FE-7B73-41AB-A7D9-475440F4731C}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{870552FE-7B73-41AB-A7D9-475440F4731C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{870552FE-7B73-41AB-A7D9-475440F4731C}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{870552FE-7B73-41AB-A7D9-475440F4731C}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{870552FE-7B73-41AB-A7D9-475440F4731C}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
179
csri/ac/subhelp.vcproj
Normal file
179
csri/ac/subhelp.vcproj
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8,00"
|
||||||
|
Name="subhelp"
|
||||||
|
ProjectGUID="{870552FE-7B73-41AB-A7D9-475440F4731C}"
|
||||||
|
RootNamespace="subhelp"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\include"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="..\include"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Quelldateien"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\subhelp\win32\openfile.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\subhelp\logging.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Headerdateien"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\subhelp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Ressourcendateien"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
67
csri/acinclude.m4
Normal file
67
csri/acinclude.m4
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
dnl AC_CPP_PRAGMA_ONCE
|
||||||
|
dnl - check for #pragma once
|
||||||
|
AC_DEFUN([AC_CPP_PRAGMA_ONCE], [{
|
||||||
|
AC_MSG_CHECKING([[whether $CPP supports #pragma once]])
|
||||||
|
AC_PREPROC_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([[#pragma once]])],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE([HAVE_PRAGMA_ONCE], [1], [Preprocessor support for #pragma once])
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
|
}])
|
||||||
|
|
||||||
|
dnl AC_C_FLAG([-flag])
|
||||||
|
dnl - check for CFLAG support in CC
|
||||||
|
AC_DEFUN([AC_C_FLAG], [{
|
||||||
|
AC_LANG_PUSH(C)
|
||||||
|
ac_c_flag_save="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $1"
|
||||||
|
AC_MSG_CHECKING([[whether $CC supports $1]])
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([[]])],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
m4_if([$3], [], [], [
|
||||||
|
CFLAGS="$ac_c_flag_save"
|
||||||
|
$3
|
||||||
|
])
|
||||||
|
], [
|
||||||
|
CFLAGS="$ac_c_flag_save"
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
$2
|
||||||
|
])
|
||||||
|
AC_LANG_POP(C)
|
||||||
|
}])
|
||||||
|
|
||||||
|
dnl AC_C_FLAG([-flag])
|
||||||
|
dnl - check for CFLAG support in CC
|
||||||
|
AC_DEFUN([AC_GCC_VISIBILITY], [{
|
||||||
|
AC_MSG_CHECKING([[whether $CC supports GCC visibility]])
|
||||||
|
# always use Werror since visibility is sensitive
|
||||||
|
# doesn't work on anything other than gcc either way, so Werror is fine...
|
||||||
|
vis_type="$1"
|
||||||
|
save_cflags="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -fvisibility=$vis_type -Werror"
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_SOURCE([[
|
||||||
|
int a() __attribute__((visibility("default")));
|
||||||
|
int b() __attribute__((visibility("hidden")));
|
||||||
|
int c() __attribute__((visibility("internal")));
|
||||||
|
|
||||||
|
int a() { return 1; }
|
||||||
|
int b() { return 2; }
|
||||||
|
int c() { return 3; }
|
||||||
|
|
||||||
|
int main() { return a()+b()+c(); }
|
||||||
|
]])],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE([HAVE_GCC_VISIBILITY], [1], [Compiler support for GCC visibility attributes])
|
||||||
|
save_cflags="$save_cflags -fvisibility=$vis_type"
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT([no])]
|
||||||
|
)
|
||||||
|
CFLAGS="$save_cflags"
|
||||||
|
}])
|
||||||
|
|
4
csri/backends/Makefile.am
Normal file
4
csri/backends/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
if BUILD_LIBASS
|
||||||
|
LIBASS_DIR = libass
|
||||||
|
endif
|
||||||
|
SUBDIRS = $(LIBASS_DIR)
|
6
csri/backends/libass/Makefile.am
Normal file
6
csri/backends/libass/Makefile.am
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
csrilib_LTLIBRARIES = libass_csri.la
|
||||||
|
libass_csri_la_SOURCES = libass_csri.c
|
||||||
|
libass_csri_la_LDFLAGS = -avoid-version -no-undefined
|
||||||
|
libass_csri_la_LIBADD = ../../subhelp/libsubhelp_la-openfile.lo $(LIBASS_LIBS)
|
||||||
|
libass_csri_la_CFLAGS = -I$(top_srcdir)/include $(LIBASS_CFLAGS)
|
||||||
|
|
258
csri/backends/libass/libass_csri.c
Normal file
258
csri/backends/libass/libass_csri.c
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** libass csri wrapper.
|
||||||
|
* Indirectly based on code from aegisub,
|
||||||
|
* (c) 2006-2007, Rodrigo Braz Monteiro, Evgeniy Stepanov
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ass/ass.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define CSRIAPI __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_GCC_VISIBILITY
|
||||||
|
# define CSRIAPI __attribute__((visibility ("default")))
|
||||||
|
# else
|
||||||
|
# define CSRIAPI
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CSRI_OWN_HANDLES
|
||||||
|
typedef struct csri_libass_rend {
|
||||||
|
ass_library_t* ass_library;
|
||||||
|
} csri_rend;
|
||||||
|
|
||||||
|
typedef struct csri_asa_inst {
|
||||||
|
ass_renderer_t* ass_renderer;
|
||||||
|
ass_track_t* ass_track;
|
||||||
|
} csri_inst;
|
||||||
|
|
||||||
|
#include <csri/csri.h>
|
||||||
|
#include <csri/stream.h>
|
||||||
|
#include <subhelp.h>
|
||||||
|
|
||||||
|
static struct csri_libass_rend csri_libass = { NULL };
|
||||||
|
|
||||||
|
csri_inst *csri_open_file(csri_rend *renderer,
|
||||||
|
const char *filename, struct csri_openflag *flags)
|
||||||
|
{
|
||||||
|
return subhelp_open_file(renderer, csri_open_mem, filename, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_inst *csri_open_mem(csri_rend *renderer,
|
||||||
|
const void *data, size_t length, struct csri_openflag *flags)
|
||||||
|
{
|
||||||
|
csri_inst *rv;
|
||||||
|
if (renderer != &csri_libass)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rv = (csri_inst *)malloc(sizeof(csri_inst));
|
||||||
|
if (!rv)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rv->ass_renderer = ass_renderer_init(renderer->ass_library);
|
||||||
|
if (!rv->ass_renderer) {
|
||||||
|
free(rv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ass_set_font_scale(rv->ass_renderer, 1.);
|
||||||
|
ass_set_fonts(rv->ass_renderer, NULL, "Sans");
|
||||||
|
rv->ass_track = ass_read_memory(csri_libass.ass_library,
|
||||||
|
(void *)data, length, "UTF-8");
|
||||||
|
if (!rv->ass_track) {
|
||||||
|
ass_renderer_done(rv->ass_renderer);
|
||||||
|
free(rv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csri_close(csri_inst *inst)
|
||||||
|
{
|
||||||
|
ass_free_track(inst->ass_track);
|
||||||
|
ass_renderer_done(inst->ass_renderer);
|
||||||
|
free(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
int csri_request_fmt(csri_inst *inst, const struct csri_fmt *fmt)
|
||||||
|
{
|
||||||
|
if (!csri_is_rgb(fmt->pixfmt) || csri_has_alpha(fmt->pixfmt))
|
||||||
|
return -1;
|
||||||
|
ass_set_frame_size(inst->ass_renderer, fmt->width, fmt->height);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csri_render(csri_inst *inst, struct csri_frame *frame, double time)
|
||||||
|
{
|
||||||
|
ass_image_t *img = ass_render_frame(inst->ass_renderer,
|
||||||
|
inst->ass_track, (int)(time * 1000), NULL);
|
||||||
|
|
||||||
|
while (img) {
|
||||||
|
unsigned bpp, alpha = 256 - (img->color && 0xFF);
|
||||||
|
int src_d, dst_d;
|
||||||
|
unsigned char *src, *dst, *endy, *endx;
|
||||||
|
unsigned char c[3] = {
|
||||||
|
(img->color >> 8) & 0xFF, /* B */
|
||||||
|
(img->color >> 16) & 0xFF, /* G */
|
||||||
|
img->color >> 24 /* R */
|
||||||
|
};
|
||||||
|
if ((frame->pixfmt | 1) == CSRI_F__RGB
|
||||||
|
|| frame->pixfmt == CSRI_F_RGB) {
|
||||||
|
unsigned char tmp = c[2];
|
||||||
|
c[2] = c[0];
|
||||||
|
c[0] = tmp;
|
||||||
|
}
|
||||||
|
bpp = frame->pixfmt >= 0x200 ? 3 : 4;
|
||||||
|
|
||||||
|
dst = frame->planes[0]
|
||||||
|
+ img->dst_y * frame->strides[0]
|
||||||
|
+ img->dst_x * bpp;
|
||||||
|
if (frame->pixfmt & 1)
|
||||||
|
dst++;
|
||||||
|
src = img->bitmap;
|
||||||
|
|
||||||
|
src_d = img->stride - img->w;
|
||||||
|
dst_d = frame->strides[0] - img->w * bpp;
|
||||||
|
endy = src + img->h * img->stride;
|
||||||
|
|
||||||
|
while (src != endy) {
|
||||||
|
endx = src + img->w;
|
||||||
|
while (src != endx) {
|
||||||
|
/* src[x]: 0..255, alpha: 1..256 (see above)
|
||||||
|
* -> src[x]*alpha: 0<<8..255<<8
|
||||||
|
* -> need 1..256 for mult => +1
|
||||||
|
*/
|
||||||
|
unsigned s = ((*src++ * alpha) >> 8) + 1;
|
||||||
|
unsigned d = 257 - s;
|
||||||
|
/* c[0]: 0.255, s/d: 1..256 */
|
||||||
|
dst[0] = (s*c[0] + d*dst[0]) >> 8;
|
||||||
|
dst[1] = (s*c[1] + d*dst[1]) >> 8;
|
||||||
|
dst[2] = (s*c[2] + d*dst[2]) >> 8;
|
||||||
|
dst += bpp;
|
||||||
|
}
|
||||||
|
dst += dst_d;
|
||||||
|
src += src_d;
|
||||||
|
}
|
||||||
|
img = img->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static csri_inst *libass_init_stream(csri_rend *renderer,
|
||||||
|
const void *header, size_t headerlen,
|
||||||
|
struct csri_openflag *flags)
|
||||||
|
{
|
||||||
|
csri_inst *rv;
|
||||||
|
|
||||||
|
if (renderer != &csri_libass)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rv = (csri_inst *)malloc(sizeof(csri_inst));
|
||||||
|
if (!rv)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rv->ass_renderer = ass_renderer_init(renderer->ass_library);
|
||||||
|
if (!rv->ass_renderer) {
|
||||||
|
free(rv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ass_set_font_scale(rv->ass_renderer, 1.);
|
||||||
|
ass_set_fonts(rv->ass_renderer, NULL, "Sans");
|
||||||
|
rv->ass_track = ass_new_track(csri_libass.ass_library);
|
||||||
|
if (!rv->ass_track) {
|
||||||
|
ass_renderer_done(rv->ass_renderer);
|
||||||
|
free(rv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ass_process_codec_private(rv->ass_track, (void *)header, headerlen);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void libass_push_packet(csri_inst *inst,
|
||||||
|
const void *packet, size_t packetlen,
|
||||||
|
double pts_start, double pts_end)
|
||||||
|
{
|
||||||
|
ass_process_chunk(inst->ass_track, (void *)packet, packetlen,
|
||||||
|
(int)(pts_start * 1000), (int)((pts_end - pts_start) * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct csri_stream_ext streamext = {
|
||||||
|
libass_init_stream,
|
||||||
|
libass_push_packet,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
void *csri_query_ext(csri_rend *rend, csri_ext_id extname)
|
||||||
|
{
|
||||||
|
if (!rend)
|
||||||
|
return NULL;
|
||||||
|
if (!strcmp(extname, CSRI_EXT_STREAM_ASS))
|
||||||
|
return &streamext;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct csri_info csri_libass_info = {
|
||||||
|
"libass",
|
||||||
|
"0.9.x",
|
||||||
|
"libass (the MPlayer SSA/ASS renderer, 0.9.x API)",
|
||||||
|
"Evgeniy Stepanov",
|
||||||
|
"Copyright (c) 2006, 2007 by Evgeniy Stepanov"
|
||||||
|
};
|
||||||
|
|
||||||
|
struct csri_info *csri_renderer_info(csri_rend *rend)
|
||||||
|
{
|
||||||
|
return &csri_libass_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_byname(const char *name,
|
||||||
|
const char *specific)
|
||||||
|
{
|
||||||
|
if (strcmp(name, csri_libass_info.name))
|
||||||
|
return NULL;
|
||||||
|
if (specific && strcmp(specific, csri_libass_info.specific))
|
||||||
|
return NULL;
|
||||||
|
return &csri_libass;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_default()
|
||||||
|
{
|
||||||
|
csri_libass.ass_library = ass_library_init();
|
||||||
|
if (!csri_libass.ass_library)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ass_set_fonts_dir(csri_libass.ass_library, "");
|
||||||
|
ass_set_extract_fonts(csri_libass.ass_library, 0);
|
||||||
|
ass_set_style_overrides(csri_libass.ass_library, NULL);
|
||||||
|
return &csri_libass;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_next(csri_rend *prev)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
4
csri/bootstrap
Executable file
4
csri/bootstrap
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash -x
|
||||||
|
|
||||||
|
autoreconf -f -i -s
|
||||||
|
|
135
csri/configure.ac
Normal file
135
csri/configure.ac
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
AC_PREREQ(2.57)
|
||||||
|
AC_INIT(csri, 0.1.0)
|
||||||
|
AC_CONFIG_AUX_DIR(ac)
|
||||||
|
AM_INIT_AUTOMAKE
|
||||||
|
AC_CONFIG_HEADER([include/acconf.h])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_C_VOLATILE
|
||||||
|
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([png.h])
|
||||||
|
AC_CHECK_LIB([z], [inflate])
|
||||||
|
AC_CHECK_LIB([m], [pow])
|
||||||
|
AC_CHECK_LIB([png], [png_init_io])
|
||||||
|
|
||||||
|
AC_CPP_PRAGMA_ONCE
|
||||||
|
AC_C_FLAG([-Wall])
|
||||||
|
AC_C_FLAG([-Wextra],[AC_C_FLAG([-W])])
|
||||||
|
AC_C_FLAG([-Wno-unused-parameter])
|
||||||
|
AC_C_FLAG([-Winvalid-pch])
|
||||||
|
AC_C_FLAG([-pedantic])
|
||||||
|
AC_C_FLAG([-std=c99],[AC_C_FLAG([-c99])])
|
||||||
|
AC_ARG_ENABLE([werror],
|
||||||
|
AC_HELP_STRING([--enable-werror], [compile with -Werror (for developers)]),
|
||||||
|
[ if test "$enableval" == "yes"
|
||||||
|
then AC_C_FLAG([-Werror])
|
||||||
|
fi])
|
||||||
|
AC_GCC_VISIBILITY([internal])
|
||||||
|
|
||||||
|
AC_PATH_XTRA
|
||||||
|
platform=""
|
||||||
|
case $host_os in
|
||||||
|
mingw*) # LoadLibraryEx + GetProcAddress
|
||||||
|
platform="win32"
|
||||||
|
;;
|
||||||
|
*) AC_SEARCH_LIBS([dlopen], [dl], [], [
|
||||||
|
AC_MSG_FAILURE([dlopen not found - unsupported dynamic loader architecture / operating system])
|
||||||
|
])
|
||||||
|
esac
|
||||||
|
|
||||||
|
AM_CONDITIONAL([BUILD_MINGW], [test "$platform" == "win32" ])
|
||||||
|
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_HEADER_STDBOOL
|
||||||
|
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/time.h sys/wait.h sys/mman.h unistd.h libgen.h getopt.h])
|
||||||
|
AC_CHECK_FUNCS([getopt_long])
|
||||||
|
#
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
# Checks for library functions.
|
||||||
|
#AC_FUNC_FORK
|
||||||
|
#AC_PROG_GCC_TRADITIONAL
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
AC_FUNC_MEMCMP
|
||||||
|
AC_CHECK_FUNCS([memset strdup strerror strtoul])
|
||||||
|
|
||||||
|
AC_ARG_WITH([libass],[
|
||||||
|
AS_HELP_STRING([--with-libass],[build libass backend @<:@default=auto@:>@])
|
||||||
|
],[],[ with_libass=auto
|
||||||
|
])
|
||||||
|
|
||||||
|
libass=no
|
||||||
|
AS_IF([test "$with_libass" != no],[
|
||||||
|
ac_cflags_save="$CFLAGS"
|
||||||
|
ac_ldflags_save="$LDFLAGS"
|
||||||
|
|
||||||
|
if test "$with_libass" != auto -a "$with_libass" != yes
|
||||||
|
then LIBASS_CFLAGS="-I$with_libass/include"
|
||||||
|
LIBASS_LIBS="-L$with_libass/lib -lass"
|
||||||
|
else PKG_CHECK_MODULES([LIBASS], libass >= 0.9.1,[],[
|
||||||
|
AC_MSG_WARN([libass not found via pkg-config])
|
||||||
|
LIBASS_LIBS="-lass"
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
CFLAGS="$CFLAGS $LIBASS_CFLAGS"
|
||||||
|
LDFLAGS="$LDFLAGS $LIBASS_LIBS"
|
||||||
|
|
||||||
|
AC_CHECK_LIB([ass], [ass_library_init], [libass_lib="yes"])
|
||||||
|
AC_CHECK_HEADER([ass/ass.h], [libass_hdr="yes"])
|
||||||
|
|
||||||
|
if test "$libass_lib" == yes -a "$libass_hdr" == yes
|
||||||
|
then libass=yes
|
||||||
|
else if "$with_libass" != auto
|
||||||
|
then AC_MSG_FAILURE([libass requested but not found])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
CFLAGS="$ac_cflags_save"
|
||||||
|
LDFLAGS="$ac_ldflags_save"
|
||||||
|
])
|
||||||
|
AM_CONDITIONAL([BUILD_LIBASS], [test "$libass" == "yes" ])
|
||||||
|
AC_SUBST([LIBASS_CFLAGS])
|
||||||
|
AC_SUBST([LIBASS_LIBS])
|
||||||
|
|
||||||
|
csrilibdir="${libdir}/csri"
|
||||||
|
AC_SUBST([csrilibdir])
|
||||||
|
|
||||||
|
csri_path="${csrilibdir}:/usr/lib/csri:/usr/local/lib/csri:~/.csri/lib"
|
||||||
|
AC_ARG_WITH(csri-libpath,
|
||||||
|
AC_HELP_STRING([--with-csri-libpath=PATH1:PATH2],
|
||||||
|
[Look for CSRI renderers in the specified directories. Separate directory names with colons. Tildes are expanded at run-time. [[$csri_path]]]),
|
||||||
|
[
|
||||||
|
if test "$withval" != "yes" -a "$withval" != "" -a "$withval" != "no"
|
||||||
|
then csri_path="$withval"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
AC_SUBST([csri_path], ["$csri_path"])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([csri.pc])
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " using search path: ${csri_path}"
|
||||||
|
echo "building libass wrapper: ${libass}"
|
||||||
|
echo ""
|
||||||
|
AC_OUTPUT([
|
||||||
|
ac/Makefile
|
||||||
|
include/Makefile
|
||||||
|
subhelp/Makefile
|
||||||
|
lib/Makefile
|
||||||
|
frontends/Makefile
|
||||||
|
frontends/avisynth25/Makefile
|
||||||
|
frontends/cmdline/Makefile
|
||||||
|
backends/Makefile
|
||||||
|
backends/libass/Makefile
|
||||||
|
Makefile
|
||||||
|
])
|
||||||
|
|
10
csri/csri.pc.in
Normal file
10
csri/csri.pc.in
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: csri
|
||||||
|
Description: csri - common subtitle renderer interface
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Libs: -L${libdir} -lcsri
|
||||||
|
Cflags: -I${includedir}
|
328
csri/csri.vcproj
Normal file
328
csri/csri.vcproj
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8,00"
|
||||||
|
Name="csri"
|
||||||
|
ProjectGUID="{4294BC27-91AC-4642-B5E1-042288478C2A}"
|
||||||
|
RootNamespace="csri"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="1"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="../lib/csri_d.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
AdditionalOptions="/machine:x64"
|
||||||
|
OutputFile="../lib/csri_d_x64.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="../lib/csri.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
AdditionalOptions="/machine:x64"
|
||||||
|
OutputFile="../lib/csri_x64.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lib\win32\enumerate.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lib\list.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\subhelp\logging.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lib\wrap.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\csri\csri.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
327
csri/csri_2008.vcproj
Normal file
327
csri/csri_2008.vcproj
Normal file
|
@ -0,0 +1,327 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="csri_2008"
|
||||||
|
ProjectGUID="{4294BC27-91AC-4642-B5E1-042288478C2A}"
|
||||||
|
RootNamespace="csri"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="131072"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="1"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="../lib/csri_d_x64.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="../lib/csri_d_x64.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="../lib/csri.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="lib;lib/win32;include;../aegisub/win32"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
DisableSpecificWarnings="4996"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="../lib/csri_x64.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lib\win32\enumerate.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lib\list.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\subhelp\logging.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lib\wrap.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\csri\csri.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
4
csri/frontends/Makefile.am
Normal file
4
csri/frontends/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
SUBDIRS = \
|
||||||
|
avisynth25 \
|
||||||
|
cmdline
|
||||||
|
|
15
csri/frontends/avisynth25/Makefile.am
Normal file
15
csri/frontends/avisynth25/Makefile.am
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
if BUILD_MINGW
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir)/include
|
||||||
|
lib_LTLIBRARIES = csri_avs.la
|
||||||
|
csri_avs_la_SOURCES = avisynth.cpp
|
||||||
|
csri_avs_la_LIBADD = \
|
||||||
|
../../lib/libcsri_la-enumerate.lo \
|
||||||
|
../../lib/libcsri_la-list.lo \
|
||||||
|
../../lib/libcsri_la-wrap.lo \
|
||||||
|
../../subhelp/libsubhelp_la-logging.lo
|
||||||
|
csri_avs_la_LDFLAGS = -avoid-version -no-undefined -module
|
||||||
|
endif
|
||||||
|
|
||||||
|
noinst_HEADERS = avisynth.h
|
||||||
|
EXTRA_DIST = avisynth.cpp
|
155
csri/frontends/avisynth25/avisynth.cpp
Normal file
155
csri/frontends/avisynth25/avisynth.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2006 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "avisynth.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <csri/csri.h>
|
||||||
|
|
||||||
|
class CSRIAviSynth : public GenericVideoFilter {
|
||||||
|
csri_inst *inst;
|
||||||
|
double spf;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CSRIAviSynth(PClip _child, IScriptEnvironment *env, const char *file,
|
||||||
|
const char *rendname, const char *rendver);
|
||||||
|
~CSRIAviSynth();
|
||||||
|
|
||||||
|
enum csri_pixfmt GetPixfmt();
|
||||||
|
|
||||||
|
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *env);
|
||||||
|
|
||||||
|
static AVSValue __cdecl Create(AVSValue args, void* user_data,
|
||||||
|
IScriptEnvironment* env);
|
||||||
|
};
|
||||||
|
|
||||||
|
CSRIAviSynth::CSRIAviSynth(PClip _child, IScriptEnvironment *env,
|
||||||
|
const char *file, const char *rendname, const char *rendver)
|
||||||
|
: GenericVideoFilter(_child)
|
||||||
|
{
|
||||||
|
csri_rend *r = csri_renderer_byname(rendname, rendver);
|
||||||
|
if (!r) {
|
||||||
|
if (rendver)
|
||||||
|
env->ThrowError("Failed to load renderer \"%s\""
|
||||||
|
" version \"%s\"", rendname, rendver);
|
||||||
|
else if (rendname)
|
||||||
|
env->ThrowError("Failed to load renderer \"%s\"",
|
||||||
|
rendname);
|
||||||
|
else
|
||||||
|
env->ThrowError("Failed to load default renderer");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct csri_fmt fmt;
|
||||||
|
fmt.pixfmt = GetPixfmt();
|
||||||
|
if (fmt.pixfmt == -1)
|
||||||
|
env->ThrowError("Pixel format not supported by "
|
||||||
|
"AviSynth interface");
|
||||||
|
|
||||||
|
inst = csri_open_file(r, file, NULL);
|
||||||
|
if (!inst)
|
||||||
|
env->ThrowError("Failed to load \"%s\"", file);
|
||||||
|
|
||||||
|
fmt.width = vi.width;
|
||||||
|
fmt.height = vi.height;
|
||||||
|
if (csri_request_fmt(inst, &fmt)) {
|
||||||
|
csri_close(inst);
|
||||||
|
env->ThrowError("Selected pixel format or size not supported "
|
||||||
|
"by selected subtitle renderer", file);
|
||||||
|
}
|
||||||
|
spf = (double)vi.fps_denominator / (double)vi.fps_numerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSRIAviSynth::~CSRIAviSynth()
|
||||||
|
{
|
||||||
|
csri_close(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum csri_pixfmt CSRIAviSynth::GetPixfmt()
|
||||||
|
{
|
||||||
|
switch (vi.pixel_type) {
|
||||||
|
case VideoInfo::CS_BGR24: return CSRI_F_BGR;
|
||||||
|
case VideoInfo::CS_BGR32: return CSRI_F_BGR_;
|
||||||
|
case VideoInfo::CS_YUY2: return CSRI_F_YUY2;
|
||||||
|
case VideoInfo::CS_YV12: return CSRI_F_YV12;
|
||||||
|
}
|
||||||
|
return (enum csri_pixfmt)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVideoFrame __stdcall CSRIAviSynth::GetFrame(int n, IScriptEnvironment *env)
|
||||||
|
{
|
||||||
|
PVideoFrame avsframe = child->GetFrame(n, env);
|
||||||
|
struct csri_frame frame;
|
||||||
|
|
||||||
|
env->MakeWritable(&avsframe);
|
||||||
|
|
||||||
|
frame.pixfmt = GetPixfmt();
|
||||||
|
frame.planes[0] = avsframe->GetWritePtr();
|
||||||
|
frame.strides[0] = avsframe->GetPitch();
|
||||||
|
if (csri_is_yuv_planar(frame.pixfmt)) {
|
||||||
|
frame.planes[1] = avsframe->GetWritePtr(PLANAR_U);
|
||||||
|
frame.strides[1] = avsframe->GetPitch(PLANAR_U);
|
||||||
|
frame.planes[2] = avsframe->GetWritePtr(PLANAR_V);
|
||||||
|
frame.strides[2] = avsframe->GetPitch(PLANAR_V);
|
||||||
|
}
|
||||||
|
if (csri_is_rgb(frame.pixfmt)) {
|
||||||
|
frame.planes[0] += (vi.height - 1) * frame.strides[0];
|
||||||
|
frame.strides[0] = -frame.strides[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_render(inst, &frame, n * spf);
|
||||||
|
return avsframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVSValue __cdecl CSRIAviSynth::Create(AVSValue args, void* user_data,
|
||||||
|
IScriptEnvironment* env)
|
||||||
|
{
|
||||||
|
const char *rname = args.ArraySize() >= 2 ? args[2].AsString() : NULL,
|
||||||
|
*rver = args.ArraySize() >= 3 ? args[3].AsString() : NULL;
|
||||||
|
return new CSRIAviSynth(args[0].AsClip(), env, args[1].AsString(),
|
||||||
|
rname, rver);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
|
||||||
|
IScriptEnvironment* env)
|
||||||
|
{
|
||||||
|
static char avs_name_f[2048];
|
||||||
|
const char *avs_cmdname = (const char *)csri_query_ext(NULL,
|
||||||
|
"csri.avisynth25.command_name");
|
||||||
|
const char *avs_name = (const char *)csri_query_ext(NULL,
|
||||||
|
"csri.avisynth25.name");
|
||||||
|
|
||||||
|
if (!csri_renderer_default())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!avs_cmdname)
|
||||||
|
avs_cmdname = "CSRI";
|
||||||
|
if (!avs_name)
|
||||||
|
avs_name = "Common Subtitle Renderer Interface";
|
||||||
|
|
||||||
|
env->AddFunction(avs_cmdname, "cs", CSRIAviSynth::Create, 0);
|
||||||
|
env->AddFunction(avs_cmdname, "css", CSRIAviSynth::Create, 0);
|
||||||
|
env->AddFunction(avs_cmdname, "csss", CSRIAviSynth::Create, 0);
|
||||||
|
|
||||||
|
snprintf(avs_name_f, sizeof(avs_name_f),
|
||||||
|
"%s [AviSynth 2.5 front-end]", avs_name);
|
||||||
|
return avs_name_f;
|
||||||
|
}
|
||||||
|
|
754
csri/frontends/avisynth25/avisynth.h
Normal file
754
csri/frontends/avisynth25/avisynth.h
Normal file
|
@ -0,0 +1,754 @@
|
||||||
|
// Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
|
||||||
|
// http://www.avisynth.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., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||||
|
// http://www.gnu.org/copyleft/gpl.html .
|
||||||
|
//
|
||||||
|
// Linking Avisynth statically or dynamically with other modules is making a
|
||||||
|
// combined work based on Avisynth. Thus, the terms and conditions of the GNU
|
||||||
|
// General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
// As a special exception, the copyright holders of Avisynth give you
|
||||||
|
// permission to link Avisynth with independent modules that communicate with
|
||||||
|
// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
|
||||||
|
// terms of these independent modules, and to copy and distribute the
|
||||||
|
// resulting combined work under terms of your choice, provided that
|
||||||
|
// every copy of the combined work is accompanied by a complete copy of
|
||||||
|
// the source code of Avisynth (the version of Avisynth used to produce the
|
||||||
|
// combined work), being distributed under the terms of the GNU General
|
||||||
|
// Public License plus this exception. An independent module is a module
|
||||||
|
// which is not derived from or based on Avisynth, such as 3rd-party filters,
|
||||||
|
// import and export plugins, or graphical user interfaces.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __AVISYNTH_H__
|
||||||
|
#define __AVISYNTH_H__
|
||||||
|
|
||||||
|
enum { AVISYNTH_INTERFACE_VERSION = 3 };
|
||||||
|
|
||||||
|
|
||||||
|
/* Define all types necessary for interfacing with avisynth.dll
|
||||||
|
Moved from internal.h */
|
||||||
|
|
||||||
|
// Win32 API macros, notably the types BYTE, DWORD, ULONG, etc.
|
||||||
|
#include <windef.h>
|
||||||
|
|
||||||
|
// COM interface macros
|
||||||
|
#include <objbase.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Raster types used by VirtualDub & Avisynth
|
||||||
|
#define in64 (__int64)(unsigned short)
|
||||||
|
typedef unsigned long Pixel; // this will break on 64-bit machines!
|
||||||
|
typedef unsigned long Pixel32;
|
||||||
|
typedef unsigned char Pixel8;
|
||||||
|
typedef long PixCoord;
|
||||||
|
typedef long PixDim;
|
||||||
|
typedef long PixOffset;
|
||||||
|
|
||||||
|
|
||||||
|
/* Compiler-specific crap */
|
||||||
|
|
||||||
|
// Tell MSVC to stop precompiling here
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set up debugging macros for MS compilers; for others, step down to the
|
||||||
|
// standard <assert.h> interface
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#else
|
||||||
|
#define _RPT0(a,b) ((void)0)
|
||||||
|
#define _RPT1(a,b,c) ((void)0)
|
||||||
|
#define _RPT2(a,b,c,d) ((void)0)
|
||||||
|
#define _RPT3(a,b,c,d,e) ((void)0)
|
||||||
|
#define _RPT4(a,b,c,d,e,f) ((void)0)
|
||||||
|
|
||||||
|
#define _ASSERTE(x) assert(x)
|
||||||
|
#define _ASSERT(x) assert(x)
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// I had problems with Premiere wanting 1-byte alignment for its structures,
|
||||||
|
// so I now set the Avisynth struct alignment explicitly here.
|
||||||
|
#pragma pack(push,8)
|
||||||
|
|
||||||
|
#define FRAME_ALIGN 16
|
||||||
|
// Default frame alignment is 16 bytes, to help P4, when using SSE2
|
||||||
|
|
||||||
|
// The VideoInfo struct holds global information about a clip (i.e.
|
||||||
|
// information that does not depend on the frame number). The GetVideoInfo
|
||||||
|
// method in IClip returns this struct.
|
||||||
|
|
||||||
|
// Audio Sample information
|
||||||
|
typedef float SFLOAT;
|
||||||
|
|
||||||
|
enum {SAMPLE_INT8 = 1<<0,
|
||||||
|
SAMPLE_INT16 = 1<<1,
|
||||||
|
SAMPLE_INT24 = 1<<2, // Int24 is a very stupid thing to code, but it's supported by some hardware.
|
||||||
|
SAMPLE_INT32 = 1<<3,
|
||||||
|
SAMPLE_FLOAT = 1<<4};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PLANAR_Y=1<<0,
|
||||||
|
PLANAR_U=1<<1,
|
||||||
|
PLANAR_V=1<<2,
|
||||||
|
PLANAR_ALIGNED=1<<3,
|
||||||
|
PLANAR_Y_ALIGNED=PLANAR_Y|PLANAR_ALIGNED,
|
||||||
|
PLANAR_U_ALIGNED=PLANAR_U|PLANAR_ALIGNED,
|
||||||
|
PLANAR_V_ALIGNED=PLANAR_V|PLANAR_ALIGNED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VideoInfo {
|
||||||
|
int width, height; // width=0 means no video
|
||||||
|
unsigned fps_numerator, fps_denominator;
|
||||||
|
int num_frames;
|
||||||
|
// This is more extensible than previous versions. More properties can be added seeminglesly.
|
||||||
|
|
||||||
|
// Colorspace properties.
|
||||||
|
enum {
|
||||||
|
CS_BGR = 1<<28,
|
||||||
|
CS_YUV = 1<<29,
|
||||||
|
CS_INTERLEAVED = 1<<30,
|
||||||
|
CS_PLANAR = 1<<31
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specific colorformats
|
||||||
|
enum { CS_UNKNOWN = 0,
|
||||||
|
CS_BGR24 = 1<<0 | CS_BGR | CS_INTERLEAVED,
|
||||||
|
CS_BGR32 = 1<<1 | CS_BGR | CS_INTERLEAVED,
|
||||||
|
CS_YUY2 = 1<<2 | CS_YUV | CS_INTERLEAVED,
|
||||||
|
CS_YV12 = 1<<3 | CS_YUV | CS_PLANAR, // y-v-u, planar
|
||||||
|
CS_I420 = 1<<4 | CS_YUV | CS_PLANAR, // y-u-v, planar
|
||||||
|
CS_IYUV = 1<<4 | CS_YUV | CS_PLANAR // same as above
|
||||||
|
};
|
||||||
|
int pixel_type; // changed to int as of 2.5
|
||||||
|
|
||||||
|
|
||||||
|
int audio_samples_per_second; // 0 means no audio
|
||||||
|
int sample_type; // as of 2.5
|
||||||
|
__int64 num_audio_samples; // changed as of 2.5
|
||||||
|
int nchannels; // as of 2.5
|
||||||
|
|
||||||
|
// Imagetype properties
|
||||||
|
|
||||||
|
int image_type;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IT_BFF = 1<<0,
|
||||||
|
IT_TFF = 1<<1,
|
||||||
|
IT_FIELDBASED = 1<<2
|
||||||
|
};
|
||||||
|
|
||||||
|
// useful functions of the above
|
||||||
|
bool HasVideo() const { return (width!=0); }
|
||||||
|
bool HasAudio() const { return (audio_samples_per_second!=0); }
|
||||||
|
bool IsRGB() const { return !!(pixel_type&CS_BGR); }
|
||||||
|
bool IsRGB24() const { return (pixel_type&CS_BGR24)==CS_BGR24; } // Clear out additional properties
|
||||||
|
bool IsRGB32() const { return (pixel_type & CS_BGR32) == CS_BGR32 ; }
|
||||||
|
bool IsYUV() const { return !!(pixel_type&CS_YUV ); }
|
||||||
|
bool IsYUY2() const { return (pixel_type & CS_YUY2) == CS_YUY2; }
|
||||||
|
bool IsYV12() const { return ((pixel_type & CS_YV12) == CS_YV12)||((pixel_type & CS_I420) == CS_I420); }
|
||||||
|
bool IsColorSpace(int c_space) const { return ((pixel_type & c_space) == c_space); }
|
||||||
|
bool Is(int property) const { return ((pixel_type & property)==property ); }
|
||||||
|
bool IsPlanar() const { return !!(pixel_type & CS_PLANAR); }
|
||||||
|
bool IsFieldBased() const { return !!(image_type & IT_FIELDBASED); }
|
||||||
|
bool IsParityKnown() const { return ((image_type & IT_FIELDBASED)&&(image_type & (IT_BFF|IT_TFF))); }
|
||||||
|
bool IsBFF() const { return !!(image_type & IT_BFF); }
|
||||||
|
bool IsTFF() const { return !!(image_type & IT_TFF); }
|
||||||
|
|
||||||
|
bool IsVPlaneFirst() const {return ((pixel_type & CS_YV12) == CS_YV12); } // Don't use this
|
||||||
|
int BytesFromPixels(int pixels) const { return pixels * (BitsPerPixel()>>3); } // Will not work on planar images, but will return only luma planes
|
||||||
|
int RowSize() const { return BytesFromPixels(width); } // Also only returns first plane on planar images
|
||||||
|
int BMPSize() const { if (IsPlanar()) {int p = height * ((RowSize()+3) & ~3); p+=p>>1; return p; } return height * ((RowSize()+3) & ~3); }
|
||||||
|
__int64 AudioSamplesFromFrames(__int64 frames) const { return (fps_numerator && HasVideo()) ? ((__int64)(frames) * audio_samples_per_second * fps_denominator / fps_numerator) : 0; }
|
||||||
|
int FramesFromAudioSamples(__int64 samples) const { return (fps_denominator && HasAudio()) ? (int)((samples * (__int64)fps_numerator)/((__int64)fps_denominator * (__int64)audio_samples_per_second)) : 0; }
|
||||||
|
__int64 AudioSamplesFromBytes(__int64 bytes) const { return HasAudio() ? bytes / BytesPerAudioSample() : 0; }
|
||||||
|
__int64 BytesFromAudioSamples(__int64 samples) const { return samples * BytesPerAudioSample(); }
|
||||||
|
int AudioChannels() const { return nchannels; }
|
||||||
|
int SampleType() const{ return sample_type;}
|
||||||
|
bool IsSampleType(int testtype) const{ return !!(sample_type&testtype);}
|
||||||
|
int SamplesPerSecond() const { return audio_samples_per_second; }
|
||||||
|
int BytesPerAudioSample() const { return nchannels*BytesPerChannelSample();}
|
||||||
|
void SetFieldBased(bool isfieldbased) { if (isfieldbased) image_type|=IT_FIELDBASED; else image_type&=~IT_FIELDBASED; }
|
||||||
|
void Set(int property) { image_type|=property; }
|
||||||
|
void Clear(int property) { image_type&=~property; }
|
||||||
|
|
||||||
|
int BitsPerPixel() const {
|
||||||
|
switch (pixel_type) {
|
||||||
|
case CS_BGR24:
|
||||||
|
return 24;
|
||||||
|
case CS_BGR32:
|
||||||
|
return 32;
|
||||||
|
case CS_YUY2:
|
||||||
|
return 16;
|
||||||
|
case CS_YV12:
|
||||||
|
case CS_I420:
|
||||||
|
return 12;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int BytesPerChannelSample() const {
|
||||||
|
switch (sample_type) {
|
||||||
|
case SAMPLE_INT8:
|
||||||
|
return sizeof(signed char);
|
||||||
|
case SAMPLE_INT16:
|
||||||
|
return sizeof(signed short);
|
||||||
|
case SAMPLE_INT24:
|
||||||
|
return 3;
|
||||||
|
case SAMPLE_INT32:
|
||||||
|
return sizeof(signed int);
|
||||||
|
case SAMPLE_FLOAT:
|
||||||
|
return sizeof(SFLOAT);
|
||||||
|
default:
|
||||||
|
_ASSERTE("Sample type not recognized!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// useful mutator
|
||||||
|
void SetFPS(unsigned numerator, unsigned denominator) {
|
||||||
|
if ((numerator == 0) || (denominator == 0)) {
|
||||||
|
fps_numerator = 0;
|
||||||
|
fps_denominator = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsigned x=numerator, y=denominator;
|
||||||
|
while (y) { // find gcd
|
||||||
|
unsigned t = x%y; x = y; y = t;
|
||||||
|
}
|
||||||
|
fps_numerator = numerator/x;
|
||||||
|
fps_denominator = denominator/x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range protected multiply-divide of FPS
|
||||||
|
void MulDivFPS(unsigned multiplier, unsigned divisor) {
|
||||||
|
unsigned __int64 numerator = UInt32x32To64(fps_numerator, multiplier);
|
||||||
|
unsigned __int64 denominator = UInt32x32To64(fps_denominator, divisor);
|
||||||
|
|
||||||
|
unsigned __int64 x=numerator, y=denominator;
|
||||||
|
while (y) { // find gcd
|
||||||
|
unsigned __int64 t = x%y; x = y; y = t;
|
||||||
|
}
|
||||||
|
numerator /= x; // normalize
|
||||||
|
denominator /= x;
|
||||||
|
|
||||||
|
unsigned __int64 temp = numerator | denominator; // Just looking top bit
|
||||||
|
unsigned u = 0;
|
||||||
|
#ifdef __GNUC__
|
||||||
|
while (temp & 0xffffffff80000000LL) { // or perhaps > 16777216*2
|
||||||
|
#else
|
||||||
|
while (temp & 0xffffffff80000000) { // or perhaps > 16777216*2
|
||||||
|
#endif
|
||||||
|
temp = Int64ShrlMod32(temp, 1);
|
||||||
|
u++;
|
||||||
|
}
|
||||||
|
if (u) { // Scale to fit
|
||||||
|
const unsigned round = 1 << (u-1);
|
||||||
|
SetFPS( (unsigned)Int64ShrlMod32(numerator + round, u),
|
||||||
|
(unsigned)Int64ShrlMod32(denominator + round, u) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fps_numerator = (unsigned)numerator;
|
||||||
|
fps_denominator = (unsigned)denominator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for same colorspace
|
||||||
|
bool IsSameColorspace(const VideoInfo& vi) const {
|
||||||
|
if (vi.pixel_type == pixel_type) return TRUE;
|
||||||
|
if (IsYV12() && vi.IsYV12()) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// VideoFrameBuffer holds information about a memory block which is used
|
||||||
|
// for video data. For efficiency, instances of this class are not deleted
|
||||||
|
// when the refcount reaches zero; instead they're stored in a linked list
|
||||||
|
// to be reused. The instances are deleted when the corresponding AVS
|
||||||
|
// file is closed.
|
||||||
|
|
||||||
|
class VideoFrameBuffer {
|
||||||
|
BYTE* const data;
|
||||||
|
const int data_size;
|
||||||
|
// sequence_number is incremented every time the buffer is changed, so
|
||||||
|
// that stale views can tell they're no longer valid.
|
||||||
|
long sequence_number;
|
||||||
|
|
||||||
|
friend class VideoFrame;
|
||||||
|
friend class Cache;
|
||||||
|
friend class ScriptEnvironment;
|
||||||
|
long refcount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VideoFrameBuffer(int size);
|
||||||
|
VideoFrameBuffer();
|
||||||
|
~VideoFrameBuffer();
|
||||||
|
|
||||||
|
const BYTE* GetReadPtr() const { return data; }
|
||||||
|
BYTE* GetWritePtr() { ++sequence_number; return data; }
|
||||||
|
int GetDataSize() { return data_size; }
|
||||||
|
int GetSequenceNumber() { return sequence_number; }
|
||||||
|
int GetRefcount() { return refcount; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class IClip;
|
||||||
|
class PClip;
|
||||||
|
class PVideoFrame;
|
||||||
|
class IScriptEnvironment;
|
||||||
|
class AVSValue;
|
||||||
|
|
||||||
|
|
||||||
|
// VideoFrame holds a "window" into a VideoFrameBuffer. Operator new
|
||||||
|
// is overloaded to recycle class instances.
|
||||||
|
|
||||||
|
class VideoFrame {
|
||||||
|
int refcount;
|
||||||
|
VideoFrameBuffer* const vfb;
|
||||||
|
const int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture.
|
||||||
|
|
||||||
|
friend class PVideoFrame;
|
||||||
|
void AddRef() { InterlockedIncrement((long *)&refcount); }
|
||||||
|
void Release() { if (refcount==1) InterlockedDecrement(&vfb->refcount); InterlockedDecrement((long *)&refcount); }
|
||||||
|
|
||||||
|
friend class ScriptEnvironment;
|
||||||
|
friend class Cache;
|
||||||
|
|
||||||
|
VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height);
|
||||||
|
VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV);
|
||||||
|
|
||||||
|
void* operator new(size_t size);
|
||||||
|
// TESTME: OFFSET U/V may be switched to what could be expected from AVI standard!
|
||||||
|
public:
|
||||||
|
int GetPitch() const { return pitch; }
|
||||||
|
int GetPitch(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: return pitchUV;} return pitch; }
|
||||||
|
int GetRowSize() const { return row_size; }
|
||||||
|
int GetRowSize(int plane) const {
|
||||||
|
switch (plane) {
|
||||||
|
case PLANAR_U: case PLANAR_V: if (pitchUV) return row_size>>1; else return 0;
|
||||||
|
case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED:
|
||||||
|
if (pitchUV) {
|
||||||
|
int r = ((row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) )>>1; // Aligned rowsize
|
||||||
|
if (r<=pitchUV)
|
||||||
|
return r;
|
||||||
|
return row_size>>1;
|
||||||
|
} else return 0;
|
||||||
|
case PLANAR_Y_ALIGNED:
|
||||||
|
int r = (row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize
|
||||||
|
if (r<=pitch)
|
||||||
|
return r;
|
||||||
|
return row_size;
|
||||||
|
}
|
||||||
|
return row_size; }
|
||||||
|
int GetHeight() const { return height; }
|
||||||
|
int GetHeight(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: if (pitchUV) return height>>1; return 0;} return height; }
|
||||||
|
|
||||||
|
// generally you shouldn't use these three
|
||||||
|
VideoFrameBuffer* GetFrameBuffer() const { return vfb; }
|
||||||
|
int GetOffset() const { return offset; }
|
||||||
|
int GetOffset(int plane) const { switch (plane) {case PLANAR_U: return offsetU;case PLANAR_V: return offsetV;default: return offset;}; }
|
||||||
|
|
||||||
|
// in plugins use env->SubFrame()
|
||||||
|
VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const;
|
||||||
|
VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV) const;
|
||||||
|
|
||||||
|
|
||||||
|
const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; }
|
||||||
|
const BYTE* GetReadPtr(int plane) const { return vfb->GetReadPtr() + GetOffset(plane); }
|
||||||
|
|
||||||
|
bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); }
|
||||||
|
|
||||||
|
BYTE* GetWritePtr() const {
|
||||||
|
if (vfb->GetRefcount()>1) {
|
||||||
|
_ASSERT(FALSE);
|
||||||
|
//throw AvisynthError("Internal Error - refcount was more than one!");
|
||||||
|
}
|
||||||
|
return IsWritable() ? (vfb->GetWritePtr() + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE* GetWritePtr(int plane) const {
|
||||||
|
if (plane==PLANAR_Y) {
|
||||||
|
if (vfb->GetRefcount()>1) {
|
||||||
|
_ASSERT(FALSE);
|
||||||
|
// throw AvisynthError("Internal Error - refcount was more than one!");
|
||||||
|
}
|
||||||
|
return IsWritable() ? vfb->GetWritePtr() + GetOffset(plane) : 0;
|
||||||
|
}
|
||||||
|
return vfb->data + GetOffset(plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
~VideoFrame() { InterlockedDecrement(&vfb->refcount); }
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CACHE_NOTHING=0,
|
||||||
|
CACHE_RANGE=1,
|
||||||
|
CACHE_ALL=2,
|
||||||
|
CACHE_AUDIO=3,
|
||||||
|
CACHE_AUDIO_NONE=4
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base class for all filters.
|
||||||
|
class IClip {
|
||||||
|
friend class PClip;
|
||||||
|
friend class AVSValue;
|
||||||
|
int refcnt;
|
||||||
|
void AddRef() { InterlockedIncrement((long *)&refcnt); }
|
||||||
|
void Release() { InterlockedDecrement((long *)&refcnt); if (!refcnt) delete this; }
|
||||||
|
public:
|
||||||
|
IClip() : refcnt(0) {}
|
||||||
|
|
||||||
|
virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; }
|
||||||
|
|
||||||
|
virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0;
|
||||||
|
virtual bool __stdcall GetParity(int n) = 0; // return field parity if field_based, else parity of first field in frame
|
||||||
|
virtual void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) = 0; // start and count are in samples
|
||||||
|
virtual void __stdcall SetCacheHints(int cachehints,int frame_range) = 0 ; // We do not pass cache requests upwards, only to the next filter.
|
||||||
|
virtual const VideoInfo& __stdcall GetVideoInfo() = 0;
|
||||||
|
virtual __stdcall ~IClip() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// smart pointer to IClip
|
||||||
|
class PClip {
|
||||||
|
|
||||||
|
IClip* p;
|
||||||
|
|
||||||
|
IClip* GetPointerWithAddRef() const { if (p) p->AddRef(); return p; }
|
||||||
|
friend class AVSValue;
|
||||||
|
friend class VideoFrame;
|
||||||
|
|
||||||
|
void Init(IClip* x) {
|
||||||
|
if (x) x->AddRef();
|
||||||
|
p=x;
|
||||||
|
}
|
||||||
|
void Set(IClip* x) {
|
||||||
|
if (x) x->AddRef();
|
||||||
|
if (p) p->Release();
|
||||||
|
p=x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PClip() { p = 0; }
|
||||||
|
PClip(const PClip& x) { Init(x.p); }
|
||||||
|
PClip(IClip* x) { Init(x); }
|
||||||
|
void operator=(IClip* x) { Set(x); }
|
||||||
|
void operator=(const PClip& x) { Set(x.p); }
|
||||||
|
|
||||||
|
IClip* operator->() const { return p; }
|
||||||
|
|
||||||
|
// useful in conditional expressions
|
||||||
|
operator void*() const { return p; }
|
||||||
|
bool operator!() const { return !p; }
|
||||||
|
|
||||||
|
~PClip() { if (p) p->Release(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// smart pointer to VideoFrame
|
||||||
|
class PVideoFrame {
|
||||||
|
|
||||||
|
VideoFrame* p;
|
||||||
|
|
||||||
|
void Init(VideoFrame* x) {
|
||||||
|
if (x) x->AddRef();
|
||||||
|
p=x;
|
||||||
|
}
|
||||||
|
void Set(VideoFrame* x) {
|
||||||
|
if (x) x->AddRef();
|
||||||
|
if (p) p->Release();
|
||||||
|
p=x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PVideoFrame() { p = 0; }
|
||||||
|
PVideoFrame(const PVideoFrame& x) { Init(x.p); }
|
||||||
|
PVideoFrame(VideoFrame* x) { Init(x); }
|
||||||
|
void operator=(VideoFrame* x) { Set(x); }
|
||||||
|
void operator=(const PVideoFrame& x) { Set(x.p); }
|
||||||
|
|
||||||
|
VideoFrame* operator->() const { return p; }
|
||||||
|
|
||||||
|
// for conditional expressions
|
||||||
|
operator void*() const { return p; }
|
||||||
|
bool operator!() const { return !p; }
|
||||||
|
|
||||||
|
~PVideoFrame() { if (p) p->Release();}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AVSValue {
|
||||||
|
public:
|
||||||
|
|
||||||
|
AVSValue() { type = 'v'; }
|
||||||
|
AVSValue(IClip* c) { type = 'c'; clip = c; if (c) c->AddRef(); }
|
||||||
|
AVSValue(const PClip& c) { type = 'c'; clip = c.GetPointerWithAddRef(); }
|
||||||
|
AVSValue(bool b) { type = 'b'; boolean = b; }
|
||||||
|
AVSValue(int i) { type = 'i'; integer = i; }
|
||||||
|
// AVSValue(__int64 l) { type = 'l'; longlong = l; }
|
||||||
|
AVSValue(float f) { type = 'f'; floating_pt = f; }
|
||||||
|
AVSValue(double f) { type = 'f'; floating_pt = float(f); }
|
||||||
|
AVSValue(const char* s) { type = 's'; string = s; }
|
||||||
|
AVSValue(const AVSValue* a, int size) { type = 'a'; array = a; array_size = size; }
|
||||||
|
AVSValue(const AVSValue& v) { Assign(&v, true); }
|
||||||
|
|
||||||
|
~AVSValue() { if (IsClip() && clip) clip->Release(); }
|
||||||
|
AVSValue& operator=(const AVSValue& v) { Assign(&v, false); return *this; }
|
||||||
|
|
||||||
|
// Note that we transparently allow 'int' to be treated as 'float'.
|
||||||
|
// There are no int<->bool conversions, though.
|
||||||
|
|
||||||
|
bool Defined() const { return type != 'v'; }
|
||||||
|
bool IsClip() const { return type == 'c'; }
|
||||||
|
bool IsBool() const { return type == 'b'; }
|
||||||
|
bool IsInt() const { return type == 'i'; }
|
||||||
|
// bool IsLong() const { return (type == 'l'|| type == 'i'); }
|
||||||
|
bool IsFloat() const { return type == 'f' || type == 'i'; }
|
||||||
|
bool IsString() const { return type == 's'; }
|
||||||
|
bool IsArray() const { return type == 'a'; }
|
||||||
|
|
||||||
|
PClip AsClip() const { _ASSERTE(IsClip()); return IsClip()?clip:0; }
|
||||||
|
bool AsBool() const { _ASSERTE(IsBool()); return boolean; }
|
||||||
|
int AsInt() const { _ASSERTE(IsInt()); return integer; }
|
||||||
|
// int AsLong() const { _ASSERTE(IsLong()); return longlong; }
|
||||||
|
const char* AsString() const { _ASSERTE(IsString()); return IsString()?string:0; }
|
||||||
|
double AsFloat() const { _ASSERTE(IsFloat()); return IsInt()?integer:floating_pt; }
|
||||||
|
|
||||||
|
bool AsBool(bool def) const { _ASSERTE(IsBool()||!Defined()); return IsBool() ? boolean : def; }
|
||||||
|
int AsInt(int def) const { _ASSERTE(IsInt()||!Defined()); return IsInt() ? integer : def; }
|
||||||
|
double AsFloat(double def) const { _ASSERTE(IsFloat()||!Defined()); return IsInt() ? integer : type=='f' ? floating_pt : def; }
|
||||||
|
const char* AsString(const char* def) const { _ASSERTE(IsString()||!Defined()); return IsString() ? string : def; }
|
||||||
|
|
||||||
|
int ArraySize() const { _ASSERTE(IsArray()); return IsArray()?array_size:1; }
|
||||||
|
|
||||||
|
const AVSValue& operator[](int index) const {
|
||||||
|
_ASSERTE(IsArray() && index>=0 && index<array_size);
|
||||||
|
return (IsArray() && index>=0 && index<array_size) ? array[index] : *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
|
||||||
|
short array_size;
|
||||||
|
union {
|
||||||
|
IClip* clip;
|
||||||
|
bool boolean;
|
||||||
|
int integer;
|
||||||
|
float floating_pt;
|
||||||
|
const char* string;
|
||||||
|
const AVSValue* array;
|
||||||
|
// __int64 longlong;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Assign(const AVSValue* src, bool init) {
|
||||||
|
if (src->IsClip() && src->clip)
|
||||||
|
src->clip->AddRef();
|
||||||
|
if (!init && IsClip() && clip)
|
||||||
|
clip->Release();
|
||||||
|
// make sure this copies the whole struct!
|
||||||
|
((__int32*)this)[0] = ((__int32*)src)[0];
|
||||||
|
((__int32*)this)[1] = ((__int32*)src)[1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// instantiable null filter
|
||||||
|
class GenericVideoFilter : public IClip {
|
||||||
|
protected:
|
||||||
|
PClip child;
|
||||||
|
VideoInfo vi;
|
||||||
|
public:
|
||||||
|
GenericVideoFilter(PClip _child) : child(_child) { vi = child->GetVideoInfo(); }
|
||||||
|
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) { return child->GetFrame(n, env); }
|
||||||
|
void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) { child->GetAudio(buf, start, count, env); }
|
||||||
|
const VideoInfo& __stdcall GetVideoInfo() { return vi; }
|
||||||
|
bool __stdcall GetParity(int n) { return child->GetParity(n); }
|
||||||
|
void __stdcall SetCacheHints(int cachehints,int frame_range) { } ; // We do not pass cache requests upwards, only to the next filter.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AvisynthError /* exception */ {
|
||||||
|
public:
|
||||||
|
const char* const msg;
|
||||||
|
AvisynthError(const char* _msg) : msg(_msg) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper classes useful to plugin authors */
|
||||||
|
|
||||||
|
class AlignPlanar : public GenericVideoFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AlignPlanar(PClip _clip);
|
||||||
|
static PClip Create(PClip clip);
|
||||||
|
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FillBorder : public GenericVideoFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FillBorder(PClip _clip);
|
||||||
|
static PClip Create(PClip clip);
|
||||||
|
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ConvertAudio : public GenericVideoFilter
|
||||||
|
/**
|
||||||
|
* Helper class to convert audio to any format
|
||||||
|
**/
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConvertAudio(PClip _clip, int prefered_format);
|
||||||
|
void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env);
|
||||||
|
void __stdcall SetCacheHints(int cachehints,int frame_range); // We do pass cache requests upwards, to the cache!
|
||||||
|
|
||||||
|
static PClip Create(PClip clip, int sample_type, int prefered_type);
|
||||||
|
static AVSValue __cdecl Create_float(AVSValue args, void*, IScriptEnvironment*);
|
||||||
|
static AVSValue __cdecl Create_32bit(AVSValue args, void*, IScriptEnvironment*);
|
||||||
|
static AVSValue __cdecl Create_24bit(AVSValue args, void*, IScriptEnvironment*);
|
||||||
|
static AVSValue __cdecl Create_16bit(AVSValue args, void*, IScriptEnvironment*);
|
||||||
|
static AVSValue __cdecl Create_8bit(AVSValue args, void*, IScriptEnvironment*);
|
||||||
|
virtual ~ConvertAudio();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void convertToFloat(char* inbuf, float* outbuf, char sample_type, int count);
|
||||||
|
void convertToFloat_3DN(char* inbuf, float* outbuf, char sample_type, int count);
|
||||||
|
void convertToFloat_SSE(char* inbuf, float* outbuf, char sample_type, int count);
|
||||||
|
void convertToFloat_SSE2(char* inbuf, float* outbuf, char sample_type, int count);
|
||||||
|
void convertFromFloat(float* inbuf, void* outbuf, char sample_type, int count);
|
||||||
|
void convertFromFloat_3DN(float* inbuf, void* outbuf, char sample_type, int count);
|
||||||
|
void convertFromFloat_SSE(float* inbuf, void* outbuf, char sample_type, int count);
|
||||||
|
void convertFromFloat_SSE2(float* inbuf, void* outbuf, char sample_type, int count);
|
||||||
|
|
||||||
|
__inline int Saturate_int8(float n);
|
||||||
|
__inline short Saturate_int16(float n);
|
||||||
|
__inline int Saturate_int24(float n);
|
||||||
|
__inline int Saturate_int32(float n);
|
||||||
|
|
||||||
|
char src_format;
|
||||||
|
char dst_format;
|
||||||
|
int src_bps;
|
||||||
|
char *tempbuffer;
|
||||||
|
SFLOAT *floatbuffer;
|
||||||
|
int tempbuffer_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// For GetCPUFlags. These are backwards-compatible with those in VirtualDub.
|
||||||
|
enum {
|
||||||
|
/* slowest CPU to support extension */
|
||||||
|
CPUF_FORCE = 0x01, // N/A
|
||||||
|
CPUF_FPU = 0x02, // 386/486DX
|
||||||
|
CPUF_MMX = 0x04, // P55C, K6, PII
|
||||||
|
CPUF_INTEGER_SSE = 0x08, // PIII, Athlon
|
||||||
|
CPUF_SSE = 0x10, // PIII, Athlon XP/MP
|
||||||
|
CPUF_SSE2 = 0x20, // PIV, Hammer
|
||||||
|
CPUF_3DNOW = 0x40, // K6-2
|
||||||
|
CPUF_3DNOW_EXT = 0x80, // Athlon
|
||||||
|
CPUF_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, which only Hammer
|
||||||
|
// will have anyway)
|
||||||
|
CPUF_SSE3 = 0x100, // Some P4 & Athlon 64.
|
||||||
|
};
|
||||||
|
#define MAX_INT 0x7fffffff
|
||||||
|
#define MIN_INT -0x7fffffff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class IScriptEnvironment {
|
||||||
|
public:
|
||||||
|
virtual __stdcall ~IScriptEnvironment() {}
|
||||||
|
|
||||||
|
virtual /*static*/ long __stdcall GetCPUFlags() = 0;
|
||||||
|
|
||||||
|
virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
|
||||||
|
virtual char* __stdcall Sprintf(const char* fmt, ...) = 0;
|
||||||
|
// note: val is really a va_list; I hope everyone typedefs va_list to a pointer
|
||||||
|
virtual char* __stdcall VSprintf(const char* fmt, void* val) = 0;
|
||||||
|
|
||||||
|
__declspec(noreturn) virtual void __stdcall ThrowError(const char* fmt, ...) = 0;
|
||||||
|
|
||||||
|
class NotFound /*exception*/ {}; // thrown by Invoke and GetVar
|
||||||
|
|
||||||
|
typedef AVSValue (__cdecl *ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);
|
||||||
|
|
||||||
|
virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
|
||||||
|
virtual bool __stdcall FunctionExists(const char* name) = 0;
|
||||||
|
virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char** arg_names=0) = 0;
|
||||||
|
|
||||||
|
virtual AVSValue __stdcall GetVar(const char* name) = 0;
|
||||||
|
virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
|
||||||
|
virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
|
||||||
|
|
||||||
|
virtual void __stdcall PushContext(int level=0) = 0;
|
||||||
|
virtual void __stdcall PopContext() = 0;
|
||||||
|
|
||||||
|
// align should be 4 or 8
|
||||||
|
virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align=FRAME_ALIGN) = 0;
|
||||||
|
|
||||||
|
virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
|
||||||
|
|
||||||
|
virtual /*static*/ void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
|
||||||
|
|
||||||
|
typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);
|
||||||
|
virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;
|
||||||
|
|
||||||
|
virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;
|
||||||
|
|
||||||
|
virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
|
||||||
|
|
||||||
|
virtual int __stdcall SetMemoryMax(int mem) = 0;
|
||||||
|
|
||||||
|
virtual int __stdcall SetWorkingDir(const char * newdir) = 0;
|
||||||
|
|
||||||
|
virtual void* __stdcall ManageCache(int key, void* data) = 0;
|
||||||
|
|
||||||
|
enum PlanarChromaAlignmentMode {
|
||||||
|
PlanarChromaAlignmentOff,
|
||||||
|
PlanarChromaAlignmentOn,
|
||||||
|
PlanarChromaAlignmentTest };
|
||||||
|
|
||||||
|
virtual bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key) = 0;
|
||||||
|
|
||||||
|
virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// avisynth.dll exports this; it's a way to use it as a library, without
|
||||||
|
// writing an AVS script or without going through AVIFile.
|
||||||
|
IScriptEnvironment* __stdcall CreateScriptEnvironment(int version = AVISYNTH_INTERFACE_VERSION);
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#endif //__AVISYNTH_H__
|
6
csri/frontends/cmdline/Makefile.am
Normal file
6
csri/frontends/cmdline/Makefile.am
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
bin_PROGRAMS = csri
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
csri_SOURCES = cmdmain.c render.c
|
||||||
|
csri_LDADD = ../../lib/libcsri.la
|
||||||
|
|
||||||
|
noinst_HEADERS = render.h
|
473
csri/frontends/cmdline/cmdmain.c
Normal file
473
csri/frontends/cmdline/cmdmain.c
Normal file
|
@ -0,0 +1,473 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <csri/csri.h>
|
||||||
|
#include <csri/logging.h>
|
||||||
|
#include <csri/openerr.h>
|
||||||
|
#include <csri/stream.h>
|
||||||
|
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
|
csri_rend *r;
|
||||||
|
|
||||||
|
static int do_usage(FILE *fd)
|
||||||
|
{
|
||||||
|
fprintf(fd, "usage: csri [COMMON-OPTIONS] COMMAND [COMMAND-OPTIONS]\n"
|
||||||
|
"\n"
|
||||||
|
"common options: [-r renderer [-s specific]]\n"
|
||||||
|
"\t-r\tselect a renderer, by name\n"
|
||||||
|
"\t-s\tselect a renderer version, by specific name\n"
|
||||||
|
"\n"
|
||||||
|
"commands:\n"
|
||||||
|
"\tlist\tshow installed renderers\n"
|
||||||
|
"\tinfo\tshow detailed renderer information\n"
|
||||||
|
"\trender\trender subtitle output\n"
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
"\t\t-i FILE\t\tread background from PNG file\n"
|
||||||
|
"\t\t-o PREFIX\twrite output to PREFIX_nnnn.png\n"
|
||||||
|
#endif
|
||||||
|
"\t\t-A\t\tkeep alpha\n"
|
||||||
|
"\t\t-t [start][:[end][:[step]]]\tspecify timestamps to be rendered\n"
|
||||||
|
"\t\tSUBFILE\t\tsubtitle file to load\n"
|
||||||
|
"\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_list(int argc, char **argv)
|
||||||
|
{
|
||||||
|
unsigned num = 0;
|
||||||
|
|
||||||
|
if (argc)
|
||||||
|
return do_usage(stderr);
|
||||||
|
|
||||||
|
while (r) {
|
||||||
|
struct csri_info *info = csri_renderer_info(r);
|
||||||
|
if (!info)
|
||||||
|
continue;
|
||||||
|
printf("%s:%s %s, %s, %s\n", info->name, info->specific,
|
||||||
|
info->longname, info->author, info->copyright);
|
||||||
|
r = csri_renderer_next(r);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%u renderers found\n", num);
|
||||||
|
return num > 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static csri_ext_id known_exts[] = {
|
||||||
|
CSRI_EXT_OPENERR,
|
||||||
|
CSRI_EXT_LOGGING,
|
||||||
|
CSRI_EXT_STREAM,
|
||||||
|
CSRI_EXT_STREAM_ASS,
|
||||||
|
CSRI_EXT_STREAM_TEXT,
|
||||||
|
CSRI_EXT_STREAM_DISCARD,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *dummy_script = "[Script Info]\r\n"
|
||||||
|
"ScriptType: v4.00\r\n"
|
||||||
|
"[V4 Styles]\r\n"
|
||||||
|
"Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, "
|
||||||
|
"TertiaryColour, BackColour, Bold, Italic, BorderStyle, "
|
||||||
|
"Outline, Shadow, Alignment, MarginL, MarginR, MarginV, "
|
||||||
|
"AlphaLevel, Encoding\r\n"
|
||||||
|
"Style: Default,Arial,20,&HFFFFFF&,&H00FFFF&,&H000000&,&H000000&,"
|
||||||
|
"0,0,1,2,2,2,10,10,10,0,0\r\n"
|
||||||
|
"[Events]\r\n"
|
||||||
|
"Format: Marked, Start, End, Style, Name, "
|
||||||
|
"MarginL, MarginR, MarginV, Effect, Text\r\n"
|
||||||
|
"Dialogue: Marked=0,0:00:01.00,0:00:02.00,Default,,0000,0000,0000,,"
|
||||||
|
"test\r\n";
|
||||||
|
|
||||||
|
static const char *dummy_stream = "1,0,Default,,0000,0000,0000,,stream\r\n";
|
||||||
|
|
||||||
|
#define e(x) { #x, CSRI_F_ ## x }
|
||||||
|
#define ree(x) e(RGB ## x), e(x ## RGB), e(BGR ## x), e(x ## BGR)
|
||||||
|
static struct csri_fmtlistent {
|
||||||
|
const char *label;
|
||||||
|
enum csri_pixfmt fmt;
|
||||||
|
} csri_fmts[] = {
|
||||||
|
ree(A), ree(_),
|
||||||
|
e(RGB), e(BGR),
|
||||||
|
e(AYUV), e(YUVA), e(YVUA), e(YUY2), e(YV12A), e(YV12),
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void listfmts()
|
||||||
|
{
|
||||||
|
csri_inst *i;
|
||||||
|
struct csri_fmtlistent *fmt;
|
||||||
|
struct csri_fmt f;
|
||||||
|
|
||||||
|
printf("\ntrying to get list of supported colorspaces:\n");
|
||||||
|
fflush(stdout);
|
||||||
|
i = csri_open_mem(r, dummy_script, strlen(dummy_script), NULL);
|
||||||
|
|
||||||
|
f.width = f.height = 256;
|
||||||
|
for (fmt = csri_fmts; fmt->label; fmt++) {
|
||||||
|
f.pixfmt = fmt->fmt;
|
||||||
|
if (!csri_request_fmt(i, &f))
|
||||||
|
printf("\t[%04x] %s\n", fmt->fmt, fmt->label);
|
||||||
|
}
|
||||||
|
csri_close(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_info(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct csri_info *info;
|
||||||
|
csri_ext_id *id;
|
||||||
|
if (argc)
|
||||||
|
return do_usage(stderr);
|
||||||
|
|
||||||
|
info = csri_renderer_info(r);
|
||||||
|
if (!info)
|
||||||
|
return 1;
|
||||||
|
printf("%s:%s\n\t%s\n\t%s\n\t%s\n", info->name, info->specific,
|
||||||
|
info->longname, info->author, info->copyright);
|
||||||
|
printf("supported CSRI extensions:\n");
|
||||||
|
for (id = known_exts; *id; id++) {
|
||||||
|
void *rext = csri_query_ext(r, *id);
|
||||||
|
void *lext = csri_query_ext(NULL, *id);
|
||||||
|
if (lext || rext) {
|
||||||
|
printf("\t%s ", *id);
|
||||||
|
if (!lext)
|
||||||
|
printf("\n");
|
||||||
|
else if (!rext)
|
||||||
|
printf("[library only]\n");
|
||||||
|
else if (rext == lext)
|
||||||
|
printf("[emulated by library]\n");
|
||||||
|
else
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listfmts();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void logfunc(void *appdata, enum csri_logging_severity sev,
|
||||||
|
const char *message)
|
||||||
|
{
|
||||||
|
char severity[32];
|
||||||
|
switch (sev) {
|
||||||
|
case CSRI_LOG_DEBUG: strcpy(severity, "[debug]"); break;
|
||||||
|
case CSRI_LOG_INFO: strcpy(severity, "[info]"); break;
|
||||||
|
case CSRI_LOG_NOTICE: strcpy(severity, "[notice]"); break;
|
||||||
|
case CSRI_LOG_WARNING: strcpy(severity, "[warning]"); break;
|
||||||
|
case CSRI_LOG_ERROR: strcpy(severity, "[error]"); break;
|
||||||
|
default: snprintf(severity, 32, "[%d?]", (int)sev);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%-10s %s\n", severity, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int real_render(double *times, const char *infile, const char *outfile,
|
||||||
|
const char *script, enum csri_pixfmt pfmt)
|
||||||
|
{
|
||||||
|
struct csri_frame *bg, *a;
|
||||||
|
csri_inst *inst;
|
||||||
|
struct csri_fmt fmt;
|
||||||
|
double now;
|
||||||
|
int idx;
|
||||||
|
uint32_t width = 640, height = 480;
|
||||||
|
|
||||||
|
bg = infile ? png_load(infile, &width, &height, pfmt)
|
||||||
|
: frame_alloc(width, height, pfmt);
|
||||||
|
a = frame_alloc(width, height, pfmt);
|
||||||
|
if (!bg || !a) {
|
||||||
|
fprintf(stderr, "failed to allocate frame\n");
|
||||||
|
if (!bg)
|
||||||
|
fprintf(stderr, "\t- problem with background.\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
inst = csri_open_file(r, script, NULL);
|
||||||
|
if (!inst) {
|
||||||
|
fprintf(stderr, "failed to open script \"%s\"\n", script);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
fmt.pixfmt = pfmt;
|
||||||
|
fmt.width = width;
|
||||||
|
fmt.height = height;
|
||||||
|
if (csri_request_fmt(inst, &fmt)) {
|
||||||
|
fprintf(stderr, "format not supported by renderer\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
for (now = times[0]; now <= times[1]; now += times[2]) {
|
||||||
|
frame_copy(a, bg, width, height);
|
||||||
|
csri_render(inst, a, now);
|
||||||
|
if (outfile) {
|
||||||
|
char buffer[256];
|
||||||
|
snprintf(buffer, sizeof(buffer),
|
||||||
|
"%s_%04d.png", outfile, idx);
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
png_store(a, buffer, width, height);
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
csri_close(inst);
|
||||||
|
inst = NULL;
|
||||||
|
frame_free(bg);
|
||||||
|
frame_free(a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_render(int argc, char **argv)
|
||||||
|
{
|
||||||
|
double times[3] = {0.0, 0.0, 1.0};
|
||||||
|
const char *outfile = NULL, *infile = NULL;
|
||||||
|
struct csri_fmtlistent *fmte;
|
||||||
|
int keepalpha = 0;
|
||||||
|
enum csri_pixfmt fmt = ~0U;
|
||||||
|
argv--, argc++;
|
||||||
|
while (1) {
|
||||||
|
int c, i;
|
||||||
|
const char *short_options = "t:o:i:F:A";
|
||||||
|
char *arg, *end, *err;
|
||||||
|
struct option long_options[] = {
|
||||||
|
{"time", 1, 0, 't'},
|
||||||
|
{"output", 1, 0, 'o'},
|
||||||
|
{"input", 1, 0, 'i'},
|
||||||
|
{"format", 0, 0, 'F'},
|
||||||
|
{"alpha", 0, 0, 'A'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
c = getopt_long(argc, argv, short_options, long_options, NULL);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 't':
|
||||||
|
arg = optarg;
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
end = strchr(arg, ':');
|
||||||
|
if (end)
|
||||||
|
*end = '\0';
|
||||||
|
if (*arg) {
|
||||||
|
times[i] = strtod(arg, &err);
|
||||||
|
if (*err) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"invalid time: %s\n",
|
||||||
|
arg);
|
||||||
|
return do_usage(stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!end)
|
||||||
|
break;
|
||||||
|
arg = end + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
infile = optarg;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
outfile = optarg;
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
if (fmt != ~0U)
|
||||||
|
return do_usage(stderr);
|
||||||
|
keepalpha = 1;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
if (keepalpha || fmt != ~0U)
|
||||||
|
return do_usage(stderr);
|
||||||
|
for (fmte = csri_fmts; fmte->label; fmte++)
|
||||||
|
if (!strcmp(fmte->label, optarg))
|
||||||
|
break;
|
||||||
|
if (!fmte->label)
|
||||||
|
return do_usage(stderr);
|
||||||
|
fmt = fmte->fmt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return do_usage(stderr);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (fmt == ~0U)
|
||||||
|
fmt = keepalpha ? CSRI_F_RGBA : CSRI_F_RGB_;
|
||||||
|
if (!isfinite(times[0])) {
|
||||||
|
fprintf(stderr, "invalid start time\n");
|
||||||
|
return do_usage(stderr);
|
||||||
|
}
|
||||||
|
if (!isfinite(times[1]) || times[1] < times[0]) {
|
||||||
|
fprintf(stderr, "invalid end time\n");
|
||||||
|
return do_usage(stderr);
|
||||||
|
}
|
||||||
|
if (!isnormal(times[2]) || times[2] < 0.0) {
|
||||||
|
fprintf(stderr, "invalid end time\n");
|
||||||
|
return do_usage(stderr);
|
||||||
|
}
|
||||||
|
if (argc - optind != 1) {
|
||||||
|
fprintf(stderr, "script name missing\n");
|
||||||
|
return do_usage(stderr);
|
||||||
|
}
|
||||||
|
return real_render(times, infile, outfile, argv[optind], fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_streamtest(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *outfile = NULL;
|
||||||
|
struct csri_fmtlistent *fmte;
|
||||||
|
enum csri_pixfmt pfmt = ~0U;
|
||||||
|
struct csri_frame *bg, *a;
|
||||||
|
csri_inst *inst;
|
||||||
|
struct csri_fmt fmt;
|
||||||
|
uint32_t width = 640, height = 480;
|
||||||
|
struct csri_stream_ext *sext;
|
||||||
|
|
||||||
|
argv--, argc++;
|
||||||
|
while (1) {
|
||||||
|
int c;
|
||||||
|
const char *short_options = "o:F:";
|
||||||
|
struct option long_options[] = {
|
||||||
|
{"output", 1, 0, 'o'},
|
||||||
|
{"format", 0, 0, 'F'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
c = getopt_long(argc, argv, short_options, long_options, NULL);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'o':
|
||||||
|
outfile = optarg;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
if (pfmt != ~0U)
|
||||||
|
return do_usage(stderr);
|
||||||
|
for (fmte = csri_fmts; fmte->label; fmte++)
|
||||||
|
if (!strcmp(fmte->label, optarg))
|
||||||
|
break;
|
||||||
|
if (!fmte->label)
|
||||||
|
return do_usage(stderr);
|
||||||
|
pfmt = fmte->fmt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return do_usage(stderr);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (pfmt == ~0U)
|
||||||
|
pfmt = CSRI_F_RGB_;
|
||||||
|
|
||||||
|
sext = (struct csri_stream_ext *)csri_query_ext(r,
|
||||||
|
CSRI_EXT_STREAM_ASS);
|
||||||
|
if (!sext) {
|
||||||
|
fprintf(stderr, "renderer does not support ASS streaming\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bg = frame_alloc(width, height, pfmt);
|
||||||
|
a = frame_alloc(width, height, pfmt);
|
||||||
|
if (!bg || !a) {
|
||||||
|
fprintf(stderr, "failed to allocate frame\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
inst = sext->init_stream(r, dummy_script, strlen(dummy_script), NULL);
|
||||||
|
if (!inst) {
|
||||||
|
fprintf(stderr, "failed to initialize stream\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
fmt.pixfmt = pfmt;
|
||||||
|
fmt.width = width;
|
||||||
|
fmt.height = height;
|
||||||
|
if (csri_request_fmt(inst, &fmt)) {
|
||||||
|
fprintf(stderr, "format not supported by renderer\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_copy(a, bg, width, height);
|
||||||
|
csri_render(inst, a, 1.75);
|
||||||
|
if (outfile) {
|
||||||
|
char buffer[256];
|
||||||
|
snprintf(buffer, sizeof(buffer),
|
||||||
|
"%s_nstream.png", outfile);
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
png_store(a, buffer, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_copy(a, bg, width, height);
|
||||||
|
sext->push_packet(inst, dummy_stream, strlen(dummy_stream),
|
||||||
|
1.5, 2.0);
|
||||||
|
csri_render(inst, a, 1.75);
|
||||||
|
if (outfile) {
|
||||||
|
char buffer[256];
|
||||||
|
snprintf(buffer, sizeof(buffer),
|
||||||
|
"%s_stream.png", outfile);
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
png_store(a, buffer, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_close(inst);
|
||||||
|
inst = NULL;
|
||||||
|
frame_free(bg);
|
||||||
|
frame_free(a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct csri_logging_ext *logext;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return do_usage(stderr);
|
||||||
|
|
||||||
|
logext = (struct csri_logging_ext *)csri_query_ext(NULL,
|
||||||
|
CSRI_EXT_LOGGING);
|
||||||
|
if (logext && logext->set_logcallback)
|
||||||
|
logext->set_logcallback(logfunc, NULL);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "warning: unable to set log callback\n");
|
||||||
|
|
||||||
|
r = csri_renderer_default();
|
||||||
|
argc--, argv++;
|
||||||
|
if (!strcmp(argv[0], "list"))
|
||||||
|
return do_list(argc - 1, argv + 1);
|
||||||
|
if (!strcmp(argv[0], "-r")) {
|
||||||
|
const char *name = NULL, *spec = NULL;
|
||||||
|
if (argc < 2)
|
||||||
|
return do_usage(stderr);
|
||||||
|
name = argv[1];
|
||||||
|
argc -= 2, argv += 2;
|
||||||
|
if (!strcmp(argv[0], "-s")) {
|
||||||
|
if (argc < 2)
|
||||||
|
return do_usage(stderr);
|
||||||
|
spec = argv[1];
|
||||||
|
}
|
||||||
|
r = csri_renderer_byname(name, spec);
|
||||||
|
if (!r) {
|
||||||
|
fprintf(stderr, "renderer %s:%s not found.\n",
|
||||||
|
name, spec ? spec : "*");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[0], "info"))
|
||||||
|
return do_info(argc - 1, argv + 1);
|
||||||
|
if (!strcmp(argv[0], "render"))
|
||||||
|
return do_render(argc - 1, argv + 1);
|
||||||
|
if (!strcmp(argv[0], "streamtest"))
|
||||||
|
return do_streamtest(argc - 1, argv + 1);
|
||||||
|
return do_usage(stderr);
|
||||||
|
}
|
240
csri/frontends/cmdline/render.c
Normal file
240
csri/frontends/cmdline/render.c
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <csri/csri.h>
|
||||||
|
#include <csri/logging.h>
|
||||||
|
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
|
extern csri_rend *r;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
struct csri_frame *png_load(const char *filename,
|
||||||
|
uint32_t *width, uint32_t *height, enum csri_pixfmt fmt)
|
||||||
|
{
|
||||||
|
struct csri_frame *frame;
|
||||||
|
int bit_depth, color_type;
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
png_bytep *rows;
|
||||||
|
unsigned char *imgdata;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (!csri_is_rgb(fmt)) {
|
||||||
|
fprintf(stderr, "PNG loader: can't load non-RGB.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = (struct csri_frame *)malloc(sizeof(struct csri_frame));
|
||||||
|
if (!frame)
|
||||||
|
return NULL;
|
||||||
|
memset(frame, 0, sizeof(*frame));
|
||||||
|
frame->pixfmt = fmt;
|
||||||
|
|
||||||
|
fp = fopen(filename, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
fprintf(stderr, "Error opening \"%s\": %s (%d)\n",
|
||||||
|
filename, strerror(errno), errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||||
|
NULL, NULL, NULL));
|
||||||
|
assert(info_ptr = png_create_info_struct(png_ptr));
|
||||||
|
//keepalpha ? CSRI_F_RGBA : CSRI_F_RGB_;
|
||||||
|
|
||||||
|
png_init_io(png_ptr, fp);
|
||||||
|
png_read_info(png_ptr, info_ptr);
|
||||||
|
png_get_IHDR(png_ptr, info_ptr,
|
||||||
|
(png_uint_32 *)width, (png_uint_32 *)height,
|
||||||
|
&bit_depth, &color_type, NULL, NULL, NULL);
|
||||||
|
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
|
png_set_palette_to_rgb(png_ptr);
|
||||||
|
if (bit_depth < 8)
|
||||||
|
png_set_packing(png_ptr);
|
||||||
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||||
|
png_set_tRNS_to_alpha(png_ptr);
|
||||||
|
if (bit_depth == 16)
|
||||||
|
png_set_strip_16(png_ptr);
|
||||||
|
|
||||||
|
if ((fmt < 0x200 && (fmt & 2)) || fmt == CSRI_F_BGR)
|
||||||
|
png_set_bgr(png_ptr);
|
||||||
|
if (csri_has_alpha(fmt)) {
|
||||||
|
int before = fmt == CSRI_F_ARGB || fmt == CSRI_F_ABGR;
|
||||||
|
if (color_type == PNG_COLOR_TYPE_RGB)
|
||||||
|
png_set_filler(png_ptr, 0xff, before
|
||||||
|
? PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
|
||||||
|
else {
|
||||||
|
png_set_invert_alpha(png_ptr);
|
||||||
|
if (before)
|
||||||
|
png_set_swap_alpha(png_ptr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||||
|
png_set_strip_alpha(png_ptr);
|
||||||
|
if (fmt != CSRI_F_RGB && fmt != CSRI_F_BGR) {
|
||||||
|
int before = fmt == CSRI_F__RGB || fmt == CSRI_F__BGR;
|
||||||
|
png_set_filler(png_ptr, 0xff, before
|
||||||
|
? PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = (png_bytep *)malloc(sizeof(png_bytep) * *height);
|
||||||
|
assert(rows);
|
||||||
|
imgdata = (unsigned char *)malloc(4 * *height * *width);
|
||||||
|
assert(imgdata);
|
||||||
|
for (uint32_t y = 0; y < *height; y++)
|
||||||
|
rows[y] = imgdata + 4 * *width * y;
|
||||||
|
png_read_image(png_ptr, rows);
|
||||||
|
png_read_end(png_ptr, NULL);
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||||
|
free(rows);
|
||||||
|
|
||||||
|
frame->planes[0] = imgdata;
|
||||||
|
frame->strides[0] = *width * 4;
|
||||||
|
printf("\033[32;1mloaded %ux%u\033[m\n", *width, *height);
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_store(struct csri_frame *frame, const char *filename,
|
||||||
|
uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
enum csri_pixfmt fmt = frame->pixfmt;
|
||||||
|
int xforms = 0, before = 0, after = 0;
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
png_bytep *rows;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(filename, "wb");
|
||||||
|
if (!fp) {
|
||||||
|
fprintf(stderr, "Error opening \"%s\": %s (%d)\n",
|
||||||
|
filename, strerror(errno), errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = (png_bytep *)malloc(sizeof(png_bytep) * height);
|
||||||
|
assert(rows);
|
||||||
|
|
||||||
|
after = fmt == CSRI_F_RGB_ || fmt == CSRI_F_BGR_;
|
||||||
|
before = fmt == CSRI_F__RGB || fmt == CSRI_F__BGR;
|
||||||
|
for (uint32_t y = 0; y < height; y++) {
|
||||||
|
rows[y] = frame->planes[0] + frame->strides[0] * y;
|
||||||
|
if (before || after) {
|
||||||
|
unsigned char *d = rows[y], *s = rows[y],
|
||||||
|
*e = d + frame->strides[0];
|
||||||
|
if (before)
|
||||||
|
s++;
|
||||||
|
while (d < e) {
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
*d++ = *s++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||||
|
NULL, NULL, NULL));
|
||||||
|
assert(info_ptr = png_create_info_struct(png_ptr));
|
||||||
|
png_init_io(png_ptr, fp);
|
||||||
|
if (csri_has_alpha(fmt)
|
||||||
|
&& (fmt == CSRI_F_ARGB || fmt == CSRI_F_ABGR))
|
||||||
|
xforms |= PNG_TRANSFORM_SWAP_ALPHA;
|
||||||
|
if ((fmt < 0x200 && (fmt & 2)) || fmt == CSRI_F_BGR)
|
||||||
|
xforms |= PNG_TRANSFORM_BGR;
|
||||||
|
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
|
||||||
|
png_set_IHDR(png_ptr, info_ptr, width, height, 8, csri_has_alpha(fmt)
|
||||||
|
? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
|
||||||
|
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||||
|
PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
png_set_rows(png_ptr, info_ptr, rows);
|
||||||
|
png_write_png(png_ptr, info_ptr, xforms, NULL);
|
||||||
|
fflush(fp);
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct csri_frame *png_load(const char *filename,
|
||||||
|
uint32_t *width, uint32_t *height, enum csri_pixfmt fmt)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "PNG support not compiled in.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_store(struct csri_frame *frame, const char *filename,
|
||||||
|
uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "PNG support not compiled in.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct csri_frame *frame_alloc(uint32_t width, uint32_t height,
|
||||||
|
enum csri_pixfmt fmt)
|
||||||
|
{
|
||||||
|
int bpp;
|
||||||
|
unsigned char *d;
|
||||||
|
struct csri_frame *frame;
|
||||||
|
|
||||||
|
if (!csri_is_rgb(fmt))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
bpp = fmt < CSRI_F_RGB ? 4 : 3;
|
||||||
|
d = (unsigned char *)malloc(width * height * bpp);
|
||||||
|
frame = (struct csri_frame *)malloc(sizeof(struct csri_frame));
|
||||||
|
if (!frame || !d)
|
||||||
|
return NULL;
|
||||||
|
memset(frame, 0, sizeof(*frame));
|
||||||
|
frame->pixfmt = fmt;
|
||||||
|
frame->strides[0] = width * bpp;
|
||||||
|
memset(d, csri_has_alpha(fmt) ? 0x00 : 0x80, width * height * bpp);
|
||||||
|
frame->planes[0] = d;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
void frame_free(struct csri_frame *frame)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
for (c = 0; c < 4; c++)
|
||||||
|
if (frame->planes[c])
|
||||||
|
free(frame->planes[c]);
|
||||||
|
|
||||||
|
free(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void frame_copy(struct csri_frame *dst, struct csri_frame *src,
|
||||||
|
uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
memcpy(dst->planes[0], src->planes[0], height * src->strides[0]);
|
||||||
|
}
|
34
csri/frontends/cmdline/render.h
Normal file
34
csri/frontends/cmdline/render.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _RENDER_H
|
||||||
|
#define _RENDER_H
|
||||||
|
|
||||||
|
extern struct csri_frame *png_load(const char *filename,
|
||||||
|
uint32_t *width, uint32_t *height, enum csri_pixfmt fmt);
|
||||||
|
extern void png_store(struct csri_frame *frame, const char *filename,
|
||||||
|
uint32_t width, uint32_t height);
|
||||||
|
extern struct csri_frame *frame_alloc(uint32_t width, uint32_t height,
|
||||||
|
enum csri_pixfmt fmt);
|
||||||
|
extern void frame_free(struct csri_frame *frame);
|
||||||
|
extern void frame_copy(struct csri_frame *dst, struct csri_frame *src,
|
||||||
|
uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
#endif
|
2
csri/include/Makefile.am
Normal file
2
csri/include/Makefile.am
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
noinst_HEADERS = subhelp.h visibility.h
|
||||||
|
pkginclude_HEADERS = csri/csri.h csri/openerr.h csri/logging.h csri/stream.h
|
348
csri/include/csri/csri.h
Normal file
348
csri/include/csri/csri.h
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** \file csri.h - main CSRI (common subtitle renderer interface) include.
|
||||||
|
* $Id: csri.h 45 2007-06-20 01:00:40Z equinox $ */
|
||||||
|
|
||||||
|
#ifndef _CSRI_H
|
||||||
|
/** \cond */
|
||||||
|
#define _CSRI_H 20070119
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
#include <stddef.h> /* ptrdiff_t */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CSRIAPI
|
||||||
|
/** CSRI API attributes.
|
||||||
|
* defaults to \c extern.
|
||||||
|
*/
|
||||||
|
#define CSRIAPI extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \defgroup base CSRI base API. */
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** pixel format specification for frames */
|
||||||
|
enum csri_pixfmt {
|
||||||
|
CSRI_F_RGBA = 0,
|
||||||
|
CSRI_F_ARGB,
|
||||||
|
CSRI_F_BGRA,
|
||||||
|
CSRI_F_ABGR,
|
||||||
|
|
||||||
|
CSRI_F_RGB_ = 0x100,
|
||||||
|
CSRI_F__RGB,
|
||||||
|
CSRI_F_BGR_, /**< Windows "RGB32" */
|
||||||
|
CSRI_F__BGR,
|
||||||
|
|
||||||
|
CSRI_F_RGB = 0x200,
|
||||||
|
CSRI_F_BGR, /**< Windows "RGB24" */
|
||||||
|
|
||||||
|
CSRI_F_AYUV = 0x1000,
|
||||||
|
CSRI_F_YUVA,
|
||||||
|
CSRI_F_YVUA,
|
||||||
|
|
||||||
|
CSRI_F_YUY2 = 0x1100,
|
||||||
|
|
||||||
|
CSRI_F_YV12A = 0x2011, /**< planar YUV 2x2 + alpha plane */
|
||||||
|
CSRI_F_YV12 = 0x2111 /**< planar YUV 2x2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define csri_is_rgb(x) ((x) < 0x1000)
|
||||||
|
#define csri_is_yuv(x) ((x) >= 0x1000)
|
||||||
|
#define csri_is_yuv_planar(x) ((x) >= 0x2000)
|
||||||
|
#define csri_get_yuv_planar_xred(x) (0xf & (x))
|
||||||
|
#define csri_get_yuv_planar_yred(x) (0xf & ((x) >> 4))
|
||||||
|
#define csri_is_yuv_packed(x) ((x) >= 0x1000 && (x) < 0x2000)
|
||||||
|
#define csri_has_alpha(x) (((x) & 0xfff) < 0x100)
|
||||||
|
|
||||||
|
/** frame/image format specification pre-fed to the renderer */
|
||||||
|
struct csri_fmt {
|
||||||
|
/** format to be used */
|
||||||
|
enum csri_pixfmt pixfmt;
|
||||||
|
/** image width, full frame.
|
||||||
|
*
|
||||||
|
* This should specify the full size of the frame.
|
||||||
|
* Specifying the video sub-size (in case of added black
|
||||||
|
* borders) is left to an extension.
|
||||||
|
*/
|
||||||
|
unsigned width;
|
||||||
|
/** image height */
|
||||||
|
unsigned height;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** single frame to be fed to the renderer. */
|
||||||
|
struct csri_frame {
|
||||||
|
/** frame format.
|
||||||
|
* It is an application bug if this differs from the one
|
||||||
|
* passed in struct #csri_fmt to csri_query_fmt()
|
||||||
|
*/
|
||||||
|
enum csri_pixfmt pixfmt;
|
||||||
|
/** the frame's data.
|
||||||
|
* Packed formats only use planes[0]; planar formats
|
||||||
|
* have the data ordered as Y, U, V[, A].
|
||||||
|
*
|
||||||
|
* Also note that the topmost line always comes first.
|
||||||
|
* The Windows biHeight strange-ity is \a NOT duplicated.
|
||||||
|
*/
|
||||||
|
unsigned char *planes[4];
|
||||||
|
/** strides for the individual planes.
|
||||||
|
* Stride means full byte offset, i.e. do \a not add
|
||||||
|
* frame width
|
||||||
|
*/
|
||||||
|
ptrdiff_t strides[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef CSRI_OWN_HANDLES
|
||||||
|
/** opaque renderer data */
|
||||||
|
typedef void csri_rend;
|
||||||
|
/** opaque instance data */
|
||||||
|
typedef void csri_inst;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
/** disable the emission of the csri_rend and csri_inst typedefs.
|
||||||
|
* define this if you are in a renderer and are typedef'ing
|
||||||
|
* csri_rend and csri_inst to your own structs.
|
||||||
|
*/
|
||||||
|
#define CSRI_OWN_HANDLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** renderer description.
|
||||||
|
* \ingroup loader
|
||||||
|
*/
|
||||||
|
struct csri_info {
|
||||||
|
/** an identifier for the renderer.
|
||||||
|
* - MUST match the regular expression
|
||||||
|
* \code ^[a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])? \endcode
|
||||||
|
* i.e. consists only of letters, numbers and underscores;
|
||||||
|
* must start with a letter and doesnt have an underscore
|
||||||
|
* as the last character.
|
||||||
|
*/
|
||||||
|
const char *name;
|
||||||
|
/** an identifier to the exact version of the renderer.
|
||||||
|
* most likely a version number or revision identifier.
|
||||||
|
*
|
||||||
|
* The helper library does a strcmp over this field in order
|
||||||
|
* to order multiple instances of the same renderer. Use
|
||||||
|
* higher-byte-value strings for newer renderers.
|
||||||
|
*/
|
||||||
|
const char *specific;
|
||||||
|
|
||||||
|
/** a nice name to be presented to the user */
|
||||||
|
const char *longname;
|
||||||
|
/** the renderer's author */
|
||||||
|
const char *author;
|
||||||
|
/** a copyright string. Copyright (c) 2042 by Mr. Nice Guy */
|
||||||
|
const char *copyright;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** data of extension-dependent type.
|
||||||
|
* The field to be used MUST be specified in the extension where it is used.
|
||||||
|
*/
|
||||||
|
union csri_vardata {
|
||||||
|
long lval;
|
||||||
|
double dval;
|
||||||
|
const char *utf8val;
|
||||||
|
void *otherval;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** extension identifier.
|
||||||
|
* This follows reverse DNS syntax, i.e.:
|
||||||
|
* \code root.branch.leaf \endcode
|
||||||
|
* you can either reverse a registered domain name, e.g.
|
||||||
|
* \code com.microsoft.csri.usegdiplus \endcode
|
||||||
|
* or ask the CSRI maintainers to assign a namespace to you.
|
||||||
|
*
|
||||||
|
* currently registered namespaces are:
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* csri.* - official extensions
|
||||||
|
* asa.* - custom extensions of the asa renderer
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
typedef const char *csri_ext_id;
|
||||||
|
|
||||||
|
/** script loading parameters.
|
||||||
|
* each flag MUST have an associated extension, which can be queried
|
||||||
|
* with csri_query_ext(). If the open flag constitutes an extension on its
|
||||||
|
* sole own, csri_query_ext() can return a meaningless non-NULL value for
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* The data field used must be specified.
|
||||||
|
*
|
||||||
|
* An extension can have multiple flags. In that case, the flags should have
|
||||||
|
* the extension name as common prefix, separated with a dot.
|
||||||
|
*
|
||||||
|
* A renderer MUST ignore unknown open flags. It MUST NOT return an error
|
||||||
|
* just because it does not support a particular flag.
|
||||||
|
*/
|
||||||
|
struct csri_openflag {
|
||||||
|
/** flag name */
|
||||||
|
csri_ext_id name;
|
||||||
|
/** flag data argument */
|
||||||
|
union csri_vardata data;
|
||||||
|
/** link to next flag */
|
||||||
|
struct csri_openflag *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** load a script from a file.
|
||||||
|
* \param renderer the handle to the renderer
|
||||||
|
* \param filename the path to the file to be loaded. \n
|
||||||
|
* The filename should be encoded as UTF-8. Windows renderers are
|
||||||
|
* expected to convert it to UTF-16 and use the Unicode Windows API
|
||||||
|
* functions.
|
||||||
|
* \param flags a linked list of open flags. \n
|
||||||
|
* The caller manages memory allocation, i.e. static allocation is OK.
|
||||||
|
* \return the renderer instance handle, or NULL on error.
|
||||||
|
*/
|
||||||
|
CSRIAPI csri_inst *csri_open_file(csri_rend *renderer,
|
||||||
|
const char *filename, struct csri_openflag *flags);
|
||||||
|
|
||||||
|
/** load a script from memory.
|
||||||
|
* \param renderer the handle to the renderer
|
||||||
|
* \param data pointer to the first data byte. \n
|
||||||
|
* The caller manages memory allocation and should free the data after
|
||||||
|
* calling csri_open_mem(). If the renderer needs to keep the data, it
|
||||||
|
* must copy it. \n
|
||||||
|
* The renderer is not allowed to write to the data.
|
||||||
|
* \param length length, in bytes, of the data
|
||||||
|
* \param flags see csri_open_file()
|
||||||
|
* \return the render instance handle, or NULL on error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSRIAPI csri_inst *csri_open_mem(csri_rend *renderer,
|
||||||
|
const void *data, size_t length, struct csri_openflag *flags);
|
||||||
|
|
||||||
|
/** close a renderer instance.
|
||||||
|
* \param inst the instance handle.
|
||||||
|
*/
|
||||||
|
CSRIAPI void csri_close(csri_inst *inst);
|
||||||
|
|
||||||
|
|
||||||
|
/** query / set the image format and size.
|
||||||
|
* \param inst the renderer instance handle
|
||||||
|
* \param fmt the format and image size to be used
|
||||||
|
* \return 0 if the format was successfully set,
|
||||||
|
* any other value in case of error.
|
||||||
|
*/
|
||||||
|
CSRIAPI int csri_request_fmt(csri_inst *inst, const struct csri_fmt *fmt);
|
||||||
|
|
||||||
|
/** render a single frame
|
||||||
|
* \param inst the renderer instance handle
|
||||||
|
* \param frame frame data to render to
|
||||||
|
* \param time associated timestamp of the frame
|
||||||
|
*/
|
||||||
|
CSRIAPI void csri_render(csri_inst *inst, struct csri_frame *frame,
|
||||||
|
double time);
|
||||||
|
|
||||||
|
|
||||||
|
/** query for an extension.
|
||||||
|
* \param rend the renderer handle
|
||||||
|
* \param extname the extension's identifier
|
||||||
|
* \return NULL if the extension is not supported,
|
||||||
|
* a pointer to extension-specific data otherwise
|
||||||
|
*
|
||||||
|
* The data pointed to by the return value does not neccessarily need to
|
||||||
|
* have any meaning; An extension that does not need to return data
|
||||||
|
* can return a pointer to whatever it wants, as long as that pointer is
|
||||||
|
* not NULL.
|
||||||
|
*
|
||||||
|
* In the usual case, the pointer is supposed to point to a struct with
|
||||||
|
* function pointers and other information as needed.
|
||||||
|
*/
|
||||||
|
CSRIAPI void *csri_query_ext(csri_rend *rend, csri_ext_id extname);
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** \defgroup loader CSRI loader API.
|
||||||
|
*
|
||||||
|
* These functions locate renderers based on given parameters.
|
||||||
|
*
|
||||||
|
* <b>Renderers must implement these functions as well.</b>
|
||||||
|
*
|
||||||
|
* They are used by the library to grab renderer information
|
||||||
|
* from a shared object; and also this way a single renderer
|
||||||
|
* can be linked directly into an appliaction.
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** get renderer information
|
||||||
|
* \param rend the renderer handle
|
||||||
|
* \return information about the renderer, or NULL in case the renderer
|
||||||
|
* encountered an internal error.
|
||||||
|
*/
|
||||||
|
CSRIAPI struct csri_info *csri_renderer_info(csri_rend *rend);
|
||||||
|
|
||||||
|
/** try to load a given renderer
|
||||||
|
* \param name the name of the renderer, as in csri_info.name
|
||||||
|
* \param specific the specific version of the renderer,
|
||||||
|
* as in csri_info.specific;\n
|
||||||
|
* alternatively NULL if any version of the renderer is ok.
|
||||||
|
* \return a handle to the renderer if it was successfully loaded,
|
||||||
|
* NULL otherwise.
|
||||||
|
*/
|
||||||
|
CSRIAPI csri_rend *csri_renderer_byname(const char *name,
|
||||||
|
const char *specific);
|
||||||
|
|
||||||
|
/** try to find an implementation of the given extensions.
|
||||||
|
* \param next number of extensions pointed to by ext
|
||||||
|
* \param ext array of extensions to search for
|
||||||
|
* \return a handle to a renderer supporting ALL of the
|
||||||
|
* extensions, NULL if none was found.
|
||||||
|
*/
|
||||||
|
CSRIAPI csri_rend *csri_renderer_byext(unsigned n_ext, csri_ext_id *ext);
|
||||||
|
|
||||||
|
/** get the default (highest priority) renderer
|
||||||
|
* \return a handle to the default renderer, or NULL if
|
||||||
|
* no renderer is installed.
|
||||||
|
*
|
||||||
|
* Together with csri_renderer_next(), this can be used
|
||||||
|
* to enumerate all installed renderers.
|
||||||
|
*/
|
||||||
|
CSRIAPI csri_rend *csri_renderer_default();
|
||||||
|
|
||||||
|
/** get the next lower priority renderer
|
||||||
|
* \param prev the current renderer
|
||||||
|
* \return the renderer with the next lower priority than
|
||||||
|
* the one named in prev, or NULL if prev is the last
|
||||||
|
* renderer installed.
|
||||||
|
*/
|
||||||
|
CSRIAPI csri_rend *csri_renderer_next(csri_rend *prev);
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CSRI_H */
|
65
csri/include/csri/fmtids.h
Normal file
65
csri/include/csri/fmtids.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** \file fmtids.h - csri.format - extension identifiers for subtitle formats.
|
||||||
|
* $Id$ */
|
||||||
|
|
||||||
|
#ifndef _CSRI_FMTIDS_H
|
||||||
|
/** \cond */
|
||||||
|
#define _CSRI_FMTIDS_H 20070119
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \defgroup fmtids csri.format identifiers.
|
||||||
|
* only includes the most important ones for now, more to be added. */
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** SSA / ASS. Sub Station Alpha - versions 2, 3, 4, 4+ and 4++ */
|
||||||
|
#define CSRI_EXT_FMT_SSA (csri_ext_id)"csri.format.ssa"
|
||||||
|
/** SRT. SubRip Text, SubRip Titles or something similar. */
|
||||||
|
#define CSRI_EXT_FMT_SRT (csri_ext_id)"csri.format.srt"
|
||||||
|
/** MicroDVD */
|
||||||
|
#define CSRI_EXT_FMT_MICRODVD (csri_ext_id)"csri.format.microdvd"
|
||||||
|
/** SAMI. Microsoft Synchronized Accessible Media Interchange */
|
||||||
|
#define CSRI_EXT_FMT_SAMI (csri_ext_id)"csri.format.sami"
|
||||||
|
/** SMIL. W3C Synchronized Multimedia Integration Language.
|
||||||
|
* NB: this format uses separate files for text streams */
|
||||||
|
#define CSRI_EXT_FMT_SMIL (csri_ext_id)"csri.format.smil"
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CSRI_OPENERR_H */
|
79
csri/include/csri/logging.h
Normal file
79
csri/include/csri/logging.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** \file logging.h - csri.logging - logging for renderers via callback.
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* <b>THE SPECIFICATION OF THIS EXTENSION IS TENTATIVE
|
||||||
|
* AND NOT FINALIZED YET</b>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CSRI_LOGGING_H
|
||||||
|
/** \cond */
|
||||||
|
#define _CSRI_LOGGING_H 20070119
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \defgroup logging csri.logging extension.
|
||||||
|
* <b>THE SPECIFICATION OF THIS EXTENSION IS TENTATIVE
|
||||||
|
* AND NOT FINALIZED YET</b>
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** extension identifier */
|
||||||
|
#define CSRI_EXT_LOGGING (csri_ext_id)"csri.logging"
|
||||||
|
|
||||||
|
/** -. TODO: add scope? */
|
||||||
|
enum csri_logging_severity {
|
||||||
|
CSRI_LOG_DEBUG = 0,
|
||||||
|
CSRI_LOG_INFO,
|
||||||
|
CSRI_LOG_NOTICE,
|
||||||
|
CSRI_LOG_WARNING,
|
||||||
|
CSRI_LOG_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void csri_logging_func(void *appdata,
|
||||||
|
enum csri_logging_severity sev,
|
||||||
|
const char *message);
|
||||||
|
|
||||||
|
struct csri_logging_ext {
|
||||||
|
void (*set_logcallback)(csri_logging_func *func, void *appdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CSRI_LOGGING_H */
|
124
csri/include/csri/openerr.h
Normal file
124
csri/include/csri/openerr.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** \file openerr.h - csri.openerr - error return extension.
|
||||||
|
* $Id$ */
|
||||||
|
|
||||||
|
#ifndef _CSRI_OPENERR_H
|
||||||
|
/** \cond */
|
||||||
|
#define _CSRI_OPENERR_H 20070119
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \defgroup openerr csri.openerr extension. */
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** extension identifier */
|
||||||
|
#define CSRI_EXT_OPENERR (csri_ext_id)"csri.openerr"
|
||||||
|
|
||||||
|
/** flag field describing which fields of #csri_openerr_flag are valid */
|
||||||
|
enum csri_openerr_flags {
|
||||||
|
/** support indicator.
|
||||||
|
* set if the structure was filled with any meaningful data
|
||||||
|
*/
|
||||||
|
CSRI_OPENERR_FILLED = (1 << 0),
|
||||||
|
/** csri_openerr_flag.posixerrno valid */
|
||||||
|
CSRI_OPENERR_ERRNO = (1 << 1),
|
||||||
|
/** csri_openerr_flag.winerr valid */
|
||||||
|
CSRI_OPENERR_WINERR = (1 << 2),
|
||||||
|
/** csri_openerr_flag.custerr valid */
|
||||||
|
CSRI_OPENERR_CUSTERR = (1 << 3),
|
||||||
|
/** csri_openerr_flag.warncount valid */
|
||||||
|
CSRI_OPENERR_WARNCOUNT = (1 << 4)
|
||||||
|
};
|
||||||
|
|
||||||
|
/** returned error information.
|
||||||
|
* to be passed via csri_vardata.otherval as an openflag with
|
||||||
|
* extension ID #CSRI_EXT_OPENERR.
|
||||||
|
*
|
||||||
|
* Memory management by caller.
|
||||||
|
*
|
||||||
|
* The three error fields should only be filled when csri_open_file()
|
||||||
|
* / csri_open_mem() returned NULL. The warning counter can indicate
|
||||||
|
* information on successfully loaded scripts.
|
||||||
|
*/
|
||||||
|
struct csri_openerr_flag {
|
||||||
|
/** bitfield of valid information */
|
||||||
|
enum csri_openerr_flags flags;
|
||||||
|
/** posix errno value indicating the error occured */
|
||||||
|
int posixerrno;
|
||||||
|
/** Windows GetLastError value */
|
||||||
|
unsigned winerr;
|
||||||
|
/** renderer-specific custom error value.
|
||||||
|
* should be string-lookupable via csri_openerr_ext.strerror
|
||||||
|
* (csri_query_ext())
|
||||||
|
*/
|
||||||
|
union csri_vardata custerr;
|
||||||
|
/** warning count.
|
||||||
|
* The number of (renderer-specific) warnings that occured
|
||||||
|
* during loading the script. The content of these warnings
|
||||||
|
* should be retrievable via a renderer-specific extension.
|
||||||
|
*/
|
||||||
|
unsigned warncount;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** openerr extension information structure */
|
||||||
|
struct csri_openerr_ext {
|
||||||
|
/** csri_openerr_flag.custerr to string lookup.
|
||||||
|
* \param renderer the renderer handle.
|
||||||
|
* \param custerr renderer-specific error
|
||||||
|
* \param buffer buffer to fill with an UTF-8 error message.
|
||||||
|
* may be NULL; in that case only size is filled in
|
||||||
|
* \param size buffer size.\n
|
||||||
|
* in: maximum bytes to write to buffer, in bytes,
|
||||||
|
* including terminating \\0.\nthe renderer MUST always
|
||||||
|
* zero-terminate this, even when the space is not sufficient
|
||||||
|
* \n\n
|
||||||
|
* out: number of bytes (including terminating \\0) needed
|
||||||
|
* to return the full error message
|
||||||
|
*
|
||||||
|
* This function pointer may be NULL if the renderer does not
|
||||||
|
* return custom error codes. #CSRI_OPENERR_CUSTERR must not be
|
||||||
|
* used in that case.
|
||||||
|
*/
|
||||||
|
void (*strerror)(csri_rend *renderer, union csri_vardata custerr,
|
||||||
|
char *buffer, size_t *size);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CSRI_OPENERR_H */
|
143
csri/include/csri/stream.h
Normal file
143
csri/include/csri/stream.h
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** \file stream.h - subtitle streaming (MKV & co).
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* <b>THE SPECIFICATION OF THIS EXTENSION IS TENTATIVE
|
||||||
|
* AND NOT FINALIZED YET</b>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CSRI_STREAM_H
|
||||||
|
/** \cond */
|
||||||
|
#define _CSRI_STREAM_H 20070119
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \defgroup stream csri.stream.* extensions. */
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** stream extension group.
|
||||||
|
* note: you cannot query for csri.stream, you need
|
||||||
|
* to query for one of the streaming formats instead,
|
||||||
|
* which will return a csri_stream_ext pointer.
|
||||||
|
*/
|
||||||
|
#define CSRI_EXT_STREAM (csri_ext_id)"csri.stream"
|
||||||
|
|
||||||
|
/** Matroska-style ASS streaming.
|
||||||
|
* header contains standard SSA stuff, packet contains
|
||||||
|
* ReadOrder,Layer,Style,Speaker,MarginL,R,V,Effect,Text
|
||||||
|
*/
|
||||||
|
#define CSRI_EXT_STREAM_ASS CSRI_EXT_STREAM ".ass"
|
||||||
|
/** Simple text + timestamp streams */
|
||||||
|
#define CSRI_EXT_STREAM_TEXT CSRI_EXT_STREAM ".text"
|
||||||
|
/* missing: USF, MPEG-4 TT */
|
||||||
|
|
||||||
|
/** stream extension information structure */
|
||||||
|
struct csri_stream_ext {
|
||||||
|
/** create streaming renderer instance.
|
||||||
|
* \param renderer the renderer handle.
|
||||||
|
* \param header codec-private stream header.
|
||||||
|
* \param headerlen byte length of header data.
|
||||||
|
* \param flags openflags.
|
||||||
|
*
|
||||||
|
* not NULL if this extension is supported.
|
||||||
|
* may take various flags like csri_openerr_flag.
|
||||||
|
*
|
||||||
|
* the returned instance can be used with
|
||||||
|
* csri_request_fmt, csri_render and csri_close.
|
||||||
|
*/
|
||||||
|
csri_inst *(*init_stream)(csri_rend *renderer,
|
||||||
|
const void *header, size_t headerlen,
|
||||||
|
struct csri_openflag *flags);
|
||||||
|
|
||||||
|
/** process a streamed packet.
|
||||||
|
* \param inst instance created with init_stream.
|
||||||
|
* \param packet stream packet data.
|
||||||
|
* \param packetlen byte length of packet.
|
||||||
|
* \param pts_start start timestamp from container.
|
||||||
|
* \param pts_end end timestamp from container.
|
||||||
|
*
|
||||||
|
* add a single packet to the renderer instance.
|
||||||
|
*/
|
||||||
|
void (*push_packet)(csri_inst *inst,
|
||||||
|
const void *packet, size_t packetlen,
|
||||||
|
double pts_start, double pts_end);
|
||||||
|
|
||||||
|
/** discard processed packets.
|
||||||
|
* \param inst instance created with init_stream.
|
||||||
|
* \param all discard possibly-active packets too.\n
|
||||||
|
* a possibly-active packet is a packet which
|
||||||
|
* has not seen a csri_render call with a pts
|
||||||
|
* beyond its end timestamp yet.
|
||||||
|
*
|
||||||
|
* frees up memory, or can force a clean renderer.
|
||||||
|
* may be NULL if unsupported, check before calling!
|
||||||
|
*/
|
||||||
|
void (*discard)(csri_inst *inst, int all);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** streaming openflag ext for controlling subtitle lifetime */
|
||||||
|
#define CSRI_EXT_STREAM_DISCARD CSRI_EXT_STREAM ".discard"
|
||||||
|
|
||||||
|
/** subtitle packet lifetime */
|
||||||
|
enum csri_stream_discard {
|
||||||
|
/** lifetime: timestamp expiry.
|
||||||
|
* delete packets from csri_render if the current
|
||||||
|
* timestamp is beyond the packet's end timestamp.
|
||||||
|
* this should be the default
|
||||||
|
*/
|
||||||
|
CSRI_STREAM_DISCARD_TSEXPIRE = 0,
|
||||||
|
/** lifetime: discard immediately.
|
||||||
|
* discard all packets on returning from csri_render.
|
||||||
|
*/
|
||||||
|
CSRI_STREAM_DISCARD_IMMEDIATELY,
|
||||||
|
/** lifetime: discard explicitly.
|
||||||
|
* never discard packets, use csri_stream_ext.discard
|
||||||
|
*/
|
||||||
|
CSRI_STREAM_DISCARD_EXPLICIT
|
||||||
|
};
|
||||||
|
|
||||||
|
/** openflag for csri_stream_ext.init_stream */
|
||||||
|
struct csri_stream_discard_flag {
|
||||||
|
/** the lifetime to be used for subtitle packets */
|
||||||
|
enum csri_stream_discard lifetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CSRI_STREAM_H */
|
114
csri/include/subhelp.h
Normal file
114
csri/include/subhelp.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* csri: common subtitle renderer interface
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/** \file subhelp.h - subtitle helper API.
|
||||||
|
* $Id$ */
|
||||||
|
|
||||||
|
#ifndef _SUBHELP_H
|
||||||
|
#define _SUBHELP_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <csri/csri.h>
|
||||||
|
#include <csri/logging.h>
|
||||||
|
|
||||||
|
/** \defgroup subhelp subtitle filter helper API. */
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/** file opening wrapper.
|
||||||
|
* can be used to implement csri_open_file() by using csri_open_mem().
|
||||||
|
* \param renderer the renderer handle
|
||||||
|
* \param memopenfunc function pointer to a csri_open_mem() implementation
|
||||||
|
* \param filename name of file to open
|
||||||
|
* \param flags pointer #csri_openflag.\n
|
||||||
|
* subhelp_open_file will fill in csri.openerr if present
|
||||||
|
* \return return value from memopenfunc or NULL on fs error
|
||||||
|
*/
|
||||||
|
extern csri_inst *subhelp_open_file(csri_rend *renderer,
|
||||||
|
csri_inst *(*memopenfunc)(csri_rend *renderer, const void *data,
|
||||||
|
size_t length, struct csri_openflag *flags),
|
||||||
|
const char *filename, struct csri_openflag *flags);
|
||||||
|
|
||||||
|
|
||||||
|
/** logging extension query function.
|
||||||
|
* call from csri_query_ext BEFORE checking whether the renderer.
|
||||||
|
* \code
|
||||||
|
* void *csri_query_ext(csri_rend *rend, csri_ext_id extname) {
|
||||||
|
* void *rv;
|
||||||
|
* if ((rv = subhelp_query_ext_logging(extname)))
|
||||||
|
* return rv;
|
||||||
|
* if (!rend)
|
||||||
|
* return NULL;
|
||||||
|
* ...
|
||||||
|
* \endcode
|
||||||
|
* \param extname the extension name. compared to "csri.logging" by
|
||||||
|
* this function.
|
||||||
|
* \return logging extension pointer, if the extension name matched.
|
||||||
|
* NULL otherwise.
|
||||||
|
*/
|
||||||
|
extern void *subhelp_query_ext_logging(csri_ext_id extname);
|
||||||
|
|
||||||
|
/** configure other renderer with our settings.
|
||||||
|
* \param logext csri.logging from configuree.
|
||||||
|
*/
|
||||||
|
extern void subhelp_logging_pass(struct csri_logging_ext *logext);
|
||||||
|
|
||||||
|
/** logging function.
|
||||||
|
* \param severity severity of this message, as defined by csri.logging
|
||||||
|
* \param msg log message, one line, without \\n at the end.
|
||||||
|
*/
|
||||||
|
extern void subhelp_log(enum csri_logging_severity severity,
|
||||||
|
const char *msg, ...)
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__((format(printf, 2, 3)))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
/** logging function, varargs version.
|
||||||
|
* \param severity severity of this message, as defined by csri.logging
|
||||||
|
* \param msg log message, one line, without \\n at the end.
|
||||||
|
* \param args argument list
|
||||||
|
*/
|
||||||
|
extern void subhelp_vlog(enum csri_logging_severity severity,
|
||||||
|
const char *msg, va_list args)
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__((format(printf, 2, 0)))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
/** logging function, fixed string version.
|
||||||
|
* \param severity severity of this message, as defined by csri.logging
|
||||||
|
* \param msg log message, one line, without \\n at the end.
|
||||||
|
*/
|
||||||
|
extern void subhelp_slog(enum csri_logging_severity severity, const char *msg);
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#endif /* _SUBHELP_H */
|
||||||
|
|
43
csri/include/visibility.h
Normal file
43
csri/include/visibility.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _VISIBILITY_H
|
||||||
|
#define _VISIBILITY_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define export __declspec(dllexport)
|
||||||
|
#define internal
|
||||||
|
#define hidden
|
||||||
|
#elif HAVE_GCC_VISIBILITY
|
||||||
|
#define export __attribute__((visibility ("default")))
|
||||||
|
#define internal __attribute__((visibility ("internal")))
|
||||||
|
#define hidden __attribute__((visibility ("hidden")))
|
||||||
|
#else
|
||||||
|
#define export
|
||||||
|
#define internal
|
||||||
|
#define hidden
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _VISIBILITY_H */
|
14
csri/lib/Makefile.am
Normal file
14
csri/lib/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
if BUILD_MINGW
|
||||||
|
PLATF = win32
|
||||||
|
else
|
||||||
|
PLATF = posix
|
||||||
|
AM_CPPFLAGS = -DCSRI_PATH="\"$(csri_path)\""
|
||||||
|
endif
|
||||||
|
lib_LTLIBRARIES = libcsri.la
|
||||||
|
noinst_HEADERS = csrilib.h posix/csrilib_os.h win32/csrilib_os.h
|
||||||
|
libcsri_la_SOURCES = list.c wrap.c $(PLATF)/enumerate.c
|
||||||
|
libcsri_la_CFLAGS = -I$(top_srcdir)/lib/posix -I$(top_srcdir)/include
|
||||||
|
libcsri_la_LIBADD = ../subhelp/libsubhelp_la-logging.lo
|
||||||
|
libcsri_la_LDFLAGS = -static
|
||||||
|
|
||||||
|
EXTRA_DIST = posix/enumerate.c win32/enumerate.c
|
85
csri/lib/csrilib.h
Normal file
85
csri/lib/csrilib.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CSRILIB_H
|
||||||
|
#define _CSRILIB_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "visibility.h"
|
||||||
|
|
||||||
|
#define CSRIAPI export
|
||||||
|
|
||||||
|
#include <csri/csri.h>
|
||||||
|
#include <csri/stream.h>
|
||||||
|
#include "csrilib_os.h"
|
||||||
|
|
||||||
|
struct csri_wrap_rend {
|
||||||
|
struct csri_wrap_rend *next;
|
||||||
|
|
||||||
|
csri_rend *rend;
|
||||||
|
csri_inst *(*open_file)(csri_rend *renderer,
|
||||||
|
const char *filename, struct csri_openflag *flags);
|
||||||
|
csri_inst *(*open_mem)(csri_rend *renderer,
|
||||||
|
const void *data, size_t length,
|
||||||
|
struct csri_openflag *flags);
|
||||||
|
void (*close)(csri_inst *inst);
|
||||||
|
int (*request_fmt)(csri_inst *inst, const struct csri_fmt *fmt);
|
||||||
|
void (*render)(csri_inst *inst, struct csri_frame *frame,
|
||||||
|
double time);
|
||||||
|
void *(*query_ext)(csri_rend *rend, csri_ext_id extname);
|
||||||
|
struct csri_stream_ext stream_ass, stream_text;
|
||||||
|
csri_inst *(*init_stream_ass)(csri_rend *renderer,
|
||||||
|
const void *header, size_t headerlen,
|
||||||
|
struct csri_openflag *flags);
|
||||||
|
csri_inst *(*init_stream_text)(csri_rend *renderer,
|
||||||
|
const void *header, size_t headerlen,
|
||||||
|
struct csri_openflag *flags);
|
||||||
|
|
||||||
|
struct csri_info *info;
|
||||||
|
struct csrilib_os os;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct csri_wrap_inst {
|
||||||
|
struct csri_wrap_inst *next;
|
||||||
|
|
||||||
|
csri_inst *inst;
|
||||||
|
struct csri_wrap_rend *wrend;
|
||||||
|
void (*close)(csri_inst *inst);
|
||||||
|
int (*request_fmt)(csri_inst *inst, const struct csri_fmt *fmt);
|
||||||
|
void (*render)(csri_inst *inst, struct csri_frame *frame,
|
||||||
|
double time);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct csri_wrap_rend *wraprends;
|
||||||
|
|
||||||
|
extern struct csri_wrap_rend *csrilib_rend_lookup(csri_rend *rend);
|
||||||
|
extern void csrilib_rend_initadd(struct csri_wrap_rend *wrend);
|
||||||
|
|
||||||
|
extern struct csri_wrap_inst *csrilib_inst_lookup(csri_inst *inst);
|
||||||
|
extern csri_inst *csrilib_inst_initadd(struct csri_wrap_rend *wrend,
|
||||||
|
csri_inst *inst);
|
||||||
|
extern void csrilib_inst_remove(struct csri_wrap_inst *winst);
|
||||||
|
|
||||||
|
extern void csrilib_os_init();
|
||||||
|
|
||||||
|
#endif /*_CSRILIB_H */
|
148
csri/lib/list.c
Normal file
148
csri/lib/list.c
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "csrilib.h"
|
||||||
|
|
||||||
|
struct csri_wrap_rend *wraprends = NULL;
|
||||||
|
|
||||||
|
struct csri_wrap_rend *csrilib_rend_lookup(csri_rend *rend)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrap = wraprends;
|
||||||
|
for (; wrap; wrap = wrap->next)
|
||||||
|
if (wrap->rend == rend)
|
||||||
|
return wrap;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INSTHASHSZ 256
|
||||||
|
#define HASH(x) (((intptr_t)(x) & 0xff00) >> 8)
|
||||||
|
static struct csri_wrap_inst *wrapinsts[INSTHASHSZ];
|
||||||
|
|
||||||
|
struct csri_wrap_inst *csrilib_inst_lookup(csri_inst *inst)
|
||||||
|
{
|
||||||
|
struct csri_wrap_inst *ent = wrapinsts[HASH(inst)];
|
||||||
|
while (ent && ent->inst != inst)
|
||||||
|
ent = ent->next;
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_inst *csrilib_inst_initadd(struct csri_wrap_rend *wrend,
|
||||||
|
csri_inst *inst)
|
||||||
|
{
|
||||||
|
struct csri_wrap_inst *winst = (struct csri_wrap_inst *)
|
||||||
|
malloc(sizeof(struct csri_wrap_inst)),
|
||||||
|
**pnext;
|
||||||
|
if (!winst) {
|
||||||
|
wrend->close(inst);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
winst->wrend = wrend;
|
||||||
|
winst->inst = inst;
|
||||||
|
winst->close = wrend->close;
|
||||||
|
winst->request_fmt = wrend->request_fmt;
|
||||||
|
winst->render = wrend->render;
|
||||||
|
winst->next = NULL;
|
||||||
|
pnext = &wrapinsts[HASH(inst)];
|
||||||
|
while (*pnext)
|
||||||
|
pnext = &(*pnext)->next;
|
||||||
|
*pnext = winst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csrilib_inst_remove(struct csri_wrap_inst *winst)
|
||||||
|
{
|
||||||
|
struct csri_wrap_inst **pnext = &wrapinsts[HASH(winst->inst)];
|
||||||
|
while (*pnext && *pnext != winst)
|
||||||
|
pnext = &(*pnext)->next;
|
||||||
|
if (!*pnext)
|
||||||
|
return;
|
||||||
|
*pnext = (*pnext)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csrilib_rend_initadd(struct csri_wrap_rend *wrend)
|
||||||
|
{
|
||||||
|
wrend->next = wraprends;
|
||||||
|
wraprends = wrend;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int initialized = 0;
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_default()
|
||||||
|
{
|
||||||
|
if (!initialized) {
|
||||||
|
csrilib_os_init();
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
|
if (!wraprends)
|
||||||
|
return NULL;
|
||||||
|
return wraprends->rend;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_next(csri_rend *prev)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend = csrilib_rend_lookup(prev);
|
||||||
|
if (!wrend || !wrend->next)
|
||||||
|
return NULL;
|
||||||
|
return wrend->next->rend;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_byname(const char *name, const char *specific)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend;
|
||||||
|
if (!initialized) {
|
||||||
|
csrilib_os_init();
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
for (wrend = wraprends; wrend; wrend = wrend->next) {
|
||||||
|
if (strcmp(wrend->info->name, name))
|
||||||
|
continue;
|
||||||
|
if (specific && strcmp(wrend->info->specific, specific))
|
||||||
|
continue;
|
||||||
|
return wrend->rend;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
csri_rend *csri_renderer_byext(unsigned n_ext, csri_ext_id *ext)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend;
|
||||||
|
unsigned i;
|
||||||
|
if (!initialized) {
|
||||||
|
csrilib_os_init();
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
|
for (wrend = wraprends; wrend; wrend = wrend->next) {
|
||||||
|
for (i = 0; i < n_ext; i++) {
|
||||||
|
if (!wrend->query_ext(wrend->rend, ext[i]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == n_ext)
|
||||||
|
return wrend->rend;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
27
csri/lib/posix/csrilib_os.h
Normal file
27
csri/lib/posix/csrilib_os.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct csrilib_os {
|
||||||
|
void *dlhandle;
|
||||||
|
dev_t device;
|
||||||
|
ino_t inode;
|
||||||
|
};
|
199
csri/lib/posix/enumerate.c
Normal file
199
csri/lib/posix/enumerate.c
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 200112L /* for PATH_MAX */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "../csrilib.h"
|
||||||
|
#include "subhelp.h"
|
||||||
|
|
||||||
|
static const char csri_path[] = CSRI_PATH;
|
||||||
|
|
||||||
|
static void csrilib_enum_dir(const char *dir);
|
||||||
|
|
||||||
|
static void csrilib_add(csri_rend *rend,
|
||||||
|
const struct csri_wrap_rend *tmp, struct csri_info *info)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend = (struct csri_wrap_rend *)
|
||||||
|
malloc(sizeof(struct csri_wrap_rend));
|
||||||
|
if (!wrend)
|
||||||
|
return;
|
||||||
|
memcpy(wrend, tmp, sizeof(struct csri_wrap_rend));
|
||||||
|
wrend->rend = rend;
|
||||||
|
wrend->info = info;
|
||||||
|
csrilib_rend_initadd(wrend);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_do_load(const char *filename, dev_t device, ino_t inode)
|
||||||
|
{
|
||||||
|
void *dlhandle = dlopen(filename, RTLD_NOW);
|
||||||
|
struct csri_wrap_rend tmp;
|
||||||
|
csri_rend *rend;
|
||||||
|
struct csri_info *(*renderer_info)(csri_rend *rend);
|
||||||
|
csri_rend *(*renderer_default)();
|
||||||
|
csri_rend *(*renderer_next)(csri_rend *prev);
|
||||||
|
const char *sym;
|
||||||
|
|
||||||
|
|
||||||
|
if (!dlhandle) {
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "dlopen(\"%s\") says: %s",
|
||||||
|
filename, dlerror());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dlsym(dlhandle, "csri_library")) {
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "ignoring library %s",
|
||||||
|
filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subhelp_log(CSRI_LOG_INFO, "loading %s", filename);
|
||||||
|
|
||||||
|
tmp.os.dlhandle = dlhandle;
|
||||||
|
tmp.os.device = device;
|
||||||
|
tmp.os.inode = inode;
|
||||||
|
|
||||||
|
/* okay, this is uber-ugly. either I end up casting from void *
|
||||||
|
* to a fptr (which yields a cast warning), or I do a *(void **)&tmp.x
|
||||||
|
* (which yields a strict-aliasing warning).
|
||||||
|
* casting via char* works because char* can alias anything.
|
||||||
|
*/
|
||||||
|
#define _dl_map_function(x, dst) do { \
|
||||||
|
char *t1 = (char *)&dst; \
|
||||||
|
union x { void *ptr; } *ptr = (union x *)t1; \
|
||||||
|
sym = "csri_" # x; \
|
||||||
|
ptr->ptr = dlsym(dlhandle, sym);\
|
||||||
|
if (!ptr->ptr) goto out_dlfail; } while (0)
|
||||||
|
#define dl_map_function(x) _dl_map_function(x, tmp.x)
|
||||||
|
dl_map_function(query_ext);
|
||||||
|
subhelp_logging_pass((struct csri_logging_ext *)
|
||||||
|
tmp.query_ext(NULL, CSRI_EXT_LOGGING));
|
||||||
|
dl_map_function(open_file);
|
||||||
|
dl_map_function(open_mem);
|
||||||
|
dl_map_function(close);
|
||||||
|
dl_map_function(request_fmt);
|
||||||
|
dl_map_function(render);
|
||||||
|
#define dl_map_local(x) _dl_map_function(x, x)
|
||||||
|
dl_map_local(renderer_info);
|
||||||
|
dl_map_local(renderer_default);
|
||||||
|
dl_map_local(renderer_next);
|
||||||
|
|
||||||
|
rend = renderer_default();
|
||||||
|
while (rend) {
|
||||||
|
csrilib_add(rend, &tmp, renderer_info(rend));
|
||||||
|
rend = renderer_next(rend);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_dlfail:
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "%s: symbol %s not found (%s)",
|
||||||
|
filename, sym, dlerror());
|
||||||
|
dlclose(dlhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_load(const char *filename)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *rend;
|
||||||
|
struct stat st;
|
||||||
|
if (stat(filename, &st))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
csrilib_enum_dir(filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!S_ISREG(st.st_mode))
|
||||||
|
return;
|
||||||
|
if (access(filename, X_OK))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (rend = wraprends; rend; rend = rend->next)
|
||||||
|
if (rend->os.device == st.st_dev
|
||||||
|
&& rend->os.inode == st.st_ino)
|
||||||
|
return;
|
||||||
|
|
||||||
|
csrilib_do_load(filename, st.st_dev, st.st_ino);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_enum_dir(const char *dir)
|
||||||
|
{
|
||||||
|
DIR *dirh;
|
||||||
|
struct dirent *e;
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
dirh = opendir(dir);
|
||||||
|
if (!dirh) {
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "ignoring directory \"%s\":"
|
||||||
|
" %s (%d)", dir, strerror(errno), errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subhelp_log(CSRI_LOG_INFO, "scanning directory \"%s\"", dir);
|
||||||
|
while ((e = readdir(dirh))) {
|
||||||
|
if (e->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
|
snprintf(buf, sizeof(buf), "%s/%s", dir, e->d_name);
|
||||||
|
csrilib_load(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dirh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_expand_enum_dir(const char *dir)
|
||||||
|
{
|
||||||
|
if (dir[0] == '~' && (dir[1] == '\0' || dir[1] == '/')) {
|
||||||
|
char buf[PATH_MAX], *home = getenv("HOME");
|
||||||
|
if (!home)
|
||||||
|
home = "";
|
||||||
|
snprintf(buf, sizeof(buf), "%s%s", home, dir + 1);
|
||||||
|
csrilib_enum_dir(buf);
|
||||||
|
} else
|
||||||
|
csrilib_enum_dir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void csrilib_os_init()
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
char *envpath = getenv("CSRI_PATH");
|
||||||
|
char *pos, *next = buf;
|
||||||
|
|
||||||
|
if (envpath)
|
||||||
|
snprintf(buf, sizeof(buf), "%s:%s", csri_path, envpath);
|
||||||
|
else {
|
||||||
|
strncpy(buf, csri_path, sizeof(buf));
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
pos = next;
|
||||||
|
next = strchr(pos, ':');
|
||||||
|
if (next)
|
||||||
|
*next++ = '\0';
|
||||||
|
csrilib_expand_enum_dir(pos);
|
||||||
|
} while (next);
|
||||||
|
}
|
||||||
|
|
25
csri/lib/win32/csrilib_os.h
Normal file
25
csri/lib/win32/csrilib_os.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
struct csrilib_os {
|
||||||
|
HMODULE dlhandle;
|
||||||
|
};
|
175
csri/lib/win32/enumerate.c
Normal file
175
csri/lib/win32/enumerate.c
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../csrilib.h"
|
||||||
|
#include "subhelp.h"
|
||||||
|
|
||||||
|
static void csrilib_enum_dir(const wchar_t *dir);
|
||||||
|
|
||||||
|
static const char *get_errstr()
|
||||||
|
{
|
||||||
|
static char msg[2048];
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
|
||||||
|
if (!FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, err, 0, msg, sizeof(msg), NULL))
|
||||||
|
strcpy(msg, "Unknown Error");
|
||||||
|
else {
|
||||||
|
int msglen = strlen(msg) - 1;
|
||||||
|
if (msg[msglen] == '\n')
|
||||||
|
msg[msglen] = '\0';
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_add(csri_rend *rend,
|
||||||
|
const struct csri_wrap_rend *tmp, struct csri_info *info)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend = (struct csri_wrap_rend *)
|
||||||
|
malloc(sizeof(struct csri_wrap_rend));
|
||||||
|
if (!wrend)
|
||||||
|
return;
|
||||||
|
memcpy(wrend, tmp, sizeof(struct csri_wrap_rend));
|
||||||
|
wrend->rend = rend;
|
||||||
|
wrend->info = info;
|
||||||
|
csrilib_rend_initadd(wrend);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_do_load(const wchar_t *filename)
|
||||||
|
{
|
||||||
|
HMODULE dlhandle = LoadLibraryExW(filename, NULL,
|
||||||
|
LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
struct csri_wrap_rend tmp;
|
||||||
|
csri_rend *rend;
|
||||||
|
struct csri_info *(*renderer_info)(csri_rend *rend);
|
||||||
|
csri_rend *(*renderer_default)();
|
||||||
|
csri_rend *(*renderer_next)(csri_rend *prev);
|
||||||
|
const char *sym;
|
||||||
|
|
||||||
|
if (!dlhandle) {
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "LoadLibraryEx(\"%ls\") failed: "
|
||||||
|
"%s", filename, get_errstr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GetProcAddress(dlhandle, "csri_library")) {
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "ignoring library %ls",
|
||||||
|
filename);
|
||||||
|
goto out_freelib;
|
||||||
|
}
|
||||||
|
subhelp_log(CSRI_LOG_INFO, "loading %ls", filename);
|
||||||
|
|
||||||
|
tmp.os.dlhandle = dlhandle;
|
||||||
|
|
||||||
|
/* okay, this is uber-ugly. either I end up casting from void *
|
||||||
|
* to a fptr (which yields a cast warning), or I do a *(void **)&tmp.x
|
||||||
|
* (which yields a strict-aliasing warning).
|
||||||
|
* casting via char* works because char* can alias anything.
|
||||||
|
*/
|
||||||
|
#define _dl_map_function(x, dst) do { \
|
||||||
|
char *t1 = (char *)&dst; \
|
||||||
|
union x { FARPROC ptr; } *ptr = (union x *)t1; \
|
||||||
|
sym = "csri_" # x; \
|
||||||
|
ptr->ptr = GetProcAddress(dlhandle, sym);\
|
||||||
|
if (!ptr->ptr) goto out_dlfail; } while (0)
|
||||||
|
#define dl_map_function(x) _dl_map_function(x, tmp.x)
|
||||||
|
dl_map_function(query_ext);
|
||||||
|
subhelp_logging_pass((struct csri_logging_ext *)
|
||||||
|
tmp.query_ext(NULL, CSRI_EXT_LOGGING));
|
||||||
|
dl_map_function(open_file);
|
||||||
|
dl_map_function(open_mem);
|
||||||
|
dl_map_function(close);
|
||||||
|
dl_map_function(request_fmt);
|
||||||
|
dl_map_function(render);
|
||||||
|
#define dl_map_local(x) _dl_map_function(x, x)
|
||||||
|
dl_map_local(renderer_info);
|
||||||
|
dl_map_local(renderer_default);
|
||||||
|
dl_map_local(renderer_next);
|
||||||
|
|
||||||
|
rend = renderer_default();
|
||||||
|
while (rend) {
|
||||||
|
csrilib_add(rend, &tmp, renderer_info(rend));
|
||||||
|
rend = renderer_next(rend);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_dlfail:
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "%ls: symbol %s not found (%s)",
|
||||||
|
filename, sym, get_errstr());
|
||||||
|
out_freelib:
|
||||||
|
FreeLibrary(dlhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_load(const wchar_t *filename)
|
||||||
|
{
|
||||||
|
DWORD attr = GetFileAttributesW(filename);
|
||||||
|
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
csrilib_enum_dir(filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
csrilib_do_load(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csrilib_enum_dir(const wchar_t *dir)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATAW data;
|
||||||
|
HANDLE res;
|
||||||
|
wchar_t buf[MAX_PATH];
|
||||||
|
|
||||||
|
_snwprintf(buf, sizeof(buf) / sizeof(buf[0]), L"%ls\\*", dir);
|
||||||
|
res = FindFirstFileW(buf, &data);
|
||||||
|
if (res == INVALID_HANDLE_VALUE) {
|
||||||
|
subhelp_log(CSRI_LOG_WARNING, "ignoring directory \"%ls\": %s",
|
||||||
|
dir, get_errstr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subhelp_log(CSRI_LOG_INFO, "scanning directory \"%ls\"", dir);
|
||||||
|
do {
|
||||||
|
if (data.cFileName[0] == '.')
|
||||||
|
continue;
|
||||||
|
_snwprintf(buf, sizeof(buf) / sizeof(buf[0]),
|
||||||
|
L"%ls\\%ls", dir, data.cFileName);
|
||||||
|
csrilib_load(buf);
|
||||||
|
} while (FindNextFileW(res, &data));
|
||||||
|
FindClose(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void csrilib_os_init()
|
||||||
|
{
|
||||||
|
wchar_t filename[MAX_PATH], *slash;
|
||||||
|
DWORD rv = GetModuleFileNameW(NULL, filename, MAX_PATH);
|
||||||
|
if (!rv)
|
||||||
|
*filename = L'\0';
|
||||||
|
slash = wcsrchr(filename, L'\\');
|
||||||
|
slash = slash ? slash + 1 : filename;
|
||||||
|
*slash = L'\0';
|
||||||
|
wcsncpy(slash, L"csri", filename + MAX_PATH - slash);
|
||||||
|
csrilib_enum_dir(filename);
|
||||||
|
}
|
||||||
|
|
118
csri/lib/wrap.c
Normal file
118
csri/lib/wrap.c
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "csrilib.h"
|
||||||
|
#include "subhelp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
csri_inst *csri_open_file(csri_rend *rend,
|
||||||
|
const char *filename, struct csri_openflag *flags)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend = csrilib_rend_lookup(rend);
|
||||||
|
if (!wrend)
|
||||||
|
return NULL;
|
||||||
|
return csrilib_inst_initadd(wrend,
|
||||||
|
wrend->open_file(rend, filename, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define instance_wrapper(wrapname, funcname) \
|
||||||
|
csri_inst *wrapname(csri_rend *rend, \
|
||||||
|
const void *data, size_t length, struct csri_openflag *flags) \
|
||||||
|
{ \
|
||||||
|
struct csri_wrap_rend *wrend = csrilib_rend_lookup(rend); \
|
||||||
|
if (!wrend) \
|
||||||
|
return NULL; \
|
||||||
|
return csrilib_inst_initadd(wrend, \
|
||||||
|
wrend->funcname(rend, data, length, flags)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
instance_wrapper(csri_open_mem, open_mem)
|
||||||
|
static instance_wrapper(wrap_init_stream_ass, init_stream_ass)
|
||||||
|
static instance_wrapper(wrap_init_stream_text, init_stream_text)
|
||||||
|
|
||||||
|
void *csri_query_ext(csri_rend *rend, csri_ext_id extname)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend;
|
||||||
|
void *rv;
|
||||||
|
|
||||||
|
if (!rend && (rv = subhelp_query_ext_logging(extname)))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
wrend = csrilib_rend_lookup(rend);
|
||||||
|
if (!wrend)
|
||||||
|
return NULL;
|
||||||
|
rv = wrend->query_ext(rend, extname);
|
||||||
|
if (rv && !strcmp(extname, CSRI_EXT_STREAM_ASS)) {
|
||||||
|
struct csri_stream_ext *e = (struct csri_stream_ext *)rv;
|
||||||
|
memcpy(&wrend->stream_ass, e, sizeof(*e));
|
||||||
|
wrend->init_stream_ass = e->init_stream;
|
||||||
|
wrend->stream_ass.init_stream = wrap_init_stream_ass;
|
||||||
|
return &wrend->stream_ass;
|
||||||
|
}
|
||||||
|
if (rv && !strcmp(extname, CSRI_EXT_STREAM_TEXT)) {
|
||||||
|
struct csri_stream_ext *e = (struct csri_stream_ext *)rv;
|
||||||
|
memcpy(&wrend->stream_text, e, sizeof(*e));
|
||||||
|
wrend->init_stream_text = e->init_stream;
|
||||||
|
wrend->stream_text.init_stream = wrap_init_stream_text;
|
||||||
|
return &wrend->stream_text;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct csri_info *csri_renderer_info(csri_rend *rend)
|
||||||
|
{
|
||||||
|
struct csri_wrap_rend *wrend = csrilib_rend_lookup(rend);
|
||||||
|
if (!wrend)
|
||||||
|
return NULL;
|
||||||
|
return wrend->info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csri_close(csri_inst *inst)
|
||||||
|
{
|
||||||
|
struct csri_wrap_inst *winst = csrilib_inst_lookup(inst);
|
||||||
|
if (!winst)
|
||||||
|
return;
|
||||||
|
winst->close(inst);
|
||||||
|
csrilib_inst_remove(winst);
|
||||||
|
}
|
||||||
|
|
||||||
|
int csri_request_fmt(csri_inst *inst, const struct csri_fmt *fmt)
|
||||||
|
{
|
||||||
|
struct csri_wrap_inst *winst = csrilib_inst_lookup(inst);
|
||||||
|
if (!winst)
|
||||||
|
return 0;
|
||||||
|
return winst->request_fmt(inst, fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void csri_render(csri_inst *inst, struct csri_frame *frame,
|
||||||
|
double time)
|
||||||
|
{
|
||||||
|
struct csri_wrap_inst *winst = csrilib_inst_lookup(inst);
|
||||||
|
if (!winst)
|
||||||
|
return;
|
||||||
|
winst->render(inst, frame, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *csri_library()
|
||||||
|
{
|
||||||
|
return "DEV";
|
||||||
|
}
|
||||||
|
|
10
csri/subhelp/Makefile.am
Normal file
10
csri/subhelp/Makefile.am
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
if BUILD_MINGW
|
||||||
|
PLATF = win32
|
||||||
|
else
|
||||||
|
PLATF = posix
|
||||||
|
endif
|
||||||
|
noinst_LTLIBRARIES = libsubhelp.la
|
||||||
|
libsubhelp_la_SOURCES = $(PLATF)/openfile.c logging.c
|
||||||
|
libsubhelp_la_CFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
EXTRA_DIST = win32/openfile.c posix/openfile.c
|
102
csri/subhelp/logging.c
Normal file
102
csri/subhelp/logging.c
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "visibility.h"
|
||||||
|
#include "subhelp.h"
|
||||||
|
#include <csri/logging.h>
|
||||||
|
|
||||||
|
static void *appdata = NULL;
|
||||||
|
static csri_logging_func *logfunc = NULL;
|
||||||
|
|
||||||
|
void setlogcallback(csri_logging_func *_logfunc, void *_appdata) hidden;
|
||||||
|
|
||||||
|
void setlogcallback(csri_logging_func *_logfunc, void *_appdata)
|
||||||
|
{
|
||||||
|
logfunc = _logfunc;
|
||||||
|
appdata = _appdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct csri_logging_ext logext = {
|
||||||
|
setlogcallback
|
||||||
|
};
|
||||||
|
|
||||||
|
void subhelp_logging_pass(struct csri_logging_ext *nlogext)
|
||||||
|
{
|
||||||
|
if (!nlogext || !nlogext->set_logcallback)
|
||||||
|
return;
|
||||||
|
nlogext->set_logcallback(logfunc, appdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *subhelp_query_ext_logging(csri_ext_id extname)
|
||||||
|
{
|
||||||
|
if (strcmp(extname, CSRI_EXT_LOGGING))
|
||||||
|
return NULL;
|
||||||
|
return &logext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void subhelp_log(enum csri_logging_severity severity, const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, msg);
|
||||||
|
subhelp_vlog(severity, msg, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void subhelp_vlog(enum csri_logging_severity severity,
|
||||||
|
const char *msg, va_list args)
|
||||||
|
{
|
||||||
|
char *buffer;
|
||||||
|
const char *final;
|
||||||
|
size_t size = 256;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
buffer = (char *)malloc(256);
|
||||||
|
while (buffer) {
|
||||||
|
n = vsnprintf(buffer, size, msg, args);
|
||||||
|
if (n >= 0 && (unsigned)n < size)
|
||||||
|
break;
|
||||||
|
size = n > 0 ? (unsigned)n + 1 : size * 2;
|
||||||
|
buffer = (char *)realloc(buffer, size);
|
||||||
|
}
|
||||||
|
final = buffer ? buffer : "<out of memory in logging function>";
|
||||||
|
subhelp_slog(severity, final);
|
||||||
|
if (buffer)
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void subhelp_slog(enum csri_logging_severity severity, const char *msg)
|
||||||
|
{
|
||||||
|
if (logfunc)
|
||||||
|
logfunc(appdata, severity, msg);
|
||||||
|
else {
|
||||||
|
fprintf(stderr, msg);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
82
csri/subhelp/posix/openfile.c
Normal file
82
csri/subhelp/posix/openfile.c
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "acconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "subhelp.h"
|
||||||
|
#include <csri/openerr.h>
|
||||||
|
|
||||||
|
csri_inst *subhelp_open_file(csri_rend *renderer,
|
||||||
|
csri_inst *(*memopenfunc)(csri_rend *renderer, const void *data,
|
||||||
|
size_t length, struct csri_openflag *flags),
|
||||||
|
const char *filename, struct csri_openflag *flags)
|
||||||
|
{
|
||||||
|
csri_inst *rv = NULL;
|
||||||
|
void *data;
|
||||||
|
int fd;
|
||||||
|
struct stat st;
|
||||||
|
struct csri_openflag *err;
|
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
goto out_err;
|
||||||
|
if (fstat(fd, &st)
|
||||||
|
|| !(data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE,
|
||||||
|
fd, 0))) {
|
||||||
|
close(fd);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = memopenfunc(renderer, data, st.st_size, flags);
|
||||||
|
|
||||||
|
munmap(data, st.st_size);
|
||||||
|
close(fd);
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
for (err = flags; err; err = err->next)
|
||||||
|
if (!strcmp(err->name, CSRI_EXT_OPENERR))
|
||||||
|
break;
|
||||||
|
if (err) {
|
||||||
|
struct csri_openerr_flag *errd = (struct csri_openerr_flag *)
|
||||||
|
err->data.otherval;
|
||||||
|
errd->flags = CSRI_OPENERR_FILLED | CSRI_OPENERR_ERRNO;
|
||||||
|
errd->posixerrno = errno;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
84
csri/subhelp/win32/openfile.c
Normal file
84
csri/subhelp/win32/openfile.c
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* asa: portable digital subtitle renderer
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2007 David Lamparter
|
||||||
|
*
|
||||||
|
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "subhelp.h"
|
||||||
|
#include <csri/openerr.h>
|
||||||
|
|
||||||
|
csri_inst *subhelp_open_file(csri_rend *renderer,
|
||||||
|
csri_inst *(*memopenfunc)(csri_rend *renderer, const void *data,
|
||||||
|
size_t length, struct csri_openflag *flags),
|
||||||
|
const char *filename, struct csri_openflag *flags)
|
||||||
|
{
|
||||||
|
csri_inst *rv = NULL;
|
||||||
|
void *data;
|
||||||
|
struct csri_openflag *err;
|
||||||
|
HANDLE file, mapping;
|
||||||
|
DWORD size;
|
||||||
|
int namesize;
|
||||||
|
wchar_t *namebuf;
|
||||||
|
|
||||||
|
namesize = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
|
||||||
|
if (!namesize)
|
||||||
|
goto out_err;
|
||||||
|
namesize++;
|
||||||
|
namebuf = malloc(sizeof(wchar_t) * namesize);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, filename, -1, namebuf, namesize);
|
||||||
|
|
||||||
|
file = CreateFileW(namebuf, GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
free(namebuf);
|
||||||
|
if (file == INVALID_HANDLE_VALUE)
|
||||||
|
goto out_err;
|
||||||
|
size = GetFileSize(file, NULL);
|
||||||
|
if (size == INVALID_FILE_SIZE || !size)
|
||||||
|
goto out_closefile;
|
||||||
|
mapping = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
|
if (!mapping)
|
||||||
|
goto out_closefile;
|
||||||
|
data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, size);
|
||||||
|
if (!data)
|
||||||
|
goto out_closemap;
|
||||||
|
|
||||||
|
rv = memopenfunc(renderer, data, size, flags);
|
||||||
|
|
||||||
|
UnmapViewOfFile(data);
|
||||||
|
CloseHandle(mapping);
|
||||||
|
CloseHandle(file);
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
out_closemap:
|
||||||
|
CloseHandle(mapping);
|
||||||
|
out_closefile:
|
||||||
|
CloseHandle(file);
|
||||||
|
out_err:
|
||||||
|
for (err = flags; err; err = err->next)
|
||||||
|
if (!strcmp(err->name, CSRI_EXT_OPENERR))
|
||||||
|
break;
|
||||||
|
if (err) {
|
||||||
|
struct csri_openerr_flag *errd = err->data.otherval;
|
||||||
|
errd->flags = CSRI_OPENERR_FILLED | CSRI_OPENERR_WINERR;
|
||||||
|
errd->winerr = GetLastError();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue