Mercurial > mplayer.hg
comparison libmpcodecs/vd_libmpeg2.c @ 18301:bf150feefe40
Fix memory corruption in vd_libmpeg2
author | uau |
---|---|
date | Thu, 27 Apr 2006 02:46:33 +0000 |
parents | 6ff3379a0862 |
children | 22805699b7b1 |
comparison
equal
deleted
inserted
replaced
18300:21cafb27aa03 | 18301:bf150feefe40 |
---|---|
27 #include "libmpeg2/attributes.h" | 27 #include "libmpeg2/attributes.h" |
28 #include "libmpeg2/mpeg2_internal.h" | 28 #include "libmpeg2/mpeg2_internal.h" |
29 | 29 |
30 #include "cpudetect.h" | 30 #include "cpudetect.h" |
31 | 31 |
32 typedef struct { | |
33 mpeg2dec_t *mpeg2dec; | |
34 int quant_store_idx; | |
35 char *quant_store[3]; | |
36 } vd_libmpeg2_ctx_t; | |
37 | |
32 // to set/get/query special features/parameters | 38 // to set/get/query special features/parameters |
33 static int control(sh_video_t *sh,int cmd,void* arg,...){ | 39 static int control(sh_video_t *sh,int cmd,void* arg,...){ |
34 mpeg2dec_t * mpeg2dec = sh->context; | 40 vd_libmpeg2_ctx_t *context = sh->context; |
41 mpeg2dec_t * mpeg2dec = context->mpeg2dec; | |
35 const mpeg2_info_t * info = mpeg2_info (mpeg2dec); | 42 const mpeg2_info_t * info = mpeg2_info (mpeg2dec); |
36 | 43 |
37 switch(cmd) { | 44 switch(cmd) { |
38 case VDCTRL_QUERY_FORMAT: | 45 case VDCTRL_QUERY_FORMAT: |
39 if (info->sequence->width >> 1 == info->sequence->chroma_width && | 46 if (info->sequence->width >> 1 == info->sequence->chroma_width && |
50 return CONTROL_UNKNOWN; | 57 return CONTROL_UNKNOWN; |
51 } | 58 } |
52 | 59 |
53 // init driver | 60 // init driver |
54 static int init(sh_video_t *sh){ | 61 static int init(sh_video_t *sh){ |
62 vd_libmpeg2_ctx_t *context; | |
55 mpeg2dec_t * mpeg2dec; | 63 mpeg2dec_t * mpeg2dec; |
56 // const mpeg2_info_t * info; | 64 // const mpeg2_info_t * info; |
57 int accel; | 65 int accel; |
58 | 66 |
59 accel = 0; | 67 accel = 0; |
73 mpeg2dec = mpeg2_init (); | 81 mpeg2dec = mpeg2_init (); |
74 | 82 |
75 if(!mpeg2dec) return 0; | 83 if(!mpeg2dec) return 0; |
76 | 84 |
77 mpeg2_custom_fbuf(mpeg2dec,1); // enable DR1 | 85 mpeg2_custom_fbuf(mpeg2dec,1); // enable DR1 |
78 | 86 |
79 sh->context=mpeg2dec; | 87 context = calloc(1, sizeof(vd_libmpeg2_ctx_t)); |
88 context->mpeg2dec = mpeg2dec; | |
89 sh->context = context; | |
80 | 90 |
81 mpeg2dec->pending_buffer = 0; | 91 mpeg2dec->pending_buffer = 0; |
82 mpeg2dec->pending_length = 0; | 92 mpeg2dec->pending_length = 0; |
83 | 93 |
84 return 1; | 94 return 1; |
85 } | 95 } |
86 | 96 |
87 // uninit driver | 97 // uninit driver |
88 static void uninit(sh_video_t *sh){ | 98 static void uninit(sh_video_t *sh){ |
89 mpeg2dec_t * mpeg2dec = sh->context; | 99 int i; |
100 vd_libmpeg2_ctx_t *context = sh->context; | |
101 mpeg2dec_t * mpeg2dec = context->mpeg2dec; | |
90 if (mpeg2dec->pending_buffer) free(mpeg2dec->pending_buffer); | 102 if (mpeg2dec->pending_buffer) free(mpeg2dec->pending_buffer); |
91 mpeg2dec->decoder.convert=NULL; | 103 mpeg2dec->decoder.convert=NULL; |
92 mpeg2dec->decoder.convert_id=NULL; | 104 mpeg2dec->decoder.convert_id=NULL; |
93 mpeg2_close (mpeg2dec); | 105 mpeg2_close (mpeg2dec); |
106 for (i=0; i < 3; i++) | |
107 free(context->quant_store[i]); | |
108 free(sh->context); | |
94 } | 109 } |
95 | 110 |
96 static void draw_slice (void * _sh, uint8_t * const * src, unsigned int y){ | 111 static void draw_slice (void * _sh, uint8_t * const * src, unsigned int y){ |
97 sh_video_t* sh = (sh_video_t*) _sh; | 112 sh_video_t* sh = (sh_video_t*) _sh; |
98 mpeg2dec_t* mpeg2dec = sh->context; | 113 vd_libmpeg2_ctx_t *context = sh->context; |
114 mpeg2dec_t* mpeg2dec = context->mpeg2dec; | |
99 const mpeg2_info_t * info = mpeg2_info (mpeg2dec); | 115 const mpeg2_info_t * info = mpeg2_info (mpeg2dec); |
100 int stride[3]; | 116 int stride[3]; |
101 | 117 |
102 // printf("draw_slice() y=%d \n",y); | 118 // printf("draw_slice() y=%d \n",y); |
103 | 119 |
111 0, y); | 127 0, y); |
112 } | 128 } |
113 | 129 |
114 // decode a frame | 130 // decode a frame |
115 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ | 131 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ |
116 mpeg2dec_t * mpeg2dec = sh->context; | 132 vd_libmpeg2_ctx_t *context = sh->context; |
133 mpeg2dec_t * mpeg2dec = context->mpeg2dec; | |
117 const mpeg2_info_t * info = mpeg2_info (mpeg2dec); | 134 const mpeg2_info_t * info = mpeg2_info (mpeg2dec); |
118 int drop_frame, framedrop=flags&3; | 135 int drop_frame, framedrop=flags&3; |
119 | 136 |
120 // MPlayer registers its own draw_slice callback, prevent libmpeg2 from freeing the context | 137 // MPlayer registers its own draw_slice callback, prevent libmpeg2 from freeing the context |
121 mpeg2dec->decoder.convert=NULL; | 138 mpeg2dec->decoder.convert=NULL; |
198 mpi_new->fields |= MP_IMGFIELD_REPEAT_FIRST; | 215 mpi_new->fields |= MP_IMGFIELD_REPEAT_FIRST; |
199 else mpi_new->fields &= ~MP_IMGFIELD_REPEAT_FIRST; | 216 else mpi_new->fields &= ~MP_IMGFIELD_REPEAT_FIRST; |
200 mpi_new->fields |= MP_IMGFIELD_ORDERED; | 217 mpi_new->fields |= MP_IMGFIELD_ORDERED; |
201 | 218 |
202 #ifdef MPEG12_POSTPROC | 219 #ifdef MPEG12_POSTPROC |
203 if(!mpi_new->qscale){ | 220 mpi_new->qstride=info->sequence->width>>4; |
204 mpi_new->qstride=info->sequence->width>>4; | 221 { |
205 mpi_new->qscale=malloc(mpi_new->qstride*(info->sequence->height>>4)); | 222 char **p = &context->quant_store[type==PIC_FLAG_CODING_TYPE_B ? |
223 2 : (context->quant_store_idx ^= 1)]; | |
224 *p = realloc(*p, mpi_new->qstride*(info->sequence->height>>4)); | |
225 mpi_new->qscale = *p; | |
206 } | 226 } |
207 mpeg2dec->decoder.quant_store=mpi_new->qscale; | 227 mpeg2dec->decoder.quant_store=mpi_new->qscale; |
208 mpeg2dec->decoder.quant_stride=mpi_new->qstride; | 228 mpeg2dec->decoder.quant_stride=mpi_new->qstride; |
209 mpi_new->pict_type=type; // 1->I, 2->P, 3->B | 229 mpi_new->pict_type=type; // 1->I, 2->P, 3->B |
210 mpi_new->qscale_type= 1; | 230 mpi_new->qscale_type= 1; |