tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_frame_queue.c (3989B)


      1 /*
      2 * Audio Frame Queue
      3 * Copyright (c) 2012 Justin Ruggles
      4 *
      5 * This file is part of FFmpeg.
      6 *
      7 * FFmpeg is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU Lesser General Public
      9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * FFmpeg is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with FFmpeg; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     20 */
     21 
     22 #include "libavutil/attributes.h"
     23 #include "libavutil/mem.h"
     24 #include "audio_frame_queue.h"
     25 #include "encode.h"
     26 #include "libavutil/avassert.h"
     27 
     28 av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
     29 {
     30    afq->avctx = avctx;
     31    afq->remaining_delay   = avctx->initial_padding;
     32    afq->remaining_samples = avctx->initial_padding;
     33    afq->frame_count       = 0;
     34 }
     35 
     36 void ff_af_queue_close(AudioFrameQueue *afq)
     37 {
     38    if(afq->frame_count)
     39        av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in the queue on closing\n", afq->frame_count);
     40    av_freep(&afq->frames);
     41    memset(afq, 0, sizeof(*afq));
     42 }
     43 
     44 int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
     45 {
     46    AudioFrame *new = av_fast_realloc(afq->frames, &afq->frame_alloc, sizeof(*afq->frames)*(afq->frame_count+1));
     47    if(!new)
     48        return AVERROR(ENOMEM);
     49    afq->frames = new;
     50    new += afq->frame_count;
     51 
     52    /* get frame parameters */
     53    new->duration = f->nb_samples;
     54    new->duration += afq->remaining_delay;
     55    if (f->pts != AV_NOPTS_VALUE) {
     56        new->pts = av_rescale_q(f->pts,
     57                                      afq->avctx->time_base,
     58                                      (AVRational){ 1, afq->avctx->sample_rate });
     59        new->pts -= afq->remaining_delay;
     60        if(afq->frame_count && new[-1].pts >= new->pts)
     61            av_log(afq->avctx, AV_LOG_WARNING, "Queue input is backward in time\n");
     62    } else {
     63        new->pts = AV_NOPTS_VALUE;
     64    }
     65    afq->remaining_delay = 0;
     66 
     67    /* add frame sample count */
     68    afq->remaining_samples += f->nb_samples;
     69 
     70    afq->frame_count++;
     71 
     72    return 0;
     73 }
     74 
     75 void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts,
     76                        int64_t *duration)
     77 {
     78    int64_t out_pts = AV_NOPTS_VALUE;
     79    int removed_samples = 0;
     80    int i;
     81 
     82    if (afq->frame_count || afq->frame_alloc) {
     83        if (afq->frames->pts != AV_NOPTS_VALUE)
     84            out_pts = afq->frames->pts;
     85    }
     86    if(!afq->frame_count)
     87        av_log(afq->avctx, AV_LOG_WARNING, "Trying to remove %d samples, but the queue is empty\n", nb_samples);
     88    if (pts)
     89        *pts = ff_samples_to_time_base(afq->avctx, out_pts);
     90 
     91    for(i=0; nb_samples && i<afq->frame_count; i++){
     92        int n= FFMIN(afq->frames[i].duration, nb_samples);
     93        afq->frames[i].duration -= n;
     94        nb_samples              -= n;
     95        removed_samples         += n;
     96        if(afq->frames[i].pts != AV_NOPTS_VALUE)
     97            afq->frames[i].pts      += n;
     98    }
     99    afq->remaining_samples -= removed_samples;
    100    i -= i && afq->frames[i-1].duration;
    101    memmove(afq->frames, afq->frames + i, sizeof(*afq->frames) * (afq->frame_count - i));
    102    afq->frame_count -= i;
    103 
    104    if(nb_samples){
    105        av_assert0(!afq->frame_count);
    106        av_assert0(afq->remaining_samples == afq->remaining_delay);
    107        if(afq->frames && afq->frames[0].pts != AV_NOPTS_VALUE)
    108            afq->frames[0].pts += nb_samples;
    109        av_log(afq->avctx, AV_LOG_DEBUG, "Trying to remove %d more samples than there are in the queue\n", nb_samples);
    110    }
    111    if (duration)
    112        *duration = ff_samples_to_time_base(afq->avctx, removed_samples);
    113 }