📄 inptstrm.cpp
字号:
char *video_file, char *video_units, Video_struc *video_info, double *startup_delay, unsigned int *video_total, unsigned int length){ FILE* info_file; double prev_offset=0.0; double pict_offset, hdr_offset, mb_offset, ud_offset, tmp_offset; Vaunit_struc access_unit; unsigned long syncword, max_bits_in_sec, frame_count, f_rate; unsigned long decoding_order=0; unsigned long group_order=0; unsigned long temporal_reference; unsigned int picture_type; double secs_per_frame, secs_per_one_field, secs_per_three_fields; unsigned short pict_rate; double DTS, PTS; int i, firstField, pulldown_flag; unsigned int retval, video_count, frame_num; int percent, oldPercent; char tmpStr[80]; int exiterror, mpeg2flag, seq_header_found = 0, gop_header_found = 0; bitstream bs; exiterror = TRUE; video_count = 0; oldPercent = -1; max_bits_in_sec = 0; mb_offset = 0.0; ud_offset = -1.0; hdr_offset = -1.0; if (!scan_video(video_file, video_info)) return FALSE; pulldown_flag = mplex_pulldown_flag; if ((mplex_type > MPEG_VCD) && (mplex_pulldown_flag == PULLDOWN_AUTO)) pulldown_flag = video_info->pulldown; DisplayInfo(" "); DisplayInfo(" Scanning video stream for pictures ..."); info_file = fopen(video_units, "wb"); if (info_file == NULL) { sprintf(tmpStr, "Unable to create temporary video units file %s: %s.", video_units, strerrno()); DisplayError(tmpStr); return FALSE; } if (!init_getbits(&bs, video_file)) goto exit2; if (!getbits(&bs, &retval, 32)) goto exit2; if (retval==SEQUENCE_HEADER) { hdr_offset = bitcount(&bs) - 32.0; /* remember position of sequence_header */ seq_header_found = 1; video_info->num_sequence++; if (!getbits(&bs, &retval, 12)) goto exit2; video_info->horizontal_size = retval; if (!getbits(&bs, &retval, 12)) goto exit2; video_info->vertical_size = retval; if (!getbits(&bs, &retval, 4)) goto exit2; video_info->aspect_ratio = retval; if (!getbits(&bs, &retval, 4)) goto exit2; pict_rate = retval; video_info->picture_rate = pict_rate; if (!getbits(&bs, &retval, 18)) goto exit2; video_info->bit_rate = retval; if (!marker_bit(&bs, 1)) goto exit2; if (!getbits(&bs, &retval, 10)) goto exit2; video_info->vbv_buffer_size = retval; if (!get1bit(&bs, &retval)) goto exit2; video_info->CSPF = retval; } else { DisplayError("Invalid MPEG Video stream header."); goto exit2; } empty_vaunit_struc (&access_unit); *startup_delay = 2 * MAX_FFFFFFFF; if (pict_rate > 0 && pict_rate < 9) { f_rate = (unsigned int)ceil(picture_rates[pict_rate]); secs_per_frame = 1.0 / picture_rates[pict_rate]; } else { f_rate = 25; secs_per_frame = 1.0 / 25.0; /* invalid pict_rate info */ } if (f_rate == 30 && ((pulldown_flag == PULLDOWN_32) || (pulldown_flag == PULLDOWN_23))) f_rate = 24; secs_per_one_field = secs_per_frame / 2.0; secs_per_three_fields = secs_per_frame + secs_per_one_field; frame_count = f_rate + 1; mpeg2flag = FALSE; firstField = 0; do { if (AbortMPEG) break; percent = (int)floor(((bitcount(&bs) / 8.0)) / ((double) length) * 100.0); if (percent != oldPercent) { sprintf(tmpStr, "Scanning video stream: %d%% - byte offset %.0f of %d.", percent, bitcount(&bs) / 8.0, length); DisplayProgress(tmpStr, percent); oldPercent = percent; } if (seek_sync(&bs, SYNCWORD_START, 24)) { if (!getbits(&bs, &retval, 8)) goto exit2; syncword = (SYNCWORD_START << 8) + retval; switch (syncword) { case SEQUENCE_HEADER: video_info->num_sequence++; hdr_offset = bitcount(&bs) - 32.0; /* remember position of sequence_header */ seq_header_found = 1; break; case EXT_START_CODE: mpeg2flag = TRUE; break; case GROUP_START: video_info->num_groups++; group_order = 0; if (hdr_offset < 0) hdr_offset = bitcount(&bs) - 32.0; /* remember position of GOP header */ gop_header_found = 1; break; case PICTURE_START: /* just in case this is the second field of a frame */ tmp_offset = bitcount(&bs) - 32.0; if (!getbits(&bs, &retval, 10)) goto exit2; temporal_reference = retval; if (!getbits(&bs, &retval, 3)) goto exit2; picture_type = retval; if (mpeg2flag) { if (!seek_sync(&bs, EXT_START_CODE, 32)) goto exit2; if (!getbits(&bs, &retval, 4)) goto exit2; if (retval != CODING_ID) { DisplayError("Invalid MPEG2 Video stream, no picture coding extension present."); goto exit2; } if (!getbits(&bs, &retval, 18)) goto exit2; if (!getbits(&bs, &retval, 2)) /* picture structure type */ goto exit2; if (retval != FRAME_PICTURE) { if (!firstField) firstField = retval; else if (firstField != (int)retval) break; /* second field, do not process */ } } pict_offset = tmp_offset; if (hdr_offset < 0) tmp_offset = pict_offset; else tmp_offset = hdr_offset; if (frame_count > f_rate) { if (tmp_offset - mb_offset > max_bits_in_sec) max_bits_in_sec = (uint)(tmp_offset - mb_offset); mb_offset = tmp_offset; frame_count = 0; } frame_count++; /* skip access unit number 0 */ if (access_unit.type != 0) { access_unit.length += (unsigned long) ceil((tmp_offset - prev_offset) / 8.0); prev_offset = tmp_offset; if (fwrite (&access_unit, sizeof (Vaunit_struc), 1, info_file) != 1) { sprintf(tmpStr, "Error writing to temporary video units file %s: %s.", video_units, strerrno()); DisplayError(tmpStr); goto exit2; } video_info->avg_frames[access_unit.type-1] += access_unit.length; } access_unit.svcd_offset = 0; access_unit.length = 0; if (mux_SVCD_scan_offsets && picture_type == IFRAME) { retval = 0xff; while ((retval != 0xb2) && (retval != 1)) { if (!seek_sync(&bs, SYNCWORD_START, 24)) goto exit2; if (!getbits(&bs, &retval, 8)) goto exit2; } if (retval == 1) ud_offset = bitcount(&bs) - 32.0; /* remember position for the scan offset */ else { if (!getbits(&bs, &retval, 16)) goto exit2; if (retval != 0x100E) ud_offset = bitcount(&bs) - 48.0; /* remember position for scan offset */ else ud_offset = -1.0; /* there is already a scan offset there */ } if (ud_offset > 0) { access_unit.svcd_offset = (unsigned long) ceil((ud_offset - tmp_offset) / 8.0); access_unit.length = 18; // size of an SVCD scan offset user data block } ud_offset = -1.0; } video_count++; access_unit.type = picture_type; if (hdr_offset >= 0) access_unit.pict_hdr_offset = (unsigned short int) ceil((pict_offset - hdr_offset) / 8.0); else access_unit.pict_hdr_offset = 0; access_unit.flags = 0; if (seq_header_found) access_unit.flags |= SEQHDR_FLAG; if (gop_header_found) access_unit.flags |= GOPHDR_FLAG; hdr_offset = -1; seq_header_found = 0; gop_header_found = 0; if ((pulldown_flag == PULLDOWN_NONE) || (pulldown_flag == PULLDOWN_AUTO)) { DTS = decoding_order * secs_per_frame*CLOCKS; PTS = (temporal_reference - group_order + 1 + decoding_order) * secs_per_frame*CLOCKS; if (!group_order) access_unit.first_frame_offset = temporal_reference * (int)(secs_per_frame * CLOCKS); else access_unit.first_frame_offset = 0; } else { DTS = (decoding_order / 2) * secs_per_frame + (decoding_order / 2) * secs_per_three_fields; if (decoding_order % 2) { if (pulldown_flag == PULLDOWN_32) DTS += secs_per_frame; else DTS += secs_per_three_fields; } if ((pulldown_flag == PULLDOWN_23) && decoding_order) DTS -= secs_per_one_field; DTS *= CLOCKS; PTS = secs_per_frame; frame_num = temporal_reference - group_order + decoding_order; PTS += (frame_num / 2) * secs_per_frame + (frame_num / 2) * secs_per_three_fields; if (frame_num % 2) { if (pulldown_flag == PULLDOWN_32) PTS += secs_per_three_fields; else PTS += secs_per_frame; } PTS *= CLOCKS; if (!group_order) { access_unit.first_frame_offset = (temporal_reference / 2) * (unsigned int)(secs_per_frame * CLOCKS) + (temporal_reference / 2) * (unsigned int)(secs_per_three_fields * CLOCKS); if (temporal_reference % 2) if (pulldown_flag == PULLDOWN_32) access_unit.first_frame_offset += (unsigned int)(secs_per_three_fields * CLOCKS); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -