int audio_decode_frame(VideoState *is, double *pts_ptr) {
    /* For example with wma audio package size can be
       like 100 000 bytes */
    long len1, data_size = 0;
    AVPacket *pkt = &is->audio_pkt;
    double pts;
    int n = 0;
#ifdef __RESAMPLER__
    long resample_size = 0;
#endif

    for(;;) {
        while(is->audio_pkt_size > 0) {
            int got_frame = 0;
            len1 = avcodec_decode_audio4(is->audio_st->codec, &is->audio_frame, &got_frame, pkt);

            if(len1 < 0) {
                /* if error, skip frame */
                is->audio_pkt_size = 0;
                break;
            }

            if(got_frame) {
                data_size =
                    av_samples_get_buffer_size
                    (
                        NULL,
                        is->audio_st->codec->channels,
                        is->audio_frame.nb_samples,
                        is->audio_st->codec->sample_fmt,
                        1
                    );

#ifdef __RESAMPLER__

                if(is->audio_need_resample == 1) {
                    resample_size = audio_tutorial_resample(is, &is->audio_frame);

                    if( resample_size > 0 ) {
                        memcpy(is->audio_buf, is->pResampledOut, resample_size);
                        memset(is->pResampledOut, 0x00, resample_size);
                    }

                } else {
#endif

                    memcpy(is->audio_buf, is->audio_frame.data[0], data_size);
#ifdef __RESAMPLER__
                }

#endif
            }

            is->audio_pkt_data += len1;
            is->audio_pkt_size -= len1;

            if(data_size <= 0) {
                /* No data yet, get more frames */
                continue;
            }

            pts = is->audio_clock;
            *pts_ptr = pts;
            n = 2 * is->audio_st->codec->channels;

#ifdef __RESAMPLER__

            /* If you just return original data_size you will suffer
               for clicks because you don't have that much data in
               queue incoming so return resampled size. */
            if(is->audio_need_resample == 1) {
                is->audio_clock += (double)resample_size /
                                   (double)(n * is->audio_st->codec->sample_rate);
                return resample_size;

            } else {
#endif
                /* We have data, return it and come back for more later */
                is->audio_clock += (double)data_size /
                                   (double)(n * is->audio_st->codec->sample_rate);
                return data_size;
#ifdef __RESAMPLER__
            }

#endif
        }

        if(pkt->data) {
            av_free_packet(pkt);
        }

        if(is->quit) {
            return -1;
        }

        /* next packet */
        if(packet_queue_get(&is->audioq, pkt, 1) < 0) {
            return -1;
        }

        if(pkt->data == flush_pkt.data) {
            avcodec_flush_buffers(is->audio_st->codec);
            continue;
        }

        is->audio_pkt_data = pkt->data;
        is->audio_pkt_size = pkt->size;

        /* if update, update the audio clock w/pts */
        if(pkt->pts != AV_NOPTS_VALUE) {
            is->audio_clock = av_q2d(is->audio_st->time_base) * pkt->pts;
        }
    }
}
Exemplo n.º 2
0
int audio_decode_frame(VideoState *is, double *pts_ptr) {

    int len1, data_size = 0, n;
    AVPacket *pkt = &is->audio_pkt;
    double pts;

    for(;;) {
        while(is->audio_pkt_size > 0) {
            int got_frame = 0;
            int resample_size = 0;
            len1 = avcodec_decode_audio4(is->audio_st->codec, &is->audio_frame, &got_frame,
                                         pkt);
            if(len1 < 0) {
                /* if error, skip frame */
                is->audio_pkt_size = 0;
                break;
            }
            if (got_frame) {
                data_size =
                    av_samples_get_buffer_size
                    (
                        NULL,
                        is->audio_st->codec->channels,
                        is->audio_frame.nb_samples,
                        is->audio_st->codec->sample_fmt,
                        1
                    );

#ifdef __RESAMPLER__
                if(is->audio_need_resample == 1) {
                    resample_size = audio_tutorial_resample(is, &is->audio_frame);
                    if( resample_size > 0 ) {
                        memcpy(is->audio_buf, is->pResampledOut, resample_size);
                        memset(is->pResampledOut, 0x00, resample_size);
                    }

                } else {
#endif

                    memcpy(is->audio_buf, is->audio_frame.data[0], data_size);
#ifdef __RESAMPLER__
                }
#endif
            }
            is->audio_pkt_data += len1;
            is->audio_pkt_size -= len1;
            if(data_size <= 0) {
                /* No data yet, get more frames */
                continue;
            }
            pts = is->audio_clock;
            *pts_ptr = pts;
            n = 2 * is->audio_st->codec->channels;
            is->audio_clock += (double)data_size /
                               (double)(n * is->audio_st->codec->sample_rate);

            /* We have data, return it and come back for more later */
            return data_size;
        }
        if(pkt->data)
            av_free_packet(pkt);

        if(is->quit) {
            return -1;
        }
        /* next packet */
        if(packet_queue_get(&is->audioq, pkt, 1) < 0) {
            return -1;
        }
        if(pkt->data == flush_pkt.data) {
            avcodec_flush_buffers(is->audio_st->codec);
            continue;
        }
        is->audio_pkt_data = pkt->data;
        is->audio_pkt_size = pkt->size;
        /* if update, update the audio clock w/pts */
        if(pkt->pts != AV_NOPTS_VALUE) {
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
        }
    }
}