[codec] Questions about FEC

Alfons Martin <alfons.martin@symonics.com> Wed, 17 April 2013 11:11 UTC

Return-Path: <alfons.martin@symonics.com>
X-Original-To: codec@ietfa.amsl.com
Delivered-To: codec@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 1C8A221F8960 for <codec@ietfa.amsl.com>; Wed, 17 Apr 2013 04:11:22 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.901
X-Spam-Level:
X-Spam-Status: No, score=-1.901 tagged_above=-999 required=5 tests=[AWL=0.365, BAYES_00=-2.599, IP_NOT_FRIENDLY=0.334]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zrGqWdQ-P4I0 for <codec@ietfa.amsl.com>; Wed, 17 Apr 2013 04:11:21 -0700 (PDT)
Received: from oproxy6-pub.bluehost.com (oproxy6-pub.bluehost.com [67.222.54.6]) by ietfa.amsl.com (Postfix) with SMTP id 4447121F894B for <codec@ietf.org>; Wed, 17 Apr 2013 04:11:21 -0700 (PDT)
Received: (qmail 31550 invoked by uid 0); 17 Apr 2013 11:10:59 -0000
Received: from unknown (HELO box785.bluehost.com) (66.147.244.85) by cpoproxy3.bluehost.com with SMTP; 17 Apr 2013 11:10:59 -0000
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=symonics.com; s=default; h=Content-Transfer-Encoding:Content-Type:Subject:CC:To:MIME-Version:From:Date:Message-ID; bh=FKpPADwEjiD0F2Iab4sabtV2J7UzNHwXyI4KKvIowjw=; b=TFMnn5ijlQe75IL5jTOwgD0TsiQxcUPXytMWtdB2w4QKt9NFX/2nBCF30UfmtBRhkRZkq/BgnRZaSj+8N0kp6wsKwWNhjW+77S4iJYLyFLfeLxB2eOsNk8LvzSZQYQXd;
Received: from [134.2.173.2] (port=46889) by box785.bluehost.com with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.80) (envelope-from <alfons.martin@symonics.com>) id 1USQGR-0006YH-HL; Wed, 17 Apr 2013 05:10:59 -0600
Message-ID: <516E8335.6080800@symonics.com>
Date: Wed, 17 Apr 2013 13:10:45 +0200
From: Alfons Martin <alfons.martin@symonics.com>
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130329 Thunderbird/17.0.5
MIME-Version: 1.0
To: codec@ietf.org
Content-Type: text/plain; charset="ISO-8859-1"; format="flowed"
Content-Transfer-Encoding: 8bit
X-Identified-User: {1573:box785.bluehost.com:soniconb:symonics.com} {sentby:smtp auth 134.2.173.2 authed with alfons.martin+symonics.com}
Cc: Patrick.Schreiner@symonics.com
Subject: [codec] Questions about FEC
X-BeenThere: codec@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Codec WG <codec.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/codec>, <mailto:codec-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/codec>
List-Post: <mailto:codec@ietf.org>
List-Help: <mailto:codec-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/codec>, <mailto:codec-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 17 Apr 2013 11:11:22 -0000

Sorry if you receive multiple copies.

Dear Jean-Marc,

I've got some problems with the FEC of Opus using the current stable 
release (1.02) from the repository.
According to my understanding of FEC, the FEC information of the next 
packet is used to restore the former lost packet. But if I use the 
"packet_size of the lost packet" to invoke FEC for it, as recomended in 
the API documentation, the function opus_decode_native uses PLC because 
of line 748 in file opus_decoder.c:

"if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || 
st->mode == MODE_CELT_ONLY){"

If I use "max_frame_size", like in the opus_demo invokation of 
opus_decode (file opus_demo.c, line 714), FEC is used for the last 
packet. But the recursive call inserts PLC for the other packets until 
"max_frame_size" is reached.
This behaviour leads to a fragmented output-file.

If I use twice the "packet_size of the lost packet" to invoke 
opus_decode, PLC and FEC still seem to be called for only 1 lost packet 
and the outputfile is fragmented again.

So I changed file opus_decoder.c line 748

if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || 
st->mode == MODE_CELT_ONLY)

to

if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || 
st->mode == MODE_CELT_ONLY)

But then

/* Otherwise, run the PLC on everything except the size for which we 
might have FEC */
duration_copy = st->last_packet_duration;
ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 
0, 0, NULL);

is called anyway, and Opus never reaches the FEC part.

I then changed the code to the following and it worked, but I'm not sure 
if I missed sth.:

opus_decoder.c:738-764

     if (decode_fec)
    {
       int duration_copy;
       int ret;
       /* If no FEC can be present, run the PLC (recursive call) */
       if (frame_size < packet_frame_size || packet_mode == 
MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY){
           return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, 
NULL);
       }
       if(frame_size == packet_frame_size && packet_mode != 
MODE_CELT_ONLY && st->mode != MODE_CELT_ONLY){
             /* Complete with FEC */
             st->mode = packet_mode;
             st->bandwidth = packet_bandwidth;
             st->frame_size = packet_frame_size;
             st->stream_channels = packet_stream_channels;
             ret = opus_decode_frame(st, data, size[0], 
pcm+st->channels*(frame_size-packet_frame_size),
                   packet_frame_size, 1);
             if (ret<0)
                return ret;
       }else{
           /* Otherwise, run the PLC on everything except the size for 
which we might have FEC */
           duration_copy = st->last_packet_duration;
           ret = opus_decode_native(st, NULL, 0, pcm, 
frame_size-packet_frame_size, 0, 0, NULL);
           if (ret<0)
           {
              st->last_packet_duration = duration_copy;
              return ret;
           }
       }
       st->last_packet_duration = frame_size;
       return frame_size;
    }

What's your opinion on this?

Regards,
Alfons

-- 
Symonics GmbH

Sand 13

72076 Tübingen

Tel +49 7071 2970573

Fax +49 7071 5681309

Email: Alfons.Martin@symonics.com


Geschäftsführer/Presidents: Michael Haun, Dr. Christian Hoene, Patrick 
Schreiner

Sitz der Gesellschaft/Place of Business: Tübingen

Registereintrag/Commercial Register: Amtsgericht Stuttgart, HRB 739918