(curse words) AVI (curse words)
Code:
#include <windows.h>
#include <vfw.h>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
class Video {
public:
Video(string path, HDC hdc, int nw);
~Video();
void showFrame(long frame);
private:
PAVIFILE aviFile;
PAVISTREAM aviStream;
AVISTREAMINFO aviStreamInfo;
BITMAPINFOHEADER bmih;
LPBITMAPINFOHEADER lpbi;
PGETFRAME pgf;
unsigned char* pdata;
HDRAWDIB hdd;
HDC drawdc;
int width, height, newwidth, newheight;
double fps, duration;
int length;
};
Video::Video(string path, HDC hdc, int nw) {
ofstream fout("video.log");
// initialise the AVI file library
// and open the video file/stream
AVIFileInit();
AVIFileOpenA(&aviFile, path.c_str(), OF_READ, NULL);
AVIFileGetStream(aviFile, &aviStream, streamtypeVIDEO, 0);
AVIStreamInfo(aviStream, &aviStreamInfo, sizeof(aviStreamInfo));
// get video stream data
width = aviStreamInfo.rcFrame.right - aviStreamInfo.rcFrame.left;
height = aviStreamInfo.rcFrame.bottom - aviStreamInfo.rcFrame.top;
DWORD aa = aviStreamInfo.fccHandler;
fps = double(aviStreamInfo.dwRate) / double(aviStreamInfo.dwScale);
length = aviStreamInfo.dwLength;
duration = double(length) / fps;
// figure out the destination width/height
newwidth = nw;
newheight = int(nw * double(height / double(width)));
// set up the destination bitmap
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biWidth = newwidth;
bmih.biHeight = newheight;
bmih.biCompression = BI_RGB;
// debug
fout << "stream size: " << width << "x" << height << endl;
fout << "dest. size: " << newwidth << "x" << newheight << endl;
fout << "fourcc: " << (char)(aa & 0xff) << endl;
fout << "framerate: " << setprecision(3) << fps << endl;
fout << "length: " << setprecision(3) << fixed
<< duration << "s (" << length << " frames)" << endl;
// open the stream for reading
pgf = AVIStreamGetFrameOpen(aviStream, NULL);
// create the bitmap and attach it to the dc
//data = 0;
//cdc = CreateCompatibleDC(0);
//hBitmap = CreateDIBSection(cdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS,
// (void**)(&data), NULL, 0);
//hOld = (HBITMAP)SelectObject(cdc, hBitmap);
// create the "drawdib" and store the DC
hdd = DrawDibOpen();
drawdc = hdc;
}
Video::~Video() {
DrawDibClose(hdd);
// SelectObject(drawdc, hOld);
// DeleteObject(hBitmap);
AVIStreamGetFrameClose(pgf);
AVIFileRelease(aviFile);
AVIFileExit();
}
void Video::showFrame(long frame) {
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frame);
pdata = (unsigned char*) lpbi + sizeof(BITMAPINFOHEADER);
DrawDibDraw(hdd, drawdc, 0, 0, newwidth, newheight,
lpbi, pdata, 0, 0, width, height, 0);
//BitBlt(drawdc, 0, 0, newwidth, newheight, cdc, 0, 0, SRCCOPY);
}
Any thoughts on why using this class just refuses to blit anything?
You use it like:
Code:
Video a("my.avi", hDC, 500) // 500 is the width of the image
a.showFrame(50);
Re: (curse words) AVI (curse words)
It seems that height may be needed as one of the new arguements in your sub named Video. You only have width in there. Don't know why though.
Re: (curse words) AVI (curse words)
Aspect Ratio reasons.
I'm conisdering monetary payments for someone that can actually show me a working C++ class to load and display AVI files. It doesn't seem like such a stretch that someone out there has done this before.
I'm at the end of my tether.
Re: (curse words) AVI (curse words)
Are we allowed to use DShow (grrrr...I can't even find the question mark on this keyboard...grrrrr)....
"Sincerely the guy that is apparently stuck in the wrong country"
Re: (curse words) AVI (curse words)
Shouldn't bmih.biSizeImage be filled out too?
Re: (curse words) AVI (curse words)
I'm not sure if this is any help to you, but there is an AVI tutorial on nehe.gamedev.net, but in OpenGL...
http://nehe.gamedev.net/data/lessons....asp?lesson=35
You might be able to get what you need from that tutorial. :)
Re: (curse words) AVI (curse words)
Btw, did you look at the link I gave you on the other avi thread?
Those examples works perfect in VB. I've made a couple of video editing programs based on those examples. Don't think it would be too hard to port into C++.
Re: (curse words) AVI (curse words)
Sounds like a challenge.
If you can seriously run AVI's via BitBlt I can probably have that done for you in no time. I do on the other hand have ZERO experience with parsing AVI Files. So are all those AVI___ functions you are using Win32 API or from a 3rd party library?
Re: (curse words) AVI (curse words)
They're from the API.
I don't think the real problem is the AVI loading but what I'm doing with the data.
I'm going to try for a few more hours and then go insane over something that should have taken one.
Re: (curse words) AVI (curse words)
Actually, about 20 minutes after I posted last, I figured everything out. I had been passing in "NULL" for a value instead of the needed BitmapInfoHeader. What a wonderful waste of time.
If anyone's interested in the code, I'll post'er up as a C++ class.
Re: (curse words) AVI (curse words)
Is it faster to BitBlt the image to a Picturebox, or is it faster to use SetDIBbits?
Cuz I got a working program using SetDIBbits, and if BitBlt is slower, I wont be needing that code...
Re: (curse words) AVI (curse words)
There's simply no way to use Bitblt in this case, so I would hope it would be faster...
avi.hpp
Code:
#ifndef __AVI_HPP__
#define __AVI_HPP__
#include <windows.h>
#include <vfw.h>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
class Video {
public:
Video(string path, HDC hdc, int nw);
~Video();
bool showFrame(long frame);
bool delayFrame();
private:
PAVIFILE aviFile;
PAVISTREAM aviStream;
AVISTREAMINFO aviStreamInfo;
BITMAPINFOHEADER bmih;
PGETFRAME pgf;
HBITMAP hBitmap, hOld;
unsigned char* pdata, data;
HDRAWDIB hdd;
HDC drawdc, cdc;
int width, height, newwidth, newheight;
double fps, duration, sttime;
int length, framedir;
LPBITMAPINFOHEADER lpbi;
};
Video::Video(string path, HDC hdc, int nw) {
// initialise the AVI file library
// and open the video file/stream
AVIFileInit();
AVIFileOpenA(&aviFile, path.c_str(), OF_READ, NULL);
AVIFileGetStream(aviFile, &aviStream, streamtypeVIDEO, 0);
AVIStreamInfo(aviStream, &aviStreamInfo, sizeof(aviStreamInfo));
// get video stream data
width = aviStreamInfo.rcFrame.right - aviStreamInfo.rcFrame.left;
height = aviStreamInfo.rcFrame.bottom - aviStreamInfo.rcFrame.top;
DWORD* aa = &aviStreamInfo.fccHandler;
fps = double(aviStreamInfo.dwRate) / double(aviStreamInfo.dwScale);
length = aviStreamInfo.dwLength;
duration = double(length) / fps;
framedir = (int)(1000.0 / fps);
drawdc = hdc;
// figure out the destination width/height
newwidth = nw;
newheight = int(nw * double(height / double(width)));
// set up the destination bitmap
bmih.biBitCount = 24;
bmih.biClrImportant = 0;
bmih.biClrUsed = 0;
bmih.biCompression = BI_RGB;
bmih.biWidth = width;
bmih.biHeight = height;
bmih.biPlanes = 1;
bmih.biSize = 40;
bmih.biXPelsPerMeter = 0;
bmih.biXPelsPerMeter = 0;
bmih.biSizeImage = (((bmih.biWidth * 3) + 3) & 0xfffc) * bmih.biHeight;
// open the stream for reading
pgf = AVIStreamGetFrameOpen(aviStream, &bmih);
sttime = -1;
}
Video::~Video() {
AVIStreamGetFrameClose(pgf);
AVIFileRelease(aviFile);
AVIFileExit();
}
bool Video::delayFrame() {
if (sttime == -1)
// start the delay process
sttime = GetTickCount();
else {
if ((GetTickCount() - sttime) >= framedir) {
// we've elapsed the time
sttime = -1;
return false;
}
}
// we want to delay a bit longer
return true;
}
bool Video::showFrame(long frame) {
long ff = AVIStreamStart(aviStream);
// get the frame
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frame + ff);
if ((long)lpbi == 0)
return false;
// show it
long pDib = (long)lpbi + 40;
StretchDIBits(drawdc, 0, 0, newwidth, newheight, 0, 0, width, height,
(void*)pDib, (BITMAPINFO*)lpbi, DIB_RGB_COLORS, SRCCOPY);
return true;
}
#endif
1 Attachment(s)
Re: (curse words) AVI (curse words)
Here's the program I made (VB)... (With some help form shrinkwrapvb.com)
I'm pretty impressed by the speed of this :bigyello: