Ivan Vučica avatar Ivan Vučica committed 293e4c5

Basic code for producing reference movies.

Comments (0)

Files changed (6)

MakeRefMovieCLI.xcodeproj/project.pbxproj

+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		7F0C43B514FAAC5100D734B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F0C43B414FAAC5100D734B7 /* Foundation.framework */; };
+		7F0C43BC14FAAC5100D734B7 /* MakeRefMovieCLI.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7F0C43BB14FAAC5100D734B7 /* MakeRefMovieCLI.1 */; };
+		7F0C43C514FAACA800D734B7 /* makerefmovie.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F0C43C414FAACA800D734B7 /* makerefmovie.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		7F0C43AE14FAAC5100D734B7 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+				7F0C43BC14FAAC5100D734B7 /* MakeRefMovieCLI.1 in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		7F0C43B014FAAC5100D734B7 /* MakeRefMovieCLI */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MakeRefMovieCLI; sourceTree = BUILT_PRODUCTS_DIR; };
+		7F0C43B414FAAC5100D734B7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		7F0C43BA14FAAC5100D734B7 /* MakeRefMovieCLI-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MakeRefMovieCLI-Prefix.pch"; sourceTree = "<group>"; };
+		7F0C43BB14FAAC5100D734B7 /* MakeRefMovieCLI.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = MakeRefMovieCLI.1; sourceTree = "<group>"; };
+		7F0C43C414FAACA800D734B7 /* makerefmovie.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = makerefmovie.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		7F0C43AD14FAAC5100D734B7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				7F0C43B514FAAC5100D734B7 /* Foundation.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		7F0C43A514FAAC5000D734B7 = {
+			isa = PBXGroup;
+			children = (
+				7F0C43B614FAAC5100D734B7 /* MakeRefMovieCLI */,
+				7F0C43B314FAAC5100D734B7 /* Frameworks */,
+				7F0C43B114FAAC5100D734B7 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		7F0C43B114FAAC5100D734B7 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				7F0C43B014FAAC5100D734B7 /* MakeRefMovieCLI */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		7F0C43B314FAAC5100D734B7 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				7F0C43B414FAAC5100D734B7 /* Foundation.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		7F0C43B614FAAC5100D734B7 /* MakeRefMovieCLI */ = {
+			isa = PBXGroup;
+			children = (
+				7F0C43C414FAACA800D734B7 /* makerefmovie.m */,
+				7F0C43BB14FAAC5100D734B7 /* MakeRefMovieCLI.1 */,
+				7F0C43B914FAAC5100D734B7 /* Supporting Files */,
+			);
+			path = MakeRefMovieCLI;
+			sourceTree = "<group>";
+		};
+		7F0C43B914FAAC5100D734B7 /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				7F0C43BA14FAAC5100D734B7 /* MakeRefMovieCLI-Prefix.pch */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		7F0C43AF14FAAC5100D734B7 /* MakeRefMovieCLI */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 7F0C43BF14FAAC5100D734B7 /* Build configuration list for PBXNativeTarget "MakeRefMovieCLI" */;
+			buildPhases = (
+				7F0C43AC14FAAC5100D734B7 /* Sources */,
+				7F0C43AD14FAAC5100D734B7 /* Frameworks */,
+				7F0C43AE14FAAC5100D734B7 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = MakeRefMovieCLI;
+			productName = MakeRefMovieCLI;
+			productReference = 7F0C43B014FAAC5100D734B7 /* MakeRefMovieCLI */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		7F0C43A714FAAC5000D734B7 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0420;
+			};
+			buildConfigurationList = 7F0C43AA14FAAC5000D734B7 /* Build configuration list for PBXProject "MakeRefMovieCLI" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 7F0C43A514FAAC5000D734B7;
+			productRefGroup = 7F0C43B114FAAC5100D734B7 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				7F0C43AF14FAAC5100D734B7 /* MakeRefMovieCLI */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		7F0C43AC14FAAC5100D734B7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				7F0C43C514FAACA800D734B7 /* makerefmovie.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		7F0C43BD14FAAC5100D734B7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		7F0C43BE14FAAC5100D734B7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		7F0C43C014FAAC5100D734B7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "MakeRefMovieCLI/MakeRefMovieCLI-Prefix.pch";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		7F0C43C114FAAC5100D734B7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "MakeRefMovieCLI/MakeRefMovieCLI-Prefix.pch";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		7F0C43AA14FAAC5000D734B7 /* Build configuration list for PBXProject "MakeRefMovieCLI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				7F0C43BD14FAAC5100D734B7 /* Debug */,
+				7F0C43BE14FAAC5100D734B7 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		7F0C43BF14FAAC5100D734B7 /* Build configuration list for PBXNativeTarget "MakeRefMovieCLI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				7F0C43C014FAAC5100D734B7 /* Debug */,
+				7F0C43C114FAAC5100D734B7 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 7F0C43A714FAAC5000D734B7 /* Project object */;
+}

MakeRefMovieCLI/MakeRefMovieCLI-Prefix.pch

+//
+// Prefix header for all source files of the 'MakeRefMovieCLI' target in the 'MakeRefMovieCLI' project
+//
+
+#ifdef __OBJC__
+    #import <Foundation/Foundation.h>
+#endif

MakeRefMovieCLI/MakeRefMovieCLI.1

+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
+.\"See Also:
+.\"man mdoc.samples for a complete listing of options
+.\"man mdoc for the short list of editing options
+.\"/usr/share/misc/mdoc.template
+.Dd 26.02.2012.               \" DATE 
+.Dt MakeRefMovieCLI 1      \" Program name and manual section number 
+.Os Darwin
+.Sh NAME                 \" Section Header - required - don't modify 
+.Nm MakeRefMovieCLI,
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line. 
+.Nm Other_name_for_same_program(),
+.Nm Yet another name for the same program.
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd This line parsed for whatis database.
+.Sh SYNOPSIS             \" Section Header - required - don't modify
+.Nm
+.Op Fl abcd              \" [-abcd]
+.Op Fl a Ar path         \" [-a path] 
+.Op Ar file              \" [file]
+.Op Ar                   \" [file ...]
+.Ar arg0                 \" Underlined argument - use .Ar anywhere to underline
+arg2 ...                 \" Arguments
+.Sh DESCRIPTION          \" Section Header - required - don't modify
+Use the .Nm macro to refer to your program throughout the man page like such:
+.Nm
+Underlining is accomplished with the .Ar macro like this:
+.Ar underlined text .
+.Pp                      \" Inserts a space
+A list of items with descriptions:
+.Bl -tag -width -indent  \" Begins a tagged list 
+.It item a               \" Each item preceded by .It macro
+Description of item a
+.It item b
+Description of item b
+.El                      \" Ends the list
+.Pp
+A list of flags and their descriptions:
+.Bl -tag -width -indent  \" Differs from above in tag removed 
+.It Fl a                 \"-a flag as a list item
+Description of -a flag
+.It Fl b
+Description of -b flag
+.El                      \" Ends the list
+.Pp
+.\" .Sh ENVIRONMENT      \" May not be needed
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
+.\" .It Ev ENV_VAR_1
+.\" Description of ENV_VAR_1
+.\" .It Ev ENV_VAR_2
+.\" Description of ENV_VAR_2
+.\" .El                      
+.Sh FILES                \" File used or created by the topic of the man page
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
+.It Pa /usr/share/file_name
+FILE_1 description
+.It Pa /Users/joeuser/Library/really_long_file_name
+FILE_2 description
+.El                      \" Ends the list
+.\" .Sh DIAGNOSTICS       \" May not be needed
+.\" .Bl -diag
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .El
+.Sh SEE ALSO 
+.\" List links in ascending order by section, alphabetically within a section.
+.\" Please do not reference files that do not exist without filing a bug report
+.Xr a 1 , 
+.Xr b 1 ,
+.Xr c 1 ,
+.Xr a 2 ,
+.Xr b 2 ,
+.Xr a 3 ,
+.Xr b 3 
+.\" .Sh BUGS              \" Document known, unremedied bugs 
+.\" .Sh HISTORY           \" Document history if command behaves in a unique manner

MakeRefMovieCLI/Makefile

+all: makerefmovie
+makerefmovie: makerefmovie.o
+	g++ makerefmovie.o -o makerefmovie -framework Foundation

MakeRefMovieCLI/makerefmovie.m

+#import <stdio.h>
+#import <Foundation/Foundation.h>
+
+#define ENDIANESS_FLIP_32(x) (\
+    ((((x) & 0xFF) << 24) & 0xFF000000) | \
+    ((((x) & 0xFF00) <<  8) & 0xFF0000) | \
+    ((((x) & 0xFF0000) >>  8) & 0xFF00) | \
+    ((((x) & 0xFF000000) >> 24) & 0xFF) \
+    )
+
+#pragma pack(0)
+struct ReferenceMovieDataRefRecord {
+    uint32_t         flags;
+    OSType           dataRefType;
+    uint32_t         dataRefSize;
+    //char             dataRef[1];
+};
+#pragma pack()
+typedef struct ReferenceMovieDataRefRecord ReferenceMovieDataRefRecord;
+
+////////////////////
+
+@interface Atom : NSObject
+{
+	NSString * _name;
+	NSMutableData * data;
+}
+@property (nonatomic, retain) NSString * name;
+@end
+@interface MovieAtom : Atom 
+{
+}
+@end
+@interface ReferenceMovieAtom : Atom 
+{
+}
+@end
+@interface ReferenceMovieDescriptorAtom : Atom 
+{
+}
+@end
+@interface ReferenceMovieDataReferenceAtom : Atom 
+{
+    ReferenceMovieDataRefRecord record;
+    NSString * _path;
+    char * _cPath;
+}
+@property (nonatomic, retain) NSString * path;
+@end
+///////////////////
+
+@implementation Atom
+@synthesize name=_name;
+- (id)initWithName:(NSString*)name;
+{
+	self = [super init];
+	if(!self)
+		return nil;
+
+    self.name = name;
+	data = [NSMutableData new];
+
+	return self;
+}
+- (void)dealloc
+{
+	[data release];
+	[super dealloc];
+}
+-(NSMutableData*)resultData
+{
+    uint32_t num = ENDIANESS_FLIP_32(data.length + /* size */ 4 + 4 /* name */);
+	NSMutableData * returnData = [NSMutableData dataWithBytes:&num length:4];
+    [returnData appendBytes:[_name UTF8String] length:4];
+    [returnData appendData:data];
+    return returnData;
+}
+-(void)appendAtom:(Atom*)atom
+{
+    [data appendData:[atom resultData]];
+}
+-(void)writeToFile:(NSString*)path
+{
+    [[self resultData] writeToFile:path atomically:YES];
+}
+@end
+
+
+@implementation MovieAtom
+-(id)init
+{
+    self = [super initWithName:@"moov"];
+    if(!self)
+        return nil;
+    
+    
+    return self;
+}
+@end
+
+
+@implementation ReferenceMovieAtom
+-(id)init
+{
+    self = [super initWithName:@"rmra"];
+    if(!self)
+        return nil;
+    
+    
+    return self;
+}
+@end
+
+
+@implementation ReferenceMovieDescriptorAtom
+-(id)init
+{
+    self = [super initWithName:@"rmda"];
+    if(!self)
+        return nil;
+    
+    
+    return self;
+}
+@end
+////////////
+@implementation ReferenceMovieDataReferenceAtom
+@synthesize path=_path;
+-(id)initWithPath:(NSString*)path
+{
+    self = [super initWithName:@"rdrf"];
+    if(!self)
+        return nil;
+    
+    self.path = path;
+    if([self.path isAbsolutePath])
+        self.path = [[NSURL fileURLWithPath:self.path] string];
+    
+    record.flags = 0; // not selfcontained
+    record.dataRefType = ENDIANESS_FLIP_32('url ');
+    record.dataRefSize = ENDIANESS_FLIP_32([self.path length]+1);
+    //record.dataRef = _cPath;
+    
+    [data appendBytes:&record length:12/*sizeof(record)*/];
+    [data appendBytes:self.path.UTF8String length:self.path.length + 1];
+    
+    return self;
+}
+-(void)dealloc
+{
+    free(_cPath);
+    [_path release];
+    [super dealloc];
+}
+@end
+
+
+
+
+void usage();
+
+void usage()
+{
+	printf("  usage: makerefmovie referencedfile.extension outputfile.mov\n");	
+}
+
+int main(int argc, char ** argv)
+{
+	if(argc != 3)
+	{
+		usage();
+		return 1;
+	}
+    NSAutoreleasePool * pool = [NSAutoreleasePool new];
+    MovieAtom * moov = [[MovieAtom new] autorelease];
+    ReferenceMovieAtom * rmra = [[ReferenceMovieAtom new] autorelease];
+    ReferenceMovieDescriptorAtom * rmda = [[ReferenceMovieDescriptorAtom new] autorelease];
+    ReferenceMovieDataReferenceAtom * rmrf = [[[ReferenceMovieDataReferenceAtom alloc] initWithPath:[NSString stringWithUTF8String:argv[1]]] autorelease];
+    
+    [rmda appendAtom:rmrf];
+    [rmra appendAtom:rmda];
+    [moov appendAtom:rmra];
+    
+    [moov writeToFile:[NSString stringWithUTF8String:argv[2]]];
+    
+    [pool release];
+    
+	return 0;
+}
+MakeRefMovieCLI
+===============
+
+This is a minimal command line tool to create a QuickTime reference movie.
+Written in Objective-C, all it does is create the few required atoms.
+It makes no use of data rate, gestalt, component check nor quality atoms.
+It has no support for "upgrading" existing QuickTime movies, nor opening
+existing QuickTime movies (either reference movies or otherwise) in any way.
+
+It makes use only of Objective-C Foundation, and makes useof no QuickTime
+APIs.
+
+It only supports creation of URL-based reference movies, and does not support
+creation of alias-based reference movies.
+
+To use it, as first argument, pass the original movie. As second argument,
+pass the output .mov file.
+
+Reference movies are a convenient way to add non-.mov and non-.mp4 files
+into your iTunes library. You can then use converter built into iTunes
+to get proper .mp4 files for putting onto your iPhone, iPod Touch or
+iPad.
+
+Based on information published on:
+<https://developer.apple.com/quicktime/icefloe/dispatch015.html>
+
+License
+-------
+
+Copyright (c) 2012, Ivan Vučica
+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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.