Quantcast
Channel: CodeGuru Forums - Visual C++ Programming
Viewing all articles
Browse latest Browse all 3042

[RESOLVED] Can only make video with 255 frames

$
0
0
Hello all,

I have code (found long time ago, ~2001) to make videos from OpenGL rendering in my view class. In my OnDraw() function I call the function SaveAsAvi(). This works as intended until I have 255 frames in the movie I am trying to make. After that, Windows Media Player claims it cannot play the file. VirtualDub claims the avi contains Palette Changes and shows the correct number of frames (>255) but all frames past 255 are the same and equal to the last frame.

Does anyone have an idea what I am doing wrong? Memory overflow? Need to free m_pixels sometime somewhere? Any help would be appreciated.

Code:

void C***View::SaveAsAvi()
{
 C***Doc* pDoc = GetDocument();

 if (pDoc->m_avi_status == -1)                // initialize AVI stuff
 {
  KillTimer(1);

  // allocate space for the pixel info

  m_big=GlobalAlloc(GHND,m_cx*m_cy*4); //m_cx and m_cy members of my view class, these store width and height
  m_pixels=GlobalLock(m_big); // m_big is defined as HGLOBAL in the header file of my view class

  CreateAVI(pDoc->m_avi_filename,m_cx,m_cy);

  glReadPixels(0,0,m_cx,m_cy,GL_BGRA_EXT,GL_UNSIGNED_BYTE,m_pixels); // m_pixels is defined as LPVOID in the header file of my view class

  int ValidWrite = 0;

  while (ValidWrite==0)
  {
  ValidWrite = WriteAVIFrame(m_pixels,15);
  }

  if (ValidWrite==1)
  {
  pDoc->m_avi_status = 1;
  GetParentFrame()->PostMessage(WM_COMMAND, MAKELONG(ID_PLAY_FORWARD, 0));
  SetTimer(1,50,NULL);
  }
 }

 if (pDoc->m_avi_status == 1)                // "normal" writing to avi file
 {
  glReadPixels(0,0,m_cx,m_cy,GL_BGRA_EXT,GL_UNSIGNED_BYTE,m_pixels);

  if (WriteAVIFrame(m_pixels,15)==0)
  {
  KillTimer(1);
  AfxGetMainWnd()->MessageBox("Error writing AVI file");
  SetTimer(1,50,NULL);
  pDoc->m_avi_status = 2;                        // will close avi file later
  }
 }

 if (pDoc->m_avi_status == 2)                // finish and close avi file
 {
  pDoc->m_avi_status = 0;
  CloseAVI();

  GlobalUnlock(m_big);                                // free up memory
  GlobalFree(m_big);

  GetParentFrame()->PostMessage(WM_COMMAND, MAKELONG(ID_STOP_DRAWING, 0));
 }
}

The code for making the avi's is in the following files:


Avi.h:

Code:

#define        ONETICKTIME        1

bool CreateAVI(LPCTSTR str,int Width,int Height);
int  WriteAVIFrame(LPVOID pixels, int fps);
void CloseAVI();

Avi.cpp:


Code:

#include "stdafx.h"
#include "avi.h"
//
#include <vfw.h>

BITMAPINFO BI ;
PAVISTREAM psCompressed;
PAVISTREAM ps;
PAVIFILE pfile;
int m_nframe;
int width,height;
//
//
//
bool CreateAVI(LPCTSTR str,int Width,int Height)
{
        int iSize = sizeof(BITMAPINFOHEADER);
        memset(&BI, 0, iSize);

        BI.bmiHeader.biSize=iSize;
        BI.bmiHeader.biWidth=Width;
        BI.bmiHeader.biHeight=Height;
        BI.bmiHeader.biPlanes=1;
        BI.bmiHeader.biBitCount=32;
        BI.bmiHeader.biCompression=BI_RGB;

        m_nframe=0;
        width=Width;
        height=Height;
        HRESULT hr;

        AVIFileInit();

        hr = AVIFileOpen(&pfile,                                // returned file pointer
                      str,                                                        // file name
                      OF_WRITE | OF_CREATE,                // mode to open file with
                      NULL);                                                // use handler determined
                                                                                        // from file extension....
        if (hr != AVIERR_OK)
                return FALSE;
        return TRUE;

//        m_timeOneFrame=timeOneFrame;
}
//
//
//
//
int WriteAVIFrame(LPVOID pixels, int fps)
{
        HRESULT hr;

        if(!m_nframe)
        {
                AVICOMPRESSOPTIONS opts;
                AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
                AVISTREAMINFO strhdr;

                memset(&strhdr, 0, sizeof(strhdr));
                strhdr.fccType                = streamtypeVIDEO;// stream type
                strhdr.fccHandler            = 0;
                strhdr.dwScale                = 1;

                strhdr.dwRate = fps;


                strhdr.dwSuggestedBufferSize  = width*height*4;
                SetRect(&strhdr.rcFrame, 0, 0,width,height);                    // rectangle for stream
                // And create the stream;
                hr = AVIFileCreateStream(pfile,                    // file pointer
                                &ps,                    // returned stream pointer
                                &strhdr);            // stream header
                if (hr != AVIERR_OK)
                        return 0;

                memset(&opts, 0, sizeof(opts));

                if (!AVISaveOptions(NULL, 0, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
                        return 2;

                hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
                if (hr != AVIERR_OK)
                        return 0;

                hr=AVIStreamSetFormat(psCompressed,0,&BI,sizeof(BITMAPINFO));
                if(hr != AVIERR_OK)
                        return 0;
        }

        hr = AVIStreamWrite(psCompressed,        // stream pointer
                (m_nframe) * ONETICKTIME,                                // time of this frame
                1,                                // number to write
                pixels,
                width*height*4,
                m_nframe+1,                        // flags....
//                AVIIF_KEYFRAME,                        // flags....
                NULL,
                NULL);

        if (hr != AVIERR_OK)
                return 0;
        m_nframe++;
        return 1;
}

//
//
//
void CloseAVI()
{

        if (ps)
                AVIStreamClose(ps);

        if (psCompressed)
                AVIStreamClose(psCompressed);

        if (pfile)
                AVIFileClose(pfile);

        AVIFileExit();
}


Viewing all articles
Browse latest Browse all 3042

Trending Articles