From 1914bcd81ea7ddadce18bf5280cb9f5ec1cdb4c8 Mon Sep 17 00:00:00 2001
From: cdu <865241727@qq.com>
Date: Sat, 13 Jan 2024 05:14:04 +0800
Subject: [PATCH] fix segment fault in /doc/examples/decode_audio.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

    /*When it is not a planar arrangement, data[1] is empty,
    and all the data is interleaved in data[0].
    This can result in a segmentation fault when accessing data[ch] .*/

    //So I delete the code below:
    for (i = 0; i < frame->nb_samples; i++)
        for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
            fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);

    //And I write this instead
        // L R data order
    if (av_sample_fmt_is_planar(dec_ctx->sample_fmt))
    {
        // planar：LLL...RRR... in different data[ch]
        for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
        {
            fwrite(frame->data[ch], 1, frame->linesize[0], outfile); // only linesize[0] has data.
        }
    }
    else
    {
        // not planar：LRLR...all in data[0]
        fwrite(frame->data[0], 1, frame->linesize[0], outfile);
    }
---
 doc/examples/decode_audio.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c
index bcb3d87a69..ed5bebeaad 100644
--- a/doc/examples/decode_audio.c
+++ b/doc/examples/decode_audio.c
@@ -72,8 +72,8 @@ static int get_format_from_sample_fmt(const char **fmt,
 static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
                    FILE *outfile)
 {
-    int i, ch;
-    int ret, data_size;
+    int  ch;
+    int ret;
 
     /* send the packet with the compressed data to the decoder */
     ret = avcodec_send_packet(dec_ctx, pkt);
@@ -83,23 +83,31 @@ static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
     }
 
     /* read all the output frames (in general there may be any number of them */
-    while (ret >= 0) {
+    while (ret >= 0)
+    {
         ret = avcodec_receive_frame(dec_ctx, frame);
         if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
             return;
-        else if (ret < 0) {
+        else if (ret < 0)
+        {
             fprintf(stderr, "Error during decoding\n");
             exit(1);
         }
-        data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
-        if (data_size < 0) {
-            /* This should not occur, checking just for paranoia */
-            fprintf(stderr, "Failed to calculate data size\n");
-            exit(1);
-        }
-        for (i = 0; i < frame->nb_samples; i++)
+
+        // L R data order
+        if (av_sample_fmt_is_planar(dec_ctx->sample_fmt))
+        {
+            // planar：LLL...RRR... in different data[ch]
             for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
-                fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
+            {
+                fwrite(frame->data[ch], 1, frame->linesize[0], outfile); // only linesize[0] has data.
+            }
+        }
+        else
+        {
+            // not planar：LRLR...all in data[0]
+            fwrite(frame->data[0], 1, frame->linesize[0], outfile);
+        }
     }
 }
 
-- 
2.34.1

