Skip to content
Snippets Groups Projects
utils.c 89.5 KiB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
/*
 * Various utilities for ffmpeg system
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
Fabrice Bellard's avatar
Fabrice Bellard committed
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
 *
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
 * 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.
Fabrice Bellard's avatar
Fabrice Bellard committed
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Fabrice Bellard's avatar
Fabrice Bellard committed
 */
Fabrice Bellard's avatar
Fabrice Bellard committed
#include "avformat.h"
#include "opt.h"
#undef NDEBUG
#include <assert.h>

/**
 * @file libavformat/utils.c
 * Various utility functions for using ffmpeg library.
 */

static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den);
static void av_frac_add(AVFrac *f, int64_t incr);

/** head of registered input format linked list. */
/** head of registered output format linked list. */
Fabrice Bellard's avatar
Fabrice Bellard committed

void av_register_input_format(AVInputFormat *format)
Fabrice Bellard's avatar
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;
Fabrice Bellard's avatar
Fabrice Bellard committed
    while (*p != NULL) p = &(*p)->next;
    *p = format;
    format->next = NULL;
}

int match_ext(const char *filename, const char *extensions)
Fabrice Bellard's avatar
Fabrice Bellard committed
{
    const char *ext, *p;
    char ext1[32], *q;

Michael Niedermayer's avatar
Michael Niedermayer committed
    if(!filename)
        return 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
    ext = strrchr(filename, '.');
    if (ext) {
        ext++;
        p = extensions;
        for(;;) {
            q = ext1;
            while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
Fabrice Bellard's avatar
Fabrice Bellard committed
                *q++ = *p++;
            *q = '\0';
            if (!strcasecmp(ext1, ext))
Fabrice Bellard's avatar
Fabrice Bellard committed
                return 1;
            if (*p == '\0')
Fabrice Bellard's avatar
Fabrice Bellard committed
                break;
            p++;
        }
    }
    return 0;
}

AVOutputFormat *guess_format(const char *short_name, const char *filename,
Fabrice Bellard's avatar
Fabrice Bellard committed
{
Fabrice Bellard's avatar
Fabrice Bellard committed
    int score_max, score;

    /* specific test for image sequences */
#ifdef CONFIG_IMAGE2_MUXER
    if (!short_name && filename &&
        av_guess_image2_codec(filename) != CODEC_ID_NONE) {
        return guess_format("image2", NULL, NULL);
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
    /* find the proper file type */
    fmt_found = NULL;
    score_max = 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
    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 &&
Fabrice Bellard's avatar
Fabrice Bellard committed
            match_ext(filename, fmt->extensions)) {
            score += 5;
        }
        if (score > score_max) {
            score_max = score;
            fmt_found = fmt;
        }
        fmt = fmt->next;
    }
    return fmt_found;
Fabrice Bellard's avatar
Fabrice Bellard 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;
}

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;

#ifdef CONFIG_IMAGE2_MUXER
        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;
}

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;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
/* memory handling */

{
    av_free(pkt->data);
    pkt->data = NULL; pkt->size = 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
int av_new_packet(AVPacket *pkt, int size)
{
    if((unsigned)size > (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
        return AVERROR_NOMEM;
    data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
    memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
    pkt->data = data;
    pkt->size = size;
    pkt->destruct = av_destruct_packet;
Fabrice Bellard's avatar
Fabrice Bellard committed
    return 0;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)
{
    int ret= av_new_packet(pkt, size);

    if(ret<0)
Loading
Loading full blame...