sigmaplayer/src/video.h

261 lines
6.1 KiB
C++

//////////////////////////////////////////////////////////////////////////
/**
* SigmaPlayer source project - Video player header file
* \file video.h
* \author bombur
* \version 0.1
* \date 07.03.2007
*
* This program 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.
*
* This program 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, USA.
*/
//////////////////////////////////////////////////////////////////////////
#ifndef SP_VIDEO_H
#define SP_VIDEO_H
typedef enum
{
VIDEO_CONTAINER_UNKNOWN = 0,
VIDEO_CONTAINER_AVI = 1,
VIDEO_CONTAINER_MPEG = 2,
VIDEO_CONTAINER_QT = 3,
} VIDEO_CONTAINER_TYPE;
typedef enum
{
VIDEO_CHUNK_UNKNOWN = 0,
VIDEO_CHUNK_VIDEO = 1,
VIDEO_CHUNK_AUDIO = 2,
VIDEO_CHUNK_VIDEO_PARTIAL = 3,
VIDEO_CHUNK_AUDIO_PARTIAL = 4,
VIDEO_CHUNK_SUBT = 5,
VIDEO_CHUNK_FRAGMENT = 6, // if chunk header is split
VIDEO_CHUNK_HEADER = 7, // MPEG header w/o audio/video data
VIDEO_CHUNK_RECOVERY = 8,
VIDEO_CHUNK_EOF = 100,
} VIDEO_CHUNK_TYPE;
typedef enum
{
RIFF_VIDEO_UNKNOWN = -1,
RIFF_VIDEO_MPEG12 = 0,
RIFF_VIDEO_MPEG4 = 1,
RIFF_VIDEO_DIV3 = 2,
} RIFF_VIDEO_FORMAT;
typedef enum
{
VIDEO_FRAME_NONE = -1,
VIDEO_FRAME_I = 0,
VIDEO_FRAME_P,
VIDEO_FRAME_B,
} VIDEO_FRAME_TYPE;
#ifdef VIDEO_INTERNAL
#include "divx.h"
extern bool video_msg;
typedef struct VideoKeyFrame
{
int i;
int len;
LONGLONG offs;
} VideoKeyFrame;
static const int num_key_frames_block = 32768 / sizeof(VideoKeyFrame);
static const int min_delta_keyframes = 10;
static const int def_max_rev_incr = 10;
static const int saved_delta_pts_num = 25;
#define VIDEO_MAX_AUDIO_TRACKS 8
#define VIDEO_KEY_FRAME_NEXT INT64(-0x7ffffffffffffff0)
#define VIDEO_KEY_FRAME_PREV INT64(-0x7ffffffffffffff1)
#define VIDEO_KEY_FRAME_CONTINUE INT64(-0x7ffffffffffffff2)
/// Generic base video player class
class Video
{
public:
/// ctor
Video();
/// dtor
virtual ~Video();
virtual BOOL Parse() = 0;
virtual VIDEO_CHUNK_TYPE GetNext(BYTE *buf, int buflen, int *pos, int *left, int *len) = 0;
/// Returns 0 if found, -1 if failed, 1 for EOF.
virtual int GetNextIndexes() = 0;
/// Find next key-frame in raw mode
virtual int GetNextKeyFrame() = 0;
virtual int GetKeyFrame(LONGLONG time);
virtual void UpdateTotalTime();
int SetCurrentIndex(int i, int len, LONGLONG offs);
int AddIndex(int i, int len, LONGLONG offs);
/// Fix audio packet PTS if audio is far ahead video
LONGLONG FixAudioPts(LONGLONG pts);
public:
VIDEO_CONTAINER_TYPE type;
bool playing, stopping, is_eof;
MEDIA_EVENT event;
int scale, rate;
LONGLONG scr;
LONGLONG good_delta_stc;
LONGLONG saved_pts, displ_pts_base;
bool wait_for_resync;
RIFF_VIDEO_FORMAT video_fmt;
RIFF_AUDIO_FORMAT audio_fmt;
SPString video_fmt_str, audio_fmt_str;
VIDEO_CHUNK_TYPE chunktype;
int chunkleft;
int video_packet_len, old_video_packet_len;
bool look4chunk;
bool test_for_qpel_gmc;
BYTE chunkheader[8];
BYTE *mux_buf[16], *allocated_mux_buf[16];
int mux_numbufs, mux_bufsize;
int allocated_numbufs;
int allocated_mux_buf_size[16];
bool no_partial;
BYTE *divx_buf[16], *divx_base[16];
int divx_cur_bufpos, divx_cur_bufleft;
bool in_divx_packet;
bool need_to_stop;
// for divx3 optimizations
bool audio_halfrate;
//// file container reader - common vars:
int fd;
int width, height;
float fps;
int video_frames;
bool qpel_flag, gmc_flag;
char fourcc[5];
RiffAudioTrack track[VIDEO_MAX_AUDIO_TRACKS];
int cur_track, first_track, num_tracks;
int cur_audio_bits;
int total_frames;
LONGLONG audio_delta, audio_total_bytes, audio_pts_offset; // needed for PTS calcs.
int num_idx;
SPClassicList<SPList<VideoKeyFrame> > indexes;
int abs_video_pos, video_pos_base, video_pos, last_key_pos, cur_key_pos;
int audio_pos;
int cur_key_idx, last_good_key_idx, last_key_idx;
int frame_pos, last_frame_pos;
int max_rev_incr;
bool skip_fwd, skip_rev, searching, skip_wait, skip_waiting;
int delayed_skip; // used to set skip_fwd/rev if not ready immediately
int last_keyframe_time;
int skip_cnt;
bool cancel_skip;
LONGLONG cur_offs, video_offs, cur_key_offs;
// for raw-mode seeking
LONGLONG last_chunk_offs;
int last_chunk_len;
LONGLONG saved_video_pts;
private:
/// Get given key-frame index
VideoKeyFrame *GetIndex(int idx);
void ResetAvgPts();
LONGLONG saved_delta_pts[saved_delta_pts_num];
LONGLONG avg_delta_pts, min_delta_pts, max_delta_pts, minus_delta_pts;
int saved_delta_pts_idx;
};
LONGLONG video_lseek(LONGLONG off, int where);
int video_read(BYTE *buf, int len);
#endif
/// Play Video file
int video_play(char *filepath = NULL);
/// Advance playing
int video_loop();
/// Pause playing
BOOL video_pause();
/// Stop playing
BOOL video_stop();
/// Seek to given time and play
BOOL video_seek(int seconds);
int video_forward(BOOL fast);
int video_rewind(BOOL fast);
void video_set_audio_offset(LONGLONG offset);
LONGLONG video_get_audio_offset();
void video_setdebug(BOOL ison);
BOOL video_getdebug();
/// Set audio track (if -1 then cycle through all)
int video_set_audio_track(int track);
bool video_search_fourcc(DWORD fourcc, const DWORD *values);
////////////////////////////////
BOOL video_open(const char *filepath);
BOOL video_close();
LONGLONG video_lseek(LONGLONG off, int where);
int video_read(BYTE *buf, int len);
bool video_eof();
VIDEO_CHUNK_TYPE video_getnext(BYTE *buf, int buflen, int *pos, int *left, int *len);
void video_shiftpos(int offs);
void video_detect_formats();
void video_update_info();
int video_play_from_last_keyframe();
void video_decode_vol_header(BYTE *buf, int len);
#endif // of SP_VIDEO_H