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