6by9 wrote:I gave the generic formula for how many buffers were required as you had not quoted any information about your port format. IL supports passing buffers in slices for pipeline efficieny purposes.
Correct with nFrameHeight = 720, nSliceHeight=720, you should only need one buffer, and you should get one sequence of buffers out the other side ending with one which has OMX_BUFFERFLAG_ENDOFFRAME set.
How many buffers and of what size have you passed in to the output port? The encode isn't complete until all of the output has been produced and it is not necessarily a one-in, one-out buffering scheme. The default output buffer size is only 80kB so that output file writing can also be pipelined via multiple buffers.
My input port has configured as:
Code: Select all
nFrameWidth=IMAGE_WIDTH;
nFrameHeight=IMAGE_HEIGHT;
nSliceHeight=IMAGE_HEIGHT;
nStride=IMAGE_WIDTH*IMAGE_STRIDES;
bFlagErrorConcealment=OMX_FALSE;
eColorFormat=OMX_COLOR_Format24bitBGR888;
eCompressionFormat=OMX_IMAGE_CodingUnused;
nBufferSize=IMAGE_WIDTH*IMAGE_HEIGHT*IMAGE_CHANNELS*IMAGE_STRIDES;
Where:
IMAGE_WIDTH=1280
IMAGE_HEIGHT=720
IMAGE_STRIDES=1
IMAGE_CHANNELS=3
(So the buffer size is exactly 1280*720*3=1 full BGR888 frame)
My output port has configured as:
Code: Select all
nFrameWidth=IMAGE_WIDTH;
nFrameHeight=IMAGE_HEIGHT;
bFlagErrorConcealment=OMX_FALSE;
eColorFormat=OMX_COLOR_FormatYUV420PackedPlanar;
eCompressionFormat=OMX_IMAGE_CodingJPEG;
My buffer i/o code as follows (for 1 frame):
Code: Select all
ctx.encoder_input_buffer_needed=1;
ctx.encoder_output_buffer_available=1;
while(true) {
if(ctx.encoder_input_buffer_needed) {
// Encoder needs something to feed into its input buffer
memcpy(ctx.encoder_ppBuffer_in->pBuffer, BGR888Data, IMAGE_WIDTH*IMAGE_HEIGHT*IMAGE_CHANNELS);
ctx.encoder_ppBuffer_in->nOffset = 0;
ctx.encoder_ppBuffer_in->nFilledLen = IMAGE_WIDTH*IMAGE_HEIGHT*IMAGE_CHANNELS;
ctx.encoder_input_buffer_needed=0; // Will be set to 1 in the event handler
if((r = OMX_EmptyThisBuffer(ctx.encoder, ctx.encoder_ppBuffer_in)) != OMX_ErrorNone) {
omx_die(r, "Failed to request emptying of the input buffer on encoder input port 340");
}
}
if(ctx.encoder_output_buffer_available) {
// Encoder needs to clear its output buffer
write(STDOUT_FILENO, ctx.encoder_ppBuffer_out->pBuffer+ctx.encoder_ppBuffer_out->nOffset, ctx.encoder_ppBuffer_out->nFilledLen);
ctx.encoder_output_buffer_available=0; // Will be set to 1 in the event handler
if((ctx.encoder_ppBuffer_out->nFlags&OMX_BUFFERFLAG_ENDOFFRAME)) {
// 1 frame completed, bail out the loop
break;
}
if((r = OMX_FillThisBuffer(ctx.encoder, ctx.encoder_ppBuffer_out)) != OMX_ErrorNone) {
omx_die(r, "Failed to request filling of the output buffer on encoder output port 341");
}
}
}
For the next frame, it just repeats the above code.
I have added a delay at the end of the code (sleep(2)), so after every one frame encoded, there are time (2s) for raspivid to continue to enocde MJPEG frames. However, it seems that the JPEG block is still not released to raspivid.