<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Hello, <br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
I'm fairly new to libav and looking forward to some advice. <br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
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.</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
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.
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
This works great when encoding single mp4 files, here is how I do it.<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Custom write/seek function:<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
int WriteFunc(void* opaque, uint8_t* buf, int buf_size) {</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
<br>
<div class="ContentPasted0"> std::vector<uint8_t>* tempBuffer = static_cast<std::vector<uint8_t>*>(opaque);</div>
<div class="ContentPasted0"> // write buf into tempBuffer<br>
</div>
<div class="ContentPasted0"> tempBuffer->insert(tempBuffer->end(), buf, buf + buf_size);</div>
<div class="ContentPasted0"> std::cout << "There are " << tempBuffer->size() << " Bytes in tempBuffer" << std::endl;</div>
<div class="ContentPasted0"> return buf_size;</div>
<div class="ContentPasted0">}</div>
<div><br class="ContentPasted0">
</div>
<div class="ContentPasted0">int64_t SeekFunc(void* opaque, int64_t offset, int whence) {</div>
<div class="ContentPasted0"> </div>
<div class="ContentPasted0"> std::vector<uint8_t>* outputBuffer = static_cast<std::vector<uint8_t>*>(opaque);</div>
<div class="ContentPasted0"> int64_t newPosition = 0;</div>
<div><br class="ContentPasted0">
</div>
<div class="ContentPasted0"> if (whence == SEEK_SET) {</div>
<div class="ContentPasted0"> newPosition = offset;</div>
<div class="ContentPasted0"> }</div>
<div class="ContentPasted0"> else if (whence == SEEK_CUR) {</div>
<div class="ContentPasted0"> newPosition = outputBuffer->size() + offset;</div>
<div class="ContentPasted0"> }</div>
<div class="ContentPasted0"> else if (whence == SEEK_END) {</div>
<div class="ContentPasted0"> newPosition = outputBuffer->size() - offset;</div>
<div class="ContentPasted0"> }</div>
<div class="ContentPasted0"> if (newPosition < 0 || newPosition > outputBuffer->size()) {</div>
<div class="ContentPasted0"> return -1;</div>
<div class="ContentPasted0"> }</div>
<div class="ContentPasted0"> return newPosition;</div>
}</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
Creating avio Context: <br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted1">
const int ioBufferSize = 32768;
<div class="ContentPasted1"> unsigned char* ioBuffer = (unsigned char*)av_malloc(ioBufferSize + AV_INPUT_BUFFER_PADDING_SIZE)</div>
AVIOContext* avio_out = avio_alloc_context(ioBuffer, ioBufferSize, 1, &tempBuffer, 0, WriteFunc, SeekFunc);<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
When I run my code with the following output_context,</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2">
avformat_alloc_output_context2(&encoder->avfc, NULL, "mp4", encoder->filename);</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2">
I can see my tempBuffer filling up. Writing the contents of tempBuffer after encoding results in a playable mp4, so my context is working.<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2">
This doesnt work at all when using 'segment' muxer. My callback functions arent even called and the segments are written</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2 ContentPasted3">
locally based on encoder->filename to file. <br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2 ContentPasted3">
Anyone got experience with that problem? <br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2 ContentPasted3">
Another solution I tried to implement was using fragmented mp4 and trying to manually segment the content of my tempBuffer, but without sucess.
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2 ContentPasted3">
Would love some hints or tips, it's clear that I'm lacking the knowledge of the underlying libav processes to create a solution.
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0 ContentPasted2 ContentPasted3">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof ContentPasted0">
Thanks in advance<br>
</div>
</body>
</html>