diff options
Diffstat (limited to 'gst/mpeg1sys/systems.c')
-rw-r--r-- | gst/mpeg1sys/systems.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/gst/mpeg1sys/systems.c b/gst/mpeg1sys/systems.c new file mode 100644 index 00000000..d0b3388a --- /dev/null +++ b/gst/mpeg1sys/systems.c @@ -0,0 +1,290 @@ +#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); + bcopy (pack->buf, index, 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; + + bcopy (sys_header->buf, index, 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); + } + +} |