Commit 6571e41d authored by Michael Niedermayer's avatar Michael Niedermayer

picture buffer cleanup, this fixes a assertion failure (if assertion checking...

picture buffer cleanup, this fixes a assertion failure (if assertion checking was manualy enabled for utils.c) and a memleak at least

Originally committed as revision 2392 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent f0bbfc4a
...@@ -239,6 +239,11 @@ int DCT_common_init(MpegEncContext *s) ...@@ -239,6 +239,11 @@ int DCT_common_init(MpegEncContext *s)
return 0; return 0;
} }
static void copy_picture(Picture *dst, Picture *src){
*dst = *src;
dst->type= FF_BUFFER_TYPE_COPY;
}
/** /**
* allocates a Picture * allocates a Picture
* The pixels are allocated/set by calling get_buffer() if shared=0 * The pixels are allocated/set by calling get_buffer() if shared=0
...@@ -1047,7 +1052,7 @@ alloc: ...@@ -1047,7 +1052,7 @@ alloc:
// s->current_picture_ptr->quality= s->new_picture_ptr->quality; // s->current_picture_ptr->quality= s->new_picture_ptr->quality;
s->current_picture_ptr->key_frame= s->pict_type == I_TYPE; s->current_picture_ptr->key_frame= s->pict_type == I_TYPE;
s->current_picture= *s->current_picture_ptr; copy_picture(&s->current_picture, s->current_picture_ptr);
if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){ if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){
if (s->pict_type != B_TYPE) { if (s->pict_type != B_TYPE) {
...@@ -1055,11 +1060,10 @@ alloc: ...@@ -1055,11 +1060,10 @@ alloc:
s->next_picture_ptr= s->current_picture_ptr; s->next_picture_ptr= s->current_picture_ptr;
} }
if(s->last_picture_ptr) s->last_picture= *s->last_picture_ptr; if(s->last_picture_ptr) copy_picture(&s->last_picture, s->last_picture_ptr);
if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr; if(s->next_picture_ptr) copy_picture(&s->next_picture, s->next_picture_ptr);
if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr;
if(s->pict_type != I_TYPE && s->last_picture_ptr==NULL){ if(s->pict_type != I_TYPE && (s->last_picture_ptr==NULL || s->last_picture_ptr->data[0]==NULL)){
fprintf(stderr, "warning: first frame is no keyframe\n"); fprintf(stderr, "warning: first frame is no keyframe\n");
assert(s->pict_type != B_TYPE); //these should have been dropped if we dont have a reference assert(s->pict_type != B_TYPE); //these should have been dropped if we dont have a reference
goto alloc; goto alloc;
...@@ -1399,22 +1403,17 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ ...@@ -1399,22 +1403,17 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
} }
alloc_picture(s, (Picture*)pic, 1); alloc_picture(s, (Picture*)pic, 1);
}else{ }else{
int offset= 16;
i= find_unused_picture(s, 0); i= find_unused_picture(s, 0);
pic= (AVFrame*)&s->picture[i]; pic= (AVFrame*)&s->picture[i];
pic->reference= 3; pic->reference= 3;
alloc_picture(s, (Picture*)pic, 0); alloc_picture(s, (Picture*)pic, 0);
for(i=0; i<4; i++){
/* the input will be 16 pixels to the right relative to the actual buffer start
* and the current_pic, so the buffer can be reused, yes its not beatifull
*/
pic->data[i]+= 16;
}
if( pic->data[0] == pic_arg->data[0] if( pic->data[0] + offset == pic_arg->data[0]
&& pic->data[1] == pic_arg->data[1] && pic->data[1] + offset == pic_arg->data[1]
&& pic->data[2] == pic_arg->data[2]){ && pic->data[2] + offset == pic_arg->data[2]){
// empty // empty
}else{ }else{
int h_chroma_shift, v_chroma_shift; int h_chroma_shift, v_chroma_shift;
...@@ -1428,7 +1427,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ ...@@ -1428,7 +1427,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
int w= s->width >>h_shift; int w= s->width >>h_shift;
int h= s->height>>v_shift; int h= s->height>>v_shift;
uint8_t *src= pic_arg->data[i]; uint8_t *src= pic_arg->data[i];
uint8_t *dst= pic->data[i]; uint8_t *dst= pic->data[i] + offset;
if(src_stride==dst_stride) if(src_stride==dst_stride)
memcpy(dst, src, src_stride*h); memcpy(dst, src, src_stride*h);
...@@ -1550,7 +1549,7 @@ static void select_input_picture(MpegEncContext *s){ ...@@ -1550,7 +1549,7 @@ static void select_input_picture(MpegEncContext *s){
if(s->reordered_input_picture[0]){ if(s->reordered_input_picture[0]){
s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE ? 3 : 0; s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE ? 3 : 0;
s->new_picture= *s->reordered_input_picture[0]; copy_picture(&s->new_picture, s->reordered_input_picture[0]);
if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED){ if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED){
// input is a shared pix, so we cant modifiy it -> alloc a new one & ensure that the shared one is reuseable // input is a shared pix, so we cant modifiy it -> alloc a new one & ensure that the shared one is reuseable
...@@ -1581,11 +1580,10 @@ static void select_input_picture(MpegEncContext *s){ ...@@ -1581,11 +1580,10 @@ static void select_input_picture(MpegEncContext *s){
s->current_picture_ptr= s->reordered_input_picture[0]; s->current_picture_ptr= s->reordered_input_picture[0];
for(i=0; i<4; i++){ for(i=0; i<4; i++){
//reverse the +16 we did before storing the input s->new_picture.data[i]+=16;
s->current_picture_ptr->data[i]-=16;
} }
} }
s->current_picture= *s->current_picture_ptr; copy_picture(&s->current_picture, s->current_picture_ptr);
s->picture_number= s->new_picture.display_picture_number; s->picture_number= s->new_picture.display_picture_number;
//printf("dpn:%d\n", s->picture_number); //printf("dpn:%d\n", s->picture_number);
......
...@@ -331,7 +331,6 @@ typedef struct MpegEncContext { ...@@ -331,7 +331,6 @@ typedef struct MpegEncContext {
Picture *last_picture_ptr; ///< pointer to the previous picture. Picture *last_picture_ptr; ///< pointer to the previous picture.
Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred)
Picture *new_picture_ptr; ///< pointer to the source picture for encoding
Picture *current_picture_ptr; ///< pointer to the current picture Picture *current_picture_ptr; ///< pointer to the current picture
int last_dc[3]; ///< last DC values for MPEG1 int last_dc[3]; ///< last DC values for MPEG1
int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous
......
...@@ -29,8 +29,8 @@ stddev: 5.28 bytes:7602176 ...@@ -29,8 +29,8 @@ stddev: 5.28 bytes:7602176
242a7a18c2793e115007bc163861ef4e *./data/a-huffyuv.avi 242a7a18c2793e115007bc163861ef4e *./data/a-huffyuv.avi
dde5895817ad9d219f79a52d0bdfb001 *./data/out.yuv dde5895817ad9d219f79a52d0bdfb001 *./data/out.yuv
stddev: 0.00 bytes:7602176 stddev: 0.00 bytes:7602176
910c4f83e031bfb0024380d674d79091 *./data/a-mpeg4-rc.avi f149deded058e0ebb778001922d869ac *./data/a-mpeg4-rc.avi
ec7bb694f4eaca71ec7b106d4fe20092 *./data/out.yuv 6f36eb7cbe1e5e91229f7356c2c88c0a *./data/out.yuv
stddev: 4.20 bytes:7145472 stddev: 4.20 bytes:7145472
bb11d9808375911ea63d4f0889306037 *./data/a-mpeg4-adv.avi bb11d9808375911ea63d4f0889306037 *./data/a-mpeg4-adv.avi
e465df12f2c8a6492a6ec0b1bddc1d0d *./data/out.yuv e465df12f2c8a6492a6ec0b1bddc1d0d *./data/out.yuv
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment