primitive LPCM generator

Originally committed as revision 2622 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Fabrice Bellard 2003-12-16 14:00:18 +00:00
parent 0dbb48d91e
commit 044007c220
1 changed files with 47 additions and 7 deletions

View File

@ -31,6 +31,8 @@ typedef struct {
int packet_number;
int64_t start_pts;
int64_t start_dts;
uint8_t lpcm_header[3];
int lpcm_align;
} StreamInfo;
typedef struct {
@ -66,12 +68,16 @@ typedef struct {
#define AUDIO_ID 0xc0
#define VIDEO_ID 0xe0
#define AC3_ID 0x80
#define LPCM_ID 0xa0
#ifdef CONFIG_ENCODERS
extern AVOutputFormat mpeg1system_mux;
extern AVOutputFormat mpeg1vcd_mux;
extern AVOutputFormat mpeg2vob_mux;
static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
static int put_pack_header(AVFormatContext *ctx,
uint8_t *buf, int64_t timestamp)
{
@ -190,7 +196,7 @@ static int get_system_header_size(AVFormatContext *ctx)
static int mpeg_mux_init(AVFormatContext *ctx)
{
MpegMuxContext *s = ctx->priv_data;
int bitrate, i, mpa_id, mpv_id, ac3_id;
int bitrate, i, mpa_id, mpv_id, ac3_id, lpcm_id, j;
AVStream *st;
StreamInfo *stream;
@ -206,8 +212,9 @@ static int mpeg_mux_init(AVFormatContext *ctx)
s->audio_bound = 0;
s->video_bound = 0;
mpa_id = AUDIO_ID;
ac3_id = 0x80;
ac3_id = AC3_ID;
mpv_id = VIDEO_ID;
lpcm_id = LPCM_ID;
s->scr_stream_index = -1;
for(i=0;i<ctx->nb_streams;i++) {
st = ctx->streams[i];
@ -218,10 +225,25 @@ static int mpeg_mux_init(AVFormatContext *ctx)
switch(st->codec.codec_type) {
case CODEC_TYPE_AUDIO:
if (st->codec.codec_id == CODEC_ID_AC3)
if (st->codec.codec_id == CODEC_ID_AC3) {
stream->id = ac3_id++;
else
} else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) {
stream->id = lpcm_id++;
for(j = 0; j < 4; j++) {
if (lpcm_freq_tab[j] == st->codec.sample_rate)
break;
}
if (j == 4)
goto fail;
if (st->codec.channels > 8)
return -1;
stream->lpcm_header[0] = 0x0c;
stream->lpcm_header[1] = (st->codec.channels - 1) | (j << 4);
stream->lpcm_header[2] = 0x80;
stream->lpcm_align = st->codec.channels * 2;
} else {
stream->id = mpa_id++;
}
stream->max_buffer_size = 4 * 1024;
s->audio_bound++;
break;
@ -335,8 +357,17 @@ static int get_packet_payload_size(AVFormatContext *ctx, int stream_index,
stream = ctx->streams[stream_index]->priv_data;
if (stream->id < 0xc0) {
/* AC3 private data header */
/* AC3/LPCM private data header */
buf_index += 4;
if (stream->id >= 0xa0) {
int n;
buf_index += 3;
/* NOTE: we round the payload size to an integer number of
LPCM samples */
n = (s->packet_size - buf_index) % stream->lpcm_align;
if (n)
buf_index += (stream->lpcm_align - n);
}
}
return s->packet_size - buf_index;
}
@ -393,6 +424,8 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
if (id < 0xc0) {
startcode = PRIVATE_STREAM_1;
payload_size -= 4;
if (id >= 0xa0)
payload_size -= 3;
} else {
startcode = 0x100 + id;
}
@ -440,7 +473,15 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
if (startcode == PRIVATE_STREAM_1) {
put_byte(&ctx->pb, id);
if (id >= 0x80 && id <= 0xbf) {
if (id >= 0xa0) {
/* LPCM (XXX: check nb_frames) */
put_byte(&ctx->pb, 7);
put_be16(&ctx->pb, 4); /* skip 3 header bytes */
put_byte(&ctx->pb, stream->lpcm_header[0]);
put_byte(&ctx->pb, stream->lpcm_header[1]);
put_byte(&ctx->pb, stream->lpcm_header[2]);
} else {
/* AC3 */
put_byte(&ctx->pb, stream->nb_frames);
put_be16(&ctx->pb, stream->frame_start_offset);
}
@ -867,7 +908,6 @@ static int mpegps_read_packet(AVFormatContext *s,
found:
if (startcode >= 0xa0 && startcode <= 0xbf) {
int b1, freq;
static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
/* for LPCM, we just skip the header and consider it is raw
audio data */