00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/common.h"
00023 #include "audio_frame_queue.h"
00024 #include "internal.h"
00025 #include "libavutil/avassert.h"
00026
00027 void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
00028 {
00029 afq->avctx = avctx;
00030 afq->remaining_delay = avctx->delay;
00031 afq->remaining_samples = avctx->delay;
00032 afq->frame_count = 0;
00033 }
00034
00035 void ff_af_queue_close(AudioFrameQueue *afq)
00036 {
00037 if(afq->frame_count)
00038 av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in que on closing\n", afq->frame_count);
00039 av_freep(&afq->frames);
00040 memset(afq, 0, sizeof(*afq));
00041 }
00042
00043 int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
00044 {
00045 AudioFrame *new = av_fast_realloc(afq->frames, &afq->frame_alloc, sizeof(*afq->frames)*(afq->frame_count+1));
00046 if(!new)
00047 return AVERROR(ENOMEM);
00048 afq->frames = new;
00049 new += afq->frame_count;
00050
00051
00052 new->duration = f->nb_samples;
00053 new->duration += afq->remaining_delay;
00054 if (f->pts != AV_NOPTS_VALUE) {
00055 new->pts = av_rescale_q(f->pts,
00056 afq->avctx->time_base,
00057 (AVRational){ 1, afq->avctx->sample_rate });
00058 new->pts -= afq->remaining_delay;
00059 if(afq->frame_count && new[-1].pts >= new->pts)
00060 av_log(afq->avctx, AV_LOG_WARNING, "Que input is backward in time\n");
00061 } else {
00062 new->pts = AV_NOPTS_VALUE;
00063 }
00064 afq->remaining_delay = 0;
00065
00066
00067 afq->remaining_samples += f->nb_samples;
00068
00069 afq->frame_count++;
00070
00071 return 0;
00072 }
00073
00074 void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts,
00075 int *duration)
00076 {
00077 int64_t out_pts = AV_NOPTS_VALUE;
00078 int removed_samples = 0;
00079 int i;
00080
00081 if (afq->frame_count || afq->frame_alloc) {
00082 if (afq->frames->pts != AV_NOPTS_VALUE)
00083 out_pts = afq->frames->pts;
00084 }
00085 if(!afq->frame_count)
00086 av_log(afq->avctx, AV_LOG_WARNING, "Trying to remove %d samples, but que empty\n", nb_samples);
00087 if (pts)
00088 *pts = ff_samples_to_time_base(afq->avctx, out_pts);
00089
00090 for(i=0; nb_samples && i<afq->frame_count; i++){
00091 int n= FFMIN(afq->frames[i].duration, nb_samples);
00092 afq->frames[i].duration -= n;
00093 nb_samples -= n;
00094 removed_samples += n;
00095 if(afq->frames[i].pts != AV_NOPTS_VALUE)
00096 afq->frames[i].pts += n;
00097 }
00098 i -= i && afq->frames[i-1].duration;
00099 memmove(afq->frames, afq->frames + i, sizeof(*afq->frames) * (afq->frame_count - i));
00100 afq->frame_count -= i;
00101
00102 if(nb_samples){
00103 av_assert0(!afq->frame_count);
00104 if(afq->frames && afq->frames[0].pts != AV_NOPTS_VALUE)
00105 afq->frames[0].pts += nb_samples;
00106 av_log(afq->avctx, AV_LOG_DEBUG, "Trying to remove %d more samples than are in the que\n", nb_samples);
00107 }
00108 if (duration)
00109 *duration = ff_samples_to_time_base(afq->avctx, removed_samples);
00110 }