【问题标题】:FFmpeg and types of samplesFFmpeg 和样本类型
【发布时间】:2011-07-23 20:50:57
【问题描述】:

使用 FFmpeg 解码音频(函数 avcodec_decode_audio3)并尝试通过 Android 中的 Audiotrack 再现它。演奏时我听到一些咆哮。没有音乐。在论坛上告知样品的问题。问题:如果与样本类型不匹配有关,如何解决此问题?代码解码:



        while (av_read_frame(pFormatCtx, &packet)>= 0) {
            if (aCodecCtx->codec_type == AVMEDIA_TYPE_AUDIO) {
                        int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
                        int size=packet.size;
 int decoded = 0;
                        while(size > 0) {
                                int len = avcodec_decode_audio3(aCodecCtx, (uint16_t *) pAudioBuffer, &data_size, &packet);


                                jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
                                memcpy(bytes + decoded, (uint16_t *) pAudioBuffer, len);
                                (*env)->ReleaseByteArrayElements(env, array, bytes, 0);

                                (*env)->CallStaticVoidMethod(env, cls, mid, array);


                                size -= len;
                                decoded += len;
                                }
            }

     }

Java 代码:


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

         int bufSize = AudioTrack.getMinBufferSize(44100,                                AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                        AudioFormat.ENCODING_PCM_16BIT);
        track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                    AudioFormat.ENCODING_PCM_16BIT, bufSize, AudioTrack.MODE_STREAM);
        track.play();

            bytes = new byte[bufSize];
            int res = main(2, "/sdcard/muzika_iz_reklami_bmw_5_series_-_bmw_5_series.mp3", bytes);


            System.out.println(res);
    }
    private static void play(byte[] play) {

        track.write(play, 0, play.length);
    }

如何解决这个问题? 附言检查文件本身 - 标准播放器播放。格式:mp3。

【问题讨论】:

    标签: android audio ffmpeg sampling


    【解决方案1】:

    在每次调用avcodec_decode_audio 后,为单个AVPacket 保留一个与len 累积的解码字节计数器。然后用它作为Java字节数组的偏移量:

    int decoded = 0;
      ...
    int len = avcodec_decode_audio3(aCodecCtx, (uint8_t *) pAudioBuffer, &data_size, &packet);
      ...
    memcpy(bytes + decoded, (uint8_t *) pAudioBuffer, len);
      ...
    size -= len;
    decoded += len;
    

    您一遍又一遍地覆盖缓冲区的开头而不是追加。

    【讨论】:

    • 更新了代码。在没有区别的声音。我能做错事吗?
    • 看看 ffplay.c。你会有所了解的。
    【解决方案2】:

    这是我的音频解码代码,希望对你有所帮助。

    int16_t* samples = (int16_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
    int sample_size;
    
    while(!m_quit && av_read_frame_wrapper(m_pAVFormatContext, &packet) >= 0) {
        if(packet.stream_index == m_audioStream) {
            org_data = packet.data;
            org_size = packet.size;
            LOGV("audio packet size = %d", packet.size);
            while (!m_quit && packet.size > 0) {
                sample_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
                len = avcodec_decode_audio3(m_pAVCodecContext, samples, &sample_size, &packet);
                LOGV("sample_size = %d, len = %d", sample_size, len);
                if (len < 0) {
                    LOGE("Error when decoding...");
                    break;
                }
    
                if (sample_size > 0) {
                    //begin = now_ms();
    
                    //audio_output_native(samples, sample_size);
    
                    /* use audio queue */
                    SampleNode* node = new SampleNode(samples, sample_size);
                    m_pSampleQueue->enqueue(node);
    
                    //end = now_ms();
    
                    //LOGV("sample_size > 0, output audio samples cost %llu ms\n", end - begin);
                }
                packet.size -= len;
                packet.data += len;
            }
    
            packet.size = org_size;
            packet.data = org_data;
    
            av_free_packet(&packet);
        } else {
            av_free_packet(&packet);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-10
      • 1970-01-01
      • 2018-07-21
      • 2016-10-22
      • 2017-02-28
      • 1970-01-01
      • 2021-02-22
      • 2019-12-24
      • 1970-01-01
      相关资源
      最近更新 更多