LCOV - code coverage report
Current view: top level - compositor - audio_render.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 195 205 95.1 %
Date: 2021-04-29 23:48:07 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2021
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / Scene Compositor sub-project
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include <gpac/internal/compositor_dev.h>
      27             : 
      28          20 : void gf_ar_rcfg_done(GF_Filter *filter, GF_FilterPid *pid, GF_FilterPacket *pck)
      29             : {
      30             :         u32 size;
      31          20 :         GF_AudioRenderer *ar = (GF_AudioRenderer *) gf_filter_pck_get_data(pck, &size);
      32             :         assert(!size);
      33             :         assert(ar->wait_for_rcfg);
      34          20 :         ar->wait_for_rcfg --;
      35          20 :         if (ar->wait_for_rcfg) {
      36           1 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Reconfigure negociation %d still pending\n", ar->wait_for_rcfg));
      37             :         } else {
      38          19 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Reconfigure negociation done\n"));
      39             :         }
      40          20 : }
      41             : 
      42         623 : static GF_Err gf_ar_setup_output_format(GF_AudioRenderer *ar)
      43             : {
      44             :         u32 freq, a_fmt, nb_chan;
      45             :         u64 ch_cfg;
      46             :         u32 bsize;
      47             : 
      48         623 :         freq = ar->compositor->asr;
      49         623 :         a_fmt = ar->compositor->afmt;
      50         623 :         nb_chan = ar->compositor->ach;
      51         623 :         ch_cfg = ar->compositor->alayout;
      52         623 :         bsize = ar->compositor->asize;
      53         623 :         if (!bsize) bsize = 1024;
      54             : 
      55         623 :         if (!freq || !a_fmt || !nb_chan || !ch_cfg) {
      56         623 :                 gf_mixer_get_config(ar->mixer, &freq, &nb_chan, &a_fmt, &ch_cfg);
      57             : 
      58             :                 /*user disabled multichannel audio*/
      59         623 :                 if (!ar->compositor->amc && (nb_chan>2) ) nb_chan = 2;
      60             :         } else {
      61           0 :                 if (!ar->config_forced) ar->config_forced++;
      62             :         }
      63             : 
      64             : 
      65         623 :         gf_mixer_set_config(ar->mixer, freq, nb_chan, a_fmt, ch_cfg);
      66             : 
      67         623 :         if (ar->samplerate) {
      68          20 :                 ar->time_at_last_config_sr = ar->current_time_sr * freq / ar->samplerate;
      69             :         }
      70         623 :         if (!ar->compositor->abuf) {
      71             : #ifdef GPAC_CONFIG_ANDROID
      72             :                 ar->compositor->abuf = 200;
      73             : #else
      74           0 :                 ar->compositor->abuf = 100;
      75             : #endif
      76             :         }
      77         623 :         ar->samplerate = freq;
      78         623 :         ar->bytes_per_samp = nb_chan * gf_audio_fmt_bit_depth(a_fmt) / 8;
      79         623 :         ar->bytes_per_second = freq * ar->bytes_per_samp;
      80         623 :         ar->max_bytes_out = ar->bytes_per_second * ar->compositor->abuf / 1000;
      81         623 :         while (ar->max_bytes_out % (2*ar->bytes_per_samp) ) ar->max_bytes_out++;
      82         623 :         ar->buffer_size = ar->bytes_per_samp * bsize;
      83             : 
      84         623 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Reconfigure audio to %d Hz %d channels %s\n", freq, nb_chan, gf_audio_fmt_name(a_fmt) ));
      85             : 
      86         623 :         if (ar->aout) {
      87          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_SAMPLE_RATE, &PROP_UINT(freq) );
      88          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_TIMESCALE, &PROP_UINT(freq) );
      89          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(nb_chan) );
      90          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_FORMAT, &PROP_UINT(a_fmt) );
      91          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(ch_cfg) );
      92          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_VOLUME, &PROP_UINT(ar->volume) );
      93          20 :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_PAN, &PROP_UINT(ar->pan) );
      94             : 
      95          20 :                 gf_filter_pid_set_max_buffer(ar->aout, 1000*ar->compositor->abuf);
      96             :         }
      97             : 
      98         623 :         ar->time_at_last_config = ar->current_time;
      99         623 :         ar->bytes_requested = 0;
     100             : 
     101         623 :         if (ar->aout) {
     102             :                 GF_FilterPacket *pck;
     103             :                 //issue a dummy packet to tag the point at which we reconfigured
     104          20 :                 pck = gf_filter_pck_new_shared(ar->aout, (u8 *) ar, 0, gf_ar_rcfg_done);
     105          20 :                 if (!pck) return GF_OUT_OF_MEM;
     106          20 :                 ar->wait_for_rcfg ++;
     107          20 :                 gf_filter_pck_set_readonly(pck);
     108          20 :                 gf_filter_pck_send(pck);
     109             :         }
     110             :         return GF_OK;
     111             : }
     112             : 
     113         668 : static void gf_ar_pause(GF_AudioRenderer *ar, Bool DoFreeze, Bool for_reconfig, Bool reset_hw_buffer)
     114             : {
     115             :         GF_FilterEvent evt;
     116         668 :         gf_mixer_lock(ar->mixer, GF_TRUE);
     117         668 :         if (DoFreeze) {
     118         333 :                 if (!ar->Frozen) {
     119         333 :                         ar->freeze_time = gf_sys_clock_high_res();
     120         333 :                         if (!for_reconfig && ar->aout) {
     121           5 :                                 GF_FEVT_INIT(evt, GF_FEVT_STOP, ar->aout);
     122           5 :                                 gf_filter_pid_send_event(ar->aout, &evt);
     123             :                         }
     124         333 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[Audio] pausing master clock - time "LLD" (sys time "LLD")\n", ar->freeze_time, gf_sys_clock_high_res()));
     125         333 :                         ar->Frozen = GF_TRUE;
     126             :                 }
     127             :         } else {
     128         335 :                 if (ar->Frozen) {
     129         333 :                         if (!for_reconfig && ar->aout) {
     130           5 :                                 GF_FEVT_INIT(evt, GF_FEVT_PLAY, ar->aout);
     131           5 :                                 evt.play.hw_buffer_reset = reset_hw_buffer ? 1 : 0;
     132           5 :                                 gf_filter_pid_send_event(ar->aout, &evt);
     133             :                         }
     134             : 
     135         333 :                         ar->start_time += gf_sys_clock_high_res() - ar->freeze_time;
     136         333 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[Audio] resuming master clock - new time "LLD" (sys time "LLD") \n", ar->start_time, gf_sys_clock_high_res()));
     137         333 :                         ar->Frozen = GF_FALSE;
     138             :                 }
     139             :         }
     140         668 :         gf_mixer_lock(ar->mixer, GF_FALSE);
     141         668 : }
     142             : 
     143             : 
     144         605 : GF_AudioRenderer *gf_sc_ar_load(GF_Compositor *compositor, u32 init_flags)
     145             : {
     146             :         GF_AudioRenderer *ar;
     147         605 :         ar = (GF_AudioRenderer *) gf_malloc(sizeof(GF_AudioRenderer));
     148             :         memset(ar, 0, sizeof(GF_AudioRenderer));
     149             : 
     150         605 :         ar->compositor = compositor;
     151             : 
     152         605 :         ar->mixer = gf_mixer_new(ar);
     153         605 :         ar->non_rt_output = GF_TRUE;
     154         605 :         ar->volume = MIN(100, compositor->avol);
     155         605 :         ar->pan = MIN(100, compositor->apan);
     156         605 :         if (! (init_flags & GF_TERM_NO_AUDIO) ) {
     157         603 :                 gf_ar_setup_output_format(ar);
     158             :         }
     159         605 :         gf_mixer_set_max_speed(ar->mixer, compositor->max_aspeed);
     160         605 :         ar->current_time = 0;
     161         605 :         return ar;
     162             : }
     163             : 
     164         604 : void gf_sc_ar_del(GF_AudioRenderer *ar)
     165             : {
     166         604 :         if (!ar) return;
     167             : 
     168         604 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Destroying compositor\n"));
     169             :         /*resume if paused (might cause deadlock otherwise)*/
     170         604 :         if (ar->Frozen) gf_sc_ar_control(ar, GF_SC_AR_RESUME);
     171             : 
     172         604 :         gf_mixer_del(ar->mixer);
     173         604 :         gf_free(ar);
     174         604 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Renderer destroyed\n"));
     175             : }
     176             : 
     177             : 
     178        2509 : void gf_sc_ar_reset(GF_AudioRenderer *ar)
     179             : {
     180        2509 :         if (!ar) return;
     181             :         
     182        2509 :         gf_mixer_remove_all(ar->mixer);
     183        2509 :         if (ar->scene_ready) {
     184         606 :                 ar->scene_ready = 0;
     185         606 :                 ar->current_time = 0;
     186         606 :                 ar->current_time_sr = 0;
     187         606 :                 ar->bytes_requested = 0;
     188         606 :                 ar->nb_audio_objects = 0;
     189             :         }
     190             : }
     191             : 
     192         628 : void gf_sc_ar_control(GF_AudioRenderer *ar, u32 PauseType)
     193             : {
     194         628 :         gf_ar_pause(ar, (PauseType==GF_SC_AR_PAUSE) ? GF_TRUE : GF_FALSE, GF_FALSE, (PauseType==GF_SC_AR_RESET_HW_AND_PLAY) ? GF_TRUE : GF_FALSE);
     195         628 : }
     196             : 
     197        1204 : void gf_sc_ar_set_volume(GF_AudioRenderer *ar, u32 Volume)
     198             : {
     199        1204 :         if (Volume>100) Volume=100;
     200        1204 :         if (ar->volume==Volume) return;
     201           0 :         ar->volume = Volume;
     202           0 :         if (ar->aout) gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_VOLUME, &PROP_UINT(ar->volume) );
     203             : }
     204             : 
     205           2 : void gf_sc_ar_mute(GF_AudioRenderer *ar, Bool mute)
     206             : {
     207           2 :         ar->mute = mute;
     208           2 :         if (ar->aout) gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_VOLUME, &PROP_UINT(mute ? 0 : ar->volume) );
     209           2 : }
     210             : 
     211        1204 : void gf_sc_ar_set_pan(GF_AudioRenderer *ar, u32 Balance)
     212             : {
     213        1204 :         if (Balance>100) Balance = 100;
     214        1204 :         if (ar->pan == Balance) return;
     215           0 :         ar->pan = Balance;
     216           0 :         if (ar->aout) gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_PAN, &PROP_UINT(ar->pan) );
     217             : }
     218             : 
     219             : 
     220             : void compositor_setup_aout(GF_Compositor *ctx);
     221          21 : void gf_sc_ar_add_src(GF_AudioRenderer *ar, GF_AudioInterface *source)
     222             : {
     223             :         Bool recfg;
     224          21 :         if (!ar) return;
     225             : 
     226          21 :         compositor_setup_aout(ar->compositor);
     227             : 
     228             :         /*lock mixer*/
     229          21 :         gf_mixer_lock(ar->mixer, GF_TRUE);
     230          21 :         gf_mixer_add_input(ar->mixer, source);
     231             :         /*if changed reconfig*/
     232          21 :         recfg = gf_mixer_reconfig(ar->mixer);
     233          21 :         if (!ar->need_reconfig) ar->need_reconfig = recfg;
     234             : 
     235          21 :         if (!gf_mixer_empty(ar->mixer) && ar->aout) {
     236             :                 GF_FilterEvent evt;
     237          21 :                 GF_FEVT_INIT(evt, GF_FEVT_PLAY, ar->aout);
     238          21 :                 gf_filter_pid_send_event(ar->aout, &evt);
     239             :         }
     240             : 
     241             :         /*unlock mixer*/
     242          21 :         gf_mixer_lock(ar->mixer, GF_FALSE);
     243             : }
     244             : 
     245          21 : void gf_sc_ar_remove_src(GF_AudioRenderer *ar, GF_AudioInterface *source)
     246             : {
     247          21 :         if (ar) {
     248          21 :                 gf_mixer_remove_input(ar->mixer, source);
     249          21 :                 if (gf_mixer_empty(ar->mixer) && ar->aout) {
     250             :                         GF_FilterEvent evt;
     251          21 :                         GF_FEVT_INIT(evt, GF_FEVT_STOP, ar->aout);
     252          21 :                         gf_filter_pid_send_event(ar->aout, &evt);
     253             :                 }
     254             :         }
     255          21 : }
     256             : 
     257             : 
     258             : #if 0 //unused
     259             : void gf_sc_ar_set_priority(GF_AudioRenderer *ar, u32 priority)
     260             : {
     261             :         if (ar->aout)
     262             :                 gf_filter_pid_set_property(ar->aout, GF_PROP_PID_AUDIO_PRIORITY, &PROP_UINT(priority) );
     263             : }
     264             : #endif
     265             : 
     266       22396 : void gf_sc_ar_update_video_clock(GF_AudioRenderer *ar, u32 video_ts)
     267             : {
     268       22396 :         ar->video_ts = video_ts;
     269       22396 : }
     270             : 
     271       34299 : static void gf_ar_pck_done(GF_Filter *filter, GF_FilterPid *pid, GF_FilterPacket *pck)
     272             : {
     273             :         u32 size;
     274       34299 :         GF_Compositor *compositor = gf_filter_pid_get_udta(pid);
     275       34299 :         /*data = */gf_filter_pck_get_data(pck, &size);
     276       34325 :         if (!size) return;
     277             :         
     278             :         assert(size <= compositor->audio_renderer->nb_bytes_out);
     279       34273 :         compositor->audio_renderer->nb_bytes_out -= size;
     280             : }
     281             : 
     282      124704 : void gf_ar_send_packets(GF_AudioRenderer *ar)
     283             : {
     284             :         u32 written, max_send=100;
     285      124704 :         u64 now = gf_sys_clock_high_res();
     286             : 
     287      124704 :         if (!ar->aout) {
     288      120981 :                 if (ar->compositor->player) {
     289          54 :                         ar->current_time = (u32) ( (now - ar->start_time)/1000);
     290             :                 }
     291             :                 return;
     292             :         }
     293        3723 :         if (!ar->scene_ready) return;
     294        3689 :         if (ar->need_reconfig) return;
     295        3689 :         if (ar->Frozen) return;
     296             : 
     297             :         //reconfiguration is pending, wait for the packet issued at reconfig to be consumed before issuing any new frame
     298        3689 :         if (ar->wait_for_rcfg) {
     299          77 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Waiting for audio output reconfiguration\n"));
     300             :                 return;
     301             :         }
     302             :         if (ar->scene_ready) {
     303        3612 :                 if (!ar->start_time) {
     304           5 :                         ar->start_time = now;
     305             :                 }
     306        3612 :                 if (!ar->nb_audio_objects && !ar->non_rt_output) {
     307         587 :                         ar->current_time = (u32) ( (now - ar->start_time)/1000);
     308         587 :                         return;
     309             :                 }
     310             :         }
     311             : 
     312       34617 :         while (max_send) {
     313             :                 u32 delay_ms = 0;
     314             :                 u8 *data;
     315             :                 u32 dur;
     316             :                 GF_FilterPacket *pck;
     317             : 
     318       34302 :                 if (gf_filter_pid_would_block(ar->aout))
     319             :                         break;
     320             : 
     321       34299 :                 pck = gf_filter_pck_new_alloc_destructor(ar->aout, ar->buffer_size, &data, gf_ar_pck_done);
     322       34299 :                 if (!pck) break;
     323             : 
     324       34299 :                 if (ar->compositor->async) {
     325             :                         GF_Fraction64 ref_ts;
     326       34299 :                         gf_filter_get_clock_hint(ar->compositor->filter, NULL, &ref_ts);
     327             :                         //valid clock hint, compute delay between last known playback point and current time
     328       34299 :                         if (ref_ts.den) {
     329           0 :                                 if (ref_ts.den != ar->samplerate) {
     330           0 :                                         delay_ms = (u32) (1000 * ar->current_time_sr / ar->samplerate);
     331           0 :                                         delay_ms -= (u32) (1000 * ref_ts.num / ref_ts.den);
     332             :                                 } else {
     333           0 :                                         delay_ms = (u32) (1000 * (ar->current_time_sr - ref_ts.num) / ar->samplerate);
     334             :                                 }
     335             :                         }
     336             :                         //unknown clock hint, use number of bytes out as delay
     337             :                         else {
     338       34299 :                                 delay_ms = (1000*ar->nb_bytes_out) / ar->bytes_per_second;
     339             :                         }
     340             :                 }
     341             : 
     342       34299 :                 gf_mixer_lock(ar->mixer, GF_TRUE);
     343       34299 :                 written = gf_mixer_get_output(ar->mixer, data, ar->buffer_size, delay_ms);
     344       34299 :                 gf_mixer_lock(ar->mixer, GF_FALSE);
     345             : 
     346       34299 :                 if (!written) {
     347       28671 :                         if (!ar->non_rt_output) written = ar->buffer_size;
     348       28671 :                         else if (ar->scene_ready && ar->nb_audio_objects && !gf_mixer_buffering(ar->mixer) ) written = ar->buffer_size;
     349             :                         else {
     350          26 :                                 gf_filter_pck_truncate(pck, 0);
     351          26 :                                 gf_filter_pck_discard(pck);
     352          26 :                                 break;
     353             :                         }
     354             :                 }
     355             : 
     356       34273 :                 if (written<ar->buffer_size) {
     357          79 :                         gf_filter_pck_truncate(pck, written);
     358             :                 }
     359       34273 :                 gf_filter_pck_set_sap(pck, GF_FILTER_SAP_1);
     360       34273 :                 gf_filter_pck_set_cts(pck, ar->current_time_sr);
     361       34273 :                 dur = written / ar->bytes_per_samp;
     362       34273 :                 gf_filter_pck_set_duration(pck, dur);
     363       34273 :                 GF_LOG(GF_LOG_INFO, GF_LOG_AUDIO, ("[Compositor] Send audio frame TS "LLU" nb samples %d - AR clock %u - delay %d ms\n", ar->current_time_sr, dur, ar->current_time, delay_ms));
     364             : 
     365       34273 :                 ar->nb_bytes_out += written;
     366       34273 :                 gf_filter_pck_send(pck);
     367             : 
     368       34273 :                 ar->bytes_requested += written;
     369       34273 :                 ar->current_time_sr = ar->time_at_last_config_sr + (u32) (ar->bytes_requested / ar->bytes_per_samp);
     370       34273 :                 ar->current_time = ar->time_at_last_config + (u32) (ar->bytes_requested * 1000 / ar->bytes_per_second);
     371             : 
     372       34273 :                 max_send--;
     373             : 
     374             :                 //this is a safety for non blocking mode, otherwise the pid_would_block is enough
     375       34273 :                 if (ar->nb_bytes_out > ar->max_bytes_out)
     376             :                         break;
     377             :         }
     378             : }
     379             : 
     380             : 
     381      124704 : void gf_sc_ar_send_or_reconfig(GF_AudioRenderer *ar)
     382             : {
     383             :         Bool frozen;
     384      124704 :         if (ar->need_reconfig) {
     385          20 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] Reconfiguring audio mixer\n"));
     386             :                 /*lock mixer*/
     387          20 :                 gf_mixer_lock(ar->mixer, GF_TRUE);
     388             : 
     389          20 :                 frozen = ar->Frozen;
     390          20 :                 if (!frozen )
     391          20 :                         gf_ar_pause(ar, GF_TRUE, GF_TRUE, GF_FALSE);
     392             : 
     393          20 :                 ar->need_reconfig = GF_FALSE;
     394          20 :                 gf_ar_setup_output_format(ar);
     395             : 
     396          20 :                 if (!frozen)
     397          20 :                         gf_ar_pause(ar, GF_FALSE, GF_TRUE, GF_FALSE);
     398             : 
     399             :                 /*unlock mixer*/
     400          20 :                 gf_mixer_lock(ar->mixer, GF_FALSE);
     401             :         }
     402      124704 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Compositor] sending audio packets\n"));
     403      124704 :         gf_ar_send_packets(ar);
     404      124704 : }
     405             : 
     406             : #if 0 //unused
     407             : u32 gf_sc_ar_get_delay(GF_AudioRenderer *ar)
     408             : {
     409             :         if (!ar->bytes_per_second) return 0;
     410             :         //try to FIXME, this is not as precise as what we have before using ar->audio_out->GetAudioDelay(ar->audio_out)
     411             :         // since we don't know how much of the first packet data out there has been consumed
     412             :         return 1000 * ar->nb_bytes_out / ar->bytes_per_second;
     413             : }
     414             : #endif
     415             : 
     416        1688 : u32 gf_sc_ar_get_clock(GF_AudioRenderer *ar)
     417             : {
     418        1688 :         return ar->current_time;
     419             : }
     420             : 
     421             : 
     422             : 

Generated by: LCOV version 1.13