[vlc-commits] packetizer: hxxx: add NAL iterators
Francois Cartegnie
git at videolan.org
Wed Oct 5 14:19:48 CEST 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Oct 4 23:22:09 2016 +0200| [c5ce96099428cdfed37365038f815f9abbb0b458] | committer: Francois Cartegnie
packetizer: hxxx: add NAL iterators
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c5ce96099428cdfed37365038f815f9abbb0b458
---
modules/packetizer/hxxx_nal.h | 65 ++++++++++++++++++++++++++++++
test/modules/packetizer/hxxx.c | 90 ++++++++++++++++++++++++++++++++++++------
2 files changed, 144 insertions(+), 11 deletions(-)
diff --git a/modules/packetizer/hxxx_nal.h b/modules/packetizer/hxxx_nal.h
index b8a6610..3da8cad 100644
--- a/modules/packetizer/hxxx_nal.h
+++ b/modules/packetizer/hxxx_nal.h
@@ -22,6 +22,7 @@
#include <vlc_common.h>
#include <vlc_es.h>
+#include "startcode_helper.h"
static const uint8_t annexb_startcode4[] = { 0x00, 0x00, 0x00, 0x01 };
#define annexb_startcode3 (&annexb_startcode4[1])
@@ -247,6 +248,70 @@ static inline uint8_t * hxxx_ep3b_to_rbsp(const uint8_t *p_src, size_t i_src, si
/* Declarations */
+typedef struct
+{
+ const uint8_t *p_head;
+ const uint8_t *p_tail;
+ uint8_t i_nal_length_size;
+} hxxx_iterator_ctx_t;
+
+static inline void hxxx_iterator_init( hxxx_iterator_ctx_t *p_ctx, const uint8_t *p_data, size_t i_data,
+ uint8_t i_nal_length_size )
+{
+ p_ctx->p_head = p_data;
+ p_ctx->p_tail = p_data + i_data;
+ if( popcount(i_nal_length_size) == 1 && i_nal_length_size <= 4 )
+ p_ctx->i_nal_length_size = i_nal_length_size;
+ else
+ p_ctx->i_nal_length_size = 0;
+}
+
+static inline bool hxxx_iterate_next( hxxx_iterator_ctx_t *p_ctx, const uint8_t **pp_start, size_t *pi_size )
+{
+ if( p_ctx->i_nal_length_size == 0 )
+ return false;
+
+ if( p_ctx->p_tail - p_ctx->p_head < p_ctx->i_nal_length_size )
+ return false;
+
+ size_t i_nal_size = 0;
+ for( uint8_t i=0; i < p_ctx->i_nal_length_size ; i++ )
+ i_nal_size = (i_nal_size << 8) | *p_ctx->p_head++;
+
+ if( (ptrdiff_t) i_nal_size > p_ctx->p_tail - p_ctx->p_head )
+ return false;
+
+ *pp_start = p_ctx->p_head;
+ *pi_size = i_nal_size;
+ p_ctx->p_head += i_nal_size;
+
+ return true;
+}
+
+static inline bool hxxx_annexb_iterate_next( hxxx_iterator_ctx_t *p_ctx, const uint8_t **pp_start, size_t *pi_size )
+{
+ if( !p_ctx->p_head )
+ return false;
+
+ p_ctx->p_head = startcode_FindAnyAnnexB( p_ctx->p_head, p_ctx->p_tail );
+ if( !p_ctx->p_head )
+ return false;
+
+ const uint8_t *p_end = startcode_FindAnyAnnexB( p_ctx->p_head + 3, p_ctx->p_tail );
+ if( !p_end )
+ p_end = p_ctx->p_tail;
+
+ /* fix 3 to 4 startcode offset and strip any trailing zeros */
+ while( p_end > p_ctx->p_head && p_end[-1] == 0 )
+ p_end--;
+
+ *pp_start = p_ctx->p_head;
+ *pi_size = p_end - p_ctx->p_head;
+ p_ctx->p_head = p_end;
+
+ return hxxx_strip_AnnexB_startcode( pp_start, pi_size );
+}
+
/* Takes any AnnexB NAL buffer and converts it to prefixed size (AVC/HEVC) */
block_t *hxxx_AnnexB_to_xVC( block_t *p_block, uint8_t i_nal_length_size );
diff --git a/test/modules/packetizer/hxxx.c b/test/modules/packetizer/hxxx.c
index a0ea85a..93362a1 100644
--- a/test/modules/packetizer/hxxx.c
+++ b/test/modules/packetizer/hxxx.c
@@ -18,7 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-#include "../../libvlc/test.h"
#ifdef NDEBUG
#undef NDEBUG
#endif
@@ -28,6 +27,56 @@
#include "../modules/packetizer/hxxx_nal.h"
#include "../modules/packetizer/hxxx_nal.c"
+static void test_iterators( const uint8_t *p_ab, size_t i_ab, /* AnnexB */
+ const uint8_t **pp_prefix, size_t *pi_prefix /* Prefixed */ )
+{
+ printf("INPUT SET : ");
+ for(size_t j=0; j<i_ab; j++)
+ printf("0x%.2x, ", p_ab[j] );
+ printf("\n");
+
+ for( unsigned int i=0; i<3; i++)
+ {
+ const uint8_t *p_prefix = pp_prefix[i];
+ size_t i_prefix = pi_prefix[i];
+
+ printf("Test with prefix len %d:\n", 1 << i);
+
+ hxxx_iterator_ctx_t it_ab;
+ hxxx_iterator_init( &it_ab, p_ab, i_ab, 0 );
+
+ hxxx_iterator_ctx_t it_prefix;
+ hxxx_iterator_init( &it_prefix, p_prefix, i_prefix, 1 << i );
+
+ const uint8_t *p_start_ab; size_t i_size_ab;
+ const uint8_t *p_start_prefix; size_t i_size_prefix;
+
+ bool b1 = true;
+ bool b2 = true;
+
+ int i_nal = 0;
+ while(b1 && b2)
+ {
+ b1 = hxxx_annexb_iterate_next( &it_ab, &p_start_ab, &i_size_ab );
+ b2 = hxxx_iterate_next( &it_prefix, &p_start_prefix, &i_size_prefix );
+ printf("NAL %d ", i_nal++);
+ if( b1 != b2 )
+ printf(", returns %d != %d\n", b1, b2);
+ assert(b1 == b2);
+ if( b1 && b2 )
+ {
+ assert(i_size_ab == i_size_prefix);
+ assert(memcmp(p_start_ab, p_start_prefix, i_size_ab) == 0);
+ for(size_t j=0; j<i_size_ab; j++)
+ printf("0x%.2x, ", p_start_ab[j] );
+ printf("\n");
+ }
+ }
+ printf("\n");
+
+ }
+}
+
static void testannexbin( const uint8_t *p_data, size_t i_data,
const uint8_t **pp_res, size_t *pi_res )
{
@@ -65,12 +114,12 @@ static void testannexbin( const uint8_t *p_data, size_t i_data,
}
}
}
-#define runtest(number, name) \
+#define runtest(number, name, testfunction) \
printf("\nTEST %d %s\n", number, name);\
p_res[0] = test##number##_avcdata1; rgi_res[0] = sizeof(test##number##_avcdata1);\
p_res[1] = test##number##_avcdata2; rgi_res[1] = sizeof(test##number##_avcdata2);\
p_res[2] = test##number##_avcdata4; rgi_res[2] = sizeof(test##number##_avcdata4);\
- testannexbin( test##number##_annexbdata, sizeof(test##number##_annexbdata), \
+ testfunction( test##number##_annexbdata, sizeof(test##number##_annexbdata), \
p_res, rgi_res )
static void test_annexb()
@@ -130,18 +179,37 @@ static void test_annexb()
const uint8_t test6_avcdata2[] = { 0, 1, 0x11, 0, 0, 0, 0 };
const uint8_t test6_avcdata4[] = { 0, 0, 0, 1, 0x11, 0, 0, 0, 0, 0, 0, 0, 0 };
- runtest(4, "empty nal test");
- runtest(2, "single nal test");
- runtest(3, "single nal test, startcode 3");
- runtest(5, "4 bytes prefixed nal only (4 prefix optz)");
- runtest(1, "mixed nal set");
- runtest(6, "startcode repeat / empty nal");
+ /* empty nal variation test */
+ const uint8_t test7_annexbdata[] = { 0, 0, 0, 1 };
+ const uint8_t test7_avcdata1[] = { 0 };
+ const uint8_t test7_avcdata2[] = { 0, 0 };
+ const uint8_t test7_avcdata4[] = { 0, 0, 0, 0 };
+
+ runtest(4, "empty nal test", testannexbin);
+ runtest(2, "single nal test", testannexbin);
+ runtest(3, "single nal test, startcode 3", testannexbin);
+ runtest(5, "4 bytes prefixed nal only (4 prefix optz)", testannexbin);
+ runtest(1, "mixed nal set", testannexbin);
+ runtest(6, "startcode repeat / empty nal", testannexbin);
+
+ runtest(1, "IT mixed nal set", test_iterators);
+ runtest(2, "IT single nal test", test_iterators);
+ runtest(3, "IT single nal test, startcode 3", test_iterators);
+ runtest(4, "IT empty nal test", test_iterators);
+ runtest(5, "IT 4 bytes prefixed nal only (4 prefix optz)", test_iterators);
+ runtest(6, "startcode repeat / empty nal", test_iterators);
+ runtest(7, "IT empty nal", test_iterators);
+
+ printf("\nTEST 8 borkage test\n");\
+ rgi_res[0] = 0;
+ rgi_res[1] = rgi_res[2] = 1;
+ p_res[0] = NULL;
+ p_res[1] = p_res[2] = test7_avcdata1;
+ test_iterators( NULL, 0, p_res, rgi_res );
}
int main( void )
{
- test_init();
-
test_annexb();
return 0;
More information about the vlc-commits
mailing list