1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-13 21:28:01 +02:00
adding AVVideoFrame
 moving quality, pict_type, key_frame, qscale_table, ... to AVVideoFrame
 removing obsolete variables in AVCodecContext
 skiping of MBs in b frames
 correctly initalizing AVCodecContext
 picture buffer cleanup

Originally committed as revision 1302 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2002-12-04 10:04:03 +00:00
parent 855ea723b0
commit 1e491e29c2
28 changed files with 989 additions and 874 deletions

View File

@ -285,6 +285,7 @@ int read_ffserver_streams(AVFormatContext *s, const char *filename)
s->nb_streams = ic->nb_streams; s->nb_streams = ic->nb_streams;
for(i=0;i<ic->nb_streams;i++) { for(i=0;i<ic->nb_streams;i++) {
AVStream *st; AVStream *st;
st = av_mallocz(sizeof(AVFormatContext)); st = av_mallocz(sizeof(AVFormatContext));
memcpy(st, ic->streams[i], sizeof(AVStream)); memcpy(st, ic->streams[i], sizeof(AVStream));
s->streams[i] = st; s->streams[i] = st;
@ -605,15 +606,21 @@ static void do_video_out(AVFormatContext *s,
/* XXX: pb because no interleaving */ /* XXX: pb because no interleaving */
for(i=0;i<nb_frames;i++) { for(i=0;i<nb_frames;i++) {
if (enc->codec_id != CODEC_ID_RAWVIDEO) { if (enc->codec_id != CODEC_ID_RAWVIDEO) {
AVVideoFrame big_picture;
memset(&big_picture, 0, sizeof(AVVideoFrame));
*(AVPicture*)&big_picture= *picture;
/* handles sameq here. This is not correct because it may /* handles sameq here. This is not correct because it may
not be a global option */ not be a global option */
if (same_quality) { if (same_quality) {
enc->quality = dec->quality; big_picture.quality = ist->st->quality;
} }else
big_picture.quality = ost->st->quality;
ret = avcodec_encode_video(enc, ret = avcodec_encode_video(enc,
video_buffer, VIDEO_BUFFER_SIZE, video_buffer, VIDEO_BUFFER_SIZE,
picture); &big_picture);
//enc->frame_number = enc->real_pict_num; //enc->frame_number = enc->real_pict_num;
av_write_frame(s, ost->index, video_buffer, ret); av_write_frame(s, ost->index, video_buffer, ret);
*frame_size = ret; *frame_size = ret;
@ -674,7 +681,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
total_size += frame_size; total_size += frame_size;
if (enc->codec_type == CODEC_TYPE_VIDEO) { if (enc->codec_type == CODEC_TYPE_VIDEO) {
frame_number = ost->frame_number; frame_number = ost->frame_number;
fprintf(fvstats, "frame= %5d q= %2d ", frame_number, enc->quality); fprintf(fvstats, "frame= %5d q= %2.1f ", frame_number, enc->coded_picture->quality);
if (do_psnr) if (do_psnr)
fprintf(fvstats, "PSNR= %6.2f ", enc->psnr_y); fprintf(fvstats, "PSNR= %6.2f ", enc->psnr_y);
@ -688,7 +695,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0; avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0;
fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
(double)total_size / 1024, ti1, bitrate, avg_bitrate); (double)total_size / 1024, ti1, bitrate, avg_bitrate);
fprintf(fvstats,"type= %s\n", enc->key_frame == 1 ? "I" : "P"); fprintf(fvstats,"type= %s\n", enc->coded_picture->key_frame == 1 ? "I" : "P");
} }
} }
@ -731,13 +738,13 @@ void print_report(AVFormatContext **output_files,
os = output_files[ost->file_index]; os = output_files[ost->file_index];
enc = &ost->st->codec; enc = &ost->st->codec;
if (vid && enc->codec_type == CODEC_TYPE_VIDEO) { if (vid && enc->codec_type == CODEC_TYPE_VIDEO) {
sprintf(buf + strlen(buf), "q=%2d ", sprintf(buf + strlen(buf), "q=%2.1f ",
enc->quality); enc->coded_picture->quality);
} }
if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) { if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {
frame_number = ost->frame_number; frame_number = ost->frame_number;
sprintf(buf + strlen(buf), "frame=%5d q=%2d ", sprintf(buf + strlen(buf), "frame=%5d q=%2.1f ",
frame_number, enc->quality); frame_number, enc->coded_picture ? enc->coded_picture->quality : 0);
if (do_psnr) if (do_psnr)
sprintf(buf + strlen(buf), "PSNR=%6.2f ", enc->psnr_y); sprintf(buf + strlen(buf), "PSNR=%6.2f ", enc->psnr_y);
vid = 1; vid = 1;
@ -1236,9 +1243,13 @@ static int av_encode(AVFormatContext **output_files,
ist->st->codec.height); ist->st->codec.height);
ret = len; ret = len;
} else { } else {
AVVideoFrame big_picture;
data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2; data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2;
ret = avcodec_decode_video(&ist->st->codec, ret = avcodec_decode_video(&ist->st->codec,
&picture, &got_picture, ptr, len); &big_picture, &got_picture, ptr, len);
picture= *(AVPicture*)&big_picture;
ist->st->quality= big_picture.quality;
if (ret < 0) { if (ret < 0) {
fail_decode: fail_decode:
fprintf(stderr, "Error while decoding stream #%d.%d\n", fprintf(stderr, "Error while decoding stream #%d.%d\n",
@ -2046,6 +2057,7 @@ void opt_output_file(const char *filename)
fprintf(stderr, "Could not alloc stream\n"); fprintf(stderr, "Could not alloc stream\n");
exit(1); exit(1);
} }
avcodec_get_context_defaults(&st->codec);
video_enc = &st->codec; video_enc = &st->codec;
if (video_stream_copy) { if (video_stream_copy) {
@ -2074,7 +2086,7 @@ void opt_output_file(const char *filename)
video_enc->gop_size = 0; video_enc->gop_size = 0;
if (video_qscale || same_quality) { if (video_qscale || same_quality) {
video_enc->flags |= CODEC_FLAG_QSCALE; video_enc->flags |= CODEC_FLAG_QSCALE;
video_enc->quality = video_qscale; st->quality = video_qscale;
} }
if (use_hq) { if (use_hq) {
@ -2181,6 +2193,7 @@ void opt_output_file(const char *filename)
fprintf(stderr, "Could not alloc stream\n"); fprintf(stderr, "Could not alloc stream\n");
exit(1); exit(1);
} }
avcodec_get_context_defaults(&st->codec);
audio_enc = &st->codec; audio_enc = &st->codec;
audio_enc->codec_type = CODEC_TYPE_AUDIO; audio_enc->codec_type = CODEC_TYPE_AUDIO;

View File

@ -1955,7 +1955,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
/* we use the codec indication because it is /* we use the codec indication because it is
more accurate than the demux flags */ more accurate than the demux flags */
pkt->flags = 0; pkt->flags = 0;
if (st->codec.key_frame) if (st->codec.coded_picture->key_frame)
pkt->flags |= PKT_FLAG_KEY; pkt->flags |= PKT_FLAG_KEY;
return 0; return 0;
} }
@ -3942,7 +3942,7 @@ int parse_ffconfig(const char *filename)
} else if (!strcasecmp(cmd, "AudioQuality")) { } else if (!strcasecmp(cmd, "AudioQuality")) {
get_arg(arg, sizeof(arg), &p); get_arg(arg, sizeof(arg), &p);
if (stream) { if (stream) {
audio_enc.quality = atof(arg) * 1000; // audio_enc.quality = atof(arg) * 1000;
} }
} else if (!strcasecmp(cmd, "VideoBitRateRange")) { } else if (!strcasecmp(cmd, "VideoBitRateRange")) {
if (stream) { if (stream) {

View File

@ -5,8 +5,8 @@
#define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION_INT 0x000406
#define LIBAVCODEC_VERSION "0.4.6" #define LIBAVCODEC_VERSION "0.4.6"
#define LIBAVCODEC_BUILD 4640 #define LIBAVCODEC_BUILD 4641
#define LIBAVCODEC_BUILD_STR "4640" #define LIBAVCODEC_BUILD_STR "4641"
enum CodecID { enum CodecID {
CODEC_ID_NONE, CODEC_ID_NONE,
@ -140,7 +140,6 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
#define CODEC_FLAG_EXTERN_HUFF 0x1000 /* use external huffman table (for mjpeg) */ #define CODEC_FLAG_EXTERN_HUFF 0x1000 /* use external huffman table (for mjpeg) */
#define CODEC_FLAG_GRAY 0x2000 /* only decode/encode grayscale */ #define CODEC_FLAG_GRAY 0x2000 /* only decode/encode grayscale */
#define CODEC_FLAG_EMU_EDGE 0x4000/* dont draw edges */ #define CODEC_FLAG_EMU_EDGE 0x4000/* dont draw edges */
#define CODEC_FLAG_DR1 0x8000 /* direct renderig type 1 (store internal frames in external buffers) */
#define CODEC_FLAG_TRUNCATED 0x00010000 /* input bitstream might be truncated at a random location instead #define CODEC_FLAG_TRUNCATED 0x00010000 /* input bitstream might be truncated at a random location instead
of only at frame boundaries */ of only at frame boundaries */
#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 /* normalize adaptive quantization */ #define CODEC_FLAG_NORMALIZE_AQP 0x00020000 /* normalize adaptive quantization */
@ -159,6 +158,111 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
#define FRAME_RATE_BASE 10000 #define FRAME_RATE_BASE 10000
#define FF_COMMON_PICTURE \
uint8_t *data[4];\
int linesize[4];\
/**\
* pointer to the first allocated byte of the picture. can be used in get_buffer/release_buffer
* this isnt used by lavc unless the default get/release_buffer() is used\
* encoding: \
* decoding: \
*/\
uint8_t *base[4];\
/**\
* 1 -> keyframe, 0-> not\
* encoding: set by lavc\
* decoding: set by lavc\
*/\
int key_frame;\
\
/**\
* picture type of the frame, see ?_TYPE below\
* encoding: set by lavc for coded_picture (and set by user for input)\
* decoding: set by lavc\
*/\
int pict_type;\
\
/**\
* presentation timestamp in micro seconds (time when frame should be shown to user)\
* if 0 then the frame_rate will be used as reference\
* encoding: MUST be set by user\
* decoding: set by lavc\
*/\
long long int pts;\
\
/**\
* picture number in bitstream order.\
* encoding: set by\
* decoding: set by lavc\
*/\
int coded_picture_number;\
/**\
* encoding: set by\
* decoding: set by lavc\
* picture number in display order.\
*/\
int display_picture_number;\
\
/**\
* quality (between 1 (good) and 31 (bad)) \
* encoding: set by lavc for coded_picture (and set by user for input)\
* decoding: set by lavc\
*/\
float quality; \
\
/**\
* buffer age (1->was last buffer and dint change, 2->..., ...).\
* set to something large if the buffer has not been used yet \
* encoding: unused\
* decoding: MUST be set by get_buffer()\
*/\
int age;\
\
/**\
* is this picture used as reference\
* encoding: unused\
* decoding: set by lavc (before get_buffer() call))\
*/\
int reference;\
\
/**\
* QP table\
* encoding: unused\
* decoding: set by lavc\
*/\
int8_t *qscale_table;\
/**\
* QP store stride\
* encoding: unused\
* decoding: set by lavc\
*/\
int qstride;\
\
/**\
* mbskip_table[mb]>=1 if MB didnt change\
* stride= mb_width = (width+15)>>4\
* encoding: unused\
* decoding: set by lavc\
*/\
uint8_t *mbskip_table;\
\
/**\
* for some private data of the user\
* encoding: unused\
* decoding: set by user\
*/\
void *opaque;\
/* FIXME: these should have FF_ */
#define I_TYPE 1 // Intra
#define P_TYPE 2 // Predicted
#define B_TYPE 3 // Bi-dir predicted
#define S_TYPE 4 // S(GMC)-VOP MPEG4
typedef struct AVVideoFrame {
FF_COMMON_PICTURE
} AVVideoFrame;
typedef struct AVCodecContext { typedef struct AVCodecContext {
/** /**
* the average bitrate * the average bitrate
@ -191,7 +295,7 @@ typedef struct AVCodecContext {
/** /**
* motion estimation algorithm used for video coding * motion estimation algorithm used for video coding
* encoding: set by user. * encoding: MUST be set by user.
* decoding: unused * decoding: unused
*/ */
int me_method; int me_method;
@ -212,21 +316,17 @@ typedef struct AVCodecContext {
* frames per sec multiplied by FRAME_RATE_BASE * frames per sec multiplied by FRAME_RATE_BASE
* for variable fps this is the precission, so if the timestamps * for variable fps this is the precission, so if the timestamps
* can be specified in msec precssion then this is 1000*FRAME_RATE_BASE * can be specified in msec precssion then this is 1000*FRAME_RATE_BASE
* encoding: set by user * encoding: MUST be set by user
* decoding: set by lavc. 0 or the frame_rate if available * decoding: set by lavc. 0 or the frame_rate if available
*/ */
int frame_rate; int frame_rate;
/** /**
* encoding: set by user. * encoding: MUST be set by user.
* decoding: set by user, some codecs might override / change it during playback * decoding: set by user, some codecs might override / change it during playback
*/ */
int width, height; int width, height;
/**
* Obsolete, will be removed
*/
int aspect_ratio_info;
#define FF_ASPECT_SQUARE 1 #define FF_ASPECT_SQUARE 1
#define FF_ASPECT_4_3_625 2 #define FF_ASPECT_4_3_625 2
#define FF_ASPECT_4_3_525 3 #define FF_ASPECT_4_3_525 3
@ -276,24 +376,12 @@ typedef struct AVCodecContext {
previous encoded frame */ previous encoded frame */
/** /**
* 1 -> keyframe, 0-> not * 1 -> keyframe, 0-> not (this if for audio only, for video, AVVideoFrame.key_frame should be used)
* encoding: set by lavc (for the outputed bitstream, not the input frame) * encoding: set by lavc (for the outputed bitstream, not the input frame)
* decoding: set by lavc (for the decoded bitstream, not the displayed frame) * decoding: set by lavc (for the decoded bitstream, not the displayed frame)
*/ */
int key_frame; int key_frame;
/**
* picture type of the previous en/decoded frame, see ?_TYPE below
* encoding: set by lavc (for the outputed bitstream, not the input frame)
* decoding: set by lavc (for the decoded bitstream, not the displayed frame)
*/
int pict_type;
/* FIXME: these should have FF_ */
#define I_TYPE 1 // Intra
#define P_TYPE 2 // Predicted
#define B_TYPE 3 // Bi-dir predicted
#define S_TYPE 4 // S(GMC)-VOP MPEG4
/** /**
* number of frames the decoded output will be delayed relative to * number of frames the decoded output will be delayed relative to
* the encoded input * the encoded input
@ -302,24 +390,7 @@ typedef struct AVCodecContext {
*/ */
int delay; int delay;
/**
* mbskip_table[mb]=1 if MB didnt change, is only valid for I/P frames
* stride= mb_width = (width+15)>>4 (FIXME export stride?)
* encoding: unused
* decoding: set by lavc
*/
uint8_t *mbskip_table;
/* encoding parameters */ /* encoding parameters */
/**
* quality (between 1 (good) and 31 (bad))
* encoding: set by user if CODEC_FLAG_QSCALE is set otherwise set by lavc
* decoding: set by lavc
*/
int quality; /* quality of the previous encoded frame
this is allso used to set the quality in vbr mode
and the per frame quality in CODEC_FLAG_TYPE (second pass mode) */
float qcompress; /* amount of qscale change between easy & hard scenes (0.0-1.0)*/ float qcompress; /* amount of qscale change between easy & hard scenes (0.0-1.0)*/
float qblur; /* amount of qscale smoothing over time (0.0-1.0) */ float qblur; /* amount of qscale smoothing over time (0.0-1.0) */
@ -485,46 +556,21 @@ typedef struct AVCodecContext {
int error_resilience; int error_resilience;
/** /**
* obsolete, just here to keep ABI compatible (should be removed perhaps, dunno) * called at the beginning of each frame to get a buffer for it.
* if pic.reference is set then the frame will be read later by lavc
* encoding: unused
* decoding: set by lavc, user can override
*/ */
int *quant_store; int (*get_buffer)(struct AVCodecContext *c, AVVideoFrame *pic);
/** /**
* QP store stride * called to release buffers which where allocated with get_buffer.
* a released buffer can be reused in get_buffer()
* pic.data[*] must be set to NULL
* encoding: unused * encoding: unused
* decoding: set by lavc * decoding: set by lavc, user can override
*/ */
int qstride; void (*release_buffer)(struct AVCodecContext *c, AVVideoFrame *pic);
/**
* buffer, where the next picture should be decoded into
* encoding: unused
* decoding: set by user in get_buffer_callback to a buffer into which the next part
* of the bitstream will be decoded, and set by lavc at end of frame to the
* next frame which needs to be displayed
*/
uint8_t *dr_buffer[3];
/**
* stride of the luminance part of the dr buffer
* encoding: unused
* decoding: set by user
*/
int dr_stride;
/**
* same behavior as dr_buffer, just for some private data of the user
* encoding: unused
* decoding: set by user in get_buffer_callback, and set by lavc at end of frame
*/
void *dr_opaque_frame;
/**
* called at the beginning of each frame to get a buffer for it
* encoding: unused
* decoding: set by user
*/
int (*get_buffer_callback)(struct AVCodecContext *c, int width, int height, int pict_type);
/** /**
* is 1 if the decoded stream contains b frames, 0 otherwise * is 1 if the decoded stream contains b frames, 0 otherwise
@ -533,20 +579,6 @@ typedef struct AVCodecContext {
*/ */
int has_b_frames; int has_b_frames;
/**
* stride of the chrominance part of the dr buffer
* encoding: unused
* decoding: set by user
*/
int dr_uvstride;
/**
* number of dr buffers
* encoding: unused
* decoding: set by user
*/
int dr_ip_buffer_count;
int block_align; /* used by some WAV based audio codecs */ int block_align; /* used by some WAV based audio codecs */
int parse_only; /* decoding only: if true, only parsing is done int parse_only; /* decoding only: if true, only parsing is done
@ -646,12 +678,6 @@ typedef struct AVCodecContext {
*/ */
float rc_initial_cplx; float rc_initial_cplx;
/**
* Obsolete, will be removed
*/
int aspected_width;
int aspected_height;
/** /**
* dct algorithm, see FF_DCT_* below * dct algorithm, see FF_DCT_* below
* encoding: set by user * encoding: set by user
@ -665,14 +691,6 @@ typedef struct AVCodecContext {
#define FF_DCT_MLIB 4 #define FF_DCT_MLIB 4
#define FF_DCT_ALTIVEC 5 #define FF_DCT_ALTIVEC 5
/**
* presentation timestamp in micro seconds (time when frame should be shown to user)
* if 0 then the frame_rate will be used as reference
* encoding: set by user
* decoding; set by lavc
*/
long long int pts;
/** /**
* luminance masking (0-> disabled) * luminance masking (0-> disabled)
* encoding: set by user * encoding: set by user
@ -754,24 +772,6 @@ typedef struct AVCodecContext {
#define FF_EC_GUESS_MVS 1 #define FF_EC_GUESS_MVS 1
#define FF_EC_DEBLOCK 2 #define FF_EC_DEBLOCK 2
/**
* QP table of the currently decoded frame
* encoding; unused
* decoding: set by lavc
*/
int8_t *current_qscale_table;
/**
* QP table of the currently displayed frame
* encoding; unused
* decoding: set by lavc
*/
int8_t *display_qscale_table;
/**
* force specific pict_type.
* encoding; set by user (I/P/B_TYPE)
* decoding: unused
*/
int force_type;
/** /**
* dsp_mask could be used to disable unwanted * dsp_mask could be used to disable unwanted
* CPU features (i.e. MMX, SSE. ...) * CPU features (i.e. MMX, SSE. ...)
@ -780,14 +780,14 @@ typedef struct AVCodecContext {
/** /**
* bits per sample/pixel from the demuxer (needed for huffyuv) * bits per sample/pixel from the demuxer (needed for huffyuv)
* encoding; set by lavc * encoding: set by lavc
* decoding: set by user * decoding: set by user
*/ */
int bits_per_sample; int bits_per_sample;
/** /**
* prediction method (needed for huffyuv) * prediction method (needed for huffyuv)
* encoding; set by user * encoding: set by user
* decoding: unused * decoding: unused
*/ */
int prediction_method; int prediction_method;
@ -801,6 +801,13 @@ typedef struct AVCodecContext {
* decoding: set by lavc. * decoding: set by lavc.
*/ */
float aspect_ratio; float aspect_ratio;
/**
* the picture in the bitstream
* encoding: set by lavc
* decoding: set by lavc
*/
AVVideoFrame *coded_picture;
} AVCodecContext; } AVCodecContext;
typedef struct AVCodec { typedef struct AVCodec {
@ -928,6 +935,7 @@ void img_resample_close(ImgReSampleContext *s);
void avpicture_fill(AVPicture *picture, UINT8 *ptr, void avpicture_fill(AVPicture *picture, UINT8 *ptr,
int pix_fmt, int width, int height); int pix_fmt, int width, int height);
int avpicture_get_size(int pix_fmt, int width, int height); int avpicture_get_size(int pix_fmt, int width, int height);
void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift);
/* convert among pixel formats */ /* convert among pixel formats */
int img_convert(AVPicture *dst, int dst_pix_fmt, int img_convert(AVPicture *dst, int dst_pix_fmt,
@ -957,12 +965,18 @@ AVCodec *avcodec_find_decoder(enum CodecID id);
AVCodec *avcodec_find_decoder_by_name(const char *name); AVCodec *avcodec_find_decoder_by_name(const char *name);
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
void avcodec_get_context_defaults(AVCodecContext *s);
AVCodecContext *avcodec_alloc_context(void); AVCodecContext *avcodec_alloc_context(void);
AVVideoFrame *avcodec_alloc_picture(void);
int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic);
void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic);
int avcodec_open(AVCodecContext *avctx, AVCodec *codec); int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples, int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples,
int *frame_size_ptr, int *frame_size_ptr,
UINT8 *buf, int buf_size); UINT8 *buf, int buf_size);
int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, int avcodec_decode_video(AVCodecContext *avctx, AVVideoFrame *picture,
int *got_picture_ptr, int *got_picture_ptr,
UINT8 *buf, int buf_size); UINT8 *buf, int buf_size);
int avcodec_parse_frame(AVCodecContext *avctx, UINT8 **pdata, int avcodec_parse_frame(AVCodecContext *avctx, UINT8 **pdata,
@ -971,7 +985,7 @@ int avcodec_parse_frame(AVCodecContext *avctx, UINT8 **pdata,
int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size, int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size,
const short *samples); const short *samples);
int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
const AVPicture *pict); const AVVideoFrame *pict);
int avcodec_close(AVCodecContext *avctx); int avcodec_close(AVCodecContext *avctx);

View File

@ -33,6 +33,7 @@ typedef struct DVVideoDecodeContext {
int sampling_411; /* 0 = 420, 1 = 411 */ int sampling_411; /* 0 = 420, 1 = 411 */
int width, height; int width, height;
UINT8 *current_picture[3]; /* picture structure */ UINT8 *current_picture[3]; /* picture structure */
AVVideoFrame picture;
int linesize[3]; int linesize[3];
DCTELEM block[5*6][64] __align8; DCTELEM block[5*6][64] __align8;
UINT8 dv_zigzag[2][64]; UINT8 dv_zigzag[2][64];
@ -499,7 +500,6 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
unsigned size; unsigned size;
UINT8 *buf_ptr; UINT8 *buf_ptr;
const UINT16 *mb_pos_ptr; const UINT16 *mb_pos_ptr;
AVPicture *picture;
/* parse id */ /* parse id */
init_get_bits(&s->gb, buf, buf_size); init_get_bits(&s->gb, buf, buf_size);
@ -561,45 +561,20 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
avctx->width = width; avctx->width = width;
avctx->height = height; avctx->height = height;
if (avctx->flags & CODEC_FLAG_DR1) s->picture.reference= 0;
{ if(avctx->get_buffer(avctx, &s->picture) < 0) {
s->width = -1;
avctx->dr_buffer[0] = avctx->dr_buffer[1] = avctx->dr_buffer[2] = 0;
if(avctx->get_buffer_callback(avctx, width, height, I_TYPE) < 0
&& avctx->flags & CODEC_FLAG_DR1) {
fprintf(stderr, "get_buffer() failed\n"); fprintf(stderr, "get_buffer() failed\n");
return -1; return -1;
} }
}
/* (re)alloc picture if needed */
if (s->width != width || s->height != height) {
if (!(avctx->flags & CODEC_FLAG_DR1))
for(i=0;i<3;i++) {
if (avctx->dr_buffer[i] != s->current_picture[i])
av_freep(&s->current_picture[i]);
avctx->dr_buffer[i] = 0;
}
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
if (avctx->dr_buffer[i]) { s->current_picture[i] = s->picture.data[i];
s->current_picture[i] = avctx->dr_buffer[i]; s->linesize[i] = s->picture.linesize[i];
s->linesize[i] = (i == 0) ? avctx->dr_stride : avctx->dr_uvstride;
} else {
size = width * height;
s->linesize[i] = width;
if (i >= 1) {
size >>= 2;
s->linesize[i] >>= s->sampling_411 ? 2 : 1;
}
s->current_picture[i] = av_malloc(size);
}
if (!s->current_picture[i]) if (!s->current_picture[i])
return -1; return -1;
} }
s->width = width; s->width = width;
s->height = height; s->height = height;
}
/* for each DIF segment */ /* for each DIF segment */
buf_ptr = buf; buf_ptr = buf;
@ -620,12 +595,11 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
emms_c(); emms_c();
/* return image */ /* return image */
*data_size = sizeof(AVPicture); *data_size = sizeof(AVVideoFrame);
picture = data; *(AVVideoFrame*)data= s->picture;
for(i=0;i<3;i++) {
picture->data[i] = s->current_picture[i]; avctx->release_buffer(avctx, &s->picture);
picture->linesize[i] = s->linesize[i];
}
return packet_size; return packet_size;
} }
@ -634,9 +608,14 @@ static int dvvideo_decode_end(AVCodecContext *avctx)
DVVideoDecodeContext *s = avctx->priv_data; DVVideoDecodeContext *s = avctx->priv_data;
int i; int i;
for(i=0;i<3;i++) if(avctx->get_buffer == avcodec_default_get_buffer){
if (avctx->dr_buffer[i] != s->current_picture[i]) for(i=0; i<4; i++){
av_freep(&s->current_picture[i]); av_freep(&s->picture.base[i]);
s->picture.data[i]= NULL;
}
av_freep(&s->picture.opaque);
}
return 0; return 0;
} }

View File

@ -464,7 +464,7 @@ int score_sum=0;
s->mb_y= mb_y; s->mb_y= mb_y;
for(j=0; j<pred_count; j++){ for(j=0; j<pred_count; j++){
int score=0; int score=0;
UINT8 *src= s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; UINT8 *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
@ -556,8 +556,8 @@ static int is_intra_more_likely(MpegEncContext *s){
if((j%skip_amount) != 0) continue; //skip a few to speed things up if((j%skip_amount) != 0) continue; //skip a few to speed things up
if(s->pict_type==I_TYPE){ if(s->pict_type==I_TYPE){
UINT8 *mb_ptr = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; UINT8 *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
UINT8 *last_mb_ptr= s->last_picture [0] + mb_x*16 + mb_y*16*s->linesize; UINT8 *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr , s->linesize); is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr , s->linesize);
is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize); is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize);
@ -802,9 +802,9 @@ void ff_error_resilience(MpegEncContext *s){
if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
// if(error&MV_ERROR) continue; //inter data damaged FIXME is this good? // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
dest_cb= s->current_picture[1] + mb_x*8 + mb_y*8 *s->uvlinesize; dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
dest_cr= s->current_picture[2] + mb_x*8 + mb_y*8 *s->uvlinesize; dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
dc_ptr= &s->dc_val[0][mb_x*2+1 + (mb_y*2+1)*(s->mb_width*2+2)]; dc_ptr= &s->dc_val[0][mb_x*2+1 + (mb_y*2+1)*(s->mb_width*2+2)];
for(n=0; n<4; n++){ for(n=0; n<4; n++){
@ -852,9 +852,9 @@ void ff_error_resilience(MpegEncContext *s){
if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter
if(!(error&AC_ERROR)) continue; //undamaged if(!(error&AC_ERROR)) continue; //undamaged
dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
dest_cb= s->current_picture[1] + mb_x*8 + mb_y*8 *s->uvlinesize; dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
dest_cr= s->current_picture[2] + mb_x*8 + mb_y*8 *s->uvlinesize; dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
} }
@ -863,14 +863,14 @@ void ff_error_resilience(MpegEncContext *s){
if(s->avctx->error_concealment&FF_EC_DEBLOCK){ if(s->avctx->error_concealment&FF_EC_DEBLOCK){
/* filter horizontal block boundaries */ /* filter horizontal block boundaries */
h_block_filter(s, s->current_picture[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
h_block_filter(s, s->current_picture[1], s->mb_width , s->mb_height , s->uvlinesize, 0); h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
h_block_filter(s, s->current_picture[2], s->mb_width , s->mb_height , s->uvlinesize, 0); h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
/* filter vertical block boundaries */ /* filter vertical block boundaries */
v_block_filter(s, s->current_picture[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
v_block_filter(s, s->current_picture[1], s->mb_width , s->mb_height , s->uvlinesize, 0); v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
v_block_filter(s, s->current_picture[2], s->mb_width , s->mb_height , s->uvlinesize, 0); v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
} }
/* clean a few tables */ /* clean a few tables */

View File

@ -272,6 +272,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d
{ {
int score0=0, score1=0; int score0=0, score1=0;
int i, n; int i, n;
int8_t * const qscale_table= s->current_picture.qscale_table;
for(n=0; n<6; n++){ for(n=0; n<6; n++){
INT16 *ac_val, *ac_val1; INT16 *ac_val, *ac_val1;
@ -282,7 +283,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d
const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width;
/* top prediction */ /* top prediction */
ac_val-= s->block_wrap[n]*16; ac_val-= s->block_wrap[n]*16;
if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
/* same qscale */ /* same qscale */
for(i=1; i<8; i++){ for(i=1; i<8; i++){
const int level= block[n][s->idct_permutation[i ]]; const int level= block[n][s->idct_permutation[i ]];
@ -296,7 +297,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d
for(i=1; i<8; i++){ for(i=1; i<8; i++){
const int level= block[n][s->idct_permutation[i ]]; const int level= block[n][s->idct_permutation[i ]];
score0+= ABS(level); score0+= ABS(level);
score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale)); score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale));
ac_val1[i ]= block[n][s->idct_permutation[i<<3]]; ac_val1[i ]= block[n][s->idct_permutation[i<<3]];
ac_val1[i+8]= level; ac_val1[i+8]= level;
} }
@ -305,7 +306,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d
const int xy= s->mb_x-1 + s->mb_y*s->mb_width; const int xy= s->mb_x-1 + s->mb_y*s->mb_width;
/* left prediction */ /* left prediction */
ac_val-= 16; ac_val-= 16;
if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
/* same qscale */ /* same qscale */
for(i=1; i<8; i++){ for(i=1; i<8; i++){
const int level= block[n][s->idct_permutation[i<<3]]; const int level= block[n][s->idct_permutation[i<<3]];
@ -319,7 +320,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d
for(i=1; i<8; i++){ for(i=1; i<8; i++){
const int level= block[n][s->idct_permutation[i<<3]]; const int level= block[n][s->idct_permutation[i<<3]];
score0+= ABS(level); score0+= ABS(level);
score1+= ABS(level - ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale)); score1+= ABS(level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale));
ac_val1[i ]= level; ac_val1[i ]= level;
ac_val1[i+8]= block[n][s->idct_permutation[i ]]; ac_val1[i+8]= block[n][s->idct_permutation[i ]];
} }
@ -335,14 +336,15 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d
*/ */
void ff_clean_h263_qscales(MpegEncContext *s){ void ff_clean_h263_qscales(MpegEncContext *s){
int i; int i;
int8_t * const qscale_table= s->current_picture.qscale_table;
for(i=1; i<s->mb_num; i++){ for(i=1; i<s->mb_num; i++){
if(s->qscale_table[i] - s->qscale_table[i-1] >2) if(qscale_table[i] - qscale_table[i-1] >2)
s->qscale_table[i]= s->qscale_table[i-1]+2; qscale_table[i]= qscale_table[i-1]+2;
} }
for(i=s->mb_num-2; i>=0; i--){ for(i=s->mb_num-2; i>=0; i--){
if(s->qscale_table[i] - s->qscale_table[i+1] >2) if(qscale_table[i] - qscale_table[i+1] >2)
s->qscale_table[i]= s->qscale_table[i+1]+2; qscale_table[i]= qscale_table[i+1]+2;
} }
} }
@ -351,11 +353,12 @@ void ff_clean_h263_qscales(MpegEncContext *s){
*/ */
void ff_clean_mpeg4_qscales(MpegEncContext *s){ void ff_clean_mpeg4_qscales(MpegEncContext *s){
int i; int i;
int8_t * const qscale_table= s->current_picture.qscale_table;
ff_clean_h263_qscales(s); ff_clean_h263_qscales(s);
for(i=1; i<s->mb_num; i++){ for(i=1; i<s->mb_num; i++){
if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){ if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){
s->mb_type[i]&= ~MB_TYPE_INTER4V; s->mb_type[i]&= ~MB_TYPE_INTER4V;
s->mb_type[i]|= MB_TYPE_INTER; s->mb_type[i]|= MB_TYPE_INTER;
} }
@ -367,21 +370,21 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){
for the actual adaptive quantization */ for the actual adaptive quantization */
for(i=0; i<s->mb_num; i++){ for(i=0; i<s->mb_num; i++){
odd += s->qscale_table[i]&1; odd += qscale_table[i]&1;
} }
if(2*odd > s->mb_num) odd=1; if(2*odd > s->mb_num) odd=1;
else odd=0; else odd=0;
for(i=0; i<s->mb_num; i++){ for(i=0; i<s->mb_num; i++){
if((s->qscale_table[i]&1) != odd) if((qscale_table[i]&1) != odd)
s->qscale_table[i]++; qscale_table[i]++;
if(s->qscale_table[i] > 31) if(qscale_table[i] > 31)
s->qscale_table[i]= 31; qscale_table[i]= 31;
} }
for(i=1; i<s->mb_num; i++){ for(i=1; i<s->mb_num; i++){
if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){ if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){
s->mb_type[i]&= ~MB_TYPE_DIRECT; s->mb_type[i]&= ~MB_TYPE_DIRECT;
s->mb_type[i]|= MB_TYPE_BIDIR; s->mb_type[i]|= MB_TYPE_BIDIR;
} }
@ -427,7 +430,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
assert(mb_type>=0); assert(mb_type>=0);
/* nothing to do if this MB was skiped in the next P Frame */ /* nothing to do if this MB was skiped in the next P Frame */
if(s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ... if(s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ...
s->skip_count++; s->skip_count++;
s->mv[0][0][0]= s->mv[0][0][0]=
s->mv[0][0][1]= s->mv[0][0][1]=
@ -435,6 +438,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
s->mv[1][0][1]= 0; s->mv[1][0][1]= 0;
s->mv_dir= MV_DIR_FORWARD; //doesnt matter s->mv_dir= MV_DIR_FORWARD; //doesnt matter
s->qscale -= s->dquant; s->qscale -= s->dquant;
// s->mb_skiped=1;
return; return;
} }
@ -451,6 +456,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
s->skip_count++; s->skip_count++;
return; return;
} }
put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */
put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge
put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we dont need it :) put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we dont need it :)
@ -547,16 +553,17 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(y+16 > s->height) y= s->height-16; if(y+16 > s->height) y= s->height-16;
offset= x + y*s->linesize; offset= x + y*s->linesize;
p_pic= s->new_picture[0] + offset; p_pic= s->new_picture.data[0] + offset;
s->mb_skiped=1; s->mb_skiped=1;
for(i=0; i<s->max_b_frames; i++){ for(i=0; i<s->max_b_frames; i++){
uint8_t *b_pic; uint8_t *b_pic;
int diff; int diff;
Picture *pic= s->reordered_input_picture[i+1];
if(s->coded_order[i+1].pict_type!=B_TYPE) break; if(pic==NULL || pic->pict_type!=B_TYPE) break;
b_pic= s->coded_order[i+1].picture[0] + offset; b_pic= pic->data[0] + offset + 16; //FIXME +16
diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize); diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize);
if(diff>s->qscale*70){ //FIXME check that 70 is optimal if(diff>s->qscale*70){ //FIXME check that 70 is optimal
s->mb_skiped=0; s->mb_skiped=0;
@ -1493,8 +1500,8 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){
s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
} }
if(s->avctx->pts) if(s->current_picture.pts)
s->time= (s->avctx->pts*s->time_increment_resolution + 500*1000)/(1000*1000); s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000);
else else
s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate;
time_div= s->time/s->time_increment_resolution; time_div= s->time/s->time_increment_resolution;
@ -1736,6 +1743,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
{ {
int i; int i;
INT16 *ac_val, *ac_val1; INT16 *ac_val, *ac_val1;
int8_t * const qscale_table= s->current_picture.qscale_table;
/* find prediction */ /* find prediction */
ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
@ -1746,7 +1754,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
/* left prediction */ /* left prediction */
ac_val -= 16; ac_val -= 16;
if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
/* same qscale */ /* same qscale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i<<3]] += ac_val[i]; block[s->idct_permutation[i<<3]] += ac_val[i];
@ -1754,7 +1762,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
}else{ }else{
/* different qscale, we must rescale */ /* different qscale, we must rescale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale); block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
} }
} }
} else { } else {
@ -1762,7 +1770,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
/* top prediction */ /* top prediction */
ac_val -= 16 * s->block_wrap[n]; ac_val -= 16 * s->block_wrap[n];
if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
/* same qscale */ /* same qscale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i]] += ac_val[i + 8]; block[s->idct_permutation[i]] += ac_val[i + 8];
@ -1770,7 +1778,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
}else{ }else{
/* different qscale, we must rescale */ /* different qscale, we must rescale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale); block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
} }
} }
} }
@ -1790,6 +1798,7 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,
{ {
int i; int i;
INT16 *ac_val; INT16 *ac_val;
int8_t * const qscale_table= s->current_picture.qscale_table;
/* find prediction */ /* find prediction */
ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
@ -1798,7 +1807,7 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,
const int xy= s->mb_x-1 + s->mb_y*s->mb_width; const int xy= s->mb_x-1 + s->mb_y*s->mb_width;
/* left prediction */ /* left prediction */
ac_val -= 16; ac_val -= 16;
if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
/* same qscale */ /* same qscale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i<<3]] -= ac_val[i]; block[s->idct_permutation[i<<3]] -= ac_val[i];
@ -1806,14 +1815,14 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,
}else{ }else{
/* different qscale, we must rescale */ /* different qscale, we must rescale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale); block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
} }
} }
} else { } else {
const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width;
/* top prediction */ /* top prediction */
ac_val -= 16 * s->block_wrap[n]; ac_val -= 16 * s->block_wrap[n];
if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
/* same qscale */ /* same qscale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i]] -= ac_val[i + 8]; block[s->idct_permutation[i]] -= ac_val[i + 8];
@ -1821,7 +1830,7 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,
}else{ }else{
/* different qscale, we must rescale */ /* different qscale, we must rescale */
for(i=1;i<8;i++) { for(i=1;i<8;i++) {
block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale); block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
} }
} }
} }
@ -2532,7 +2541,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
if(cbpc & 4) { if(cbpc & 4) {
change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
} }
s->qscale_table[xy]= s->qscale; s->current_picture.qscale_table[xy]= s->qscale;
s->mbintra_table[xy]= 1; s->mbintra_table[xy]= 1;
for(i=0; i<6; i++){ for(i=0; i<6; i++){
@ -2704,7 +2713,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
if(s->cbp_table[xy] & 8) { if(s->cbp_table[xy] & 8) {
change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
} }
s->qscale_table[xy]= s->qscale; s->current_picture.qscale_table[xy]= s->qscale;
for(i=0; i<6; i++){ for(i=0; i<6; i++){
int dc_pred_dir; int dc_pred_dir;
@ -2721,7 +2730,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
s->pred_dir_table[xy]= dir | (ac_pred<<7); s->pred_dir_table[xy]= dir | (ac_pred<<7);
s->error_status_table[xy]&= ~DC_ERROR; s->error_status_table[xy]&= ~DC_ERROR;
}else if(s->mb_type[xy]&MB_TYPE_SKIPED){ }else if(s->mb_type[xy]&MB_TYPE_SKIPED){
s->qscale_table[xy]= s->qscale; s->current_picture.qscale_table[xy]= s->qscale;
s->cbp_table[xy]= 0; s->cbp_table[xy]= 0;
}else{ }else{
int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
@ -2734,7 +2743,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
if(s->cbp_table[xy] & 8) { if(s->cbp_table[xy] & 8) {
change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
} }
s->qscale_table[xy]= s->qscale; s->current_picture.qscale_table[xy]= s->qscale;
s->cbp_table[xy]&= 3; //remove dquant s->cbp_table[xy]&= 3; //remove dquant
s->cbp_table[xy]|= (cbpy^0xf)<<2; s->cbp_table[xy]|= (cbpy^0xf)<<2;
@ -2801,8 +2810,8 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
mb_type= s->mb_type[xy]; mb_type= s->mb_type[xy];
cbp = s->cbp_table[xy]; cbp = s->cbp_table[xy];
if(s->qscale_table[xy] != s->qscale){ if(s->current_picture.qscale_table[xy] != s->qscale){
s->qscale= s->qscale_table[xy]; s->qscale= s->current_picture.qscale_table[xy];
s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ];
s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];
} }
@ -3054,7 +3063,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
} }
/* if we skipped it in the future P Frame than skip it now too */ /* if we skipped it in the future P Frame than skip it now too */
s->mb_skiped= s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC s->mb_skiped= s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC
if(s->mb_skiped){ if(s->mb_skiped){
/* skip mb */ /* skip mb */
@ -3287,7 +3296,7 @@ end:
/* per-MB end of slice check */ /* per-MB end of slice check */
if(s->codec_id==CODEC_ID_MPEG4){ if(s->codec_id==CODEC_ID_MPEG4){
if(mpeg4_is_resync(s)){ if(mpeg4_is_resync(s)){
if(s->pict_type==B_TYPE && s->mbskip_table[s->mb_y * s->mb_width + s->mb_x+1]) if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x+1])
return SLICE_OK; return SLICE_OK;
return SLICE_END; return SLICE_END;
} }
@ -4441,7 +4450,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
} }
s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution; s->current_picture.pts= s->time*1000LL*1000LL / s->time_increment_resolution;
if(check_marker(gb, "before vop_coded")==0 && s->picture_number==0){ if(check_marker(gb, "before vop_coded")==0 && s->picture_number==0){
printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n"); printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n");

View File

@ -199,6 +199,7 @@ static int decode_slice(MpegEncContext *s){
s->mv_dir = MV_DIR_FORWARD; s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16; s->mv_type = MV_TYPE_16X16;
// s->mb_skiped = 0;
//printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24)); //printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24));
ret= s->decode_mb(s, s->block); ret= s->decode_mb(s, s->block);
@ -347,7 +348,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
{ {
MpegEncContext *s = avctx->priv_data; MpegEncContext *s = avctx->priv_data;
int ret,i; int ret,i;
AVPicture *pict = data; AVVideoFrame *pict = data;
float new_aspect; float new_aspect;
#ifdef PRINT_FRAME_TIME #ifdef PRINT_FRAME_TIME
@ -357,7 +358,6 @@ uint64_t time= rdtsc();
printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); 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]); printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
#endif #endif
s->flags= avctx->flags; s->flags= avctx->flags;
*data_size = 0; *data_size = 0;
@ -523,8 +523,9 @@ retry:
return -1; return -1;
} }
s->avctx->key_frame = (s->pict_type == I_TYPE); // for hurry_up==5
s->avctx->pict_type = s->pict_type; s->current_picture.pict_type= s->pict_type;
s->current_picture.key_frame= s->pict_type == I_TYPE;
/* skip b frames if we dont have reference frames */ /* skip b frames if we dont have reference frames */
if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size); if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
@ -580,7 +581,9 @@ retry:
} }
if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE)
if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1; if(msmpeg4_decode_ext_header(s, buf_size) < 0){
s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR;
}
/* divx 5.01+ bistream reorder stuff */ /* divx 5.01+ bistream reorder stuff */
if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){ if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){
@ -644,7 +647,7 @@ retry:
int y= mb_y*16 + 8; int y= mb_y*16 + 8;
for(mb_x=0; mb_x<s->mb_width; mb_x++){ for(mb_x=0; mb_x<s->mb_width; mb_x++){
int x= mb_x*16 + 8; int x= mb_x*16 + 8;
uint8_t *ptr= s->last_picture[0]; uint8_t *ptr= s->last_picture.data[0];
int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2); int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2);
int mx= (s->motion_val[xy][0]>>1) + x; int mx= (s->motion_val[xy][0]>>1) + x;
int my= (s->motion_val[xy][1]>>1) + y; int my= (s->motion_val[xy][1]>>1) + y;
@ -671,19 +674,10 @@ retry:
} }
#endif #endif
if(s->pict_type==B_TYPE || (!s->has_b_frames)){ if(s->pict_type==B_TYPE || (!s->has_b_frames)){
pict->data[0] = s->current_picture[0]; *pict= *(AVVideoFrame*)&s->current_picture;
pict->data[1] = s->current_picture[1];
pict->data[2] = s->current_picture[2];
} else { } else {
pict->data[0] = s->last_picture[0]; *pict= *(AVVideoFrame*)&s->last_picture;
pict->data[1] = s->last_picture[1];
pict->data[2] = s->last_picture[2];
} }
pict->linesize[0] = s->linesize;
pict->linesize[1] = s->uvlinesize;
pict->linesize[2] = s->uvlinesize;
avctx->quality = s->qscale;
/* Return the Picture timestamp as the frame number */ /* Return the Picture timestamp as the frame number */
/* we substract 1 because it is added on utils.c */ /* we substract 1 because it is added on utils.c */
@ -692,7 +686,7 @@ retry:
/* dont output the last pic after seeking /* dont output the last pic after seeking
note we allready added +1 for the current pix in MPV_frame_end(s) */ note we allready added +1 for the current pix in MPV_frame_end(s) */
if(s->num_available_buffers>=2 || (!s->has_b_frames)) if(s->num_available_buffers>=2 || (!s->has_b_frames))
*data_size = sizeof(AVPicture); *data_size = sizeof(AVVideoFrame);
#ifdef PRINT_FRAME_TIME #ifdef PRINT_FRAME_TIME
printf("%Ld\n", rdtsc()-time); printf("%Ld\n", rdtsc()-time);
#endif #endif

View File

@ -52,13 +52,12 @@ typedef struct HYuvContext{
int flags; int flags;
int picture_number; int picture_number;
int last_slice_end; int last_slice_end;
int linesize[3];
uint8_t __align8 temp[3][2500]; uint8_t __align8 temp[3][2500];
uint64_t stats[3][256]; uint64_t stats[3][256];
uint8_t len[3][256]; uint8_t len[3][256];
uint32_t bits[3][256]; uint32_t bits[3][256];
VLC vlc[3]; VLC vlc[3];
uint8_t __align8 *picture[3]; AVVideoFrame picture;
uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
DSPContext dsp; DSPContext dsp;
}HYuvContext; }HYuvContext;
@ -324,7 +323,7 @@ static int read_old_huffman_tables(HYuvContext *s){
static int decode_init(AVCodecContext *avctx) static int decode_init(AVCodecContext *avctx)
{ {
HYuvContext *s = avctx->priv_data; HYuvContext *s = avctx->priv_data;
int width, height, y_size, c_size, stride; int width, height;
s->avctx= avctx; s->avctx= avctx;
s->flags= avctx->flags; s->flags= avctx->flags;
@ -333,6 +332,8 @@ static int decode_init(AVCodecContext *avctx)
width= s->width= avctx->width; width= s->width= avctx->width;
height= s->height= avctx->height; height= s->height= avctx->height;
avctx->coded_picture= &s->picture;
s->bgr32=1; s->bgr32=1;
assert(width && height); assert(width && height);
//if(avctx->extradata) //if(avctx->extradata)
@ -388,52 +389,27 @@ s->bgr32=1;
s->interlaced= height > 288; s->interlaced= height > 288;
c_size= 0;
switch(s->bitstream_bpp){ switch(s->bitstream_bpp){
case 12: case 12:
avctx->pix_fmt = PIX_FMT_YUV420P; avctx->pix_fmt = PIX_FMT_YUV420P;
stride= (width+15)&~15;
c_size= height*stride/4;
break; break;
case 16: case 16:
if(s->yuy2){ if(s->yuy2){
avctx->pix_fmt = PIX_FMT_YUV422; avctx->pix_fmt = PIX_FMT_YUV422;
stride= (width*2+15)&~15;
}else{ }else{
avctx->pix_fmt = PIX_FMT_YUV422P; avctx->pix_fmt = PIX_FMT_YUV422P;
stride= (width+15)&~15;
c_size= height*stride/2;
} }
break; break;
case 24: case 24:
case 32: case 32:
if(s->bgr32){ if(s->bgr32){
avctx->pix_fmt = PIX_FMT_BGRA32; avctx->pix_fmt = PIX_FMT_BGRA32;
stride= (width*4+15)&~15;
}else{ }else{
avctx->pix_fmt = PIX_FMT_BGR24; avctx->pix_fmt = PIX_FMT_BGR24;
stride= (width*3+15)&~15;
} }
break; break;
default: default:
assert(0); assert(0);
stride=0; //gcc fix
}
y_size= height*stride;
if(!(avctx->flags&CODEC_FLAG_DR1)){
s->linesize[0]= stride;
s->picture[0]= av_mallocz(y_size);
if(c_size){
s->picture[1]= av_mallocz(c_size);
s->picture[2]= av_mallocz(c_size);
s->linesize[1]= s->linesize[2]= stride/2;
memset(s->picture[1], 128, c_size);
memset(s->picture[2], 128, c_size);
}
} }
// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
@ -484,6 +460,10 @@ static int encode_init(AVCodecContext *avctx)
avctx->stats_out= av_mallocz(1024*10); avctx->stats_out= av_mallocz(1024*10);
s->version=2; s->version=2;
avctx->coded_picture= &s->picture;
s->picture.pict_type= I_TYPE;
s->picture.key_frame= 1;
switch(avctx->pix_fmt){ switch(avctx->pix_fmt){
case PIX_FMT_YUV420P: case PIX_FMT_YUV420P:
if(avctx->strict_std_compliance>=0){ if(avctx->strict_std_compliance>=0){
@ -674,12 +654,12 @@ static void draw_slice(HYuvContext *s, int y){
cy= y; cy= y;
} }
src_ptr[0] = s->picture[0] + s->linesize[0]*y; src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y;
src_ptr[1] = s->picture[1] + s->linesize[1]*cy; src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy;
src_ptr[2] = s->picture[2] + s->linesize[2]*cy; src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy;
emms_c(); emms_c();
s->avctx->draw_horiz_band(s->avctx, src_ptr, s->linesize[0], y, s->width, h); s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h);
s->last_slice_end= y + h; s->last_slice_end= y + h;
} }
@ -690,9 +670,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
const int width2= s->width>>1; const int width2= s->width>>1;
const int height= s->height; const int height= s->height;
int fake_ystride, fake_ustride, fake_vstride; int fake_ystride, fake_ustride, fake_vstride;
int i; AVVideoFrame * const p= &s->picture;
AVPicture *picture = data; AVVideoFrame *picture = data;
*data_size = 0; *data_size = 0;
@ -704,22 +684,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
init_get_bits(&s->gb, s->bitstream_buffer, buf_size); init_get_bits(&s->gb, s->bitstream_buffer, buf_size);
if(avctx->flags&CODEC_FLAG_DR1){ p->reference= 0;
if(avctx->get_buffer_callback(avctx, s->width, s->height, I_TYPE) < 0){ if(avctx->get_buffer(avctx, p) < 0){
fprintf(stderr, "get_buffer() failed\n"); fprintf(stderr, "get_buffer() failed\n");
return -1; return -1;
} }
s->linesize[0]= avctx->dr_stride; fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
s->linesize[1]= fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
s->linesize[2]= avctx->dr_uvstride; fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
for(i=0; i<3;i++)
s->picture[i]= avctx->dr_buffer[i];
}
fake_ystride= s->interlaced ? s->linesize[0]*2 : s->linesize[0];
fake_ustride= s->interlaced ? s->linesize[1]*2 : s->linesize[1];
fake_vstride= s->interlaced ? s->linesize[2]*2 : s->linesize[2];
s->last_slice_end= 0; s->last_slice_end= 0;
@ -729,28 +702,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
int lefttopy, lefttopu, lefttopv; int lefttopy, lefttopu, lefttopv;
if(s->yuy2){ if(s->yuy2){
s->picture[0][3]= get_bits(&s->gb, 8); p->data[0][3]= get_bits(&s->gb, 8);
s->picture[0][2]= get_bits(&s->gb, 8); p->data[0][2]= get_bits(&s->gb, 8);
s->picture[0][1]= get_bits(&s->gb, 8); p->data[0][1]= get_bits(&s->gb, 8);
s->picture[0][0]= get_bits(&s->gb, 8); p->data[0][0]= get_bits(&s->gb, 8);
fprintf(stderr, "YUY2 output isnt implemenetd yet\n"); fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
return -1; return -1;
}else{ }else{
leftv= s->picture[2][0]= get_bits(&s->gb, 8); leftv= p->data[2][0]= get_bits(&s->gb, 8);
lefty= s->picture[0][1]= get_bits(&s->gb, 8); lefty= p->data[0][1]= get_bits(&s->gb, 8);
leftu= s->picture[1][0]= get_bits(&s->gb, 8); leftu= p->data[1][0]= get_bits(&s->gb, 8);
s->picture[0][0]= get_bits(&s->gb, 8); p->data[0][0]= get_bits(&s->gb, 8);
switch(s->predictor){ switch(s->predictor){
case LEFT: case LEFT:
case PLANE: case PLANE:
decode_422_bitstream(s, width-2); decode_422_bitstream(s, width-2);
lefty= add_left_prediction(s->picture[0] + 2, s->temp[0], width-2, lefty); lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu); leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
} }
for(cy=y=1; y<s->height; y++,cy++){ for(cy=y=1; y<s->height; y++,cy++){
@ -759,7 +732,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
if(s->bitstream_bpp==12){ if(s->bitstream_bpp==12){
decode_gray_bitstream(s, width); decode_gray_bitstream(s, width);
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
lefty= add_left_prediction(ydst, s->temp[0], width, lefty); lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
if(s->predictor == PLANE){ if(s->predictor == PLANE){
@ -772,12 +745,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
draw_slice(s, y); draw_slice(s, y);
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
udst= s->picture[1] + s->linesize[1]*cy; udst= p->data[1] + p->linesize[1]*cy;
vdst= s->picture[2] + s->linesize[2]*cy; vdst= p->data[2] + p->linesize[2]*cy;
decode_422_bitstream(s, width); decode_422_bitstream(s, width);
lefty= add_left_prediction(ydst, s->temp[0], width, lefty); lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
leftu= add_left_prediction(udst, s->temp[1], width2, leftu); leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
@ -799,10 +771,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
case MEDIAN: case MEDIAN:
/* first line except first 2 pixels is left predicted */ /* first line except first 2 pixels is left predicted */
decode_422_bitstream(s, width-2); decode_422_bitstream(s, width-2);
lefty= add_left_prediction(s->picture[0] + 2, s->temp[0], width-2, lefty); lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu); leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
} }
cy=y=1; cy=y=1;
@ -810,31 +782,31 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
/* second line is left predicted for interlaced case */ /* second line is left predicted for interlaced case */
if(s->interlaced){ if(s->interlaced){
decode_422_bitstream(s, width); decode_422_bitstream(s, width);
lefty= add_left_prediction(s->picture[0] + s->linesize[0], s->temp[0], width, lefty); lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
leftu= add_left_prediction(s->picture[1] + s->linesize[2], s->temp[1], width2, leftu); leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
leftv= add_left_prediction(s->picture[2] + s->linesize[1], s->temp[2], width2, leftv); leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
} }
y++; cy++; y++; cy++;
} }
/* next 4 pixels are left predicted too */ /* next 4 pixels are left predicted too */
decode_422_bitstream(s, 4); decode_422_bitstream(s, 4);
lefty= add_left_prediction(s->picture[0] + fake_ystride, s->temp[0], 4, lefty); lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
leftu= add_left_prediction(s->picture[1] + fake_ustride, s->temp[1], 2, leftu); leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
leftv= add_left_prediction(s->picture[2] + fake_vstride, s->temp[2], 2, leftv); leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
} }
/* next line except the first 4 pixels is median predicted */ /* next line except the first 4 pixels is median predicted */
lefttopy= s->picture[0][3]; lefttopy= p->data[0][3];
decode_422_bitstream(s, width-4); decode_422_bitstream(s, width-4);
add_median_prediction(s->picture[0] + fake_ystride+4, s->picture[0]+4, s->temp[0], width-4, &lefty, &lefttopy); add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
lefttopu= s->picture[1][1]; lefttopu= p->data[1][1];
lefttopv= s->picture[2][1]; lefttopv= p->data[2][1];
add_median_prediction(s->picture[1] + fake_ustride+2, s->picture[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
add_median_prediction(s->picture[2] + fake_vstride+2, s->picture[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
} }
y++; cy++; y++; cy++;
@ -844,7 +816,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
if(s->bitstream_bpp==12){ if(s->bitstream_bpp==12){
while(2*cy > y){ while(2*cy > y){
decode_gray_bitstream(s, width); decode_gray_bitstream(s, width);
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
y++; y++;
} }
@ -854,9 +826,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
decode_422_bitstream(s, width); decode_422_bitstream(s, width);
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
udst= s->picture[1] + s->linesize[1]*cy; udst= p->data[1] + p->linesize[1]*cy;
vdst= s->picture[2] + s->linesize[2]*cy; vdst= p->data[2] + p->linesize[2]*cy;
add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
if(!(s->flags&CODEC_FLAG_GRAY)){ if(!(s->flags&CODEC_FLAG_GRAY)){
@ -872,17 +844,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
}else{ }else{
int y; int y;
int leftr, leftg, leftb; int leftr, leftg, leftb;
const int last_line= (height-1)*s->linesize[0]; const int last_line= (height-1)*p->linesize[0];
if(s->bitstream_bpp==32){ if(s->bitstream_bpp==32){
s->picture[0][last_line+3]= get_bits(&s->gb, 8); p->data[0][last_line+3]= get_bits(&s->gb, 8);
leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8); leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8); leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8); leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
}else{ }else{
leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8); leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8); leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8); leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
skip_bits(&s->gb, 8); skip_bits(&s->gb, 8);
} }
@ -891,16 +863,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
case LEFT: case LEFT:
case PLANE: case PLANE:
decode_bgr_bitstream(s, width-1); decode_bgr_bitstream(s, width-1);
add_left_prediction_bgr32(s->picture[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
for(y=s->height-2; y>=0; y--){ //yes its stored upside down for(y=s->height-2; y>=0; y--){ //yes its stored upside down
decode_bgr_bitstream(s, width); decode_bgr_bitstream(s, width);
add_left_prediction_bgr32(s->picture[0] + s->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
if(s->predictor == PLANE){ if(s->predictor == PLANE){
if((y&s->interlaced)==0){ if((y&s->interlaced)==0){
s->dsp.add_bytes(s->picture[0] + s->linesize[0]*y, s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
s->picture[0] + s->linesize[0]*y + fake_ystride, fake_ystride); p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
} }
} }
} }
@ -917,12 +889,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
} }
emms_c(); emms_c();
for(i=0;i<3;i++) { *picture= *p;
picture->data[i] = s->picture[i];
picture->linesize[i]= s->linesize[i];
}
*data_size = sizeof(AVPicture); avctx->release_buffer(avctx, p);
*data_size = sizeof(AVVideoFrame);
return (get_bits_count(&s->gb)+7)>>3; return (get_bits_count(&s->gb)+7)>>3;
} }
@ -933,44 +904,47 @@ static int decode_end(AVCodecContext *avctx)
int i; int i;
for(i=0; i<3; i++){ for(i=0; i<3; i++){
if(!(avctx->flags&CODEC_FLAG_DR1))
av_freep(&s->picture[i]);
free_vlc(&s->vlc[i]); free_vlc(&s->vlc[i]);
} }
if(avctx->get_buffer == avcodec_default_get_buffer){
for(i=0; i<4; i++){
av_freep(&s->picture.base[i]);
s->picture.data[i]= NULL;
}
av_freep(&s->picture.opaque);
}
return 0; return 0;
} }
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
HYuvContext *s = avctx->priv_data; HYuvContext *s = avctx->priv_data;
AVPicture *pict = data; AVVideoFrame *pict = data;
const int width= s->width; const int width= s->width;
const int width2= s->width>>1; const int width2= s->width>>1;
const int height= s->height; const int height= s->height;
const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
AVVideoFrame * const p= &s->picture;
int i, size; int i, size;
init_put_bits(&s->pb, buf, buf_size, NULL, NULL); init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
for(i=0; i<3; i++){ *p = *pict;
s->picture[i]= pict->data[i];
s->linesize[i]= pict->linesize[i];
}
if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
int lefty, leftu, leftv, y, cy; int lefty, leftu, leftv, y, cy;
put_bits(&s->pb, 8, leftv= s->picture[2][0]); put_bits(&s->pb, 8, leftv= p->data[2][0]);
put_bits(&s->pb, 8, lefty= s->picture[0][1]); put_bits(&s->pb, 8, lefty= p->data[0][1]);
put_bits(&s->pb, 8, leftu= s->picture[1][0]); put_bits(&s->pb, 8, leftu= p->data[1][0]);
put_bits(&s->pb, 8, s->picture[0][0]); put_bits(&s->pb, 8, p->data[0][0]);
lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+2, width-2 , lefty); lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+1, width2-1, leftu); leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+1, width2-1, leftv); leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
encode_422_bitstream(s, width-2); encode_422_bitstream(s, width-2);
@ -978,26 +952,26 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
int lefttopy, lefttopu, lefttopv; int lefttopy, lefttopu, lefttopv;
cy=y=1; cy=y=1;
if(s->interlaced){ if(s->interlaced){
lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+s->linesize[0], width , lefty); lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+s->linesize[1], width2, leftu); leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+s->linesize[2], width2, leftv); leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
encode_422_bitstream(s, width); encode_422_bitstream(s, width);
y++; cy++; y++; cy++;
} }
lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+fake_ystride, 4, lefty); lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+fake_ystride, 2, leftu); leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+fake_ystride, 2, leftv); leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
encode_422_bitstream(s, 4); encode_422_bitstream(s, 4);
lefttopy= s->picture[0][3]; lefttopy= p->data[0][3];
lefttopu= s->picture[1][1]; lefttopu= p->data[1][1];
lefttopv= s->picture[2][1]; lefttopv= p->data[2][1];
sub_median_prediction(s->temp[0], s->picture[0]+4, s->picture[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
sub_median_prediction(s->temp[1], s->picture[1]+2, s->picture[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
sub_median_prediction(s->temp[2], s->picture[2]+2, s->picture[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
encode_422_bitstream(s, width-4); encode_422_bitstream(s, width-4);
y++; cy++; y++; cy++;
@ -1006,16 +980,16 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
if(s->bitstream_bpp==12){ if(s->bitstream_bpp==12){
while(2*cy > y){ while(2*cy > y){
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
encode_gray_bitstream(s, width); encode_gray_bitstream(s, width);
y++; y++;
} }
if(y>=height) break; if(y>=height) break;
} }
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
udst= s->picture[1] + s->linesize[1]*cy; udst= p->data[1] + p->linesize[1]*cy;
vdst= s->picture[2] + s->linesize[2]*cy; vdst= p->data[2] + p->linesize[2]*cy;
sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
@ -1029,7 +1003,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
/* encode a luma only line & y++ */ /* encode a luma only line & y++ */
if(s->bitstream_bpp==12){ if(s->bitstream_bpp==12){
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
if(s->predictor == PLANE && s->interlaced < y){ if(s->predictor == PLANE && s->interlaced < y){
s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
@ -1043,9 +1017,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
if(y>=height) break; if(y>=height) break;
} }
ydst= s->picture[0] + s->linesize[0]*y; ydst= p->data[0] + p->linesize[0]*y;
udst= s->picture[1] + s->linesize[1]*cy; udst= p->data[1] + p->linesize[1]*cy;
vdst= s->picture[2] + s->linesize[2]*cy; vdst= p->data[2] + p->linesize[2]*cy;
if(s->predictor == PLANE && s->interlaced < cy){ if(s->predictor == PLANE && s->interlaced < cy){
s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
@ -1088,9 +1062,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
} }
avctx->key_frame= 1;
avctx->pict_type= I_TYPE;
s->picture_number++; s->picture_number++;
return size*4; return size*4;

View File

@ -1180,9 +1180,11 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
get_bits(&s->gb, 8), get_bits(&s->gb, 8)); get_bits(&s->gb, 8), get_bits(&s->gb, 8));
if (get_bits(&s->gb, 8) == 0) if (get_bits(&s->gb, 8) == 0)
{ {
s->avctx->aspect_ratio_info = FF_ASPECT_EXTENDED; int x_density = get_bits(&s->gb, 16);
s->avctx->aspected_width = get_bits(&s->gb, 16); int y_density = get_bits(&s->gb, 16);
s->avctx->aspected_height = get_bits(&s->gb, 16);
//MN: needs to be checked
s->avctx->aspect_ratio= s->width*y_density/((float)s->height*x_density);
} }
else else
{ {
@ -1468,7 +1470,7 @@ eoi_parser:
} }
/* dummy quality */ /* dummy quality */
/* XXX: infer it with matrix */ /* XXX: infer it with matrix */
avctx->quality = 3; // avctx->quality = 3;
goto the_end; goto the_end;
} }
break; break;
@ -1635,7 +1637,7 @@ read_header:
} }
/* dummy quality */ /* dummy quality */
/* XXX: infer it with matrix */ /* XXX: infer it with matrix */
avctx->quality = 3; // avctx->quality = 3;
return buf_ptr - buf; return buf_ptr - buf;
} }

View File

@ -92,7 +92,7 @@ static int full_motion_search(MpegEncContext * s,
y2 = yy + range - 1; y2 = yy + range - 1;
if (y2 > ymax) if (y2 > ymax)
y2 = ymax; y2 = ymax;
pix = s->new_picture[0] + (yy * s->linesize) + xx; pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
dmin = 0x7fffffff; dmin = 0x7fffffff;
mx = 0; mx = 0;
my = 0; my = 0;
@ -155,7 +155,7 @@ static int log_motion_search(MpegEncContext * s,
if (y2 > ymax) if (y2 > ymax)
y2 = ymax; y2 = ymax;
pix = s->new_picture[0] + (yy * s->linesize) + xx; pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
dmin = 0x7fffffff; dmin = 0x7fffffff;
mx = 0; mx = 0;
my = 0; my = 0;
@ -231,7 +231,7 @@ static int phods_motion_search(MpegEncContext * s,
if (y2 > ymax) if (y2 > ymax)
y2 = ymax; y2 = ymax;
pix = s->new_picture[0] + (yy * s->linesize) + xx; pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
mx = 0; mx = 0;
my = 0; my = 0;
@ -560,7 +560,7 @@ static int epzs_motion_search(MpegEncContext * s,
uint16_t *score_map= s->me_score_map; uint16_t *score_map= s->me_score_map;
int map_generation; int map_generation;
new_pic = s->new_picture[0] + pic_xy; new_pic = s->new_picture.data[0] + pic_xy;
old_pic = ref_picture + pic_xy; old_pic = ref_picture + pic_xy;
map_generation= update_map_generation(s); map_generation= update_map_generation(s);
@ -649,7 +649,7 @@ static int epzs_motion_search4(MpegEncContext * s, int block,
uint16_t *score_map= s->me_score_map; uint16_t *score_map= s->me_score_map;
int map_generation; int map_generation;
new_pic = s->new_picture[0] + pic_xy; new_pic = s->new_picture.data[0] + pic_xy;
old_pic = ref_picture + pic_xy; old_pic = ref_picture + pic_xy;
map_generation= update_map_generation(s); map_generation= update_map_generation(s);
@ -723,7 +723,7 @@ static inline int halfpel_motion_search(MpegEncContext * s,
xx = 16 * s->mb_x + 8*(n&1); xx = 16 * s->mb_x + 8*(n&1);
yy = 16 * s->mb_y + 8*(n>>1); yy = 16 * s->mb_y + 8*(n>>1);
pix = s->new_picture[0] + (yy * s->linesize) + xx; pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
mx = *mx_ptr; mx = *mx_ptr;
my = *my_ptr; my = *my_ptr;
@ -789,7 +789,7 @@ static inline int fast_halfpel_motion_search(MpegEncContext * s,
xx = 16 * s->mb_x + 8*(n&1); xx = 16 * s->mb_x + 8*(n&1);
yy = 16 * s->mb_y + 8*(n>>1); yy = 16 * s->mb_y + 8*(n>>1);
pix = s->new_picture[0] + (yy * s->linesize) + xx; pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
mx = *mx_ptr; mx = *mx_ptr;
my = *my_ptr; my = *my_ptr;
@ -931,7 +931,7 @@ static inline int mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, in
{ {
int block; int block;
int P[10][2]; int P[10][2];
uint8_t *ref_picture= s->last_picture[0]; uint8_t *ref_picture= s->last_picture.data[0];
int dmin_sum=0; int dmin_sum=0;
for(block=0; block<4; block++){ for(block=0; block<4; block++){
@ -1019,7 +1019,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
int P[10][2]; int P[10][2];
const int shift= 1+s->quarter_sample; const int shift= 1+s->quarter_sample;
int mb_type=0; int mb_type=0;
uint8_t *ref_picture= s->last_picture[0]; uint8_t *ref_picture= s->last_picture.data[0];
Picture * const pic= &s->current_picture;
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code); get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);
rel_xmin= xmin - mb_x*16; rel_xmin= xmin - mb_x*16;
@ -1104,7 +1105,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
xx = mb_x * 16; xx = mb_x * 16;
yy = mb_y * 16; yy = mb_y * 16;
pix = s->new_picture[0] + (yy * s->linesize) + xx; pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
/* At this point (mx,my) are full-pell and the relative displacement */ /* At this point (mx,my) are full-pell and the relative displacement */
ppix = ref_picture + ((yy+my) * s->linesize) + (xx+mx); ppix = ref_picture + ((yy+my) * s->linesize) + (xx+mx);
@ -1115,11 +1116,11 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
vard = (s->dsp.pix_norm(pix, ppix, s->linesize)+128)>>8; vard = (s->dsp.pix_norm(pix, ppix, s->linesize)+128)>>8;
//printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); //printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
s->mb_var [s->mb_width * mb_y + mb_x] = varc; pic->mb_var [s->mb_width * mb_y + mb_x] = varc;
s->mc_mb_var[s->mb_width * mb_y + mb_x] = vard; pic->mc_mb_var[s->mb_width * mb_y + mb_x] = vard;
s->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8; pic->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8;
s->mb_var_sum += varc; pic->mb_var_sum += varc;
s->mc_mb_var_sum += vard; pic->mc_mb_var_sum += vard;
//printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); //printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
#if 0 #if 0
@ -1318,7 +1319,7 @@ static inline int check_bidir_mv(MpegEncContext * s,
if (src_y == s->height) if (src_y == s->height)
dxy&= 1; dxy&= 1;
ptr = s->last_picture[0] + (src_y * s->linesize) + src_x; ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x;
s->dsp.put_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); s->dsp.put_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16);
fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale; fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale;
@ -1333,10 +1334,10 @@ static inline int check_bidir_mv(MpegEncContext * s,
if (src_y == s->height) if (src_y == s->height)
dxy&= 1; dxy&= 1;
ptr = s->next_picture[0] + (src_y * s->linesize) + src_x; ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x;
s->dsp.avg_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); s->dsp.avg_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16);
fbmin += s->dsp.pix_abs16x16(s->new_picture[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize); fbmin += s->dsp.pix_abs16x16(s->new_picture.data[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);
return fbmin; return fbmin;
} }
@ -1418,7 +1419,7 @@ static inline int direct_search(MpegEncContext * s,
src_y = clip(src_y, -16, height); src_y = clip(src_y, -16, height);
if (src_y == height) dxy &= ~2; if (src_y == height) dxy &= ~2;
ptr = s->last_picture[0] + (src_y * s->linesize) + src_x; ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x;
s->dsp.put_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); s->dsp.put_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16);
dxy = ((motion_by & 1) << 1) | (motion_bx & 1); dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
@ -1511,8 +1512,8 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
dmin= direct_search(s, mb_x, mb_y); dmin= direct_search(s, mb_x, mb_y);
fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code); fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture.data[0], s->f_code);
bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code) - quant; bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture.data[0], s->b_code) - quant;
//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
fbmin= bidir_refine(s, mb_x, mb_y); fbmin= bidir_refine(s, mb_x, mb_y);
@ -1534,8 +1535,8 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
type= MB_TYPE_BIDIR; type= MB_TYPE_BIDIR;
} }
score= ((unsigned)(score*score + 128*256))>>16; score= ((unsigned)(score*score + 128*256))>>16;
s->mc_mb_var_sum += score; s->current_picture.mc_mb_var_sum += score;
s->mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD s->current_picture.mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD
} }
if(s->flags&CODEC_FLAG_HQ){ if(s->flags&CODEC_FLAG_HQ){
@ -1581,7 +1582,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
int j; int j;
for(j=0; j<fcode && j<8; j++){ for(j=0; j<fcode && j<8; j++){
if(s->pict_type==B_TYPE || s->mc_mb_var[i] < s->mb_var[i]) if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[i] < s->current_picture.mb_var[i])
score[j]-= 170; score[j]-= 170;
} }
} }

View File

@ -134,7 +134,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
int n; int n;
UINT64 time_code; UINT64 time_code;
if (s->picture_in_gop_number == 0) { if (s->current_picture.key_frame) {
/* mpeg1 header repeated every gop */ /* mpeg1 header repeated every gop */
put_header(s, SEQ_START_CODE); put_header(s, SEQ_START_CODE);
@ -1359,7 +1359,6 @@ static int mpeg_decode_init(AVCodecContext *avctx)
s->mpeg_enc_ctx.picture_number = 0; s->mpeg_enc_ctx.picture_number = 0;
s->repeat_field = 0; s->repeat_field = 0;
s->mpeg_enc_ctx.codec_id= avctx->codec->id; s->mpeg_enc_ctx.codec_id= avctx->codec->id;
avctx->mbskip_table= s->mpeg_enc_ctx.mbskip_table;
return 0; return 0;
} }
@ -1403,9 +1402,6 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
s->pict_type = get_bits(&s->gb, 3); s->pict_type = get_bits(&s->gb, 3);
dprintf("pict_type=%d number=%d\n", s->pict_type, s->picture_number); dprintf("pict_type=%d number=%d\n", s->pict_type, s->picture_number);
avctx->pict_type= s->pict_type;
avctx->key_frame= s->pict_type == I_TYPE;
skip_bits(&s->gb, 16); skip_bits(&s->gb, 16);
if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
s->full_pel[0] = get_bits1(&s->gb); s->full_pel[0] = get_bits1(&s->gb);
@ -1423,6 +1419,8 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
s->mpeg_f_code[1][0] = f_code; s->mpeg_f_code[1][0] = f_code;
s->mpeg_f_code[1][1] = f_code; s->mpeg_f_code[1][1] = f_code;
} }
s->current_picture.pict_type= s->pict_type;
s->current_picture.key_frame= s->pict_type == I_TYPE;
s->y_dc_scale = 8; s->y_dc_scale = 8;
s->c_dc_scale = 8; s->c_dc_scale = 8;
s->first_slice = 1; s->first_slice = 1;
@ -1576,7 +1574,7 @@ static void mpeg_decode_extension(AVCodecContext *avctx,
* DECODE_SLICE_EOP if the end of the picture is reached * DECODE_SLICE_EOP if the end of the picture is reached
*/ */
static int mpeg_decode_slice(AVCodecContext *avctx, static int mpeg_decode_slice(AVCodecContext *avctx,
AVPicture *pict, AVVideoFrame *pict,
int start_code, int start_code,
UINT8 *buf, int buf_size) UINT8 *buf, int buf_size)
{ {
@ -1677,38 +1675,25 @@ eos: //end of slice
if (/*s->mb_x == 0 &&*/ if (/*s->mb_x == 0 &&*/
s->mb_y == s->mb_height) { s->mb_y == s->mb_height) {
/* end of image */ /* end of image */
UINT8 **picture;
if(s->mpeg2)
s->qscale >>=1;
MPV_frame_end(s); MPV_frame_end(s);
if (s->pict_type == B_TYPE) { if (s->pict_type == B_TYPE) {
picture = s->current_picture; *pict= *(AVVideoFrame*)&s->current_picture;
avctx->quality = s->qscale;
} else { } else {
s->picture_number++;
/* latency of 1 frame for I and P frames */ /* latency of 1 frame for I and P frames */
/* XXX: use another variable than picture_number */ /* XXX: use another variable than picture_number */
if (s->picture_number == 0) { if (s->picture_number == 1) {
picture = NULL;
} else {
picture = s->last_picture;
avctx->quality = s->last_qscale;
}
s->last_qscale = s->qscale;
s->picture_number++;
}
if(s->mpeg2)
avctx->quality>>=1;
if (picture) {
pict->data[0] = picture[0];
pict->data[1] = picture[1];
pict->data[2] = picture[2];
pict->linesize[0] = s->linesize;
pict->linesize[1] = s->uvlinesize;
pict->linesize[2] = s->uvlinesize;
return DECODE_SLICE_EOP;
} else {
return DECODE_SLICE_OK; return DECODE_SLICE_OK;
} else {
*pict= *(AVVideoFrame*)&s->last_picture;
} }
}
return DECODE_SLICE_EOP;
} else { } else {
return DECODE_SLICE_OK; return DECODE_SLICE_OK;
} }
@ -1827,7 +1812,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
Mpeg1Context *s = avctx->priv_data; Mpeg1Context *s = avctx->priv_data;
UINT8 *buf_end, *buf_ptr, *buf_start; UINT8 *buf_end, *buf_ptr, *buf_start;
int len, start_code_found, ret, code, start_code, input_size; int len, start_code_found, ret, code, start_code, input_size;
AVPicture *picture = data; AVVideoFrame *picture = data;
MpegEncContext *s2 = &s->mpeg_enc_ctx; MpegEncContext *s2 = &s->mpeg_enc_ctx;
dprintf("fill_buffer\n"); dprintf("fill_buffer\n");
@ -1837,13 +1822,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
/* special case for last picture */ /* special case for last picture */
if (buf_size == 0) { if (buf_size == 0) {
if (s2->picture_number > 0) { if (s2->picture_number > 0) {
picture->data[0] = s2->next_picture[0]; *picture= *(AVVideoFrame*)&s2->next_picture;
picture->data[1] = s2->next_picture[1];
picture->data[2] = s2->next_picture[2]; *data_size = sizeof(AVVideoFrame);
picture->linesize[0] = s2->linesize;
picture->linesize[1] = s2->uvlinesize;
picture->linesize[2] = s2->uvlinesize;
*data_size = sizeof(AVPicture);
} }
return 0; return 0;
} }

View File

@ -46,7 +46,6 @@ void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edg
static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h,
int src_x, int src_y, int w, int h); int src_x, int src_y, int w, int h);
#define EDGE_WIDTH 16
/* enable all paranoid tests for rounding, overflows, etc... */ /* enable all paranoid tests for rounding, overflows, etc... */
//#define PARANOID //#define PARANOID
@ -268,10 +267,47 @@ int DCT_common_init(MpegEncContext *s)
return 0; return 0;
} }
/**
* allocates various arrays for a Picture structure, except the pixels themself.
* The pixels are allocated/set in te get_buffer()
*/
static int alloc_picture(MpegEncContext *s, Picture *pic){
if (s->encoding) {
CHECKED_ALLOCZ(pic->mb_var , s->mb_num * sizeof(INT16))
CHECKED_ALLOCZ(pic->mc_mb_var, s->mb_num * sizeof(INT16))
CHECKED_ALLOCZ(pic->mb_mean , s->mb_num * sizeof(INT8))
}
CHECKED_ALLOCZ(pic->mbskip_table , s->mb_num * sizeof(UINT8)+1) //the +1 is for the slice end check
CHECKED_ALLOCZ(pic->qscale_table , s->mb_num * sizeof(UINT8))
pic->qstride= s->mb_width;
return 0;
fail: //for the CHECKED_ALLOCZ macro
return -1;
}
static void free_picture(MpegEncContext *s, Picture *pic){
int i;
av_freep(&pic->mb_var);
av_freep(&pic->mc_mb_var);
av_freep(&pic->mb_mean);
av_freep(&pic->mbskip_table);
av_freep(&pic->qscale_table);
if(s->avctx->get_buffer == avcodec_default_get_buffer){
for(i=0; i<4; i++){
av_freep(&pic->base[i]);
pic->data[i]= NULL;
}
av_freep(&pic->opaque);
}
}
/* init common structure for both encoder and decoder */ /* init common structure for both encoder and decoder */
int MPV_common_init(MpegEncContext *s) int MPV_common_init(MpegEncContext *s)
{ {
UINT8 *pict;
int y_size, c_size, yc_size, i; int y_size, c_size, yc_size, i;
dsputil_init(&s->dsp, s->avctx->dsp_mask); dsputil_init(&s->dsp, s->avctx->dsp_mask);
@ -298,51 +334,12 @@ int MPV_common_init(MpegEncContext *s)
+ (toupper((s->avctx->fourcc>>16)&0xFF)<<16) + (toupper((s->avctx->fourcc>>16)&0xFF)<<16)
+ (toupper((s->avctx->fourcc>>24)&0xFF)<<24); + (toupper((s->avctx->fourcc>>24)&0xFF)<<24);
if(!(s->flags&CODEC_FLAG_DR1)){
s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH;
s->uvlinesize = s->mb_width * 8 + EDGE_WIDTH;
for(i=0;i<3;i++) {
int w, h, shift, pict_start;
unsigned size;
w = s->linesize;
h = s->mb_height * 16 + 2 * EDGE_WIDTH;
shift = (i == 0) ? 0 : 1;
size = (s->linesize>>shift) * (h >> shift);
pict_start = (s->linesize>>shift) * (EDGE_WIDTH >> shift) + (EDGE_WIDTH >> shift);
CHECKED_ALLOCZ(pict, size)
s->last_picture_base[i] = pict;
s->last_picture[i] = pict + pict_start;
if(i>0) memset(s->last_picture_base[i], 128, size);
CHECKED_ALLOCZ(pict, size)
s->next_picture_base[i] = pict;
s->next_picture[i] = pict + pict_start;
if(i>0) memset(s->next_picture_base[i], 128, size);
if (s->has_b_frames || s->codec_id==CODEC_ID_MPEG4) {
/* Note the MPEG4 stuff is here cuz of buggy encoders which dont set the low_delay flag but
do low-delay encoding, so we cant allways distinguish b-frame containing streams from low_delay streams */
CHECKED_ALLOCZ(pict, size)
s->aux_picture_base[i] = pict;
s->aux_picture[i] = pict + pict_start;
if(i>0) memset(s->aux_picture_base[i], 128, size);
}
}
s->ip_buffer_count= 2;
}
CHECKED_ALLOCZ(s->edge_emu_buffer, (s->width+64)*2*17*2); //(width + edge + align)*interlaced*MBsize*tolerance CHECKED_ALLOCZ(s->edge_emu_buffer, (s->width+64)*2*17*2); //(width + edge + align)*interlaced*MBsize*tolerance
if (s->encoding) { s->avctx->coded_picture= (AVVideoFrame*)&s->current_picture;
int j;
int mv_table_size= (s->mb_width+2)*(s->mb_height+2);
CHECKED_ALLOCZ(s->mb_var , s->mb_num * sizeof(INT16)) if (s->encoding) {
CHECKED_ALLOCZ(s->mc_mb_var, s->mb_num * sizeof(INT16)) int mv_table_size= (s->mb_width+2)*(s->mb_height+2);
CHECKED_ALLOCZ(s->mb_mean , s->mb_num * sizeof(INT8))
/* Allocate MV tables */ /* Allocate MV tables */
CHECKED_ALLOCZ(s->p_mv_table , mv_table_size * 2 * sizeof(INT16)) CHECKED_ALLOCZ(s->p_mv_table , mv_table_size * 2 * sizeof(INT16))
@ -354,28 +351,12 @@ int MPV_common_init(MpegEncContext *s)
CHECKED_ALLOCZ(s->b_direct_back_mv_table, mv_table_size * 2 * sizeof(INT16)) CHECKED_ALLOCZ(s->b_direct_back_mv_table, mv_table_size * 2 * sizeof(INT16))
CHECKED_ALLOCZ(s->b_direct_mv_table , mv_table_size * 2 * sizeof(INT16)) CHECKED_ALLOCZ(s->b_direct_mv_table , mv_table_size * 2 * sizeof(INT16))
CHECKED_ALLOCZ(s->me_scratchpad, s->linesize*16*3*sizeof(uint8_t)) //FIXME should be linesize instead of s->width*2 but that isnt known before get_buffer()
CHECKED_ALLOCZ(s->me_scratchpad, s->width*2*16*3*sizeof(uint8_t))
CHECKED_ALLOCZ(s->me_map , ME_MAP_SIZE*sizeof(uint32_t)) CHECKED_ALLOCZ(s->me_map , ME_MAP_SIZE*sizeof(uint32_t))
CHECKED_ALLOCZ(s->me_score_map, ME_MAP_SIZE*sizeof(uint16_t)) CHECKED_ALLOCZ(s->me_score_map, ME_MAP_SIZE*sizeof(uint16_t))
if(s->max_b_frames){
for(j=0; j<REORDER_BUFFER_SIZE; j++){
int i;
for(i=0;i<3;i++) {
int w, h, shift, size;
w = s->linesize;
h = s->mb_height * 16;
shift = (i == 0) ? 0 : 1;
size = (w >> shift) * (h >> shift);
CHECKED_ALLOCZ(pict, size);
s->picture_buffer[j][i] = pict;
}
}
}
if(s->codec_id==CODEC_ID_MPEG4){ if(s->codec_id==CODEC_ID_MPEG4){
CHECKED_ALLOCZ(s->tex_pb_buffer, PB_BUFFER_SIZE); CHECKED_ALLOCZ(s->tex_pb_buffer, PB_BUFFER_SIZE);
CHECKED_ALLOCZ( s->pb2_buffer, PB_BUFFER_SIZE); CHECKED_ALLOCZ( s->pb2_buffer, PB_BUFFER_SIZE);
@ -434,12 +415,6 @@ int MPV_common_init(MpegEncContext *s)
s->dc_val[0][i] = 1024; s->dc_val[0][i] = 1024;
} }
CHECKED_ALLOCZ(s->next_qscale_table , s->mb_num * sizeof(UINT8))
CHECKED_ALLOCZ(s->last_qscale_table , s->mb_num * sizeof(UINT8))
CHECKED_ALLOCZ(s->aux_qscale_table , s->mb_num * sizeof(UINT8))
s->qscale_table= s->next_qscale_table;
s->avctx->qstride= s->mb_width;
/* which mb is a intra block */ /* which mb is a intra block */
CHECKED_ALLOCZ(s->mbintra_table, s->mb_num); CHECKED_ALLOCZ(s->mbintra_table, s->mb_num);
memset(s->mbintra_table, 1, s->mb_num); memset(s->mbintra_table, 1, s->mb_num);
@ -470,10 +445,13 @@ void MPV_common_end(MpegEncContext *s)
{ {
int i; int i;
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0]){
s->avctx->release_buffer(s->avctx, (AVVideoFrame*)&s->picture[i]);
}
}
av_freep(&s->mb_type); av_freep(&s->mb_type);
av_freep(&s->mb_var);
av_freep(&s->mc_mb_var);
av_freep(&s->mb_mean);
av_freep(&s->p_mv_table); av_freep(&s->p_mv_table);
av_freep(&s->b_forw_mv_table); av_freep(&s->b_forw_mv_table);
av_freep(&s->b_back_mv_table); av_freep(&s->b_back_mv_table);
@ -489,9 +467,6 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->mbintra_table); av_freep(&s->mbintra_table);
av_freep(&s->cbp_table); av_freep(&s->cbp_table);
av_freep(&s->pred_dir_table); av_freep(&s->pred_dir_table);
av_freep(&s->next_qscale_table);
av_freep(&s->last_qscale_table);
av_freep(&s->aux_qscale_table);
av_freep(&s->me_scratchpad); av_freep(&s->me_scratchpad);
av_freep(&s->me_map); av_freep(&s->me_map);
av_freep(&s->me_score_map); av_freep(&s->me_score_map);
@ -508,23 +483,8 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->ac_stats); av_freep(&s->ac_stats);
av_freep(&s->error_status_table); av_freep(&s->error_status_table);
for(i=0;i<3;i++) { for(i=0; i<MAX_PICTURE_COUNT; i++){
int j; free_picture(s, &s->picture[i]);
if(!(s->flags&CODEC_FLAG_DR1)){
av_freep(&s->last_picture_base[i]);
av_freep(&s->next_picture_base[i]);
av_freep(&s->aux_picture_base[i]);
}
s->last_picture_base[i]=
s->next_picture_base[i]=
s->aux_picture_base [i] = NULL;
s->last_picture[i]=
s->next_picture[i]=
s->aux_picture [i] = NULL;
for(j=0; j<REORDER_BUFFER_SIZE; j++){
av_freep(&s->picture_buffer[j][i]);
}
} }
s->context_initialized = 0; s->context_initialized = 0;
} }
@ -813,70 +773,70 @@ static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w)
/* generic function for encode/decode called before a frame is coded/decoded */ /* generic function for encode/decode called before a frame is coded/decoded */
int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
{ {
int i; int i, r;
UINT8 *tmp; AVVideoFrame *pic;
s->mb_skiped = 0; s->mb_skiped = 0;
avctx->mbskip_table= s->mbskip_table;
/* mark&release old frames */
if (s->pict_type != B_TYPE && s->last_picture.data[0]) {
Picture *pic= NULL;
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] == s->last_picture.data[0]){
// s->picture[i].reference=0;
avctx->release_buffer(avctx, (AVVideoFrame*)&s->picture[i]);
break;
}
}
assert(i<MAX_PICTURE_COUNT);
/* release forgotten pictures */
/* if(mpeg124/h263) */
if(!s->encoding){
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] && s->picture[i].data[0] != s->next_picture.data[0] && s->picture[i].reference){
fprintf(stderr, "releasing zombie picture\n");
avctx->release_buffer(avctx, (AVVideoFrame*)&s->picture[i]);
}
}
}
}
if(!s->encoding){
/* find unused Picture */
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0]==NULL) break;
}
assert(i<MAX_PICTURE_COUNT);
pic= (AVVideoFrame*)&s->picture[i];
pic->reference= s->pict_type != B_TYPE;
pic->coded_picture_number= s->current_picture.coded_picture_number+1;
r= avctx->get_buffer(avctx, pic);
if(r<0 || (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))){
fprintf(stderr, "get_buffer() failed (stride changed), bye bye\n");
return -1;
}
s->linesize = pic->linesize[0];
s->uvlinesize= pic->linesize[1];
if(pic->qscale_table==NULL)
alloc_picture(s, (Picture*)pic);
s->current_picture= s->picture[i];
}
s->hurry_up= s->avctx->hurry_up; s->hurry_up= s->avctx->hurry_up;
s->error_resilience= avctx->error_resilience; s->error_resilience= avctx->error_resilience;
if(avctx->flags&CODEC_FLAG_DR1){ if (s->pict_type != B_TYPE) {
if(avctx->get_buffer_callback(avctx, s->width, s->height, s->pict_type) < 0){ s->last_picture= s->next_picture;
fprintf(stderr, "get_buffer() failed\n"); s->next_picture= s->current_picture;
return -1;
} }
s->linesize = avctx->dr_stride;
s->uvlinesize= avctx->dr_uvstride;
s->ip_buffer_count= avctx->dr_ip_buffer_count;
}
avctx->dr_ip_buffer_count= s->ip_buffer_count;
if (s->pict_type == B_TYPE) {
for(i=0;i<3;i++) {
if(avctx->flags&CODEC_FLAG_DR1)
s->aux_picture[i]= avctx->dr_buffer[i];
//FIXME the following should never be needed, the decoder should drop b frames if no reference is available
if(s->next_picture[i]==NULL)
s->next_picture[i]= s->aux_picture[i];
if(s->last_picture[i]==NULL)
s->last_picture[i]= s->next_picture[i];
s->current_picture[i] = s->aux_picture[i];
}
s->avctx->display_qscale_table=
s->avctx->current_qscale_table=
s->qscale_table= s->aux_qscale_table;
} else {
for(i=0;i<3;i++) {
/* swap next and last */
if(avctx->flags&CODEC_FLAG_DR1)
tmp= avctx->dr_buffer[i];
else
tmp = s->last_picture[i];
s->last_picture[i] = s->next_picture[i];
s->next_picture[i] = tmp;
s->current_picture[i] = tmp;
if(s->last_picture[i]==NULL)
s->last_picture[i]= s->next_picture[i];
s->last_dr_opaque= s->next_dr_opaque;
s->next_dr_opaque= avctx->dr_opaque_frame;
if(s->has_b_frames && s->last_dr_opaque && s->codec_id!=CODEC_ID_SVQ1)
avctx->dr_opaque_frame= s->last_dr_opaque;
else
avctx->dr_opaque_frame= s->next_dr_opaque;
}
s->avctx->current_qscale_table= s->qscale_table = s->last_qscale_table;
s->avctx->display_qscale_table= s->last_qscale_table = s->next_qscale_table;
s->next_qscale_table= s->qscale_table;
}
/* set dequantizer, we cant do it during init as it might change for mpeg4 /* set dequantizer, we cant do it during init as it might change for mpeg4
and we cant do it in the header decode as init isnt called for mpeg4 there yet */ and we cant do it in the header decode as init isnt called for mpeg4 there yet */
if(s->out_format == FMT_H263){ if(s->out_format == FMT_H263){
@ -893,14 +853,15 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
/* generic function for encode/decode called after a frame has been coded/decoded */ /* generic function for encode/decode called after a frame has been coded/decoded */
void MPV_frame_end(MpegEncContext *s) void MPV_frame_end(MpegEncContext *s)
{ {
s->avctx->key_frame = (s->pict_type == I_TYPE); int i;
s->avctx->pict_type = s->pict_type;
/* draw edge for correct motion prediction if outside */ /* draw edge for correct motion prediction if outside */
if(s->codec_id!=CODEC_ID_SVQ1){
if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) { if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
draw_edges(s->current_picture[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH ); draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH );
draw_edges(s->current_picture[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
draw_edges(s->current_picture[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
}
} }
emms_c(); emms_c();
@ -910,84 +871,154 @@ void MPV_frame_end(MpegEncContext *s)
s->num_available_buffers++; s->num_available_buffers++;
if(s->num_available_buffers>2) s->num_available_buffers= 2; if(s->num_available_buffers>2) s->num_available_buffers= 2;
} }
s->current_picture.quality= s->qscale; //FIXME get average of qscale_table
s->current_picture.pict_type= s->pict_type;
s->current_picture.key_frame= s->pict_type == I_TYPE;
/* copy back current_picture variables */
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] == s->current_picture.data[0]){
s->picture[i]= s->current_picture;
break;
}
}
assert(i<MAX_PICTURE_COUNT);
/* release non refernce frames */
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] && !s->picture[i].reference)
s->avctx->release_buffer(s->avctx, (AVVideoFrame*)&s->picture[i]);
}
} }
/* reorder input for encoding */ static int load_input_picture(MpegEncContext *s, AVVideoFrame *pic_arg){
void reorder_input(MpegEncContext *s, AVPicture *pict) AVVideoFrame *pic;
{ int i,r;
int i, j, index; const int encoding_delay= s->max_b_frames;
if(s->max_b_frames > FF_MAX_B_FRAMES) s->max_b_frames= FF_MAX_B_FRAMES; /* find unused Picture */
for(i=0; i<MAX_PICTURE_COUNT; i++){
// delay= s->max_b_frames+1; (or 0 if no b frames cuz decoder diff) if(s->picture[i].data[0]==NULL) break;
for(j=0; j<REORDER_BUFFER_SIZE-1; j++){
s->coded_order[j]= s->coded_order[j+1];
} }
s->coded_order[j].picture[0]= s->coded_order[j].picture[1]= s->coded_order[j].picture[2]= NULL; //catch uninitalized buffers assert(i<MAX_PICTURE_COUNT);
s->coded_order[j].pict_type=0;
switch(s->input_pict_type){ pic= (AVVideoFrame*)&s->picture[i];
default: pic->reference= 1;
case I_TYPE:
case S_TYPE: // assert(avctx->get_buffer == default_get_buffer || avctx->get_buffer==NULL);
case P_TYPE: r= s->avctx->get_buffer(s->avctx, pic);
index= s->max_b_frames - s->b_frames_since_non_b;
s->b_frames_since_non_b=0; if(r<0 || (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))){
break; fprintf(stderr, "get_buffer() failed (stride changed), bye bye\n");
case B_TYPE: return -1;
index= s->max_b_frames + 1;
s->b_frames_since_non_b++;
break;
}
//printf("index:%d type:%d strides: %d %d\n", index, s->input_pict_type, pict->linesize[0], s->linesize);
if( (index==0 || (s->flags&CODEC_FLAG_INPUT_PRESERVED))
&& pict->linesize[0] == s->linesize
&& pict->linesize[1] == s->uvlinesize
&& pict->linesize[2] == s->uvlinesize){
//printf("ptr\n");
for(i=0; i<3; i++){
s->coded_order[index].picture[i]= pict->data[i];
} }
assert(s->linesize==0 || s->linesize ==pic->linesize[0]);
assert(s->uvlinesize==0 || s->uvlinesize==pic->linesize[1]);
assert(pic->linesize[1] == pic->linesize[2]);
s->linesize = pic->linesize[0];
s->uvlinesize= pic->linesize[1];
if(pic->qscale_table==NULL)
alloc_picture(s, (Picture*)pic);
// assert(s->input_picture[0]==NULL || s->input_picture[0]->data[0]==NULL);
if(s->input_picture[encoding_delay])
pic->display_picture_number= s->input_picture[encoding_delay]->display_picture_number + 1;
//printf("dpn2:%d\n", pic->display_picture_number);
/* shift buffer entries */
for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)
s->input_picture[i-1]= s->input_picture[i];
s->input_picture[encoding_delay]= (Picture*)pic;
pic->pict_type= pic_arg->pict_type;
pic->quality= pic_arg->quality;
if( pic->data[0] == pic_arg->data[0]
&& pic->data[1] == pic_arg->data[1]
&& pic->data[2] == pic_arg->data[2]){
// empty
}else{ }else{
//printf("copy\n"); int h_chroma_shift, v_chroma_shift;
for(i=0; i<3; i++){
uint8_t *src = pict->data[i];
uint8_t *dest;
int src_wrap = pict->linesize[i];
int dest_wrap = s->linesize;
int w = s->width;
int h = s->height;
if(index==0) dest= s->last_picture[i]+16; //is current_picture indeed but the switch hapens after reordering avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
else dest= s->picture_buffer[s->picture_buffer_index][i];
if (i >= 1) {
dest_wrap >>= 1;
w >>= 1;
h >>= 1;
}
s->coded_order[index].picture[i]= dest;
for(j=0;j<h;j++) {
memcpy(dest, src, w);
dest += dest_wrap;
src += src_wrap;
}
}
if(index!=0){
s->picture_buffer_index++;
if(s->picture_buffer_index >= REORDER_BUFFER_SIZE) s->picture_buffer_index=0;
}
}
s->coded_order[index].pict_type = s->input_pict_type;
s->coded_order[index].qscale = s->input_qscale;
s->coded_order[index].force_type= s->force_input_type;
s->coded_order[index].picture_in_gop_number= s->input_picture_in_gop_number;
s->coded_order[index].picture_number= s->input_picture_number;
for(i=0; i<3; i++){ for(i=0; i<3; i++){
s->new_picture[i]= s->coded_order[0].picture[i]; int src_stride= pic_arg->linesize[i];
int dst_stride= i ? s->uvlinesize : s->linesize;
int h_shift= i ? h_chroma_shift : 0;
int v_shift= i ? v_chroma_shift : 0;
int w= s->width >>h_shift;
int h= s->height>>v_shift;
uint8_t *src= pic_arg->data[i];
uint8_t *dst= pic->data[i] + 16;
if(src_stride==dst_stride)
memcpy(dst, src, src_stride*h);
else{
while(h--){
memcpy(dst, src, w);
dst += dst_stride;
src += src_stride;
}
}
}
}
return 0;
}
static void select_input_picture(MpegEncContext *s){
int i;
const int encoding_delay= s->max_b_frames;
int coded_pic_num=0;
if(s->reordered_input_picture[0])
coded_pic_num= s->reordered_input_picture[0]->coded_picture_number + 1;
//printf("cpn:%d\n", coded_pic_num);
for(i=1; i<MAX_PICTURE_COUNT; i++)
s->reordered_input_picture[i-1]= s->reordered_input_picture[i];
s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL;
/* set next picture types & ordering */
if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){
if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture.data[0]==NULL || s->intra_only){
s->reordered_input_picture[0]= s->input_picture[0];
s->reordered_input_picture[0]->pict_type= I_TYPE;
s->reordered_input_picture[0]->coded_picture_number= coded_pic_num;
}else{
s->reordered_input_picture[0]= s->input_picture[s->max_b_frames];
if(s->picture_in_gop_number + s->max_b_frames >= s->gop_size)
s->reordered_input_picture[0]->pict_type= I_TYPE;
else
s->reordered_input_picture[0]->pict_type= P_TYPE;
s->reordered_input_picture[0]->coded_picture_number= coded_pic_num;
for(i=0; i<s->max_b_frames; i++){
coded_pic_num++;
s->reordered_input_picture[i+1]= s->input_picture[i];
s->reordered_input_picture[i+1]->pict_type= B_TYPE;
s->reordered_input_picture[i+1]->coded_picture_number= coded_pic_num;
}
}
}
if(s->reordered_input_picture[0]){
if(s->reordered_input_picture[0]->pict_type==B_TYPE){
s->reordered_input_picture[0]->reference=0;
}
s->current_picture= *s->reordered_input_picture[0];
s->new_picture= s->current_picture;
s->new_picture.data[0]+=16;
s->new_picture.data[1]+=16;
s->new_picture.data[2]+=16;
s->picture_number= s->new_picture.display_picture_number;
//printf("dpn:%d\n", s->picture_number);
}else{
memset(&s->new_picture, 0, sizeof(Picture));
} }
} }
@ -995,52 +1026,26 @@ int MPV_encode_picture(AVCodecContext *avctx,
unsigned char *buf, int buf_size, void *data) unsigned char *buf, int buf_size, void *data)
{ {
MpegEncContext *s = avctx->priv_data; MpegEncContext *s = avctx->priv_data;
AVPicture *pict = data; AVVideoFrame *pic_arg = data;
s->input_qscale = avctx->quality;
init_put_bits(&s->pb, buf, buf_size, NULL, NULL); init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
if(avctx->force_type){ s->picture_in_gop_number++;
s->input_pict_type=
s->force_input_type= avctx->force_type;
}else if(s->flags&CODEC_FLAG_PASS2){
s->input_pict_type=
s->force_input_type= s->rc_context.entry[s->input_picture_number].new_pict_type;
}else{
s->force_input_type=0;
if (!s->intra_only) {
/* first picture of GOP is intra */
if (s->input_picture_in_gop_number % s->gop_size==0){
s->input_pict_type = I_TYPE;
}else if(s->max_b_frames==0){
s->input_pict_type = P_TYPE;
}else{
if(s->b_frames_since_non_b < s->max_b_frames) //FIXME more IQ
s->input_pict_type = B_TYPE;
else
s->input_pict_type = P_TYPE;
}
} else {
s->input_pict_type = I_TYPE;
}
}
if(s->input_pict_type==I_TYPE) load_input_picture(s, pic_arg);
s->input_picture_in_gop_number=0;
reorder_input(s, pict); select_input_picture(s);
/* output? */ /* output? */
if(s->coded_order[0].picture[0]){ if(s->new_picture.data[0]){
s->pict_type= s->coded_order[0].pict_type;
if (s->fixed_qscale) /* the ratecontrol needs the last qscale so we dont touch it for CBR */
s->qscale= s->coded_order[0].qscale;
s->force_type= s->coded_order[0].force_type;
s->picture_in_gop_number= s->coded_order[0].picture_in_gop_number;
s->picture_number= s->coded_order[0].picture_number;
s->pict_type= s->new_picture.pict_type;
if (s->fixed_qscale){ /* the ratecontrol needs the last qscale so we dont touch it for CBR */
s->qscale= (int)(s->new_picture.quality+0.5);
assert(s->qscale);
}
//emms_c();
//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale);
MPV_frame_start(s, avctx); MPV_frame_start(s, avctx);
encode_picture(s, s->picture_number); encode_picture(s, s->picture_number);
@ -1060,16 +1065,11 @@ int MPV_encode_picture(AVCodecContext *avctx,
if (s->out_format == FMT_MJPEG) if (s->out_format == FMT_MJPEG)
mjpeg_picture_trailer(s); mjpeg_picture_trailer(s);
if(!s->fixed_qscale)
avctx->quality = s->qscale;
if(s->flags&CODEC_FLAG_PASS1) if(s->flags&CODEC_FLAG_PASS1)
ff_write_pass1_stats(s); ff_write_pass1_stats(s);
} }
s->input_picture_number++; s->input_picture_number++;
s->input_picture_in_gop_number++;
flush_put_bits(&s->pb); flush_put_bits(&s->pb);
s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8; s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
@ -1088,14 +1088,16 @@ if(s->max_b_frames==0)
fprintf(f, "%7d, %7d, %2.4f\n", pbBufPtr(&s->pb) - s->pb.buf, s->qscale, avctx->psnr_y); fprintf(f, "%7d, %7d, %2.4f\n", pbBufPtr(&s->pb) - s->pb.buf, s->qscale, avctx->psnr_y);
} }
#endif #endif
#if 0
if (avctx->get_psnr) { if (avctx->get_psnr) {
/* At this point pict->data should have the original frame */ /* At this point pict->data should have the original frame */
/* an s->current_picture should have the coded/decoded frame */ /* an s->current_picture should have the coded/decoded frame */
get_psnr(pict->data, s->current_picture, get_psnr(pict->data, s->current_picture.data,
pict->linesize, s->linesize, avctx); pict->linesize, s->linesize, avctx);
// printf("%f\n", avctx->psnr_y); // printf("%f\n", avctx->psnr_y);
} }
#endif
return pbBufPtr(&s->pb) - s->pb.buf; return pbBufPtr(&s->pb) - s->pb.buf;
} }
@ -1757,7 +1759,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
mb_x = s->mb_x; mb_x = s->mb_x;
mb_y = s->mb_y; mb_y = s->mb_y;
s->qscale_table[mb_xy]= s->qscale; s->current_picture.qscale_table[mb_xy]= s->qscale;
/* update DC predictors for P macroblocks */ /* update DC predictors for P macroblocks */
if (!s->mb_intra) { if (!s->mb_intra) {
@ -1823,33 +1825,47 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
op_pixels_func (*op_pix)[4]; op_pixels_func (*op_pix)[4];
qpel_mc_func (*op_qpix)[16]; qpel_mc_func (*op_qpix)[16];
/* avoid copy if macroblock skipped in last frame too /* avoid copy if macroblock skipped in last frame too */
dont touch it for B-frames as they need the skip info from the next p-frame */
if (s->pict_type != B_TYPE) { if (s->pict_type != B_TYPE) {
s->current_picture.mbskip_table[mb_xy]= s->mb_skiped;
}
/* skip only during decoding as we might trash the buffers during encoding a bit */
if(!s->encoding){
UINT8 *mbskip_ptr = &s->mbskip_table[mb_xy]; UINT8 *mbskip_ptr = &s->mbskip_table[mb_xy];
const int age= s->current_picture.age;
assert(age);
if (s->mb_skiped) { if (s->mb_skiped) {
s->mb_skiped = 0; s->mb_skiped= 0;
assert(s->pict_type!=I_TYPE);
(*mbskip_ptr) ++; /* indicate that this time we skiped it */ (*mbskip_ptr) ++; /* indicate that this time we skiped it */
if(*mbskip_ptr >99) *mbskip_ptr= 99; if(*mbskip_ptr >99) *mbskip_ptr= 99;
/* if previous was skipped too, then nothing to do ! /* if previous was skipped too, then nothing to do ! */
skip only during decoding as we might trash the buffers during encoding a bit */ if (*mbskip_ptr >= age){
if (*mbskip_ptr >= s->ip_buffer_count && !s->encoding) //if(s->pict_type!=B_TYPE && s->mb_x==0) printf("\n");
return; //if(s->pict_type!=B_TYPE) printf("%d%d ", *mbskip_ptr, age);
if(s->pict_type!=B_TYPE) return;
if(s->avctx->draw_horiz_band==NULL && *mbskip_ptr > age) return;
/* we dont draw complete frames here so we cant skip */
}
} else { } else {
*mbskip_ptr = 0; /* not skipped */ *mbskip_ptr = 0; /* not skipped */
} }
} }else
s->mb_skiped= 0;
if(s->pict_type==B_TYPE && s->avctx->draw_horiz_band){ if(s->pict_type==B_TYPE && s->avctx->draw_horiz_band){
dest_y = s->current_picture [0] + mb_x * 16; dest_y = s->current_picture.data[0] + mb_x * 16;
dest_cb = s->current_picture[1] + mb_x * 8; dest_cb = s->current_picture.data[1] + mb_x * 8;
dest_cr = s->current_picture[2] + mb_x * 8; dest_cr = s->current_picture.data[2] + mb_x * 8;
}else{ }else{
dest_y = s->current_picture [0] + (mb_y * 16* s->linesize ) + mb_x * 16; dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16;
dest_cb = s->current_picture[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
dest_cr = s->current_picture[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
} }
if (s->interlaced_dct) { if (s->interlaced_dct) {
@ -1873,12 +1889,12 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
} }
if (s->mv_dir & MV_DIR_FORWARD) { if (s->mv_dir & MV_DIR_FORWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
op_pix = s->dsp.avg_pixels_tab; op_pix = s->dsp.avg_pixels_tab;
op_qpix= s->dsp.avg_qpel_pixels_tab; op_qpix= s->dsp.avg_qpel_pixels_tab;
} }
if (s->mv_dir & MV_DIR_BACKWARD) { if (s->mv_dir & MV_DIR_BACKWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix); MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
} }
} }
@ -2154,13 +2170,13 @@ void ff_draw_horiz_band(MpegEncContext *s){
offset = y * s->linesize; offset = y * s->linesize;
if(s->pict_type==B_TYPE || (!s->has_b_frames)){ if(s->pict_type==B_TYPE || (!s->has_b_frames)){
src_ptr[0] = s->current_picture[0] + offset; src_ptr[0] = s->current_picture.data[0] + offset;
src_ptr[1] = s->current_picture[1] + (offset >> 2); src_ptr[1] = s->current_picture.data[1] + (offset >> 2);
src_ptr[2] = s->current_picture[2] + (offset >> 2); src_ptr[2] = s->current_picture.data[2] + (offset >> 2);
} else { } else {
src_ptr[0] = s->last_picture[0] + offset; src_ptr[0] = s->last_picture.data[0] + offset;
src_ptr[1] = s->last_picture[1] + (offset >> 2); src_ptr[1] = s->last_picture.data[1] + (offset >> 2);
src_ptr[2] = s->last_picture[2] + (offset >> 2); src_ptr[2] = s->last_picture.data[2] + (offset >> 2);
} }
emms_c(); emms_c();
@ -2180,7 +2196,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
for(i=0; i<6; i++) skip_dct[i]=0; for(i=0; i<6; i++) skip_dct[i]=0;
if(s->adaptive_quant){ if(s->adaptive_quant){
s->dquant= s->qscale_table[mb_x + mb_y*s->mb_width] - s->qscale; s->dquant= s->current_picture.qscale_table[mb_x + mb_y*s->mb_width] - s->qscale;
if(s->out_format==FMT_H263){ if(s->out_format==FMT_H263){
if (s->dquant> 2) s->dquant= 2; if (s->dquant> 2) s->dquant= 2;
@ -2206,7 +2222,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
int emu=0; int emu=0;
wrap_y = s->linesize; wrap_y = s->linesize;
ptr = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16; ptr = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height); emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
@ -2239,14 +2255,14 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
skip_dct[5]= 1; skip_dct[5]= 1;
}else{ }else{
int wrap_c = s->uvlinesize; int wrap_c = s->uvlinesize;
ptr = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8; ptr = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
if(emu){ if(emu){
emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
ptr= s->edge_emu_buffer; ptr= s->edge_emu_buffer;
} }
s->dsp.get_pixels(s->block[4], ptr, wrap_c); s->dsp.get_pixels(s->block[4], ptr, wrap_c);
ptr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8; ptr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
if(emu){ if(emu){
emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
ptr= s->edge_emu_buffer; ptr= s->edge_emu_buffer;
@ -2261,14 +2277,14 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
int wrap_y, wrap_c; int wrap_y, wrap_c;
int emu=0; int emu=0;
dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize ) + mb_x * 16; dest_y = s->current_picture.data[0] + (mb_y * 16 * s->linesize ) + mb_x * 16;
dest_cb = s->current_picture[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; dest_cb = s->current_picture.data[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
dest_cr = s->current_picture[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; dest_cr = s->current_picture.data[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
wrap_y = s->linesize; wrap_y = s->linesize;
wrap_c = s->uvlinesize; wrap_c = s->uvlinesize;
ptr_y = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16; ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8; ptr_cb = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8; ptr_cr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
if ((!s->no_rounding) || s->pict_type==B_TYPE){ if ((!s->no_rounding) || s->pict_type==B_TYPE){
op_pix = s->dsp.put_pixels_tab; op_pix = s->dsp.put_pixels_tab;
@ -2279,12 +2295,12 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
} }
if (s->mv_dir & MV_DIR_FORWARD) { if (s->mv_dir & MV_DIR_FORWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
op_pix = s->dsp.avg_pixels_tab; op_pix = s->dsp.avg_pixels_tab;
op_qpix= s->dsp.avg_qpel_pixels_tab; op_qpix= s->dsp.avg_qpel_pixels_tab;
} }
if (s->mv_dir & MV_DIR_BACKWARD) { if (s->mv_dir & MV_DIR_BACKWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix); MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
} }
if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
@ -2330,9 +2346,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
} }
s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
} }
/* pre quantization */ /* pre quantization */
if(s->mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){ if(s->current_picture.mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){
//FIXME optimize //FIXME optimize
if(s->dsp.pix_abs8x8(ptr_y , dest_y , wrap_y) < 20*s->qscale) skip_dct[0]= 1; if(s->dsp.pix_abs8x8(ptr_y , dest_y , wrap_y) < 20*s->qscale) skip_dct[0]= 1;
if(s->dsp.pix_abs8x8(ptr_y + 8, dest_y + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1; if(s->dsp.pix_abs8x8(ptr_y + 8, dest_y + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1;
@ -2557,8 +2572,8 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->block_wrap[5]= s->mb_width + 2; s->block_wrap[5]= s->mb_width + 2;
/* Reset the average MB variance */ /* Reset the average MB variance */
s->mb_var_sum = 0; s->current_picture.mb_var_sum = 0;
s->mc_mb_var_sum = 0; s->current_picture.mc_mb_var_sum = 0;
/* we need to initialize some time vars before we can encode b-frames */ /* we need to initialize some time vars before we can encode b-frames */
if (s->h263_pred && !s->h263_msmpeg4) if (s->h263_pred && !s->h263_msmpeg4)
@ -2604,15 +2619,15 @@ static void encode_picture(MpegEncContext *s, int picture_number)
for(mb_x=0; mb_x < s->mb_width; mb_x++) { for(mb_x=0; mb_x < s->mb_width; mb_x++) {
int xx = mb_x * 16; int xx = mb_x * 16;
int yy = mb_y * 16; int yy = mb_y * 16;
uint8_t *pix = s->new_picture[0] + (yy * s->linesize) + xx; uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
int varc; int varc;
int sum = s->dsp.pix_sum(pix, s->linesize); int sum = s->dsp.pix_sum(pix, s->linesize);
varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
s->mb_var [s->mb_width * mb_y + mb_x] = varc; s->current_picture.mb_var [s->mb_width * mb_y + mb_x] = varc;
s->mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8; s->current_picture.mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8;
s->mb_var_sum += varc; s->current_picture.mb_var_sum += varc;
} }
} }
} }
@ -2622,11 +2637,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
if(s->scene_change_score > 0 && s->pict_type == P_TYPE){ if(s->scene_change_score > 0 && s->pict_type == P_TYPE){
s->pict_type= I_TYPE; s->pict_type= I_TYPE;
memset(s->mb_type , MB_TYPE_INTRA, sizeof(UINT8)*s->mb_width*s->mb_height); memset(s->mb_type , MB_TYPE_INTRA, sizeof(UINT8)*s->mb_width*s->mb_height);
if(s->max_b_frames==0){ //printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
s->input_pict_type= I_TYPE;
s->input_picture_in_gop_number=0;
}
//printf("Scene change detected, encoding as I Frame %d %d\n", s->mb_var_sum, s->mc_mb_var_sum);
} }
if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) if(s->pict_type==P_TYPE || s->pict_type==S_TYPE)
@ -2643,7 +2654,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
} }
if (s->fixed_qscale) if (s->fixed_qscale)
s->frame_qscale = s->avctx->quality; s->frame_qscale = s->current_picture.quality;
else else
s->frame_qscale = ff_rate_estimate_qscale(s); s->frame_qscale = ff_rate_estimate_qscale(s);
@ -2658,7 +2669,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
break; break;
} }
s->qscale= s->qscale_table[0]; s->qscale= s->current_picture.qscale_table[0];
}else }else
s->qscale= (int)(s->frame_qscale + 0.5); s->qscale= (int)(s->frame_qscale + 0.5);
@ -2674,6 +2685,13 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias, 8, 8); s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias, 8, 8);
} }
//FIXME var duplication
s->current_picture.key_frame= s->pict_type == I_TYPE;
s->current_picture.pict_type= s->pict_type;
if(s->current_picture.key_frame)
s->picture_in_gop_number=0;
s->last_bits= get_bit_count(&s->pb); s->last_bits= get_bit_count(&s->pb);
switch(s->out_format) { switch(s->out_format) {
case FMT_MJPEG: case FMT_MJPEG:

View File

@ -28,6 +28,8 @@ enum OutputFormat {
FMT_MJPEG, FMT_MJPEG,
}; };
#define EDGE_WIDTH 16
#define MPEG_BUF_SIZE (16 * 1024) #define MPEG_BUF_SIZE (16 * 1024)
#define QMAT_SHIFT_MMX 16 #define QMAT_SHIFT_MMX 16
@ -35,7 +37,8 @@ enum OutputFormat {
#define MAX_FCODE 7 #define MAX_FCODE 7
#define MAX_MV 2048 #define MAX_MV 2048
#define REORDER_BUFFER_SIZE (FF_MAX_B_FRAMES+2)
#define MAX_PICTURE_COUNT 7
#define ME_MAP_SIZE 64 #define ME_MAP_SIZE 64
#define ME_MAP_SHIFT 3 #define ME_MAP_SHIFT 3
@ -90,14 +93,6 @@ typedef struct RateControlContext{
int last_non_b_pict_type; int last_non_b_pict_type;
}RateControlContext; }RateControlContext;
typedef struct ReorderBuffer{
UINT8 *picture[3];
int pict_type;
int qscale;
int force_type;
int picture_number;
int picture_in_gop_number;
} ReorderBuffer;
typedef struct ScanTable{ typedef struct ScanTable{
const UINT8 *scantable; const UINT8 *scantable;
@ -109,6 +104,16 @@ typedef struct ScanTable{
#endif #endif
} ScanTable; } ScanTable;
typedef struct Picture{
FF_COMMON_PICTURE
int mb_var_sum; /* sum of MB variance for current frame */
int mc_mb_var_sum; /* motion compensated MB variance for current frame */
uint16_t *mb_var; /* Table for MB variances */
uint16_t *mc_mb_var; /* Table for motion compensated MB variances */
uint8_t *mb_mean; /* Table for MB luminance */
} Picture;
typedef struct ParseContext{ typedef struct ParseContext{
UINT8 *buffer; UINT8 *buffer;
int index; int index;
@ -145,7 +150,6 @@ typedef struct MpegEncContext {
int max_qdiff; /* max qscale difference between frames */ int max_qdiff; /* max qscale difference between frames */
int encoding; /* true if we are encoding (vs decoding) */ int encoding; /* true if we are encoding (vs decoding) */
int flags; /* AVCodecContext.flags (HQ, MV4, ...) */ int flags; /* AVCodecContext.flags (HQ, MV4, ...) */
int force_input_type;/* 0= no force, otherwise I_TYPE, P_TYPE, ... */
int max_b_frames; /* max number of b-frames for encoding */ int max_b_frames; /* max number of b-frames for encoding */
int b_frame_strategy; int b_frame_strategy;
int luma_elim_threshold; int luma_elim_threshold;
@ -160,10 +164,7 @@ typedef struct MpegEncContext {
/* sequence parameters */ /* sequence parameters */
int context_initialized; int context_initialized;
int input_picture_number; int input_picture_number;
int input_picture_in_gop_number; /* 0-> first pic in gop, ... */
int picture_number; 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 based on fake_pic_num & mpeg1 specific */
int picture_in_gop_number; /* 0-> first pic in gop, ... */ int picture_in_gop_number; /* 0-> first pic in gop, ... */
int b_frames_since_non_b; /* used for encoding, relative to not yet reordered input */ int b_frames_since_non_b; /* used for encoding, relative to not yet reordered input */
int mb_width, mb_height; /* number of MBs horizontally & vertically */ int mb_width, mb_height; /* number of MBs horizontally & vertically */
@ -171,20 +172,13 @@ typedef struct MpegEncContext {
int mb_num; /* number of MBs of a picture */ int mb_num; /* number of MBs of a picture */
int linesize; /* line size, in bytes, may be different from width */ int linesize; /* line size, in bytes, may be different from width */
int uvlinesize; /* line size, for chroma in bytes, may be different from width */ int uvlinesize; /* line size, for chroma in bytes, may be different from width */
UINT8 *new_picture[3]; /* picture to be compressed */ Picture picture[MAX_PICTURE_COUNT]; /* main picture buffer */
UINT8 *picture_buffer[REORDER_BUFFER_SIZE][3]; /* internal buffers used for reordering of input pictures */ Picture *input_picture[MAX_PICTURE_COUNT]; /* next pictures on display order for encoding*/
int picture_buffer_index; Picture *reordered_input_picture[MAX_PICTURE_COUNT]; /* pointer to the next pictures in codedorder for encoding*/
ReorderBuffer coded_order[REORDER_BUFFER_SIZE]; Picture last_picture; /* previous picture */
UINT8 *last_picture[3]; /* previous picture */ Picture next_picture; /* previous picture (for bidir pred) */
UINT8 *last_picture_base[3]; /* real start of the picture */ Picture new_picture; /* source picture for encoding */
UINT8 *next_picture[3]; /* previous picture (for bidir pred) */ Picture current_picture; /* buffer to store the decompressed current picture */
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 */
void *last_dr_opaque;
void *next_dr_opaque;
int ip_buffer_count; /* number of buffers, currently only >2 if dr1 is used */
int num_available_buffers; /* is 0 at the start & after seeking, after the first I frame its 1 after next I/P 2 */ int num_available_buffers; /* is 0 at the start & after seeking, after the first I frame its 1 after next I/P 2 */
int last_dc[3]; /* last DC values for MPEG1 */ int last_dc[3]; /* last DC values for MPEG1 */
INT16 *dc_val[3]; /* used for mpeg4 DC prediction, all 3 arrays must be continuous */ INT16 *dc_val[3]; /* used for mpeg4 DC prediction, all 3 arrays must be continuous */
@ -200,17 +194,10 @@ typedef struct MpegEncContext {
UINT8 *mbintra_table; /* used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding */ UINT8 *mbintra_table; /* used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding */
UINT8 *cbp_table; /* used to store cbp, ac_pred for partitioned decoding */ UINT8 *cbp_table; /* used to store cbp, ac_pred for partitioned decoding */
UINT8 *pred_dir_table; /* used to store pred_dir for partitioned decoding */ UINT8 *pred_dir_table; /* used to store pred_dir for partitioned decoding */
INT8 *qscale_table; /* used to store qscale */
INT8 *aux_qscale_table;
INT8 *next_qscale_table;
INT8 *last_qscale_table; //FIXME move these into some picture struct (MpegEncContext.aux.qscale_table[])
UINT8 *edge_emu_buffer; UINT8 *edge_emu_buffer;
int input_qscale; /* qscale prior to reordering of frames */
int input_pict_type; /* pict_type prior to reordering of frames */
int force_type; /* 0= no force, otherwise I_TYPE, P_TYPE, ... */
int qscale; /* QP */ int qscale; /* QP */
float frame_qscale; /* qscale from the frame level rc */ float frame_qscale; /* qscale from the frame level rc FIXME remove*/
int adaptive_quant; /* use adaptive quantization */ int adaptive_quant; /* use adaptive quantization */
int dquant; /* qscale difference to prev qscale */ int dquant; /* qscale difference to prev qscale */
int pict_type; /* I_TYPE, P_TYPE, B_TYPE, ... */ int pict_type; /* I_TYPE, P_TYPE, B_TYPE, ... */
@ -272,9 +259,6 @@ typedef struct MpegEncContext {
int mb_x, mb_y; int mb_x, mb_y;
int mb_incr; int mb_incr;
int mb_intra; int mb_intra;
UINT16 *mb_var; /* Table for MB variances */
UINT16 *mc_mb_var; /* Table for motion compensated MB variances */
UINT8 *mb_mean; /* Table for MB luminance */
UINT8 *mb_type; /* Table for MB type */ UINT8 *mb_type; /* Table for MB type */
#define MB_TYPE_INTRA 0x01 #define MB_TYPE_INTRA 0x01
#define MB_TYPE_INTER 0x02 #define MB_TYPE_INTER 0x02
@ -325,8 +309,6 @@ typedef struct MpegEncContext {
/* bit rate control */ /* bit rate control */
int I_frame_bits; //FIXME used in mpeg12 ... int I_frame_bits; //FIXME used in mpeg12 ...
int mb_var_sum; /* sum of MB variance for current frame */
int mc_mb_var_sum; /* motion compensated MB variance for current frame */
INT64 wanted_bits; INT64 wanted_bits;
INT64 total_bits; INT64 total_bits;
int frame_bits; /* bits used for the current frame */ int frame_bits; /* bits used for the current frame */
@ -476,6 +458,10 @@ typedef struct MpegEncContext {
/* decompression specific */ /* decompression specific */
GetBitContext gb; GetBitContext gb;
/* Mpeg1 specific */
int fake_picture_number; /* picture number at the bitstream frame rate */
int gop_picture_number; /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */
/* MPEG2 specific - I wish I had not to support this mess. */ /* MPEG2 specific - I wish I had not to support this mess. */
int progressive_sequence; int progressive_sequence;
int mpeg_f_code[2][2]; int mpeg_f_code[2][2];
@ -498,7 +484,6 @@ typedef struct MpegEncContext {
int mpeg2; int mpeg2;
int full_pel[2]; int full_pel[2];
int interlaced_dct; int interlaced_dct;
int last_qscale;
int first_slice; int first_slice;
/* RTP specific */ /* RTP specific */

View File

@ -759,10 +759,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
}else{ }else{
if(n<4){ if(n<4){
wrap= s->linesize; wrap= s->linesize;
dest= s->current_picture[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8; dest= s->current_picture.data[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8;
}else{ }else{
wrap= s->uvlinesize; wrap= s->uvlinesize;
dest= s->current_picture[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8; dest= s->current_picture.data[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
} }
if(s->mb_x==0) a= (1024 + (scale>>1))/scale; if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
else a= get_dc(dest-8, wrap, scale*8); else a= get_dc(dest-8, wrap, scale*8);

View File

@ -41,7 +41,7 @@ void ff_write_pass1_stats(MpegEncContext *s){
sprintf(s->avctx->stats_out, "in:%d out:%d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d;\n", sprintf(s->avctx->stats_out, "in:%d out:%d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d;\n",
s->picture_number, s->input_picture_number - s->max_b_frames, s->pict_type, s->picture_number, s->input_picture_number - s->max_b_frames, s->pict_type,
s->frame_qscale, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits, s->frame_qscale, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
s->f_code, s->b_code, s->mc_mb_var_sum, s->mb_var_sum, s->i_count); s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count);
} }
int ff_rate_control_init(MpegEncContext *s) int ff_rate_control_init(MpegEncContext *s)
@ -475,11 +475,12 @@ static void adaptive_quantization(MpegEncContext *s, double q){
float bits_tab[s->mb_num]; float bits_tab[s->mb_num];
const int qmin= 2; //s->avctx->mb_qmin; const int qmin= 2; //s->avctx->mb_qmin;
const int qmax= 31; //s->avctx->mb_qmax; const int qmax= 31; //s->avctx->mb_qmax;
Picture * const pic= &s->current_picture;
for(i=0; i<s->mb_num; i++){ for(i=0; i<s->mb_num; i++){
float temp_cplx= sqrt(s->mc_mb_var[i]); float temp_cplx= sqrt(pic->mc_mb_var[i]);
float spat_cplx= sqrt(s->mb_var[i]); float spat_cplx= sqrt(pic->mb_var[i]);
const int lumi= s->mb_mean[i]; const int lumi= pic->mb_mean[i];
float bits, cplx, factor; float bits, cplx, factor;
if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
@ -533,8 +534,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){
newq*= bits_sum/cplx_sum; newq*= bits_sum/cplx_sum;
} }
if(i && ABS(s->qscale_table[i-1] - newq)<0.75) if(i && ABS(pic->qscale_table[i-1] - newq)<0.75)
intq= s->qscale_table[i-1]; intq= pic->qscale_table[i-1];
else else
intq= (int)(newq + 0.5); intq= (int)(newq + 0.5);
@ -542,7 +543,7 @@ static void adaptive_quantization(MpegEncContext *s, double q){
else if(intq < qmin) intq= qmin; else if(intq < qmin) intq= qmin;
//if(i%s->mb_width==0) printf("\n"); //if(i%s->mb_width==0) printf("\n");
//printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i])); //printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i]));
s->qscale_table[i]= intq; pic->qscale_table[i]= intq;
} }
} }
@ -562,6 +563,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
double rate_factor; double rate_factor;
int var; int var;
const int pict_type= s->pict_type; const int pict_type= s->pict_type;
Picture * const pic= &s->current_picture;
emms_c(); emms_c();
get_qminmax(&qmin, &qmax, s, pict_type); get_qminmax(&qmin, &qmax, s, pict_type);
@ -588,7 +590,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance; br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance;
if(br_compensation<=0.0) br_compensation=0.001; if(br_compensation<=0.0) br_compensation=0.001;
var= pict_type == I_TYPE ? s->mb_var_sum : s->mc_mb_var_sum; var= pict_type == I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum;
if(s->flags&CODEC_FLAG_PASS2){ if(s->flags&CODEC_FLAG_PASS2){
if(pict_type!=I_TYPE) if(pict_type!=I_TYPE)
@ -599,8 +601,8 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
}else{ }else{
rce->pict_type= rce->pict_type=
rce->new_pict_type= pict_type; rce->new_pict_type= pict_type;
rce->mc_mb_var_sum= s->mc_mb_var_sum; rce->mc_mb_var_sum= pic->mc_mb_var_sum;
rce->mb_var_sum = s-> mb_var_sum; rce->mb_var_sum = pic-> mb_var_sum;
rce->qscale = 2; rce->qscale = 2;
rce->f_code = s->f_code; rce->f_code = s->f_code;
rce->b_code = s->b_code; rce->b_code = s->b_code;
@ -664,9 +666,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
// printf("%f %d %d %d\n", q, picture_number, (int)wanted_bits, (int)s->total_bits); // printf("%f %d %d %d\n", q, picture_number, (int)wanted_bits, (int)s->total_bits);
//printf("%f %f %f\n", q, br_compensation, short_term_q); //printf("diff:%d comp:%f st_q:%f last_size:%d type:%d\n", (int)diff, br_compensation,
//printf("q:%d diff:%d comp:%f st_q:%f last_size:%d type:%d\n", qscale, (int)diff, br_compensation,
// short_term_q, s->frame_bits, pict_type); // short_term_q, s->frame_bits, pict_type);
//printf("%d %d\n", s->bit_rate, (int)fps); //printf("%d %d\n", s->bit_rate, (int)fps);
@ -676,8 +676,16 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
q= (int)(q + 0.5); q= (int)(q + 0.5);
rcc->last_qscale= q; rcc->last_qscale= q;
rcc->last_mc_mb_var_sum= s->mc_mb_var_sum; rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum;
rcc->last_mb_var_sum= s->mb_var_sum; rcc->last_mb_var_sum= pic->mb_var_sum;
#if 0
{
static int mvsum=0, texsum=0;
mvsum += s->mv_bits;
texsum += s->i_tex_bits + s->p_tex_bits;
printf("%d %d//\n\n", mvsum, texsum);
}
#endif
return q; return q;
} }

View File

@ -472,7 +472,7 @@ static int rv10_decode_frame(AVCodecContext *avctx,
{ {
MpegEncContext *s = avctx->priv_data; MpegEncContext *s = avctx->priv_data;
int i; int i;
AVPicture *pict = data; AVVideoFrame *pict = data;
#ifdef DEBUG #ifdef DEBUG
printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
@ -505,15 +505,9 @@ static int rv10_decode_frame(AVCodecContext *avctx,
if(s->mb_y>=s->mb_height){ if(s->mb_y>=s->mb_height){
MPV_frame_end(s); MPV_frame_end(s);
pict->data[0] = s->current_picture[0]; *pict= *(AVVideoFrame*)&s->current_picture;
pict->data[1] = s->current_picture[1];
pict->data[2] = s->current_picture[2];
pict->linesize[0] = s->linesize;
pict->linesize[1] = s->uvlinesize;
pict->linesize[2] = s->uvlinesize;
avctx->quality = s->qscale; *data_size = sizeof(AVVideoFrame);
*data_size = sizeof(AVPicture);
}else{ }else{
*data_size = 0; *data_size = 0;
} }

View File

@ -1063,7 +1063,7 @@ static int svq1_decode_frame(AVCodecContext *avctx,
MpegEncContext *s=avctx->priv_data; MpegEncContext *s=avctx->priv_data;
uint8_t *current, *previous; uint8_t *current, *previous;
int result, i, x, y, width, height; int result, i, x, y, width, height;
AVPicture *pict = data; AVVideoFrame *pict = data;
/* initialize bit buffer */ /* initialize bit buffer */
init_get_bits(&s->gb,buf,buf_size); init_get_bits(&s->gb,buf,buf_size);
@ -1085,9 +1085,6 @@ static int svq1_decode_frame(AVCodecContext *avctx,
result = svq1_decode_frame_header (&s->gb, s); result = svq1_decode_frame_header (&s->gb, s);
if(MPV_frame_start(s, avctx) < 0)
return -1;
if (result != 0) if (result != 0)
{ {
#ifdef DEBUG_SVQ1 #ifdef DEBUG_SVQ1
@ -1098,6 +1095,9 @@ static int svq1_decode_frame(AVCodecContext *avctx,
if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size; if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size;
if(MPV_frame_start(s, avctx) < 0)
return -1;
/* decode y, u and v components */ /* decode y, u and v components */
for (i=0; i < 3; i++) { for (i=0; i < 3; i++) {
int linesize; int linesize;
@ -1112,12 +1112,12 @@ static int svq1_decode_frame(AVCodecContext *avctx,
linesize= s->uvlinesize; linesize= s->uvlinesize;
} }
current = s->current_picture[i]; current = s->current_picture.data[i];
if(s->pict_type==B_TYPE){ if(s->pict_type==B_TYPE){
previous = s->next_picture[i]; previous = s->next_picture.data[i];
}else{ }else{
previous = s->last_picture[i]; previous = s->last_picture.data[i];
} }
if (s->pict_type == I_TYPE) { if (s->pict_type == I_TYPE) {
@ -1159,12 +1159,14 @@ static int svq1_decode_frame(AVCodecContext *avctx,
current += 16*linesize; current += 16*linesize;
} }
} }
pict->data[i] = s->current_picture[i];
pict->linesize[i] = linesize;
} }
*data_size=sizeof(AVPicture); *pict = *(AVVideoFrame*)&s->current_picture;
MPV_frame_end(s);
*data_size=sizeof(AVVideoFrame);
return buf_size; return buf_size;
} }
@ -1176,7 +1178,6 @@ static int svq1_decode_init(AVCodecContext *avctx)
s->width = (avctx->width+3)&~3; s->width = (avctx->width+3)&~3;
s->height = (avctx->height+3)&~3; s->height = (avctx->height+3)&~3;
s->codec_id= avctx->codec->id; s->codec_id= avctx->codec->id;
avctx->mbskip_table= s->mbskip_table;
avctx->pix_fmt = PIX_FMT_YUV410P; avctx->pix_fmt = PIX_FMT_YUV410P;
avctx->has_b_frames= s->has_b_frames=1; // not true, but DP frames and these behave like unidirectional b frames avctx->has_b_frames= s->has_b_frames=1; // not true, but DP frames and these behave like unidirectional b frames
s->flags= avctx->flags; s->flags= avctx->flags;

View File

@ -86,6 +86,123 @@ void register_avcodec(AVCodec *format)
format->next = NULL; format->next = NULL;
} }
void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift){
switch(fmt){
case PIX_FMT_YUV410P:
*h_shift=2;
*v_shift=2;
break;
case PIX_FMT_YUV420P:
*h_shift=1;
*v_shift=1;
break;
case PIX_FMT_YUV411P:
*h_shift=2;
*v_shift=0;
break;
case PIX_FMT_YUV422P:
case PIX_FMT_YUV422:
*h_shift=1;
*v_shift=0;
break;
default: //RGB/...
*h_shift=0;
*v_shift=0;
break;
}
}
typedef struct DefaultPicOpaque{
int last_pic_num;
uint8_t *data[4];
}DefaultPicOpaque;
int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic){
int i;
const int width = s->width;
const int height= s->height;
DefaultPicOpaque *opaque;
if(pic->opaque){
opaque= (DefaultPicOpaque *)pic->opaque;
for(i=0; i<3; i++)
pic->data[i]= opaque->data[i];
// printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num);
pic->age= pic->coded_picture_number - opaque->last_pic_num;
opaque->last_pic_num= pic->coded_picture_number;
//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number);
}else{
int align, h_chroma_shift, v_chroma_shift;
int w, h, pixel_size;
avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
switch(s->pix_fmt){
case PIX_FMT_YUV422:
pixel_size=2;
break;
case PIX_FMT_RGB24:
case PIX_FMT_BGR24:
pixel_size=3;
break;
case PIX_FMT_BGRA32:
case PIX_FMT_RGBA32:
pixel_size=4;
break;
default:
pixel_size=1;
}
if(s->codec_id==CODEC_ID_SVQ1) align=63;
else align=15;
w= (width +align)&~align;
h= (height+align)&~align;
if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
w+= EDGE_WIDTH*2;
h+= EDGE_WIDTH*2;
}
opaque= av_mallocz(sizeof(DefaultPicOpaque));
if(opaque==NULL) return -1;
pic->opaque= opaque;
opaque->last_pic_num= -256*256*256*64;
for(i=0; i<3; i++){
int h_shift= i==0 ? 0 : h_chroma_shift;
int v_shift= i==0 ? 0 : v_chroma_shift;
pic->linesize[i]= pixel_size*w>>h_shift;
pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
if(pic->base[i]==NULL) return -1;
memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift);
if(s->flags&CODEC_FLAG_EMU_EDGE)
pic->data[i] = pic->base[i];
else
pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift);
opaque->data[i]= pic->data[i];
}
pic->age= 256*256*256*64;
}
return 0;
}
void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic){
int i;
for(i=0; i<3; i++)
pic->data[i]=NULL;
//printf("R%X\n", pic->opaque);
}
void avcodec_get_context_defaults(AVCodecContext *s){ void avcodec_get_context_defaults(AVCodecContext *s){
s->bit_rate= 800*1000; s->bit_rate= 800*1000;
s->bit_rate_tolerance= s->bit_rate*10; s->bit_rate_tolerance= s->bit_rate*10;
@ -104,6 +221,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){
s->frame_rate = 25 * FRAME_RATE_BASE; s->frame_rate = 25 * FRAME_RATE_BASE;
s->gop_size= 50; s->gop_size= 50;
s->me_method= ME_EPZS; s->me_method= ME_EPZS;
s->get_buffer= avcodec_default_get_buffer;
s->release_buffer= avcodec_default_release_buffer;
} }
/** /**
@ -120,6 +239,16 @@ AVCodecContext *avcodec_alloc_context(void){
return avctx; return avctx;
} }
/**
* allocates a AVPicture and set it to defaults.
* this can be deallocated by simply calling free()
*/
AVVideoFrame *avcodec_alloc_picture(void){
AVVideoFrame *pic= av_mallocz(sizeof(AVVideoFrame));
return pic;
}
int avcodec_open(AVCodecContext *avctx, AVCodec *codec) int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{ {
int ret; int ret;
@ -152,7 +281,7 @@ int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size,
} }
int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
const AVPicture *pict) const AVVideoFrame *pict)
{ {
int ret; int ret;
@ -167,7 +296,7 @@ int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
/* decode a frame. return -1 if error, otherwise return the number of /* decode a frame. return -1 if error, otherwise return the number of
bytes used. If no frame could be decompressed, *got_picture_ptr is bytes used. If no frame could be decompressed, *got_picture_ptr is
zero. Otherwise, it is non zero */ zero. Otherwise, it is non zero */
int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, int avcodec_decode_video(AVCodecContext *avctx, AVVideoFrame *picture,
int *got_picture_ptr, int *got_picture_ptr,
UINT8 *buf, int buf_size) UINT8 *buf, int buf_size)
{ {

View File

@ -556,7 +556,7 @@ static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestam
int val; int val;
val = stream->num; val = stream->num;
if (s->streams[val - 1]->codec.key_frame /* && frag_offset == 0 */) if (s->streams[val - 1]->codec.coded_picture->key_frame /* && frag_offset == 0 */)
val |= 0x80; val |= 0x80;
put_byte(pb, val); put_byte(pb, val);
put_byte(pb, stream->seq); put_byte(pb, stream->seq);
@ -793,6 +793,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
st = av_mallocz(sizeof(AVStream)); st = av_mallocz(sizeof(AVStream));
if (!st) if (!st)
goto fail; goto fail;
avcodec_get_context_defaults(&st->codec);
s->streams[s->nb_streams] = st; s->streams[s->nb_streams] = st;
asf_st = av_mallocz(sizeof(ASFStream)); asf_st = av_mallocz(sizeof(ASFStream));
if (!asf_st) if (!asf_st)

View File

@ -143,6 +143,8 @@ static int au_read_header(AVFormatContext *s,
st = av_malloc(sizeof(AVStream)); st = av_malloc(sizeof(AVStream));
if (!st) if (!st)
return -1; return -1;
avcodec_get_context_defaults(&st->codec);
s->nb_streams = 1; s->nb_streams = 1;
s->streams[0] = st; s->streams[0] = st;

View File

@ -144,6 +144,9 @@ typedef struct AVStream {
AVFrac pts; AVFrac pts;
/* ffmpeg.c private use */ /* ffmpeg.c private use */
int stream_copy; /* if TRUE, just copy stream */ int stream_copy; /* if TRUE, just copy stream */
/* quality, as it has been removed from AVCodecContext and put in AVVideoFrame
* MN:dunno if thats the right place, for it */
float quality;
} AVStream; } AVStream;
#define MAX_STREAMS 20 #define MAX_STREAMS 20

View File

@ -103,6 +103,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *st = av_mallocz(sizeof(AVStream)); AVStream *st = av_mallocz(sizeof(AVStream));
if (!st) if (!st)
goto fail; goto fail;
avcodec_get_context_defaults(&st->codec);
s->streams[i] = st; s->streams[i] = st;
} }
url_fskip(pb, size - 7 * 4); url_fskip(pb, size - 7 * 4);

View File

@ -320,7 +320,7 @@ static int avi_write_packet(AVFormatContext *s, int stream_index,
if (enc->codec_type == CODEC_TYPE_VIDEO) { if (enc->codec_type == CODEC_TYPE_VIDEO) {
tag[2] = 'd'; tag[2] = 'd';
tag[3] = 'c'; tag[3] = 'c';
flags = enc->key_frame ? 0x10 : 0x00; flags = enc->coded_picture->key_frame ? 0x10 : 0x00;
} else { } else {
tag[2] = 'w'; tag[2] = 'w';
tag[3] = 'b'; tag[3] = 'b';

View File

@ -151,7 +151,7 @@ static int ffm_write_header(AVFormatContext *s)
put_be32(pb, codec->codec_id); put_be32(pb, codec->codec_id);
put_byte(pb, codec->codec_type); put_byte(pb, codec->codec_type);
put_be32(pb, codec->bit_rate); put_be32(pb, codec->bit_rate);
put_be32(pb, codec->quality); put_be32(pb, st->quality);
put_be32(pb, codec->flags); put_be32(pb, codec->flags);
/* specific info */ /* specific info */
switch(codec->codec_type) { switch(codec->codec_type) {
@ -232,7 +232,7 @@ static int ffm_write_packet(AVFormatContext *s, int stream_index,
/* packet size & key_frame */ /* packet size & key_frame */
header[0] = stream_index; header[0] = stream_index;
header[1] = 0; header[1] = 0;
if (st->codec.key_frame) if (st->codec.coded_picture->key_frame)
header[1] |= FLAG_KEY_FRAME; header[1] |= FLAG_KEY_FRAME;
header[2] = (size >> 16) & 0xff; header[2] = (size >> 16) & 0xff;
header[3] = (size >> 8) & 0xff; header[3] = (size >> 8) & 0xff;
@ -394,6 +394,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
st = av_mallocz(sizeof(AVStream)); st = av_mallocz(sizeof(AVStream));
if (!st) if (!st)
goto fail; goto fail;
avcodec_get_context_defaults(&st->codec);
s->streams[i] = st; s->streams[i] = st;
fst = av_mallocz(sizeof(FFMStream)); fst = av_mallocz(sizeof(FFMStream));
if (!fst) if (!fst)
@ -405,7 +406,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec.codec_id = get_be32(pb); st->codec.codec_id = get_be32(pb);
st->codec.codec_type = get_byte(pb); /* codec_type */ st->codec.codec_type = get_byte(pb); /* codec_type */
codec->bit_rate = get_be32(pb); codec->bit_rate = get_be32(pb);
codec->quality = get_be32(pb); st->quality = get_be32(pb);
codec->flags = get_be32(pb); codec->flags = get_be32(pb);
/* specific info */ /* specific info */
switch(codec->codec_type) { switch(codec->codec_type) {

View File

@ -170,6 +170,8 @@ static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap)
av_free(s); av_free(s);
return -ENOMEM; return -ENOMEM;
} }
avcodec_get_context_defaults(&st->codec);
s1->streams[0] = st; s1->streams[0] = st;
s->img_number = 0; s->img_number = 0;

View File

@ -352,7 +352,7 @@ static int rm_write_video(AVFormatContext *s, UINT8 *buf, int size)
RMContext *rm = s->priv_data; RMContext *rm = s->priv_data;
ByteIOContext *pb = &s->pb; ByteIOContext *pb = &s->pb;
StreamInfo *stream = rm->video_stream; StreamInfo *stream = rm->video_stream;
int key_frame = stream->enc->key_frame; int key_frame = stream->enc->coded_picture->key_frame;
/* XXX: this is incorrect: should be a parameter */ /* XXX: this is incorrect: should be a parameter */
@ -527,6 +527,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
st = av_mallocz(sizeof(AVStream)); st = av_mallocz(sizeof(AVStream));
if (!st) if (!st)
goto fail; goto fail;
avcodec_get_context_defaults(&st->codec);
s->streams[s->nb_streams++] = st; s->streams[s->nb_streams++] = st;
st->id = get_be16(pb); st->id = get_be16(pb);
get_be32(pb); /* max bit rate */ get_be32(pb); /* max bit rate */

View File

@ -482,6 +482,8 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
st = av_mallocz(sizeof(AVStream)); st = av_mallocz(sizeof(AVStream));
if (!st) if (!st)
return -ENOMEM; return -ENOMEM;
avcodec_get_context_defaults(&st->codec);
if (v & 0x01) if (v & 0x01)
st->codec.channels = 2; st->codec.channels = 2;
else else

View File

@ -458,7 +458,7 @@ int av_find_stream_info(AVFormatContext *ic)
AVCodec *codec; AVCodec *codec;
AVStream *st; AVStream *st;
AVPacket *pkt; AVPacket *pkt;
AVPicture picture; AVVideoFrame picture;
AVPacketList *pktl=NULL, **ppktl; AVPacketList *pktl=NULL, **ppktl;
short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2]; short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
UINT8 *ptr; UINT8 *ptr;
@ -694,6 +694,8 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
st = av_mallocz(sizeof(AVStream)); st = av_mallocz(sizeof(AVStream));
if (!st) if (!st)
return NULL; return NULL;
avcodec_get_context_defaults(&st->codec);
st->index = s->nb_streams; st->index = s->nb_streams;
st->id = id; st->id = id;
s->streams[s->nb_streams++] = st; s->streams[s->nb_streams++] = st;