OpenVisualCloud / SVT-HEVC

SVT HEVC encoder. Scalable Video Technology (SVT) is a software-based video coding technology that is highly optimized for Intel® Xeon® processors. Using the open source SVT-HEVC encoder, it is possible to spread video encoding processing across multiple Intel® Xeon® processors to achieve a real advantage of processing efficiency.
Other
507 stars 169 forks source link

Segmented video #571

Open solSwimmer opened 3 years ago

solSwimmer commented 3 years ago

Is there a prescribed way of using this library with segmented video without having to reallocate the buffers? My current usage is passing in a gop, flushing it, and then passing in another gop, but I'm getting a segfault from the next segment.

tianjunwork commented 3 years ago

Hi @mwbanks , yes there is. We happen to use SVT-HEVC in similar way in one project. I could not share the code since it is not open sourced. I suppose you use sample app directly, not through ffmpeg. In general, Only sample app needs to be tailored to your needs, encoder library stays unchanged. You need to modify the main(){} in sample app code. You only init + start encoder once(allocate all the resources). After https://github.com/OpenVisualCloud/SVT-HEVC/blob/master/Source/App/EbAppMain.c#L197, it should be a loop to encode each gop input files. The input file path can be different each time. All other parameters can NOT be changed on the fly. Good luck. Let me know if you have questions using encoder APIs.

solSwimmer commented 3 years ago

Thank you for your response. So when I'm looping and want to flush a complete gop for packaging, I can just do a normal flush like so?

            headerPtr->nFilledLen   = 0;
            headerPtr->nTickCount   = 0;
            headerPtr->pAppPrivate  = NULL;
            headerPtr->nFlags       = EB_BUFFERFLAG_EOS;
            headerPtr->pBuffer      = NULL;
            headerPtr->sliceType    = EB_INVALID_PICTURE;

            EbH265EncSendPicture(componentHandle, headerPtr);

This is how I'm currently running the app, and I'm getting a segfault from one of the library threads after outputting 2 segments.

tianjunwork commented 3 years ago

If you init encoder once, then encode different input yuv files in a loop. You can NOT flush by sending EOS after each gop. Encoder will perform some finalization internally when it sees EB_BUFFERFLAG_EOS. fflush and fdatasync can be used on bitstream file handle to flush the data from memory to file when one gop if finished. Would you consider a pipe file type as parameter of -i? With that encoder only init once, but read continues data from the pipe. This solution involves less code change to sample app.

solSwimmer commented 3 years ago

I'm actually attempting to use the library in the application we use to encode, our pattern with other codecs is to put a gop in, encode and flush it, package it, and then put another gop in.

So do you flush a gop that is in the library by sending a new IDR frame in? Is this the only way?

What method can I use for determining if I have received a full GOP from the library?

tianjunwork commented 3 years ago

Okay, I thought you are modifying based on SVT sample app. You already have an application that integrates svt library. Yes, you need to config the encoder with -intra-period = gop_size -1, probably -irefresh-type >= 0(based on your need). EbH265GetPacket is the api to get output frame from encoder, how about counting the number of frames you get?

solSwimmer commented 3 years ago

Ok, so with my latest attempt I put the frames for the gop I want to encode in, then put a "flush" IDR frame in to get the encoded segment out. This didn't work. Do I just need to keep putting frames in until I get the original gop out? If I attempt to flush on EbH265GetPacket it hangs unless I send the eos frame, even if I've sent an IDR

tianjunwork commented 3 years ago

Do I just need to keep putting frames in until I get the original gop out? ==> Yes.