Skip to content

Commit

Permalink
Merge pull request #705 from MediaArea/sony9pin
Browse files Browse the repository at this point in the history
Add camera control support through Sony9Pin or DeckLink native interface
  • Loading branch information
dericed authored Jul 12, 2023
2 parents 6ca3c8b + 4df21b2 commit 7b527fb
Show file tree
Hide file tree
Showing 29 changed files with 5,036 additions and 78 deletions.
11 changes: 10 additions & 1 deletion Project/GNU/CLI/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ dvrescue_SOURCES = \
INCLUDES = -I../../../Source \
-I../../../Source/ThirdParty/ccdecoder \
-I../../../Source/ThirdParty/TimeCode \
-I../../../Source/ThirdParty/serial/include \
-I../../../../MediaInfoLib/Source \
-I../../../../ZenLib/Source
AM_CXXFLAGS = -std=c++11

AM_CXXFLAGS = -std=c++17

bin_SCRIPTS = \
../../../tools/dvloupe \
Expand Down Expand Up @@ -55,6 +57,13 @@ if BUILD_DECKLINK
../../../Source/Common/Output_Mkv.cpp
endif

if BUILD_SONY9PIN
dvrescue_SOURCES += ../../../Source/Common/Sony9PinWrapper.cpp \
../../../Source/ThirdParty/serial/src/impl/list_ports/list_ports_osx.cc \
../../../Source/ThirdParty/serial/src/impl/unix.cc \
../../../Source/ThirdParty/serial/src/serial.cc
endif

if BUILD_LNX1394
dvrescue_SOURCES += ../../../Source/Common/LinuxWrapper.cpp
endif
Expand Down
15 changes: 14 additions & 1 deletion Project/GNU/CLI/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dnl -------------------------------------------------------------------------
dnl Autotools init
dnl
CFLAGS="$CFLAGS"
CXXFLAGS="$CXXFLAGS"
CXXFLAGS="-std=c++17 $CXXFLAGS"
AC_PROG_CC
AC_PROG_CXX
AC_PROG_OBJC
Expand Down Expand Up @@ -52,6 +52,7 @@ AC_ARG_ENABLE(staticlibs, AC_HELP_STRING([--enable-staticlibs], [Use
AC_ARG_ENABLE(avfctl, AC_HELP_STRING([--enable-avfctl], [Build avfctl tool (macOS only)]), , enable_avfctl=yes)
AC_ARG_ENABLE(capture, AC_HELP_STRING([--enable-capture], [Use libavc1394 and libdc1394 for capture support on linux]), , enable_capture=yes)
AC_ARG_ENABLE(decklink, AC_HELP_STRING([--enable-decklink], [Enable capture from Blackmagic capture devices]), , enable_decklink=no)
AC_ARG_ENABLE(sony9pin, AC_HELP_STRING([--enable-sony9pin], [Enable control through Sony9Pin serial interface]), , enable_sony9pin=no)

dnl -------------------------------------------------------------------------
dnl Arguments - With
Expand All @@ -60,6 +61,7 @@ AC_ARG_WITH(macosx-sdk, AC_HELP_STRING([--with-macosx-sdk], [For
AC_ARG_WITH(macosx-version-min, AC_HELP_STRING([--with-macosx-version-min], [Force the Mac Version]), , with_macosx_version_min=no)
AC_ARG_WITH(dll, AC_HELP_STRING([--with-dll], [Do not link to libmediainfo, dynamic loading]), , with_dll=no)
AC_ARG_WITH(decklink-sdk, AC_HELP_STRING([--with-decklink-sdk], [Path of the decklink SDK]), , with_decklink_sdk=no)
AC_ARG_WITH(sony9pin-sdk, AC_HELP_STRING([--with-sony9pin-sdk], [Path of the sony9pin SDK]), , with_sony9pin_sdk=no)

dnl #########################################################################
dnl ### Options from elsewhere
Expand Down Expand Up @@ -112,6 +114,17 @@ if test "$host_macos" = "yes" -a "$enable_decklink" = "yes" ; then
AC_CHECK_HEADERS([DeckLinkAPI.h], , [AC_MSG_ERROR([Blackmagic DeckLink SDK is not found])])
fi

AM_CONDITIONAL([BUILD_SONY9PIN], [test "$host_macos" = "yes" -a "$enable_sony9pin" = "yes"])
if test "$host_macos" = "yes" -a "$enable_sony9pin" = "yes" ; then
AC_DEFINE(ENABLE_CAPTURE)
AC_DEFINE(ENABLE_SONY9PIN)
if test "$with_sony9pin_sdk" != "no" ; then
CXXFLAGS="$CXXFLAGS -I$with_sony9pin_sdk"
fi
dnl TODO: find a way to check for Sony9PinRemote.h
dnl AC_CHECK_HEADERS([Sony9PinRemote.h], , [AC_MSG_ERROR([Sony9pin SDK is not found])])
fi

dnl #########################################################################
dnl ### MediaInfo flags
dnl #########################################################################
Expand Down
11 changes: 11 additions & 0 deletions Source/CLI/CLI_Help.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,24 @@ return_value Help(ostream& Out, const char* Name, bool Full)
" Is the default if no --cmd option is provided.\n"
" Usable only if input is a device.\n"
"\n"
#if defined(ENABLE_SONY9PIN) || defined(ENABLE_DECKLINK)
" --control <port>\n"
" Set the serial port used to control the DeckLink capture device through sony9pin interface.\n"
" Use \"native\" to request control through DeckLink serial inteface.\n"
"\n"
#endif
" --in-control\n"
" Include an integrated command line input for controlling the input.\n"
" Usable only if input is a device.\n"
"\n"
" --list_devices\n"
" List detected devices and their indices.\n"
"\n"
#ifdef ENABLE_SONY9PIN
" --list_controls\n"
" List detected serial ports and their indices.\n"
"\n"
#endif
" --status\n"
" Provide the status (playing, stop...) of the input.\n"
" By default device://0 is used.\n"
Expand Down
19 changes: 19 additions & 0 deletions Source/CLI/CommandLine_Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,25 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
{
Device_Command = 1;
}
#ifdef ENABLE_SONY9PIN
else if (!strcmp(argv_ansi[i], "--list_controls") || !strcmp(argv_ansi[i], "-list_controls"))
{
Device_Command = 4;
}
#endif
#if defined(ENABLE_SONY9PIN) || defined(ENABLE_DECKLINK)
else if (!strcmp(argv_ansi[i], "--control"))
{
if (++i >= argc)
{
if (C.Err)
*C.Err << "Error: missing control port name after " << argv_ansi[i - 1] << ".\n";
ReturnValue = ReturnValue_ERROR;
continue;
}
Control_Port = argv_ansi[i];
}
#endif
else if (!strcmp(argv_ansi[i], "--device") || !strcmp(argv_ansi[i], "-device"))
{
if (++i >= argc)
Expand Down
5 changes: 3 additions & 2 deletions Source/Common/AvfCtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

@interface AVFCtl : NSObject {
id <ReceiverTimer> receiverInstance;
id externalController;
}

@property (nonatomic, retain) AVCaptureDevice *device;
Expand All @@ -57,8 +58,8 @@
+ (NSString*) getDeviceID:(NSUInteger) index;
+ (NSInteger) getDeviceIndex:(NSString*) uniqueID;
+ (BOOL) isTransportControlsSupported:(NSUInteger) index;
- (id) initWithDeviceIndex:(NSUInteger) index;
- (id) initWithDeviceID:(NSString*) uniqueID;
- (id) initWithDeviceIndex:(NSUInteger) index controller:(id) extCtl;
- (id) initWithDeviceID:(NSString*) uniqueID controller:(id) extCtl;
- (void) dealloc;
- (NSString*) getStatus;
- (void) createCaptureSession:(id) receiver;
Expand Down
25 changes: 22 additions & 3 deletions Source/Common/AvfCtl.m
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ + (BOOL) isTransportControlsSupported:(NSUInteger) index
return [[[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed] objectAtIndex:index] transportControlsSupported];
}

- (id) initWithDeviceIndex:(NSUInteger) index
- (id) initWithDeviceIndex:(NSUInteger) index controller:(id) extCtl
{
if (index >= [[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed] count])
return nil;
Expand All @@ -172,11 +172,13 @@ - (id) initWithDeviceIndex:(NSUInteger) index

keyPath = NSStringFromSelector(@selector(transportControlsSpeed));
[_device addObserver:self forKeyPath:keyPath options:options context:nil];

externalController = extCtl;
}
return self;
}

- (id) initWithDeviceID:(NSString*) uniqueID
- (id) initWithDeviceID:(NSString*) uniqueID controller:(id) extCtl
{
self = [super init];
if (self) {
Expand Down Expand Up @@ -205,6 +207,8 @@ - (id) initWithDeviceID:(NSString*) uniqueID

keyPath = NSStringFromSelector(@selector(transportControlsSpeed));
[_device addObserver:self forKeyPath:keyPath options:options context:nil];

externalController = extCtl;
}
return self;
}
Expand Down Expand Up @@ -261,6 +265,9 @@ - (void) observeValueForKeyPath:(NSString *)keyPath

- (NSString*) getStatus
{
if (externalController)
return [externalController getStatus];

NSString *status;

float speed = [_device transportControlsSpeed];
Expand Down Expand Up @@ -343,6 +350,12 @@ - (void) stopCaptureSession

- (void) setPlaybackMode:(AVCaptureDeviceTransportControlsPlaybackMode)theMode speed:(AVCaptureDeviceTransportControlsSpeed) theSpeed
{
if (externalController)
{
[externalController setPlaybackMode:theMode speed:theSpeed];
return;
}

@try {
NSError *error = nil;
if ([_device lockForConfiguration:&error] == YES) {
Expand All @@ -359,11 +372,17 @@ - (void) setPlaybackMode:(AVCaptureDeviceTransportControlsPlaybackMode)theMode s

- (AVCaptureDeviceTransportControlsSpeed) getSpeed
{
if (externalController)
return [externalController getSpeed];

return [_device transportControlsSpeed];
}

- (AVCaptureDeviceTransportControlsPlaybackMode) getMode
{
if (externalController)
return [externalController getMode];

return [_device transportControlsPlaybackMode];
}

Expand All @@ -377,7 +396,7 @@ - (BOOL) waitForSessionEnd:(NSUInteger) timeout
[formatter setDateFormat:@"YYYY-MM-dd-HH-mm-ss"];
// block as long as the capture session is running
// terminates if playback mode changes to NotPlaying
while ([_device transportControlsSpeed] != 0.0f) {
while ([self getSpeed] != 0.0f) {
if (timeout && receiverInstance && [[NSDate dateWithTimeInterval:timeout sinceDate:[receiverInstance lastInput]] compare:[NSDate date]] == NSOrderedAscending)
{
[self setPlaybackMode:AVCaptureDeviceTransportControlsNotPlayingMode speed: 0.0f];
Expand Down
5 changes: 3 additions & 2 deletions Source/Common/AvfCtlWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
class AVFCtlWrapper : public BaseWrapper {
public:
// Constructor/Destructor
AVFCtlWrapper(std::size_t DeviceIndex);
AVFCtlWrapper(std::string DeviceID);
AVFCtlWrapper(std::size_t DeviceIndex, ControllerBaseWrapper* ExtCtl = nullptr);
AVFCtlWrapper(std::string DeviceID, ControllerBaseWrapper* ExtCtl = nullptr);
~AVFCtlWrapper();

// Functions
Expand All @@ -40,4 +40,5 @@ class AVFCtlWrapper : public BaseWrapper {

private:
void* Ctl;
ControllerBaseWrapper* ExtCtl;
};
68 changes: 64 additions & 4 deletions Source/Common/AvfCtlWrapper.mm
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,74 @@ - (void) captureOutput:(AVCaptureOutput *)captureOutput
}
@end

AVFCtlWrapper::AVFCtlWrapper(size_t DeviceIndex)
@interface AVFCtlExternalController : NSObject
@property (assign,nonatomic) ControllerBaseWrapper *controller;
- (id) initWithController:(ControllerBaseWrapper*)extCtl;
- (NSString*) getStatus;
- (void) setPlaybackMode:(AVCaptureDeviceTransportControlsPlaybackMode)theMode speed:(AVCaptureDeviceTransportControlsSpeed) theSpeed;
- (AVCaptureDeviceTransportControlsPlaybackMode) getMode;
- (AVCaptureDeviceTransportControlsSpeed) getSpeed;
@end

@implementation AVFCtlExternalController

- (id) initWithController:(ControllerBaseWrapper*)extCtl
{
self = [super init];

if (self)
_controller = extCtl;

return self;
}

- (NSString*) getStatus
{
if (_controller)
return [NSString stringWithUTF8String:_controller->GetStatus().c_str()];

return @"unknown";
}

- (void) setPlaybackMode:(AVCaptureDeviceTransportControlsPlaybackMode)theMode speed:(AVCaptureDeviceTransportControlsSpeed) theSpeed;
{
Ctl = (void*)[[AVFCtl alloc] initWithDeviceIndex:DeviceIndex];
if (_controller)
_controller->SetPlaybackMode((playback_mode)theMode, (float)theSpeed);
}

AVFCtlWrapper::AVFCtlWrapper(string DeviceID)
- (AVCaptureDeviceTransportControlsPlaybackMode) getMode
{
Ctl = (void*)[[AVFCtl alloc] initWithDeviceID:[NSString stringWithUTF8String:DeviceID.c_str()]];
if (_controller)
return (AVCaptureDeviceTransportControlsPlaybackMode)_controller->GetMode();

return AVCaptureDeviceTransportControlsNotPlayingMode;
}

- (AVCaptureDeviceTransportControlsSpeed) getSpeed
{
if (_controller)
return (AVCaptureDeviceTransportControlsSpeed)_controller->GetSpeed();

return (AVCaptureDeviceTransportControlsSpeed)0.0f;
}
@end

AVFCtlWrapper::AVFCtlWrapper(size_t DeviceIndex, ControllerBaseWrapper* ExtCtl) : ExtCtl(ExtCtl)
{
AVFCtlExternalController* ExternalController = nil;
if (ExtCtl)
ExternalController = [[AVFCtlExternalController alloc] initWithController:ExtCtl];

Ctl = (void*)[[AVFCtl alloc] initWithDeviceIndex:DeviceIndex controller:ExternalController];
}

AVFCtlWrapper::AVFCtlWrapper(string DeviceID, ControllerBaseWrapper* ExtCtl) : ExtCtl(ExtCtl)
{
AVFCtlExternalController* ExternalController = nil;
if (ExtCtl)
ExternalController = [[AVFCtlExternalController alloc] initWithController:ExtCtl];

Ctl = (void*)[[AVFCtl alloc] initWithDeviceID:[NSString stringWithUTF8String:DeviceID.c_str()] controller:ExternalController];
}

AVFCtlWrapper::~AVFCtlWrapper()
Expand Down
Loading

0 comments on commit 7b527fb

Please sign in to comment.