ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 09.06.11 18:38
Оценка:
Приветствую,

Я на этом ресурсе новый человек, посему если что не так, поправьте пожалуйста.

Проблема в том, что папу Джобса как всегда сутра клюнул жаренный петух и теперь по какойто причине Apple убрали поддержку AudioQueue output поддержку для AMR кодека в iOS 4.3. В старых системах мое приложение замечательно так читало пакеты из RTSP и играло видео и аудио, теперь играет только видео. Я решил сделать методы перекодирования из AMR в MP3 используя ffmpeg библиотеку, которую я кокраз и использую для работы с RTSP. Т.е. идея такова: получаем AVPacket для аудио, декодируем его в raw buffer, а потом энкодируем в MP3, запихиваем в новый AVPacket и гадим его в AudioQueue. Я сделал два метода (для decode и encode), но, толи у меня не хватает понимания как это работает, толи Джобс гдета капнул, но звук полон всяких артифактов и звучит аки поезд что по рельсам едет. Два дня читал всякие доки и форумы, пока не нашел ничего. Может тут мне подскажут что не так. Вот собственно методы (смесь Objective C и С. код переделовался много раз, потому не слишком чист):

- (void) decodeAudioPacketToRaw:(AVPacket) inPacket
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    
    int out_size, size, len, total;
    uint8_t *outbuf;    
    uint8_t *readybuf;        
    uint8_t *buf;            
    
    total = 0;
    
    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;
    }
    
    readybuf = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
    memset(readybuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
    size = inPacket.size;
    
    NSLog(@"Input packet size is %i", size);
    
    while (size > 0) {
        outbuf = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);   
        out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
        len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &inPacket);
        if (len < 0) {
            fprintf(stderr, "Error while decoding\n");
            return;
        }
        NSLog(@"Decoded len is %i", len);
        NSLog(@"Decoded out size is %i", out_size);        
        if (out_size > 0) {
            size -= len;
            inPacket.size -= len;
            inPacket.data += len;
            memcpy(readybuf + total, outbuf, out_size);
            total += out_size;
            //[self encodeAudioBuffer:(const short *)outbuf withSize:out_size andSourcePacket:inPacket];    Пробовал даже так, еще хуже                
        }
        free(outbuf);
    }    
    if(total > 0)
    {
        buf = (uint8_t*) malloc(total);        
        memcpy(buf, readybuf, total);
        free(readybuf);        
        [self encodeAudioBuffer:(const short *)buf withSize:total andSourcePacket:inPacket];        
        free(buf);
    }
}



- (void) encodeAudioBuffer:(const short *) in_buffer withSize:(unsigned int) in_buf_byte_size andSourcePacket:(AVPacket)sourcePacket
{
    AVCodec * codec;
    AVCodecContext * c= NULL;
    int count, out_size, outbuf_size, frame_byte_size;
    uint8_t * outbuf;    
    uint8_t * totaloutbuf;        

    printf("Audio encoding\n");
    
    codec = avcodec_find_encoder(CODEC_ID_MP3);
    if (!codec) {
        fprintf(stderr, "output codec not found\n");
        return;
    }
    
    c= avcodec_alloc_context();
    
    c->bit_rate = 16000;
    c->sample_rate = 8000;
    c->channels = 1;
    
    if (avcodec_open(c, codec) < 0) {
        fprintf(stderr, "could not open output codec\n");
        return;
    }
            
    NSLog(@"START");
    
    int total = 0;
    int test = in_buf_byte_size;
    out_size = 0;
    while(out_size <= 0)
    {
        outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
        outbuf = (uint8_t*) malloc(outbuf_size);
        memset(outbuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
        
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, (short*)in_buffer);
        if(out_size > 0)
        {
            AVPacket resPacket;
            av_init_packet(&resPacket);
            resPacket.data = malloc(out_size);
            resPacket.size = 0;
            memset(resPacket.data, 0, out_size);
            memcpy(resPacket.data, outbuf, out_size);
            resPacket.size = out_size;
            
            // тут гадим пакет в очередь.

            test -= out_size;
            total += out_size;
        }
        
        free(outbuf);        
    }
        
    avcodec_close(c);
    av_free(c);
    NSLog(@"FINISH");    

}


На самом деле не совсем ясно, что возвращает avcodec_encode_audio. В одной инструкции говорится, что возвращает скока использовалось байт из входного буфера, в другой, скока получилось байт в output буфере. В общем загадка. Странно, но первый раз оно возвращает 0, потому я там цикл сделал. Забавно то, что MP2 при первой попытке возвращает значчение более 0, но AudioQueue на iPhone не поддержывает и его.

Помогите кто может, а то уже моск кипит!!!

Спасибо!
Re: ffmpeg. decode AMR to MP3
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 09.06.11 18:49
Оценка:
Здравствуйте, VictorKozachek, Вы писали:

VK>Помогите кто может, а то уже моск кипит!!!

VK>Спасибо!

с ffmpeg дела не имел, но совершенно не понятно почему вы постоянно пересоздаете encoder instance, в mp3 ведь каждый следующий фрэйм зависит от пердидущего, конечно у вас будет много шумов на выходе... в случае же с Layer 2 (mp2) зависимостей таких нет, поэтому и шумов у вас не имеется
Re[2]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 09.06.11 19:11
Оценка:
Здравствуйте, dabeat_bf, Вы писали:

_>Здравствуйте, VictorKozachek, Вы писали:


VK>>Помогите кто может, а то уже моск кипит!!!

VK>>Спасибо!

_>с ffmpeg дела не имел, но совершенно не понятно почему вы постоянно пересоздаете encoder instance, в mp3 ведь каждый следующий фрэйм зависит от пердидущего, конечно у вас будет много шумов на выходе... в случае же с Layer 2 (mp2) зависимостей таких нет, поэтому и шумов у вас не имеется


Т.е. регистрацию кодека и контекста нада один раз делать?

Layer 2 звуков не издает, так как AudioQueue не поддерживает его и output к аудио устройству не открывает. но да, оно энкодится.
Re[2]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 09.06.11 19:43
Оценка: :)
Здравствуйте, dabeat_bf, Вы писали:

_>Здравствуйте, VictorKozachek, Вы писали:


VK>>Помогите кто может, а то уже моск кипит!!!

VK>>Спасибо!

_>с ffmpeg дела не имел, но совершенно не понятно почему вы постоянно пересоздаете encoder instance, в mp3 ведь каждый следующий фрэйм зависит от пердидущего, конечно у вас будет много шумов на выходе... в случае же с Layer 2 (mp2) зависимостей таких нет, поэтому и шумов у вас не имеется


О великий гуру, спасибо вам!!! Действительно так и было.
Сделал мемберы класса:
AVCodec * mp3Codec;
AVCodecContext *mp3Context;

Иничу один раз и все. Тот страшный шум пропал.


СПАСИБО!!!
Re: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 10.06.11 15:06
Оценка:
Здравствуйте, VictorKozachek, Вы писали:

VK>Приветствую,


VK>Я на этом ресурсе новый человек, посему если что не так, поправьте пожалуйста.


VK>Проблема в том, что папу Джобса как всегда сутра клюнул жаренный петух и теперь по какойто причине Apple убрали поддержку AudioQueue output поддержку для AMR кодека в iOS 4.3. В старых системах мое приложение замечательно так читало пакеты из RTSP и играло видео и аудио, теперь играет только видео. Я решил сделать методы перекодирования из AMR в MP3 используя ffmpeg библиотеку, которую я кокраз и использую для работы с RTSP. Т.е. идея такова: получаем AVPacket для аудио, декодируем его в raw buffer, а потом энкодируем в MP3, запихиваем в новый AVPacket и гадим его в AudioQueue. Я сделал два метода (для decode и encode), но, толи у меня не хватает понимания как это работает, толи Джобс гдета капнул, но звук полон всяких артифактов и звучит аки поезд что по рельсам едет. Два дня читал всякие доки и форумы, пока не нашел ничего. Может тут мне подскажут что не так. Вот собственно методы (смесь Objective C и С. код переделовался много раз, потому не слишком чист):


VK>
VK>- (void) decodeAudioPacketToRaw:(AVPacket) inPacket
VK>{
VK>    AVCodec *codec;
VK>    AVCodecContext *c= NULL;
    
VK>    int out_size, size, len, total;
VK>    uint8_t *outbuf;    
VK>    uint8_t *readybuf;        
VK>    uint8_t *buf;            
    
VK>    total = 0;
    
VK>    codec = avcodec_find_decoder(CODEC_ID_AMR_NB);
VK>    if (!codec) {
VK>        fprintf(stderr, "input codec not found\n");
VK>        return;
VK>    }
    
VK>    c= avcodec_alloc_context();
    
VK>    if (avcodec_open(c, codec) < 0) {
VK>        fprintf(stderr, "could not open input codec\n");
VK>        return;
VK>    }
    
VK>    readybuf = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
VK>    memset(readybuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
VK>    size = inPacket.size;
    
VK>    NSLog(@"Input packet size is %i", size);
    
VK>    while (size > 0) {
VK>        outbuf = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);   
VK>        out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
VK>        len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &inPacket);
VK>        if (len < 0) {
VK>            fprintf(stderr, "Error while decoding\n");
VK>            return;
VK>        }
VK>        NSLog(@"Decoded len is %i", len);
VK>        NSLog(@"Decoded out size is %i", out_size);        
VK>        if (out_size > 0) {
VK>            size -= len;
VK>            inPacket.size -= len;
VK>            inPacket.data += len;
VK>            memcpy(readybuf + total, outbuf, out_size);
VK>            total += out_size;
VK>            //[self encodeAudioBuffer:(const short *)outbuf withSize:out_size andSourcePacket:inPacket];    Пробовал даже так, еще хуже                
VK>        }
VK>        free(outbuf);
VK>    }    
VK>    if(total > 0)
VK>    {
VK>        buf = (uint8_t*) malloc(total);        
VK>        memcpy(buf, readybuf, total);
VK>        free(readybuf);        
VK>        [self encodeAudioBuffer:(const short *)buf withSize:total andSourcePacket:inPacket];        
VK>        free(buf);
VK>    }
VK>}

VK>



VK>
VK>- (void) encodeAudioBuffer:(const short *) in_buffer withSize:(unsigned int) in_buf_byte_size andSourcePacket:(AVPacket)sourcePacket
VK>{
VK>    AVCodec * codec;
VK>    AVCodecContext * c= NULL;
VK>    int count, out_size, outbuf_size, frame_byte_size;
VK>    uint8_t * outbuf;    
VK>    uint8_t * totaloutbuf;        

VK>    printf("Audio encoding\n");
    
VK>    codec = avcodec_find_encoder(CODEC_ID_MP3);
VK>    if (!codec) {
VK>        fprintf(stderr, "output codec not found\n");
VK>        return;
VK>    }
    
VK>    c= avcodec_alloc_context();
    
    c->>bit_rate = 16000;
    c->>sample_rate = 8000;
    c->>channels = 1;
    
VK>    if (avcodec_open(c, codec) < 0) {
VK>        fprintf(stderr, "could not open output codec\n");
VK>        return;
VK>    }
            
VK>    NSLog(@"START");
    
VK>    int total = 0;
VK>    int test = in_buf_byte_size;
VK>    out_size = 0;
VK>    while(out_size <= 0)
VK>    {
VK>        outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
VK>        outbuf = (uint8_t*) malloc(outbuf_size);
VK>        memset(outbuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
        
VK>        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, (short*)in_buffer);
VK>        if(out_size > 0)
VK>        {
VK>            AVPacket resPacket;
VK>            av_init_packet(&resPacket);
VK>            resPacket.data = malloc(out_size);
VK>            resPacket.size = 0;
VK>            memset(resPacket.data, 0, out_size);
VK>            memcpy(resPacket.data, outbuf, out_size);
VK>            resPacket.size = out_size;
            
VK>            // тут гадим пакет в очередь.

VK>            test -= out_size;
VK>            total += out_size;
VK>        }
        
VK>        free(outbuf);        
VK>    }
        
VK>    avcodec_close(c);
VK>    av_free(c);
VK>    NSLog(@"FINISH");    

VK>}

VK>


VK>На самом деле не совсем ясно, что возвращает avcodec_encode_audio. В одной инструкции говорится, что возвращает скока использовалось байт из входного буфера, в другой, скока получилось байт в output буфере. В общем загадка. Странно, но первый раз оно возвращает 0, потому я там цикл сделал. Забавно то, что MP2 при первой попытке возвращает значчение более 0, но AudioQueue на iPhone не поддержывает и его.


VK>Помогите кто может, а то уже моск кипит!!!


VK>Спасибо!



Ну в общем действительно нелзя для MP3 каждый раз создавать контекст, сделал контекст мембером класса иничу один раз, дергание пропало. Но реального звука не слышно практически, только шум, как будто телек антену потерял. Пока не знаю как починить, можнт чтото в логике не так :(
Re[2]: ffmpeg. decode AMR to MP3
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 10.06.11 18:10
Оценка:
Здравствуйте, VictorKozachek, Вы писали:

VK>Здравствуйте, VictorKozachek, Вы писали:


VK>Ну в общем действительно нелзя для MP3 каждый раз создавать контекст, сделал контекст мембером класса иничу один раз, дергание пропало. Но реального звука не слышно практически, только шум, как будто телек антену потерял. Пока не знаю как починить, можнт чтото в логике не так



VK>    while(out_size <= 0)
VK>    {
VK>        outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
VK>        outbuf = (uint8_t*) malloc(outbuf_size);
VK>        memset(outbuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
        
VK>        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, (short*)in_buffer);


проблема скорее всего тут mp3 энкодер процессит одновременно 1152 для одного канала, как следствие ваш outbuf_size должен быть не меньше чем 2304, а у вас возможно меньше... так как while цикл решает эту проблему то готов предположить что ffmpeg накапливает данные пока не будет достаточно для кодирования. попробуйте просто закоментировать while и проверить помогло или нет
Re[3]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 11.06.11 07:49
Оценка:
Здравствуйте, dabeat_bf, Вы писали:

_>Здравствуйте, VictorKozachek, Вы писали:


VK>>Здравствуйте, VictorKozachek, Вы писали:


VK>>Ну в общем действительно нелзя для MP3 каждый раз создавать контекст, сделал контекст мембером класса иничу один раз, дергание пропало. Но реального звука не слышно практически, только шум, как будто телек антену потерял. Пока не знаю как починить, можнт чтото в логике не так :(



_>
VK>>    while(out_size <= 0)
VK>>    {
VK>>        outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
VK>>        outbuf = (uint8_t*) malloc(outbuf_size);
VK>>        memset(outbuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
        
VK>>        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, (short*)in_buffer);
_>


_>проблема скорее всего тут mp3 энкодер процессит одновременно 1152 для одного канала, как следствие ваш outbuf_size должен быть не меньше чем 2304, а у вас возможно меньше... так как while цикл решает эту проблему то готов предположить что ffmpeg накапливает данные пока не будет достаточно для кодирования. попробуйте просто закоментировать while и проверить помогло или нет


Меня вот наоборот смущает большой размер буфера, AVCODEC_MAX_AUDIO_FRAME_SIZE = 19200. Цикл я там поставил, потому что функция avcodec_encode_audio возвращает при первой попытке 0, что есть странно и не понятно. Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.
Re[4]: ffmpeg. decode AMR to MP3
От: butcha Россия  
Дата: 14.06.11 21:06
Оценка:
VK>Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.
Попался на глаза ваш пост и заинтересовало, дело в том что у меня тоже были проблемы с декодированием декодером ффмпег CODEC_ID_AMR_NB, сплошной хрип на выходе. MP2,MP3, WMA, ac3,aac ffmpeg-декодеры работали нормально, проблемы возникли с wma-pro и с упомянутым amr. Единственое что между ними общего это то что оба выдают float семплы. В общем ничего я от них не добился и решил что глючать сами функции декодирования этих форматов в ffmpeg. Если не трудно, отпишите, получилось ли у вас что нибудь. Я использую директ-шоу, поэтому взял декодер аудио от медиа-плеер-класик (MPA decoder) Он, кстати декодирует amr как раз используя "opencore-amr"
Re[5]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 15.06.11 07:14
Оценка:
Здравствуйте, butcha, Вы писали:

VK>>Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.

B>Попался на глаза ваш пост и заинтересовало, дело в том что у меня тоже были проблемы с декодированием декодером ффмпег CODEC_ID_AMR_NB, сплошной хрип на выходе. MP2,MP3, WMA, ac3,aac ffmpeg-декодеры работали нормально, проблемы возникли с wma-pro и с упомянутым amr. Единственое что между ними общего это то что оба выдают float семплы. В общем ничего я от них не добился и решил что глючать сами функции декодирования этих форматов в ffmpeg. Если не трудно, отпишите, получилось ли у вас что нибудь. Я использую директ-шоу, поэтому взял декодер аудио от медиа-плеер-класик (MPA decoder) Он, кстати декодирует amr как раз используя "opencore-amr"

Приветствую,

Ну я вот только вчера попробовал Opencore-amr, она декодирует корректно в raw и у них есть замечательный пример в тестах, по сохранению в WAV. Там дело в том, что одного рав буфера не достаточно и они еще производят маневры с декодированным буфером. Также, они сохраняют хедер файла. Добиться играть это в реалтайме, используя AudioQueue (это низкоуровневая технология на iPhone для проигрывания и записи звука напрямую через звуковые устройства) пока не удалось. Но вот запись в файл работает. Вогу покзать код, но он на смеси Objective-C и С. Немного както непонятно с размером буфера при декодировании, они используют константу в 160 байт и проеобразованный размер 320.
Re[5]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 15.06.11 08:35
Оценка:
Здравствуйте, butcha, Вы писали:

VK>>Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.

B>Попался на глаза ваш пост и заинтересовало, дело в том что у меня тоже были проблемы с декодированием декодером ффмпег CODEC_ID_AMR_NB, сплошной хрип на выходе. MP2,MP3, WMA, ac3,aac ffmpeg-декодеры работали нормально, проблемы возникли с wma-pro и с упомянутым amr. Единственое что между ними общего это то что оба выдают float семплы. В общем ничего я от них не добился и решил что глючать сами функции декодирования этих форматов в ffmpeg. Если не трудно, отпишите, получилось ли у вас что нибудь. Я использую директ-шоу, поэтому взял декодер аудио от медиа-плеер-класик (MPA decoder) Он, кстати декодирует amr как раз используя "opencore-amr"

Кстати, эти товарищи сделали AAC Encoder, буду тестить :)
Re[6]: ffmpeg. decode AMR to MP3
От: butcha Россия  
Дата: 15.06.11 09:23
Оценка:
Здравствуйте, VictorKozachek, Вы писали:

VK>Здравствуйте, butcha, Вы писали:


VK>>>Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.

B>>Попался на глаза ваш пост и заинтересовало, дело в том что у меня тоже были проблемы с декодированием декодером ффмпег CODEC_ID_AMR_NB, сплошной хрип на выходе. MP2,MP3, WMA, ac3,aac ffmpeg-декодеры работали нормально, проблемы возникли с wma-pro и с упомянутым amr. Единственое что между ними общего это то что оба выдают float семплы. В общем ничего я от них не добился и решил что глючать сами функции декодирования этих форматов в ffmpeg. Если не трудно, отпишите, получилось ли у вас что нибудь. Я использую директ-шоу, поэтому взял декодер аудио от медиа-плеер-класик (MPA decoder) Он, кстати декодирует amr как раз используя "opencore-amr"

VK>Кстати, эти товарищи сделали AAC Encoder, буду тестить


Понятно, спасибо, надо покопать ""opencore-amr" а то использовать из-за одного формата(amr) отдельный длл/фильтр как то неуклюже. Странно что в багтрекере ffmpeg я не нашёл тем по поводу декодера amr.
p.s. что то не сработала пописка на сообщения этой темы
Re[7]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 15.06.11 09:40
Оценка:
Здравствуйте, butcha, Вы писали:

B>Здравствуйте, VictorKozachek, Вы писали:


VK>>Здравствуйте, butcha, Вы писали:


VK>>>>Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.

B>>>Попался на глаза ваш пост и заинтересовало, дело в том что у меня тоже были проблемы с декодированием декодером ффмпег CODEC_ID_AMR_NB, сплошной хрип на выходе. MP2,MP3, WMA, ac3,aac ffmpeg-декодеры работали нормально, проблемы возникли с wma-pro и с упомянутым amr. Единственое что между ними общего это то что оба выдают float семплы. В общем ничего я от них не добился и решил что глючать сами функции декодирования этих форматов в ffmpeg. Если не трудно, отпишите, получилось ли у вас что нибудь. Я использую директ-шоу, поэтому взял декодер аудио от медиа-плеер-класик (MPA decoder) Он, кстати декодирует amr как раз используя "opencore-amr"

VK>>Кстати, эти товарищи сделали AAC Encoder, буду тестить :)


B>Понятно, спасибо, надо покопать ""opencore-amr" а то использовать из-за одного формата(amr) отдельный длл/фильтр как то неуклюже. Странно что в багтрекере ffmpeg я не нашёл тем по поводу декодера amr.

B>p.s. что то не сработала пописка на сообщения этой темы :(

Вообщето бага там есть и опытные сабаководы рекомендуют включать opencore-amr при сборке ffmpeg. Дело в том, что товарищи из ffmpeg абсолютно невежливы и неккоректны. Они или не отвечают вообще или посылают куда подальше. Они вот даже перепугались между собой и теперь libav — отдельный проект.
Re[7]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 15.06.11 11:28
Оценка:
Здравствуйте, butcha, Вы писали:

B>Здравствуйте, VictorKozachek, Вы писали:


VK>>Здравствуйте, butcha, Вы писали:


VK>>>>Еще есть предположение что както неправильно декодируется в raw, хотя там все прозаично на самом деле. Тут вот еще нашел одну вещицу, буду пробовать: opencore-amr. Там вроде есть пример как в один присест перекодировать с AMR в любой другой кодек. Если получится, опишу тут, может кому пригодится. В любом случае спасибо за поддержку, действительно помогло, теперь буду знать, что MP3 загадочен и каждая инстанция контекста создает проблему.

B>>>Попался на глаза ваш пост и заинтересовало, дело в том что у меня тоже были проблемы с декодированием декодером ффмпег CODEC_ID_AMR_NB, сплошной хрип на выходе. MP2,MP3, WMA, ac3,aac ffmpeg-декодеры работали нормально, проблемы возникли с wma-pro и с упомянутым amr. Единственое что между ними общего это то что оба выдают float семплы. В общем ничего я от них не добился и решил что глючать сами функции декодирования этих форматов в ffmpeg. Если не трудно, отпишите, получилось ли у вас что нибудь. Я использую директ-шоу, поэтому взял декодер аудио от медиа-плеер-класик (MPA decoder) Он, кстати декодирует amr как раз используя "opencore-amr"

VK>>Кстати, эти товарищи сделали AAC Encoder, буду тестить :)


B>Понятно, спасибо, надо покопать ""opencore-amr" а то использовать из-за одного формата(amr) отдельный длл/фильтр как то неуклюже. Странно что в багтрекере ffmpeg я не нашёл тем по поводу декодера amr.

B>p.s. что то не сработала пописка на сообщения этой темы :(

Итак, либа opencore-amr и ее расширение для AAC encode работает просто афигенно, без шумов и все прозрачно, да и кода меньше :)
Re[8]: ffmpeg. decode AMR to MP3
От: butcha Россия  
Дата: 18.06.11 09:25
Оценка:
Здравствуйте, VictorKozachek, Вы писали:

VK>Итак, либа opencore-amr и ее расширение для AAC encode работает просто афигенно, без шумов и все прозрачно, да и кода меньше


Насчет "кода меньше" наверное шутка? (400 файлов кода против одного у ффмпег) Но действительно работает, спасибо за подсказку . Я не стал заморачивать с мейк-файлами, gcc, свалил все файлы в одну директорию, сделал проект msvc, выкинул несколько файлов которые не захотели сразу компилится (какой-то CPvGsmAmrEncoder-вропер над всем этим), остальное скомпилилось и заработало без проблем.
Re[9]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 20.06.11 12:26
Оценка:
Здравствуйте, butcha, Вы писали:

B>Здравствуйте, VictorKozachek, Вы писали:


VK>>Итак, либа opencore-amr и ее расширение для AAC encode работает просто афигенно, без шумов и все прозрачно, да и кода меньше :)


B>Насчет "кода меньше" наверное шутка? (400 файлов кода против одного у ффмпег) Но действительно работает, спасибо за подсказку . Я не стал заморачивать с мейк-файлами, gcc, свалил все файлы в одну директорию, сделал проект msvc, выкинул несколько файлов которые не захотели сразу компилится (какой-то CPvGsmAmrEncoder-вропер над всем этим), остальное скомпилилось и заработало без проблем.


Количество кода — не шутка :) Я имею ввиду код, который нада писать, а так, я статик либу сделал и юзаю. Только вот иногда их энкодер возвращает ошибку на GetOutputData. Пока не могу понять почему :(
Re[10]: ffmpeg. decode AMR to MP3
От: butcha Россия  
Дата: 20.06.11 20:02
Оценка:
Здравствуйте, VictorKozachek, Вы писали:

VK>Количество кода — не шутка Я имею ввиду код, который нада писать, а так, я статик либу сделал и юзаю. Только вот иногда их энкодер возвращает ошибку на GetOutputData. Пока не могу понять почему


Понятно, я пока с енкодером не занимался — только скомпилировал, подключил к ффпег попробовал отрыть — открывается. А родной ффпег аас енкодер уже при инициализации вываливал ошибку деления на ноль. Мне и код писать не надо — в ффпег есть обёртки над vo-aac, open-amr так что я узаю всё через ффпег.
Re[11]: ffmpeg. decode AMR to MP3
От: VictorKozachek  
Дата: 21.06.11 08:02
Оценка:
Здравствуйте, butcha, Вы писали:

B>Здравствуйте, VictorKozachek, Вы писали:


VK>>Количество кода — не шутка :) Я имею ввиду код, который нада писать, а так, я статик либу сделал и юзаю. Только вот иногда их энкодер возвращает ошибку на GetOutputData. Пока не могу понять почему :(


B>Понятно, я пока с енкодером не занимался — только скомпилировал, подключил к ффпег попробовал отрыть — открывается. А родной ффпег аас енкодер уже при инициализации вываливал ошибку деления на ноль. Мне и код писать не надо — в ффпег есть обёртки над vo-aac, open-amr так что я узаю всё через ффпег.


Да, я поговорил с неким товарищем Мартином из тима Opencore-amr на предмет этой ошибки и он мне все прояснил и теперь декодер и енкодер работают. Вся проблема в генах, как оказалось. AMR пакет, который считывается из RSTP, да и не только, состоит из нескольких фреймов с определенным размером, в моем случае пакет содержит 4 фрейма по 16 байт, первый байт служебный и содержит размер фрейма, который можно получить парсингом, код его имеется в примере, вот он, если что:

const int sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };

int size = sizes[(packet.data[0] >> 3) & 0x0f];

Декодировать нужно каждый фрейм по отдельности, такая рекомендация этого товарища. С энкодером тут обстоит так, AAC encoder воспринимает буфер не менее 1024 байтов, посему давать ему чтото тменьшее нет смысла, он вернет ошибку. Для этого, нада декодированный фреймы складывать в буфер и как только он достигнет нужного размера, процессить энкодирование. Работает 100%, но, блин, я пока не пойму по какому принципу работает, точнее требует буферы AudioQueue на iPhone. Она процессит буферы быстрее, чем работает процедура декодирования, тут и возникают проблемы :(
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.