www.pudn.com > XvidQP.rar > AVIIndex.cpp


//	VirtualDub - Video processing and capture application 
//	Copyright (C) 1998-2001 Avery Lee 
// 
//	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., 675 Mass Ave, Cambridge, MA 02139, USA. 
 
#include  
#include  
 
#include "AVIIndex.h" 
 
/////////////////////////////////////////////////////////////////////////// 
 
class AVIIndexChainNode { 
public: 
	enum { ENTS=2048 }; 
 
	AVIIndexChainNode *next; 
 
	AVIIndexEntry2 ient[ENTS]; 
	int num_ents; 
 
	AVIIndexChainNode() { 
		num_ents = 0; 
		next = NULL; 
	} 
 
	bool add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) { 
		if (num_ents < ENTS) { 
			ient[num_ents].ckid = ckid; 
			ient[num_ents].pos = pos; 
			ient[num_ents].size = is_keyframe ? size : 0x80000000+size; 
			++num_ents; 
			return true; 
		} 
		return false; 
	} 
 
	void put(AVIINDEXENTRY *&avieptr) { 
		int i; 
 
		for(i=0; ickid			= ient[i].ckid; 
			avieptr->dwFlags		= ient[i].size & 0x80000000 ? 0 : AVIIF_KEYFRAME; 
			avieptr->dwChunkOffset	= ient[i].pos; 
			avieptr->dwChunkLength	= ient[i].size & 0x7FFFFFFF; 
 
			++avieptr; 
		} 
	} 
 
	void put(AVIIndexEntry2 *&avie2ptr) { 
		int i; 
 
		for(i=0; idwSizeKeyframe	= ient[i].size; 
			avie3ptr->dwOffset			= (DWORD)(ient[i].pos - offset); 
 
			++avie3ptr; 
		} 
	} 
}; 
 
/////////////////////////////////////////////////////////////////////////// 
 
AVIIndexChain::AVIIndexChain() { 
	head = tail = NULL; 
	total_ents = 0; 
} 
 
void AVIIndexChain::delete_chain() { 
	AVIIndexChainNode *aicn = head,*aicn2; 
 
	while(aicn) { 
		aicn2 = aicn->next; 
		delete aicn; 
		aicn = aicn2; 
	} 
 
	head = tail = NULL; 
} 
 
AVIIndexChain::~AVIIndexChain() { 
	delete_chain(); 
} 
 
bool AVIIndexChain::add(AVIINDEXENTRY *avie) { 
	if (!tail || !tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) { 
		AVIIndexChainNode *aicn = new AVIIndexChainNode(); 
 
		if (tail) tail->next = aicn; else head=aicn; 
		tail = aicn; 
 
		if (tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) { 
			++total_ents; 
			return true; 
		} 
 
		return false; 
	} 
 
	++total_ents; 
 
	return true; 
} 
 
bool AVIIndexChain::add(AVIIndexEntry2 *avie2) { 
	return add(avie2->ckid, avie2->pos, avie2->size & 0x7FFFFFFF, !!(avie2->size & 0x80000000)); 
} 
 
bool AVIIndexChain::add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) { 
	if (!tail || !tail->add(ckid, pos, size, is_keyframe)) { 
		AVIIndexChainNode *aicn = new AVIIndexChainNode(); 
 
		if (tail) tail->next = aicn; else head=aicn; 
		tail = aicn; 
 
		if (tail->add(ckid, pos, size, is_keyframe)) { 
			++total_ents; 
			return true; 
		} 
 
		return false; 
	} 
 
	++total_ents; 
 
	return true; 
} 
 
void AVIIndexChain::put(AVIINDEXENTRY *avietbl) { 
	AVIIndexChainNode *aicn = head; 
 
	while(aicn) { 
		aicn->put(avietbl); 
		aicn=aicn->next; 
	} 
 
	delete_chain(); 
} 
 
void AVIIndexChain::put(AVIIndexEntry2 *avie2tbl) { 
	AVIIndexChainNode *aicn = head; 
 
	while(aicn) { 
		aicn->put(avie2tbl); 
		aicn=aicn->next; 
	} 
 
	delete_chain(); 
} 
 
void AVIIndexChain::put(AVIIndexEntry3 *avie3tbl, __int64 offset) { 
	AVIIndexChainNode *aicn = head; 
 
	while(aicn) { 
		aicn->put(avie3tbl, offset); 
		aicn=aicn->next; 
	} 
 
	delete_chain(); 
} 
 
AVIIndex::AVIIndex() { 
	index = NULL; 
	index2 = NULL; 
	index3 = NULL; 
} 
 
AVIIndex::~AVIIndex() { 
	delete[] index; 
	delete[] index2; 
	delete[] index3; 
} 
 
bool AVIIndex::makeIndex() { 
	if (!allocateIndex(total_ents)) return false; 
 
	put(indexPtr()); 
 
	return true; 
} 
 
bool AVIIndex::makeIndex2() { 
	if (!allocateIndex2(total_ents)) return false; 
 
	put(index2Ptr()); 
 
	return true; 
} 
 
bool AVIIndex::makeIndex3(__int64 offset) { 
	if (!allocateIndex3(total_ents)) return false; 
 
	put(index3Ptr(), offset); 
 
	return true; 
} 
 
void AVIIndex::clear() { 
	delete_chain(); 
	delete[] index; 
	delete[] index2; 
	delete[] index3; 
	index = NULL; 
	index2 = NULL; 
	index3 = NULL; 
	total_ents = 0; 
}