status_t
OutputView::GetCodecsForFamily(const media_format_family &family,
					const int32 &width, const int32 &height,
					BMenu *codecs, media_format &initialFormat)
{
	SetInitialFormat(width, height, Settings().ClipDepth(),
		10, initialFormat);
	
	// find the full media_file_format corresponding to
	// the given format family (e.g. AVI)
	media_file_format fileFormat;
	if (!GetMediaFileFormat(family, fileFormat))
		return B_ERROR;
	
	BString currentCodec;
	BMenuItem *marked = codecs->FindMarked();
	if (marked != NULL)
		currentCodec = marked->Label();
	
	// suspend updates while we're rebuilding this menu in order to
	// reduce window flicker and other annoyances
	Window()->BeginViewTransaction();
		
	codecs->RemoveItems(0, codecs->CountItems(), true);
	
	int32 cookie = 0;
	media_codec_info codec;
	media_format dummyFormat;
	while (get_next_encoder(&cookie, &fileFormat, &initialFormat,
			&dummyFormat, &codec) == B_OK) {
		BMenuItem *item = CreateCodecMenuItem(codec);
		if (item != NULL)
			codecs->AddItem(item);
				
		if (codec.pretty_name == currentCodec)
			item->SetMarked(true);
	}
	
	if (codecs->FindMarked() == NULL) {
		BMenuItem *item = codecs->ItemAt(0);
		if (item != NULL)
			item->SetMarked(true);
	}
	
	Window()->EndViewTransaction();
	
	marked = codecs->FindMarked();
	BMessage *message = marked->Message();
	media_codec_info *info;
	ssize_t size;
	if (message->FindData(kCodecData, B_SIMPLE_DATA,
			(const void **)&info, &size) == B_OK)
		fController->SetMediaCodecInfo(*info);
		
	return B_OK;
}
status_t
MovieEncoder::Encode()
{
	int32 framesLeft = fFileList->CountItems();
	int32 framesWritten = 0;
	
	if (framesLeft <= 0) {
		DisposeData();
		BMessage message(kEncodingFinished);
		message.AddInt32("status", (int32)B_ERROR);
		fMessenger.SendMessage(&message);
		return B_ERROR;
	}
	
	// Create movie
	char movieName[B_FILE_NAME_LENGTH];
	MakeUniqueName(fOutputFile.Path(), movieName, B_FILE_NAME_LENGTH);
	entry_ref movieRef;
	get_ref_for_path(movieName, &movieRef);
	
	media_file_format fileFormat;
	if (!GetMediaFileFormat(fFamily, fileFormat)) {
		BMessage message(kEncodingFinished);
		message.AddInt32("status", (int32)B_ERROR);
		fMessenger.SendMessage(&message);
		return B_ERROR;
	}
	
	BBitmap* bitmap = BTranslationUtils::GetBitmapFile(fFileList->ItemAt(0));
	BRect sourceFrame = bitmap->Bounds();
	delete bitmap;
		
	if (!fDestFrame.IsValid())
		fDestFrame = sourceFrame.OffsetToCopy(B_ORIGIN);
				
	BitmapMovie* movie = new BitmapMovie(fDestFrame.IntegerWidth() + 1,
					fDestFrame.IntegerHeight() + 1, fColorSpace);
				
	status_t error = movie->CreateFile(movieRef, fileFormat, fFormat, fCodecInfo);
	if (error < B_OK) {
		delete movie;
		DisposeData();
		BMessage message(kEncodingFinished);
		message.AddInt32("status", (int32)error);
		fMessenger.SendMessage(&message);		
		return error;
	}
		
	// Bitmap and view used to convert the source bitmap
	// to the correct size and depth	
	BBitmap* destBitmap = new BBitmap(fDestFrame, fColorSpace, true);
	BView* destDrawer = new BView(fDestFrame, "drawing view", B_FOLLOW_NONE, 0);
	if (destBitmap->Lock()) {
		destBitmap->AddChild(destDrawer);
		destBitmap->Unlock();
	}
	
	const uint32 keyFrameFrequency = 10;
	
	BMessage progressMessage(B_UPDATE_STATUS_BAR);
	progressMessage.AddFloat("delta", 1.0);
	bool keyFrame = true;		
	for (int32 i = 0; i < fFileList->CountItems(); i++) {
		if (framesWritten % keyFrameFrequency == 0)
			keyFrame = true;
		const char* fileName = fFileList->ItemAt(i);
		BBitmap* frame = BTranslationUtils::GetBitmapFile(fileName);
		if (frame == NULL)
			continue;
						
		// Draw scaled
		if (error == B_OK) {
			destBitmap->Lock();
			destDrawer->DrawBitmap(frame, frame->Bounds(), destDrawer->Bounds());
			destDrawer->Sync();
			destBitmap->Unlock();
		}
		
		delete frame;
			
		if (error == B_OK)
			error = movie->WriteFrame(destBitmap, keyFrame);
		
		if (error == B_OK) {
			framesWritten++;
			keyFrame = false;				
		} else {
			printf("%s\n", strerror(error));
			break;
		}
		
		if (fMessenger.IsValid())
			fMessenger.SendMessage(new BMessage(progressMessage));		
	}
	
	//printf("%ld frames written\n", framesWritten);
		
	delete movie;
	delete destBitmap;
	//delete cursor;
	
	DisposeData();
	
	BMessage message(kEncodingFinished);
	message.AddInt32("status", (int32)B_OK);
	fMessenger.SendMessage(&message);
		
	return B_OK;
}