[Libav-user] alternative to file inputs

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[Libav-user] alternative to file inputs

Ed Rupp
Hi,

TL;DR; Any direction on how to feed avformat a buffer of bytes (the contents of which are a complete file) instead of a file from disk is all I really need.
Thanks for making this lib it's pretty amazing and I'm just getting started...

I'm working within a framework in which I receive complete files in the form of a uint8_t* and length.
At first it seemed like the way to go would be custom IO... 
Here's some of the code
//////////////////////
AVFormatContext *fmt = avformat_alloc_context();
std::fstream ifs;
ifs.read(reinterpret_cast<char*>(my_data_from_framework), length);
uint8_t *buf = (unsigned char*)av_malloc(8192); // magic number from web examples
//The read functions below us fstream operations tellg and seekp.
AVIOContext *avio = avio_alloc_context(buf, 8192, 0, (void*)&ifs, read_fun, NULL, seek_fun);
fmt->pb = avio;

//Some of the docs I read made it seem like passing a NULL for filename would work.
int status = avformat_open_input(&fmt, NULL, NULL,NULL)
//avformat_open_input is returning -1 and yes the seg fault happens at the next call below

///////////////

After doing the above I follow up with the following call and get a segfault

avformat_find_stream_info(fmt, NULL);


The docs and the code in libformat utils.c: init_input (see below) make it seem like I should be able to do this i.e. set pb on AVFormatContext but its not doing what I hoped:

325
 /* Open input file and probe the format if necessary. */
326 static int init_input(AVFormatContext *s, const char *filename,
328 {
329  int ret;
330  AVProbeData pd = { filename, NULL, 0 };
331  int score = AVPROBE_SCORE_RETRY;
332 
333  if (s->pb) {
335  if (!s->iformat)
336  return av_probe_input_buffer2(s->pb, &s->iformat, filename,
337  s, 0, s->format_probesize);
338  else if (s->iformat->flags & AVFMT_NOFILE)
339  av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
340  "will be ignored with AVFMT_NOFILE format.\n");
341  return 0;
342  }
343 
344  if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
345  (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
346  return score;
347 
348  if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags,
349  &s->interrupt_callback, options)) < 0)
350  return ret;
351  if (s->iformat)
352  return 0;
353  return av_probe_input_buffer2(s->pb, &s->iformat, filename,
354




Thanks
Ed

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: alternative to file inputs

Ed Rupp
Hey - thanks a lot, that really helped. You focused right in on my issue... I guess a lot of libav noobs screw up the read function. OK now I'm getting  FFERRTAG( 'I','N','D','A') at least I'm making better progress now...
Thanks again!

On Thu, Jan 23, 2020 at 3:41 PM drwho <[hidden email]> wrote:


avio_alloc_context() is the right direction.  Here is my implementation of your "read_fun" which uses a QIODevice instead of std::fstream.   libav calls read_fun when it wants data.  opaque will point to your ifs.  You need to read from ifs and fill libav's buffer (*buf) and then return how many bytes you put into the buffer.

static int read_fun(void *opaque, uint8_t *buf, int bufSize)
{
    QIODevice *dataStream = (QIODevice *) opaque;
    bufSize = FFMIN(bufSize, dataStream->bytesAvailable());
    dataStream->read((char*)buf, bufSize);

    return bufSize;
}

On 2020-01-23 1:22 p.m., Ed Rupp wrote:
Hi,

TL;DR; Any direction on how to feed avformat a buffer of bytes (the contents of which are a complete file) instead of a file from disk is all I really need.
Thanks for making this lib it's pretty amazing and I'm just getting started...

I'm working within a framework in which I receive complete files in the form of a uint8_t* and length.
At first it seemed like the way to go would be custom IO... 
Here's some of the code
//////////////////////
AVFormatContext *fmt = avformat_alloc_context();
std::fstream ifs;
ifs.read(reinterpret_cast<char*>(my_data_from_framework), length);
uint8_t *buf = (unsigned char*)av_malloc(8192); // magic number from web examples
//The read functions below us fstream operations tellg and seekp.
AVIOContext *avio = avio_alloc_context(buf, 8192, 0, (void*)&ifs, read_fun, NULL, seek_fun);
fmt->pb = avio;

//Some of the docs I read made it seem like passing a NULL for filename would work.
int status = avformat_open_input(&fmt, NULL, NULL,NULL)
//avformat_open_input is returning -1 and yes the seg fault happens at the next call below

///////////////

After doing the above I follow up with the following call and get a segfault

avformat_find_stream_info(fmt, NULL);


The docs and the code in libformat utils.c: init_input (see below) make it seem like I should be able to do this i.e. set pb on AVFormatContext but its not doing what I hoped:
325 /* Open input file and probe the format if necessary. */
326 static int init_input(AVFormatContext *s, const char *filename,
328 {
329  int ret;
330  AVProbeData pd = { filename, NULL, 0 };
331  int score = AVPROBE_SCORE_RETRY;
332 
333  if (s->pb) {
335  if (!s->iformat)
336  return av_probe_input_buffer2(s->pb, &s->iformat, filename,
337  s, 0, s->format_probesize);
338  else if (s->iformat->flags & AVFMT_NOFILE)
339  av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
340  "will be ignored with AVFMT_NOFILE format.\n");
341  return 0;
342  }
343 
344  if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
345  (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
346  return score;
347 
348  if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags,
349  &s->interrupt_callback, options)) < 0)
350  return ret;
351  if (s->iformat)
352  return 0;
353  return av_probe_input_buffer2(s->pb, &s->iformat, filename,
354
Thanks
Ed

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".