Commit 1e491e29 authored by Michael Niedermayer's avatar Michael Niedermayer
Browse files

cleanup

 adding AVVideoFrame
 moving quality, pict_type, key_frame, qscale_table, ... to AVVideoFrame
 removing obsolete variables in AVCodecContext
 skiping of MBs in b frames
 correctly initalizing AVCodecContext
 picture buffer cleanup

Originally committed as revision 1302 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 855ea723
......@@ -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];