mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
Reusing the probe buffer to rewind the ByteIOContext in ff_probe_input_buffer() instead of seeking back to the start of the file. Once exhausted, the size of the buffer is reduced.
Originally committed as revision 22821 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
ba659bedb8
commit
01d91b9be9
@ -432,6 +432,21 @@ int url_setbufsize(ByteIOContext *s, int buf_size);
|
|||||||
int url_resetbuf(ByteIOContext *s, int flags);
|
int url_resetbuf(ByteIOContext *s, int flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file.
|
||||||
|
* Used after probing to avoid seeking.
|
||||||
|
* Joins buf and s->buffer, taking any overlap into consideration.
|
||||||
|
* @note s->buffer must overlap with buf or they can't be joined and the function fails
|
||||||
|
* @note This function is NOT part of the public API
|
||||||
|
*
|
||||||
|
* @param s The read-only ByteIOContext to rewind
|
||||||
|
* @param buf The probe buffer containing the first buf_size bytes of the file
|
||||||
|
* @param buf_size The size of buf
|
||||||
|
* @return 0 in case of success, a negative value corresponding to an
|
||||||
|
* AVERROR code in case of failure
|
||||||
|
*/
|
||||||
|
int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and initializes a ByteIOContext for accessing the
|
* Creates and initializes a ByteIOContext for accessing the
|
||||||
* resource indicated by url.
|
* resource indicated by url.
|
||||||
|
@ -295,6 +295,7 @@ static void fill_buffer(ByteIOContext *s)
|
|||||||
{
|
{
|
||||||
uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_ptr : s->buffer;
|
uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_ptr : s->buffer;
|
||||||
int len= s->buffer_size - (dst - s->buffer);
|
int len= s->buffer_size - (dst - s->buffer);
|
||||||
|
int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE;
|
||||||
|
|
||||||
assert(s->buf_ptr == s->buf_end);
|
assert(s->buf_ptr == s->buf_end);
|
||||||
|
|
||||||
@ -308,6 +309,14 @@ static void fill_buffer(ByteIOContext *s)
|
|||||||
s->checksum_ptr= s->buffer;
|
s->checksum_ptr= s->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make buffer smaller in case it ended up large after probing */
|
||||||
|
if (s->buffer_size > max_buffer_size) {
|
||||||
|
url_setbufsize(s, max_buffer_size);
|
||||||
|
|
||||||
|
s->checksum_ptr = dst = s->buffer;
|
||||||
|
len = s->buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
if(s->read_packet)
|
if(s->read_packet)
|
||||||
len = s->read_packet(s->opaque, dst, len);
|
len = s->read_packet(s->opaque, dst, len);
|
||||||
else
|
else
|
||||||
@ -611,6 +620,42 @@ static int url_resetbuf(ByteIOContext *s, int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size)
|
||||||
|
{
|
||||||
|
int64_t buffer_start;
|
||||||
|
int buffer_size;
|
||||||
|
int overlap, new_size;
|
||||||
|
|
||||||
|
if (s->write_flag)
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
|
buffer_size = s->buf_end - s->buffer;
|
||||||
|
|
||||||
|
/* the buffers must touch or overlap */
|
||||||
|
if ((buffer_start = s->pos - buffer_size) > buf_size)
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
|
overlap = buf_size - buffer_start;
|
||||||
|
new_size = buf_size + buffer_size - overlap;
|
||||||
|
|
||||||
|
if (new_size > buf_size) {
|
||||||
|
if (!(buf = av_realloc(buf, new_size)))
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
|
||||||
|
buf_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_free(s->buffer);
|
||||||
|
s->buf_ptr = s->buffer = buf;
|
||||||
|
s->pos = s->buffer_size = buf_size;
|
||||||
|
s->buf_end = s->buf_ptr + buf_size;
|
||||||
|
s->eof_reached = 0;
|
||||||
|
s->must_flush = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int url_fopen(ByteIOContext **s, const char *filename, int flags)
|
int url_fopen(ByteIOContext **s, const char *filename, int flags)
|
||||||
{
|
{
|
||||||
URLContext *h;
|
URLContext *h;
|
||||||
|
@ -516,19 +516,16 @@ int ff_probe_input_buffer(ByteIOContext **pb, AVInputFormat **fmt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
av_free(buf);
|
|
||||||
|
|
||||||
if (!*fmt) {
|
if (!*fmt) {
|
||||||
|
av_free(buf);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url_fseek(*pb, 0, SEEK_SET) < 0) {
|
/* rewind. reuse probe buffer to avoid seeking */
|
||||||
url_fclose(*pb);
|
if ((ret = ff_rewind_with_probe_data(*pb, buf, pd.buf_size)) < 0)
|
||||||
if (url_fopen(pb, filename, URL_RDONLY) < 0)
|
av_free(buf);
|
||||||
return AVERROR(EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
|
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
|
||||||
|
Loading…
Reference in New Issue
Block a user