Mercurial > libavcodec.hg
comparison mp3lameaudio.c @ 1913:486236d25f89 libavcodec
split stream into valid mp3 frames, at least flv & nut absolutely need this, but probably most other formats too
author | michael |
---|---|
date | Thu, 01 Apr 2004 17:07:06 +0000 |
parents | 9457292b0b65 |
children | 81a1a5be13aa |
comparison
equal
deleted
inserted
replaced
1912:351e996f29d9 | 1913:486236d25f89 |
---|---|
24 | 24 |
25 #include "avcodec.h" | 25 #include "avcodec.h" |
26 #include "mpegaudio.h" | 26 #include "mpegaudio.h" |
27 #include <lame/lame.h> | 27 #include <lame/lame.h> |
28 | 28 |
29 #define BUFFER_SIZE (2*MPA_FRAME_SIZE) | |
29 typedef struct Mp3AudioContext { | 30 typedef struct Mp3AudioContext { |
30 lame_global_flags *gfp; | 31 lame_global_flags *gfp; |
31 int stereo; | 32 int stereo; |
33 uint8_t buffer[BUFFER_SIZE]; | |
34 int buffer_index; | |
32 } Mp3AudioContext; | 35 } Mp3AudioContext; |
33 | |
34 | 36 |
35 static int MP3lame_encode_init(AVCodecContext *avctx) | 37 static int MP3lame_encode_init(AVCodecContext *avctx) |
36 { | 38 { |
37 Mp3AudioContext *s = avctx->priv_data; | 39 Mp3AudioContext *s = avctx->priv_data; |
38 | 40 |
66 lame_close(s->gfp); | 68 lame_close(s->gfp); |
67 err: | 69 err: |
68 return -1; | 70 return -1; |
69 } | 71 } |
70 | 72 |
73 static const int sSampleRates[3] = { | |
74 44100, 48000, 32000 | |
75 }; | |
76 | |
77 static const int sBitRates[2][3][15] = { | |
78 { { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448}, | |
79 { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384}, | |
80 { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320} | |
81 }, | |
82 { { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256}, | |
83 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, | |
84 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160} | |
85 }, | |
86 }; | |
87 | |
88 static const int sSamplesPerFrame[2][3] = | |
89 { | |
90 { 384, 1152, 1152 }, | |
91 { 384, 1152, 576 } | |
92 }; | |
93 | |
94 static const int sBitsPerSlot[3] = { | |
95 32, | |
96 8, | |
97 8 | |
98 }; | |
99 | |
100 static int mp3len(void *data, int *samplesPerFrame, int *sampleRate) | |
101 { | |
102 uint8_t *dataTmp = (uint8_t *)data; | |
103 uint32_t header = ( (uint32_t)dataTmp[0] << 24 ) | ( (uint32_t)dataTmp[1] << 16 ) | ( (uint32_t)dataTmp[2] << 8 ) | (uint32_t)dataTmp[3]; | |
104 int layerID = 3 - ((header >> 17) & 0x03); | |
105 int bitRateID = ((header >> 12) & 0x0f); | |
106 int sampleRateID = ((header >> 10) & 0x03); | |
107 int bitsPerSlot = sBitsPerSlot[layerID]; | |
108 int isPadded = ((header >> 9) & 0x01); | |
109 static int const mode_tab[4]= {2,3,1,0}; | |
110 int mode= mode_tab[(header >> 19) & 0x03]; | |
111 int mpeg_id= mode>0; | |
112 int temp0, temp1, bitRate; | |
113 | |
114 if ( (( header >> 21 ) & 0x7ff) != 0x7ff || mode == 3 || layerID==3 || sampleRateID==3) { | |
115 return -1; | |
116 } | |
117 | |
118 if(!samplesPerFrame) samplesPerFrame= &temp0; | |
119 if(!sampleRate ) sampleRate = &temp1; | |
120 | |
121 // *isMono = ((header >> 6) & 0x03) == 0x03; | |
122 | |
123 *sampleRate = sSampleRates[sampleRateID]>>mode; | |
124 bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000; | |
125 *samplesPerFrame = sSamplesPerFrame[mpeg_id][layerID]; | |
126 //av_log(NULL, AV_LOG_DEBUG, "sr:%d br:%d spf:%d l:%d m:%d\n", *sampleRate, bitRate, *samplesPerFrame, layerID, mode); | |
127 | |
128 return *samplesPerFrame * bitRate / (bitsPerSlot * *sampleRate) + isPadded; | |
129 } | |
130 | |
71 int MP3lame_encode_frame(AVCodecContext *avctx, | 131 int MP3lame_encode_frame(AVCodecContext *avctx, |
72 unsigned char *frame, int buf_size, void *data) | 132 unsigned char *frame, int buf_size, void *data) |
73 { | 133 { |
74 Mp3AudioContext *s = avctx->priv_data; | 134 Mp3AudioContext *s = avctx->priv_data; |
75 int num, i; | 135 int len, i; |
76 //av_log(avctx, AV_LOG_DEBUG, "%X %d %X\n", (int)frame, buf_size, (int)data); | |
77 // if(data==NULL) | |
78 // return lame_encode_flush(s->gfp, frame, buf_size); | |
79 | 136 |
80 /* lame 3.91 dies on '1-channel interleaved' data */ | 137 /* lame 3.91 dies on '1-channel interleaved' data */ |
81 if (s->stereo) { | 138 if (s->stereo) { |
82 num = lame_encode_buffer_interleaved(s->gfp, data, | 139 s->buffer_index += lame_encode_buffer_interleaved( |
83 MPA_FRAME_SIZE, frame, buf_size); | 140 s->gfp, |
141 data, | |
142 MPA_FRAME_SIZE, | |
143 s->buffer + s->buffer_index, | |
144 BUFFER_SIZE - s->buffer_index | |
145 ); | |
84 } else { | 146 } else { |
85 num = lame_encode_buffer(s->gfp, data, data, MPA_FRAME_SIZE, | 147 s->buffer_index += lame_encode_buffer( |
86 frame, buf_size); | 148 s->gfp, |
149 data, | |
150 data, | |
151 MPA_FRAME_SIZE, | |
152 s->buffer + s->buffer_index, | |
153 BUFFER_SIZE - s->buffer_index | |
154 ); | |
155 } | |
156 if(s->buffer_index<4) | |
157 return 0; | |
87 | 158 |
88 /*av_log(avctx, AV_LOG_DEBUG, "in:%d out:%d\n", MPA_FRAME_SIZE, num); | 159 len= mp3len(s->buffer, NULL, NULL); |
89 for(i=0; i<num; i++){ | 160 //av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", MPA_FRAME_SIZE, len, s->buffer_index); |
161 if(len <= s->buffer_index){ | |
162 memcpy(frame, s->buffer, len); | |
163 s->buffer_index -= len; | |
164 | |
165 memmove(s->buffer, s->buffer+len, s->buffer_index); | |
166 //FIXME fix the audio codec API, so we dont need the memcpy() | |
167 //FIXME fix the audio codec API, so we can output multiple packets if we have them | |
168 /*for(i=0; i<len; i++){ | |
90 av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]); | 169 av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]); |
91 }*/ | 170 }*/ |
92 } | 171 return len; |
93 | 172 }else |
94 return num; | 173 return 0; |
95 } | 174 } |
96 | 175 |
97 int MP3lame_encode_close(AVCodecContext *avctx) | 176 int MP3lame_encode_close(AVCodecContext *avctx) |
98 { | 177 { |
99 Mp3AudioContext *s = avctx->priv_data; | 178 Mp3AudioContext *s = avctx->priv_data; |