I try to refine the code like below(only show the code i modify meaningful),  I 
calculate the each 1ms timer wanted_wpos which I named it wanted_wpos_delta 
first instead of caculate the hole duration wanted_wpos in one time
and summer all of them to calcute the wanted_wpos


   /* calcute each 1ms delta wanted pos */

    int64_t wanted_wpos_delta = hda_bytes_per_second(st) * (now - 
st->last_start) 

                    / NANOSECONDS_PER_SECOND;



    /* summer it all to wanted_wpos */
    st->wanted_wpos += wanted_wpos_delta;


    error_report("delta = %ld, wanted = %ld wpos = %ld, 
now=%ld,buft=%ld,last=%ld\n",
            wanted_wpos_delta, st->wanted_wpos, wpos, now, buft_start, 
st->last_start);


    /* mark the last timer timestamp */
    st->last_start = now; 



in the function hda_timer_sync_adjust, i add the corr to the last_start value

    st->last_start += corr;



the output  log like below:
2023-08-17T05:29:17.730066Z qemu-fix: delta = 196, wanted = 22027480 wpos = 
22027284, now=213350279414,buft=97328733406,last=213349253800
2023-08-17T05:29:17.731090Z qemu-fix: delta = 196, wanted = 22027676 wpos = 
22027480, now=213351303295,buft=97328733406,last=213350279414
2023-08-17T05:29:17.732179Z qemu-fix: delta = 209, wanted = 22027884 wpos = 
22027676, now=213352392204,buft=97328733406,last=213351303295
2023-08-17T05:29:17.733201Z qemu-fix: delta = 196, wanted = 22028080 wpos = 
22027884, now=213353414012,buft=97328733406,last=213352392204
2023-08-17T05:29:17.734234Z qemu-fix: delta = 198, wanted = 22028276 wpos = 
22028080, now=213354447484,buft=97328733406,last=213353414012


I currently test with playback, it works and seems to work as expected.


What about this solution for this bug? any suggestion for me?












在 2023-08-16 15:04:14,"Volker Rümelin" <[email protected]> 写道:
>Cc: [email protected]
>
>> cc Volker Rümelin
>>
>> ==========================================
>>
>> so I was curious about:
>> 1. why using wpos, rpos which will increasing along the time, which 
>> may overflow in the feature time?
>
>wpos and rpos are 64 bit integers. At a sample rate of 96kHz and with 32 
>bit stereo audio frames they overflow after 2^63 bytes / (8 bytes/frame 
>* 96000 frames/s) = 1.2E13 s = 380561.23 years. I don't think you will 
>notice an overflow.
>
>But you're right anyway. The wanted_rpos and wanted_wpos calculation 
>overflows quite early. At a sample rate of 44100kHz and with 16 bit 
>stereo samples the multiplication hda_bytes_per_second(st) * (now - 
>buft_start) overflows after 2^63 bytes / 176400 bytes/ns = 5,23E13 ns = 
>14.58 hours.
>
>I don't think your fix below is correct. There are certainly ways to 
>prevent the overflow without resetting the buffer.
>
>> 2. how to fix the wanted_wpos or wanted_rpos, I current don't 
>> understand the  wanted_pos mean and how it work to optimize the codec
>
>This is a jitter-buffer implementation to decouple the audio backend 
>updates from the hda device updates. The code splits large  >10ms sized 
>audio packets into 1ms sized audio packets.
>
>With best regards,
>Volker
>
>> =======================================================================================================
>>
>> Currently  I got Playback and Capture issue
>>
>> I test Playing and recoding for a very long time, Playback issue is 
>> hard to reproduce, Capture issue is easy to reproduce for recording 
>> about 14 hours
>>
>> Playback issue current can only be found on qemu 2.11, which I found 
>> the code below (remove some unnecessary)
>>
>> wanted_wpos overflow, and is always little then the wpos,(current wpos 
>> - rpos = 0) so qemu will no long get data from vm, as a result
>>
>> static void hda_audio_output_timer(void *opaque)
>> {
>> .............
>>
>>     int64_t wanted_wpos = hda_bytes_per_second(st) * (now - 
>> buft_start) ============> overflow here
>>                           / NANOSECONDS_PER_SECOND;
>>     wanted_wpos &= -4; /* IMPORTANT! clip to frames */
>>
>>     if (wanted_wpos <= wpos) {
>>         /* we already received the data */
>>         goto out_timer;
>>     }
>> }
>>
>>
>> Capture issue: Just record all the time
>> (i using qemu 6.0 to test) I add code below to the input callback 
>> function like below, the issue dispear
>> hda_audio_input_cb
>>     if (wpos - rpos == B_SIZE) {
>>         /* drop buffer, reset timer adjust */
>>         st->rpos = 0;
>>         st->wpos = 0;
>>         st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>>         error_report("input drop buffer, reset timer adjust\n");
>>         return;
>>     }
>>
>>
>>
>>
>>
>>

Reply via email to