www.pudn.com > jm74.zip > sei.c
/*! ************************************************************************ * \file sei.c * * \brief * Functions to implement SEI messages * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Dong Tian* - Karsten Suehring ************************************************************************ */ #include "contributors.h" #include #include #include #include "global.h" #include "memalloc.h" #include "sei.h" #include "vlc.h" #include "header.h" extern int UsedBits; extern seq_parameter_set_rbsp_t SeqParSet[MAXSPS]; // #define PRINT_BUFFERING_PERIOD_INFO // uncomment to print buffering period SEI info // #define PRINT_PCITURE_TIMING_INFO // uncomment to print picture timing SEI info // #define WRITE_MAP_IMAGE // uncomment to write spare picture map // #define PRINT_SUBSEQUENCE_INFO // uncomment to print sub-sequence SEI info // #define PRINT_SUBSEQUENCE_LAYER_CHAR // uncomment to print sub-sequence layer characteristics SEI info // #define PRINT_SUBSEQUENCE_CHAR // uncomment to print sub-sequence characteristics SEI info // #define PRINT_SCENE_INFORMATION // uncomment to print scene information SEI info // #define PRINT_PAN_SCAN_RECT // uncomment to print pan-scan rectangle SEI info // #define PRINT_RANDOM_ACCESS // uncomment to print random access point SEI info // #define PRINT_FILLER_PAYLOAD_INFO // uncomment to print filler payload SEI info // #define PRINT_DEC_REF_PIC_MARKING // uncomment to print decoded picture buffer management repetition SEI info // #define PRINT_RESERVED_INFO // uncomment to print reserved SEI info // #define PRINT_USER_DATA_UNREGISTERED_INFO // uncomment to print unregistered user data SEI info // #define PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO // uncomment to print ITU-T T.35 user data SEI info // #define PRINT_FULL_FRAME_FREEZE_INFO // uncomment to print full-frame freeze SEI info // #define PRINT_FULL_FRAME_FREEZE_RELEASE_INFO // uncomment to print full-frame freeze release SEI info // #define PRINT_FULL_FRAME_SNAPSHOT_INFO // uncomment to print full-frame snapshot SEI info // #define PRINT_PROGRESSIVE_REFINEMENT_END_INFO // uncomment to print Progressive refinement segment start SEI info // #define PRINT_PROGRESSIVE_REFINEMENT_END_INFO // uncomment to print Progressive refinement segment end SEI info // #define PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO // uncomment to print Motion-constrained slice group set SEI info /*! ************************************************************************ * \brief * Interpret the SEI rbsp * \param msg * a pointer that point to the sei message. * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void InterpretSEIMessage(byte* msg, int size, ImageParameters *img) { int payload_type = 0; int payload_size = 0; int offset = 0; byte tmp_byte; do { // sei_message(); payload_type = 0; tmp_byte = msg[offset++]; while (tmp_byte == 0xFF) { payload_type += 255; tmp_byte = msg[offset++]; } payload_type += tmp_byte; // this is the last byte payload_size = 0; tmp_byte = msg[offset++]; while (tmp_byte == 0xFF) { payload_size += 255; tmp_byte = msg[offset++]; } payload_size += tmp_byte; // this is the last byte switch ( payload_type ) // sei_payload( type, size ); { case SEI_BUFFERING_PERIOD: interpret_buffering_period_info( msg+offset, payload_size, img ); break; case SEI_PIC_TIMING: interpret_picture_timing_info( msg+offset, payload_size, img ); break; case SEI_PAN_SCAN_RECT: interpret_pan_scan_rect_info( msg+offset, payload_size, img ); break; case SEI_FILLER_PAYLOAD: interpret_filler_payload_info( msg+offset, payload_size, img ); break; case SEI_USER_DATA_REGISTERED_ITU_T_T35: interpret_user_data_registered_itu_t_t35_info( msg+offset, payload_size, img ); break; case SEI_USER_DATA_UNREGISTERED: interpret_user_data_unregistered_info( msg+offset, payload_size, img ); break; case SEI_RANDOM_ACCESS_POINT: interpret_random_access_info( msg+offset, payload_size, img ); break; case SEI_DEC_REF_PIC_MARKING_REPETITION: interpret_dec_ref_pic_marking_repetition_info( msg+offset, payload_size, img ); break; case SEI_SPARE_PIC: interpret_spare_pic( msg+offset, payload_size, img ); break; case SEI_SCENE_INFO: interpret_scene_information( msg+offset, payload_size, img ); break; case SEI_SUB_SEQ_INFO: interpret_subsequence_info( msg+offset, payload_size, img ); break; case SEI_SUB_SEQ_LAYER_CHARACTERISTICS: interpret_subsequence_layer_characteristics_info( msg+offset, payload_size, img ); break; case SEI_SUB_SEQ_CHARACTERISTICS: interpret_subsequence_characteristics_info( msg+offset, payload_size, img ); break; case SEI_FULL_FRAME_FREEZE: interpret_full_frame_freeze_info( msg+offset, payload_size, img ); break; case SEI_FULL_FRAME_FREEZE_RELEASE: interpret_full_frame_freeze_release_info( msg+offset, payload_size, img ); break; case SEI_FULL_FRAME_SNAPSHOT: interpret_full_frame_snapshot_info( msg+offset, payload_size, img ); break; case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START: interpret_progressive_refinement_end_info( msg+offset, payload_size, img ); break; case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END: interpret_progressive_refinement_end_info( msg+offset, payload_size, img ); break; case SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET: interpret_motion_constrained_slice_group_set_info( msg+offset, payload_size, img ); break; default: interpret_reserved_info( msg+offset, payload_size, img ); break; } offset += payload_size; } while( msg[offset] != 0x80 ); // more_rbsp_data() msg[offset] != 0x80 // ignore the trailing bits rbsp_trailing_bits(); assert(msg[offset] == 0x80); // this is the trailing bits assert( offset+1 == size ); } /*! ************************************************************************ * \brief * Interpret the spare picture SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_spare_pic( byte* payload, int size, ImageParameters *img ) { int i,x,y; Bitstream* buf; int bit0, bit1, bitc, no_bit0; int target_frame_num; int num_spare_pics; int delta_spare_frame_num, CandidateSpareFrameNum, SpareFrameNum = 0; int ref_area_indicator; int m, n, left, right, top, bottom,directx, directy; byte ***map; #ifdef WRITE_MAP_IMAGE int j, k, i0, j0, tmp, kk; char filename[20] = "map_dec.yuv"; FILE *fp; byte** Y; static int old_pn=-1; static int first = 1; printf("Spare picture SEI message\n"); #endif UsedBits = 0; assert( payload!=NULL); assert( img!=NULL); buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; target_frame_num = ue_v("SEI: target_frame_num", buf); #ifdef WRITE_MAP_IMAGE printf( "target_frame_num is %d\n", target_frame_num ); #endif num_spare_pics = 1 + ue_v("SEI: num_spare_pics_minus1", buf); #ifdef WRITE_MAP_IMAGE printf( "num_spare_pics is %d\n", num_spare_pics ); #endif get_mem3D(&map, num_spare_pics, img->height/16, img->width/16); for (i=0; i height/16; y++) for (x=0; x width/16; x++) map[i][y][x] = 0; break; case 1: // The map is not compressed for (y=0; y height/16; y++) for (x=0; x width/16; x++) { map[i][y][x] = u_1("SEI: ref_mb_indicator", buf); } break; case 2: // The map is compressed //!KS: could not check this function, description is unclear (as stated in Ed. Note) bit0 = 0; bit1 = 1; bitc = bit0; no_bit0 = -1; x = ( img->width/16 - 1 ) / 2; y = ( img->height/16 - 1 ) / 2; left = right = x; top = bottom = y; directx = 0; directy = 1; for (m=0; m height/16; m++) for (n=0; n width/16; n++) { if (no_bit0<0) { no_bit0 = ue_v("SEI: zero_run_length", buf); } if (no_bit0>0) map[i][y][x] = bit0; else map[i][y][x] = bit1; no_bit0--; // go to the next mb: if ( directx == -1 && directy == 0 ) { if (x > left) x--; else if (x == 0) { y = bottom + 1; bottom++; directx = 1; directy = 0; } else if (x == left) { x--; left--; directx = 0; directy = 1; } } else if ( directx == 1 && directy == 0 ) { if (x < right) x++; else if (x == img->width/16 - 1) { y = top - 1; top--; directx = -1; directy = 0; } else if (x == right) { x++; right++; directx = 0; directy = -1; } } else if ( directx == 0 && directy == -1 ) { if ( y > top) y--; else if (y == 0) { x = left - 1; left--; directx = 0; directy = 1; } else if (y == top) { y--; top--; directx = -1; directy = 0; } } else if ( directx == 0 && directy == 1 ) { if (y < bottom) y++; else if (y == img->height/16 - 1) { x = right+1; right++; directx = 0; directy = -1; } else if (y == bottom) { y++; bottom++; directx = 1; directy = 0; } } } break; default: printf( "Wrong ref_area_indicator %d!\n", ref_area_indicator ); exit(0); break; } } // end of num_spare_pics #ifdef WRITE_MAP_IMAGE // begin to write map seq if ( old_pn != img->number ) { old_pn = img->number; get_mem2D(&Y, img->height, img->width); if (first) { fp = fopen( filename, "wb" ); first = 0; } else fp = fopen( filename, "ab" ); assert( fp != NULL ); for (kk=0; kk height/16; i++) for (j=0; j < img->width/16; j++) { tmp=map[kk][i][j]==0? 255 : 0; for (i0=0; i0<16; i0++) for (j0=0; j0<16; j0++) Y[i*16+i0][j*16+j0]=tmp; } // write the map image for (i=0; i < img->height; i++) for (j=0; j < img->width; j++) fputc(Y[i][j], fp); for (k=0; k < 2; k++) for (i=0; i < img->height/2; i++) for (j=0; j < img->width/2; j++) fputc(128, fp); } fclose( fp ); free_mem2D( Y ); } // end of writing map image #undef WRITE_MAP_IMAGE #endif free_mem3D( map, num_spare_pics ); free(buf); } /*! ************************************************************************ * \brief * Interpret the Sub-sequence information SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_subsequence_info( byte* payload, int size, ImageParameters *img ) { Bitstream* buf; int sub_seq_layer_num, sub_seq_id, first_ref_pic_flag, leading_non_ref_pic_flag, last_pic_flag, sub_seq_frame_num_flag, sub_seq_frame_num; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; sub_seq_layer_num = ue_v("SEI: sub_seq_layer_num" , buf); sub_seq_id = ue_v("SEI: sub_seq_id" , buf); first_ref_pic_flag = u_1 ("SEI: first_ref_pic_flag" , buf); leading_non_ref_pic_flag = u_1 ("SEI: leading_non_ref_pic_flag", buf); last_pic_flag = u_1 ("SEI: last_pic_flag" , buf); sub_seq_frame_num_flag = u_1 ("SEI: sub_seq_frame_num_flag" , buf); if (sub_seq_frame_num_flag) { sub_seq_frame_num = ue_v("SEI: sub_seq_frame_num" , buf); } #ifdef PRINT_SUBSEQUENCE_INFO printf("Sub-sequence information SEI message\n"); printf("sub_seq_layer_num = %d\n", sub_seq_layer_num ); printf("sub_seq_id = %d\n", sub_seq_id); printf("first_ref_pic_flag = %d\n", first_ref_pic_flag); printf("leading_non_ref_pic_flag = %d\n", leading_non_ref_pic_flag); printf("last_pic_flag = %d\n", last_pic_flag); printf("sub_seq_frame_num_flag = %d\n", sub_seq_frame_num_flag); if (sub_seq_frame_num_flag) { printf("sub_seq_frame_num = %d\n", sub_seq_frame_num); } #endif free(buf); #ifdef PRINT_SUBSEQUENCE_INFO #undef PRINT_SUBSEQUENCE_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Sub-sequence layer characteristics SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_subsequence_layer_characteristics_info( byte* payload, int size, ImageParameters *img ) { Bitstream* buf; long num_sub_layers, accurate_statistics_flag, average_bit_rate, average_frame_rate; int i; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; num_sub_layers = 1 + ue_v("SEI: num_sub_layers_minus1", buf); #ifdef PRINT_SUBSEQUENCE_LAYER_CHAR printf("Sub-sequence layer characteristics SEI message\n"); printf("num_sub_layers_minus1 = %d\n", num_sub_layers - 1); #endif for (i=0; i bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; sub_seq_layer_num = ue_v("SEI: sub_seq_layer_num", buf); sub_seq_id = ue_v("SEI: sub_seq_id", buf); duration_flag = u_1 ("SEI: duration_flag", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("Sub-sequence characteristics SEI message\n"); printf("sub_seq_layer_num = %d\n", sub_seq_layer_num ); printf("sub_seq_id = %d\n", sub_seq_id); printf("duration_flag = %d\n", duration_flag); #endif if ( duration_flag ) { sub_seq_duration = u_v (32, "SEI: duration_flag", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("sub_seq_duration = %ld\n", sub_seq_duration); #endif } average_rate_flag = u_1 ("SEI: average_rate_flag", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("average_rate_flag = %d\n", average_rate_flag); #endif if ( average_rate_flag ) { accurate_statistics_flag = u_1 ( "SEI: accurate_statistics_flag", buf); average_bit_rate = u_v (16, "SEI: average_bit_rate", buf); average_frame_rate = u_v (16, "SEI: average_frame_rate", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("accurate_statistics_flag = %d\n", accurate_statistics_flag); printf("average_bit_rate = %ld\n", average_bit_rate); printf("average_frame_rate = %ld\n", average_frame_rate); #endif } num_referenced_subseqs = ue_v("SEI: num_referenced_subseqs", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("num_referenced_subseqs = %d\n", num_referenced_subseqs); #endif for (i=0; i bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; scene_id = ue_v("SEI: scene_id" , buf); scene_transition_type = ue_v("SEI: scene_transition_type", buf); if ( scene_transition_type > 3 ) { second_scene_id = ue_v("SEI: scene_transition_type", buf);; } #ifdef PRINT_SCENE_INFORMATION printf("Scene information SEI message\n"); printf("scene_transition_type = %d\n", scene_transition_type); printf("scene_id = %d\n", scene_id); if ( scene_transition_type > 3 ) { printf("second_scene_id = %d\n", second_scene_id); } #endif free( buf ); #ifdef PRINT_SCENE_INFORMATION #undef PRINT_SCENE_INFORMATION #endif } /*! ************************************************************************ * \brief * Interpret the Filler payload SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_filler_payload_info( byte* payload, int size, ImageParameters *img ) { int offset = 0; byte payload_cnt = 0; while (offset bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; pan_scan_rect_id = ue_v("SEI: pan_scan_rect_id", buf); pan_scan_rect_left_offset = se_v("SEI: pan_scan_rect_left_offset" , buf); pan_scan_rect_right_offset = se_v("SEI: pan_scan_rect_right_offset" , buf); pan_scan_rect_top_offset = se_v("SEI: pan_scan_rect_top_offset" , buf); pan_scan_rect_bottom_offset = se_v("SEI: pan_scan_rect_bottom_offset", buf); #ifdef PRINT_PAN_SCAN_RECT printf("Pan scan rectangle SEI message\n"); printf("pan_scan_rect_id = %d\n", pan_scan_rect_id); printf("pan_scan_rect_left_offset = %d\n", pan_scan_rect_left_offset); printf("pan_scan_rect_right_offset = %d\n", pan_scan_rect_right_offset); printf("pan_scan_rect_top_offset = %d\n", pan_scan_rect_top_offset); printf("pan_scan_rect_bottom_offset = %d\n", pan_scan_rect_bottom_offset); #endif free (buf); #ifdef PRINT_PAN_SCAN_RECT #undef PRINT_PAN_SCAN_RECT #endif } /*! ************************************************************************ * \brief * Interpret the Random access point SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_random_access_info( byte* payload, int size, ImageParameters *img ) { int recovery_frame_cnt, exact_match_flag, broken_link_flag, changing_slice_group_idc; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; recovery_frame_cnt = ue_v( "SEI: recovery_frame_cnt" , buf); exact_match_flag = u_1 ( "SEI: exact_match_flag" , buf); broken_link_flag = u_1 ( "SEI: broken_link_flag" , buf); changing_slice_group_idc = u_v ( 2, "SEI: changing_slice_group_idc", buf); #ifdef PRINT_RANDOM_ACCESS printf("Random access point SEI message\n"); printf("recovery_frame_cnt = %d\n", recovery_frame_cnt); printf("exact_match_flag = %d\n", exact_match_flag); printf("broken_link_flag = %d\n", broken_link_flag); printf("changing_slice_group_idc = %d\n", changing_slice_group_idc); #endif free (buf); #ifdef PRINT_RANDOM_ACCESS #undef PRINT_RANDOM_ACCESS #endif } /*! ************************************************************************ * \brief * Interpret the Decoded Picture Buffer Management Repetition SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_dec_ref_pic_marking_repetition_info( byte* payload, int size, ImageParameters *img ) { int original_idr_flag, original_frame_num; DecRefPicMarking_t *tmp_drpm; DecRefPicMarking_t *old_drpm; int old_idr_flag , old_no_output_of_prior_pics_flag, old_long_term_reference_flag , old_adaptive_ref_pic_buffering_flag; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; original_idr_flag = u_1 ( "SEI: original_idr_flag" , buf); original_frame_num = ue_v( "SEI: original_frame_num" , buf); #ifdef PRINT_DEC_REF_PIC_MARKING printf("Decoded Picture Buffer Management Repetition SEI message\n"); printf("original_idr_flag = %d\n", original_idr_flag); printf("original_frame_num = %d\n", original_frame_num); #endif // we need to save everything that is probably overwritten in dec_ref_pic_marking() old_drpm = img->dec_ref_pic_marking_buffer; old_idr_flag = img->idr_flag; old_no_output_of_prior_pics_flag = img->no_output_of_prior_pics_flag; old_long_term_reference_flag = img->long_term_reference_flag; old_adaptive_ref_pic_buffering_flag = img->adaptive_ref_pic_buffering_flag; // set new initial values img->idr_flag = original_idr_flag; img->dec_ref_pic_marking_buffer = NULL; dec_ref_pic_marking(buf); // print out decoded values #ifdef PRINT_DEC_REF_PIC_MARKING if (img->idr_flag) { printf("no_output_of_prior_pics_flag = %d\n", img->no_output_of_prior_pics_flag); printf("long_term_reference_flag = %d\n", img->long_term_reference_flag); } else { printf("adaptive_ref_pic_buffering_flag = %d\n", img->adaptive_ref_pic_buffering_flag); if (img->adaptive_ref_pic_buffering_flag) { tmp_drpm=img->dec_ref_pic_marking_buffer; while (tmp_drpm != NULL) { printf("memory_management_control_operation = %d\n", tmp_drpm->memory_management_control_operation); if ((tmp_drpm->memory_management_control_operation==1)||(tmp_drpm->memory_management_control_operation==3)) { printf("difference_of_pic_nums_minus1 = %d\n", tmp_drpm->difference_of_pic_nums_minus1); } if (tmp_drpm->memory_management_control_operation==2) { printf("long_term_pic_num = %d\n", tmp_drpm->long_term_pic_num); } if ((tmp_drpm->memory_management_control_operation==3)||(tmp_drpm->memory_management_control_operation==6)) { printf("long_term_frame_idx = %d\n", tmp_drpm->long_term_frame_idx); } if (tmp_drpm->memory_management_control_operation==4) { printf("max_long_term_pic_idx_plus1 = %d\n", tmp_drpm->max_long_term_frame_idx_plus1); } tmp_drpm = tmp_drpm->Next; } } } #endif while (img->dec_ref_pic_marking_buffer) { tmp_drpm = img->dec_ref_pic_marking_buffer->Next; free (tmp_drpm); } // restore old values in img img->dec_ref_pic_marking_buffer = old_drpm; img->idr_flag = old_idr_flag; img->no_output_of_prior_pics_flag = old_no_output_of_prior_pics_flag; img->long_term_reference_flag = old_long_term_reference_flag; img->adaptive_ref_pic_buffering_flag = old_adaptive_ref_pic_buffering_flag; free (buf); #ifdef PRINT_DEC_REF_PIC_MARKING #undef PRINT_DEC_REF_PIC_MARKING #endif } /*! ************************************************************************ * \brief * Interpret the Full-frame freeze SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_full_frame_freeze_info( byte* payload, int size, ImageParameters *img ) { #ifdef PRINT_FULL_FRAME_FREEZE_INFO printf("Full-frame freeze SEI message\n"); if (size) { printf("payload size of this message should be zero, but is %d bytes.\n", size); } #endif #ifdef PRINT_FULL_FRAME_FREEZE_INFO #undef PRINT_FULL_FRAME_FREEZE_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Full-frame freeze release SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_full_frame_freeze_release_info( byte* payload, int size, ImageParameters *img ) { #ifdef PRINT_FULL_FRAME_FREEZE_RELEASE_INFO printf("Full-frame freeze release SEI message\n"); if (size) { printf("payload size of this message should be zero, but is %d bytes.\n", size); } #endif #ifdef PRINT_FULL_FRAME_FREEZE_RELEASE_INFO #undef PRINT_FULL_FRAME_FREEZE_RELEASE_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Full-frame snapshot SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_full_frame_snapshot_info( byte* payload, int size, ImageParameters *img ) { int snapshot_id; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; snapshot_id = ue_v("SEI: snapshot_id", buf); #ifdef PRINT_FULL_FRAME_SNAPSHOT_INFO printf("Full-frame snapshot SEI message\n"); printf("snapshot_id = %d\n", snapshot_id); #endif free (buf); #ifdef PRINT_FULL_FRAME_SNAPSHOT_INFO #undef PRINT_FULL_FRAME_SNAPSHOT_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Progressive refinement segment start SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_progressive_refinement_start_info( byte* payload, int size, ImageParameters *img ) { int progressive_refinement_id, num_refinement_steps_minus1; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; progressive_refinement_id = ue_v("SEI: progressive_refinement_id" , buf); num_refinement_steps_minus1 = ue_v("SEI: num_refinement_steps_minus1", buf); #ifdef PRINT_PROGRESSIVE_REFINEMENT_START_INFO printf("Progressive refinement segment start SEI message\n"); printf("progressive_refinement_id = %d\n", progressive_refinement_id); printf("num_refinement_steps_minus1 = %d\n", num_refinement_steps_minus1); #endif free (buf); #ifdef PRINT_PROGRESSIVE_REFINEMENT_START_INFO #undef PRINT_PROGRESSIVE_REFINEMENT_START_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Progressive refinement segment end SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_progressive_refinement_end_info( byte* payload, int size, ImageParameters *img ) { int progressive_refinement_id; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; progressive_refinement_id = ue_v("SEI: progressive_refinement_id" , buf); #ifdef PRINT_PROGRESSIVE_REFINEMENT_END_INFO printf("Progressive refinement segment end SEI message\n"); printf("progressive_refinement_id = %d\n", progressive_refinement_id); #endif free (buf); #ifdef PRINT_PROGRESSIVE_REFINEMENT_END_INFO #undef PRINT_PROGRESSIVE_REFINEMENT_END_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Motion-constrained slice group set SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_motion_constrained_slice_group_set_info( byte* payload, int size, ImageParameters *img ) { int num_slice_groups_minus1, slice_group_id, exact_match_flag, pan_scan_rect_flag, pan_scan_rect_id; int i; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; num_slice_groups_minus1 = ue_v("SEI: num_slice_groups_minus1" , buf); #ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO printf("Motion-constrained slice group set SEI message\n"); printf("num_slice_groups_minus1 = %d\n", num_slice_groups_minus1); #endif for (i=0; i<=num_slice_groups_minus1;i++) { slice_group_id = ue_v("SEI: slice_group_id" , buf); #ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO printf("slice_group_id = %d\n", slice_group_id); #endif } exact_match_flag = u_1("SEI: exact_match_flag" , buf); pan_scan_rect_flag = u_1("SEI: pan_scan_rect_flag" , buf); #ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO printf("exact_match_flag = %d\n", exact_match_flag); printf("pan_scan_rect_flag = %d\n", pan_scan_rect_flag); #endif if (pan_scan_rect_flag) { pan_scan_rect_id = ue_v("SEI: pan_scan_rect_id" , buf); #ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO printf("pan_scan_rect_id = %d\n", pan_scan_rect_id); #endif } free (buf); #ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO #undef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Reserved SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_reserved_info( byte* payload, int size, ImageParameters *img ) { int offset = 0; byte payload_byte; #ifdef PRINT_RESERVED_INFO printf("Reserved SEI message\n"); #endif assert (size<16); while (offset < size) { payload_byte = payload[offset]; offset ++; #ifdef PRINT_RESERVED_INFO printf("reserved_sei_message_payload_byte = %d\n", payload_byte); #endif } #ifdef PRINT_RESERVED_INFO #undef PRINT_RESERVED_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Buffering period SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_buffering_period_info( byte* payload, int size, ImageParameters *img ) { int seq_parameter_set_id, initial_cpb_removal_delay, initial_cpb_removal_delay_offset; unsigned int k; Bitstream* buf; seq_parameter_set_rbsp_t *sps; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; seq_parameter_set_id = ue_v("SEI: seq_parameter_set_id" , buf); sps = &SeqParSet[seq_parameter_set_id]; #ifdef PRINT_BUFFERING_PERIOD_INFO printf("Buffering period SEI message\n"); printf("seq_parameter_set_id = %d\n", seq_parameter_set_id); #endif if (sps->vui_seq_parameters.nal_hrd_parameters_present_flag) { for (k=0; k vui_seq_parameters.nal_hrd_parameters.cpb_cnt; k++) { initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay" , buf); initial_cpb_removal_delay_offset = u_v(sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay_offset" , buf); #ifdef PRINT_BUFFERING_PERIOD_INFO printf("nal initial_cpb_removal_delay[%d] = %d\n", k, initial_cpb_removal_delay); printf("nal initial_cpb_removal_delay_offset[%d] = %d\n", k, initial_cpb_removal_delay_offset); #endif } } if (sps->vui_seq_parameters.vcl_hrd_parameters_present_flag) { for (k=0; k vui_seq_parameters.vcl_hrd_parameters.cpb_cnt; k++) { initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay" , buf); initial_cpb_removal_delay_offset = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay_offset" , buf); #ifdef PRINT_BUFFERING_PERIOD_INFO printf("vcl initial_cpb_removal_delay[%d] = %d\n", k, initial_cpb_removal_delay); printf("vcl initial_cpb_removal_delay_offset[%d] = %d\n", k, initial_cpb_removal_delay_offset); #endif } } free (buf); #ifdef PRINT_BUFFERING_PERIOD_INFO #undef PRINT_BUFFERING_PERIOD_INFO #endif } /*! ************************************************************************ * \brief * Interpret the Picture timing SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_picture_timing_info( byte* payload, int size, ImageParameters *img ) { int cpb_removal_delay, dpb_output_delay, picture_structure_present_flag, picture_structure; int clock_time_stamp_flag; int ct_type, nuit_field_based_flag, counting_type, full_timestamp_flag, discontinuity_flag, cnt_dropped_flag, nframes; int seconds_value, minutes_value, hours_value, seconds_flag, minutes_flag, hours_flag, time_offset; int NumClockTs = 0; int i; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; assert (NULL!=active_sps); #ifdef PRINT_PCITURE_TIMING_INFO printf("Picture timing SEI message\n"); #endif if ((active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)|| (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)) { cpb_removal_delay = ue_v("SEI: cpb_removal_delay" , buf); dpb_output_delay = ue_v("SEI: dpb_output_delay" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("cpb_removal_delay = %d\n",cpb_removal_delay); printf("dpb_output_delay = %d\n",dpb_output_delay); #endif } picture_structure_present_flag = u_1("SEI: picture_structure_present_flag" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("picture_structure_present_flag = %d\n",picture_structure_present_flag); #endif if (picture_structure_present_flag) { picture_structure = u_v(3, "SEI: picture_structure" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("picture_structure = %d\n",picture_structure); #endif switch (picture_structure) { case 0: case 1: case 2: NumClockTs = 1; break; case 3: case 4: case 7: NumClockTs = 2; break; case 5: case 6: case 8: NumClockTs = 3; break; default: error("reserved picture_structure used (can't determine NumClockTs)", 500); } for (i=0; i vui_seq_parameters.nal_hrd_parameters.time_offset_length) //!KS which HRD params shall be used? { time_offset=0; // time_offset = i_v(active_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length, "SEI: time_offset" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("time_offset = %d\n",time_offset); #endif } } } } free (buf); #ifdef PRINT_PCITURE_TIMING_INFO #undef PRINT_PCITURE_TIMING_INFO #endif }