[vlc-commits] h264_nal: Support resuming bitstream format conversion across buffers
Martin Storsjö
git at videolan.org
Mon Mar 18 21:10:35 CET 2013
vlc | branch: master | Martin Storsjö <martin at martin.st> | Mon Mar 18 21:39:20 2013 +0200| [eb39bd4a8ffbe31cb954d3176d64ff24d7c560f8] | committer: 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ö <martin at martin.st>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=eb39bd4a8ffbe31cb954d3176d64ff24d7c560f8
---
modules/codec/h264_nal.h | 44 ++++++++++++++++++++++--------
modules/codec/omxil/android_mediacodec.c | 3 +-
modules/codec/omxil/omxil.c | 3 +-
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/modules/codec/h264_nal.h b/modules/codec/h264_nal.h
index ed9f6ae..7fd3526 100644
--- a/modules/codec/h264_nal.h
+++ b/modules/codec/h264_nal.h
@@ -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;
}
}
diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index c3c7095..dd9171e 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -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)
diff --git a/modules/codec/omxil/omxil.c b/modules/codec/omxil/omxil.c
index bcc2684..eff2375 100644
--- a/modules/codec/omxil/omxil.c
+++ b/modules/codec/omxil/omxil.c
@@ -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 );
More information about the vlc-commits
mailing list