Mercurial > libavcodec.hg
comparison mpegvideo.c @ 9124:7f0d34340349 libavcodec
Add frame buffer allocators. aka simplify calls to
AVCodecContext.{get,release}_buffer().
author | gb |
---|---|
date | Wed, 04 Mar 2009 08:47:29 +0000 |
parents | bea68afbf199 |
children | 9e66ada64b76 |
comparison
equal
deleted
inserted
replaced
9123:36a5caff8540 | 9124:7f0d34340349 |
---|---|
163 *dst = *src; | 163 *dst = *src; |
164 dst->type= FF_BUFFER_TYPE_COPY; | 164 dst->type= FF_BUFFER_TYPE_COPY; |
165 } | 165 } |
166 | 166 |
167 /** | 167 /** |
168 * Releases a frame buffer | |
169 */ | |
170 static void free_frame_buffer(MpegEncContext *s, Picture *pic) | |
171 { | |
172 s->avctx->release_buffer(s->avctx, (AVFrame*)pic); | |
173 } | |
174 | |
175 /** | |
176 * Allocates a frame buffer | |
177 */ | |
178 static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) | |
179 { | |
180 int r; | |
181 | |
182 r = s->avctx->get_buffer(s->avctx, (AVFrame*)pic); | |
183 | |
184 if (r<0 || !pic->age || !pic->type || !pic->data[0]) { | |
185 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]); | |
186 return -1; | |
187 } | |
188 | |
189 if (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])) { | |
190 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n"); | |
191 free_frame_buffer(s, pic); | |
192 return -1; | |
193 } | |
194 | |
195 if (pic->linesize[1] != pic->linesize[2]) { | |
196 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n"); | |
197 free_frame_buffer(s, pic); | |
198 return -1; | |
199 } | |
200 | |
201 return 0; | |
202 } | |
203 | |
204 /** | |
168 * allocates a Picture | 205 * allocates a Picture |
169 * The pixels are allocated/set by calling get_buffer() if shared=0 | 206 * The pixels are allocated/set by calling get_buffer() if shared=0 |
170 */ | 207 */ |
171 int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ | 208 int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ |
172 const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) does not sig11 | 209 const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) does not sig11 |
181 assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED); | 218 assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED); |
182 pic->type= FF_BUFFER_TYPE_SHARED; | 219 pic->type= FF_BUFFER_TYPE_SHARED; |
183 }else{ | 220 }else{ |
184 assert(!pic->data[0]); | 221 assert(!pic->data[0]); |
185 | 222 |
186 r= s->avctx->get_buffer(s->avctx, (AVFrame*)pic); | 223 if (alloc_frame_buffer(s, pic) < 0) |
187 | |
188 if(r<0 || !pic->age || !pic->type || !pic->data[0]){ | |
189 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]); | |
190 return -1; | 224 return -1; |
191 } | |
192 | |
193 if(s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])){ | |
194 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n"); | |
195 s->avctx->release_buffer(s->avctx, (AVFrame*)pic); | |
196 return -1; | |
197 } | |
198 | |
199 if(pic->linesize[1] != pic->linesize[2]){ | |
200 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n"); | |
201 s->avctx->release_buffer(s->avctx, (AVFrame*)pic); | |
202 return -1; | |
203 } | |
204 | 225 |
205 s->linesize = pic->linesize[0]; | 226 s->linesize = pic->linesize[0]; |
206 s->uvlinesize= pic->linesize[1]; | 227 s->uvlinesize= pic->linesize[1]; |
207 } | 228 } |
208 | 229 |
247 pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway. | 268 pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway. |
248 | 269 |
249 return 0; | 270 return 0; |
250 fail: //for the CHECKED_ALLOCZ macro | 271 fail: //for the CHECKED_ALLOCZ macro |
251 if(r>=0) | 272 if(r>=0) |
252 s->avctx->release_buffer(s->avctx, (AVFrame*)pic); | 273 free_frame_buffer(s, pic); |
253 return -1; | 274 return -1; |
254 } | 275 } |
255 | 276 |
256 /** | 277 /** |
257 * deallocates a picture | 278 * deallocates a picture |
258 */ | 279 */ |
259 static void free_picture(MpegEncContext *s, Picture *pic){ | 280 static void free_picture(MpegEncContext *s, Picture *pic){ |
260 int i; | 281 int i; |
261 | 282 |
262 if(pic->data[0] && pic->type!=FF_BUFFER_TYPE_SHARED){ | 283 if(pic->data[0] && pic->type!=FF_BUFFER_TYPE_SHARED){ |
263 s->avctx->release_buffer(s->avctx, (AVFrame*)pic); | 284 free_frame_buffer(s, pic); |
264 } | 285 } |
265 | 286 |
266 av_freep(&pic->mb_var); | 287 av_freep(&pic->mb_var); |
267 av_freep(&pic->mc_mb_var); | 288 av_freep(&pic->mc_mb_var); |
268 av_freep(&pic->mb_mean); | 289 av_freep(&pic->mb_mean); |
837 assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3); | 858 assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3); |
838 | 859 |
839 /* mark&release old frames */ | 860 /* mark&release old frames */ |
840 if (s->pict_type != FF_B_TYPE && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) { | 861 if (s->pict_type != FF_B_TYPE && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) { |
841 if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){ | 862 if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){ |
842 avctx->release_buffer(avctx, (AVFrame*)s->last_picture_ptr); | 863 free_frame_buffer(s, s->last_picture_ptr); |
843 | 864 |
844 /* release forgotten pictures */ | 865 /* release forgotten pictures */ |
845 /* if(mpeg124/h263) */ | 866 /* if(mpeg124/h263) */ |
846 if(!s->encoding){ | 867 if(!s->encoding){ |
847 for(i=0; i<MAX_PICTURE_COUNT; i++){ | 868 for(i=0; i<MAX_PICTURE_COUNT; i++){ |
848 if(s->picture[i].data[0] && &s->picture[i] != s->next_picture_ptr && s->picture[i].reference){ | 869 if(s->picture[i].data[0] && &s->picture[i] != s->next_picture_ptr && s->picture[i].reference){ |
849 av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n"); | 870 av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n"); |
850 avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]); | 871 free_frame_buffer(s, &s->picture[i]); |
851 } | 872 } |
852 } | 873 } |
853 } | 874 } |
854 } | 875 } |
855 } | 876 } |
856 alloc: | 877 alloc: |
857 if(!s->encoding){ | 878 if(!s->encoding){ |
858 /* release non reference frames */ | 879 /* release non reference frames */ |
859 for(i=0; i<MAX_PICTURE_COUNT; i++){ | 880 for(i=0; i<MAX_PICTURE_COUNT; i++){ |
860 if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ | 881 if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ |
861 s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]); | 882 free_frame_buffer(s, &s->picture[i]); |
862 } | 883 } |
863 } | 884 } |
864 | 885 |
865 if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL) | 886 if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL) |
866 pic= (AVFrame*)s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header) | 887 pic= (AVFrame*)s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header) |
994 | 1015 |
995 if(s->encoding){ | 1016 if(s->encoding){ |
996 /* release non-reference frames */ | 1017 /* release non-reference frames */ |
997 for(i=0; i<MAX_PICTURE_COUNT; i++){ | 1018 for(i=0; i<MAX_PICTURE_COUNT; i++){ |
998 if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ | 1019 if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ |
999 s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]); | 1020 free_frame_buffer(s, &s->picture[i]); |
1000 } | 1021 } |
1001 } | 1022 } |
1002 } | 1023 } |
1003 // clear copies, to avoid confusion | 1024 // clear copies, to avoid confusion |
1004 #if 0 | 1025 #if 0 |
2066 return; | 2087 return; |
2067 | 2088 |
2068 for(i=0; i<MAX_PICTURE_COUNT; i++){ | 2089 for(i=0; i<MAX_PICTURE_COUNT; i++){ |
2069 if(s->picture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL | 2090 if(s->picture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL |
2070 || s->picture[i].type == FF_BUFFER_TYPE_USER)) | 2091 || s->picture[i].type == FF_BUFFER_TYPE_USER)) |
2071 avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]); | 2092 free_frame_buffer(s, &s->picture[i]); |
2072 } | 2093 } |
2073 s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; | 2094 s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; |
2074 | 2095 |
2075 s->mb_x= s->mb_y= 0; | 2096 s->mb_x= s->mb_y= 0; |
2076 | 2097 |