| #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); |
| } |
| |
| } |