[Libav-user] Segment mp4 using custom Avio I/O Context

Clemens Krone forkfighter2 at hotmail.de
Sun Jul 16 12:14:47 EEST 2023


Hello,

I'm fairly new to libav and looking forward to some advice.
Here is my problem: I'm encoding a video source (webcam, large file) and for direct processing I want the output to be segmented mp4 files.
Instead of writing the segments to file on the hard disk, I was looking for outputting the data into a temp buffer via a custom AvioContext.

This works great when encoding single mp4 files, here is how I do it.
Custom write/seek function:

int WriteFunc(void* opaque, uint8_t* buf, int buf_size) {

    std::vector<uint8_t>* tempBuffer = static_cast<std::vector<uint8_t>*>(opaque);
    // write buf into tempBuffer
    tempBuffer->insert(tempBuffer->end(), buf, buf + buf_size);
    std::cout << "There are " << tempBuffer->size() << " Bytes in tempBuffer" << std::endl;
    return buf_size;
}

int64_t SeekFunc(void* opaque, int64_t offset, int whence) {

    std::vector<uint8_t>* outputBuffer = static_cast<std::vector<uint8_t>*>(opaque);
    int64_t newPosition = 0;

    if (whence == SEEK_SET) {
        newPosition = offset;
    }
    else if (whence == SEEK_CUR) {
        newPosition = outputBuffer->size() + offset;
    }
    else if (whence == SEEK_END) {
        newPosition = outputBuffer->size() - offset;
    }
    if (newPosition < 0 || newPosition > outputBuffer->size()) {
        return -1;
    }
    return newPosition;
}

Creating avio Context:
const int ioBufferSize = 32768;
    unsigned char* ioBuffer = (unsigned char*)av_malloc(ioBufferSize + AV_INPUT_BUFFER_PADDING_SIZE)
    AVIOContext* avio_out = avio_alloc_context(ioBuffer, ioBufferSize, 1, &tempBuffer, 0, WriteFunc, SeekFunc);

When I run my code with the following output_context,
avformat_alloc_output_context2(&encoder->avfc, NULL, "mp4", encoder->filename);
I can see my tempBuffer filling up. Writing the contents of tempBuffer after encoding results in a playable mp4, so my context is working.

This doesnt work at all when using 'segment' muxer. My callback functions arent even called and the segments are written
locally based on encoder->filename to file.
Anyone got experience with that problem?
Another solution I tried to implement was using fragmented mp4 and trying to manually segment the content of my tempBuffer, but without sucess.
Would love some hints or tips, it's clear that I'm lacking the knowledge of the underlying libav processes to create a solution.

Thanks in advance
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20230716/20a0f3de/attachment.htm>


More information about the Libav-user mailing list