#ifdef HAVE_CONFIG_H #include "config.h" #endif #include <string.h> #include "main.h" static void buffer_timecode (timecode, marker, buffer) guint64 timecode; unsigned char marker; unsigned char **buffer; { unsigned char temp; temp = (marker << 4) | ((timecode >> 29) & 0x38) | ((timecode >> 29) & 0x6) | 1; *((*buffer)++) = temp; temp = (timecode & 0x3fc00000) >> 22; *((*buffer)++) = temp; temp = ((timecode & 0x003f8000) >> 14) | 1; *((*buffer)++) = temp; temp = (timecode & 0x7f80) >> 7; *((*buffer)++) = temp; temp = ((timecode & 0x007f) << 1) | 1; *((*buffer)++) = temp; } /************************************************************************* creates a complete sector. Also copies Pack and Sys_Header informations into the sector buffer, then reads a packet full of data from the input stream into the sector buffer. *************************************************************************/ void create_sector (sector, pack, sys_header, packet_size, inputbuffer, type, buffer_scale, buffer_size, buffers, PTS, DTS, timestamps, which_streams) Sector_struc *sector; Pack_struc *pack; Sys_header_struc *sys_header; unsigned int packet_size; unsigned char *inputbuffer; unsigned char type; unsigned char buffer_scale; unsigned int buffer_size; unsigned char buffers; guint64 PTS; guint64 DTS; unsigned char timestamps; unsigned int which_streams; { int i, j, tmp; unsigned char *index; unsigned char *size_offset; /* printf("creating sector\n"); */ index = sector->buf; sector->length_of_sector = 0; /* Should we copy Pack Header information ? */ if (pack != NULL) { i = sizeof (pack->buf); memcpy (index, pack->buf, i); index += i; sector->length_of_sector += i; } /* Should we copy System Header information ? */ if (sys_header != NULL) { i = sizeof (sys_header->buf); /* only one stream? 3 bytes less in sys header */ if (which_streams != STREAMS_BOTH) i -= 3; memcpy (index, sys_header->buf, i); index += i; sector->length_of_sector += i; } /* write constant packet header data */ *(index++) = (unsigned char) (PACKET_START) >> 16; *(index++) = (unsigned char) (PACKET_START & 0x00ffff) >> 8; *(index++) = (unsigned char) (PACKET_START & 0x0000ff); *(index++) = type; /* we remember this offset in case we will have to shrink this packet */ size_offset = index; *(index++) = (unsigned char) ((packet_size - PACKET_HEADER_SIZE) >> 8); *(index++) = (unsigned char) ((packet_size - PACKET_HEADER_SIZE) & 0xff); *(index++) = STUFFING_BYTE; *(index++) = STUFFING_BYTE; *(index++) = STUFFING_BYTE; i = 0; if (!buffers) i += 2; if (timestamps == TIMESTAMPS_NO) i += 9; else if (timestamps == TIMESTAMPS_PTS) i += 5; /* printf("%i stuffing %d\n", i, timestamps); */ for (j = 0; j < i; j++) *(index++) = STUFFING_BYTE; /* should we write buffer info ? */ if (buffers) { *(index++) = (unsigned char) (0x40 | (buffer_scale << 5) | (buffer_size >> 8)); *(index++) = (unsigned char) (buffer_size & 0xff); } /* should we write PTS, PTS & DTS or nothing at all ? */ switch (timestamps) { case TIMESTAMPS_NO: *(index++) = MARKER_NO_TIMESTAMPS; break; case TIMESTAMPS_PTS: buffer_timecode (PTS, MARKER_JUST_PTS, &index); sector->TS = PTS; break; case TIMESTAMPS_PTS_DTS: buffer_timecode (PTS, MARKER_PTS, &index); buffer_timecode (DTS, MARKER_DTS, &index); sector->TS = DTS; break; } /* read in packet data */ i = (packet_size - PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH); if (type == PADDING_STR) { for (j = 0; j < i; j++) *(index++) = (unsigned char) STUFFING_BYTE; tmp = i; } else { /*tmp = fread (index, sizeof (unsigned char), i, inputstream); */ memcpy (index, inputbuffer, i); tmp = i; index += tmp; /* if we did not get enough data bytes, shorten the Packet length */ if (tmp != i) { packet_size -= (i - tmp); *(size_offset++) = (unsigned char) ((packet_size - PACKET_HEADER_SIZE) >> 8); *(size_offset++) = (unsigned char) ((packet_size - PACKET_HEADER_SIZE) & 0xff); /* zero byte stuffing in the last Packet of a stream */ /* we don't need this any more, since we shortenend the packet */ /* for (j=tmp; j<i; j++) */ /* *(index++)=(unsigned char) ZERO_STUFFING_BYTE; */ } } /* write other struct data */ sector->length_of_sector += packet_size; sector->length_of_packet_data = tmp; } /************************************************************************* writes specifical pack header information into a buffer later this will be copied from the sector routine into the sector buffer *************************************************************************/ void create_pack (pack, SCR, mux_rate) Pack_struc *pack; unsigned int mux_rate; guint64 SCR; { unsigned char *index; index = pack->buf; *(index++) = (unsigned char) ((PACK_START) >> 24); *(index++) = (unsigned char) ((PACK_START & 0x00ff0000) >> 16); *(index++) = (unsigned char) ((PACK_START & 0x0000ff00) >> 8); *(index++) = (unsigned char) (PACK_START & 0x000000ff); buffer_timecode (SCR, MARKER_SCR, &index); *(index++) = (unsigned char) (0x80 | (mux_rate >> 15)); *(index++) = (unsigned char) (0xff & (mux_rate >> 7)); *(index++) = (unsigned char) (0x01 | ((mux_rate & 0x7f) << 1)); pack->SCR = SCR; } /************************************************************************* writes specifical system header information into a buffer later this will be copied from the sector routine into the sector buffer *************************************************************************/ void create_sys_header (sys_header, rate_bound, audio_bound, fixed, CSPS, audio_lock, video_lock, video_bound, stream1, buffer1_scale, buffer1_size, stream2, buffer2_scale, buffer2_size, which_streams) Sys_header_struc *sys_header; unsigned int rate_bound; unsigned char audio_bound; unsigned char fixed; unsigned char CSPS; unsigned char audio_lock; unsigned char video_lock; unsigned char video_bound; unsigned char stream1; unsigned char buffer1_scale; unsigned int buffer1_size; unsigned char stream2; unsigned char buffer2_scale; unsigned int buffer2_size; unsigned int which_streams; { unsigned char *index; index = sys_header->buf; /* if we are not using both streams, we should clear some options here */ if (!(which_streams & STREAMS_AUDIO)) audio_bound = 0; if (!(which_streams & STREAMS_VIDEO)) video_bound = 0; *(index++) = (unsigned char) ((SYS_HEADER_START) >> 24); *(index++) = (unsigned char) ((SYS_HEADER_START & 0x00ff0000) >> 16); *(index++) = (unsigned char) ((SYS_HEADER_START & 0x0000ff00) >> 8); *(index++) = (unsigned char) (SYS_HEADER_START & 0x000000ff); if (which_streams == STREAMS_BOTH) { *(index++) = (unsigned char) (SYS_HEADER_LENGTH >> 8); *(index++) = (unsigned char) (SYS_HEADER_LENGTH & 0xff); } else { *(index++) = (unsigned char) ((SYS_HEADER_LENGTH - 3) >> 8); *(index++) = (unsigned char) ((SYS_HEADER_LENGTH - 3) & 0xff); } *(index++) = (unsigned char) (0x80 | (rate_bound >> 15)); *(index++) = (unsigned char) (0xff & (rate_bound >> 7)); *(index++) = (unsigned char) (0x01 | ((rate_bound & 0x7f) << 1)); *(index++) = (unsigned char) ((audio_bound << 2) | (fixed << 1) | CSPS); *(index++) = (unsigned char) ((audio_lock << 7) | (video_lock << 6) | 0x20 | video_bound); *(index++) = (unsigned char) RESERVED_BYTE; if (which_streams & STREAMS_AUDIO) { *(index++) = stream1; *(index++) = (unsigned char) (0xc0 | (buffer1_scale << 5) | (buffer1_size >> 8)); *(index++) = (unsigned char) (buffer1_size & 0xff); } if (which_streams & STREAMS_VIDEO) { *(index++) = stream2; *(index++) = (unsigned char) (0xc0 | (buffer2_scale << 5) | (buffer2_size >> 8)); *(index++) = (unsigned char) (buffer2_size & 0xff); } }