Mercurial > libavformat.hg
changeset 336:d75fd4c6ab62 libavformat
primitive LPCM generator
author | bellard |
---|---|
date | Tue, 16 Dec 2003 14:00:18 +0000 |
parents | b0ac206f232d |
children | f6b2b0718235 |
files | mpeg.c |
diffstat | 1 files changed, 47 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/mpeg.c Tue Dec 16 11:25:30 2003 +0000 +++ b/mpeg.c Tue Dec 16 14:00:18 2003 +0000 @@ -31,6 +31,8 @@ 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 @@ #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 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 @@ 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 @@ 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 @@ 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 @@ if (id < 0xc0) { startcode = PRIVATE_STREAM_1; payload_size -= 4; + if (id >= 0xa0) + payload_size -= 3; } else { startcode = 0x100 + id; } @@ -440,7 +473,15 @@ 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 @@ 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 */