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