From 6bea16fb8408d80701ba329edfb3cd7ae5b880af Mon Sep 17 00:00:00 2001 From: Guenter Bartsch Date: Tue, 28 Aug 2001 19:16:19 +0000 Subject: update to ffmpeg 0.4.5, buf types cleanup based on patch provided by Miguel Freitas CVS patchset: 510 CVS date: 2001/08/28 19:16:19 --- AUTHORS | 3 + src/demuxers/demux_avi.c | 154 +++++++++++++++-------------- src/demuxers/demux_mpeg.c | 4 +- src/demuxers/demux_mpeg_block.c | 4 +- src/demuxers/demux_pes.c | 6 +- src/demuxers/demux_ts.c | 4 +- src/libac3/xine_decoder.c | 4 +- src/libffmpeg/libavcodec/avcodec.h | 34 ++++++- src/libffmpeg/libavcodec/common.c | 20 +--- src/libffmpeg/libavcodec/common.h | 109 +++++++++++++++++++- src/libffmpeg/libavcodec/dsputil.c | 6 +- src/libffmpeg/libavcodec/dsputil.h | 14 ++- src/libffmpeg/libavcodec/dsputil_mmx.c | 3 - src/libffmpeg/libavcodec/dsputil_mmx_avg.h | 5 - src/libffmpeg/libavcodec/h263.c | 133 ++++++++++++++++--------- src/libffmpeg/libavcodec/h263dec.c | 49 ++++++--- src/libffmpeg/libavcodec/idct_mmx.c | 2 +- src/libffmpeg/libavcodec/mjpeg.c | 68 +++++++++++-- src/libffmpeg/libavcodec/mpeg12.c | 112 +++++++++++++-------- src/libffmpeg/libavcodec/mpeg12data.h | 82 +++++++++++---- src/libffmpeg/libavcodec/mpegvideo.c | 44 +++++---- src/libffmpeg/libavcodec/mpegvideo.h | 10 +- src/libffmpeg/libavcodec/msmpeg4.c | 10 +- src/libffmpeg/libavcodec/rv10.c | 26 +++-- src/libffmpeg/libavcodec/utils.c | 101 ++++++++++++++++++- src/libffmpeg/xine_decoder.c | 64 +++++------- src/libw32dll/w32codec.c | 14 ++- src/video_out/video_out_xshm.c | 3 +- src/xine-engine/buffer.h | 16 ++- src/xine-engine/video_decoder.c | 67 +++++++------ 30 files changed, 810 insertions(+), 361 deletions(-) diff --git a/AUTHORS b/AUTHORS index aaf21914e..94dbf81b3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -129,6 +129,9 @@ Contributions Marco Solari FAQ italian translation + Miguel Freitas + buf types cleanup, bitrate detection + (let us know if we've forgotten anyone) diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index 52eae48b7..5a6f499b2 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_avi.c,v 1.25 2001/08/25 07:42:30 guenter Exp $ + * $Id: demux_avi.c,v 1.26 2001/08/28 19:16:19 guenter Exp $ * * demultiplexer for avi streams * @@ -91,6 +91,9 @@ typedef struct long audio_posc; /* Audio position: chunk */ long audio_posb; /* Audio position: byte within chunk */ + uint32_t video_type; /* BUF_VIDEO_xxx type */ + uint32_t audio_type; /* BUF_AUDIO_xxx type */ + long pos; /* position in file */ long n_idx; /* number of index entries actually filled */ long max_idx; /* number of index entries actually allocated */ @@ -563,58 +566,12 @@ static avi_t *AVI_init(demux_avi_t *this) return AVI; } -static long AVI_frame_size(demux_avi_t *this, avi_t *AVI, long frame) -{ - if(!AVI->video_index) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; } - - if(frame < 0 || frame >= AVI->video_frames) return 0; - return(AVI->video_index[frame].len); -} - static void AVI_seek_start(avi_t *AVI) { AVI->video_posf = 0; AVI->video_posb = 0; } -static int AVI_set_video_position(demux_avi_t *this, avi_t *AVI, long frame) -{ - if(!AVI->video_index) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; } - - if (frame < 0 ) frame = 0; - AVI->video_posf = frame; - AVI->video_posb = 0; - return 0; -} - -static int AVI_set_audio_position(demux_avi_t *this, avi_t *AVI, long byte) -{ - long n0, n1, n; - - if(!AVI->audio_index) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; } - - if(byte < 0) byte = 0; - - /* Binary search in the audio chunks */ - - n0 = 0; - n1 = AVI->audio_chunks; - - while(n0audio_index[n].tot>byte) - n1 = n; - else - n0 = n; - } - - AVI->audio_posc = n0; - AVI->audio_posb = byte - AVI->audio_index[n0].tot; - - return 0; -} - static long AVI_read_audio(demux_avi_t *this, avi_t *AVI, char *audbuf, long bytes, int *bFrameDone) { @@ -766,26 +723,7 @@ static int demux_avi_next (demux_avi_t *this) { buf->input_pos = this->input->get_current_pos(this->input); - switch (this->avi->a_fmt) { - case 0x01: - buf->type = BUF_AUDIO_LPCM; - break; - case 0x2000: - buf->type = BUF_AUDIO_AC3; - break; - case 0x50: - case 0x55: - buf->type = BUF_AUDIO_MPEG; - break; - case 0x161: - buf->type = BUF_AUDIO_AVI; - break; - default: - printf ("demux_avi: unknown audio type 0x%lx =>exit\n", this->avi->a_fmt); - this->status = DEMUX_FINISHED; - buf->type = BUF_AUDIO_MPEG; - break; - } + buf->type = this->avi->audio_type; if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); @@ -799,7 +737,7 @@ static int demux_avi_next (demux_avi_t *this) { buf->PTS = video_pts; buf->size = AVI_read_video (this, this->avi, buf->mem, 2048, &buf->decoder_info[0]); - buf->type = BUF_VIDEO_AVI ; + buf->type = this->avi->video_type; if (buf->size<0) { buf->free_buffer (buf); @@ -968,7 +906,74 @@ static void demux_avi_start (demux_plugin_t *this_gen, buf->decoder_info[1] = this->video_step; memcpy (buf->content, &this->avi->bih, sizeof (this->avi->bih)); buf->size = sizeof (this->avi->bih); - buf->type = BUF_VIDEO_AVI; + + switch (this->avi->bih.biCompression) { + case mmioFOURCC('M', 'P', 'G', '4'): + case mmioFOURCC('m', 'p', 'g', '4'): + case mmioFOURCC('M', 'P', '4', '1'): + case mmioFOURCC('m', 'p', '4', '1'): + case mmioFOURCC('M', 'P', '4', '2'): + case mmioFOURCC('m', 'p', '4', '2'): + case mmioFOURCC('M', 'P', '4', '3'): + case mmioFOURCC('m', 'p', '4', '3'): + case mmioFOURCC('D', 'I', 'V', '3'): + case mmioFOURCC('d', 'i', 'v', '3'): + case mmioFOURCC('D', 'I', 'V', '4'): + case mmioFOURCC('d', 'i', 'v', '4'): + /* Video in Microsoft MPEG-4 format */ + this->avi->video_type = BUF_VIDEO_MSMPEG4; + break; + case mmioFOURCC('D', 'I', 'V', 'X'): + case mmioFOURCC('d', 'i', 'v', 'x'): + case mmioFOURCC('D', 'i', 'v', 'x'): + case mmioFOURCC('D', 'i', 'v', 'X'): + /* Video in mpeg4 (opendivx) format */ + this->avi->video_type = BUF_VIDEO_MPEG4; + break; + case mmioFOURCC('d', 'm', 'b', '1'): + case mmioFOURCC('M', 'J', 'P', 'G'): + /* Video in motion jpeg format */ + this->avi->video_type = BUF_VIDEO_MJPEG; + break; + case mmioFOURCC('I', 'V', '5', '0'): + case mmioFOURCC('i', 'v', '5', '0'): + /* Video in Indeo Video 5.0 format */ + this->avi->video_type = BUF_VIDEO_IV50; + + case mmioFOURCC('I', 'V', '4', '1'): + case mmioFOURCC('i', 'v', '4', '1'): + /* Video in Indeo Video 4.1 format */ + this->avi->video_type = BUF_VIDEO_IV41; + break; + case mmioFOURCC('I', 'V', '3', '2'): + case mmioFOURCC('i', 'v', '3', '2'): + /* Video in Indeo Video 3.2 format */ + this->avi->video_type = BUF_VIDEO_IV32; + break; + + case mmioFOURCC('c', 'v', 'i', 'd'): + /* Video in Cinepak format */ + this->avi->video_type = BUF_VIDEO_CINEPACK; + break; + case mmioFOURCC('V', 'C', 'R', '1'): + /* Video in ATI VCR1 format */ + this->avi->video_type = BUF_VIDEO_ATIVCR1; + break; + case mmioFOURCC('V', 'C', 'R', '2'): + /* Video in ATI VCR2 format */ + this->avi->video_type = BUF_VIDEO_ATIVCR2; + break; + case mmioFOURCC('I', '2', '6', '3'): + case mmioFOURCC('i', '2', '6', '3'): + /* Video in I263 format */ + this->avi->video_type = BUF_VIDEO_I263; + break; + default: + this->avi->video_type = BUF_VIDEO_AVI; + break; + } + buf->type = this->avi->video_type; + this->video_fifo->put (this->video_fifo, buf); if(this->audio_fifo) { @@ -979,24 +984,25 @@ static void demux_avi_start (demux_plugin_t *this_gen, buf->size = sizeof (this->avi->wavex); switch (this->avi->a_fmt) { case 0x01: - buf->type = BUF_AUDIO_LPCM; + this->avi->audio_type = BUF_AUDIO_LPCM; break; case 0x2000: - buf->type = BUF_AUDIO_AC3; + this->avi->audio_type = BUF_AUDIO_A52; break; case 0x50: case 0x55: - buf->type = BUF_AUDIO_MPEG; + this->avi->audio_type = BUF_AUDIO_MPEG; break; case 0x161: - buf->type = BUF_AUDIO_AVI; + this->avi->audio_type = BUF_AUDIO_AVI; break; default: printf ("demux_avi: unknown audio type 0x%lx =>exit\n", this->avi->a_fmt); this->status = DEMUX_FINISHED; - buf->type = BUF_AUDIO_MPEG; + this->avi->audio_type = BUF_AUDIO_MPEG; break; } + buf->type = this->avi->audio_type; buf->decoder_info[0] = 0; /* first package, containing wavex */ this->audio_fifo->put (this->audio_fifo, buf); } diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c index b895ea109..1096f310c 100644 --- a/src/demuxers/demux_mpeg.c +++ b/src/demuxers/demux_mpeg.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpeg.c,v 1.30 2001/08/18 23:30:51 guenter Exp $ + * $Id: demux_mpeg.c,v 1.31 2001/08/28 19:16:19 guenter Exp $ * * demultiplexer for mpeg 1/2 program streams * reads streams of variable blocksizes @@ -166,7 +166,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int nID) { this->status = DEMUX_FINISHED; return ; } - buf->type = BUF_AUDIO_AC3 + track; + buf->type = BUF_AUDIO_A52 + track; buf->PTS = pts; buf->DTS = 0 ; /* FIXME */ if (this->preview_mode) diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index 57e595eb4..61787fb8c 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpeg_block.c,v 1.31 2001/08/18 23:30:51 guenter Exp $ + * $Id: demux_mpeg_block.c,v 1.32 2001/08/28 19:16:19 guenter Exp $ * * demultiplexer for mpeg 1/2 program streams * @@ -285,7 +285,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m buf->content = p+4; buf->size = nPacketLen-4; - buf->type = BUF_AUDIO_AC3 + nTrack; + buf->type = BUF_AUDIO_A52 + nTrack; buf->PTS = nPTS; buf->DTS = nDTS ; buf->input_pos = this->input->get_current_pos(this->input); diff --git a/src/demuxers/demux_pes.c b/src/demuxers/demux_pes.c index 48dcad246..419b0a3fa 100644 --- a/src/demuxers/demux_pes.c +++ b/src/demuxers/demux_pes.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_pes.c,v 1.4 2001/08/20 11:17:20 joachim_koenig Exp $ + * $Id: demux_pes.c,v 1.5 2001/08/28 19:16:19 guenter Exp $ * * demultiplexer for mpeg 2 PES (Packetized Elementary Streams) * reads streams of variable blocksizes @@ -165,7 +165,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int nID) { this->status = DEMUX_FINISHED; return ; } - buf->type = BUF_AUDIO_AC3 + track; + buf->type = BUF_AUDIO_A52 + track; buf->PTS = pts; buf->DTS = 0 ; /* FIXME */ if (this->preview_mode) @@ -354,7 +354,7 @@ static void *demux_mpeg_loop (void *this_gen) { } static void demux_mpeg_stop (demux_plugin_t *this_gen) { - void *p; + demux_mpeg_t *this = (demux_mpeg_t *) this_gen; buf_element_t *buf; diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 7881fd6e9..e97549cbd 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_ts.c,v 1.7 2001/08/20 22:56:36 jcdutton Exp $ + * $Id: demux_ts.c,v 1.8 2001/08/28 19:16:19 guenter Exp $ * * Demultiplexer for MPEG2 Transport Streams. * @@ -840,7 +840,7 @@ static void demux_ts_queue_pes( buf->content = p+4; buf->size = nPacketLen-4; - buf->type = BUF_AUDIO_AC3; + buf->type = BUF_AUDIO_A52; buf->PTS = nPTS; buf->DTS = nDTS ; buf->input_pos = this->input->seek(this->input, 0, SEEK_CUR); diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c index 6bd357f04..7b7ee8794 100644 --- a/src/libac3/xine_decoder.c +++ b/src/libac3/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.23 2001/08/21 19:39:50 jcdutton Exp $ + * $Id: xine_decoder.c,v 1.24 2001/08/28 19:16:19 guenter Exp $ * * stuff needed to turn libac3 into a xine decoder plugin */ @@ -79,7 +79,7 @@ typedef struct ac3dec_decoder_s { } ac3dec_decoder_t; int ac3dec_can_handle (audio_decoder_t *this_gen, int buf_type) { - return ((buf_type & 0xFFFF0000) == BUF_AUDIO_AC3) ; + return ((buf_type & 0xFFFF0000) == BUF_AUDIO_A52) ; } diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h index fe7855740..5155c8fd2 100644 --- a/src/libffmpeg/libavcodec/avcodec.h +++ b/src/libffmpeg/libavcodec/avcodec.h @@ -8,7 +8,7 @@ enum CodecID { CODEC_ID_MP2, CODEC_ID_AC3, CODEC_ID_MJPEG, - CODEC_ID_OPENDIVX, + CODEC_ID_MPEG4, CODEC_ID_PCM, CODEC_ID_RAWVIDEO, CODEC_ID_MSMPEG4, @@ -45,6 +45,11 @@ extern int motion_estimation_method; #define CODEC_FLAG_HQ 0x0001 /* high quality (non real time) encoding */ #define CODEC_FLAG_QSCALE 0x0002 /* use fixed qscale */ +/* codec capabilities */ + +/* decoder can use draw_horiz_band callback */ +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 + #define FRAME_RATE_BASE 10000 typedef struct AVCodecContext { @@ -57,6 +62,15 @@ typedef struct AVCodecContext { int width, height; int gop_size; /* 0 = intra only */ int pix_fmt; /* pixel format, see PIX_FMT_xxx */ + + /* if non NULL, 'draw_horiz_band' is called by the libavcodec + decoder to draw an horizontal band. It improve cache usage. Not + all codecs can do that. You must check the codec capabilities + before */ + void (*draw_horiz_band)(struct AVCodecContext *s, + UINT8 **src_ptr, int linesize, + int y, int width, int height); + /* audio only */ int sample_rate; /* samples per sec */ int channels; @@ -72,6 +86,7 @@ typedef struct AVCodecContext { void *priv_data; /* the following fields are ignored */ + void *opaque; /* can be used to carry app specific stuff */ char codec_name[32]; int codec_type; /* see CODEC_TYPE_xxx */ int codec_id; /* see CODEC_ID_xxx */ @@ -88,6 +103,7 @@ typedef struct AVCodec { int (*close)(AVCodecContext *); int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, UINT8 *buf, int buf_size); + int capabilities; struct AVCodec *next; } AVCodec; @@ -104,11 +120,11 @@ extern AVCodec h263_encoder; extern AVCodec h263p_encoder; extern AVCodec rv10_encoder; extern AVCodec mjpeg_encoder; -extern AVCodec opendivx_encoder; +extern AVCodec mpeg4_encoder; extern AVCodec msmpeg4_encoder; extern AVCodec h263_decoder; -extern AVCodec opendivx_decoder; +extern AVCodec mpeg4_decoder; extern AVCodec msmpeg4_decoder; extern AVCodec mpeg_decoder; extern AVCodec h263i_decoder; @@ -147,7 +163,17 @@ void img_resample(ImgReSampleContext *s, void img_resample_close(ImgReSampleContext *s); -int img_convert_to_yuv420(UINT8 *img_out, UINT8 *img, +void avpicture_fill(AVPicture *picture, UINT8 *ptr, + int pix_fmt, int width, int height); +int avpicture_get_size(int pix_fmt, int width, int height); + +/* convert among pixel formats */ +int img_convert(AVPicture *dst, int dst_pix_fmt, + AVPicture *src, int pix_fmt, + int width, int height); + +/* deinterlace a picture */ +int avpicture_deinterlace(AVPicture *dst, AVPicture *src, int pix_fmt, int width, int height); /* external high level API */ diff --git a/src/libffmpeg/libavcodec/common.c b/src/libffmpeg/libavcodec/common.c index 77b6d85d2..b3ce07c05 100644 --- a/src/libffmpeg/libavcodec/common.c +++ b/src/libffmpeg/libavcodec/common.c @@ -16,20 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#ifdef __FreeBSD__ -#include -#endif -#include -#include #include "common.h" - -#define NDEBUG -#include - -#include "xine-engine/bswap.h" +#include void init_put_bits(PutBitContext *s, UINT8 *buffer, int buffer_size, @@ -79,7 +67,7 @@ void put_bits(PutBitContext *s, int n, unsigned int value) bit_cnt+=n; } else { bit_buf |= value >> (n + bit_cnt - 32); - *(UINT32 *)s->buf_ptr = htonl(bit_buf); + *(UINT32 *)s->buf_ptr = be2me_32(bit_buf); //printf("bitbuf = %08x\n", bit_buf); s->buf_ptr+=4; if (s->buf_ptr >= s->buf_end) @@ -97,9 +85,9 @@ void put_bits(PutBitContext *s, int n, unsigned int value) } /* return the number of bits output */ -long long get_bit_count(PutBitContext *s) +INT64 get_bit_count(PutBitContext *s) { - return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (long long)s->bit_cnt; + return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (INT64)s->bit_cnt; } void align_put_bits(PutBitContext *s) diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h index 75908245c..aeb9ab52b 100644 --- a/src/libffmpeg/libavcodec/common.h +++ b/src/libffmpeg/libavcodec/common.h @@ -1,10 +1,87 @@ #ifndef COMMON_H #define COMMON_H +#define FFMPEG_VERSION_INT 0x000405 +#define FFMPEG_VERSION "0.4.5" + +#ifdef WIN32 +#define CONFIG_WIN32 +#endif + #ifdef HAVE_AV_CONFIG_H +/* only include the following when compiling package */ #include "../config.h" + +#include +#include +#include +#include + +#ifndef ENODATA +#define ENODATA 61 +#endif + +#endif + +#ifdef CONFIG_WIN32 + +/* windows */ + +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned char UINT8; +typedef unsigned int UINT32; +typedef unsigned __int64 UINT64; +typedef signed char INT8; +typedef signed int INT32; +typedef signed __int64 INT64; + +typedef UINT8 uint8_t; +typedef INT8 int8_t; +typedef UINT16 uint16_t; +typedef INT16 int16_t; +typedef UINT32 uint32_t; +typedef INT32 int32_t; + +#define INT64_C(c) (c ## i64) +#define UINT64_C(c) (c ## i64) + +#define inline __inline + +/* + Disable warning messages: + warning C4244: '=' : conversion from 'double' to 'float', possible loss of data + warning C4305: 'argument' : truncation from 'const double' to 'float' +*/ +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) + +#define M_PI 3.14159265358979323846 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ + +#ifdef _DEBUG +#define DEBUG #endif +// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc. +#define bswap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#define be2me_32(x) bswap_32(x) + +#define snprintf _snprintf + +#define CONFIG_ENCODERS 1 +#define CONFIG_DECODERS 1 +#define CONFIG_AC3 1 +#define CONFIG_MPGLIB 1 + +#else + +/* unix */ + +#include + #ifndef __WINE_WINDEF16_H /* workaround for typedef conflict in MPlayer (wine typedefs) */ typedef unsigned short UINT16; @@ -18,6 +95,32 @@ typedef signed char INT8; typedef signed int INT32; typedef signed long long INT64; +#ifdef HAVE_AV_CONFIG_H + +#ifdef __FreeBSD__ +#include +#endif + +#ifndef INT64_C +#define INT64_C(c) (c ## LL) +#define UINT64_C(c) (c ## ULL) +#endif + +#include "xine-engine/bswap.h" + +#ifdef USE_FASTMEMCPY +#include "fastmemcpy.h" +#endif + +#ifndef DEBUG +#define NDEBUG +#endif +#include + +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* !CONFIG_WIN32 */ + /* bit output */ struct PutBitContext; @@ -28,7 +131,7 @@ typedef struct PutBitContext { UINT32 bit_buf; int bit_cnt; UINT8 *buf, *buf_ptr, *buf_end; - long long data_out_size; /* in bytes */ + INT64 data_out_size; /* in bytes */ void *opaque; WriteDataFunc write_data; } PutBitContext; @@ -38,7 +141,7 @@ void init_put_bits(PutBitContext *s, void *opaque, void (*write_data)(void *, UINT8 *, int)); void put_bits(PutBitContext *s, int n, unsigned int value); -long long get_bit_count(PutBitContext *s); +INT64 get_bit_count(PutBitContext *s); void align_put_bits(PutBitContext *s); void flush_put_bits(PutBitContext *s); @@ -195,7 +298,7 @@ void print_stats(void); /* misc math functions */ -extern inline int log2(unsigned int v) +extern inline int av_log2(unsigned int v) { int n; diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c index 96072db67..abbca19da 100644 --- a/src/libffmpeg/libavcodec/dsputil.c +++ b/src/libffmpeg/libavcodec/dsputil.c @@ -31,7 +31,7 @@ op_pixels_abs_func pix_abs16x16_x2; op_pixels_abs_func pix_abs16x16_y2; op_pixels_abs_func pix_abs16x16_xy2; -static UINT8 cropTbl[256 + 2 * MAX_NEG_CROP]; +UINT8 cropTbl[256 + 2 * MAX_NEG_CROP]; UINT32 squareTbl[512]; extern UINT16 default_intra_matrix[64]; @@ -447,10 +447,10 @@ void dsputil_init(void) block_permute(default_intra_matrix); block_permute(default_non_intra_matrix); -#ifndef DEBUG #ifdef HAVE_MMX - printf ("ffmpeg: init mmx\n"); dsputil_init_mmx(); #endif +#ifdef ARCH_ARMV4L + dsputil_init_armv4l(); #endif } diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h index ebb4d8446..80a934ccd 100644 --- a/src/libffmpeg/libavcodec/dsputil.h +++ b/src/libffmpeg/libavcodec/dsputil.h @@ -2,7 +2,6 @@ #define DSPUTIL_H #include "common.h" -#include /* dct code */ typedef short DCTELEM; @@ -25,6 +24,7 @@ extern UINT8 zigzag_direct[64]; /* temporary */ extern UINT32 squareTbl[512]; +extern UINT8 cropTbl[256 + 2 * MAX_NEG_CROP]; void dsputil_init(void); @@ -74,7 +74,7 @@ static inline int block_permute_op(int j) void block_permute(INT16 *block); -#ifdef HAVE_MMX +#if defined(HAVE_MMX) #define MM_MMX 0x0001 /* standard MMX */ #define MM_3DNOW 0x0004 /* AMD 3DNOW */ @@ -101,6 +101,16 @@ static inline void emms(void) void dsputil_init_mmx(void); +#elif defined(ARCH_ARMV4L) + +#define emms_c() + +/* This is to use 4 bytes read to the IDCT pointers for some 'zero' + line ptimizations */ +#define __align8 __attribute__ ((aligned (4))) + +void dsputil_init_armv4l(void); + #else #define emms_c() diff --git a/src/libffmpeg/libavcodec/dsputil_mmx.c b/src/libffmpeg/libavcodec/dsputil_mmx.c index 4261259e5..29a069566 100644 --- a/src/libffmpeg/libavcodec/dsputil_mmx.c +++ b/src/libffmpeg/libavcodec/dsputil_mmx.c @@ -22,8 +22,6 @@ #include "dsputil.h" #include "cpu_accel.h" -#ifndef DEBUG - int mm_flags; /* multimedia extension flags */ int pix_abs16x16_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h); @@ -1055,4 +1053,3 @@ void dsputil_init_mmx(void) } } } -#endif /* DEBUG */ diff --git a/src/libffmpeg/libavcodec/dsputil_mmx_avg.h b/src/libffmpeg/libavcodec/dsputil_mmx_avg.h index 81b9fd482..5cd640f71 100644 --- a/src/libffmpeg/libavcodec/dsputil_mmx_avg.h +++ b/src/libffmpeg/libavcodec/dsputil_mmx_avg.h @@ -19,10 +19,6 @@ * MMX optimization by Nick Kurshev */ -#include "config.h" - -#ifndef DEBUG - static void DEF(put_pixels_x2)(UINT8 *block, const UINT8 *pixels, int line_size, int h) { int dh, hh; @@ -346,4 +342,3 @@ static void DEF(sub_pixels_y2)( DCTELEM *block, const UINT8 *pixels, int line_s } while (--h); } -#endif diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c index 73355a6ed..12f14db04 100644 --- a/src/libffmpeg/libavcodec/h263.c +++ b/src/libffmpeg/libavcodec/h263.c @@ -18,9 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include #include "common.h" #include "dsputil.h" #include "avcodec.h" @@ -28,9 +25,6 @@ #include "h263data.h" #include "mpeg4data.h" -#define NDEBUG -#include - static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n); static void h263_encode_motion(MpegEncContext * s, int val); @@ -1166,43 +1160,66 @@ int mpeg4_decode_picture_header(MpegEncContext * s) } if (startcode == 0x120) { - int time_increment_resolution, width, height; + int time_increment_resolution, width, height, vo_ver_id; /* vol header */ skip_bits(&s->gb, 1); /* random access */ skip_bits(&s->gb, 8); /* vo_type */ - skip_bits(&s->gb, 1); /* is_ol_id */ - skip_bits(&s->gb, 4); /* vo_ver_id */ - skip_bits(&s->gb, 3); /* vo_priority */ + if (get_bits1(&s->gb) != 0) { /* is_ol_id */ + vo_ver_id = get_bits(&s->gb, 4); /* vo_ver_id */ + skip_bits(&s->gb, 3); /* vo_priority */ + } else { + vo_ver_id = 1; + } skip_bits(&s->gb, 4); /* aspect_ratio_info */ - skip_bits(&s->gb, 1); /* vol control parameter */ - skip_bits(&s->gb, 2); /* vol shape */ + skip_bits1(&s->gb); /* vol control parameter */ + s->shape = get_bits(&s->gb, 2); /* vol shape */ skip_bits1(&s->gb); /* marker */ time_increment_resolution = get_bits(&s->gb, 16); - s->time_increment_bits = log2(time_increment_resolution - 1) + 1; + s->time_increment_bits = av_log2(time_increment_resolution - 1) + 1; + if (s->time_increment_bits < 1) + s->time_increment_bits = 1; skip_bits1(&s->gb); /* marker */ - skip_bits1(&s->gb); /* vop rate */ - skip_bits(&s->gb, s->time_increment_bits); - skip_bits1(&s->gb); /* marker */ - - width = get_bits(&s->gb, 13); - skip_bits1(&s->gb); /* marker */ - height = get_bits(&s->gb, 13); - skip_bits1(&s->gb); /* marker */ - - skip_bits1(&s->gb); /* interfaced */ - skip_bits1(&s->gb); /* OBMC */ - skip_bits(&s->gb, 2); /* vol_sprite_usage */ - skip_bits1(&s->gb); /* not_8_bit */ - - skip_bits1(&s->gb); /* vol_quant_type */ - skip_bits1(&s->gb); /* vol_quarter_pixel */ - skip_bits1(&s->gb); /* complexity_estimation_disabled */ - skip_bits1(&s->gb); /* resync_marker_disabled */ - skip_bits1(&s->gb); /* data_partioning_enabled */ + if (get_bits1(&s->gb) != 0) { /* fixed_vop_rate */ + skip_bits(&s->gb, s->time_increment_bits); + } + + if (s->shape != 2) { + if (s->shape == 0) { + skip_bits1(&s->gb); /* marker */ + width = get_bits(&s->gb, 13); + skip_bits1(&s->gb); /* marker */ + height = get_bits(&s->gb, 13); + skip_bits1(&s->gb); /* marker */ + } + + skip_bits1(&s->gb); /* interlaced */ + skip_bits1(&s->gb); /* OBMC */ + if (vo_ver_id == 1) { + s->vol_sprite_usage = get_bits1(&s->gb); /* vol_sprite_usage */ + } else { + s->vol_sprite_usage = get_bits(&s->gb, 2); /* vol_sprite_usage */ + } + if (get_bits1(&s->gb) == 1) { /* not_8_bit */ + s->quant_precision = get_bits(&s->gb, 4); /* quant_precision */ + skip_bits(&s->gb, 4); /* bits_per_pixel */ + } else { + s->quant_precision = 5; + } + + skip_bits1(&s->gb); /* vol_quant_type */ + skip_bits1(&s->gb); /* vol_quarter_pixel */ + skip_bits1(&s->gb); /* complexity_estimation_disabled */ + skip_bits1(&s->gb); /* resync_marker_disabled */ + skip_bits1(&s->gb); /* data_partioning_enabled */ + if (get_bits1(&s->gb) != 0) { /* scalability */ + printf("bad scalability!!!\n"); + return -1; + } + } goto redo; } else if (startcode != 0x1b6) { goto redo; @@ -1223,22 +1240,50 @@ int mpeg4_decode_picture_header(MpegEncContext * s) skip_bits1(&s->gb); /* marker */ /* vop coded */ if (get_bits1(&s->gb) != 1) - return -1; + goto redo; - if (s->pict_type == P_TYPE) { + if (s->shape != 2 && s->pict_type == P_TYPE) { /* rounding type for motion estimation */ s->no_rounding = get_bits1(&s->gb); + } else { + s->no_rounding = 0; } - - if (get_bits(&s->gb, 3) != 0) - return -1; /* intra dc VLC threshold */ - - s->qscale = get_bits(&s->gb, 5); - - if (s->pict_type != I_TYPE) { - s->f_code = get_bits(&s->gb, 3); /* fcode_for */ - } - return 0; + + if (s->shape != 0) { + if (s->vol_sprite_usage != 1 || s->pict_type != I_TYPE) { + int width, height, hor_spat_ref, ver_spat_ref; + + width = get_bits(&s->gb, 13); + skip_bits1(&s->gb); /* marker */ + height = get_bits(&s->gb, 13); + skip_bits1(&s->gb); /* marker */ + hor_spat_ref = get_bits(&s->gb, 13); /* hor_spat_ref */ + skip_bits1(&s->gb); /* marker */ + ver_spat_ref = get_bits(&s->gb, 13); /* ver_spat_ref */ + } + skip_bits1(&s->gb); /* change_CR_disable */ + + if (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); /* constant_alpha_value */ + } + } + + if (s->shape != 2) { + skip_bits(&s->gb, 3); /* intra dc VLC threshold */ + + /* note: we do not use quant_precision to avoid problem if no + MPEG4 vol header as it is found on some old opendivx + movies */ + s->qscale = get_bits(&s->gb, 5); + + if (s->pict_type != I_TYPE) { + s->f_code = get_bits(&s->gb, 3); /* fcode_for */ + } + if (s->shape && (s->pict_type != I_TYPE)) { + skip_bits1(&s->gb); // vop shape coding type + } + } + return 0; } /* don't understand why they choose a different header ! */ diff --git a/src/libffmpeg/libavcodec/h263dec.c b/src/libffmpeg/libavcodec/h263dec.c index 24b4288e7..758f9ed52 100644 --- a/src/libffmpeg/libavcodec/h263dec.c +++ b/src/libffmpeg/libavcodec/h263dec.c @@ -23,10 +23,14 @@ #include "avcodec.h" #include "mpegvideo.h" +#undef DEBUG + static int h263_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - + int i; + + s->avctx = avctx; s->out_format = FMT_H263; s->width = avctx->width; @@ -36,7 +40,7 @@ static int h263_decode_init(AVCodecContext *avctx) switch(avctx->codec->id) { case CODEC_ID_H263: break; - case CODEC_ID_OPENDIVX: + case CODEC_ID_MPEG4: s->time_increment_bits = 4; /* default value for broken headers */ s->h263_pred = 1; break; @@ -55,6 +59,11 @@ static int h263_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; + /* XXX: suppress this matrix init, only needed because using mpeg1 + dequantize in mmx case */ + for(i=0;i<64;i++) + s->non_intra_matrix[i] = default_non_intra_matrix[i]; + if (s->h263_msmpeg4) msmpeg4_decode_init_vlc(s); else @@ -79,7 +88,7 @@ static int h263_decode_frame(AVCodecContext *avctx, int ret; AVPicture *pict = data; -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); #endif @@ -105,21 +114,17 @@ static int h263_decode_frame(AVCodecContext *avctx, if (ret < 0) return -1; - /* make sure we start with an I-Frame */ - if (!s->slice_height && (s->pict_type != I_TYPE)) - return -1; - MPV_frame_start(s); -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("qscale=%d\n", s->qscale); #endif /* decode each macroblock */ for(s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) { for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { -#ifdef DEBUG_PRINTS - printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); +#ifdef DEBUG + printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); #endif /* DCT & quantize */ if (s->h263_msmpeg4) { @@ -144,6 +149,20 @@ static int h263_decode_frame(AVCodecContext *avctx, } MPV_decode_mb(s, s->block); } + if (avctx->draw_horiz_band) { + UINT8 *src_ptr[3]; + int y, h, offset; + y = s->mb_y * 16; + h = s->height - y; + if (h > 16) + h = 16; + offset = y * s->linesize; + src_ptr[0] = s->current_picture[0] + offset; + src_ptr[1] = s->current_picture[1] + (offset >> 2); + src_ptr[2] = s->current_picture[2] + (offset >> 2); + avctx->draw_horiz_band(avctx, src_ptr, s->linesize, + y, s->width, h); + } } MPV_frame_end(s); @@ -160,15 +179,16 @@ static int h263_decode_frame(AVCodecContext *avctx, return buf_size; } -AVCodec opendivx_decoder = { - "opendivx", +AVCodec mpeg4_decoder = { + "mpeg4", CODEC_TYPE_VIDEO, - CODEC_ID_OPENDIVX, + CODEC_ID_MPEG4, sizeof(MpegEncContext), h263_decode_init, NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; AVCodec h263_decoder = { @@ -180,6 +200,7 @@ AVCodec h263_decoder = { NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; AVCodec msmpeg4_decoder = { @@ -191,6 +212,7 @@ AVCodec msmpeg4_decoder = { NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; AVCodec h263i_decoder = { @@ -202,5 +224,6 @@ AVCodec h263i_decoder = { NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; diff --git a/src/libffmpeg/libavcodec/idct_mmx.c b/src/libffmpeg/libavcodec/idct_mmx.c index d004481b1..34c25b411 100644 --- a/src/libffmpeg/libavcodec/idct_mmx.c +++ b/src/libffmpeg/libavcodec/idct_mmx.c @@ -24,7 +24,7 @@ #include -#include "config.h" +#include "../config.h" #include "cpu_accel.h" diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c index df7415b81..1103e11d0 100644 --- a/src/libffmpeg/libavcodec/mjpeg.c +++ b/src/libffmpeg/libavcodec/mjpeg.c @@ -16,8 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -423,12 +421,20 @@ void mjpeg_encode_mb(MpegEncContext *s, //#define DEBUG +#ifndef CONFIG_WIN32 + #ifdef DEBUG #define dprintf(fmt,args...) printf(fmt, ## args) #else #define dprintf(fmt,args...) #endif +#else + +inline void dprintf(const char* fmt,...) {} + +#endif + /* compressed picture size */ #define PICTURE_BUFFER_SIZE 100000 @@ -443,6 +449,12 @@ typedef struct MJpegDecodeContext { int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ INT16 quant_matrixes[4][64]; VLC vlcs[2][4]; + + int org_width, org_height; /* size given at codec init */ + int first_picture; /* true if decoding first picture */ + int interlaced; /* true if interlaced */ + int bottom_field; /* true if bottom field */ + int width, height; int nb_components; int component_id[MAX_COMPONENTS]; @@ -479,6 +491,9 @@ static int mjpeg_decode_init(AVCodecContext *avctx) account FF 00 case */ s->start_code = -1; s->buf_ptr = s->buffer; + s->first_picture = 1; + s->org_width = avctx->width; + s->org_height = avctx->height; build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12); build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12); @@ -611,6 +626,14 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, } s->width = width; s->height = height; + /* test interlaced mode */ + if (s->first_picture && + s->org_height != 0 && + s->height < ((s->org_height * 3) / 4)) { + s->interlaced = 1; + s->bottom_field = 0; + } + for(i=0;ih_max / s->h_count[i]; @@ -619,12 +642,15 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, h = (s->height + 8 * vv - 1) / (8 * vv); w = w * 8; h = h * 8; + if (s->interlaced) + w *= 2; s->linesize[i] = w; /* memory test is done in mjpeg_decode_sos() */ s->current_picture[i] = av_mallocz(w * h); } + s->first_picture = 0; } - + return 0; } @@ -704,7 +730,7 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block, static int mjpeg_decode_sos(MJpegDecodeContext *s, UINT8 *buf, int buf_size) { - int len, nb_components, i, j, n, h, v; + int len, nb_components, i, j, n, h, v, ret; int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id; int comp_index[4]; int dc_index[4]; @@ -781,12 +807,15 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, dc_index[i], ac_index[i], s->quant_index[c]) < 0) { dprintf("error %d %d\n", mb_y, mb_x); - return -1; + ret = -1; + goto the_end; } ff_idct (s->block); ptr = s->current_picture[c] + (s->linesize[c] * (v * mb_y + y) * 8) + (h * mb_x + x) * 8; + if (s->interlaced && s->bottom_field) + ptr += s->linesize[c] >> 1; put_pixels_clamped(s->block, ptr, s->linesize[c]); if (++x == h) { x = 0; @@ -796,7 +825,10 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, } } } - return 0; + ret = 0; + the_end: + emms_c(); + return ret; } /* return the 8 bit start code value and update the search @@ -843,11 +875,11 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, int len, code, start_code, input_size, i; AVPicture *picture = data; + *data_size = 0; + /* no supplementary picture */ - if (buf_size == 0) { - *data_size = 0; + if (buf_size == 0) return 0; - } buf_ptr = buf; buf_end = buf + buf_size; @@ -874,6 +906,7 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, start_code = s->start_code; s->buf_ptr = s->buffer; s->start_code = code; + dprintf("marker=%x\n", start_code); switch(start_code) { case SOI: /* nothing to do on SOI */ @@ -890,12 +923,24 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, case SOS: mjpeg_decode_sos(s, s->buffer, input_size); if (s->start_code == EOI) { + int l; + if (s->interlaced) { + s->bottom_field ^= 1; + /* if not bottom field, do not output image yet */ + if (s->bottom_field) + goto the_end; + } for(i=0;i<3;i++) { picture->data[i] = s->current_picture[i]; - picture->linesize[i] = s->linesize[i]; + l = s->linesize[i]; + if (s->interlaced) + l >>= 1; + picture->linesize[i] = l; } *data_size = sizeof(AVPicture); avctx->height = s->height; + if (s->interlaced) + avctx->height *= 2; avctx->width = s->width; /* XXX: not complete test ! */ switch((s->h_count[0] << 4) | s->v_count[0]) { @@ -910,6 +955,9 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, avctx->pix_fmt = PIX_FMT_YUV420P; break; } + /* dummy quality */ + /* XXX: infer it with matrix */ + avctx->quality = 3; goto the_end; } break; diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c index 44fdfc0b4..f0aecd980 100644 --- a/src/libffmpeg/libavcodec/mpeg12.c +++ b/src/libffmpeg/libavcodec/mpeg12.c @@ -16,26 +16,28 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" #include "mpeg12data.h" -#ifdef USE_FASTMEMCPY -#include "fastmemcpy.h" -#endif -//#define DEBUG_PRINTS +//#define DEBUG + +#ifndef CONFIG_WIN32 -#ifdef DEBUG_PRINTS +#ifdef DEBUG #define dprintf(fmt,args...) printf(fmt, ## args) #else #define dprintf(fmt,args...) #endif +#else + +inline void dprintf(const char* fmt,...) {} + +#endif + /* Start codes. */ #define SEQ_END_CODE 0x000001b7 #define SEQ_START_CODE 0x000001b3 @@ -118,11 +120,11 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) fps = frame_rate_tab[s->frame_rate_index]; time_code = s->fake_picture_number * FRAME_RATE_BASE; s->gop_picture_number = s->fake_picture_number; - put_bits(&s->pb, 5, (time_code / (fps * 3600)) % 24); - put_bits(&s->pb, 6, (time_code / (fps * 60)) % 60); + put_bits(&s->pb, 5, (UINT32)((time_code / (fps * 3600)) % 24)); + put_bits(&s->pb, 6, (UINT32)((time_code / (fps * 60)) % 60)); put_bits(&s->pb, 1, 1); - put_bits(&s->pb, 6, (time_code / fps) % 60); - put_bits(&s->pb, 6, (time_code % fps) / FRAME_RATE_BASE); + put_bits(&s->pb, 6, (UINT32)((time_code / fps) % 60)); + put_bits(&s->pb, 6, (UINT32)((time_code % fps) / FRAME_RATE_BASE)); put_bits(&s->pb, 1, 1); /* closed gop */ put_bits(&s->pb, 1, 0); /* broken link */ } @@ -456,7 +458,7 @@ void mpeg1_init_vlc(MpegEncContext *s) init_vlc(&mv_vlc, 9, 17, &mbMotionVectorTable[0][1], 2, 1, &mbMotionVectorTable[0][0], 2, 1); - init_vlc(&mbincr_vlc, 9, 34, + init_vlc(&mbincr_vlc, 9, 35, &mbAddrIncrTable[0][1], 2, 1, &mbAddrIncrTable[0][0], 2, 1); init_vlc(&mb_pat_vlc, 9, 63, @@ -489,6 +491,22 @@ static inline int get_dmv(MpegEncContext *s) return 0; } +static inline int get_qscale(MpegEncContext *s) +{ + int qscale; + if (s->mpeg2) { + if (s->q_scale_type) { + qscale = non_linear_qscale[get_bits(&s->gb, 5)]; + } else { + qscale = get_bits(&s->gb, 5) << 1; + } + } else { + /* for mpeg1, we use the generic unquant code */ + qscale = get_bits(&s->gb, 5); + } + return qscale; +} + /* motion type (for mpeg2) */ #define MT_FIELD 1 #define MT_FRAME 2 @@ -538,6 +556,7 @@ static int mpeg_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; s->mv[0][0][0] = s->mv[0][0][1] = 0; s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; + s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; } else { /* if B type, reuse previous vectors and directions */ s->mv[0][0][0] = s->last_mv[0][0][0]; @@ -585,7 +604,7 @@ static int mpeg_decode_mb(MpegEncContext *s, !s->frame_pred_frame_dct && (mb_type & (MB_PAT | MB_INTRA))) { s->interlaced_dct = get_bits1(&s->gb); -#ifdef DEBUG_PRINTS +#ifdef DEBUG if (s->interlaced_dct) printf("interlaced_dct\n"); #endif @@ -594,16 +613,7 @@ static int mpeg_decode_mb(MpegEncContext *s, } if (mb_type & MB_QUANT) { - if (s->mpeg2) { - if (s->q_scale_type) { - s->qscale = non_linear_qscale[get_bits(&s->gb, 5)]; - } else { - s->qscale = get_bits(&s->gb, 5) << 1; - } - } else { - /* for mpeg1, we use the generic unquant code */ - s->qscale = get_bits(&s->gb, 5); - } + s->qscale = get_qscale(s); } if (mb_type & MB_INTRA) { if (s->concealment_motion_vectors) { @@ -626,6 +636,8 @@ static int mpeg_decode_mb(MpegEncContext *s, s->mv_type = MV_TYPE_16X16; s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; + s->last_mv[0][1][0] = 0; + s->last_mv[0][1][1] = 0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; } else if (mb_type & (MB_FOR | MB_BACK)) { @@ -634,7 +646,7 @@ static int mpeg_decode_mb(MpegEncContext *s, for(i=0;i<2;i++) { if (mb_type & (MB_FOR >> i)) { s->mv_dir |= (MV_DIR_FORWARD >> i); - dprintf("mv_type=%d\n", motion_type); + dprintf("motion_type=%d\n", motion_type); switch(motion_type) { case MT_FRAME: /* or MT_16X8 */ if (s->picture_structure == PICT_FRAME) { @@ -972,7 +984,13 @@ static int mpeg2_decode_block_non_intra(MpegEncContext *s, add_coef: j = scan_table[i]; dprintf("%d: run=%d level=%d\n", n, run, level); - level = ((level * 2 + 1) * s->qscale * matrix[j]) / 32; + /* XXX: optimize */ + if (level > 0) { + level = ((level * 2 + 1) * s->qscale * matrix[j]) >> 5; + } else { + level = ((-level * 2 + 1) * s->qscale * matrix[j]) >> 5; + level = -level; + } /* XXX: is it really necessary to saturate since the encoder knows whats going on ? */ mismatch ^= level; @@ -999,7 +1017,6 @@ static int mpeg2_decode_block_intra(MpegEncContext *s, scan_table = ff_alternate_vertical_scan; else scan_table = zigzag_direct; - mismatch = 1; /* DC coef */ component = (n <= 3 ? 0 : n - 4 + 1); @@ -1011,6 +1028,7 @@ static int mpeg2_decode_block_intra(MpegEncContext *s, s->last_dc[component] = dc; block[0] = dc << (3 - s->intra_dc_precision); dprintf("dc=%d\n", block[0]); + mismatch = block[0] ^ 1; i = 1; if (s->intra_vlc_format) rl = &rl_mpeg2; @@ -1020,7 +1038,7 @@ static int mpeg2_decode_block_intra(MpegEncContext *s, matrix = s->intra_matrix; else matrix = s->chroma_intra_matrix; - + /* now quantify & encode AC coefs */ for(;;) { code = get_vlc(&s->gb, &rl->vlc); @@ -1120,7 +1138,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, ref = get_bits(&s->gb, 10); /* temporal ref */ s->pict_type = get_bits(&s->gb, 3); - dprintf("pict_type=%d\n", s->pict_type); + dprintf("pict_type=%d number=%d\n", s->pict_type, s->picture_number); skip_bits(&s->gb, 16); if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { s->full_pel[0] = get_bits1(&s->gb); @@ -1174,10 +1192,12 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) { int i, v, j; + dprintf("matrix extension\n"); + if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); - j = block_permute_op(i); + j = zigzag_direct[i]; s->intra_matrix[j] = v; s->chroma_intra_matrix[j] = v; } @@ -1185,7 +1205,7 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); - j = block_permute_op(i); + j = zigzag_direct[i]; s->non_intra_matrix[j] = v; s->chroma_non_intra_matrix[j] = v; } @@ -1193,14 +1213,14 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); - j = block_permute_op(i); + j = zigzag_direct[i]; s->chroma_intra_matrix[j] = v; } } if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); - j = block_permute_op(i); + j = zigzag_direct[i]; s->chroma_non_intra_matrix[j] = v; } } @@ -1225,10 +1245,11 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) s->chroma_420_type = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb); /* composite display not parsed */ - dprintf("dc_preci=%d\n", s->intra_dc_precision); - dprintf("pict_structure=%d\n", s->picture_structure); + dprintf("intra_dc_precion=%d\n", s->intra_dc_precision); + dprintf("picture_structure=%d\n", s->picture_structure); dprintf("conceal=%d\n", s->concealment_motion_vectors); - dprintf("intrafmt=%d\n", s->intra_vlc_format); + dprintf("intra_vlc_format=%d\n", s->intra_vlc_format); + dprintf("alternate_scan=%d\n", s->alternate_scan); dprintf("frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); } @@ -1287,7 +1308,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx, init_get_bits(&s->gb, buf, buf_size); - s->qscale = get_bits(&s->gb, 5); + s->qscale = get_qscale(s); /* extra slice info */ while (get_bits1(&s->gb) != 0) { skip_bits(&s->gb, 8); @@ -1375,6 +1396,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->width = width; s->height = height; s->has_b_frames = 1; + s->avctx = avctx; avctx->width = width; avctx->height = height; avctx->frame_rate = frame_rate_tab[s->frame_rate_index]; @@ -1393,10 +1415,16 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); - j = block_permute_op(i); + j = zigzag_direct[i]; s->intra_matrix[j] = v; s->chroma_intra_matrix[j] = v; } +#ifdef DEBUG + dprintf("intra matrix present\n"); + for(i=0;i<64;i++) + dprintf(" %d", s->intra_matrix[zigzag_direct[i]]); + printf("\n"); +#endif } else { for(i=0;i<64;i++) { v = default_intra_matrix[i]; @@ -1407,10 +1435,16 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); - j = block_permute_op(i); + j = zigzag_direct[i]; s->non_intra_matrix[j] = v; s->chroma_non_intra_matrix[j] = v; } +#ifdef DEBUG + dprintf("non intra matrix present\n"); + for(i=0;i<64;i++) + dprintf(" %d", s->non_intra_matrix[zigzag_direct[i]]); + printf("\n"); +#endif } else { for(i=0;i<64;i++) { v = default_non_intra_matrix[i]; diff --git a/src/libffmpeg/libavcodec/mpeg12data.h b/src/libffmpeg/libavcodec/mpeg12data.h index 4f6a95b79..f7d29a5cb 100644 --- a/src/libffmpeg/libavcodec/mpeg12data.h +++ b/src/libffmpeg/libavcodec/mpeg12data.h @@ -288,27 +288,73 @@ static const UINT8 mbPatTable[63][2] = { #define MB_QUANT 0x10 static const UINT8 table_mb_ptype[32][2] = { - [ MB_FOR|MB_PAT ] { 1, 1 }, - [ MB_PAT ] { 1, 2 }, - [ MB_FOR ] { 1, 3 }, - [ MB_INTRA ] { 3, 5 }, - [ MB_QUANT|MB_FOR|MB_PAT ] { 2, 5 }, - [ MB_QUANT|MB_PAT ] { 1, 5 }, - [ MB_QUANT|MB_INTRA ] { 1, 6 }, + { 0, 0 }, // 0x00 + { 3, 5 }, // 0x01 MB_INTRA + { 1, 2 }, // 0x02 MB_PAT + { 0, 0 }, // 0x03 + { 0, 0 }, // 0x04 + { 0, 0 }, // 0x05 + { 0, 0 }, // 0x06 + { 0, 0 }, // 0x07 + { 1, 3 }, // 0x08 MB_FOR + { 0, 0 }, // 0x09 + { 1, 1 }, // 0x0A MB_FOR|MB_PAT + { 0, 0 }, // 0x0B + { 0, 0 }, // 0x0C + { 0, 0 }, // 0x0D + { 0, 0 }, // 0x0E + { 0, 0 }, // 0x0F + { 0, 0 }, // 0x10 + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 1, 5 }, // 0x12 MB_QUANT|MB_PAT + { 0, 0 }, // 0x13 + { 0, 0 }, // 0x14 + { 0, 0 }, // 0x15 + { 0, 0 }, // 0x16 + { 0, 0 }, // 0x17 + { 0, 0 }, // 0x18 + { 0, 0 }, // 0x19 + { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT + { 0, 0 }, // 0x1B + { 0, 0 }, // 0x1C + { 0, 0 }, // 0x1D + { 0, 0 }, // 0x1E + { 0, 0 }, // 0x1F }; static const UINT8 table_mb_btype[32][2] = { - [ MB_FOR|MB_BACK ] { 2, 2 }, - [ MB_FOR|MB_BACK|MB_PAT ] { 3, 2 }, - [ MB_BACK ] { 2, 3 }, - [ MB_BACK|MB_PAT ] { 3, 3 }, - [ MB_FOR ] { 2, 4 }, - [ MB_FOR|MB_PAT ] { 3, 4 }, - [ MB_INTRA ] { 3, 5 }, - [ MB_QUANT|MB_FOR|MB_BACK|MB_PAT ] { 2, 5 }, - [ MB_QUANT|MB_FOR|MB_PAT ] { 3, 6 }, - [ MB_QUANT|MB_BACK|MB_PAT ] { 2, 6 }, - [ MB_QUANT|MB_INTRA ] { 1, 6 }, + { 0, 0 }, // 0x00 + { 3, 5 }, // 0x01 MB_INTRA + { 0, 0 }, // 0x02 + { 0, 0 }, // 0x03 + { 2, 3 }, // 0x04 MB_BACK + { 0, 0 }, // 0x05 + { 3, 3 }, // 0x06 MB_BACK|MB_PAT + { 0, 0 }, // 0x07 + { 2, 4 }, // 0x08 MB_FOR + { 0, 0 }, // 0x09 + { 3, 4 }, // 0x0A MB_FOR|MB_PAT + { 0, 0 }, // 0x0B + { 2, 2 }, // 0x0C MB_FOR|MB_BACK + { 0, 0 }, // 0x0D + { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT + { 0, 0 }, // 0x0F + { 0, 0 }, // 0x10 + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 0, 0 }, // 0x12 + { 0, 0 }, // 0x13 + { 0, 0 }, // 0x14 + { 0, 0 }, // 0x15 + { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT + { 0, 0 }, // 0x17 + { 0, 0 }, // 0x18 + { 0, 0 }, // 0x19 + { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT + { 0, 0 }, // 0x1B + { 0, 0 }, // 0x1C + { 0, 0 }, // 0x1D + { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT + { 0, 0 }, // 0x1F }; static const UINT8 mbMotionVectorTable[17][2] = { diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c index a2b1cb61e..ea7979bb8 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.c +++ b/src/libffmpeg/libavcodec/mpegvideo.c @@ -81,7 +81,8 @@ static void convert_matrix(int *qmat, const UINT16 *quant_matrix, int qscale) /* 16 <= qscale * quant_matrix[i] <= 7905 */ /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ - qmat[i] = (int)((1ULL << (QMAT_SHIFT + 11)) / (aanscales[i] * qscale * quant_matrix[i])); + qmat[i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) / + (aanscales[i] * qscale * quant_matrix[i])); } } else { for(i=0;i<64;i++) { @@ -183,13 +184,6 @@ int MPV_common_init(MpegEncContext *s) /* default structure is frame */ s->picture_structure = PICT_FRAME; - /* init default q matrix (only for mpeg and mjpeg) */ - for(i=0;i<64;i++) { - s->intra_matrix[i] = default_intra_matrix[i]; - s->chroma_intra_matrix[i] = default_intra_matrix[i]; - s->non_intra_matrix[i] = default_non_intra_matrix[i]; - s->chroma_non_intra_matrix[i] = default_non_intra_matrix[i]; - } /* init macroblock skip table */ if (!s->encoding) { s->mbskip_table = av_mallocz(s->mb_width * s->mb_height); @@ -248,6 +242,7 @@ void MPV_common_end(MpegEncContext *s) int MPV_encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + int i; s->bit_rate = avctx->bit_rate; s->frame_rate = avctx->frame_rate; @@ -288,7 +283,7 @@ int MPV_encode_init(AVCodecContext *avctx) s->out_format = FMT_H263; s->h263_rv10 = 1; break; - case CODEC_ID_OPENDIVX: + case CODEC_ID_MPEG4: s->out_format = FMT_H263; s->h263_pred = 1; s->unrestricted_mv = 1; @@ -312,6 +307,12 @@ int MPV_encode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; + /* init default q matrix */ + for(i=0;i<64;i++) { + s->intra_matrix[i] = default_intra_matrix[i]; + s->non_intra_matrix[i] = default_non_intra_matrix[i]; + } + /* rate control init */ rate_control_init(s); @@ -370,6 +371,7 @@ void MPV_frame_start(MpegEncContext *s) int i; UINT8 *tmp; + s->mb_skiped = 0; if (s->pict_type == B_TYPE) { for(i=0;i<3;i++) { s->current_picture[i] = s->aux_picture[i]; @@ -789,8 +791,8 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) add_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize); add_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize); - add_dct(s, block[4], 4, dest_cb, dct_linesize >> 1); - add_dct(s, block[5], 5, dest_cr, dct_linesize >> 1); + add_dct(s, block[4], 4, dest_cb, s->linesize >> 1); + add_dct(s, block[5], 5, dest_cr, s->linesize >> 1); } else { /* dct only in intra block */ put_dct(s, block[0], 0, dest_y, dct_linesize); @@ -798,8 +800,8 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) put_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize); put_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize); - put_dct(s, block[4], 4, dest_cb, dct_linesize >> 1); - put_dct(s, block[5], 5, dest_cr, dct_linesize >> 1); + put_dct(s, block[4], 4, dest_cb, s->linesize >> 1); + put_dct(s, block[5], 5, dest_cr, s->linesize >> 1); } } the_end: @@ -982,6 +984,10 @@ static int dct_quantize(MpegEncContext *s, av_fdct (block); + /* we need this permutation so that we correct the IDCT + permutation. will be moved into DCT code */ + block_permute(block); + if (s->mb_intra) { if (n < 4) q = s->y_dc_scale; @@ -1250,7 +1256,7 @@ static void rate_control_init(MpegEncContext *s) */ static int rate_estimate_qscale(MpegEncContext *s) { - long long total_bits = s->total_bits; + INT64 total_bits = s->total_bits; float q; int qscale, diff, qmin; @@ -1275,9 +1281,9 @@ static int rate_estimate_qscale(MpegEncContext *s) q = 31; qscale = (int)(q + 0.5); #if defined(DEBUG) - printf("%d: total=%Ld br=%0.1f diff=%d qest=%0.1f\n", + printf("%d: total=%0.0f br=%0.1f diff=%d qest=%0.1f\n", s->picture_number, - total_bits, + (double)total_bits, (float)s->frame_rate / FRAME_RATE_BASE * total_bits / s->picture_number, diff, q); @@ -1335,10 +1341,10 @@ AVCodec mjpeg_encoder = { MPV_encode_end, }; -AVCodec opendivx_encoder = { - "opendivx", +AVCodec mpeg4_encoder = { + "mpeg4", CODEC_TYPE_VIDEO, - CODEC_ID_OPENDIVX, + CODEC_ID_MPEG4, sizeof(MpegEncContext), MPV_encode_init, MPV_encode_picture, diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h index a225dedbe..dccdeb24b 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.h +++ b/src/libffmpeg/libavcodec/mpegvideo.h @@ -31,6 +31,7 @@ enum OutputFormat { #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; @@ -40,7 +41,7 @@ typedef struct MpegEncContext { enum OutputFormat out_format; /* output format */ int h263_plus; /* h263 plus headers */ int h263_rv10; /* use RV10 variation for H263 */ - int h263_pred; /* use OpenDIVX (aka mpeg4) ac/dc predictions */ + 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 */ @@ -125,11 +126,14 @@ typedef struct MpegEncContext { /* bit rate control */ int I_frame_bits; /* wanted number of bits per I frame */ int P_frame_bits; /* same for P frame */ - long long wanted_bits; - long long total_bits; + INT64 wanted_bits; + INT64 total_bits; /* 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 */ diff --git a/src/libffmpeg/libavcodec/msmpeg4.c b/src/libffmpeg/libavcodec/msmpeg4.c index 971ea7182..63f111bdd 100644 --- a/src/libffmpeg/libavcodec/msmpeg4.c +++ b/src/libffmpeg/libavcodec/msmpeg4.c @@ -30,7 +30,7 @@ * - (encoding) select best vlc/dc table * - (decoding) handle slice indication */ -//#define DEBUG_PRINTS +#undef DEBUG /* motion vector table */ typedef struct MVTable { @@ -50,7 +50,7 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); static int msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); -#ifdef DEBUG_PRINTS +#ifdef DEBUG int intra_count = 0; int frame_count = 0; #endif @@ -197,7 +197,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) init_rl(&rl_table[i]); } -#ifdef DEBUG_PRINTS +#ifdef DEBUG intra_count = 0; printf("*****frame %d:\n", frame_count++); #endif @@ -592,7 +592,7 @@ int msmpeg4_decode_init_vlc(MpegEncContext *s) init_vlc(&mb_non_intra_vlc, 9, 128, &table_mb_non_intra[0][1], 8, 4, &table_mb_non_intra[0][0], 8, 4); - init_vlc(&mb_intra_vlc, 9, 128, + init_vlc(&mb_intra_vlc, 9, 64, &table_mb_intra[0][1], 4, 2, &table_mb_intra[0][0], 4, 2); return 0; @@ -642,7 +642,7 @@ int msmpeg4_decode_picture_header(MpegEncContext * s) s->mv_table_index = get_bits1(&s->gb); s->no_rounding ^= 1; } -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("*****frame %d:\n", frame_count++); #endif return 0; diff --git a/src/libffmpeg/libavcodec/rv10.c b/src/libffmpeg/libavcodec/rv10.c index de1d4abce..6d9376c54 100644 --- a/src/libffmpeg/libavcodec/rv10.c +++ b/src/libffmpeg/libavcodec/rv10.c @@ -24,6 +24,8 @@ #include "avcodec.h" #include "mpegvideo.h" +#undef DEBUG + static const UINT16 rv_lum_code[256] = { 0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06, @@ -288,7 +290,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) pb_frame = get_bits(&s->gb, 1); -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); #endif @@ -303,7 +305,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) s->last_dc[0] = get_bits(&s->gb, 8); s->last_dc[1] = get_bits(&s->gb, 8); s->last_dc[2] = get_bits(&s->gb, 8); -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("DC:%d %d %d\n", s->last_dc[0], s->last_dc[1], @@ -335,6 +337,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) static int rv10_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + int i; static int done; s->out_format = FMT_H263; @@ -348,6 +351,11 @@ static int rv10_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; + /* XXX: suppress this matrix init, only needed because using mpeg1 + dequantize in mmx case */ + for(i=0;i<64;i++) + s->non_intra_matrix[i] = default_non_intra_matrix[i]; + h263_decode_init_vlc(s); /* init rv vlc */ @@ -381,7 +389,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, DCTELEM block[6][64]; AVPicture *pict = data; -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); #endif @@ -395,7 +403,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, mb_count = rv10_decode_picture_header(s); if (mb_count < 0) { -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("HEADER ERROR\n"); #endif return -1; @@ -403,7 +411,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, if (s->mb_x >= s->mb_width || s->mb_y >= s->mb_height) { -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("POS ERROR %d %d\n", s->mb_x, s->mb_y); #endif return -1; @@ -411,7 +419,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, mb_pos = s->mb_y * s->mb_width + s->mb_x; left = s->mb_width * s->mb_height - mb_pos; if (mb_count > left) { -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("COUNT ERROR\n"); #endif return -1; @@ -421,7 +429,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, MPV_frame_start(s); } -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("qscale=%d\n", s->qscale); #endif @@ -434,7 +442,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, /* decode each macroblock */ for(i=0;imb_x, s->mb_y); #endif @@ -442,7 +450,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; if (h263_decode_mb(s, block) < 0) { -#ifdef DEBUG_PRINTS +#ifdef DEBUG printf("ERROR\n"); #endif return -1; diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c index 958f6d32d..26510d87c 100644 --- a/src/libffmpeg/libavcodec/utils.c +++ b/src/libffmpeg/libavcodec/utils.c @@ -174,6 +174,15 @@ AVCodec *avcodec_find(enum CodecID id) return NULL; } +const char *pix_fmt_str[] = { + "yuv420p", + "yuv422", + "rgb24", + "bgr24", + "yuv422p", + "yuv444p", +}; + void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { const char *codec_name; @@ -208,6 +217,11 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) snprintf(buf, buf_size, "Video: %s%s", codec_name, enc->flags & CODEC_FLAG_HQ ? " (hq)" : ""); + if (enc->codec_id == CODEC_ID_RAWVIDEO) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %s", + pix_fmt_str[enc->pix_fmt]); + } if (enc->width) { snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %dx%d, %0.2f fps", @@ -235,6 +249,89 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) } } +/* Picture field are filled with 'ptr' addresses */ +void avpicture_fill(AVPicture *picture, UINT8 *ptr, + int pix_fmt, int width, int height) +{ + int size; + + size = width * height; + switch(pix_fmt) { + case PIX_FMT_YUV420P: + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size / 4; + picture->linesize[0] = width; + picture->linesize[1] = width / 2; + picture->linesize[2] = width / 2; + break; + case PIX_FMT_YUV422P: + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size / 2; + picture->linesize[0] = width; + picture->linesize[1] = width / 2; + picture->linesize[2] = width / 2; + break; + case PIX_FMT_YUV444P: + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size; + picture->linesize[0] = width; + picture->linesize[1] = width; + picture->linesize[2] = width; + break; + case PIX_FMT_RGB24: + case PIX_FMT_BGR24: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width * 3; + break; + case PIX_FMT_YUV422: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width * 2; + break; + default: + picture->data[0] = NULL; + picture->data[1] = NULL; + picture->data[2] = NULL; + break; + } +} + +int avpicture_get_size(int pix_fmt, int width, int height) +{ + int size; + + size = width * height; + switch(pix_fmt) { + case PIX_FMT_YUV420P: + size = (size * 3) / 2; + break; + case PIX_FMT_YUV422P: + size = (size * 2); + break; + case PIX_FMT_YUV444P: + size = (size * 3); + break; + case PIX_FMT_RGB24: + case PIX_FMT_BGR24: + size = (size * 3); + break; + case PIX_FMT_YUV422: + size = (size * 2); + break; + default: + size = -1; + break; + } + return size; +} + + /* must be called before any other functions */ void avcodec_init(void) { @@ -253,7 +350,7 @@ void avcodec_register_all(void) register_avcodec(&h263p_encoder); register_avcodec(&rv10_encoder); register_avcodec(&mjpeg_encoder); - register_avcodec(&opendivx_encoder); + register_avcodec(&mpeg4_encoder); register_avcodec(&msmpeg4_encoder); #endif /* CONFIG_ENCODERS */ register_avcodec(&pcm_codec); @@ -262,7 +359,7 @@ void avcodec_register_all(void) /* decoders */ #ifdef CONFIG_DECODERS register_avcodec(&h263_decoder); - register_avcodec(&opendivx_decoder); + register_avcodec(&mpeg4_decoder); register_avcodec(&msmpeg4_decoder); register_avcodec(&mpeg_decoder); register_avcodec(&h263i_decoder); diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c index bd6391bf5..42637b9d1 100644 --- a/src/libffmpeg/xine_decoder.c +++ b/src/libffmpeg/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.6 2001/08/10 22:14:24 guenter Exp $ + * $Id: xine_decoder.c,v 1.7 2001/08/28 19:16:20 guenter Exp $ * * xine decoder plugin using ffmpeg * @@ -32,6 +32,7 @@ #include #include +#include "xine_internal.h" #include "cpu_accel.h" #include "video_out.h" #include "buffer.h" @@ -39,19 +40,6 @@ #include "libavcodec/avcodec.h" -/* this def is taken from xine_internal.h */ -typedef struct video_decoder_s video_decoder_t; -struct video_decoder_s { - int interface_version; - int (*can_handle) (video_decoder_t *this, int buf_type); - void (*init) (video_decoder_t *this, vo_instance_t *video_out); - void (*decode_data) (video_decoder_t *this, buf_element_t *buf); - void (*close) (video_decoder_t *this); - char* (*get_identifier) (void); - int priority; - metronom_t *metronom; -}; - /* now this is ripped of wine's vfw.h */ typedef struct { long biSize; @@ -94,7 +82,13 @@ typedef struct ff_decoder_s { */ static int ff_can_handle (video_decoder_t *this_gen, int buf_type) { - return ((buf_type & 0xFFFF0000) == BUF_VIDEO_AVI) ; + buf_type &= 0xFFFF0000; + + return ( buf_type == BUF_VIDEO_MSMPEG4 || + buf_type == BUF_VIDEO_MJPEG || + buf_type == BUF_VIDEO_MPEG4 || + buf_type == BUF_VIDEO_I263 || + buf_type == BUF_VIDEO_RV10 ); } static void ff_init (video_decoder_t *this_gen, vo_instance_t *video_out) { @@ -116,6 +110,7 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { if (buf->decoder_info[0] == 0) { AVCodec *codec = NULL; + int codec_type; /* init package containing bih */ @@ -124,6 +119,8 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { /* init codec */ + codec_type = buf->type & 0xFFFF0000; + /* if (this->bih.biCompression == mmioFOURCC('D', 'I', 'V', 'X')) { printf ("ffmpeg: mpeg4 (opendivx) format detected\n"); @@ -135,36 +132,25 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { } */ - switch (this->bih.biCompression) { - case mmioFOURCC('M', 'P', 'G', '4'): - case mmioFOURCC('m', 'p', 'g', '4'): - case mmioFOURCC('M', 'P', '4', '2'): - case mmioFOURCC('m', 'p', '4', '2'): - case mmioFOURCC('M', 'P', '4', '3'): - case mmioFOURCC('m', 'p', '4', '3'): - case mmioFOURCC('D', 'I', 'V', '3'): - case mmioFOURCC('d', 'i', 'v', '3'): - case mmioFOURCC('D', 'I', 'V', '4'): - case mmioFOURCC('d', 'i', 'v', '4'): - case mmioFOURCC('M', 'P', '4', '1'): - case mmioFOURCC('m', 'p', '4', '1'): - printf ("ffmpeg: ms mpeg4 format detected\n"); + switch (buf->type & 0xFFFF0000) { + case BUF_VIDEO_MSMPEG4: codec = avcodec_find_decoder (CODEC_ID_MSMPEG4); break; - case mmioFOURCC('D', 'I', 'V', 'X'): - case mmioFOURCC('d', 'i', 'v', 'x'): - case mmioFOURCC('D', 'i', 'v', 'x'): - case mmioFOURCC('D', 'i', 'v', 'X'): - printf ("ffmpeg: mpeg4 (opendivx) format detected\n"); - codec = avcodec_find_decoder (CODEC_ID_OPENDIVX); + case BUF_VIDEO_MPEG4 : + codec = avcodec_find_decoder (CODEC_ID_MPEG4); break; - case mmioFOURCC('d', 'm', 'b', '1'): - printf ("ffmpeg: motion jpeg format detected\n"); + case BUF_VIDEO_MJPEG: codec = avcodec_find_decoder (CODEC_ID_MJPEG); break; + case BUF_VIDEO_I263: + codec = avcodec_find_decoder (CODEC_ID_H263); + break; + case BUF_VIDEO_RV10: + codec = avcodec_find_decoder (CODEC_ID_RV10); + break; default: - printf ("ffmpeg: unknown video format 0x%08X\n", - this->bih.biCompression); + printf ("ffmpeg: unknown video format (buftype: 0x%08X)\n", + buf->type & 0xFFFF0000); } if (!codec) { diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c index 69abf2e9f..1b062de41 100644 --- a/src/libw32dll/w32codec.c +++ b/src/libw32dll/w32codec.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: w32codec.c,v 1.16 2001/08/21 19:39:50 jcdutton Exp $ + * $Id: w32codec.c,v 1.17 2001/08/28 19:16:20 guenter Exp $ * * routines for using w32 codecs * @@ -172,7 +172,17 @@ static char* get_vids_codec_name(w32v_decoder_t *this, #define IMGFMT_15RGB mmioFOURCC( 15,'R','G','B') static int w32v_can_handle (video_decoder_t *this_gen, int buf_type) { - return ((buf_type & 0xFFFF0000) == BUF_VIDEO_AVI) ; + buf_type &= 0xFFFF0000; + + return ( buf_type == BUF_VIDEO_AVI || + buf_type == BUF_VIDEO_MSMPEG4 || + buf_type == BUF_VIDEO_MJPEG || + buf_type == BUF_VIDEO_IV50 || + buf_type == BUF_VIDEO_IV41 || + buf_type == BUF_VIDEO_IV32 || + buf_type == BUF_VIDEO_CINEPACK || + /* buf_type == BUF_VIDEO_ATIVCR1 || */ + buf_type == BUF_VIDEO_ATIVCR2 ); } static void w32v_init (video_decoder_t *this_gen, vo_instance_t *video_out) { diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index f55f7a39c..a8f1a7d80 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xshm.c,v 1.27 2001/08/23 11:27:35 jkeil Exp $ + * $Id: video_out_xshm.c,v 1.28 2001/08/28 19:16:20 guenter Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -49,6 +49,7 @@ #include #include +#include #include "xine_internal.h" #include "monitor.h" diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index 6f9aeb9a0..c7396b49f 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: buffer.h,v 1.5 2001/07/18 21:38:17 f1rmb Exp $ + * $Id: buffer.h,v 1.6 2001/08/28 19:16:20 guenter Exp $ * * * contents: @@ -69,14 +69,24 @@ extern "C" { #define BUF_VIDEO_BASE 0x02000000 #define BUF_VIDEO_MPEG 0x02000000 -#define BUF_VIDEO_OPENDIVX 0x02010000 +#define BUF_VIDEO_MPEG4 0x02010000 #define BUF_VIDEO_QUICKTIME 0x02020000 #define BUF_VIDEO_AVI 0x02030000 +#define BUF_VIDEO_MSMPEG4 0x02040000 +#define BUF_VIDEO_MJPEG 0x02050000 +#define BUF_VIDEO_IV50 0x02060000 +#define BUF_VIDEO_IV41 0x02070000 +#define BUF_VIDEO_IV32 0x02080000 +#define BUF_VIDEO_CINEPACK 0x02090000 +#define BUF_VIDEO_ATIVCR1 0x020a0000 +#define BUF_VIDEO_ATIVCR2 0x020b0000 +#define BUF_VIDEO_I263 0x020c0000 +#define BUF_VIDEO_RV10 0x020d0000 /* audio buffer types: */ #define BUF_AUDIO_BASE 0x03000000 -#define BUF_AUDIO_AC3 0x03000000 +#define BUF_AUDIO_A52 0x03000000 #define BUF_AUDIO_MPEG 0x03010000 #define BUF_AUDIO_LPCM 0x03020000 #define BUF_AUDIO_AVI 0x03030000 diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 0d6fe341d..64d9748e4 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_decoder.c,v 1.43 2001/08/25 08:48:12 guenter Exp $ + * $Id: video_decoder.c,v 1.44 2001/08/28 19:16:20 guenter Exp $ * */ @@ -114,37 +114,6 @@ void *video_decoder_loop (void *this_gen) { } break; - case BUF_VIDEO_MPEG: - case BUF_VIDEO_AVI: - - /* - printf ("video_decoder: got package %d, decoder_info[0]:%d\n", - buf, buf->decoder_info[0]); - */ - - streamtype = (buf->type>>16) & 0xFF; - - decoder = this->video_decoder_plugins [streamtype]; - - if (decoder) { - - if (this->cur_video_decoder_plugin != decoder) { - - if (this->cur_video_decoder_plugin) - this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin); - - this->cur_video_decoder_plugin = decoder; - this->cur_video_decoder_plugin->init (this->cur_video_decoder_plugin, this->video_out); - - printf ("video_decoder: using decoder >%s< \n", - decoder->get_identifier()); - - } - - decoder->decode_data (this->cur_video_decoder_plugin, buf); - } - break; - case BUF_CONTROL_END: this->metronom->video_stream_end (this->metronom); @@ -187,6 +156,40 @@ void *video_decoder_loop (void *this_gen) { running = 0; break; + default: + if ( (buf->type & 0xFF000000) == BUF_VIDEO_BASE ) { + + /* + printf ("video_decoder: got package %d, decoder_info[0]:%d\n", + buf, buf->decoder_info[0]); + */ + + streamtype = (buf->type>>16) & 0xFF; + + decoder = this->video_decoder_plugins [streamtype]; + + if (decoder) { + + if (this->cur_video_decoder_plugin != decoder) { + + if (this->cur_video_decoder_plugin) + this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin); + + this->cur_video_decoder_plugin = decoder; + this->cur_video_decoder_plugin->init (this->cur_video_decoder_plugin, this->video_out); + + printf ("video_decoder: using decoder >%s< \n", + decoder->get_identifier()); + + } + + decoder->decode_data (this->cur_video_decoder_plugin, buf); + } + } else + printf ("video_decoder: unknown buffer type: %08x\n", buf->type); + + break; + } buf->free_buffer (buf); -- cgit v1.2.3