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 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 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 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 memset(&format, 0, sizeof(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 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