fixing mixed dr1 + internal buffers
Originally committed as revision 1820 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		@@ -1089,6 +1089,17 @@ typedef struct AVCodecContext {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    int color_table_id;
 | 
					    int color_table_id;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * internal_buffer count. 
 | 
				
			||||||
 | 
					     * Dont touch, used by lavc default_get_buffer()
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int internal_buffer_count;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * internal_buffers. 
 | 
				
			||||||
 | 
					     * Dont touch, used by lavc default_get_buffer()
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void *internal_buffer;
 | 
				
			||||||
} AVCodecContext;
 | 
					} AVCodecContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1320,6 +1331,7 @@ AVFrame *avcodec_alloc_frame(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
 | 
					int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
 | 
				
			||||||
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
 | 
					void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
 | 
				
			||||||
 | 
					void avcodec_default_free_buffers(AVCodecContext *s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
 | 
					int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
 | 
				
			||||||
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, 
 | 
					int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -624,15 +624,8 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
 | 
				
			|||||||
static int dvvideo_decode_end(AVCodecContext *avctx)
 | 
					static int dvvideo_decode_end(AVCodecContext *avctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DVVideoDecodeContext *s = avctx->priv_data;
 | 
					    DVVideoDecodeContext *s = avctx->priv_data;
 | 
				
			||||||
    int i;
 | 
					
 | 
				
			||||||
    
 | 
					    avcodec_default_free_buffers(avctx);    
 | 
				
			||||||
    if(avctx->get_buffer == avcodec_default_get_buffer){
 | 
					 | 
				
			||||||
        for(i=0; i<4; i++){
 | 
					 | 
				
			||||||
            av_freep(&s->picture.base[i]);
 | 
					 | 
				
			||||||
            s->picture.data[i]= NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        av_freep(&s->picture.opaque);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3868,6 +3868,7 @@ fprintf(stderr, "FMO not supported\n");
 | 
				
			|||||||
|)                                                  |   |        |
 | 
					|)                                                  |   |        |
 | 
				
			||||||
|    slice_group_id[ i ]                            |1  |u(v)    |
 | 
					|    slice_group_id[ i ]                            |1  |u(v)    |
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;
 | 
					    pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;
 | 
				
			||||||
@@ -4366,6 +4367,6 @@ AVCodec h264_decoder = {
 | 
				
			|||||||
    NULL,
 | 
					    NULL,
 | 
				
			||||||
    decode_end,
 | 
					    decode_end,
 | 
				
			||||||
    decode_frame,
 | 
					    decode_frame,
 | 
				
			||||||
    /*CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | */CODEC_CAP_TRUNCATED,
 | 
					    /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -959,14 +959,8 @@ static int decode_end(AVCodecContext *avctx)
 | 
				
			|||||||
    for(i=0; i<3; i++){
 | 
					    for(i=0; i<3; i++){
 | 
				
			||||||
        free_vlc(&s->vlc[i]);
 | 
					        free_vlc(&s->vlc[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    if(avctx->get_buffer == avcodec_default_get_buffer){
 | 
					    avcodec_default_free_buffers(avctx);
 | 
				
			||||||
        for(i=0; i<4; i++){
 | 
					 | 
				
			||||||
            av_freep(&s->picture.base[i]);
 | 
					 | 
				
			||||||
            s->picture.data[i]= NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        av_freep(&s->picture.opaque);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -305,15 +305,8 @@ static void free_picture(MpegEncContext *s, Picture *pic){
 | 
				
			|||||||
        av_freep(&pic->motion_val[i]);
 | 
					        av_freep(&pic->motion_val[i]);
 | 
				
			||||||
        av_freep(&pic->ref_index[i]);
 | 
					        av_freep(&pic->ref_index[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    if(pic->type == FF_BUFFER_TYPE_INTERNAL){
 | 
					    if(pic->type == FF_BUFFER_TYPE_SHARED){
 | 
				
			||||||
        for(i=0; i<4; i++){
 | 
					 | 
				
			||||||
            av_freep(&pic->base[i]);
 | 
					 | 
				
			||||||
            pic->data[i]= NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        av_freep(&pic->opaque);
 | 
					 | 
				
			||||||
        pic->type= 0;
 | 
					 | 
				
			||||||
    }else if(pic->type == FF_BUFFER_TYPE_SHARED){
 | 
					 | 
				
			||||||
        for(i=0; i<4; i++){
 | 
					        for(i=0; i<4; i++){
 | 
				
			||||||
            pic->base[i]=
 | 
					            pic->base[i]=
 | 
				
			||||||
            pic->data[i]= NULL;
 | 
					            pic->data[i]= NULL;
 | 
				
			||||||
@@ -524,6 +517,7 @@ void MPV_common_end(MpegEncContext *s)
 | 
				
			|||||||
    for(i=0; i<MAX_PICTURE_COUNT; i++){
 | 
					    for(i=0; i<MAX_PICTURE_COUNT; i++){
 | 
				
			||||||
        free_picture(s, &s->picture[i]);
 | 
					        free_picture(s, &s->picture[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    avcodec_default_free_buffers(s->avctx);
 | 
				
			||||||
    s->context_initialized = 0;
 | 
					    s->context_initialized = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -978,6 +972,7 @@ alloc:
 | 
				
			|||||||
        s->last_picture_ptr= s->next_picture_ptr;
 | 
					        s->last_picture_ptr= s->next_picture_ptr;
 | 
				
			||||||
        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) s->last_picture= *s->last_picture_ptr;
 | 
				
			||||||
    if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr;
 | 
					    if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr;
 | 
				
			||||||
    if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr;
 | 
					    if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,29 +119,39 @@ void register_avcodec(AVCodec *format)
 | 
				
			|||||||
    format->next = NULL;
 | 
					    format->next = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct DefaultPicOpaque{
 | 
					typedef struct InternalBuffer{
 | 
				
			||||||
    int last_pic_num;
 | 
					    int last_pic_num;
 | 
				
			||||||
 | 
					    uint8_t *base[4];
 | 
				
			||||||
    uint8_t *data[4];
 | 
					    uint8_t *data[4];
 | 
				
			||||||
}DefaultPicOpaque;
 | 
					}InternalBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INTERNAL_BUFFER_SIZE 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
 | 
					int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    const int width = s->width;
 | 
					    const int width = s->width;
 | 
				
			||||||
    const int height= s->height;
 | 
					    const int height= s->height;
 | 
				
			||||||
    DefaultPicOpaque *opaque;
 | 
					    InternalBuffer *buf;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    assert(pic->data[0]==NULL);
 | 
					    assert(pic->data[0]==NULL);
 | 
				
			||||||
    assert(pic->type==0 || pic->type==FF_BUFFER_TYPE_INTERNAL);
 | 
					    assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(pic->opaque){
 | 
					    if(s->internal_buffer==NULL){
 | 
				
			||||||
        opaque= (DefaultPicOpaque *)pic->opaque;
 | 
					        s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer));
 | 
				
			||||||
        for(i=0; i<3; i++)
 | 
					    }
 | 
				
			||||||
            pic->data[i]= opaque->data[i];
 | 
					#if 0
 | 
				
			||||||
 | 
					    s->internal_buffer= av_fast_realloc(
 | 
				
			||||||
 | 
					        s->internal_buffer, 
 | 
				
			||||||
 | 
					        &s->internal_buffer_size, 
 | 
				
			||||||
 | 
					        sizeof(InternalBuffer)*FFMAX(99,  s->internal_buffer_count+1)/*FIXME*/
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//    printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num);    
 | 
					    if(buf->base[0]){
 | 
				
			||||||
        pic->age= pic->coded_picture_number - opaque->last_pic_num;
 | 
					        pic->age= pic->coded_picture_number - buf->last_pic_num;
 | 
				
			||||||
        opaque->last_pic_num= pic->coded_picture_number;
 | 
					        buf->last_pic_num= pic->coded_picture_number;
 | 
				
			||||||
//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number);
 | 
					 | 
				
			||||||
    }else{
 | 
					    }else{
 | 
				
			||||||
        int align, h_chroma_shift, v_chroma_shift;
 | 
					        int align, h_chroma_shift, v_chroma_shift;
 | 
				
			||||||
        int w, h, pixel_size;
 | 
					        int w, h, pixel_size;
 | 
				
			||||||
@@ -174,11 +184,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
 | 
				
			|||||||
            h+= EDGE_WIDTH*2;
 | 
					            h+= EDGE_WIDTH*2;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        opaque= av_mallocz(sizeof(DefaultPicOpaque));
 | 
					        buf->last_pic_num= -256*256*256*64;
 | 
				
			||||||
        if(opaque==NULL) return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        pic->opaque= opaque;
 | 
					 | 
				
			||||||
        opaque->last_pic_num= -256*256*256*64;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(i=0; i<3; i++){
 | 
					        for(i=0; i<3; i++){
 | 
				
			||||||
            const int h_shift= i==0 ? 0 : h_chroma_shift;
 | 
					            const int h_shift= i==0 ? 0 : h_chroma_shift;
 | 
				
			||||||
@@ -186,32 +192,51 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            pic->linesize[i]= pixel_size*w>>h_shift;
 | 
					            pic->linesize[i]= pixel_size*w>>h_shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
 | 
					            buf->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
 | 
				
			||||||
            if(pic->base[i]==NULL) return -1;
 | 
					            if(buf->base[i]==NULL) return -1;
 | 
				
			||||||
 | 
					            memset(buf->base[i], 128, pic->linesize[i]*h>>v_shift);
 | 
				
			||||||
            memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift);
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
            if(s->flags&CODEC_FLAG_EMU_EDGE)
 | 
					            if(s->flags&CODEC_FLAG_EMU_EDGE)
 | 
				
			||||||
                pic->data[i] = pic->base[i];
 | 
					                buf->data[i] = buf->base[i];
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift);
 | 
					                buf->data[i] = buf->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;
 | 
					        pic->age= 256*256*256*64;
 | 
				
			||||||
        pic->type= FF_BUFFER_TYPE_INTERNAL;
 | 
					        pic->type= FF_BUFFER_TYPE_INTERNAL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(i=0; i<4; i++){
 | 
				
			||||||
 | 
					        pic->base[i]= buf->base[i];
 | 
				
			||||||
 | 
					        pic->data[i]= buf->data[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    s->internal_buffer_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
 | 
					void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    
 | 
					    InternalBuffer *buf, *last, temp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
 | 
					    assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    for(i=0; i<3; i++)
 | 
					    for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize
 | 
				
			||||||
 | 
					        buf= &((InternalBuffer*)s->internal_buffer)[i];
 | 
				
			||||||
 | 
					        if(buf->data[0] == pic->data[0])
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    assert(i < s->internal_buffer_count);
 | 
				
			||||||
 | 
					    s->internal_buffer_count--;
 | 
				
			||||||
 | 
					    last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    temp= *buf;
 | 
				
			||||||
 | 
					    *buf= *last;
 | 
				
			||||||
 | 
					    *last= temp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(i=0; i<3; i++){
 | 
				
			||||||
        pic->data[i]=NULL;
 | 
					        pic->data[i]=NULL;
 | 
				
			||||||
 | 
					//        pic->base[i]=NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
//printf("R%X\n", pic->opaque);
 | 
					//printf("R%X\n", pic->opaque);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -592,6 +617,23 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void avcodec_default_free_buffers(AVCodecContext *s){
 | 
				
			||||||
 | 
					    int i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(s->internal_buffer==NULL) return;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for(i=0; i<INTERNAL_BUFFER_SIZE; i++){
 | 
				
			||||||
 | 
					        InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i];
 | 
				
			||||||
 | 
					        for(j=0; j<4; j++){
 | 
				
			||||||
 | 
					            av_freep(&buf->base[j]);
 | 
				
			||||||
 | 
					            buf->data[j]= NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    av_freep(&s->internal_buffer);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    s->internal_buffer_count=0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){
 | 
					int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){
 | 
				
			||||||
    int exact=1, sign=0;
 | 
					    int exact=1, sign=0;
 | 
				
			||||||
    int64_t gcd, larger;
 | 
					    int64_t gcd, larger;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user