Commit eb39bd4a authored by Martin Storsjö's avatar Martin Storsjö

h264_nal: Support resuming bitstream format conversion across buffers

This is necessary in order to pass one single H264 packet in
multiple OMX buffers to the decoder.
Signed-off-by: Martin Storsjö's avatarMartin Storsjö <martin@martin.st>
parent d7cc0fc2
......@@ -99,24 +99,46 @@ static int convert_sps_pps( decoder_t *p_dec, const uint8_t *p_buf,
}
/* Convert H.264 NAL format to annex b in-place */
struct H264ConvertState {
uint32_t nal_len;
uint32_t nal_pos;
};
static void convert_h264_to_annexb( uint8_t *p_buf, uint32_t i_len,
size_t i_nal_size )
size_t i_nal_size,
struct H264ConvertState *state )
{
if( i_nal_size < 3 || i_nal_size > 4 )
return;
/* This only works for NAL sizes 3-4 */
while( i_len >= i_nal_size )
while( i_len > 0 )
{
uint32_t nal_len = 0;
for( unsigned int i = 0; i < i_nal_size; i++ ) {
nal_len = (nal_len << 8) | p_buf[i];
p_buf[i] = 0;
if( state->nal_pos < i_nal_size ) {
unsigned int i;
for( i = 0; state->nal_pos < i_nal_size && i < i_len; i++, state->nal_pos++ ) {
state->nal_len = (state->nal_len << 8) | p_buf[i];
p_buf[i] = 0;
}
if( state->nal_pos < i_nal_size )
return;
p_buf[i - 1] = 1;
p_buf += i;
i_len -= i;
}
if( state->nal_len > INT_MAX )
return;
if( state->nal_len > i_len )
{
state->nal_len -= i_len;
return;
}
else
{
p_buf += state->nal_len;
i_len -= state->nal_len;
state->nal_len = 0;
state->nal_pos = 0;
}
p_buf[i_nal_size - 1] = 1;
if( nal_len > INT_MAX || nal_len + i_nal_size > (unsigned int) i_len )
break;
p_buf += nal_len + i_nal_size;
i_len -= nal_len + i_nal_size;
}
}
......@@ -495,6 +495,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
decoder_sys_t *p_sys = p_dec->p_sys;
picture_t *p_pic = NULL;
JNIEnv *env = NULL;
struct H264ConvertState convert_state = { 0, 0 };
if (!pp_block || !*pp_block)
return NULL;
......@@ -527,7 +528,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
size = p_block->i_buffer;
memcpy(bufptr, p_block->p_buffer, size);
convert_h264_to_annexb(bufptr, size, p_sys->nal_size);
convert_h264_to_annexb(bufptr, size, p_sys->nal_size, &convert_state);
int64_t ts = p_block->i_pts;
if (!ts && p_block->i_dts)
......
......@@ -1135,6 +1135,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
OMX_BUFFERHEADERTYPE *p_header;
block_t *p_block;
int i_input_used = 0;
struct H264ConvertState convert_state = { 0, 0 };
if( !pp_block || !*pp_block )
return NULL;
......@@ -1271,7 +1272,7 @@ more_input:
* i_nal_size_length == 0, which is the case for codecs other
* than H.264 */
convert_h264_to_annexb( p_header->pBuffer, p_header->nFilledLen,
p_sys->i_nal_size_length );
p_sys->i_nal_size_length, &convert_state );
#ifdef OMXIL_EXTRA_DEBUG
msg_Dbg( p_dec, "EmptyThisBuffer %p, %p, %i", p_header, p_header->pBuffer,
(int)p_header->nFilledLen );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment