You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
10 KiB

/*
* Generic DCT based hybrid video encoder
* Copyright (c) 2000,2001 Gerard Lantau.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Macros for picture code type. */
#define I_TYPE 1
#define P_TYPE 2
#define B_TYPE 3
enum OutputFormat {
FMT_MPEG1,
FMT_H263,
FMT_MJPEG,
};
#define MPEG_BUF_SIZE (16 * 1024)
typedef struct MpegEncContext {
struct AVCodecContext *avctx;
/* the following parameters must be initialized before encoding */
int width, height; /* picture size. must be a multiple of 16 */
int gop_size;
int frame_rate; /* number of frames per second */
int intra_only; /* if true, only intra pictures are generated */
int bit_rate; /* wanted bit rate */
enum OutputFormat out_format; /* output format */
int h263_plus; /* h263 plus headers */
int h263_rv10; /* use RV10 variation for H263 */
int h263_pred; /* use mpeg4/h263 ac/dc predictions */
int h263_msmpeg4; /* generate MSMPEG4 compatible stream */
int h263_intel; /* use I263 intel h263 header */
int fixed_qscale; /* fixed qscale if non zero */
int encoding; /* true if we are encoding (vs decoding) */
/* the following fields are managed internally by the encoder */
/* bit output */
PutBitContext pb;
/* sequence parameters */
int context_initialized;
int picture_number;
int fake_picture_number; /* picture number at the bitstream frame rate */
int gop_picture_number; /* index of the first picture of a GOP */
int mb_width, mb_height;
int linesize; /* line size, in bytes, may be different from width */
UINT8 *new_picture[3]; /* picture to be compressed */
UINT8 *last_picture[3]; /* previous picture */
UINT8 *last_picture_base[3]; /* real start of the picture */
UINT8 *next_picture[3]; /* previous picture (for bidir pred) */
UINT8 *next_picture_base[3]; /* real start of the picture */
UINT8 *aux_picture[3]; /* aux picture (for B frames only) */
UINT8 *aux_picture_base[3]; /* real start of the picture */
UINT8 *current_picture[3]; /* buffer to store the decompressed current picture */
int last_dc[3]; /* last DC values for MPEG1 */
INT16 *dc_val[3]; /* used for mpeg4 DC prediction */
int y_dc_scale, c_dc_scale;
UINT8 *coded_block; /* used for coded block pattern prediction */
INT16 (*ac_val[3])[16]; /* used for for mpeg4 AC prediction */
int ac_pred;
int mb_skiped; /* MUST BE SET only during DECODING */
UINT8 *mbskip_table; /* used to avoid copy if macroblock
skipped (for black regions for example) */
int qscale;
int pict_type;
int frame_rate_index;
/* motion compensation */
int unrestricted_mv;
int h263_long_vectors; /* use horrible h263v1 long vector mode */
int f_code; /* resolution */
INT16 (*motion_val)[2]; /* used for MV prediction */
int full_search;
int mv_dir;
#define MV_DIR_BACKWARD 1
#define MV_DIR_FORWARD 2
int mv_type;
#define MV_TYPE_16X16 0 /* 1 vector for the whole mb */
#define MV_TYPE_8X8 1 /* 4 vectors (h263) */
#define MV_TYPE_16X8 2 /* 2 vectors, one per 16x8 block */
#define MV_TYPE_FIELD 3 /* 2 vectors, one per field */
#define MV_TYPE_DMV 4 /* 2 vectors, special mpeg2 Dual Prime Vectors */
/* motion vectors for a macroblock
first coordinate : 0 = forward 1 = backward
second " : depend on type
third " : 0 = x, 1 = y
*/
int mv[2][4][2];
int field_select[2][2];
int last_mv[2][2][2];
int has_b_frames;
int no_rounding; /* apply no rounding to motion estimation (MPEG4) */
/* macroblock layer */
int mb_x, mb_y;
int mb_incr;
int mb_intra;
/* matrix transmitted in the bitstream */
UINT16 intra_matrix[64];
UINT16 chroma_intra_matrix[64];
UINT16 non_intra_matrix[64];
UINT16 chroma_non_intra_matrix[64];
/* precomputed matrix (combine qscale and DCT renorm) */
int q_intra_matrix[64];
int q_non_intra_matrix[64];
int block_last_index[6]; /* last non zero coefficient in block */
void *opaque; /* private data for the user */
/* bit rate control */
int I_frame_bits; /* wanted number of bits per I frame */
int P_frame_bits; /* same for P frame */
INT64 wanted_bits;
INT64 total_bits;
/* H.263 specific */
int gob_number;
int gob_index;
int first_gob_line;
/* H.263+ specific */
int umvplus;
int umvplus_dec;
/* mpeg4 specific */
int time_increment_bits;
int shape;
int vol_sprite_usage;
int quant_precision;
/* RV10 specific */
int rv10_version; /* RV10 version: 0 or 3 */
int rv10_first_dc_coded[3];
/* MJPEG specific */
struct MJpegContext *mjpeg_ctx;
/* MSMPEG4 specific */
int mv_table_index;
int rl_table_index;
int rl_chroma_table_index;
int dc_table_index;
int use_skip_mb_code;
int slice_height; /* in macroblocks */
int first_slice_line;
/* decompression specific */
GetBitContext gb;
/* MPEG2 specific - I wish I had not to support this mess. */
int progressive_sequence;
int mpeg_f_code[2][2];
int picture_structure;
/* picture type */
#define PICT_TOP_FIELD 1
#define PICT_BOTTOM_FIELD 2
#define PICT_FRAME 3
int intra_dc_precision;
int frame_pred_frame_dct;
int top_field_first;
int concealment_motion_vectors;
int q_scale_type;
int intra_vlc_format;
int alternate_scan;
int repeat_first_field;
int chroma_420_type;
int progressive_frame;
int mpeg2;
int full_pel[2];
int interlaced_dct;
int last_qscale;
int first_slice;
/* RTP specific */
int rtp_mode;
int rtp_payload_size;
UINT8 *ptr_lastgob;
UINT8 *ptr_last_mb_line;
UINT32 mb_line_avgsize;
DCTELEM block[6][64] __align8;
void (*dct_unquantize)(struct MpegEncContext *s,
DCTELEM *block, int n, int qscale);
} MpegEncContext;
int MPV_common_init(MpegEncContext *s);
void MPV_common_end(MpegEncContext *s);
void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
void MPV_frame_start(MpegEncContext *s);
void MPV_frame_end(MpegEncContext *s);
#ifdef HAVE_MMX
void MPV_common_init_mmx(MpegEncContext *s);
#endif
/* motion_est.c */
int estimate_motion(MpegEncContext *s,
int mb_x, int mb_y,
int *mx_ptr, int *my_ptr);
/* mpeg12.c */
extern INT16 default_intra_matrix[64];
extern INT16 default_non_intra_matrix[64];
void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
void mpeg1_encode_mb(MpegEncContext *s,
DCTELEM block[6][64],
int motion_x, int motion_y);
/* h263enc.c */
/* run length table */
#define MAX_RUN 64
#define MAX_LEVEL 64
typedef struct RLTable {
int n; /* number of entries of table_vlc minus 1 */
int last; /* number of values for last = 0 */
const UINT16 (*table_vlc)[2];
const INT8 *table_run;
const INT8 *table_level;
UINT8 *index_run[2]; /* encoding only */
INT8 *max_level[2]; /* encoding & decoding */
INT8 *max_run[2]; /* encoding & decoding */
VLC vlc; /* decoding only */
} RLTable;
void init_rl(RLTable *rl);
void init_vlc_rl(RLTable *rl);
extern inline int get_rl_index(const RLTable *rl, int last, int run, int level)
{
int index;
index = rl->index_run[last][run];
if (index >= rl->n)
return rl->n;
if (level > rl->max_level[last][run])
return rl->n;
return index + level - 1;
}
void h263_encode_mb(MpegEncContext *s,
DCTELEM block[6][64],
int motion_x, int motion_y);
void h263_encode_picture_header(MpegEncContext *s, int picture_number);
int h263_encode_gob_header(MpegEncContext * s, int mb_line);
void h263_dc_scale(MpegEncContext *s);
INT16 *h263_pred_motion(MpegEncContext * s, int block,
int *px, int *py);
void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
int dir);
void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void h263_encode_init_vlc(MpegEncContext *s);
void h263_decode_init_vlc(MpegEncContext *s);
int h263_decode_picture_header(MpegEncContext *s);
int h263_decode_gob_header(MpegEncContext *s);
int mpeg4_decode_picture_header(MpegEncContext * s);
int intel_h263_decode_picture_header(MpegEncContext *s);
int h263_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]);
int h263_get_picture_format(int width, int height);
/* rv10.c */
void rv10_encode_picture_header(MpegEncContext *s, int picture_number);
int rv_decode_dc(MpegEncContext *s, int n);
/* msmpeg4.c */
void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
void msmpeg4_encode_mb(MpegEncContext * s,
DCTELEM block[6][64],
int motion_x, int motion_y);
void msmpeg4_dc_scale(MpegEncContext * s);
int msmpeg4_decode_picture_header(MpegEncContext * s);
int msmpeg4_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]);
int msmpeg4_decode_init_vlc(MpegEncContext *s);
/* mjpegenc.c */
int mjpeg_init(MpegEncContext *s);
void mjpeg_close(MpegEncContext *s);
void mjpeg_encode_mb(MpegEncContext *s,
DCTELEM block[6][64]);
void mjpeg_picture_header(MpegEncContext *s);
void mjpeg_picture_trailer(MpegEncContext *s);