From d1f62e8a4f976e11634d2f9187821e8686cec76d Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 27 Jul 2003 05:24:15 +0000 Subject: Moved to gst-libs/ext/mplex Original commit message from CVS: Moved to gst-libs/ext/mplex --- ext/mplex/videostrm_in.cc | 429 ---------------------------------------------- 1 file changed, 429 deletions(-) delete mode 100644 ext/mplex/videostrm_in.cc (limited to 'ext/mplex/videostrm_in.cc') diff --git a/ext/mplex/videostrm_in.cc b/ext/mplex/videostrm_in.cc deleted file mode 100644 index df9578a8..00000000 --- a/ext/mplex/videostrm_in.cc +++ /dev/null @@ -1,429 +0,0 @@ -/* - * inptstrm.c: Members of video stream class related to raw stream - * scanning and buffering. - * - * Copyright (C) 2001 Andrew Stevens - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include - -#include "videostrm.hh" -#include "outputstream.hh" - - - -static void -marker_bit (IBitStream & bs, unsigned int what) -{ - if (what != bs.get1bit ()) { - mjpeg_error ("Illegal MPEG stream at offset (bits) %d: supposed marker bit not found.", - (int)bs.bitcount ()); - exit (1); - } -} - - -void -VideoStream::ScanFirstSeqHeader () -{ - if (bs.getbits (32) == SEQUENCE_HEADER) { - num_sequence++; - horizontal_size = bs.getbits (12); - vertical_size = bs.getbits (12); - aspect_ratio = bs.getbits (4); - pict_rate = bs.getbits (4); - picture_rate = pict_rate; - bit_rate = bs.getbits (18); - marker_bit (bs, 1); - vbv_buffer_size = bs.getbits (10); - CSPF = bs.get1bit (); - - } else { - mjpeg_error ("Invalid MPEG Video stream header."); - exit (1); - } - - if (pict_rate > 0 && pict_rate <= mpeg_num_framerates) { - frame_rate = Y4M_RATIO_DBL (mpeg_framerate (pict_rate)); - } else { - frame_rate = 25.0; - } - -} - - - - -void -VideoStream::Init (const int stream_num) -{ - mjpeg_debug ("SETTING video buffer to %d", muxinto.video_buffer_size); - MuxStream::Init (VIDEO_STR_0 + stream_num, 1, // Buffer scale - muxinto.video_buffer_size, 0, // Zero stuffing - muxinto.buffers_in_video, muxinto.always_buffers_in_video); - mjpeg_info ("Scanning for header info: Video stream %02x ", VIDEO_STR_0 + stream_num); - InitAUbuffer (); - - ScanFirstSeqHeader (); - - /* Skip to the end of the 1st AU (*2nd* Picture start!) - */ - AU_hdr = SEQUENCE_HEADER; - AU_pict_data = 0; - AU_start = 0LL; - - OutputSeqhdrInfo (); -} - -// -// Set the Maximum STD buffer delay for this video stream. -// By default we set 1 second but if we have specified a video -// buffer that can hold more than 1.0 seconds demuxed data we -// set the delay to the time to fill the buffer. -// - -void -VideoStream::SetMaxStdBufferDelay (unsigned int dmux_rate) -{ - double max_delay = CLOCKS; - - if (static_cast < double >(BufferSize ()) / dmux_rate > 1.0) - max_delay *= static_cast < double >(BufferSize ()) / dmux_rate; - - // - // To enforce a maximum STD buffer residency the - // calculation is a bit tricky as when we decide to mux we may - // (but not always) have some of the *previous* picture left to - // mux in which case it is the timestamp of the next picture that counts. - // For simplicity we simply reduce the limit by 1.5 frame intervals - // and use the timestamp for the current picture. - // - if (frame_rate > 10.0) - max_STD_buffer_delay = static_cast < clockticks > (max_delay * (frame_rate - 1.5) / frame_rate); - else - max_STD_buffer_delay = static_cast < clockticks > (10.0 * max_delay / frame_rate); - -} - -// -// Return whether AU buffer needs refilling. There are two cases: -// 1. We have less than our look-ahead "FRAME_CHUNK" buffer AU's -// buffered 2. AU's are very small and we could have less than 1 -// sector's worth of data buffered. -// - -bool -VideoStream::AUBufferNeedsRefill () -{ - return - !eoscan - && (aunits.current () + FRAME_CHUNK > last_buffered_AU - || bs.buffered_bytes () < muxinto.sector_size); -} - -// -// Refill the AU unit buffer setting AU PTS DTS from the scanned -// header information... -// - -void -VideoStream::FillAUbuffer (unsigned int frames_to_buffer) -{ - if (eoscan) - return; - - last_buffered_AU += frames_to_buffer; - mjpeg_debug ("Scanning %d video frames to frame %d", frames_to_buffer, last_buffered_AU); - - // We set a limit of 2M to seek before we give up. - // This is intentionally very high because some heavily - // padded still frames may have a loooong gap before - // a following sequence end marker. - while (!bs.eos () && - bs.seek_sync (SYNCWORD_START, 24, 2 * 1024 * 1024) && - decoding_order < last_buffered_AU) - { - syncword = (SYNCWORD_START << 8) + bs.getbits (8); - if (AU_pict_data) { - - /* Handle the header *ending* an AU... - If we have the AU picture data an AU and have now - reached a header marking the end of an AU fill in the - the AU length and append it to the list of AU's and - start a new AU. I.e. sequence and gop headers count as - part of the AU of the corresponding picture - */ - stream_length = bs.bitcount () - 32LL; - switch (syncword) { - case SEQUENCE_HEADER: - case GROUP_START: - case PICTURE_START: - access_unit.start = AU_start; - access_unit.length = (int) (stream_length - AU_start) >> 3; - access_unit.end_seq = 0; - avg_frames[access_unit.type - 1] += access_unit.length; - aunits.append (access_unit); - mjpeg_debug ("Found AU %d: DTS=%d", access_unit.dorder, (int) access_unit.DTS / 300); - AU_hdr = syncword; - AU_start = stream_length; - AU_pict_data = 0; - break; - case SEQUENCE_END: - access_unit.length = ((stream_length - AU_start) >> 3) + 4; - access_unit.end_seq = 1; - aunits.append (access_unit); - mjpeg_info ("Scanned to end AU %d", access_unit.dorder); - avg_frames[access_unit.type - 1] += access_unit.length; - - /* Do we have a sequence split in the video stream? */ - if (!bs.eos () && bs.getbits (32) == SEQUENCE_HEADER) { - stream_length = bs.bitcount () - 32LL; - AU_start = stream_length; - syncword = AU_hdr = SEQUENCE_HEADER; - AU_pict_data = 0; - if (opt_multifile_segment) - mjpeg_warn - ("Sequence end marker found in video stream but single-segment splitting specified!"); - } else { - if (!bs.eos () && !opt_multifile_segment) - mjpeg_warn ("No seq. header starting new sequence after seq. end!"); - } - - num_seq_end++; - break; - } - } - - /* Handle the headers starting an AU... */ - switch (syncword) { - case SEQUENCE_HEADER: - /* TODO: Really we should update the info here so we can handle - streams where parameters change on-the-fly... */ - num_sequence++; - break; - - case GROUP_START: - num_groups++; - group_order = 0; - break; - - case PICTURE_START: - /* We have reached AU's picture data... */ - AU_pict_data = 1; - - prev_temp_ref = temporal_reference; - temporal_reference = bs.getbits (10); - access_unit.type = bs.getbits (3); - - /* Now scan forward a little for an MPEG-2 picture coding extension - so we can get pulldown info (if present) */ - if (bs.seek_sync (EXT_START_CODE, 32, 64) && bs.getbits (4) == CODING_EXT_ID) { - /* Skip: 4 F-codes (4)... */ - (void) bs.getbits (16); - /* Skip: DC Precision(2) */ - (void) bs.getbits (2); - pict_struct = bs.getbits (2); - /* Skip: topfirst (1) frame pred dct (1), - concealment_mv(1), q_scale_type (1), */ - (void) bs.getbits (4); - /* Skip: intra_vlc_format(1), alternate_scan (1) */ - (void) bs.getbits (2); - repeat_first_field = bs.getbits (1); - pulldown_32 |= repeat_first_field; - - } else { - repeat_first_field = 0; - pict_struct = PIC_FRAME; - } - - if (access_unit.type == IFRAME) { - unsigned int bits_persec = - (unsigned int) (((double) (stream_length - prev_offset)) * - 2 * frame_rate / ((double) (2 + fields_presented - group_start_field))); - - if (bits_persec > max_bits_persec) { - max_bits_persec = bits_persec; - } - prev_offset = stream_length; - group_start_pic = decoding_order; - group_start_field = fields_presented; - } - - NextDTSPTS (access_unit.DTS, access_unit.PTS); - - access_unit.dorder = decoding_order; - access_unit.porder = temporal_reference + group_start_pic; - access_unit.seq_header = (AU_hdr == SEQUENCE_HEADER); - - decoding_order++; - group_order++; - - if ((access_unit.type > 0) && (access_unit.type < 5)) { - num_frames[access_unit.type - 1]++; - } - - - if (decoding_order >= old_frames + 1000) { - mjpeg_debug ("Got %d picture headers.", decoding_order); - old_frames = decoding_order; - } - - break; - - - - } - } - last_buffered_AU = decoding_order; - num_pictures = decoding_order; - eoscan = bs.eos (); -} - -void -VideoStream::Close () -{ - - bs.close (); - stream_length = (unsigned int) (AU_start / 8); - for (int i = 0; i < 4; i++) { - avg_frames[i] /= num_frames[i] == 0 ? 1 : num_frames[i]; - } - - comp_bit_rate = (unsigned int) - ((((double) stream_length) / ((double) fields_presented)) * 2.0 - * ((double) frame_rate) + 25.0) / 50; - - /* Peak bit rate in 50B/sec units... */ - peak_bit_rate = ((max_bits_persec / 8) / 50); - mjpeg_info ("VIDEO_STATISTICS: %02x", stream_id); - mjpeg_info ("Video Stream length: %11u bytes", (int)stream_length / 8); - mjpeg_info ("Sequence headers: %8u", num_sequence); - mjpeg_info ("Sequence ends : %8u", num_seq_end); - mjpeg_info ("No. Pictures : %8u", num_pictures); - mjpeg_info ("No. Groups : %8u", num_groups); - mjpeg_info ("No. I Frames : %8u avg. size%6u bytes", num_frames[0], avg_frames[0]); - mjpeg_info ("No. P Frames : %8u avg. size%6u bytes", num_frames[1], avg_frames[1]); - mjpeg_info ("No. B Frames : %8u avg. size%6u bytes", num_frames[2], avg_frames[2]); - mjpeg_info ("No. D Frames : %8u avg. size%6u bytes", num_frames[3], avg_frames[3]); - mjpeg_info ("Average bit-rate : %8u bits/sec", comp_bit_rate * 400); - mjpeg_info ("Peak bit-rate : %8u bits/sec", peak_bit_rate * 400); - -} - - - - -/************************************************************************* - OutputSeqHdrInfo - Display sequence header parameters -*************************************************************************/ - -void -VideoStream::OutputSeqhdrInfo () -{ - const char *str; - - mjpeg_info ("VIDEO STREAM: %02x", stream_id); - - mjpeg_info ("Frame width : %u", horizontal_size); - mjpeg_info ("Frame height : %u", vertical_size); - if (aspect_ratio <= mpeg_num_aspect_ratios[opt_mpeg - 1]) - str = mpeg_aspect_code_definition (opt_mpeg, aspect_ratio); - else - str = "forbidden"; - mjpeg_info ("Aspect ratio : %s", str); - - - if (picture_rate == 0) - mjpeg_info ("Picture rate : forbidden"); - else if (picture_rate <= mpeg_num_framerates) - mjpeg_info ("Picture rate : %2.3f frames/sec", - Y4M_RATIO_DBL (mpeg_framerate (picture_rate))); - else - mjpeg_info ("Picture rate : %x reserved", picture_rate); - - if (bit_rate == 0x3ffff) { - bit_rate = 0; - mjpeg_info ("Bit rate : variable"); - } else if (bit_rate == 0) - mjpeg_info ("Bit rate : forbidden"); - else - mjpeg_info ("Bit rate : %u bits/sec", bit_rate * 400); - - mjpeg_info ("Vbv buffer size : %u bytes", vbv_buffer_size * 2048); - mjpeg_info ("CSPF : %u", CSPF); -} - -// -// Compute PTS DTS of current AU in the video sequence being -// scanned. This is is the PTS/DTS calculation for normal video only. -// It is virtual and over-ridden for non-standard streams (Stills -// etc!). -// - -void -VideoStream::NextDTSPTS (clockticks & DTS, clockticks & PTS) -{ - if (pict_struct != PIC_FRAME) { - DTS = static_cast < clockticks > (fields_presented * (double) (CLOCKS / 2) / frame_rate); - int dts_fields = temporal_reference * 2 + group_start_field + 1; - - if (temporal_reference == prev_temp_ref) - dts_fields += 1; - PTS = static_cast < clockticks > (dts_fields * (double) (CLOCKS / 2) / frame_rate); - access_unit.porder = temporal_reference + group_start_pic; - fields_presented += 1; - } else if (pulldown_32) { - int frames2field; - int frames3field; - - DTS = static_cast < clockticks > (fields_presented * (double) (CLOCKS / 2) / frame_rate); - if (repeat_first_field) { - frames2field = (temporal_reference + 1) / 2; - frames3field = temporal_reference / 2; - fields_presented += 3; - } else { - frames2field = (temporal_reference) / 2; - frames3field = (temporal_reference + 1) / 2; - fields_presented += 2; - } - PTS = static_cast < clockticks > - ((frames2field * 2 + frames3field * 3 + group_start_field + - 1) * (double) (CLOCKS / 2) / frame_rate); - access_unit.porder = temporal_reference + group_start_pic; - } else { - DTS = static_cast < clockticks > (decoding_order * (double) CLOCKS / frame_rate); - PTS = static_cast < clockticks > - ((temporal_reference + group_start_pic + 1) * (double) CLOCKS / frame_rate); - fields_presented += 2; - } - -} - - - - - -/* - * Local variables: - * c-file-style: "stroustrup" - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ -- cgit v1.2.1