forked from bartvdbraak/blender
Quicktime: remove backend with the old quicktime API, and keep the QTKit backend.
This means that if you have WITH_BF_QUICKTIME or WITH_CODEC_QUICKTIME enabled, it will always use QTKit. The old backend was only used on 32 bit OS X builds, now 32 and 64 bit builds will give consistent input/output. On Windows or Linux quicktime isn't being used.
This commit is contained in:
parent
299812f28d
commit
99c5e71397
@ -218,7 +218,7 @@ option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)
|
||||
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
|
||||
|
||||
option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
|
||||
if(APPLE OR (WIN32 AND NOT UNIX))
|
||||
if(APPLE)
|
||||
option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" OFF)
|
||||
endif()
|
||||
|
||||
@ -380,11 +380,7 @@ if(APPLE)
|
||||
add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
|
||||
option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF)
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
|
||||
set(USE_QTKIT ON CACHE BOOL "ON" FORCE) # no Quicktime in 64bit
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@ -491,14 +487,6 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
if(WITH_CODEC_QUICKTIME)
|
||||
message(FATAL_ERROR "MINGW requires WITH_CODEC_QUICKTIME to be OFF "
|
||||
"because it is currently unsupported, remove this "
|
||||
"line if youre a developer who wants to add support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
||||
|
||||
TEST_STDBOOL_SUPPORT()
|
||||
@ -1029,13 +1017,6 @@ elseif(WIN32)
|
||||
set(SDL_LIBPATH ${SDL}/lib)
|
||||
endif()
|
||||
|
||||
if(WITH_CODEC_QUICKTIME)
|
||||
set(QUICKTIME ${LIBDIR}/QTDevWin)
|
||||
set(QUICKTIME_INCLUDE_DIRS ${QUICKTIME}/CIncludes)
|
||||
set(QUICKTIME_LIBRARIES qtmlClient)
|
||||
set(QUICKTIME_LIBPATH ${QUICKTIME}/Libraries)
|
||||
endif()
|
||||
|
||||
if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
|
||||
add_definitions(-D__SSE__ -D__MMX__)
|
||||
endif()
|
||||
@ -1613,15 +1594,12 @@ elseif(APPLE)
|
||||
|
||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
|
||||
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio")
|
||||
if(USE_QTKIT)
|
||||
set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DUSE_QTKIT")
|
||||
if(WITH_CODEC_QUICKTIME)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QTKit")
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
|
||||
# libSDL still needs 32bit carbon quicktime
|
||||
endif()
|
||||
elseif(WITH_CODEC_QUICKTIME)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
|
||||
endif()
|
||||
|
||||
# XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED!
|
||||
|
@ -342,9 +342,6 @@ if env['WITH_BF_OPENMP'] == 1:
|
||||
else:
|
||||
env.Append(CCFLAGS=['-fopenmp'])
|
||||
|
||||
if env['USE_QTKIT'] == True:
|
||||
env.Append(CPPFLAGS=['-DUSE_QTKIT'])
|
||||
|
||||
#check for additional debug libnames
|
||||
|
||||
if env.has_key('BF_DEBUG_LIBS'):
|
||||
|
@ -45,6 +45,7 @@ if XCODE_SELECT_PATH.endswith("/Contents/Developer"):
|
||||
else:
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH
|
||||
|
||||
|
||||
# Default target OSX settings per architecture
|
||||
# Can be customized
|
||||
|
||||
@ -332,10 +333,7 @@ CPPFLAGS = list(ARCH_FLAGS)
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME:
|
||||
if USE_QTKIT:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
|
||||
if not WITH_OSX_STATICPYTHON:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
|
||||
|
@ -45,6 +45,7 @@ if XCODE_SELECT_PATH.endswith("/Contents/Developer"):
|
||||
else:
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH
|
||||
|
||||
|
||||
# Default target OSX settings per architecture
|
||||
# Can be customized
|
||||
|
||||
@ -332,10 +333,7 @@ CPPFLAGS = list(ARCH_FLAGS)
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME:
|
||||
if USE_QTKIT:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
|
||||
if not WITH_OSX_STATICPYTHON:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
|
||||
|
@ -45,6 +45,7 @@ if XCODE_SELECT_PATH.endswith("/Contents/Developer"):
|
||||
else:
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH
|
||||
|
||||
|
||||
# Default target OSX settings per architecture
|
||||
# Can be customized
|
||||
|
||||
@ -333,10 +334,7 @@ CPPFLAGS = list(ARCH_FLAGS)
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME:
|
||||
if USE_QTKIT:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
|
||||
if not WITH_OSX_STATICPYTHON:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
|
||||
|
@ -90,11 +90,6 @@ BF_FREETYPE = '/usr/local'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
|
||||
### XXX Find what this actually wants; it doesn't want libquicktime.
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = True
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@ -100,10 +100,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
#BF_FREETYPE_LIB_STATIC = '${BF_FREETYPE}/lib/libfreetype.a'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = "/usr"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@ -101,10 +101,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = LIBDIR + "/gcc/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@ -112,10 +112,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@ -133,12 +133,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype2ST'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = LIBDIR + '/QTDevWin'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/CIncludes'
|
||||
BF_QUICKTIME_LIB = 'qtmlClient'
|
||||
BF_QUICKTIME_LIBPATH = '${BF_QUICKTIME}/Libraries'
|
||||
|
||||
WITH_BF_OPENJPEG = True
|
||||
BF_OPENJPEG = '#extern/libopenjpeg'
|
||||
BF_OPENJPEG_LIB = ''
|
||||
|
@ -111,8 +111,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2/'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@ -143,7 +143,6 @@ def validate_arguments(args, bc):
|
||||
'WITH_X11_XINPUT',
|
||||
'WITH_X11_XF86VMODE',
|
||||
'BF_GHOST_DEBUG',
|
||||
'USE_QTKIT',
|
||||
'BF_FANCY', 'BF_QUIET', 'BF_LINE_OVERWRITE',
|
||||
'BF_X264_CONFIG',
|
||||
'BF_XVIDCORE_CONFIG',
|
||||
@ -426,7 +425,6 @@ def read_opts(env, cfg, args):
|
||||
(BoolVariable('WITH_GHOST_SDL', 'Enable building blender against SDL for windowing rather then the native APIs', False)),
|
||||
(BoolVariable('WITH_X11_XINPUT', 'Enable X11 Xinput (tablet support and unicode input)', True)),
|
||||
(BoolVariable('WITH_X11_XF86VMODE', 'Enable X11 video mode switching', True)),
|
||||
(BoolVariable('USE_QTKIT', 'Use QTKIT if true', True)),
|
||||
('BF_OPENMP_LIB_STATIC', 'OpenMP static library', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_QUICKTIME', 'Use QuickTime if true', False)),
|
||||
|
@ -98,8 +98,6 @@ elif window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64
|
||||
elif window_system == 'darwin':
|
||||
if env['WITH_BF_QUICKTIME']:
|
||||
defs.append('WITH_QUICKTIME')
|
||||
if env['USE_QTKIT']:
|
||||
defs.append('USE_QTKIT')
|
||||
for f in pf:
|
||||
try:
|
||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||
@ -107,7 +105,6 @@ elif window_system == 'darwin':
|
||||
sources.remove('intern' + os.sep + f + 'SDL.cpp')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
else:
|
||||
print "Unknown window system specified."
|
||||
Exit()
|
||||
|
@ -395,10 +395,7 @@ class RENDER_PT_output(RenderButtonsPanel, Panel):
|
||||
|
||||
layout.template_image_settings(image_settings, color_management=False)
|
||||
|
||||
if file_format == 'QUICKTIME_CARBON':
|
||||
layout.operator("scene.render_data_set_quicktime_codec")
|
||||
|
||||
elif file_format == 'QUICKTIME_QTKIT':
|
||||
if file_format == 'QUICKTIME':
|
||||
quicktime = rd.quicktime
|
||||
|
||||
split = layout.split()
|
||||
|
@ -1617,6 +1617,9 @@ static int convert_exec(bContext *C, wmOperator *op)
|
||||
for (nu = cu->nurb.first; nu; nu = nu->next)
|
||||
nu->charidx = 0;
|
||||
|
||||
cu->flag &= ~CU_3D;
|
||||
BKE_curve_curve_dimension_update(cu);
|
||||
|
||||
if (target == OB_MESH) {
|
||||
curvetomesh(scene, newob);
|
||||
|
||||
|
@ -61,9 +61,6 @@ if env['WITH_BF_QUICKTIME']:
|
||||
incs += ' ../../quicktime'
|
||||
env.Append(CFLAGS=['-DWITH_QUICKTIME'])
|
||||
|
||||
if env['USE_QTKIT']:
|
||||
env.Append(CFLAGS=['-DUSE_QTKIT'])
|
||||
|
||||
if env['WITH_BF_INTERNATIONAL']:
|
||||
defs.append('WITH_INTERNATIONAL')
|
||||
|
||||
|
@ -37,10 +37,6 @@
|
||||
|
||||
#include "render_intern.h" // own include
|
||||
|
||||
#if (defined(WITH_QUICKTIME) && !defined(USE_QTKIT))
|
||||
#include "quicktime_export.h"
|
||||
#endif
|
||||
|
||||
/***************************** render ***********************************/
|
||||
|
||||
void ED_operatortypes_render(void)
|
||||
@ -81,10 +77,6 @@ void ED_operatortypes_render(void)
|
||||
WM_operatortype_append(SCENE_OT_freestyle_modifier_copy);
|
||||
#endif
|
||||
|
||||
#if (defined(WITH_QUICKTIME) && !defined(USE_QTKIT))
|
||||
WM_operatortype_append(SCENE_OT_render_data_set_quicktime_codec);
|
||||
#endif
|
||||
|
||||
WM_operatortype_append(TEXTURE_OT_slot_copy);
|
||||
WM_operatortype_append(TEXTURE_OT_slot_paste);
|
||||
WM_operatortype_append(TEXTURE_OT_slot_move);
|
||||
|
@ -261,11 +261,7 @@ EnumPropertyItem image_type_items[] = {
|
||||
{R_IMF_IMTYPE_THEORA, "THEORA", ICON_FILE_MOVIE, "Ogg Theora", "Output video in Ogg format"},
|
||||
#endif
|
||||
#ifdef WITH_QUICKTIME
|
||||
# ifdef USE_QTKIT
|
||||
{R_IMF_IMTYPE_QUICKTIME, "QUICKTIME_QTKIT", ICON_FILE_MOVIE, "QuickTime", "Output video in Quicktime format"},
|
||||
# else
|
||||
{R_IMF_IMTYPE_QUICKTIME, "QUICKTIME_CARBON", ICON_FILE_MOVIE, "QuickTime", "Output video in Quicktime format"},
|
||||
# endif
|
||||
{R_IMF_IMTYPE_QUICKTIME, "QUICKTIME", ICON_FILE_MOVIE, "QuickTime", "Output video in Quicktime format"},
|
||||
#endif
|
||||
#ifdef WITH_FFMPEG
|
||||
{R_IMF_IMTYPE_XVID, "XVID", ICON_FILE_MOVIE, "Xvid", "Output video in Xvid format"},
|
||||
@ -955,7 +951,6 @@ static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bCon
|
||||
return item;
|
||||
}
|
||||
|
||||
#ifdef USE_QTKIT
|
||||
static int rna_RenderSettings_qtcodecsettings_audiocodecType_get(PointerRNA *ptr)
|
||||
{
|
||||
QuicktimeCodecSettings *settings = (QuicktimeCodecSettings *)ptr->data;
|
||||
@ -994,7 +989,6 @@ static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_audiocodecType_itemf
|
||||
return item;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
static void rna_FFmpegSettings_lossless_output_set(PointerRNA *ptr, int value)
|
||||
@ -3954,7 +3948,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef USE_QTKIT
|
||||
static EnumPropertyItem quicktime_audio_samplerate_items[] = {
|
||||
{22050, "22050", 0, "22kHz", ""},
|
||||
{44100, "44100", 0, "44.1kHz", ""},
|
||||
@ -3984,7 +3977,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna)
|
||||
{320000, "320000", 0, "320kbps", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
#endif
|
||||
|
||||
/* QuickTime */
|
||||
srna = RNA_def_struct(brna, "QuickTimeSettings", NULL);
|
||||
@ -4006,7 +3998,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Spatial quality", "Intra-frame spatial quality level");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
#ifdef USE_QTKIT
|
||||
prop = RNA_def_property(srna, "audiocodec_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "audiocodecType");
|
||||
RNA_def_property_enum_items(prop, quicktime_codec_type_items);
|
||||
@ -4043,7 +4034,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna)
|
||||
RNA_def_property_enum_items(prop, quicktime_audio_bitrate_items);
|
||||
RNA_def_property_ui_text(prop, "Bitrate", "Compressed audio bitrate");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -41,23 +41,13 @@ set(INC_SYS
|
||||
${QUICKTIME_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if(USE_QTKIT)
|
||||
set(SRC
|
||||
apple/qtkit_import.m
|
||||
apple/qtkit_export.m
|
||||
set(SRC
|
||||
apple/qtkit_import.m
|
||||
apple/qtkit_export.m
|
||||
|
||||
quicktime_export.h
|
||||
quicktime_import.h
|
||||
)
|
||||
else()
|
||||
set(SRC
|
||||
apple/quicktime_import.c
|
||||
apple/quicktime_export.c
|
||||
|
||||
quicktime_export.h
|
||||
quicktime_import.h
|
||||
)
|
||||
endif()
|
||||
quicktime_export.h
|
||||
quicktime_import.h
|
||||
)
|
||||
|
||||
add_definitions(-DWITH_QUICKTIME)
|
||||
|
||||
|
@ -28,12 +28,8 @@
|
||||
Import ('env')
|
||||
|
||||
|
||||
if env['USE_QTKIT']:
|
||||
source_files = ['apple/qtkit_import.m',
|
||||
source_files = ['apple/qtkit_import.m',
|
||||
'apple/qtkit_export.m']
|
||||
else:
|
||||
source_files = ['apple/quicktime_import.c',
|
||||
'apple/quicktime_export.c']
|
||||
|
||||
|
||||
incs = ['.',
|
||||
|
@ -1,927 +0,0 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
* The Original Code is written by Rob Haarsma (phase)
|
||||
*
|
||||
* Contributor(s): Stefan Gartner (sgefant)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/quicktime/apple/quicktime_export.c
|
||||
* \ingroup quicktime
|
||||
*
|
||||
* Code to create QuickTime Movies with Blender
|
||||
*/
|
||||
|
||||
|
||||
#ifdef WITH_QUICKTIME
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
#ifndef USE_QTKIT
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "quicktime_import.h"
|
||||
#include "quicktime_export.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <QTML.h>
|
||||
#include <Movies.h>
|
||||
#include <QuickTimeComponents.h>
|
||||
#include <TextUtils.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* evil */
|
||||
#ifndef __AIFF__
|
||||
#define __AIFF__
|
||||
#endif
|
||||
#include <QuickTime/Movies.h>
|
||||
#include <QuickTime/QuickTimeComponents.h>
|
||||
#include <fcntl.h> /* open() */
|
||||
#include <unistd.h> /* close() */
|
||||
#include <sys/stat.h> /* file permissions */
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#define kMyCreatorType FOUR_CHAR_CODE('TVOD')
|
||||
#define kTrackStart 0
|
||||
#define kMediaStart 0
|
||||
|
||||
static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, int recty, struct ReportList *reports);
|
||||
static void QT_DoAddVideoSamplesToMedia(int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
|
||||
static void QT_EndAddVideoSamplesToMedia(void);
|
||||
static void QT_CreateMyVideoTrack(int rectx, int recty, struct ReportList *reports);
|
||||
static void QT_EndCreateMyVideoTrack(struct ReportList *reports);
|
||||
static void check_renderbutton_framerate(struct RenderData *rd, struct ReportList *reports);
|
||||
static int get_qtcodec_settings(struct RenderData *rd, struct ReportList *reports);
|
||||
|
||||
typedef struct QuicktimeExport {
|
||||
|
||||
FSSpec theSpec;
|
||||
short resRefNum;
|
||||
Str255 qtfilename;
|
||||
|
||||
Media theMedia;
|
||||
Movie theMovie;
|
||||
Track theTrack;
|
||||
|
||||
GWorldPtr theGWorld;
|
||||
PixMapHandle thePixMap;
|
||||
ImageDescription **anImageDescription;
|
||||
|
||||
ImBuf *ibuf; /* imagedata for Quicktime's Gworld */
|
||||
ImBuf *ibuf2; /* copy of renderdata, to be Y-flipped */
|
||||
|
||||
} QuicktimeExport;
|
||||
|
||||
typedef struct QuicktimeComponentData {
|
||||
|
||||
ComponentInstance theComponent;
|
||||
SCTemporalSettings gTemporalSettings;
|
||||
SCSpatialSettings gSpatialSettings;
|
||||
SCDataRateSettings aDataRateSetting;
|
||||
TimeValue duration;
|
||||
long kVideoTimeScale;
|
||||
|
||||
} QuicktimeComponentData;
|
||||
|
||||
static struct QuicktimeExport *qtexport;
|
||||
static struct QuicktimeComponentData *qtdata;
|
||||
|
||||
static int sframe;
|
||||
|
||||
/* RNA functions */
|
||||
|
||||
static QuicktimeCodecTypeDesc qtVideoCodecList[] = {
|
||||
{kRawCodecType, 1, "Uncompressed"},
|
||||
{kJPEGCodecType, 2, "JPEG"},
|
||||
{kMotionJPEGACodecType, 3, "M-JPEG A"},
|
||||
{kMotionJPEGBCodecType, 4, "M-JPEG B"},
|
||||
{kDVCPALCodecType, 5, "DV PAL"},
|
||||
{kDVCNTSCCodecType, 6, "DV/DVCPRO NTSC"},
|
||||
{kDVCPROHD720pCodecType, 7, "DVCPRO HD 720p"},
|
||||
{kDVCPROHD1080i50CodecType, 8, "DVCPRO HD 1080i50"},
|
||||
{kDVCPROHD1080i60CodecType, 9, "DVCPRO HD 1080i60"},
|
||||
{kMPEG4VisualCodecType, 10, "MPEG4"},
|
||||
{kH263CodecType, 11, "H.263"},
|
||||
{kH264CodecType, 12, "H.264"},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
static int qtVideoCodecCount = 12;
|
||||
|
||||
int quicktime_get_num_videocodecs()
|
||||
{
|
||||
return qtVideoCodecCount;
|
||||
}
|
||||
|
||||
QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue)
|
||||
{
|
||||
if ((indexValue >= 0) && (indexValue < qtVideoCodecCount))
|
||||
return &qtVideoCodecList[indexValue];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int quicktime_rnatmpvalue_from_videocodectype(int codecType)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < qtVideoCodecCount; i++) {
|
||||
if (qtVideoCodecList[i].codecType == codecType)
|
||||
return qtVideoCodecList[i].rnatmpvalue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < qtVideoCodecCount; i++) {
|
||||
if (qtVideoCodecList[i].rnatmpvalue == rnatmpvalue)
|
||||
return qtVideoCodecList[i].codecType;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void CheckError(OSErr err, char *msg, ReportList *reports)
|
||||
{
|
||||
if (err != noErr) {
|
||||
BKE_reportf(reports, RPT_ERROR, "%s: %d", msg, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports)
|
||||
{
|
||||
QTAtomContainer myContainer = NULL;
|
||||
ComponentResult myErr = noErr;
|
||||
Ptr myPtr;
|
||||
long mySize = 0;
|
||||
|
||||
CodecInfo ci;
|
||||
|
||||
QuicktimeCodecData *qcd = rd->qtcodecdata;
|
||||
|
||||
/* check if current scene already has qtcodec settings, and clear them */
|
||||
if (qcd) {
|
||||
free_qtcodecdata(qcd);
|
||||
}
|
||||
else {
|
||||
qcd = rd->qtcodecdata = MEM_callocN(sizeof(QuicktimeCodecData), "QuicktimeCodecData");
|
||||
}
|
||||
|
||||
/* obtain all current codec settings */
|
||||
SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
|
||||
/* retreive codecdata from quicktime in a atomcontainer */
|
||||
myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent, &myContainer);
|
||||
if (myErr != noErr) {
|
||||
BKE_report(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* get the size of the atomcontainer */
|
||||
mySize = GetHandleSize((Handle)myContainer);
|
||||
|
||||
/* lock and convert the atomcontainer to a *valid* pointer */
|
||||
QTLockContainer(myContainer);
|
||||
myPtr = *(Handle)myContainer;
|
||||
|
||||
/* copy the Quicktime data into the blender qtcodecdata struct */
|
||||
if (myPtr) {
|
||||
qcd->cdParms = MEM_mallocN(mySize, "qt.cdParms");
|
||||
memcpy(qcd->cdParms, myPtr, mySize);
|
||||
qcd->cdSize = mySize;
|
||||
|
||||
GetCodecInfo(&ci, qtdata->gSpatialSettings.codecType, 0);
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed");
|
||||
}
|
||||
|
||||
QTUnlockContainer(myContainer);
|
||||
|
||||
bail:
|
||||
if (myContainer != NULL)
|
||||
QTDisposeAtomContainer(myContainer);
|
||||
|
||||
return((OSErr)myErr);
|
||||
}
|
||||
|
||||
|
||||
static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports)
|
||||
{
|
||||
Handle myHandle = NULL;
|
||||
ComponentResult myErr = noErr;
|
||||
|
||||
QuicktimeCodecData *qcd = rd->qtcodecdata;
|
||||
|
||||
/* if there is codecdata in the blendfile, convert it to a Quicktime handle */
|
||||
if (qcd) {
|
||||
myHandle = NewHandle(qcd->cdSize);
|
||||
PtrToHand(qcd->cdParms, &myHandle, qcd->cdSize);
|
||||
}
|
||||
|
||||
/* restore codecsettings to the quicktime component */
|
||||
if (qcd->cdParms && qcd->cdSize) {
|
||||
myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle);
|
||||
if (myErr != noErr) {
|
||||
BKE_report(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* update runtime codecsettings for use with the codec dialog */
|
||||
SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
|
||||
|
||||
/* Fill the render QuicktimeCodecSettigns struct */
|
||||
rd->qtcodecsettings.codecTemporalQuality = (qtdata->gTemporalSettings.temporalQuality * 100) / codecLosslessQuality;
|
||||
/* Do not override scene frame rate (qtdata->gTemporalSettings.framerate) */
|
||||
rd->qtcodecsettings.keyFrameRate = qtdata->gTemporalSettings.keyFrameRate;
|
||||
|
||||
rd->qtcodecsettings.codecType = qtdata->gSpatialSettings.codecType;
|
||||
rd->qtcodecsettings.codec = (int)qtdata->gSpatialSettings.codec;
|
||||
rd->qtcodecsettings.colorDepth = qtdata->gSpatialSettings.depth;
|
||||
rd->qtcodecsettings.codecSpatialQuality = (qtdata->gSpatialSettings.spatialQuality * 100) / codecLosslessQuality;
|
||||
|
||||
rd->qtcodecsettings.bitRate = qtdata->aDataRateSetting.dataRate;
|
||||
rd->qtcodecsettings.minSpatialQuality = (qtdata->aDataRateSetting.minSpatialQuality * 100) / codecLosslessQuality;
|
||||
rd->qtcodecsettings.minTemporalQuality = (qtdata->aDataRateSetting.minTemporalQuality * 100) / codecLosslessQuality;
|
||||
/* Frame duration is already known (qtdata->aDataRateSetting.frameDuration) */
|
||||
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed");
|
||||
}
|
||||
bail:
|
||||
if (myHandle != NULL)
|
||||
DisposeHandle(myHandle);
|
||||
|
||||
return((OSErr)myErr);
|
||||
}
|
||||
|
||||
|
||||
static OSErr QT_AddUserDataTextToMovie(Movie theMovie, char *theText, OSType theType)
|
||||
{
|
||||
UserData myUserData = NULL;
|
||||
Handle myHandle = NULL;
|
||||
long myLength = strlen(theText);
|
||||
OSErr myErr = noErr;
|
||||
|
||||
/* get the movie's user data list */
|
||||
myUserData = GetMovieUserData(theMovie);
|
||||
if (myUserData == NULL)
|
||||
return(paramErr);
|
||||
|
||||
/* copy the specified text into a new handle */
|
||||
myHandle = NewHandleClear(myLength);
|
||||
if (myHandle == NULL)
|
||||
return(MemError());
|
||||
|
||||
BlockMoveData(theText, *myHandle, myLength);
|
||||
|
||||
/* add the data to the movie's user data */
|
||||
myErr = AddUserDataText(myUserData, myHandle, theType, 1, (short)GetScriptManagerVariable(smRegionCode));
|
||||
|
||||
/* clean up */
|
||||
DisposeHandle(myHandle);
|
||||
return(myErr);
|
||||
}
|
||||
|
||||
|
||||
static void QT_CreateMyVideoTrack(int rectx, int recty, ReportList *reports)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
Rect trackFrame;
|
||||
// MatrixRecord myMatrix;
|
||||
|
||||
trackFrame.top = 0;
|
||||
trackFrame.left = 0;
|
||||
trackFrame.bottom = recty;
|
||||
trackFrame.right = rectx;
|
||||
|
||||
qtexport->theTrack = NewMovieTrack(qtexport->theMovie,
|
||||
FixRatio(trackFrame.right, 1),
|
||||
FixRatio(trackFrame.bottom, 1),
|
||||
0);
|
||||
CheckError(GetMoviesError(), "NewMovieTrack error", reports);
|
||||
|
||||
// SetIdentityMatrix(&myMatrix);
|
||||
// ScaleMatrix(&myMatrix, fixed1, Long2Fix(-1), 0, 0);
|
||||
// TranslateMatrix(&myMatrix, 0, Long2Fix(trackFrame.bottom));
|
||||
// SetMovieMatrix(qtexport->theMovie, &myMatrix);
|
||||
|
||||
qtexport->theMedia = NewTrackMedia(qtexport->theTrack,
|
||||
VideoMediaType,
|
||||
qtdata->kVideoTimeScale,
|
||||
nil,
|
||||
0);
|
||||
CheckError(GetMoviesError(), "NewTrackMedia error", reports);
|
||||
|
||||
err = BeginMediaEdits(qtexport->theMedia);
|
||||
CheckError(err, "BeginMediaEdits error", reports);
|
||||
|
||||
QT_StartAddVideoSamplesToMedia(&trackFrame, rectx, recty, reports);
|
||||
}
|
||||
|
||||
|
||||
static void QT_EndCreateMyVideoTrack(ReportList *reports)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
|
||||
QT_EndAddVideoSamplesToMedia();
|
||||
|
||||
err = EndMediaEdits(qtexport->theMedia);
|
||||
CheckError(err, "EndMediaEdits error", reports);
|
||||
|
||||
err = InsertMediaIntoTrack(qtexport->theTrack,
|
||||
kTrackStart, /* track start time */
|
||||
kMediaStart, /* media start time */
|
||||
GetMediaDuration(qtexport->theMedia),
|
||||
fixed1);
|
||||
CheckError(err, "InsertMediaIntoTrack error", reports);
|
||||
}
|
||||
|
||||
|
||||
static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, int recty, ReportList *reports)
|
||||
{
|
||||
SCTemporalSettings gTemporalSettings;
|
||||
OSErr err = noErr;
|
||||
|
||||
qtexport->ibuf = IMB_allocImBuf(rectx, recty, 32, IB_rect);
|
||||
qtexport->ibuf2 = IMB_allocImBuf(rectx, recty, 32, IB_rect);
|
||||
|
||||
err = NewGWorldFromPtr(&qtexport->theGWorld,
|
||||
k32ARGBPixelFormat,
|
||||
trackFrame,
|
||||
NULL, NULL, 0,
|
||||
(Ptr)qtexport->ibuf->rect,
|
||||
rectx * 4);
|
||||
CheckError(err, "NewGWorldFromPtr error", reports);
|
||||
|
||||
qtexport->thePixMap = GetGWorldPixMap(qtexport->theGWorld);
|
||||
LockPixels(qtexport->thePixMap);
|
||||
|
||||
SCDefaultPixMapSettings(qtdata->theComponent, qtexport->thePixMap, true);
|
||||
|
||||
/* workaround for crash with H.264, which requires an upgrade to
|
||||
* the new callback based api for proper encoding, but that's not
|
||||
* really compatible with rendering out frames sequentially */
|
||||
gTemporalSettings = qtdata->gTemporalSettings;
|
||||
if (qtdata->gSpatialSettings.codecType == kH264CodecType) {
|
||||
if (gTemporalSettings.temporalQuality != codecMinQuality) {
|
||||
BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for Quicktime H.264");
|
||||
gTemporalSettings.temporalQuality = codecMinQuality;
|
||||
}
|
||||
}
|
||||
|
||||
SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &gTemporalSettings);
|
||||
SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
|
||||
err = SCCompressSequenceBegin(qtdata->theComponent, qtexport->thePixMap, NULL, &qtexport->anImageDescription);
|
||||
CheckError(err, "SCCompressSequenceBegin error", reports);
|
||||
}
|
||||
|
||||
|
||||
static void QT_DoAddVideoSamplesToMedia(int frame, int *pixels, int rectx, int recty, ReportList *reports)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
Rect imageRect;
|
||||
|
||||
int index;
|
||||
int boxsize;
|
||||
unsigned char *from, *to;
|
||||
|
||||
short syncFlag;
|
||||
long dataSize;
|
||||
Handle compressedData;
|
||||
Ptr myPtr;
|
||||
|
||||
|
||||
/* copy and flip renderdata */
|
||||
memcpy(qtexport->ibuf2->rect, pixels, 4 * rectx * recty);
|
||||
IMB_flipy(qtexport->ibuf2);
|
||||
|
||||
/* get pointers to parse bitmapdata */
|
||||
myPtr = GetPixBaseAddr(qtexport->thePixMap);
|
||||
imageRect = (**qtexport->thePixMap).bounds;
|
||||
|
||||
from = (unsigned char *) qtexport->ibuf2->rect;
|
||||
to = (unsigned char *) myPtr;
|
||||
|
||||
/* parse RGBA bitmap into Quicktime's ARGB GWorld */
|
||||
boxsize = rectx * recty;
|
||||
for (index = 0; index < boxsize; index++) {
|
||||
to[0] = from[3];
|
||||
to[1] = from[0];
|
||||
to[2] = from[1];
|
||||
to[3] = from[2];
|
||||
to += 4, from += 4;
|
||||
}
|
||||
|
||||
err = SCCompressSequenceFrame(qtdata->theComponent,
|
||||
qtexport->thePixMap,
|
||||
&imageRect,
|
||||
&compressedData,
|
||||
&dataSize,
|
||||
&syncFlag);
|
||||
CheckError(err, "SCCompressSequenceFrame error", reports);
|
||||
|
||||
err = AddMediaSample(qtexport->theMedia,
|
||||
compressedData,
|
||||
0,
|
||||
dataSize,
|
||||
qtdata->duration,
|
||||
(SampleDescriptionHandle)qtexport->anImageDescription,
|
||||
1,
|
||||
syncFlag,
|
||||
NULL);
|
||||
CheckError(err, "AddMediaSample error", reports);
|
||||
}
|
||||
|
||||
|
||||
static void QT_EndAddVideoSamplesToMedia(void)
|
||||
{
|
||||
SCCompressSequenceEnd(qtdata->theComponent);
|
||||
|
||||
UnlockPixels(qtexport->thePixMap);
|
||||
if (qtexport->theGWorld)
|
||||
DisposeGWorld(qtexport->theGWorld);
|
||||
|
||||
if (qtexport->ibuf)
|
||||
IMB_freeImBuf(qtexport->ibuf);
|
||||
|
||||
if (qtexport->ibuf2)
|
||||
IMB_freeImBuf(qtexport->ibuf2);
|
||||
}
|
||||
|
||||
|
||||
void filepath_qt(char *string, RenderData *rd)
|
||||
{
|
||||
char txt[64];
|
||||
|
||||
if (string == 0) return;
|
||||
|
||||
strcpy(string, rd->pic);
|
||||
BLI_path_abs(string, G.main->name);
|
||||
|
||||
BLI_make_existing_file(string);
|
||||
|
||||
if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) {
|
||||
sprintf(txt, "%04d-%04d.mov", (rd->sfra), (rd->efra));
|
||||
strcat(string, txt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
|
||||
char name[2048];
|
||||
char theFullPath[255];
|
||||
|
||||
#ifdef __APPLE__
|
||||
int myFile;
|
||||
FSRef myRef;
|
||||
#else
|
||||
char *qtname;
|
||||
#endif
|
||||
int success = 1;
|
||||
|
||||
if (qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
|
||||
|
||||
if (qtdata) {
|
||||
if (qtdata->theComponent) CloseComponent(qtdata->theComponent);
|
||||
free_qtcomponentdata();
|
||||
}
|
||||
|
||||
qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeCodecDataExt");
|
||||
|
||||
if (rd->qtcodecdata == NULL || rd->qtcodecdata->cdParms == NULL) {
|
||||
get_qtcodec_settings(rd, reports);
|
||||
}
|
||||
else {
|
||||
qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
|
||||
|
||||
QT_GetCodecSettingsFromScene(rd, reports);
|
||||
check_renderbutton_framerate(rd, reports);
|
||||
}
|
||||
|
||||
sframe = (rd->sfra);
|
||||
|
||||
filepath_qt(name, rd);
|
||||
|
||||
#ifdef __APPLE__
|
||||
EnterMoviesOnThread(0);
|
||||
strcpy(theFullPath, name);
|
||||
|
||||
/* hack: create an empty file to make FSPathMakeRef() happy */
|
||||
myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR);
|
||||
if (myFile < 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Error while creating movie file!");
|
||||
/* do something? */
|
||||
}
|
||||
close(myFile);
|
||||
err = FSPathMakeRef((const UInt8 *)theFullPath, &myRef, 0);
|
||||
CheckError(err, "FsPathMakeRef error", reports);
|
||||
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL);
|
||||
CheckError(err, "FsGetCatalogInfoRef error", reports);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
qtname = get_valid_qtname(name);
|
||||
strcpy(theFullPath, qtname);
|
||||
strcpy(name, qtname);
|
||||
MEM_freeN(qtname);
|
||||
|
||||
CopyCStringToPascal(theFullPath, qtexport->qtfilename);
|
||||
err = FSMakeFSSpec(0, 0L, qtexport->qtfilename, &qtexport->theSpec);
|
||||
#endif
|
||||
|
||||
err = CreateMovieFile(&qtexport->theSpec,
|
||||
kMyCreatorType,
|
||||
smCurrentScript,
|
||||
createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
|
||||
&qtexport->resRefNum,
|
||||
&qtexport->theMovie);
|
||||
CheckError(err, "CreateMovieFile error", reports);
|
||||
|
||||
if (err != noErr) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Unable to create Quicktime movie: %s", name);
|
||||
success = 0;
|
||||
#ifdef __APPLE__
|
||||
ExitMoviesOnThread();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* printf("Created QuickTime movie: %s\n", name); */
|
||||
|
||||
QT_CreateMyVideoTrack(rectx, recty, reports);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
int append_qt(struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports)
|
||||
{
|
||||
QT_DoAddVideoSamplesToMedia(frame, pixels, rectx, recty, reports);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void end_qt(void)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
short resId = movieInDataForkResID;
|
||||
|
||||
if (qtexport->theMovie) {
|
||||
QT_EndCreateMyVideoTrack(NULL);
|
||||
|
||||
err = AddMovieResource(qtexport->theMovie, qtexport->resRefNum, &resId, qtexport->qtfilename);
|
||||
CheckError(err, "AddMovieResource error", NULL);
|
||||
|
||||
err = QT_AddUserDataTextToMovie(qtexport->theMovie, "Made with Blender", kUserDataTextInformation);
|
||||
CheckError(err, "AddUserDataTextToMovie error", NULL);
|
||||
|
||||
err = UpdateMovieResource(qtexport->theMovie, qtexport->resRefNum, resId, qtexport->qtfilename);
|
||||
CheckError(err, "UpdateMovieResource error", NULL);
|
||||
|
||||
if (qtexport->resRefNum) CloseMovieFile(qtexport->resRefNum);
|
||||
|
||||
DisposeMovie(qtexport->theMovie);
|
||||
|
||||
/* printf("Finished QuickTime movie.\n"); */
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
ExitMoviesOnThread();
|
||||
#endif
|
||||
|
||||
if (qtexport) {
|
||||
MEM_freeN(qtexport);
|
||||
qtexport = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void free_qtcomponentdata(void)
|
||||
{
|
||||
if (qtdata) {
|
||||
if (qtdata->theComponent) CloseComponent(qtdata->theComponent);
|
||||
MEM_freeN(qtdata);
|
||||
qtdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void check_renderbutton_framerate(RenderData *rd, ReportList *reports)
|
||||
{
|
||||
/* to keep float framerates consistent between the codec dialog and frs/sec button. */
|
||||
OSErr err;
|
||||
|
||||
err = SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
CheckError(err, "SCGetInfo fr error", reports);
|
||||
|
||||
if ( (rd->frs_sec == 24 || rd->frs_sec == 30 || rd->frs_sec == 60) &&
|
||||
(qtdata->gTemporalSettings.frameRate == 1571553 ||
|
||||
qtdata->gTemporalSettings.frameRate == 1964113 ||
|
||||
qtdata->gTemporalSettings.frameRate == 3928227))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else {
|
||||
if (rd->frs_sec_base > 0)
|
||||
qtdata->gTemporalSettings.frameRate =
|
||||
((float)(rd->frs_sec << 16) / rd->frs_sec_base);
|
||||
}
|
||||
|
||||
err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
CheckError(err, "SCSetInfo error", reports);
|
||||
|
||||
if (qtdata->gTemporalSettings.frameRate == 1571553) { /* 23.98 fps */
|
||||
qtdata->kVideoTimeScale = 24000;
|
||||
qtdata->duration = 1001;
|
||||
}
|
||||
else if (qtdata->gTemporalSettings.frameRate == 1964113) { /* 29.97 fps */
|
||||
qtdata->kVideoTimeScale = 30000;
|
||||
qtdata->duration = 1001;
|
||||
}
|
||||
else if (qtdata->gTemporalSettings.frameRate == 3928227) { /* 59.94 fps */
|
||||
qtdata->kVideoTimeScale = 60000;
|
||||
qtdata->duration = 1001;
|
||||
}
|
||||
else {
|
||||
qtdata->kVideoTimeScale = (qtdata->gTemporalSettings.frameRate >> 16) * 100;
|
||||
qtdata->duration = 100;
|
||||
}
|
||||
}
|
||||
|
||||
void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf)
|
||||
{
|
||||
if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) {
|
||||
if ((rd->qtcodecsettings.codecType == 0) ||
|
||||
(rd->qtcodecsettings.codecSpatialQuality < 0) ||
|
||||
(rd->qtcodecsettings.codecSpatialQuality > 100))
|
||||
{
|
||||
rd->qtcodecsettings.codecType = kJPEGCodecType;
|
||||
rd->qtcodecsettings.codec = (int)anyCodec;
|
||||
rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality * 100) / codecLosslessQuality;
|
||||
rd->qtcodecsettings.codecTemporalQuality = (codecHighQuality * 100) / codecLosslessQuality;
|
||||
rd->qtcodecsettings.keyFrameRate = 25;
|
||||
rd->qtcodecsettings.bitRate = 5000000; /* 5 Mbps */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int get_qtcodec_settings(RenderData *rd, ReportList *reports)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
/* erase any existing codecsetting */
|
||||
if (qtdata) {
|
||||
if (qtdata->theComponent) CloseComponent(qtdata->theComponent);
|
||||
free_qtcomponentdata();
|
||||
}
|
||||
|
||||
/* allocate new */
|
||||
qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData");
|
||||
qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
|
||||
|
||||
/* get previous selected codecsetting, from qtatom or detailed settings */
|
||||
if (rd->qtcodecdata && rd->qtcodecdata->cdParms) {
|
||||
QT_GetCodecSettingsFromScene(rd, reports);
|
||||
}
|
||||
else {
|
||||
SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
|
||||
qtdata->gSpatialSettings.codecType = rd->qtcodecsettings.codecType;
|
||||
qtdata->gSpatialSettings.codec = (CodecComponent)rd->qtcodecsettings.codec;
|
||||
qtdata->gSpatialSettings.spatialQuality = (rd->qtcodecsettings.codecSpatialQuality * codecLosslessQuality) / 100;
|
||||
qtdata->gTemporalSettings.temporalQuality = (rd->qtcodecsettings.codecTemporalQuality * codecLosslessQuality) / 100;
|
||||
qtdata->gTemporalSettings.keyFrameRate = rd->qtcodecsettings.keyFrameRate;
|
||||
qtdata->aDataRateSetting.dataRate = rd->qtcodecsettings.bitRate;
|
||||
qtdata->gSpatialSettings.depth = rd->qtcodecsettings.colorDepth;
|
||||
qtdata->aDataRateSetting.minSpatialQuality = (rd->qtcodecsettings.minSpatialQuality * codecLosslessQuality) / 100;
|
||||
qtdata->aDataRateSetting.minTemporalQuality = (rd->qtcodecsettings.minTemporalQuality * codecLosslessQuality) / 100;
|
||||
|
||||
qtdata->aDataRateSetting.frameDuration = rd->frs_sec;
|
||||
SetMovieTimeScale(qtexport->theMovie, rd->frs_sec_base * 1000);
|
||||
|
||||
|
||||
err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
CheckError(err, "SCSetInfo1 error", reports);
|
||||
err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
CheckError(err, "SCSetInfo2 error", reports);
|
||||
err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
CheckError(err, "SCSetInfo3 error", reports);
|
||||
}
|
||||
|
||||
check_renderbutton_framerate(rd, reports);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int request_qtcodec_settings_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
OSErr err = noErr;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
RenderData *rd = &scene->r;
|
||||
|
||||
/* erase any existing codecsetting */
|
||||
if (qtdata) {
|
||||
if (qtdata->theComponent) CloseComponent(qtdata->theComponent);
|
||||
free_qtcomponentdata();
|
||||
}
|
||||
|
||||
/* allocate new */
|
||||
qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData");
|
||||
qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
|
||||
|
||||
/* get previous selected codecsetting, from qtatom or detailed settings */
|
||||
if (rd->qtcodecdata && rd->qtcodecdata->cdParms) {
|
||||
QT_GetCodecSettingsFromScene(rd, op->reports);
|
||||
}
|
||||
else {
|
||||
SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
|
||||
qtdata->gSpatialSettings.codecType = rd->qtcodecsettings.codecType;
|
||||
qtdata->gSpatialSettings.codec = (CodecComponent)rd->qtcodecsettings.codec;
|
||||
qtdata->gSpatialSettings.spatialQuality = (rd->qtcodecsettings.codecSpatialQuality * codecLosslessQuality) / 100;
|
||||
qtdata->gTemporalSettings.temporalQuality = (rd->qtcodecsettings.codecTemporalQuality * codecLosslessQuality) / 100;
|
||||
qtdata->gTemporalSettings.keyFrameRate = rd->qtcodecsettings.keyFrameRate;
|
||||
qtdata->gTemporalSettings.frameRate = ((float)(rd->frs_sec << 16) / rd->frs_sec_base);
|
||||
qtdata->aDataRateSetting.dataRate = rd->qtcodecsettings.bitRate;
|
||||
qtdata->gSpatialSettings.depth = rd->qtcodecsettings.colorDepth;
|
||||
qtdata->aDataRateSetting.minSpatialQuality = (rd->qtcodecsettings.minSpatialQuality * codecLosslessQuality) / 100;
|
||||
qtdata->aDataRateSetting.minTemporalQuality = (rd->qtcodecsettings.minTemporalQuality * codecLosslessQuality) / 100;
|
||||
|
||||
qtdata->aDataRateSetting.frameDuration = rd->frs_sec;
|
||||
|
||||
err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
CheckError(err, "SCSetInfo1 error", op->reports);
|
||||
err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
CheckError(err, "SCSetInfo2 error", op->reports);
|
||||
err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
CheckError(err, "SCSetInfo3 error", op->reports);
|
||||
}
|
||||
/* put up the dialog box - it needs to be called from the main thread */
|
||||
err = SCRequestSequenceSettings(qtdata->theComponent);
|
||||
|
||||
if (err == scUserCancelled) {
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* update runtime codecsettings for use with the codec dialog */
|
||||
SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
|
||||
SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings);
|
||||
SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
|
||||
|
||||
|
||||
/* Fill the render QuicktimeCodecSettings struct */
|
||||
rd->qtcodecsettings.codecTemporalQuality = (qtdata->gTemporalSettings.temporalQuality * 100) / codecLosslessQuality;
|
||||
/* Do not override scene frame rate (qtdata->gTemporalSettings.framerate) */
|
||||
rd->qtcodecsettings.keyFrameRate = qtdata->gTemporalSettings.keyFrameRate;
|
||||
|
||||
rd->qtcodecsettings.codecType = qtdata->gSpatialSettings.codecType;
|
||||
rd->qtcodecsettings.codec = (int)qtdata->gSpatialSettings.codec;
|
||||
rd->qtcodecsettings.colorDepth = qtdata->gSpatialSettings.depth;
|
||||
rd->qtcodecsettings.codecSpatialQuality = (qtdata->gSpatialSettings.spatialQuality * 100) / codecLosslessQuality;
|
||||
|
||||
rd->qtcodecsettings.bitRate = qtdata->aDataRateSetting.dataRate;
|
||||
rd->qtcodecsettings.minSpatialQuality = (qtdata->aDataRateSetting.minSpatialQuality * 100) / codecLosslessQuality;
|
||||
rd->qtcodecsettings.minTemporalQuality = (qtdata->aDataRateSetting.minTemporalQuality * 100) / codecLosslessQuality;
|
||||
/* Frame duration is already known (qtdata->aDataRateSetting.frameDuration) */
|
||||
|
||||
QT_SaveCodecSettingsToScene(rd, op->reports);
|
||||
|
||||
/* framerate jugglin' */
|
||||
if (qtdata->gTemporalSettings.frameRate == 1571553) { /* 23.98 fps */
|
||||
qtdata->kVideoTimeScale = 24000;
|
||||
qtdata->duration = 1001;
|
||||
|
||||
rd->frs_sec = 24;
|
||||
rd->frs_sec_base = 1.001;
|
||||
}
|
||||
else if (qtdata->gTemporalSettings.frameRate == 1964113) { /* 29.97 fps */
|
||||
qtdata->kVideoTimeScale = 30000;
|
||||
qtdata->duration = 1001;
|
||||
|
||||
rd->frs_sec = 30;
|
||||
rd->frs_sec_base = 1.001;
|
||||
}
|
||||
else if (qtdata->gTemporalSettings.frameRate == 3928227) { /* 59.94 fps */
|
||||
qtdata->kVideoTimeScale = 60000;
|
||||
qtdata->duration = 1001;
|
||||
|
||||
rd->frs_sec = 60;
|
||||
rd->frs_sec_base = 1.001;
|
||||
}
|
||||
else {
|
||||
double fps = qtdata->gTemporalSettings.frameRate;
|
||||
|
||||
qtdata->kVideoTimeScale = 60000;
|
||||
qtdata->duration = qtdata->kVideoTimeScale / (qtdata->gTemporalSettings.frameRate / 65536);
|
||||
|
||||
if ((qtdata->gTemporalSettings.frameRate & 0xffff) == 0) {
|
||||
rd->frs_sec = fps / 65536;
|
||||
rd->frs_sec_base = 1.0;
|
||||
}
|
||||
else {
|
||||
/* we do our very best... */
|
||||
rd->frs_sec = fps / 65536;
|
||||
rd->frs_sec_base = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int ED_operator_setqtcodec(bContext *C)
|
||||
{
|
||||
return G.have_quicktime != FALSE;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* Need to set up a Cocoa NSAutoReleasePool to avoid memory leak
|
||||
* And it must be done in an objC file, so use a GHOST_SystemCocoa.mm function for that */
|
||||
extern int cocoa_request_qtcodec_settings_exec(bContext *C, wmOperator *op);
|
||||
|
||||
int fromcocoa_request_qtcodec_settings(bContext *C, wmOperator *op)
|
||||
{
|
||||
return request_qtcodec_settings_exec(C, op);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Change Codec";
|
||||
ot->description = "Change Quicktime codec Settings";
|
||||
ot->idname = "SCENE_OT_render_data_set_quicktime_codec";
|
||||
|
||||
/* api callbacks */
|
||||
#if defined(__APPLE__)
|
||||
ot->exec = cocoa_request_qtcodec_settings_exec;
|
||||
#else
|
||||
ot->exec = request_qtcodec_settings_exec;
|
||||
#endif
|
||||
ot->poll = ED_operator_setqtcodec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
#endif /* USE_QTKIT */
|
||||
#endif /* _WIN32 || __APPLE__ */
|
||||
#endif /* WITH_QUICKTIME */
|
||||
|
@ -1,833 +0,0 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
* The Original Code is written by Rob Haarsma (phase)
|
||||
*
|
||||
* Contributor(s): Stefan Gartner (sgefant)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/quicktime/apple/quicktime_import.c
|
||||
* \ingroup quicktime
|
||||
*
|
||||
* Code to use Quicktime to load images/movies as texture.
|
||||
*/
|
||||
|
||||
#ifdef WITH_QUICKTIME
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
#ifndef USE_QTKIT
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "IMB_anim.h"
|
||||
#include "BLI_sys_types.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <QuickTime/Movies.h>
|
||||
#include <QuickTime/QuickTimeComponents.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Movies.h>
|
||||
#include <QTML.h>
|
||||
#include <TextUtils.h>
|
||||
#include <QuickTimeComponents.h>
|
||||
#include <QTLoadLibraryUtils.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
#include "quicktime_import.h"
|
||||
#include "quicktime_export.h"
|
||||
|
||||
#define RECT_WIDTH(r) (r.right - r.left)
|
||||
#define RECT_HEIGHT(r) (r.bottom - r.top)
|
||||
|
||||
#define QTIME_DEBUG 0
|
||||
|
||||
typedef struct _QuicktimeMovie {
|
||||
|
||||
GWorldPtr offscreenGWorld;
|
||||
PixMapHandle offscreenPixMap;
|
||||
Movie movie;
|
||||
Rect movieBounds;
|
||||
short movieRefNum;
|
||||
short movieResId;
|
||||
int movWidth, movHeight;
|
||||
|
||||
|
||||
int framecount;
|
||||
|
||||
|
||||
ImBuf *ibuf;
|
||||
|
||||
|
||||
TimeValue *frameIndex;
|
||||
Media theMedia;
|
||||
Track theTrack;
|
||||
long trackIndex;
|
||||
short depth;
|
||||
|
||||
int have_gw; /* ugly */
|
||||
} QuicktimeMovie;
|
||||
|
||||
|
||||
|
||||
void quicktime_init(void)
|
||||
{
|
||||
OSErr nerr;
|
||||
#ifdef _WIN32
|
||||
QTLoadLibrary("QTCF.dll");
|
||||
nerr = InitializeQTML(0);
|
||||
if (nerr != noErr) {
|
||||
G.have_quicktime = FALSE;
|
||||
}
|
||||
else
|
||||
G.have_quicktime = TRUE;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* Initialize QuickTime */
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
nerr = EnterMovies();
|
||||
if (nerr != noErr)
|
||||
G.have_quicktime = FALSE;
|
||||
else
|
||||
#endif /* _WIN32 || __APPLE__ */
|
||||
#ifdef __linux__
|
||||
/* inititalize quicktime codec registry */
|
||||
lqt_registry_init();
|
||||
#endif
|
||||
G.have_quicktime = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void quicktime_exit(void)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
#ifdef WITH_QUICKTIME
|
||||
if (G.have_quicktime) {
|
||||
free_qtcomponentdata();
|
||||
ExitMovies();
|
||||
#ifdef _WIN32
|
||||
TerminateQTML();
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
#endif /* WITH_QUICKTIME */
|
||||
#endif /* _WIN32 || __APPLE__ */
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
char *get_valid_qtname(char *name)
|
||||
{
|
||||
TCHAR Buffer[MAX_PATH];
|
||||
DWORD dwRet;
|
||||
char *qtname;
|
||||
DynStr *ds = BLI_dynstr_new();
|
||||
|
||||
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
|
||||
|
||||
if (name[1] != ':') {
|
||||
char drive[2];
|
||||
|
||||
if (name[0] == '/' || name[0] == '\\') {
|
||||
drive[0] = Buffer[0];
|
||||
drive[1] = '\0';
|
||||
|
||||
BLI_dynstr_append(ds, drive);
|
||||
BLI_dynstr_append(ds, ":");
|
||||
BLI_dynstr_append(ds, name);
|
||||
}
|
||||
else {
|
||||
BLI_dynstr_append(ds, Buffer);
|
||||
BLI_dynstr_append(ds, "/");
|
||||
BLI_dynstr_append(ds, name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_dynstr_append(ds, name);
|
||||
}
|
||||
|
||||
qtname = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
return qtname;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
int anim_is_quicktime(const char *name)
|
||||
{
|
||||
FSSpec theFSSpec;
|
||||
char theFullPath[255];
|
||||
|
||||
Boolean isMovieFile = false;
|
||||
AliasHandle myAlias = NULL;
|
||||
Component myImporter = NULL;
|
||||
#ifdef __APPLE__
|
||||
FInfo myFinderInfo;
|
||||
FSRef myRef;
|
||||
#else
|
||||
char *qtname;
|
||||
Str255 dst;
|
||||
#endif
|
||||
OSErr err = noErr;
|
||||
|
||||
// don't let quicktime movie import handle these
|
||||
if (BLI_testextensie(name, ".swf") ||
|
||||
BLI_testextensie(name, ".txt") ||
|
||||
BLI_testextensie(name, ".mpg") ||
|
||||
BLI_testextensie(name, ".avi") || /* wouldn't be appropriate ;) */
|
||||
BLI_testextensie(name, ".tga") ||
|
||||
BLI_testextensie(name, ".png") ||
|
||||
BLI_testextensie(name, ".bmp") ||
|
||||
BLI_testextensie(name, ".jpg") ||
|
||||
BLI_testextensie(name, ".tif") ||
|
||||
BLI_testextensie(name, ".exr") ||
|
||||
BLI_testextensie(name, ".wav") ||
|
||||
BLI_testextensie(name, ".zip") ||
|
||||
BLI_testextensie(name, ".mp3"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
|
||||
|
||||
#ifdef __APPLE__
|
||||
strcpy(theFullPath, name);
|
||||
|
||||
err = FSPathMakeRef(theFullPath, &myRef, 0);
|
||||
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
|
||||
#else
|
||||
qtname = get_valid_qtname(name);
|
||||
strcpy(theFullPath, qtname);
|
||||
MEM_freeN(qtname);
|
||||
|
||||
CopyCStringToPascal(theFullPath, dst);
|
||||
err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// see whether the file type is MovieFileType; to do this, get the Finder information
|
||||
err = FSpGetFInfo(&theFSSpec, &myFinderInfo);
|
||||
if (err == noErr) {
|
||||
if (myFinderInfo.fdType == kQTFileTypeMovie) {
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* on mac os x this results in using quicktime for other formats as well
|
||||
* not sure whether this is intended
|
||||
*/
|
||||
// if it isn't a movie file, see whether the file can be imported as a movie
|
||||
err = QTNewAlias(&theFSSpec, &myAlias, true);
|
||||
if (err == noErr) {
|
||||
if (myAlias != NULL) {
|
||||
err = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter);
|
||||
DisposeHandle((Handle)myAlias);
|
||||
}
|
||||
}
|
||||
|
||||
if ((err == noErr) && (myImporter != NULL)) { /* this file is a movie file */
|
||||
isMovieFile = true;
|
||||
}
|
||||
|
||||
return(isMovieFile);
|
||||
}
|
||||
|
||||
|
||||
void free_anim_quicktime(struct anim *anim)
|
||||
{
|
||||
if (anim == NULL) return;
|
||||
if (anim->qtime == NULL) return;
|
||||
|
||||
UnlockPixels(anim->qtime->offscreenPixMap);
|
||||
|
||||
if (anim->qtime->have_gw)
|
||||
DisposeGWorld(anim->qtime->offscreenGWorld);
|
||||
if (anim->qtime->ibuf)
|
||||
IMB_freeImBuf(anim->qtime->ibuf);
|
||||
|
||||
DisposeMovie(anim->qtime->movie);
|
||||
CloseMovieFile(anim->qtime->movieRefNum);
|
||||
|
||||
if (anim->qtime->frameIndex) MEM_freeN(anim->qtime->frameIndex);
|
||||
if (anim->qtime) MEM_freeN(anim->qtime);
|
||||
|
||||
anim->qtime = NULL;
|
||||
|
||||
anim->duration = 0;
|
||||
}
|
||||
|
||||
|
||||
static OSErr QT_get_frameIndexes(struct anim *anim)
|
||||
{
|
||||
int i;
|
||||
OSErr anErr = noErr;
|
||||
OSType media = VideoMediaType;
|
||||
TimeValue nextTime = 0;
|
||||
TimeValue startPoint;
|
||||
TimeValue tmpstartPoint;
|
||||
long sampleCount = 0;
|
||||
|
||||
startPoint = -1;
|
||||
|
||||
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample + nextTimeEdgeOK, (TimeValue)1, &media, 0,
|
||||
1, &startPoint, NULL);
|
||||
|
||||
tmpstartPoint = startPoint;
|
||||
|
||||
anim->qtime->framecount = 0;
|
||||
|
||||
sampleCount = GetMediaSampleCount(anim->qtime->theMedia);
|
||||
anErr = GetMoviesError();
|
||||
if (anErr != noErr) return anErr;
|
||||
|
||||
anim->qtime->framecount = sampleCount;
|
||||
|
||||
anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
|
||||
|
||||
//rewind
|
||||
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, (TimeValue)1, 0, &tmpstartPoint, NULL);
|
||||
|
||||
anim->qtime->frameIndex[0] = startPoint;
|
||||
for (i = 1; i < anim->qtime->framecount; i++) {
|
||||
nextTime = 0;
|
||||
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, startPoint, 0, &nextTime, NULL);
|
||||
startPoint = nextTime;
|
||||
anim->qtime->frameIndex[i] = nextTime;
|
||||
}
|
||||
|
||||
anErr = GetMoviesError();
|
||||
return anErr;
|
||||
}
|
||||
|
||||
|
||||
ImBuf *qtime_fetchibuf(struct anim *anim, int position)
|
||||
{
|
||||
PixMapHandle myPixMap = NULL;
|
||||
Ptr myPtr;
|
||||
|
||||
register int index;
|
||||
register int boxsize;
|
||||
|
||||
register uint32_t *readPos;
|
||||
register uint32_t *changePos;
|
||||
|
||||
ImBuf *ibuf = NULL;
|
||||
unsigned int *rect;
|
||||
#ifdef __APPLE__
|
||||
unsigned char *from, *to;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
unsigned char *crect;
|
||||
#endif
|
||||
|
||||
if (anim == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
|
||||
rect = ibuf->rect;
|
||||
|
||||
SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]);
|
||||
UpdateMovie(anim->qtime->movie);
|
||||
MoviesTask(anim->qtime->movie, 0);
|
||||
|
||||
|
||||
myPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
|
||||
myPtr = GetPixBaseAddr(myPixMap);
|
||||
|
||||
if (myPtr == NULL) {
|
||||
printf("Error reading frame from Quicktime");
|
||||
IMB_freeImBuf(ibuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
boxsize = anim->x * anim->y;
|
||||
readPos = (uint32_t *) myPtr;
|
||||
changePos = (uint32_t *) rect; //textureIMBuf *THE* data pointerrr
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Swap alpha byte to the end, so ARGB become RGBA;
|
||||
from = (unsigned char *)readPos;
|
||||
to = (unsigned char *)changePos;
|
||||
|
||||
for (index = 0; index < boxsize; index++, from += 4, to += 4) {
|
||||
to[3] = from[0];
|
||||
to[0] = from[1];
|
||||
to[1] = from[2];
|
||||
to[2] = from[3];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
for (index = 0; index < boxsize; index++, changePos++, readPos++)
|
||||
*(changePos) = *(readPos);
|
||||
|
||||
if (anim->qtime->depth < 32) {
|
||||
//add alpha to ibuf
|
||||
boxsize = anim->x * anim->y * 4;
|
||||
crect = (unsigned char *) rect;
|
||||
for (index = 0; index < boxsize; index += 4, crect += 4) {
|
||||
crect[3] = 0xFF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
IMB_flipy(ibuf);
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
|
||||
// following two functions only here to get movie pixeldepth
|
||||
|
||||
static int GetFirstVideoMedia(struct anim *anim)
|
||||
{
|
||||
long numTracks;
|
||||
OSType mediaType;
|
||||
|
||||
numTracks = GetMovieTrackCount(anim->qtime->movie);
|
||||
|
||||
for (anim->qtime->trackIndex = 1; anim->qtime->trackIndex <= numTracks; (anim->qtime->trackIndex)++) {
|
||||
anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex);
|
||||
|
||||
if (anim->qtime->theTrack)
|
||||
anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack);
|
||||
|
||||
if (anim->qtime->theMedia)
|
||||
GetMediaHandlerDescription(anim->qtime->theMedia, &mediaType, nil, nil);
|
||||
if (mediaType == VideoMediaType) return 1;
|
||||
}
|
||||
|
||||
anim->qtime->trackIndex = 0; // trackIndex can't be 0
|
||||
return 0; // went through all tracks and no video
|
||||
}
|
||||
|
||||
static short GetFirstVideoTrackPixelDepth(struct anim *anim)
|
||||
{
|
||||
SampleDescriptionHandle imageDescH = (SampleDescriptionHandle)NewHandle(sizeof(Handle));
|
||||
// long trackIndex = 0; /*unused*/
|
||||
|
||||
if (!GetFirstVideoMedia(anim))
|
||||
return -1;
|
||||
|
||||
if (!anim->qtime->trackIndex || !anim->qtime->theMedia) return -1; // we need both
|
||||
GetMediaSampleDescription(anim->qtime->theMedia, anim->qtime->trackIndex, imageDescH);
|
||||
|
||||
return (*(ImageDescriptionHandle)imageDescH)->depth;
|
||||
}
|
||||
|
||||
|
||||
int startquicktime(struct anim *anim)
|
||||
{
|
||||
FSSpec theFSSpec;
|
||||
|
||||
OSErr err = noErr;
|
||||
char theFullPath[255];
|
||||
#ifdef __APPLE__
|
||||
FSRef myRef;
|
||||
#else
|
||||
char *qtname;
|
||||
Str255 dst;
|
||||
#endif
|
||||
short depth = 0;
|
||||
|
||||
anim->qtime = MEM_callocN(sizeof(QuicktimeMovie), "animqt");
|
||||
anim->qtime->have_gw = FALSE;
|
||||
|
||||
if (anim->qtime == NULL) {
|
||||
if (QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
|
||||
|
||||
#ifdef __APPLE__
|
||||
strcpy(theFullPath, anim->name);
|
||||
|
||||
err = FSPathMakeRef(theFullPath, &myRef, 0);
|
||||
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
|
||||
#else
|
||||
qtname = get_valid_qtname(anim->name);
|
||||
strcpy(theFullPath, qtname);
|
||||
MEM_freeN(qtname);
|
||||
|
||||
CopyCStringToPascal(theFullPath, dst);
|
||||
FSMakeFSSpec(0, 0L, dst, &theFSSpec);
|
||||
#endif
|
||||
|
||||
err = OpenMovieFile(&theFSSpec, &anim->qtime->movieRefNum, fsRdPerm);
|
||||
|
||||
if (err == noErr) {
|
||||
if (QTIME_DEBUG) printf("qt: movie opened\n");
|
||||
err = NewMovieFromFile(&anim->qtime->movie,
|
||||
anim->qtime->movieRefNum,
|
||||
&anim->qtime->movieResId, NULL, newMovieActive, NULL);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name);
|
||||
if (anim->qtime->movie) {
|
||||
DisposeMovie(anim->qtime->movie);
|
||||
MEM_freeN(anim->qtime);
|
||||
if (QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
GetMovieBox(anim->qtime->movie, &anim->qtime->movieBounds);
|
||||
anim->x = anim->qtime->movWidth = RECT_WIDTH(anim->qtime->movieBounds);
|
||||
anim->y = anim->qtime->movHeight = RECT_HEIGHT(anim->qtime->movieBounds);
|
||||
if (QTIME_DEBUG) printf("qt: got bounds %s\n", anim->name);
|
||||
|
||||
if (anim->x == 0 && anim->y == 0) {
|
||||
if (QTIME_DEBUG) printf("qt: error, no dimensions\n");
|
||||
free_anim_quicktime(anim);
|
||||
return -1;
|
||||
}
|
||||
|
||||
anim->qtime->ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
|
||||
|
||||
#ifdef _WIN32
|
||||
err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
|
||||
k32RGBAPixelFormat,
|
||||
&anim->qtime->movieBounds,
|
||||
NULL, NULL, 0,
|
||||
(unsigned char *)anim->qtime->ibuf->rect,
|
||||
anim->x * 4);
|
||||
#else
|
||||
err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
|
||||
k32ARGBPixelFormat,
|
||||
&anim->qtime->movieBounds,
|
||||
NULL, NULL, 0,
|
||||
(unsigned char *)anim->qtime->ibuf->rect,
|
||||
anim->x * 4);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if (err == noErr) {
|
||||
anim->qtime->have_gw = TRUE;
|
||||
|
||||
SetMovieGWorld(anim->qtime->movie,
|
||||
anim->qtime->offscreenGWorld,
|
||||
GetGWorldDevice(anim->qtime->offscreenGWorld));
|
||||
SetMoviePlayHints(anim->qtime->movie, hintsHighQuality, hintsHighQuality);
|
||||
|
||||
// sets Media and Track!
|
||||
depth = GetFirstVideoTrackPixelDepth(anim);
|
||||
|
||||
QT_get_frameIndexes(anim);
|
||||
}
|
||||
|
||||
anim->qtime->offscreenPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
|
||||
LockPixels(anim->qtime->offscreenPixMap);
|
||||
|
||||
//fill blender's anim struct
|
||||
anim->qtime->depth = depth;
|
||||
|
||||
anim->duration = anim->qtime->framecount;
|
||||
anim->params = 0;
|
||||
|
||||
anim->interlacing = 0;
|
||||
anim->orientation = 0;
|
||||
anim->framesize = anim->x * anim->y * 4;
|
||||
|
||||
anim->curposition = 0;
|
||||
|
||||
if (QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth,
|
||||
anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int imb_is_a_quicktime(char *name)
|
||||
{
|
||||
GraphicsImportComponent theImporter = NULL;
|
||||
|
||||
FSSpec theFSSpec;
|
||||
#ifdef _WIN32
|
||||
Str255 dst; /*unused*/
|
||||
#endif
|
||||
char theFullPath[255];
|
||||
|
||||
// Boolean isMovieFile = false; /*unused*/
|
||||
// AliasHandle myAlias = NULL; /*unused*/
|
||||
// Component myImporter = NULL; /*unused*/
|
||||
#ifdef __APPLE__
|
||||
// FInfo myFinderInfo; /*unused*/
|
||||
FSRef myRef;
|
||||
#endif
|
||||
OSErr err = noErr;
|
||||
|
||||
if (!G.have_quicktime) return 0;
|
||||
|
||||
if (QTIME_DEBUG) printf("qt: checking as image %s\n", name);
|
||||
|
||||
// don't let quicktime image import handle these
|
||||
if (BLI_testextensie(name, ".swf") ||
|
||||
BLI_testextensie(name, ".txt") ||
|
||||
BLI_testextensie(name, ".mpg") ||
|
||||
BLI_testextensie(name, ".wav") ||
|
||||
BLI_testextensie(name, ".mov") || // not as image, doesn't work
|
||||
BLI_testextensie(name, ".avi") ||
|
||||
BLI_testextensie(name, ".mp3"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(theFullPath, name);
|
||||
#ifdef __APPLE__
|
||||
err = FSPathMakeRef(theFullPath, &myRef, 0);
|
||||
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
|
||||
#else
|
||||
CopyCStringToPascal(theFullPath, dst);
|
||||
err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
|
||||
#endif
|
||||
|
||||
GetGraphicsImporterForFile(&theFSSpec, &theImporter);
|
||||
|
||||
if (theImporter != NULL) {
|
||||
if (QTIME_DEBUG) printf("qt: %s valid\n", name);
|
||||
CloseComponent(theImporter);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags)
|
||||
{
|
||||
Rect myRect;
|
||||
OSErr err = noErr;
|
||||
GraphicsImportComponent gImporter = NULL;
|
||||
|
||||
ImageDescriptionHandle desc;
|
||||
|
||||
ComponentInstance dataHandler;
|
||||
PointerDataRef dataref;
|
||||
|
||||
int x, y, depth;
|
||||
int have_gw = FALSE;
|
||||
ImBuf *ibuf = NULL;
|
||||
// ImBuf *imbuf = NULL; /*unused*/
|
||||
GWorldPtr offGWorld;
|
||||
PixMapHandle myPixMap = NULL;
|
||||
|
||||
#ifdef __APPLE__
|
||||
Ptr myPtr;
|
||||
|
||||
register int index;
|
||||
register int boxsize;
|
||||
|
||||
register uint32_t *readPos;
|
||||
register uint32_t *changePos;
|
||||
|
||||
ImBuf *wbuf = NULL;
|
||||
unsigned int *rect;
|
||||
unsigned char *from, *to;
|
||||
#endif
|
||||
|
||||
if (mem == NULL || !G.have_quicktime)
|
||||
goto bail;
|
||||
|
||||
if (QTIME_DEBUG) printf("qt: attempt to load mem as image\n");
|
||||
|
||||
dataref = (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
|
||||
(**dataref).data = mem;
|
||||
(**dataref).dataLength = size;
|
||||
|
||||
err = OpenADataHandler((Handle)dataref,
|
||||
PointerDataHandlerSubType,
|
||||
nil,
|
||||
(OSType)0,
|
||||
nil,
|
||||
kDataHCanRead,
|
||||
&dataHandler);
|
||||
if (err != noErr) {
|
||||
if (QTIME_DEBUG) printf("no datahandler\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
err = GetGraphicsImporterForDataRef((Handle)dataref, PointerDataHandlerSubType, &gImporter);
|
||||
if (err != noErr) {
|
||||
if (QTIME_DEBUG) printf("no graphimport\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
err = GraphicsImportGetNaturalBounds(gImporter, &myRect);
|
||||
if (err != noErr) {
|
||||
if (QTIME_DEBUG) printf("no bounds\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
err = GraphicsImportGetImageDescription(gImporter, &desc);
|
||||
if (err != noErr) {
|
||||
if (QTIME_DEBUG) printf("no imagedescription\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
x = RECT_WIDTH(myRect);
|
||||
y = RECT_HEIGHT(myRect);
|
||||
depth = (**desc).depth;
|
||||
|
||||
if (flags & IB_test) {
|
||||
ibuf = IMB_allocImBuf(x, y, depth, 0);
|
||||
ibuf->ftype = QUICKTIME;
|
||||
DisposeHandle((Handle)dataref);
|
||||
if (gImporter != NULL) CloseComponent(gImporter);
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
ibuf = IMB_allocImBuf(x, y, 32, IB_rect);
|
||||
wbuf = IMB_allocImBuf(x, y, 32, IB_rect);
|
||||
|
||||
err = NewGWorldFromPtr(&offGWorld,
|
||||
k32ARGBPixelFormat,
|
||||
&myRect, NULL, NULL, 0,
|
||||
(unsigned char *)wbuf->rect, x * 4);
|
||||
#else
|
||||
|
||||
ibuf = IMB_allocImBuf(x, y, 32, IB_rect);
|
||||
|
||||
err = NewGWorldFromPtr(&offGWorld,
|
||||
k32RGBAPixelFormat,
|
||||
&myRect, NULL, NULL, 0,
|
||||
(unsigned char *)ibuf->rect, x * 4);
|
||||
#endif
|
||||
|
||||
if (err != noErr) {
|
||||
if (QTIME_DEBUG) printf("no newgworld\n");
|
||||
goto bail;
|
||||
}
|
||||
else {
|
||||
have_gw = TRUE;
|
||||
}
|
||||
|
||||
GraphicsImportSetGWorld(gImporter, offGWorld, NULL);
|
||||
GraphicsImportDraw(gImporter);
|
||||
|
||||
#ifdef __APPLE__
|
||||
rect = ibuf->rect;
|
||||
|
||||
myPixMap = GetGWorldPixMap(offGWorld);
|
||||
LockPixels(myPixMap);
|
||||
myPtr = GetPixBaseAddr(myPixMap);
|
||||
|
||||
if (myPtr == NULL) {
|
||||
printf("Error reading frame from Quicktime");
|
||||
IMB_freeImBuf(ibuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
boxsize = x * y;
|
||||
readPos = (uint32_t *) myPtr;
|
||||
changePos = (uint32_t *) rect;
|
||||
|
||||
// Swap alpha byte to the end, so ARGB become RGBA;
|
||||
from = (unsigned char *)readPos;
|
||||
to = (unsigned char *)changePos;
|
||||
|
||||
for (index = 0; index < boxsize; index++, from += 4, to += 4) {
|
||||
to[3] = from[0];
|
||||
to[0] = from[1];
|
||||
to[1] = from[2];
|
||||
to[2] = from[3];
|
||||
}
|
||||
#endif
|
||||
|
||||
bail:
|
||||
|
||||
DisposeHandle((Handle)dataref);
|
||||
UnlockPixels(myPixMap);
|
||||
if (have_gw) DisposeGWorld(offGWorld);
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (wbuf) {
|
||||
IMB_freeImBuf(wbuf);
|
||||
wbuf = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gImporter != NULL) CloseComponent(gImporter);
|
||||
|
||||
if (err != noErr) {
|
||||
if (QTIME_DEBUG) printf("quicktime import unsuccesfull\n");
|
||||
if (ibuf) {
|
||||
IMB_freeImBuf(ibuf);
|
||||
ibuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ibuf) {
|
||||
|
||||
#ifdef _WIN32
|
||||
// add non transparent alpha layer, so images without alpha show up in the sequence editor
|
||||
// exception for GIF images since these can be transparent without being 32 bit
|
||||
// (might also be nescessary for OSX)
|
||||
int i;
|
||||
int box = x * y;
|
||||
unsigned char *arect = (unsigned char *) ibuf->rect;
|
||||
|
||||
if (depth < 32 && (**desc).cType != kGIFCodecType) {
|
||||
for (i = 0; i < box; i++, arect += 4)
|
||||
arect[3] = 0xFF;
|
||||
}
|
||||
#endif
|
||||
|
||||
IMB_flipy(ibuf);
|
||||
ibuf->ftype = QUICKTIME;
|
||||
}
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
#endif /* USE_QTKIT */
|
||||
#endif /* _WIN32 || __APPLE__ */
|
||||
|
||||
#endif /* WITH_QUICKTIME */
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
struct ImageDescription {
|
||||
long idSize;
|
||||
CodecType cType;
|
||||
long resvd1;
|
||||
short resvd2;
|
||||
short dataRefIndex;
|
||||
short version;
|
||||
short revisionLevel;
|
||||
long vendor;
|
||||
CodecQ temporalQuality;
|
||||
CodecQ spatialQuality;
|
||||
short width;
|
||||
short height;
|
||||
Fixed hRes;
|
||||
Fixed vRes;
|
||||
long dataSize;
|
||||
short frameCount;
|
||||
Str31 name;
|
||||
short depth;
|
||||
short clutID;
|
||||
};
|
||||
|
||||
#endif // 0
|
@ -69,25 +69,18 @@ QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue);
|
||||
int quicktime_rnatmpvalue_from_videocodectype(int codecType);
|
||||
int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue);
|
||||
|
||||
#ifdef USE_QTKIT
|
||||
/*Audio codec type*/
|
||||
int quicktime_get_num_audiocodecs(void);
|
||||
QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue);
|
||||
int quicktime_rnatmpvalue_from_audiocodectype(int codecType);
|
||||
int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue);
|
||||
#endif
|
||||
|
||||
#ifndef USE_QTKIT
|
||||
void SCENE_OT_render_data_set_quicktime_codec(struct wmOperatorType *ot); //Operator to raise quicktime standard dialog to request codec settings
|
||||
#endif
|
||||
|
||||
|
||||
void free_qtcomponentdata(void);
|
||||
void makeqtstring(struct RenderData *rd, char *string); //for playanim.c
|
||||
|
||||
|
||||
|
||||
#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__)
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__)
|
||||
//Include the quicktime codec types constants that are missing in QTKitDefines.h
|
||||
enum {
|
||||
kRawCodecType = 'raw ',
|
||||
|
@ -42,18 +42,6 @@
|
||||
#include "../imbuf/IMB_imbuf.h"
|
||||
#include "../imbuf/IMB_imbuf_types.h"
|
||||
|
||||
#ifndef USE_QTKIT
|
||||
# ifndef __MOVIES__
|
||||
# ifdef _WIN32
|
||||
# include <Movies.h>
|
||||
# elif defined(__APPLE__)
|
||||
# define __CARBONSOUND__
|
||||
# import <Carbon/Carbon.h>
|
||||
# include <QuickTime/Movies.h>
|
||||
# endif
|
||||
# endif /* __MOVIES__ */
|
||||
#endif /* USE_QTKIT */
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef __FIXMATH__
|
||||
# include <FixMath.h>
|
||||
|
Loading…
Reference in New Issue
Block a user