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
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