home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
wvis0626.zip
/
warpvision_20020626.zip
/
wvision.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-06-26
|
32KB
|
1,172 lines
/*
* WarpVision main
*
* Copyleft Alex Strelnikov.
*
* WarpVision is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* WarpVision is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#define INCL_DOS
#define INCL_DOSPROFILE
#define INCL_GPI
#define INCL_WIN
#define INCL_OS2MM
#include <os2.h>
#include <os2me.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <mmioos2.h>
#include <dive.h>
#include <fourcc.h>
#include <sys\types.h>
#include <inttypes.h>
#include "libDIVE.h"
#include "libDIVEpm.h"
#include "wvision.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "avcodec.h"
#include "yuv2rgb.h"
#include "avifmt.h"
#include "stream.h"
#include "demuxer.h"
#include "stheader.h"
#include "codecs.h"
#include "audio\dart.h"
#include "audio\adecode.h"
#include "video\vdecode.h"
HMTX demux_mtx;
HMTX dart_cb_mtx;
extern DartStruct DART;
extern int index_mode;
extern audio_header_t audio_header;
extern video_header_t video_header;
float audio_time, video_time;
#define Q2LL(a) ((ULONG)a.ulHi<<32)|((ULONG)a.ulLo)
//#define singlecadr (TimerFreq/sh_video->fps)
void dprintf(char fmt[],...)
{
return;
}
#ifdef __cplusplus
}
#endif
//-----------------------------------------
// Global variables
//-----------------------------------------
demux_stream_t *d_audio = NULL;
demux_stream_t *d_video = NULL;
sh_audio_t *sh_audio = NULL;
sh_video_t *sh_video = NULL;
stream_t* stream = NULL;
demuxer_t* demuxer = NULL;
int FullScreen = FALSE;
int Shutdown = FALSE;
int ScreenGamma = 0;
int SeekFlag = SEEK_NONE;
float SyncCorrection = 0.0;
diveWindow *dW;
int no_audio;
int Pause = FALSE;
int Mute = FALSE;
int AudioVolume = 0;
//-----------------------------------------
// Utility routines
//-----------------------------------------
void CheckMenuItem(HWND hMenu, USHORT ulID)
{
WinSendMsg(hMenu, MM_SETITEMATTR, (MPARAM)ulID,
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
}
extern "C" void CalcAVtime(void)
{
unsigned int samples;
if (no_audio != TRUE)
{
if (sh_audio->audio.dwSampleSize == 0)
{
audio_time = d_audio->pts;
}
else
{
samples = ((ds_tell(d_audio)-sh_audio->a_in_buffer_len) /
sh_audio->audio.dwSampleSize);
samples += sh_audio->audio.dwStart;
audio_time = samples * (float)sh_audio->audio.dwScale /
(float)sh_audio->audio.dwRate;
}
audio_time -= (float)audio_header.audio_buffer_used/sh_audio->i_bps;
audio_time -= (float)audio_header.dart_buffer_size/sh_audio->o_bps;
video_time = d_video->pts;
audio_time += SyncCorrection;
}
else
{
video_time = d_video->pts;
audio_time = video_time;
}
}
//-----------------------------------------
// Gamma adjustment dialog
//-----------------------------------------
MRESULT EXPENTRY GammaProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
ULONG ulValue;
char cData[128];
switch (msg)
{
case WM_CLOSE:
WinDismissDlg(hwndDlg, DID_CANCEL);
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case ID_CLOSE:
WinDismissDlg(hwndDlg, ID_CLOSE);
break;
}
break;
case WM_INITDLG:
{
USHORT usValue = (ScreenGamma + 128)/(256/32);
WinSendDlgItemMsg(hwndDlg, ID_GAMMA, SLM_SETTICKSIZE,
MPFROM2SHORT(SMA_SETALLTICKS, 6), NULL);
WinSendDlgItemMsg(hwndDlg, ID_GAMMA, SLM_SETSLIDERINFO,
MPFROM2SHORT(SMA_SLIDERARMPOSITION,
SMA_INCREMENTVALUE),
MPFROMSHORT(usValue));
sprintf(cData, "Gamma Correction (%d)", ScreenGamma);
WinSetWindowText(hwndDlg, cData);
}
break;
case WM_CONTROL:
switch (SHORT1FROMMP(mp1))
{
case ID_GAMMA:
ulValue = (ULONG)WinSendDlgItemMsg(hwndDlg, ID_GAMMA,
SLM_QUERYSLIDERINFO,
MPFROM2SHORT(SMA_SLIDERARMPOSITION,
SMA_INCREMENTVALUE),
NULL);
ulValue = ulValue * (256/32) - 128;
ScreenGamma = ulValue;
yuv2rgb_set_gamma(ScreenGamma);
sprintf(cData, "Gamma Correction (%d)", ScreenGamma);
WinSetWindowText(hwndDlg, cData);
break;
}
break;
default:
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return (MRESULT) FALSE;
}
//-----------------------------------------
// Various handlers
//-----------------------------------------
void TerminateHandler(diveWindow*, void *Self)
{
Shutdown = TRUE;
}
void MouseHandler(diveWindow* pWnd, HWND hWnd, void *param, int Button, bool Down,
int x, int y, int ShiftFlags)
{
if(Button == 2)
{
HWND hwndPopup;
POINTL ptlPoint;
HWND hwndFrame = WinQueryWindow(hWnd, QW_PARENT);
hwndPopup = WinLoadMenu(hwndFrame, 0, idDiveMenu);
if(pWnd->isPaused())
CheckMenuItem(hwndPopup, cmdPause2);
if(!pWnd->isAspectRatioConst())
CheckMenuItem(hwndPopup, cmdToggleAspect);
if(pWnd->isFullScreen())
CheckMenuItem(hwndPopup, cmdFullScreen2);
WinQueryPointerPos(HWND_DESKTOP, &ptlPoint);
WinPopupMenu(HWND_DESKTOP, hwndFrame, hwndPopup,
ptlPoint.x, ptlPoint.y, 0,
0
| PU_NONE
| PU_KEYBOARD
| PU_MOUSEBUTTON1
| PU_MOUSEBUTTON2
| PU_HCONSTRAIN
| PU_VCONSTRAIN);
}
}
void KeyboardHandler(diveWindow*, void *Self, unsigned char ScanCode,
unsigned char CharCode, bool Down, unsigned char RepeatCount, int ShiftFlags)
{
// printf("Key - Scancode(%d) Char(%c) Pressed(%d) Count(%d) ShiftFlags(%04X)\n",
// ScanCode, CharCode, Down, RepeatCount, ShiftFlags);
if(ScanCode == ScanExit)
{
Shutdown = TRUE;
return;
}
if(Down != 1)
return;
switch(ScanCode)
{
case ScanFS:
{
if(FullScreen == TRUE)
{
FullScreen = FALSE;
dW->MouseVisible(TRUE);
}
else
{
FullScreen = TRUE;
dW->MouseVisible(FALSE);
}
dW->Command(cmdFullScreen);
}
break;
case ScanGammaDec:
if (ScreenGamma > -128)
{
ScreenGamma--;
yuv2rgb_set_gamma(ScreenGamma);
}
break;
case ScanGammaInc:
if (ScreenGamma < 128)
{
ScreenGamma++;
yuv2rgb_set_gamma(ScreenGamma);
}
break;
case ScanPause1:
case ScanPause2:
if (Pause == TRUE)
{
Pause = FALSE;
dart_resume();
dW->Command(cmdPause);
}
else
{
DosRequestMutexSem(dart_cb_mtx, (ULONG)SEM_INDEFINITE_WAIT);
Pause = TRUE;
dart_pause();
dW->Command(cmdPause);
DosReleaseMutexSem(dart_cb_mtx);
}
break;
case ScanBack10s:
SeekFlag = SEEK_BACKWARD_10S;
break;
case ScanFwd10s:
SeekFlag = SEEK_FORWARD_10S;
break;
case ScanFwd60s:
SeekFlag = SEEK_FORWARD_60S;
break;
case ScanBack60s:
SeekFlag = SEEK_BACKWARD_60S;
break;
case ScanFwd600s:
SeekFlag = SEEK_FORWARD_600S;
break;
case ScanBack600s:
SeekFlag = SEEK_BACKWARD_600S;
break;
case ScanSyncDec:
SyncCorrection -= 0.1f;
break;
case ScanSyncInc:
SyncCorrection += 0.1f;
break;
case ScanMute:
if (Mute == FALSE)
{
Mute = TRUE;
DosRequestMutexSem(dart_cb_mtx, (ULONG)SEM_INDEFINITE_WAIT);
dart_set_sound_state(Mute);
DosReleaseMutexSem(dart_cb_mtx);
}
else
{
Mute = FALSE;
DosRequestMutexSem(dart_cb_mtx, (ULONG)SEM_INDEFINITE_WAIT);
dart_set_sound_state(Mute);
DosReleaseMutexSem(dart_cb_mtx);
}
break;
case ScanVolumeInc:
if (AudioVolume < 100)
AudioVolume++;
DosRequestMutexSem(dart_cb_mtx, (ULONG)SEM_INDEFINITE_WAIT);
dart_set_volume(AudioVolume);
DosReleaseMutexSem(dart_cb_mtx);
break;
case ScanVolumeDec:
if (AudioVolume > 0)
AudioVolume--;
DosRequestMutexSem(dart_cb_mtx, (ULONG)SEM_INDEFINITE_WAIT);
dart_set_volume(AudioVolume);
DosReleaseMutexSem(dart_cb_mtx);
break;
}
}
MPARAM CmdHandler(diveWindow* p, void *param, HWND hWnd, MPARAM mp1, MPARAM mp2, int Mode)
{
if(!Mode) //Ignore pre-action call
{
//Return same command as passed.
//This allows default command handlers to work properly.
return mp1;
}
switch((ULONG) mp1)
{
case cmdFullScreen2: KeyboardHandler(0, p, ScanFS, 0, 1, 0, 0); break;
case cmdPause2 : KeyboardHandler(0, p, ScanPause2, 0, 1, 0, 0); break;
case cmdSeek10sFwd : KeyboardHandler(0, p, ScanFwd10s, 0, 1, 0, 0); break;
case cmdSeek60sFwd : KeyboardHandler(0, p, ScanFwd60s, 0, 1, 0, 0); break;
case cmdSeek10mFwd : KeyboardHandler(0, p, ScanFwd600s, 0, 1, 0, 0); break;
case cmdSeek10sBack: KeyboardHandler(0, p, ScanBack10s, 0, 1, 0, 0); break;
case cmdSeek60sBack: KeyboardHandler(0, p, ScanBack60s, 0, 1, 0, 0); break;
case cmdSeek10mBack: KeyboardHandler(0, p, ScanBack600s, 0, 1, 0, 0); break;
case cmdGammInc : KeyboardHandler(0, p, ScanGammaInc, 0, 1, 0, 0); break;
case cmdGammaDec : KeyboardHandler(0, p, ScanGammaDec, 0, 1, 0, 0); break;
case cmdGamma:
{
HWND wnd = WinLoadDlg(HWND_DESKTOP, hWnd,
GammaProc, 0, ID_SET_DLG, 0);
WinProcessDlg(wnd);
WinDestroyWindow(wnd);
}
break;
}
return 0; //Value does not matter, it's ignored
}
//-----------------------------------------
// DART worker
//-----------------------------------------
void APIENTRY PlayAudio(ULONG Parm)
{
dart_play();
while(DART.Stopped != TRUE)
{
DosSleep(100);
}
dart_stop();
no_audio = TRUE;
return;
}
//-----------------------------------------
// Video worker
//-----------------------------------------
void APIENTRY PlayVideo(ULONG Parm)
{
int rc;
ULONG TimerFreq;
int FrameTimer;
QWORD Qres;
unsigned long long StartDec, EndDec;
float frame_delay;
ULONG numwait;
int numcadr;
int SkipFrame = 0;
int SkippedFrames = 0;
ULONG bpl = 0;
int show_info = -1;
unsigned char *DiveMemory;
DosTmrQueryFreq(&TimerFreq);
DosTmrQueryTime(&Qres);
StartDec = Q2LL(Qres);
FrameTimer = 0;
CalcAVtime();
while(Shutdown == 0)
{
DosTmrQueryTime(&Qres);
EndDec = Q2LL(Qres);
if (no_audio == TRUE)
CalcAVtime();
frame_delay = (audio_time - video_time) / sh_video->fps;
if (show_info++ > (int)sh_video->fps * 5.0f || show_info < 0)
{
printf("A: %5.1f V: %5.1f A-V: %3.2f C: %3.2f \r",
audio_time, video_time, audio_time - video_time,
SyncCorrection);
fflush(stdout);
show_info = 0;
}
FrameTimer += (EndDec - StartDec);
if (frame_delay)
{
FrameTimer += (TimerFreq/sh_video->fps) * frame_delay;
frame_delay = 0;
}
StartDec = EndDec;
numcadr = ((float)FrameTimer)/TimerFreq;
// A and B defines maximum proportion of frames to be skipped.
// Now for 5 skipped we must show at least 1 real.
if (numcadr > 2 + max(0, SkippedFrames) / 2)
{
SkipFrame = TRUE;
SkippedFrames++; // A
}
else
if (SkippedFrames > 0)
SkippedFrames = 0; // B
if (numcadr > 0)
{
FrameTimer -= TimerFreq/sh_video->fps;
NextMem:
if (SeekFlag != SEEK_NONE)
{
DosRequestMutexSem(dart_cb_mtx, (ULONG)SEM_INDEFINITE_WAIT);
switch(SeekFlag)
{
case SEEK_FORWARD_10S:
demux_seek(demuxer, 10, 0);
break;
case SEEK_BACKWARD_10S:
demux_seek(demuxer, -10, 0);
break;
case SEEK_FORWARD_60S:
demux_seek(demuxer, 60, 0);
break;
case SEEK_BACKWARD_60S:
demux_seek(demuxer, -60, 0);
break;
case SEEK_FORWARD_600S:
demux_seek(demuxer, 600, 0);
break;
case SEEK_BACKWARD_600S:
demux_seek(demuxer, -600, 0);
break;
}
DosReleaseMutexSem(dart_cb_mtx);
SeekFlag = SEEK_NONE;
FrameTimer = 0;
frame_delay = 0;
SkipFrame = FALSE;
CalcAVtime();
}
if (Pause == TRUE)
{
DosSleep(2);
continue;
}
switch(video_header.codec)
{
case CODEC_FFMPEG:
{
if ((rc = video_decode(sh_video, NULL, 0)) == -1)
{
Shutdown = TRUE;
break;
}
if (rc == 0 && SkipFrame == FALSE)
{
DiveMemory = (unsigned char *)dW->BeginPaint(&bpl, DIVE_NEXTBUFFER);
if (DiveMemory == NULL)
continue;
video_blit(sh_video, DiveMemory, bpl);
dW->EndPaint();
dW->Switch(DIVE_NEXTBUFFER);
dW->WaitSwitch();
}
else
SkipFrame = FALSE;
}
break;
case CODEC_LIBMPEG2:
{
if (SkipFrame == FALSE)
{
DiveMemory = (unsigned char *)dW->BeginPaint(&bpl, DIVE_NEXTBUFFER);
if (DiveMemory == NULL)
continue;
rc = video_decode(sh_video, DiveMemory, bpl);
dW->EndPaint();
dW->Switch(DIVE_NEXTBUFFER);
dW->WaitSwitch();
if (rc == -1)
{
Shutdown = TRUE;
break;
}
}
else
SkipFrame = FALSE;
}
break;
}
}
else
{
DosSleep(1);
}
}
dart_stop();
printf("video thread exiting\n");
fflush(stdout);
return;
}
int GetBestDIVEMode(void)
{
DIVE_CAPS caps;
FOURCC fourcc;
char *caps_buffer;
int i, best_format;
caps_buffer = (char *)malloc(512);
caps.ulStructLen = sizeof(DIVE_CAPS);
caps.ulFormatLength = 512;
caps.pFormatData = caps_buffer;
caps.ulPlaneCount = 0;
DiveQueryCaps(&caps, DIVE_BUFFER_SCREEN);
best_format = -1;
#if 0
for (i = 0; i < caps.ulInputFormats; i++)
{
fourcc = ((FOURCC *) caps.pFormatData)[i];
printf("%.4s ", (char*)&fourcc);
}
printf("\n");
#endif
for (i = 0; i < caps.ulInputFormats; i++)
{
fourcc = ((FOURCC *) caps.pFormatData)[i];
if (strnicmp((char*)&fourcc, "Y422", 4) == 0)
{
best_format = FMT_YUV422;
break;
}
if (strnicmp((char*)&fourcc, "R565", 4) == 0)
{
best_format = FMT_RGB16;
break;
}
if (strnicmp((char*)&fourcc, "BGR3", 4) == 0)
{
best_format = FMT_BGR24;
break;
}
}
free(caps_buffer);
return best_format;
}
int main(int argc, char *argv[])
{
PPIB pib;
PTIB tib;
ULONG OldProcessType;
TID AudioThread, VideoThread;
HWND WinHandle;
PMrq rq;
FOURCC fccColorFormat;
char pszTitleText[64];
int WindowX, WindowY, WindowWidth, WindowHeight;
int SrcWindowWidth, SrcWindowHeight;
int rc, outbytes;
int AudioDeviceIndex = 0;
int AudioResampleFlag = RESAMPLE_NONE;
int AudioID = -1;
int VideoID = -1;
int VideoFormat = -1;
int file_format = DEMUXER_TYPE_UNKNOWN;
int ArgNum;
int show_info;
int AudioDisable = FALSE;
int KeepAspect = FALSE;
int ForceAspect = FALSE;
float NewAspect = 1.0;
// Detect the best output format
VideoFormat = GetBestDIVEMode();
if (argc <= 1) {
printf("Usage: WarpVision [options] movie_file\n\n");
printf(" Audio options:\n");
printf(" -noaudio - Disable audio\n");
printf(" -44100 - Resample audio 48kHz to 44kHz\n");
printf(" -48000 - Resample any audio samplerate to 48kHz\n");
printf(" -adevXX - Select audio device 0...\n");
printf(" -aidXXX - Select audio channel\n");
printf("\n");
printf(" Video options:\n");
printf(" -vrgb - Output decoded frames in RGB16\n");
printf(" -vbgr - Output decoded frames in BGR24\n");
printf(" -vyuv - Output decoded frames in YUV422\n");
printf(" -idx - Rebuild AVI file index\n");
printf(" -vidXXX - Select video channel\n");
printf(" -vaspect - Keep aspect ratio\n");
printf(" -vasp43 - Force aspect ratio to 4:3\n");
printf(" -vasp169 - Force aspect ratio to 16:9\n");
exit(1);
}
printf("Command line:");
for(ArgNum = 0; ArgNum < argc; ArgNum++)
{
if (strcmp(argv[ArgNum], "-44100") == 0)
AudioResampleFlag = RESAMPLE_TO_44100;
if (strcmp(argv[ArgNum], "-48000") == 0)
AudioResampleFlag = RESAMPLE_TO_48000;
if (strncmp(argv[ArgNum], "-adev", 5) == 0)
AudioDeviceIndex = atoi(argv[ArgNum] + 5);
if (strcmp(argv[ArgNum], "-idx") == 0)
index_mode = 2; // generate index
if (strcmp(argv[ArgNum], "-noaudio") == 0)
AudioDisable = TRUE;
if (strcmp(argv[ArgNum], "-vaspect") == 0)
KeepAspect = TRUE;
if (strcmp(argv[ArgNum], "-vasp43") == 0)
{
ForceAspect = TRUE;
NewAspect = 4.0/3.0;
}
if (strcmp(argv[ArgNum], "-vasp169") == 0)
{
ForceAspect = TRUE;
NewAspect = 16.0/9.0;
}
if (strncmp(argv[ArgNum], "-aid", 4) == 0)
AudioID = atoi(argv[ArgNum] + 4);
if (strncmp(argv[ArgNum], "-vid", 4) == 0)
VideoID = atoi(argv[ArgNum] + 4);
if (strcmp(argv[ArgNum], "-vrgb") == 0)
VideoFormat = FMT_RGB16;
if (strcmp(argv[ArgNum], "-vbgr") == 0)
VideoFormat = FMT_BGR24;
if (strcmp(argv[ArgNum], "-vyuv") == 0)
VideoFormat = FMT_YUV422;
if (strncmp(argv[ArgNum], "-dvd", 4) == 0)
dvd_title = atoi(argv[ArgNum] + 4);
if (strncmp(argv[ArgNum], "-chapter", 8) == 0)
dvd_chapter = atoi(argv[ArgNum] + 8);
if (strncmp(argv[ArgNum], "-angle", 6) == 0)
dvd_angle = atoi(argv[ArgNum] + 6);
printf(" '%s'",argv[ArgNum]);
}
printf("\n");
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MINIMUM, PRTYS_PROCESSTREE);
// DosSetPriority (PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, PRTYS_PROCESSTREE);
DosGetInfoBlocks (&tib, &pib);
OldProcessType = pib->pib_ultype;
pib->pib_ultype = 3;
gdMH = NULLHANDLE;
DosCreateMutexSem(NULL, &demux_mtx, 0, FALSE);
DosCreateMutexSem(NULL, &dart_cb_mtx, 0, FALSE);
// Init streams
stream = open_stream(argv[argc-1], 0, &file_format);
if(!stream)
{
exit(1);
}
if (AudioDisable == TRUE)
{
printf("Audio: disabled\n");
AudioID = -2; // don't read audio packets
}
demuxer = demux_open(stream, file_format, AudioID, VideoID, -1);
if(demuxer == NULL)
{
printf("Cannot open demuxer\n");
exit(1);
}
d_audio = demuxer->audio;
d_video = demuxer->video;
if (AudioDisable == TRUE)
sh_audio = NULL;
else
sh_audio=(sh_audio_t *)d_audio->sh;
sh_video=(sh_video_t *)d_video->sh;
// Find & init audio codec
if (sh_audio != NULL)
{
sh_audio->codec=find_audio_codec(sh_audio->format);
if (sh_audio->codec->codec_supported == TRUE)
{
printf("Found audio codec: %s\n", sh_audio->codec->codec_name);
rc = audio_init(sh_audio, AudioDeviceIndex, AudioResampleFlag);
AudioVolume = dart_get_volume();
printf("Audio: sample rate: %d, bit rate: %d kbps, scannels: %d\n",
audio_header.sample_rate, audio_header.bit_rate,
audio_header.channels);
if (rc != TRUE)
no_audio = TRUE;
else
no_audio = FALSE;
}
else
{
printf("Found audio codec: %s\n", sh_audio->codec->codec_name);
ds_free_packs(d_audio);
d_audio->id = -2;
no_audio = TRUE;
sh_audio = NULL;
d_audio->sh = NULL;
}
}
else
{
ds_free_packs(d_audio);
d_audio->id = -2;
no_audio = TRUE;
sh_audio = NULL;
d_audio->sh = NULL;
}
if (sh_video != NULL)
{
video_read_properties(sh_video);
switch(sh_video->ds->demuxer->file_format)
{
case DEMUXER_TYPE_ASF:
sh_video->aspect = 1.0;
printf("Video: fourcc:[%.4s] size:%dx%d\n",
(char *)&sh_video->format,
sh_video->disp_w,sh_video->disp_h);
break;
case DEMUXER_TYPE_AVI:
case DEMUXER_TYPE_AVI_NI:
case DEMUXER_TYPE_AVI_NINI:
sh_video->aspect = 1.0;
printf("Video: fourcc:[%.4s] size:%dx%d fps:%5.2f\n",
(char *)&sh_video->format, sh_video->disp_w,sh_video->disp_h,
sh_video->fps);
break;
case DEMUXER_TYPE_MPEG_ES:
case DEMUXER_TYPE_MPEG_PS:
char aspect[8];
switch(sh_video->aspect_info)
{
case 2:
case 4:
case 8:
case 12:
strcpy(aspect, "4:3");
break;
case 3:
case 6:
strcpy(aspect, "16:9");
break;
default:
strcpy(aspect, "1:1");
sh_video->aspect = 1.0;
break;
}
printf("Video: MPEG%d size:%dx%d aspect:%d(%s) fps:%5.2f\n",
sh_video->format & 0xF,
sh_video->disp_w,sh_video->disp_h,
sh_video->aspect_info, aspect,
sh_video->fps);
if (KeepAspect == TRUE)
sh_video->aspect = 1.0;
if (ForceAspect == TRUE)
sh_video->aspect = NewAspect;
break;
}
// Find & init video codec
sh_video->codec=find_video_codec(sh_video->format);
printf("Found video codec: %s\n", sh_video->codec->codec_name);
if (sh_video->codec->codec_supported == FALSE)
return 1;
}
switch(VideoFormat)
{
case FMT_RGB16:
printf("Using RGB16 (R565) for DIVE blitting\n");
break;
case FMT_BGR24:
printf("Using BGR24 (BGR3) for DIVE blitting\n");
break;
case FMT_YUV422:
printf("Using YUV422 (Y422) for DIVE blitting\n");
break;
default:
{
printf("Cannot detect usable DIVE mode.\n");
printf("Using RGB16 (R565) for DIVE blitting\n");
VideoFormat = FMT_RGB16;
}
}
video_header.format = VideoFormat;
if (video_init(sh_video, sh_video->codec->codec_type) != 0)
exit(1);
// DIVE Output video frame format
switch(video_header.format)
{
case FMT_RGB16:
fccColorFormat = FOURCC_R565;
video_header.format_bpp = 2;
break;
case FMT_BGR24:
fccColorFormat = FOURCC_BGR3;
video_header.format_bpp = 3;
break;
case FMT_YUV422:
fccColorFormat = FOURCC_Y422;
video_header.format_bpp = 2;
break;
}
// Initialize DIVE
if (!gdDiveInitialize ())
{
printf ("Unable to initialize DIVE\n");
exit (1);
}
// Calc window size
WindowX = 10;
WindowY = 10;
SrcWindowWidth = (sh_video->disp_w + 15) &~ 15;
SrcWindowHeight = sh_video->disp_h;
WindowWidth = (sh_video->disp_w + 15) &~ 15;
WindowHeight = sh_video->disp_h;
if (sh_video->aspect != 1.0)
{
if (((float)WindowHeight * (float)sh_video->aspect) < SrcWindowWidth)
{ // 4/3
WindowHeight = (float)WindowWidth / (float)sh_video->aspect;
}
else
{ // 16/9
WindowWidth = (float)WindowHeight * (float)sh_video->aspect;
WindowWidth = (WindowWidth + 15) &~ 15;
}
printf("Video aspect correction: %dx%d -> %dx%d\n", sh_video->disp_w, sh_video->disp_h,
WindowWidth, WindowHeight);
}
// Create PM window
sprintf(pszTitleText,
"WarpVision v0.0.14e (%dx%d)",
sh_video->disp_w, sh_video->disp_h);
rq.Parm.CreateWindow.Title = pszTitleText;
if ((rc = PMcall (pmcmdCreateWindow, &rq)) != pmrcOK)
{
printf ("Cannot create PM window: no resources bound to executable?\n");
return FALSE;
}
WinHandle = rq.Parm.CreateWindow.Handle;
FGVideoMode Mode = // selected mode with double buffering
{ WindowWidth, WindowHeight, fccColorFormat, 2, SrcWindowWidth, SrcWindowHeight, vmfWindowed };
// Create DIVE contect
rq.Parm.CreateCtx.Mode = &Mode;
if ((rc = PMcall (pmcmdCreateDIVEctx, &rq)) != pmrcOK)
{
printf ("Cannot create DIVE context\n");
return FALSE;
}
dW = rq.Parm.CreateCtx.dW;
// Setup event handlers
dW->SetKeyboardHandler(KeyboardHandler, NULL);
dW->SetMouseHandler(MouseHandler, NULL);
dW->SetTerminateHandler(TerminateHandler, NULL);
dW->SetCmdHandler(CmdHandler, NULL);
// Bind DIVE context to window
rq.Parm.BindCtx.dW = dW;
rq.Parm.BindCtx.Handle = WinHandle;
rq.Parm.BindCtx.DesktopW = DesktopW;
rq.Parm.BindCtx.DesktopH = DesktopH;
if ((rc = PMcall (pmcmdBindDIVEctx, &rq)) != pmrcOK)
{
printf ("Cannot bind DIVE context to window!\n");
return FALSE;
}
if ((WindowWidth != -1) && (WindowHeight != -1))
{
rq.Parm.Resize.dW = dW;
rq.Parm.Resize.Width = WindowWidth;
rq.Parm.Resize.Height = WindowHeight;
rq.Parm.Resize.Center = TRUE;
PMcall (pmcmdResizeWindow, &rq);
}
// Show window
rq.Parm.ShowWin.dW = dW;
rq.Parm.ShowWin.State = 1;
if ((rc = PMcall (pmcmdShowWindow, &rq)) != pmrcOK)
return FALSE;
DosCreateThread(&AudioThread,
(PFNTHREAD) PlayAudio,
0, 0L, 32767L);
DosCreateThread(&VideoThread,
(PFNTHREAD) PlayVideo,
0, 0L, 32767L);
DosWaitThread(&VideoThread, DCWW_WAIT);
DosKillThread(AudioThread);
DosSleep(200);
// Close stream
close_stream(stream);
// Destroy DIVE context
rq.Parm.DestroyCtx.dW = dW;
PMcall (pmcmdDestroyDIVEctx, &rq);
// Destroy PM window
rq.Parm.DestroyWindow.Handle = WinHandle;
PMcall (pmcmdDestroyWindow, &rq);
// Deallocate DIVE resources
gdDiveDeinitialize ();
rc = DosCloseMutexSem(demux_mtx);
rc = DosCloseMutexSem(dart_cb_mtx);
pib->pib_ultype = OldProcessType;
return 0;
}