aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/mpeg.c
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2003-12-16 14:00:18 +0000
committerFabrice Bellard <fabrice@bellard.org>2003-12-16 14:00:18 +0000
commit044007c220ddda46e33432fc0501c1c244caa6fb (patch)
tree0b0e05e6cd5a98e4b59bf361754f43fd11172872 /libavformat/mpeg.c
parent0dbb48d91e9e97c7eb11f4ebc03c4ff4b6f5b692 (diff)
downloadffmpeg-044007c220ddda46e33432fc0501c1c244caa6fb.tar.gz
primitive LPCM generator
Originally committed as revision 2622 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mpeg.c')
-rw-r--r--libavformat/mpeg.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index b4161f3524..873b8e5dad 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -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 */