www.pudn.com > avi 到 mpeg 的转换程序及源代码.zip > SYSTEMS.C
/*************************************************************************
* mplex - MPEG/SYSTEMS multiplexer *
* Copyright (C) 1994 1995 Christoph Moar *
* Siemens ZFE ST SN 11 / T SN 6 *
* *
* moar@informatik.tu-muenchen.de *
* (Christoph Moar) *
* klee@heaven.zfe.siemens.de *
* (Christian Kleegrewe, Siemens only requests) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
*************************************************************************/
/*
* 4/4/97 - John Schlichther
*
* extensively altered to create avi2mpg1 - avi to mpeg-1 encoder
*
* Since avi file, and the avi subsystem are platform dependant, cross
* platform compatibility removed, many optional features disabled or
* removed, code generally trimmed to a minimum.
*
*/
#include "mplex.h"
//
// bcopy
//
void bcopy(unsigned char *source, unsigned char *dest, int k)
{
unsigned char *from, *to;
from = source;
to = dest;
while(k!=0)
{
*to = *from;
to++;
from++;
k--;
}
}
/*************************************************************************
Create_Sector
erstellt einen gesamten Sektor.
Kopiert in dem Sektorbuffer auch die eventuell vorhandenen
Pack und Sys_Header Informationen und holt dann aus der
Inputstreamdatei einen Packet voll von Daten, die im
Sektorbuffer abgelegt werden.
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, inputstream, 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;
FILE *inputstream;
unsigned char type;
unsigned char buffer_scale;
unsigned int buffer_size;
unsigned char buffers;
Timecode_struc *PTS;
Timecode_struc *DTS;
unsigned char timestamps;
unsigned int which_streams;
{
int i,j,tmp;
unsigned char *index;
unsigned char *size_offset;
// FILE* file;
index = sector->buf;
sector->length_of_sector=0;
/* soll ein Pack Header mit auf dem Sektor gespeichert werden? */
/* 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;
}
/* soll ein System Header mit auf dem Sektor gespeichert werden? */
/* 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;
}
/* konstante Packet Headerwerte eintragen */
/* 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;
/* wir merken uns diese Position, falls sich an der Paketlaenge noch was tut */
/* 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;
for (j=0; j> 8));
*(index++) = (unsigned char) (buffer_size & 0xff);
}
/* PTS, PTS & DTS, oder gar nichts? */
/* 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);
copy_timecode (PTS, §or->TS);
break;
case TIMESTAMPS_PTS_DTS:
buffer_timecode (PTS, MARKER_PTS, &index);
buffer_timecode (DTS, MARKER_DTS, &index);
copy_timecode (DTS, §or->TS);
break;
}
/* Packet Daten eintragen */
/* read in packet data */
i = (packet_size - PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH);
if (type == PADDING_STR)
{
for (j=0; j>8);
*(size_offset++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)&0xff);
/* zero stuffing bytes beim letzten Packet eines Streams*/
/* braucht es seit Verkuerzung des Paketes nicht mehr */
/* 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; jlength_of_sector += packet_size;
sector->length_of_packet_data = tmp;
}
/*************************************************************************
Create_Pack
erstellt in einem Buffer die spezifischen Pack-Informationen.
Diese werden dann spaeter von der Sector-Routine nochmals
in dem Sektor kopiert.
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;
Timecode_struc *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));
copy_timecode (SCR,&pack->SCR);
}
/*************************************************************************
Create_Sys_Header
erstelle in einem Buffer die spezifischen Sys_Header
Informationen. Diese werden spaeter von der Sector-Routine
nochmals zum Sectorbuffer kopiert.
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);
}
}