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/trunktags/v0.5
@@ -285,6 +285,7 @@ int read_ffserver_streams(AVFormatContext *s, const char *filename) | |||
s->nb_streams = ic->nb_streams; | |||
for(i=0;i<ic->nb_streams;i++) { | |||
AVStream *st; | |||
st = av_mallocz(sizeof(AVFormatContext)); | |||
memcpy(st, ic->streams[i], sizeof(AVStream)); | |||
s->streams[i] = st; | |||
@@ -605,15 +606,21 @@ static void do_video_out(AVFormatContext *s, | |||
/* XXX: pb because no interleaving */ | |||
for(i=0;i<nb_frames;i++) { | |||
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 | |||
not be a global option */ | |||
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, | |||
video_buffer, VIDEO_BUFFER_SIZE, | |||
picture); | |||
&big_picture); | |||
//enc->frame_number = enc->real_pict_num; | |||
av_write_frame(s, ost->index, video_buffer, ret); | |||
*frame_size = ret; | |||
@@ -674,7 +681,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, | |||
total_size += frame_size; | |||
if (enc->codec_type == CODEC_TYPE_VIDEO) { | |||
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) | |||
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; | |||
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); | |||
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]; | |||
enc = &ost->st->codec; | |||
if (vid && enc->codec_type == CODEC_TYPE_VIDEO) { | |||
sprintf(buf + strlen(buf), "q=%2d ", | |||
enc->quality); | |||
sprintf(buf + strlen(buf), "q=%2.1f ", | |||
enc->coded_picture->quality); | |||
} | |||
if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) { | |||
frame_number = ost->frame_number; | |||
sprintf(buf + strlen(buf), "frame=%5d q=%2d ", | |||
frame_number, enc->quality); | |||
sprintf(buf + strlen(buf), "frame=%5d q=%2.1f ", | |||
frame_number, enc->coded_picture ? enc->coded_picture->quality : 0); | |||
if (do_psnr) | |||
sprintf(buf + strlen(buf), "PSNR=%6.2f ", enc->psnr_y); | |||
vid = 1; | |||
@@ -1236,9 +1243,13 @@ static int av_encode(AVFormatContext **output_files, | |||
ist->st->codec.height); | |||
ret = len; | |||
} else { | |||
AVVideoFrame big_picture; | |||
data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2; | |||
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) { | |||
fail_decode: | |||
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"); | |||
exit(1); | |||
} | |||
avcodec_get_context_defaults(&st->codec); | |||
video_enc = &st->codec; | |||
if (video_stream_copy) { | |||
@@ -2074,7 +2086,7 @@ void opt_output_file(const char *filename) | |||
video_enc->gop_size = 0; | |||
if (video_qscale || same_quality) { | |||
video_enc->flags |= CODEC_FLAG_QSCALE; | |||
video_enc->quality = video_qscale; | |||
st->quality = video_qscale; | |||
} | |||
if (use_hq) { | |||
@@ -2181,6 +2193,7 @@ void opt_output_file(const char *filename) | |||
fprintf(stderr, "Could not alloc stream\n"); | |||
exit(1); | |||
} | |||
avcodec_get_context_defaults(&st->codec); | |||
audio_enc = &st->codec; | |||
audio_enc->codec_type = CODEC_TYPE_AUDIO; | |||
@@ -1955,7 +1955,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) | |||
/* we use the codec indication because it is | |||
more accurate than the demux flags */ | |||
pkt->flags = 0; | |||
if (st->codec.key_frame) | |||
if (st->codec.coded_picture->key_frame) | |||
pkt->flags |= PKT_FLAG_KEY; | |||
return 0; | |||
} | |||
@@ -3942,7 +3942,7 @@ int parse_ffconfig(const char *filename) | |||
} else if (!strcasecmp(cmd, "AudioQuality")) { | |||
get_arg(arg, sizeof(arg), &p); | |||
if (stream) { | |||
audio_enc.quality = atof(arg) * 1000; | |||
// audio_enc.quality = atof(arg) * 1000; | |||
} | |||
} else if (!strcasecmp(cmd, "VideoBitRateRange")) { | |||
if (stream) { | |||
@@ -5,8 +5,8 @@ | |||
#define LIBAVCODEC_VERSION_INT 0x000406 | |||
#define LIBAVCODEC_VERSION "0.4.6" | |||
#define LIBAVCODEC_BUILD 4640 | |||
#define LIBAVCODEC_BUILD_STR "4640" | |||
#define LIBAVCODEC_BUILD 4641 | |||
#define LIBAVCODEC_BUILD_STR "4641" | |||
enum CodecID { | |||
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_GRAY 0x2000 /* only decode/encode grayscale */ | |||
#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 | |||
of only at frame boundaries */ | |||
#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 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 { | |||
/** | |||
* the average bitrate | |||
@@ -191,7 +295,7 @@ typedef struct AVCodecContext { | |||
/** | |||
* motion estimation algorithm used for video coding | |||
* encoding: set by user. | |||
* encoding: MUST be set by user. | |||
* decoding: unused | |||
*/ | |||
int me_method; | |||
@@ -212,21 +316,17 @@ typedef struct AVCodecContext { | |||
* frames per sec multiplied by FRAME_RATE_BASE | |||
* for variable fps this is the precission, so if the timestamps | |||
* 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 | |||
*/ | |||
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 | |||
*/ | |||
int width, height; | |||
/** | |||
* Obsolete, will be removed | |||
*/ | |||
int aspect_ratio_info; | |||
#define FF_ASPECT_SQUARE 1 | |||
#define FF_ASPECT_4_3_625 2 | |||
#define FF_ASPECT_4_3_525 3 | |||
@@ -274,26 +374,14 @@ typedef struct AVCodecContext { | |||
int frame_number; /* audio or video frame number */ | |||
int real_pict_num; /* returns the real picture number of | |||
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) | |||
* decoding: set by lavc (for the decoded bitstream, not the displayed 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 | |||
* the encoded input | |||
@@ -301,25 +389,8 @@ typedef struct AVCodecContext { | |||
* decoding: unused | |||
*/ | |||
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 */ | |||
/** | |||
* 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 qblur; /* amount of qscale smoothing over time (0.0-1.0) */ | |||
@@ -485,46 +556,21 @@ typedef struct AVCodecContext { | |||
int error_resilience; | |||
/** | |||
* obsolete, just here to keep ABI compatible (should be removed perhaps, dunno) | |||
*/ | |||
int *quant_store; | |||
/** | |||
* QP store stride | |||
* encoding: unused | |||
* decoding: set by lavc | |||
*/ | |||
int qstride; | |||
/** | |||
* buffer, where the next picture should be decoded into | |||
* 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 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 | |||
* decoding: set by lavc, user can override | |||
*/ | |||
uint8_t *dr_buffer[3]; | |||
int (*get_buffer)(struct AVCodecContext *c, AVVideoFrame *pic); | |||
/** | |||
* stride of the luminance part of the dr buffer | |||
* 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 | |||
* decoding: set by user | |||
* decoding: set by lavc, user can override | |||
*/ | |||
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); | |||
void (*release_buffer)(struct AVCodecContext *c, AVVideoFrame *pic); | |||
/** | |||
* is 1 if the decoded stream contains b frames, 0 otherwise | |||
@@ -532,20 +578,6 @@ typedef struct AVCodecContext { | |||
* decoding: set by lavc | |||
*/ | |||
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 */ | |||
@@ -646,12 +678,6 @@ typedef struct AVCodecContext { | |||
*/ | |||
float rc_initial_cplx; | |||
/** | |||
* Obsolete, will be removed | |||
*/ | |||
int aspected_width; | |||
int aspected_height; | |||
/** | |||
* dct algorithm, see FF_DCT_* below | |||
* encoding: set by user | |||
@@ -664,14 +690,6 @@ typedef struct AVCodecContext { | |||
#define FF_DCT_MMX 3 | |||
#define FF_DCT_MLIB 4 | |||
#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) | |||
@@ -754,24 +772,6 @@ typedef struct AVCodecContext { | |||
#define FF_EC_GUESS_MVS 1 | |||
#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 | |||
* CPU features (i.e. MMX, SSE. ...) | |||
@@ -780,14 +780,14 @@ typedef struct AVCodecContext { | |||
/** | |||
* bits per sample/pixel from the demuxer (needed for huffyuv) | |||
* encoding; set by lavc | |||
* encoding: set by lavc | |||
* decoding: set by user | |||
*/ | |||
int bits_per_sample; | |||
/** | |||
* prediction method (needed for huffyuv) | |||
* encoding; set by user | |||
* encoding: set by user | |||
* decoding: unused | |||
*/ | |||
int prediction_method; | |||
@@ -801,6 +801,13 @@ typedef struct AVCodecContext { | |||
* decoding: set by lavc. | |||
*/ | |||
float aspect_ratio; | |||
/** | |||
* the picture in the bitstream | |||
* encoding: set by lavc | |||
* decoding: set by lavc | |||
*/ | |||
AVVideoFrame *coded_picture; | |||
} AVCodecContext; | |||
typedef struct AVCodec { | |||
@@ -928,6 +935,7 @@ void img_resample_close(ImgReSampleContext *s); | |||
void avpicture_fill(AVPicture *picture, UINT8 *ptr, | |||
int pix_fmt, int width, int height); | |||
int avpicture_get_size(int pix_fmt, int width, int height); | |||
void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift); | |||
/* convert among pixel formats */ | |||
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); | |||
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); | |||
void avcodec_get_context_defaults(AVCodecContext *s); | |||
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_decode_audio(AVCodecContext *avctx, INT16 *samples, | |||
int *frame_size_ptr, | |||
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, | |||
UINT8 *buf, int buf_size); | |||
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, | |||
const short *samples); | |||
int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
const AVPicture *pict); | |||
const AVVideoFrame *pict); | |||
int avcodec_close(AVCodecContext *avctx); | |||
@@ -33,6 +33,7 @@ typedef struct DVVideoDecodeContext { | |||
int sampling_411; /* 0 = 420, 1 = 411 */ | |||
int width, height; | |||
UINT8 *current_picture[3]; /* picture structure */ | |||
AVVideoFrame picture; | |||
int linesize[3]; | |||
DCTELEM block[5*6][64] __align8; | |||
UINT8 dv_zigzag[2][64]; | |||
@@ -128,7 +129,7 @@ static int dvvideo_decode_init(AVCodecContext *avctx) | |||
/* XXX: do it only for constant case */ | |||
dv_build_unquantize_tables(s); | |||
return 0; | |||
} | |||
@@ -499,7 +500,6 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||
unsigned size; | |||
UINT8 *buf_ptr; | |||
const UINT16 *mb_pos_ptr; | |||
AVPicture *picture; | |||
/* parse id */ | |||
init_get_bits(&s->gb, buf, buf_size); | |||
@@ -561,45 +561,20 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||
avctx->width = width; | |||
avctx->height = height; | |||
if (avctx->flags & CODEC_FLAG_DR1) | |||
{ | |||
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"); | |||
return -1; | |||
} | |||
s->picture.reference= 0; | |||
if(avctx->get_buffer(avctx, &s->picture) < 0) { | |||
fprintf(stderr, "get_buffer() failed\n"); | |||
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++) { | |||
if (avctx->dr_buffer[i]) { | |||
s->current_picture[i] = avctx->dr_buffer[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]) | |||
return -1; | |||
} | |||
s->width = width; | |||
s->height = height; | |||
for(i=0;i<3;i++) { | |||
s->current_picture[i] = s->picture.data[i]; | |||
s->linesize[i] = s->picture.linesize[i]; | |||
if (!s->current_picture[i]) | |||
return -1; | |||
} | |||
s->width = width; | |||
s->height = height; | |||
/* for each DIF segment */ | |||
buf_ptr = buf; | |||
@@ -620,12 +595,11 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||
emms_c(); | |||
/* return image */ | |||
*data_size = sizeof(AVPicture); | |||
picture = data; | |||
for(i=0;i<3;i++) { | |||
picture->data[i] = s->current_picture[i]; | |||
picture->linesize[i] = s->linesize[i]; | |||
} | |||
*data_size = sizeof(AVVideoFrame); | |||
*(AVVideoFrame*)data= s->picture; | |||
avctx->release_buffer(avctx, &s->picture); | |||
return packet_size; | |||
} | |||
@@ -633,10 +607,15 @@ static int dvvideo_decode_end(AVCodecContext *avctx) | |||
{ | |||
DVVideoDecodeContext *s = avctx->priv_data; | |||
int 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); | |||
} | |||
for(i=0;i<3;i++) | |||
if (avctx->dr_buffer[i] != s->current_picture[i]) | |||
av_freep(&s->current_picture[i]); | |||
return 0; | |||
} | |||
@@ -464,7 +464,7 @@ int score_sum=0; | |||
s->mb_y= mb_y; | |||
for(j=0; j<pred_count; j++){ | |||
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][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(s->pict_type==I_TYPE){ | |||
UINT8 *mb_ptr = s->current_picture[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 *mb_ptr = s->current_picture.data[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, 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(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_cb= s->current_picture[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
dest_cr= s->current_picture[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | |||
dest_cb= s->current_picture.data[1] + 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)]; | |||
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(!(error&AC_ERROR)) continue; //undamaged | |||
dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; | |||
dest_cb= s->current_picture[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
dest_cr= s->current_picture[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | |||
dest_cb= s->current_picture.data[1] + 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); | |||
} | |||
@@ -863,14 +863,14 @@ void ff_error_resilience(MpegEncContext *s){ | |||
if(s->avctx->error_concealment&FF_EC_DEBLOCK){ | |||
/* 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[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[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | |||
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.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
/* 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[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[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | |||
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.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
} | |||
/* clean a few tables */ | |||
@@ -272,6 +272,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
{ | |||
int score0=0, score1=0; | |||
int i, n; | |||
int8_t * const qscale_table= s->current_picture.qscale_table; | |||
for(n=0; n<6; n++){ | |||
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; | |||
/* top prediction */ | |||
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 */ | |||
for(i=1; i<8; 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++){ | |||
const int level= block[n][s->idct_permutation[i ]]; | |||
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+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; | |||
/* left prediction */ | |||
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 */ | |||
for(i=1; i<8; i++){ | |||
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++){ | |||
const int level= block[n][s->idct_permutation[i<<3]]; | |||
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+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){ | |||
int i; | |||
int8_t * const qscale_table= s->current_picture.qscale_table; | |||
for(i=1; i<s->mb_num; i++){ | |||
if(s->qscale_table[i] - s->qscale_table[i-1] >2) | |||
s->qscale_table[i]= s->qscale_table[i-1]+2; | |||
if(qscale_table[i] - qscale_table[i-1] >2) | |||
qscale_table[i]= qscale_table[i-1]+2; | |||
} | |||
for(i=s->mb_num-2; i>=0; i--){ | |||
if(s->qscale_table[i] - s->qscale_table[i+1] >2) | |||
s->qscale_table[i]= s->qscale_table[i+1]+2; | |||
if(qscale_table[i] - 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){ | |||
int i; | |||
int8_t * const qscale_table= s->current_picture.qscale_table; | |||
ff_clean_h263_qscales(s); | |||
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_INTER; | |||
} | |||
@@ -367,21 +370,21 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){ | |||
for the actual adaptive quantization */ | |||
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; | |||
else odd=0; | |||
for(i=0; i<s->mb_num; i++){ | |||
if((s->qscale_table[i]&1) != odd) | |||
s->qscale_table[i]++; | |||
if(s->qscale_table[i] > 31) | |||
s->qscale_table[i]= 31; | |||
if((qscale_table[i]&1) != odd) | |||
qscale_table[i]++; | |||
if(qscale_table[i] > 31) | |||
qscale_table[i]= 31; | |||
} | |||
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_BIDIR; | |||
} | |||
@@ -427,7 +430,7 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
assert(mb_type>=0); | |||
/* 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->mv[0][0][0]= | |||
s->mv[0][0][1]= | |||
@@ -435,6 +438,8 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
s->mv[1][0][1]= 0; | |||
s->mv_dir= MV_DIR_FORWARD; //doesnt matter | |||
s->qscale -= s->dquant; | |||
// s->mb_skiped=1; | |||
return; | |||
} | |||
@@ -451,6 +456,7 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
s->skip_count++; | |||
return; | |||
} | |||
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, 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; | |||
offset= x + y*s->linesize; | |||
p_pic= s->new_picture[0] + offset; | |||
p_pic= s->new_picture.data[0] + offset; | |||
s->mb_skiped=1; | |||
for(i=0; i<s->max_b_frames; i++){ | |||
uint8_t *b_pic; | |||
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); | |||
if(diff>s->qscale*70){ //FIXME check that 70 is optimal | |||
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; | |||
} | |||
if(s->avctx->pts) | |||
s->time= (s->avctx->pts*s->time_increment_resolution + 500*1000)/(1000*1000); | |||
if(s->current_picture.pts) | |||
s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000); | |||
else | |||
s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; | |||
time_div= s->time/s->time_increment_resolution; | |||
@@ -1736,6 +1743,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
{ | |||
int i; | |||
INT16 *ac_val, *ac_val1; | |||
int8_t * const qscale_table= s->current_picture.qscale_table; | |||
/* find prediction */ | |||
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 */ | |||
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 */ | |||
for(i=1;i<8;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{ | |||
/* different qscale, we must rescale */ | |||
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 { | |||
@@ -1762,7 +1770,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
/* top prediction */ | |||
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 */ | |||
for(i=1;i<8;i++) { | |||
block[s->idct_permutation[i]] += ac_val[i + 8]; | |||
@@ -1770,7 +1778,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
}else{ | |||
/* different qscale, we must rescale */ | |||
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; | |||
INT16 *ac_val; | |||
int8_t * const qscale_table= s->current_picture.qscale_table; | |||
/* find prediction */ | |||
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; | |||
/* left prediction */ | |||
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 */ | |||
for(i=1;i<8;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{ | |||
/* different qscale, we must rescale */ | |||
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 { | |||
const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; | |||
/* top prediction */ | |||
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 */ | |||
for(i=1;i<8;i++) { | |||
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{ | |||
/* different qscale, we must rescale */ | |||
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) { | |||
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; | |||
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) { | |||
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++){ | |||
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->error_status_table[xy]&= ~DC_ERROR; | |||
}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; | |||
}else{ | |||
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) { | |||
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]|= (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]; | |||
cbp = s->cbp_table[xy]; | |||
if(s->qscale_table[xy] != s->qscale){ | |||
s->qscale= s->qscale_table[xy]; | |||
if(s->current_picture.qscale_table[xy] != s->qscale){ | |||
s->qscale= s->current_picture.qscale_table[xy]; | |||
s->y_dc_scale= s->y_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 */ | |||
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){ | |||
/* skip mb */ | |||
@@ -3287,7 +3296,7 @@ end: | |||
/* per-MB end of slice check */ | |||
if(s->codec_id==CODEC_ID_MPEG4){ | |||
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_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; | |||
} | |||
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){ | |||
printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n"); | |||
@@ -199,6 +199,7 @@ static int decode_slice(MpegEncContext *s){ | |||
s->mv_dir = MV_DIR_FORWARD; | |||
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)); | |||
ret= s->decode_mb(s, s->block); | |||
@@ -347,7 +348,7 @@ static int h263_decode_frame(AVCodecContext *avctx, | |||
{ | |||
MpegEncContext *s = avctx->priv_data; | |||
int ret,i; | |||
AVPicture *pict = data; | |||
AVVideoFrame *pict = data; | |||
float new_aspect; | |||
#ifdef PRINT_FRAME_TIME | |||
@@ -357,7 +358,6 @@ uint64_t time= rdtsc(); | |||
printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); | |||
printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); | |||
#endif | |||
s->flags= avctx->flags; | |||
*data_size = 0; | |||
@@ -523,8 +523,9 @@ retry: | |||
return -1; | |||
} | |||
s->avctx->key_frame = (s->pict_type == I_TYPE); | |||
s->avctx->pict_type = s->pict_type; | |||
// for hurry_up==5 | |||
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 */ | |||
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(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 */ | |||
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; | |||
for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |||
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 mx= (s->motion_val[xy][0]>>1) + x; | |||
int my= (s->motion_val[xy][1]>>1) + y; | |||
@@ -669,21 +672,12 @@ retry: | |||
} | |||
} | |||
#endif | |||
#endif | |||
if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | |||
pict->data[0] = s->current_picture[0]; | |||
pict->data[1] = s->current_picture[1]; | |||
pict->data[2] = s->current_picture[2]; | |||
*pict= *(AVVideoFrame*)&s->current_picture; | |||
} else { | |||
pict->data[0] = s->last_picture[0]; | |||
pict->data[1] = s->last_picture[1]; | |||
pict->data[2] = s->last_picture[2]; | |||
*pict= *(AVVideoFrame*)&s->last_picture; | |||
} | |||
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 */ | |||
/* we substract 1 because it is added on utils.c */ | |||
@@ -692,7 +686,7 @@ retry: | |||
/* dont output the last pic after seeking | |||
note we allready added +1 for the current pix in MPV_frame_end(s) */ | |||
if(s->num_available_buffers>=2 || (!s->has_b_frames)) | |||
*data_size = sizeof(AVPicture); | |||
*data_size = sizeof(AVVideoFrame); | |||
#ifdef PRINT_FRAME_TIME | |||
printf("%Ld\n", rdtsc()-time); | |||
#endif | |||
@@ -30,7 +30,7 @@ | |||
#endif | |||
#define VLC_BITS 11 | |||
typedef enum Predictor{ | |||
LEFT= 0, | |||
PLANE, | |||
@@ -52,13 +52,12 @@ typedef struct HYuvContext{ | |||
int flags; | |||
int picture_number; | |||
int last_slice_end; | |||
int linesize[3]; | |||
uint8_t __align8 temp[3][2500]; | |||
uint64_t stats[3][256]; | |||
uint8_t len[3][256]; | |||
uint32_t bits[3][256]; | |||
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 | |||
DSPContext dsp; | |||
}HYuvContext; | |||
@@ -324,7 +323,7 @@ static int read_old_huffman_tables(HYuvContext *s){ | |||
static int decode_init(AVCodecContext *avctx) | |||
{ | |||
HYuvContext *s = avctx->priv_data; | |||
int width, height, y_size, c_size, stride; | |||
int width, height; | |||
s->avctx= avctx; | |||
s->flags= avctx->flags; | |||
@@ -333,6 +332,8 @@ static int decode_init(AVCodecContext *avctx) | |||
width= s->width= avctx->width; | |||
height= s->height= avctx->height; | |||
avctx->coded_picture= &s->picture; | |||
s->bgr32=1; | |||
assert(width && height); | |||
//if(avctx->extradata) | |||
@@ -388,52 +389,27 @@ s->bgr32=1; | |||
s->interlaced= height > 288; | |||
c_size= 0; | |||
switch(s->bitstream_bpp){ | |||
case 12: | |||
avctx->pix_fmt = PIX_FMT_YUV420P; | |||
stride= (width+15)&~15; | |||
c_size= height*stride/4; | |||
break; | |||
case 16: | |||
if(s->yuy2){ | |||
avctx->pix_fmt = PIX_FMT_YUV422; | |||
stride= (width*2+15)&~15; | |||
}else{ | |||
avctx->pix_fmt = PIX_FMT_YUV422P; | |||
stride= (width+15)&~15; | |||
c_size= height*stride/2; | |||
} | |||
break; | |||
case 24: | |||
case 32: | |||
if(s->bgr32){ | |||
avctx->pix_fmt = PIX_FMT_BGRA32; | |||
stride= (width*4+15)&~15; | |||
}else{ | |||
avctx->pix_fmt = PIX_FMT_BGR24; | |||
stride= (width*3+15)&~15; | |||
} | |||
break; | |||
default: | |||
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); | |||
@@ -484,6 +460,10 @@ static int encode_init(AVCodecContext *avctx) | |||
avctx->stats_out= av_mallocz(1024*10); | |||
s->version=2; | |||
avctx->coded_picture= &s->picture; | |||
s->picture.pict_type= I_TYPE; | |||
s->picture.key_frame= 1; | |||
switch(avctx->pix_fmt){ | |||
case PIX_FMT_YUV420P: | |||
if(avctx->strict_std_compliance>=0){ | |||
@@ -674,12 +654,12 @@ static void draw_slice(HYuvContext *s, int y){ | |||
cy= y; | |||
} | |||
src_ptr[0] = s->picture[0] + s->linesize[0]*y; | |||
src_ptr[1] = s->picture[1] + s->linesize[1]*cy; | |||
src_ptr[2] = s->picture[2] + s->linesize[2]*cy; | |||
src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y; | |||
src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy; | |||
src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy; | |||
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; | |||
} | |||
@@ -690,9 +670,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
const int width2= s->width>>1; | |||
const int height= s->height; | |||
int fake_ystride, fake_ustride, fake_vstride; | |||
int i; | |||
AVVideoFrame * const p= &s->picture; | |||
AVPicture *picture = data; | |||
AVVideoFrame *picture = data; | |||
*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); | |||
if(avctx->flags&CODEC_FLAG_DR1){ | |||
if(avctx->get_buffer_callback(avctx, s->width, s->height, I_TYPE) < 0){ | |||
fprintf(stderr, "get_buffer() failed\n"); | |||
return -1; | |||
} | |||
s->linesize[0]= avctx->dr_stride; | |||
s->linesize[1]= | |||
s->linesize[2]= avctx->dr_uvstride; | |||
for(i=0; i<3;i++) | |||
s->picture[i]= avctx->dr_buffer[i]; | |||
p->reference= 0; | |||
if(avctx->get_buffer(avctx, p) < 0){ | |||
fprintf(stderr, "get_buffer() failed\n"); | |||
return -1; | |||
} | |||
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]; | |||
fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; | |||
fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; | |||
fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2]; | |||
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; | |||
if(s->yuy2){ | |||
s->picture[0][3]= get_bits(&s->gb, 8); | |||
s->picture[0][2]= get_bits(&s->gb, 8); | |||
s->picture[0][1]= get_bits(&s->gb, 8); | |||
s->picture[0][0]= get_bits(&s->gb, 8); | |||
p->data[0][3]= get_bits(&s->gb, 8); | |||
p->data[0][2]= get_bits(&s->gb, 8); | |||
p->data[0][1]= get_bits(&s->gb, 8); | |||
p->data[0][0]= get_bits(&s->gb, 8); | |||
fprintf(stderr, "YUY2 output isnt implemenetd yet\n"); | |||
return -1; | |||
}else{ | |||
leftv= s->picture[2][0]= get_bits(&s->gb, 8); | |||
lefty= s->picture[0][1]= get_bits(&s->gb, 8); | |||
leftu= s->picture[1][0]= get_bits(&s->gb, 8); | |||
s->picture[0][0]= get_bits(&s->gb, 8); | |||
leftv= p->data[2][0]= get_bits(&s->gb, 8); | |||
lefty= p->data[0][1]= get_bits(&s->gb, 8); | |||
leftu= p->data[1][0]= get_bits(&s->gb, 8); | |||
p->data[0][0]= get_bits(&s->gb, 8); | |||
switch(s->predictor){ | |||
case LEFT: | |||
case PLANE: | |||
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)){ | |||
leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu); | |||
leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); | |||
leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); | |||
leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); | |||
} | |||
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){ | |||
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); | |||
if(s->predictor == PLANE){ | |||
@@ -772,12 +745,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
draw_slice(s, y); | |||
ydst= s->picture[0] + s->linesize[0]*y; | |||
udst= s->picture[1] + s->linesize[1]*cy; | |||
vdst= s->picture[2] + s->linesize[2]*cy; | |||
ydst= p->data[0] + p->linesize[0]*y; | |||
udst= p->data[1] + p->linesize[1]*cy; | |||
vdst= p->data[2] + p->linesize[2]*cy; | |||
decode_422_bitstream(s, width); | |||
lefty= add_left_prediction(ydst, s->temp[0], width, lefty); | |||
if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
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: | |||
/* first line except first 2 pixels is left predicted */ | |||
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)){ | |||
leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu); | |||
leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); | |||
leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); | |||
leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); | |||
} | |||
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 */ | |||
if(s->interlaced){ | |||
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)){ | |||
leftu= add_left_prediction(s->picture[1] + s->linesize[2], s->temp[1], width2, leftu); | |||
leftv= add_left_prediction(s->picture[2] + s->linesize[1], s->temp[2], width2, leftv); | |||
leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); | |||
leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); | |||
} | |||
y++; cy++; | |||
} | |||
/* next 4 pixels are left predicted too */ | |||
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)){ | |||
leftu= add_left_prediction(s->picture[1] + fake_ustride, s->temp[1], 2, leftu); | |||
leftv= add_left_prediction(s->picture[2] + fake_vstride, s->temp[2], 2, leftv); | |||
leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); | |||
leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); | |||
} | |||
/* 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); | |||
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)){ | |||
lefttopu= s->picture[1][1]; | |||
lefttopv= s->picture[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(s->picture[2] + fake_vstride+2, s->picture[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); | |||
lefttopu= p->data[1][1]; | |||
lefttopv= p->data[2][1]; | |||
add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); | |||
add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); | |||
} | |||
y++; cy++; | |||
@@ -844,7 +816,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
if(s->bitstream_bpp==12){ | |||
while(2*cy > y){ | |||
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); | |||
y++; | |||
} | |||
@@ -854,9 +826,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
decode_422_bitstream(s, width); | |||
ydst= s->picture[0] + s->linesize[0]*y; | |||
udst= s->picture[1] + s->linesize[1]*cy; | |||
vdst= s->picture[2] + s->linesize[2]*cy; | |||
ydst= p->data[0] + p->linesize[0]*y; | |||
udst= p->data[1] + p->linesize[1]*cy; | |||
vdst= p->data[2] + p->linesize[2]*cy; | |||
add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); | |||
if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
@@ -872,17 +844,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
}else{ | |||
int y; | |||
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){ | |||
s->picture[0][last_line+3]= get_bits(&s->gb, 8); | |||
leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8); | |||
leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8); | |||
leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8); | |||
p->data[0][last_line+3]= get_bits(&s->gb, 8); | |||
leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); | |||
leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); | |||
leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8); | |||
}else{ | |||
leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8); | |||
leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8); | |||
leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8); | |||
leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); | |||
leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); | |||
leftb= p->data[0][last_line+0]= get_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 PLANE: | |||
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 | |||
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((y&s->interlaced)==0){ | |||
s->dsp.add_bytes(s->picture[0] + s->linesize[0]*y, | |||
s->picture[0] + s->linesize[0]*y + fake_ystride, fake_ystride); | |||
s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, | |||
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(); | |||
for(i=0;i<3;i++) { | |||
picture->data[i] = s->picture[i]; | |||
picture->linesize[i]= s->linesize[i]; | |||
} | |||
*picture= *p; | |||
avctx->release_buffer(avctx, p); | |||
*data_size = sizeof(AVPicture); | |||
*data_size = sizeof(AVVideoFrame); | |||
return (get_bits_count(&s->gb)+7)>>3; | |||
} | |||
@@ -933,44 +904,47 @@ static int decode_end(AVCodecContext *avctx) | |||
int i; | |||
for(i=0; i<3; i++){ | |||
if(!(avctx->flags&CODEC_FLAG_DR1)) | |||
av_freep(&s->picture[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; | |||
} | |||
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |||
HYuvContext *s = avctx->priv_data; | |||
AVPicture *pict = data; | |||
AVVideoFrame *pict = data; | |||
const int width= s->width; | |||
const int width2= s->width>>1; | |||
const int height= s->height; | |||
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_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; | |||
AVVideoFrame * const p= &s->picture; | |||
int i, size; | |||
init_put_bits(&s->pb, buf, buf_size, NULL, NULL); | |||
for(i=0; i<3; i++){ | |||
s->picture[i]= pict->data[i]; | |||
s->linesize[i]= pict->linesize[i]; | |||
} | |||
*p = *pict; | |||
if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ | |||
int lefty, leftu, leftv, y, cy; | |||
put_bits(&s->pb, 8, leftv= s->picture[2][0]); | |||
put_bits(&s->pb, 8, lefty= s->picture[0][1]); | |||
put_bits(&s->pb, 8, leftu= s->picture[1][0]); | |||
put_bits(&s->pb, 8, s->picture[0][0]); | |||
put_bits(&s->pb, 8, leftv= p->data[2][0]); | |||
put_bits(&s->pb, 8, lefty= p->data[0][1]); | |||
put_bits(&s->pb, 8, leftu= p->data[1][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); | |||
leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+1, width2-1, leftu); | |||
leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+1, width2-1, leftv); | |||
lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty); | |||
leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu); | |||
leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv); | |||
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; | |||
cy=y=1; | |||
if(s->interlaced){ | |||
lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+s->linesize[0], width , lefty); | |||
leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+s->linesize[1], width2, leftu); | |||
leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+s->linesize[2], width2, leftv); | |||
lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty); | |||
leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu); | |||
leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv); | |||
encode_422_bitstream(s, width); | |||
y++; cy++; | |||
} | |||
lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+fake_ystride, 4, lefty); | |||
leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+fake_ystride, 2, leftu); | |||
leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+fake_ystride, 2, leftv); | |||
lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty); | |||
leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu); | |||
leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv); | |||
encode_422_bitstream(s, 4); | |||
lefttopy= s->picture[0][3]; | |||
lefttopu= s->picture[1][1]; | |||
lefttopv= s->picture[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[1], s->picture[1]+2, s->picture[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); | |||
lefttopy= p->data[0][3]; | |||
lefttopu= p->data[1][1]; | |||
lefttopv= p->data[2][1]; | |||
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], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); | |||
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); | |||
y++; cy++; | |||
@@ -1006,16 +980,16 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
if(s->bitstream_bpp==12){ | |||
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); | |||
encode_gray_bitstream(s, width); | |||
y++; | |||
} | |||
if(y>=height) break; | |||
} | |||
ydst= s->picture[0] + s->linesize[0]*y; | |||
udst= s->picture[1] + s->linesize[1]*cy; | |||
vdst= s->picture[2] + s->linesize[2]*cy; | |||
ydst= p->data[0] + p->linesize[0]*y; | |||
udst= p->data[1] + p->linesize[1]*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[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++ */ | |||
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){ | |||
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; | |||
} | |||
ydst= s->picture[0] + s->linesize[0]*y; | |||
udst= s->picture[1] + s->linesize[1]*cy; | |||
vdst= s->picture[2] + s->linesize[2]*cy; | |||
ydst= p->data[0] + p->linesize[0]*y; | |||
udst= p->data[1] + p->linesize[1]*cy; | |||
vdst= p->data[2] + p->linesize[2]*cy; | |||
if(s->predictor == PLANE && s->interlaced < cy){ | |||
s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); | |||
@@ -1088,11 +1062,8 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); | |||
} | |||
avctx->key_frame= 1; | |||
avctx->pict_type= I_TYPE; | |||
s->picture_number++; | |||
return size*4; | |||
} | |||
@@ -1180,9 +1180,11 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) | |||
get_bits(&s->gb, 8), get_bits(&s->gb, 8)); | |||
if (get_bits(&s->gb, 8) == 0) | |||
{ | |||
s->avctx->aspect_ratio_info = FF_ASPECT_EXTENDED; | |||
s->avctx->aspected_width = get_bits(&s->gb, 16); | |||
s->avctx->aspected_height = get_bits(&s->gb, 16); | |||
int x_density = get_bits(&s->gb, 16); | |||
int y_density = get_bits(&s->gb, 16); | |||
//MN: needs to be checked | |||
s->avctx->aspect_ratio= s->width*y_density/((float)s->height*x_density); | |||
} | |||
else | |||
{ | |||
@@ -1468,7 +1470,7 @@ eoi_parser: | |||
} | |||
/* dummy quality */ | |||
/* XXX: infer it with matrix */ | |||
avctx->quality = 3; | |||
// avctx->quality = 3; | |||
goto the_end; | |||
} | |||
break; | |||
@@ -1635,7 +1637,7 @@ read_header: | |||
} | |||
/* dummy quality */ | |||
/* XXX: infer it with matrix */ | |||
avctx->quality = 3; | |||
// avctx->quality = 3; | |||
return buf_ptr - buf; | |||
} | |||
@@ -92,7 +92,7 @@ static int full_motion_search(MpegEncContext * s, | |||
y2 = yy + range - 1; | |||
if (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; | |||
mx = 0; | |||
my = 0; | |||
@@ -155,7 +155,7 @@ static int log_motion_search(MpegEncContext * s, | |||
if (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; | |||
mx = 0; | |||
my = 0; | |||
@@ -231,7 +231,7 @@ static int phods_motion_search(MpegEncContext * s, | |||
if (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; | |||
my = 0; | |||
@@ -560,7 +560,7 @@ static int epzs_motion_search(MpegEncContext * s, | |||
uint16_t *score_map= s->me_score_map; | |||
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; | |||
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; | |||
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; | |||
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); | |||
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; | |||
my = *my_ptr; | |||
@@ -789,7 +789,7 @@ static inline int fast_halfpel_motion_search(MpegEncContext * s, | |||
xx = 16 * s->mb_x + 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; | |||
my = *my_ptr; | |||
@@ -931,7 +931,7 @@ static inline int mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, in | |||
{ | |||
int block; | |||
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; | |||
for(block=0; block<4; block++){ | |||
@@ -1019,7 +1019,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, | |||
int P[10][2]; | |||
const int shift= 1+s->quarter_sample; | |||
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); | |||
rel_xmin= xmin - mb_x*16; | |||
@@ -1104,7 +1105,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, | |||
xx = mb_x * 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 */ | |||
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; | |||
//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; | |||
s->mc_mb_var[s->mb_width * mb_y + mb_x] = vard; | |||
s->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
s->mb_var_sum += varc; | |||
s->mc_mb_var_sum += vard; | |||
pic->mb_var [s->mb_width * mb_y + mb_x] = varc; | |||
pic->mc_mb_var[s->mb_width * mb_y + mb_x] = vard; | |||
pic->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
pic->mb_var_sum += varc; | |||
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); | |||
#if 0 | |||
@@ -1318,7 +1319,7 @@ static inline int check_bidir_mv(MpegEncContext * s, | |||
if (src_y == s->height) | |||
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); | |||
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) | |||
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); | |||
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; | |||
} | |||
@@ -1418,7 +1419,7 @@ static inline int direct_search(MpegEncContext * s, | |||
src_y = clip(src_y, -16, height); | |||
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); | |||
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); | |||
fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[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; | |||
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.data[0], s->b_code) - quant; | |||
//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); | |||
@@ -1534,8 +1535,8 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, | |||
type= MB_TYPE_BIDIR; | |||
} | |||
score= ((unsigned)(score*score + 128*256))>>16; | |||
s->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_sum += score; | |||
s->current_picture.mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD | |||
} | |||
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; | |||
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; | |||
} | |||
} | |||
@@ -134,7 +134,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) | |||
int n; | |||
UINT64 time_code; | |||
if (s->picture_in_gop_number == 0) { | |||
if (s->current_picture.key_frame) { | |||
/* mpeg1 header repeated every gop */ | |||
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->repeat_field = 0; | |||
s->mpeg_enc_ctx.codec_id= avctx->codec->id; | |||
avctx->mbskip_table= s->mpeg_enc_ctx.mbskip_table; | |||
return 0; | |||
} | |||
@@ -1403,9 +1402,6 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, | |||
s->pict_type = get_bits(&s->gb, 3); | |||
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); | |||
if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { | |||
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][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->c_dc_scale = 8; | |||
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 | |||
*/ | |||
static int mpeg_decode_slice(AVCodecContext *avctx, | |||
AVPicture *pict, | |||
AVVideoFrame *pict, | |||
int start_code, | |||
UINT8 *buf, int buf_size) | |||
{ | |||
@@ -1677,38 +1675,25 @@ eos: //end of slice | |||
if (/*s->mb_x == 0 &&*/ | |||
s->mb_y == s->mb_height) { | |||
/* end of image */ | |||
UINT8 **picture; | |||
if(s->mpeg2) | |||
s->qscale >>=1; | |||
MPV_frame_end(s); | |||
if (s->pict_type == B_TYPE) { | |||
picture = s->current_picture; | |||
avctx->quality = s->qscale; | |||
*pict= *(AVVideoFrame*)&s->current_picture; | |||
} else { | |||
s->picture_number++; | |||
/* latency of 1 frame for I and P frames */ | |||
/* XXX: use another variable than picture_number */ | |||
if (s->picture_number == 0) { | |||
picture = NULL; | |||
if (s->picture_number == 1) { | |||
return DECODE_SLICE_OK; | |||
} else { | |||
picture = s->last_picture; | |||
avctx->quality = s->last_qscale; | |||
*pict= *(AVVideoFrame*)&s->last_picture; | |||
} | |||
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_EOP; | |||
} else { | |||
return DECODE_SLICE_OK; | |||
} | |||
@@ -1827,7 +1812,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, | |||
Mpeg1Context *s = avctx->priv_data; | |||
UINT8 *buf_end, *buf_ptr, *buf_start; | |||
int len, start_code_found, ret, code, start_code, input_size; | |||
AVPicture *picture = data; | |||
AVVideoFrame *picture = data; | |||
MpegEncContext *s2 = &s->mpeg_enc_ctx; | |||
dprintf("fill_buffer\n"); | |||
@@ -1837,13 +1822,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx, | |||
/* special case for last picture */ | |||
if (buf_size == 0) { | |||
if (s2->picture_number > 0) { | |||
picture->data[0] = s2->next_picture[0]; | |||
picture->data[1] = s2->next_picture[1]; | |||
picture->data[2] = s2->next_picture[2]; | |||
picture->linesize[0] = s2->linesize; | |||
picture->linesize[1] = s2->uvlinesize; | |||
picture->linesize[2] = s2->uvlinesize; | |||
*data_size = sizeof(AVPicture); | |||
*picture= *(AVVideoFrame*)&s2->next_picture; | |||
*data_size = sizeof(AVVideoFrame); | |||
} | |||
return 0; | |||
} | |||
@@ -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, | |||
int src_x, int src_y, int w, int h); | |||
#define EDGE_WIDTH 16 | |||
/* enable all paranoid tests for rounding, overflows, etc... */ | |||
//#define PARANOID | |||
@@ -268,10 +267,47 @@ int DCT_common_init(MpegEncContext *s) | |||
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 */ | |||
int MPV_common_init(MpegEncContext *s) | |||
{ | |||
UINT8 *pict; | |||
int y_size, c_size, yc_size, i; | |||
dsputil_init(&s->dsp, s->avctx->dsp_mask); | |||
@@ -279,7 +315,7 @@ int MPV_common_init(MpegEncContext *s) | |||
s->flags= s->avctx->flags; | |||
s->mb_width = (s->width + 15) / 16; | |||
s->mb_width = (s->width + 15) / 16; | |||
s->mb_height = (s->height + 15) / 16; | |||
/* set default edge pos, will be overriden in decode_header if needed */ | |||
@@ -298,51 +334,12 @@ int MPV_common_init(MpegEncContext *s) | |||
+ (toupper((s->avctx->fourcc>>16)&0xFF)<<16) | |||
+ (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 | |||
s->avctx->coded_picture= (AVVideoFrame*)&s->current_picture; | |||
if (s->encoding) { | |||
int j; | |||
int mv_table_size= (s->mb_width+2)*(s->mb_height+2); | |||
CHECKED_ALLOCZ(s->mb_var , s->mb_num * sizeof(INT16)) | |||
CHECKED_ALLOCZ(s->mc_mb_var, s->mb_num * sizeof(INT16)) | |||
CHECKED_ALLOCZ(s->mb_mean , s->mb_num * sizeof(INT8)) | |||
/* Allocate MV tables */ | |||
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_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_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){ | |||
CHECKED_ALLOCZ(s->tex_pb_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; | |||
} | |||
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 */ | |||
CHECKED_ALLOCZ(s->mbintra_table, s->mb_num); | |||
memset(s->mbintra_table, 1, s->mb_num); | |||
@@ -470,10 +445,13 @@ void MPV_common_end(MpegEncContext *s) | |||
{ | |||
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_var); | |||
av_freep(&s->mc_mb_var); | |||
av_freep(&s->mb_mean); | |||
av_freep(&s->p_mv_table); | |||
av_freep(&s->b_forw_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->cbp_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_map); | |||
av_freep(&s->me_score_map); | |||
@@ -507,24 +482,9 @@ void MPV_common_end(MpegEncContext *s) | |||
av_freep(&s->avctx->stats_out); | |||
av_freep(&s->ac_stats); | |||
av_freep(&s->error_status_table); | |||
for(i=0;i<3;i++) { | |||
int j; | |||
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]); | |||
} | |||
for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
free_picture(s, &s->picture[i]); | |||
} | |||
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 */ | |||
int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) | |||
{ | |||
int i; | |||
UINT8 *tmp; | |||
int i, r; | |||
AVVideoFrame *pic; | |||
s->mb_skiped = 0; | |||
avctx->mbskip_table= s->mbskip_table; | |||
s->hurry_up= s->avctx->hurry_up; | |||
s->error_resilience= avctx->error_resilience; | |||
if(avctx->flags&CODEC_FLAG_DR1){ | |||
if(avctx->get_buffer_callback(avctx, s->width, s->height, s->pict_type) < 0){ | |||
fprintf(stderr, "get_buffer() failed\n"); | |||
return -1; | |||
/* 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]); | |||
} | |||
} | |||
} | |||
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]; | |||
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->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; | |||
s->linesize = pic->linesize[0]; | |||
s->uvlinesize= pic->linesize[1]; | |||
if(pic->qscale_table==NULL) | |||
alloc_picture(s, (Picture*)pic); | |||
if(s->last_picture[i]==NULL) | |||
s->last_picture[i]= s->next_picture[i]; | |||
s->current_picture= s->picture[i]; | |||
} | |||
s->last_dr_opaque= s->next_dr_opaque; | |||
s->next_dr_opaque= avctx->dr_opaque_frame; | |||
s->hurry_up= s->avctx->hurry_up; | |||
s->error_resilience= avctx->error_resilience; | |||
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; | |||
if (s->pict_type != B_TYPE) { | |||
s->last_picture= s->next_picture; | |||
s->next_picture= s->current_picture; | |||
} | |||
/* 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 */ | |||
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 */ | |||
void MPV_frame_end(MpegEncContext *s) | |||
{ | |||
s->avctx->key_frame = (s->pict_type == I_TYPE); | |||
s->avctx->pict_type = s->pict_type; | |||
int i; | |||
/* draw edge for correct motion prediction if outside */ | |||
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[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); | |||
if(s->codec_id!=CODEC_ID_SVQ1){ | |||
if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH ); | |||
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.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
} | |||
} | |||
emms_c(); | |||
@@ -910,84 +871,154 @@ void MPV_frame_end(MpegEncContext *s) | |||
s->num_available_buffers++; | |||
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 */ | |||
void reorder_input(MpegEncContext *s, AVPicture *pict) | |||
{ | |||
int i, j, index; | |||
if(s->max_b_frames > FF_MAX_B_FRAMES) s->max_b_frames= FF_MAX_B_FRAMES; | |||
// delay= s->max_b_frames+1; (or 0 if no b frames cuz decoder diff) | |||
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 | |||
s->coded_order[j].pict_type=0; | |||
switch(s->input_pict_type){ | |||
default: | |||
case I_TYPE: | |||
case S_TYPE: | |||
case P_TYPE: | |||
index= s->max_b_frames - s->b_frames_since_non_b; | |||
s->b_frames_since_non_b=0; | |||
break; | |||
case B_TYPE: | |||
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]; | |||
} | |||
static int load_input_picture(MpegEncContext *s, AVVideoFrame *pic_arg){ | |||
AVVideoFrame *pic; | |||
int i,r; | |||
const int encoding_delay= s->max_b_frames; | |||
/* 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= 1; | |||
// assert(avctx->get_buffer == default_get_buffer || avctx->get_buffer==NULL); | |||
r= s->avctx->get_buffer(s->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; | |||
} | |||
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{ | |||
//printf("copy\n"); | |||
int h_chroma_shift, v_chroma_shift; | |||
avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &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 | |||
else dest= s->picture_buffer[s->picture_buffer_index][i]; | |||
if (i >= 1) { | |||
dest_wrap >>= 1; | |||
w >>= 1; | |||
h >>= 1; | |||
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; | |||
} | |||
} | |||
} | |||
} | |||
s->coded_order[index].picture[i]= dest; | |||
for(j=0;j<h;j++) { | |||
memcpy(dest, src, w); | |||
dest += dest_wrap; | |||
src += src_wrap; | |||
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(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++){ | |||
s->new_picture[i]= s->coded_order[0].picture[i]; | |||
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) | |||
{ | |||
MpegEncContext *s = avctx->priv_data; | |||
AVPicture *pict = data; | |||
s->input_qscale = avctx->quality; | |||
AVVideoFrame *pic_arg = data; | |||
init_put_bits(&s->pb, buf, buf_size, NULL, NULL); | |||
if(avctx->force_type){ | |||
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; | |||
} | |||
} | |||
s->picture_in_gop_number++; | |||
if(s->input_pict_type==I_TYPE) | |||
s->input_picture_in_gop_number=0; | |||
load_input_picture(s, pic_arg); | |||
reorder_input(s, pict); | |||
select_input_picture(s); | |||
/* output? */ | |||
if(s->coded_order[0].picture[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; | |||
if(s->new_picture.data[0]){ | |||
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); | |||
encode_picture(s, s->picture_number); | |||
@@ -1059,17 +1064,12 @@ int MPV_encode_picture(AVCodecContext *avctx, | |||
if (s->out_format == FMT_MJPEG) | |||
mjpeg_picture_trailer(s); | |||
if(!s->fixed_qscale) | |||
avctx->quality = s->qscale; | |||
if(s->flags&CODEC_FLAG_PASS1) | |||
ff_write_pass1_stats(s); | |||
} | |||
s->input_picture_number++; | |||
s->input_picture_in_gop_number++; | |||
flush_put_bits(&s->pb); | |||
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); | |||
} | |||
#endif | |||
#if 0 | |||
if (avctx->get_psnr) { | |||
/* At this point pict->data should have the original 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); | |||
// printf("%f\n", avctx->psnr_y); | |||
} | |||
#endif | |||
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_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 */ | |||
if (!s->mb_intra) { | |||
@@ -1823,33 +1825,47 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |||
op_pixels_func (*op_pix)[4]; | |||
qpel_mc_func (*op_qpix)[16]; | |||
/* 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 */ | |||
/* avoid copy if macroblock skipped in last frame too */ | |||
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]; | |||
if (s->mb_skiped) { | |||
s->mb_skiped = 0; | |||
const int age= s->current_picture.age; | |||
assert(age); | |||
if (s->mb_skiped) { | |||
s->mb_skiped= 0; | |||
assert(s->pict_type!=I_TYPE); | |||
(*mbskip_ptr) ++; /* indicate that this time we skiped it */ | |||
if(*mbskip_ptr >99) *mbskip_ptr= 99; | |||
/* 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 >= s->ip_buffer_count && !s->encoding) | |||
return; | |||
/* if previous was skipped too, then nothing to do ! */ | |||
if (*mbskip_ptr >= age){ | |||
//if(s->pict_type!=B_TYPE && s->mb_x==0) printf("\n"); | |||
//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 { | |||
*mbskip_ptr = 0; /* not skipped */ | |||
} | |||
} | |||
}else | |||
s->mb_skiped= 0; | |||
if(s->pict_type==B_TYPE && s->avctx->draw_horiz_band){ | |||
dest_y = s->current_picture [0] + mb_x * 16; | |||
dest_cb = s->current_picture[1] + mb_x * 8; | |||
dest_cr = s->current_picture[2] + mb_x * 8; | |||
dest_y = s->current_picture.data[0] + mb_x * 16; | |||
dest_cb = s->current_picture.data[1] + mb_x * 8; | |||
dest_cr = s->current_picture.data[2] + mb_x * 8; | |||
}else{ | |||
dest_y = s->current_picture [0] + (mb_y * 16* s->linesize ) + mb_x * 16; | |||
dest_cb = s->current_picture[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; | |||
dest_cr = s->current_picture[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; | |||
dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16; | |||
dest_cb = s->current_picture.data[1] + (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) { | |||
@@ -1873,12 +1889,12 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |||
} | |||
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_qpix= s->dsp.avg_qpel_pixels_tab; | |||
} | |||
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; | |||
if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | |||
src_ptr[0] = s->current_picture[0] + offset; | |||
src_ptr[1] = s->current_picture[1] + (offset >> 2); | |||
src_ptr[2] = s->current_picture[2] + (offset >> 2); | |||
src_ptr[0] = s->current_picture.data[0] + offset; | |||
src_ptr[1] = s->current_picture.data[1] + (offset >> 2); | |||
src_ptr[2] = s->current_picture.data[2] + (offset >> 2); | |||
} else { | |||
src_ptr[0] = s->last_picture[0] + offset; | |||
src_ptr[1] = s->last_picture[1] + (offset >> 2); | |||
src_ptr[2] = s->last_picture[2] + (offset >> 2); | |||
src_ptr[0] = s->last_picture.data[0] + offset; | |||
src_ptr[1] = s->last_picture.data[1] + (offset >> 2); | |||
src_ptr[2] = s->last_picture.data[2] + (offset >> 2); | |||
} | |||
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; | |||
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->dquant> 2) s->dquant= 2; | |||
@@ -2206,7 +2222,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
int emu=0; | |||
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){ | |||
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; | |||
}else{ | |||
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){ | |||
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; | |||
} | |||
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){ | |||
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; | |||
@@ -2261,14 +2277,14 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
int wrap_y, wrap_c; | |||
int emu=0; | |||
dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize ) + mb_x * 16; | |||
dest_cb = s->current_picture[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |||
dest_cr = s->current_picture[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |||
dest_y = s->current_picture.data[0] + (mb_y * 16 * s->linesize ) + mb_x * 16; | |||
dest_cb = s->current_picture.data[1] + (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_c = s->uvlinesize; | |||
ptr_y = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16; | |||
ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; | |||
ptr_cb = s->new_picture.data[1] + (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){ | |||
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) { | |||
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_qpix= s->dsp.avg_qpel_pixels_tab; | |||
} | |||
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){ | |||
@@ -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); | |||
} | |||
/* 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 | |||
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; | |||
@@ -2557,8 +2572,8 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
s->block_wrap[5]= s->mb_width + 2; | |||
/* Reset the average MB variance */ | |||
s->mb_var_sum = 0; | |||
s->mc_mb_var_sum = 0; | |||
s->current_picture.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 */ | |||
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++) { | |||
int xx = mb_x * 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 sum = s->dsp.pix_sum(pix, s->linesize); | |||
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->mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
s->mb_var_sum += varc; | |||
s->current_picture.mb_var [s->mb_width * mb_y + mb_x] = varc; | |||
s->current_picture.mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
s->current_picture.mb_var_sum += varc; | |||
} | |||
} | |||
} | |||
@@ -2622,13 +2637,9 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
if(s->scene_change_score > 0 && s->pict_type == P_TYPE){ | |||
s->pict_type= I_TYPE; | |||
memset(s->mb_type , MB_TYPE_INTRA, sizeof(UINT8)*s->mb_width*s->mb_height); | |||
if(s->max_b_frames==0){ | |||
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); | |||
//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum); | |||
} | |||
if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) | |||
s->f_code= ff_get_best_fcode(s, s->p_mv_table, MB_TYPE_INTER); | |||
ff_fix_long_p_mvs(s); | |||
@@ -2643,7 +2654,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
} | |||
if (s->fixed_qscale) | |||
s->frame_qscale = s->avctx->quality; | |||
s->frame_qscale = s->current_picture.quality; | |||
else | |||
s->frame_qscale = ff_rate_estimate_qscale(s); | |||
@@ -2658,7 +2669,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
break; | |||
} | |||
s->qscale= s->qscale_table[0]; | |||
s->qscale= s->current_picture.qscale_table[0]; | |||
}else | |||
s->qscale= (int)(s->frame_qscale + 0.5); | |||
@@ -2673,6 +2684,13 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16, | |||
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); | |||
switch(s->out_format) { | |||
@@ -28,6 +28,8 @@ enum OutputFormat { | |||
FMT_MJPEG, | |||
}; | |||
#define EDGE_WIDTH 16 | |||
#define MPEG_BUF_SIZE (16 * 1024) | |||
#define QMAT_SHIFT_MMX 16 | |||
@@ -35,7 +37,8 @@ enum OutputFormat { | |||
#define MAX_FCODE 7 | |||
#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_SHIFT 3 | |||
@@ -90,14 +93,6 @@ typedef struct RateControlContext{ | |||
int last_non_b_pict_type; | |||
}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{ | |||
const UINT8 *scantable; | |||
@@ -109,6 +104,16 @@ typedef struct ScanTable{ | |||
#endif | |||
} 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{ | |||
UINT8 *buffer; | |||
int index; | |||
@@ -145,7 +150,6 @@ typedef struct MpegEncContext { | |||
int max_qdiff; /* max qscale difference between frames */ | |||
int encoding; /* true if we are encoding (vs decoding) */ | |||
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 b_frame_strategy; | |||
int luma_elim_threshold; | |||
@@ -160,10 +164,7 @@ typedef struct MpegEncContext { | |||
/* sequence parameters */ | |||
int context_initialized; | |||
int input_picture_number; | |||
int input_picture_in_gop_number; /* 0-> first pic in gop, ... */ | |||
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 b_frames_since_non_b; /* used for encoding, relative to not yet reordered input */ | |||
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 linesize; /* line size, 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 */ | |||
UINT8 *picture_buffer[REORDER_BUFFER_SIZE][3]; /* internal buffers used for reordering of input pictures */ | |||
int picture_buffer_index; | |||
ReorderBuffer coded_order[REORDER_BUFFER_SIZE]; | |||
UINT8 *last_picture[3]; /* previous picture */ | |||
UINT8 *last_picture_base[3]; /* real start of the picture */ | |||
UINT8 *next_picture[3]; /* previous picture (for bidir pred) */ | |||
UINT8 *next_picture_base[3]; /* real start of the picture */ | |||
UINT8 *aux_picture[3]; /* aux picture (for B frames only) */ | |||
UINT8 *aux_picture_base[3]; /* real start of the picture */ | |||
UINT8 *current_picture[3]; /* buffer to store the decompressed current picture */ | |||
void *last_dr_opaque; | |||
void *next_dr_opaque; | |||
int ip_buffer_count; /* number of buffers, currently only >2 if dr1 is used */ | |||
Picture picture[MAX_PICTURE_COUNT]; /* main picture buffer */ | |||
Picture *input_picture[MAX_PICTURE_COUNT]; /* next pictures on display order for encoding*/ | |||
Picture *reordered_input_picture[MAX_PICTURE_COUNT]; /* pointer to the next pictures in codedorder for encoding*/ | |||
Picture last_picture; /* previous picture */ | |||
Picture next_picture; /* previous picture (for bidir pred) */ | |||
Picture new_picture; /* source picture for encoding */ | |||
Picture current_picture; /* buffer to store the decompressed current picture */ | |||
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 */ | |||
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 *cbp_table; /* used to store cbp, ac_pred 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; | |||
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 */ | |||
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 dquant; /* qscale difference to prev qscale */ | |||
int pict_type; /* I_TYPE, P_TYPE, B_TYPE, ... */ | |||
@@ -272,9 +259,6 @@ typedef struct MpegEncContext { | |||
int mb_x, mb_y; | |||
int mb_incr; | |||
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 */ | |||
#define MB_TYPE_INTRA 0x01 | |||
#define MB_TYPE_INTER 0x02 | |||
@@ -325,8 +309,6 @@ typedef struct MpegEncContext { | |||
/* bit rate control */ | |||
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 total_bits; | |||
int frame_bits; /* bits used for the current frame */ | |||
@@ -476,6 +458,10 @@ typedef struct MpegEncContext { | |||
/* decompression specific */ | |||
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. */ | |||
int progressive_sequence; | |||
int mpeg_f_code[2][2]; | |||
@@ -498,7 +484,6 @@ typedef struct MpegEncContext { | |||
int mpeg2; | |||
int full_pel[2]; | |||
int interlaced_dct; | |||
int last_qscale; | |||
int first_slice; | |||
/* RTP specific */ | |||
@@ -759,10 +759,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, | |||
}else{ | |||
if(n<4){ | |||
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{ | |||
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; | |||
else a= get_dc(dest-8, wrap, scale*8); | |||
@@ -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", | |||
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->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) | |||
@@ -475,11 +475,12 @@ static void adaptive_quantization(MpegEncContext *s, double q){ | |||
float bits_tab[s->mb_num]; | |||
const int qmin= 2; //s->avctx->mb_qmin; | |||
const int qmax= 31; //s->avctx->mb_qmax; | |||
Picture * const pic= &s->current_picture; | |||
for(i=0; i<s->mb_num; i++){ | |||
float temp_cplx= sqrt(s->mc_mb_var[i]); | |||
float spat_cplx= sqrt(s->mb_var[i]); | |||
const int lumi= s->mb_mean[i]; | |||
float temp_cplx= sqrt(pic->mc_mb_var[i]); | |||
float spat_cplx= sqrt(pic->mb_var[i]); | |||
const int lumi= pic->mb_mean[i]; | |||
float bits, cplx, factor; | |||
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; | |||
} | |||
if(i && ABS(s->qscale_table[i-1] - newq)<0.75) | |||
intq= s->qscale_table[i-1]; | |||
if(i && ABS(pic->qscale_table[i-1] - newq)<0.75) | |||
intq= pic->qscale_table[i-1]; | |||
else | |||
intq= (int)(newq + 0.5); | |||
@@ -542,7 +543,7 @@ static void adaptive_quantization(MpegEncContext *s, double q){ | |||
else if(intq < qmin) intq= qmin; | |||
//if(i%s->mb_width==0) printf("\n"); | |||
//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; | |||
int var; | |||
const int pict_type= s->pict_type; | |||
Picture * const pic= &s->current_picture; | |||
emms_c(); | |||
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; | |||
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(pict_type!=I_TYPE) | |||
@@ -599,8 +601,8 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
}else{ | |||
rce->pict_type= | |||
rce->new_pict_type= pict_type; | |||
rce->mc_mb_var_sum= s->mc_mb_var_sum; | |||
rce->mb_var_sum = s-> mb_var_sum; | |||
rce->mc_mb_var_sum= pic->mc_mb_var_sum; | |||
rce->mb_var_sum = pic-> mb_var_sum; | |||
rce->qscale = 2; | |||
rce->f_code = s->f_code; | |||
rce->b_code = s->b_code; | |||
@@ -663,10 +665,8 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
else if(q>qmax) q=qmax; | |||
// 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("q:%d diff:%d comp:%f st_q:%f last_size:%d type:%d\n", qscale, (int)diff, br_compensation, | |||
//printf("diff:%d comp:%f st_q:%f last_size:%d type:%d\n", (int)diff, br_compensation, | |||
// short_term_q, s->frame_bits, pict_type); | |||
//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); | |||
rcc->last_qscale= q; | |||
rcc->last_mc_mb_var_sum= s->mc_mb_var_sum; | |||
rcc->last_mb_var_sum= s->mb_var_sum; | |||
rcc->last_mc_mb_var_sum= pic->mc_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; | |||
} | |||
@@ -472,7 +472,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, | |||
{ | |||
MpegEncContext *s = avctx->priv_data; | |||
int i; | |||
AVPicture *pict = data; | |||
AVVideoFrame *pict = data; | |||
#ifdef DEBUG | |||
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){ | |||
MPV_frame_end(s); | |||
pict->data[0] = s->current_picture[0]; | |||
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; | |||
*pict= *(AVVideoFrame*)&s->current_picture; | |||
avctx->quality = s->qscale; | |||
*data_size = sizeof(AVPicture); | |||
*data_size = sizeof(AVVideoFrame); | |||
}else{ | |||
*data_size = 0; | |||
} | |||
@@ -1063,7 +1063,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
MpegEncContext *s=avctx->priv_data; | |||
uint8_t *current, *previous; | |||
int result, i, x, y, width, height; | |||
AVPicture *pict = data; | |||
AVVideoFrame *pict = data; | |||
/* initialize bit buffer */ | |||
init_get_bits(&s->gb,buf,buf_size); | |||
@@ -1084,9 +1084,6 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
} | |||
result = svq1_decode_frame_header (&s->gb, s); | |||
if(MPV_frame_start(s, avctx) < 0) | |||
return -1; | |||
if (result != 0) | |||
{ | |||
@@ -1098,6 +1095,9 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
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 */ | |||
for (i=0; i < 3; i++) { | |||
int linesize; | |||
@@ -1112,12 +1112,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
linesize= s->uvlinesize; | |||
} | |||
current = s->current_picture[i]; | |||
current = s->current_picture.data[i]; | |||
if(s->pict_type==B_TYPE){ | |||
previous = s->next_picture[i]; | |||
previous = s->next_picture.data[i]; | |||
}else{ | |||
previous = s->last_picture[i]; | |||
previous = s->last_picture.data[i]; | |||
} | |||
if (s->pict_type == I_TYPE) { | |||
@@ -1159,12 +1159,14 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
current += 16*linesize; | |||
} | |||
} | |||
pict->data[i] = s->current_picture[i]; | |||
pict->linesize[i] = linesize; | |||
} | |||
*pict = *(AVVideoFrame*)&s->current_picture; | |||
*data_size=sizeof(AVPicture); | |||
MPV_frame_end(s); | |||
*data_size=sizeof(AVVideoFrame); | |||
return buf_size; | |||
} | |||
@@ -1176,7 +1178,6 @@ static int svq1_decode_init(AVCodecContext *avctx) | |||
s->width = (avctx->width+3)&~3; | |||
s->height = (avctx->height+3)&~3; | |||
s->codec_id= avctx->codec->id; | |||
avctx->mbskip_table= s->mbskip_table; | |||
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 | |||
s->flags= avctx->flags; | |||
@@ -86,6 +86,123 @@ void register_avcodec(AVCodec *format) | |||
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){ | |||
s->bit_rate= 800*1000; | |||
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->gop_size= 50; | |||
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; | |||
} | |||
/** | |||
* 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 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, | |||
const AVPicture *pict) | |||
const AVVideoFrame *pict) | |||
{ | |||
int ret; | |||
@@ -167,17 +296,17 @@ int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
/* decode a frame. return -1 if error, otherwise return the number of | |||
bytes used. If no frame could be decompressed, *got_picture_ptr is | |||
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, | |||
UINT8 *buf, int buf_size) | |||
{ | |||
int ret; | |||
ret = avctx->codec->decode(avctx, picture, got_picture_ptr, | |||
buf, buf_size); | |||
emms_c(); //needed to avoid a emms_c() call before every return; | |||
if (*got_picture_ptr) | |||
avctx->frame_number++; | |||
return ret; | |||
@@ -556,7 +556,7 @@ static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestam | |||
int val; | |||
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; | |||
put_byte(pb, val); | |||
put_byte(pb, stream->seq); | |||
@@ -793,6 +793,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
st = av_mallocz(sizeof(AVStream)); | |||
if (!st) | |||
goto fail; | |||
avcodec_get_context_defaults(&st->codec); | |||
s->streams[s->nb_streams] = st; | |||
asf_st = av_mallocz(sizeof(ASFStream)); | |||
if (!asf_st) | |||
@@ -143,6 +143,8 @@ static int au_read_header(AVFormatContext *s, | |||
st = av_malloc(sizeof(AVStream)); | |||
if (!st) | |||
return -1; | |||
avcodec_get_context_defaults(&st->codec); | |||
s->nb_streams = 1; | |||
s->streams[0] = st; | |||
@@ -144,6 +144,9 @@ typedef struct AVStream { | |||
AVFrac pts; | |||
/* ffmpeg.c private use */ | |||
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; | |||
#define MAX_STREAMS 20 | |||
@@ -103,6 +103,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
AVStream *st = av_mallocz(sizeof(AVStream)); | |||
if (!st) | |||
goto fail; | |||
avcodec_get_context_defaults(&st->codec); | |||
s->streams[i] = st; | |||
} | |||
url_fskip(pb, size - 7 * 4); | |||
@@ -320,7 +320,7 @@ static int avi_write_packet(AVFormatContext *s, int stream_index, | |||
if (enc->codec_type == CODEC_TYPE_VIDEO) { | |||
tag[2] = 'd'; | |||
tag[3] = 'c'; | |||
flags = enc->key_frame ? 0x10 : 0x00; | |||
flags = enc->coded_picture->key_frame ? 0x10 : 0x00; | |||
} else { | |||
tag[2] = 'w'; | |||
tag[3] = 'b'; | |||
@@ -151,7 +151,7 @@ static int ffm_write_header(AVFormatContext *s) | |||
put_be32(pb, codec->codec_id); | |||
put_byte(pb, codec->codec_type); | |||
put_be32(pb, codec->bit_rate); | |||
put_be32(pb, codec->quality); | |||
put_be32(pb, st->quality); | |||
put_be32(pb, codec->flags); | |||
/* specific info */ | |||
switch(codec->codec_type) { | |||
@@ -232,7 +232,7 @@ static int ffm_write_packet(AVFormatContext *s, int stream_index, | |||
/* packet size & key_frame */ | |||
header[0] = stream_index; | |||
header[1] = 0; | |||
if (st->codec.key_frame) | |||
if (st->codec.coded_picture->key_frame) | |||
header[1] |= FLAG_KEY_FRAME; | |||
header[2] = (size >> 16) & 0xff; | |||
header[3] = (size >> 8) & 0xff; | |||
@@ -394,6 +394,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
st = av_mallocz(sizeof(AVStream)); | |||
if (!st) | |||
goto fail; | |||
avcodec_get_context_defaults(&st->codec); | |||
s->streams[i] = st; | |||
fst = av_mallocz(sizeof(FFMStream)); | |||
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_type = get_byte(pb); /* codec_type */ | |||
codec->bit_rate = get_be32(pb); | |||
codec->quality = get_be32(pb); | |||
st->quality = get_be32(pb); | |||
codec->flags = get_be32(pb); | |||
/* specific info */ | |||
switch(codec->codec_type) { | |||
@@ -170,6 +170,8 @@ static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||
av_free(s); | |||
return -ENOMEM; | |||
} | |||
avcodec_get_context_defaults(&st->codec); | |||
s1->streams[0] = st; | |||
s->img_number = 0; | |||
@@ -352,7 +352,7 @@ static int rm_write_video(AVFormatContext *s, UINT8 *buf, int size) | |||
RMContext *rm = s->priv_data; | |||
ByteIOContext *pb = &s->pb; | |||
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 */ | |||
@@ -527,6 +527,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
st = av_mallocz(sizeof(AVStream)); | |||
if (!st) | |||
goto fail; | |||
avcodec_get_context_defaults(&st->codec); | |||
s->streams[s->nb_streams++] = st; | |||
st->id = get_be16(pb); | |||
get_be32(pb); /* max bit rate */ | |||
@@ -482,6 +482,8 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
st = av_mallocz(sizeof(AVStream)); | |||
if (!st) | |||
return -ENOMEM; | |||
avcodec_get_context_defaults(&st->codec); | |||
if (v & 0x01) | |||
st->codec.channels = 2; | |||
else | |||
@@ -458,7 +458,7 @@ int av_find_stream_info(AVFormatContext *ic) | |||
AVCodec *codec; | |||
AVStream *st; | |||
AVPacket *pkt; | |||
AVPicture picture; | |||
AVVideoFrame picture; | |||
AVPacketList *pktl=NULL, **ppktl; | |||
short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2]; | |||
UINT8 *ptr; | |||
@@ -694,6 +694,8 @@ AVStream *av_new_stream(AVFormatContext *s, int id) | |||
st = av_mallocz(sizeof(AVStream)); | |||
if (!st) | |||
return NULL; | |||
avcodec_get_context_defaults(&st->codec); | |||
st->index = s->nb_streams; | |||
st->id = id; | |||
s->streams[s->nb_streams++] = st; | |||