[FFmpeg-devel] [PATCH] experimental multichannel cook support

Michael Niedermayer michaelni
Mon Jan 26 00:20:35 CET 2009


On Sat, Jan 24, 2009 at 07:18:04PM +0100, Sascha Sommer wrote:
> Hi,
> 
> while testing the wmapro decoder I stumbled over a matroska file with an 
> additional realaudio cook 5.1 track. I then realized that the ffmpeg decoder 
> does not yet support multichannel cook files.
> It looks like for multichannel files several mono or stereo packets are 
> concatenated together. The same goes for the extra data of the packets. The 
> per subpacket extradata seems to be identical to the joint stereo version 
> apart from an additional integer field that looks like some kind of channel 
> mask. The lengths of the individual mono or stereo subpackets are stored at 
> the end of the surrounding packet.
> 
> So here is an experimental patch to make it work.
> Cleanup + channel layout handling still todo.
> 
> I'll be busy with wmapro so I also wouldn't mind if someone else wants to 
> finish the patch.

if someone wants to cleanup/split/... it here are some trivial things to fix


trailing whitespace
cook5.1.patch:551:+		
cook5.1.patch:552:+    /* estimate subpacket sizes */	
cook5.1.patch:554:+	
cook5.1.patch:730:+			
cook5.1.patch:733:+ 
cook5.1.patch:747:+	    }		
cook5.1.patch:748:+	     av_log(NULL,AV_LOG_ERROR,"total %i\n",q->subpacket[s].total_subbands);		
cook5.1.patch:754:+			

tabs
cook5.1.patch:551:+		
cook5.1.patch:552:+    /* estimate subpacket sizes */	
cook5.1.patch:554:+	
cook5.1.patch:574:+//	break;
cook5.1.patch:730:+			
cook5.1.patch:735:+	    	q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start;
cook5.1.patch:736:+            	q->subpacket[s].joint_stereo = 1;
cook5.1.patch:747:+	    }		
cook5.1.patch:748:+	     av_log(NULL,AV_LOG_ERROR,"total %i\n",q->subpacket[s].total_subbands);		
cook5.1.patch:754:+			

Missing context in av_log
cook5.1.patch:140:+            av_log(NULL,AV_LOG_DEBUG,"subpacket %i Joint-stereo VLC used.\n",i);
cook5.1.patch:157:+//av_log(NULL,AV_LOG_ERROR,"initial off %i\n",off);
cook5.1.patch:375:+//    av_log(NULL,AV_LOG_ERROR,"decouple info %i %i %i\n",get_bits_count(&q->gb),p->subbands,p->js_subband_start);
cook5.1.patch:585:+    av_log(NULL,AV_LOG_ERROR,"cookversion=%x\n",q->subpacket[0].cookversion);
cook5.1.patch:689:+    av_log(NULL,AV_LOG_DEBUG,"subpacket[%i].cookversion=%x\n",s,q->subpacket[s].cookversion);
cook5.1.patch:748:+	     av_log(NULL,AV_LOG_ERROR,"total %i\n",q->subpacket[s].total_subbands);		

 Non doxy comments
cook5.1.patch:29:+    VLC                 ccpl;             //channel coupling
cook5.1.patch:30:+    int                 joint_stereo;
cook5.1.patch:31:+    int                 bits_per_subpacket;
--
cook5.1.patch:33:+    int                 numvector_size;                //1 << log2_numvector_size;
cook5.1.patch-34-+
cook5.1.patch:35:+    float               mono_previous_buffer1[1024];
--
cook5.1.patch-37-+    /* gain buffers */
cook5.1.patch:38:+    cook_gains          gains1;
cook5.1.patch:39:+    cook_gains          gains2;


> 
> Regards
> 
> Sascha

> Index: cook.c
> ===================================================================
> --- cook.c	(revision 16545)
> +++ cook.c	(working copy)
> @@ -61,6 +61,7 @@
>  #define MC_COOK         0x2000000   //multichannel Cook, not supported
>  
>  #define SUBBAND_SIZE    20
> +#define MAX_SUBPACKETS     5
>  //#define COOKDEBUG
>  

vertical align

>  typedef struct {
> @@ -68,6 +69,37 @@
>      int *previous;
>  } cook_gains;
>  
> +typedef struct {
> +    int                 ch_idx;
> +    int                 size;
> +    int                 num_channels;
> +    int                 cookversion;
> +    int                 samples_per_frame;
> +    int                 subbands;
> +    int                 js_subband_start;
> +    int                 js_vlc_bits;
> +    int                 samples_per_channel;
> +    int                 log2_numvector_size;
> +    unsigned int        channel_mask;
> +    VLC                 ccpl;             //channel coupling
> +    int                 joint_stereo;
> +    int                 bits_per_subpacket;
> +    int                 total_subbands;
> +    int                 numvector_size;                //1 << log2_numvector_size;
> +
> +    float               mono_previous_buffer1[1024];
> +    float               mono_previous_buffer2[1024];
> +    /* gain buffers */
> +    cook_gains          gains1;
> +    cook_gains          gains2;
> +    int                 gain_1[9];
> +    int                 gain_2[9];
> +    int                 gain_3[9];
> +    int                 gain_4[9];
> +
> +} COOKSubpacket;
> +
> +
>  typedef struct cook {
>      /*
>       * The following 5 functions provide the lowlevel arithmetic on

this split out should be a seperate patch

[...]
> @@ -202,6 +216,9 @@
>  }
>  
>  
> +
> +
> +
>  static int init_cook_vlc_tables(COOKContext *q) {
>      int i, result;
>  

empty lines


> @@ -218,17 +235,20 @@
>              cvh_huffcodes[i], 2, 2, 0);
>      }
>  
> -    if (q->nb_channels==2 && q->joint_stereo==1){
> -        result |= init_vlc (&q->ccpl, 6, (1<<q->js_vlc_bits)-1,
> -            ccpl_huffbits[q->js_vlc_bits-2], 1, 1,
> -            ccpl_huffcodes[q->js_vlc_bits-2], 2, 2, 0);
> -        av_log(NULL,AV_LOG_DEBUG,"Joint-stereo VLC used.\n");
> +    for(i=0;i<q->num_subpackets;i++){
> +        if (q->subpacket[i].joint_stereo==1){
> +            result |= init_vlc (&q->subpacket[i].ccpl, 6, (1<<q->subpacket[i].js_vlc_bits)-1,
> +            ccpl_huffbits[q->subpacket[i].js_vlc_bits-2], 1, 1,
> +            ccpl_huffcodes[q->subpacket[i].js_vlc_bits-2], 2, 2, 0);
> +            av_log(NULL,AV_LOG_DEBUG,"subpacket %i Joint-stereo VLC used.\n",i);
> +        }
>      }
>  
>      av_log(NULL,AV_LOG_DEBUG,"VLC tables initialized.\n");
>      return result;
>  }
>  
> +
>  static int init_cook_mlt(COOKContext *q) {
>      int j;
>      int mlt_size = q->samples_per_channel;

> @@ -301,6 +321,8 @@
>       * Buffer alignment needs to be checked. */
>  
>      off = (int)((long)inbuffer & 3);
> +//off = 0;
> +//av_log(NULL,AV_LOG_ERROR,"initial off %i\n",off);
>      buf = (const uint32_t*) (inbuffer - off);
>      c = be2me_32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8))));
>      bytes += 3 + off;

debug code


[...]
> @@ -541,7 +564,7 @@
>              f1 = dither_tab[index];
>              if (av_random(&q->random_state) < 0x80000000) f1 = -f1;
>          }
> -        mlt_p[i] = f1 * rootpow2tab[quant_index+63];
> +        mlt_p[i] = f1 * rootpow2tab[(quant_index+63)];
>      }
>  }
>  /**

senselss ()

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

When you are offended at any man's fault, turn to yourself and study your
own failings. Then you will forget your anger. -- Epictetus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090126/cd95163f/attachment.pgp>



More information about the ffmpeg-devel mailing list