You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
7.9 KiB

/*
** ʶ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>ý<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>һЩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
#include "../berrno.h"
#include "avformat.h"
#include <assert.h>
#define UINT_MAX (0xffffffff)
#define PROBE_BUF_MIN 2048
#define PROBE_BUF_MAX 131072
/* <EFBFBD><EFBFBD>Ϊ֧<EFBFBD>ֵĸ<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>кܶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֵĸ<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
AVInputFormat *first_iformat = NULL;
/* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>ʽ*/
void av_register_input_format(AVInputFormat *format)
{
AVInputFormat **p;
p = &first_iformat;
while (*p != NULL)
p = &(*p)->next;
*p = format;
format->next = NULL;
}
/* <EFBFBD>Ƚ<EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
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;
}
/* ̽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ʽ */
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)
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;
}
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int av_open_input_stream(AVFormatContext **ic_ptr, ByteIOContext *pb, const char *filename,
AVInputFormat *fmt, AVFormatParameters *ap)
{
int err;
AVFormatContext *ic;
AVFormatParameters default_ap;
if (!ap)
{
ap = &default_ap;
memset(ap, 0, sizeof(default_ap));
}
ic = av_mallocz(sizeof(AVFormatContext));
if (!ic)
{
err = AVERROR_NOMEM;
goto fail;
}
ic->iformat = fmt;
if (pb)
ic->pb = *pb;
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;
*ic_ptr = ic;
return 0;
fail:
if (ic)
av_freep(&ic->priv_data);
av_free(ic);
*ic_ptr = NULL;
return err;
}
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD>ý<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ */
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, probe_size;
AVProbeData probe_data, *pd = &probe_data;
ByteIOContext pb1, *pb = &pb1;
file_opened = 0;
pd->filename = "";
if (filename)
pd->filename = filename;
pd->buf = NULL;
pd->buf_size = 0;
must_open_file = 1;
if (!fmt || must_open_file)
{
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);
for (probe_size = PROBE_BUF_MIN; probe_size <= PROBE_BUF_MAX && !fmt; probe_size <<= 1)
{
pd->buf = av_realloc(pd->buf, probe_size);
pd->buf_size = url_fread(pb, pd->buf, probe_size);
if (url_fseek(pb, 0, SEEK_SET) == (offset_t) - EPIPE)
{
url_fclose(pb);
if (url_fopen(pb, filename, URL_RDONLY) < 0)
{
file_opened = 0;
err = AVERROR_IO;
goto fail;
}
}
fmt = av_probe_input_format(pd, 1);
}
av_freep(&pd->buf);
}
if (!fmt)
{
err = AVERROR_NOFMT;
goto fail;
}
err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);
if (err)
goto fail;
return 0;
fail:
av_freep(&pd->buf);
if (file_opened)
url_fclose(pb);
*ic_ptr = NULL;
return err;
}
/* һ<EFBFBD>ζ<EFBFBD>ȡһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD> */
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
{
return s->iformat->read_packet(s, pkt);
}
/*
** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щý<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> seek<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ffplay <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
** <EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
{
AVIndexEntry *entries, *ie;
int index;
if ((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) // Խ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
return - 1;
entries = av_fast_realloc(st->index_entries, &st->index_entries_allocated_size,
(st->nb_index_entries + 1) * sizeof(AVIndexEntry));
if (!entries)
return - 1;
st->index_entries = entries;
index = av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY);
if (index < 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
index = st->nb_index_entries++;
ie = &entries[index];
assert(index == 0 || ie[ - 1].timestamp < timestamp);
}
else // <EFBFBD>в<EFBFBD>
{
ie = &entries[index];
if (ie->timestamp != timestamp)
{
if (ie->timestamp <= timestamp)
return - 1;
memmove(entries + index + 1, entries + index,
sizeof(AVIndexEntry)*(st->nb_index_entries - index));
st->nb_index_entries++;
}
}
ie->pos = pos;
ie->timestamp = timestamp;
ie->size = size;
ie->flags = flags;
return index;
}
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
{
AVIndexEntry *entries = st->index_entries;
int nb_entries = st->nb_index_entries;
int a, b, m;
int64_t timestamp;
a = - 1;
b = nb_entries;
while (b - a > 1) //<EFBFBD><EFBFBD>û<EFBFBD>м<EFBFBD>¼idxֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>۰<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
m = (a + b) >> 1;
timestamp = entries[m].timestamp;
if (timestamp >= wanted_timestamp)
b = m;
if (timestamp <= wanted_timestamp)
a = m;
}
m = (flags &AVSEEK_FLAG_BACKWARD) ? a : b;
if (!(flags &AVSEEK_FLAG_ANY))
{
while (m >= 0 && m < nb_entries && !(entries[m].flags &AVINDEX_KEYFRAME))
{
m += (flags &AVSEEK_FLAG_BACKWARD) ? - 1: 1;
}
}
if (m == nb_entries)
return - 1;
return m;
}
void av_close_input_file(AVFormatContext *s)
{
int i;
AVStream *st;
if (s->iformat->read_close)
s->iformat->read_close(s);
for (i = 0; i < s->nb_streams; i++)
{
st = s->streams[i];
av_free(st->index_entries);
av_free(st->actx);
av_free(st);
}
url_fclose(&s->pb);
av_freep(&s->priv_data);
av_free(s);
}
AVStream *av_new_stream(AVFormatContext *s, int id)
{
AVStream *st;
if (s->nb_streams >= MAX_STREAMS)
return NULL;
st = av_mallocz(sizeof(AVStream));
if (!st)
return NULL;
st->actx = avcodec_alloc_context();
s->streams[s->nb_streams++] = st;
return st;
}
void av_set_pts_info(AVStream *s, int pts_wrap_bits, int pts_num, int pts_den)
{
s->time_base.num = pts_num;
s->time_base.den = pts_den;
}