For all I know, iOS 4.3 doesn't support AMR frames to play it with AudioQueue output. I receive AVPacket instance from RTSP server as AMR frame. I'm trying to make two methods to decode AMR into raw buffer and then encode it into AAC. I've found example code of using LIBAV to perform this operation but faced with problem. There are my methods:
- (void) decodeAudioPacketToRaw:(AVPacket) inPacket
{
AVCodec *codec;
AVCodecContext *c= NULL;
int out_size, size, len;
uint8_t *outbuf;
codec = avcodec_find_decoder(CODEC_ID_AMR_NB);
if (!codec) {
fprintf(stderr, "input codec not found\n");
return;
}
c= avcodec_alloc_context();
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open input codec\n");
return;
}
outbuf = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
size = inPacket.size;
NSLog(@"Input packet size is %i", size);
while (size > 0) {
len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &inPacket);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
return;
}
NSLog(@"Decoded len in %i", len);
NSLog(@"Decoded out size in %i", out_size);
if (out_size > 0) {
[self encodeAudioBuffer:(const short *)outbuf withSize:out_size];
}
size -= len;
inPacket.data += len;
}
}
And encode:
- (void) encodeAudioBuffer:(const short *) in_buffer withSize:(unsigned int) in_buf_byte_size
{
AVCodec * codec;
AVCodecContext * c= NULL;
int count, out_size, outbuf_size, frame_byte_size;
uint8_t * outbuf;
printf("Audio encoding\n");
codec = avcodec_find_encoder(CODEC_ID_AAC);
if (!codec) {
fprintf(stderr, "output codec not found\n");
return;
}
c= avcodec_alloc_context();
c->bit_rate = 32000;
c->sample_rate = 12000;
c->channels = 1;
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open output codec\n");
return;
}
frame_byte_size=c->frame_size * 2; // NOT SURE
count = in_buf_byte_size / frame_byte_size;
fprintf(stderr, "Number of frames: %d\n", count);
outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
outbuf = (uint8_t*) malloc(outbuf_size);
for(int i = 0; i < count; i++) {
out_size = avcodec_encode_audio(c, outbuf, outbuf_size, &in_buffer[frame_byte_size*i]);
// DO SOMETHING WITH BUFFER fwrite(outbuf, 1, out_size, f);
fprintf(stderr, "bits_frame: %d\n", c->frame_bits);
}
free(outbuf);
avcodec_close(c);
av_free(c);
}
In fact, it decodes input packet and I can see raw buffer and its size (input size = 64 and output = 640, len = 16). I'm not sure if it is correct. Now encoding. This string frame_byte_size=c->frame_size * 2; returns 2048 bytes that is biggest than 640, thus, it can't perform encoding at all. If I remove FOR loop and will try to perform encoding directly then it returns 0 in line out_size = avcodec_encode_audio(c, outbuf, outbuf_size, &in_buffer[frame_byte_size*i]);
Maybe somebody faced with such task and could help me or know some links to exmaples?
Thanks.