Newer
Older
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* 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
Philip Gladstone
committed
#undef NDEBUG
#include <assert.h>
Michael Niedermayer
committed
AVInputFormat *first_iformat = NULL;
AVOutputFormat *first_oformat = NULL;
AVImageFormat *first_image_format = NULL;
Fabrice Bellard
committed
void av_register_input_format(AVInputFormat *format)
Fabrice Bellard
committed
AVInputFormat **p;
p = &first_iformat;
while (*p != NULL) p = &(*p)->next;
*p = format;
format->next = NULL;
}
void av_register_output_format(AVOutputFormat *format)
{
AVOutputFormat **p;
p = &first_oformat;
while (*p != NULL) p = &(*p)->next;
*p = format;
format->next = NULL;
}
Fabrice Bellard
committed
int match_ext(const char *filename, const char *extensions)
ext = strrchr(filename, '.');
if (ext) {
ext++;
p = extensions;
for(;;) {
q = ext1;
while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
*q++ = *p++;
*q = '\0';
if (!strcasecmp(ext1, ext))
return 1;
if (*p == '\0')
break;
p++;
}
}
return 0;
}
Fabrice Bellard
committed
AVOutputFormat *guess_format(const char *short_name, const char *filename,
const char *mime_type)
Fabrice Bellard
committed
AVOutputFormat *fmt, *fmt_found;
if (!short_name && filename &&
filename_number_test(filename) >= 0 &&
av_guess_image2_codec(filename) != CODEC_ID_NONE) {
return guess_format("image2", NULL, NULL);
}
if (!short_name && filename &&
filename_number_test(filename) >= 0 &&
guess_image_format(filename)) {
return guess_format("image", NULL, NULL);
}
/* find the proper file type */
fmt_found = NULL;
score_max = 0;
Fabrice Bellard
committed
fmt = first_oformat;
while (fmt != NULL) {
score = 0;
if (fmt->name && short_name && !strcmp(fmt->name, short_name))
score += 100;
if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
score += 10;
if (filename && fmt->extensions &&
match_ext(filename, fmt->extensions)) {
score += 5;
}
if (score > score_max) {
score_max = score;
fmt_found = fmt;
}
fmt = fmt->next;
}
return fmt_found;
}
Philip Gladstone
committed
AVOutputFormat *guess_stream_format(const char *short_name, const char *filename,
const char *mime_type)
{
AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
if (fmt) {
AVOutputFormat *stream_fmt;
char stream_format_name[64];
snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
stream_fmt = guess_format(stream_format_name, NULL, NULL);
if (stream_fmt)
fmt = stream_fmt;
}
return fmt;
}
/**
* guesses the codec id based upon muxer and filename.
*/
enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
const char *filename, const char *mime_type, enum CodecType type){
if(type == CODEC_TYPE_VIDEO){
enum CodecID codec_id= CODEC_ID_NONE;
if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
codec_id= av_guess_image2_codec(filename);
}
if(codec_id == CODEC_ID_NONE)
codec_id= fmt->video_codec;
return codec_id;
}else if(type == CODEC_TYPE_AUDIO)
return fmt->audio_codec;
else
return CODEC_ID_NONE;
}
Fabrice Bellard
committed
AVInputFormat *av_find_input_format(const char *short_name)
{
AVInputFormat *fmt;
for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
if (!strcmp(fmt->name, short_name))
return fmt;
}
return NULL;
}
/**
* Default packet destructor
*/
static void av_destruct_packet(AVPacket *pkt)
{
av_free(pkt->data);
pkt->data = NULL; pkt->size = 0;
}
Fabrice Bellard
committed
/**
* Allocate the payload of a packet and intialized its fields to default values.
*
* @param pkt packet
* @param size wanted payload size
* @return 0 if OK. AVERROR_xxx otherwise.
*/
void *data;
if((unsigned)size > (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
return AVERROR_NOMEM;
data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
Fabrice Bellard
committed
return AVERROR_NOMEM;
memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
av_init_packet(pkt);
pkt->data = data;
pkt->size = size;
pkt->destruct = av_destruct_packet;
/* This is a hack - the packet memory allocation stuff is broken. The
packet is allocated if it was not really allocated */
int av_dup_packet(AVPacket *pkt)
{
if (pkt->destruct != av_destruct_packet) {
uint8_t *data;
/* we duplicate the packet and don't forget to put the padding
again */
if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
return AVERROR_NOMEM;
data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!data) {
return AVERROR_NOMEM;
}
memcpy(data, pkt->data, pkt->size);
memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
pkt->data = data;
pkt->destruct = av_destruct_packet;
}
return 0;
}
/* fifo handling */
int fifo_init(FifoBuffer *f, int size)
{
if (!f->buffer)
return -1;
f->end = f->buffer + size;
f->wptr = f->rptr = f->buffer;
return 0;
}
void fifo_free(FifoBuffer *f)
{
int fifo_size(FifoBuffer *f, uint8_t *rptr)
if (f->wptr >= rptr) {
size = f->wptr - rptr;
} else {
size = (f->end - rptr) + (f->wptr - f->buffer);
}
return size;
}
/* get data from the fifo (return -1 if not enough data) */
int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr)
if(!rptr_ptr)
rptr_ptr= &f->rptr;
rptr = *rptr_ptr;
if (f->wptr >= rptr) {
size = f->wptr - rptr;
} else {
size = (f->end - rptr) + (f->wptr - f->buffer);
}
if (size < buf_size)
return -1;
while (buf_size > 0) {
len = f->end - rptr;
if (len > buf_size)
len = buf_size;
memcpy(buf, rptr, len);
buf += len;
rptr += len;
if (rptr >= f->end)
rptr = f->buffer;
buf_size -= len;
}
*rptr_ptr = rptr;
return 0;
}
void fifo_realloc(FifoBuffer *f, unsigned int new_size){
unsigned int old_size= f->end - f->buffer;
if(old_size < new_size){
uint8_t *old= f->buffer;
f->buffer= av_realloc(f->buffer, new_size);
f->rptr += f->buffer - old;
f->wptr += f->buffer - old;
if(f->wptr < f->rptr){
memmove(f->rptr + new_size - old_size, f->rptr, f->buffer + old_size - f->rptr);
f->rptr += new_size - old_size;
}
f->end= f->buffer + new_size;
}
}
void fifo_write(FifoBuffer *f, uint8_t *buf, int
Loading
Loading full blame...