// Return TRUE if all was read. FALSE if a problem occured: // If a bitstream syntax problem occured the bitstream will // point to after the problem, in case we run out of data the bitstream // will point to where we want to restart after getting more. static int read_pic_data(struct bitstream *esstream) { dbg_print(DMT_VERBOSE, "Read PIC Data\n"); uint8_t startcode = next_start_code(esstream); // Possibly the last call to this function ended with the last // bit of the slice? I.e. in_pic_data is still true, but we are // seeing the next start code. // We only get here after seeing that start code if (startcode < 0x01 || startcode > 0xAF) { dbg_print(DMT_VERBOSE, "Read Pic Data - processed0\n"); return 1; } // If we get here esstream points to the start of a slice_start_code // should we run out of data in esstream this is where we want to restart // after getting more. unsigned char *slice_start = esstream->pos; do { startcode = next_start_code(esstream); // Syntax check if (startcode == 0xB4) { if (esstream->bitsleft < 0) init_bitstream(esstream, slice_start, esstream->end); if ( esstream->error ) dbg_print(DMT_VERBOSE, "read_pic_data: syntax problem.\n"); else dbg_print(DMT_VERBOSE, "read_pic_data: reached end of bitstream.\n"); return 0; } slice_start = esstream->pos; // No need to come back if ( startcode >= 0x01 && startcode <= 0xAF ) { read_u32(esstream); // Advance bitstream search_start_code(esstream); // Skip this slice } } while(startcode >= 0x01 && startcode <= 0xAF); if (esstream->bitsleft < 0) { init_bitstream(esstream, slice_start, esstream->end); return 0; } dbg_print(DMT_VERBOSE, "Read Pic Data - processed\n"); return 1; }
void sequence_scalable_extension() { int i; sequence_scalable_extension_present = 1; zprintf(1, " sequence_scalable_extension_id = %01X\n", getbits(4)); scalable_mode = getbits(2); zprintf(2, " scalable_mode = %d\n", scalable_mode); zprintf(2, " layer_id = %d\n", getbits(4)); if (scalable_mode == SPATIAL_SCALABILITY) { zprintf(2, " lower_layer_prediction_horizontal_size = %d\n", getbits(14)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " lower_layer_prediction_vertical_size = %d\n", getbits(14)); zprintf(2, " horizontal_subsampling_factor_m = %d\n", getbits(5)); zprintf(2, " horizontal_subsampling_factor_n = %d\n", getbits(5)); zprintf(2, " vertical_subsampling_factor_m = %d\n", getbits(5)); zprintf(2, " vertical_subsampling_factor_n = %d\n", getbits(5)); } if (scalable_mode == TEMPORAL_SCALABILITY) { i = get1bit(); zprintf(2, " picture_mux_enable = %d\n", i); if (i) zprintf(2, " mux_to_progressive_sequence = %d\n", get1bit()); zprintf(2, " picture_mux_order = %d\n", getbits(3)); zprintf(2, " picture_mux_factor = %d\n", getbits(3)); } next_start_code(); }
void picture_coding_extension() { int i; zprintf(1, "\nextension_start_code = 0x000001%02X\n", getbits(8)); zprintf(1, " picture_coding_extension_id = %01X\n", getbits(4)); zprintf(2, " f_code[0][0] forward horizontal = %d\n", getbits(4)); zprintf(2, " f_code[0][1] forward vertical = %d\n", getbits(4)); zprintf(2, " f_code[1][0] backward horizontal = %d\n", getbits(4)); zprintf(2, " f_code[1][1] backward vertical = %d\n", getbits(4)); zprintf(2, " intra_dc_precision = %d\n", getbits(2)); picture_structure = getbits(2); zprintf(2, " picture_structure = %d\n", picture_structure); zprintf(2, " top_field_first = %d\n", get1bit()); zprintf(2, " frame_pred_frame_dct = %d\n", get1bit()); zprintf(2, " concealment_motion_vectors = %d\n", get1bit()); zprintf(2, " q_scale_type= %d\n", get1bit()); zprintf(2, " intra_vlc_format = %d\n", get1bit()); zprintf(2, " alternate_scan = %d\n", get1bit()); repeat_first_field = get1bit(); zprintf(2, " repeat_first_field = %d\n", repeat_first_field); zprintf(2, " chroma_420_type = %d\n", get1bit()); zprintf(2, " progressive_frame = %d\n", get1bit()); i = get1bit(); zprintf(2, " composite_display_flag = %d\n", i); if (i) { zprintf(2, " v_axis = %d\n", get1bit()); zprintf(2, " field_sequence = %d\n", getbits(3)); zprintf(2, " sub_carrier = %d\n", get1bit()); zprintf(2, " burst_amplitude = %d\n", getbits(7)); zprintf(2, " sub_carrier_phase = %d\n", getbits(8)); } next_start_code(); }
void slice() { slice_vertical_position = getbits(8); zprintf(3, "\nslice_start_code = 0x000001%02X\n", slice_vertical_position); if (vertical_size > 2800) { slice_vertical_position_extension = getbits(3); zprintf(3, " slice_vertical_position_extension = %d\n", slice_vertical_position_extension); mb_row = (slice_vertical_position_extension << 7) + slice_vertical_position - 1; } else mb_row = slice_vertical_position - 1; previous_macroblock_address = (mb_row * mb_width) - 1; if (sequence_scalable_extension_present == 1) if (scalable_mode == DATA_PARTITIONING) zprintf(3, " priority_breakpoint = %d\n", getbits(7)); zprintf(3, " quantiser_scale_code = %d\n", getbits(5)); if (nextbits(1) == 1) { zprintf(3, " intra_slice_flag = %d\n", get1bit()); zprintf(3, " intra_slice = %d\n", get1bit()); zprintf(3, " reserve_bits = %d\n", getbits(7)); while (nextbits(1) == 1) { zprintf(3, " extra_bit_slice = %d\n", get1bit()); zprintf(3, " extra_information_slice = %d\n", getbits(8)); } } zprintf(3, " extra_bit_slice = %d\n", get1bit()); // do // macroblock(); // while (nextbits(23) != 0); next_start_code(); }
/* * decode headers from one input stream * until an End of Sequence or picture start code * is found */ int Get_Hdr() { unsigned int code; for (;;) { /* look for next_start_code */ next_start_code(); code = Get_Bits32(); switch (code) { case SEQUENCE_HEADER_CODE: sequence_header(); break; case GROUP_START_CODE: group_of_pictures_header(); break; case PICTURE_START_CODE: picture_header(); return 1; break; case SEQUENCE_END_CODE: return 0; break; default: if (!Quiet_Flag) fprintf(stderr,"Unexpected next_start_code %08x (ignored)\n",code); break; } } }
void picture_header() { int i; zprintf(1, "\npicture_header = 0x000001%02X\n", getbits(8)); zprintf(2, " temporal_reference = %d\n", getbits(10)); i = getbits(3); zprintf(2, " picture_coding_type = %d\n", i); zprintf(2, " vbv_delay = %d\n", getbits(16)); if (i == 2 || i == 3) { zprintf(2, " full_pel_forward_vector = %d\n", get1bit()); zprintf(2, " forward_f_code = %d\n", getbits(3)); } if (i == 3) { zprintf(2, " full_pel_backward_vector = %d\n", get1bit()); zprintf(2, " backward_f_code = %d\n", getbits(3)); } while (nextbits(1) == 1) { zprintf(2, " extra_bit_picture = %d\n", get1bit()); zprintf(2, " extra_information_picture = %d\n", getbits(8)); } zprintf(2, " extra_bit_picture = %d\n", get1bit()); next_start_code(); }
void picture_temporal_scalable_extension() { zprintf(1, " picture_temporal_scalable_extension_id = %01X\n", getbits(4)); zprintf(2, " reference_select_code = %d\n", getbits(2)); zprintf(2, " forward_temporal_reference = %d\n", getbits(10)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " backward_temporal_reference = %d\n", getbits(10)); next_start_code(); }
void user_data() { zprintf(1, "\nuser_data_start_code = 0x000001%02X\n", getbits(8)); while (nextbits(24) != START_CODE_PREFIX) { getbits(8); user_data_bytes++; } next_start_code(); }
void group_of_pictures_header() { zprintf(1, "\ngroup_start_code = 0x000001%02X\n", getbits(8)); zprintf(2, " drop_frame_flag = %d\n", get1bit()); zprintf(2, " time_code_hours = %d\n", getbits(5)); zprintf(2, " time_code_minutes = %d\n", getbits(6)); zprintf(2, " marker_bit = %d\n", get1bit()); zprintf(2, " time_code_seconds = %d\n", getbits(6)); zprintf(2, " time_code_pictures = %d\n", getbits(6)); zprintf(2, " closed_gop = %d\n", get1bit()); zprintf(2, " broken_link = %d\n", get1bit()); next_start_code(); }
void picture_spatial_scalable_extension() { zprintf(1, " picture_spatial_scalable_extension_id = %01X\n", getbits(4)); zprintf(2, " lower_layer_temporal_reference = %d\n", getbits(10)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " lower_layer_horizontal_offset = %d\n", getbits(15)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " lower_layer_vertical_offset = %d\n", getbits(15)); zprintf(2, " spatial_temporal_weight_code_table_index = %d\n", getbits(2)); zprintf(2, " lower_layer_progressive_frame = %d\n", get1bit()); zprintf(2, " lower_layer_deinterlaced_field_select = %d\n", get1bit()); next_start_code(); }
// Return TRUE if the data parsing finished, FALSE otherwise. // estream->pos is advanced. Data is only processed if esstream->error // is FALSE, parsing can set esstream->error to TRUE. static int pic_coding_ext(struct bitstream *esstream) { dbg_print(DMT_VERBOSE, "Picture coding extension %lld\n", esstream->bitsleft); if (esstream->error || esstream->bitsleft <= 0) return 0; // Syntax check if (next_start_code(esstream) != 0xB5) { dbg_print(DMT_VERBOSE, "pic_coding_ext: syntax problem.\n"); return 0; } read_u32(esstream); // Advance // Read extension_start_code_identifier unsigned extension_id = (unsigned int) read_bits(esstream, 4); if (extension_id != 0x8) // Picture Coding Extension ID { if (esstream->bitsleft >= 0) // When bits left, this is wrong esstream->error = 1; if (esstream->error) dbg_print(DMT_VERBOSE, "pic_coding_ext: syntax problem.\n"); return 0; } // Discard some information skip_bits(esstream, 4*4+2); picture_structure = (unsigned int) read_bits(esstream, 2); top_field_first = (unsigned int) read_bits(esstream, 1); skip_bits(esstream, 5*1); repeat_first_field = (unsigned int) read_bits(esstream, 1); skip_bits(esstream, 1); // chroma progressive_frame = (unsigned int) read_bits(esstream, 1); unsigned composite_display = (unsigned int) read_bits(esstream,1); if (composite_display) skip_bits(esstream, 1+3+1+7+8); if (esstream->bitsleft < 0) return 0; dbg_print(DMT_VERBOSE, "Picture coding extension - processed\n"); // Read complete return 1; }
// Return TRUE if the data parsing finished, FALSE otherwise. // estream->pos is advanced. Data is only processed if esstream->error // is FALSE, parsing can set esstream->error to TRUE. static int sequence_ext(struct bitstream *esstream) { dbg_print(DMT_VERBOSE, "Sequence extension\n"); if (esstream->error || esstream->bitsleft <= 0) return 0; // Syntax check if (next_start_code(esstream) != 0xB5) { dbg_print(DMT_VERBOSE, "sequence_ext: syntax problem.\n"); return 0; } read_u32(esstream); // Advance // Read extension_start_code_identifier unsigned extension_id = (unsigned) read_bits(esstream, 4); if (extension_id != 0x1) // Sequence Extension ID { if (esstream->bitsleft >= 0) // When bits left, this is wrong esstream->error = 1; if (esstream->error) dbg_print(DMT_VERBOSE, "sequence_ext: syntax problem.\n"); return 0; } // Discard some information skip_bits(esstream, 8); unsigned progressive_sequence = (unsigned) read_bits(esstream,1); if (progressive_sequence!=current_progressive_sequence) { current_progressive_sequence = progressive_sequence; mprint(" [progressive: %s]\n\n", (progressive_sequence ? "yes" : "no")); } skip_bits(esstream, 2+2+2+12+1+8+1+2+5); if (esstream->bitsleft < 0) return 0; // Read complete return 1; }
void sequence_extension() { sequence_extensions++; zprintf(1, "\nextension_start_code = 0x000001%02X\n", getbits(8)); zprintf(2, " sequence_extension_id = %d\n", getbits(4)); zprintf(2, " profile_and_level_indication = %d\n", getbits(8)); progressive_sequence = get1bit(); zprintf(2, " progressive_sequence = %d\n", progressive_sequence); zprintf(2, " chroma_format = %d\n", getbits(2)); zprintf(2, " horizontal_size_extension = %d\n", getbits(2)); zprintf(2, " vertical_size_extension = %d\n", getbits(2)); zprintf(2, " bit_rate_extension = %d\n", getbits(12)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " vbv_buffer_size_extension = %d\n", getbits(8)); zprintf(2, " low_delay = %d\n", get1bit()); zprintf(2, " frame_rate_extension_n = %d\n", getbits(2)); zprintf(2, " frame_rate_extension_d = %d\n", getbits(5)); next_start_code(); }
void sequence_display_extension() { int i; zprintf(1, " sequence_display_extension_id = %01X\n", getbits(4)); zprintf(2, " video_format = %d\n", getbits(3)); i = get1bit(); zprintf(2, " colour_description = %d\n", i); if (i) { zprintf(2, " colour_primaries = %d\n", getbits(8)); zprintf(2, " transfer_characteristics = %d\n", getbits(8)); zprintf(2, " matrix_coefficients = %d\n", getbits(8)); } zprintf(2, " display_horizontal_size = %d\n", getbits(14)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " display_vertical_size = %d\n", getbits(14)); next_start_code(); }
void picture_display_extension() { int i, number_of_frame_centre_offsets; zprintf(1, " picture_display_extension_id = %01X\n", getbits(4)); if ((progressive_sequence == 1) || (picture_structure == 3)) number_of_frame_centre_offsets = 1; else if (repeat_first_field == 1) number_of_frame_centre_offsets = 3; else number_of_frame_centre_offsets = 2; for (i = 0; i < number_of_frame_centre_offsets; i++) { zprintf(2, " frame_centre_horizontal_offset = %d\n", getbits(16)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " frame_centre_vertical_offset = %d\n", getbits(16)); zprintf(2, " marker bit = %d\n", get1bit()); } next_start_code(); }
void quant_matrix_extension() { int i; zprintf(1, " quant_matrix_extension_id = %01X\n", getbits(4)); i = get1bit(); zprintf(2, " load_intra_quantiser_matrix = %d\n", i); if (i) { for (i = 0; i < 64; i++) getbits(8); zprintf(2, " read %d intra_quantiser_matrix bytes = %d\n", i); } i = get1bit(); zprintf(2, " load_non_intra_quantiser_matrix = %d\n", i); if (i) { for (i = 0; i < 64; i++) getbits(8); zprintf(2, " read %d non_intra_quantiser_matrix bytes = %d\n", i); } i = get1bit(); zprintf(2, " load_chroma_intra_quantiser_matrix = %d\n", i); if (i) { for (i = 0; i < 64; i++) getbits(8); zprintf(2, " read %d chroma_intra_quantiser_matrix bytes = %d\n", i); } i = get1bit(); zprintf(2, " load_chroma_non_intra_quantiser_matrix = %d\n", i); if (i) { for (i = 0; i < 64; i++) getbits(8); zprintf(2, " read %d chroma_non_intra_quantiser_matrix bytes = %d\n", i); } next_start_code(); }
void sequence_header() { int i; sequence_headers++; zprintf(1, "\n\nsequence_header_code = 0x000001%02X\n", getbits(8)); horizontal_size = getbits(12); mb_width = horizontal_size / 16; if (mb_width % 16) mb_width++; zprintf(2, " horizontal_size_value = %d\n", horizontal_size); vertical_size = getbits(12); zprintf(2, " vertical_size_value = %d\n", vertical_size); zprintf(2, " aspect_ratio_information = %d\n", getbits(4)); zprintf(2, " frame_rate_code = %d\n", getbits(4)); zprintf(2, " bit_rate_value = %d\n", getbits(18)); zprintf(2, " marker bit = %d\n", get1bit()); zprintf(2, " vbv_buffer_size_value = %d\n", getbits(10)); zprintf(2, " constrained_parameters_flag = %d\n", get1bit()); i = get1bit(); zprintf(2, " load_intra_quantiser_matrix = %d\n", i); if (i) { for (i = 0; i < 64; i++) getbits(8); zprintf(2, " read %d intra_quantiser_matrix bytes = %d\n", i); } i = get1bit(); zprintf(2, " load_non_intra_quantiser_matrix = %d\n", i); if (i) { for (i = 0; i < 64; i++) getbits(8); zprintf(2, " read %d non_intra_quantiser_matrix bytes = %d\n", i); } next_start_code(); }
// Return TRUE if the video sequence was finished, FALSE // Otherwise. estream->pos shall point to the position where // the next call will continue, i.e. the possible begin of an // unfinished video sequence or after the finished sequence. static int es_video_sequence(struct bitstream *esstream) { // Avoid "Skip forward" message on first call and later only // once per search. static int noskipmessage = 1; uint8_t startcode; dbg_print(DMT_VERBOSE, "es_video_sequence()\n"); esstream->error = 0; // Analyze sequence header ... if (!no_bitstream_error) { // We might start here because of a syntax error. Discard // all data until a new sequence_header_code or group_start_code // is found. if (!noskipmessage) // Avoid unnecessary output. mprint("\nSkip forward to the next Sequence or GOP start.\n"); else noskipmessage = 0; uint8_t startcode; while(1) { // search_start_code() cannot produce esstream->error startcode = search_start_code(esstream); if (esstream->bitsleft < 0) { noskipmessage = 1; return 0; } if (startcode == 0xB3 || startcode == 0xB8) // found it break; skip_bits(esstream, 4*8); } no_bitstream_error = 1; saw_seqgoppic = 0; in_pic_data = 0; } do { startcode = next_start_code(esstream); dbg_print(DMT_VERBOSE, "\nM2V - next start code %02X %d\n", startcode, in_pic_data); // Syntax check - also returns on bitsleft < 0 if (startcode == 0xB4) { if (esstream->error) { no_bitstream_error = 0; dbg_print(DMT_VERBOSE, "es_video_sequence: syntax problem.\n"); } dbg_print(DMT_VERBOSE, "es_video_sequence: return on B4 startcode.\n"); return 0; } // Sequence_end_code if (startcode == 0xB7) { read_u32(esstream); // Advance bitstream no_bitstream_error = 0; break; } if (!in_pic_data && startcode == 0xB3) { if (!read_seq_info(esstream)) { if (esstream->error) no_bitstream_error = 0; return 0; } saw_seqgoppic = 1; continue; } if (!in_pic_data && startcode == 0xB8) { if (!read_gop_info(esstream)) { if (esstream->error) no_bitstream_error = 0; return 0; } saw_seqgoppic = 2; continue; } if (!in_pic_data && startcode == 0x00) { if (!read_pic_info(esstream)) { if (esstream->error) no_bitstream_error = 0; return 0; } saw_seqgoppic = 3; in_pic_data = 1; continue; } // Only looks for extension and user data if we saw sequence, gop // or picture info before. // This check needs to be before the "in_pic_data" part. if ( saw_seqgoppic && (startcode == 0xB2 || startcode == 0xB5)) { if (!read_eau_info(esstream, saw_seqgoppic-1)) { if (esstream->error) no_bitstream_error = 0; return 0; } saw_seqgoppic = 0; continue; } if (in_pic_data) // See comment in read_pic_data() { if (!read_pic_data(esstream)) { if (esstream->error) no_bitstream_error = 0; return 0; } saw_seqgoppic = 0; in_pic_data = 0; continue; } // Nothing found - bitstream error if (startcode == 0xBA) { mprint("\nFound PACK header in ES data. Probably wrong stream mode!\n"); } else { mprint("\nUnexpected startcode: %02X\n", startcode); } no_bitstream_error = 0; return 0; } while(1); return 1; }
int read_MPEG_video (media_entry *me, uint8 *data, uint32 *data_size, double *mtime, int *recallme, uint8 *marker) /* reads MPEG-1,2 Video */ { int ret; uint32 num_bytes; char *vsh1_1; #ifdef MPEG2VSHE char *vsh2_1; #endif uint32 count,flag=0,seq_head_pres=0; unsigned char *data_tmp; static_MPEG_video *s=NULL; uint32 wasSeeking=0; if (!(me->flags & ME_FD)) { if ( (ret=mediaopen(me)) < 0 ) return ret; s = (static_MPEG_video *) calloc (1, sizeof(static_MPEG_video)); me->stat = (void *) s; s->final_byte=0x00; s->std=TO_PROBE; s->fragmented=0; } else s = (static_MPEG_video *) me->stat; num_bytes = ((me->description).byte_per_pckt>261)?(me->description).byte_per_pckt:DEFAULT_BYTE_X_PKT; #if HAVE_ALLOCA data_tmp=(unsigned char *)alloca(65000); #else data_tmp=(unsigned char *)calloc(1,65000); #endif if (data_tmp==NULL) return ERR_ALLOC; if (s->std == MPEG_2) {/*the first time is TO_PROBE*/ #ifdef MPEG2VSHE *data_size = 8; #else *data_size = 4; #endif /* bytes for the video specific header */ } else { *data_size = 4; } if (s->std == TO_PROBE) { probe_standard(me,data_tmp,data_size,me->fd,&s->std); flag=1; seq_head_pres=1; } /*---- Random Access ----*/ if((me->description).msource!=live && me->play_offset!=me->prev_mstart_offset){ if(!me->description.bitrate){ //Bit Rate unavaible in sequence header, so i calculate it from scratch me->description.bitrate=(int)(s->data_total * 8 / (*mtime))*1000; } else{ s->fragmented=0; wasSeeking=1; if(!flag){ lseek(me->fd,0,SEEK_SET); probe_standard(me,data_tmp,data_size,me->fd,&s->std); seq_head_pres=1; } } count=random_access(me); lseek(me->fd,count,SEEK_SET); me->prev_mstart_offset=me->play_offset; } /*---- end Random Access ----*/ #if 0 if(num_bytes==0){ /*TODO:case 1 slice for pkt*/ do{ if(!flag){ if ( next_start_code(data_tmp,data_size,me->fd) == -1) { close(me->fd); #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } read(me->fd,&s->final_byte,1); data_tmp[*data_size]=s->final_byte; *data_size+=1; }else{ s->final_byte=data_tmp[*data_size-1]; } if (s->final_byte == 0xb3) { read_seq_head(me,data_tmp,data_size,me->fd,&s->final_byte,s->std); seq_head_pres=1; } if (s->final_byte == 0xb8) { read_gop_head(data_tmp,data_size,me->fd,&s->final_byte,&s->hours,&s->minutes,&s->seconds,&s->picture,s->std); } if (s->final_byte == 0x00) { read_picture_head(data_tmp,data_size,me->fd,&s->final_byte,&s->temp_ref,&s->vsh1,s->std); if (s->std == MPEG_2) { read_picture_coding_ext(data_tmp,data_size,me->fd,&s->final_byte,&s->vsh2); } } }while(s->final_byte>0xAF); read_slice(data_tmp,data_size,me->fd,&s->final_byte); s->vsh1.b=1; }/*end if(num_bytes==0)*/ else #endif if(!s->fragmented)/*num_bytes !=0 and slice was not fragmented*/{ char buf_aux[3]; int i; if(flag && wasSeeking==0) s->final_byte=data_tmp[*data_size-1]; else{ data_tmp[*data_size]=0x00; *data_size+=1; data_tmp[*data_size]=0x00; *data_size+=1; data_tmp[*data_size]=0x01; *data_size+=1; data_tmp[*data_size]=s->final_byte; *data_size+=1; } if(s->final_byte==0xb7){ if (next_start_code(data_tmp,data_size,me->fd)==-1){ /* If there aren't 3 more bytes we are at EOF */ #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } if(read(me->fd,&s->final_byte,1)<1) { #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } data_tmp[*data_size]=s->final_byte; *data_size+=1; } *recallme=1; while((s->final_byte > 0xAF || s->final_byte==0x00) && *recallme){ if (s->final_byte == 0xb3) { read_seq_head(me, data_tmp, data_size, me->fd, &s->final_byte, s->std); seq_head_pres=1; } if (s->final_byte == 0xb8) { read_gop_head(data_tmp, data_size, me->fd, &s->final_byte, &s->hours, &s->minutes, &s->seconds, &s->picture, s->std); } if (s->final_byte == 0x00) { read_picture_head(data_tmp, data_size, me->fd, &s->final_byte, &s->temp_ref, &s->vsh1, s->std); if (s->std == MPEG_2 && *data_size<num_bytes) { read_picture_coding_ext(data_tmp, data_size, me->fd, &s->final_byte, &s->vsh2); } } if (s->final_byte == 0xb7) {/*sequence end code*/ *recallme=0; s->fragmented=0; } while(s->final_byte==0xb2||s->final_byte==0xb5){ if(next_start_code(data_tmp,data_size,me->fd)<0) { #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } if(read(me->fd,&s->final_byte,1)<1) { #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } data_tmp[*data_size]=s->final_byte; *data_size+=1; } } // *data_size-=4; while(num_bytes > *data_size && *recallme){ // *data_size+=4; if ( read(me->fd,&buf_aux,3) <3){ /* If there aren't 3 more bytes we are at EOF */ // close(me->fd); #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } while ( !((buf_aux[0] == 0x00) && (buf_aux[1]==0x00) && (buf_aux[2]==0x01)) && *data_size <num_bytes) { data_tmp[*data_size]=buf_aux[0]; *data_size+=1; buf_aux[0]=buf_aux[1]; buf_aux[1]=buf_aux[2]; if ( read(me->fd,&buf_aux[2],1) <1){ // close(me->fd); #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } } for (i=0;i<3;i++) { data_tmp[*data_size]=buf_aux[i]; *data_size+=1; } if(read(me->fd,&s->final_byte,1)<1) { #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } data_tmp[*data_size]=s->final_byte; *data_size+=1; if ( ((buf_aux[0] == 0x00) && (buf_aux[1]==0x00) && (buf_aux[2]==0x01)) ) { if(((s->final_byte > 0xAF)||(s->final_byte==0x00)) ){/*TODO: 0xb7*/ *recallme = 0; // *data_size-=4; } else *recallme=1; s->fragmented=0; } else{ *recallme=1; s->fragmented=1; } }/*end while *data_size < num_bytes && *recallme*/ s->vsh1.b=1; if ( ((buf_aux[0] == 0x00) && (buf_aux[1]==0x00) && (buf_aux[2]==0x01)) ) *data_size-=4; }/*end else num_bytes!=0 and slice was not fragmented*/ else{/*num_bytes!=0 and slice was fragmented*/ char buf_aux[3]; int i; if ( read(me->fd,&buf_aux,3) <3){ /* If there aren't 3 more bytes we are at EOF */ // close(me->fd); #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } while ( !((buf_aux[0] == 0x00) && (buf_aux[1]==0x00) && (buf_aux[2]==0x01)) && *data_size <num_bytes) { data_tmp[*data_size]=buf_aux[0]; *data_size+=1; buf_aux[0]=buf_aux[1]; buf_aux[1]=buf_aux[2]; if ( read(me->fd,&buf_aux[2],1) <1){ // close(me->fd); #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } } for (i=0;i<3;i++) { data_tmp[*data_size]=buf_aux[i]; *data_size+=1; } if(read(me->fd,&s->final_byte,1)<1) { #if !HAVE_ALLOCA free(data_tmp); #endif return ERR_EOF; } data_tmp[*data_size]=s->final_byte; *data_size+=1; if ( ((buf_aux[0] == 0x00) && (buf_aux[1]==0x00) && (buf_aux[2]==0x01)) ) { if(((s->final_byte > 0xAF)||(s->final_byte==0x00)) ){/*TODO: 0xb7*/ *recallme = 0; } else *recallme=1; s->fragmented=0; *data_size-=4; } else{ *recallme=1; s->fragmented=1; } s->vsh1.b=0; } if ( me->description.msource != live ) *mtime = (s->hours * 3.6e6) + (s->minutes * 6e4) + (s->seconds * 1000) + (s->temp_ref*40) + (s->picture*40); s->data_total+=*data_size; if (s->std==MPEG_2 && !flag) { #ifdef MPEG2VSHE s->data_total-=8; s->vsh1.t=1; #else s->data_total-=4; s->vsh1.t=0; #endif } else { s->data_total-=4; s->vsh1.t=0; } s->vsh1.mbz=0; s->vsh1.an=0; s->vsh1.n=0; if (seq_head_pres) { s->vsh1.s=1; } else { s->vsh1.s=0; } // s->vsh1.b=1; if (!s->fragmented) { s->vsh1.e=1; } else { s->vsh1.e=0; } vsh1_1 = (char *)(&s->vsh1); /* to see the struct as a set of bytes */ data_tmp[0] = vsh1_1[3]; data_tmp[1] = vsh1_1[2]; data_tmp[2] = vsh1_1[1]; data_tmp[3] = vsh1_1[0]; #ifdef MPEG2VSHE if (s->std == MPEG_2 && !flag) { vsh2_1 = (char *)(&s->vsh2); data_tmp[4] = vsh2_1[3]; data_tmp[5] = vsh2_1[2]; data_tmp[6] = vsh2_1[1]; data_tmp[7] = vsh2_1[0]; } #endif flag=0; /*so it is just probed*/ memcpy(data, data_tmp, *data_size); #if !HAVE_ALLOCA free(data_tmp); #endif *marker=!(*recallme); return ERR_NOERROR; }
int main(int argc, char* argv[]) { char tmpStr[256]; col = 0; verbose_level = 1; sequence_headers = 0; sequence_extensions = 0; user_data_bytes = 0; sequence_scalable_extension_present = 0; printf("bbVINFO - version 1.7, by Brent Beyeler ([email protected])\n"); printf(" speed increases by, Apachez and Christian Vogelgsang\n\n"); if (argc < 2) { printf("\nbbVINFO is an MPEG video stream analyzer\n\n"); printf("Usage: bbVINFO MPEG video filename <verbose level 1..3, default = 1>\n\n"); printf("Examples:\n"); printf(" To list all packet start codes (excluding slice codes) to file test.txt\n"); printf(" bbVINFO test.mpg 1 > test.txt\n\n"); printf(" To list all packets (excluding slice packets) in detail\n"); printf(" bbVINFO test.vob 2\n\n"); printf(" To list all packets (including slice packets) in detail to file test.txt\n"); printf(" bbVINFO test.mpg 3 > test.txt\n\n"); exit (1); } init_getbits(argv[1]); strcpy(tmpStr, argv[1]); // strlwr(tmpStr); if (argc > 2) { sscanf(argv[2], "%d", &verbose_level); if (verbose_level < 1) verbose_level = 1; if (verbose_level > 3) verbose_level = 3; } next_start_code(); if (getbits(8) != SEQUENCE_HEADER_CODE) { printf("\nFile is not an MPEG Video Stream\n"); exit(1); } next_start_code(); if (getbits(8) != EXTENSION_START_CODE) mpeg2 = 0; else mpeg2 = 1; printf("\nFile %s is an MPEG-%d video stream\n", argv[1], mpeg2 + 1); finish_getbits(); init_getbits(argv[1]); next_start_code(); sequence_header(); if (mpeg2) sequence_extension(); do { extension_and_user_data(0); do { if (nextbits(8) == GROUP_START_CODE) { group_of_pictures_header(); extension_and_user_data(1); } picture_header(); if (mpeg2) picture_coding_extension(); extension_and_user_data(2); picture_data(); } while ((nextbits(8) == PICTURE_START_CODE) || (nextbits(8) == GROUP_START_CODE)); if (nextbits(8) != SEQUENCE_END_CODE) { sequence_header(); if (mpeg2) sequence_extension(); } } while (nextbits(8) != SEQUENCE_END_CODE); zprintf(1, "\nsequence_end_code = 0x000001%02X\n", getbits(8)); finish_getbits(); return (0); }
// Open function modified by Donald Graft as part of fix for dropped frames and random frame access. int CMPEG2Decoder::Open(const char *path) { char buf[2048], *buf_p; Choose_Prediction(this->fastMC); char ID[80], PASS[80] = "DGIndexProjectFile16"; DWORD i, j, size, code, type, tff, rff, film, ntsc, gop, top, bottom, mapping; int repeat_on, repeat_off, repeat_init; int vob_id, cell_id; __int64 position; int HadI; CMPEG2Decoder* out = this; out->VF_File = fopen(path, "r"); if (fgets(ID, 79, out->VF_File)==NULL) return 1; if (strstr(ID, "DGIndexProjectFile") == NULL) return 5; if (strncmp(ID, PASS, 20)) return 2; fscanf(out->VF_File, "%d\n", &File_Limit); i = File_Limit; while (i) { Infilename[File_Limit-i] = (char*)aligned_malloc(_MAX_PATH, 16); fgets(Infilename[File_Limit-i], _MAX_PATH - 1, out->VF_File); // Strip newline. Infilename[File_Limit-i][strlen(Infilename[File_Limit-i])-1] = 0; if (PathIsRelative(Infilename[File_Limit-i])) { char *p, d2v_stem[_MAX_PATH], open_path[_MAX_PATH]; if (PathIsRelative(path)) { GetCurrentDirectory(_MAX_PATH, d2v_stem); if (*(d2v_stem + strlen(d2v_stem) - 1) != '\\') strcat(d2v_stem, "\\"); strcat(d2v_stem, path); } else { strcpy(d2v_stem, path); } p = d2v_stem + strlen(d2v_stem); while (*p != '\\' && p != d2v_stem) p--; if (p != d2v_stem) { p[1] = 0; strcat(d2v_stem, Infilename[File_Limit-i]); PathCanonicalize(open_path, d2v_stem); if ((Infile[File_Limit-i] = _open(open_path, _O_RDONLY | _O_BINARY))==-1) return 3; } else { // This should never happen because the code should guarantee that d2v_stem has a '\' character. return 3; } } else { if ((Infile[File_Limit-i] = _open(Infilename[File_Limit-i], _O_RDONLY | _O_BINARY))==-1) return 3; } i--; } fscanf(out->VF_File, "\nStream_Type=%d\n", &SystemStream_Flag); if (SystemStream_Flag == 2) { fscanf(out->VF_File, "MPEG2_Transport_PID=%x,%x,%x\n", &MPEG2_Transport_VideoPID, &MPEG2_Transport_AudioPID, &MPEG2_Transport_PCRPID); fscanf(out->VF_File, "Transport_Packet_Size=%d\n", &TransportPacketSize); } fscanf(out->VF_File, "MPEG_Type=%d\n", &mpeg_type); fscanf(out->VF_File, "iDCT_Algorithm=%d\n", &IDCT_Flag); switch (IDCT_Flag) { case IDCT_MMX: idctFunc = MMX_IDCT; break; case IDCT_SSEMMX: idctFunc = SSEMMX_IDCT; if (!cpu.ssemmx) { IDCT_Flag = IDCT_MMX; idctFunc = MMX_IDCT; } break; case IDCT_FPU: if (!fpuinit) { Initialize_FPU_IDCT(); fpuinit = true; } idctFunc = FPU_IDCT; break; case IDCT_REF: if (!refinit) { refinit = true; } idctFunc = REF_IDCT; break; case IDCT_SSE2MMX: idctFunc = SSE2MMX_IDCT; if (!cpu.sse2mmx) { IDCT_Flag = IDCT_SSEMMX; idctFunc = SSEMMX_IDCT; if (!cpu.ssemmx) { IDCT_Flag = IDCT_MMX; idctFunc = MMX_IDCT; } } break; case IDCT_SKALSSE: idctFunc = Skl_IDct16_Sparse_SSE; //Skl_IDct16_SSE; if (!cpu.ssemmx) { IDCT_Flag = IDCT_MMX; idctFunc = MMX_IDCT; } break; case IDCT_SIMPLEIDCT: idctFunc = simple_idct_mmx; if (!cpu.ssemmx) { IDCT_Flag = IDCT_MMX; idctFunc = MMX_IDCT; } break; } File_Flag = 0; _lseeki64(Infile[0], 0, SEEK_SET); Initialize_Buffer(); do { if (Fault_Flag == OUT_OF_BITS) return 4; next_start_code(); code = Get_Bits(32); } while (code!=SEQUENCE_HEADER_CODE); sequence_header(); mb_width = (horizontal_size+15)/16; mb_height = progressive_sequence ? (vertical_size+15)/16 : 2*((vertical_size+31)/32); QP = (int*)aligned_malloc(sizeof(int)*mb_width*mb_height, 32); backwardQP = (int*)aligned_malloc(sizeof(int)*mb_width*mb_height, 32); auxQP = (int*)aligned_malloc(sizeof(int)*mb_width*mb_height, 32); Coded_Picture_Width = 16 * mb_width; Coded_Picture_Height = 16 * mb_height; Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width : Coded_Picture_Width>>1; Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height : Coded_Picture_Height>>1; block_count = ChromaFormat[chroma_format]; for (i=0; i<8; i++) { p_block[i] = (short *)aligned_malloc(sizeof(short)*64 + 64, 32); block[i] = (short *)((long)p_block[i] + 64 - (long)p_block[i]%64); } for (i=0; i<3; i++) { if (i==0) size = Coded_Picture_Width * Coded_Picture_Height; else size = Chroma_Width * Chroma_Height; backward_reference_frame[i] = (unsigned char*)aligned_malloc(2*size+4096, 32); //>>> cheap safety bump forward_reference_frame[i] = (unsigned char*)aligned_malloc(2*size+4096, 32); auxframe[i] = (unsigned char*)aligned_malloc(2*size+4096, 32); } fscanf(out->VF_File, "YUVRGB_Scale=%d\n", &pc_scale); fscanf(out->VF_File, "Luminance_Filter=%d,%d\n", &i, &j); if (i==0 && j==0) Luminance_Flag = 0; else { Luminance_Flag = 1; InitializeLuminanceFilter(i, j); } fscanf(out->VF_File, "Clipping=%d,%d,%d,%d\n", &Clip_Left, &Clip_Right, &Clip_Top, &Clip_Bottom); fscanf(out->VF_File, "Aspect_Ratio=%s\n", Aspect_Ratio); fscanf(out->VF_File, "Picture_Size=%dx%d\n", &D2V_Width, &D2V_Height); Clip_Width = Coded_Picture_Width; Clip_Height = Coded_Picture_Height; if (upConv > 0 && chroma_format == 1) { // these are labeled u422 and v422, but I'm only using them as a temporary // storage place for YV12 chroma before upsampling to 4:2:2 so that's why its // /4 and not /2 -- (tritical - 1/05/2005) int tpitch = (((Chroma_Width+15)>>4)<<4); // mod 16 chroma pitch needed to work with YV12PICTs u422 = (unsigned char*)aligned_malloc((tpitch * Coded_Picture_Height / 2)+2048, 32); v422 = (unsigned char*)aligned_malloc((tpitch * Coded_Picture_Height / 2)+2048, 32); auxFrame1 = create_YV12PICT(Coded_Picture_Height,Coded_Picture_Width,chroma_format+1); auxFrame2 = create_YV12PICT(Coded_Picture_Height,Coded_Picture_Width,chroma_format+1); }
// Return TRUE if the data parsing finished, FALSE otherwise. // estream->pos is advanced. Data is only processed if esstream->error // is FALSE, parsing can set esstream->error to TRUE. static int extension_and_user_data(struct bitstream *esstream, int udtype) { dbg_print(DMT_VERBOSE, "Extension and user data(%d)\n", udtype); if (esstream->error || esstream->bitsleft <= 0) return 0; // Remember where to continue unsigned char *eau_start = esstream->pos; uint8_t startcode; do { startcode = next_start_code(esstream); if ( startcode == 0xB2 || startcode == 0xB5 ) { read_u32(esstream); // Advance bitstream unsigned char *dstart = esstream->pos; // Advanve esstream to the next startcode. Verify that // the whole extension was available and discard blocks // followed by PACK headers. The latter usually indicates // a PS treated as an ES. uint8_t nextstartcode = search_start_code(esstream); if (nextstartcode == 0xBA) { mprint("\nFound PACK header in ES data. Probably wrong stream mode!\n"); esstream->error = 1; return 0; } if (esstream->error) { dbg_print(DMT_VERBOSE, "Extension and user data - syntax problem\n"); return 0; } if (esstream->bitsleft < 0) { dbg_print(DMT_VERBOSE, "Extension and user data - inclomplete\n"); // Restore to where we need to continue init_bitstream(esstream, eau_start, esstream->end); esstream->bitsleft = -1; // Redundant return 0; } if (startcode == 0xB2) { struct bitstream ustream; init_bitstream(&ustream, dstart, esstream->pos); user_data(&ustream, udtype); } else { dbg_print(DMT_VERBOSE, "Skip %d bytes extension data.\n", esstream->pos - dstart); } // If we get here esstream points to the end of a block // of extension or user data. Should we run out of data in // this loop this is where we want to restart after getting more. eau_start = esstream->pos; } } while(startcode == 0xB2 || startcode == 0xB5); if (esstream->error) { dbg_print(DMT_VERBOSE, "Extension and user data - syntax problem\n"); return 0; } if (esstream->bitsleft < 0) { dbg_print(DMT_VERBOSE, "Extension and user data - inclomplete\n"); // Restore to where we need to continue init_bitstream(esstream, eau_start, esstream->end); esstream->bitsleft = -1; // Redundant return 0; } dbg_print(DMT_VERBOSE, "Extension and user data - processed\n"); // Read complete return 1; }
int read_MPEG_system(media_entry *me, uint8 *data,uint32 *data_size, double *mtime, int *recallme, uint8 *marker) { int ret; uint32 num_bytes; int count,count1,flag,packet_done=0,not_remove=0,time_set=0,pts_diff,clock,dts_present=0,audio_flag=0; float pkt_len; static_MPEG_system *s=NULL; if (!(me->flags & ME_FD)) { if ( (ret=mediaopen(me)) < 0 ) return ret; s = (static_MPEG_system *) calloc (1, sizeof(static_MPEG_system)); me->stat = (void *) s; s->final_byte=0x00; s->offset_flag=0; s->offset=0; s->new_dts=0; } else s = (static_MPEG_system *) me->stat; num_bytes = (me->description).byte_per_pckt; *data_size=0; count=count1=0; flag = 1; lseek(me->fd,s->data_total,SEEK_SET); /* At this point it should be right to find the nearest lower frame */ /* computing it from the value of mtime */ //*data=(unsigned char *)calloc(1,65000); /* and starting the reading from this */ //if (*data==NULL) { /* feature not yet implemented */ // return ERR_ALLOC; //} if ( next_start_code(data,data_size,me->fd) == -1) { close(me->fd); return ERR_EOF; } read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; if (s->final_byte == 0xba) { read_pack_head(data,data_size,me->fd,&s->final_byte,&s->scr); } if (s->final_byte >= 0xbc) { if (s->final_byte == 0xc0) { audio_flag = 1; } read_packet_head(data,data_size,me->fd,&s->final_byte,&time_set,&s->pts,&s->dts,&dts_present,&s->pts_audio); if (s->new_dts != 1){ s->new_dts = dts_present; } if ( (!s->offset_flag) && (s->pts.pts!=0) ) { s->offset=s->pts.pts; s->offset_flag=1; } } if (num_bytes != 0) { time_set=0; while ( ((*data_size <= num_bytes) && (*recallme == 1)) || (!packet_done) ) { count = read_packet(data,data_size,me->fd,&s->final_byte); if (!packet_done) { not_remove = 1; } else { not_remove = 0; } packet_done = 1; next_start_code(data,data_size,me->fd); read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; if ( (s->final_byte < 0xbc) && (*data_size <= num_bytes) ) { *recallme = 0; flag = 0; // next packet coudn't stay in the same rtp packet } } if (flag && !not_remove) { count+=4; lseek(me->fd,-count,SEEK_CUR); *data_size-=count; not_remove = 0; } else { lseek(me->fd,-4,SEEK_CUR); *data_size-=4; } s->data_total+=*data_size; clock = (me->description).clock_rate; if (!audio_flag){ *mtime = ((float)(s->pts.pts-s->offset)*1000)/(float)clock; } else { *mtime = ((float)(s->pts_audio.pts-s->offset)*1000)/(float)clock; } count=0; do { /* finds next packet */ count1=next_start_code(data,data_size,me->fd); count+=count1; count+=3; read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; count+=1; } while ((s->final_byte < 0xbc) && (s->final_byte != 0xb9) ); if (s->final_byte == 0xb9) { s->data_total+=4; } else { count1=read_packet_head(data,data_size,me->fd,&s->final_byte,&time_set,&s->next_pts,&s->next_dts,&dts_present,&s->pts_audio); /* reads next packet head */ count += count1; *data_size-=count; if ( (s->pts.pts == s->next_pts.pts) || (s->final_byte == 0xbe) || (s->final_byte == 0xc0) || (s->offset==0)) { *recallme=1; } else { if (!dts_present){ /* dts_present now is referring to the next packet */ if (!s->new_dts){ pts_diff = s->next_pts.pts - s->pts.pts; } else { pts_diff = s->next_pts.pts - s->dts.pts; } } else { pts_diff = s->next_dts.pts - s->pts.pts; } pkt_len = (((float)pts_diff*1000)/(float)clock); changePacketLength(pkt_len,me); *recallme=0; s->new_dts = 0; } /* compute the delta_mtime */ me->description.delta_mtime = (s->next_pts.pts - s->pts.pts)*1000/(float)clock; *mtime=(s->scr.scr*1000)/(double)me->description.clock_rate; /* adjust SRC value to be passed as argument to the msec2tick and do not */ } *marker=!(*recallme); return ERR_NOERROR; } else { read_packet(data,data_size,me->fd,&s->final_byte); s->data_total+=*data_size; clock = (me->description).clock_rate; if (!audio_flag){ *mtime = ((float)(s->pts.pts-s->offset)*1000)/(float)clock; } else { *mtime = ((float)(s->pts_audio.pts-s->offset)*1000)/(float)clock; } count=0; time_set=0; do { count1=next_start_code(data,data_size,me->fd); count+=count1; count+=3; read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; count+=1; } while ((s->final_byte < 0xbc) && (s->final_byte != 0xb9) ); if (s->final_byte == 0xb9) { s->data_total+=4; } else { count1=read_packet_head(data,data_size,me->fd,&s->final_byte,&time_set,&s->next_pts,&s->next_dts,&dts_present,&s->pts_audio); count += count1; *data_size-=count; if ( (s->pts.pts == s->next_pts.pts) || (s->final_byte == 0xbe) || (s->final_byte == 0xc0) || (s->offset==0)) { *recallme=1; } else { if (!dts_present){ /* dts_present now is referring to the next packet */ if (!s->new_dts){ pts_diff = s->next_pts.pts - s->pts.pts; } else { pts_diff = s->next_pts.pts - s->dts.pts; } } else { pts_diff = s->next_dts.pts - s->pts.pts; } pkt_len = (((float)pts_diff*1000)/(float)clock); changePacketLength(pkt_len,me); *recallme=0; s->new_dts = 0; } /* compute the delta_mtime */ me->description.delta_mtime = (s->next_pts.pts - s->pts.pts)*1000/(float)clock; *mtime=(s->scr.scr*1000)/(double)me->description.clock_rate; /* adjust SRC value to be passed as argument to the msec2tick and do not */ } *marker=!(*recallme); return ERR_NOERROR; } }