Skocz do zawartości

Witaj!

Zaloguj lub Zarejestruj się aby uzyskać pełny dostęp do forum.

- - - - -

Przeglądanie atomów pliku mov


  • Zamknięty Temat jest zamknięty
1 odpowiedź w tym temacie

#1 Gość_oneghost_*

Gość_oneghost_*

Napisano 05 lutego 2015 - 13:42

Chciałem napisać program, który zrobi mi drzewo tagów w pliku mov. Częściowo działa, ale nie wiem czemu czasami się gubi. Znajduje część tagów, a w którymś chyba jest źle policzone przesunięcie w pliku i wychodzą głupoty. Proszę o pomoc. Kod źródłowy z XCode:

//
//  main.m
//  ReadMOVAtoms
//
//  Created by Damian Dudycz on 04.02.2015.
//  Copyright (c) 2015 Damian Dudycz. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <stdio.h>

#define ATOM_TYPE_FTYP 1718909296
#define ATOM_TYPE_MOOV 1836019574
#define ATOM_TYPE_WIDE 2003395685
#define ATOM_TYPE_MDAT 1835295092

@interface AtomReader : NSObject {
	long fileSize;
}

- (void)perform;

@end

@implementation AtomReader

// Funkcja wyszukuje atomy pomiędzy podanymi pozycjami w pliku.
- (NSArray *)rootAtomsInFile:(FILE *)movFile from:(UInt64)startPosition to:(UInt64)endPosition {
	// Przesuń wskaźnij na początek przedziału.
	fseek(movFile, startPosition, SEEK_SET);
	// Rozmiar przeszukiwanego przedziału
	UInt64 spaceLength = endPosition - startPosition;
	// Ilość pozostałych do przeczytania w przedziale bajtów
	int64_t bytesLeft = spaceLength;
	// Pozycja wskaźnika względem pliku i względem początku przedziału
	UInt64 currentPosInFile = startPosition;
	UInt64 atomPositionInFile;

	// Bufor dla wczytywania pliku
	char buffer[1000];
	
	// Wyniki
	NSMutableArray *atoms = [NSMutableArray arrayWithCapacity:10];

	while (bytesLeft > 0) {
		atomPositionInFile = currentPosInFile;
		
		size_t bytesRead;
		
		// Get atom size
		bytesRead = fread(buffer, 1, 4, movFile);
		//bytesLeft -= bytesRead;
		UInt32 atomSize1 = 0;
		for (unsigned n = 0; n < sizeof(atomSize1); ++n) {
			atomSize1 = (atomSize1 << 8) + buffer[n];
		}
		
		// Get atom type
		bytesRead = fread(buffer, 1, 4, movFile);
		//bytesLeft -= bytesRead;
		NSMutableString *atomName = [NSMutableString stringWithCapacity:4];
		UInt32 atomType = 0;
		for (short n = 0; n < sizeof(atomType); ++n) {
			atomType = (atomType << 8) + buffer[n];
			[atomName appendFormat:@"%c", buffer[n]];
		}
		
		UInt64 atomDataOffset = 8;
		
		// If atom size is equal to 1, get 64bit atom size
		UInt64 trueAtomSize = atomSize1;
		UInt64 atomSize2 = 0;
		if (atomSize1 == 1) {
			bytesRead = fread(buffer, 1, 8, movFile);
			//bytesLeft -= bytesRead;
			for (short n = 0; n < sizeof(atomSize2); ++n) {
				atomSize2 = (atomSize2 << 8) + buffer[n];
			}
			trueAtomSize = atomSize2;
			
			atomDataOffset = 16;
		}
		
		if (trueAtomSize == 0) {
			trueAtomSize = fileSize - atomPositionInFile;
		}
		
		// Przesuń wskaźnik o resztę atomu
		currentPosInFile = trueAtomSize + atomPositionInFile;
		
		fseek(movFile, currentPosInFile, SEEK_SET);
		bytesLeft -= trueAtomSize;
		
		NSNumber *atomSizeNumber = @(trueAtomSize);
		[atoms addObject:@{@"TYPE" : atomName, @"SIZE" : atomSizeNumber}];
		
		if (atomType == ATOM_TYPE_MOOV) {
			UInt64 start = atomPositionInFile + atomDataOffset;
			UInt64 end = atomPositionInFile + trueAtomSize;
			[atoms addObject:[self rootAtomsInFile:movFile from:start to:end]];
		}
		fseek(movFile, currentPosInFile, SEEK_SET);
	}
	
	return atoms;
}

- (void)perform {	
	FILE *file = fopen("/Users/damiandudycz/Desktop/Movie.mov", "rb");
	assert(file != nil);
	
	fseek(file, 0, SEEK_END);
	fileSize = ftell(file);
	fseek(file, 0, SEEK_SET);
	
	NSArray *atoms = [self rootAtomsInFile:file from:0 to:fileSize];
	NSLog(@"%@", atoms);
	
	fclose(file);
}

@end

int main(int argc, const char * argv[]) {
	@autoreleasepool {
		AtomReader *reader = [[AtomReader alloc] init];
		[reader perform];
	}
	return 0;
}

Przykładowe wyjście:

(
        {
        SIZE = 20;
        TYPE = ftyp;
    },
        {
        SIZE = 9240;
        TYPE = moov;
    },
        (
                {
            SIZE = 108;
            TYPE = mvhd;
        },
                {
            SIZE = 7211;
            TYPE = trak;
        },
                {
            SIZE = 1500;
            TYPE = trak;
        },
                {
            SIZE = 3667779;
            TYPE = "9*\U2018";
        }
    ),
        {
        SIZE = 8;
        TYPE = wide;
    },
        {
        SIZE = 4927064;
        TYPE = mdat;
    }
)

Część tagów jest ok, ale pojawia się ten 9*\U2018 nie wiadomo skąd. Poza tym czasami są źle wyciągnięte rozmiary atomów.


Użytkownik oneghost edytował ten post 05 lutego 2015 - 13:44


#2 Gość_oneghost_*

Gość_oneghost_*

Napisano 05 lutego 2015 - 20:28

Ok znalazłem, buffer powinien być typu unsigned char[1000].

Można zamknąć






Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych