📄 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "avformat.h"#undef NDEBUG#include <assert.h>AVInputFormat *first_iformat;AVOutputFormat *first_oformat;AVImageFormat *first_image_format;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++ = *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 && 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;}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 */static 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 = 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;}/* 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 */ 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 (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){ 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; 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_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr){ int len; uint8_t *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;}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 *//** * open a media file from an IO stream. 'fmt' must be specified. */static const char* format_to_name(void* ptr){ AVFormatContext* fc = (AVFormatContext*) ptr; if(fc->iformat) return fc->iformat->name; else if(fc->oformat) return fc->oformat->name; else return "NULL";}static const AVClass av_format_context_class = { "AVFormatContext", format_to_name };AVFormatContext *av_alloc_format_context(void){ AVFormatContext *ic; ic = av_mallocz(sizeof(AVFormatContext)); if (!ic) return ic; ic->av_class = &av_format_context_class; return ic;}int av_open_input_stream(AVFormatContext **ic_ptr, ByteIOContext *pb, const char *filename, AVInputFormat *fmt, AVFormatParameters *ap){ int err; AVFormatContext *ic; ic = av_alloc_format_context(); if (!ic) { err = AVERROR_NOMEM; goto fail; } ic->iformat = fmt; if (pb) ic->pb = *pb; ic->duration = AV_NOPTS_VALUE; ic->start_time = AV_NOPTS_VALUE; pstrcpy(ic->filename, sizeof(ic->filename), filename); /* allocate private data */ if (fmt->priv_data_size > 0) { ic->priv_data = av_mallocz(fmt->priv_data_size); if (!ic->priv_data) { err = AVERROR_NOMEM; goto fail; } } else { ic->priv_data = NULL; } err = ic->iformat->read_header(ic, ap); if (err < 0) goto fail; if (pb) ic->data_offset = url_ftell(&ic->pb); *ic_ptr = ic; return 0; fail: if (ic) { av_freep(&ic->priv_data); } av_free(ic); *ic_ptr = NULL; return err;}#define PROBE_BUF_SIZE 2048/** * Open a media file as input. The codec are not opened. Only the file * header (if present) is read. * * @param ic_ptr the opened media file handle is put here * @param filename filename to open. * @param fmt if non NULL, force the file format to use * @param buf_size optional buffer size (zero if default is OK) * @param ap additionnal parameters needed when opening the file (NULL if default) * @return 0 if OK. AVERROR_xxx otherwise. */int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, AVInputFormat *fmt, int buf_size, AVFormatParameters *ap){ int err, must_open_file, file_opened; uint8_t buf[PROBE_BUF_SIZE]; AVProbeData probe_data, *pd = &probe_data; ByteIOContext pb1, *pb = &pb1; file_opened = 0; pd->filename = ""; if (filename) pd->filename = filename; pd->buf = buf; pd->buf_size = 0; if (!fmt) { /* guess format if no file can be opened */ fmt = av_probe_input_format(pd, 0); } /* do not open file if the format does not need it. XXX: specific hack needed to handle RTSP/TCP */ must_open_file = 1; if (fmt && (fmt->flags & AVFMT_NOFILE)) { must_open_file = 0; } if (!fmt || must_open_file) { /* if no file needed do not try to open one */ if (url_fopen(pb, filename, URL_RDONLY) < 0) { err = AVERROR_IO; goto fail; } file_opened = 1; if (buf_size > 0) { url_setbufsize(pb, buf_size); } if (!fmt) { /* read probe data */ pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE); url_fseek(pb, 0, SEEK_SET); } } /* guess file format */ if (!fmt) { fmt = av_probe_input_format(pd, 1); } /* if still no format found, error */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -