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;