mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Add AVIO_FLAG_DIRECT.
Allows avoiding the buffer when using avio read, write and seek functions. When using the ffmpeg executable -avioflags direct can be used to enable this mode for input files, but has no effect on output files. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
This commit is contained in:
parent
fde63146d2
commit
a45605a1ba
@ -1083,6 +1083,8 @@ typedef struct AVFormatContext {
|
|||||||
*/
|
*/
|
||||||
#define RAW_PACKET_BUFFER_SIZE 2500000
|
#define RAW_PACKET_BUFFER_SIZE 2500000
|
||||||
int raw_packet_buffer_remaining_size;
|
int raw_packet_buffer_remaining_size;
|
||||||
|
|
||||||
|
int avio_flags;
|
||||||
} AVFormatContext;
|
} AVFormatContext;
|
||||||
|
|
||||||
typedef struct AVPacketList {
|
typedef struct AVPacketList {
|
||||||
|
@ -121,6 +121,13 @@ typedef struct {
|
|||||||
* This field is internal to libavformat and access from outside is not allowed.
|
* This field is internal to libavformat and access from outside is not allowed.
|
||||||
*/
|
*/
|
||||||
int64_t maxsize;
|
int64_t maxsize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* avio_read and avio_write should if possible be satisfied directly
|
||||||
|
* instead of going through a buffer, and avio_seek will always
|
||||||
|
* call the underlying seek function directly.
|
||||||
|
*/
|
||||||
|
int direct;
|
||||||
} AVIOContext;
|
} AVIOContext;
|
||||||
|
|
||||||
/* unbuffered I/O */
|
/* unbuffered I/O */
|
||||||
@ -319,6 +326,14 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen);
|
|||||||
*/
|
*/
|
||||||
#define AVIO_FLAG_NONBLOCK 8
|
#define AVIO_FLAG_NONBLOCK 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use direct mode.
|
||||||
|
* avio_read and avio_write should if possible be satisfied directly
|
||||||
|
* instead of going through a buffer, and avio_seek will always
|
||||||
|
* call the underlying seek function directly.
|
||||||
|
*/
|
||||||
|
#define AVIO_FLAG_DIRECT 0x8000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and initialize a AVIOContext for accessing the
|
* Create and initialize a AVIOContext for accessing the
|
||||||
* resource indicated by url.
|
* resource indicated by url.
|
||||||
|
@ -80,6 +80,7 @@ int ffio_init_context(AVIOContext *s,
|
|||||||
s->buffer_size = buffer_size;
|
s->buffer_size = buffer_size;
|
||||||
s->buf_ptr = buffer;
|
s->buf_ptr = buffer;
|
||||||
s->opaque = opaque;
|
s->opaque = opaque;
|
||||||
|
s->direct = 0;
|
||||||
url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
|
url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
|
||||||
s->write_packet = write_packet;
|
s->write_packet = write_packet;
|
||||||
s->read_packet = read_packet;
|
s->read_packet = read_packet;
|
||||||
@ -117,20 +118,25 @@ AVIOContext *avio_alloc_context(
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_buffer(AVIOContext *s)
|
static void writeout(AVIOContext *s, const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
if (s->buf_ptr > s->buffer) {
|
|
||||||
if (s->write_packet && !s->error){
|
if (s->write_packet && !s->error){
|
||||||
int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
|
int ret= s->write_packet(s->opaque, data, len);
|
||||||
if(ret < 0){
|
if(ret < 0){
|
||||||
s->error = ret;
|
s->error = ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s->pos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flush_buffer(AVIOContext *s)
|
||||||
|
{
|
||||||
|
if (s->buf_ptr > s->buffer) {
|
||||||
|
writeout(s, s->buffer, s->buf_ptr - s->buffer);
|
||||||
if(s->update_checksum){
|
if(s->update_checksum){
|
||||||
s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
|
s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
|
||||||
s->checksum_ptr= s->buffer;
|
s->checksum_ptr= s->buffer;
|
||||||
}
|
}
|
||||||
s->pos += s->buf_ptr - s->buffer;
|
|
||||||
}
|
}
|
||||||
s->buf_ptr = s->buffer;
|
s->buf_ptr = s->buffer;
|
||||||
}
|
}
|
||||||
@ -158,6 +164,11 @@ void ffio_fill(AVIOContext *s, int b, int count)
|
|||||||
|
|
||||||
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
|
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
|
||||||
{
|
{
|
||||||
|
if (s->direct && !s->update_checksum) {
|
||||||
|
avio_flush(s);
|
||||||
|
writeout(s, buf, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
int len = FFMIN(s->buf_end - s->buf_ptr, size);
|
int len = FFMIN(s->buf_end - s->buf_ptr, size);
|
||||||
memcpy(s->buf_ptr, buf, len);
|
memcpy(s->buf_ptr, buf, len);
|
||||||
@ -199,13 +210,14 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
|
|||||||
offset += offset1;
|
offset += offset1;
|
||||||
}
|
}
|
||||||
offset1 = offset - pos;
|
offset1 = offset - pos;
|
||||||
if (!s->must_flush &&
|
if (!s->must_flush && (!s->direct || !s->seek) &&
|
||||||
offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
|
offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
|
||||||
/* can do the seek inside the buffer */
|
/* can do the seek inside the buffer */
|
||||||
s->buf_ptr = s->buffer + offset1;
|
s->buf_ptr = s->buffer + offset1;
|
||||||
} else if ((!s->seekable ||
|
} else if ((!s->seekable ||
|
||||||
offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
|
offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
|
||||||
!s->write_flag && offset1 >= 0 &&
|
!s->write_flag && offset1 >= 0 &&
|
||||||
|
(!s->direct || !s->seek) &&
|
||||||
(whence != SEEK_END || force)) {
|
(whence != SEEK_END || force)) {
|
||||||
while(s->pos < offset && !s->eof_reached)
|
while(s->pos < offset && !s->eof_reached)
|
||||||
fill_buffer(s);
|
fill_buffer(s);
|
||||||
@ -458,7 +470,7 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
|
|||||||
if (len > size)
|
if (len > size)
|
||||||
len = size;
|
len = size;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
if(size > s->buffer_size && !s->update_checksum){
|
if((s->direct || size > s->buffer_size) && !s->update_checksum){
|
||||||
if(s->read_packet)
|
if(s->read_packet)
|
||||||
len = s->read_packet(s->opaque, buf, size);
|
len = s->read_packet(s->opaque, buf, size);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
@ -670,6 +682,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
|
|||||||
av_free(buffer);
|
av_free(buffer);
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
(*s)->direct = h->flags & AVIO_FLAG_DIRECT;
|
||||||
(*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
|
(*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
|
||||||
(*s)->max_packet_size = max_packet_size;
|
(*s)->max_packet_size = max_packet_size;
|
||||||
if(h->prot) {
|
if(h->prot) {
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#define D AV_OPT_FLAG_DECODING_PARAM
|
#define D AV_OPT_FLAG_DECODING_PARAM
|
||||||
|
|
||||||
static const AVOption options[]={
|
static const AVOption options[]={
|
||||||
|
{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
|
||||||
|
{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.dbl = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
|
||||||
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
|
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
|
||||||
{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
|
{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
|
||||||
{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
|
{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
|
||||||
|
@ -543,7 +543,7 @@ static int init_input(AVFormatContext *s, const char *filename, AVDictionary **o
|
|||||||
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
|
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ,
|
if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags,
|
||||||
&s->interrupt_callback, options)) < 0)
|
&s->interrupt_callback, options)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (s->iformat)
|
if (s->iformat)
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
FATE_DEMUX += fate-avio-direct
|
||||||
|
fate-avio-direct: CMD = framecrc -avioflags direct -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi -avioflags direct
|
||||||
|
|
||||||
FATE_DEMUX += fate-adts-demux
|
FATE_DEMUX += fate-adts-demux
|
||||||
fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
|
fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user