/* * Copyright 2008, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Alexandre Deckner */ #include "VideoFileTexture.h" #include #include #include #include #include #include #include #include VideoFileTexture::VideoFileTexture(const char* fileName) : Texture(), fMediaFile(NULL), fVideoTrack(NULL), fVideoBitmap(NULL) { _Load(fileName); } VideoFileTexture::~VideoFileTexture() { delete fVideoBitmap; if (fMediaFile != NULL) { fMediaFile->ReleaseAllTracks(); fMediaFile->CloseFile(); delete fMediaFile; } } void VideoFileTexture::_Load(const char* fileName) { BEntry entry(fileName); entry_ref ref; entry.GetRef(&ref); fMediaFile = new BMediaFile(&ref); status_t err = fMediaFile->InitCheck(); if (err != B_OK) { printf("cannot contruct BMediaFile object -- %s\n", strerror(err)); return; } int32 trackCount = fMediaFile->CountTracks(); for (int32 i = 0; i < trackCount; i++) { BMediaTrack* track = fMediaFile->TrackAt(i); if (track == NULL) { printf("cannot contruct BMediaTrack object\n"); return; } // get the encoded format media_format format; err = track->EncodedFormat(&format); if (err != B_OK) { printf("BMediaTrack::EncodedFormat error -- %s\n", strerror(err)); return; } if (format.type == B_MEDIA_ENCODED_VIDEO) { fVideoTrack = track; // allocate a bitmap large enough to contain the decoded frame. BRect bounds(0.0, 0.0, format.u.encoded_video.output.display.line_width - 1.0, format.u.encoded_video.output.display.line_count - 1.0); fVideoBitmap = new BBitmap(bounds, B_RGB32); // specifiy the decoded format. we derive this information from // the encoded format. format = media_format(); format.u.raw_video.last_active = (int32) (bounds.Height() - 1.0); format.u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT; format.u.raw_video.pixel_width_aspect = 1; format.u.raw_video.pixel_height_aspect = 3; format.u.raw_video.display.format = fVideoBitmap->ColorSpace(); format.u.raw_video.display.line_width = (int32) bounds.Width(); format.u.raw_video.display.line_count = (int32) bounds.Height(); format.u.raw_video.display.bytes_per_row = fVideoBitmap->BytesPerRow(); err = fVideoTrack->DecodedFormat(&format); if (err != B_OK) { printf("error with BMediaTrack::DecodedFormat() -- %s\n", strerror(err)); return; } // Create Texture glGenTextures(1, &fId); glBindTexture(GL_TEXTURE_2D, fId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 4, (int) fVideoBitmap->Bounds().Width() + 1, (int) fVideoBitmap->Bounds().Height() + 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, fVideoBitmap->Bits()); } } } void VideoFileTexture::Update(float /*dt*/) { // TODO loop int64 frameCount = 0; media_header mh; status_t err = fVideoTrack->ReadFrames(fVideoBitmap->Bits(), &frameCount, &mh); if (err) { printf("BMediaTrack::ReadFrames error -- %s\n", strerror(err)); return; } glBindTexture(GL_TEXTURE_2D, fId); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (int)fVideoBitmap->Bounds().Width() + 1, (int)fVideoBitmap->Bounds().Height() + 1, GL_BGRA, GL_UNSIGNED_BYTE, fVideoBitmap->Bits()); }