📄 utils.c
字号:
/* * 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 + -