summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/utils.c')
-rw-r--r--src/libffmpeg/libavcodec/utils.c177
1 files changed, 173 insertions, 4 deletions
diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c
index 6797508e1..bc7da83ef 100644
--- a/src/libffmpeg/libavcodec/utils.c
+++ b/src/libffmpeg/libavcodec/utils.c
@@ -23,6 +23,9 @@
void *av_mallocz(unsigned int size)
{
void *ptr;
+
+ if(size == 0) fprintf(stderr, "Warning, allocating 0 bytes\n");
+
ptr = av_malloc(size);
if (!ptr)
return NULL;
@@ -30,6 +33,43 @@ void *av_mallocz(unsigned int size)
return ptr;
}
+/* allocation of static arrays - do not use for normal allocation */
+static unsigned int last_static = 0;
+static char*** array_static = NULL;
+static const unsigned int grow_static = 64; // ^2
+void *__av_mallocz_static(void** location, unsigned int size)
+{
+ int l = (last_static + grow_static) & ~(grow_static - 1);
+ void *ptr = av_mallocz(size);
+ if (!ptr)
+ return NULL;
+
+ if (location)
+ {
+ if (l > last_static)
+ array_static = realloc(array_static, l);
+ array_static[last_static++] = (char**) location;
+ *location = ptr;
+ }
+ return ptr;
+}
+/* free all static arrays and reset pointers to 0 */
+void av_free_static()
+{
+ if (array_static)
+ {
+ unsigned i;
+ for (i = 0; i < last_static; i++)
+ {
+ free(*array_static[i]);
+ *array_static[i] = NULL;
+ }
+ free(array_static);
+ array_static = 0;
+ }
+ last_static = 0;
+}
+
/* cannot call it directly because of 'void **' casting is not automatic */
void __av_freep(void **ptr)
{
@@ -49,6 +89,123 @@ void register_avcodec(AVCodec *format)
format->next = NULL;
}
+void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift){
+ switch(fmt){
+ case PIX_FMT_YUV410P:
+ *h_shift=2;
+ *v_shift=2;
+ break;
+ case PIX_FMT_YUV420P:
+ *h_shift=1;
+ *v_shift=1;
+ break;
+ case PIX_FMT_YUV411P:
+ *h_shift=2;
+ *v_shift=0;
+ break;
+ case PIX_FMT_YUV422P:
+ case PIX_FMT_YUV422:
+ *h_shift=1;
+ *v_shift=0;
+ break;
+ default: //RGB/...
+ *h_shift=0;
+ *v_shift=0;
+ break;
+ }
+}
+
+typedef struct DefaultPicOpaque{
+ int last_pic_num;
+ uint8_t *data[4];
+}DefaultPicOpaque;
+
+int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic){
+ int i;
+ const int width = s->width;
+ const int height= s->height;
+ DefaultPicOpaque *opaque;
+
+ if(pic->opaque){
+ opaque= (DefaultPicOpaque *)pic->opaque;
+ for(i=0; i<3; i++)
+ pic->data[i]= opaque->data[i];
+
+// printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num);
+ pic->age= pic->coded_picture_number - opaque->last_pic_num;
+ opaque->last_pic_num= pic->coded_picture_number;
+//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number);
+ }else{
+ int align, h_chroma_shift, v_chroma_shift;
+ int w, h, pixel_size;
+
+ avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+
+ switch(s->pix_fmt){
+ case PIX_FMT_YUV422:
+ pixel_size=2;
+ break;
+ case PIX_FMT_RGB24:
+ case PIX_FMT_BGR24:
+ pixel_size=3;
+ break;
+ case PIX_FMT_BGRA32:
+ case PIX_FMT_RGBA32:
+ pixel_size=4;
+ break;
+ default:
+ pixel_size=1;
+ }
+
+ if(s->codec_id==CODEC_ID_SVQ1) align=63;
+ else align=15;
+
+ w= (width +align)&~align;
+ h= (height+align)&~align;
+
+ if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
+ w+= EDGE_WIDTH*2;
+ h+= EDGE_WIDTH*2;
+ }
+
+ opaque= av_mallocz(sizeof(DefaultPicOpaque));
+ if(opaque==NULL) return -1;
+
+ pic->opaque= opaque;
+ opaque->last_pic_num= -256*256*256*64;
+
+ for(i=0; i<3; i++){
+ int h_shift= i==0 ? 0 : h_chroma_shift;
+ int v_shift= i==0 ? 0 : v_chroma_shift;
+
+ pic->linesize[i]= pixel_size*w>>h_shift;
+
+ pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
+ if(pic->base[i]==NULL) return -1;
+
+ memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift);
+
+ if(s->flags&CODEC_FLAG_EMU_EDGE)
+ pic->data[i] = pic->base[i];
+ else
+ pic->data[i] = pic->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;
+ }
+
+ return 0;
+}
+
+void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic){
+ int i;
+
+ for(i=0; i<3; i++)
+ pic->data[i]=NULL;
+//printf("R%X\n", pic->opaque);
+}
+
void avcodec_get_context_defaults(AVCodecContext *s){
s->bit_rate= 800*1000;
s->bit_rate_tolerance= s->bit_rate*10;
@@ -67,6 +224,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){
s->frame_rate = 25 * FRAME_RATE_BASE;
s->gop_size= 50;
s->me_method= ME_EPZS;
+ s->get_buffer= avcodec_default_get_buffer;
+ s->release_buffer= avcodec_default_release_buffer;
}
/**
@@ -83,6 +242,16 @@ AVCodecContext *avcodec_alloc_context(void){
return avctx;
}
+/**
+ * allocates a AVPicture and set it to defaults.
+ * this can be deallocated by simply calling free()
+ */
+AVVideoFrame *avcodec_alloc_picture(void){
+ AVVideoFrame *pic= av_mallocz(sizeof(AVVideoFrame));
+
+ return pic;
+}
+
int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{
int ret;
@@ -115,7 +284,7 @@ int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size,
}
int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
- const AVPicture *pict)
+ const AVVideoFrame *pict)
{
int ret;
@@ -130,17 +299,17 @@ int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
/* decode a frame. return -1 if error, otherwise return the number of
bytes used. If no frame could be decompressed, *got_picture_ptr is
zero. Otherwise, it is non zero */
-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 ret;
-
+
ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
buf, buf_size);
emms_c(); //needed to avoid a emms_c() call before every return;
-
+
if (*got_picture_ptr)
avctx->frame_number++;
return ret;