문제

Libavcodec (3/3/10 기준 최신 Git)을 사용하여 원시 PCM을 AAC (LibFAAC 지원 활성화)로 인코딩합니다. 나는 avcodec_encode_audio를 매번 codec_context-> frame_size 샘플로 반복적으로 호출하여 이것을합니다. 처음 네 번의 전화는 성공적으로 반환되지만 다섯 번째 전화는 결코 돌아 오지 않습니다. GDB를 사용하여 파손되면 스택이 손상되었습니다.

Audacity를 사용하여 PCM 데이터를 .wav 파일로 내보내면 명령 줄 ffmpeg를 사용하여 아무런 문제없이 AAC로 변환 할 수 있으므로 내가 잘못하고있는 일이라고 확신합니다.

나는 내 문제를 복제하는 작은 테스트 프로그램을 작성했습니다. 여기에서 사용할 수있는 파일에서 테스트 데이터를 읽습니다.http://birdie.protoven.com/audio.pcm (~ 2 초의 서명 16 비트 LE PCM)

FAAC를 직접 사용하면 모든 것이 작동 할 수 있지만 비디오를 인코딩하고 MP4에 둘 다 글을 쓰기 때문에 Libavcodec을 사용할 수 있다면 코드가 약간 더 깨끗합니다.

FFMPEG 버전 정보 :

FFmpeg version git-c280040, Copyright (c) 2000-2010 the FFmpeg developers
  built on Mar  3 2010 15:40:46 with gcc 4.4.1
  configuration: --enable-libfaac --enable-gpl --enable-nonfree --enable-version3 --enable-postproc --enable-pthreads --enable-debug=3 --enable-shared
  libavutil     50.10. 0 / 50.10. 0
  libavcodec    52.55. 0 / 52.55. 0
  libavformat   52.54. 0 / 52.54. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libswscale     0.10. 0 /  0.10. 0
  libpostproc   51. 2. 0 / 51. 2. 0

내 코덱 컨텍스트에서 설정하지 않거나 잘못 설정하지 않습니까? 모든 도움이 감사합니다!

내 테스트 코드는 다음과 같습니다.

#include <stdio.h>
#include <libavcodec/avcodec.h>

void EncodeTest(int sampleRate, int channels, int audioBitrate,
    uint8_t *audioData, size_t audioSize)
{
    AVCodecContext  *audioCodec;
    AVCodec *codec;
    uint8_t *buf;
    int bufSize, frameBytes;

    avcodec_register_all();

    //Set up audio encoder
    codec = avcodec_find_encoder(CODEC_ID_AAC);
    if (codec == NULL) return;
    audioCodec = avcodec_alloc_context();
    audioCodec->bit_rate = audioBitrate;
    audioCodec->sample_fmt = SAMPLE_FMT_S16;
    audioCodec->sample_rate = sampleRate;
    audioCodec->channels = channels;
    audioCodec->profile = FF_PROFILE_AAC_MAIN;
    audioCodec->time_base = (AVRational){1, sampleRate};
    audioCodec->codec_type = CODEC_TYPE_AUDIO;
    if (avcodec_open(audioCodec, codec) < 0) return;

    bufSize = FF_MIN_BUFFER_SIZE * 10;
    buf = (uint8_t *)malloc(bufSize);
    if (buf == NULL) return;

    frameBytes = audioCodec->frame_size * audioCodec->channels * 2;
    while (audioSize >= frameBytes)
    {
        int packetSize;

        packetSize = avcodec_encode_audio(audioCodec, buf, bufSize, (short *)audioData);
        printf("encoder returned %d bytes of data\n", packetSize);
        audioData += frameBytes;
        audioSize -= frameBytes;
    }
}

int main()
{
    FILE *stream = fopen("audio.pcm", "rb");
    size_t size;
    uint8_t *buf;

    if (stream == NULL)
    {
        printf("Unable to open file\n");
        return 1;
    }

    fseek(stream, 0, SEEK_END);
    size = ftell(stream);
    fseek(stream, 0, SEEK_SET);
    buf = (uint8_t *)malloc(size);
    fread(buf, sizeof(uint8_t), size, stream);
    fclose(stream);

    EncodeTest(32000, 2, 448000, buf, size);
}
도움이 되었습니까?

해결책

비트 전송률이 386000 미만이면 문제가 사라지는 것 같습니다. FAAC를 직접 사용하는 것보다 비트 전송기에서 더 높은 인코딩 할 수 있으므로 왜 이것이 왜 이것이인지 확실하지 않습니다. 그러나 128000은 내 목적에 충분하기 때문에 앞으로 나아갈 수 있습니다.

다른 팁

AAC 형식으로 압축하려고 시도하고 있습니다. 인코딩에 다른 문제가 있습니다. FFMPEG (2.8.0)의 마지막 개정에는 몇 가지 기능이 있습니다. 먼저 샘플 형식이 지원되었는지 확인 했습니까? 내 버전에서 유일하게 지원되는 형식은 av_sample_fmt_fltp입니다. 형식 검사는 예입니다.

/ *주어진 샘플 형식은 인코더 */ int check_sample_fmt (avcodec *codec, enum avsampleformat sample_fmt) {const enum avsample format *p = codec-> sample_fmts;

while (*p != AV_SAMPLE_FMT_NONE) {
    if (*p == sample_fmt)
        return 1;
    p++;
}
return 0;

}

지원되는 형식을 관찰하면 AV_SAMPLE_FMT_FLTP 만 AAC Codec에 의해 지원됩니다. swresample (제안 된대로)을 사용하여 Planare Float 형식으로 변환하거나 손으로 할 수 있습니다. Codec을 개방하기 위해 엄격한 Sperimental 옵션이있는 AVCODEC_OPEN2를 사용해야합니다. 문안 인사

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top