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 16bee3c7a9SAlexandre Deckner #include <opengl/GL/gl.h> 17bee3c7a9SAlexandre Deckner #include <opengl/GL/glu.h> 18bee3c7a9SAlexandre Deckner #include <string.h> 19bee3c7a9SAlexandre Deckner #include <stdio.h> 20bee3c7a9SAlexandre Deckner 21bee3c7a9SAlexandre Deckner 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 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 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. 86bee3c7a9SAlexandre Deckner memset(&format, 0, sizeof(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(); 94*3904801cSAlexandre Deckner format.u.raw_video.display.bytes_per_row 95*3904801cSAlexandre 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 119bee3c7a9SAlexandre Deckner VideoFileTexture::Update(float /*dt*/) { 120bee3c7a9SAlexandre Deckner // TODO loop 121bee3c7a9SAlexandre Deckner int64 frameCount = 0; 122bee3c7a9SAlexandre Deckner media_header mh; 123*3904801cSAlexandre Deckner status_t err 124*3904801cSAlexandre 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