cog/Plugins/Quicktime/QuicktimeDecoder.m

201 lines
6.3 KiB
Matlab
Raw Normal View History

2007-06-10 21:34:20 +00:00
//
// QuicktimeDecoder.m
// Quicktime
//
// Created by Vincent Spader on 6/10/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "QuicktimeDecoder.h"
#import "Quicktime/QuicktimeComponents.h"
2007-06-10 21:34:20 +00:00
@implementation QuicktimeDecoder
- (BOOL)open:(id<CogSource>)source {
2007-06-10 21:34:20 +00:00
NSLog(@"Opening!");
NSURL *url = [source url];
OSErr error;
Handle dataRef;
OSType dataRefType;
NSLog(@"EnterMovies...");
2007-06-10 21:34:20 +00:00
EnterMovies();
2007-06-10 21:34:20 +00:00
NSLog(@"Creating new data reference...");
error = QTNewDataReferenceFromCFURL((CFURLRef)url, 0, &dataRef, &dataRefType);
NSLog(@" %d", error);
2007-06-10 21:34:20 +00:00
NSLog(@"Creating new movie...");
short fileID = movieInDataForkResID;
short flags = 0; // newMovieDontResolveDataRefs | newMovieDontAskUnresolvedDataRefs;
2007-06-10 22:21:50 +00:00
error = NewMovieFromDataRef(&_movie, flags, &fileID, dataRef, dataRefType);
if(error != noErr) {
NSLog(@" %d", error);
return NO;
}
2007-06-10 21:34:20 +00:00
NSLog(@"Setting movie active...");
2007-06-10 22:21:50 +00:00
SetMovieActive(_movie, TRUE);
2007-06-10 21:34:20 +00:00
NSLog(@"Beginning extraction session...");
error = MovieAudioExtractionBegin(_movie, 0, &_extractionSessionRef);
if(error != noErr) {
NSLog(@" %d", error);
return NO;
2007-06-10 21:34:20 +00:00
}
2007-06-10 21:34:20 +00:00
NSLog(@"Getting audio stream basic description (absd)...");
error = MovieAudioExtractionGetProperty(_extractionSessionRef,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
sizeof(_asbd), &_asbd, nil);
if(error != noErr) {
NSLog(@" %d", error);
return NO;
2007-06-10 21:34:20 +00:00
}
NSLog(@"bits per sample: %i", _asbd.mBitsPerChannel);
2007-06-10 21:34:20 +00:00
_asbd.mFormatID = kAudioFormatLinearPCM;
_asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsBigEndian;
// _asbd.mBitsPerChannel = 8*sizeof(int);
_asbd.mBytesPerFrame = (_asbd.mBitsPerChannel / 8) * _asbd.mChannelsPerFrame;
2007-06-10 21:34:20 +00:00
_asbd.mBytesPerPacket = _asbd.mBytesPerFrame;
_asbd.mFramesPerPacket = 1;
2007-06-10 21:34:20 +00:00
NSLog(@"Setting new _asbd...");
error = MovieAudioExtractionSetProperty(_extractionSessionRef,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
sizeof(_asbd), &_asbd);
if(error != noErr) {
NSLog(@" %d", error);
return NO;
}
/* THIS IS BROKEN
error = MovieAudioExtractionGetProperty(_extractionSessionRef,
kQTPropertyClass_SoundDescription,
kQTSoundDescriptionPropertyID_BitRate,
sizeof(_bitrate),&_bitrate,nil);
if (error != noErr) {
NSLog(@" %d",error);
_bitrate = 0;
}
*/
_totalFrames = _asbd.mSampleRate * ((float)GetMovieDuration(_movie) / (float)GetMovieTimeScale(_movie));
2007-06-10 21:34:20 +00:00
[self willChangeValueForKey:@"properties"];
[self didChangeValueForKey:@"properties"];
2007-06-10 21:34:20 +00:00
return YES;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size {
2007-06-10 21:34:20 +00:00
OSErr error;
UInt32 extractionFlags = 0;
AudioBufferList buffer;
2007-06-10 21:34:20 +00:00
UInt32 numFrames = size / _asbd.mBytesPerFrame;
2007-06-10 21:34:20 +00:00
buffer.mNumberBuffers = 1;
buffer.mBuffers[0].mNumberChannels = _asbd.mChannelsPerFrame;
buffer.mBuffers[0].mDataByteSize = size;
2007-06-10 21:34:20 +00:00
buffer.mBuffers[0].mData = buf;
2007-06-10 21:34:20 +00:00
error = MovieAudioExtractionFillBuffer(_extractionSessionRef, &numFrames, &buffer, &extractionFlags);
if(error) {
NSLog(@" %d", error);
NSLog(@" Extraction flags = %d (complete? %d)", extractionFlags, kQTMovieAudioExtractionComplete);
2007-06-10 21:34:20 +00:00
}
2007-06-10 21:34:20 +00:00
return numFrames * _asbd.mBytesPerFrame;
}
- (void)close {
OSErr error;
2007-06-10 21:34:20 +00:00
NSLog(@"Ending extraction session...");
error = MovieAudioExtractionEnd(_extractionSessionRef);
NSLog(@" %d", error);
2007-06-10 21:34:20 +00:00
NSLog(@"ExitMovies...");
ExitMovies();
}
- (double)seekToTime:(double)milliseconds {
2007-06-10 22:21:50 +00:00
OSErr error;
TimeRecord timeRec;
timeRec.scale = GetMovieTimeScale(_movie);
timeRec.base = NULL;
2007-06-10 22:21:50 +00:00
timeRec.value.hi = 0;
timeRec.value.lo = (milliseconds / 1000.0) * timeRec.scale;
error = MovieAudioExtractionSetProperty(_extractionSessionRef, kQTPropertyClass_MovieAudioExtraction_Movie, kQTMovieAudioExtractionMoviePropertyID_CurrentTime, sizeof(timeRec), &timeRec);
if(error) {
2007-06-10 22:21:50 +00:00
NSLog(@"Error seeking! %i", error);
return 0.0;
}
2007-06-10 22:21:50 +00:00
return milliseconds;
2007-06-10 21:34:20 +00:00
}
+ (NSArray *)fileTypes {
NSMutableArray *extensions = [NSMutableArray array];
Component component = NULL;
ComponentDescription looking;
NSCharacterSet *spaceSet = [NSCharacterSet characterSetWithCharactersInString:@" '"];
looking.componentType = MovieImportType;
looking.componentSubType = 0; // Any subtype is OK
looking.componentManufacturer = 0; // Any manufacturer is OK
looking.componentFlags = movieImportSubTypeIsFileExtension;
looking.componentFlagsMask = movieImportSubTypeIsFileExtension;
while(component = FindNextComponent(component, &looking)) {
ComponentDescription description;
if(GetComponentInfo(component, &description, NULL, NULL, NULL) == noErr) {
NSString *HFSType = NSFileTypeForHFSTypeCode(description.componentSubType);
NSLog(@"Extension?: %@", HFSType);
[extensions addObject:[HFSType stringByTrimmingCharactersInSet:spaceSet]];
// the extension is present in the description.componentSubType field, which really holds
// a 32-bit number. you need to convert that to a string, and trim off any trailing spaces.
// here's a quickie...
char ext[5] = { 0 };
NSString *extension;
bcopy(&description.componentSubType, ext, 4);
extension = [[NSString stringWithCString:ext] stringByTrimmingCharactersInSet:spaceSet];
// do something with extension here ...
[extensions addObject:extension];
}
}
return extensions;
2007-06-10 21:34:20 +00:00
}
+ (NSArray *)mimeTypes {
2007-10-14 18:39:58 +00:00
return nil;
}
- (NSDictionary *)properties {
2007-06-10 21:34:20 +00:00
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:_asbd.mChannelsPerFrame], @"channels",
[NSNumber numberWithInt:_asbd.mBitsPerChannel], @"bitsPerSample",
[NSNumber numberWithInt:0 /*_bitrate*/], @"bitrate",
[NSNumber numberWithFloat:_asbd.mSampleRate], @"sampleRate",
[NSNumber numberWithDouble:_totalFrames / (_asbd.mSampleRate / 1000.0)], @"length",
[NSNumber numberWithBool:YES], @"seekable",
@"big", @"endian",
nil];
2007-06-10 21:34:20 +00:00
}
@end