h->i_height -= 2 * bs_read_ue( &s ); }
/* vui: ignored */ }
else if( nal->i_type >= NAL_SLICE && nal->i_type <= NAL_SLICE_IDR ) {
int i_tmp;
/* i_first_mb */ bs_read_ue( &s ); /* picture type */
switch( bs_read_ue( &s ) ) {
case 0: case 5: /* P */ case 1: case 6: /* B */ case 3: case 8: /* SP */ h->b_key = 0; break;
case 2: case 7: /* I */ case 4: case 9: /* SI */
h->b_key = (nal->i_type == NAL_SLICE_IDR); break; }
/* pps id */
bs_read_ue( &s );
/* frame num */
i_tmp = bs_read( &s, h->i_log2_max_frame_num );
if( i_tmp != h->i_frame_num ) *pb_nal_start = 1;
h->i_frame_num = i_tmp;
if( nal->i_type == NAL_SLICE_IDR ) {
i_tmp = bs_read_ue( &s );
if( h->i_nal_type == NAL_SLICE_IDR && h->i_idr_pic_id != i_tmp ) *pb_nal_start = 1;
h->i_idr_pic_id = i_tmp; }
if( h->i_poc_type == 0 ) {
i_tmp = bs_read( &s, h->i_log2_max_poc_lsb ); if( i_tmp != h->i_poc ) *pb_nal_start = 1; h->i_poc = i_tmp; } }
h->i_nal_type = nal->i_type; h->i_ref_idc = nal->i_ref_idc; }
static int ParseNAL( nal_t *nal, avi_t *a, h264_t *h, int *pb_slice ) {
int b_flush = 0; int b_start;
h264_parser_parse( h, nal, &b_start );
if( b_start && *pb_slice ) {
b_flush = 1; *pb_slice = 0; }
if( nal->i_type >= NAL_SLICE && nal->i_type <= NAL_SLICE_IDR ) *pb_slice = 1;
return b_flush; }
/***************************************************************************** * vbuf: variable buffer
*****************************************************************************/ void vbuf_init( vbuf_t *v ) {
v->i_data = 0;
v->i_data_max = 10000;
v->p_data = malloc( v->i_data_max ); }
void vbuf_add( vbuf_t *v, int i_data, void *p_data ) {
if( i_data + v->i_data >= v->i_data_max )
{
v->i_data_max += i_data;
v->p_data = realloc( v->p_data, v->i_data_max ); }
memcpy( &v->p_data[v->i_data], p_data, i_data );
v->i_data += i_data; }
void vbuf_reset( vbuf_t *v ) {
v->i_data = 0; }
/***************************************************************************** * avi:
*****************************************************************************/ void avi_write_uint16( avi_t *a, uint16_t w ) {
fputc( ( w ) & 0xff, a->f ); fputc( ( w >> 8 ) & 0xff, a->f ); }
void avi_write_uint32( avi_t *a, uint32_t dw ) {
fputc( ( dw ) & 0xff, a->f ); fputc( ( dw >> 8 ) & 0xff, a->f ); fputc( ( dw >> 16) & 0xff, a->f ); fputc( ( dw >> 24) & 0xff, a->f ); }
void avi_write_fourcc( avi_t *a, char fcc[4] ) {
fputc( fcc[0], a->f ); fputc( fcc[1], a->f ); fputc( fcc[2], a->f ); fputc( fcc[3], a->f ); }
/* Flags in avih */
#define AVIF_HASINDEX 0x00000010 // Index at end of file? #define AVIF_ISINTERLEAVED 0x00000100
#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames?
#define AVIIF_KEYFRAME 0x00000010L /* this frame is a key frame.*/
void avi_write_header( avi_t *a ) {
avi_write_fourcc( a, \
avi_write_uint32( a, a->i_riff > 0 ? a->i_riff - 8 : 0xFFFFFFFF ); avi_write_fourcc( a, \
avi_write_fourcc( a, \
avi_write_uint32( a, 4 + 4*16 + 12 + 4*16 + 4*12 ); avi_write_fourcc( a, \
avi_write_fourcc( a, \ avi_write_uint32( a, 4*16 - 8 );
avi_write_uint32( a, 1000000 / a->f_fps ); avi_write_uint32( a, 0xffffffff ); avi_write_uint32( a, 0 );
avi_write_uint32( a, AVIF_HASINDEX|AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE); avi_write_uint32( a, a->i_frame ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 1 );
avi_write_uint32( a, 1000000 ); avi_write_uint32( a, a->i_width ); avi_write_uint32( a, a->i_height ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 0 );
avi_write_fourcc( a, \
avi_write_uint32( a, 4 + 4*16 + 4*12 ); avi_write_fourcc( a, \
avi_write_fourcc( a, \ avi_write_uint32( a, 4*16 - 8 ); avi_write_fourcc( a, \ avi_write_fourcc( a, a->fcc ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 0 ); avi_write_uint32( a, 1000 );
avi_write_uint32( a, a->f_fps * 1000 ); avi_write_uint32( a, 0 );
avi_write_uint32( a, a->i_frame ); avi_write_uint32( a, 1024*1024 );