#10611: ff_g723_1_gen_dirac_train function enters dead loop
-------------------------------------+-------------------------------------
             Reporter:  songtao      |                    Owner:  (none)
                 Type:  defect       |                   Status:  new
             Priority:  normal       |                Component:
                                     |  undetermined
              Version:  5.1.3        |               Resolution:
             Keywords:  G723_1,      |               Blocked By:
  dead loop                          |
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
Description changed by songtao:

Old description:

> Summary of the bug:
> How to reproduce:
> i create 5 threads to encode/decode G723_1 from different rtp session,
> when there's a high concurrent, it enters died loop.
>
> pstack output, `pitch_lag=0` cases the died loop
> ```
> Thread 1 (Thread 0x7f70ab7fe700 (LWP 640449)):
> #0  ff_g723_1_gen_dirac_train (buf=buf@entry=0x7f70ab7fc850, pitch_lag=0)
> at src/libavcodec/g723_1.c:1154
> #1  0x0000000000642096 in get_fcb_param
> (optim=optim@entry=0x7f70ab7fd2b0,
> impulse_resp=impulse_resp@entry=0x7f70ab7fcf50,
> buf=buf@entry=0x7f709401d238, pulse_cnt=pulse_cnt@entry=5,
> pitch_lag=<optimized out>) at src/libavcodec/g723_1enc.c:840
> #2  0x0000000000646489 in fcb_search (index=1, buf=0x7f709401d238,
> impulse_resp=0x7f70ab7fcf50, p=<optimized out>) at
> src/libavcodec/g723_1enc.c:1022
> #3  g723_1_encode_frame (avctx=<optimized out>, avpkt=<optimized out>,
> frame=<optimized out>, got_packet_ptr=<optimized out>) at
> src/libavcodec/g723_1enc.c:1198
> #4  0x00000000005ea2e1 in encode_simple_internal (avpkt=0x7f70a420c980,
> avctx=0x7f70a44534c0) at src/libavcodec/encode.c:214
> #5  encode_simple_receive_packet (avpkt=<optimized out>, avctx=<optimized
> out>) at src/libavcodec/encode.c:269
> #6  encode_receive_packet_internal (avctx=avctx@entry=0x7f70a44534c0,
> avpkt=0x7f70a420c980) at src/libavcodec/encode.c:303
> #7  0x00000000005ea727 in avcodec_send_frame
> (avctx=avctx@entry=0x7f70a44534c0, frame=frame@entry=0x7f70a40cee00) at
> src/libavcodec/encode.c:380
> ```
> my code, it reads 160 samples from rtp, resamples to 240 samples, then
> send samples to G723_1 encoder
> ```
> static void encode(AVCodecContext *ctx, AVAudioFifo *fifo, AVFrame
> *frame,
>                    AVPacket *pkt, uint8_t *out, size_t *out_size) {
>   int ret;
>   *out_size = 0;
>   // need resample to 240
>   if (fifo != NULL) {
>     add_samples_to_fifo(fifo, &frame->data[0], frame->nb_samples);
>     if (av_audio_fifo_size(fifo) < 240) {
>       return;
>     }
>     // read out 240
>     if (av_audio_fifo_read(fifo, (void **)&frame->data, 240) < 240) {
>       log_error("Could not read data from FIFO");
>       return;
>     }
>     frame->nb_samples = 240;
>   }
>
>   /* send the frame for encoding */
>   ret = avcodec_send_frame(ctx, frame);
>   if (ret < 0) {
>     log_error("Error sending the frame to the encoder");
>     exit(1);
>   }
>
>   /* read all the available output packets (in general there may be any
>    * number of them */
>   while (ret >= 0) {
>     ret = avcodec_receive_packet(ctx, pkt);
>     if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
>       return;
>     } else if (ret < 0) {
>       log_error("Error encoding audio frame");
>       exit(1);
>     }
>
>     memcpy(out, pkt->data, pkt->size);
>     *out_size = pkt->size;
>     av_packet_unref(pkt);
>   }
> }
>
> int ff_encoder_input(ff_encoder_ctx *ff_ctx, uint16_t *data, size_t
> data_size,
>                      uint8_t *out, size_t *out_size) {
>
>   int ret = av_frame_make_writable(ff_ctx->frame);
>   if (ret < 0) {
>     exit(1);
>   }
>   uint16_t *samples = (uint16_t *)ff_ctx->frame->data[0];
>   memcpy(samples, data, data_size * sizeof(uint16_t));
>   ff_ctx->frame->nb_samples = data_size;
>   encode(ff_ctx->c, ff_ctx->fifo, ff_ctx->frame, ff_ctx->pkt, out,
> out_size);
>   return 0;
> }
> ```
>
> {{{
> % git status
> HEAD detached at n5.1
> }}}
> Patches should be submitted to the ffmpeg-devel mailing list and not this
> bug tracker.

New description:

 Summary of the bug:
 How to reproduce:
 i create 5 threads to encode/decode G723_1 from different rtp session,
 when there's a high concurrent, it enters died loop.

 pstack output, `pitch_lag=0` cases the died loop
 {{{
 Thread 1 (Thread 0x7f70ab7fe700 (LWP 640449)):
 #0  ff_g723_1_gen_dirac_train (buf=buf@entry=0x7f70ab7fc850, pitch_lag=0)
 at src/libavcodec/g723_1.c:1154
 #1  0x0000000000642096 in get_fcb_param (optim=optim@entry=0x7f70ab7fd2b0,
 impulse_resp=impulse_resp@entry=0x7f70ab7fcf50,
 buf=buf@entry=0x7f709401d238, pulse_cnt=pulse_cnt@entry=5,
 pitch_lag=<optimized out>) at src/libavcodec/g723_1enc.c:840
 #2  0x0000000000646489 in fcb_search (index=1, buf=0x7f709401d238,
 impulse_resp=0x7f70ab7fcf50, p=<optimized out>) at
 src/libavcodec/g723_1enc.c:1022
 #3  g723_1_encode_frame (avctx=<optimized out>, avpkt=<optimized out>,
 frame=<optimized out>, got_packet_ptr=<optimized out>) at
 src/libavcodec/g723_1enc.c:1198
 #4  0x00000000005ea2e1 in encode_simple_internal (avpkt=0x7f70a420c980,
 avctx=0x7f70a44534c0) at src/libavcodec/encode.c:214
 #5  encode_simple_receive_packet (avpkt=<optimized out>, avctx=<optimized
 out>) at src/libavcodec/encode.c:269
 #6  encode_receive_packet_internal (avctx=avctx@entry=0x7f70a44534c0,
 avpkt=0x7f70a420c980) at src/libavcodec/encode.c:303
 #7  0x00000000005ea727 in avcodec_send_frame
 (avctx=avctx@entry=0x7f70a44534c0, frame=frame@entry=0x7f70a40cee00) at
 src/libavcodec/encode.c:380
 }}}

 my code, it reads 160 samples from rtp, resamples to 240 samples, then
 send samples to G723_1 encoder

 {{{
 static void encode(AVCodecContext *ctx, AVAudioFifo *fifo, AVFrame *frame,
                    AVPacket *pkt, uint8_t *out, size_t *out_size) {
   int ret;
   *out_size = 0;
   // need resample to 240
   if (fifo != NULL) {
     add_samples_to_fifo(fifo, &frame->data[0], frame->nb_samples);
     if (av_audio_fifo_size(fifo) < 240) {
       return;
     }
     // read out 240
     if (av_audio_fifo_read(fifo, (void **)&frame->data, 240) < 240) {
       log_error("Could not read data from FIFO");
       return;
     }
     frame->nb_samples = 240;
   }

   /* send the frame for encoding */
   ret = avcodec_send_frame(ctx, frame);
   if (ret < 0) {
     log_error("Error sending the frame to the encoder");
     exit(1);
   }

   /* read all the available output packets (in general there may be any
    * number of them */
   while (ret >= 0) {
     ret = avcodec_receive_packet(ctx, pkt);
     if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
       return;
     } else if (ret < 0) {
       log_error("Error encoding audio frame");
       exit(1);
     }

     memcpy(out, pkt->data, pkt->size);
     *out_size = pkt->size;
     av_packet_unref(pkt);
   }
 }

 int ff_encoder_input(ff_encoder_ctx *ff_ctx, uint16_t *data, size_t
 data_size,
                      uint8_t *out, size_t *out_size) {

   int ret = av_frame_make_writable(ff_ctx->frame);
   if (ret < 0) {
     exit(1);
   }
   uint16_t *samples = (uint16_t *)ff_ctx->frame->data[0];
   memcpy(samples, data, data_size * sizeof(uint16_t));
   ff_ctx->frame->nb_samples = data_size;
   encode(ff_ctx->c, ff_ctx->fifo, ff_ctx->frame, ff_ctx->pkt, out,
 out_size);
   return 0;
 }
 }}}


 {{{
 % git status
 HEAD detached at n5.1
 }}}
 Patches should be submitted to the ffmpeg-devel mailing list and not this
 bug tracker.

--
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/10611#comment:1>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
_______________________________________________
FFmpeg-trac mailing list
FFmpeg-trac@avcodec.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-trac

To unsubscribe, visit link above, or email
ffmpeg-trac-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to