⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Various utilities for ffmpeg system * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "avformat.h"#undef NDEBUG#include <assert.h>/** * @file libavformat/utils.c * Various utility functions for using ffmpeg library. *//** head of registered input format linked list. */AVInputFormat *first_iformat = NULL;/** head of registered output format linked list. */AVOutputFormat *first_oformat = NULL;/** head of registered image format linked list. */AVImageFormat *first_image_format = NULL;void av_register_input_format(AVInputFormat *format){    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;}int match_ext(const char *filename, const char *extensions){    const char *ext, *p;    char ext1[32], *q;    if(!filename)        return 0;    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;}AVOutputFormat *guess_format(const char *short_name, const char *filename,                             const char *mime_type){    AVOutputFormat *fmt, *fmt_found;    int score_max, score;    /* specific test for image sequences */    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;    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;}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;}/** * finds AVInputFormat based on input format's short name. */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;}/* memory handling *//** * Default packet destructor. */void av_destruct_packet(AVPacket *pkt){    av_free(pkt->data);    pkt->data = NULL; pkt->size = 0;}/** * 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. */int av_new_packet(AVPacket *pkt, int size){    void *data;    if((unsigned)size > (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)        return AVERROR_NOMEM;    data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);    if (!data)        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;    return 0;}/** * Allocate and read the payload of a packet and intialized its fields to default values. * * @param pkt packet * @param size wanted payload size * @return >0 (read size) if OK. AVERROR_xxx otherwise. */int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size){    int ret= av_new_packet(pkt, size);    if(ret<0)        return ret;    pkt->pos= url_ftell(s);    ret= get_buffer(s, pkt->data, size);    if(ret<=0)        av_free_packet(pkt);    else        pkt->size= ret;    return ret;}/* 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){    f->buffer = av_malloc(size);    if (!f->buffer)        return -1;    f->end = f->buffer + size;    f->wptr = f->rptr = f->buffer;    return 0;}void fifo_free(FifoBuffer *f){    av_free(f->buffer);}int fifo_size(FifoBuffer *f, uint8_t *rptr){    int size;    if(!rptr)        rptr= f->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 (returns -1 if not enough data). */int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr){    uint8_t *rptr;    int size, len;    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;}/** * Resizes a FIFO. */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 size, uint8_t **wptr_ptr){    int len;    uint8_t *wptr;    if(!wptr_ptr)        wptr_ptr= &f->wptr;    wptr = *wptr_ptr;    while (size > 0) {        len = f->end - wptr;        if (len > size)            len = size;        memcpy(wptr, buf, len);        wptr += len;        if (wptr >= f->end)            wptr = f->buffer;        buf += len;        size -= len;    }    *wptr_ptr = wptr;}/* get data from the fifo (return -1 if not enough data) */int put_fifo(ByteIOContext *pb, FifoBuffer *f, int buf_size, uint8_t **rptr_ptr){    uint8_t *rptr = *rptr_ptr;    int size, len;    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;        put_buffer(pb, rptr, len);        rptr += len;        if (rptr >= f->end)            rptr = f->buffer;        buf_size -= len;    }    *rptr_ptr = rptr;    return 0;}int filename_number_test(const char *filename){    char buf[1024];    if(!filename)        return -1;    return get_frame_filename(buf, sizeof(buf), filename, 1);}/** * Guess file format. */AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){    AVInputFormat *fmt1, *fmt;    int score, score_max;    fmt = NULL;    score_max = 0;    for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {        if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))            continue;        score = 0;        if (fmt1->read_probe) {            score = fmt1->read_probe(pd);        } else if (fmt1->extensions) {            if (match_ext(pd->filename, fmt1->extensions)) {                score = 50;            }        }        if (score > score_max) {            score_max = score;            fmt = fmt1;        }    }    return fmt;}/************************************************************//* input media file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -