Newer
Older
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
if(size == 0) fprintf(stderr, "Warning, allocating 0 bytes\n");
ptr = av_malloc(size);
if (!ptr)
return NULL;
memset(ptr, 0, size);
return ptr;
}
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/* 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)
{
av_free(*ptr);
*ptr = NULL;
}
/* encoder management */
AVCodec *first_avcodec;
void register_avcodec(AVCodec *format)
{
AVCodec **p;
p = &first_avcodec;
while (*p != NULL) p = &(*p)->next;
*p = format;
format->next = NULL;
}
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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, AVFrame *pic){
int i;
const int width = s->width;
const int height= s->height;
DefaultPicOpaque *opaque;
assert(pic->data[0]==NULL);
assert(pic->type==0 || pic->type==FF_TYPE_INTERNAL);
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift) + 16; //FIXME 16
opaque->data[i]= pic->data[i];
}
pic->age= 256*256*256*64;
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
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;
s->rc_eq= "tex^qComp";
s->qcompress= 0.5;
s->max_qdiff= 3;
s->b_quant_factor=1.25;
s->b_quant_offset=1.25;
Michael Niedermayer
committed
s->i_quant_factor=-0.8;
s->error_concealment= 3;
s->workaround_bugs= FF_BUG_AUTODETECT;
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;
}
/**
* allocates a AVCodecContext and set it to defaults.
* this can be deallocated by simply calling free()
*/
AVCodecContext *avctx= av_mallocz(sizeof(AVCodecContext));
if(avctx==NULL) return NULL;
avcodec_get_context_defaults(avctx);
return avctx;
}
* allocates a AVPFrame and set it to defaults.
AVFrame *avcodec_alloc_frame(void){
AVFrame *pic= av_mallocz(sizeof(AVFrame));
int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{
int ret;
avctx->codec = codec;
if (codec->priv_data_size > 0) {
avctx->priv_data = av_mallocz(codec->priv_data_size);
if (!avctx->priv_data)
return -ENOMEM;
} else {
avctx->priv_data = NULL;
}
return ret;
}
return 0;
}
int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size,
const short *samples)
{
int ret;
ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
avctx->frame_number++;
return ret;
}
int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
{
int ret;
ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
emms_c(); //needed to avoid a emms_c() call before every return;
avctx->frame_number++;
return ret;
}
/* 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, AVFrame *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;
}
/* decode an audio frame. return -1 if error, otherwise return the
*number of bytes used. If no frame could be decompressed,
*frame_size_ptr is zero. Otherwise, it is the decompressed frame
*size in BYTES. */
int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples,
int *frame_size_ptr,
UINT8 *buf, int buf_size)
{
int ret;
ret = avctx->codec->decode(avctx, samples, frame_size_ptr,
buf, buf_size);
avctx->frame_number++;
return ret;
}
int avcodec_close(AVCodecContext *avctx)
{
if (avctx->codec->close)
avctx->codec->close(avctx);
avctx->codec = NULL;
return 0;
}
AVCodec *avcodec_find_encoder(enum CodecID id)
{
AVCodec *p;
p = first_avcodec;
while (p) {
if (p->encode != NULL && p->id == id)
return p;
p = p->next;
}
return NULL;
}
AVCodec *avcodec_find_encoder_by_name(const char *name)
{
AVCodec *p;
p = first_avcodec;
while (p) {
if (p->encode != NULL && strcmp(name,p->name) == 0)
return p;
p = p->next;
}
return NULL;
}
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
AVCodec *avcodec_find_decoder(enum CodecID id)
{
AVCodec *p;
p = first_avcodec;
while (p) {
if (p->decode != NULL && p->id == id)
return p;
p = p->next;
}
return NULL;
}
AVCodec *avcodec_find_decoder_by_name(const char *name)
{
AVCodec *p;
p = first_avcodec;
while (p) {
if (p->decode != NULL && strcmp(name,p->name) == 0)
return p;
p = p->next;
}
return NULL;
}
AVCodec *avcodec_find(enum CodecID id)
{
AVCodec *p;
p = first_avcodec;
while (p) {
if (p->id == id)
return p;
p = p->next;
}
return NULL;
}
const char *pix_fmt_str[] = {
"yuv420p",
"yuv422",
"rgb24",
"bgr24",
"yuv422p",
"yuv444p",
"rgba32",
"bgra32",
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
{
const char *codec_name;
AVCodec *p;
char buf1[32];
char channels_str[100];
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
if (encode)
p = avcodec_find_encoder(enc->codec_id);
else
p = avcodec_find_decoder(enc->codec_id);
if (p) {
codec_name = p->name;
} else if (enc->codec_name[0] != '\0') {
codec_name = enc->codec_name;
} else {
/* output avi tags */
if (enc->codec_type == CODEC_TYPE_VIDEO) {
snprintf(buf1, sizeof(buf1), "%c%c%c%c",
enc->codec_tag & 0xff,
(enc->codec_tag >> 8) & 0xff,
(enc->codec_tag >> 16) & 0xff,
(enc->codec_tag >> 24) & 0xff);
} else {
snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag);
}
codec_name = buf1;
}
switch(enc->codec_type) {
case CODEC_TYPE_VIDEO:
snprintf(buf, buf_size,
"Video: %s%s",
codec_name, enc->flags & CODEC_FLAG_HQ ? " (hq)" : "");
if (enc->codec_id == CODEC_ID_RAWVIDEO) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %s",
pix_fmt_str[enc->pix_fmt]);
}
if (enc->width) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %dx%d, %0.2f fps",
enc->width, enc->height,
(float)enc->frame_rate / FRAME_RATE_BASE);
}
if (encode) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", q=%d-%d", enc->qmin, enc->qmax);
}
break;
case CODEC_TYPE_AUDIO:
snprintf(buf, buf_size,
"Audio: %s",
codec_name);
switch (enc->channels) {
case 1:
strcpy(channels_str, "mono");
break;
case 2:
strcpy(channels_str, "stereo");
break;
case 6:
strcpy(channels_str, "5:1");
break;
default:
sprintf(channels_str, "%d channels", enc->channels);
break;
}
if (enc->sample_rate) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %d Hz, %s",
enc->sample_rate,
channels_str);
/* for PCM codecs, compute bitrate directly */
switch(enc->codec_id) {
case CODEC_ID_PCM_S16LE:
case CODEC_ID_PCM_S16BE:
case CODEC_ID_PCM_U16LE:
case CODEC_ID_PCM_U16BE:
break;
case CODEC_ID_PCM_S8:
case CODEC_ID_PCM_U8:
case CODEC_ID_PCM_ALAW:
case CODEC_ID_PCM_MULAW:
break;
default:
bitrate = enc->bit_rate;
break;
}
if (encode) {
if (enc->flags & CODEC_FLAG_PASS1)
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", pass 1");
if (enc->flags & CODEC_FLAG_PASS2)
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", pass 2");
}
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
/* Picture field are filled with 'ptr' addresses */
void avpicture_fill(AVPicture *picture, UINT8 *ptr,
int pix_fmt, int width, int height)
{
int size;
size = width * height;
switch(pix_fmt) {
case PIX_FMT_YUV420P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 4;
picture->linesize[0] = width;
picture->linesize[1] = width / 2;
picture->linesize[2] = width / 2;
break;
case PIX_FMT_YUV422P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 2;
picture->linesize[0] = width;
picture->linesize[1] = width / 2;
picture->linesize[2] = width / 2;
break;
case PIX_FMT_YUV444P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size;
picture->linesize[0] = width;
picture->linesize[1] = width;
picture->linesize[2] = width;
break;
case PIX_FMT_RGB24:
case PIX_FMT_BGR24:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width * 3;
break;
case PIX_FMT_RGBA32:
case PIX_FMT_BGRA32:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width * 4;
break;
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
case PIX_FMT_YUV422:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width * 2;
break;
default:
picture->data[0] = NULL;
picture->data[1] = NULL;
picture->data[2] = NULL;
break;
}
}
int avpicture_get_size(int pix_fmt, int width, int height)
{
int size;
size = width * height;
switch(pix_fmt) {
case PIX_FMT_YUV420P:
size = (size * 3) / 2;
break;
case PIX_FMT_YUV422P:
size = (size * 2);
break;
case PIX_FMT_YUV444P:
size = (size * 3);
break;
case PIX_FMT_RGB24:
case PIX_FMT_BGR24:
size = (size * 3);
break;
case PIX_FMT_RGBA32:
case PIX_FMT_BGRA32:
size = (size * 4);
break;
case PIX_FMT_YUV422:
size = (size * 2);
break;
default:
size = -1;
break;
}
return size;
}
unsigned avcodec_version( void )
{
return LIBAVCODEC_VERSION_INT;
}
unsigned avcodec_build( void )
{
return LIBAVCODEC_BUILD;
}
/* must be called before any other functions */
void avcodec_init(void)
{
static int inited = 0;
if (inited != 0)
return;
inited = 1;
/* this can be called after seeking and before trying to decode the next keyframe */
void avcodec_flush_buffers(AVCodecContext *avctx)
{
switch(avctx->codec_id){
case CODEC_ID_MPEG1VIDEO:
case CODEC_ID_H263:
case CODEC_ID_RV10:
case CODEC_ID_MJPEG:
case CODEC_ID_MJPEGB:
case CODEC_ID_MPEG4:
case CODEC_ID_MSMPEG4V1:
case CODEC_ID_MSMPEG4V2:
case CODEC_ID_MSMPEG4V3:
case CODEC_ID_WMV1:
case CODEC_ID_WMV2:
case CODEC_ID_H263P:
case CODEC_ID_H263I:
case CODEC_ID_SVQ1:
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL
|| s->picture[i].type == FF_BUFFER_TYPE_USER))
avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]);
}
break;
default:
//FIXME
break;
}
static int raw_encode_init(AVCodecContext *s)
static int raw_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
UINT8 *buf, int buf_size)
static int raw_encode_frame(AVCodecContext *avctx,
unsigned char *frame, int buf_size, void *data)
{
return -1;
}
AVCodec rawvideo_codec = {
"rawvideo",
CODEC_TYPE_VIDEO,
CODEC_ID_RAWVIDEO,
0,
raw_encode_init,
raw_encode_frame,
raw_decode_frame,