xref: /haiku/src/apps/haiku3d/texture/VideoFileTexture.cpp (revision f259502c907963f01803a757d60ed55258fe6e4c)
1bee3c7a9SAlexandre Deckner /*
2bee3c7a9SAlexandre Deckner  * Copyright 2008, Haiku Inc. All rights reserved.
3bee3c7a9SAlexandre Deckner  * Distributed under the terms of the MIT License.
4bee3c7a9SAlexandre Deckner  *
5bee3c7a9SAlexandre Deckner  * Authors:
6bee3c7a9SAlexandre Deckner  * 		Alexandre Deckner <alex@zappotek.com>
7bee3c7a9SAlexandre Deckner  */
8bee3c7a9SAlexandre Deckner 
9bee3c7a9SAlexandre Deckner #include "VideoFileTexture.h"
10bee3c7a9SAlexandre Deckner 
11bee3c7a9SAlexandre Deckner #include <Bitmap.h>
12bee3c7a9SAlexandre Deckner #include <Entry.h>
13bee3c7a9SAlexandre Deckner #include <MediaFile.h>
14bee3c7a9SAlexandre Deckner #include <MediaTrack.h>
15bee3c7a9SAlexandre Deckner 
168e4cdaaeSAlexander von Gluck IV #include <GL/gl.h>
178e4cdaaeSAlexander von Gluck IV #include <GL/glu.h>
18bee3c7a9SAlexandre Deckner #include <string.h>
19bee3c7a9SAlexandre Deckner #include <stdio.h>
20bee3c7a9SAlexandre Deckner 
21bee3c7a9SAlexandre Deckner 
VideoFileTexture(const char * fileName)22bee3c7a9SAlexandre Deckner VideoFileTexture::VideoFileTexture(const char* fileName)
23bee3c7a9SAlexandre Deckner 	:
24bee3c7a9SAlexandre Deckner 	Texture(),
25bee3c7a9SAlexandre Deckner 	fMediaFile(NULL),
26bee3c7a9SAlexandre Deckner 	fVideoTrack(NULL),
27bee3c7a9SAlexandre Deckner 	fVideoBitmap(NULL)
28bee3c7a9SAlexandre Deckner {
29bee3c7a9SAlexandre Deckner 	_Load(fileName);
30bee3c7a9SAlexandre Deckner }
31bee3c7a9SAlexandre Deckner 
32bee3c7a9SAlexandre Deckner 
~VideoFileTexture()33bee3c7a9SAlexandre Deckner VideoFileTexture::~VideoFileTexture()
34bee3c7a9SAlexandre Deckner {
35bee3c7a9SAlexandre Deckner 	delete fVideoBitmap;
36bee3c7a9SAlexandre Deckner 
37bee3c7a9SAlexandre Deckner 	if (fMediaFile != NULL) {
38bee3c7a9SAlexandre Deckner 		fMediaFile->ReleaseAllTracks();
39bee3c7a9SAlexandre Deckner 		fMediaFile->CloseFile();
40bee3c7a9SAlexandre Deckner 		delete fMediaFile;
41bee3c7a9SAlexandre Deckner 	}
42bee3c7a9SAlexandre Deckner }
43bee3c7a9SAlexandre Deckner 
44bee3c7a9SAlexandre Deckner 
45bee3c7a9SAlexandre Deckner void
_Load(const char * fileName)46bee3c7a9SAlexandre Deckner VideoFileTexture::_Load(const char* fileName)
47bee3c7a9SAlexandre Deckner {
48bee3c7a9SAlexandre Deckner 	BEntry entry(fileName);
49bee3c7a9SAlexandre Deckner 	entry_ref ref;
50bee3c7a9SAlexandre Deckner 	entry.GetRef(&ref);
51bee3c7a9SAlexandre Deckner 
52bee3c7a9SAlexandre Deckner 	fMediaFile = new BMediaFile(&ref);
53bee3c7a9SAlexandre Deckner 	status_t err = fMediaFile->InitCheck();
54bee3c7a9SAlexandre Deckner 	if (err != B_OK) {
55bee3c7a9SAlexandre Deckner 		printf("cannot contruct BMediaFile object -- %s\n", strerror(err));
56bee3c7a9SAlexandre Deckner 		return;
57bee3c7a9SAlexandre Deckner 	}
58bee3c7a9SAlexandre Deckner 
59bee3c7a9SAlexandre Deckner 	int32 trackCount = fMediaFile->CountTracks();
60bee3c7a9SAlexandre Deckner 
61bee3c7a9SAlexandre Deckner 	for (int32 i = 0; i < trackCount; i++) {
62bee3c7a9SAlexandre Deckner 		BMediaTrack* track = fMediaFile->TrackAt(i);
63bee3c7a9SAlexandre Deckner 		if (track == NULL) {
64bee3c7a9SAlexandre Deckner 			printf("cannot contruct BMediaTrack object\n");
65bee3c7a9SAlexandre Deckner 			return;
66bee3c7a9SAlexandre Deckner 		}
67bee3c7a9SAlexandre Deckner 
68bee3c7a9SAlexandre Deckner 		// get the encoded format
69bee3c7a9SAlexandre Deckner 		media_format format;
70bee3c7a9SAlexandre Deckner 		err = track->EncodedFormat(&format);
71bee3c7a9SAlexandre Deckner 		if (err != B_OK) {
72bee3c7a9SAlexandre Deckner 			printf("BMediaTrack::EncodedFormat error -- %s\n", strerror(err));
73bee3c7a9SAlexandre Deckner 			return;
74bee3c7a9SAlexandre Deckner 		}
75bee3c7a9SAlexandre Deckner 
76bee3c7a9SAlexandre Deckner 		if (format.type == B_MEDIA_ENCODED_VIDEO) {
77bee3c7a9SAlexandre Deckner 			fVideoTrack = track;
78bee3c7a9SAlexandre Deckner 			// allocate a bitmap large enough to contain the decoded frame.
79bee3c7a9SAlexandre Deckner 			BRect bounds(0.0, 0.0,
80bee3c7a9SAlexandre Deckner 				format.u.encoded_video.output.display.line_width - 1.0,
81bee3c7a9SAlexandre Deckner 				format.u.encoded_video.output.display.line_count - 1.0);
82bee3c7a9SAlexandre Deckner 			fVideoBitmap = new BBitmap(bounds, B_RGB32);
83bee3c7a9SAlexandre Deckner 
84bee3c7a9SAlexandre Deckner 			// specifiy the decoded format. we derive this information from
85bee3c7a9SAlexandre Deckner 			// the encoded format.
86*f259502cSAugustin Cavalier 			format = media_format();
87bee3c7a9SAlexandre Deckner 			format.u.raw_video.last_active = (int32) (bounds.Height() - 1.0);
88bee3c7a9SAlexandre Deckner 			format.u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT;
89bee3c7a9SAlexandre Deckner 			format.u.raw_video.pixel_width_aspect = 1;
90bee3c7a9SAlexandre Deckner 			format.u.raw_video.pixel_height_aspect = 3;
91bee3c7a9SAlexandre Deckner 			format.u.raw_video.display.format = fVideoBitmap->ColorSpace();
92bee3c7a9SAlexandre Deckner 			format.u.raw_video.display.line_width = (int32) bounds.Width();
93bee3c7a9SAlexandre Deckner 			format.u.raw_video.display.line_count = (int32) bounds.Height();
943904801cSAlexandre Deckner 			format.u.raw_video.display.bytes_per_row
953904801cSAlexandre Deckner 				= fVideoBitmap->BytesPerRow();
96bee3c7a9SAlexandre Deckner 
97bee3c7a9SAlexandre Deckner 			err = fVideoTrack->DecodedFormat(&format);
98bee3c7a9SAlexandre Deckner 			if (err != B_OK) {
99bee3c7a9SAlexandre Deckner 				printf("error with BMediaTrack::DecodedFormat() -- %s\n",
100bee3c7a9SAlexandre Deckner 					strerror(err));
101bee3c7a9SAlexandre Deckner 				return;
102bee3c7a9SAlexandre Deckner 			}
103bee3c7a9SAlexandre Deckner 
104bee3c7a9SAlexandre Deckner 			// Create Texture
105bee3c7a9SAlexandre Deckner 			glGenTextures(1, &fId);
106bee3c7a9SAlexandre Deckner 			glBindTexture(GL_TEXTURE_2D, fId);
107bee3c7a9SAlexandre Deckner 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
108bee3c7a9SAlexandre Deckner 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
109bee3c7a9SAlexandre Deckner 			glTexImage2D(GL_TEXTURE_2D, 0, 4,
110bee3c7a9SAlexandre Deckner 				(int) fVideoBitmap->Bounds().Width() + 1,
111bee3c7a9SAlexandre Deckner 				(int) fVideoBitmap->Bounds().Height() + 1,
112bee3c7a9SAlexandre Deckner 				0, GL_BGRA, GL_UNSIGNED_BYTE, fVideoBitmap->Bits());
113bee3c7a9SAlexandre Deckner 		}
114bee3c7a9SAlexandre Deckner 	}
115bee3c7a9SAlexandre Deckner }
116bee3c7a9SAlexandre Deckner 
117bee3c7a9SAlexandre Deckner 
118bee3c7a9SAlexandre Deckner void
Update(float)119bee3c7a9SAlexandre Deckner VideoFileTexture::Update(float /*dt*/) {
120bee3c7a9SAlexandre Deckner 	// TODO loop
121bee3c7a9SAlexandre Deckner 	int64 frameCount = 0;
122bee3c7a9SAlexandre Deckner 	media_header mh;
1233904801cSAlexandre Deckner 	status_t err
1243904801cSAlexandre Deckner 		= fVideoTrack->ReadFrames(fVideoBitmap->Bits(), &frameCount, &mh);
125bee3c7a9SAlexandre Deckner 	if (err) {
126bee3c7a9SAlexandre Deckner 		printf("BMediaTrack::ReadFrames error -- %s\n", strerror(err));
127bee3c7a9SAlexandre Deckner 		return;
128bee3c7a9SAlexandre Deckner 	}
129bee3c7a9SAlexandre Deckner 
130bee3c7a9SAlexandre Deckner 	glBindTexture(GL_TEXTURE_2D, fId);
131bee3c7a9SAlexandre Deckner 	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
132bee3c7a9SAlexandre Deckner 		(int)fVideoBitmap->Bounds().Width() + 1,
133bee3c7a9SAlexandre Deckner 		(int)fVideoBitmap->Bounds().Height() + 1,
134bee3c7a9SAlexandre Deckner 		GL_BGRA, GL_UNSIGNED_BYTE, fVideoBitmap->Bits());
135bee3c7a9SAlexandre Deckner }
136bee3c7a9SAlexandre Deckner 
137