| /*! |
| ************************************************************************ |
| * \file sei.c |
| * |
| * \brief |
| * Functions to implement SEI messages |
| * |
| * \author |
| * Main contributors (see contributors.h for copyright, address and affiliation details) |
| * - Dong Tian <tian@cs.tut.fi> |
| * - Karsten Suehring <suehring@hhi.de> |
| ************************************************************************ |
| */ |
| |
| #include "contributors.h" |
| |
| #include <stdlib.h> |
| #include <assert.h> |
| #include <string.h> |
| |
| #include "global.h" |
| #include "memalloc.h" |
| #include "sei.h" |
| #include "vlc.h" |
| #include "header.h" |
| #include "mbuffer.h" |
| #include "parset.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_RECOVERY_POINT // 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 |
| // #define PRINT_FILM_GRAIN_CHARACTERISTICS_INFO // uncomment to print Film grain characteristics SEI info |
| // #define PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO // uncomment to print deblocking filter display preference SEI info |
| // #define PRINT_STEREO_VIDEO_INFO_INFO // uncomment to print stero video 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 = 1; |
| 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_RECOVERY_POINT: |
| interpret_recovery_point_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 ); |
| case SEI_FILM_GRAIN_CHARACTERISTICS: |
| interpret_film_grain_characteristics_info ( msg+offset, payload_size, img ); |
| break; |
| case SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE: |
| interpret_deblocking_filter_display_preference_info ( msg+offset, payload_size, img ); |
| break; |
| case SEI_STEREO_VIDEO_INFO: |
| interpret_stereo_video_info_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 = 0; |
| 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 symbol_size_in_bytes = img->pic_unit_bitsize_on_disk/8; |
| int j, k, i0, j0, tmp, kk; |
| char filename[20] = "map_dec.yuv"; |
| FILE *fp; |
| imgpel** 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<num_spare_pics; i++) |
| { |
| if (i==0) |
| { |
| CandidateSpareFrameNum = target_frame_num - 1; |
| if ( CandidateSpareFrameNum < 0 ) CandidateSpareFrameNum = MAX_FN - 1; |
| } |
| else |
| CandidateSpareFrameNum = SpareFrameNum; |
| |
| delta_spare_frame_num = ue_v("SEI: delta_spare_frame_num", buf); |
| |
| SpareFrameNum = CandidateSpareFrameNum - delta_spare_frame_num; |
| if( SpareFrameNum < 0 ) |
| SpareFrameNum = MAX_FN + SpareFrameNum; |
| |
| ref_area_indicator = ue_v("SEI: ref_area_indicator", buf); |
| |
| switch ( ref_area_indicator ) |
| { |
| case 0: // The whole frame can serve as spare picture |
| for (y=0; y<img->height/16; y++) |
| for (x=0; x<img->width/16; x++) |
| map[i][y][x] = 0; |
| break; |
| case 1: // The map is not compressed |
| for (y=0; y<img->height/16; y++) |
| for (x=0; x<img->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<img->height/16; m++) |
| for (n=0; n<img->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_mem2Dpel(&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<num_spare_pics; kk++) |
| { |
| for (i=0; i < img->height/16; i++) |
| for (j=0; j < img->width/16; j++) |
| { |
| tmp=map[kk][i][j]==0? img->max_imgpel_value : 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++) |
| fwrite(&(Y[i][j]), symbol_size_in_bytes, 1, p_out); |
| |
| for (k=0; k < 2; k++) |
| for (i=0; i < img->height/2; i++) |
| for (j=0; j < img->width/2; j++) |
| fwrite(&(img->dc_pred_value_chroma), symbol_size_in_bytes, 1, p_out); |
| } |
| fclose( fp ); |
| free_mem2Dpel( 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<num_sub_layers; i++) |
| { |
| 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_LAYER_CHAR |
| printf("layer %d: accurate_statistics_flag = %ld \n", i, accurate_statistics_flag); |
| printf("layer %d: average_bit_rate = %ld \n", i, average_bit_rate); |
| printf("layer %d: average_frame_rate = %ld \n", i, average_frame_rate); |
| #endif |
| } |
| free (buf); |
| } |
| |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the Sub-sequence 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_characteristics_info( byte* payload, int size, ImageParameters *img ) |
| { |
| Bitstream* buf; |
| int i; |
| int sub_seq_layer_num, sub_seq_id, duration_flag, average_rate_flag, accurate_statistics_flag; |
| unsigned long sub_seq_duration, average_bit_rate, average_frame_rate; |
| int num_referenced_subseqs, ref_sub_seq_layer_num, ref_sub_seq_id, ref_sub_seq_direction; |
| |
| 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); |
| 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<num_referenced_subseqs; i++) |
| { |
| ref_sub_seq_layer_num = ue_v("SEI: ref_sub_seq_layer_num", buf); |
| ref_sub_seq_id = ue_v("SEI: ref_sub_seq_id", buf); |
| ref_sub_seq_direction = u_1 ("SEI: ref_sub_seq_direction", buf); |
| |
| #ifdef PRINT_SUBSEQUENCE_CHAR |
| printf("ref_sub_seq_layer_num = %d\n", ref_sub_seq_layer_num); |
| printf("ref_sub_seq_id = %d\n", ref_sub_seq_id); |
| printf("ref_sub_seq_direction = %d\n", ref_sub_seq_direction); |
| #endif |
| } |
| |
| free( buf ); |
| #ifdef PRINT_SUBSEQUENCE_CHAR |
| #undef PRINT_SUBSEQUENCE_CHAR |
| #endif |
| } |
| |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the Scene 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_scene_information( byte* payload, int size, ImageParameters *img ) |
| { |
| Bitstream* buf; |
| int scene_id, scene_transition_type, second_scene_id; |
| |
| buf = malloc(sizeof(Bitstream)); |
| buf->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 payload_cnt = 0; |
| |
| while (payload_cnt<size) |
| { |
| if (payload[payload_cnt] == 0xFF) |
| { |
| payload_cnt++; |
| } |
| } |
| |
| |
| #ifdef PRINT_FILLER_PAYLOAD_INFO |
| printf("Filler payload SEI message\n"); |
| if (payload_cnt==size) |
| { |
| printf("read %d bytes of filler payload\n", payload_cnt); |
| } |
| else |
| { |
| printf("error reading filler payload: not all bytes are 0xFF (%d of %d)\n", payload_cnt, size); |
| } |
| #endif |
| |
| #ifdef PRINT_FILLER_PAYLOAD_INFO |
| #undef PRINT_FILLER_PAYLOAD_INFO |
| #endif |
| } |
| |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the User data unregistered 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_user_data_unregistered_info( byte* payload, int size, ImageParameters *img ) |
| { |
| int offset = 0; |
| byte payload_byte; |
| |
| #ifdef PRINT_USER_DATA_UNREGISTERED_INFO |
| printf("User data unregistered SEI message\n"); |
| printf("uuid_iso_11578 = 0x"); |
| #endif |
| assert (size>=16); |
| |
| for (offset = 0; offset < 16; offset++) |
| { |
| #ifdef PRINT_USER_DATA_UNREGISTERED_INFO |
| printf("%02x",payload[offset]); |
| #endif |
| } |
| |
| #ifdef PRINT_USER_DATA_UNREGISTERED_INFO |
| printf("\n"); |
| #endif |
| |
| while (offset < size) |
| { |
| payload_byte = payload[offset]; |
| offset ++; |
| #ifdef PRINT_USER_DATA_UNREGISTERED_INFO |
| printf("Unreg data payload_byte = %d\n", payload_byte); |
| #endif |
| } |
| #ifdef PRINT_USER_DATA_UNREGISTERED_INFO |
| #undef PRINT_USER_DATA_UNREGISTERED_INFO |
| #endif |
| } |
| |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the User data registered by ITU-T T.35 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_user_data_registered_itu_t_t35_info( byte* payload, int size, ImageParameters *img ) |
| { |
| int offset = 0; |
| byte itu_t_t35_country_code, itu_t_t35_country_code_extension_byte, payload_byte; |
| |
| itu_t_t35_country_code = payload[offset]; |
| offset++; |
| #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO |
| printf("User data registered by ITU-T T.35 SEI message\n"); |
| printf(" itu_t_t35_country_code = %d \n", itu_t_t35_country_code); |
| #endif |
| if(itu_t_t35_country_code == 0xFF) |
| { |
| itu_t_t35_country_code_extension_byte = payload[offset]; |
| offset++; |
| #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO |
| printf(" ITU_T_T35_COUNTRY_CODE_EXTENSION_BYTE %d \n", itu_t_t35_country_code_extension_byte); |
| #endif |
| } |
| while (offset < size) |
| { |
| payload_byte = payload[offset]; |
| offset ++; |
| #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO |
| printf("itu_t_t35 payload_byte = %d\n", payload_byte); |
| #endif |
| } |
| #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO |
| #undef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO |
| #endif |
| } |
| |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the Pan scan rectangle 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_pan_scan_rect_info( byte* payload, int size, ImageParameters *img ) |
| { |
| int pan_scan_rect_cancel_flag; |
| int pan_scan_cnt_minus1, i; |
| int pan_scan_rect_repetition_period; |
| int pan_scan_rect_id, pan_scan_rect_left_offset, pan_scan_rect_right_offset; |
| int pan_scan_rect_top_offset, pan_scan_rect_bottom_offset; |
| |
| Bitstream* buf; |
| |
| buf = malloc(sizeof(Bitstream)); |
| buf->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_cancel_flag = u_1("SEI: pan_scan_rect_cancel_flag", buf); |
| if (!pan_scan_rect_cancel_flag) { |
| pan_scan_cnt_minus1 = ue_v("SEI: pan_scan_cnt_minus1", buf); |
| for (i = 0; i <= pan_scan_cnt_minus1; i++) { |
| 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 %d/%d\n", i, pan_scan_cnt_minus1); |
| 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 |
| } |
| pan_scan_rect_repetition_period = ue_v("SEI: pan_scan_rect_repetition_period", buf); |
| } |
| |
| 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_recovery_point_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); |
| |
| img->recovery_point = 1; |
| img->recovery_frame_cnt = recovery_frame_cnt; |
| |
| #ifdef PRINT_RECOVERY_POINT |
| printf("Recovery 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_RECOVERY_POINT |
| #undef PRINT_RECOVERY_POINT |
| #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; |
| |
| img->dec_ref_pic_marking_buffer=tmp_drpm->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; |
| int sliceGroupSize; |
| |
| 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); |
| sliceGroupSize = CeilLog2( num_slice_groups_minus1 + 1 ); |
| #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 = u_v (sliceGroupSize, "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 film grain 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_film_grain_characteristics_info( byte* payload, int size, ImageParameters *img ) |
| { |
| int film_grain_characteristics_cancel_flag; |
| int model_id, separate_colour_description_present_flag; |
| int film_grain_bit_depth_luma_minus8, film_grain_bit_depth_chroma_minus8, film_grain_full_range_flag, film_grain_colour_primaries, film_grain_transfer_characteristics, film_grain_matrix_coefficients; |
| int blending_mode_id, log2_scale_factor, comp_model_present_flag[3]; |
| int num_intensity_intervals_minus1, num_model_values_minus1; |
| int intensity_interval_lower_bound, intensity_interval_upper_bound; |
| int comp_model_value; |
| int film_grain_characteristics_repetition_period; |
| |
| int c, i, j; |
| |
| Bitstream* buf; |
| |
| buf = malloc(sizeof(Bitstream)); |
| buf->bitstream_length = size; |
| buf->streamBuffer = payload; |
| buf->frame_bitoffset = 0; |
| |
| film_grain_characteristics_cancel_flag = u_1("SEI: film_grain_characteristics_cancel_flag", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("film_grain_characteristics_cancel_flag = %d\n", film_grain_characteristics_cancel_flag); |
| #endif |
| if(!film_grain_characteristics_cancel_flag) |
| { |
| |
| model_id = u_v(2, "SEI: model_id", buf); |
| separate_colour_description_present_flag = u_1("SEI: separate_colour_description_present_flag", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("model_id = %d\n", model_id); |
| printf("separate_colour_description_present_flag = %d\n", separate_colour_description_present_flag); |
| #endif |
| if (separate_colour_description_present_flag) |
| { |
| film_grain_bit_depth_luma_minus8 = u_v(3, "SEI: film_grain_bit_depth_luma_minus8", buf); |
| film_grain_bit_depth_chroma_minus8 = u_v(3, "SEI: film_grain_bit_depth_chroma_minus8", buf); |
| film_grain_full_range_flag = u_v(1, "SEI: film_grain_full_range_flag", buf); |
| film_grain_colour_primaries = u_v(8, "SEI: film_grain_colour_primaries", buf); |
| film_grain_transfer_characteristics = u_v(8, "SEI: film_grain_transfer_characteristics", buf); |
| film_grain_matrix_coefficients = u_v(8, "SEI: film_grain_matrix_coefficients", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("film_grain_bit_depth_luma_minus8 = %d\n", film_grain_bit_depth_luma_minus8); |
| printf("film_grain_bit_depth_chroma_minus8 = %d\n", film_grain_bit_depth_chroma_minus8); |
| printf("film_grain_full_range_flag = %d\n", film_grain_full_range_flag); |
| printf("film_grain_colour_primaries = %d\n", film_grain_colour_primaries); |
| printf("film_grain_transfer_characteristics = %d\n", film_grain_transfer_characteristics); |
| printf("film_grain_matrix_coefficients = %d\n", film_grain_matrix_coefficients); |
| #endif |
| } |
| blending_mode_id = u_v(2, "SEI: blending_mode_id", buf); |
| log2_scale_factor = u_v(4, "SEI: log2_scale_factor", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("blending_mode_id = %d\n", blending_mode_id); |
| printf("log2_scale_factor = %d\n", log2_scale_factor); |
| #endif |
| for (c = 0; c < 3; c ++) |
| { |
| comp_model_present_flag[c] = u_1("SEI: comp_model_present_flag", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("comp_model_present_flag = %d\n", comp_model_present_flag[c]); |
| #endif |
| } |
| for (c = 0; c < 3; c ++) |
| if (comp_model_present_flag[c]) |
| { |
| num_intensity_intervals_minus1 = u_v(8, "SEI: num_intensity_intervals_minus1", buf); |
| num_model_values_minus1 = u_v(3, "SEI: num_model_values_minus1", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("num_intensity_intervals_minus1 = %d\n", num_intensity_intervals_minus1); |
| printf("num_model_values_minus1 = %d\n", num_model_values_minus1); |
| #endif |
| for (i = 0; i <= num_intensity_intervals_minus1; i ++) |
| { |
| intensity_interval_lower_bound = u_v(8, "SEI: intensity_interval_lower_bound", buf); |
| intensity_interval_upper_bound = u_v(8, "SEI: intensity_interval_upper_bound", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("intensity_interval_lower_bound = %d\n", intensity_interval_lower_bound); |
| printf("intensity_interval_upper_bound = %d\n", intensity_interval_upper_bound); |
| #endif |
| for (j = 0; j <= num_model_values_minus1; j++) |
| { |
| comp_model_value = se_v("SEI: comp_model_value", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("comp_model_value = %d\n", comp_model_value); |
| #endif |
| } |
| } |
| } |
| film_grain_characteristics_repetition_period = ue_v("SEI: film_grain_characteristics_repetition_period", buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| printf("film_grain_characteristics_repetition_period = %d\n", film_grain_characteristics_repetition_period); |
| #endif |
| } |
| |
| free (buf); |
| #ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| #undef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO |
| #endif |
| } |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the deblocking filter display preference 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_deblocking_filter_display_preference_info( byte* payload, int size, ImageParameters *img ) |
| { |
| int deblocking_display_preference_cancel_flag; |
| int display_prior_to_deblocking_preferred_flag, dec_frame_buffering_constraint_flag, deblocking_display_preference_repetition_period; |
| |
| Bitstream* buf; |
| |
| buf = malloc(sizeof(Bitstream)); |
| buf->bitstream_length = size; |
| buf->streamBuffer = payload; |
| buf->frame_bitoffset = 0; |
| |
| deblocking_display_preference_cancel_flag = u_1("SEI: deblocking_display_preference_cancel_flag", buf); |
| #ifdef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO |
| printf("deblocking_display_preference_cancel_flag = %d\n", deblocking_display_preference_cancel_flag); |
| #endif |
| if(!deblocking_display_preference_cancel_flag) |
| { |
| display_prior_to_deblocking_preferred_flag = u_1("SEI: display_prior_to_deblocking_preferred_flag", buf); |
| dec_frame_buffering_constraint_flag = u_1("SEI: dec_frame_buffering_constraint_flag", buf); |
| deblocking_display_preference_repetition_period = ue_v("SEI: deblocking_display_preference_repetition_period", buf); |
| #ifdef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO |
| printf("display_prior_to_deblocking_preferred_flag = %d\n", display_prior_to_deblocking_preferred_flag); |
| printf("dec_frame_buffering_constraint_flag = %d\n", dec_frame_buffering_constraint_flag); |
| printf("deblocking_display_preference_repetition_period = %d\n", deblocking_display_preference_repetition_period); |
| #endif |
| } |
| |
| free (buf); |
| #ifdef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO |
| #undef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO |
| #endif |
| } |
| |
| /*! |
| ************************************************************************ |
| * \brief |
| * Interpret the stereo video info 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_stereo_video_info_info( byte* payload, int size, ImageParameters *img ) |
| { |
| int field_views_flags; |
| int top_field_is_left_view_flag, current_frame_is_left_view_flag, next_frame_is_second_view_flag; |
| int left_view_self_contained_flag; |
| int right_view_self_contained_flag; |
| |
| Bitstream* buf; |
| |
| buf = malloc(sizeof(Bitstream)); |
| buf->bitstream_length = size; |
| buf->streamBuffer = payload; |
| buf->frame_bitoffset = 0; |
| |
| field_views_flags = u_1("SEI: field_views_flags", buf); |
| #ifdef PRINT_STEREO_VIDEO_INFO_INFO |
| printf("field_views_flags = %d\n", field_views_flags); |
| #endif |
| if (field_views_flags) |
| { |
| top_field_is_left_view_flag = u_1("SEI: top_field_is_left_view_flag", buf); |
| #ifdef PRINT_STEREO_VIDEO_INFO_INFO |
| printf("top_field_is_left_view_flag = %d\n", top_field_is_left_view_flag); |
| #endif |
| } |
| else |
| { |
| current_frame_is_left_view_flag = u_1("SEI: current_frame_is_left_view_flag", buf); |
| next_frame_is_second_view_flag = u_1("SEI: next_frame_is_second_view_flag", buf); |
| #ifdef PRINT_STEREO_VIDEO_INFO_INFO |
| printf("current_frame_is_left_view_flag = %d\n", current_frame_is_left_view_flag); |
| printf("next_frame_is_second_view_flag = %d\n", next_frame_is_second_view_flag); |
| #endif |
| } |
| |
| left_view_self_contained_flag = u_1("SEI: left_view_self_contained_flag", buf); |
| right_view_self_contained_flag = u_1("SEI: right_view_self_contained_flag", buf); |
| #ifdef PRINT_STEREO_VIDEO_INFO_INFO |
| printf("left_view_self_contained_flag = %d\n", left_view_self_contained_flag); |
| printf("right_view_self_contained_flag = %d\n", right_view_self_contained_flag); |
| #endif |
| |
| free (buf); |
| #ifdef PRINT_STEREO_VIDEO_INFO_INFO |
| #undef PRINT_STEREO_VIDEO_INFO_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 |
| |
| 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]; |
| |
| activate_sps(sps); |
| |
| #ifdef PRINT_BUFFERING_PERIOD_INFO |
| printf("Buffering period SEI message\n"); |
| printf("seq_parameter_set_id = %d\n", seq_parameter_set_id); |
| #endif |
| |
| // Note: NalHrdBpPresentFlag and CpbDpbDelaysPresentFlag can also be set "by some means not specified in this Recommendation | International Standard" |
| if (sps->vui_parameters_present_flag) |
| { |
| |
| if (sps->vui_seq_parameters.nal_hrd_parameters_present_flag) |
| { |
| for (k=0; k<sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1+1; k++) |
| { |
| initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.nal_hrd_parameters.initial_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.initial_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<sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1+1; k++) |
| { |
| initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.initial_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.initial_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; |
| |
| int cpb_removal_len = 24; |
| int dpb_output_len = 24; |
| |
| Boolean CpbDpbDelaysPresentFlag; |
| |
| Bitstream* buf; |
| |
| if (NULL==active_sps) |
| { |
| fprintf (stderr, "Warning: no active SPS, timing SEI cannot be parsed\n"); |
| return; |
| } |
| |
| buf = malloc(sizeof(Bitstream)); |
| buf->bitstream_length = size; |
| buf->streamBuffer = payload; |
| buf->frame_bitoffset = 0; |
| |
| UsedBits = 0; |
| |
| |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("Picture timing SEI message\n"); |
| #endif |
| |
| // CpbDpbDelaysPresentFlag can also be set "by some means not specified in this Recommendation | International Standard" |
| CpbDpbDelaysPresentFlag = (Boolean) (active_sps->vui_parameters_present_flag |
| && ( (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag != 0) |
| ||(active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag != 0))); |
| |
| if (CpbDpbDelaysPresentFlag ) |
| { |
| if (active_sps->vui_parameters_present_flag) |
| { |
| if (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag) |
| { |
| cpb_removal_len = active_sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1; |
| dpb_output_len = active_sps->vui_seq_parameters.nal_hrd_parameters.dpb_output_delay_length_minus1 + 1; |
| } |
| else if (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag) |
| { |
| cpb_removal_len = active_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1; |
| dpb_output_len = active_sps->vui_seq_parameters.vcl_hrd_parameters.dpb_output_delay_length_minus1 + 1; |
| } |
| } |
| |
| if ((active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)|| |
| (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)) |
| { |
| cpb_removal_delay = u_v(cpb_removal_len, "SEI: cpb_removal_delay" , buf); |
| dpb_output_delay = u_v(dpb_output_len, "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 |
| } |
| } |
| |
| if (!active_sps->vui_parameters_present_flag) |
| { |
| picture_structure_present_flag = 0; |
| } |
| else |
| { |
| picture_structure_present_flag = active_sps->vui_seq_parameters.pic_struct_present_flag; |
| } |
| |
| if (picture_structure_present_flag) |
| { |
| picture_structure = u_v(4, "SEI: pic_struct" , 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<NumClockTs; i++) |
| { |
| clock_time_stamp_flag = u_1("SEI: clock_time_stamp_flag" , buf); |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("clock_time_stamp_flag = %d\n",clock_time_stamp_flag); |
| #endif |
| if (clock_time_stamp_flag) |
| { |
| ct_type = u_v(2, "SEI: ct_type" , buf); |
| nuit_field_based_flag = u_1( "SEI: nuit_field_based_flag" , buf); |
| counting_type = u_v(5, "SEI: counting_type" , buf); |
| full_timestamp_flag = u_1( "SEI: full_timestamp_flag" , buf); |
| discontinuity_flag = u_1( "SEI: discontinuity_flag" , buf); |
| cnt_dropped_flag = u_1( "SEI: cnt_dropped_flag" , buf); |
| nframes = u_v(8, "SEI: nframes" , buf); |
| |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("ct_type = %d\n",ct_type); |
| printf("nuit_field_based_flag = %d\n",nuit_field_based_flag); |
| printf("full_timestamp_flag = %d\n",full_timestamp_flag); |
| printf("discontinuity_flag = %d\n",discontinuity_flag); |
| printf("cnt_dropped_flag = %d\n",cnt_dropped_flag); |
| printf("nframes = %d\n",nframes); |
| #endif |
| if (full_timestamp_flag) |
| { |
| seconds_value = u_v(6, "SEI: seconds_value" , buf); |
| minutes_value = u_v(6, "SEI: minutes_value" , buf); |
| hours_value = u_v(5, "SEI: hours_value" , buf); |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("seconds_value = %d\n",seconds_value); |
| printf("minutes_value = %d\n",minutes_value); |
| printf("hours_value = %d\n",hours_value); |
| #endif |
| } |
| else |
| { |
| seconds_flag = u_1( "SEI: seconds_flag" , buf); |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("seconds_flag = %d\n",seconds_flag); |
| #endif |
| if (seconds_flag) |
| { |
| seconds_value = u_v(6, "SEI: seconds_value" , buf); |
| minutes_flag = u_1( "SEI: minutes_flag" , buf); |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("seconds_value = %d\n",seconds_value); |
| printf("minutes_flag = %d\n",minutes_flag); |
| #endif |
| if(minutes_flag) |
| { |
| minutes_value = u_v(6, "SEI: minutes_value" , buf); |
| hours_flag = u_1( "SEI: hours_flag" , buf); |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("minutes_value = %d\n",minutes_value); |
| printf("hours_flag = %d\n",hours_flag); |
| #endif |
| if(hours_flag) |
| { |
| hours_value = u_v(5, "SEI: hours_value" , buf); |
| #ifdef PRINT_PCITURE_TIMING_INFO |
| printf("hours_value = %d\n",hours_value); |
| #endif |
| } |
| } |
| } |
| } |
| { |
| int time_offset_length; |
| if (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag) |
| time_offset_length = active_sps->vui_seq_parameters.vcl_hrd_parameters.time_offset_length; |
| else if (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag) |
| time_offset_length = active_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length; |
| else |
| time_offset_length = 24; |
| if (time_offset_length) |
| time_offset = u_v(time_offset_length, "SEI: time_offset" , buf); // TODO interpretation is unsigned, need signed interpretation (i_v) |
| else |
| time_offset = 0; |
| #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 |
| } |