From wschildbach at real.com  Wed Jun  9 07:12:12 2004
From: wschildbach at real.com (Wolfgang Schildbach)
Date: Wed Jun  9 07:12:26 2004
Subject: [Common-dev] CR: helix.bif
Message-ID: <5.1.0.14.2.20040609160841.03931fd0@mailone.real.com>

Synopsis:
   Target all_dist_components in helix.bif is broken

Overview:
   When the BIF files were adapted for automatic dist lib generation, some 
targets were removed and renamed. Apparently, this diff was forgotten.

Without this patch, target all_dist_components is broken because 
datatype_dist_rm_audio_codec_ra8lbr does not exist anymore.

- Wolfgang

Index: helix.bif
===================================================================
RCS file: /cvsroot/common/build/BIF/helix.bif,v
retrieving revision 1.421
diff -u -w -r1.421 helix.bif
--- helix.bif   7 Jun 2004 14:11:23 -0000       1.421
+++ helix.bif   9 Jun 2004 14:08:32 -0000
@@ -6372,7 +6372,8 @@
          datatype_dist_rm_fileformat
          datatype_dist_rm_audio_common
          datatype_dist_rm_audio_renderer
-        datatype_dist_rm_audio_codec_ra8lbr
+        datatype_dist_rm_audio_codec_ra8lbr_decoder
+        datatype_dist_rm_audio_codec_ra8lbr_fltpt_encoder
          datatype_dist_rm_audio_codec_sipro
          datatype_dist_rm_audio_codec_ra8hbr
          datatype_dist_rm_video_common

-
- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
- fon +49-(0)911-46 23 621, email wschildbach@real.com



From ehyche at real.com  Wed Jun  9 07:42:50 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun  9 07:42:58 2004
Subject: [Common-dev] CR: helix.bif
In-Reply-To: <5.1.0.14.2.20040609160841.03931fd0@mailone.real.com>
Message-ID: <5.1.0.14.2.20040609104218.02c57be8@mailone.real.com>


Looks good. This must have been my mistake - I did most
of the auto-dist-lib stuff. Thanks for fixing this.

Eric

At 04:12 PM 6/9/2004 +0200, Wolfgang Schildbach wrote:
>Synopsis:
>   Target all_dist_components in helix.bif is broken
>
>Overview:
>   When the BIF files were adapted for automatic dist lib generation, some 
> targets were removed and renamed. Apparently, this diff was forgotten.
>
>Without this patch, target all_dist_components is broken because 
>datatype_dist_rm_audio_codec_ra8lbr does not exist anymore.
>
>- Wolfgang
>
>Index: helix.bif
>===================================================================
>RCS file: /cvsroot/common/build/BIF/helix.bif,v
>retrieving revision 1.421
>diff -u -w -r1.421 helix.bif
>--- helix.bif   7 Jun 2004 14:11:23 -0000       1.421
>+++ helix.bif   9 Jun 2004 14:08:32 -0000
>@@ -6372,7 +6372,8 @@
>          datatype_dist_rm_fileformat
>          datatype_dist_rm_audio_common
>          datatype_dist_rm_audio_renderer
>-        datatype_dist_rm_audio_codec_ra8lbr
>+        datatype_dist_rm_audio_codec_ra8lbr_decoder
>+        datatype_dist_rm_audio_codec_ra8lbr_fltpt_encoder
>          datatype_dist_rm_audio_codec_sipro
>          datatype_dist_rm_audio_codec_ra8hbr
>          datatype_dist_rm_video_common
>
>-
>- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
>- fon +49-(0)911-46 23 621, email wschildbach@real.com
>
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From wschildbach at helixcommunity.org  Wed Jun  9 08:21:05 2004
From: wschildbach at helixcommunity.org (Wolfgang Schildbach)
Date: Wed Jun  9 08:21:19 2004
Subject: [Common-dev] CR: helix.bif
In-Reply-To: <5.1.0.14.2.20040609104218.02c57be8@mailone.real.com>
References: <5.1.0.14.2.20040609160841.03931fd0@mailone.real.com>
Message-ID: <5.1.0.14.2.20040609172039.02993240@mailone.real.com>

Thanks for the review, Eric. This is now checked in.

- Wolfgang

At 10:42 AM 6/9/2004 -0400, Eric Hyche wrote:

>Looks good. This must have been my mistake - I did most
>of the auto-dist-lib stuff. Thanks for fixing this.
>
>Eric
>
>At 04:12 PM 6/9/2004 +0200, Wolfgang Schildbach wrote:
>>Synopsis:
>>   Target all_dist_components in helix.bif is broken
>>
>>Overview:
>>   When the BIF files were adapted for automatic dist lib generation, 
>> some targets were removed and renamed. Apparently, this diff was forgotten.
>>
>>Without this patch, target all_dist_components is broken because 
>>datatype_dist_rm_audio_codec_ra8lbr does not exist anymore.
>>
>>- Wolfgang
>>
>>Index: helix.bif
>>===================================================================
>>RCS file: /cvsroot/common/build/BIF/helix.bif,v
>>retrieving revision 1.421
>>diff -u -w -r1.421 helix.bif
>>--- helix.bif   7 Jun 2004 14:11:23 -0000       1.421
>>+++ helix.bif   9 Jun 2004 14:08:32 -0000
>>@@ -6372,7 +6372,8 @@
>>          datatype_dist_rm_fileformat
>>          datatype_dist_rm_audio_common
>>          datatype_dist_rm_audio_renderer
>>-        datatype_dist_rm_audio_codec_ra8lbr
>>+        datatype_dist_rm_audio_codec_ra8lbr_decoder
>>+        datatype_dist_rm_audio_codec_ra8lbr_fltpt_encoder
>>          datatype_dist_rm_audio_codec_sipro
>>          datatype_dist_rm_audio_codec_ra8hbr
>>          datatype_dist_rm_video_common
>>
>>-
>>- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
>>- fon +49-(0)911-46 23 621, email wschildbach@real.com
>>
>>
>>
>>_______________________________________________
>>Common-dev mailing list
>>Common-dev@lists.helixcommunity.org
>>http://lists.helixcommunity.org/mailman/listinfo/common-dev
>
>======================================
>M. Eric Hyche (ehyche@real.com)
>Core Technologies
>RealNetworks, Inc.
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

-
- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
- email wschildbach@helixcommunity.org



From nhart at real.com  Wed Jun  9 15:33:26 2004
From: nhart at real.com (Nicholas Hart)
Date: Wed Jun  9 15:33:33 2004
Subject: [Common-dev] CR: yuv.h, math64.h
Message-ID: <1086820406.13498.189.camel@linicks.dev.prognet.com>


I'm once again resurrecting a long-dead thread.  We had tentatively
settled on making this change to yuv.h, but contingent upon putting in
place some asserts to ensure that the RGB_MAX, VMAX and UMAX hard-coded
values match the old calculations.  The reason for the change is that
the buggy Sun compiler on Solaris x86 for some reason doesn't like these
complicated calculations in a macro.

I've also attached a change to math64.h.  Both of these should get the
helix player building on solaris x86.

I'd like to commit these to hxclient_1_3_0_neptunex and HEAD.


-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com
-------------- next part --------------
? Makefile
? a
? colorcvt.exp
? cvt1.exp
? dbg
? dllumake.mak
? dllumake.upp
? hxltcolor.exp
? leanumake.mak
? leanumake.upp
? libumake.mak
? libumake.upp
? noplusumake.mak
? noplusumake.upp
? umakefil.upp
Index: setclrs.c
===================================================================
RCS file: /cvsroot/video/colconverter/setclrs.c,v
retrieving revision 1.2
diff -u -w -r1.2 setclrs.c
--- setclrs.c	7 Jan 2003 21:11:05 -0000	1.2
+++ setclrs.c	9 Jun 2004 21:05:46 -0000
@@ -196,6 +196,16 @@
 
 void SetDestI420Colors (float brightness, float contrast, float saturation, float hue)
 {
+    /*
+     * Santiy check our macros.  Sun compiler limitations on Solaris-x86
+     * prevent us from using complicated arithmetic in these macros, so
+     * we hard-code the resulting values in yuv.h instead.  These asserts
+     * should ensure that those values are equal to the calculated ones.
+     */
+    HX_ASSERT(RGB_MAX == ((1U << 8) - 1));
+    HX_ASSERT(VMAX == (int)((double)(1.-CCIR601_YRCOEF) * RGB_MAX + 1));
+    HX_ASSERT(UMAX == (int)((double)(1.-CCIR601_YBCOEF) * RGB_MAX + 1));
+
     /* currently, we do not support color adjustments when destination
      * format is I420 (YCrCb 4:1:1), and conversion is always CCIR 601-2 -
      * compliant (regardless of values of papameters). */
Index: yuv.h
===================================================================
RCS file: /cvsroot/video/colconverter/yuv.h,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 yuv.h
--- yuv.h	18 Oct 2002 02:04:47 -0000	1.1.1.1
+++ yuv.h	9 Jun 2004 21:05:46 -0000
@@ -92,7 +92,8 @@
  * Also, we typically will deal with quantized R'G'B' signal, represented
  * by 8-bit quantities for R', G' and B' components:
  */
-#define RGB_MAX ((1U << 8) - 1)
+/*#define RGB_MAX ((1U << 8) - 1)*/
+#define RGB_MAX (0xff)
 
 /*
  * Forward R'G'B'->Y'Cr'Cb' conversion:
@@ -108,9 +109,11 @@
 #define USCALE  ((double)CCIR601_UMAX/RGB_MAX * 0.5/(1.-CCIR601_YBCOEF))
 
 #define YMAX    (RGB_MAX + 3)       /* include max. rounding error */
-#define VMAX    (int)((double)(1.-CCIR601_YRCOEF) * RGB_MAX + 1)
+/*#define VMAX    (int)((double)(1.-CCIR601_YRCOEF) * RGB_MAX + 1)*/
+#define VMAX    134511620
 #define VMIN    VMAX
-#define UMAX    (int)((double)(1.-CCIR601_YBCOEF) * RGB_MAX + 1)
+/*#define UMAX    (int)((double)(1.-CCIR601_YBCOEF) * RGB_MAX + 1)*/
+#define UMAX    134511620
 #define UMIN    UMAX
 
 /* R'G'B' -> Y'Cr'Cb' conversion tables: */
-------------- next part --------------
? a
Index: math64.h
===================================================================
RCS file: /cvsroot/audio/fixptutil/pub/math64.h,v
retrieving revision 1.18
diff -u -w -r1.18 math64.h
--- math64.h	31 Oct 2003 23:14:55 -0000	1.18
+++ math64.h	9 Jun 2004 19:31:49 -0000
@@ -110,7 +110,7 @@
 // GCC / i386
 ///////////////////////////////////////////////////////////////////////////////////////
 
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && defined(__i386__) && !defined(_NO_GNU_AS)
 
 #define HAVE_PLATFORM_MACROS
 
@@ -235,6 +235,44 @@
 #define ASSERT(x)  assert(x)
 #endif
 #endif // defined(__sparc)
+
+#if (defined(__SVR4) && defined(__i386) && (defined(_NO_GNU_AS) || !defined(__GNUC__)) )
+/* No 64bit, no asm provided in some other file..
+ * need normal funcs for sun forte CC + 386 
+ * However... forte's inline assembly for MulShift32 is just as good
+ * as the "hand tuned" gcc version, if you use
+ *  cc -fast
+ */
+static inline int MulDiv64(int a, int b, int c)
+{
+	long long t = (long long)((long long)a * (long long)b) ;
+	return (int)(t / c) ;
+}
+/* Compute (a * b) >> 32, using 64-bit intermediate result */
+static inline int MulShift32(int a, int b)
+{
+	long long res ;
+	res = (long long)((long long)a * (long long)b);
+	return (res>>32);
+}
+
+/* Compute (a * b) >> 31, using 64-bit intermediate result */
+static inline int MulShift31(int a, int b)
+{
+	long long res ;
+	res = (long long)((long long)a * (long long)b);
+	return (res>>31);
+}
+
+/* Compute (a * b) >> 30, using 64-bit intermediate result */
+static inline int MulShift30(int a, int b)
+{
+	long long res ;
+	res = (long long)((long long)a * (long long)b);
+	return (res>>30);
+}
+
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////////////
 // Codewarrior / PowerPC
From gwright at real.com  Wed Jun  9 15:50:00 2004
From: gwright at real.com (Greg Wright)
Date: Wed Jun  9 15:49:27 2004
Subject: [Common-dev] CR: yuv.h, math64.h
References: <1086820406.13498.189.camel@linicks.dev.prognet.com>
Message-ID: <0f4a01c44e74$1894bbf0$ff8317ac@gwright5>

These look OK to me.
--greg.


----- Original Message ----- 
From: "Nicholas Hart" 
To: 
Sent: Wednesday, June 09, 2004 3:33 PM
Subject: [Common-dev] CR: yuv.h, math64.h


> 
> I'm once again resurrecting a long-dead thread.  We had tentatively
> settled on making this change to yuv.h, but contingent upon putting in
> place some asserts to ensure that the RGB_MAX, VMAX and UMAX hard-coded
> values match the old calculations.  The reason for the change is that
> the buggy Sun compiler on Solaris x86 for some reason doesn't like these
> complicated calculations in a macro.
> 
> I've also attached a change to math64.h.  Both of these should get the
> helix player building on solaris x86.
> 
> I'd like to commit these to hxclient_1_3_0_neptunex and HEAD.
> 
> 
> -- 
> Nicholas Hart
> nhart@real.com
> Technical Lead, Helix Player
> https://player.helixcommunity.org
> http://www.real.com
> 


--------------------------------------------------------------------------------


> _______________________________________________
> Common-dev mailing list
> Common-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 

From nhart at real.com  Wed Jun  9 17:19:09 2004
From: nhart at real.com (Nicholas Hart)
Date: Wed Jun  9 17:19:11 2004
Subject: [Common-dev] CN: yuv.h, math64.h
In-Reply-To: <0f4a01c44e74$1894bbf0$ff8317ac@gwright5>
References: <1086820406.13498.189.camel@linicks.dev.prognet.com>
	<0f4a01c44e74$1894bbf0$ff8317ac@gwright5>
Message-ID: <1086826748.12630.220.camel@linicks.dev.prognet.com>

Committed to HEAD and hxclient_1_3_0_neptunex.

On Wed, 2004-06-09 at 15:50, Greg Wright wrote:
> These look OK to me.
> --greg.
> 
> 
> ----- Original Message ----- 
> From: "Nicholas Hart" 
> To: 
> Sent: Wednesday, June 09, 2004 3:33 PM
> Subject: [Common-dev] CR: yuv.h, math64.h
> 
> 
> > 
> > I'm once again resurrecting a long-dead thread.  We had tentatively
> > settled on making this change to yuv.h, but contingent upon putting in
> > place some asserts to ensure that the RGB_MAX, VMAX and UMAX hard-coded
> > values match the old calculations.  The reason for the change is that
> > the buggy Sun compiler on Solaris x86 for some reason doesn't like these
> > complicated calculations in a macro.
> > 
> > I've also attached a change to math64.h.  Both of these should get the
> > helix player building on solaris x86.
> > 
> > I'd like to commit these to hxclient_1_3_0_neptunex and HEAD.
> > 
> > 
> > -- 
> > Nicholas Hart
> > nhart@real.com
> > Technical Lead, Helix Player
> > https://player.helixcommunity.org
> > http://www.real.com
> > 
> 
> 
> --------------------------------------------------------------------------------
> 
> 
> > _______________________________________________
> > Common-dev mailing list
> > Common-dev@lists.helixcommunity.org
> > http://lists.helixcommunity.org/mailman/listinfo/common-dev
> > 
-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com


From wschildbach at helixcommunity.org  Thu Jun 10 01:28:45 2004
From: wschildbach at helixcommunity.org (Wolfgang Schildbach)
Date: Thu Jun 10 01:29:01 2004
Subject: [Common-dev] CR: yuv.h, math64.h
In-Reply-To: <1086820406.13498.189.camel@linicks.dev.prognet.com>
Message-ID: <5.1.0.14.2.20040610102557.034c1c50@mailone.real.com>

Looks good to me. Two questions:

- Where does _NO_GNU_AS come from? Does this come from the .pcf files or 
from the compiler? What does it signify?

- In the colconverter patch,

-#define RGB_MAX ((1U << 8) - 1)
+/*#define RGB_MAX ((1U << 8) - 1)*/
+#define RGB_MAX (0xff)

I wonder if we should explicitly make RGB_MAX unsigned? Off-hand I don't 
know if C might possibly interpret this as a signed char (not good).

- Wolfgang

At 03:33 PM 6/9/2004 -0700, Nicholas Hart wrote:

>I'm once again resurrecting a long-dead thread.  We had tentatively
>settled on making this change to yuv.h, but contingent upon putting in
>place some asserts to ensure that the RGB_MAX, VMAX and UMAX hard-coded
>values match the old calculations.  The reason for the change is that
>the buggy Sun compiler on Solaris x86 for some reason doesn't like these
>complicated calculations in a macro.
>
>I've also attached a change to math64.h.  Both of these should get the
>helix player building on solaris x86.
>
>I'd like to commit these to hxclient_1_3_0_neptunex and HEAD.
>
>
>--
>Nicholas Hart
>nhart@real.com
>Technical Lead, Helix Player
>https://player.helixcommunity.org
>http://www.real.com
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

-
- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
- email wschildbach@helixcommunity.org



From nhart at real.com  Thu Jun 10 10:09:46 2004
From: nhart at real.com (Nicholas Hart)
Date: Thu Jun 10 10:09:51 2004
Subject: [Common-dev] CR: yuv.h, math64.h
In-Reply-To: <5.1.0.14.2.20040610102557.034c1c50@mailone.real.com>
References: <5.1.0.14.2.20040610102557.034c1c50@mailone.real.com>
Message-ID: <1086887386.539.4.camel@linicks.dev.prognet.com>

I'm looping in Philip, who submitted the patch.  I don't actually see
where the _NO_GNU_AS macro is coming from.  Perhaps it isn't needed,
needs to be defined somewhere, or there is an equivalent macro already
available in helix.

Philip?

As for the unsigned RGB_MAX, it sounds fine to me.  I can make that
change if you'd like.


On Thu, 2004-06-10 at 01:28, Wolfgang Schildbach wrote:
> Looks good to me. Two questions:
> 
> - Where does _NO_GNU_AS come from? Does this come from the .pcf files or 
> from the compiler? What does it signify?
> 
> - In the colconverter patch,
> 
> -#define RGB_MAX ((1U << 8) - 1)
> +/*#define RGB_MAX ((1U << 8) - 1)*/
> +#define RGB_MAX (0xff)
> 
> I wonder if we should explicitly make RGB_MAX unsigned? Off-hand I don't 
> know if C might possibly interpret this as a signed char (not good).
> 
> - Wolfgang
> 
> At 03:33 PM 6/9/2004 -0700, Nicholas Hart wrote:
> 
> >I'm once again resurrecting a long-dead thread.  We had tentatively
> >settled on making this change to yuv.h, but contingent upon putting in
> >place some asserts to ensure that the RGB_MAX, VMAX and UMAX hard-coded
> >values match the old calculations.  The reason for the change is that
> >the buggy Sun compiler on Solaris x86 for some reason doesn't like these
> >complicated calculations in a macro.
> >
> >I've also attached a change to math64.h.  Both of these should get the
> >helix player building on solaris x86.
> >
> >I'd like to commit these to hxclient_1_3_0_neptunex and HEAD.
> >
> >
> >--
> >Nicholas Hart
> >nhart@real.com
> >Technical Lead, Helix Player
> >https://player.helixcommunity.org
> >http://www.real.com
> >
> >
> >_______________________________________________
> >Common-dev mailing list
> >Common-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 
> -
> - Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
> - email wschildbach@helixcommunity.org
> 
-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com


From helix at bolthole.com  Thu Jun 10 11:32:59 2004
From: helix at bolthole.com (Philip Brown)
Date: Thu Jun 10 11:33:10 2004
Subject: [Common-dev] CR: yuv.h, math64.h
In-Reply-To: <1086887386.539.4.camel@linicks.dev.prognet.com>;
	from nhart@real.com on Thu, Jun 10, 2004 at 10:09:46AM -0700
References: <5.1.0.14.2.20040610102557.034c1c50@mailone.real.com>
	<1086887386.539.4.camel@linicks.dev.prognet.com>
Message-ID: <20040610113259.C91528@bolthole.com>

On Thu, Jun 10, 2004 at 10:09:46AM -0700, Nicholas Hart wrote:
> I'm looping in Philip, who submitted the patch.  I don't actually see
> where the _NO_GNU_AS macro is coming from.  Perhaps it isn't needed,
> needs to be defined somewhere, or there is an equivalent macro already
> available in helix.
> 
> Philip?



I added it so that it can now become an option in umakecf files.
I set it in sunos-5.8-i386.cf

It is quite needed, to get rid of GNU-assembler specific code when
compiling on x86.
If someone has the sun compilers, they arent using GNU-as.
So the compile will break without that extra #ifndef


From nhart at real.com  Thu Jun 10 11:50:06 2004
From: nhart at real.com (Nicholas Hart)
Date: Thu Jun 10 11:50:08 2004
Subject: [Common-dev] CR: yuv.h, math64.h
In-Reply-To: <20040610113259.C91528@bolthole.com>
References: <5.1.0.14.2.20040610102557.034c1c50@mailone.real.com>
	<1086887386.539.4.camel@linicks.dev.prognet.com>
	<20040610113259.C91528@bolthole.com>
Message-ID: <1086893406.540.47.camel@linicks.dev.prognet.com>

Ok, so we need to add that macro to the sunos-5.8-i386.cf file, or
create two different cf files: one for the sun compiler and one for gcc.


On Thu, 2004-06-10 at 11:32, Philip Brown wrote:
> On Thu, Jun 10, 2004 at 10:09:46AM -0700, Nicholas Hart wrote:
> > I'm looping in Philip, who submitted the patch.  I don't actually see
> > where the _NO_GNU_AS macro is coming from.  Perhaps it isn't needed,
> > needs to be defined somewhere, or there is an equivalent macro already
> > available in helix.
> > 
> > Philip?
> 
> 
> 
> I added it so that it can now become an option in umakecf files.
> I set it in sunos-5.8-i386.cf
> 
> It is quite needed, to get rid of GNU-assembler specific code when
> compiling on x86.
> If someone has the sun compilers, they arent using GNU-as.
> So the compile will break without that extra #ifndef
-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com


From nhart at real.com  Fri Jun 11 13:25:16 2004
From: nhart at real.com (Nicholas Hart)
Date: Fri Jun 11 13:25:17 2004
Subject: [Common-dev] problem compiling audio/limiter
Message-ID: <1086985515.13139.52.camel@linicks.dev.prognet.com>


I'm trying to track down a problem that has shown up on linux in the
last 24 hours.  When trying to play RV we get a missing "colo" component
error.  I suspect that this is due to my recent change to yuv.h and
setclrs.c for solaris x86.  I ran "nm -u" on colorcvt.so and there's an
undefined "HX_ASSERT" symbol.  (Shame on me for assuming that since it
compiled it was a safe change.)

Anyhow, I'm trying to verify my fix in release mode, but for some reason
audio/limiter won't build.  It *will* build in debug mode though.  I get
the exact same results if I back out the change to math64.h (which just
removes the check for _NO_GNU_AS).  Here's the error:

limiter.c: In function `LimiterStereo':
../../audio/fixptutil/pub/math64.h:125: error: impossible register
constraint in `asm'

And the code that it's complaining about:

#if defined(__GNUC__) && defined(__i386__) && !defined(_NO_GNU_AS)

#define HAVE_PLATFORM_MACROS

/* Compute a * b / c, using 64-bit intermediate result */
static __inline__ int MulDiv64(register int x, register int y, register
int z)
{
    int zhi ;
    /* we specify four alternatives here, one for each permutation of
memory or
       register operand in the multiplier and the divisor. All are
commutative in
       the multiplication arguments, one of which needs to be in eax
when we
       start. */
    __asm__ volatile ("imull %3\n\t"
                      "idivl %4"
                      : "=&d,&d,&d,&d" (zhi), "+a,a,a,a" (x)
                      : "%1,%1,%1,%1" (x), "m,r,m,r" (y), "m,m,r,r" (z))
;

    return x ;
}

Anyone have any ideas why this might compile in debug mode but not
release mode?  I verified that this is being compiled in debug mode, so
it's not an issue with the macros that enable compilation of this
function.

BTW, my system_id is linux-2.2-libc6-gcc32-i586.  This builds fine on
the build farm machine w/that id.


-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com


From wschildbach at helixcommunity.org  Mon Jun 14 06:44:43 2004
From: wschildbach at helixcommunity.org (Wolfgang Schildbach)
Date: Mon Jun 14 06:44:57 2004
Subject: [Common-dev] problem compiling audio/limiter
In-Reply-To: <1086985515.13139.52.camel@linicks.dev.prognet.com>
Message-ID: <5.1.0.14.2.20040614152554.032cbb18@mailone.real.com>

At 01:25 PM 6/11/2004 -0700, Nicholas Hart wrote:

>I'm trying to track down a problem that has shown up on linux in the
>last 24 hours.  When trying to play RV we get a missing "colo" component
>error.  I suspect that this is due to my recent change to yuv.h and
>setclrs.c for solaris x86.  I ran "nm -u" on colorcvt.so and there's an
>undefined "HX_ASSERT" symbol.  (Shame on me for assuming that since it
>compiled it was a safe change.)
>
>Anyhow, I'm trying to verify my fix in release mode, but for some reason
>audio/limiter won't build.  It *will* build in debug mode though.  I get
>the exact same results if I back out the change to math64.h (which just
>removes the check for _NO_GNU_AS).  Here's the error:

I think you must have changed your compiler version between the time it 
worked and it did not work. The code itself did not change.

Inline assembly such as this does trigger compiler bugs more often than 
normal code. So it may be the case that the compiler simply has a bug that 
appears when it also optimizes, or it may be that the constraints are 
indeed impossible or wrong. I don't believe the second to be the case, 
because this code works in gcc 2.95 and 3.2, but I could be wrong. Which 
version of gcc are you using?

What this...

>     __asm__ volatile ("imull %3\n\t"
>                       "idivl %4"
>                       : "=&d,&d,&d,&d" (zhi), "+a,a,a,a" (x)
>                       : "%1,%1,%1,%1" (x), "m,r,m,r" (y), "m,m,r,r" (z))

... is trying to say is that there are four different register allocation 
alternatives specified. In all, the output (destination) resides in 
registers eax ("a") and edx ("d") (that's because idivl will deliver the 
result there). Because edx is modified by the first asm instruction, before 
idivl gets to run, it better not contain an input parameter ("&", early 
clobber). Because eax needs to be an input, and is modified, it is marked 
read-write ("+").

The other two inputs can either come from memory (m), or from any register 
(r). Parameter number 1 (x) is commutative ("%") with input number 2 (y).

- Wolfgang


>limiter.c: In function `LimiterStereo':
>../../audio/fixptutil/pub/math64.h:125: error: impossible register
>constraint in `asm'
>
>And the code that it's complaining about:
>
>#if defined(__GNUC__) && defined(__i386__) && !defined(_NO_GNU_AS)
>
>#define HAVE_PLATFORM_MACROS
>
>/* Compute a * b / c, using 64-bit intermediate result */
>static __inline__ int MulDiv64(register int x, register int y, register
>int z)
>{
>     int zhi ;
>     /* we specify four alternatives here, one for each permutation of
>memory or
>        register operand in the multiplier and the divisor. All are
>commutative in
>        the multiplication arguments, one of which needs to be in eax
>when we
>        start. */
>     __asm__ volatile ("imull %3\n\t"
>                       "idivl %4"
>                       : "=&d,&d,&d,&d" (zhi), "+a,a,a,a" (x)
>                       : "%1,%1,%1,%1" (x), "m,r,m,r" (y), "m,m,r,r" (z))
>;
>
>     return x ;
>}
>
>Anyone have any ideas why this might compile in debug mode but not
>release mode?  I verified that this is being compiled in debug mode, so
>it's not an issue with the macros that enable compilation of this
>function.
>
>BTW, my system_id is linux-2.2-libc6-gcc32-i586.  This builds fine on
>the build farm machine w/that id.
>
>
>--
>Nicholas Hart
>nhart@real.com
>Technical Lead, Helix Player
>https://player.helixcommunity.org
>http://www.real.com
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

-
- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
- email wschildbach@helixcommunity.org



From nhart at real.com  Mon Jun 14 10:40:55 2004
From: nhart at real.com (Nicholas Hart)
Date: Mon Jun 14 10:40:59 2004
Subject: [Common-dev] problem compiling audio/limiter
In-Reply-To: <5.1.0.14.2.20040614152554.032cbb18@mailone.real.com>
References: <5.1.0.14.2.20040614152554.032cbb18@mailone.real.com>
Message-ID: <1087234855.12449.6.camel@linicks.dev.prognet.com>

I'm not claiming this problem has shown up in the last 24 hours.  It's
just that this was refusing to compile in release mode and was
preventing me from tracking something else down that had broken in the
last 24 hours.

I'm using gcc 3.3, and it still won't build for me in release mode, but
I already fixed the other problem, so I don't really care if this gets
resolved or not (just so long as it continues to build in release mode
on the build farm, which it apparently does.)


On Mon, 2004-06-14 at 06:44, Wolfgang Schildbach wrote:
> At 01:25 PM 6/11/2004 -0700, Nicholas Hart wrote:
> 
> >I'm trying to track down a problem that has shown up on linux in the
> >last 24 hours.  When trying to play RV we get a missing "colo" component
> >error.  I suspect that this is due to my recent change to yuv.h and
> >setclrs.c for solaris x86.  I ran "nm -u" on colorcvt.so and there's an
> >undefined "HX_ASSERT" symbol.  (Shame on me for assuming that since it
> >compiled it was a safe change.)
> >
> >Anyhow, I'm trying to verify my fix in release mode, but for some reason
> >audio/limiter won't build.  It *will* build in debug mode though.  I get
> >the exact same results if I back out the change to math64.h (which just
> >removes the check for _NO_GNU_AS).  Here's the error:
> 
> I think you must have changed your compiler version between the time it 
> worked and it did not work. The code itself did not change.
> 
> Inline assembly such as this does trigger compiler bugs more often than 
> normal code. So it may be the case that the compiler simply has a bug that 
> appears when it also optimizes, or it may be that the constraints are 
> indeed impossible or wrong. I don't believe the second to be the case, 
> because this code works in gcc 2.95 and 3.2, but I could be wrong. Which 
> version of gcc are you using?
> 
> What this...
> 
> >     __asm__ volatile ("imull %3\n\t"
> >                       "idivl %4"
> >                       : "=&d,&d,&d,&d" (zhi), "+a,a,a,a" (x)
> >                       : "%1,%1,%1,%1" (x), "m,r,m,r" (y), "m,m,r,r" (z))
> 
> ... is trying to say is that there are four different register allocation 
> alternatives specified. In all, the output (destination) resides in 
> registers eax ("a") and edx ("d") (that's because idivl will deliver the 
> result there). Because edx is modified by the first asm instruction, before 
> idivl gets to run, it better not contain an input parameter ("&", early 
> clobber). Because eax needs to be an input, and is modified, it is marked 
> read-write ("+").
> 
> The other two inputs can either come from memory (m), or from any register 
> (r). Parameter number 1 (x) is commutative ("%") with input number 2 (y).
> 
> - Wolfgang
> 
> 
> >limiter.c: In function `LimiterStereo':
> >../../audio/fixptutil/pub/math64.h:125: error: impossible register
> >constraint in `asm'
> >
> >And the code that it's complaining about:
> >
> >#if defined(__GNUC__) && defined(__i386__) && !defined(_NO_GNU_AS)
> >
> >#define HAVE_PLATFORM_MACROS
> >
> >/* Compute a * b / c, using 64-bit intermediate result */
> >static __inline__ int MulDiv64(register int x, register int y, register
> >int z)
> >{
> >     int zhi ;
> >     /* we specify four alternatives here, one for each permutation of
> >memory or
> >        register operand in the multiplier and the divisor. All are
> >commutative in
> >        the multiplication arguments, one of which needs to be in eax
> >when we
> >        start. */
> >     __asm__ volatile ("imull %3\n\t"
> >                       "idivl %4"
> >                       : "=&d,&d,&d,&d" (zhi), "+a,a,a,a" (x)
> >                       : "%1,%1,%1,%1" (x), "m,r,m,r" (y), "m,m,r,r" (z))
> >;
> >
> >     return x ;
> >}
> >
> >Anyone have any ideas why this might compile in debug mode but not
> >release mode?  I verified that this is being compiled in debug mode, so
> >it's not an issue with the macros that enable compilation of this
> >function.
> >
> >BTW, my system_id is linux-2.2-libc6-gcc32-i586.  This builds fine on
> >the build farm machine w/that id.
> >
> >
> >--
> >Nicholas Hart
> >nhart@real.com
> >Technical Lead, Helix Player
> >https://player.helixcommunity.org
> >http://www.real.com
> >
> >
> >_______________________________________________
> >Common-dev mailing list
> >Common-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 
> -
> - Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
> - email wschildbach@helixcommunity.org
> 
-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com


From acolwell at real.com  Mon Jun 14 17:03:03 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon Jun 14 17:04:35 2004
Subject: [Common-dev] CR-Client: Changes to turn off client rate adaptation
Message-ID: <20040615000303.GA30519@real.com>

Synopsis: Added functionality to allow client rate adaptation to be turned off
          on a per stream basis

Overview: These changes allow you to turn client rate adaptation on an off
          for each stream. You can use either the IHXClientRateAdaptControl
          interface or the IHXASMStream2 interface to do this.
          The IHXClientRateAdaptControl interface is needed because some code
          may want to turn off rate adaptation before any IHXASMStream2 objects
          are available. This can happen if rate adaptation is negotiated 
          before the renderers are initialized.

          - IHXClientRateAdaptControl interface was added to HXSource 
            so that the RTSP code can turn off rate adaptation before
            IHXASMStream2 objects are available

          - IHXASMStream2 interface was extended to allow the subscriptions to
            be locked and unlocked. This is how the rate adaptation is turned
            on and off. When the subscriptions are locked the ASM code will
            not change the subscriptions for that stream. Client rate 
            adaptation is on by default. Code was added to HXASMStream for 
            these new methods.
            IHXASMStream2 is currently only used by the RA renderer so
            adding to this interface should not cause any problems.

          - Fixed a memory leak in the ASMRuleExpression code

          - Cleaned up some of the ASMRuleExpression code and made it a little
            more robust. Parts of the old code were implemented incorrectly or
            made huge assumptions about the rule expressions. Several blind
            casts were removed and checks were added to make sure the 
            expression is actually a bandwidth expression. I also added checks
            to make sure the expression is of the expected form.

Files Modified:
client/core/hxbsrc.h
client/core/hxsrc.cpp
client/core/strminfo.cpp
client/core/strminfo.h
client/core/asm/hxsmstr.cpp
client/core/pub/hxsmstr.h
common/util/asmrulep.cpp
common/util/pub/asmrulpp.h
common/include/hxasm.h
common/include/hxpiids.h

Files Added:
common/include/ihxrateadaptctl.h

Image Size and Heap Use impact:

Platforms and Profiles affected: all

Distribution Libraries affected: none

Distribution library impact and planned action: none

Platforms and Profiles Build Verified: win32

Platforms and Profiles Functionality verified: win32

Branch: HEAD

QA Instructions: none


Index: hxbsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxbsrc.h,v
retrieving revision 1.18
diff -u -r1.18 hxbsrc.h
--- hxbsrc.h	19 May 2004 19:37:33 -0000	1.18
+++ hxbsrc.h	14 Jun 2004 23:43:08 -0000
@@ -59,6 +59,7 @@
 #include "smiltype.h"
 #include "recordctl.h"
 #include "hxcore.h"
+#include "ihxrateadaptctl.h"
 
 // need to go in hxresult.h
 #define HX_INVALID_HEADER			HXR_INVALID_PARAMETER
@@ -232,6 +233,7 @@
 		  public IHXPrivateStreamSource,
 		  public IHXBackChannel,
 		  public IHXASMSource,
+                  public IHXClientRateAdaptControl,
 #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
 		  public IHXHyperNavigate,
 		  public IHXHyperNavigate2,
@@ -512,6 +514,39 @@
 				   REF(INT64)  llHighestTimestamp,
 				   REF(UINT32) ulNumBytes,
 				   REF(BOOL)   bDone);
+
+
+    /*
+     * IHXClientRateAdaptControl Methods
+     */
+
+    /************************************************************************
+     *	Method:
+     *	    IHXClientRateAdaptControl::Enable
+     *	Purpose:
+     *	    Enable client rate adaptation for the specified stream
+     *
+     */
+    STDMETHOD(Enable) (THIS_ UINT16 uStreamNum);
+
+    /************************************************************************
+     *	Method:
+     *	    IHXClientRateAdaptControl::Disable
+     *	Purpose:
+     *	    Disable client rate adaptation for the specified stream
+     *
+     */
+    STDMETHOD(Disable) (THIS_ UINT16 uStreamNum);
+
+    /************************************************************************
+     *	Method:
+     *	    IHXClientRateAdaptControl::IsEnabled
+     *	Purpose:
+     *	    Is client rate adaptation enabled for the specified stream
+     *
+     */
+    STDMETHOD(IsEnabled) (THIS_ UINT16 uStreamNum,
+                          REF(BOOL) bEnabled);
 
     HX_RESULT		Init(HXPlayer * player, UINT32 unRegistryID);
     HX_RESULT		SetupRegistry(void);
Index: hxsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxsrc.cpp,v
retrieving revision 1.44
diff -u -r1.44 hxsrc.cpp
--- hxsrc.cpp	19 May 2004 19:37:33 -0000	1.44
+++ hxsrc.cpp	14 Jun 2004 23:43:08 -0000
@@ -342,6 +342,8 @@
             { GET_IIDHANDLE(IID_IHXPrivateStreamSource), (IHXPrivateStreamSource*)this },
             { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*)this },
             { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*)this },
+            { GET_IIDHANDLE(IID_IHXClientRateAdaptControl), 
+              (IHXClientRateAdaptControl*)this },
 #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
             { GET_IIDHANDLE(IID_IHXHyperNavigate), (IHXHyperNavigate*)this },
             { GET_IIDHANDLE(IID_IHXHyperNavigate2), (IHXHyperNavigate2*)this },
@@ -691,6 +693,20 @@
 	pStreamInfo->m_pStream->AddRef();
 
 	pStreamInfo->BufferingState().OnStream((IHXStream*)pStream);
+
+        // Now that we have an HXStream object and
+        // set pStreamInfo->m_pStream, we should 
+        // use the cached rate adaptation state 
+        // to update the rate adaptation state in
+        // the HXStream object.
+        if (pStreamInfo->m_bClientRateAdapt)
+        {
+            Enable(pStreamInfo->m_uStreamNumber);
+        }
+        else
+        {
+            Disable(pStreamInfo->m_uStreamNumber);
+        }
     }
 }
 
@@ -2284,6 +2300,147 @@
     }
 
 
+    return res;
+}
+
+/*
+ * IHXClientRateAdaptControl Methods
+ */
+
+/************************************************************************
+ *	Method:
+ *	    IHXClientRateAdaptControl::Enable
+ *	Purpose:
+ *	    Enable client rate adaptation for the specified stream
+ *
+ */
+STDMETHODIMP
+HXSource::Enable(THIS_ UINT16 uStreamNum)
+{
+    HX_RESULT res = HXR_INVALID_PARAMETER;
+
+    STREAM_INFO* pStreamInfo = NULL;
+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& )pStreamInfo) &&
+        pStreamInfo)
+    {
+        if (pStreamInfo->m_pStream)
+        {
+            IHXASMStream2* pASMStr = NULL;
+            res = pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
+                                                         (void**)&pASMStr);
+
+            if (HXR_OK == res)
+            {
+                res = pASMStr->UnlockSubscriptions();
+
+                if (HXR_OK == res)
+                {
+                    pStreamInfo->m_bClientRateAdapt = TRUE;
+                }
+            }
+
+            HX_RELEASE(pASMStr);
+        }
+        else
+        {
+            // We don't have an HXStream object for
+            // this stream yet so cache the state
+            // in the STREAM_INFO object
+            pStreamInfo->m_bClientRateAdapt = TRUE;
+            res = HXR_OK;
+        }
+    }
+
+    return res;
+}
+
+/************************************************************************
+ *	Method:
+ *	    IHXClientRateAdaptControl::Disable
+ *	Purpose:
+ *	    Disable client rate adaptation for the specified stream
+ *
+ */
+STDMETHODIMP
+HXSource::Disable(THIS_ UINT16 uStreamNum)
+{
+    HX_RESULT res = HXR_INVALID_PARAMETER;
+
+    STREAM_INFO* pStreamInfo = NULL;
+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& )pStreamInfo) &&
+        pStreamInfo)
+    {
+        if (pStreamInfo->m_pStream)
+        {
+            IHXASMStream2* pASMStr = NULL;
+            res = pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
+                                                         (void**)&pASMStr);
+
+            if (HXR_OK == res)
+            {
+                res = pASMStr->LockSubscriptions();
+
+                if (HXR_OK == res)
+                {
+                    pStreamInfo->m_bClientRateAdapt = FALSE;
+                }
+            }
+
+            HX_RELEASE(pASMStr);
+        }
+        else
+        {
+            // We don't have an HXStream object for
+            // this stream yet so cache the state
+            // in the STREAM_INFO object
+            pStreamInfo->m_bClientRateAdapt = FALSE;
+            res = HXR_OK;
+        }
+    }
+
+    return res;
+}
+
+/************************************************************************
+ *	Method:
+ *	    IHXClientRateAdaptControl::IsEnabled
+ *	Purpose:
+ *	    Is client rate adaptation enabled for the specified stream
+ *
+ */
+STDMETHODIMP
+HXSource::IsEnabled(THIS_ UINT16 uStreamNum,
+                    REF(BOOL) bEnabled)
+{
+    HX_RESULT res = HXR_INVALID_PARAMETER;
+
+    STREAM_INFO* pStreamInfo = NULL;
+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& )pStreamInfo) &&
+        pStreamInfo)
+    {
+        if (pStreamInfo->m_pStream)
+        {
+            IHXASMStream2* pASMStr = NULL;
+            res = pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
+                                                         (void**)&pASMStr);
+
+            if (HXR_OK == res)
+            {
+                bEnabled = !pASMStr->AreSubscriptionsLocked();
+            }
+
+            HX_RELEASE(pASMStr);
+        }
+        else
+        {
+            // We don't have an HXStream object for
+            // this stream yet so used the cached
+            // value in the STREAM_INFO object
+            bEnabled = pStreamInfo->m_bClientRateAdapt;
+            res = HXR_OK;
+        }
+    }
+    
     return res;
 }
 
Index: strminfo.cpp
===================================================================
RCS file: /cvsroot/client/core/strminfo.cpp,v
retrieving revision 1.6
diff -u -r1.6 strminfo.cpp
--- strminfo.cpp	1 Mar 2004 22:13:52 -0000	1.6
+++ strminfo.cpp	14 Jun 2004 23:43:08 -0000
@@ -84,6 +84,7 @@
 
     m_pStream			    = NULL;
     m_bCanBeStoppedAnyTime	    = FALSE;
+    m_bClientRateAdapt = TRUE;
 
     // reconnect stuff
     m_pPreReconnectEventList = NULL;
Index: strminfo.h
===================================================================
RCS file: /cvsroot/client/core/strminfo.h,v
retrieving revision 1.5
diff -u -r1.5 strminfo.h
--- strminfo.h	1 Mar 2004 22:13:52 -0000	1.5
+++ strminfo.h	14 Jun 2004 23:43:08 -0000
@@ -121,6 +121,7 @@
     HX_BITFIELD		m_bPacketRequested : 1;		// is the packet requested from 
     HX_BITFIELD		m_bCustomEndTime : 1;
     HX_BITFIELD		m_bCanBeStoppedAnyTime : 1;
+    HX_BITFIELD		m_bClientRateAdapt : 1;
 };
 
 /*
Index: asm/hxsmstr.cpp
===================================================================
RCS file: /cvsroot/client/core/asm/hxsmstr.cpp,v
retrieving revision 1.13
diff -u -r1.13 hxsmstr.cpp
--- asm/hxsmstr.cpp	26 Nov 2003 01:37:16 -0000	1.13
+++ asm/hxsmstr.cpp	14 Jun 2004 23:43:08 -0000
@@ -87,6 +87,7 @@
     , m_ulBandwidthAllocation(0)
     , m_bStartRecalc(FALSE)
     , m_bTimeStampDeliveryMode(FALSE)
+    , m_bInitialSubscribe(TRUE)
     , m_ulLastLimitBandwidth(0xffffffff)
     , m_pAtomicRuleChange(0)
     , m_pSubList(0)
@@ -97,6 +98,8 @@
     , m_bHasExpression(FALSE)
     , m_bEndOneRuleEndAll(FALSE)
     , m_ulLastBandwidth(0)
+    , m_pRuleEnableState(NULL)
+    , m_bSubsLocked(FALSE)
 #ifndef GOLD
     , m_pEM(0)
 #endif
@@ -169,6 +172,7 @@
 	m_bRuleTimeStampDelivery = new BOOL[m_nNumRules];
 	m_pSubInfo = new BOOL[m_nNumRules];
 	m_pRuleSubscribeStatus = new BOOL[m_nNumRules];
+        m_pRuleEnableState = new RuleEnableState[m_nNumRules];
 
         for (UINT16 i = 0; i < m_nNumRules; i++)
         {
@@ -180,6 +184,7 @@
 	    m_ulRuleBw[i] = 0;
 	    m_ulRulePreData[i] = 0;
 	    m_bRuleTimeStampDelivery[i] = FALSE;
+            m_pRuleEnableState[i] = resEnabled;
 
 	    if (HXR_OK == pValues->GetPropertyCString("PreData",
 		pBuffer))
@@ -486,6 +491,7 @@
     }
 
     DEBUG_OUT(m_pEM, DOL_ASM, (s, "(%p)Subscribe: Stream=%d Rule=%d", m_pSource, m_uStreamNumber, uRuleNumber));
+    printf("(%p)Subscribe: Stream=%d Rule=%d\n", m_pSource, m_uStreamNumber, uRuleNumber);
 
     m_pRuleSubscribeStatus[uRuleNumber] = TRUE;
     
@@ -529,6 +535,7 @@
     }
 
     DEBUG_OUT(m_pEM, DOL_ASM, (s, "(%p)Unsubscribe: Stream=%d Rule=%d", m_pSource, m_uStreamNumber, uRuleNumber));
+    printf("(%p)Unsubscribe: Stream=%d Rule=%d\n", m_pSource, m_uStreamNumber, uRuleNumber);
 
     m_pRuleSubscribeStatus[uRuleNumber] = FALSE;
     
@@ -909,7 +916,28 @@
 	    }
 
             m_pSubInfo[i] = pCurrentSubInfo[i];
+
         }
+
+        if (m_bInitialSubscribe && 
+            m_bSubsLocked &&
+            m_pRuleEnableState && 
+            m_pRuleBook &&
+            !m_pSubInfo[i])
+        {
+            // This is the initial subscription and
+            // this rule was not selected.
+            // Mark it as locked and disable
+            // the rule in the rulebook
+            m_pRuleEnableState[i] = resLocked;
+            m_pRuleBook->Disable(i);
+        }
+    }
+
+    if (m_bInitialSubscribe)
+    {
+        m_bInitialSubscribe = FALSE;
+        m_pRuleBook->ReCompute();
     }
 
     if (m_pAtomicRuleChange && (!m_pSubList) && (!SubChange.IsEmpty()))
@@ -1122,9 +1150,24 @@
 STDMETHODIMP_(HX_RESULT)
 HXASMStream::Enable( UINT16 nRule )
 {
-   if( m_pRuleBook )
+   if( m_pRuleBook  && m_pRuleEnableState)
    {
-      m_pRuleBook->Enable( nRule );
+       if (m_bSubsLocked)
+       {
+           // Change the enable state to locked,
+           // but leave the rule disabled in the
+           // rulebook. When we leave the locked
+           // state this rule will be reenabled
+           // in the rulebook
+           m_pRuleEnableState[nRule] = resLocked;
+       }
+       else
+       {
+           // Change the enable state and enable
+           // the rule in the rulebook
+           m_pRuleEnableState[nRule] = resEnabled;
+           m_pRuleBook->Enable( nRule );
+       }
    }
    return HXR_OK;
 }
@@ -1132,9 +1175,10 @@
 STDMETHODIMP_(HX_RESULT)
 HXASMStream::Disable( UINT16 nRule )
 {
-   if( m_pRuleBook )
+   if( m_pRuleBook && m_pRuleEnableState)
    {
-      m_pRuleBook->Disable( nRule );
+       m_pRuleEnableState[nRule] = resDisabled;
+       m_pRuleBook->Disable( nRule );
    }
     return HXR_OK;
 }
@@ -1176,11 +1220,114 @@
           // We can't subscribe to any stream so reset and fail.
           for( int ii=0; iiEnable( ii );
+              Enable( ii );
           }
           m_pRuleBook->ReCompute();
           retVal = HXR_FAIL;
       }
    }
    return retVal;
+}
+
+STDMETHODIMP_(BOOL)
+HXASMStream::IsEnabled( UINT16 nRule )
+{
+    BOOL bRet = TRUE;
+    if( m_pRuleBook && m_pRuleEnableState &&
+        (m_pRuleEnableState[nRule] != resDisabled))
+    {
+        bRet = FALSE;
+    }
+
+    return bRet;
+}
+
+STDMETHODIMP 
+HXASMStream::LockSubscriptions(THIS)
+{
+    HX_RESULT res = HXR_FAILED;
+
+    if( m_pRuleBook  && m_pRuleEnableState)
+    {
+        if (m_bSubsLocked)
+        {
+            // The subscriptions are already locked
+            res = HXR_OK;
+        }
+        else
+        {
+            if (!m_bInitialSubscribe)
+            {
+                // We only lock and disable rules if we have
+                // done the inital subscription.
+                // If we haven't done the initial subscription,
+                // the locking and disabling of rules will
+                // happen when the initial subscription occurs.
+                
+                for (UINT16 i = 0; i < m_nNumRules; i++)
+                {
+                    // Change the state of any rules that
+                    // are currently enabled, but not subscribed
+                    // to. This makes it so that the rulebook
+                    // will always evaluate to the current 
+                    // subscriptions
+                    if (!m_pSubInfo[i] &&
+                        (m_pRuleEnableState[i] == resEnabled))
+                    {
+                        m_pRuleEnableState[i] = resLocked;
+                        m_pRuleBook->Disable(i);
+                    }
+                    
+                }
+                m_pRuleBook->ReCompute();
+            }
+            
+            m_bSubsLocked = TRUE;
+            res = HXR_OK;
+        }
+    }
+    
+    return res;
+}
+
+STDMETHODIMP 
+HXASMStream::UnlockSubscriptions(THIS)
+{
+    HX_RESULT res = HXR_FAILED;
+
+    if( m_pRuleBook  && m_pRuleEnableState)
+    {
+        if (m_bSubsLocked)
+        {
+            for (UINT16 i = 0; i < m_nNumRules; i++)
+            {
+                // Change the state of any rules that
+                // are currently locked and enable them
+                // in the rulebook. This makes it so that 
+                // the rulebook can evaluate to any of the
+                // enabled rules
+                if (m_pRuleEnableState[i] == resLocked)
+                {
+                    m_pRuleEnableState[i] = resEnabled;
+                    m_pRuleBook->Enable(i);
+                }
+            }
+            m_pRuleBook->ReCompute();
+                        
+            m_bSubsLocked = FALSE;
+        }
+        else
+        {
+            // We are currently in an unlocked state
+            res = HXR_OK;
+        }
+    }
+    
+    return res;
+}
+
+STDMETHODIMP_(BOOL)
+HXASMStream::AreSubscriptionsLocked(THIS)
+{
+    return m_bSubsLocked;
 }
Index: pub/hxsmstr.h
===================================================================
RCS file: /cvsroot/client/core/pub/hxsmstr.h,v
retrieving revision 1.6
diff -u -r1.6 hxsmstr.h
--- pub/hxsmstr.h	3 May 2004 18:59:31 -0000	1.6
+++ pub/hxsmstr.h	14 Jun 2004 23:43:08 -0000
@@ -76,6 +76,9 @@
     STDMETHOD(Unsubscribe)	(THIS_
 				UINT16	uRuleNumber);
 
+    /*
+     *	IHXASMStream2 methods
+     */
     STDMETHOD(Disable)	        (THIS_
 				UINT16	uRuleNumber);
 
@@ -84,6 +87,16 @@
 
     STDMETHOD(ReCompute)	(THIS);
 
+    STDMETHOD_(BOOL,IsEnabled) (THIS_
+				UINT16	uRuleNumber);
+
+    STDMETHOD(LockSubscriptions) (THIS);
+
+    STDMETHOD (UnlockSubscriptions) (THIS);
+
+    STDMETHOD_(BOOL,AreSubscriptionsLocked)(THIS);
+
+
     /*
      *	IHXStreamBandwidthNegotiator methods
      */
@@ -157,6 +170,10 @@
     HX_BITFIELD		m_bInitialSubscribe : 1;
 
 private:
+    typedef enum {resEnabled,
+                  resDisabled,
+                  resLocked} RuleEnableState;
+
     HX_BITFIELD		m_bHasExpression : 1;
     HX_BITFIELD		m_bEndOneRuleEndAll : 1;
 
@@ -197,6 +214,8 @@
 
     BOOL*		m_pRuleSubscribeStatus;
     CASMRuleState*	m_pASMRuleState;
+    RuleEnableState*    m_pRuleEnableState;
+    BOOL                m_bSubsLocked;
 
     void Recalc();
     void RecalcCurrentProps();

Index: asmrulep.cpp
===================================================================
RCS file: /cvsroot/common/util/asmrulep.cpp,v
retrieving revision 1.14
diff -u -r1.14 asmrulep.cpp
--- asmrulep.cpp	17 Dec 2003 23:41:33 -0000	1.14
+++ asmrulep.cpp	14 Jun 2004 23:43:19 -0000
@@ -42,6 +42,7 @@
 #include "asmrulep.h"	/* ASM Public Include File */
 #include "asmrulpp.h"	/* ASM Private Include File */
 #include "chxpckts.h"
+#include "hxassert.h"
 
 #define RULE_VAL_INFINITY -1
 
@@ -687,6 +688,7 @@
 void
 ASMRule::SetExpression(const char* pExpression)
 {
+    HX_DELETE(m_pRuleExpression);
     m_pRuleExpression = new ASMRuleExpression(pExpression);
 }
 
@@ -801,7 +803,7 @@
     for (i = 0; i < m_unNumRules; i++)
     {
         if( m_pDeletedRulesArray && m_pDeletedRulesArray[i] == TRUE )
-	{
+	{  
             pSubInfo[i] = 0;
 	}
 	else if (m_pRules[i].m_pRuleExpression)
@@ -1181,7 +1183,7 @@
    // Find the "left edge" rule.
    for( ii=m_unNumRules-1; ii>=0; ii-- )
    {
-      if( ( m_pDeletedRulesArray[ii] == FALSE ) && ( m_pRules[ ii ].m_pRuleExpression->GetLeft() || m_pRules[ ii ].m_pRuleExpression->GetRight() ) )
+      if( !m_pDeletedRulesArray[ii] && m_pRules[ii].m_pRuleExpression->IsLeftEdge() )
       {
          nLeftEdge = ii;
       }
@@ -1260,61 +1262,122 @@
 void
 ASMRuleExpression::SetLeft( int nLeft )
 {
-   int nRight = ((IntegerNode*) ((VariableNode*)m_pHead->m_pRight))->m_Data;
-   if( nRight == 1 )
-   {
-      ((IntegerNode*)(m_pHead->m_pLeft->m_pRight))->m_Data = nLeft;
-   }
+    // This function assumes the following forms
+    // ($Bandwidth > 123)
+    // ($Bandwidth >= 123)
+    // ($Bandwidth > 123) && ($Bandwidth < 1234)
+    // ($Bandwidth >= 123) && ($Bandwidth < 1234)
+    //
+    // It assumes the left-most expression is > or >=
+
+    if (m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
+    {
+        OperatorNode* pOp = (OperatorNode*)m_pHead;
+
+        if (pOp->m_pLeft &&
+            (pOp->m_pLeft->m_Type == HX_RE_OPERATOR))
+        {
+            // ($Bandwidth >= 123) && ($Bandwidth < 1234)
+            // We want to update the left side
+            pOp = (OperatorNode*)pOp->m_pLeft;
+        }
+
+        if (NormalizeBwNode(pOp) &&
+            ((pOp->m_Data == HX_RE_GREATER) ||
+             (pOp->m_Data == HX_RE_GREATEREQUAL)))
+        {
+            IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
+            pInt->m_Data = nLeft;
+        }
+    }
 }
 
 void
 ASMRuleExpression::SetRight( int nRight )
 {
-   int nTmpRight = 0;
-   if( m_pHead && m_pHead->m_pRight )
-   {
-      nTmpRight = ((IntegerNode*) ((VariableNode*)m_pHead->m_pRight))->m_Data;
-   }
+    // This function assumes the following forms
+    // ($Bandwidth < 123)
+    // ($Bandwidth <= 123)
+    // ($Bandwidth > 123) && ($Bandwidth < 1234)
+    // ($Bandwidth > 123) && ($Bandwidth <= 1234)
+    //
+    // It assumes the right-most expression is < or <=
 
-   if( nTmpRight == 1 )
-   {
-      ( (IntegerNode*)((VariableNode*) ((VariableNode*)m_pHead->m_pRight)->m_pRight) )->m_Data = nRight;
-   }
-   else if( nTmpRight != 0 )
-   {
-      ((VariableNode*)m_pHead->m_pRight)->m_Data = (char*)nRight;
-   }
+    if (m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
+    {
+        OperatorNode* pOp = (OperatorNode*)m_pHead;
+
+        if (pOp->m_pRight &&
+            (pOp->m_pRight->m_Type == HX_RE_OPERATOR))
+        {
+            // ($Bandwidth > 123) && ($Bandwidth < 1234)
+            // We want to update the right side
+            pOp = (OperatorNode*)pOp->m_pRight;
+        }
+
+        if (NormalizeBwNode(pOp) &&
+            ((pOp->m_Data == HX_RE_LESS) ||
+             (pOp->m_Data == HX_RE_LESSEQUAL)))
+        {
+            IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
+            pInt->m_Data = nRight;
+        }
+    }
 }
 
 float
 ASMRuleExpression::GetLeft()
 {
-   int nLeft = 0;
-   int nRight = 0;
-   if( m_pHead && m_pHead->m_pRight )
-   {
-      nRight = ((IntegerNode*) ((VariableNode*)m_pHead->m_pRight))->m_Data;
-   }
-   if( nRight == 1 )
-   {
-      nLeft = ((IntegerNode*) ((VariableNode*)m_pHead->m_pLeft->m_pRight))->m_Data;
-   }
-   return (float)nLeft;
+    // This function returns the
+    // lower bandwidth threshold. It assumes
+    // that the lower threshold expression
+    // is always on the left
+    OperatorNode* pOp = NULL;
+
+    if(m_pHead && m_pHead->m_pLeft &&
+       (m_pHead->m_Type == HX_RE_OPERATOR))
+    {
+        // Test for ($Bandwidth > 123) && ($Bandwidth <= 123)
+        if (m_pHead->m_pLeft->m_Type == HX_RE_OPERATOR)
+        {
+            // We want the value from the left node
+            pOp = (OperatorNode*)m_pHead->m_pLeft;
+        }
+        else
+        {
+            pOp = (OperatorNode*)m_pHead;
+        }
+    }
+   
+    return (float)GetBwValue(pOp);
 }
 
 float
 ASMRuleExpression::GetRight()
 {
-   int nRight = 0;
-   if( m_pHead && m_pHead->m_pRight )
-   {
-      nRight = ((IntegerNode*) ((VariableNode*)(m_pHead->m_pRight)))->m_Data;
-   }
-   if( nRight == 1 )
-   {
-      nRight = ((IntegerNode*) ((VariableNode*)m_pHead->m_pRight->m_pRight))->m_Data;
-   }
-   return (float)nRight;
+    // This function returns the
+    // upper bandwidth threshold. It assumes
+    // that the upper threshold expression
+    // is always on the right
+
+    OperatorNode* pOp = NULL;
+
+    if(m_pHead && m_pHead->m_pRight &&
+       (m_pHead->m_Type == HX_RE_OPERATOR))
+    {
+        // Test for ($Bandwidth > 123) && ($Bandwidth <= 123)
+        if (m_pHead->m_pRight->m_Type == HX_RE_OPERATOR)
+        {
+            // We want the value from the right node
+            pOp = (OperatorNode*)m_pHead->m_pRight;
+        }
+        else
+        {
+            pOp = (OperatorNode*)m_pHead;
+        }
+    }
+   
+    return (float)GetBwValue(pOp);
 }
 
 int
@@ -1323,30 +1386,36 @@
    return (int) ((OperatorNode*) m_pHead)->m_Data;
 }
 
+BOOL
+ASMRuleExpression::IsLeftEdge()
+{
+    // This is a left edge if it
+    // has a bandwidth value on
+    // either the left or the right
+    return ( GetLeft() || GetRight() );
+}
+
+
 // This function checks to see if the current rule's operator is GREATER or
 // GREATEROREQUAL, both of which would suggest that we are the "right edge"
 // rule.
 BOOL
 ASMRuleExpression::IsRightEdge()
 {
-   if( m_pHead )
-   {
-      switch(((OperatorNode*)m_pHead)->m_Data)
-      {
-	  case HX_RE_GREATER:
-	  case HX_RE_GREATEREQUAL:
-	      return TRUE;
-	      break;
-
-          default:
-	      return FALSE;
-	      break;
-      }
-   }
-   else
-   {
-      return FALSE;
-   }
+    BOOL bRet = FALSE;
+    if( m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
+    {
+        OperatorNode* pOp = (OperatorNode*)m_pHead;
+
+        if (NormalizeBwNode(pOp) &&
+            ((pOp->m_Data == HX_RE_GREATER) ||
+             (pOp->m_Data == HX_RE_GREATEREQUAL)))
+        {
+            bRet = TRUE;
+        }
+    }
+
+    return bRet;
 }
 
 HX_RESULT
@@ -1487,6 +1556,7 @@
 	}
     }
 
+    HX_VECTOR_DELETE(m_pDeletedRulesArray);
     return InitRulesArray();
 }
 
@@ -1506,4 +1576,88 @@
     }
 
     return TRUE;
+}
+
+int 
+ASMRuleExpression::GetBwValue(OperatorNode* pOp) const
+{
+    int ret = 0;
+
+    if (NormalizeBwNode(pOp))
+    {
+        // The bandwidth value is always on the right
+        // after the node has been normalized
+        IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
+        
+        ret = pInt->m_Data;
+    }
+
+    return ret;
+}
+
+BOOL 
+ASMRuleExpression::NormalizeBwNode(OperatorNode* pOp) const
+{
+    // This function determines if the expression is a
+    // bandwidth threshold expression and if so it makes sure it 
+    // always has the bandwidth variable on the left side
+    // and the bandwidth value on the right side
+    BOOL bRet = FALSE;
+
+    if (pOp && pOp->m_pLeft && pOp->m_pRight)
+    {
+        VariableNode* pVar = NULL;
+        IntegerNode* pInt = NULL;
+        
+        if ((pOp->m_pLeft->m_Type == HX_RE_INTEGER) &&
+            (pOp->m_pRight->m_Type == HX_RE_VARIABLE))
+        {
+            // (123 > somevar)
+            // (123 >= somevar)
+            pInt = (IntegerNode*)pOp->m_pLeft;
+            pVar = (VariableNode*)pOp->m_pRight;
+        }
+        else if ((pOp->m_pLeft->m_Type == HX_RE_VARIABLE) &&
+                 (pOp->m_pRight->m_Type == HX_RE_INTEGER))
+        {
+            // (somevar < 123)
+            // (somevar <= 123)
+            pVar = (VariableNode*)pOp->m_pLeft;
+            pInt = (IntegerNode*)pOp->m_pRight;
+        }
+        
+        if (pVar && pInt &&
+            !strcasecmp(pVar->m_Data, "Bandwidth"))
+        {
+            // This is a bandwidth node
+
+            if (pVar != pOp->m_pLeft)
+            {
+                // We need to swap the left and
+                // right nodes
+                pOp->m_pLeft = pVar;
+                pOp->m_pRight = pInt;
+
+                // Flip operator around
+                switch(pOp->m_Data) {
+                case HX_RE_GREATER:
+                    pOp->m_Data = HX_RE_LESS;
+                    break;
+                case HX_RE_LESS:
+                    pOp->m_Data = HX_RE_GREATER;
+                    break;
+                case HX_RE_GREATEREQUAL:
+                    pOp->m_Data = HX_RE_LESSEQUAL;
+                    break;
+                case HX_RE_LESSEQUAL:
+                    pOp->m_Data = HX_RE_GREATEREQUAL;
+                    break;
+                };
+            }
+
+            bRet = TRUE;
+        }
+    }
+
+    return bRet;
 }
Index: pub/asmrulpp.h
===================================================================
RCS file: /cvsroot/common/util/pub/asmrulpp.h,v
retrieving revision 1.3
diff -u -r1.3 asmrulpp.h
--- pub/asmrulpp.h	18 Apr 2003 18:04:36 -0000	1.3
+++ pub/asmrulpp.h	14 Jun 2004 23:43:20 -0000
@@ -68,6 +68,7 @@
 		    	~ASMRuleExpression();
     void		Dump();
     BOOL		Evaluate(IHXValues* pVars);
+    BOOL		IsLeftEdge();
     BOOL		IsRightEdge();
     float		GetLeft();
     float		GetRight();
@@ -124,6 +125,8 @@
                                 float*& pThreshold, UINT32& ulNumThreshold,
                                 BOOL& bInvolvesTheOpenVariable);
     BOOL		RFindVariable(Node* pNode, const char* pVariable);
+    int                 GetBwValue(OperatorNode* pOp) const;
+    BOOL                NormalizeBwNode(OperatorNode* pOp) const;
 
     UINT32		m_ulNumThresholds;
     Node*	    	m_pHead;
Index: hxasm.h
===================================================================
RCS file: /cvsroot/common/include/hxasm.h,v
retrieving revision 1.3
diff -u -r1.3 hxasm.h
--- hxasm.h	18 Apr 2003 18:03:27 -0000	1.3
+++ hxasm.h	14 Jun 2004 23:44:15 -0000
@@ -301,6 +301,44 @@
 				UINT16	uRuleNumber) PURE;
 
     STDMETHOD (ReCompute)	(THIS) PURE;
+
+    /************************************************************************
+     *	Method:
+     *	    IHXASMStream2::IsEnabled
+     *	Purpose:
+     *      Allows a user to determine if a rule is enabled or not
+     */
+    STDMETHOD_(BOOL,IsEnabled) (THIS_
+				UINT16	uRuleNumber) PURE;
+
+    /************************************************************************
+     *	Method:
+     *	    IHXASMStream2::LockSubscriptions
+     *	Purpose:
+     *      Locks the stream to the current subscriptions. This has the
+     *      effect of disabling the client side rate adaptation for this
+     *      stream.
+     */
+    STDMETHOD (LockSubscriptions)(THIS) PURE;
+
+    /************************************************************************
+     *	Method:
+     *	    IHXASMStream2::UnlockSubscriptions
+     *	Purpose:
+     *      Unlocks the stream so that the enabled streams can be selected
+     *      by the ASM code. This has the effect of reenabling the client side
+     *      rate adaptation for this stream.
+     */
+    STDMETHOD (UnlockSubscriptions)(THIS) PURE;
+
+    /************************************************************************
+     *	Method:
+     *	    IHXASMStream2::AreSubscriptionsLocked
+     *	Purpose:
+     *      Lets you determine whether the stream subscriptions are locked
+     *      or not.
+     */
+    STDMETHOD_(BOOL, AreSubscriptionsLocked)(THIS) PURE;
 };
 
 
Index: hxpiids.h
===================================================================
RCS file: /cvsroot/common/include/hxpiids.h,v
retrieving revision 1.28
diff -u -r1.28 hxpiids.h
--- hxpiids.h	8 Apr 2004 00:55:04 -0000	1.28
+++ hxpiids.h	14 Jun 2004 23:44:15 -0000
@@ -989,4 +989,14 @@
 DEFINE_GUID_ENUM(IID_IHXAccessPointSelector, 0x9e9ca2d6, 0xcbfe, 0x40f8, 0x94,
 		 0xfd, 0x38, 0xf4, 0xeb, 0x5d, 0xf8, 0x12)
 
+/* File:
+ *      ihxrateadaptctl.h
+ *
+ * Description:
+ *      Rate adaptation control interfaces
+ */
+DEFINE_GUID_ENUM(IID_IHXClientRateAdaptControl, 0x44f5ac8c, 0x654c, 0x414e, 0x9d, 
+                 0x18, 0xe7, 0xa4, 0x80, 0x90, 0x70, 0x9)
+
 #endif /* _HXPRIVATEIIDS_H_ */
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ihxrateadaptctl.h
Type: text/x-chdr
Size: 3543 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040614/1e394415/ihxrateadaptctl-0001.bin
From ping at real.com  Tue Jun 15 08:47:51 2004
From: ping at real.com (Henry Ping)
Date: Tue Jun 15 08:48:46 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Changes to turn off client
 rate adaptation
In-Reply-To: <20040615000303.GA30519@real.com>
Message-ID: <5.1.0.14.2.20040615084500.03810ef0@mailone.real.com>

Looks good, except m_pRuleEnableState needs to be deleted and printf() 
statement needs to be removed

-->Henry

At 05:03 PM 6/14/2004 -0700, Aaron Colwell wrote:
>Synopsis: Added functionality to allow client rate adaptation to be turned off
>           on a per stream basis
>
>Overview: These changes allow you to turn client rate adaptation on an off
>           for each stream. You can use either the IHXClientRateAdaptControl
>           interface or the IHXASMStream2 interface to do this.
>           The IHXClientRateAdaptControl interface is needed because some code
>           may want to turn off rate adaptation before any IHXASMStream2 
> objects
>           are available. This can happen if rate adaptation is negotiated
>           before the renderers are initialized.
>
>           - IHXClientRateAdaptControl interface was added to HXSource
>             so that the RTSP code can turn off rate adaptation before
>             IHXASMStream2 objects are available
>
>           - IHXASMStream2 interface was extended to allow the 
> subscriptions to
>             be locked and unlocked. This is how the rate adaptation is turned
>             on and off. When the subscriptions are locked the ASM code will
>             not change the subscriptions for that stream. Client rate
>             adaptation is on by default. Code was added to HXASMStream for
>             these new methods.
>             IHXASMStream2 is currently only used by the RA renderer so
>             adding to this interface should not cause any problems.
>
>           - Fixed a memory leak in the ASMRuleExpression code
>
>           - Cleaned up some of the ASMRuleExpression code and made it a 
> little
>             more robust. Parts of the old code were implemented 
> incorrectly or
>             made huge assumptions about the rule expressions. Several blind
>             casts were removed and checks were added to make sure the
>             expression is actually a bandwidth expression. I also added 
> checks
>             to make sure the expression is of the expected form.
>
>Files Modified:
>client/core/hxbsrc.h
>client/core/hxsrc.cpp
>client/core/strminfo.cpp
>client/core/strminfo.h
>client/core/asm/hxsmstr.cpp
>client/core/pub/hxsmstr.h
>common/util/asmrulep.cpp
>common/util/pub/asmrulpp.h
>common/include/hxasm.h
>common/include/hxpiids.h
>
>Files Added:
>common/include/ihxrateadaptctl.h
>
>Image Size and Heap Use impact:
>
>Platforms and Profiles affected: all
>
>Distribution Libraries affected: none
>
>Distribution library impact and planned action: none
>
>Platforms and Profiles Build Verified: win32
>
>Platforms and Profiles Functionality verified: win32
>
>Branch: HEAD
>
>QA Instructions: none
>
>
>Index: hxbsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbsrc.h,v
>retrieving revision 1.18
>diff -u -r1.18 hxbsrc.h
>--- hxbsrc.h    19 May 2004 19:37:33 -0000      1.18
>+++ hxbsrc.h    14 Jun 2004 23:43:08 -0000
>@@ -59,6 +59,7 @@
>  #include "smiltype.h"
>  #include "recordctl.h"
>  #include "hxcore.h"
>+#include "ihxrateadaptctl.h"
>
>  // need to go in hxresult.h
>  #define HX_INVALID_HEADER                      HXR_INVALID_PARAMETER
>@@ -232,6 +233,7 @@
>                   public IHXPrivateStreamSource,
>                   public IHXBackChannel,
>                   public IHXASMSource,
>+                  public IHXClientRateAdaptControl,
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>                   public IHXHyperNavigate,
>                   public IHXHyperNavigate2,
>@@ -512,6 +514,39 @@
>                                    REF(INT64)  llHighestTimestamp,
>                                    REF(UINT32) ulNumBytes,
>                                    REF(BOOL)   bDone);
>+
>+
>+    /*
>+     * IHXClientRateAdaptControl Methods
>+     */
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXClientRateAdaptControl::Enable
>+     * Purpose:
>+     *     Enable client rate adaptation for the specified stream
>+     *
>+     */
>+    STDMETHOD(Enable) (THIS_ UINT16 uStreamNum);
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXClientRateAdaptControl::Disable
>+     * Purpose:
>+     *     Disable client rate adaptation for the specified stream
>+     *
>+     */
>+    STDMETHOD(Disable) (THIS_ UINT16 uStreamNum);
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXClientRateAdaptControl::IsEnabled
>+     * Purpose:
>+     *     Is client rate adaptation enabled for the specified stream
>+     *
>+     */
>+    STDMETHOD(IsEnabled) (THIS_ UINT16 uStreamNum,
>+                          REF(BOOL) bEnabled);
>
>      HX_RESULT          Init(HXPlayer * player, UINT32 unRegistryID);
>      HX_RESULT          SetupRegistry(void);
>Index: hxsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxsrc.cpp,v
>retrieving revision 1.44
>diff -u -r1.44 hxsrc.cpp
>--- hxsrc.cpp   19 May 2004 19:37:33 -0000      1.44
>+++ hxsrc.cpp   14 Jun 2004 23:43:08 -0000
>@@ -342,6 +342,8 @@
>              { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> (IHXPrivateStreamSource*)this },
>              { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
> (IHXSourceBufferingStats*)this },
>              { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
> (IHXSourceBufferingStats2*)this },
>+            { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
>+              (IHXClientRateAdaptControl*)this },
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>              { GET_IIDHANDLE(IID_IHXHyperNavigate), 
> (IHXHyperNavigate*)this },
>              { GET_IIDHANDLE(IID_IHXHyperNavigate2), 
> (IHXHyperNavigate2*)this },
>@@ -691,6 +693,20 @@
>         pStreamInfo->m_pStream->AddRef();
>
>         pStreamInfo->BufferingState().OnStream((IHXStream*)pStream);
>+
>+        // Now that we have an HXStream object and
>+        // set pStreamInfo->m_pStream, we should
>+        // use the cached rate adaptation state
>+        // to update the rate adaptation state in
>+        // the HXStream object.
>+        if (pStreamInfo->m_bClientRateAdapt)
>+        {
>+            Enable(pStreamInfo->m_uStreamNumber);
>+        }
>+        else
>+        {
>+            Disable(pStreamInfo->m_uStreamNumber);
>+        }
>      }
>  }
>
>@@ -2284,6 +2300,147 @@
>      }
>
>
>+    return res;
>+}
>+
>+/*
>+ * IHXClientRateAdaptControl Methods
>+ */
>+
>+/************************************************************************
>+ *     Method:
>+ *         IHXClientRateAdaptControl::Enable
>+ *     Purpose:
>+ *         Enable client rate adaptation for the specified stream
>+ *
>+ */
>+STDMETHODIMP
>+HXSource::Enable(THIS_ UINT16 uStreamNum)
>+{
>+    HX_RESULT res = HXR_INVALID_PARAMETER;
>+
>+    STREAM_INFO* pStreamInfo = NULL;
>+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& 
>)pStreamInfo) &&
>+        pStreamInfo)
>+    {
>+        if (pStreamInfo->m_pStream)
>+        {
>+            IHXASMStream2* pASMStr = NULL;
>+            res = pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
>+                                                         (void**)&pASMStr);
>+
>+            if (HXR_OK == res)
>+            {
>+                res = pASMStr->UnlockSubscriptions();
>+
>+                if (HXR_OK == res)
>+                {
>+                    pStreamInfo->m_bClientRateAdapt = TRUE;
>+                }
>+            }
>+
>+            HX_RELEASE(pASMStr);
>+        }
>+        else
>+        {
>+            // We don't have an HXStream object for
>+            // this stream yet so cache the state
>+            // in the STREAM_INFO object
>+            pStreamInfo->m_bClientRateAdapt = TRUE;
>+            res = HXR_OK;
>+        }
>+    }
>+
>+    return res;
>+}
>+
>+/************************************************************************
>+ *     Method:
>+ *         IHXClientRateAdaptControl::Disable
>+ *     Purpose:
>+ *         Disable client rate adaptation for the specified stream
>+ *
>+ */
>+STDMETHODIMP
>+HXSource::Disable(THIS_ UINT16 uStreamNum)
>+{
>+    HX_RESULT res = HXR_INVALID_PARAMETER;
>+
>+    STREAM_INFO* pStreamInfo = NULL;
>+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& 
>)pStreamInfo) &&
>+        pStreamInfo)
>+    {
>+        if (pStreamInfo->m_pStream)
>+        {
>+            IHXASMStream2* pASMStr = NULL;
>+            res = pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
>+                                                         (void**)&pASMStr);
>+
>+            if (HXR_OK == res)
>+            {
>+                res = pASMStr->LockSubscriptions();
>+
>+                if (HXR_OK == res)
>+                {
>+                    pStreamInfo->m_bClientRateAdapt = FALSE;
>+                }
>+            }
>+
>+            HX_RELEASE(pASMStr);
>+        }
>+        else
>+        {
>+            // We don't have an HXStream object for
>+            // this stream yet so cache the state
>+            // in the STREAM_INFO object
>+            pStreamInfo->m_bClientRateAdapt = FALSE;
>+            res = HXR_OK;
>+        }
>+    }
>+
>+    return res;
>+}
>+
>+/************************************************************************
>+ *     Method:
>+ *         IHXClientRateAdaptControl::IsEnabled
>+ *     Purpose:
>+ *         Is client rate adaptation enabled for the specified stream
>+ *
>+ */
>+STDMETHODIMP
>+HXSource::IsEnabled(THIS_ UINT16 uStreamNum,
>+                    REF(BOOL) bEnabled)
>+{
>+    HX_RESULT res = HXR_INVALID_PARAMETER;
>+
>+    STREAM_INFO* pStreamInfo = NULL;
>+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& 
>)pStreamInfo) &&
>+        pStreamInfo)
>+    {
>+        if (pStreamInfo->m_pStream)
>+        {
>+            IHXASMStream2* pASMStr = NULL;
>+            res = pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
>+                                                         (void**)&pASMStr);
>+
>+            if (HXR_OK == res)
>+            {
>+                bEnabled = !pASMStr->AreSubscriptionsLocked();
>+            }
>+
>+            HX_RELEASE(pASMStr);
>+        }
>+        else
>+        {
>+            // We don't have an HXStream object for
>+            // this stream yet so used the cached
>+            // value in the STREAM_INFO object
>+            bEnabled = pStreamInfo->m_bClientRateAdapt;
>+            res = HXR_OK;
>+        }
>+    }
>+
>      return res;
>  }
>
>Index: strminfo.cpp
>===================================================================
>RCS file: /cvsroot/client/core/strminfo.cpp,v
>retrieving revision 1.6
>diff -u -r1.6 strminfo.cpp
>--- strminfo.cpp        1 Mar 2004 22:13:52 -0000       1.6
>+++ strminfo.cpp        14 Jun 2004 23:43:08 -0000
>@@ -84,6 +84,7 @@
>
>      m_pStream                      = NULL;
>      m_bCanBeStoppedAnyTime         = FALSE;
>+    m_bClientRateAdapt = TRUE;
>
>      // reconnect stuff
>      m_pPreReconnectEventList = NULL;
>Index: strminfo.h
>===================================================================
>RCS file: /cvsroot/client/core/strminfo.h,v
>retrieving revision 1.5
>diff -u -r1.5 strminfo.h
>--- strminfo.h  1 Mar 2004 22:13:52 -0000       1.5
>+++ strminfo.h  14 Jun 2004 23:43:08 -0000
>@@ -121,6 +121,7 @@
>      HX_BITFIELD                m_bPacketRequested : 1;         // is the 
> packet requested from
>      HX_BITFIELD                m_bCustomEndTime : 1;
>      HX_BITFIELD                m_bCanBeStoppedAnyTime : 1;
>+    HX_BITFIELD                m_bClientRateAdapt : 1;
>  };
>
>  /*
>Index: asm/hxsmstr.cpp
>===================================================================
>RCS file: /cvsroot/client/core/asm/hxsmstr.cpp,v
>retrieving revision 1.13
>diff -u -r1.13 hxsmstr.cpp
>--- asm/hxsmstr.cpp     26 Nov 2003 01:37:16 -0000      1.13
>+++ asm/hxsmstr.cpp     14 Jun 2004 23:43:08 -0000
>@@ -87,6 +87,7 @@
>      , m_ulBandwidthAllocation(0)
>      , m_bStartRecalc(FALSE)
>      , m_bTimeStampDeliveryMode(FALSE)
>+    , m_bInitialSubscribe(TRUE)
>      , m_ulLastLimitBandwidth(0xffffffff)
>      , m_pAtomicRuleChange(0)
>      , m_pSubList(0)
>@@ -97,6 +98,8 @@
>      , m_bHasExpression(FALSE)
>      , m_bEndOneRuleEndAll(FALSE)
>      , m_ulLastBandwidth(0)
>+    , m_pRuleEnableState(NULL)
>+    , m_bSubsLocked(FALSE)
>  #ifndef GOLD
>      , m_pEM(0)
>  #endif
>@@ -169,6 +172,7 @@
>         m_bRuleTimeStampDelivery = new BOOL[m_nNumRules];
>         m_pSubInfo = new BOOL[m_nNumRules];
>         m_pRuleSubscribeStatus = new BOOL[m_nNumRules];
>+        m_pRuleEnableState = new RuleEnableState[m_nNumRules];
>
>          for (UINT16 i = 0; i < m_nNumRules; i++)
>          {
>@@ -180,6 +184,7 @@
>             m_ulRuleBw[i] = 0;
>             m_ulRulePreData[i] = 0;
>             m_bRuleTimeStampDelivery[i] = FALSE;
>+            m_pRuleEnableState[i] = resEnabled;
>
>             if (HXR_OK == pValues->GetPropertyCString("PreData",
>                 pBuffer))
>@@ -486,6 +491,7 @@
>      }
>
>      DEBUG_OUT(m_pEM, DOL_ASM, (s, "(%p)Subscribe: Stream=%d Rule=%d", 
> m_pSource, m_uStreamNumber, uRuleNumber));
>+    printf("(%p)Subscribe: Stream=%d Rule=%d\n", m_pSource, 
>m_uStreamNumber, uRuleNumber);
>
>      m_pRuleSubscribeStatus[uRuleNumber] = TRUE;
>
>@@ -529,6 +535,7 @@
>      }
>
>      DEBUG_OUT(m_pEM, DOL_ASM, (s, "(%p)Unsubscribe: Stream=%d Rule=%d", 
> m_pSource, m_uStreamNumber, uRuleNumber));
>+    printf("(%p)Unsubscribe: Stream=%d Rule=%d\n", m_pSource, 
>m_uStreamNumber, uRuleNumber);
>
>      m_pRuleSubscribeStatus[uRuleNumber] = FALSE;
>
>@@ -909,7 +916,28 @@
>             }
>
>              m_pSubInfo[i] = pCurrentSubInfo[i];
>+
>          }
>+
>+        if (m_bInitialSubscribe &&
>+            m_bSubsLocked &&
>+            m_pRuleEnableState &&
>+            m_pRuleBook &&
>+            !m_pSubInfo[i])
>+        {
>+            // This is the initial subscription and
>+            // this rule was not selected.
>+            // Mark it as locked and disable
>+            // the rule in the rulebook
>+            m_pRuleEnableState[i] = resLocked;
>+            m_pRuleBook->Disable(i);
>+        }
>+    }
>+
>+    if (m_bInitialSubscribe)
>+    {
>+        m_bInitialSubscribe = FALSE;
>+        m_pRuleBook->ReCompute();
>      }
>
>      if (m_pAtomicRuleChange && (!m_pSubList) && (!SubChange.IsEmpty()))
>@@ -1122,9 +1150,24 @@
>  STDMETHODIMP_(HX_RESULT)
>  HXASMStream::Enable( UINT16 nRule )
>  {
>-   if( m_pRuleBook )
>+   if( m_pRuleBook  && m_pRuleEnableState)
>     {
>-      m_pRuleBook->Enable( nRule );
>+       if (m_bSubsLocked)
>+       {
>+           // Change the enable state to locked,
>+           // but leave the rule disabled in the
>+           // rulebook. When we leave the locked
>+           // state this rule will be reenabled
>+           // in the rulebook
>+           m_pRuleEnableState[nRule] = resLocked;
>+       }
>+       else
>+       {
>+           // Change the enable state and enable
>+           // the rule in the rulebook
>+           m_pRuleEnableState[nRule] = resEnabled;
>+           m_pRuleBook->Enable( nRule );
>+       }
>     }
>     return HXR_OK;
>  }
>@@ -1132,9 +1175,10 @@
>  STDMETHODIMP_(HX_RESULT)
>  HXASMStream::Disable( UINT16 nRule )
>  {
>-   if( m_pRuleBook )
>+   if( m_pRuleBook && m_pRuleEnableState)
>     {
>-      m_pRuleBook->Disable( nRule );
>+       m_pRuleEnableState[nRule] = resDisabled;
>+       m_pRuleBook->Disable( nRule );
>     }
>      return HXR_OK;
>  }
>@@ -1176,11 +1220,114 @@
>            // We can't subscribe to any stream so reset and fail.
>            for( int ii=0; ii            {
>-              m_pRuleBook->Enable( ii );
>+              Enable( ii );
>            }
>            m_pRuleBook->ReCompute();
>            retVal = HXR_FAIL;
>        }
>     }
>     return retVal;
>+}
>+
>+STDMETHODIMP_(BOOL)
>+HXASMStream::IsEnabled( UINT16 nRule )
>+{
>+    BOOL bRet = TRUE;
>+    if( m_pRuleBook && m_pRuleEnableState &&
>+        (m_pRuleEnableState[nRule] != resDisabled))
>+    {
>+        bRet = FALSE;
>+    }
>+
>+    return bRet;
>+}
>+
>+STDMETHODIMP
>+HXASMStream::LockSubscriptions(THIS)
>+{
>+    HX_RESULT res = HXR_FAILED;
>+
>+    if( m_pRuleBook  && m_pRuleEnableState)
>+    {
>+        if (m_bSubsLocked)
>+        {
>+            // The subscriptions are already locked
>+            res = HXR_OK;
>+        }
>+        else
>+        {
>+            if (!m_bInitialSubscribe)
>+            {
>+                // We only lock and disable rules if we have
>+                // done the inital subscription.
>+                // If we haven't done the initial subscription,
>+                // the locking and disabling of rules will
>+                // happen when the initial subscription occurs.
>+
>+                for (UINT16 i = 0; i < m_nNumRules; i++)
>+                {
>+                    // Change the state of any rules that
>+                    // are currently enabled, but not subscribed
>+                    // to. This makes it so that the rulebook
>+                    // will always evaluate to the current
>+                    // subscriptions
>+                    if (!m_pSubInfo[i] &&
>+                        (m_pRuleEnableState[i] == resEnabled))
>+                    {
>+                        m_pRuleEnableState[i] = resLocked;
>+                        m_pRuleBook->Disable(i);
>+                    }
>+
>+                }
>+                m_pRuleBook->ReCompute();
>+            }
>+
>+            m_bSubsLocked = TRUE;
>+            res = HXR_OK;
>+        }
>+    }
>+
>+    return res;
>+}
>+
>+STDMETHODIMP
>+HXASMStream::UnlockSubscriptions(THIS)
>+{
>+    HX_RESULT res = HXR_FAILED;
>+
>+    if( m_pRuleBook  && m_pRuleEnableState)
>+    {
>+        if (m_bSubsLocked)
>+        {
>+            for (UINT16 i = 0; i < m_nNumRules; i++)
>+            {
>+                // Change the state of any rules that
>+                // are currently locked and enable them
>+                // in the rulebook. This makes it so that
>+                // the rulebook can evaluate to any of the
>+                // enabled rules
>+                if (m_pRuleEnableState[i] == resLocked)
>+                {
>+                    m_pRuleEnableState[i] = resEnabled;
>+                    m_pRuleBook->Enable(i);
>+                }
>+            }
>+            m_pRuleBook->ReCompute();
>+
>+            m_bSubsLocked = FALSE;
>+        }
>+        else
>+        {
>+            // We are currently in an unlocked state
>+            res = HXR_OK;
>+        }
>+    }
>+
>+    return res;
>+}
>+
>+STDMETHODIMP_(BOOL)
>+HXASMStream::AreSubscriptionsLocked(THIS)
>+{
>+    return m_bSubsLocked;
>  }
>Index: pub/hxsmstr.h
>===================================================================
>RCS file: /cvsroot/client/core/pub/hxsmstr.h,v
>retrieving revision 1.6
>diff -u -r1.6 hxsmstr.h
>--- pub/hxsmstr.h       3 May 2004 18:59:31 -0000       1.6
>+++ pub/hxsmstr.h       14 Jun 2004 23:43:08 -0000
>@@ -76,6 +76,9 @@
>      STDMETHOD(Unsubscribe)     (THIS_
>                                 UINT16  uRuleNumber);
>
>+    /*
>+     * IHXASMStream2 methods
>+     */
>      STDMETHOD(Disable)         (THIS_
>                                 UINT16  uRuleNumber);
>
>@@ -84,6 +87,16 @@
>
>      STDMETHOD(ReCompute)       (THIS);
>
>+    STDMETHOD_(BOOL,IsEnabled) (THIS_
>+                               UINT16  uRuleNumber);
>+
>+    STDMETHOD(LockSubscriptions) (THIS);
>+
>+    STDMETHOD (UnlockSubscriptions) (THIS);
>+
>+    STDMETHOD_(BOOL,AreSubscriptionsLocked)(THIS);
>+
>+
>      /*
>       * IHXStreamBandwidthNegotiator methods
>       */
>@@ -157,6 +170,10 @@
>      HX_BITFIELD                m_bInitialSubscribe : 1;
>
>  private:
>+    typedef enum {resEnabled,
>+                  resDisabled,
>+                  resLocked} RuleEnableState;
>+
>      HX_BITFIELD                m_bHasExpression : 1;
>      HX_BITFIELD                m_bEndOneRuleEndAll : 1;
>
>@@ -197,6 +214,8 @@
>
>      BOOL*              m_pRuleSubscribeStatus;
>      CASMRuleState*     m_pASMRuleState;
>+    RuleEnableState*    m_pRuleEnableState;
>+    BOOL                m_bSubsLocked;
>
>      void Recalc();
>      void RecalcCurrentProps();
>
>Index: asmrulep.cpp
>===================================================================
>RCS file: /cvsroot/common/util/asmrulep.cpp,v
>retrieving revision 1.14
>diff -u -r1.14 asmrulep.cpp
>--- asmrulep.cpp        17 Dec 2003 23:41:33 -0000      1.14
>+++ asmrulep.cpp        14 Jun 2004 23:43:19 -0000
>@@ -42,6 +42,7 @@
>  #include "asmrulep.h"  /* ASM Public Include File */
>  #include "asmrulpp.h"  /* ASM Private Include File */
>  #include "chxpckts.h"
>+#include "hxassert.h"
>
>  #define RULE_VAL_INFINITY -1
>
>@@ -687,6 +688,7 @@
>  void
>  ASMRule::SetExpression(const char* pExpression)
>  {
>+    HX_DELETE(m_pRuleExpression);
>      m_pRuleExpression = new ASMRuleExpression(pExpression);
>  }
>
>@@ -801,7 +803,7 @@
>      for (i = 0; i < m_unNumRules; i++)
>      {
>          if( m_pDeletedRulesArray && m_pDeletedRulesArray[i] == TRUE )
>-       {
>+       {
>              pSubInfo[i] = 0;
>         }
>         else if (m_pRules[i].m_pRuleExpression)
>@@ -1181,7 +1183,7 @@
>     // Find the "left edge" rule.
>     for( ii=m_unNumRules-1; ii>=0; ii-- )
>     {
>-      if( ( m_pDeletedRulesArray[ii] == FALSE ) && ( m_pRules[ ii 
>].m_pRuleExpression->GetLeft() || m_pRules[ ii 
>].m_pRuleExpression->GetRight() ) )
>+      if( !m_pDeletedRulesArray[ii] && 
>m_pRules[ii].m_pRuleExpression->IsLeftEdge() )
>        {
>           nLeftEdge = ii;
>        }
>@@ -1260,61 +1262,122 @@
>  void
>  ASMRuleExpression::SetLeft( int nLeft )
>  {
>-   int nRight = ((IntegerNode*) ((VariableNode*)m_pHead->m_pRight))->m_Data;
>-   if( nRight == 1 )
>-   {
>-      ((IntegerNode*)(m_pHead->m_pLeft->m_pRight))->m_Data = nLeft;
>-   }
>+    // This function assumes the following forms
>+    // ($Bandwidth > 123)
>+    // ($Bandwidth >= 123)
>+    // ($Bandwidth > 123) && ($Bandwidth < 1234)
>+    // ($Bandwidth >= 123) && ($Bandwidth < 1234)
>+    //
>+    // It assumes the left-most expression is > or >=
>+
>+    if (m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
>+    {
>+        OperatorNode* pOp = (OperatorNode*)m_pHead;
>+
>+        if (pOp->m_pLeft &&
>+            (pOp->m_pLeft->m_Type == HX_RE_OPERATOR))
>+        {
>+            // ($Bandwidth >= 123) && ($Bandwidth < 1234)
>+            // We want to update the left side
>+            pOp = (OperatorNode*)pOp->m_pLeft;
>+        }
>+
>+        if (NormalizeBwNode(pOp) &&
>+            ((pOp->m_Data == HX_RE_GREATER) ||
>+             (pOp->m_Data == HX_RE_GREATEREQUAL)))
>+        {
>+            IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
>+            pInt->m_Data = nLeft;
>+        }
>+    }
>  }
>
>  void
>  ASMRuleExpression::SetRight( int nRight )
>  {
>-   int nTmpRight = 0;
>-   if( m_pHead && m_pHead->m_pRight )
>-   {
>-      nTmpRight = ((IntegerNode*) 
>((VariableNode*)m_pHead->m_pRight))->m_Data;
>-   }
>+    // This function assumes the following forms
>+    // ($Bandwidth < 123)
>+    // ($Bandwidth <= 123)
>+    // ($Bandwidth > 123) && ($Bandwidth < 1234)
>+    // ($Bandwidth > 123) && ($Bandwidth <= 1234)
>+    //
>+    // It assumes the right-most expression is < or <=
>
>-   if( nTmpRight == 1 )
>-   {
>-      ( (IntegerNode*)((VariableNode*) 
>((VariableNode*)m_pHead->m_pRight)->m_pRight) )->m_Data = nRight;
>-   }
>-   else if( nTmpRight != 0 )
>-   {
>-      ((VariableNode*)m_pHead->m_pRight)->m_Data = (char*)nRight;
>-   }
>+    if (m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
>+    {
>+        OperatorNode* pOp = (OperatorNode*)m_pHead;
>+
>+        if (pOp->m_pRight &&
>+            (pOp->m_pRight->m_Type == HX_RE_OPERATOR))
>+        {
>+            // ($Bandwidth > 123) && ($Bandwidth < 1234)
>+            // We want to update the right side
>+            pOp = (OperatorNode*)pOp->m_pRight;
>+        }
>+
>+        if (NormalizeBwNode(pOp) &&
>+            ((pOp->m_Data == HX_RE_LESS) ||
>+             (pOp->m_Data == HX_RE_LESSEQUAL)))
>+        {
>+            IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
>+            pInt->m_Data = nRight;
>+        }
>+    }
>  }
>
>  float
>  ASMRuleExpression::GetLeft()
>  {
>-   int nLeft = 0;
>-   int nRight = 0;
>-   if( m_pHead && m_pHead->m_pRight )
>-   {
>-      nRight = ((IntegerNode*) ((VariableNode*)m_pHead->m_pRight))->m_Data;
>-   }
>-   if( nRight == 1 )
>-   {
>-      nLeft = ((IntegerNode*) 
>((VariableNode*)m_pHead->m_pLeft->m_pRight))->m_Data;
>-   }
>-   return (float)nLeft;
>+    // This function returns the
>+    // lower bandwidth threshold. It assumes
>+    // that the lower threshold expression
>+    // is always on the left
>+    OperatorNode* pOp = NULL;
>+
>+    if(m_pHead && m_pHead->m_pLeft &&
>+       (m_pHead->m_Type == HX_RE_OPERATOR))
>+    {
>+        // Test for ($Bandwidth > 123) && ($Bandwidth <= 123)
>+        if (m_pHead->m_pLeft->m_Type == HX_RE_OPERATOR)
>+        {
>+            // We want the value from the left node
>+            pOp = (OperatorNode*)m_pHead->m_pLeft;
>+        }
>+        else
>+        {
>+            pOp = (OperatorNode*)m_pHead;
>+        }
>+    }
>+
>+    return (float)GetBwValue(pOp);
>  }
>
>  float
>  ASMRuleExpression::GetRight()
>  {
>-   int nRight = 0;
>-   if( m_pHead && m_pHead->m_pRight )
>-   {
>-      nRight = ((IntegerNode*) ((VariableNode*)(m_pHead->m_pRight)))->m_Data;
>-   }
>-   if( nRight == 1 )
>-   {
>-      nRight = ((IntegerNode*) 
>((VariableNode*)m_pHead->m_pRight->m_pRight))->m_Data;
>-   }
>-   return (float)nRight;
>+    // This function returns the
>+    // upper bandwidth threshold. It assumes
>+    // that the upper threshold expression
>+    // is always on the right
>+
>+    OperatorNode* pOp = NULL;
>+
>+    if(m_pHead && m_pHead->m_pRight &&
>+       (m_pHead->m_Type == HX_RE_OPERATOR))
>+    {
>+        // Test for ($Bandwidth > 123) && ($Bandwidth <= 123)
>+        if (m_pHead->m_pRight->m_Type == HX_RE_OPERATOR)
>+        {
>+            // We want the value from the right node
>+            pOp = (OperatorNode*)m_pHead->m_pRight;
>+        }
>+        else
>+        {
>+            pOp = (OperatorNode*)m_pHead;
>+        }
>+    }
>+
>+    return (float)GetBwValue(pOp);
>  }
>
>  int
>@@ -1323,30 +1386,36 @@
>     return (int) ((OperatorNode*) m_pHead)->m_Data;
>  }
>
>+BOOL
>+ASMRuleExpression::IsLeftEdge()
>+{
>+    // This is a left edge if it
>+    // has a bandwidth value on
>+    // either the left or the right
>+    return ( GetLeft() || GetRight() );
>+}
>+
>+
>  // This function checks to see if the current rule's operator is GREATER or
>  // GREATEROREQUAL, both of which would suggest that we are the "right edge"
>  // rule.
>  BOOL
>  ASMRuleExpression::IsRightEdge()
>  {
>-   if( m_pHead )
>-   {
>-      switch(((OperatorNode*)m_pHead)->m_Data)
>-      {
>-         case HX_RE_GREATER:
>-         case HX_RE_GREATEREQUAL:
>-             return TRUE;
>-             break;
>-
>-          default:
>-             return FALSE;
>-             break;
>-      }
>-   }
>-   else
>-   {
>-      return FALSE;
>-   }
>+    BOOL bRet = FALSE;
>+    if( m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
>+    {
>+        OperatorNode* pOp = (OperatorNode*)m_pHead;
>+
>+        if (NormalizeBwNode(pOp) &&
>+            ((pOp->m_Data == HX_RE_GREATER) ||
>+             (pOp->m_Data == HX_RE_GREATEREQUAL)))
>+        {
>+            bRet = TRUE;
>+        }
>+    }
>+
>+    return bRet;
>  }
>
>  HX_RESULT
>@@ -1487,6 +1556,7 @@
>         }
>      }
>
>+    HX_VECTOR_DELETE(m_pDeletedRulesArray);
>      return InitRulesArray();
>  }
>
>@@ -1506,4 +1576,88 @@
>      }
>
>      return TRUE;
>+}
>+
>+int
>+ASMRuleExpression::GetBwValue(OperatorNode* pOp) const
>+{
>+    int ret = 0;
>+
>+    if (NormalizeBwNode(pOp))
>+    {
>+        // The bandwidth value is always on the right
>+        // after the node has been normalized
>+        IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
>+
>+        ret = pInt->m_Data;
>+    }
>+
>+    return ret;
>+}
>+
>+BOOL
>+ASMRuleExpression::NormalizeBwNode(OperatorNode* pOp) const
>+{
>+    // This function determines if the expression is a
>+    // bandwidth threshold expression and if so it makes sure it
>+    // always has the bandwidth variable on the left side
>+    // and the bandwidth value on the right side
>+    BOOL bRet = FALSE;
>+
>+    if (pOp && pOp->m_pLeft && pOp->m_pRight)
>+    {
>+        VariableNode* pVar = NULL;
>+        IntegerNode* pInt = NULL;
>+
>+        if ((pOp->m_pLeft->m_Type == HX_RE_INTEGER) &&
>+            (pOp->m_pRight->m_Type == HX_RE_VARIABLE))
>+        {
>+            // (123 > somevar)
>+            // (123 >= somevar)
>+            pInt = (IntegerNode*)pOp->m_pLeft;
>+            pVar = (VariableNode*)pOp->m_pRight;
>+        }
>+        else if ((pOp->m_pLeft->m_Type == HX_RE_VARIABLE) &&
>+                 (pOp->m_pRight->m_Type == HX_RE_INTEGER))
>+        {
>+            // (somevar < 123)
>+            // (somevar <= 123)
>+            pVar = (VariableNode*)pOp->m_pLeft;
>+            pInt = (IntegerNode*)pOp->m_pRight;
>+        }
>+
>+        if (pVar && pInt &&
>+            !strcasecmp(pVar->m_Data, "Bandwidth"))
>+        {
>+            // This is a bandwidth node
>+
>+            if (pVar != pOp->m_pLeft)
>+            {
>+                // We need to swap the left and
>+                // right nodes
>+                pOp->m_pLeft = pVar;
>+                pOp->m_pRight = pInt;
>+
>+                // Flip operator around
>+                switch(pOp->m_Data) {
>+                case HX_RE_GREATER:
>+                    pOp->m_Data = HX_RE_LESS;
>+                    break;
>+                case HX_RE_LESS:
>+                    pOp->m_Data = HX_RE_GREATER;
>+                    break;
>+                case HX_RE_GREATEREQUAL:
>+                    pOp->m_Data = HX_RE_LESSEQUAL;
>+                    break;
>+                case HX_RE_LESSEQUAL:
>+                    pOp->m_Data = HX_RE_GREATEREQUAL;
>+                    break;
>+                };
>+            }
>+
>+            bRet = TRUE;
>+        }
>+    }
>+
>+    return bRet;
>  }
>Index: pub/asmrulpp.h
>===================================================================
>RCS file: /cvsroot/common/util/pub/asmrulpp.h,v
>retrieving revision 1.3
>diff -u -r1.3 asmrulpp.h
>--- pub/asmrulpp.h      18 Apr 2003 18:04:36 -0000      1.3
>+++ pub/asmrulpp.h      14 Jun 2004 23:43:20 -0000
>@@ -68,6 +68,7 @@
>                         ~ASMRuleExpression();
>      void               Dump();
>      BOOL               Evaluate(IHXValues* pVars);
>+    BOOL               IsLeftEdge();
>      BOOL               IsRightEdge();
>      float              GetLeft();
>      float              GetRight();
>@@ -124,6 +125,8 @@
>                                  float*& pThreshold, UINT32& ulNumThreshold,
>                                  BOOL& bInvolvesTheOpenVariable);
>      BOOL               RFindVariable(Node* pNode, const char* pVariable);
>+    int                 GetBwValue(OperatorNode* pOp) const;
>+    BOOL                NormalizeBwNode(OperatorNode* pOp) const;
>
>      UINT32             m_ulNumThresholds;
>      Node*              m_pHead;
>Index: hxasm.h
>===================================================================
>RCS file: /cvsroot/common/include/hxasm.h,v
>retrieving revision 1.3
>diff -u -r1.3 hxasm.h
>--- hxasm.h     18 Apr 2003 18:03:27 -0000      1.3
>+++ hxasm.h     14 Jun 2004 23:44:15 -0000
>@@ -301,6 +301,44 @@
>                                 UINT16  uRuleNumber) PURE;
>
>      STDMETHOD (ReCompute)      (THIS) PURE;
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXASMStream2::IsEnabled
>+     * Purpose:
>+     *      Allows a user to determine if a rule is enabled or not
>+     */
>+    STDMETHOD_(BOOL,IsEnabled) (THIS_
>+                               UINT16  uRuleNumber) PURE;
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXASMStream2::LockSubscriptions
>+     * Purpose:
>+     *      Locks the stream to the current subscriptions. This has the
>+     *      effect of disabling the client side rate adaptation for this
>+     *      stream.
>+     */
>+    STDMETHOD (LockSubscriptions)(THIS) PURE;
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXASMStream2::UnlockSubscriptions
>+     * Purpose:
>+     *      Unlocks the stream so that the enabled streams can be selected
>+     *      by the ASM code. This has the effect of reenabling the client 
>side
>+     *      rate adaptation for this stream.
>+     */
>+    STDMETHOD (UnlockSubscriptions)(THIS) PURE;
>+
>+    /************************************************************************
>+     * Method:
>+     *     IHXASMStream2::AreSubscriptionsLocked
>+     * Purpose:
>+     *      Lets you determine whether the stream subscriptions are locked
>+     *      or not.
>+     */
>+    STDMETHOD_(BOOL, AreSubscriptionsLocked)(THIS) PURE;
>  };
>
>
>Index: hxpiids.h
>===================================================================
>RCS file: /cvsroot/common/include/hxpiids.h,v
>retrieving revision 1.28
>diff -u -r1.28 hxpiids.h
>--- hxpiids.h   8 Apr 2004 00:55:04 -0000       1.28
>+++ hxpiids.h   14 Jun 2004 23:44:15 -0000
>@@ -989,4 +989,14 @@
>  DEFINE_GUID_ENUM(IID_IHXAccessPointSelector, 0x9e9ca2d6, 0xcbfe, 0x40f8, 
> 0x94,
>                 0xfd, 0x38, 0xf4, 0xeb, 0x5d, 0xf8, 0x12)
>
>+/* File:
>+ *      ihxrateadaptctl.h
>+ *
>+ * Description:
>+ *      Rate adaptation control interfaces
>+ */
>+DEFINE_GUID_ENUM(IID_IHXClientRateAdaptControl, 0x44f5ac8c, 0x654c, 
>0x414e, 0x9d,
>+                 0x18, 0xe7, 0xa4, 0x80, 0x90, 0x70, 0x9)
>+
>  #endif /* _HXPRIVATEIIDS_H_ */
>+
>
>_______________________________________________
>Client-dev mailing list
>Client-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/client-dev


From acolwell at real.com  Tue Jun 15 09:40:29 2004
From: acolwell at real.com (Aaron Colwell)
Date: Tue Jun 15 09:42:06 2004
Subject: [Common-dev] CN-Client: Changes to turn off client rate adaptation
In-Reply-To: <5.1.0.14.2.20040615084500.03810ef0@mailone.real.com>
References: <20040615000303.GA30519@real.com>
	<5.1.0.14.2.20040615084500.03810ef0@mailone.real.com>
Message-ID: <20040615164029.GA941@real.com>

Good catches. I noticed the printfs right after I sent out the review, but I
didn't see that I forgot to delete m_pRuleEnableState. m_pRuleEnableState is 
now deleted with all the other arrays in that class.

The code is now checked in.

Modified by: acolwell@real.com

Reviewed by: ping@real.com

Date: 06:15:2004

Project: HEAD, hxclient_ipv4_2004-5-19




On Tue, Jun 15, 2004 at 08:47:51AM -0700, Henry Ping wrote:
> Looks good, except m_pRuleEnableState needs to be deleted and printf() 
> statement needs to be removed
> 
> -->Henry
> 
> At 05:03 PM 6/14/2004 -0700, Aaron Colwell wrote:
> >Synopsis: Added functionality to allow client rate adaptation to be turned 
> >off
> >          on a per stream basis
> >
> >Overview: These changes allow you to turn client rate adaptation on an off
> >          for each stream. You can use either the IHXClientRateAdaptControl
> >          interface or the IHXASMStream2 interface to do this.
> >          The IHXClientRateAdaptControl interface is needed because some 
> >          code
> >          may want to turn off rate adaptation before any IHXASMStream2 
> >objects
> >          are available. This can happen if rate adaptation is negotiated
> >          before the renderers are initialized.
> >
> >          - IHXClientRateAdaptControl interface was added to HXSource
> >            so that the RTSP code can turn off rate adaptation before
> >            IHXASMStream2 objects are available
> >
> >          - IHXASMStream2 interface was extended to allow the 
> >subscriptions to
> >            be locked and unlocked. This is how the rate adaptation is 
> >            turned
> >            on and off. When the subscriptions are locked the ASM code will
> >            not change the subscriptions for that stream. Client rate
> >            adaptation is on by default. Code was added to HXASMStream for
> >            these new methods.
> >            IHXASMStream2 is currently only used by the RA renderer so
> >            adding to this interface should not cause any problems.
> >
> >          - Fixed a memory leak in the ASMRuleExpression code
> >
> >          - Cleaned up some of the ASMRuleExpression code and made it a 
> >little
> >            more robust. Parts of the old code were implemented 
> >incorrectly or
> >            made huge assumptions about the rule expressions. Several blind
> >            casts were removed and checks were added to make sure the
> >            expression is actually a bandwidth expression. I also added 
> >checks
> >            to make sure the expression is of the expected form.
> >
> >Files Modified:
> >client/core/hxbsrc.h
> >client/core/hxsrc.cpp
> >client/core/strminfo.cpp
> >client/core/strminfo.h
> >client/core/asm/hxsmstr.cpp
> >client/core/pub/hxsmstr.h
> >common/util/asmrulep.cpp
> >common/util/pub/asmrulpp.h
> >common/include/hxasm.h
> >common/include/hxpiids.h
> >
> >Files Added:
> >common/include/ihxrateadaptctl.h
> >
> >Image Size and Heap Use impact:
> >
> >Platforms and Profiles affected: all
> >
> >Distribution Libraries affected: none
> >
> >Distribution library impact and planned action: none
> >
> >Platforms and Profiles Build Verified: win32
> >
> >Platforms and Profiles Functionality verified: win32
> >
> >Branch: HEAD
> >
> >QA Instructions: none
> >
> >
> >Index: hxbsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbsrc.h,v
> >retrieving revision 1.18
> >diff -u -r1.18 hxbsrc.h
> >--- hxbsrc.h    19 May 2004 19:37:33 -0000      1.18
> >+++ hxbsrc.h    14 Jun 2004 23:43:08 -0000
> >@@ -59,6 +59,7 @@
> > #include "smiltype.h"
> > #include "recordctl.h"
> > #include "hxcore.h"
> >+#include "ihxrateadaptctl.h"
> >
> > // need to go in hxresult.h
> > #define HX_INVALID_HEADER                      HXR_INVALID_PARAMETER
> >@@ -232,6 +233,7 @@
> >                  public IHXPrivateStreamSource,
> >                  public IHXBackChannel,
> >                  public IHXASMSource,
> >+                  public IHXClientRateAdaptControl,
> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >                  public IHXHyperNavigate,
> >                  public IHXHyperNavigate2,
> >@@ -512,6 +514,39 @@
> >                                   REF(INT64)  llHighestTimestamp,
> >                                   REF(UINT32) ulNumBytes,
> >                                   REF(BOOL)   bDone);
> >+
> >+
> >+    /*
> >+     * IHXClientRateAdaptControl Methods
> >+     */
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXClientRateAdaptControl::Enable
> >+     * Purpose:
> >+     *     Enable client rate adaptation for the specified stream
> >+     *
> >+     */
> >+    STDMETHOD(Enable) (THIS_ UINT16 uStreamNum);
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXClientRateAdaptControl::Disable
> >+     * Purpose:
> >+     *     Disable client rate adaptation for the specified stream
> >+     *
> >+     */
> >+    STDMETHOD(Disable) (THIS_ UINT16 uStreamNum);
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXClientRateAdaptControl::IsEnabled
> >+     * Purpose:
> >+     *     Is client rate adaptation enabled for the specified stream
> >+     *
> >+     */
> >+    STDMETHOD(IsEnabled) (THIS_ UINT16 uStreamNum,
> >+                          REF(BOOL) bEnabled);
> >
> >     HX_RESULT          Init(HXPlayer * player, UINT32 unRegistryID);
> >     HX_RESULT          SetupRegistry(void);
> >Index: hxsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxsrc.cpp,v
> >retrieving revision 1.44
> >diff -u -r1.44 hxsrc.cpp
> >--- hxsrc.cpp   19 May 2004 19:37:33 -0000      1.44
> >+++ hxsrc.cpp   14 Jun 2004 23:43:08 -0000
> >@@ -342,6 +342,8 @@
> >             { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> >(IHXPrivateStreamSource*)this },
> >             { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
> >(IHXSourceBufferingStats*)this },
> >             { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
> >(IHXSourceBufferingStats2*)this },
> >+            { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
> >+              (IHXClientRateAdaptControl*)this },
> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >             { GET_IIDHANDLE(IID_IHXHyperNavigate), 
> >(IHXHyperNavigate*)this },
> >             { GET_IIDHANDLE(IID_IHXHyperNavigate2), 
> >(IHXHyperNavigate2*)this },
> >@@ -691,6 +693,20 @@
> >        pStreamInfo->m_pStream->AddRef();
> >
> >        pStreamInfo->BufferingState().OnStream((IHXStream*)pStream);
> >+
> >+        // Now that we have an HXStream object and
> >+        // set pStreamInfo->m_pStream, we should
> >+        // use the cached rate adaptation state
> >+        // to update the rate adaptation state in
> >+        // the HXStream object.
> >+        if (pStreamInfo->m_bClientRateAdapt)
> >+        {
> >+            Enable(pStreamInfo->m_uStreamNumber);
> >+        }
> >+        else
> >+        {
> >+            Disable(pStreamInfo->m_uStreamNumber);
> >+        }
> >     }
> > }
> >
> >@@ -2284,6 +2300,147 @@
> >     }
> >
> >
> >+    return res;
> >+}
> >+
> >+/*
> >+ * IHXClientRateAdaptControl Methods
> >+ */
> >+
> >+/************************************************************************
> >+ *     Method:
> >+ *         IHXClientRateAdaptControl::Enable
> >+ *     Purpose:
> >+ *         Enable client rate adaptation for the specified stream
> >+ *
> >+ */
> >+STDMETHODIMP
> >+HXSource::Enable(THIS_ UINT16 uStreamNum)
> >+{
> >+    HX_RESULT res = HXR_INVALID_PARAMETER;
> >+
> >+    STREAM_INFO* pStreamInfo = NULL;
> >+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& 
> >)pStreamInfo) &&
> >+        pStreamInfo)
> >+    {
> >+        if (pStreamInfo->m_pStream)
> >+        {
> >+            IHXASMStream2* pASMStr = NULL;
> >+            res = 
> >pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
> >+                                                         
> >(void**)&pASMStr);
> >+
> >+            if (HXR_OK == res)
> >+            {
> >+                res = pASMStr->UnlockSubscriptions();
> >+
> >+                if (HXR_OK == res)
> >+                {
> >+                    pStreamInfo->m_bClientRateAdapt = TRUE;
> >+                }
> >+            }
> >+
> >+            HX_RELEASE(pASMStr);
> >+        }
> >+        else
> >+        {
> >+            // We don't have an HXStream object for
> >+            // this stream yet so cache the state
> >+            // in the STREAM_INFO object
> >+            pStreamInfo->m_bClientRateAdapt = TRUE;
> >+            res = HXR_OK;
> >+        }
> >+    }
> >+
> >+    return res;
> >+}
> >+
> >+/************************************************************************
> >+ *     Method:
> >+ *         IHXClientRateAdaptControl::Disable
> >+ *     Purpose:
> >+ *         Disable client rate adaptation for the specified stream
> >+ *
> >+ */
> >+STDMETHODIMP
> >+HXSource::Disable(THIS_ UINT16 uStreamNum)
> >+{
> >+    HX_RESULT res = HXR_INVALID_PARAMETER;
> >+
> >+    STREAM_INFO* pStreamInfo = NULL;
> >+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& 
> >)pStreamInfo) &&
> >+        pStreamInfo)
> >+    {
> >+        if (pStreamInfo->m_pStream)
> >+        {
> >+            IHXASMStream2* pASMStr = NULL;
> >+            res = 
> >pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
> >+                                                         
> >(void**)&pASMStr);
> >+
> >+            if (HXR_OK == res)
> >+            {
> >+                res = pASMStr->LockSubscriptions();
> >+
> >+                if (HXR_OK == res)
> >+                {
> >+                    pStreamInfo->m_bClientRateAdapt = FALSE;
> >+                }
> >+            }
> >+
> >+            HX_RELEASE(pASMStr);
> >+        }
> >+        else
> >+        {
> >+            // We don't have an HXStream object for
> >+            // this stream yet so cache the state
> >+            // in the STREAM_INFO object
> >+            pStreamInfo->m_bClientRateAdapt = FALSE;
> >+            res = HXR_OK;
> >+        }
> >+    }
> >+
> >+    return res;
> >+}
> >+
> >+/************************************************************************
> >+ *     Method:
> >+ *         IHXClientRateAdaptControl::IsEnabled
> >+ *     Purpose:
> >+ *         Is client rate adaptation enabled for the specified stream
> >+ *
> >+ */
> >+STDMETHODIMP
> >+HXSource::IsEnabled(THIS_ UINT16 uStreamNum,
> >+                    REF(BOOL) bEnabled)
> >+{
> >+    HX_RESULT res = HXR_INVALID_PARAMETER;
> >+
> >+    STREAM_INFO* pStreamInfo = NULL;
> >+    if (mStreamInfoTable->Lookup((LONG32) uStreamNum, (void*& 
> >)pStreamInfo) &&
> >+        pStreamInfo)
> >+    {
> >+        if (pStreamInfo->m_pStream)
> >+        {
> >+            IHXASMStream2* pASMStr = NULL;
> >+            res = 
> >pStreamInfo->m_pStream->QueryInterface(IID_IHXASMStream2,
> >+                                                         
> >(void**)&pASMStr);
> >+
> >+            if (HXR_OK == res)
> >+            {
> >+                bEnabled = !pASMStr->AreSubscriptionsLocked();
> >+            }
> >+
> >+            HX_RELEASE(pASMStr);
> >+        }
> >+        else
> >+        {
> >+            // We don't have an HXStream object for
> >+            // this stream yet so used the cached
> >+            // value in the STREAM_INFO object
> >+            bEnabled = pStreamInfo->m_bClientRateAdapt;
> >+            res = HXR_OK;
> >+        }
> >+    }
> >+
> >     return res;
> > }
> >
> >Index: strminfo.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/strminfo.cpp,v
> >retrieving revision 1.6
> >diff -u -r1.6 strminfo.cpp
> >--- strminfo.cpp        1 Mar 2004 22:13:52 -0000       1.6
> >+++ strminfo.cpp        14 Jun 2004 23:43:08 -0000
> >@@ -84,6 +84,7 @@
> >
> >     m_pStream                      = NULL;
> >     m_bCanBeStoppedAnyTime         = FALSE;
> >+    m_bClientRateAdapt = TRUE;
> >
> >     // reconnect stuff
> >     m_pPreReconnectEventList = NULL;
> >Index: strminfo.h
> >===================================================================
> >RCS file: /cvsroot/client/core/strminfo.h,v
> >retrieving revision 1.5
> >diff -u -r1.5 strminfo.h
> >--- strminfo.h  1 Mar 2004 22:13:52 -0000       1.5
> >+++ strminfo.h  14 Jun 2004 23:43:08 -0000
> >@@ -121,6 +121,7 @@
> >     HX_BITFIELD                m_bPacketRequested : 1;         // is the 
> >packet requested from
> >     HX_BITFIELD                m_bCustomEndTime : 1;
> >     HX_BITFIELD                m_bCanBeStoppedAnyTime : 1;
> >+    HX_BITFIELD                m_bClientRateAdapt : 1;
> > };
> >
> > /*
> >Index: asm/hxsmstr.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/asm/hxsmstr.cpp,v
> >retrieving revision 1.13
> >diff -u -r1.13 hxsmstr.cpp
> >--- asm/hxsmstr.cpp     26 Nov 2003 01:37:16 -0000      1.13
> >+++ asm/hxsmstr.cpp     14 Jun 2004 23:43:08 -0000
> >@@ -87,6 +87,7 @@
> >     , m_ulBandwidthAllocation(0)
> >     , m_bStartRecalc(FALSE)
> >     , m_bTimeStampDeliveryMode(FALSE)
> >+    , m_bInitialSubscribe(TRUE)
> >     , m_ulLastLimitBandwidth(0xffffffff)
> >     , m_pAtomicRuleChange(0)
> >     , m_pSubList(0)
> >@@ -97,6 +98,8 @@
> >     , m_bHasExpression(FALSE)
> >     , m_bEndOneRuleEndAll(FALSE)
> >     , m_ulLastBandwidth(0)
> >+    , m_pRuleEnableState(NULL)
> >+    , m_bSubsLocked(FALSE)
> > #ifndef GOLD
> >     , m_pEM(0)
> > #endif
> >@@ -169,6 +172,7 @@
> >        m_bRuleTimeStampDelivery = new BOOL[m_nNumRules];
> >        m_pSubInfo = new BOOL[m_nNumRules];
> >        m_pRuleSubscribeStatus = new BOOL[m_nNumRules];
> >+        m_pRuleEnableState = new RuleEnableState[m_nNumRules];
> >
> >         for (UINT16 i = 0; i < m_nNumRules; i++)
> >         {
> >@@ -180,6 +184,7 @@
> >            m_ulRuleBw[i] = 0;
> >            m_ulRulePreData[i] = 0;
> >            m_bRuleTimeStampDelivery[i] = FALSE;
> >+            m_pRuleEnableState[i] = resEnabled;
> >
> >            if (HXR_OK == pValues->GetPropertyCString("PreData",
> >                pBuffer))
> >@@ -486,6 +491,7 @@
> >     }
> >
> >     DEBUG_OUT(m_pEM, DOL_ASM, (s, "(%p)Subscribe: Stream=%d Rule=%d", 
> >m_pSource, m_uStreamNumber, uRuleNumber));
> >+    printf("(%p)Subscribe: Stream=%d Rule=%d\n", m_pSource, 
> >m_uStreamNumber, uRuleNumber);
> >
> >     m_pRuleSubscribeStatus[uRuleNumber] = TRUE;
> >
> >@@ -529,6 +535,7 @@
> >     }
> >
> >     DEBUG_OUT(m_pEM, DOL_ASM, (s, "(%p)Unsubscribe: Stream=%d Rule=%d", 
> >m_pSource, m_uStreamNumber, uRuleNumber));
> >+    printf("(%p)Unsubscribe: Stream=%d Rule=%d\n", m_pSource, 
> >m_uStreamNumber, uRuleNumber);
> >
> >     m_pRuleSubscribeStatus[uRuleNumber] = FALSE;
> >
> >@@ -909,7 +916,28 @@
> >            }
> >
> >             m_pSubInfo[i] = pCurrentSubInfo[i];
> >+
> >         }
> >+
> >+        if (m_bInitialSubscribe &&
> >+            m_bSubsLocked &&
> >+            m_pRuleEnableState &&
> >+            m_pRuleBook &&
> >+            !m_pSubInfo[i])
> >+        {
> >+            // This is the initial subscription and
> >+            // this rule was not selected.
> >+            // Mark it as locked and disable
> >+            // the rule in the rulebook
> >+            m_pRuleEnableState[i] = resLocked;
> >+            m_pRuleBook->Disable(i);
> >+        }
> >+    }
> >+
> >+    if (m_bInitialSubscribe)
> >+    {
> >+        m_bInitialSubscribe = FALSE;
> >+        m_pRuleBook->ReCompute();
> >     }
> >
> >     if (m_pAtomicRuleChange && (!m_pSubList) && (!SubChange.IsEmpty()))
> >@@ -1122,9 +1150,24 @@
> > STDMETHODIMP_(HX_RESULT)
> > HXASMStream::Enable( UINT16 nRule )
> > {
> >-   if( m_pRuleBook )
> >+   if( m_pRuleBook  && m_pRuleEnableState)
> >    {
> >-      m_pRuleBook->Enable( nRule );
> >+       if (m_bSubsLocked)
> >+       {
> >+           // Change the enable state to locked,
> >+           // but leave the rule disabled in the
> >+           // rulebook. When we leave the locked
> >+           // state this rule will be reenabled
> >+           // in the rulebook
> >+           m_pRuleEnableState[nRule] = resLocked;
> >+       }
> >+       else
> >+       {
> >+           // Change the enable state and enable
> >+           // the rule in the rulebook
> >+           m_pRuleEnableState[nRule] = resEnabled;
> >+           m_pRuleBook->Enable( nRule );
> >+       }
> >    }
> >    return HXR_OK;
> > }
> >@@ -1132,9 +1175,10 @@
> > STDMETHODIMP_(HX_RESULT)
> > HXASMStream::Disable( UINT16 nRule )
> > {
> >-   if( m_pRuleBook )
> >+   if( m_pRuleBook && m_pRuleEnableState)
> >    {
> >-      m_pRuleBook->Disable( nRule );
> >+       m_pRuleEnableState[nRule] = resDisabled;
> >+       m_pRuleBook->Disable( nRule );
> >    }
> >     return HXR_OK;
> > }
> >@@ -1176,11 +1220,114 @@
> >           // We can't subscribe to any stream so reset and fail.
> >           for( int ii=0; ii >           {
> >-              m_pRuleBook->Enable( ii );
> >+              Enable( ii );
> >           }
> >           m_pRuleBook->ReCompute();
> >           retVal = HXR_FAIL;
> >       }
> >    }
> >    return retVal;
> >+}
> >+
> >+STDMETHODIMP_(BOOL)
> >+HXASMStream::IsEnabled( UINT16 nRule )
> >+{
> >+    BOOL bRet = TRUE;
> >+    if( m_pRuleBook && m_pRuleEnableState &&
> >+        (m_pRuleEnableState[nRule] != resDisabled))
> >+    {
> >+        bRet = FALSE;
> >+    }
> >+
> >+    return bRet;
> >+}
> >+
> >+STDMETHODIMP
> >+HXASMStream::LockSubscriptions(THIS)
> >+{
> >+    HX_RESULT res = HXR_FAILED;
> >+
> >+    if( m_pRuleBook  && m_pRuleEnableState)
> >+    {
> >+        if (m_bSubsLocked)
> >+        {
> >+            // The subscriptions are already locked
> >+            res = HXR_OK;
> >+        }
> >+        else
> >+        {
> >+            if (!m_bInitialSubscribe)
> >+            {
> >+                // We only lock and disable rules if we have
> >+                // done the inital subscription.
> >+                // If we haven't done the initial subscription,
> >+                // the locking and disabling of rules will
> >+                // happen when the initial subscription occurs.
> >+
> >+                for (UINT16 i = 0; i < m_nNumRules; i++)
> >+                {
> >+                    // Change the state of any rules that
> >+                    // are currently enabled, but not subscribed
> >+                    // to. This makes it so that the rulebook
> >+                    // will always evaluate to the current
> >+                    // subscriptions
> >+                    if (!m_pSubInfo[i] &&
> >+                        (m_pRuleEnableState[i] == resEnabled))
> >+                    {
> >+                        m_pRuleEnableState[i] = resLocked;
> >+                        m_pRuleBook->Disable(i);
> >+                    }
> >+
> >+                }
> >+                m_pRuleBook->ReCompute();
> >+            }
> >+
> >+            m_bSubsLocked = TRUE;
> >+            res = HXR_OK;
> >+        }
> >+    }
> >+
> >+    return res;
> >+}
> >+
> >+STDMETHODIMP
> >+HXASMStream::UnlockSubscriptions(THIS)
> >+{
> >+    HX_RESULT res = HXR_FAILED;
> >+
> >+    if( m_pRuleBook  && m_pRuleEnableState)
> >+    {
> >+        if (m_bSubsLocked)
> >+        {
> >+            for (UINT16 i = 0; i < m_nNumRules; i++)
> >+            {
> >+                // Change the state of any rules that
> >+                // are currently locked and enable them
> >+                // in the rulebook. This makes it so that
> >+                // the rulebook can evaluate to any of the
> >+                // enabled rules
> >+                if (m_pRuleEnableState[i] == resLocked)
> >+                {
> >+                    m_pRuleEnableState[i] = resEnabled;
> >+                    m_pRuleBook->Enable(i);
> >+                }
> >+            }
> >+            m_pRuleBook->ReCompute();
> >+
> >+            m_bSubsLocked = FALSE;
> >+        }
> >+        else
> >+        {
> >+            // We are currently in an unlocked state
> >+            res = HXR_OK;
> >+        }
> >+    }
> >+
> >+    return res;
> >+}
> >+
> >+STDMETHODIMP_(BOOL)
> >+HXASMStream::AreSubscriptionsLocked(THIS)
> >+{
> >+    return m_bSubsLocked;
> > }
> >Index: pub/hxsmstr.h
> >===================================================================
> >RCS file: /cvsroot/client/core/pub/hxsmstr.h,v
> >retrieving revision 1.6
> >diff -u -r1.6 hxsmstr.h
> >--- pub/hxsmstr.h       3 May 2004 18:59:31 -0000       1.6
> >+++ pub/hxsmstr.h       14 Jun 2004 23:43:08 -0000
> >@@ -76,6 +76,9 @@
> >     STDMETHOD(Unsubscribe)     (THIS_
> >                                UINT16  uRuleNumber);
> >
> >+    /*
> >+     * IHXASMStream2 methods
> >+     */
> >     STDMETHOD(Disable)         (THIS_
> >                                UINT16  uRuleNumber);
> >
> >@@ -84,6 +87,16 @@
> >
> >     STDMETHOD(ReCompute)       (THIS);
> >
> >+    STDMETHOD_(BOOL,IsEnabled) (THIS_
> >+                               UINT16  uRuleNumber);
> >+
> >+    STDMETHOD(LockSubscriptions) (THIS);
> >+
> >+    STDMETHOD (UnlockSubscriptions) (THIS);
> >+
> >+    STDMETHOD_(BOOL,AreSubscriptionsLocked)(THIS);
> >+
> >+
> >     /*
> >      * IHXStreamBandwidthNegotiator methods
> >      */
> >@@ -157,6 +170,10 @@
> >     HX_BITFIELD                m_bInitialSubscribe : 1;
> >
> > private:
> >+    typedef enum {resEnabled,
> >+                  resDisabled,
> >+                  resLocked} RuleEnableState;
> >+
> >     HX_BITFIELD                m_bHasExpression : 1;
> >     HX_BITFIELD                m_bEndOneRuleEndAll : 1;
> >
> >@@ -197,6 +214,8 @@
> >
> >     BOOL*              m_pRuleSubscribeStatus;
> >     CASMRuleState*     m_pASMRuleState;
> >+    RuleEnableState*    m_pRuleEnableState;
> >+    BOOL                m_bSubsLocked;
> >
> >     void Recalc();
> >     void RecalcCurrentProps();
> >
> >Index: asmrulep.cpp
> >===================================================================
> >RCS file: /cvsroot/common/util/asmrulep.cpp,v
> >retrieving revision 1.14
> >diff -u -r1.14 asmrulep.cpp
> >--- asmrulep.cpp        17 Dec 2003 23:41:33 -0000      1.14
> >+++ asmrulep.cpp        14 Jun 2004 23:43:19 -0000
> >@@ -42,6 +42,7 @@
> > #include "asmrulep.h"  /* ASM Public Include File */
> > #include "asmrulpp.h"  /* ASM Private Include File */
> > #include "chxpckts.h"
> >+#include "hxassert.h"
> >
> > #define RULE_VAL_INFINITY -1
> >
> >@@ -687,6 +688,7 @@
> > void
> > ASMRule::SetExpression(const char* pExpression)
> > {
> >+    HX_DELETE(m_pRuleExpression);
> >     m_pRuleExpression = new ASMRuleExpression(pExpression);
> > }
> >
> >@@ -801,7 +803,7 @@
> >     for (i = 0; i < m_unNumRules; i++)
> >     {
> >         if( m_pDeletedRulesArray && m_pDeletedRulesArray[i] == TRUE )
> >-       {
> >+       {
> >             pSubInfo[i] = 0;
> >        }
> >        else if (m_pRules[i].m_pRuleExpression)
> >@@ -1181,7 +1183,7 @@
> >    // Find the "left edge" rule.
> >    for( ii=m_unNumRules-1; ii>=0; ii-- )
> >    {
> >-      if( ( m_pDeletedRulesArray[ii] == FALSE ) && ( m_pRules[ ii 
> >].m_pRuleExpression->GetLeft() || m_pRules[ ii 
> >].m_pRuleExpression->GetRight() ) )
> >+      if( !m_pDeletedRulesArray[ii] && 
> >m_pRules[ii].m_pRuleExpression->IsLeftEdge() )
> >       {
> >          nLeftEdge = ii;
> >       }
> >@@ -1260,61 +1262,122 @@
> > void
> > ASMRuleExpression::SetLeft( int nLeft )
> > {
> >-   int nRight = ((IntegerNode*) 
> >((VariableNode*)m_pHead->m_pRight))->m_Data;
> >-   if( nRight == 1 )
> >-   {
> >-      ((IntegerNode*)(m_pHead->m_pLeft->m_pRight))->m_Data = nLeft;
> >-   }
> >+    // This function assumes the following forms
> >+    // ($Bandwidth > 123)
> >+    // ($Bandwidth >= 123)
> >+    // ($Bandwidth > 123) && ($Bandwidth < 1234)
> >+    // ($Bandwidth >= 123) && ($Bandwidth < 1234)
> >+    //
> >+    // It assumes the left-most expression is > or >=
> >+
> >+    if (m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
> >+    {
> >+        OperatorNode* pOp = (OperatorNode*)m_pHead;
> >+
> >+        if (pOp->m_pLeft &&
> >+            (pOp->m_pLeft->m_Type == HX_RE_OPERATOR))
> >+        {
> >+            // ($Bandwidth >= 123) && ($Bandwidth < 1234)
> >+            // We want to update the left side
> >+            pOp = (OperatorNode*)pOp->m_pLeft;
> >+        }
> >+
> >+        if (NormalizeBwNode(pOp) &&
> >+            ((pOp->m_Data == HX_RE_GREATER) ||
> >+             (pOp->m_Data == HX_RE_GREATEREQUAL)))
> >+        {
> >+            IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
> >+            pInt->m_Data = nLeft;
> >+        }
> >+    }
> > }
> >
> > void
> > ASMRuleExpression::SetRight( int nRight )
> > {
> >-   int nTmpRight = 0;
> >-   if( m_pHead && m_pHead->m_pRight )
> >-   {
> >-      nTmpRight = ((IntegerNode*) 
> >((VariableNode*)m_pHead->m_pRight))->m_Data;
> >-   }
> >+    // This function assumes the following forms
> >+    // ($Bandwidth < 123)
> >+    // ($Bandwidth <= 123)
> >+    // ($Bandwidth > 123) && ($Bandwidth < 1234)
> >+    // ($Bandwidth > 123) && ($Bandwidth <= 1234)
> >+    //
> >+    // It assumes the right-most expression is < or <=
> >
> >-   if( nTmpRight == 1 )
> >-   {
> >-      ( (IntegerNode*)((VariableNode*) 
> >((VariableNode*)m_pHead->m_pRight)->m_pRight) )->m_Data = nRight;
> >-   }
> >-   else if( nTmpRight != 0 )
> >-   {
> >-      ((VariableNode*)m_pHead->m_pRight)->m_Data = (char*)nRight;
> >-   }
> >+    if (m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
> >+    {
> >+        OperatorNode* pOp = (OperatorNode*)m_pHead;
> >+
> >+        if (pOp->m_pRight &&
> >+            (pOp->m_pRight->m_Type == HX_RE_OPERATOR))
> >+        {
> >+            // ($Bandwidth > 123) && ($Bandwidth < 1234)
> >+            // We want to update the right side
> >+            pOp = (OperatorNode*)pOp->m_pRight;
> >+        }
> >+
> >+        if (NormalizeBwNode(pOp) &&
> >+            ((pOp->m_Data == HX_RE_LESS) ||
> >+             (pOp->m_Data == HX_RE_LESSEQUAL)))
> >+        {
> >+            IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
> >+            pInt->m_Data = nRight;
> >+        }
> >+    }
> > }
> >
> > float
> > ASMRuleExpression::GetLeft()
> > {
> >-   int nLeft = 0;
> >-   int nRight = 0;
> >-   if( m_pHead && m_pHead->m_pRight )
> >-   {
> >-      nRight = ((IntegerNode*) 
> >((VariableNode*)m_pHead->m_pRight))->m_Data;
> >-   }
> >-   if( nRight == 1 )
> >-   {
> >-      nLeft = ((IntegerNode*) 
> >((VariableNode*)m_pHead->m_pLeft->m_pRight))->m_Data;
> >-   }
> >-   return (float)nLeft;
> >+    // This function returns the
> >+    // lower bandwidth threshold. It assumes
> >+    // that the lower threshold expression
> >+    // is always on the left
> >+    OperatorNode* pOp = NULL;
> >+
> >+    if(m_pHead && m_pHead->m_pLeft &&
> >+       (m_pHead->m_Type == HX_RE_OPERATOR))
> >+    {
> >+        // Test for ($Bandwidth > 123) && ($Bandwidth <= 123)
> >+        if (m_pHead->m_pLeft->m_Type == HX_RE_OPERATOR)
> >+        {
> >+            // We want the value from the left node
> >+            pOp = (OperatorNode*)m_pHead->m_pLeft;
> >+        }
> >+        else
> >+        {
> >+            pOp = (OperatorNode*)m_pHead;
> >+        }
> >+    }
> >+
> >+    return (float)GetBwValue(pOp);
> > }
> >
> > float
> > ASMRuleExpression::GetRight()
> > {
> >-   int nRight = 0;
> >-   if( m_pHead && m_pHead->m_pRight )
> >-   {
> >-      nRight = ((IntegerNode*) 
> >((VariableNode*)(m_pHead->m_pRight)))->m_Data;
> >-   }
> >-   if( nRight == 1 )
> >-   {
> >-      nRight = ((IntegerNode*) 
> >((VariableNode*)m_pHead->m_pRight->m_pRight))->m_Data;
> >-   }
> >-   return (float)nRight;
> >+    // This function returns the
> >+    // upper bandwidth threshold. It assumes
> >+    // that the upper threshold expression
> >+    // is always on the right
> >+
> >+    OperatorNode* pOp = NULL;
> >+
> >+    if(m_pHead && m_pHead->m_pRight &&
> >+       (m_pHead->m_Type == HX_RE_OPERATOR))
> >+    {
> >+        // Test for ($Bandwidth > 123) && ($Bandwidth <= 123)
> >+        if (m_pHead->m_pRight->m_Type == HX_RE_OPERATOR)
> >+        {
> >+            // We want the value from the right node
> >+            pOp = (OperatorNode*)m_pHead->m_pRight;
> >+        }
> >+        else
> >+        {
> >+            pOp = (OperatorNode*)m_pHead;
> >+        }
> >+    }
> >+
> >+    return (float)GetBwValue(pOp);
> > }
> >
> > int
> >@@ -1323,30 +1386,36 @@
> >    return (int) ((OperatorNode*) m_pHead)->m_Data;
> > }
> >
> >+BOOL
> >+ASMRuleExpression::IsLeftEdge()
> >+{
> >+    // This is a left edge if it
> >+    // has a bandwidth value on
> >+    // either the left or the right
> >+    return ( GetLeft() || GetRight() );
> >+}
> >+
> >+
> > // This function checks to see if the current rule's operator is GREATER 
> > or
> > // GREATEROREQUAL, both of which would suggest that we are the "right 
> > edge"
> > // rule.
> > BOOL
> > ASMRuleExpression::IsRightEdge()
> > {
> >-   if( m_pHead )
> >-   {
> >-      switch(((OperatorNode*)m_pHead)->m_Data)
> >-      {
> >-         case HX_RE_GREATER:
> >-         case HX_RE_GREATEREQUAL:
> >-             return TRUE;
> >-             break;
> >-
> >-          default:
> >-             return FALSE;
> >-             break;
> >-      }
> >-   }
> >-   else
> >-   {
> >-      return FALSE;
> >-   }
> >+    BOOL bRet = FALSE;
> >+    if( m_pHead && (m_pHead->m_Type == HX_RE_OPERATOR))
> >+    {
> >+        OperatorNode* pOp = (OperatorNode*)m_pHead;
> >+
> >+        if (NormalizeBwNode(pOp) &&
> >+            ((pOp->m_Data == HX_RE_GREATER) ||
> >+             (pOp->m_Data == HX_RE_GREATEREQUAL)))
> >+        {
> >+            bRet = TRUE;
> >+        }
> >+    }
> >+
> >+    return bRet;
> > }
> >
> > HX_RESULT
> >@@ -1487,6 +1556,7 @@
> >        }
> >     }
> >
> >+    HX_VECTOR_DELETE(m_pDeletedRulesArray);
> >     return InitRulesArray();
> > }
> >
> >@@ -1506,4 +1576,88 @@
> >     }
> >
> >     return TRUE;
> >+}
> >+
> >+int
> >+ASMRuleExpression::GetBwValue(OperatorNode* pOp) const
> >+{
> >+    int ret = 0;
> >+
> >+    if (NormalizeBwNode(pOp))
> >+    {
> >+        // The bandwidth value is always on the right
> >+        // after the node has been normalized
> >+        IntegerNode* pInt = (IntegerNode*)pOp->m_pRight;
> >+
> >+        ret = pInt->m_Data;
> >+    }
> >+
> >+    return ret;
> >+}
> >+
> >+BOOL
> >+ASMRuleExpression::NormalizeBwNode(OperatorNode* pOp) const
> >+{
> >+    // This function determines if the expression is a
> >+    // bandwidth threshold expression and if so it makes sure it
> >+    // always has the bandwidth variable on the left side
> >+    // and the bandwidth value on the right side
> >+    BOOL bRet = FALSE;
> >+
> >+    if (pOp && pOp->m_pLeft && pOp->m_pRight)
> >+    {
> >+        VariableNode* pVar = NULL;
> >+        IntegerNode* pInt = NULL;
> >+
> >+        if ((pOp->m_pLeft->m_Type == HX_RE_INTEGER) &&
> >+            (pOp->m_pRight->m_Type == HX_RE_VARIABLE))
> >+        {
> >+            // (123 > somevar)
> >+            // (123 >= somevar)
> >+            pInt = (IntegerNode*)pOp->m_pLeft;
> >+            pVar = (VariableNode*)pOp->m_pRight;
> >+        }
> >+        else if ((pOp->m_pLeft->m_Type == HX_RE_VARIABLE) &&
> >+                 (pOp->m_pRight->m_Type == HX_RE_INTEGER))
> >+        {
> >+            // (somevar < 123)
> >+            // (somevar <= 123)
> >+            pVar = (VariableNode*)pOp->m_pLeft;
> >+            pInt = (IntegerNode*)pOp->m_pRight;
> >+        }
> >+
> >+        if (pVar && pInt &&
> >+            !strcasecmp(pVar->m_Data, "Bandwidth"))
> >+        {
> >+            // This is a bandwidth node
> >+
> >+            if (pVar != pOp->m_pLeft)
> >+            {
> >+                // We need to swap the left and
> >+                // right nodes
> >+                pOp->m_pLeft = pVar;
> >+                pOp->m_pRight = pInt;
> >+
> >+                // Flip operator around
> >+                switch(pOp->m_Data) {
> >+                case HX_RE_GREATER:
> >+                    pOp->m_Data = HX_RE_LESS;
> >+                    break;
> >+                case HX_RE_LESS:
> >+                    pOp->m_Data = HX_RE_GREATER;
> >+                    break;
> >+                case HX_RE_GREATEREQUAL:
> >+                    pOp->m_Data = HX_RE_LESSEQUAL;
> >+                    break;
> >+                case HX_RE_LESSEQUAL:
> >+                    pOp->m_Data = HX_RE_GREATEREQUAL;
> >+                    break;
> >+                };
> >+            }
> >+
> >+            bRet = TRUE;
> >+        }
> >+    }
> >+
> >+    return bRet;
> > }
> >Index: pub/asmrulpp.h
> >===================================================================
> >RCS file: /cvsroot/common/util/pub/asmrulpp.h,v
> >retrieving revision 1.3
> >diff -u -r1.3 asmrulpp.h
> >--- pub/asmrulpp.h      18 Apr 2003 18:04:36 -0000      1.3
> >+++ pub/asmrulpp.h      14 Jun 2004 23:43:20 -0000
> >@@ -68,6 +68,7 @@
> >                        ~ASMRuleExpression();
> >     void               Dump();
> >     BOOL               Evaluate(IHXValues* pVars);
> >+    BOOL               IsLeftEdge();
> >     BOOL               IsRightEdge();
> >     float              GetLeft();
> >     float              GetRight();
> >@@ -124,6 +125,8 @@
> >                                 float*& pThreshold, UINT32& 
> >                                 ulNumThreshold,
> >                                 BOOL& bInvolvesTheOpenVariable);
> >     BOOL               RFindVariable(Node* pNode, const char* pVariable);
> >+    int                 GetBwValue(OperatorNode* pOp) const;
> >+    BOOL                NormalizeBwNode(OperatorNode* pOp) const;
> >
> >     UINT32             m_ulNumThresholds;
> >     Node*              m_pHead;
> >Index: hxasm.h
> >===================================================================
> >RCS file: /cvsroot/common/include/hxasm.h,v
> >retrieving revision 1.3
> >diff -u -r1.3 hxasm.h
> >--- hxasm.h     18 Apr 2003 18:03:27 -0000      1.3
> >+++ hxasm.h     14 Jun 2004 23:44:15 -0000
> >@@ -301,6 +301,44 @@
> >                                UINT16  uRuleNumber) PURE;
> >
> >     STDMETHOD (ReCompute)      (THIS) PURE;
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXASMStream2::IsEnabled
> >+     * Purpose:
> >+     *      Allows a user to determine if a rule is enabled or not
> >+     */
> >+    STDMETHOD_(BOOL,IsEnabled) (THIS_
> >+                               UINT16  uRuleNumber) PURE;
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXASMStream2::LockSubscriptions
> >+     * Purpose:
> >+     *      Locks the stream to the current subscriptions. This has the
> >+     *      effect of disabling the client side rate adaptation for this
> >+     *      stream.
> >+     */
> >+    STDMETHOD (LockSubscriptions)(THIS) PURE;
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXASMStream2::UnlockSubscriptions
> >+     * Purpose:
> >+     *      Unlocks the stream so that the enabled streams can be selected
> >+     *      by the ASM code. This has the effect of reenabling the client 
> >side
> >+     *      rate adaptation for this stream.
> >+     */
> >+    STDMETHOD (UnlockSubscriptions)(THIS) PURE;
> >+
> >+    
> >/************************************************************************
> >+     * Method:
> >+     *     IHXASMStream2::AreSubscriptionsLocked
> >+     * Purpose:
> >+     *      Lets you determine whether the stream subscriptions are locked
> >+     *      or not.
> >+     */
> >+    STDMETHOD_(BOOL, AreSubscriptionsLocked)(THIS) PURE;
> > };
> >
> >
> >Index: hxpiids.h
> >===================================================================
> >RCS file: /cvsroot/common/include/hxpiids.h,v
> >retrieving revision 1.28
> >diff -u -r1.28 hxpiids.h
> >--- hxpiids.h   8 Apr 2004 00:55:04 -0000       1.28
> >+++ hxpiids.h   14 Jun 2004 23:44:15 -0000
> >@@ -989,4 +989,14 @@
> > DEFINE_GUID_ENUM(IID_IHXAccessPointSelector, 0x9e9ca2d6, 0xcbfe, 0x40f8, 
> >0x94,
> >                0xfd, 0x38, 0xf4, 0xeb, 0x5d, 0xf8, 0x12)
> >
> >+/* File:
> >+ *      ihxrateadaptctl.h
> >+ *
> >+ * Description:
> >+ *      Rate adaptation control interfaces
> >+ */
> >+DEFINE_GUID_ENUM(IID_IHXClientRateAdaptControl, 0x44f5ac8c, 0x654c, 
> >0x414e, 0x9d,
> >+                 0x18, 0xe7, 0xa4, 0x80, 0x90, 0x70, 0x9)
> >+
> > #endif /* _HXPRIVATEIIDS_H_ */
> >+
> >
> >_______________________________________________
> >Client-dev mailing list
> >Client-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/client-dev
> 

From ehyche at real.com  Wed Jun 16 15:38:47 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 16 15:38:57 2004
Subject: [Common-dev] Two suggestions for new net interfaces
Message-ID: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>


Tom/Liam:

I have two suggestions for modifications to the new
networking interfaces:

1) In the following methods:

   IHXSockAddr
     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
     STDMETHOD(GetPort)                      (THIS_ char* pBuf) PURE;
     STDMETHOD(GetAddPort)                   (THIS_ UINT16 n, char* pBuf) PURE;
     STDMETHOD(GetSubPort)                   (THIS_ UINT16 n, char* pBuf) PURE;
     STDMETHOD_(BOOL,Get)            (THIS_ void* dst) PURE;
     STDMETHOD_(BOOL,Set)            (THIS_ void* src) PURE;

   IHXSockAddrLocal
     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;

   IHXSockAddrIN6
     STDMETHOD(GetFullAddr)                  (THIS_ char* pBuf) PURE;
     STDMETHOD(GetFullAddrZ)                 (THIS_ char* pBuf) PURE;


    we should add a buffer length parameter. For instance, in the
    case of the IHXSockAddr::GetAddr(), it might be:

    STDMETHOD(GetAddr) (THIS_ char* pBuf, UINT32 ulBufLen) PURE;

    The reason is that it makes security checking much much cleaner.
    After having done three security audits on our codebase, it makes it
    much easier to replace potentially problematic sprintf()'s with
    safe versions if you know the buffer size. Most of the time I was
    able to modify the code to pass the buffer size in. However, if it
    was an interface, then you can't modify it once it's gone out the
    door.

    Alternatively, we could just make the input be an IHXBuffer, as in:

    STDMETHOD(GetAddr) (THIS_ IHXBuffer* pBuffer) PURE;

    but that's a lot more work for the user, having to create and size
    and IHXBuffer.

2) In IHXSockAddrIN4, it would be nice to add:

    STDMETHOD_(UINT32,GetIN4Address) (THIS);
    STDMETHOD_(UINT16,GetIN4Port)    (THIS);

    which would be a shorthand for:

    char szMyAddr[HX_ADDRSTRLEN];
    pSockAddr->GetAddr(szMyAddr, HX_ADDRSTRLEN);
    UINT32 ulAddr = inet_addr(szMyAddr);

    and

    char szMyPort[16];
    pSockAddr->GetPort(szMyPort, 16);
    UINT32 ulAddr = (UINT32) atol(szMyPort);

    I have a feeling that inet_addr() may have slightly different
    prototypes on different platforms.

What do you guys think?

Eric




======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From liamm at real.com  Wed Jun 16 16:18:47 2004
From: liamm at real.com (Liam Murray)
Date: Wed Jun 16 16:20:55 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
Message-ID: <6.1.1.1.0.20040616154302.043d18b8@mailone.real.com>


I was also thinking about suggesting (1).

I do think the IHXBuffer* approach is safer because the implementation has 
full control in ensuring that the buffer is sufficiently sized and 
therefore provides the best guard against programmer error. Otherwise we 
have to assume that people remember to use the right constant in sizing the 
buffer (or pass the correct size of the buffer they allocated in the first 
alternate version you suggest).

// implementation creates an appropriately sized buffer
STDMETHOD(GetAddr) (THIS_ IHXBuffer*& pBufferOut) PURE;

or

// implementation sizes buffer to appropriate length but caller needs to create
STDMETHOD(GetAddr) (THIS_ IHXBuffer* pBufferModified) PURE;

However, the max length for the buffer is defined in hxnet.h in well known 
constants (e.g., HX_PORTSTRLEN), so as long as we document this in the 
interfaces and feel comfortable assuming that that users of the interfaces 
abide by this it might by OK.

As for (2) I believe (correct me if I'm wrong) that Tom intentionally 
avoided this because he wanted to eliminate hassles relating to 
host-order/net-order ambiguities. Ideally the port (service) would be 
stored as a string in client code, so theoretically code should never need 
to obtain the port as a UINT16.

A lot of our code currently uses UINT16 for ports, so it is a bit of a 
hassle while we convert (until we use strings for ports). There is some 
code that needs to compare ports with other ports (for port range checking) 
so it might be hard to avoid UINT16s in certain cases.


Liam


At 03:38 PM 6/16/2004, Eric Hyche wrote:

>Tom/Liam:
>
>I have two suggestions for modifications to the new
>networking interfaces:
>
>1) In the following methods:
>
>   IHXSockAddr
>     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
>     STDMETHOD(GetPort)                      (THIS_ char* pBuf) PURE;
>     STDMETHOD(GetAddPort)                   (THIS_ UINT16 n, char* pBuf) 
> PURE;
>     STDMETHOD(GetSubPort)                   (THIS_ UINT16 n, char* pBuf) 
> PURE;
>     STDMETHOD_(BOOL,Get)            (THIS_ void* dst) PURE;
>     STDMETHOD_(BOOL,Set)            (THIS_ void* src) PURE;
>
>   IHXSockAddrLocal
>     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
>
>   IHXSockAddrIN6
>     STDMETHOD(GetFullAddr)                  (THIS_ char* pBuf) PURE;
>     STDMETHOD(GetFullAddrZ)                 (THIS_ char* pBuf) PURE;
>
>
>    we should add a buffer length parameter. For instance, in the
>    case of the IHXSockAddr::GetAddr(), it might be:
>
>    STDMETHOD(GetAddr) (THIS_ char* pBuf, UINT32 ulBufLen) PURE;
>
>    The reason is that it makes security checking much much cleaner.
>    After having done three security audits on our codebase, it makes it
>    much easier to replace potentially problematic sprintf()'s with
>    safe versions if you know the buffer size. Most of the time I was
>    able to modify the code to pass the buffer size in. However, if it
>    was an interface, then you can't modify it once it's gone out the
>    door.
>
>    Alternatively, we could just make the input be an IHXBuffer, as in:
>
>    STDMETHOD(GetAddr) (THIS_ IHXBuffer* pBuffer) PURE;
>
>    but that's a lot more work for the user, having to create and size
>    and IHXBuffer.
>
>2) In IHXSockAddrIN4, it would be nice to add:
>
>    STDMETHOD_(UINT32,GetIN4Address) (THIS);
>    STDMETHOD_(UINT16,GetIN4Port)    (THIS);
>
>    which would be a shorthand for:
>
>    char szMyAddr[HX_ADDRSTRLEN];
>    pSockAddr->GetAddr(szMyAddr, HX_ADDRSTRLEN);
>    UINT32 ulAddr = inet_addr(szMyAddr);
>
>    and
>
>    char szMyPort[16];
>    pSockAddr->GetPort(szMyPort, 16);
>    UINT32 ulAddr = (UINT32) atol(szMyPort);
>
>    I have a feeling that inet_addr() may have slightly different
>    prototypes on different platforms.
>
>What do you guys think?
>
>Eric
>
>
>
>
>======================================
>M. Eric Hyche (ehyche@real.com)
>Core Technologies
>RealNetworks, Inc.
>


From tmarshall at helixcommunity.org  Wed Jun 16 16:28:11 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Wed Jun 16 16:28:14 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
Message-ID: <20040616232810.GG9637@real.com>

> I have two suggestions for modifications to the new
> networking interfaces:
> 
> 1) In the following methods:
> 
>   IHXSockAddr
>     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
>     STDMETHOD(GetPort)                      (THIS_ char* pBuf) PURE;
>     STDMETHOD(GetAddPort)                   (THIS_ UINT16 n, char* pBuf) 
>     PURE;
>     STDMETHOD(GetSubPort)                   (THIS_ UINT16 n, char* pBuf) 
>     PURE;
>     STDMETHOD_(BOOL,Get)            (THIS_ void* dst) PURE;
>     STDMETHOD_(BOOL,Set)            (THIS_ void* src) PURE;
> 
>   IHXSockAddrLocal
>     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
> 
>   IHXSockAddrIN6
>     STDMETHOD(GetFullAddr)                  (THIS_ char* pBuf) PURE;
>     STDMETHOD(GetFullAddrZ)                 (THIS_ char* pBuf) PURE;
> 
> 
>    we should add a buffer length parameter. For instance, in the
>    case of the IHXSockAddr::GetAddr(), it might be:
> 
>    STDMETHOD(GetAddr) (THIS_ char* pBuf, UINT32 ulBufLen) PURE;
> 
>    The reason is that it makes security checking much much cleaner.
>    After having done three security audits on our codebase, it makes it
>    much easier to replace potentially problematic sprintf()'s with
>    safe versions if you know the buffer size. Most of the time I was
>    able to modify the code to pass the buffer size in. However, if it
>    was an interface, then you can't modify it once it's gone out the
>    door.
> 
>    Alternatively, we could just make the input be an IHXBuffer, as in:
> 
>    STDMETHOD(GetAddr) (THIS_ IHXBuffer* pBuffer) PURE;
> 
>    but that's a lot more work for the user, having to create and size
>    and IHXBuffer.

I do sympathize with your security concerns.  However, I don't think this is
going to be a problem.

The most common use case for GetAddr() and related methods is to display an
address string (eg. in a log message, dialog, etc.) Using a buffer is not
only too much work, it's also quite inefficient.  This is why I went with
the char array.

I agree that, in general, passing a length is a good thing for interfaces
that write into char arrays.  But I believe this is a special case that is
easily used.  We have HX_ADDRSTRLEN that makes allocating the proper size
buffer very easy.  The majority of use cases are likely to be similar to
this one, taken from server/protocol/rtsp:

    IHXSockAddr* pRtspPeerAddr = NULL;
    char szRtspPeerAddr[HX_ADDRSTRLEN];
    char szDestPeerAddr[HX_ADDRSTRLEN];
    m_pSocket->GetPeerAddr(&pRtspPeerAddr);
    pRtspPeerAddr->GetAddr(szRtspPeerAddr);
    HX_RELEASE(pRtspPeerAddr);
    pPeerAddr->GetAddr(szDestPeerAddr);

    char logMsg[64+2*HX_ADDRSTRLEN];
    sprintf(logMsg, "client IP %s redirecting to %s\n",
            szRtspPeerAddr, szDestPeerAddr);
    m_pErrorMessages->Report(HXLOG_INFO, 0, 0, logMsg, NULL);

This is easy to implement, simple to read, and efficient.

The underlying inet_ntop() function does take a length parameter, so it
would be easy to add a length to GetAddr().  However, if we go changing
GetAddr(), we will also want to change GetPort().  That is implemented with
sprintf().  We could use snprintf() in theory, but it seems an awful waste
to pass in and check the length when the max is 6 anyway.  The IPv6 method
GetFullAddr() is similar in that it is implemented via sprintf() and the
length is not highly variable.  GetFullAddrZ() always uses the same space
regardless of the input (HX_ADDRSTRLEN_IN6 bytes).  Changing it seems even
more of a waste.

If your main complaint is that automated tools will flag this as a potential
buffer overrun, that argues for more intelligent tools.  I am strongly
opposed to changing code for an automated system that is lacking in basic
intelligence.  In particular, flawfinder could (and should!) be taught about
the most commonly occuring false positives that it warns about.  The most
irritating in my experience is printf format strings.  Last time I ran it,
it was not even able to detect this as safe code:

    UINT16 port;
    char nbuf[5+1];
    sprintf(nbuf, "%hu", port);

GCC can detect format string types and match them up with their arguments,
and that's not even the compiler's job.  This is so much more basic.

> 2) In IHXSockAddrIN4, it would be nice to add:
> 
>    STDMETHOD_(UINT32,GetIN4Address) (THIS);
>    STDMETHOD_(UINT16,GetIN4Port)    (THIS);
> 
>    which would be a shorthand for:
> 
>    char szMyAddr[HX_ADDRSTRLEN];
>    pSockAddr->GetAddr(szMyAddr, HX_ADDRSTRLEN);
>    UINT32 ulAddr = inet_addr(szMyAddr);
> 
>    and
> 
>    char szMyPort[16];
>    pSockAddr->GetPort(szMyPort, 16);
>    UINT32 ulAddr = (UINT32) atol(szMyPort);
> 
>    I have a feeling that inet_addr() may have slightly different
>    prototypes on different platforms.

I have explicitly chosen not provided these methods because they got us into
the trouble that we are in today.  If the old net API always used dotted
decimal strings for addresses, we would probably still be using it (not that
I think that is a particularly good thing, of course).  Further, there are
endian issues when dealing with host and net order.  I recall several endian
bugs with the old interfaces and, believe it or not, the 9.0 server actually
returned its own IP address backwards in SDP for a time.  :-o

-- 
It is by the fortune of God that, in this country, we have three benefits:
freedom of speech, freedom of thought, and the wisdom never to use either.
        -- Mark Twain
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040616/3a5175a0/attachment.bin
From ehyche at real.com  Wed Jun 16 16:59:58 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 16 17:00:09 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <20040616232810.GG9637@real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
Message-ID: <5.1.0.14.2.20040616193850.0260a198@mailone.real.com>


At 04:28 PM 6/16/2004 -0700, Tom Marshall wrote:
> > I have two suggestions for modifications to the new
> > networking interfaces:
> >
> > 1) In the following methods:
> >
> >   IHXSockAddr
> >     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
> >     STDMETHOD(GetPort)                      (THIS_ char* pBuf) PURE;
> >     STDMETHOD(GetAddPort)                   (THIS_ UINT16 n, char* pBuf)
> >     PURE;
> >     STDMETHOD(GetSubPort)                   (THIS_ UINT16 n, char* pBuf)
> >     PURE;
> >     STDMETHOD_(BOOL,Get)            (THIS_ void* dst) PURE;
> >     STDMETHOD_(BOOL,Set)            (THIS_ void* src) PURE;
> >
> >   IHXSockAddrLocal
> >     STDMETHOD(GetAddr)                      (THIS_ char* pBuf) PURE;
> >
> >   IHXSockAddrIN6
> >     STDMETHOD(GetFullAddr)                  (THIS_ char* pBuf) PURE;
> >     STDMETHOD(GetFullAddrZ)                 (THIS_ char* pBuf) PURE;
> >
> >
> >    we should add a buffer length parameter. For instance, in the
> >    case of the IHXSockAddr::GetAddr(), it might be:
> >
> >    STDMETHOD(GetAddr) (THIS_ char* pBuf, UINT32 ulBufLen) PURE;
> >
> >    The reason is that it makes security checking much much cleaner.
> >    After having done three security audits on our codebase, it makes it
> >    much easier to replace potentially problematic sprintf()'s with
> >    safe versions if you know the buffer size. Most of the time I was
> >    able to modify the code to pass the buffer size in. However, if it
> >    was an interface, then you can't modify it once it's gone out the
> >    door.
> >
> >    Alternatively, we could just make the input be an IHXBuffer, as in:
> >
> >    STDMETHOD(GetAddr) (THIS_ IHXBuffer* pBuffer) PURE;
> >
> >    but that's a lot more work for the user, having to create and size
> >    and IHXBuffer.
>
>I do sympathize with your security concerns.  However, I don't think this is
>going to be a problem.
>
>The most common use case for GetAddr() and related methods is to display an
>address string (eg. in a log message, dialog, etc.) Using a buffer is not
>only too much work, it's also quite inefficient.  This is why I went with
>the char array.
>
>I agree that, in general, passing a length is a good thing for interfaces
>that write into char arrays.  But I believe this is a special case that is
>easily used.  We have HX_ADDRSTRLEN that makes allocating the proper size
>buffer very easy.  The majority of use cases are likely to be similar to
>this one, taken from server/protocol/rtsp:
>
>     IHXSockAddr* pRtspPeerAddr = NULL;
>     char szRtspPeerAddr[HX_ADDRSTRLEN];
>     char szDestPeerAddr[HX_ADDRSTRLEN];
>     m_pSocket->GetPeerAddr(&pRtspPeerAddr);
>     pRtspPeerAddr->GetAddr(szRtspPeerAddr);
>     HX_RELEASE(pRtspPeerAddr);
>     pPeerAddr->GetAddr(szDestPeerAddr);
>
>     char logMsg[64+2*HX_ADDRSTRLEN];
>     sprintf(logMsg, "client IP %s redirecting to %s\n",
>             szRtspPeerAddr, szDestPeerAddr);
>     m_pErrorMessages->Report(HXLOG_INFO, 0, 0, logMsg, NULL);
>
>This is easy to implement, simple to read, and efficient.
>
>The underlying inet_ntop() function does take a length parameter, so it
>would be easy to add a length to GetAddr().  However, if we go changing
>GetAddr(), we will also want to change GetPort().  That is implemented with
>sprintf().  We could use snprintf() in theory, but it seems an awful waste
>to pass in and check the length when the max is 6 anyway.  The IPv6 method
>GetFullAddr() is similar in that it is implemented via sprintf() and the
>length is not highly variable.  GetFullAddrZ() always uses the same space
>regardless of the input (HX_ADDRSTRLEN_IN6 bytes).  Changing it seems even
>more of a waste.
>
>If your main complaint is that automated tools will flag this as a potential
>buffer overrun, that argues for more intelligent tools.  I am strongly
>opposed to changing code for an automated system that is lacking in basic
>intelligence.  In particular, flawfinder could (and should!) be taught about
>the most commonly occuring false positives that it warns about.  The most
>irritating in my experience is printf format strings.  Last time I ran it,
>it was not even able to detect this as safe code:

I agree that the fact that Flawfinder and other tools flag these
as unsafe is not sufficient cause in and of itself. However, those
tools are pointing out the obvious: when you don't pass in a length
parameter in an interface, you make it impossible to "do the right thing"
further down the line. Sure, the user can still lie about the buffer
length, but there's never any way around that.

I can very easily see problems where someone doesn't bother to check
that there's a HX_ADDRSTRLEN define in the file and just does
the following:

char szAddr[16]; // enough space for IPv4 address
pSockAddr->GetAddr(szAddr);

then it works fine for IPv4 and and would crash for IPv6.
But if you had the string length parameter, then you could fail
out for IPv6, thus catching the error. I think forcing the user
to provide the string length not only makes it more secure,
but it helps catch sloppy code like above.

>    UINT16 port;
>     char nbuf[5+1];
>     sprintf(nbuf, "%hu", port);
>
>GCC can detect format string types and match them up with their arguments,
>and that's not even the compiler's job.  This is so much more basic.
>
> > 2) In IHXSockAddrIN4, it would be nice to add:
> >
> >    STDMETHOD_(UINT32,GetIN4Address) (THIS);
> >    STDMETHOD_(UINT16,GetIN4Port)    (THIS);
> >
> >    which would be a shorthand for:
> >
> >    char szMyAddr[HX_ADDRSTRLEN];
> >    pSockAddr->GetAddr(szMyAddr, HX_ADDRSTRLEN);
> >    UINT32 ulAddr = inet_addr(szMyAddr);
> >
> >    and
> >
> >    char szMyPort[16];
> >    pSockAddr->GetPort(szMyPort, 16);
> >    UINT32 ulAddr = (UINT32) atol(szMyPort);
> >
> >    I have a feeling that inet_addr() may have slightly different
> >    prototypes on different platforms.
>
>I have explicitly chosen not provided these methods because they got us into
>the trouble that we are in today.  If the old net API always used dotted
>decimal strings for addresses, we would probably still be using it (not that
>I think that is a particularly good thing, of course).  Further, there are
>endian issues when dealing with host and net order.  I recall several endian
>bugs with the old interfaces and, believe it or not, the 9.0 server actually
>returned its own IP address backwards in SDP for a time.  :-o

I think there will probably be several places where we have to
integrate the new interfaces into existing code that use UINT32's for
IPv4 addresses (this shim I'm working on is just one example). If that's
so, then that 3 line block of code of above will be frequently copied
whenever we need to get an IPv4 address as a UINT32. This just seems like
a natural thing we would want in the IHXSockAddrIN4.

Eric

>--
>It is by the fortune of God that, in this country, we have three benefits:
>freedom of speech, freedom of thought, and the wisdom never to use either.
>         -- Mark Twain
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From jgordon at real.com  Wed Jun 16 17:08:38 2004
From: jgordon at real.com (Jamie Gordon)
Date: Wed Jun 16 17:12:00 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <20040616232810.GG9637@real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<20040616232810.GG9637@real.com>
Message-ID: <40D0E106.3070401@real.com>

Tom Marshall wrote:

> I do sympathize with your security concerns.  However, I don't think this is
> going to be a problem.
> 
> The most common use case for GetAddr() and related methods is to display an
> address string (eg. in a log message, dialog, etc.) Using a buffer is not
> only too much work, it's also quite inefficient.  This is why I went with
> the char array.
> 
> I agree that, in general, passing a length is a good thing for interfaces
> that write into char arrays.  But I believe this is a special case that is
> easily used.  We have HX_ADDRSTRLEN that makes allocating the proper size
> buffer very easy.  The majority of use cases are likely to be similar to
> this one, taken from server/protocol/rtsp:
> 
>     IHXSockAddr* pRtspPeerAddr = NULL;
>     char szRtspPeerAddr[HX_ADDRSTRLEN];
>     char szDestPeerAddr[HX_ADDRSTRLEN];
>     m_pSocket->GetPeerAddr(&pRtspPeerAddr);
>     pRtspPeerAddr->GetAddr(szRtspPeerAddr);
>     HX_RELEASE(pRtspPeerAddr);
>     pPeerAddr->GetAddr(szDestPeerAddr);
> 
>     char logMsg[64+2*HX_ADDRSTRLEN];
>     sprintf(logMsg, "client IP %s redirecting to %s\n",
>             szRtspPeerAddr, szDestPeerAddr);
>     m_pErrorMessages->Report(HXLOG_INFO, 0, 0, logMsg, NULL);
> 
> This is easy to implement, simple to read, and efficient.

But would it not be just as easy to implement and read and
also more efficient if the method just returned a reference
to a buffer object, like:

     STDMETHOD(GetAddr) (THIS_ REF(IHXBuffer*) pBuffer) PURE;

so no new buffer needs to be allocated and the value does
not have to be copied, everyone can just reference the same
copy of the string? And then the calling code just becomes:

     IHXSockAddr* pRtspPeerAddr = NULL;
     IHXBuffer* pRtspPeerAddrBuf = NULL;
     IHXBuffer* pDestPeerAddrBuf = NULL;
     m_pSocket->GetPeerAddr(&pRtspPeerAddr);
     pRtspPeerAddr->GetAddr(pRtspPeerAddrBuf);
     HX_RELEASE(pRtspPeerAddr);
     pPeerAddr->GetAddr(pDestPeerAddrBuf);

     char logMsg[64+2*HX_ADDRSTRLEN];
     sprintf(logMsg, "client IP %s redirecting to %s\n",
             pRtspPeerAddrBuf->GetBuffer(),
             pDestPeerAddrBuf->GetBuffer());
     m_pErrorMessages->Report(HXLOG_INFO, 0, 0, logMsg, NULL);

     HX_RELEASE(pRtspPeerAddrBuf);
     HX_RELEASE(pDestPeerAddrBuf);

From tmarshall at helixcommunity.org  Wed Jun 16 17:20:32 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Wed Jun 16 17:20:35 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
Message-ID: <20040617002032.GJ9637@real.com>

> >If your main complaint is that automated tools will flag this as a
> >potential buffer overrun, that argues for more intelligent tools.  I am
> >strongly opposed to changing code for an automated system that is lacking
> >in basic intelligence.  In particular, flawfinder could (and should!) be
> >taught about the most commonly occuring false positives that it warns
> >about.  The most irritating in my experience is printf format strings. 
> >Last time I ran it, it was not even able to detect this as safe code:
> 
> I agree that the fact that Flawfinder and other tools flag these
> as unsafe is not sufficient cause in and of itself. However, those
> tools are pointing out the obvious: when you don't pass in a length
> parameter in an interface, you make it impossible to "do the right thing"
> further down the line. Sure, the user can still lie about the buffer
> length, but there's never any way around that.
> 
> I can very easily see problems where someone doesn't bother to check
> that there's a HX_ADDRSTRLEN define in the file and just does
> the following:
> 
> char szAddr[16]; // enough space for IPv4 address
> pSockAddr->GetAddr(szAddr);

That someone should be given a severe lecture.

C and C++ are dangerous languages.  There's no way around it.  I've seen
people create buffer overruns with NEW_FAST_TEMP_STR and other "safe"
constructs.

> >I have explicitly chosen not provided these methods because they got us
> >into the trouble that we are in today.  If the old net API always used
> >dotted decimal strings for addresses, we would probably still be using it
> >(not that I think that is a particularly good thing, of course). 
> >Further, there are endian issues when dealing with host and net order.  I
> >recall several endian bugs with the old interfaces and, believe it or
> >not, the 9.0 server actually returned its own IP address backwards in SDP
> >for a time.  :-o
> 
> I think there will probably be several places where we have to
> integrate the new interfaces into existing code that use UINT32's for
> IPv4 addresses (this shim I'm working on is just one example). If that's
> so, then that 3 line block of code of above will be frequently copied
> whenever we need to get an IPv4 address as a UINT32. This just seems like
> a natural thing we would want in the IHXSockAddrIN4.

The majority of the existing code has already been converted and this has
not been a problem.  There is virtually no place in the codebase where it
works exclusively with IPv4 addresses, so this was not an issue.  Your
compatibility shim will be one of the few, if not the only, place that works
with IPv4 only.

-- 
"It's today!" said Piglet.  "My favorite day," said Pooh.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040616/8d78ec04/attachment.bin
From tmarshall at helixcommunity.org  Wed Jun 16 17:40:20 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Wed Jun 16 17:40:21 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <40D0E106.3070401@real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<20040616232810.GG9637@real.com> <40D0E106.3070401@real.com>
Message-ID: <20040617004019.GK9637@real.com>

> >    IHXSockAddr* pRtspPeerAddr = NULL;
> >    char szRtspPeerAddr[HX_ADDRSTRLEN];
> >    char szDestPeerAddr[HX_ADDRSTRLEN];
> >    m_pSocket->GetPeerAddr(&pRtspPeerAddr);
> >    pRtspPeerAddr->GetAddr(szRtspPeerAddr);
> >    HX_RELEASE(pRtspPeerAddr);
> >    pPeerAddr->GetAddr(szDestPeerAddr);
> >
> >    char logMsg[64+2*HX_ADDRSTRLEN];
> >    sprintf(logMsg, "client IP %s redirecting to %s\n",
> >            szRtspPeerAddr, szDestPeerAddr);
> >    m_pErrorMessages->Report(HXLOG_INFO, 0, 0, logMsg, NULL);
> >
> >This is easy to implement, simple to read, and efficient.
> 
> But would it not be just as easy to implement and read and
> also more efficient if the method just returned a reference
> to a buffer object, like:
> 
>     STDMETHOD(GetAddr) (THIS_ REF(IHXBuffer*) pBuffer) PURE;
> 
> so no new buffer needs to be allocated and the value does
> not have to be copied, everyone can just reference the same
> copy of the string? And then the calling code just becomes:

It would, except the address is stored in native format, not in IHXBuffer
format.  This would just push the buffer creation to the IHXSockAddr instead
of its user.  Of course, that does make the buffer reusable, but GetAddr()
is probably not called often per address object anyway.

-- 
What is a magician but a practising theorist?
        -- Obi-Wan Kenobi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040616/994b0671/attachment.bin
From ping at real.com  Wed Jun 16 17:40:11 2004
From: ping at real.com (Henry Ping)
Date: Wed Jun 16 17:40:24 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <20040617002032.GJ9637@real.com>
References: <5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
Message-ID: <5.1.0.14.2.20040616173526.03b4e1b0@mailone.real.com>

At 05:20 PM 6/16/2004 -0700, Tom Marshall wrote:
> > >If your main complaint is that automated tools will flag this as a
> > >potential buffer overrun, that argues for more intelligent tools.  I am
> > >strongly opposed to changing code for an automated system that is lacking
> > >in basic intelligence.  In particular, flawfinder could (and should!) be
> > >taught about the most commonly occuring false positives that it warns
> > >about.  The most irritating in my experience is printf format strings.
> > >Last time I ran it, it was not even able to detect this as safe code:
> >
> > I agree that the fact that Flawfinder and other tools flag these
> > as unsafe is not sufficient cause in and of itself. However, those
> > tools are pointing out the obvious: when you don't pass in a length
> > parameter in an interface, you make it impossible to "do the right thing"
> > further down the line. Sure, the user can still lie about the buffer
> > length, but there's never any way around that.
> >
> > I can very easily see problems where someone doesn't bother to check
> > that there's a HX_ADDRSTRLEN define in the file and just does
> > the following:
> >
> > char szAddr[16]; // enough space for IPv4 address
> > pSockAddr->GetAddr(szAddr);
>
>That someone should be given a severe lecture.
>
>C and C++ are dangerous languages.  There's no way around it.  I've seen
>people create buffer overruns with NEW_FAST_TEMP_STR and other "safe"
>constructs.

We are the provider of the interface, we should design our interface in 
such a way to help the caller to avoid such problem instead of making any 
assumption of the caller's background.

-->Henry

> > >I have explicitly chosen not provided these methods because they got us
> > >into the trouble that we are in today.  If the old net API always used
> > >dotted decimal strings for addresses, we would probably still be using it
> > >(not that I think that is a particularly good thing, of course).
> > >Further, there are endian issues when dealing with host and net order.  I
> > >recall several endian bugs with the old interfaces and, believe it or
> > >not, the 9.0 server actually returned its own IP address backwards in SDP
> > >for a time.  :-o
> >
> > I think there will probably be several places where we have to
> > integrate the new interfaces into existing code that use UINT32's for
> > IPv4 addresses (this shim I'm working on is just one example). If that's
> > so, then that 3 line block of code of above will be frequently copied
> > whenever we need to get an IPv4 address as a UINT32. This just seems like
> > a natural thing we would want in the IHXSockAddrIN4.
>
>The majority of the existing code has already been converted and this has
>not been a problem.  There is virtually no place in the codebase where it
>works exclusively with IPv4 addresses, so this was not an issue.  Your
>compatibility shim will be one of the few, if not the only, place that works
>with IPv4 only.
>
>--
>"It's today!" said Piglet.  "My favorite day," said Pooh.
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev


From tmarshall at helixcommunity.org  Wed Jun 16 18:11:54 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Wed Jun 16 18:11:56 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <5.1.0.14.2.20040616173526.03b4e1b0@mailone.real.com>
References: <5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616173526.03b4e1b0@mailone.real.com>
Message-ID: <20040617011154.GM9637@real.com>

> >> I can very easily see problems where someone doesn't bother to check
> >> that there's a HX_ADDRSTRLEN define in the file and just does
> >> the following:
> >>
> >> char szAddr[16]; // enough space for IPv4 address
> >> pSockAddr->GetAddr(szAddr);
> >
> >That someone should be given a severe lecture.
> >
> >C and C++ are dangerous languages.  There's no way around it.  I've seen
> >people create buffer overruns with NEW_FAST_TEMP_STR and other "safe"
> >constructs.
> 
> We are the provider of the interface, we should design our interface in 
> such a way to help the caller to avoid such problem instead of making any 
> assumption of the caller's background.

If the interface accepts a length parameter, you create the possibility for
truncated addresses.  This is not as severe as a buffer overrun but it's
still trading one bug for another at the expense of an unneeded parameter.

We can put a comment above the method definition that tells the caller what
buffer size it needs and put an assert in the implementation.  That also
helps the caller and removes any assumption about the caller's background.

-- 
It has been said that man is a rational animal.  All my life I have
been searching for evidence which could support this.
        -- Bertrand Russell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040616/bac7f249/attachment.bin
From liamm at real.com  Wed Jun 16 18:06:30 2004
From: liamm at real.com (Liam Murray)
Date: Wed Jun 16 18:15:45 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <20040617002032.GJ9637@real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<20040617002032.GJ9637@real.com>
Message-ID: <6.1.1.1.0.20040616175746.0470b558@mailone.real.com>

At 05:20 PM 6/16/2004, Tom Marshall wrote:
> > >If your main complaint is that automated tools will flag this as a
> > >potential buffer overrun, that argues for more intelligent tools.  I am
> > >strongly opposed to changing code for an automated system that is lacking
> > >in basic intelligence.  In particular, flawfinder could (and should!) be
> > >taught about the most commonly occuring false positives that it warns
> > >about.  The most irritating in my experience is printf format strings.
> > >Last time I ran it, it was not even able to detect this as safe code:
> >
> > I agree that the fact that Flawfinder and other tools flag these
> > as unsafe is not sufficient cause in and of itself. However, those
> > tools are pointing out the obvious: when you don't pass in a length
> > parameter in an interface, you make it impossible to "do the right thing"
> > further down the line. Sure, the user can still lie about the buffer
> > length, but there's never any way around that.
> >
> > I can very easily see problems where someone doesn't bother to check
> > that there's a HX_ADDRSTRLEN define in the file and just does
> > the following:
> >
> > char szAddr[16]; // enough space for IPv4 address
> > pSockAddr->GetAddr(szAddr);
>
>That someone should be given a severe lecture.
>
>C and C++ are dangerous languages.  There's no way around it.  I've seen
>people create buffer overruns with NEW_FAST_TEMP_STR and other "safe"
>constructs.

There is a way to address dangers in the language: use higher level 
constructs (smart pointers,
"resource acquisition is initialization", string classes, etc.) except when 
performance concerns require otherwise. I think IHXBuffer*& would 
technically make the interface "safer" than all the other suggested 
alternatives (at the cost of some performance) since the address class 
could ensure the size of the buffer is sufficient. Since performance is 
most likely not a concern, ease of use and clarity is the most relevant 
tradeoff (vs. safety) as I see it.

Liam



> > >I have explicitly chosen not provided these methods because they got us
> > >into the trouble that we are in today.  If the old net API always used
> > >dotted decimal strings for addresses, we would probably still be using it
> > >(not that I think that is a particularly good thing, of course).
> > >Further, there are endian issues when dealing with host and net order.  I
> > >recall several endian bugs with the old interfaces and, believe it or
> > >not, the 9.0 server actually returned its own IP address backwards in SDP
> > >for a time.  :-o
> >
> > I think there will probably be several places where we have to
> > integrate the new interfaces into existing code that use UINT32's for
> > IPv4 addresses (this shim I'm working on is just one example). If that's
> > so, then that 3 line block of code of above will be frequently copied
> > whenever we need to get an IPv4 address as a UINT32. This just seems like
> > a natural thing we would want in the IHXSockAddrIN4.
>
>The majority of the existing code has already been converted and this has
>not been a problem.  There is virtually no place in the codebase where it
>works exclusively with IPv4 addresses, so this was not an issue.  Your
>compatibility shim will be one of the few, if not the only, place that works
>with IPv4 only.
>
>--
>"It's today!" said Piglet.  "My favorite day," said Pooh.


From ehyche at real.com  Wed Jun 16 19:57:40 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 16 19:57:50 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <20040617011154.GM9637@real.com>
References: <5.1.0.14.2.20040616173526.03b4e1b0@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616173526.03b4e1b0@mailone.real.com>
Message-ID: <5.1.0.14.2.20040616225551.0260a198@mailone.real.com>


At 06:11 PM 6/16/2004 -0700, Tom Marshall wrote:
> > >> I can very easily see problems where someone doesn't bother to check
> > >> that there's a HX_ADDRSTRLEN define in the file and just does
> > >> the following:
> > >>
> > >> char szAddr[16]; // enough space for IPv4 address
> > >> pSockAddr->GetAddr(szAddr);
> > >
> > >That someone should be given a severe lecture.
> > >
> > >C and C++ are dangerous languages.  There's no way around it.  I've seen
> > >people create buffer overruns with NEW_FAST_TEMP_STR and other "safe"
> > >constructs.
> >
> > We are the provider of the interface, we should design our interface in
> > such a way to help the caller to avoid such problem instead of making any
> > assumption of the caller's background.
>
>If the interface accepts a length parameter, you create the possibility for
>truncated addresses.  This is not as severe as a buffer overrun but it's
>still trading one bug for another at the expense of an unneeded parameter.
>
>We can put a comment above the method definition that tells the caller what
>buffer size it needs and put an assert in the implementation.  That also
>helps the caller and removes any assumption about the caller's background.

In addition to the assert, the GetAddr() implementation (and all
similar methods) should return failure if the buffer size is not
large enough. That allows the user to be aware if they have passed
in a buffer of insufficient size.

Eric

>--
>It has been said that man is a rational animal.  All my life I have
>been searching for evidence which could support this.
>         -- Bertrand Russell

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From tmarshall at helixcommunity.org  Wed Jun 16 21:03:50 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Wed Jun 16 21:03:53 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
In-Reply-To: <6.1.1.1.0.20040616175746.0470b558@mailone.real.com>
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616181732.0260a198@mailone.real.com>
	<5.1.0.14.2.20040616193850.0260a198@mailone.real.com>
	<20040617002032.GJ9637@real.com>
	<6.1.1.1.0.20040616175746.0470b558@mailone.real.com>
Message-ID: <20040617040350.GA11293@real.com>

> >C and C++ are dangerous languages.  There's no way around it.  I've seen
> >people create buffer overruns with NEW_FAST_TEMP_STR and other "safe"
> >constructs.
> 
> There is a way to address dangers in the language: use higher level
> constructs (smart pointers, "resource acquisition is initialization",
> string classes, etc.) except when performance concerns require otherwise.
> I think IHXBuffer*& would technically make the interface "safer" than all
> the other suggested alternatives (at the cost of some performance) since
> the address class could ensure the size of the buffer is sufficient. Since
> performance is most likely not a concern, ease of use and clarity is the
> most relevant tradeoff (vs. safety) as I see it.

I absolutely agree.  In addition to the reasons you cite, there is also the
issue of compiler compatibility.  Believe it or not, the server coding
standard still prohibits using any templates at all.  I kid you not.  Not
even smart pointers.  But all the higher level constructs in the world will
not prevent users from declaring fixed size local arrays as Eric's example. 
C and C++ are dangerous not because you cannot create safe constructs -- you
can -- but because (1) you cannot force users to always use them, and (2)
there is virtually always some way to screw it up.

Regarding performance, this tends to take top priority in the server code. 
I suppose it would be much easier to argue for safety if we had a nice set
of safe APIs that could be used easier than the "raw" COM API.  One example
in particular is using IHXBuffer as a string container.  It's very awkward
because (1) no guarantee is made that the buffer is NUL terminated.  This
makes it pretty much equally dangerous as raw char arrays, and (2) using the
buffer as a string requires a cast from UINT8* to char* for every operation. 
Certainly not a winner in the ease of use category.

I would be ecstatic if someone came up with some cross platform classes that
implemented basic things like smart pointers, typesafe containers, and other
basic tools in terms of Helix code.  Unfortunately, the client team seems to
have migrated to STL.  I believe the main problem with this strategy is that
various STL implementations and/or compilers are buggy.  I have a sneaking
suspicion that there's some code bloat that goes along with the STL but I
don't have any hard numbers.

I did start implementing some COM containers a couple years ago.  That could
make a nice start on deprecating atrocicies such as IHXValues.

-- 
One is not superior merely because one sees the world as odious.
        -- Chateaubriand (1768-1848)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040616/4416fab4/attachment-0001.bin
From gwright at real.com  Thu Jun 17 09:53:26 2004
From: gwright at real.com (Greg Wright)
Date: Thu Jun 17 09:51:27 2004
Subject: [Common-dev] Re: Two suggestions for new net interfaces
References: <5.1.0.14.2.20040616181732.0260a198@mailone.real.com><5.1.0.14.2.20040616181732.0260a198@mailone.real.com><5.1.0.14.2.20040616193850.0260a198@mailone.real.com><20040617002032.GJ9637@real.com><6.1.1.1.0.20040616175746.0470b558@mailone.real.com>
	<20040617040350.GA11293@real.com>
Message-ID: <007b01c4548b$9c945290$ff8317ac@gwright5>

> I would be ecstatic if someone came up with some cross platform classes that
> implemented basic things like smart pointers, typesafe containers, and other
> basic tools in terms of Helix code.  Unfortunately, the client team seems to
> have migrated to STL.  
^^^^^^^^^^^^^^^^^^^^^^^^^^

The client team (at least the core) has *not* migrated to the STL.
We still have plenty of platforms/compilers that don't support
templates. In places where the STL is in use, there should always
be a non-STL versions for the cross platform code.

--greg.


> I believe the main problem with this strategy is that
> various STL implementations and/or compilers are buggy.  I have a sneaking
> suspicion that there's some code bloat that goes along with the STL but I
> don't have any hard numbers.
> 
> I did start implementing some COM containers a couple years ago.  That could
> make a nice start on deprecating atrocicies such as IHXValues.
> 
> -- 
> One is not superior merely because one sees the world as odious.
>         -- Chateaubriand (1768-1848)
> 
> 

From liamm at real.com  Thu Jun 17 17:24:58 2004
From: liamm at real.com (Liam Murray)
Date: Thu Jun 17 17:27:04 2004
Subject: [Common-dev] CR: sockimp GetLocalAddr, GetPeerAddr fix
Message-ID: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>


HEAD fix to common/netio/sockimp.cpp

We were failing to init (Set) the IHXSockAddr in IHXSockAddr::GetLocalAddr 
and IHXSockAddr::GetPeerAddr.

Liam


Index: platform/posix/sockimp.cpp
===================================================================
RCS file: /cvsroot/common/netio/platform/posix/sockimp.cpp,v
retrieving revision 1.9
diff -u -w -r1.9 sockimp.cpp
--- platform/posix/sockimp.cpp	2 Jun 2004 01:47:26 -0000	1.9
+++ platform/posix/sockimp.cpp	18 Jun 2004 00:18:08 -0000

@@ -1312,7 +1319,12 @@
          return HXR_FAIL;
      }

-    return m_pNetSvc->CreateSockAddr(m_family, ppAddr);
+    HX_RESULT hr = m_pNetSvc->CreateSockAddr(m_family, ppAddr);
+    if(SUCCEEDED(hr))
+    {
+        (*ppAddr)->Set(&sa);
+    }
+    return hr;
  }

  STDMETHODIMP
@@ -1325,7 +1337,12 @@
          return HXR_FAIL;
      }

-    return m_pNetSvc->CreateSockAddr(m_family, ppAddr);
+    HX_RESULT hr = m_pNetSvc->CreateSockAddr(m_family, ppAddr);
+    if(SUCCEEDED(hr))
+    {
+        (*ppAddr)->Set(&sa);
+    }
+    return hr;
  }

  STDMETHODIMP


From tmarshall at helixcommunity.org  Thu Jun 17 21:46:13 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Thu Jun 17 21:46:14 2004
Subject: [Common-dev] Re: CR: sockimp GetLocalAddr, GetPeerAddr fix
In-Reply-To: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>
References: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>
Message-ID: <20040618044613.GA2857@real.com>

On Thu, Jun 17, 2004 at 05:24:58PM -0700, Liam Murray wrote:
> 
> HEAD fix to common/netio/sockimp.cpp
> 
> We were failing to init (Set) the IHXSockAddr in IHXSockAddr::GetLocalAddr 
> and IHXSockAddr::GetPeerAddr.

I already had a similar fix in my local tree, but you beat me to the CR. 

Looks good to me but could you add a space between the if and open paren for
coding style?

-- 
There is hopeful symbolism in the fact that flags do not wave in a vacuum.
        --Arthur C. Clarke
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040617/aca37090/attachment.bin
From tmarshall at helixcommunity.org  Fri Jun 18 10:50:21 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Fri Jun 18 10:50:22 2004
Subject: [Common-dev] Failed checkouts
Message-ID: <20040618175021.GC4610@real.com>

Almost every time I try to checkout fresh source on Win32, I get this error
for at least one module:

  ssh: connect to host cvs.helixcommunity.org port 22: Address already in use
  cvs [checkout aborted]: end of file from server (consult above messages if any)

I'm using cygwin ssh and cvs.  Does anyone else have this problem?  Is there
a solution?

-- 
The mark of the immature man is that he wants to die nobly for a cause,
while the mark of a mature man is that he wants to live humbly for one.
        -- Wilhelm Stekel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040618/15b08a44/attachment.bin
From liamm at real.com  Fri Jun 18 10:49:54 2004
From: liamm at real.com (Liam Murray)
Date: Fri Jun 18 10:52:00 2004
Subject: [Common-dev] CN: sockimp GetLocalAddr, GetPeerAddr fix
In-Reply-To: <20040618044613.GA2857@real.com>
References: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>
	<20040618044613.GA2857@real.com>
Message-ID: <6.1.1.1.0.20040618104928.044374b8@mailone.real.com>

Done, with space!

At 09:46 PM 6/17/2004, Tom Marshall wrote:
>On Thu, Jun 17, 2004 at 05:24:58PM -0700, Liam Murray wrote:
> >
> > HEAD fix to common/netio/sockimp.cpp
> >
> > We were failing to init (Set) the IHXSockAddr in IHXSockAddr::GetLocalAddr
> > and IHXSockAddr::GetPeerAddr.
>
>I already had a similar fix in my local tree, but you beat me to the CR.
>
>Looks good to me but could you add a space between the if and open paren for
>coding style?
>
>--
>There is hopeful symbolism in the fact that flags do not wave in a vacuum.
>         --Arthur C. Clarke


From gwright at real.com  Fri Jun 18 11:04:24 2004
From: gwright at real.com (Greg Wright)
Date: Fri Jun 18 11:02:23 2004
Subject: [Common-dev] Failed checkouts
References: <20040618175021.GC4610@real.com>
Message-ID: <060e01c4555e$b095f180$ff8317ac@gwright5>

try making your ~/.ssh/config file like this:


# work around a bug in winsock:
# (this is only needed with cygwin ssh, but should do no harm with others)
ConnectionAttempts=4
# connect to helixcommunity.org:
host=cvs.helixcommunity.org
BatchMode=no
IdentityFile=~/.ssh/HelixCVSKey.key
User=gwright


----- Original Message ----- 
From: "Tom Marshall" 
To: 
Sent: Friday, June 18, 2004 10:50 AM
Subject: [Common-dev] Failed checkouts


> _______________________________________________
> Common-dev mailing list
> Common-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 

From tmarshall at helixcommunity.org  Fri Jun 18 11:19:11 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Fri Jun 18 11:19:11 2004
Subject: [Common-dev] CN: sockimp GetLocalAddr, GetPeerAddr fix
In-Reply-To: <6.1.1.1.0.20040618104928.044374b8@mailone.real.com>
References: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>
	<20040618044613.GA2857@real.com>
	<6.1.1.1.0.20040618104928.044374b8@mailone.real.com>
Message-ID: <20040618181911.GD4610@real.com>

On Fri, Jun 18, 2004 at 10:49:54AM -0700, Liam Murray wrote:
> Done, with space!

Looks like you added this also:

  1.10         (liam_mur 18-Jun-04): // SYMBIAN requires DEFAULT_UDP_READ_SIZE <= 0xf00 
  1.10         (liam_mur 18-Jun-04): // SO_MAX_MSG_SIZE for windows?

I believe there's a '0' missing for Symbian; isn't it 0xf000?

I have another CR here, I'll fix it at the same time.  This CR does the following:

 - Add a MaskEvents() method to IHXSocket.  This is desirable for various
   protocols that want to enable reading and/or writing part of the time. 
   The protocol typically wants to flip a bit (eg. turn on write events)
   without worrying about the other events.

 - Add family LBOUND for server's (lame but necessary) localbound sockets.

 - Add a couple more socket error codes.


  Index: hxnet.h
  ===================================================================
  RCS file: /cvsroot/common/include/hxnet.h,v
  retrieving revision 1.7
  diff -u -d -r1.7 hxnet.h
  --- hxnet.h     2 Jun 2004 20:05:41 -0000       1.7
  +++ hxnet.h     18 Jun 2004 18:14:40 -0000
  @@ -134,6 +134,7 @@
       HX_SOCK_FAMILY_IN4,         /* IPv4 */
       HX_SOCK_FAMILY_IN6,         /* IPv6 */
       HX_SOCK_FAMILY_INANY,       /* IPv6 with IPv4 fallback */
  +    HX_SOCK_FAMILY_LBOUND,      /* Hack for proxy, don't use in new code */
       HX_SOCK_FAMILY_LAST
   } HXSockFamily;
   
  @@ -378,6 +379,8 @@
   typedef int HX_SOCKERR;
   #define HX_SOCKERR_NONE         0
   #define HX_SOCKERR_INTR         EINTR
  +#define HX_SOCKERR_ALREADY      EALREADY
  +#define HX_SOCKERR_NOTCONN      ENOTCONN
   #define HX_SOCKERR_INPROGRESS   EINPROGRESS
   #define HX_SOCKERR_WOULDBLOCK   EAGAIN
   #define HX_SOCKERR_PROTOTYPE    EPROTOTYPE
  @@ -390,6 +393,8 @@
   typedef int HX_SOCKERR;
   #define HX_SOCKERR_NONE         0       /* XXX */
   #define HX_SOCKERR_INTR         WSAEINTR
  +#define HX_SOCKERR_ALREADY      WSAEALREADY
  +#define HX_SOCKERR_NOTCONN      WSAENOTCONN
   #define HX_SOCKERR_INPROGRESS   WSAEINPROGRESS
   #define HX_SOCKERR_WOULDBLOCK   WSAEWOULDBLOCK
   #define HX_SOCKERR_PROTOTYPE    WSAEPROTOTYPE
  @@ -411,6 +416,17 @@
   #define HX_SOCK_EVENT_CLOSE     (1<<5)
   #define HX_SOCK_EVENT_TIMEOUT   (1<<6)
   
  +/* Initially for MaskEventSelection but makes a good general purpose enum */
  +enum HXMaskOp
  +{
  +    HX_MASK_OP_NONE,
  +    HX_MASK_OP_SET,
  +    HX_MASK_OP_AND,
  +    HX_MASK_OP_OR,
  +    HX_MASK_OP_XOR,
  +    HX_MASK_OP_LAST
  +};
  +
   #define HX_MAXBACKLOG           SOMAXCONN
   
   /* Socket options for IHXSocket::GetOption() and IHXSocket::SetOption() */
  @@ -511,6 +527,7 @@
       STDMETHOD(GetPeerAddr)          (THIS_ IHXSockAddr** ppAddr) PURE;
   
       STDMETHOD(SelectEvents)         (THIS_ UINT32 uEventMask) PURE;
  +    STDMETHOD(MaskEvents)           (THIS_ HXMaskOp op, UINT32 uEvents) PURE;
       STDMETHOD_(INT32,Peek)          (THIS_ IHXBuffer* pBuf) PURE;
       STDMETHOD_(INT32,Read)          (THIS_ IHXBuffer* pBuf) PURE;
       STDMETHOD_(INT32,Write)         (THIS_ IHXBuffer* pBuf) PURE;

  Index: pub/platform/posix/sockimp.h
  ===================================================================
  RCS file: /cvsroot/common/netio/pub/platform/posix/sockimp.h,v
  retrieving revision 1.5
  diff -u -d -b -B -r1.5 sockimp.h
  --- pub/platform/posix/sockimp.h        2 Jun 2004 01:47:26 -0000       1.5
  +++ pub/platform/posix/sockimp.h        18 Jun 2004 18:13:58 -0000
  @@ -251,6 +251,7 @@
       STDMETHOD(GetPeerAddr)          (THIS_ IHXSockAddr** ppAddr);
   
       STDMETHOD(SelectEvents)         (THIS_ UINT32 uEventMask);
  +    STDMETHOD(MaskEvents)           (THIS_ HXMaskOp op, UINT32 uEvents);
       STDMETHOD_(INT32,Peek)          (THIS_ IHXBuffer* pBuf);
       STDMETHOD_(INT32,Read)          (THIS_ IHXBuffer* pBuf);
       STDMETHOD_(INT32,Write)         (THIS_ IHXBuffer* pBuf);

  Index: pub/platform/posix/sockimp.cpp
  ===================================================================
  RCS file: /cvsroot/common/netio/platform/posix/sockimp.cpp,v
  retrieving revision 1.10
  diff -u -d -b -B -r1.10 sockimp.cpp
  --- sockimp.cpp 18 Jun 2004 17:51:17 -0000      1.10
  +++ sockimp.cpp 18 Jun 2004 18:12:58 -0000
  @@ -59,10 +59,9 @@
   // Default read size for all other sockets when MSS is unavailable
   #define DEFAULT_UDP_READ_SIZE 0xffff
   
  -// SYMBIAN requires DEFAULT_UDP_READ_SIZE <= 0xf00 
  +// SYMBIAN requires DEFAULT_UDP_READ_SIZE <= 0xf000
   // SO_MAX_MSG_SIZE for windows?
   
  -
   /*** CHXSockAddrLocal ***/
   
   CHXSockAddrLocal::CHXSockAddrLocal(void) :
  @@ -1351,6 +1348,14 @@
       return HXR_UNEXPECTED;
   }
   
  +STDMETHODIMP
  +CHXSocket::MaskEvents(HXMaskOp op, UINT32 uEvents)
  +{
  +    // Implementation must subclass this
  +    HX_ASSERT(FALSE);
  +    return HXR_UNEXPECTED;
  +}
  +
   STDMETHODIMP_(INT32)
   CHXSocket::Peek(IHXBuffer* pBuf)
   {


-- 
I mean, if 10 years from now, when you are doing something quick and dirty,
you suddenly visualize that I am looking over your shoulders and say to
yourself, "Dijkstra would not have liked this", well that would be enough
immortality for me.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040618/c40ef971/attachment.bin
From tmarshall at helixcommunity.org  Fri Jun 18 11:22:41 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Fri Jun 18 11:22:42 2004
Subject: [Common-dev] Failed checkouts
In-Reply-To: <060e01c4555e$b095f180$ff8317ac@gwright5>
References: <20040618175021.GC4610@real.com>
	<060e01c4555e$b095f180$ff8317ac@gwright5>
Message-ID: <20040618182241.GE4610@real.com>

> # work around a bug in winsock:
> # (this is only needed with cygwin ssh, but should do no harm with others)
> ConnectionAttempts=4

 I remember seeing this before, I should have remembered. 
Thanks!

-- 
One of the saddest lessons of history is this:  If we've been bamboozled
long enough, we tend to reject any evidence of the bamboozle.  We're no
longer interested in finding out the truth.
        -- Carl Sagan, "The Fine Art of Baloney Detection"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040618/8487d936/attachment.bin
From tmarshall at helixcommunity.org  Fri Jun 18 12:43:12 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Fri Jun 18 12:43:13 2004
Subject: [Common-dev] CN: sockimp GetLocalAddr, GetPeerAddr fix
In-Reply-To: <20040618181911.GD4610@real.com>
References: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>
	<20040618044613.GA2857@real.com>
	<6.1.1.1.0.20040618104928.044374b8@mailone.real.com>
	<20040618181911.GD4610@real.com>
Message-ID: <20040618194312.GH4610@real.com>

On Fri, Jun 18, 2004 at 11:19:11AM -0700, Tom Marshall wrote:
> On Fri, Jun 18, 2004 at 10:49:54AM -0700, Liam Murray wrote:
> > Done, with space!
> 
> Looks like you added this also:
> 
>   1.10         (liam_mur 18-Jun-04): // SYMBIAN requires DEFAULT_UDP_READ_SIZE <= 0xf00 
>   1.10         (liam_mur 18-Jun-04): // SO_MAX_MSG_SIZE for windows?
> 
> I believe there's a '0' missing for Symbian; isn't it 0xf000?
> 
> I have another CR here, I'll fix it at the same time.  This CR does the following:
> 
>  - Add a MaskEvents() method to IHXSocket.  This is desirable for various
>    protocols that want to enable reading and/or writing part of the time. 
>    The protocol typically wants to flip a bit (eg. turn on write events)
>    without worrying about the other events.
> 
>  - Add family LBOUND for server's (lame but necessary) localbound sockets.
> 
>  - Add a couple more socket error codes.

I went ahead and checked this in since the server depends on it.

-- 
The nice thing about standards is that there are so many of them to choose from.
        -- Andrew Tanenbaum
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040618/c22ef924/attachment-0001.bin
From liamm at real.com  Fri Jun 18 12:46:27 2004
From: liamm at real.com (Liam Murray)
Date: Fri Jun 18 12:48:35 2004
Subject: [Common-dev] CN: sockimp GetLocalAddr, GetPeerAddr fix
In-Reply-To: <20040618194312.GH4610@real.com>
References: <6.1.1.1.0.20040617171651.045df630@mailone.real.com>
	<20040618044613.GA2857@real.com>
	<6.1.1.1.0.20040618104928.044374b8@mailone.real.com>
	<20040618181911.GD4610@real.com> <20040618194312.GH4610@real.com>
Message-ID: <6.1.1.1.0.20040618124619.045df630@mailone.real.com>

Looks good... :)

At 12:43 PM 6/18/2004, Tom Marshall wrote:
>On Fri, Jun 18, 2004 at 11:19:11AM -0700, Tom Marshall wrote:
> > On Fri, Jun 18, 2004 at 10:49:54AM -0700, Liam Murray wrote:
> > > Done, with space!
> >
> > Looks like you added this also:
> >
> >   1.10         (liam_mur 18-Jun-04): // SYMBIAN requires 
> DEFAULT_UDP_READ_SIZE <= 0xf00
> >   1.10         (liam_mur 18-Jun-04): // SO_MAX_MSG_SIZE for windows?
> >
> > I believe there's a '0' missing for Symbian; isn't it 0xf000?
> >
> > I have another CR here, I'll fix it at the same time.  This CR does the 
> following:
> >
> >  - Add a MaskEvents() method to IHXSocket.  This is desirable for various
> >    protocols that want to enable reading and/or writing part of the time.
> >    The protocol typically wants to flip a bit (eg. turn on write events)
> >    without worrying about the other events.
> >
> >  - Add family LBOUND for server's (lame but necessary) localbound sockets.
> >
> >  - Add a couple more socket error codes.
>
>I went ahead and checked this in since the server depends on it.
>
>--
>The nice thing about standards is that there are so many of them to choose 
>from.
>         -- Andrew Tanenbaum


From tmarshall at helixcommunity.org  Fri Jun 18 17:32:01 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Fri Jun 18 17:32:04 2004
Subject: [Common-dev] CR: Fix RTP/TCP
Message-ID: <20040619003201.GN5156@real.com>

Skipped content of type multipart/mixed-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040618/91e7ebc0/attachment.bin
From dcollins at real.com  Fri Jun 18 17:34:55 2004
From: dcollins at real.com (Dean Collins)
Date: Fri Jun 18 17:34:56 2004
Subject: [Common-dev] Re: [Helix-server-dev] CR: Fix RTP/TCP
In-Reply-To: <20040619003201.GN5156@real.com>
References: <20040619003201.GN5156@real.com>
Message-ID: <20040619003455.GZ14985@jedi.dev.prognet.com>

ok

On Fri, Jun 18, 2004 at 05:32:01PM -0700, Tom Marshall wrote:
> The old socket API returned an HX_RESULT code from the Write*() methods. 
> The new socket API returns the number of bytes written from the Write*()
> methods.  This causes the RTP/TCP transport to think its writes fail.
> 
> Tested for functionality on Linux.
> 
> -- 
> The intelligence of any discussion diminishes with the square of the
> number of participants.
>         -- Adam Walinsky


-- 
Dean Collins
Server Technical Lead, RealNetworks, Inc. -- http://www.realnetworks.com
Helix Server Project Owner -- http://helix-server.helixcommunity.org

From tmarshall at helixcommunity.org  Fri Jun 18 18:03:10 2004
From: tmarshall at helixcommunity.org (Tom Marshall)
Date: Fri Jun 18 18:03:12 2004
Subject: [Common-dev] Re: [Helix-server-dev] CR: Fix RTP/TCP
In-Reply-To: <20040619003455.GZ14985@jedi.dev.prognet.com>
References: <20040619003201.GN5156@real.com>
	<20040619003455.GZ14985@jedi.dev.prognet.com>
Message-ID: <20040619010310.GQ5156@real.com>

On Fri, Jun 18, 2004 at 05:34:55PM -0700, Dean Collins wrote:
> ok
> 
> On Fri, Jun 18, 2004 at 05:32:01PM -0700, Tom Marshall wrote:
> > The old socket API returned an HX_RESULT code from the Write*() methods. 
> > The new socket API returns the number of bytes written from the Write*()
> > methods.  This causes the RTP/TCP transport to think its writes fail.
> > 
> > Tested for functionality on Linux.

Committed.

-- 
To use violence is to already be defeated.
        -- Chinese proverb
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040618/2b175734/attachment.bin
From dcollins at real.com  Mon Jun 21 00:23:18 2004
From: dcollins at real.com (Dean Collins)
Date: Mon Jun 21 00:23:20 2004
Subject: [Common-dev] CR: netdrv.cpp fixes
Message-ID: <20040621072318.GA12218@jedi.dev.prognet.com>

Several routines in common/netio/platform/posix/netdrv.cpp have a
return type of int while the .h file specifies ssize_t.  Since these are
different sizes on Linux/AMD64 this causes a build error.  Other supported
platforms should be unaffected by this modification since for them the
types must be interchangable or they wouldn't be building curently.
I will check this in tomorrow.

Dean

-- 
Dean Collins
Server Technical Lead, RealNetworks, Inc. -- http://www.realnetworks.com
Helix Server Project Owner -- http://helix-server.helixcommunity.org
-------------- next part --------------
Index: common/netio/platform/posix/netdrv.cpp
===================================================================
RCS file: /cvsroot/common/netio/platform/posix/netdrv.cpp,v
retrieving revision 1.7
diff -u -r1.7 netdrv.cpp
--- common/netio/platform/posix/netdrv.cpp	27 May 2004 04:39:33 -0000	1.7
+++ common/netio/platform/posix/netdrv.cpp	21 Jun 2004 06:55:34 -0000
@@ -867,7 +867,7 @@
     return rc;
 }
 
-int
+ssize_t
 hx_peek(HX_SOCK* s, void* buf, size_t len)
 {
     ssize_t n;
@@ -881,7 +881,7 @@
     return n;
 }
 
-int
+ssize_t
 hx_read(HX_SOCK* s, void* buf, size_t len)
 {
     ssize_t n;
@@ -902,7 +902,7 @@
     return n;
 }
 
-int
+ssize_t
 hx_readv(HX_SOCK* s, UINT32 vlen, const hx_iov* iov)
 {
 //XXXTDM: this is a nasty hack but it works until I implement
@@ -929,7 +929,7 @@
 #endif
 }
 
-int
+ssize_t
 hx_readfrom(HX_SOCK* s, void* buf, size_t len,
                 sockaddr_storage* addr)
 {
@@ -951,7 +951,7 @@
     return n;
 }
 
-int
+ssize_t
 hx_readfromv(HX_SOCK* s, UINT32 vlen, const hx_iov* iov,
                 sockaddr_storage* addr)
 {
@@ -988,7 +988,7 @@
 #endif
 }
 
-int
+ssize_t
 hx_write(HX_SOCK* s, const void* buf, size_t len)
 {
     ssize_t n;
@@ -1001,7 +1001,7 @@
     return n;
 }
 
-int
+ssize_t
 hx_writev(HX_SOCK* s, UINT32 vlen, const hx_iov* iov)
 {
 #ifdef _WIN32
@@ -1017,7 +1017,7 @@
 #endif
 }
 
-int
+ssize_t
 hx_writeto(HX_SOCK* s, const void* buf, size_t len,
                 const sockaddr_storage* addr)
 {
@@ -1032,7 +1032,7 @@
     return n;
 }
 
-int
+ssize_t
 hx_writetov(HX_SOCK* s, UINT32 vlen, const hx_iov* iov,
                 const sockaddr_storage* addr)
 {
From liamm at real.com  Mon Jun 21 18:38:25 2004
From: liamm at real.com (Liam Murray)
Date: Mon Jun 21 18:40:30 2004
Subject: [Common-dev] rfc: new net api needs better multicast socket support
Message-ID: <6.1.1.1.0.20040621114613.04782778@mailone.real.com>

The multicast implementation in the new net api is currently incomplete. In 
sockimp.cpp there is a class CHXSocket (derives from IHXSocket) and 
CHXMulticastSocket (derives from IHXMulticastSocket). The 
CHXMulticastSocket is more or less a place holder and hasn't been 
used/tested yet. (You can't create an instance via net services.)

The current multicast interface is:

// incomplete
DECLARE_INTERFACE_(IHXMulticastSocket, IUnknown)
{
     // ...
     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
};

1) I'd like to update these to pass an interface address, i.e.,:

     /* NULL may be passed for pInterface to indicate INADDR_ANY */
     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroup, 
IHXSockAddr* pInterface) PURE;
     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroup, 
IHXSockAddr* pInterface) PURE;

2) For convenience we can add a

STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl) PURE;

However, some may object because we can use IHXSocket::SetOption with 
HX_SOCKOPT_IN4_MULTICAST_TTL or HX_SOCKOPT_IN6_MULTICAST_HOPS (depending on 
the socket family).

3) There are also some IGMPv3 options that might be worth exposing while we 
are at it (even though we may defer implementation and just return 
HXR_NOTIMPL for now), for example:

   // IGMPv3 options
     typedef enum
     {
         HX_MCAST_SOURCE_ADD,
         HX_MCAST_SOURCE_DROP,
         HX_MCAST_SOURCE_BLOCK,
         HX_MCAST_SOURCE_UNBLOCK
     } HXMulticastSourceOption;

STDMETHOD(SetMulticastSourceOption)   (THIS_ HXMulticastSourceOption flag, 
IHXSockAddr* pGroup, IHXSockAddr* pSource, IHXSockAddr* pInterface) PURE;

4) Alternatively, we already have a get/set option interface in IHXSocket:

     STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) PURE;
     STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;

We could theoretically expand on these so we can configure multicast 
behavior via them, e.g., by adding a GetOption() method that takes a const 
void* and defining structs for various HXSockOpt socket options as needed. 
That would match bsd socket api semantics and perhaps be more flexible in 
the sense that we wouldn't really need to define new interfaces for future 
socket options that may become available/needed (we'd just have to define a 
new struct and update the implementation).

Currently any socket option that is associated with data that doesn't fit 
in a UINT32 (e.g., one of the multicast options) has to be exposed via an 
interface.

I think I may still prefer the interfaces for the convenience factor, plus 
I don't anticipate a bunch of new socket options.

Comments?


Liam







From ping at real.com  Tue Jun 22 11:31:03 2004
From: ping at real.com (Henry Ping)
Date: Tue Jun 22 11:31:12 2004
Subject: [Common-dev] rfc: new net api needs better multicast
	socket support
In-Reply-To: <6.1.1.1.0.20040621114613.04782778@mailone.real.com>
Message-ID: <5.1.0.14.2.20040622105500.0394ce10@mailone.real.com>

My comments inline

At 06:38 PM 6/21/2004 -0700, Liam Murray wrote:
>The multicast implementation in the new net api is currently incomplete. 
>In sockimp.cpp there is a class CHXSocket (derives from IHXSocket) and 
>CHXMulticastSocket (derives from IHXMulticastSocket). The 
>CHXMulticastSocket is more or less a place holder and hasn't been 
>used/tested yet. (You can't create an instance via net services.)
>
>The current multicast interface is:
>
>// incomplete
>DECLARE_INTERFACE_(IHXMulticastSocket, IUnknown)
>{
>     // ...
>     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
>     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
>};
>
>1) I'd like to update these to pass an interface address, i.e.,:
>
>     /* NULL may be passed for pInterface to indicate INADDR_ANY */
>     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroup, 
> IHXSockAddr* pInterface) PURE;
>     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroup, 
> IHXSockAddr* pInterface) PURE;

I suggest to add the following:
SetInterface(IHXSockAddr* pInterface);
GetInterface(REF(IHXSockAddr*) pInterface);

If the interface is not set before JoinMulticastGroup() is called, then 
INADDR_ANY is assumed.

>2) For convenience we can add a
>
>STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl) PURE;
>
>However, some may object because we can use IHXSocket::SetOption with 
>HX_SOCKOPT_IN4_MULTICAST_TTL or HX_SOCKOPT_IN6_MULTICAST_HOPS (depending 
>on the socket family).

TTL is an important option for multicast, so it's probably better for us to 
add explicit method. In addition to SetMulticastTTL(), we need also support 
GetMulticastTTL()

>3) There are also some IGMPv3 options that might be worth exposing while 
>we are at it (even though we may defer implementation and just return 
>HXR_NOTIMPL for now), for example:
>
>   // IGMPv3 options
>     typedef enum
>     {
>         HX_MCAST_SOURCE_ADD,
>         HX_MCAST_SOURCE_DROP,
>         HX_MCAST_SOURCE_BLOCK,
>         HX_MCAST_SOURCE_UNBLOCK
>     } HXMulticastSourceOption;
>
>STDMETHOD(SetMulticastSourceOption)   (THIS_ HXMulticastSourceOption flag, 
>IHXSockAddr* pGroup, IHXSockAddr* pSource, IHXSockAddr* pInterface) PURE;

I agree, but instead of adding 4 parameters in one call, can we separate it 
out? similar to JoinMulticastGroup and SetInterface approach.

>4) Alternatively, we already have a get/set option interface in IHXSocket:
>
>     STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) 
> PURE;
>     STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;
>
>We could theoretically expand on these so we can configure multicast 
>behavior via them, e.g., by adding a GetOption() method that takes a const 
>void* and defining structs for various HXSockOpt socket options as needed. 
>That would match bsd socket api semantics and perhaps be more flexible in 
>the sense that we wouldn't really need to define new interfaces for future 
>socket options that may become available/needed (we'd just have to define 
>a new struct and update the implementation).

I think the new method you proposed can be applied to IHXSocket as well and 
deprecate the current Get/SetOption

Instead of keeping IHXMulticastSocket and IHXSocket as separate interfaces, 
I suggest to inherit IHXMulticastSocket from IHXSocket.

I have another minor cosmetic suggestion to remove "Multicast" from the 
methods' name belong to IHXMulticastSocket since the type of socket is 
already indicated by the interface.

-->Henry

>Currently any socket option that is associated with data that doesn't fit 
>in a UINT32 (e.g., one of the multicast options) has to be exposed via an 
>interface.
>
>I think I may still prefer the interfaces for the convenience factor, plus 
>I don't anticipate a bunch of new socket options.
>Comments?
>
>Liam
>
>
>
>
>
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev


From liamm at real.com  Tue Jun 22 12:40:34 2004
From: liamm at real.com (Liam Murray)
Date: Tue Jun 22 12:42:39 2004
Subject: [Common-dev] rfc: new net api needs better multicast
	socket support
In-Reply-To: <5.1.0.14.2.20040622105500.0394ce10@mailone.real.com>
References: <6.1.1.1.0.20040621114613.04782778@mailone.real.com>
	<5.1.0.14.2.20040622105500.0394ce10@mailone.real.com>
Message-ID: <6.1.1.1.0.20040622122800.01c34a80@mailone.real.com>

Thanks Henry,

My responses below...

At 11:31 AM 6/22/2004, Henry Ping wrote:
>My comments inline
>
>At 06:38 PM 6/21/2004 -0700, Liam Murray wrote:
>>The multicast implementation in the new net api is currently incomplete. 
>>In sockimp.cpp there is a class CHXSocket (derives from IHXSocket) and 
>>CHXMulticastSocket (derives from IHXMulticastSocket). The 
>>CHXMulticastSocket is more or less a place holder and hasn't been 
>>used/tested yet. (You can't create an instance via net services.)
>>
>>The current multicast interface is:
>>
>>// incomplete
>>DECLARE_INTERFACE_(IHXMulticastSocket, IUnknown)
>>{
>>     // ...
>>     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
>>     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
>>};
>>
>>1) I'd like to update these to pass an interface address, i.e.,:
>>
>>     /* NULL may be passed for pInterface to indicate INADDR_ANY */
>>     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroup, 
>> IHXSockAddr* pInterface) PURE;
>>     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroup, 
>> IHXSockAddr* pInterface) PURE;
>
>I suggest to add the following:
>SetInterface(IHXSockAddr* pInterface);
>GetInterface(REF(IHXSockAddr*) pInterface);
>
>If the interface is not set before JoinMulticastGroup() is called, then 
>INADDR_ANY is assumed.

I think this is a little awkward because then we have to keep state 
information around to apply the next time Join/Leave is called.

// joining two groups, each on a differnent interface
pIHXSock->SetInterface(pIFaceOne);
pIHXSock->JoinMulticastGroup(pGroupOne);
pIHXSock->SetInterface(pIfaceTwo);
pIHXSock->JoinMulticastGroup(pGropuTwo);

Also, if you want to join on any interface, you might think

pIHXSock->JoinMulticast(pGroup)

is sufficient, but then get unexpected results if SetInterface happened to 
get called somewhere else previously.

I myself would tend to be suspicious of the current interface state set 
(especially if the code that creates the socket resides outside the current 
function), so to be on the safe side I'd probably play it safe:

pIHXSock->SetInterface(0); // make sure INADDR_ANY is specified, just in case
pIHXSock->JoinMulticastGroup(pGroupOne);




>>2) For convenience we can add a
>>
>>STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl) PURE;
>>
>>However, some may object because we can use IHXSocket::SetOption with 
>>HX_SOCKOPT_IN4_MULTICAST_TTL or HX_SOCKOPT_IN6_MULTICAST_HOPS (depending 
>>on the socket family).
>
>TTL is an important option for multicast, so it's probably better for us 
>to add explicit method. In addition to SetMulticastTTL(), we need also 
>support GetMulticastTTL()

Sounds good.

>>3) There are also some IGMPv3 options that might be worth exposing while 
>>we are at it (even though we may defer implementation and just return 
>>HXR_NOTIMPL for now), for example:
>>
>>   // IGMPv3 options
>>     typedef enum
>>     {
>>         HX_MCAST_SOURCE_ADD,
>>         HX_MCAST_SOURCE_DROP,
>>         HX_MCAST_SOURCE_BLOCK,
>>         HX_MCAST_SOURCE_UNBLOCK
>>     } HXMulticastSourceOption;
>>
>>STDMETHOD(SetMulticastSourceOption)   (THIS_ HXMulticastSourceOption 
>>flag, IHXSockAddr* pGroup, IHXSockAddr* pSource, IHXSockAddr* pInterface) PURE;
>
>I agree, but instead of adding 4 parameters in one call, can we separate 
>it out? similar to JoinMulticastGroup and SetInterface approach.
>
>>4) Alternatively, we already have a get/set option interface in IHXSocket:
>>
>>     STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) 
>> PURE;
>>     STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;
>>
>>We could theoretically expand on these so we can configure multicast 
>>behavior via them, e.g., by adding a GetOption() method that takes a 
>>const void* and defining structs for various HXSockOpt socket options as 
>>needed. That would match bsd socket api semantics and perhaps be more 
>>flexible in the sense that we wouldn't really need to define new 
>>interfaces for future socket options that may become available/needed 
>>(we'd just have to define a new struct and update the implementation).
>
>I think the new method you proposed can be applied to IHXSocket as well 
>and deprecate the current Get/SetOption

The Get/Set option is useful for setting a wide variety of options (notably 
REUSE_ADDR). If we deprecate this we'd have to otherwise create more 
interfaces for a possible variety of options that are currently used. (I 
only know of REUSE_ADDR right now.) Plus the advantage of Get/Set option is 
that it is relatively easy to support new options in the future by adding 
HXSockOpt's.

>Instead of keeping IHXMulticastSocket and IHXSocket as separate 
>interfaces, I suggest to inherit IHXMulticastSocket from IHXSocket.

That's what I was thinking. A mutlicast socket is just a udp socket so the 
methods seem applicable to IHXSocket.

Liam

>I have another minor cosmetic suggestion to remove "Multicast" from the 
>methods' name belong to IHXMulticastSocket since the type of socket is 
>already indicated by the interface.
>
>-->Henry
>
>>Currently any socket option that is associated with data that doesn't fit 
>>in a UINT32 (e.g., one of the multicast options) has to be exposed via an 
>>interface.
>>
>>I think I may still prefer the interfaces for the convenience factor, 
>>plus I don't anticipate a bunch of new socket options.
>>Comments?
>>
>>Liam
>>
>>
>>
>>
>>
>>
>>
>>_______________________________________________
>>Common-dev mailing list
>>Common-dev@lists.helixcommunity.org
>>http://lists.helixcommunity.org/mailman/listinfo/common-dev
>


From acolwell at real.com  Tue Jun 22 16:52:02 2004
From: acolwell at real.com (Aaron Colwell)
Date: Tue Jun 22 16:54:02 2004
Subject: [Common-dev] CR-Client: Moving IHXSourceBufferingStats2
	implementation
Message-ID: <20040622235202.GA5152@real.com>

Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
          number information can be maintained as well.

Overview: These changes move the IHXSourceBufferingStats2 implementation
          out of HXBufferingState and into a new class called 
          HXSourceBufferStats. This was done because the client needs to
          track packet sequence numbers for 3GPP-Rel6 OBSN support.
          There was no good way to get the sequence number information to
          the HXBufferingState class so the IHXSourceBufferingStats2 logic
          was moved to where this information is available.

          A new interface called IHXTransportOnTimeSync was created to
          propagate OnTimeSync() like calls to HXSourceBufferStats. The
          time passed to the OnTimeSync() call in this interface MUST
          NOT have any offsets created by SMIL or live playback. The time
          should be in the same time frame as the packets coming from the
          transport. If someone wants to rename this interface that is fine
          by me.


          - Created HXSourceBufferStats to contain the base 
            IHXSourceBufferingStats2 implementation. This class is
            used by HXFileSource.
 
          - Created HXNetSourceBufStats which derives from HXSourceBufferStats.
            This class just overloads the GetCurrentBuffering() so that it
            returns the amount of data in the transport buffer. This is
            used by RTSPClientProtocol.

          - Removed IHXSourceBufferingStats2 code from HXSource

          - Removed packet tracking code from HXBufferingState. This 
            functionality is implemented by HXSourceBufferStats now

          - Added code to HXSource to provide OnTimeSync() calls to the
            IHXTransportOnTimeSync interface. 

          - HXSource now exposes IHXSourceBufferingStats functionality through
            it's m_pSrcBufStats member variable instead of implementing it
            itself. The file and network sources are expected to provide an
            IHXSourceBufferingStats2 interface via a
            HXSource::SetSrcBufStats() call.

          - Added code to HXFileSource to use HXSourceBufferStats

          - Added code to RTSPClientProtocol to use HXNetSourceBufStats

          - Fixed some code in CBufferManager that was expecting HXSource
            to implement IHXSourceBufferingStats. This code now QI's for
            IHXSourceBufferingStats and uses that interface.
      
             

Files Modified:
client/core/buffmgr.cpp
client/core/hxbsrc.h
client/core/hxbufstate.h
client/core/hxbufstate.cpp
client/core/hxflsrc.cpp
client/core/hxflsrc.h
client/core/hxntsrc.cpp
client/core/hxntsrc.h
client/core/hxsrc.cpp
client/core/rtspprotocol.cpp
protocol/rtsp/Umakefil
protocol/rtsp/rtspclnt.cpp
protocol/rtsp/pub/rtspclnt.h
protocol/transport/common/system/rtsptran.cpp
protocol/transport/common/system/pub/rtsptran.h
client/common/util/Umakefil
common/include/hxcore.h
common/include/hxpiids.h

Files Added:
client/common/util/pub/hxsrcbufstats.h
client/common/util/hxsrcbufstats.cpp
protocol/rtsp/ntsrcbufstats.h
protocol/rtsp/ntsrcbufstats.cpp

Image Size and Heap Use impact:

Platforms and Profiles affected: all

Distribution Libraries affected: rdtclntlib

Distribution library impact and planned action: 
m_bIsLive and m_pSrcBufStats member variables were added to 
RTSPClientProtocol so any derived objects will need to be
recompiled

Platforms and Profiles Build Verified: win32

Platforms and Profiles Functionality verified: win32

Branch: HEAD

QA Instructions: none

Index: buffmgr.cpp
===================================================================
RCS file: /cvsroot/client/core/buffmgr.cpp,v
retrieving revision 1.21
diff -u -r1.21 buffmgr.cpp
--- buffmgr.cpp	11 Mar 2004 19:44:10 -0000	1.21
+++ buffmgr.cpp	22 Jun 2004 22:52:26 -0000
@@ -610,6 +610,11 @@
      * - Keep track of the stream with the lowest timestamp and is 
      *   buffering data
      */
+    IHXSourceBufferingStats* pSrcBufStats = NULL;
+    
+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
+                              (void**)&pSrcBufStats);
+
     for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
     {
 	pStreamInfo = (STREAM_INFO*) (*i);
@@ -619,12 +624,15 @@
 	ULONG32 ulNumBytesAtTransport = 0;
 	BOOL bDoneAtTransport = FALSE;
 
-	m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
-				       llLowestTimestampAtTransport,
-				       llHighestTimestampAtTransport,
-				       ulNumBytesAtTransport,
-				       bDoneAtTransport);
-
+        if (pSrcBufStats)
+        {
+            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
+                                              llLowestTimestampAtTransport,
+                                              llHighestTimestampAtTransport,
+                                              ulNumBytesAtTransport,
+                                              bDoneAtTransport);
+        }
+            
 	pStreamInfo->BufferingState().UpdateTransportStats(
 	    llLowestTimestampAtTransport,
 	    llHighestTimestampAtTransport,
@@ -658,6 +666,7 @@
 
 	}
     }
+    HX_RELEASE(pSrcBufStats);
 
     /* If none of the streams have any data buffered at the transport layer,
      * return.
Index: hxbsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxbsrc.h,v
retrieving revision 1.18.2.1
diff -u -r1.18.2.1 hxbsrc.h
--- hxbsrc.h	15 Jun 2004 16:26:43 -0000	1.18.2.1
+++ hxbsrc.h	22 Jun 2004 22:52:26 -0000
@@ -233,12 +233,11 @@
 		  public IHXPrivateStreamSource,
 		  public IHXBackChannel,
 		  public IHXASMSource,
-                  public IHXClientRateAdaptControl,
+                  public IHXClientRateAdaptControl
 #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
-		  public IHXHyperNavigate,
-		  public IHXHyperNavigate2,
+		  , public IHXHyperNavigate,
+		  public IHXHyperNavigate2
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
-                  public IHXSourceBufferingStats2
 {
 protected:
     LONG32			m_lRefCount;
@@ -487,35 +486,6 @@
 			    IHXValues* pParams);
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
 
-    /************************************************************************
-     *	Method:
-     *	    IHXSourceBufferingStats2::GetCurrentBuffering
-     *	Purpose:
-     *	    Get the current buffering information
-     */
-
-    STDMETHOD(GetCurrentBuffering) (THIS_ 
-                                    UINT16  uStreamNumber,
-                                    REF(INT64)  llLowestTimestamp, 
-                                    REF(INT64)  llHighestTimestamp,
-                                    REF(UINT32) ulNumBytes,
-                                    REF(BOOL)   bDone) PURE;
-    /************************************************************************
-     *	Method:
-     *	    IHXSourceBufferingStats2::GetTotalBuffering
-     *	Purpose:
-     *	    Get the total amount of data buffered for a stream.
-     *      This includes what is in the transport buffer and in
-     *      the renderer
-     */
-    
-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
-				   REF(INT64)  llLowestTimestamp, 
-				   REF(INT64)  llHighestTimestamp,
-				   REF(UINT32) ulNumBytes,
-				   REF(BOOL)   bDone);
-
-
     /*
      * IHXClientRateAdaptControl Methods
      */
@@ -731,7 +701,7 @@
 	    virtual HX_RESULT	FillRecordControl() = 0;
 		    BOOL	IsPlayingFromRecordControl() { return m_bPlayFromRecordControl; };
 
-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
 
             const char*         GetRedirectURL() { return (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
             const char*         GetSDPURL() { return (m_pSDPURL ? m_pSDPURL->GetURL() : NULL); };
@@ -769,6 +739,8 @@
             void        ProcessFileHeader(void);
             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, STREAM_INFO*& pStreamInfo);
 
+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
+
     HX_RESULT			mLastError;
     CHXMapLongToObj*            mStreamInfoTable;
     
@@ -868,6 +840,8 @@
     CHXURL*                     m_pRedirectURL;
     CHXURL*                     m_pSDPURL;
     BOOL                        m_bRedirectPending;
+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
+    IHXSourceBufferingStats2*   m_pSrcBufStats;
 };
 
 // Defined flags
Index: hxbufstate.cpp
===================================================================
RCS file: /cvsroot/client/core/hxbufstate.cpp,v
retrieving revision 1.7
diff -u -r1.7 hxbufstate.cpp
--- hxbufstate.cpp	9 Mar 2004 19:51:11 -0000	1.7
+++ hxbufstate.cpp	22 Jun 2004 22:52:26 -0000
@@ -83,18 +83,11 @@
     , m_ulLastPacketTimeStamp(0)
     , m_ulAvgBandwidth(0)
     , m_pASMProps(NULL)
-    , m_llCurrentPlaybackTime(0)
-    , m_ulBufferedData(0)
-    , m_ulLastTimeSync(0)
-    , m_llFirstLivePacketTimestamp(0)
-    , m_ulTimeSyncRollOver(0)
 {}
 
 HXBufferingState::~HXBufferingState()
 {
     HX_RELEASE(m_pASMProps);
-
-    ClearPktInfo();
 }
 
 void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
@@ -179,8 +172,6 @@
     m_ulLastPacketTimeStamp = 0;
     m_bIsFirstPacket = TRUE;
 
-    ClearPktInfo();
-
     if (bIsSeeking)
     {
 	m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
@@ -288,11 +279,6 @@
     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
 }
 
-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
-{
-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
-}
-
 void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
 				UINT32 ulElapsedTime,
 				BOOL bIsLive, BOOL bIsBufferedPlayMode)
@@ -318,16 +304,12 @@
 	if (bIsLive)
 	{
 	    m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
         }
 
 	m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
 	m_bIsFirstPacket = FALSE;
     }
 
-    // Add this packet to our packet info statistics
-    AddPktInfo(llActualTimeStamp, ulPacketSize);
-
     // data based preroll
     if (DataBasedPreroll())
     {
@@ -451,47 +433,6 @@
     m_bDoneAtTransport = bDoneAtTransport;
 }
 
-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp, 
-					      REF(INT64) llHighTimestamp,
-					      REF(UINT32) ulBytesBuffered,
-					      BOOL bUseTransportStats)
-{
-    HX_RESULT res = HXR_NO_DATA;
-
-    if (!m_bIsFirstPacket)
-    {
-	if (!m_pktInfo.IsEmpty())
-	{
-	    HXBufferedPktInfo* pPktInfo = 
-		(HXBufferedPktInfo*)m_pktInfo.GetHead();
-
-	    llLowTimestamp = pPktInfo->Timestamp();
-	}
-	else
-	{
-	    llLowTimestamp = m_llHighestTimeStamp;
-	}
-
-	llHighTimestamp = m_llHighestTimeStamp;
-	ulBytesBuffered = GetBufferedData();
-	
-
-	if (bUseTransportStats)
-	{
-	    if (m_llHighestTimestampAtTransport > llHighTimestamp)
-	    {
-		llHighTimestamp = m_llHighestTimestampAtTransport;
-	    }
-
-	    ulBytesBuffered += m_ulNumBytesAtTransport;
-	}
-
-	res = HXR_OK;
-    }
-
-    return res;
-}
-
 void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
 					   INT64 llTheHighestTS,
 					   BOOL bIsSeekPerformed,
@@ -569,19 +510,6 @@
 
 }
 
-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
-{
-    //  0xFA .. 0xFF [roll over] (0x01)
-    if (m_ulLastTimeSync > ulCurrentTime &&
-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
-    {
-       m_ulTimeSyncRollOver++;
-    }
-    m_ulLastTimeSync = ulCurrentTime;
-
-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
-}
-
 void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs, 
 					 ULONG32 ulMinBufferingInMs)
 {
@@ -771,62 +699,4 @@
     {
 	m_ulAvgBandwidth = ulBandwidth;
     }
-}
-
-void HXBufferingState::ClearPktInfo()
-{
-    m_ulBufferedData = 0;
-    while(!m_pktInfo.IsEmpty())
-    {
-	HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
-	delete pInfo;
-    }
-}
-
-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
-{
-    // Subtract off the first live packet timestamp.
-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
-    llTimestamp -= m_llFirstLivePacketTimestamp;
-    // Create the HXBufferedPktInfo class
-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp, 
-							ulPacketSize);
-    if (pPktInfo)
-    {
-	m_pktInfo.AddTail(pPktInfo);
-	m_ulBufferedData += ulPacketSize;
-    }
-
-    // purge the old packet info data
-    //  this keeps the list short and prevents the Symbian
-    //  allocator from freaking out
-    (void)GetBufferedData();
-}
-
-UINT32 HXBufferingState::GetBufferedData()
-{
-    BOOL bDone = m_pktInfo.IsEmpty();
-    
-    // Remove all packet info that is past due
-    // and subtract their sizes from our buffering total
-    while(!bDone)
-    {
-	HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
-	
-	if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
-	{
-	    m_ulBufferedData -= pPktInfo->Size();
-	    
-	    m_pktInfo.RemoveHead();
-	    delete pPktInfo;
-	    
-	    bDone = m_pktInfo.IsEmpty();
-	}
-	else
-	{
-	    bDone = TRUE;
-	}
-    }
-
-    return m_ulBufferedData;
 }
Index: hxbufstate.h
===================================================================
RCS file: /cvsroot/client/core/hxbufstate.h,v
retrieving revision 1.4
diff -u -r1.4 hxbufstate.h
--- hxbufstate.h	19 May 2004 19:37:33 -0000	1.4
+++ hxbufstate.h	22 Jun 2004 22:52:26 -0000
@@ -81,7 +81,6 @@
     BOOL HasPredata(BOOL bIsSeekPerformed);
 
     INT64 CreateINT64Timestamp(UINT32 ulTime);
-    INT64 CreateINT64Timesync(UINT32 ulTime);
 
     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize, 
 		  UINT32 ulElapsedTime, BOOL bIsLive,
@@ -98,11 +97,6 @@
 			      ULONG32 ulBytesAtTransport,
 			      BOOL bDoneAtTransport);
 
-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp, 
-				REF(INT64) llHighTimestamp,
-				REF(UINT32) ulBytesBuffered,
-				BOOL bUseTransportStats);
-
     void GetExcessBufferInfo(INT64 llTheLowestTS,
 			     INT64 llTheHighestTS,
 			     BOOL bIsSeekPerformed,
@@ -119,8 +113,6 @@
 
     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
 
-    void OnTimeSync(UINT32 ulCurrentTime);
-
     // Should remove
     void SetAvgBWToASMBw();
     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
@@ -149,19 +141,6 @@
 			 UINT32 ulCurrentBuffering,
 			 UINT32 ulMinimumPreroll,
 			 UINT32 ulDenom) const;
-    
-    /* Functions for tracking the amount of data
-     * buffered in the renderer
-     */
-    void ClearPktInfo(); /* Clears out information about buffered packets */
-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
-							      * a packet is 
-							      * sent to the
-							      * renderer 
-							      */
-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
-			       * in the renderer
-			       */
 
     ULONG32		m_ulPreroll;
     ULONG32		m_ulPredata;
@@ -196,20 +175,6 @@
     ULONG32		m_ulLastPacketTimeStamp;
     ULONG32		m_ulAvgBandwidth;
     IHXASMProps*	m_pASMProps;
-    UINT32              m_ulLastTimeSync;
-    INT64               m_llFirstLivePacketTimestamp;
-    UINT32              m_ulTimeSyncRollOver;    
-    // These variable keep track of the amount of
-    // data buffered in the renderer
-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
-						  * OnTimeSync() call
-						  */
-
-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
-					   * Always use GetBufferedData()
-					   * to retreive the value
-					   */
-    CHXSimpleList       m_pktInfo; /* List of packet information */
 };
 
 inline
Index: hxflsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxflsrc.cpp,v
retrieving revision 1.54
diff -u -r1.54 hxflsrc.cpp
--- hxflsrc.cpp	19 May 2004 19:37:33 -0000	1.54
+++ hxflsrc.cpp	22 Jun 2004 22:52:26 -0000
@@ -76,6 +76,7 @@
 #include "uri_schemes.h"
 #include "stream_desc_hlpr.h"
 #include "findfile.h"
+#include "hxsrcbufstats.h"
 
 #include "hxheap.h"
 #ifdef _DEBUG
@@ -115,6 +116,7 @@
     , m_bValidateMetaDone(FALSE)
     , m_pFileRecognizer(NULL)
     , m_pFileReader(NULL)
+    , m_pSrcBufStats(NULL)
 {
     m_bAltURL = FALSE;
     m_bPerfectPlay = TRUE;
@@ -306,6 +308,13 @@
 
     HX_VECTOR_DELETE(m_pszURL);
     HX_DELETE(m_pURL);
+    
+    HX_RELEASE(m_pSrcBufStats);
+    m_pSrcBufStats = new HXSourceBufferStats();
+    if (m_pSrcBufStats)
+    {
+        m_pSrcBufStats->AddRef();
+    }
 
     if (!theErr && pURL)
     {
@@ -938,6 +947,7 @@
     }
 #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
 
+    HX_RELEASE(m_pSrcBufStats);
     HXSource::DoCleanup();
 
     return HXR_OK;
@@ -1068,6 +1078,11 @@
 
     m_llLastFillEndTime = 0;   
 
+    if (m_pSrcBufStats)
+    {
+        m_pSrcBufStats->Reset();
+    }
+
 cleanup:
 
     return HXR_OK;
@@ -1442,6 +1457,11 @@
 
 	    if(m_pBufferManager)
 		m_pBufferManager->UpdateCounters(pPacket, 0);
+            
+            if (m_pSrcBufStats && !pPacket->IsLost())
+            {
+                m_pSrcBufStats->OnPacket(pPacket);
+            }
 
 	    HX_RELEASE(pPacket);
 	}
@@ -2103,6 +2123,13 @@
 	}
 	HX_RELEASE(pszParentName);
 #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
+
+        if (pStreamInfo && m_pSrcBufStats)
+        {
+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
+                                 mLiveStream);
+        }
+
         m_ulStreamIndex++;
         m_uNumStreams++;
     }
@@ -2115,6 +2142,11 @@
 
 	theErr = AdjustClipTime();
 	m_pBufferManager->Init();
+
+        if (m_pSrcBufStats)
+        {
+            SetSrcBufStats(m_pSrcBufStats);
+        }
     }
 
     return theErr;
@@ -2313,6 +2345,11 @@
 	{
 	    m_pBufferManager->UpdateCounters(pPacket, 0);
 	}
+
+        if (m_pSrcBufStats && !pPacket->IsLost())
+        {
+            m_pSrcBufStats->OnPacket(pPacket);
+        }
     }
 
     m_llLastFillEndTime = llActualPacketTime;
Index: hxflsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxflsrc.h,v
retrieving revision 1.12
diff -u -r1.12 hxflsrc.h
--- hxflsrc.h	3 May 2004 18:59:30 -0000	1.12
+++ hxflsrc.h	22 Jun 2004 22:52:26 -0000
@@ -52,6 +52,8 @@
 #include "hxfiles.h"
 #include "recognizer.h"
 
+class HXSourceBufferStats;
+
 class HXFileSource : public HXSource, 
 		      public IHXFormatResponse,
                       public IHXHTTPRedirectResponse
@@ -349,6 +351,7 @@
 
     CFileReader*                m_pFileReader;
     CHXFileRecognizer*          m_pFileRecognizer;
+    HXSourceBufferStats*        m_pSrcBufStats;
 };
 
 #endif // _HX_FILE_SOURCE
Index: hxntsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxntsrc.cpp,v
retrieving revision 1.90
diff -u -r1.90 hxntsrc.cpp
--- hxntsrc.cpp	19 May 2004 19:37:33 -0000	1.90
+++ hxntsrc.cpp	22 Jun 2004 22:52:26 -0000
@@ -675,6 +675,7 @@
     HX_RESULT   rc = HXR_OK;
     BOOL        bSDPInitiated = FALSE;
     CHXString   pString;
+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
 
     // start off with the preferred protocol
     rc = CreateProtocol();
@@ -722,6 +723,14 @@
         goto cleanup;
     }
 
+    // Setup source buffer stats 
+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
+                                           (void**)&pSrcBufStats))
+    {
+        SetSrcBufStats(pSrcBufStats);
+        HX_RELEASE(pSrcBufStats);
+    }
+
     // create log info list
     m_pLogInfoList = new CHXSimpleList;
     m_ulLogInfoLength = 0;
@@ -6295,6 +6304,12 @@
 #else
     return HXR_NOTIMPL;
 #endif /* HELIX_FEATURE_RECORDCONTROL */
+}
+
+HX_RESULT 
+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
+{
+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
 }
 
 ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
Index: hxntsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxntsrc.h,v
retrieving revision 1.24
diff -u -r1.24 hxntsrc.h
--- hxntsrc.h	3 May 2004 18:59:30 -0000	1.24
+++ hxntsrc.h	22 Jun 2004 22:52:26 -0000
@@ -282,6 +282,7 @@
 
 	virtual HX_RESULT	FillRecordControl();
 
+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
 protected:
 
 	virtual 			~HXNetSource(void);
@@ -470,7 +471,6 @@
 private:
         IHXBufferControl*                m_pBufferCtl;
         IHXWatermarkBufferControl*       m_pWMBufferCtl;
-
 public:
 	HX_RESULT	FinishSetup();
 	void		ReSetup();
Index: hxsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxsrc.cpp,v
retrieving revision 1.44.2.1
diff -u -r1.44.2.1 hxsrc.cpp
--- hxsrc.cpp	15 Jun 2004 16:26:43 -0000	1.44.2.1
+++ hxsrc.cpp	22 Jun 2004 22:52:26 -0000
@@ -213,6 +213,8 @@
         , m_pRedirectURL(NULL)
         , m_pSDPURL(NULL)
         , m_bRedirectPending(FALSE)
+        , m_pTransOnTimeSync(NULL)
+        , m_pSrcBufStats(NULL)
 {
     mStreamInfoTable = new CHXMapLongToObj;
 }
@@ -313,6 +315,8 @@
     HX_DELETE(m_pRedirectURL);
     HX_DELETE(m_pSDPURL);
     m_bRedirectPending  = FALSE;
+    HX_RELEASE(m_pTransOnTimeSync);
+    HX_RELEASE(m_pSrcBufStats);
 
 #if defined(HELIX_FEATURE_RECORDCONTROL)
     if(m_pRecordControl)
@@ -340,8 +344,6 @@
             { GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*)this },
             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
             { GET_IIDHANDLE(IID_IHXPrivateStreamSource), (IHXPrivateStreamSource*)this },
-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*)this },
-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*)this },
             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl), 
               (IHXClientRateAdaptControl*)this },
 #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
@@ -388,6 +390,14 @@
 	    return HXR_NOINTERFACE;
 	}
     }
+    else if (m_pSrcBufStats &&
+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
+    {
+        m_pSrcBufStats->AddRef();
+        *ppvObj = m_pSrcBufStats;
+        return HXR_OK;
+    }
 
 #if defined(HELIX_FEATURE_AUTOUPGRADE)
     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
@@ -2250,59 +2260,6 @@
 }
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
 
-STDMETHODIMP
-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
-			    REF(INT64)  llLowestTimestamp, 
-			    REF(INT64)  llHighestTimestamp,
-			    REF(UINT32) ulNumBytes,
-			    REF(BOOL)   bDone)
-{
-    HX_RESULT res = HXR_NO_DATA;
-    
-    llLowestTimestamp = 0;
-    llHighestTimestamp = 0;
-    ulNumBytes = 0;
-    bDone = FALSE;
-
-    STREAM_INFO* pStreamInfo;
-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
-    {
-	HXBufferingState& bufState = pStreamInfo->BufferingState();
-	BOOL   bUseTransportStats = FALSE;
-
-	INT64  llTransportLowTS = 0;
-	INT64  llTransportHighTS = 0;
-	UINT32 ulTransportBytes = 0;
-	BOOL   bTransportDone = FALSE;
-
-	if (!IsLocalSource() &&
-	    (HXR_OK == GetCurrentBuffering(uStreamNumber,
-					   llTransportLowTS,
-					   llTransportHighTS,
-					   ulTransportBytes,
-					   bTransportDone)))
-	{
-	    bufState.UpdateTransportStats(llTransportLowTS,
-					  llTransportHighTS,
-					  ulTransportBytes,
-					  bTransportDone);
-
-	    bUseTransportStats = TRUE;
-
-	    // Update bDone with what the transport says.
-	    bDone = bTransportDone;
-	}
-
-	res = bufState.GetBufferingStats(llLowestTimestamp,
-					 llHighestTimestamp,
-					 ulNumBytes,
-					 bUseTransportStats);
-    }
-
-
-    return res;
-}
-
 /*
  * IHXClientRateAdaptControl Methods
  */
@@ -2948,13 +2905,34 @@
 {
     HX_RESULT res = HXR_OK;
 
-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
-         i != mStreamInfoTable->End(); ++i) 
-    {    
-	STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
-
-	pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
+    // Convert presentation time to transport time
+    if (m_pTransOnTimeSync)
+    {
+        ULONG32 ulOffset = m_ulDelay;
+        ULONG32 ulTransportTime = m_ulStartTime;
+        
+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
+        {
+            ulTransportTime += ulCurrentTime - ulOffset;
+        }
+    
+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
     }
 
     return res;
+}
+
+void 
+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
+{
+    HX_RELEASE(m_pSrcBufStats);
+    HX_RELEASE(m_pTransOnTimeSync);
+
+    if (pSrcBufStats)
+    {
+        m_pSrcBufStats = pSrcBufStats;
+        m_pSrcBufStats->AddRef();
+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
+                                       (void**)&m_pTransOnTimeSync);
+    }
 }
Index: rtspprotocol.cpp
===================================================================
RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
retrieving revision 1.39
diff -u -r1.39 rtspprotocol.cpp
--- rtspprotocol.cpp	11 May 2004 00:55:19 -0000	1.39
+++ rtspprotocol.cpp	22 Jun 2004 22:52:26 -0000
@@ -2626,12 +2626,12 @@
     UINT16 seekFrom
 )
 {
+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
+
     if (IsLive())
     {
-        return m_pProtocolLib->SeekFlush();
+        return theErr;
     }
-
-    HX_RESULT theErr = HXR_OK;
 
     m_uCurrentStreamCount = m_uStreamCount;
 

Index: Umakefil
===================================================================
RCS file: /cvsroot/protocol/rtsp/Umakefil,v
retrieving revision 1.9.2.1
diff -u -r1.9.2.1 Umakefil
--- Umakefil	16 Jun 2004 18:44:01 -0000	1.9.2.1
+++ Umakefil	22 Jun 2004 22:52:32 -0000
@@ -46,6 +46,7 @@
 			  'common/runtime/pub',
 			  'common/lang/xml/pub',
 			  'client/common/container/pub',
+                          'client/common/util/pub',
 			  'protocol/transport/rtp/include',
 		          'server/include',	
                           'server/common/struct/pub',
@@ -65,7 +66,7 @@
 		   'rtspmsg.cpp', 'rtspmdsc.cpp',
 		   'rtsppars.cpp', 'mhprop.cpp',
 		   'servrsnd.cpp', '3gpadapthdr.cpp',
-                   'rateadaptinfo.cpp')
+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
 
 if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
     project.AddSources('pipelinedesc.cpp')
Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.79.2.1
diff -u -r1.79.2.1 rtspclnt.cpp
--- rtspclnt.cpp	17 Jun 2004 04:32:09 -0000	1.79.2.1
+++ rtspclnt.cpp	22 Jun 2004 22:52:32 -0000
@@ -95,6 +95,7 @@
 #include "pipelinedesc.h"
 #include "errdbg.h"
 #include "rateadaptinfo.h"
+#include "ntsrcbufstats.h"
 
 #include "hxheap.h"
 #ifdef _DEBUG
@@ -302,6 +303,12 @@
     {
         return HXR_OK;
     }
+    else if (m_pSrcBufStats &&
+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
+                                                       ppvObj)))
+    {
+        return HXR_OK;
+    }
     *ppvObj = NULL;
     return HXR_NOINTERFACE;
 }
@@ -388,6 +395,7 @@
     m_bReportedSuccessfulTransport(FALSE),
     m_bSDPInitiated(FALSE),
     m_bMulticast(FALSE),
+    m_bIsLive(FALSE),
     m_pSDPFileHeader(NULL),
     m_pSDPStreamHeaders(NULL),
     m_bSessionSucceeded(FALSE),
@@ -404,7 +412,8 @@
     m_ulCurrentTimeOut(0),
     m_pUAProfURI(NULL),
     m_pUAProfDiff(NULL),
-    m_pRateAdaptInfo(NULL)
+    m_pRateAdaptInfo(NULL),
+    m_pSrcBufStats(NULL)
 #if defined(_MACINTOSH)
     , m_pCallback(NULL)
 #endif /* _MACINTOSH */
@@ -460,6 +469,8 @@
         m_pRateAdaptInfo->Close();
         HX_DELETE(m_pRateAdaptInfo);
     }
+
+    HX_RELEASE(m_pSrcBufStats);
 }
 
 /*
@@ -810,6 +821,21 @@
         }
     }
 
+    if (HXR_OK == hresult)
+    {
+        HX_RELEASE(m_pSrcBufStats);
+        m_pSrcBufStats = new HXNetSourceBufStats(this);
+        
+        if (m_pSrcBufStats)
+        {
+            m_pSrcBufStats->AddRef();
+        }
+        else
+        {
+            hresult = HXR_OUTOFMEMORY;
+        }
+    }
+
 #if defined(_MACINTOSH)
     if (m_pCallback &&
         m_pCallback->m_bIsCallbackPending &&
@@ -2191,7 +2217,14 @@
         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
     if (pTrans)
     {
-        rc = pTrans->getPacket(uStreamNumber, pPacket);
+        UINT32 uSeqNum;
+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
+
+        if ((HXR_OK == rc) && m_pSrcBufStats &&
+            (!pPacket->IsLost()))
+        {
+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
+        }
     }
 
     m_pMutex->Unlock();
@@ -3291,16 +3324,24 @@
     HX_RESULT rc = HXR_OK;
     m_pMutex->Lock();
 
-    CHXMapLongToObj::Iterator i;
-    for(i=m_pTransportStreamMap->Begin();
-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
+    if (m_bIsLive)
     {
-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
-        UINT16 streamNumber = (UINT16)i.get_key();
-
-        HX_ASSERT(pTransport);
+        CHXMapLongToObj::Iterator i;
+        for(i=m_pTransportStreamMap->Begin();
+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
+        {
+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
+            UINT16 streamNumber = (UINT16)i.get_key();
+            
+            HX_ASSERT(pTransport);
+            
+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
+        }
+    }
 
-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
+    if (m_pSrcBufStats)
+    {
+        m_pSrcBufStats->Reset();
     }
 
     m_pMutex->Unlock();
@@ -6964,6 +7005,11 @@
         // Get session level RTP bandwidth modifiers
         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
+        
+        if (ulIsSessionLive)
+        {
+            m_bIsLive = TRUE;
+        }
 
         // get multicast address from the session description
         if (HXR_OK == ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
@@ -7187,6 +7233,11 @@
             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
             pInfo->m_bRealMedia = bRealMedia;
 
+            if (m_pSrcBufStats)
+            {
+                m_pSrcBufStats->Init((UINT16)streamNumber, pInfo->m_bIsLive);
+            }
+
             if (m_pRateAdaptInfo)
             {
                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
@@ -7222,6 +7273,7 @@
         if (m_bMulticast)
         {
             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
+            m_bIsLive = TRUE;
         }
     }
 
Index: pub/rtspclnt.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.30.2.1
diff -u -r1.30.2.1 rtspclnt.h
--- pub/rtspclnt.h	17 Jun 2004 04:32:09 -0000	1.30.2.1
+++ pub/rtspclnt.h	22 Jun 2004 22:52:32 -0000
@@ -46,6 +46,7 @@
 #include "hxbufctl.h" // IHXTransportBufferLimit
 #include "hxrtsp2.h"
 #include "hxrsdbf.h" // IHXResendBufferControl
+#include "hxprefs.h" // IHXPreferences
 
 class RTSPClientState;
 class RTSPOptionsMessage;
@@ -63,6 +64,7 @@
 class MIMEHeader;
 class PipelinedDescribeLogic;
 class CHXRateAdaptationInfo;
+class HXNetSourceBufStats;
 
 struct IHXKeyValueList;
 struct IHXValues;
@@ -1039,6 +1041,7 @@
     
     BOOL                                m_bSDPInitiated;
     BOOL                                m_bMulticast;
+    BOOL                                m_bIsLive;
     IHXValues*                          m_pSDPFileHeader;
     CHXSimpleList*                      m_pSDPStreamHeaders;
 
@@ -1074,6 +1077,7 @@
     UINT32                              m_ulServerTimeOut;
     UINT32                              m_ulCurrentTimeOut;
     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
+    HXNetSourceBufStats*                m_pSrcBufStats;
 
 #if defined(_MACINTOSH)
     RTSPClientProtocolCallback*		m_pCallback;

Index: rtsptran.cpp
===================================================================
RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
retrieving revision 1.26
diff -u -r1.26 rtsptran.cpp
--- rtsptran.cpp	21 Apr 2004 19:16:30 -0000	1.26
+++ rtsptran.cpp	22 Jun 2004 22:53:16 -0000
@@ -526,8 +526,17 @@
     }
 }
 
+HX_RESULT 
+RTSPTransport::getPacket(UINT16 uStreamNumber,
+                         IHXPacket*& pPacket)
+{
+    UINT32 uSeqNum;
+    return getPacket(uStreamNumber, pPacket, uSeqNum);
+}
+
 HX_RESULT
-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket, 
+                         REF(UINT32) uSeqNum)
 {
     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
     RTSPStreamData* pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
@@ -547,6 +556,7 @@
     }
 
     pPacket = clientPacket->GetPacket();
+    uSeqNum = clientPacket->GetSequenceNumber();
 
     if (!pPacket)
     {
Index: pub/rtsptran.h
===================================================================
RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
retrieving revision 1.19
diff -u -r1.19 rtsptran.h
--- pub/rtsptran.h	20 Apr 2004 18:33:22 -0000	1.19
+++ pub/rtsptran.h	22 Jun 2004 22:53:16 -0000
@@ -259,6 +259,9 @@
     HX_RESULT resetFlags		(UINT16 streamNumber);
     HX_RESULT getPacket			(UINT16 uStreamNumber,
 					 IHXPacket*& pPacket);
+    HX_RESULT getPacket			(UINT16 uStreamNumber,
+					 IHXPacket*& pPacket,
+                                         REF(UINT32) uSeqNum);
     virtual HX_RESULT startPackets	(UINT16 uStreamNumber);
     virtual HX_RESULT stopPackets	(UINT16 uStreamNumber);
 
Index: Umakefil
===================================================================
RCS file: /cvsroot/client/common/util/Umakefil,v
retrieving revision 1.3
diff -u -r1.3 Umakefil
--- Umakefil	7 Feb 2003 22:37:08 -0000	1.3
+++ Umakefil	22 Jun 2004 22:53:43 -0000
@@ -53,6 +53,7 @@
 		   'chxphook.cpp',
 		   'xnetchck.cpp',
 		   'littobig.cpp',
-		   'hxunicod.cpp')
+		   'hxunicod.cpp', 
+                   'hxsrcbufstats.cpp')
 
 LibraryTarget('utlclntlib')
Index: hxcore.h
===================================================================
RCS file: /cvsroot/common/include/hxcore.h,v
retrieving revision 1.5
diff -u -r1.5 hxcore.h
--- hxcore.h	19 May 2004 19:38:28 -0000	1.5
+++ hxcore.h	22 Jun 2004 23:00:23 -0000
@@ -2060,7 +2060,50 @@
 
 // $EndPrivate.
 
+// $Private:
 
+/****************************************************************************
+ * 
+ *  Interface:
+ *
+ *	IID_IHXTransportOnTimeSync
+ *
+ *  Purpose:
+ *
+ *	This interface is used to send OnTimeSync() calls down
+ *      to the transport layer. Note that the value passed to
+ *      OnTimeSync() MUST be in the same units and have the same
+ *      offset as the packets coming from the transport. This means
+ *      that any offets caused by SMIL or live playback must be
+ *      removed before calling OnTimeSync() on this interface
+ *
+ *      IID_IHXTransportOnTimeSync
+ *
+ *	{DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
+ *
+ */
+DEFINE_GUID(IID_IHXTransportOnTimeSync, 
+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1);
+
+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
+{
+    /*
+     *	IUnknown methods
+     */
+
+    STDMETHOD(QueryInterface)	(THIS_
+				REFIID riid,
+				void** ppvObj) PURE;
+    STDMETHOD_(ULONG32,AddRef)	(THIS) PURE;
+    STDMETHOD_(ULONG32,Release)	(THIS) PURE;
+
+    /*
+     * IHXTransportOnTimeSync methods
+     */
+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
+};
+
+// $EndPrivate.
 
 #endif /* _HXCORE_H_ */
 
Index: hxpiids.h
===================================================================
RCS file: /cvsroot/common/include/hxpiids.h,v
retrieving revision 1.28.2.1
diff -u -r1.28.2.1 hxpiids.h
--- hxpiids.h	15 Jun 2004 16:38:55 -0000	1.28.2.1
+++ hxpiids.h	22 Jun 2004 23:00:23 -0000
@@ -533,6 +533,7 @@
 DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
 DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
 DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 0xa9,  0x69,  0x37,  0x3b,  0x4d)
+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
 #endif /* _HXCORE_H_ */
 
 /*
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hxsrcbufstats.h
Type: text/x-chdr
Size: 3393 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040622/469d9eb9/hxsrcbufstats-0002.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hxsrcbufstats.cpp
Type: text/x-c++src
Size: 13776 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040622/469d9eb9/hxsrcbufstats-0003.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ntsrcbufstats.h
Type: text/x-chdr
Size: 2515 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040622/469d9eb9/ntsrcbufstats-0002.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ntsrcbufstats.cpp
Type: text/x-c++src
Size: 3035 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040622/469d9eb9/ntsrcbufstats-0003.bin
From avijit at cs.ucsb.edu  Tue Jun 22 23:26:37 2004
From: avijit at cs.ucsb.edu (Avijit SenMazumder)
Date: Tue Jun 22 23:26:10 2004
Subject: [Common-dev] rfc: new net api needs better multicast socket
	support
In-Reply-To: <6.1.1.1.0.20040621114613.04782778@mailone.real.com>
References: <6.1.1.1.0.20040621114613.04782778@mailone.real.com>
Message-ID: 

Hi Liam,

Please find my comments below.

Avijit

On Mon, 21 Jun 2004, Liam Murray wrote:

> The multicast implementation in the new net api is currently incomplete. In 
> sockimp.cpp there is a class CHXSocket (derives from IHXSocket) and 
> CHXMulticastSocket (derives from IHXMulticastSocket). The 
> CHXMulticastSocket is more or less a place holder and hasn't been 
> used/tested yet. (You can't create an instance via net services.)
> 
> The current multicast interface is:
> 
> // incomplete
> DECLARE_INTERFACE_(IHXMulticastSocket, IUnknown)
> {
>      // ...
>      STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
>      STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
> };
> 
> 1) I'd like to update these to pass an interface address, i.e.,:
> 
>      /* NULL may be passed for pInterface to indicate INADDR_ANY */
>      STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroup, 
> IHXSockAddr* pInterface) PURE;
>      STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroup, 
> IHXSockAddr* pInterface) PURE;

I totally agree with you. One thing to keep in mind though that these 
would be a group of api which would take more than one soc address as 
parameters, so need to be checked that both belong to same family - i.e. 
IP V4 or V6.

 
> 2) For convenience we can add a
> 
> STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl) PURE;
> 
> However, some may object because we can use IHXSocket::SetOption with 
> HX_SOCKOPT_IN4_MULTICAST_TTL or HX_SOCKOPT_IN6_MULTICAST_HOPS (depending on 
> the socket family).

The TTL in multicast is becoming obselete. They are mainly used by sender for 
scoped flooding of content data. The flood and prune multicast routing 
protocols do not make sense in internet, though could be used within a LAN. 
So may be as a legacy we could carry it forward.


 
> 3) There are also some IGMPv3 options that might be worth exposing while we 
> are at it (even though we may defer implementation and just return 
> HXR_NOTIMPL for now), for example:
> 
>    // IGMPv3 options
>      typedef enum
>      {
>          HX_MCAST_SOURCE_ADD,
>          HX_MCAST_SOURCE_DROP,
>          HX_MCAST_SOURCE_BLOCK,
>          HX_MCAST_SOURCE_UNBLOCK
>      } HXMulticastSourceOption;
> 
> STDMETHOD(SetMulticastSourceOption)   (THIS_ HXMulticastSourceOption flag, 
> IHXSockAddr* pGroup, IHXSockAddr* pSource, IHXSockAddr* pInterface) PURE;

For source specific multicast - a combination of source and group is 
called channel. And receiver apps subscribes to a channel for receiveing 
content. From that perspective may be having following method name make 
sense.

SubscribeChannel( IHXSockAddr* pGroup, IHXSockAddr* pSource, IHXSockAddr* 
pInterface )

UnsubscribeChannel( IHXSockAddr* pGroup, IHXSockAddr* pSource, 
IHXSockAddr* pInterface )

Similarly 
BlockChannel and UnblockChannel

 
> 4) Alternatively, we already have a get/set option interface in IHXSocket:
> 
>      STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) PURE;
>      STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;
> 
> We could theoretically expand on these so we can configure multicast 
> behavior via them, e.g., by adding a GetOption() method that takes a const 
> void* and defining structs for various HXSockOpt socket options as needed. 
> That would match bsd socket api semantics and perhaps be more flexible in 
> the sense that we wouldn't really need to define new interfaces for future 
> socket options that may become available/needed (we'd just have to define a 
> new struct and update the implementation).
> 
> Currently any socket option that is associated with data that doesn't fit 
> in a UINT32 (e.g., one of the multicast options) has to be exposed via an 
> interface.

I think this would be exposing too much through interface. However you can 
implement this as member method of CHXSocket class and then use internally 
for all those interface methods. Also I agree that with you and Henry that 
IHXMulticastSocket should be derived from IHXSocket.


> I think I may still prefer the interfaces for the convenience factor, plus 
> I don't anticipate a bunch of new socket options.
> 
> Comments?
>

This is not directly related to multicast join/leave interface, but 
relevant to multicast address. A range of multicast address is set aside 
for source specific multicast, 232/8 for IP V4 and FF3x::/32 for IP V6.
So I think GetAddrClass() method for both IP V4 and V6 need to take 
accoutn of that. We should have HX_IN4_CLASS_SOURCE_SPECIFIC_MULTICAST and
HX_IN6_CLASS_SOURCE_SPECIFIC_MULTICAST.  

> 
> Liam
> 
> 
> 
> 
> 
> 
> 
> _______________________________________________
> Common-dev mailing list
> Common-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 

From rgammon at real.com  Tue Jun 22 23:59:16 2004
From: rgammon at real.com (Ryan Gammon)
Date: Tue Jun 22 23:59:05 2004
Subject: [Common-dev] LC_CLIENT_LEVEL* problems
Message-ID: <40D92A44.6000700@real.com>

Hi all,

I'm having problems using producer's logging mechanism in the client.

Line 113 of hxtwritermanager.cpp reads:

    // If the message is a dev-level message, and they aren't allowed, 
reject the log request
    if( szNamespace && 0 == strcmp(szNamespace, "RealNetworks") && (0x01 
& nLogCode) && !m_bAllowRNLevelMsgs )
    {
        return HXR_FAIL;
    }


There are two potential issues here:
- Is this a good place for error messages to be getting rejected? (maybe 
this should be in the log observer filtering?)
- The nLogCode for client is one of the following:

    // Client-related log codes
    LC_CLIENT_LEVEL1 = 0x00000001,
    LC_CLIENT_LEVEL2 = 0x00000002,
    LC_CLIENT_LEVEL3 = 0x00000004,
    LC_CLIENT_LEVEL4 = 0x00000008

hxtwritermanager seems to be assuming that the bottom bit is used to 
discriminate between dev and non-dev messages. This makes level 1 errors 
dev messages, and the rest non-dev. Default behavior seems to be to not 
log dev messages (unless one creates an empty debug.txt file), which 
leads to odd logging behavior.

I think either the level values might have to change here, or the 
hxtwritermanager code above has to be modified to not recognize 
LC_CLIENT_LEVEL1 as a dev message.

Am I missing something?

From ehyche at real.com  Wed Jun 23 06:28:30 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 23 06:28:40 2004
Subject: [Common-dev] LC_CLIENT_LEVEL* problems
In-Reply-To: <40D92A44.6000700@real.com>
Message-ID: <5.1.0.14.2.20040623092522.02bead80@mailone.real.com>



At 11:59 PM 6/22/2004 -0700, Ryan Gammon wrote:
>Hi all,
>
>I'm having problems using producer's logging mechanism in the client.
>
>Line 113 of hxtwritermanager.cpp reads:
>
>    // If the message is a dev-level message, and they aren't allowed, 
> reject the log request
>    if( szNamespace && 0 == strcmp(szNamespace, "RealNetworks") && (0x01 & 
> nLogCode) && !m_bAllowRNLevelMsgs )
>    {
>        return HXR_FAIL;
>    }
>
>
>There are two potential issues here:
>- Is this a good place for error messages to be getting rejected? (maybe 
>this should be in the log observer filtering?)
>- The nLogCode for client is one of the following:
>
>    // Client-related log codes
>    LC_CLIENT_LEVEL1 = 0x00000001,
>    LC_CLIENT_LEVEL2 = 0x00000002,
>    LC_CLIENT_LEVEL3 = 0x00000004,
>    LC_CLIENT_LEVEL4 = 0x00000008
>
>hxtwritermanager seems to be assuming that the bottom bit is used to 
>discriminate between dev and non-dev messages. This makes level 1 errors 
>dev messages, and the rest non-dev. Default behavior seems to be to not 
>log dev messages (unless one creates an empty debug.txt file), which leads 
>to odd logging behavior.
>
>I think either the level values might have to change here, or the 
>hxtwritermanager code above has to be modified to not recognize 
>LC_CLIENT_LEVEL1 as a dev message.

Ryan,

I *thought* that I put both of these sections of code behind
producer-specific defines, but looking through the file, it
looks like I neglected to do that. I'll fix that.

Eric

>Am I missing something?
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From ehyche at real.com  Wed Jun 23 06:42:40 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 23 06:42:51 2004
Subject: [Common-dev] rfc: new net api needs better multicast
	socket support
In-Reply-To: <6.1.1.1.0.20040621114613.04782778@mailone.real.com>
Message-ID: <5.1.0.14.2.20040623094001.02bead80@mailone.real.com>


Liam,

Comments inline...

At 06:38 PM 6/21/2004 -0700, Liam Murray wrote:
>The multicast implementation in the new net api is currently incomplete. 
>In sockimp.cpp there is a class CHXSocket (derives from IHXSocket) and 
>CHXMulticastSocket (derives from IHXMulticastSocket). The 
>CHXMulticastSocket is more or less a place holder and hasn't been 
>used/tested yet. (You can't create an instance via net services.)
>
>The current multicast interface is:
>
>// incomplete
>DECLARE_INTERFACE_(IHXMulticastSocket, IUnknown)
>{
>     // ...
>     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
>     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
>};
>
>1) I'd like to update these to pass an interface address, i.e.,:
>
>     /* NULL may be passed for pInterface to indicate INADDR_ANY */
>     STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroup, 
> IHXSockAddr* pInterface) PURE;
>     STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroup, 
> IHXSockAddr* pInterface) PURE;

This sounds good to me.

>2) For convenience we can add a
>
>STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl) PURE;
>
>However, some may object because we can use IHXSocket::SetOption with 
>HX_SOCKOPT_IN4_MULTICAST_TTL or HX_SOCKOPT_IN6_MULTICAST_HOPS (depending 
>on the socket family).

I prefer using SetOption() for this, especially if we
derive IHXMulticastSocket from IHXSocket.

>3) There are also some IGMPv3 options that might be worth exposing while 
>we are at it (even though we may defer implementation and just return 
>HXR_NOTIMPL for now), for example:
>
>   // IGMPv3 options
>     typedef enum
>     {
>         HX_MCAST_SOURCE_ADD,
>         HX_MCAST_SOURCE_DROP,
>         HX_MCAST_SOURCE_BLOCK,
>         HX_MCAST_SOURCE_UNBLOCK
>     } HXMulticastSourceOption;
>
>STDMETHOD(SetMulticastSourceOption)   (THIS_ HXMulticastSourceOption flag, 
>IHXSockAddr* pGroup, IHXSockAddr* pSource, IHXSockAddr* pInterface) PURE;
>
>4) Alternatively, we already have a get/set option interface in IHXSocket:
>
>     STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) 
> PURE;
>     STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;
>
>We could theoretically expand on these so we can configure multicast 
>behavior via them, e.g., by adding a GetOption() method that takes a const 
>void* and defining structs for various HXSockOpt socket options as needed. 
>That would match bsd socket api semantics and perhaps be more flexible in 
>the sense that we wouldn't really need to define new interfaces for future 
>socket options that may become available/needed (we'd just have to define 
>a new struct and update the implementation).

Ditto here. I think deriving IHXMulticastSocket from IHXSocket makes sense,
and if we do that, let's use the existing GetOption/SetOption methods.

I agree that we may want to change/add the options methods to take a void*
instead of a UINT32 so that we can pass structs around.

Eric

>Currently any socket option that is associated with data that doesn't fit 
>in a UINT32 (e.g., one of the multicast options) has to be exposed via an 
>interface.
>
>I think I may still prefer the interfaces for the convenience factor, plus 
>I don't anticipate a bunch of new socket options.
>
>Comments?
>
>
>Liam
>
>
>
>
>
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From ehyche at real.com  Wed Jun 23 06:55:46 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 23 06:56:21 2004
Subject: [Common-dev] CR-Client: Moving IHXSourceBufferingStats2
	implementation
In-Reply-To: <20040622235202.GA5152@real.com>
Message-ID: <5.1.0.14.2.20040623095240.02bead80@mailone.real.com>


This is a pretty complicated change, so I doubt I'm
hitting any of the subtleties, but after a cursory examination,
these changes look good to me.

Just wondering though, why do we need the

>+// $Private:

and

>+// $EndPrivate.

around the new interface definition? Seems like since
hxcore.h is out in the public anyway, that our
Private/EndPrivate stuff is moot.

I'm not suggesting we go through and remove them from
all header files, but it seems to me we shouldn't be
adding any *more* of them.

Eric

At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
>Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
>           number information can be maintained as well.
>
>Overview: These changes move the IHXSourceBufferingStats2 implementation
>           out of HXBufferingState and into a new class called
>           HXSourceBufferStats. This was done because the client needs to
>           track packet sequence numbers for 3GPP-Rel6 OBSN support.
>           There was no good way to get the sequence number information to
>           the HXBufferingState class so the IHXSourceBufferingStats2 logic
>           was moved to where this information is available.
>
>           A new interface called IHXTransportOnTimeSync was created to
>           propagate OnTimeSync() like calls to HXSourceBufferStats. The
>           time passed to the OnTimeSync() call in this interface MUST
>           NOT have any offsets created by SMIL or live playback. The time
>           should be in the same time frame as the packets coming from the
>           transport. If someone wants to rename this interface that is fine
>           by me.
>
>
>           - Created HXSourceBufferStats to contain the base
>             IHXSourceBufferingStats2 implementation. This class is
>             used by HXFileSource.
>
>           - Created HXNetSourceBufStats which derives from 
> HXSourceBufferStats.
>             This class just overloads the GetCurrentBuffering() so that it
>             returns the amount of data in the transport buffer. This is
>             used by RTSPClientProtocol.
>
>           - Removed IHXSourceBufferingStats2 code from HXSource
>
>           - Removed packet tracking code from HXBufferingState. This
>             functionality is implemented by HXSourceBufferStats now
>
>           - Added code to HXSource to provide OnTimeSync() calls to the
>             IHXTransportOnTimeSync interface.
>
>           - HXSource now exposes IHXSourceBufferingStats functionality 
> through
>             it's m_pSrcBufStats member variable instead of implementing it
>             itself. The file and network sources are expected to provide an
>             IHXSourceBufferingStats2 interface via a
>             HXSource::SetSrcBufStats() call.
>
>           - Added code to HXFileSource to use HXSourceBufferStats
>
>           - Added code to RTSPClientProtocol to use HXNetSourceBufStats
>
>           - Fixed some code in CBufferManager that was expecting HXSource
>             to implement IHXSourceBufferingStats. This code now QI's for
>             IHXSourceBufferingStats and uses that interface.
>
>
>
>Files Modified:
>client/core/buffmgr.cpp
>client/core/hxbsrc.h
>client/core/hxbufstate.h
>client/core/hxbufstate.cpp
>client/core/hxflsrc.cpp
>client/core/hxflsrc.h
>client/core/hxntsrc.cpp
>client/core/hxntsrc.h
>client/core/hxsrc.cpp
>client/core/rtspprotocol.cpp
>protocol/rtsp/Umakefil
>protocol/rtsp/rtspclnt.cpp
>protocol/rtsp/pub/rtspclnt.h
>protocol/transport/common/system/rtsptran.cpp
>protocol/transport/common/system/pub/rtsptran.h
>client/common/util/Umakefil
>common/include/hxcore.h
>common/include/hxpiids.h
>
>Files Added:
>client/common/util/pub/hxsrcbufstats.h
>client/common/util/hxsrcbufstats.cpp
>protocol/rtsp/ntsrcbufstats.h
>protocol/rtsp/ntsrcbufstats.cpp
>
>Image Size and Heap Use impact:
>
>Platforms and Profiles affected: all
>
>Distribution Libraries affected: rdtclntlib
>
>Distribution library impact and planned action:
>m_bIsLive and m_pSrcBufStats member variables were added to
>RTSPClientProtocol so any derived objects will need to be
>recompiled
>
>Platforms and Profiles Build Verified: win32
>
>Platforms and Profiles Functionality verified: win32
>
>Branch: HEAD
>
>QA Instructions: none
>
>Index: buffmgr.cpp
>===================================================================
>RCS file: /cvsroot/client/core/buffmgr.cpp,v
>retrieving revision 1.21
>diff -u -r1.21 buffmgr.cpp
>--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
>+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
>@@ -610,6 +610,11 @@
>       * - Keep track of the stream with the lowest timestamp and is
>       *   buffering data
>       */
>+    IHXSourceBufferingStats* pSrcBufStats = NULL;
>+
>+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
>+                              (void**)&pSrcBufStats);
>+
>      for (i = m_pStreamInfoTable->Begin(); i != 
> m_pStreamInfoTable->End(); ++i)
>      {
>         pStreamInfo = (STREAM_INFO*) (*i);
>@@ -619,12 +624,15 @@
>         ULONG32 ulNumBytesAtTransport = 0;
>         BOOL bDoneAtTransport = FALSE;
>
>-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
>-                                      llLowestTimestampAtTransport,
>-                                      llHighestTimestampAtTransport,
>-                                      ulNumBytesAtTransport,
>-                                      bDoneAtTransport);
>-
>+        if (pSrcBufStats)
>+        {
>+            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
>+                                              llLowestTimestampAtTransport,
>+                                              llHighestTimestampAtTransport,
>+                                              ulNumBytesAtTransport,
>+                                              bDoneAtTransport);
>+        }
>+
>         pStreamInfo->BufferingState().UpdateTransportStats(
>             llLowestTimestampAtTransport,
>             llHighestTimestampAtTransport,
>@@ -658,6 +666,7 @@
>
>         }
>      }
>+    HX_RELEASE(pSrcBufStats);
>
>      /* If none of the streams have any data buffered at the transport layer,
>       * return.
>Index: hxbsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbsrc.h,v
>retrieving revision 1.18.2.1
>diff -u -r1.18.2.1 hxbsrc.h
>--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
>+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
>@@ -233,12 +233,11 @@
>                   public IHXPrivateStreamSource,
>                   public IHXBackChannel,
>                   public IHXASMSource,
>-                  public IHXClientRateAdaptControl,
>+                  public IHXClientRateAdaptControl
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>-                 public IHXHyperNavigate,
>-                 public IHXHyperNavigate2,
>+                 , public IHXHyperNavigate,
>+                 public IHXHyperNavigate2
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>-                  public IHXSourceBufferingStats2
>  {
>  protected:
>      LONG32                     m_lRefCount;
>@@ -487,35 +486,6 @@
>                             IHXValues* pParams);
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>
>-    /************************************************************************
>-     * Method:
>-     *     IHXSourceBufferingStats2::GetCurrentBuffering
>-     * Purpose:
>-     *     Get the current buffering information
>-     */
>-
>-    STDMETHOD(GetCurrentBuffering) (THIS_
>-                                    UINT16  uStreamNumber,
>-                                    REF(INT64)  llLowestTimestamp,
>-                                    REF(INT64)  llHighestTimestamp,
>-                                    REF(UINT32) ulNumBytes,
>-                                    REF(BOOL)   bDone) PURE;
>-    /************************************************************************
>-     * Method:
>-     *     IHXSourceBufferingStats2::GetTotalBuffering
>-     * Purpose:
>-     *     Get the total amount of data buffered for a stream.
>-     *      This includes what is in the transport buffer and in
>-     *      the renderer
>-     */
>-
>-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
>-                                  REF(INT64)  llLowestTimestamp,
>-                                  REF(INT64)  llHighestTimestamp,
>-                                  REF(UINT32) ulNumBytes,
>-                                  REF(BOOL)   bDone);
>-
>-
>      /*
>       * IHXClientRateAdaptControl Methods
>       */
>@@ -731,7 +701,7 @@
>             virtual HX_RESULT   FillRecordControl() = 0;
>                     BOOL        IsPlayingFromRecordControl() { return 
> m_bPlayFromRecordControl; };
>
>-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>
>              const char*         GetRedirectURL() { return 
> (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
>              const char*         GetSDPURL() { return (m_pSDPURL ? 
> m_pSDPURL->GetURL() : NULL); };
>@@ -769,6 +739,8 @@
>              void        ProcessFileHeader(void);
>              HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, 
> STREAM_INFO*& pStreamInfo);
>
>+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
>+
>      HX_RESULT                  mLastError;
>      CHXMapLongToObj*            mStreamInfoTable;
>
>@@ -868,6 +840,8 @@
>      CHXURL*                     m_pRedirectURL;
>      CHXURL*                     m_pSDPURL;
>      BOOL                        m_bRedirectPending;
>+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
>+    IHXSourceBufferingStats2*   m_pSrcBufStats;
>  };
>
>  // Defined flags
>Index: hxbufstate.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxbufstate.cpp,v
>retrieving revision 1.7
>diff -u -r1.7 hxbufstate.cpp
>--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
>+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
>@@ -83,18 +83,11 @@
>      , m_ulLastPacketTimeStamp(0)
>      , m_ulAvgBandwidth(0)
>      , m_pASMProps(NULL)
>-    , m_llCurrentPlaybackTime(0)
>-    , m_ulBufferedData(0)
>-    , m_ulLastTimeSync(0)
>-    , m_llFirstLivePacketTimestamp(0)
>-    , m_ulTimeSyncRollOver(0)
>  {}
>
>  HXBufferingState::~HXBufferingState()
>  {
>      HX_RELEASE(m_pASMProps);
>-
>-    ClearPktInfo();
>  }
>
>  void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
>@@ -179,8 +172,6 @@
>      m_ulLastPacketTimeStamp = 0;
>      m_bIsFirstPacket = TRUE;
>
>-    ClearPktInfo();
>-
>      if (bIsSeeking)
>      {
>         m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
>@@ -288,11 +279,6 @@
>      return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + 
> CAST_TO_INT64 ulTime;
>  }
>
>-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
>-{
>-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 
>MAX_UINT32 + CAST_TO_INT64 ulTime;
>-}
>-
>  void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>                                 UINT32 ulElapsedTime,
>                                 BOOL bIsLive, BOOL bIsBufferedPlayMode)
>@@ -318,16 +304,12 @@
>         if (bIsLive)
>         {
>             m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
>-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
>          }
>
>         m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
>         m_bIsFirstPacket = FALSE;
>      }
>
>-    // Add this packet to our packet info statistics
>-    AddPktInfo(llActualTimeStamp, ulPacketSize);
>-
>      // data based preroll
>      if (DataBasedPreroll())
>      {
>@@ -451,47 +433,6 @@
>      m_bDoneAtTransport = bDoneAtTransport;
>  }
>
>-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
>-                                             REF(INT64) llHighTimestamp,
>-                                             REF(UINT32) ulBytesBuffered,
>-                                             BOOL bUseTransportStats)
>-{
>-    HX_RESULT res = HXR_NO_DATA;
>-
>-    if (!m_bIsFirstPacket)
>-    {
>-       if (!m_pktInfo.IsEmpty())
>-       {
>-           HXBufferedPktInfo* pPktInfo =
>-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
>-
>-           llLowTimestamp = pPktInfo->Timestamp();
>-       }
>-       else
>-       {
>-           llLowTimestamp = m_llHighestTimeStamp;
>-       }
>-
>-       llHighTimestamp = m_llHighestTimeStamp;
>-       ulBytesBuffered = GetBufferedData();
>-
>-
>-       if (bUseTransportStats)
>-       {
>-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
>-           {
>-               llHighTimestamp = m_llHighestTimestampAtTransport;
>-           }
>-
>-           ulBytesBuffered += m_ulNumBytesAtTransport;
>-       }
>-
>-       res = HXR_OK;
>-    }
>-
>-    return res;
>-}
>-
>  void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
>                                            INT64 llTheHighestTS,
>                                            BOOL bIsSeekPerformed,
>@@ -569,19 +510,6 @@
>
>  }
>
>-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
>-{
>-    //  0xFA .. 0xFF [roll over] (0x01)
>-    if (m_ulLastTimeSync > ulCurrentTime &&
>-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
>-    {
>-       m_ulTimeSyncRollOver++;
>-    }
>-    m_ulLastTimeSync = ulCurrentTime;
>-
>-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
>-}
>-
>  void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
>                                         ULONG32 ulMinBufferingInMs)
>  {
>@@ -771,62 +699,4 @@
>      {
>         m_ulAvgBandwidth = ulBandwidth;
>      }
>-}
>-
>-void HXBufferingState::ClearPktInfo()
>-{
>-    m_ulBufferedData = 0;
>-    while(!m_pktInfo.IsEmpty())
>-    {
>-       HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
>-       delete pInfo;
>-    }
>-}
>-
>-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
>-{
>-    // Subtract off the first live packet timestamp.
>-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
>-    llTimestamp -= m_llFirstLivePacketTimestamp;
>-    // Create the HXBufferedPktInfo class
>-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
>-                                                       ulPacketSize);
>-    if (pPktInfo)
>-    {
>-       m_pktInfo.AddTail(pPktInfo);
>-       m_ulBufferedData += ulPacketSize;
>-    }
>-
>-    // purge the old packet info data
>-    //  this keeps the list short and prevents the Symbian
>-    //  allocator from freaking out
>-    (void)GetBufferedData();
>-}
>-
>-UINT32 HXBufferingState::GetBufferedData()
>-{
>-    BOOL bDone = m_pktInfo.IsEmpty();
>-
>-    // Remove all packet info that is past due
>-    // and subtract their sizes from our buffering total
>-    while(!bDone)
>-    {
>-       HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
>-
>-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
>-       {
>-           m_ulBufferedData -= pPktInfo->Size();
>-
>-           m_pktInfo.RemoveHead();
>-           delete pPktInfo;
>-
>-           bDone = m_pktInfo.IsEmpty();
>-       }
>-       else
>-       {
>-           bDone = TRUE;
>-       }
>-    }
>-
>-    return m_ulBufferedData;
>  }
>Index: hxbufstate.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbufstate.h,v
>retrieving revision 1.4
>diff -u -r1.4 hxbufstate.h
>--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
>+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
>@@ -81,7 +81,6 @@
>      BOOL HasPredata(BOOL bIsSeekPerformed);
>
>      INT64 CreateINT64Timestamp(UINT32 ulTime);
>-    INT64 CreateINT64Timesync(UINT32 ulTime);
>
>      void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>                   UINT32 ulElapsedTime, BOOL bIsLive,
>@@ -98,11 +97,6 @@
>                               ULONG32 ulBytesAtTransport,
>                               BOOL bDoneAtTransport);
>
>-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
>-                               REF(INT64) llHighTimestamp,
>-                               REF(UINT32) ulBytesBuffered,
>-                               BOOL bUseTransportStats);
>-
>      void GetExcessBufferInfo(INT64 llTheLowestTS,
>                              INT64 llTheHighestTS,
>                              BOOL bIsSeekPerformed,
>@@ -119,8 +113,6 @@
>
>      UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
>
>-    void OnTimeSync(UINT32 ulCurrentTime);
>-
>      // Should remove
>      void SetAvgBWToASMBw();
>      BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
>@@ -149,19 +141,6 @@
>                         UINT32 ulCurrentBuffering,
>                         UINT32 ulMinimumPreroll,
>                         UINT32 ulDenom) const;
>-
>-    /* Functions for tracking the amount of data
>-     * buffered in the renderer
>-     */
>-    void ClearPktInfo(); /* Clears out information about buffered packets */
>-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
>-                                                             * a packet is
>-                                                             * sent to the
>-                                                             * renderer
>-                                                             */
>-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
>-                              * in the renderer
>-                              */
>
>      ULONG32            m_ulPreroll;
>      ULONG32            m_ulPredata;
>@@ -196,20 +175,6 @@
>      ULONG32            m_ulLastPacketTimeStamp;
>      ULONG32            m_ulAvgBandwidth;
>      IHXASMProps*       m_pASMProps;
>-    UINT32              m_ulLastTimeSync;
>-    INT64               m_llFirstLivePacketTimestamp;
>-    UINT32              m_ulTimeSyncRollOver;
>-    // These variable keep track of the amount of
>-    // data buffered in the renderer
>-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
>-                                                 * OnTimeSync() call
>-                                                 */
>-
>-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
>-                                          * Always use GetBufferedData()
>-                                          * to retreive the value
>-                                          */
>-    CHXSimpleList       m_pktInfo; /* List of packet information */
>  };
>
>  inline
>Index: hxflsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxflsrc.cpp,v
>retrieving revision 1.54
>diff -u -r1.54 hxflsrc.cpp
>--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
>+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
>@@ -76,6 +76,7 @@
>  #include "uri_schemes.h"
>  #include "stream_desc_hlpr.h"
>  #include "findfile.h"
>+#include "hxsrcbufstats.h"
>
>  #include "hxheap.h"
>  #ifdef _DEBUG
>@@ -115,6 +116,7 @@
>      , m_bValidateMetaDone(FALSE)
>      , m_pFileRecognizer(NULL)
>      , m_pFileReader(NULL)
>+    , m_pSrcBufStats(NULL)
>  {
>      m_bAltURL = FALSE;
>      m_bPerfectPlay = TRUE;
>@@ -306,6 +308,13 @@
>
>      HX_VECTOR_DELETE(m_pszURL);
>      HX_DELETE(m_pURL);
>+
>+    HX_RELEASE(m_pSrcBufStats);
>+    m_pSrcBufStats = new HXSourceBufferStats();
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->AddRef();
>+    }
>
>      if (!theErr && pURL)
>      {
>@@ -938,6 +947,7 @@
>      }
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
>
>+    HX_RELEASE(m_pSrcBufStats);
>      HXSource::DoCleanup();
>
>      return HXR_OK;
>@@ -1068,6 +1078,11 @@
>
>      m_llLastFillEndTime = 0;
>
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->Reset();
>+    }
>+
>  cleanup:
>
>      return HXR_OK;
>@@ -1442,6 +1457,11 @@
>
>             if(m_pBufferManager)
>                 m_pBufferManager->UpdateCounters(pPacket, 0);
>+
>+            if (m_pSrcBufStats && !pPacket->IsLost())
>+            {
>+                m_pSrcBufStats->OnPacket(pPacket);
>+            }
>
>             HX_RELEASE(pPacket);
>         }
>@@ -2103,6 +2123,13 @@
>         }
>         HX_RELEASE(pszParentName);
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
>+
>+        if (pStreamInfo && m_pSrcBufStats)
>+        {
>+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
>+                                 mLiveStream);
>+        }
>+
>          m_ulStreamIndex++;
>          m_uNumStreams++;
>      }
>@@ -2115,6 +2142,11 @@
>
>         theErr = AdjustClipTime();
>         m_pBufferManager->Init();
>+
>+        if (m_pSrcBufStats)
>+        {
>+            SetSrcBufStats(m_pSrcBufStats);
>+        }
>      }
>
>      return theErr;
>@@ -2313,6 +2345,11 @@
>         {
>             m_pBufferManager->UpdateCounters(pPacket, 0);
>         }
>+
>+        if (m_pSrcBufStats && !pPacket->IsLost())
>+        {
>+            m_pSrcBufStats->OnPacket(pPacket);
>+        }
>      }
>
>      m_llLastFillEndTime = llActualPacketTime;
>Index: hxflsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxflsrc.h,v
>retrieving revision 1.12
>diff -u -r1.12 hxflsrc.h
>--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
>+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
>@@ -52,6 +52,8 @@
>  #include "hxfiles.h"
>  #include "recognizer.h"
>
>+class HXSourceBufferStats;
>+
>  class HXFileSource : public HXSource,
>                       public IHXFormatResponse,
>                        public IHXHTTPRedirectResponse
>@@ -349,6 +351,7 @@
>
>      CFileReader*                m_pFileReader;
>      CHXFileRecognizer*          m_pFileRecognizer;
>+    HXSourceBufferStats*        m_pSrcBufStats;
>  };
>
>  #endif // _HX_FILE_SOURCE
>Index: hxntsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxntsrc.cpp,v
>retrieving revision 1.90
>diff -u -r1.90 hxntsrc.cpp
>--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
>+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
>@@ -675,6 +675,7 @@
>      HX_RESULT   rc = HXR_OK;
>      BOOL        bSDPInitiated = FALSE;
>      CHXString   pString;
>+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
>
>      // start off with the preferred protocol
>      rc = CreateProtocol();
>@@ -722,6 +723,14 @@
>          goto cleanup;
>      }
>
>+    // Setup source buffer stats
>+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
>+                                           (void**)&pSrcBufStats))
>+    {
>+        SetSrcBufStats(pSrcBufStats);
>+        HX_RELEASE(pSrcBufStats);
>+    }
>+
>      // create log info list
>      m_pLogInfoList = new CHXSimpleList;
>      m_ulLogInfoLength = 0;
>@@ -6295,6 +6304,12 @@
>  #else
>      return HXR_NOTIMPL;
>  #endif /* HELIX_FEATURE_RECORDCONTROL */
>+}
>+
>+HX_RESULT
>+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
>+{
>+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
>  }
>
>  ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
>Index: hxntsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxntsrc.h,v
>retrieving revision 1.24
>diff -u -r1.24 hxntsrc.h
>--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
>+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
>@@ -282,6 +282,7 @@
>
>         virtual HX_RESULT       FillRecordControl();
>
>+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>  protected:
>
>         virtual                         ~HXNetSource(void);
>@@ -470,7 +471,6 @@
>  private:
>          IHXBufferControl*                m_pBufferCtl;
>          IHXWatermarkBufferControl*       m_pWMBufferCtl;
>-
>  public:
>         HX_RESULT       FinishSetup();
>         void            ReSetup();
>Index: hxsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxsrc.cpp,v
>retrieving revision 1.44.2.1
>diff -u -r1.44.2.1 hxsrc.cpp
>--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
>+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
>@@ -213,6 +213,8 @@
>          , m_pRedirectURL(NULL)
>          , m_pSDPURL(NULL)
>          , m_bRedirectPending(FALSE)
>+        , m_pTransOnTimeSync(NULL)
>+        , m_pSrcBufStats(NULL)
>  {
>      mStreamInfoTable = new CHXMapLongToObj;
>  }
>@@ -313,6 +315,8 @@
>      HX_DELETE(m_pRedirectURL);
>      HX_DELETE(m_pSDPURL);
>      m_bRedirectPending  = FALSE;
>+    HX_RELEASE(m_pTransOnTimeSync);
>+    HX_RELEASE(m_pSrcBufStats);
>
>  #if defined(HELIX_FEATURE_RECORDCONTROL)
>      if(m_pRecordControl)
>@@ -340,8 +344,6 @@
>              { GET_IIDHANDLE(IID_IHXPendingStatus), 
> (IHXPendingStatus*)this },
>              { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
>              { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> (IHXPrivateStreamSource*)this },
>-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
>(IHXSourceBufferingStats*)this },
>-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
>(IHXSourceBufferingStats2*)this },
>              { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
>                (IHXClientRateAdaptControl*)this },
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>@@ -388,6 +390,14 @@
>             return HXR_NOINTERFACE;
>         }
>      }
>+    else if (m_pSrcBufStats &&
>+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
>+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
>+    {
>+        m_pSrcBufStats->AddRef();
>+        *ppvObj = m_pSrcBufStats;
>+        return HXR_OK;
>+    }
>
>  #if defined(HELIX_FEATURE_AUTOUPGRADE)
>      else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
>@@ -2250,59 +2260,6 @@
>  }
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>
>-STDMETHODIMP
>-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
>-                           REF(INT64)  llLowestTimestamp,
>-                           REF(INT64)  llHighestTimestamp,
>-                           REF(UINT32) ulNumBytes,
>-                           REF(BOOL)   bDone)
>-{
>-    HX_RESULT res = HXR_NO_DATA;
>-
>-    llLowestTimestamp = 0;
>-    llHighestTimestamp = 0;
>-    ulNumBytes = 0;
>-    bDone = FALSE;
>-
>-    STREAM_INFO* pStreamInfo;
>-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& 
>)pStreamInfo))
>-    {
>-       HXBufferingState& bufState = pStreamInfo->BufferingState();
>-       BOOL   bUseTransportStats = FALSE;
>-
>-       INT64  llTransportLowTS = 0;
>-       INT64  llTransportHighTS = 0;
>-       UINT32 ulTransportBytes = 0;
>-       BOOL   bTransportDone = FALSE;
>-
>-       if (!IsLocalSource() &&
>-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
>-                                          llTransportLowTS,
>-                                          llTransportHighTS,
>-                                          ulTransportBytes,
>-                                          bTransportDone)))
>-       {
>-           bufState.UpdateTransportStats(llTransportLowTS,
>-                                         llTransportHighTS,
>-                                         ulTransportBytes,
>-                                         bTransportDone);
>-
>-           bUseTransportStats = TRUE;
>-
>-           // Update bDone with what the transport says.
>-           bDone = bTransportDone;
>-       }
>-
>-       res = bufState.GetBufferingStats(llLowestTimestamp,
>-                                       llHighestTimestamp,
>-                                       ulNumBytes,
>-                                       bUseTransportStats);
>-    }
>-
>-
>-    return res;
>-}
>-
>  /*
>   * IHXClientRateAdaptControl Methods
>   */
>@@ -2948,13 +2905,34 @@
>  {
>      HX_RESULT res = HXR_OK;
>
>-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
>-         i != mStreamInfoTable->End(); ++i)
>-    {
>-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
>-
>-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
>+    // Convert presentation time to transport time
>+    if (m_pTransOnTimeSync)
>+    {
>+        ULONG32 ulOffset = m_ulDelay;
>+        ULONG32 ulTransportTime = m_ulStartTime;
>+
>+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
>+        {
>+            ulTransportTime += ulCurrentTime - ulOffset;
>+        }
>+
>+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
>      }
>
>      return res;
>+}
>+
>+void
>+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
>+{
>+    HX_RELEASE(m_pSrcBufStats);
>+    HX_RELEASE(m_pTransOnTimeSync);
>+
>+    if (pSrcBufStats)
>+    {
>+        m_pSrcBufStats = pSrcBufStats;
>+        m_pSrcBufStats->AddRef();
>+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
>+                                       (void**)&m_pTransOnTimeSync);
>+    }
>  }
>Index: rtspprotocol.cpp
>===================================================================
>RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
>retrieving revision 1.39
>diff -u -r1.39 rtspprotocol.cpp
>--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
>+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
>@@ -2626,12 +2626,12 @@
>      UINT16 seekFrom
>  )
>  {
>+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
>+
>      if (IsLive())
>      {
>-        return m_pProtocolLib->SeekFlush();
>+        return theErr;
>      }
>-
>-    HX_RESULT theErr = HXR_OK;
>
>      m_uCurrentStreamCount = m_uStreamCount;
>
>
>Index: Umakefil
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/Umakefil,v
>retrieving revision 1.9.2.1
>diff -u -r1.9.2.1 Umakefil
>--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
>+++ Umakefil    22 Jun 2004 22:52:32 -0000
>@@ -46,6 +46,7 @@
>                           'common/runtime/pub',
>                           'common/lang/xml/pub',
>                           'client/common/container/pub',
>+                          'client/common/util/pub',
>                           'protocol/transport/rtp/include',
>                           'server/include',
>                            'server/common/struct/pub',
>@@ -65,7 +66,7 @@
>                    'rtspmsg.cpp', 'rtspmdsc.cpp',
>                    'rtsppars.cpp', 'mhprop.cpp',
>                    'servrsnd.cpp', '3gpadapthdr.cpp',
>-                   'rateadaptinfo.cpp')
>+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
>
>  if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
>      project.AddSources('pipelinedesc.cpp')
>Index: rtspclnt.cpp
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
>retrieving revision 1.79.2.1
>diff -u -r1.79.2.1 rtspclnt.cpp
>--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
>+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
>@@ -95,6 +95,7 @@
>  #include "pipelinedesc.h"
>  #include "errdbg.h"
>  #include "rateadaptinfo.h"
>+#include "ntsrcbufstats.h"
>
>  #include "hxheap.h"
>  #ifdef _DEBUG
>@@ -302,6 +303,12 @@
>      {
>          return HXR_OK;
>      }
>+    else if (m_pSrcBufStats &&
>+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
>+                                                       ppvObj)))
>+    {
>+        return HXR_OK;
>+    }
>      *ppvObj = NULL;
>      return HXR_NOINTERFACE;
>  }
>@@ -388,6 +395,7 @@
>      m_bReportedSuccessfulTransport(FALSE),
>      m_bSDPInitiated(FALSE),
>      m_bMulticast(FALSE),
>+    m_bIsLive(FALSE),
>      m_pSDPFileHeader(NULL),
>      m_pSDPStreamHeaders(NULL),
>      m_bSessionSucceeded(FALSE),
>@@ -404,7 +412,8 @@
>      m_ulCurrentTimeOut(0),
>      m_pUAProfURI(NULL),
>      m_pUAProfDiff(NULL),
>-    m_pRateAdaptInfo(NULL)
>+    m_pRateAdaptInfo(NULL),
>+    m_pSrcBufStats(NULL)
>  #if defined(_MACINTOSH)
>      , m_pCallback(NULL)
>  #endif /* _MACINTOSH */
>@@ -460,6 +469,8 @@
>          m_pRateAdaptInfo->Close();
>          HX_DELETE(m_pRateAdaptInfo);
>      }
>+
>+    HX_RELEASE(m_pSrcBufStats);
>  }
>
>  /*
>@@ -810,6 +821,21 @@
>          }
>      }
>
>+    if (HXR_OK == hresult)
>+    {
>+        HX_RELEASE(m_pSrcBufStats);
>+        m_pSrcBufStats = new HXNetSourceBufStats(this);
>+
>+        if (m_pSrcBufStats)
>+        {
>+            m_pSrcBufStats->AddRef();
>+        }
>+        else
>+        {
>+            hresult = HXR_OUTOFMEMORY;
>+        }
>+    }
>+
>  #if defined(_MACINTOSH)
>      if (m_pCallback &&
>          m_pCallback->m_bIsCallbackPending &&
>@@ -2191,7 +2217,14 @@
>          (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
>      if (pTrans)
>      {
>-        rc = pTrans->getPacket(uStreamNumber, pPacket);
>+        UINT32 uSeqNum;
>+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
>+
>+        if ((HXR_OK == rc) && m_pSrcBufStats &&
>+            (!pPacket->IsLost()))
>+        {
>+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
>+        }
>      }
>
>      m_pMutex->Unlock();
>@@ -3291,16 +3324,24 @@
>      HX_RESULT rc = HXR_OK;
>      m_pMutex->Lock();
>
>-    CHXMapLongToObj::Iterator i;
>-    for(i=m_pTransportStreamMap->Begin();
>-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
>+    if (m_bIsLive)
>      {
>-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
>-        UINT16 streamNumber = (UINT16)i.get_key();
>-
>-        HX_ASSERT(pTransport);
>+        CHXMapLongToObj::Iterator i;
>+        for(i=m_pTransportStreamMap->Begin();
>+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
>+        {
>+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
>+            UINT16 streamNumber = (UINT16)i.get_key();
>+
>+            HX_ASSERT(pTransport);
>+
>+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
>+        }
>+    }
>
>-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->Reset();
>      }
>
>      m_pMutex->Unlock();
>@@ -6964,6 +7005,11 @@
>          // Get session level RTP bandwidth modifiers
>          ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
>          ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
>+
>+        if (ulIsSessionLive)
>+        {
>+            m_bIsLive = TRUE;
>+        }
>
>          // get multicast address from the session description
>          if (HXR_OK == 
> ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
>@@ -7187,6 +7233,11 @@
>              pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
>              pInfo->m_bRealMedia = bRealMedia;
>
>+            if (m_pSrcBufStats)
>+            {
>+                m_pSrcBufStats->Init((UINT16)streamNumber, pInfo->m_bIsLive);
>+            }
>+
>              if (m_pRateAdaptInfo)
>              {
>                  m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
>@@ -7222,6 +7273,7 @@
>          if (m_bMulticast)
>          {
>              m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
>+            m_bIsLive = TRUE;
>          }
>      }
>
>Index: pub/rtspclnt.h
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
>retrieving revision 1.30.2.1
>diff -u -r1.30.2.1 rtspclnt.h
>--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
>+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
>@@ -46,6 +46,7 @@
>  #include "hxbufctl.h" // IHXTransportBufferLimit
>  #include "hxrtsp2.h"
>  #include "hxrsdbf.h" // IHXResendBufferControl
>+#include "hxprefs.h" // IHXPreferences
>
>  class RTSPClientState;
>  class RTSPOptionsMessage;
>@@ -63,6 +64,7 @@
>  class MIMEHeader;
>  class PipelinedDescribeLogic;
>  class CHXRateAdaptationInfo;
>+class HXNetSourceBufStats;
>
>  struct IHXKeyValueList;
>  struct IHXValues;
>@@ -1039,6 +1041,7 @@
>
>      BOOL                                m_bSDPInitiated;
>      BOOL                                m_bMulticast;
>+    BOOL                                m_bIsLive;
>      IHXValues*                          m_pSDPFileHeader;
>      CHXSimpleList*                      m_pSDPStreamHeaders;
>
>@@ -1074,6 +1077,7 @@
>      UINT32                              m_ulServerTimeOut;
>      UINT32                              m_ulCurrentTimeOut;
>      CHXRateAdaptationInfo*              m_pRateAdaptInfo;
>+    HXNetSourceBufStats*                m_pSrcBufStats;
>
>  #if defined(_MACINTOSH)
>      RTSPClientProtocolCallback*                m_pCallback;
>
>Index: rtsptran.cpp
>===================================================================
>RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
>retrieving revision 1.26
>diff -u -r1.26 rtsptran.cpp
>--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
>+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
>@@ -526,8 +526,17 @@
>      }
>  }
>
>+HX_RESULT
>+RTSPTransport::getPacket(UINT16 uStreamNumber,
>+                         IHXPacket*& pPacket)
>+{
>+    UINT32 uSeqNum;
>+    return getPacket(uStreamNumber, pPacket, uSeqNum);
>+}
>+
>  HX_RESULT
>-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
>+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
>+                         REF(UINT32) uSeqNum)
>  {
>      RTSPTransportBuffer* pTransportBuffer = 
> getTransportBuffer(uStreamNumber);
>      RTSPStreamData* pStreamData = 
> m_pStreamHandler->getStreamData(uStreamNumber);
>@@ -547,6 +556,7 @@
>      }
>
>      pPacket = clientPacket->GetPacket();
>+    uSeqNum = clientPacket->GetSequenceNumber();
>
>      if (!pPacket)
>      {
>Index: pub/rtsptran.h
>===================================================================
>RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
>retrieving revision 1.19
>diff -u -r1.19 rtsptran.h
>--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
>+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
>@@ -259,6 +259,9 @@
>      HX_RESULT resetFlags               (UINT16 streamNumber);
>      HX_RESULT getPacket                        (UINT16 uStreamNumber,
>                                         IHXPacket*& pPacket);
>+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
>+                                       IHXPacket*& pPacket,
>+                                         REF(UINT32) uSeqNum);
>      virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
>      virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
>
>Index: Umakefil
>===================================================================
>RCS file: /cvsroot/client/common/util/Umakefil,v
>retrieving revision 1.3
>diff -u -r1.3 Umakefil
>--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
>+++ Umakefil    22 Jun 2004 22:53:43 -0000
>@@ -53,6 +53,7 @@
>                    'chxphook.cpp',
>                    'xnetchck.cpp',
>                    'littobig.cpp',
>-                  'hxunicod.cpp')
>+                  'hxunicod.cpp',
>+                   'hxsrcbufstats.cpp')
>
>  LibraryTarget('utlclntlib')
>Index: hxcore.h
>===================================================================
>RCS file: /cvsroot/common/include/hxcore.h,v
>retrieving revision 1.5
>diff -u -r1.5 hxcore.h
>--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
>+++ hxcore.h    22 Jun 2004 23:00:23 -0000
>@@ -2060,7 +2060,50 @@
>
>  // $EndPrivate.
>
>+// $Private:
>
>+/****************************************************************************
>+ *
>+ *  Interface:
>+ *
>+ *     IID_IHXTransportOnTimeSync
>+ *
>+ *  Purpose:
>+ *
>+ *     This interface is used to send OnTimeSync() calls down
>+ *      to the transport layer. Note that the value passed to
>+ *      OnTimeSync() MUST be in the same units and have the same
>+ *      offset as the packets coming from the transport. This means
>+ *      that any offets caused by SMIL or live playback must be
>+ *      removed before calling OnTimeSync() on this interface
>+ *
>+ *      IID_IHXTransportOnTimeSync
>+ *
>+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
>+ *
>+ */
>+DEFINE_GUID(IID_IHXTransportOnTimeSync,
>+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1);
>+
>+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
>+{
>+    /*
>+     * IUnknown methods
>+     */
>+
>+    STDMETHOD(QueryInterface)  (THIS_
>+                               REFIID riid,
>+                               void** ppvObj) PURE;
>+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
>+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
>+
>+    /*
>+     * IHXTransportOnTimeSync methods
>+     */
>+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
>+};
>+
>+// $EndPrivate.
>
>  #endif /* _HXCORE_H_ */
>
>Index: hxpiids.h
>===================================================================
>RCS file: /cvsroot/common/include/hxpiids.h,v
>retrieving revision 1.28.2.1
>diff -u -r1.28.2.1 hxpiids.h
>--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
>+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
>@@ -533,6 +533,7 @@
>  DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 
> 0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
>  DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 
> 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
>  DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 
> 0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 
> 0xa9,  0x69,  0x37,  0x3b,  0x4d)
>+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 
>0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
>  #endif /* _HXCORE_H_ */
>
>  /*
>
>
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From ehyche at real.com  Wed Jun 23 07:06:41 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 23 07:06:50 2004
Subject: [Common-dev] LC_CLIENT_LEVEL* problems
In-Reply-To: <5.1.0.14.2.20040623092522.02bead80@mailone.real.com>
References: <40D92A44.6000700@real.com>
Message-ID: <5.1.0.14.2.20040623100620.02bead80@mailone.real.com>


Ryan,

This should be fixed now. Just update
hxtwritermanager.cpp.

Eric

At 09:28 AM 6/23/2004 -0400, Eric Hyche wrote:


>At 11:59 PM 6/22/2004 -0700, Ryan Gammon wrote:
>>Hi all,
>>
>>I'm having problems using producer's logging mechanism in the client.
>>
>>Line 113 of hxtwritermanager.cpp reads:
>>
>>    // If the message is a dev-level message, and they aren't allowed, 
>> reject the log request
>>    if( szNamespace && 0 == strcmp(szNamespace, "RealNetworks") && (0x01 
>> & nLogCode) && !m_bAllowRNLevelMsgs )
>>    {
>>        return HXR_FAIL;
>>    }
>>
>>
>>There are two potential issues here:
>>- Is this a good place for error messages to be getting rejected? (maybe 
>>this should be in the log observer filtering?)
>>- The nLogCode for client is one of the following:
>>
>>    // Client-related log codes
>>    LC_CLIENT_LEVEL1 = 0x00000001,
>>    LC_CLIENT_LEVEL2 = 0x00000002,
>>    LC_CLIENT_LEVEL3 = 0x00000004,
>>    LC_CLIENT_LEVEL4 = 0x00000008
>>
>>hxtwritermanager seems to be assuming that the bottom bit is used to 
>>discriminate between dev and non-dev messages. This makes level 1 errors 
>>dev messages, and the rest non-dev. Default behavior seems to be to not 
>>log dev messages (unless one creates an empty debug.txt file), which 
>>leads to odd logging behavior.
>>
>>I think either the level values might have to change here, or the 
>>hxtwritermanager code above has to be modified to not recognize 
>>LC_CLIENT_LEVEL1 as a dev message.
>
>Ryan,
>
>I *thought* that I put both of these sections of code behind
>producer-specific defines, but looking through the file, it
>looks like I neglected to do that. I'll fix that.
>
>Eric
>
>>Am I missing something?
>>
>>_______________________________________________
>>Common-dev mailing list
>>Common-dev@lists.helixcommunity.org
>>http://lists.helixcommunity.org/mailman/listinfo/common-dev
>
>======================================
>M. Eric Hyche (ehyche@real.com)
>Core Technologies
>RealNetworks, Inc.
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From acolwell at real.com  Wed Jun 23 09:48:25 2004
From: acolwell at real.com (Aaron Colwell)
Date: Wed Jun 23 09:50:19 2004
Subject: [Common-dev] CR-Client: Moving IHXSourceBufferingStats2
	implementation
In-Reply-To: <5.1.0.14.2.20040623095240.02bead80@mailone.real.com>
References: <20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623095240.02bead80@mailone.real.com>
Message-ID: <20040623164825.GB7758@real.com>

On Wed, Jun 23, 2004 at 09:55:46AM -0400, Eric Hyche wrote:
> 
> This is a pretty complicated change, so I doubt I'm
> hitting any of the subtleties, but after a cursory examination,
> these changes look good to me.

Thanks for taking a look. This is basically just moving code from one place to
another, but the diffs don't show that the call flow is basically equivalent.

> 
> Just wondering though, why do we need the
> 
> >+// $Private:
> 
> and
> 
> >+// $EndPrivate.

I just put them in there because I noticed them around other "private" 
interfaces. I just wanted to mark this interface as something that the general
public shouldn't use because it could cause "bad things" to happen.

Perhaps hxcore.h isn't the right place for this interface. Any suggestions?

> 
> around the new interface definition? Seems like since
> hxcore.h is out in the public anyway, that our
> Private/EndPrivate stuff is moot.
> 
> I'm not suggesting we go through and remove them from
> all header files, but it seems to me we shouldn't be
> adding any *more* of them.
> 
> Eric
> 
> At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
> >Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> >          number information can be maintained as well.
> >
> >Overview: These changes move the IHXSourceBufferingStats2 implementation
> >          out of HXBufferingState and into a new class called
> >          HXSourceBufferStats. This was done because the client needs to
> >          track packet sequence numbers for 3GPP-Rel6 OBSN support.
> >          There was no good way to get the sequence number information to
> >          the HXBufferingState class so the IHXSourceBufferingStats2 logic
> >          was moved to where this information is available.
> >
> >          A new interface called IHXTransportOnTimeSync was created to
> >          propagate OnTimeSync() like calls to HXSourceBufferStats. The
> >          time passed to the OnTimeSync() call in this interface MUST
> >          NOT have any offsets created by SMIL or live playback. The time
> >          should be in the same time frame as the packets coming from the
> >          transport. If someone wants to rename this interface that is fine
> >          by me.
> >
> >
> >          - Created HXSourceBufferStats to contain the base
> >            IHXSourceBufferingStats2 implementation. This class is
> >            used by HXFileSource.
> >
> >          - Created HXNetSourceBufStats which derives from 
> >HXSourceBufferStats.
> >            This class just overloads the GetCurrentBuffering() so that it
> >            returns the amount of data in the transport buffer. This is
> >            used by RTSPClientProtocol.
> >
> >          - Removed IHXSourceBufferingStats2 code from HXSource
> >
> >          - Removed packet tracking code from HXBufferingState. This
> >            functionality is implemented by HXSourceBufferStats now
> >
> >          - Added code to HXSource to provide OnTimeSync() calls to the
> >            IHXTransportOnTimeSync interface.
> >
> >          - HXSource now exposes IHXSourceBufferingStats functionality 
> >through
> >            it's m_pSrcBufStats member variable instead of implementing it
> >            itself. The file and network sources are expected to provide an
> >            IHXSourceBufferingStats2 interface via a
> >            HXSource::SetSrcBufStats() call.
> >
> >          - Added code to HXFileSource to use HXSourceBufferStats
> >
> >          - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> >
> >          - Fixed some code in CBufferManager that was expecting HXSource
> >            to implement IHXSourceBufferingStats. This code now QI's for
> >            IHXSourceBufferingStats and uses that interface.
> >
> >
> >
> >Files Modified:
> >client/core/buffmgr.cpp
> >client/core/hxbsrc.h
> >client/core/hxbufstate.h
> >client/core/hxbufstate.cpp
> >client/core/hxflsrc.cpp
> >client/core/hxflsrc.h
> >client/core/hxntsrc.cpp
> >client/core/hxntsrc.h
> >client/core/hxsrc.cpp
> >client/core/rtspprotocol.cpp
> >protocol/rtsp/Umakefil
> >protocol/rtsp/rtspclnt.cpp
> >protocol/rtsp/pub/rtspclnt.h
> >protocol/transport/common/system/rtsptran.cpp
> >protocol/transport/common/system/pub/rtsptran.h
> >client/common/util/Umakefil
> >common/include/hxcore.h
> >common/include/hxpiids.h
> >
> >Files Added:
> >client/common/util/pub/hxsrcbufstats.h
> >client/common/util/hxsrcbufstats.cpp
> >protocol/rtsp/ntsrcbufstats.h
> >protocol/rtsp/ntsrcbufstats.cpp
> >
> >Image Size and Heap Use impact:
> >
> >Platforms and Profiles affected: all
> >
> >Distribution Libraries affected: rdtclntlib
> >
> >Distribution library impact and planned action:
> >m_bIsLive and m_pSrcBufStats member variables were added to
> >RTSPClientProtocol so any derived objects will need to be
> >recompiled
> >
> >Platforms and Profiles Build Verified: win32
> >
> >Platforms and Profiles Functionality verified: win32
> >
> >Branch: HEAD
> >
> >QA Instructions: none
> >
> >Index: buffmgr.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/buffmgr.cpp,v
> >retrieving revision 1.21
> >diff -u -r1.21 buffmgr.cpp
> >--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
> >+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> >@@ -610,6 +610,11 @@
> >      * - Keep track of the stream with the lowest timestamp and is
> >      *   buffering data
> >      */
> >+    IHXSourceBufferingStats* pSrcBufStats = NULL;
> >+
> >+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> >+                              (void**)&pSrcBufStats);
> >+
> >     for (i = m_pStreamInfoTable->Begin(); i != 
> >m_pStreamInfoTable->End(); ++i)
> >     {
> >        pStreamInfo = (STREAM_INFO*) (*i);
> >@@ -619,12 +624,15 @@
> >        ULONG32 ulNumBytesAtTransport = 0;
> >        BOOL bDoneAtTransport = FALSE;
> >
> >-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> >-                                      llLowestTimestampAtTransport,
> >-                                      llHighestTimestampAtTransport,
> >-                                      ulNumBytesAtTransport,
> >-                                      bDoneAtTransport);
> >-
> >+        if (pSrcBufStats)
> >+        {
> >+            
> >pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> >+                                              
> >llLowestTimestampAtTransport,
> >+                                              
> >llHighestTimestampAtTransport,
> >+                                              ulNumBytesAtTransport,
> >+                                              bDoneAtTransport);
> >+        }
> >+
> >        pStreamInfo->BufferingState().UpdateTransportStats(
> >            llLowestTimestampAtTransport,
> >            llHighestTimestampAtTransport,
> >@@ -658,6 +666,7 @@
> >
> >        }
> >     }
> >+    HX_RELEASE(pSrcBufStats);
> >
> >     /* If none of the streams have any data buffered at the transport 
> >     layer,
> >      * return.
> >Index: hxbsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbsrc.h,v
> >retrieving revision 1.18.2.1
> >diff -u -r1.18.2.1 hxbsrc.h
> >--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
> >+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
> >@@ -233,12 +233,11 @@
> >                  public IHXPrivateStreamSource,
> >                  public IHXBackChannel,
> >                  public IHXASMSource,
> >-                  public IHXClientRateAdaptControl,
> >+                  public IHXClientRateAdaptControl
> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >-                 public IHXHyperNavigate,
> >-                 public IHXHyperNavigate2,
> >+                 , public IHXHyperNavigate,
> >+                 public IHXHyperNavigate2
> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >-                  public IHXSourceBufferingStats2
> > {
> > protected:
> >     LONG32                     m_lRefCount;
> >@@ -487,35 +486,6 @@
> >                            IHXValues* pParams);
> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >
> >-    
> >/************************************************************************
> >-     * Method:
> >-     *     IHXSourceBufferingStats2::GetCurrentBuffering
> >-     * Purpose:
> >-     *     Get the current buffering information
> >-     */
> >-
> >-    STDMETHOD(GetCurrentBuffering) (THIS_
> >-                                    UINT16  uStreamNumber,
> >-                                    REF(INT64)  llLowestTimestamp,
> >-                                    REF(INT64)  llHighestTimestamp,
> >-                                    REF(UINT32) ulNumBytes,
> >-                                    REF(BOOL)   bDone) PURE;
> >-    
> >/************************************************************************
> >-     * Method:
> >-     *     IHXSourceBufferingStats2::GetTotalBuffering
> >-     * Purpose:
> >-     *     Get the total amount of data buffered for a stream.
> >-     *      This includes what is in the transport buffer and in
> >-     *      the renderer
> >-     */
> >-
> >-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> >-                                  REF(INT64)  llLowestTimestamp,
> >-                                  REF(INT64)  llHighestTimestamp,
> >-                                  REF(UINT32) ulNumBytes,
> >-                                  REF(BOOL)   bDone);
> >-
> >-
> >     /*
> >      * IHXClientRateAdaptControl Methods
> >      */
> >@@ -731,7 +701,7 @@
> >            virtual HX_RESULT   FillRecordControl() = 0;
> >                    BOOL        IsPlayingFromRecordControl() { return 
> >m_bPlayFromRecordControl; };
> >
> >-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >
> >             const char*         GetRedirectURL() { return 
> >(m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
> >             const char*         GetSDPURL() { return (m_pSDPURL ? 
> >m_pSDPURL->GetURL() : NULL); };
> >@@ -769,6 +739,8 @@
> >             void        ProcessFileHeader(void);
> >             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, 
> >STREAM_INFO*& pStreamInfo);
> >
> >+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> >+
> >     HX_RESULT                  mLastError;
> >     CHXMapLongToObj*            mStreamInfoTable;
> >
> >@@ -868,6 +840,8 @@
> >     CHXURL*                     m_pRedirectURL;
> >     CHXURL*                     m_pSDPURL;
> >     BOOL                        m_bRedirectPending;
> >+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> >+    IHXSourceBufferingStats2*   m_pSrcBufStats;
> > };
> >
> > // Defined flags
> >Index: hxbufstate.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> >retrieving revision 1.7
> >diff -u -r1.7 hxbufstate.cpp
> >--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
> >+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
> >@@ -83,18 +83,11 @@
> >     , m_ulLastPacketTimeStamp(0)
> >     , m_ulAvgBandwidth(0)
> >     , m_pASMProps(NULL)
> >-    , m_llCurrentPlaybackTime(0)
> >-    , m_ulBufferedData(0)
> >-    , m_ulLastTimeSync(0)
> >-    , m_llFirstLivePacketTimestamp(0)
> >-    , m_ulTimeSyncRollOver(0)
> > {}
> >
> > HXBufferingState::~HXBufferingState()
> > {
> >     HX_RELEASE(m_pASMProps);
> >-
> >-    ClearPktInfo();
> > }
> >
> > void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> >@@ -179,8 +172,6 @@
> >     m_ulLastPacketTimeStamp = 0;
> >     m_bIsFirstPacket = TRUE;
> >
> >-    ClearPktInfo();
> >-
> >     if (bIsSeeking)
> >     {
> >        m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> >@@ -288,11 +279,6 @@
> >     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + 
> >CAST_TO_INT64 ulTime;
> > }
> >
> >-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> >-{
> >-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 
> >MAX_UINT32 + CAST_TO_INT64 ulTime;
> >-}
> >-
> > void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> >                                UINT32 ulElapsedTime,
> >                                BOOL bIsLive, BOOL bIsBufferedPlayMode)
> >@@ -318,16 +304,12 @@
> >        if (bIsLive)
> >        {
> >            m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
> >         }
> >
> >        m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >        m_bIsFirstPacket = FALSE;
> >     }
> >
> >-    // Add this packet to our packet info statistics
> >-    AddPktInfo(llActualTimeStamp, ulPacketSize);
> >-
> >     // data based preroll
> >     if (DataBasedPreroll())
> >     {
> >@@ -451,47 +433,6 @@
> >     m_bDoneAtTransport = bDoneAtTransport;
> > }
> >
> >-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
> >-                                             REF(INT64) llHighTimestamp,
> >-                                             REF(UINT32) ulBytesBuffered,
> >-                                             BOOL bUseTransportStats)
> >-{
> >-    HX_RESULT res = HXR_NO_DATA;
> >-
> >-    if (!m_bIsFirstPacket)
> >-    {
> >-       if (!m_pktInfo.IsEmpty())
> >-       {
> >-           HXBufferedPktInfo* pPktInfo =
> >-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
> >-
> >-           llLowTimestamp = pPktInfo->Timestamp();
> >-       }
> >-       else
> >-       {
> >-           llLowTimestamp = m_llHighestTimeStamp;
> >-       }
> >-
> >-       llHighTimestamp = m_llHighestTimeStamp;
> >-       ulBytesBuffered = GetBufferedData();
> >-
> >-
> >-       if (bUseTransportStats)
> >-       {
> >-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
> >-           {
> >-               llHighTimestamp = m_llHighestTimestampAtTransport;
> >-           }
> >-
> >-           ulBytesBuffered += m_ulNumBytesAtTransport;
> >-       }
> >-
> >-       res = HXR_OK;
> >-    }
> >-
> >-    return res;
> >-}
> >-
> > void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
> >                                           INT64 llTheHighestTS,
> >                                           BOOL bIsSeekPerformed,
> >@@ -569,19 +510,6 @@
> >
> > }
> >
> >-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> >-{
> >-    //  0xFA .. 0xFF [roll over] (0x01)
> >-    if (m_ulLastTimeSync > ulCurrentTime &&
> >-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> >-    {
> >-       m_ulTimeSyncRollOver++;
> >-    }
> >-    m_ulLastTimeSync = ulCurrentTime;
> >-
> >-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> >-}
> >-
> > void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
> >                                        ULONG32 ulMinBufferingInMs)
> > {
> >@@ -771,62 +699,4 @@
> >     {
> >        m_ulAvgBandwidth = ulBandwidth;
> >     }
> >-}
> >-
> >-void HXBufferingState::ClearPktInfo()
> >-{
> >-    m_ulBufferedData = 0;
> >-    while(!m_pktInfo.IsEmpty())
> >-    {
> >-       HXBufferedPktInfo* pInfo = 
> >(HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> >-       delete pInfo;
> >-    }
> >-}
> >-
> >-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
> >-{
> >-    // Subtract off the first live packet timestamp.
> >-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> >-    llTimestamp -= m_llFirstLivePacketTimestamp;
> >-    // Create the HXBufferedPktInfo class
> >-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
> >-                                                       ulPacketSize);
> >-    if (pPktInfo)
> >-    {
> >-       m_pktInfo.AddTail(pPktInfo);
> >-       m_ulBufferedData += ulPacketSize;
> >-    }
> >-
> >-    // purge the old packet info data
> >-    //  this keeps the list short and prevents the Symbian
> >-    //  allocator from freaking out
> >-    (void)GetBufferedData();
> >-}
> >-
> >-UINT32 HXBufferingState::GetBufferedData()
> >-{
> >-    BOOL bDone = m_pktInfo.IsEmpty();
> >-
> >-    // Remove all packet info that is past due
> >-    // and subtract their sizes from our buffering total
> >-    while(!bDone)
> >-    {
> >-       HXBufferedPktInfo* pPktInfo = 
> >(HXBufferedPktInfo*)m_pktInfo.GetHead();
> >-
> >-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> >-       {
> >-           m_ulBufferedData -= pPktInfo->Size();
> >-
> >-           m_pktInfo.RemoveHead();
> >-           delete pPktInfo;
> >-
> >-           bDone = m_pktInfo.IsEmpty();
> >-       }
> >-       else
> >-       {
> >-           bDone = TRUE;
> >-       }
> >-    }
> >-
> >-    return m_ulBufferedData;
> > }
> >Index: hxbufstate.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbufstate.h,v
> >retrieving revision 1.4
> >diff -u -r1.4 hxbufstate.h
> >--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
> >+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
> >@@ -81,7 +81,6 @@
> >     BOOL HasPredata(BOOL bIsSeekPerformed);
> >
> >     INT64 CreateINT64Timestamp(UINT32 ulTime);
> >-    INT64 CreateINT64Timesync(UINT32 ulTime);
> >
> >     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> >                  UINT32 ulElapsedTime, BOOL bIsLive,
> >@@ -98,11 +97,6 @@
> >                              ULONG32 ulBytesAtTransport,
> >                              BOOL bDoneAtTransport);
> >
> >-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
> >-                               REF(INT64) llHighTimestamp,
> >-                               REF(UINT32) ulBytesBuffered,
> >-                               BOOL bUseTransportStats);
> >-
> >     void GetExcessBufferInfo(INT64 llTheLowestTS,
> >                             INT64 llTheHighestTS,
> >                             BOOL bIsSeekPerformed,
> >@@ -119,8 +113,6 @@
> >
> >     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
> >
> >-    void OnTimeSync(UINT32 ulCurrentTime);
> >-
> >     // Should remove
> >     void SetAvgBWToASMBw();
> >     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> >@@ -149,19 +141,6 @@
> >                        UINT32 ulCurrentBuffering,
> >                        UINT32 ulMinimumPreroll,
> >                        UINT32 ulDenom) const;
> >-
> >-    /* Functions for tracking the amount of data
> >-     * buffered in the renderer
> >-     */
> >-    void ClearPktInfo(); /* Clears out information about buffered packets 
> >*/
> >-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called 
> >when
> >-                                                             * a packet is
> >-                                                             * sent to the
> >-                                                             * renderer
> >-                                                             */
> >-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
> >-                              * in the renderer
> >-                              */
> >
> >     ULONG32            m_ulPreroll;
> >     ULONG32            m_ulPredata;
> >@@ -196,20 +175,6 @@
> >     ULONG32            m_ulLastPacketTimeStamp;
> >     ULONG32            m_ulAvgBandwidth;
> >     IHXASMProps*       m_pASMProps;
> >-    UINT32              m_ulLastTimeSync;
> >-    INT64               m_llFirstLivePacketTimestamp;
> >-    UINT32              m_ulTimeSyncRollOver;
> >-    // These variable keep track of the amount of
> >-    // data buffered in the renderer
> >-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
> >-                                                 * OnTimeSync() call
> >-                                                 */
> >-
> >-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> >-                                          * Always use GetBufferedData()
> >-                                          * to retreive the value
> >-                                          */
> >-    CHXSimpleList       m_pktInfo; /* List of packet information */
> > };
> >
> > inline
> >Index: hxflsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> >retrieving revision 1.54
> >diff -u -r1.54 hxflsrc.cpp
> >--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
> >+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> >@@ -76,6 +76,7 @@
> > #include "uri_schemes.h"
> > #include "stream_desc_hlpr.h"
> > #include "findfile.h"
> >+#include "hxsrcbufstats.h"
> >
> > #include "hxheap.h"
> > #ifdef _DEBUG
> >@@ -115,6 +116,7 @@
> >     , m_bValidateMetaDone(FALSE)
> >     , m_pFileRecognizer(NULL)
> >     , m_pFileReader(NULL)
> >+    , m_pSrcBufStats(NULL)
> > {
> >     m_bAltURL = FALSE;
> >     m_bPerfectPlay = TRUE;
> >@@ -306,6 +308,13 @@
> >
> >     HX_VECTOR_DELETE(m_pszURL);
> >     HX_DELETE(m_pURL);
> >+
> >+    HX_RELEASE(m_pSrcBufStats);
> >+    m_pSrcBufStats = new HXSourceBufferStats();
> >+    if (m_pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats->AddRef();
> >+    }
> >
> >     if (!theErr && pURL)
> >     {
> >@@ -938,6 +947,7 @@
> >     }
> > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
> >
> >+    HX_RELEASE(m_pSrcBufStats);
> >     HXSource::DoCleanup();
> >
> >     return HXR_OK;
> >@@ -1068,6 +1078,11 @@
> >
> >     m_llLastFillEndTime = 0;
> >
> >+    if (m_pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats->Reset();
> >+    }
> >+
> > cleanup:
> >
> >     return HXR_OK;
> >@@ -1442,6 +1457,11 @@
> >
> >            if(m_pBufferManager)
> >                m_pBufferManager->UpdateCounters(pPacket, 0);
> >+
> >+            if (m_pSrcBufStats && !pPacket->IsLost())
> >+            {
> >+                m_pSrcBufStats->OnPacket(pPacket);
> >+            }
> >
> >            HX_RELEASE(pPacket);
> >        }
> >@@ -2103,6 +2123,13 @@
> >        }
> >        HX_RELEASE(pszParentName);
> > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> >+
> >+        if (pStreamInfo && m_pSrcBufStats)
> >+        {
> >+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> >+                                 mLiveStream);
> >+        }
> >+
> >         m_ulStreamIndex++;
> >         m_uNumStreams++;
> >     }
> >@@ -2115,6 +2142,11 @@
> >
> >        theErr = AdjustClipTime();
> >        m_pBufferManager->Init();
> >+
> >+        if (m_pSrcBufStats)
> >+        {
> >+            SetSrcBufStats(m_pSrcBufStats);
> >+        }
> >     }
> >
> >     return theErr;
> >@@ -2313,6 +2345,11 @@
> >        {
> >            m_pBufferManager->UpdateCounters(pPacket, 0);
> >        }
> >+
> >+        if (m_pSrcBufStats && !pPacket->IsLost())
> >+        {
> >+            m_pSrcBufStats->OnPacket(pPacket);
> >+        }
> >     }
> >
> >     m_llLastFillEndTime = llActualPacketTime;
> >Index: hxflsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxflsrc.h,v
> >retrieving revision 1.12
> >diff -u -r1.12 hxflsrc.h
> >--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
> >+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
> >@@ -52,6 +52,8 @@
> > #include "hxfiles.h"
> > #include "recognizer.h"
> >
> >+class HXSourceBufferStats;
> >+
> > class HXFileSource : public HXSource,
> >                      public IHXFormatResponse,
> >                       public IHXHTTPRedirectResponse
> >@@ -349,6 +351,7 @@
> >
> >     CFileReader*                m_pFileReader;
> >     CHXFileRecognizer*          m_pFileRecognizer;
> >+    HXSourceBufferStats*        m_pSrcBufStats;
> > };
> >
> > #endif // _HX_FILE_SOURCE
> >Index: hxntsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> >retrieving revision 1.90
> >diff -u -r1.90 hxntsrc.cpp
> >--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
> >+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> >@@ -675,6 +675,7 @@
> >     HX_RESULT   rc = HXR_OK;
> >     BOOL        bSDPInitiated = FALSE;
> >     CHXString   pString;
> >+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
> >
> >     // start off with the preferred protocol
> >     rc = CreateProtocol();
> >@@ -722,6 +723,14 @@
> >         goto cleanup;
> >     }
> >
> >+    // Setup source buffer stats
> >+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> >+                                           (void**)&pSrcBufStats))
> >+    {
> >+        SetSrcBufStats(pSrcBufStats);
> >+        HX_RELEASE(pSrcBufStats);
> >+    }
> >+
> >     // create log info list
> >     m_pLogInfoList = new CHXSimpleList;
> >     m_ulLogInfoLength = 0;
> >@@ -6295,6 +6304,12 @@
> > #else
> >     return HXR_NOTIMPL;
> > #endif /* HELIX_FEATURE_RECORDCONTROL */
> >+}
> >+
> >+HX_RESULT
> >+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> >+{
> >+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
> > }
> >
> > ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> >Index: hxntsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxntsrc.h,v
> >retrieving revision 1.24
> >diff -u -r1.24 hxntsrc.h
> >--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
> >+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
> >@@ -282,6 +282,7 @@
> >
> >        virtual HX_RESULT       FillRecordControl();
> >
> >+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > protected:
> >
> >        virtual                         ~HXNetSource(void);
> >@@ -470,7 +471,6 @@
> > private:
> >         IHXBufferControl*                m_pBufferCtl;
> >         IHXWatermarkBufferControl*       m_pWMBufferCtl;
> >-
> > public:
> >        HX_RESULT       FinishSetup();
> >        void            ReSetup();
> >Index: hxsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxsrc.cpp,v
> >retrieving revision 1.44.2.1
> >diff -u -r1.44.2.1 hxsrc.cpp
> >--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
> >+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
> >@@ -213,6 +213,8 @@
> >         , m_pRedirectURL(NULL)
> >         , m_pSDPURL(NULL)
> >         , m_bRedirectPending(FALSE)
> >+        , m_pTransOnTimeSync(NULL)
> >+        , m_pSrcBufStats(NULL)
> > {
> >     mStreamInfoTable = new CHXMapLongToObj;
> > }
> >@@ -313,6 +315,8 @@
> >     HX_DELETE(m_pRedirectURL);
> >     HX_DELETE(m_pSDPURL);
> >     m_bRedirectPending  = FALSE;
> >+    HX_RELEASE(m_pTransOnTimeSync);
> >+    HX_RELEASE(m_pSrcBufStats);
> >
> > #if defined(HELIX_FEATURE_RECORDCONTROL)
> >     if(m_pRecordControl)
> >@@ -340,8 +344,6 @@
> >             { GET_IIDHANDLE(IID_IHXPendingStatus), 
> >(IHXPendingStatus*)this },
> >             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
> >             { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> >(IHXPrivateStreamSource*)this },
> >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
> >(IHXSourceBufferingStats*)this },
> >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
> >(IHXSourceBufferingStats2*)this },
> >             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
> >               (IHXClientRateAdaptControl*)this },
> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >@@ -388,6 +390,14 @@
> >            return HXR_NOINTERFACE;
> >        }
> >     }
> >+    else if (m_pSrcBufStats &&
> >+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> >+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> >+    {
> >+        m_pSrcBufStats->AddRef();
> >+        *ppvObj = m_pSrcBufStats;
> >+        return HXR_OK;
> >+    }
> >
> > #if defined(HELIX_FEATURE_AUTOUPGRADE)
> >     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> >@@ -2250,59 +2260,6 @@
> > }
> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >
> >-STDMETHODIMP
> >-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> >-                           REF(INT64)  llLowestTimestamp,
> >-                           REF(INT64)  llHighestTimestamp,
> >-                           REF(UINT32) ulNumBytes,
> >-                           REF(BOOL)   bDone)
> >-{
> >-    HX_RESULT res = HXR_NO_DATA;
> >-
> >-    llLowestTimestamp = 0;
> >-    llHighestTimestamp = 0;
> >-    ulNumBytes = 0;
> >-    bDone = FALSE;
> >-
> >-    STREAM_INFO* pStreamInfo;
> >-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& 
> >)pStreamInfo))
> >-    {
> >-       HXBufferingState& bufState = pStreamInfo->BufferingState();
> >-       BOOL   bUseTransportStats = FALSE;
> >-
> >-       INT64  llTransportLowTS = 0;
> >-       INT64  llTransportHighTS = 0;
> >-       UINT32 ulTransportBytes = 0;
> >-       BOOL   bTransportDone = FALSE;
> >-
> >-       if (!IsLocalSource() &&
> >-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
> >-                                          llTransportLowTS,
> >-                                          llTransportHighTS,
> >-                                          ulTransportBytes,
> >-                                          bTransportDone)))
> >-       {
> >-           bufState.UpdateTransportStats(llTransportLowTS,
> >-                                         llTransportHighTS,
> >-                                         ulTransportBytes,
> >-                                         bTransportDone);
> >-
> >-           bUseTransportStats = TRUE;
> >-
> >-           // Update bDone with what the transport says.
> >-           bDone = bTransportDone;
> >-       }
> >-
> >-       res = bufState.GetBufferingStats(llLowestTimestamp,
> >-                                       llHighestTimestamp,
> >-                                       ulNumBytes,
> >-                                       bUseTransportStats);
> >-    }
> >-
> >-
> >-    return res;
> >-}
> >-
> > /*
> >  * IHXClientRateAdaptControl Methods
> >  */
> >@@ -2948,13 +2905,34 @@
> > {
> >     HX_RESULT res = HXR_OK;
> >
> >-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> >-         i != mStreamInfoTable->End(); ++i)
> >-    {
> >-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> >-
> >-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> >+    // Convert presentation time to transport time
> >+    if (m_pTransOnTimeSync)
> >+    {
> >+        ULONG32 ulOffset = m_ulDelay;
> >+        ULONG32 ulTransportTime = m_ulStartTime;
> >+
> >+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> >+        {
> >+            ulTransportTime += ulCurrentTime - ulOffset;
> >+        }
> >+
> >+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
> >     }
> >
> >     return res;
> >+}
> >+
> >+void
> >+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> >+{
> >+    HX_RELEASE(m_pSrcBufStats);
> >+    HX_RELEASE(m_pTransOnTimeSync);
> >+
> >+    if (pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats = pSrcBufStats;
> >+        m_pSrcBufStats->AddRef();
> >+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> >+                                       (void**)&m_pTransOnTimeSync);
> >+    }
> > }
> >Index: rtspprotocol.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> >retrieving revision 1.39
> >diff -u -r1.39 rtspprotocol.cpp
> >--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
> >+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
> >@@ -2626,12 +2626,12 @@
> >     UINT16 seekFrom
> > )
> > {
> >+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> >+
> >     if (IsLive())
> >     {
> >-        return m_pProtocolLib->SeekFlush();
> >+        return theErr;
> >     }
> >-
> >-    HX_RESULT theErr = HXR_OK;
> >
> >     m_uCurrentStreamCount = m_uStreamCount;
> >
> >
> >Index: Umakefil
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> >retrieving revision 1.9.2.1
> >diff -u -r1.9.2.1 Umakefil
> >--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
> >+++ Umakefil    22 Jun 2004 22:52:32 -0000
> >@@ -46,6 +46,7 @@
> >                          'common/runtime/pub',
> >                          'common/lang/xml/pub',
> >                          'client/common/container/pub',
> >+                          'client/common/util/pub',
> >                          'protocol/transport/rtp/include',
> >                          'server/include',
> >                           'server/common/struct/pub',
> >@@ -65,7 +66,7 @@
> >                   'rtspmsg.cpp', 'rtspmdsc.cpp',
> >                   'rtsppars.cpp', 'mhprop.cpp',
> >                   'servrsnd.cpp', '3gpadapthdr.cpp',
> >-                   'rateadaptinfo.cpp')
> >+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
> >
> > if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
> >     project.AddSources('pipelinedesc.cpp')
> >Index: rtspclnt.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> >retrieving revision 1.79.2.1
> >diff -u -r1.79.2.1 rtspclnt.cpp
> >--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
> >+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
> >@@ -95,6 +95,7 @@
> > #include "pipelinedesc.h"
> > #include "errdbg.h"
> > #include "rateadaptinfo.h"
> >+#include "ntsrcbufstats.h"
> >
> > #include "hxheap.h"
> > #ifdef _DEBUG
> >@@ -302,6 +303,12 @@
> >     {
> >         return HXR_OK;
> >     }
> >+    else if (m_pSrcBufStats &&
> >+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> >+                                                       ppvObj)))
> >+    {
> >+        return HXR_OK;
> >+    }
> >     *ppvObj = NULL;
> >     return HXR_NOINTERFACE;
> > }
> >@@ -388,6 +395,7 @@
> >     m_bReportedSuccessfulTransport(FALSE),
> >     m_bSDPInitiated(FALSE),
> >     m_bMulticast(FALSE),
> >+    m_bIsLive(FALSE),
> >     m_pSDPFileHeader(NULL),
> >     m_pSDPStreamHeaders(NULL),
> >     m_bSessionSucceeded(FALSE),
> >@@ -404,7 +412,8 @@
> >     m_ulCurrentTimeOut(0),
> >     m_pUAProfURI(NULL),
> >     m_pUAProfDiff(NULL),
> >-    m_pRateAdaptInfo(NULL)
> >+    m_pRateAdaptInfo(NULL),
> >+    m_pSrcBufStats(NULL)
> > #if defined(_MACINTOSH)
> >     , m_pCallback(NULL)
> > #endif /* _MACINTOSH */
> >@@ -460,6 +469,8 @@
> >         m_pRateAdaptInfo->Close();
> >         HX_DELETE(m_pRateAdaptInfo);
> >     }
> >+
> >+    HX_RELEASE(m_pSrcBufStats);
> > }
> >
> > /*
> >@@ -810,6 +821,21 @@
> >         }
> >     }
> >
> >+    if (HXR_OK == hresult)
> >+    {
> >+        HX_RELEASE(m_pSrcBufStats);
> >+        m_pSrcBufStats = new HXNetSourceBufStats(this);
> >+
> >+        if (m_pSrcBufStats)
> >+        {
> >+            m_pSrcBufStats->AddRef();
> >+        }
> >+        else
> >+        {
> >+            hresult = HXR_OUTOFMEMORY;
> >+        }
> >+    }
> >+
> > #if defined(_MACINTOSH)
> >     if (m_pCallback &&
> >         m_pCallback->m_bIsCallbackPending &&
> >@@ -2191,7 +2217,14 @@
> >         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> >     if (pTrans)
> >     {
> >-        rc = pTrans->getPacket(uStreamNumber, pPacket);
> >+        UINT32 uSeqNum;
> >+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> >+
> >+        if ((HXR_OK == rc) && m_pSrcBufStats &&
> >+            (!pPacket->IsLost()))
> >+        {
> >+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> >+        }
> >     }
> >
> >     m_pMutex->Unlock();
> >@@ -3291,16 +3324,24 @@
> >     HX_RESULT rc = HXR_OK;
> >     m_pMutex->Lock();
> >
> >-    CHXMapLongToObj::Iterator i;
> >-    for(i=m_pTransportStreamMap->Begin();
> >-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> >+    if (m_bIsLive)
> >     {
> >-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> >-        UINT16 streamNumber = (UINT16)i.get_key();
> >-
> >-        HX_ASSERT(pTransport);
> >+        CHXMapLongToObj::Iterator i;
> >+        for(i=m_pTransportStreamMap->Begin();
> >+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> >+        {
> >+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> >+            UINT16 streamNumber = (UINT16)i.get_key();
> >+
> >+            HX_ASSERT(pTransport);
> >+
> >+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : 
> >HXR_OK;
> >+        }
> >+    }
> >
> >-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> >+    if (m_pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats->Reset();
> >     }
> >
> >     m_pMutex->Unlock();
> >@@ -6964,6 +7005,11 @@
> >         // Get session level RTP bandwidth modifiers
> >         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
> >         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> >+
> >+        if (ulIsSessionLive)
> >+        {
> >+            m_bIsLive = TRUE;
> >+        }
> >
> >         // get multicast address from the session description
> >         if (HXR_OK == 
> >ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> >@@ -7187,6 +7233,11 @@
> >             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
> >             pInfo->m_bRealMedia = bRealMedia;
> >
> >+            if (m_pSrcBufStats)
> >+            {
> >+                m_pSrcBufStats->Init((UINT16)streamNumber, 
> >pInfo->m_bIsLive);
> >+            }
> >+
> >             if (m_pRateAdaptInfo)
> >             {
> >                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> >@@ -7222,6 +7273,7 @@
> >         if (m_bMulticast)
> >         {
> >             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> >+            m_bIsLive = TRUE;
> >         }
> >     }
> >
> >Index: pub/rtspclnt.h
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> >retrieving revision 1.30.2.1
> >diff -u -r1.30.2.1 rtspclnt.h
> >--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
> >+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
> >@@ -46,6 +46,7 @@
> > #include "hxbufctl.h" // IHXTransportBufferLimit
> > #include "hxrtsp2.h"
> > #include "hxrsdbf.h" // IHXResendBufferControl
> >+#include "hxprefs.h" // IHXPreferences
> >
> > class RTSPClientState;
> > class RTSPOptionsMessage;
> >@@ -63,6 +64,7 @@
> > class MIMEHeader;
> > class PipelinedDescribeLogic;
> > class CHXRateAdaptationInfo;
> >+class HXNetSourceBufStats;
> >
> > struct IHXKeyValueList;
> > struct IHXValues;
> >@@ -1039,6 +1041,7 @@
> >
> >     BOOL                                m_bSDPInitiated;
> >     BOOL                                m_bMulticast;
> >+    BOOL                                m_bIsLive;
> >     IHXValues*                          m_pSDPFileHeader;
> >     CHXSimpleList*                      m_pSDPStreamHeaders;
> >
> >@@ -1074,6 +1077,7 @@
> >     UINT32                              m_ulServerTimeOut;
> >     UINT32                              m_ulCurrentTimeOut;
> >     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> >+    HXNetSourceBufStats*                m_pSrcBufStats;
> >
> > #if defined(_MACINTOSH)
> >     RTSPClientProtocolCallback*                m_pCallback;
> >
> >Index: rtsptran.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> >retrieving revision 1.26
> >diff -u -r1.26 rtsptran.cpp
> >--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
> >+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
> >@@ -526,8 +526,17 @@
> >     }
> > }
> >
> >+HX_RESULT
> >+RTSPTransport::getPacket(UINT16 uStreamNumber,
> >+                         IHXPacket*& pPacket)
> >+{
> >+    UINT32 uSeqNum;
> >+    return getPacket(uStreamNumber, pPacket, uSeqNum);
> >+}
> >+
> > HX_RESULT
> >-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> >+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
> >+                         REF(UINT32) uSeqNum)
> > {
> >     RTSPTransportBuffer* pTransportBuffer = 
> >getTransportBuffer(uStreamNumber);
> >     RTSPStreamData* pStreamData = 
> >m_pStreamHandler->getStreamData(uStreamNumber);
> >@@ -547,6 +556,7 @@
> >     }
> >
> >     pPacket = clientPacket->GetPacket();
> >+    uSeqNum = clientPacket->GetSequenceNumber();
> >
> >     if (!pPacket)
> >     {
> >Index: pub/rtsptran.h
> >===================================================================
> >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> >retrieving revision 1.19
> >diff -u -r1.19 rtsptran.h
> >--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
> >+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
> >@@ -259,6 +259,9 @@
> >     HX_RESULT resetFlags               (UINT16 streamNumber);
> >     HX_RESULT getPacket                        (UINT16 uStreamNumber,
> >                                        IHXPacket*& pPacket);
> >+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
> >+                                       IHXPacket*& pPacket,
> >+                                         REF(UINT32) uSeqNum);
> >     virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
> >     virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
> >
> >Index: Umakefil
> >===================================================================
> >RCS file: /cvsroot/client/common/util/Umakefil,v
> >retrieving revision 1.3
> >diff -u -r1.3 Umakefil
> >--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
> >+++ Umakefil    22 Jun 2004 22:53:43 -0000
> >@@ -53,6 +53,7 @@
> >                   'chxphook.cpp',
> >                   'xnetchck.cpp',
> >                   'littobig.cpp',
> >-                  'hxunicod.cpp')
> >+                  'hxunicod.cpp',
> >+                   'hxsrcbufstats.cpp')
> >
> > LibraryTarget('utlclntlib')
> >Index: hxcore.h
> >===================================================================
> >RCS file: /cvsroot/common/include/hxcore.h,v
> >retrieving revision 1.5
> >diff -u -r1.5 hxcore.h
> >--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
> >+++ hxcore.h    22 Jun 2004 23:00:23 -0000
> >@@ -2060,7 +2060,50 @@
> >
> > // $EndPrivate.
> >
> >+// $Private:
> >
> >+/****************************************************************************
> >+ *
> >+ *  Interface:
> >+ *
> >+ *     IID_IHXTransportOnTimeSync
> >+ *
> >+ *  Purpose:
> >+ *
> >+ *     This interface is used to send OnTimeSync() calls down
> >+ *      to the transport layer. Note that the value passed to
> >+ *      OnTimeSync() MUST be in the same units and have the same
> >+ *      offset as the packets coming from the transport. This means
> >+ *      that any offets caused by SMIL or live playback must be
> >+ *      removed before calling OnTimeSync() on this interface
> >+ *
> >+ *      IID_IHXTransportOnTimeSync
> >+ *
> >+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> >+ *
> >+ */
> >+DEFINE_GUID(IID_IHXTransportOnTimeSync,
> >+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 
> >0xc1);
> >+
> >+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> >+{
> >+    /*
> >+     * IUnknown methods
> >+     */
> >+
> >+    STDMETHOD(QueryInterface)  (THIS_
> >+                               REFIID riid,
> >+                               void** ppvObj) PURE;
> >+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> >+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
> >+
> >+    /*
> >+     * IHXTransportOnTimeSync methods
> >+     */
> >+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> >+};
> >+
> >+// $EndPrivate.
> >
> > #endif /* _HXCORE_H_ */
> >
> >Index: hxpiids.h
> >===================================================================
> >RCS file: /cvsroot/common/include/hxpiids.h,v
> >retrieving revision 1.28.2.1
> >diff -u -r1.28.2.1 hxpiids.h
> >--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
> >+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
> >@@ -533,6 +533,7 @@
> > DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 
> >0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
> > DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 
> >0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
> > DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 
> >0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 
> >0xa9,  0x69,  0x37,  0x3b,  0x4d)
> >+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 
> >0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
> > #endif /* _HXCORE_H_ */
> >
> > /*
> >
> >
> >
> >
> >_______________________________________________
> >Common-dev mailing list
> >Common-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 
> ======================================
> M. Eric Hyche (ehyche@real.com)
> Core Technologies
> RealNetworks, Inc.
> 

From gwright at real.com  Wed Jun 23 10:03:57 2004
From: gwright at real.com (Greg Wright)
Date: Wed Jun 23 10:02:10 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Moving
	IHXSourceBufferingStats2implementation
References: <20040622235202.GA5152@real.com>
Message-ID: <0a4601c45944$13118520$ff8317ac@gwright5>

Is this not needed on 130NepX?

Also, there was a new interface added called IHXTimelineWatcher
that provides OnTimeSync calls from the auido services. If that
is the same time you are after you can just use that. However,
if this is a different based time then maybe we should not 
call it OnTimeSync. At least in my mind, OnTimeSync means the
current audio timeline position whenever I see it.

--greg.


----- Original Message ----- 
From: "Aaron Colwell" 
To: ; ; 
Sent: Tuesday, June 22, 2004 4:52 PM
Subject: [Client-dev] CR-Client: Moving IHXSourceBufferingStats2implementation


> Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
>           number information can be maintained as well.
> 
> Overview: These changes move the IHXSourceBufferingStats2 implementation
>           out of HXBufferingState and into a new class called 
>           HXSourceBufferStats. This was done because the client needs to
>           track packet sequence numbers for 3GPP-Rel6 OBSN support.
>           There was no good way to get the sequence number information to
>           the HXBufferingState class so the IHXSourceBufferingStats2 logic
>           was moved to where this information is available.
> 
>           A new interface called IHXTransportOnTimeSync was created to
>           propagate OnTimeSync() like calls to HXSourceBufferStats. The
>           time passed to the OnTimeSync() call in this interface MUST
>           NOT have any offsets created by SMIL or live playback. The time
>           should be in the same time frame as the packets coming from the
>           transport. If someone wants to rename this interface that is fine
>           by me.
> 
> 
>           - Created HXSourceBufferStats to contain the base 
>             IHXSourceBufferingStats2 implementation. This class is
>             used by HXFileSource.
>  
>           - Created HXNetSourceBufStats which derives from HXSourceBufferStats.
>             This class just overloads the GetCurrentBuffering() so that it
>             returns the amount of data in the transport buffer. This is
>             used by RTSPClientProtocol.
> 
>           - Removed IHXSourceBufferingStats2 code from HXSource
> 
>           - Removed packet tracking code from HXBufferingState. This 
>             functionality is implemented by HXSourceBufferStats now
> 
>           - Added code to HXSource to provide OnTimeSync() calls to the
>             IHXTransportOnTimeSync interface. 
> 
>           - HXSource now exposes IHXSourceBufferingStats functionality through
>             it's m_pSrcBufStats member variable instead of implementing it
>             itself. The file and network sources are expected to provide an
>             IHXSourceBufferingStats2 interface via a
>             HXSource::SetSrcBufStats() call.
> 
>           - Added code to HXFileSource to use HXSourceBufferStats
> 
>           - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> 
>           - Fixed some code in CBufferManager that was expecting HXSource
>             to implement IHXSourceBufferingStats. This code now QI's for
>             IHXSourceBufferingStats and uses that interface.
>       
>              
> 
> Files Modified:
> client/core/buffmgr.cpp
> client/core/hxbsrc.h
> client/core/hxbufstate.h
> client/core/hxbufstate.cpp
> client/core/hxflsrc.cpp
> client/core/hxflsrc.h
> client/core/hxntsrc.cpp
> client/core/hxntsrc.h
> client/core/hxsrc.cpp
> client/core/rtspprotocol.cpp
> protocol/rtsp/Umakefil
> protocol/rtsp/rtspclnt.cpp
> protocol/rtsp/pub/rtspclnt.h
> protocol/transport/common/system/rtsptran.cpp
> protocol/transport/common/system/pub/rtsptran.h
> client/common/util/Umakefil
> common/include/hxcore.h
> common/include/hxpiids.h
> 
> Files Added:
> client/common/util/pub/hxsrcbufstats.h
> client/common/util/hxsrcbufstats.cpp
> protocol/rtsp/ntsrcbufstats.h
> protocol/rtsp/ntsrcbufstats.cpp
> 
> Image Size and Heap Use impact:
> 
> Platforms and Profiles affected: all
> 
> Distribution Libraries affected: rdtclntlib
> 
> Distribution library impact and planned action: 
> m_bIsLive and m_pSrcBufStats member variables were added to 
> RTSPClientProtocol so any derived objects will need to be
> recompiled
> 
> Platforms and Profiles Build Verified: win32
> 
> Platforms and Profiles Functionality verified: win32
> 
> Branch: HEAD
> 
> QA Instructions: none
> 
> Index: buffmgr.cpp
> ===================================================================
> RCS file: /cvsroot/client/core/buffmgr.cpp,v
> retrieving revision 1.21
> diff -u -r1.21 buffmgr.cpp
> --- buffmgr.cpp 11 Mar 2004 19:44:10 -0000 1.21
> +++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> @@ -610,6 +610,11 @@
>       * - Keep track of the stream with the lowest timestamp and is 
>       *   buffering data
>       */
> +    IHXSourceBufferingStats* pSrcBufStats = NULL;
> +    
> +    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> +                              (void**)&pSrcBufStats);
> +
>      for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
>      {
>   pStreamInfo = (STREAM_INFO*) (*i);
> @@ -619,12 +624,15 @@
>   ULONG32 ulNumBytesAtTransport = 0;
>   BOOL bDoneAtTransport = FALSE;
>  
> - m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
> -        llLowestTimestampAtTransport,
> -        llHighestTimestampAtTransport,
> -        ulNumBytesAtTransport,
> -        bDoneAtTransport);
> -
> +        if (pSrcBufStats)
> +        {
> +            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
> +                                              llLowestTimestampAtTransport,
> +                                              llHighestTimestampAtTransport,
> +                                              ulNumBytesAtTransport,
> +                                              bDoneAtTransport);
> +        }
> +            
>   pStreamInfo->BufferingState().UpdateTransportStats(
>       llLowestTimestampAtTransport,
>       llHighestTimestampAtTransport,
> @@ -658,6 +666,7 @@
>  
>   }
>      }
> +    HX_RELEASE(pSrcBufStats);
>  
>      /* If none of the streams have any data buffered at the transport layer,
>       * return.
> Index: hxbsrc.h
> ===================================================================
> RCS file: /cvsroot/client/core/hxbsrc.h,v
> retrieving revision 1.18.2.1
> diff -u -r1.18.2.1 hxbsrc.h
> --- hxbsrc.h 15 Jun 2004 16:26:43 -0000 1.18.2.1
> +++ hxbsrc.h 22 Jun 2004 22:52:26 -0000
> @@ -233,12 +233,11 @@
>     public IHXPrivateStreamSource,
>     public IHXBackChannel,
>     public IHXASMSource,
> -                  public IHXClientRateAdaptControl,
> +                  public IHXClientRateAdaptControl
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> -   public IHXHyperNavigate,
> -   public IHXHyperNavigate2,
> +   , public IHXHyperNavigate,
> +   public IHXHyperNavigate2
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> -                  public IHXSourceBufferingStats2
>  {
>  protected:
>      LONG32 m_lRefCount;
> @@ -487,35 +486,6 @@
>       IHXValues* pParams);
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>  
> -    /************************************************************************
> -     * Method:
> -     *     IHXSourceBufferingStats2::GetCurrentBuffering
> -     * Purpose:
> -     *     Get the current buffering information
> -     */
> -
> -    STDMETHOD(GetCurrentBuffering) (THIS_ 
> -                                    UINT16  uStreamNumber,
> -                                    REF(INT64)  llLowestTimestamp, 
> -                                    REF(INT64)  llHighestTimestamp,
> -                                    REF(UINT32) ulNumBytes,
> -                                    REF(BOOL)   bDone) PURE;
> -    /************************************************************************
> -     * Method:
> -     *     IHXSourceBufferingStats2::GetTotalBuffering
> -     * Purpose:
> -     *     Get the total amount of data buffered for a stream.
> -     *      This includes what is in the transport buffer and in
> -     *      the renderer
> -     */
> -    
> -    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> -    REF(INT64)  llLowestTimestamp, 
> -    REF(INT64)  llHighestTimestamp,
> -    REF(UINT32) ulNumBytes,
> -    REF(BOOL)   bDone);
> -
> -
>      /*
>       * IHXClientRateAdaptControl Methods
>       */
> @@ -731,7 +701,7 @@
>       virtual HX_RESULT FillRecordControl() = 0;
>       BOOL IsPlayingFromRecordControl() { return m_bPlayFromRecordControl; };
>  
> -            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> +            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>  
>              const char*         GetRedirectURL() { return (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
>              const char*         GetSDPURL() { return (m_pSDPURL ? m_pSDPURL->GetURL() : NULL); };
> @@ -769,6 +739,8 @@
>              void        ProcessFileHeader(void);
>              HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, STREAM_INFO*& pStreamInfo);
>  
> +    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> +
>      HX_RESULT mLastError;
>      CHXMapLongToObj*            mStreamInfoTable;
>      
> @@ -868,6 +840,8 @@
>      CHXURL*                     m_pRedirectURL;
>      CHXURL*                     m_pSDPURL;
>      BOOL                        m_bRedirectPending;
> +    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> +    IHXSourceBufferingStats2*   m_pSrcBufStats;
>  };
>  
>  // Defined flags
> Index: hxbufstate.cpp
> ===================================================================
> RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> retrieving revision 1.7
> diff -u -r1.7 hxbufstate.cpp
> --- hxbufstate.cpp 9 Mar 2004 19:51:11 -0000 1.7
> +++ hxbufstate.cpp 22 Jun 2004 22:52:26 -0000
> @@ -83,18 +83,11 @@
>      , m_ulLastPacketTimeStamp(0)
>      , m_ulAvgBandwidth(0)
>      , m_pASMProps(NULL)
> -    , m_llCurrentPlaybackTime(0)
> -    , m_ulBufferedData(0)
> -    , m_ulLastTimeSync(0)
> -    , m_llFirstLivePacketTimestamp(0)
> -    , m_ulTimeSyncRollOver(0)
>  {}
>  
>  HXBufferingState::~HXBufferingState()
>  {
>      HX_RELEASE(m_pASMProps);
> -
> -    ClearPktInfo();
>  }
>  
>  void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> @@ -179,8 +172,6 @@
>      m_ulLastPacketTimeStamp = 0;
>      m_bIsFirstPacket = TRUE;
>  
> -    ClearPktInfo();
> -
>      if (bIsSeeking)
>      {
>   m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> @@ -288,11 +279,6 @@
>      return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
>  }
>  
> -INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> -{
> -    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
> -}
> -
>  void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>   UINT32 ulElapsedTime,
>   BOOL bIsLive, BOOL bIsBufferedPlayMode)
> @@ -318,16 +304,12 @@
>   if (bIsLive)
>   {
>       m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> -            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
>          }
>  
>   m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
>   m_bIsFirstPacket = FALSE;
>      }
>  
> -    // Add this packet to our packet info statistics
> -    AddPktInfo(llActualTimeStamp, ulPacketSize);
> -
>      // data based preroll
>      if (DataBasedPreroll())
>      {
> @@ -451,47 +433,6 @@
>      m_bDoneAtTransport = bDoneAtTransport;
>  }
>  
> -HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp, 
> -       REF(INT64) llHighTimestamp,
> -       REF(UINT32) ulBytesBuffered,
> -       BOOL bUseTransportStats)
> -{
> -    HX_RESULT res = HXR_NO_DATA;
> -
> -    if (!m_bIsFirstPacket)
> -    {
> - if (!m_pktInfo.IsEmpty())
> - {
> -     HXBufferedPktInfo* pPktInfo = 
> - (HXBufferedPktInfo*)m_pktInfo.GetHead();
> -
> -     llLowTimestamp = pPktInfo->Timestamp();
> - }
> - else
> - {
> -     llLowTimestamp = m_llHighestTimeStamp;
> - }
> -
> - llHighTimestamp = m_llHighestTimeStamp;
> - ulBytesBuffered = GetBufferedData();
> - 
> -
> - if (bUseTransportStats)
> - {
> -     if (m_llHighestTimestampAtTransport > llHighTimestamp)
> -     {
> - llHighTimestamp = m_llHighestTimestampAtTransport;
> -     }
> -
> -     ulBytesBuffered += m_ulNumBytesAtTransport;
> - }
> -
> - res = HXR_OK;
> -    }
> -
> -    return res;
> -}
> -
>  void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
>      INT64 llTheHighestTS,
>      BOOL bIsSeekPerformed,
> @@ -569,19 +510,6 @@
>  
>  }
>  
> -void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> -{
> -    //  0xFA .. 0xFF [roll over] (0x01)
> -    if (m_ulLastTimeSync > ulCurrentTime &&
> -       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> -    {
> -       m_ulTimeSyncRollOver++;
> -    }
> -    m_ulLastTimeSync = ulCurrentTime;
> -
> -    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> -}
> -
>  void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs, 
>   ULONG32 ulMinBufferingInMs)
>  {
> @@ -771,62 +699,4 @@
>      {
>   m_ulAvgBandwidth = ulBandwidth;
>      }
> -}
> -
> -void HXBufferingState::ClearPktInfo()
> -{
> -    m_ulBufferedData = 0;
> -    while(!m_pktInfo.IsEmpty())
> -    {
> - HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> - delete pInfo;
> -    }
> -}
> -
> -void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
> -{
> -    // Subtract off the first live packet timestamp.
> -    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> -    llTimestamp -= m_llFirstLivePacketTimestamp;
> -    // Create the HXBufferedPktInfo class
> -    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp, 
> - ulPacketSize);
> -    if (pPktInfo)
> -    {
> - m_pktInfo.AddTail(pPktInfo);
> - m_ulBufferedData += ulPacketSize;
> -    }
> -
> -    // purge the old packet info data
> -    //  this keeps the list short and prevents the Symbian
> -    //  allocator from freaking out
> -    (void)GetBufferedData();
> -}
> -
> -UINT32 HXBufferingState::GetBufferedData()
> -{
> -    BOOL bDone = m_pktInfo.IsEmpty();
> -    
> -    // Remove all packet info that is past due
> -    // and subtract their sizes from our buffering total
> -    while(!bDone)
> -    {
> - HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
> - 
> - if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> - {
> -     m_ulBufferedData -= pPktInfo->Size();
> -     
> -     m_pktInfo.RemoveHead();
> -     delete pPktInfo;
> -     
> -     bDone = m_pktInfo.IsEmpty();
> - }
> - else
> - {
> -     bDone = TRUE;
> - }
> -    }
> -
> -    return m_ulBufferedData;
>  }
> Index: hxbufstate.h
> ===================================================================
> RCS file: /cvsroot/client/core/hxbufstate.h,v
> retrieving revision 1.4
> diff -u -r1.4 hxbufstate.h
> --- hxbufstate.h 19 May 2004 19:37:33 -0000 1.4
> +++ hxbufstate.h 22 Jun 2004 22:52:26 -0000
> @@ -81,7 +81,6 @@
>      BOOL HasPredata(BOOL bIsSeekPerformed);
>  
>      INT64 CreateINT64Timestamp(UINT32 ulTime);
> -    INT64 CreateINT64Timesync(UINT32 ulTime);
>  
>      void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize, 
>     UINT32 ulElapsedTime, BOOL bIsLive,
> @@ -98,11 +97,6 @@
>         ULONG32 ulBytesAtTransport,
>         BOOL bDoneAtTransport);
>  
> -    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp, 
> - REF(INT64) llHighTimestamp,
> - REF(UINT32) ulBytesBuffered,
> - BOOL bUseTransportStats);
> -
>      void GetExcessBufferInfo(INT64 llTheLowestTS,
>        INT64 llTheHighestTS,
>        BOOL bIsSeekPerformed,
> @@ -119,8 +113,6 @@
>  
>      UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
>  
> -    void OnTimeSync(UINT32 ulCurrentTime);
> -
>      // Should remove
>      void SetAvgBWToASMBw();
>      BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> @@ -149,19 +141,6 @@
>   UINT32 ulCurrentBuffering,
>   UINT32 ulMinimumPreroll,
>   UINT32 ulDenom) const;
> -    
> -    /* Functions for tracking the amount of data
> -     * buffered in the renderer
> -     */
> -    void ClearPktInfo(); /* Clears out information about buffered packets */
> -    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
> -       * a packet is 
> -       * sent to the
> -       * renderer 
> -       */
> -    UINT32 GetBufferedData(); /* Get the current amount of data buffered
> -        * in the renderer
> -        */
>  
>      ULONG32 m_ulPreroll;
>      ULONG32 m_ulPredata;
> @@ -196,20 +175,6 @@
>      ULONG32 m_ulLastPacketTimeStamp;
>      ULONG32 m_ulAvgBandwidth;
>      IHXASMProps* m_pASMProps;
> -    UINT32              m_ulLastTimeSync;
> -    INT64               m_llFirstLivePacketTimestamp;
> -    UINT32              m_ulTimeSyncRollOver;    
> -    // These variable keep track of the amount of
> -    // data buffered in the renderer
> -    INT64               m_llCurrentPlaybackTime; /* Cached value of last
> -   * OnTimeSync() call
> -   */
> -
> -    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> -    * Always use GetBufferedData()
> -    * to retreive the value
> -    */
> -    CHXSimpleList       m_pktInfo; /* List of packet information */
>  };
>  
>  inline
> Index: hxflsrc.cpp
> ===================================================================
> RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> retrieving revision 1.54
> diff -u -r1.54 hxflsrc.cpp
> --- hxflsrc.cpp 19 May 2004 19:37:33 -0000 1.54
> +++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> @@ -76,6 +76,7 @@
>  #include "uri_schemes.h"
>  #include "stream_desc_hlpr.h"
>  #include "findfile.h"
> +#include "hxsrcbufstats.h"
>  
>  #include "hxheap.h"
>  #ifdef _DEBUG
> @@ -115,6 +116,7 @@
>      , m_bValidateMetaDone(FALSE)
>      , m_pFileRecognizer(NULL)
>      , m_pFileReader(NULL)
> +    , m_pSrcBufStats(NULL)
>  {
>      m_bAltURL = FALSE;
>      m_bPerfectPlay = TRUE;
> @@ -306,6 +308,13 @@
>  
>      HX_VECTOR_DELETE(m_pszURL);
>      HX_DELETE(m_pURL);
> +    
> +    HX_RELEASE(m_pSrcBufStats);
> +    m_pSrcBufStats = new HXSourceBufferStats();
> +    if (m_pSrcBufStats)
> +    {
> +        m_pSrcBufStats->AddRef();
> +    }
>  
>      if (!theErr && pURL)
>      {
> @@ -938,6 +947,7 @@
>      }
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
>  
> +    HX_RELEASE(m_pSrcBufStats);
>      HXSource::DoCleanup();
>  
>      return HXR_OK;
> @@ -1068,6 +1078,11 @@
>  
>      m_llLastFillEndTime = 0;   
>  
> +    if (m_pSrcBufStats)
> +    {
> +        m_pSrcBufStats->Reset();
> +    }
> +
>  cleanup:
>  
>      return HXR_OK;
> @@ -1442,6 +1457,11 @@
>  
>       if(m_pBufferManager)
>   m_pBufferManager->UpdateCounters(pPacket, 0);
> +            
> +            if (m_pSrcBufStats && !pPacket->IsLost())
> +            {
> +                m_pSrcBufStats->OnPacket(pPacket);
> +            }
>  
>       HX_RELEASE(pPacket);
>   }
> @@ -2103,6 +2123,13 @@
>   }
>   HX_RELEASE(pszParentName);
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> +
> +        if (pStreamInfo && m_pSrcBufStats)
> +        {
> +            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> +                                 mLiveStream);
> +        }
> +
>          m_ulStreamIndex++;
>          m_uNumStreams++;
>      }
> @@ -2115,6 +2142,11 @@
>  
>   theErr = AdjustClipTime();
>   m_pBufferManager->Init();
> +
> +        if (m_pSrcBufStats)
> +        {
> +            SetSrcBufStats(m_pSrcBufStats);
> +        }
>      }
>  
>      return theErr;
> @@ -2313,6 +2345,11 @@
>   {
>       m_pBufferManager->UpdateCounters(pPacket, 0);
>   }
> +
> +        if (m_pSrcBufStats && !pPacket->IsLost())
> +        {
> +            m_pSrcBufStats->OnPacket(pPacket);
> +        }
>      }
>  
>      m_llLastFillEndTime = llActualPacketTime;
> Index: hxflsrc.h
> ===================================================================
> RCS file: /cvsroot/client/core/hxflsrc.h,v
> retrieving revision 1.12
> diff -u -r1.12 hxflsrc.h
> --- hxflsrc.h 3 May 2004 18:59:30 -0000 1.12
> +++ hxflsrc.h 22 Jun 2004 22:52:26 -0000
> @@ -52,6 +52,8 @@
>  #include "hxfiles.h"
>  #include "recognizer.h"
>  
> +class HXSourceBufferStats;
> +
>  class HXFileSource : public HXSource, 
>         public IHXFormatResponse,
>                        public IHXHTTPRedirectResponse
> @@ -349,6 +351,7 @@
>  
>      CFileReader*                m_pFileReader;
>      CHXFileRecognizer*          m_pFileRecognizer;
> +    HXSourceBufferStats*        m_pSrcBufStats;
>  };
>  
>  #endif // _HX_FILE_SOURCE
> Index: hxntsrc.cpp
> ===================================================================
> RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> retrieving revision 1.90
> diff -u -r1.90 hxntsrc.cpp
> --- hxntsrc.cpp 19 May 2004 19:37:33 -0000 1.90
> +++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> @@ -675,6 +675,7 @@
>      HX_RESULT   rc = HXR_OK;
>      BOOL        bSDPInitiated = FALSE;
>      CHXString   pString;
> +    IHXSourceBufferingStats2* pSrcBufStats = NULL;
>  
>      // start off with the preferred protocol
>      rc = CreateProtocol();
> @@ -722,6 +723,14 @@
>          goto cleanup;
>      }
>  
> +    // Setup source buffer stats 
> +    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> +                                           (void**)&pSrcBufStats))
> +    {
> +        SetSrcBufStats(pSrcBufStats);
> +        HX_RELEASE(pSrcBufStats);
> +    }
> +
>      // create log info list
>      m_pLogInfoList = new CHXSimpleList;
>      m_ulLogInfoLength = 0;
> @@ -6295,6 +6304,12 @@
>  #else
>      return HXR_NOTIMPL;
>  #endif /* HELIX_FEATURE_RECORDCONTROL */
> +}
> +
> +HX_RESULT 
> +HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> +{
> +    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
>  }
>  
>  ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> Index: hxntsrc.h
> ===================================================================
> RCS file: /cvsroot/client/core/hxntsrc.h,v
> retrieving revision 1.24
> diff -u -r1.24 hxntsrc.h
> --- hxntsrc.h 3 May 2004 18:59:30 -0000 1.24
> +++ hxntsrc.h 22 Jun 2004 22:52:26 -0000
> @@ -282,6 +282,7 @@
>  
>   virtual HX_RESULT FillRecordControl();
>  
> +        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>  protected:
>  
>   virtual ~HXNetSource(void);
> @@ -470,7 +471,6 @@
>  private:
>          IHXBufferControl*                m_pBufferCtl;
>          IHXWatermarkBufferControl*       m_pWMBufferCtl;
> -
>  public:
>   HX_RESULT FinishSetup();
>   void ReSetup();
> Index: hxsrc.cpp
> ===================================================================
> RCS file: /cvsroot/client/core/hxsrc.cpp,v
> retrieving revision 1.44.2.1
> diff -u -r1.44.2.1 hxsrc.cpp
> --- hxsrc.cpp 15 Jun 2004 16:26:43 -0000 1.44.2.1
> +++ hxsrc.cpp 22 Jun 2004 22:52:26 -0000
> @@ -213,6 +213,8 @@
>          , m_pRedirectURL(NULL)
>          , m_pSDPURL(NULL)
>          , m_bRedirectPending(FALSE)
> +        , m_pTransOnTimeSync(NULL)
> +        , m_pSrcBufStats(NULL)
>  {
>      mStreamInfoTable = new CHXMapLongToObj;
>  }
> @@ -313,6 +315,8 @@
>      HX_DELETE(m_pRedirectURL);
>      HX_DELETE(m_pSDPURL);
>      m_bRedirectPending  = FALSE;
> +    HX_RELEASE(m_pTransOnTimeSync);
> +    HX_RELEASE(m_pSrcBufStats);
>  
>  #if defined(HELIX_FEATURE_RECORDCONTROL)
>      if(m_pRecordControl)
> @@ -340,8 +344,6 @@
>              { GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*)this },
>              { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
>              { GET_IIDHANDLE(IID_IHXPrivateStreamSource), (IHXPrivateStreamSource*)this },
> -            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*)this },
> -            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*)this },
>              { GET_IIDHANDLE(IID_IHXClientRateAdaptControl), 
>                (IHXClientRateAdaptControl*)this },
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> @@ -388,6 +390,14 @@
>       return HXR_NOINTERFACE;
>   }
>      }
> +    else if (m_pSrcBufStats &&
> +             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> +              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> +    {
> +        m_pSrcBufStats->AddRef();
> +        *ppvObj = m_pSrcBufStats;
> +        return HXR_OK;
> +    }
>  
>  #if defined(HELIX_FEATURE_AUTOUPGRADE)
>      else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> @@ -2250,59 +2260,6 @@
>  }
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>  
> -STDMETHODIMP
> -HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> -     REF(INT64)  llLowestTimestamp, 
> -     REF(INT64)  llHighestTimestamp,
> -     REF(UINT32) ulNumBytes,
> -     REF(BOOL)   bDone)
> -{
> -    HX_RESULT res = HXR_NO_DATA;
> -    
> -    llLowestTimestamp = 0;
> -    llHighestTimestamp = 0;
> -    ulNumBytes = 0;
> -    bDone = FALSE;
> -
> -    STREAM_INFO* pStreamInfo;
> -    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
> -    {
> - HXBufferingState& bufState = pStreamInfo->BufferingState();
> - BOOL   bUseTransportStats = FALSE;
> -
> - INT64  llTransportLowTS = 0;
> - INT64  llTransportHighTS = 0;
> - UINT32 ulTransportBytes = 0;
> - BOOL   bTransportDone = FALSE;
> -
> - if (!IsLocalSource() &&
> -     (HXR_OK == GetCurrentBuffering(uStreamNumber,
> -    llTransportLowTS,
> -    llTransportHighTS,
> -    ulTransportBytes,
> -    bTransportDone)))
> - {
> -     bufState.UpdateTransportStats(llTransportLowTS,
> -   llTransportHighTS,
> -   ulTransportBytes,
> -   bTransportDone);
> -
> -     bUseTransportStats = TRUE;
> -
> -     // Update bDone with what the transport says.
> -     bDone = bTransportDone;
> - }
> -
> - res = bufState.GetBufferingStats(llLowestTimestamp,
> - llHighestTimestamp,
> - ulNumBytes,
> - bUseTransportStats);
> -    }
> -
> -
> -    return res;
> -}
> -
>  /*
>   * IHXClientRateAdaptControl Methods
>   */
> @@ -2948,13 +2905,34 @@
>  {
>      HX_RESULT res = HXR_OK;
>  
> -    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> -         i != mStreamInfoTable->End(); ++i) 
> -    {    
> - STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> -
> - pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> +    // Convert presentation time to transport time
> +    if (m_pTransOnTimeSync)
> +    {
> +        ULONG32 ulOffset = m_ulDelay;
> +        ULONG32 ulTransportTime = m_ulStartTime;
> +        
> +        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> +        {
> +            ulTransportTime += ulCurrentTime - ulOffset;
> +        }
> +    
> +        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
>      }
>  
>      return res;
> +}
> +
> +void 
> +HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> +{
> +    HX_RELEASE(m_pSrcBufStats);
> +    HX_RELEASE(m_pTransOnTimeSync);
> +
> +    if (pSrcBufStats)
> +    {
> +        m_pSrcBufStats = pSrcBufStats;
> +        m_pSrcBufStats->AddRef();
> +        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> +                                       (void**)&m_pTransOnTimeSync);
> +    }
>  }
> Index: rtspprotocol.cpp
> ===================================================================
> RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> retrieving revision 1.39
> diff -u -r1.39 rtspprotocol.cpp
> --- rtspprotocol.cpp 11 May 2004 00:55:19 -0000 1.39
> +++ rtspprotocol.cpp 22 Jun 2004 22:52:26 -0000
> @@ -2626,12 +2626,12 @@
>      UINT16 seekFrom
>  )
>  {
> +    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> +
>      if (IsLive())
>      {
> -        return m_pProtocolLib->SeekFlush();
> +        return theErr;
>      }
> -
> -    HX_RESULT theErr = HXR_OK;
>  
>      m_uCurrentStreamCount = m_uStreamCount;
>  
> 
> Index: Umakefil
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> retrieving revision 1.9.2.1
> diff -u -r1.9.2.1 Umakefil
> --- Umakefil 16 Jun 2004 18:44:01 -0000 1.9.2.1
> +++ Umakefil 22 Jun 2004 22:52:32 -0000
> @@ -46,6 +46,7 @@
>     'common/runtime/pub',
>     'common/lang/xml/pub',
>     'client/common/container/pub',
> +                          'client/common/util/pub',
>     'protocol/transport/rtp/include',
>             'server/include', 
>                            'server/common/struct/pub',
> @@ -65,7 +66,7 @@
>      'rtspmsg.cpp', 'rtspmdsc.cpp',
>      'rtsppars.cpp', 'mhprop.cpp',
>      'servrsnd.cpp', '3gpadapthdr.cpp',
> -                   'rateadaptinfo.cpp')
> +                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
>  
>  if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
>      project.AddSources('pipelinedesc.cpp')
> Index: rtspclnt.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> retrieving revision 1.79.2.1
> diff -u -r1.79.2.1 rtspclnt.cpp
> --- rtspclnt.cpp 17 Jun 2004 04:32:09 -0000 1.79.2.1
> +++ rtspclnt.cpp 22 Jun 2004 22:52:32 -0000
> @@ -95,6 +95,7 @@
>  #include "pipelinedesc.h"
>  #include "errdbg.h"
>  #include "rateadaptinfo.h"
> +#include "ntsrcbufstats.h"
>  
>  #include "hxheap.h"
>  #ifdef _DEBUG
> @@ -302,6 +303,12 @@
>      {
>          return HXR_OK;
>      }
> +    else if (m_pSrcBufStats &&
> +             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> +                                                       ppvObj)))
> +    {
> +        return HXR_OK;
> +    }
>      *ppvObj = NULL;
>      return HXR_NOINTERFACE;
>  }
> @@ -388,6 +395,7 @@
>      m_bReportedSuccessfulTransport(FALSE),
>      m_bSDPInitiated(FALSE),
>      m_bMulticast(FALSE),
> +    m_bIsLive(FALSE),
>      m_pSDPFileHeader(NULL),
>      m_pSDPStreamHeaders(NULL),
>      m_bSessionSucceeded(FALSE),
> @@ -404,7 +412,8 @@
>      m_ulCurrentTimeOut(0),
>      m_pUAProfURI(NULL),
>      m_pUAProfDiff(NULL),
> -    m_pRateAdaptInfo(NULL)
> +    m_pRateAdaptInfo(NULL),
> +    m_pSrcBufStats(NULL)
>  #if defined(_MACINTOSH)
>      , m_pCallback(NULL)
>  #endif /* _MACINTOSH */
> @@ -460,6 +469,8 @@
>          m_pRateAdaptInfo->Close();
>          HX_DELETE(m_pRateAdaptInfo);
>      }
> +
> +    HX_RELEASE(m_pSrcBufStats);
>  }
>  
>  /*
> @@ -810,6 +821,21 @@
>          }
>      }
>  
> +    if (HXR_OK == hresult)
> +    {
> +        HX_RELEASE(m_pSrcBufStats);
> +        m_pSrcBufStats = new HXNetSourceBufStats(this);
> +        
> +        if (m_pSrcBufStats)
> +        {
> +            m_pSrcBufStats->AddRef();
> +        }
> +        else
> +        {
> +            hresult = HXR_OUTOFMEMORY;
> +        }
> +    }
> +
>  #if defined(_MACINTOSH)
>      if (m_pCallback &&
>          m_pCallback->m_bIsCallbackPending &&
> @@ -2191,7 +2217,14 @@
>          (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
>      if (pTrans)
>      {
> -        rc = pTrans->getPacket(uStreamNumber, pPacket);
> +        UINT32 uSeqNum;
> +        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> +
> +        if ((HXR_OK == rc) && m_pSrcBufStats &&
> +            (!pPacket->IsLost()))
> +        {
> +            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> +        }
>      }
>  
>      m_pMutex->Unlock();
> @@ -3291,16 +3324,24 @@
>      HX_RESULT rc = HXR_OK;
>      m_pMutex->Lock();
>  
> -    CHXMapLongToObj::Iterator i;
> -    for(i=m_pTransportStreamMap->Begin();
> -            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> +    if (m_bIsLive)
>      {
> -        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> -        UINT16 streamNumber = (UINT16)i.get_key();
> -
> -        HX_ASSERT(pTransport);
> +        CHXMapLongToObj::Iterator i;
> +        for(i=m_pTransportStreamMap->Begin();
> +            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> +        {
> +            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> +            UINT16 streamNumber = (UINT16)i.get_key();
> +            
> +            HX_ASSERT(pTransport);
> +            
> +            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> +        }
> +    }
>  
> -        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> +    if (m_pSrcBufStats)
> +    {
> +        m_pSrcBufStats->Reset();
>      }
>  
>      m_pMutex->Unlock();
> @@ -6964,6 +7005,11 @@
>          // Get session level RTP bandwidth modifiers
>          ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
>          ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> +        
> +        if (ulIsSessionLive)
> +        {
> +            m_bIsLive = TRUE;
> +        }
>  
>          // get multicast address from the session description
>          if (HXR_OK == ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> @@ -7187,6 +7233,11 @@
>              pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
>              pInfo->m_bRealMedia = bRealMedia;
>  
> +            if (m_pSrcBufStats)
> +            {
> +                m_pSrcBufStats->Init((UINT16)streamNumber, pInfo->m_bIsLive);
> +            }
> +
>              if (m_pRateAdaptInfo)
>              {
>                  m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> @@ -7222,6 +7273,7 @@
>          if (m_bMulticast)
>          {
>              m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> +            m_bIsLive = TRUE;
>          }
>      }
>  
> Index: pub/rtspclnt.h
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> retrieving revision 1.30.2.1
> diff -u -r1.30.2.1 rtspclnt.h
> --- pub/rtspclnt.h 17 Jun 2004 04:32:09 -0000 1.30.2.1
> +++ pub/rtspclnt.h 22 Jun 2004 22:52:32 -0000
> @@ -46,6 +46,7 @@
>  #include "hxbufctl.h" // IHXTransportBufferLimit
>  #include "hxrtsp2.h"
>  #include "hxrsdbf.h" // IHXResendBufferControl
> +#include "hxprefs.h" // IHXPreferences
>  
>  class RTSPClientState;
>  class RTSPOptionsMessage;
> @@ -63,6 +64,7 @@
>  class MIMEHeader;
>  class PipelinedDescribeLogic;
>  class CHXRateAdaptationInfo;
> +class HXNetSourceBufStats;
>  
>  struct IHXKeyValueList;
>  struct IHXValues;
> @@ -1039,6 +1041,7 @@
>      
>      BOOL                                m_bSDPInitiated;
>      BOOL                                m_bMulticast;
> +    BOOL                                m_bIsLive;
>      IHXValues*                          m_pSDPFileHeader;
>      CHXSimpleList*                      m_pSDPStreamHeaders;
>  
> @@ -1074,6 +1077,7 @@
>      UINT32                              m_ulServerTimeOut;
>      UINT32                              m_ulCurrentTimeOut;
>      CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> +    HXNetSourceBufStats*                m_pSrcBufStats;
>  
>  #if defined(_MACINTOSH)
>      RTSPClientProtocolCallback* m_pCallback;
> 
> Index: rtsptran.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> retrieving revision 1.26
> diff -u -r1.26 rtsptran.cpp
> --- rtsptran.cpp 21 Apr 2004 19:16:30 -0000 1.26
> +++ rtsptran.cpp 22 Jun 2004 22:53:16 -0000
> @@ -526,8 +526,17 @@
>      }
>  }
>  
> +HX_RESULT 
> +RTSPTransport::getPacket(UINT16 uStreamNumber,
> +                         IHXPacket*& pPacket)
> +{
> +    UINT32 uSeqNum;
> +    return getPacket(uStreamNumber, pPacket, uSeqNum);
> +}
> +
>  HX_RESULT
> -RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> +RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket, 
> +                         REF(UINT32) uSeqNum)
>  {
>      RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
>      RTSPStreamData* pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
> @@ -547,6 +556,7 @@
>      }
>  
>      pPacket = clientPacket->GetPacket();
> +    uSeqNum = clientPacket->GetSequenceNumber();
>  
>      if (!pPacket)
>      {
> Index: pub/rtsptran.h
> ===================================================================
> RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> retrieving revision 1.19
> diff -u -r1.19 rtsptran.h
> --- pub/rtsptran.h 20 Apr 2004 18:33:22 -0000 1.19
> +++ pub/rtsptran.h 22 Jun 2004 22:53:16 -0000
> @@ -259,6 +259,9 @@
>      HX_RESULT resetFlags (UINT16 streamNumber);
>      HX_RESULT getPacket (UINT16 uStreamNumber,
>   IHXPacket*& pPacket);
> +    HX_RESULT getPacket (UINT16 uStreamNumber,
> + IHXPacket*& pPacket,
> +                                         REF(UINT32) uSeqNum);
>      virtual HX_RESULT startPackets (UINT16 uStreamNumber);
>      virtual HX_RESULT stopPackets (UINT16 uStreamNumber);
>  
> Index: Umakefil
> ===================================================================
> RCS file: /cvsroot/client/common/util/Umakefil,v
> retrieving revision 1.3
> diff -u -r1.3 Umakefil
> --- Umakefil 7 Feb 2003 22:37:08 -0000 1.3
> +++ Umakefil 22 Jun 2004 22:53:43 -0000
> @@ -53,6 +53,7 @@
>      'chxphook.cpp',
>      'xnetchck.cpp',
>      'littobig.cpp',
> -    'hxunicod.cpp')
> +    'hxunicod.cpp', 
> +                   'hxsrcbufstats.cpp')
>  
>  LibraryTarget('utlclntlib')
> Index: hxcore.h
> ===================================================================
> RCS file: /cvsroot/common/include/hxcore.h,v
> retrieving revision 1.5
> diff -u -r1.5 hxcore.h
> --- hxcore.h 19 May 2004 19:38:28 -0000 1.5
> +++ hxcore.h 22 Jun 2004 23:00:23 -0000
> @@ -2060,7 +2060,50 @@
>  
>  // $EndPrivate.
>  
> +// $Private:
>  
> +/****************************************************************************
> + * 
> + *  Interface:
> + *
> + * IID_IHXTransportOnTimeSync
> + *
> + *  Purpose:
> + *
> + * This interface is used to send OnTimeSync() calls down
> + *      to the transport layer. Note that the value passed to
> + *      OnTimeSync() MUST be in the same units and have the same
> + *      offset as the packets coming from the transport. This means
> + *      that any offets caused by SMIL or live playback must be
> + *      removed before calling OnTimeSync() on this interface
> + *
> + *      IID_IHXTransportOnTimeSync
> + *
> + * {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> + *
> + */
> +DEFINE_GUID(IID_IHXTransportOnTimeSync, 
> +0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1);
> +
> +DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> +{
> +    /*
> +     * IUnknown methods
> +     */
> +
> +    STDMETHOD(QueryInterface) (THIS_
> + REFIID riid,
> + void** ppvObj) PURE;
> +    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> +    STDMETHOD_(ULONG32,Release) (THIS) PURE;
> +
> +    /*
> +     * IHXTransportOnTimeSync methods
> +     */
> +    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> +};
> +
> +// $EndPrivate.
>  
>  #endif /* _HXCORE_H_ */
>  
> Index: hxpiids.h
> ===================================================================
> RCS file: /cvsroot/common/include/hxpiids.h,v
> retrieving revision 1.28.2.1
> diff -u -r1.28.2.1 hxpiids.h
> --- hxpiids.h 15 Jun 2004 16:38:55 -0000 1.28.2.1
> +++ hxpiids.h 22 Jun 2004 23:00:23 -0000
> @@ -533,6 +533,7 @@
>  DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
>  DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
>  DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 0xa9,  0x69,  0x37,  0x3b,  0x4d)
> +DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
>  #endif /* _HXCORE_H_ */
>  
>  /*
> 


--------------------------------------------------------------------------------


> _______________________________________________
> Client-dev mailing list
> Client-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/client-dev
> 

From ping at real.com  Wed Jun 23 10:06:30 2004
From: ping at real.com (Henry Ping)
Date: Wed Jun 23 10:07:04 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Moving
 IHXSourceBufferingStats2 implementation
In-Reply-To: <20040622235202.GA5152@real.com>
Message-ID: <5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>

- m_pSrcBufStats in hxflsrc.cpp needs to take a closer look, it's a bit 
confusing:
1. its definition is different from the base class, HXSourceBufferStats* 
instead of IHXSourceBufferingStats2*
hxbsrc.h: +    IHXSourceBufferingStats2*   m_pSrcBufStats;
hxflsrc.h: +    HXSourceBufferStats*        m_pSrcBufStats;
2. it's first assigned with "new HXSourceBufferStats()", but then is 
re-assigned in SetSrcBufStats()

- do you think we need to addref the m_pProto in HXNetSourceBufStats?

- do you think we need to return error if Init() is not called beforehand 
in HXSourceBufferStats?

-->Henry

At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
>Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
>           number information can be maintained as well.
>
>Overview: These changes move the IHXSourceBufferingStats2 implementation
>           out of HXBufferingState and into a new class called
>           HXSourceBufferStats. This was done because the client needs to
>           track packet sequence numbers for 3GPP-Rel6 OBSN support.
>           There was no good way to get the sequence number information to
>           the HXBufferingState class so the IHXSourceBufferingStats2 logic
>           was moved to where this information is available.
>
>           A new interface called IHXTransportOnTimeSync was created to
>           propagate OnTimeSync() like calls to HXSourceBufferStats. The
>           time passed to the OnTimeSync() call in this interface MUST
>           NOT have any offsets created by SMIL or live playback. The time
>           should be in the same time frame as the packets coming from the
>           transport. If someone wants to rename this interface that is fine
>           by me.
>
>
>           - Created HXSourceBufferStats to contain the base
>             IHXSourceBufferingStats2 implementation. This class is
>             used by HXFileSource.
>
>           - Created HXNetSourceBufStats which derives from 
> HXSourceBufferStats.
>             This class just overloads the GetCurrentBuffering() so that it
>             returns the amount of data in the transport buffer. This is
>             used by RTSPClientProtocol.
>
>           - Removed IHXSourceBufferingStats2 code from HXSource
>
>           - Removed packet tracking code from HXBufferingState. This
>             functionality is implemented by HXSourceBufferStats now
>
>           - Added code to HXSource to provide OnTimeSync() calls to the
>             IHXTransportOnTimeSync interface.
>
>           - HXSource now exposes IHXSourceBufferingStats functionality 
> through
>             it's m_pSrcBufStats member variable instead of implementing it
>             itself. The file and network sources are expected to provide an
>             IHXSourceBufferingStats2 interface via a
>             HXSource::SetSrcBufStats() call.
>
>           - Added code to HXFileSource to use HXSourceBufferStats
>
>           - Added code to RTSPClientProtocol to use HXNetSourceBufStats
>
>           - Fixed some code in CBufferManager that was expecting HXSource
>             to implement IHXSourceBufferingStats. This code now QI's for
>             IHXSourceBufferingStats and uses that interface.
>
>
>
>Files Modified:
>client/core/buffmgr.cpp
>client/core/hxbsrc.h
>client/core/hxbufstate.h
>client/core/hxbufstate.cpp
>client/core/hxflsrc.cpp
>client/core/hxflsrc.h
>client/core/hxntsrc.cpp
>client/core/hxntsrc.h
>client/core/hxsrc.cpp
>client/core/rtspprotocol.cpp
>protocol/rtsp/Umakefil
>protocol/rtsp/rtspclnt.cpp
>protocol/rtsp/pub/rtspclnt.h
>protocol/transport/common/system/rtsptran.cpp
>protocol/transport/common/system/pub/rtsptran.h
>client/common/util/Umakefil
>common/include/hxcore.h
>common/include/hxpiids.h
>
>Files Added:
>client/common/util/pub/hxsrcbufstats.h
>client/common/util/hxsrcbufstats.cpp
>protocol/rtsp/ntsrcbufstats.h
>protocol/rtsp/ntsrcbufstats.cpp
>
>Image Size and Heap Use impact:
>
>Platforms and Profiles affected: all
>
>Distribution Libraries affected: rdtclntlib
>
>Distribution library impact and planned action:
>m_bIsLive and m_pSrcBufStats member variables were added to
>RTSPClientProtocol so any derived objects will need to be
>recompiled
>
>Platforms and Profiles Build Verified: win32
>
>Platforms and Profiles Functionality verified: win32
>
>Branch: HEAD
>
>QA Instructions: none
>
>Index: buffmgr.cpp
>===================================================================
>RCS file: /cvsroot/client/core/buffmgr.cpp,v
>retrieving revision 1.21
>diff -u -r1.21 buffmgr.cpp
>--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
>+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
>@@ -610,6 +610,11 @@
>       * - Keep track of the stream with the lowest timestamp and is
>       *   buffering data
>       */
>+    IHXSourceBufferingStats* pSrcBufStats = NULL;
>+
>+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
>+                              (void**)&pSrcBufStats);
>+
>      for (i = m_pStreamInfoTable->Begin(); i != 
> m_pStreamInfoTable->End(); ++i)
>      {
>         pStreamInfo = (STREAM_INFO*) (*i);
>@@ -619,12 +624,15 @@
>         ULONG32 ulNumBytesAtTransport = 0;
>         BOOL bDoneAtTransport = FALSE;
>
>-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
>-                                      llLowestTimestampAtTransport,
>-                                      llHighestTimestampAtTransport,
>-                                      ulNumBytesAtTransport,
>-                                      bDoneAtTransport);
>-
>+        if (pSrcBufStats)
>+        {
>+            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
>+                                              llLowestTimestampAtTransport,
>+                                              llHighestTimestampAtTransport,
>+                                              ulNumBytesAtTransport,
>+                                              bDoneAtTransport);
>+        }
>+
>         pStreamInfo->BufferingState().UpdateTransportStats(
>             llLowestTimestampAtTransport,
>             llHighestTimestampAtTransport,
>@@ -658,6 +666,7 @@
>
>         }
>      }
>+    HX_RELEASE(pSrcBufStats);
>
>      /* If none of the streams have any data buffered at the transport layer,
>       * return.
>Index: hxbsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbsrc.h,v
>retrieving revision 1.18.2.1
>diff -u -r1.18.2.1 hxbsrc.h
>--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
>+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
>@@ -233,12 +233,11 @@
>                   public IHXPrivateStreamSource,
>                   public IHXBackChannel,
>                   public IHXASMSource,
>-                  public IHXClientRateAdaptControl,
>+                  public IHXClientRateAdaptControl
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>-                 public IHXHyperNavigate,
>-                 public IHXHyperNavigate2,
>+                 , public IHXHyperNavigate,
>+                 public IHXHyperNavigate2
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>-                  public IHXSourceBufferingStats2
>  {
>  protected:
>      LONG32                     m_lRefCount;
>@@ -487,35 +486,6 @@
>                             IHXValues* pParams);
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>
>-    /************************************************************************
>-     * Method:
>-     *     IHXSourceBufferingStats2::GetCurrentBuffering
>-     * Purpose:
>-     *     Get the current buffering information
>-     */
>-
>-    STDMETHOD(GetCurrentBuffering) (THIS_
>-                                    UINT16  uStreamNumber,
>-                                    REF(INT64)  llLowestTimestamp,
>-                                    REF(INT64)  llHighestTimestamp,
>-                                    REF(UINT32) ulNumBytes,
>-                                    REF(BOOL)   bDone) PURE;
>-    /************************************************************************
>-     * Method:
>-     *     IHXSourceBufferingStats2::GetTotalBuffering
>-     * Purpose:
>-     *     Get the total amount of data buffered for a stream.
>-     *      This includes what is in the transport buffer and in
>-     *      the renderer
>-     */
>-
>-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
>-                                  REF(INT64)  llLowestTimestamp,
>-                                  REF(INT64)  llHighestTimestamp,
>-                                  REF(UINT32) ulNumBytes,
>-                                  REF(BOOL)   bDone);
>-
>-
>      /*
>       * IHXClientRateAdaptControl Methods
>       */
>@@ -731,7 +701,7 @@
>             virtual HX_RESULT   FillRecordControl() = 0;
>                     BOOL        IsPlayingFromRecordControl() { return 
> m_bPlayFromRecordControl; };
>
>-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>
>              const char*         GetRedirectURL() { return 
> (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
>              const char*         GetSDPURL() { return (m_pSDPURL ? 
> m_pSDPURL->GetURL() : NULL); };
>@@ -769,6 +739,8 @@
>              void        ProcessFileHeader(void);
>              HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, 
> STREAM_INFO*& pStreamInfo);
>
>+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
>+
>      HX_RESULT                  mLastError;
>      CHXMapLongToObj*            mStreamInfoTable;
>
>@@ -868,6 +840,8 @@
>      CHXURL*                     m_pRedirectURL;
>      CHXURL*                     m_pSDPURL;
>      BOOL                        m_bRedirectPending;
>+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
>+    IHXSourceBufferingStats2*   m_pSrcBufStats;
>  };
>
>  // Defined flags
>Index: hxbufstate.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxbufstate.cpp,v
>retrieving revision 1.7
>diff -u -r1.7 hxbufstate.cpp
>--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
>+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
>@@ -83,18 +83,11 @@
>      , m_ulLastPacketTimeStamp(0)
>      , m_ulAvgBandwidth(0)
>      , m_pASMProps(NULL)
>-    , m_llCurrentPlaybackTime(0)
>-    , m_ulBufferedData(0)
>-    , m_ulLastTimeSync(0)
>-    , m_llFirstLivePacketTimestamp(0)
>-    , m_ulTimeSyncRollOver(0)
>  {}
>
>  HXBufferingState::~HXBufferingState()
>  {
>      HX_RELEASE(m_pASMProps);
>-
>-    ClearPktInfo();
>  }
>
>  void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
>@@ -179,8 +172,6 @@
>      m_ulLastPacketTimeStamp = 0;
>      m_bIsFirstPacket = TRUE;
>
>-    ClearPktInfo();
>-
>      if (bIsSeeking)
>      {
>         m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
>@@ -288,11 +279,6 @@
>      return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + 
> CAST_TO_INT64 ulTime;
>  }
>
>-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
>-{
>-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 
>MAX_UINT32 + CAST_TO_INT64 ulTime;
>-}
>-
>  void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>                                 UINT32 ulElapsedTime,
>                                 BOOL bIsLive, BOOL bIsBufferedPlayMode)
>@@ -318,16 +304,12 @@
>         if (bIsLive)
>         {
>             m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
>-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
>          }
>
>         m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
>         m_bIsFirstPacket = FALSE;
>      }
>
>-    // Add this packet to our packet info statistics
>-    AddPktInfo(llActualTimeStamp, ulPacketSize);
>-
>      // data based preroll
>      if (DataBasedPreroll())
>      {
>@@ -451,47 +433,6 @@
>      m_bDoneAtTransport = bDoneAtTransport;
>  }
>
>-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
>-                                             REF(INT64) llHighTimestamp,
>-                                             REF(UINT32) ulBytesBuffered,
>-                                             BOOL bUseTransportStats)
>-{
>-    HX_RESULT res = HXR_NO_DATA;
>-
>-    if (!m_bIsFirstPacket)
>-    {
>-       if (!m_pktInfo.IsEmpty())
>-       {
>-           HXBufferedPktInfo* pPktInfo =
>-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
>-
>-           llLowTimestamp = pPktInfo->Timestamp();
>-       }
>-       else
>-       {
>-           llLowTimestamp = m_llHighestTimeStamp;
>-       }
>-
>-       llHighTimestamp = m_llHighestTimeStamp;
>-       ulBytesBuffered = GetBufferedData();
>-
>-
>-       if (bUseTransportStats)
>-       {
>-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
>-           {
>-               llHighTimestamp = m_llHighestTimestampAtTransport;
>-           }
>-
>-           ulBytesBuffered += m_ulNumBytesAtTransport;
>-       }
>-
>-       res = HXR_OK;
>-    }
>-
>-    return res;
>-}
>-
>  void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
>                                            INT64 llTheHighestTS,
>                                            BOOL bIsSeekPerformed,
>@@ -569,19 +510,6 @@
>
>  }
>
>-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
>-{
>-    //  0xFA .. 0xFF [roll over] (0x01)
>-    if (m_ulLastTimeSync > ulCurrentTime &&
>-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
>-    {
>-       m_ulTimeSyncRollOver++;
>-    }
>-    m_ulLastTimeSync = ulCurrentTime;
>-
>-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
>-}
>-
>  void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
>                                         ULONG32 ulMinBufferingInMs)
>  {
>@@ -771,62 +699,4 @@
>      {
>         m_ulAvgBandwidth = ulBandwidth;
>      }
>-}
>-
>-void HXBufferingState::ClearPktInfo()
>-{
>-    m_ulBufferedData = 0;
>-    while(!m_pktInfo.IsEmpty())
>-    {
>-       HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
>-       delete pInfo;
>-    }
>-}
>-
>-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
>-{
>-    // Subtract off the first live packet timestamp.
>-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
>-    llTimestamp -= m_llFirstLivePacketTimestamp;
>-    // Create the HXBufferedPktInfo class
>-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
>-                                                       ulPacketSize);
>-    if (pPktInfo)
>-    {
>-       m_pktInfo.AddTail(pPktInfo);
>-       m_ulBufferedData += ulPacketSize;
>-    }
>-
>-    // purge the old packet info data
>-    //  this keeps the list short and prevents the Symbian
>-    //  allocator from freaking out
>-    (void)GetBufferedData();
>-}
>-
>-UINT32 HXBufferingState::GetBufferedData()
>-{
>-    BOOL bDone = m_pktInfo.IsEmpty();
>-
>-    // Remove all packet info that is past due
>-    // and subtract their sizes from our buffering total
>-    while(!bDone)
>-    {
>-       HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
>-
>-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
>-       {
>-           m_ulBufferedData -= pPktInfo->Size();
>-
>-           m_pktInfo.RemoveHead();
>-           delete pPktInfo;
>-
>-           bDone = m_pktInfo.IsEmpty();
>-       }
>-       else
>-       {
>-           bDone = TRUE;
>-       }
>-    }
>-
>-    return m_ulBufferedData;
>  }
>Index: hxbufstate.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbufstate.h,v
>retrieving revision 1.4
>diff -u -r1.4 hxbufstate.h
>--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
>+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
>@@ -81,7 +81,6 @@
>      BOOL HasPredata(BOOL bIsSeekPerformed);
>
>      INT64 CreateINT64Timestamp(UINT32 ulTime);
>-    INT64 CreateINT64Timesync(UINT32 ulTime);
>
>      void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>                   UINT32 ulElapsedTime, BOOL bIsLive,
>@@ -98,11 +97,6 @@
>                               ULONG32 ulBytesAtTransport,
>                               BOOL bDoneAtTransport);
>
>-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
>-                               REF(INT64) llHighTimestamp,
>-                               REF(UINT32) ulBytesBuffered,
>-                               BOOL bUseTransportStats);
>-
>      void GetExcessBufferInfo(INT64 llTheLowestTS,
>                              INT64 llTheHighestTS,
>                              BOOL bIsSeekPerformed,
>@@ -119,8 +113,6 @@
>
>      UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
>
>-    void OnTimeSync(UINT32 ulCurrentTime);
>-
>      // Should remove
>      void SetAvgBWToASMBw();
>      BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
>@@ -149,19 +141,6 @@
>                         UINT32 ulCurrentBuffering,
>                         UINT32 ulMinimumPreroll,
>                         UINT32 ulDenom) const;
>-
>-    /* Functions for tracking the amount of data
>-     * buffered in the renderer
>-     */
>-    void ClearPktInfo(); /* Clears out information about buffered packets */
>-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
>-                                                             * a packet is
>-                                                             * sent to the
>-                                                             * renderer
>-                                                             */
>-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
>-                              * in the renderer
>-                              */
>
>      ULONG32            m_ulPreroll;
>      ULONG32            m_ulPredata;
>@@ -196,20 +175,6 @@
>      ULONG32            m_ulLastPacketTimeStamp;
>      ULONG32            m_ulAvgBandwidth;
>      IHXASMProps*       m_pASMProps;
>-    UINT32              m_ulLastTimeSync;
>-    INT64               m_llFirstLivePacketTimestamp;
>-    UINT32              m_ulTimeSyncRollOver;
>-    // These variable keep track of the amount of
>-    // data buffered in the renderer
>-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
>-                                                 * OnTimeSync() call
>-                                                 */
>-
>-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
>-                                          * Always use GetBufferedData()
>-                                          * to retreive the value
>-                                          */
>-    CHXSimpleList       m_pktInfo; /* List of packet information */
>  };
>
>  inline
>Index: hxflsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxflsrc.cpp,v
>retrieving revision 1.54
>diff -u -r1.54 hxflsrc.cpp
>--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
>+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
>@@ -76,6 +76,7 @@
>  #include "uri_schemes.h"
>  #include "stream_desc_hlpr.h"
>  #include "findfile.h"
>+#include "hxsrcbufstats.h"
>
>  #include "hxheap.h"
>  #ifdef _DEBUG
>@@ -115,6 +116,7 @@
>      , m_bValidateMetaDone(FALSE)
>      , m_pFileRecognizer(NULL)
>      , m_pFileReader(NULL)
>+    , m_pSrcBufStats(NULL)
>  {
>      m_bAltURL = FALSE;
>      m_bPerfectPlay = TRUE;
>@@ -306,6 +308,13 @@
>
>      HX_VECTOR_DELETE(m_pszURL);
>      HX_DELETE(m_pURL);
>+
>+    HX_RELEASE(m_pSrcBufStats);
>+    m_pSrcBufStats = new HXSourceBufferStats();
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->AddRef();
>+    }
>
>      if (!theErr && pURL)
>      {
>@@ -938,6 +947,7 @@
>      }
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
>
>+    HX_RELEASE(m_pSrcBufStats);
>      HXSource::DoCleanup();
>
>      return HXR_OK;
>@@ -1068,6 +1078,11 @@
>
>      m_llLastFillEndTime = 0;
>
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->Reset();
>+    }
>+
>  cleanup:
>
>      return HXR_OK;
>@@ -1442,6 +1457,11 @@
>
>             if(m_pBufferManager)
>                 m_pBufferManager->UpdateCounters(pPacket, 0);
>+
>+            if (m_pSrcBufStats && !pPacket->IsLost())
>+            {
>+                m_pSrcBufStats->OnPacket(pPacket);
>+            }
>
>             HX_RELEASE(pPacket);
>         }
>@@ -2103,6 +2123,13 @@
>         }
>         HX_RELEASE(pszParentName);
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
>+
>+        if (pStreamInfo && m_pSrcBufStats)
>+        {
>+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
>+                                 mLiveStream);
>+        }
>+
>          m_ulStreamIndex++;
>          m_uNumStreams++;
>      }
>@@ -2115,6 +2142,11 @@
>
>         theErr = AdjustClipTime();
>         m_pBufferManager->Init();
>+
>+        if (m_pSrcBufStats)
>+        {
>+            SetSrcBufStats(m_pSrcBufStats);
>+        }
>      }
>
>      return theErr;
>@@ -2313,6 +2345,11 @@
>         {
>             m_pBufferManager->UpdateCounters(pPacket, 0);
>         }
>+
>+        if (m_pSrcBufStats && !pPacket->IsLost())
>+        {
>+            m_pSrcBufStats->OnPacket(pPacket);
>+        }
>      }
>
>      m_llLastFillEndTime = llActualPacketTime;
>Index: hxflsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxflsrc.h,v
>retrieving revision 1.12
>diff -u -r1.12 hxflsrc.h
>--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
>+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
>@@ -52,6 +52,8 @@
>  #include "hxfiles.h"
>  #include "recognizer.h"
>
>+class HXSourceBufferStats;
>+
>  class HXFileSource : public HXSource,
>                       public IHXFormatResponse,
>                        public IHXHTTPRedirectResponse
>@@ -349,6 +351,7 @@
>
>      CFileReader*                m_pFileReader;
>      CHXFileRecognizer*          m_pFileRecognizer;
>+    HXSourceBufferStats*        m_pSrcBufStats;
>  };
>
>  #endif // _HX_FILE_SOURCE
>Index: hxntsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxntsrc.cpp,v
>retrieving revision 1.90
>diff -u -r1.90 hxntsrc.cpp
>--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
>+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
>@@ -675,6 +675,7 @@
>      HX_RESULT   rc = HXR_OK;
>      BOOL        bSDPInitiated = FALSE;
>      CHXString   pString;
>+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
>
>      // start off with the preferred protocol
>      rc = CreateProtocol();
>@@ -722,6 +723,14 @@
>          goto cleanup;
>      }
>
>+    // Setup source buffer stats
>+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
>+                                           (void**)&pSrcBufStats))
>+    {
>+        SetSrcBufStats(pSrcBufStats);
>+        HX_RELEASE(pSrcBufStats);
>+    }
>+
>      // create log info list
>      m_pLogInfoList = new CHXSimpleList;
>      m_ulLogInfoLength = 0;
>@@ -6295,6 +6304,12 @@
>  #else
>      return HXR_NOTIMPL;
>  #endif /* HELIX_FEATURE_RECORDCONTROL */
>+}
>+
>+HX_RESULT
>+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
>+{
>+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
>  }
>
>  ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
>Index: hxntsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxntsrc.h,v
>retrieving revision 1.24
>diff -u -r1.24 hxntsrc.h
>--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
>+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
>@@ -282,6 +282,7 @@
>
>         virtual HX_RESULT       FillRecordControl();
>
>+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>  protected:
>
>         virtual                         ~HXNetSource(void);
>@@ -470,7 +471,6 @@
>  private:
>          IHXBufferControl*                m_pBufferCtl;
>          IHXWatermarkBufferControl*       m_pWMBufferCtl;
>-
>  public:
>         HX_RESULT       FinishSetup();
>         void            ReSetup();
>Index: hxsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxsrc.cpp,v
>retrieving revision 1.44.2.1
>diff -u -r1.44.2.1 hxsrc.cpp
>--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
>+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
>@@ -213,6 +213,8 @@
>          , m_pRedirectURL(NULL)
>          , m_pSDPURL(NULL)
>          , m_bRedirectPending(FALSE)
>+        , m_pTransOnTimeSync(NULL)
>+        , m_pSrcBufStats(NULL)
>  {
>      mStreamInfoTable = new CHXMapLongToObj;
>  }
>@@ -313,6 +315,8 @@
>      HX_DELETE(m_pRedirectURL);
>      HX_DELETE(m_pSDPURL);
>      m_bRedirectPending  = FALSE;
>+    HX_RELEASE(m_pTransOnTimeSync);
>+    HX_RELEASE(m_pSrcBufStats);
>
>  #if defined(HELIX_FEATURE_RECORDCONTROL)
>      if(m_pRecordControl)
>@@ -340,8 +344,6 @@
>              { GET_IIDHANDLE(IID_IHXPendingStatus), 
> (IHXPendingStatus*)this },
>              { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
>              { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> (IHXPrivateStreamSource*)this },
>-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
>(IHXSourceBufferingStats*)this },
>-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
>(IHXSourceBufferingStats2*)this },
>              { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
>                (IHXClientRateAdaptControl*)this },
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>@@ -388,6 +390,14 @@
>             return HXR_NOINTERFACE;
>         }
>      }
>+    else if (m_pSrcBufStats &&
>+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
>+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
>+    {
>+        m_pSrcBufStats->AddRef();
>+        *ppvObj = m_pSrcBufStats;
>+        return HXR_OK;
>+    }
>
>  #if defined(HELIX_FEATURE_AUTOUPGRADE)
>      else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
>@@ -2250,59 +2260,6 @@
>  }
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>
>-STDMETHODIMP
>-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
>-                           REF(INT64)  llLowestTimestamp,
>-                           REF(INT64)  llHighestTimestamp,
>-                           REF(UINT32) ulNumBytes,
>-                           REF(BOOL)   bDone)
>-{
>-    HX_RESULT res = HXR_NO_DATA;
>-
>-    llLowestTimestamp = 0;
>-    llHighestTimestamp = 0;
>-    ulNumBytes = 0;
>-    bDone = FALSE;
>-
>-    STREAM_INFO* pStreamInfo;
>-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& 
>)pStreamInfo))
>-    {
>-       HXBufferingState& bufState = pStreamInfo->BufferingState();
>-       BOOL   bUseTransportStats = FALSE;
>-
>-       INT64  llTransportLowTS = 0;
>-       INT64  llTransportHighTS = 0;
>-       UINT32 ulTransportBytes = 0;
>-       BOOL   bTransportDone = FALSE;
>-
>-       if (!IsLocalSource() &&
>-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
>-                                          llTransportLowTS,
>-                                          llTransportHighTS,
>-                                          ulTransportBytes,
>-                                          bTransportDone)))
>-       {
>-           bufState.UpdateTransportStats(llTransportLowTS,
>-                                         llTransportHighTS,
>-                                         ulTransportBytes,
>-                                         bTransportDone);
>-
>-           bUseTransportStats = TRUE;
>-
>-           // Update bDone with what the transport says.
>-           bDone = bTransportDone;
>-       }
>-
>-       res = bufState.GetBufferingStats(llLowestTimestamp,
>-                                       llHighestTimestamp,
>-                                       ulNumBytes,
>-                                       bUseTransportStats);
>-    }
>-
>-
>-    return res;
>-}
>-
>  /*
>   * IHXClientRateAdaptControl Methods
>   */
>@@ -2948,13 +2905,34 @@
>  {
>      HX_RESULT res = HXR_OK;
>
>-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
>-         i != mStreamInfoTable->End(); ++i)
>-    {
>-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
>-
>-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
>+    // Convert presentation time to transport time
>+    if (m_pTransOnTimeSync)
>+    {
>+        ULONG32 ulOffset = m_ulDelay;
>+        ULONG32 ulTransportTime = m_ulStartTime;
>+
>+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
>+        {
>+            ulTransportTime += ulCurrentTime - ulOffset;
>+        }
>+
>+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
>      }
>
>      return res;
>+}
>+
>+void
>+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
>+{
>+    HX_RELEASE(m_pSrcBufStats);
>+    HX_RELEASE(m_pTransOnTimeSync);
>+
>+    if (pSrcBufStats)
>+    {
>+        m_pSrcBufStats = pSrcBufStats;
>+        m_pSrcBufStats->AddRef();
>+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
>+                                       (void**)&m_pTransOnTimeSync);
>+    }
>  }
>Index: rtspprotocol.cpp
>===================================================================
>RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
>retrieving revision 1.39
>diff -u -r1.39 rtspprotocol.cpp
>--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
>+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
>@@ -2626,12 +2626,12 @@
>      UINT16 seekFrom
>  )
>  {
>+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
>+
>      if (IsLive())
>      {
>-        return m_pProtocolLib->SeekFlush();
>+        return theErr;
>      }
>-
>-    HX_RESULT theErr = HXR_OK;
>
>      m_uCurrentStreamCount = m_uStreamCount;
>
>
>Index: Umakefil
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/Umakefil,v
>retrieving revision 1.9.2.1
>diff -u -r1.9.2.1 Umakefil
>--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
>+++ Umakefil    22 Jun 2004 22:52:32 -0000
>@@ -46,6 +46,7 @@
>                           'common/runtime/pub',
>                           'common/lang/xml/pub',
>                           'client/common/container/pub',
>+                          'client/common/util/pub',
>                           'protocol/transport/rtp/include',
>                           'server/include',
>                            'server/common/struct/pub',
>@@ -65,7 +66,7 @@
>                    'rtspmsg.cpp', 'rtspmdsc.cpp',
>                    'rtsppars.cpp', 'mhprop.cpp',
>                    'servrsnd.cpp', '3gpadapthdr.cpp',
>-                   'rateadaptinfo.cpp')
>+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
>
>  if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
>      project.AddSources('pipelinedesc.cpp')
>Index: rtspclnt.cpp
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
>retrieving revision 1.79.2.1
>diff -u -r1.79.2.1 rtspclnt.cpp
>--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
>+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
>@@ -95,6 +95,7 @@
>  #include "pipelinedesc.h"
>  #include "errdbg.h"
>  #include "rateadaptinfo.h"
>+#include "ntsrcbufstats.h"
>
>  #include "hxheap.h"
>  #ifdef _DEBUG
>@@ -302,6 +303,12 @@
>      {
>          return HXR_OK;
>      }
>+    else if (m_pSrcBufStats &&
>+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
>+                                                       ppvObj)))
>+    {
>+        return HXR_OK;
>+    }
>      *ppvObj = NULL;
>      return HXR_NOINTERFACE;
>  }
>@@ -388,6 +395,7 @@
>      m_bReportedSuccessfulTransport(FALSE),
>      m_bSDPInitiated(FALSE),
>      m_bMulticast(FALSE),
>+    m_bIsLive(FALSE),
>      m_pSDPFileHeader(NULL),
>      m_pSDPStreamHeaders(NULL),
>      m_bSessionSucceeded(FALSE),
>@@ -404,7 +412,8 @@
>      m_ulCurrentTimeOut(0),
>      m_pUAProfURI(NULL),
>      m_pUAProfDiff(NULL),
>-    m_pRateAdaptInfo(NULL)
>+    m_pRateAdaptInfo(NULL),
>+    m_pSrcBufStats(NULL)
>  #if defined(_MACINTOSH)
>      , m_pCallback(NULL)
>  #endif /* _MACINTOSH */
>@@ -460,6 +469,8 @@
>          m_pRateAdaptInfo->Close();
>          HX_DELETE(m_pRateAdaptInfo);
>      }
>+
>+    HX_RELEASE(m_pSrcBufStats);
>  }
>
>  /*
>@@ -810,6 +821,21 @@
>          }
>      }
>
>+    if (HXR_OK == hresult)
>+    {
>+        HX_RELEASE(m_pSrcBufStats);
>+        m_pSrcBufStats = new HXNetSourceBufStats(this);
>+
>+        if (m_pSrcBufStats)
>+        {
>+            m_pSrcBufStats->AddRef();
>+        }
>+        else
>+        {
>+            hresult = HXR_OUTOFMEMORY;
>+        }
>+    }
>+
>  #if defined(_MACINTOSH)
>      if (m_pCallback &&
>          m_pCallback->m_bIsCallbackPending &&
>@@ -2191,7 +2217,14 @@
>          (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
>      if (pTrans)
>      {
>-        rc = pTrans->getPacket(uStreamNumber, pPacket);
>+        UINT32 uSeqNum;
>+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
>+
>+        if ((HXR_OK == rc) && m_pSrcBufStats &&
>+            (!pPacket->IsLost()))
>+        {
>+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
>+        }
>      }
>
>      m_pMutex->Unlock();
>@@ -3291,16 +3324,24 @@
>      HX_RESULT rc = HXR_OK;
>      m_pMutex->Lock();
>
>-    CHXMapLongToObj::Iterator i;
>-    for(i=m_pTransportStreamMap->Begin();
>-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
>+    if (m_bIsLive)
>      {
>-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
>-        UINT16 streamNumber = (UINT16)i.get_key();
>-
>-        HX_ASSERT(pTransport);
>+        CHXMapLongToObj::Iterator i;
>+        for(i=m_pTransportStreamMap->Begin();
>+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
>+        {
>+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
>+            UINT16 streamNumber = (UINT16)i.get_key();
>+
>+            HX_ASSERT(pTransport);
>+
>+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
>+        }
>+    }
>
>-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->Reset();
>      }
>
>      m_pMutex->Unlock();
>@@ -6964,6 +7005,11 @@
>          // Get session level RTP bandwidth modifiers
>          ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
>          ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
>+
>+        if (ulIsSessionLive)
>+        {
>+            m_bIsLive = TRUE;
>+        }
>
>          // get multicast address from the session description
>          if (HXR_OK == 
> ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
>@@ -7187,6 +7233,11 @@
>              pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
>              pInfo->m_bRealMedia = bRealMedia;
>
>+            if (m_pSrcBufStats)
>+            {
>+                m_pSrcBufStats->Init((UINT16)streamNumber, pInfo->m_bIsLive);
>+            }
>+
>              if (m_pRateAdaptInfo)
>              {
>                  m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
>@@ -7222,6 +7273,7 @@
>          if (m_bMulticast)
>          {
>              m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
>+            m_bIsLive = TRUE;
>          }
>      }
>
>Index: pub/rtspclnt.h
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
>retrieving revision 1.30.2.1
>diff -u -r1.30.2.1 rtspclnt.h
>--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
>+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
>@@ -46,6 +46,7 @@
>  #include "hxbufctl.h" // IHXTransportBufferLimit
>  #include "hxrtsp2.h"
>  #include "hxrsdbf.h" // IHXResendBufferControl
>+#include "hxprefs.h" // IHXPreferences
>
>  class RTSPClientState;
>  class RTSPOptionsMessage;
>@@ -63,6 +64,7 @@
>  class MIMEHeader;
>  class PipelinedDescribeLogic;
>  class CHXRateAdaptationInfo;
>+class HXNetSourceBufStats;
>
>  struct IHXKeyValueList;
>  struct IHXValues;
>@@ -1039,6 +1041,7 @@
>
>      BOOL                                m_bSDPInitiated;
>      BOOL                                m_bMulticast;
>+    BOOL                                m_bIsLive;
>      IHXValues*                          m_pSDPFileHeader;
>      CHXSimpleList*                      m_pSDPStreamHeaders;
>
>@@ -1074,6 +1077,7 @@
>      UINT32                              m_ulServerTimeOut;
>      UINT32                              m_ulCurrentTimeOut;
>      CHXRateAdaptationInfo*              m_pRateAdaptInfo;
>+    HXNetSourceBufStats*                m_pSrcBufStats;
>
>  #if defined(_MACINTOSH)
>      RTSPClientProtocolCallback*                m_pCallback;
>
>Index: rtsptran.cpp
>===================================================================
>RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
>retrieving revision 1.26
>diff -u -r1.26 rtsptran.cpp
>--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
>+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
>@@ -526,8 +526,17 @@
>      }
>  }
>
>+HX_RESULT
>+RTSPTransport::getPacket(UINT16 uStreamNumber,
>+                         IHXPacket*& pPacket)
>+{
>+    UINT32 uSeqNum;
>+    return getPacket(uStreamNumber, pPacket, uSeqNum);
>+}
>+
>  HX_RESULT
>-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
>+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
>+                         REF(UINT32) uSeqNum)
>  {
>      RTSPTransportBuffer* pTransportBuffer = 
> getTransportBuffer(uStreamNumber);
>      RTSPStreamData* pStreamData = 
> m_pStreamHandler->getStreamData(uStreamNumber);
>@@ -547,6 +556,7 @@
>      }
>
>      pPacket = clientPacket->GetPacket();
>+    uSeqNum = clientPacket->GetSequenceNumber();
>
>      if (!pPacket)
>      {
>Index: pub/rtsptran.h
>===================================================================
>RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
>retrieving revision 1.19
>diff -u -r1.19 rtsptran.h
>--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
>+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
>@@ -259,6 +259,9 @@
>      HX_RESULT resetFlags               (UINT16 streamNumber);
>      HX_RESULT getPacket                        (UINT16 uStreamNumber,
>                                         IHXPacket*& pPacket);
>+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
>+                                       IHXPacket*& pPacket,
>+                                         REF(UINT32) uSeqNum);
>      virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
>      virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
>
>Index: Umakefil
>===================================================================
>RCS file: /cvsroot/client/common/util/Umakefil,v
>retrieving revision 1.3
>diff -u -r1.3 Umakefil
>--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
>+++ Umakefil    22 Jun 2004 22:53:43 -0000
>@@ -53,6 +53,7 @@
>                    'chxphook.cpp',
>                    'xnetchck.cpp',
>                    'littobig.cpp',
>-                  'hxunicod.cpp')
>+                  'hxunicod.cpp',
>+                   'hxsrcbufstats.cpp')
>
>  LibraryTarget('utlclntlib')
>Index: hxcore.h
>===================================================================
>RCS file: /cvsroot/common/include/hxcore.h,v
>retrieving revision 1.5
>diff -u -r1.5 hxcore.h
>--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
>+++ hxcore.h    22 Jun 2004 23:00:23 -0000
>@@ -2060,7 +2060,50 @@
>
>  // $EndPrivate.
>
>+// $Private:
>
>+/****************************************************************************
>+ *
>+ *  Interface:
>+ *
>+ *     IID_IHXTransportOnTimeSync
>+ *
>+ *  Purpose:
>+ *
>+ *     This interface is used to send OnTimeSync() calls down
>+ *      to the transport layer. Note that the value passed to
>+ *      OnTimeSync() MUST be in the same units and have the same
>+ *      offset as the packets coming from the transport. This means
>+ *      that any offets caused by SMIL or live playback must be
>+ *      removed before calling OnTimeSync() on this interface
>+ *
>+ *      IID_IHXTransportOnTimeSync
>+ *
>+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
>+ *
>+ */
>+DEFINE_GUID(IID_IHXTransportOnTimeSync,
>+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1);
>+
>+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
>+{
>+    /*
>+     * IUnknown methods
>+     */
>+
>+    STDMETHOD(QueryInterface)  (THIS_
>+                               REFIID riid,
>+                               void** ppvObj) PURE;
>+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
>+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
>+
>+    /*
>+     * IHXTransportOnTimeSync methods
>+     */
>+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
>+};
>+
>+// $EndPrivate.
>
>  #endif /* _HXCORE_H_ */
>
>Index: hxpiids.h
>===================================================================
>RCS file: /cvsroot/common/include/hxpiids.h,v
>retrieving revision 1.28.2.1
>diff -u -r1.28.2.1 hxpiids.h
>--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
>+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
>@@ -533,6 +533,7 @@
>  DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 
> 0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
>  DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 
> 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
>  DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 
> 0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 
> 0xa9,  0x69,  0x37,  0x3b,  0x4d)
>+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 
>0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
>  #endif /* _HXCORE_H_ */
>
>  /*
>
>
>
>
>_______________________________________________
>Client-dev mailing list
>Client-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/client-dev


From acolwell at real.com  Wed Jun 23 10:31:16 2004
From: acolwell at real.com (Aaron Colwell)
Date: Wed Jun 23 10:33:12 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Moving
	IHXSourceBufferingStats2 implementation
In-Reply-To: <5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
References: <20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
Message-ID: <20040623173116.GC7758@real.com>

On Wed, Jun 23, 2004 at 10:06:30AM -0700, Henry Ping wrote:
> - m_pSrcBufStats in hxflsrc.cpp needs to take a closer look, it's a bit 
> confusing:
> 1. its definition is different from the base class, HXSourceBufferStats* 
> instead of IHXSourceBufferingStats2*
> hxbsrc.h: +    IHXSourceBufferingStats2*   m_pSrcBufStats;
> hxflsrc.h: +    HXSourceBufferStats*        m_pSrcBufStats;

Good catch. The HXSource member variable is used to provide the 
IHXSourceBufferingStats2 interface to the rest of the core. The HXFileSource 
member variable is used to pass in the packet information.


> 2. it's first assigned with "new HXSourceBufferStats()", but then is 
> re-assigned in SetSrcBufStats()

They are 2 seperate member variables. I just happened to name them the same
which makes things confusing. I've renamed the one in HXFileSource to
m_pHXSrcBufStats so that it is easier to see that they are 2 different member
variables.

> 
> - do you think we need to addref the m_pProto in HXNetSourceBufStats?

Yes your right. I forgot that someone else could have a handle to this object
even after m_pProto gets destroyed. I'll make the appropriate fixes.

> 
> - do you think we need to return error if Init() is not called beforehand 
> in HXSourceBufferStats?

Are you suggesting that GetCurrentBuffering() and GetTotalBuffering() should
return an error if Init() has not been called for the requested stream? If so,
then I am ok with that idea.


> 
> -->Henry
> 
> At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
> >Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> >          number information can be maintained as well.
> >
> >Overview: These changes move the IHXSourceBufferingStats2 implementation
> >          out of HXBufferingState and into a new class called
> >          HXSourceBufferStats. This was done because the client needs to
> >          track packet sequence numbers for 3GPP-Rel6 OBSN support.
> >          There was no good way to get the sequence number information to
> >          the HXBufferingState class so the IHXSourceBufferingStats2 logic
> >          was moved to where this information is available.
> >
> >          A new interface called IHXTransportOnTimeSync was created to
> >          propagate OnTimeSync() like calls to HXSourceBufferStats. The
> >          time passed to the OnTimeSync() call in this interface MUST
> >          NOT have any offsets created by SMIL or live playback. The time
> >          should be in the same time frame as the packets coming from the
> >          transport. If someone wants to rename this interface that is fine
> >          by me.
> >
> >
> >          - Created HXSourceBufferStats to contain the base
> >            IHXSourceBufferingStats2 implementation. This class is
> >            used by HXFileSource.
> >
> >          - Created HXNetSourceBufStats which derives from 
> >HXSourceBufferStats.
> >            This class just overloads the GetCurrentBuffering() so that it
> >            returns the amount of data in the transport buffer. This is
> >            used by RTSPClientProtocol.
> >
> >          - Removed IHXSourceBufferingStats2 code from HXSource
> >
> >          - Removed packet tracking code from HXBufferingState. This
> >            functionality is implemented by HXSourceBufferStats now
> >
> >          - Added code to HXSource to provide OnTimeSync() calls to the
> >            IHXTransportOnTimeSync interface.
> >
> >          - HXSource now exposes IHXSourceBufferingStats functionality 
> >through
> >            it's m_pSrcBufStats member variable instead of implementing it
> >            itself. The file and network sources are expected to provide an
> >            IHXSourceBufferingStats2 interface via a
> >            HXSource::SetSrcBufStats() call.
> >
> >          - Added code to HXFileSource to use HXSourceBufferStats
> >
> >          - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> >
> >          - Fixed some code in CBufferManager that was expecting HXSource
> >            to implement IHXSourceBufferingStats. This code now QI's for
> >            IHXSourceBufferingStats and uses that interface.
> >
> >
> >
> >Files Modified:
> >client/core/buffmgr.cpp
> >client/core/hxbsrc.h
> >client/core/hxbufstate.h
> >client/core/hxbufstate.cpp
> >client/core/hxflsrc.cpp
> >client/core/hxflsrc.h
> >client/core/hxntsrc.cpp
> >client/core/hxntsrc.h
> >client/core/hxsrc.cpp
> >client/core/rtspprotocol.cpp
> >protocol/rtsp/Umakefil
> >protocol/rtsp/rtspclnt.cpp
> >protocol/rtsp/pub/rtspclnt.h
> >protocol/transport/common/system/rtsptran.cpp
> >protocol/transport/common/system/pub/rtsptran.h
> >client/common/util/Umakefil
> >common/include/hxcore.h
> >common/include/hxpiids.h
> >
> >Files Added:
> >client/common/util/pub/hxsrcbufstats.h
> >client/common/util/hxsrcbufstats.cpp
> >protocol/rtsp/ntsrcbufstats.h
> >protocol/rtsp/ntsrcbufstats.cpp
> >
> >Image Size and Heap Use impact:
> >
> >Platforms and Profiles affected: all
> >
> >Distribution Libraries affected: rdtclntlib
> >
> >Distribution library impact and planned action:
> >m_bIsLive and m_pSrcBufStats member variables were added to
> >RTSPClientProtocol so any derived objects will need to be
> >recompiled
> >
> >Platforms and Profiles Build Verified: win32
> >
> >Platforms and Profiles Functionality verified: win32
> >
> >Branch: HEAD
> >
> >QA Instructions: none
> >
> >Index: buffmgr.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/buffmgr.cpp,v
> >retrieving revision 1.21
> >diff -u -r1.21 buffmgr.cpp
> >--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
> >+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> >@@ -610,6 +610,11 @@
> >      * - Keep track of the stream with the lowest timestamp and is
> >      *   buffering data
> >      */
> >+    IHXSourceBufferingStats* pSrcBufStats = NULL;
> >+
> >+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> >+                              (void**)&pSrcBufStats);
> >+
> >     for (i = m_pStreamInfoTable->Begin(); i != 
> >m_pStreamInfoTable->End(); ++i)
> >     {
> >        pStreamInfo = (STREAM_INFO*) (*i);
> >@@ -619,12 +624,15 @@
> >        ULONG32 ulNumBytesAtTransport = 0;
> >        BOOL bDoneAtTransport = FALSE;
> >
> >-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> >-                                      llLowestTimestampAtTransport,
> >-                                      llHighestTimestampAtTransport,
> >-                                      ulNumBytesAtTransport,
> >-                                      bDoneAtTransport);
> >-
> >+        if (pSrcBufStats)
> >+        {
> >+            
> >pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> >+                                              
> >llLowestTimestampAtTransport,
> >+                                              
> >llHighestTimestampAtTransport,
> >+                                              ulNumBytesAtTransport,
> >+                                              bDoneAtTransport);
> >+        }
> >+
> >        pStreamInfo->BufferingState().UpdateTransportStats(
> >            llLowestTimestampAtTransport,
> >            llHighestTimestampAtTransport,
> >@@ -658,6 +666,7 @@
> >
> >        }
> >     }
> >+    HX_RELEASE(pSrcBufStats);
> >
> >     /* If none of the streams have any data buffered at the transport 
> >     layer,
> >      * return.
> >Index: hxbsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbsrc.h,v
> >retrieving revision 1.18.2.1
> >diff -u -r1.18.2.1 hxbsrc.h
> >--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
> >+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
> >@@ -233,12 +233,11 @@
> >                  public IHXPrivateStreamSource,
> >                  public IHXBackChannel,
> >                  public IHXASMSource,
> >-                  public IHXClientRateAdaptControl,
> >+                  public IHXClientRateAdaptControl
> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >-                 public IHXHyperNavigate,
> >-                 public IHXHyperNavigate2,
> >+                 , public IHXHyperNavigate,
> >+                 public IHXHyperNavigate2
> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >-                  public IHXSourceBufferingStats2
> > {
> > protected:
> >     LONG32                     m_lRefCount;
> >@@ -487,35 +486,6 @@
> >                            IHXValues* pParams);
> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >
> >-    
> >/************************************************************************
> >-     * Method:
> >-     *     IHXSourceBufferingStats2::GetCurrentBuffering
> >-     * Purpose:
> >-     *     Get the current buffering information
> >-     */
> >-
> >-    STDMETHOD(GetCurrentBuffering) (THIS_
> >-                                    UINT16  uStreamNumber,
> >-                                    REF(INT64)  llLowestTimestamp,
> >-                                    REF(INT64)  llHighestTimestamp,
> >-                                    REF(UINT32) ulNumBytes,
> >-                                    REF(BOOL)   bDone) PURE;
> >-    
> >/************************************************************************
> >-     * Method:
> >-     *     IHXSourceBufferingStats2::GetTotalBuffering
> >-     * Purpose:
> >-     *     Get the total amount of data buffered for a stream.
> >-     *      This includes what is in the transport buffer and in
> >-     *      the renderer
> >-     */
> >-
> >-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> >-                                  REF(INT64)  llLowestTimestamp,
> >-                                  REF(INT64)  llHighestTimestamp,
> >-                                  REF(UINT32) ulNumBytes,
> >-                                  REF(BOOL)   bDone);
> >-
> >-
> >     /*
> >      * IHXClientRateAdaptControl Methods
> >      */
> >@@ -731,7 +701,7 @@
> >            virtual HX_RESULT   FillRecordControl() = 0;
> >                    BOOL        IsPlayingFromRecordControl() { return 
> >m_bPlayFromRecordControl; };
> >
> >-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >
> >             const char*         GetRedirectURL() { return 
> >(m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
> >             const char*         GetSDPURL() { return (m_pSDPURL ? 
> >m_pSDPURL->GetURL() : NULL); };
> >@@ -769,6 +739,8 @@
> >             void        ProcessFileHeader(void);
> >             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, 
> >STREAM_INFO*& pStreamInfo);
> >
> >+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> >+
> >     HX_RESULT                  mLastError;
> >     CHXMapLongToObj*            mStreamInfoTable;
> >
> >@@ -868,6 +840,8 @@
> >     CHXURL*                     m_pRedirectURL;
> >     CHXURL*                     m_pSDPURL;
> >     BOOL                        m_bRedirectPending;
> >+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> >+    IHXSourceBufferingStats2*   m_pSrcBufStats;
> > };
> >
> > // Defined flags
> >Index: hxbufstate.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> >retrieving revision 1.7
> >diff -u -r1.7 hxbufstate.cpp
> >--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
> >+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
> >@@ -83,18 +83,11 @@
> >     , m_ulLastPacketTimeStamp(0)
> >     , m_ulAvgBandwidth(0)
> >     , m_pASMProps(NULL)
> >-    , m_llCurrentPlaybackTime(0)
> >-    , m_ulBufferedData(0)
> >-    , m_ulLastTimeSync(0)
> >-    , m_llFirstLivePacketTimestamp(0)
> >-    , m_ulTimeSyncRollOver(0)
> > {}
> >
> > HXBufferingState::~HXBufferingState()
> > {
> >     HX_RELEASE(m_pASMProps);
> >-
> >-    ClearPktInfo();
> > }
> >
> > void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> >@@ -179,8 +172,6 @@
> >     m_ulLastPacketTimeStamp = 0;
> >     m_bIsFirstPacket = TRUE;
> >
> >-    ClearPktInfo();
> >-
> >     if (bIsSeeking)
> >     {
> >        m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> >@@ -288,11 +279,6 @@
> >     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + 
> >CAST_TO_INT64 ulTime;
> > }
> >
> >-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> >-{
> >-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 
> >MAX_UINT32 + CAST_TO_INT64 ulTime;
> >-}
> >-
> > void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> >                                UINT32 ulElapsedTime,
> >                                BOOL bIsLive, BOOL bIsBufferedPlayMode)
> >@@ -318,16 +304,12 @@
> >        if (bIsLive)
> >        {
> >            m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
> >         }
> >
> >        m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >        m_bIsFirstPacket = FALSE;
> >     }
> >
> >-    // Add this packet to our packet info statistics
> >-    AddPktInfo(llActualTimeStamp, ulPacketSize);
> >-
> >     // data based preroll
> >     if (DataBasedPreroll())
> >     {
> >@@ -451,47 +433,6 @@
> >     m_bDoneAtTransport = bDoneAtTransport;
> > }
> >
> >-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
> >-                                             REF(INT64) llHighTimestamp,
> >-                                             REF(UINT32) ulBytesBuffered,
> >-                                             BOOL bUseTransportStats)
> >-{
> >-    HX_RESULT res = HXR_NO_DATA;
> >-
> >-    if (!m_bIsFirstPacket)
> >-    {
> >-       if (!m_pktInfo.IsEmpty())
> >-       {
> >-           HXBufferedPktInfo* pPktInfo =
> >-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
> >-
> >-           llLowTimestamp = pPktInfo->Timestamp();
> >-       }
> >-       else
> >-       {
> >-           llLowTimestamp = m_llHighestTimeStamp;
> >-       }
> >-
> >-       llHighTimestamp = m_llHighestTimeStamp;
> >-       ulBytesBuffered = GetBufferedData();
> >-
> >-
> >-       if (bUseTransportStats)
> >-       {
> >-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
> >-           {
> >-               llHighTimestamp = m_llHighestTimestampAtTransport;
> >-           }
> >-
> >-           ulBytesBuffered += m_ulNumBytesAtTransport;
> >-       }
> >-
> >-       res = HXR_OK;
> >-    }
> >-
> >-    return res;
> >-}
> >-
> > void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
> >                                           INT64 llTheHighestTS,
> >                                           BOOL bIsSeekPerformed,
> >@@ -569,19 +510,6 @@
> >
> > }
> >
> >-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> >-{
> >-    //  0xFA .. 0xFF [roll over] (0x01)
> >-    if (m_ulLastTimeSync > ulCurrentTime &&
> >-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> >-    {
> >-       m_ulTimeSyncRollOver++;
> >-    }
> >-    m_ulLastTimeSync = ulCurrentTime;
> >-
> >-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> >-}
> >-
> > void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
> >                                        ULONG32 ulMinBufferingInMs)
> > {
> >@@ -771,62 +699,4 @@
> >     {
> >        m_ulAvgBandwidth = ulBandwidth;
> >     }
> >-}
> >-
> >-void HXBufferingState::ClearPktInfo()
> >-{
> >-    m_ulBufferedData = 0;
> >-    while(!m_pktInfo.IsEmpty())
> >-    {
> >-       HXBufferedPktInfo* pInfo = 
> >(HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> >-       delete pInfo;
> >-    }
> >-}
> >-
> >-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
> >-{
> >-    // Subtract off the first live packet timestamp.
> >-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> >-    llTimestamp -= m_llFirstLivePacketTimestamp;
> >-    // Create the HXBufferedPktInfo class
> >-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
> >-                                                       ulPacketSize);
> >-    if (pPktInfo)
> >-    {
> >-       m_pktInfo.AddTail(pPktInfo);
> >-       m_ulBufferedData += ulPacketSize;
> >-    }
> >-
> >-    // purge the old packet info data
> >-    //  this keeps the list short and prevents the Symbian
> >-    //  allocator from freaking out
> >-    (void)GetBufferedData();
> >-}
> >-
> >-UINT32 HXBufferingState::GetBufferedData()
> >-{
> >-    BOOL bDone = m_pktInfo.IsEmpty();
> >-
> >-    // Remove all packet info that is past due
> >-    // and subtract their sizes from our buffering total
> >-    while(!bDone)
> >-    {
> >-       HXBufferedPktInfo* pPktInfo = 
> >(HXBufferedPktInfo*)m_pktInfo.GetHead();
> >-
> >-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> >-       {
> >-           m_ulBufferedData -= pPktInfo->Size();
> >-
> >-           m_pktInfo.RemoveHead();
> >-           delete pPktInfo;
> >-
> >-           bDone = m_pktInfo.IsEmpty();
> >-       }
> >-       else
> >-       {
> >-           bDone = TRUE;
> >-       }
> >-    }
> >-
> >-    return m_ulBufferedData;
> > }
> >Index: hxbufstate.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxbufstate.h,v
> >retrieving revision 1.4
> >diff -u -r1.4 hxbufstate.h
> >--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
> >+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
> >@@ -81,7 +81,6 @@
> >     BOOL HasPredata(BOOL bIsSeekPerformed);
> >
> >     INT64 CreateINT64Timestamp(UINT32 ulTime);
> >-    INT64 CreateINT64Timesync(UINT32 ulTime);
> >
> >     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> >                  UINT32 ulElapsedTime, BOOL bIsLive,
> >@@ -98,11 +97,6 @@
> >                              ULONG32 ulBytesAtTransport,
> >                              BOOL bDoneAtTransport);
> >
> >-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
> >-                               REF(INT64) llHighTimestamp,
> >-                               REF(UINT32) ulBytesBuffered,
> >-                               BOOL bUseTransportStats);
> >-
> >     void GetExcessBufferInfo(INT64 llTheLowestTS,
> >                             INT64 llTheHighestTS,
> >                             BOOL bIsSeekPerformed,
> >@@ -119,8 +113,6 @@
> >
> >     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
> >
> >-    void OnTimeSync(UINT32 ulCurrentTime);
> >-
> >     // Should remove
> >     void SetAvgBWToASMBw();
> >     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> >@@ -149,19 +141,6 @@
> >                        UINT32 ulCurrentBuffering,
> >                        UINT32 ulMinimumPreroll,
> >                        UINT32 ulDenom) const;
> >-
> >-    /* Functions for tracking the amount of data
> >-     * buffered in the renderer
> >-     */
> >-    void ClearPktInfo(); /* Clears out information about buffered packets 
> >*/
> >-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called 
> >when
> >-                                                             * a packet is
> >-                                                             * sent to the
> >-                                                             * renderer
> >-                                                             */
> >-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
> >-                              * in the renderer
> >-                              */
> >
> >     ULONG32            m_ulPreroll;
> >     ULONG32            m_ulPredata;
> >@@ -196,20 +175,6 @@
> >     ULONG32            m_ulLastPacketTimeStamp;
> >     ULONG32            m_ulAvgBandwidth;
> >     IHXASMProps*       m_pASMProps;
> >-    UINT32              m_ulLastTimeSync;
> >-    INT64               m_llFirstLivePacketTimestamp;
> >-    UINT32              m_ulTimeSyncRollOver;
> >-    // These variable keep track of the amount of
> >-    // data buffered in the renderer
> >-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
> >-                                                 * OnTimeSync() call
> >-                                                 */
> >-
> >-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> >-                                          * Always use GetBufferedData()
> >-                                          * to retreive the value
> >-                                          */
> >-    CHXSimpleList       m_pktInfo; /* List of packet information */
> > };
> >
> > inline
> >Index: hxflsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> >retrieving revision 1.54
> >diff -u -r1.54 hxflsrc.cpp
> >--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
> >+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> >@@ -76,6 +76,7 @@
> > #include "uri_schemes.h"
> > #include "stream_desc_hlpr.h"
> > #include "findfile.h"
> >+#include "hxsrcbufstats.h"
> >
> > #include "hxheap.h"
> > #ifdef _DEBUG
> >@@ -115,6 +116,7 @@
> >     , m_bValidateMetaDone(FALSE)
> >     , m_pFileRecognizer(NULL)
> >     , m_pFileReader(NULL)
> >+    , m_pSrcBufStats(NULL)
> > {
> >     m_bAltURL = FALSE;
> >     m_bPerfectPlay = TRUE;
> >@@ -306,6 +308,13 @@
> >
> >     HX_VECTOR_DELETE(m_pszURL);
> >     HX_DELETE(m_pURL);
> >+
> >+    HX_RELEASE(m_pSrcBufStats);
> >+    m_pSrcBufStats = new HXSourceBufferStats();
> >+    if (m_pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats->AddRef();
> >+    }
> >
> >     if (!theErr && pURL)
> >     {
> >@@ -938,6 +947,7 @@
> >     }
> > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
> >
> >+    HX_RELEASE(m_pSrcBufStats);
> >     HXSource::DoCleanup();
> >
> >     return HXR_OK;
> >@@ -1068,6 +1078,11 @@
> >
> >     m_llLastFillEndTime = 0;
> >
> >+    if (m_pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats->Reset();
> >+    }
> >+
> > cleanup:
> >
> >     return HXR_OK;
> >@@ -1442,6 +1457,11 @@
> >
> >            if(m_pBufferManager)
> >                m_pBufferManager->UpdateCounters(pPacket, 0);
> >+
> >+            if (m_pSrcBufStats && !pPacket->IsLost())
> >+            {
> >+                m_pSrcBufStats->OnPacket(pPacket);
> >+            }
> >
> >            HX_RELEASE(pPacket);
> >        }
> >@@ -2103,6 +2123,13 @@
> >        }
> >        HX_RELEASE(pszParentName);
> > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> >+
> >+        if (pStreamInfo && m_pSrcBufStats)
> >+        {
> >+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> >+                                 mLiveStream);
> >+        }
> >+
> >         m_ulStreamIndex++;
> >         m_uNumStreams++;
> >     }
> >@@ -2115,6 +2142,11 @@
> >
> >        theErr = AdjustClipTime();
> >        m_pBufferManager->Init();
> >+
> >+        if (m_pSrcBufStats)
> >+        {
> >+            SetSrcBufStats(m_pSrcBufStats);
> >+        }
> >     }
> >
> >     return theErr;
> >@@ -2313,6 +2345,11 @@
> >        {
> >            m_pBufferManager->UpdateCounters(pPacket, 0);
> >        }
> >+
> >+        if (m_pSrcBufStats && !pPacket->IsLost())
> >+        {
> >+            m_pSrcBufStats->OnPacket(pPacket);
> >+        }
> >     }
> >
> >     m_llLastFillEndTime = llActualPacketTime;
> >Index: hxflsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxflsrc.h,v
> >retrieving revision 1.12
> >diff -u -r1.12 hxflsrc.h
> >--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
> >+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
> >@@ -52,6 +52,8 @@
> > #include "hxfiles.h"
> > #include "recognizer.h"
> >
> >+class HXSourceBufferStats;
> >+
> > class HXFileSource : public HXSource,
> >                      public IHXFormatResponse,
> >                       public IHXHTTPRedirectResponse
> >@@ -349,6 +351,7 @@
> >
> >     CFileReader*                m_pFileReader;
> >     CHXFileRecognizer*          m_pFileRecognizer;
> >+    HXSourceBufferStats*        m_pSrcBufStats;
> > };
> >
> > #endif // _HX_FILE_SOURCE
> >Index: hxntsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> >retrieving revision 1.90
> >diff -u -r1.90 hxntsrc.cpp
> >--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
> >+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> >@@ -675,6 +675,7 @@
> >     HX_RESULT   rc = HXR_OK;
> >     BOOL        bSDPInitiated = FALSE;
> >     CHXString   pString;
> >+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
> >
> >     // start off with the preferred protocol
> >     rc = CreateProtocol();
> >@@ -722,6 +723,14 @@
> >         goto cleanup;
> >     }
> >
> >+    // Setup source buffer stats
> >+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> >+                                           (void**)&pSrcBufStats))
> >+    {
> >+        SetSrcBufStats(pSrcBufStats);
> >+        HX_RELEASE(pSrcBufStats);
> >+    }
> >+
> >     // create log info list
> >     m_pLogInfoList = new CHXSimpleList;
> >     m_ulLogInfoLength = 0;
> >@@ -6295,6 +6304,12 @@
> > #else
> >     return HXR_NOTIMPL;
> > #endif /* HELIX_FEATURE_RECORDCONTROL */
> >+}
> >+
> >+HX_RESULT
> >+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> >+{
> >+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
> > }
> >
> > ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> >Index: hxntsrc.h
> >===================================================================
> >RCS file: /cvsroot/client/core/hxntsrc.h,v
> >retrieving revision 1.24
> >diff -u -r1.24 hxntsrc.h
> >--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
> >+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
> >@@ -282,6 +282,7 @@
> >
> >        virtual HX_RESULT       FillRecordControl();
> >
> >+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > protected:
> >
> >        virtual                         ~HXNetSource(void);
> >@@ -470,7 +471,6 @@
> > private:
> >         IHXBufferControl*                m_pBufferCtl;
> >         IHXWatermarkBufferControl*       m_pWMBufferCtl;
> >-
> > public:
> >        HX_RESULT       FinishSetup();
> >        void            ReSetup();
> >Index: hxsrc.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/hxsrc.cpp,v
> >retrieving revision 1.44.2.1
> >diff -u -r1.44.2.1 hxsrc.cpp
> >--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
> >+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
> >@@ -213,6 +213,8 @@
> >         , m_pRedirectURL(NULL)
> >         , m_pSDPURL(NULL)
> >         , m_bRedirectPending(FALSE)
> >+        , m_pTransOnTimeSync(NULL)
> >+        , m_pSrcBufStats(NULL)
> > {
> >     mStreamInfoTable = new CHXMapLongToObj;
> > }
> >@@ -313,6 +315,8 @@
> >     HX_DELETE(m_pRedirectURL);
> >     HX_DELETE(m_pSDPURL);
> >     m_bRedirectPending  = FALSE;
> >+    HX_RELEASE(m_pTransOnTimeSync);
> >+    HX_RELEASE(m_pSrcBufStats);
> >
> > #if defined(HELIX_FEATURE_RECORDCONTROL)
> >     if(m_pRecordControl)
> >@@ -340,8 +344,6 @@
> >             { GET_IIDHANDLE(IID_IHXPendingStatus), 
> >(IHXPendingStatus*)this },
> >             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
> >             { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> >(IHXPrivateStreamSource*)this },
> >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
> >(IHXSourceBufferingStats*)this },
> >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
> >(IHXSourceBufferingStats2*)this },
> >             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
> >               (IHXClientRateAdaptControl*)this },
> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >@@ -388,6 +390,14 @@
> >            return HXR_NOINTERFACE;
> >        }
> >     }
> >+    else if (m_pSrcBufStats &&
> >+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> >+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> >+    {
> >+        m_pSrcBufStats->AddRef();
> >+        *ppvObj = m_pSrcBufStats;
> >+        return HXR_OK;
> >+    }
> >
> > #if defined(HELIX_FEATURE_AUTOUPGRADE)
> >     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> >@@ -2250,59 +2260,6 @@
> > }
> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >
> >-STDMETHODIMP
> >-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> >-                           REF(INT64)  llLowestTimestamp,
> >-                           REF(INT64)  llHighestTimestamp,
> >-                           REF(UINT32) ulNumBytes,
> >-                           REF(BOOL)   bDone)
> >-{
> >-    HX_RESULT res = HXR_NO_DATA;
> >-
> >-    llLowestTimestamp = 0;
> >-    llHighestTimestamp = 0;
> >-    ulNumBytes = 0;
> >-    bDone = FALSE;
> >-
> >-    STREAM_INFO* pStreamInfo;
> >-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& 
> >)pStreamInfo))
> >-    {
> >-       HXBufferingState& bufState = pStreamInfo->BufferingState();
> >-       BOOL   bUseTransportStats = FALSE;
> >-
> >-       INT64  llTransportLowTS = 0;
> >-       INT64  llTransportHighTS = 0;
> >-       UINT32 ulTransportBytes = 0;
> >-       BOOL   bTransportDone = FALSE;
> >-
> >-       if (!IsLocalSource() &&
> >-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
> >-                                          llTransportLowTS,
> >-                                          llTransportHighTS,
> >-                                          ulTransportBytes,
> >-                                          bTransportDone)))
> >-       {
> >-           bufState.UpdateTransportStats(llTransportLowTS,
> >-                                         llTransportHighTS,
> >-                                         ulTransportBytes,
> >-                                         bTransportDone);
> >-
> >-           bUseTransportStats = TRUE;
> >-
> >-           // Update bDone with what the transport says.
> >-           bDone = bTransportDone;
> >-       }
> >-
> >-       res = bufState.GetBufferingStats(llLowestTimestamp,
> >-                                       llHighestTimestamp,
> >-                                       ulNumBytes,
> >-                                       bUseTransportStats);
> >-    }
> >-
> >-
> >-    return res;
> >-}
> >-
> > /*
> >  * IHXClientRateAdaptControl Methods
> >  */
> >@@ -2948,13 +2905,34 @@
> > {
> >     HX_RESULT res = HXR_OK;
> >
> >-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> >-         i != mStreamInfoTable->End(); ++i)
> >-    {
> >-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> >-
> >-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> >+    // Convert presentation time to transport time
> >+    if (m_pTransOnTimeSync)
> >+    {
> >+        ULONG32 ulOffset = m_ulDelay;
> >+        ULONG32 ulTransportTime = m_ulStartTime;
> >+
> >+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> >+        {
> >+            ulTransportTime += ulCurrentTime - ulOffset;
> >+        }
> >+
> >+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
> >     }
> >
> >     return res;
> >+}
> >+
> >+void
> >+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> >+{
> >+    HX_RELEASE(m_pSrcBufStats);
> >+    HX_RELEASE(m_pTransOnTimeSync);
> >+
> >+    if (pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats = pSrcBufStats;
> >+        m_pSrcBufStats->AddRef();
> >+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> >+                                       (void**)&m_pTransOnTimeSync);
> >+    }
> > }
> >Index: rtspprotocol.cpp
> >===================================================================
> >RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> >retrieving revision 1.39
> >diff -u -r1.39 rtspprotocol.cpp
> >--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
> >+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
> >@@ -2626,12 +2626,12 @@
> >     UINT16 seekFrom
> > )
> > {
> >+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> >+
> >     if (IsLive())
> >     {
> >-        return m_pProtocolLib->SeekFlush();
> >+        return theErr;
> >     }
> >-
> >-    HX_RESULT theErr = HXR_OK;
> >
> >     m_uCurrentStreamCount = m_uStreamCount;
> >
> >
> >Index: Umakefil
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> >retrieving revision 1.9.2.1
> >diff -u -r1.9.2.1 Umakefil
> >--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
> >+++ Umakefil    22 Jun 2004 22:52:32 -0000
> >@@ -46,6 +46,7 @@
> >                          'common/runtime/pub',
> >                          'common/lang/xml/pub',
> >                          'client/common/container/pub',
> >+                          'client/common/util/pub',
> >                          'protocol/transport/rtp/include',
> >                          'server/include',
> >                           'server/common/struct/pub',
> >@@ -65,7 +66,7 @@
> >                   'rtspmsg.cpp', 'rtspmdsc.cpp',
> >                   'rtsppars.cpp', 'mhprop.cpp',
> >                   'servrsnd.cpp', '3gpadapthdr.cpp',
> >-                   'rateadaptinfo.cpp')
> >+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
> >
> > if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
> >     project.AddSources('pipelinedesc.cpp')
> >Index: rtspclnt.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> >retrieving revision 1.79.2.1
> >diff -u -r1.79.2.1 rtspclnt.cpp
> >--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
> >+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
> >@@ -95,6 +95,7 @@
> > #include "pipelinedesc.h"
> > #include "errdbg.h"
> > #include "rateadaptinfo.h"
> >+#include "ntsrcbufstats.h"
> >
> > #include "hxheap.h"
> > #ifdef _DEBUG
> >@@ -302,6 +303,12 @@
> >     {
> >         return HXR_OK;
> >     }
> >+    else if (m_pSrcBufStats &&
> >+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> >+                                                       ppvObj)))
> >+    {
> >+        return HXR_OK;
> >+    }
> >     *ppvObj = NULL;
> >     return HXR_NOINTERFACE;
> > }
> >@@ -388,6 +395,7 @@
> >     m_bReportedSuccessfulTransport(FALSE),
> >     m_bSDPInitiated(FALSE),
> >     m_bMulticast(FALSE),
> >+    m_bIsLive(FALSE),
> >     m_pSDPFileHeader(NULL),
> >     m_pSDPStreamHeaders(NULL),
> >     m_bSessionSucceeded(FALSE),
> >@@ -404,7 +412,8 @@
> >     m_ulCurrentTimeOut(0),
> >     m_pUAProfURI(NULL),
> >     m_pUAProfDiff(NULL),
> >-    m_pRateAdaptInfo(NULL)
> >+    m_pRateAdaptInfo(NULL),
> >+    m_pSrcBufStats(NULL)
> > #if defined(_MACINTOSH)
> >     , m_pCallback(NULL)
> > #endif /* _MACINTOSH */
> >@@ -460,6 +469,8 @@
> >         m_pRateAdaptInfo->Close();
> >         HX_DELETE(m_pRateAdaptInfo);
> >     }
> >+
> >+    HX_RELEASE(m_pSrcBufStats);
> > }
> >
> > /*
> >@@ -810,6 +821,21 @@
> >         }
> >     }
> >
> >+    if (HXR_OK == hresult)
> >+    {
> >+        HX_RELEASE(m_pSrcBufStats);
> >+        m_pSrcBufStats = new HXNetSourceBufStats(this);
> >+
> >+        if (m_pSrcBufStats)
> >+        {
> >+            m_pSrcBufStats->AddRef();
> >+        }
> >+        else
> >+        {
> >+            hresult = HXR_OUTOFMEMORY;
> >+        }
> >+    }
> >+
> > #if defined(_MACINTOSH)
> >     if (m_pCallback &&
> >         m_pCallback->m_bIsCallbackPending &&
> >@@ -2191,7 +2217,14 @@
> >         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> >     if (pTrans)
> >     {
> >-        rc = pTrans->getPacket(uStreamNumber, pPacket);
> >+        UINT32 uSeqNum;
> >+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> >+
> >+        if ((HXR_OK == rc) && m_pSrcBufStats &&
> >+            (!pPacket->IsLost()))
> >+        {
> >+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> >+        }
> >     }
> >
> >     m_pMutex->Unlock();
> >@@ -3291,16 +3324,24 @@
> >     HX_RESULT rc = HXR_OK;
> >     m_pMutex->Lock();
> >
> >-    CHXMapLongToObj::Iterator i;
> >-    for(i=m_pTransportStreamMap->Begin();
> >-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> >+    if (m_bIsLive)
> >     {
> >-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> >-        UINT16 streamNumber = (UINT16)i.get_key();
> >-
> >-        HX_ASSERT(pTransport);
> >+        CHXMapLongToObj::Iterator i;
> >+        for(i=m_pTransportStreamMap->Begin();
> >+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> >+        {
> >+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> >+            UINT16 streamNumber = (UINT16)i.get_key();
> >+
> >+            HX_ASSERT(pTransport);
> >+
> >+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : 
> >HXR_OK;
> >+        }
> >+    }
> >
> >-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> >+    if (m_pSrcBufStats)
> >+    {
> >+        m_pSrcBufStats->Reset();
> >     }
> >
> >     m_pMutex->Unlock();
> >@@ -6964,6 +7005,11 @@
> >         // Get session level RTP bandwidth modifiers
> >         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
> >         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> >+
> >+        if (ulIsSessionLive)
> >+        {
> >+            m_bIsLive = TRUE;
> >+        }
> >
> >         // get multicast address from the session description
> >         if (HXR_OK == 
> >ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> >@@ -7187,6 +7233,11 @@
> >             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
> >             pInfo->m_bRealMedia = bRealMedia;
> >
> >+            if (m_pSrcBufStats)
> >+            {
> >+                m_pSrcBufStats->Init((UINT16)streamNumber, 
> >pInfo->m_bIsLive);
> >+            }
> >+
> >             if (m_pRateAdaptInfo)
> >             {
> >                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> >@@ -7222,6 +7273,7 @@
> >         if (m_bMulticast)
> >         {
> >             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> >+            m_bIsLive = TRUE;
> >         }
> >     }
> >
> >Index: pub/rtspclnt.h
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> >retrieving revision 1.30.2.1
> >diff -u -r1.30.2.1 rtspclnt.h
> >--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
> >+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
> >@@ -46,6 +46,7 @@
> > #include "hxbufctl.h" // IHXTransportBufferLimit
> > #include "hxrtsp2.h"
> > #include "hxrsdbf.h" // IHXResendBufferControl
> >+#include "hxprefs.h" // IHXPreferences
> >
> > class RTSPClientState;
> > class RTSPOptionsMessage;
> >@@ -63,6 +64,7 @@
> > class MIMEHeader;
> > class PipelinedDescribeLogic;
> > class CHXRateAdaptationInfo;
> >+class HXNetSourceBufStats;
> >
> > struct IHXKeyValueList;
> > struct IHXValues;
> >@@ -1039,6 +1041,7 @@
> >
> >     BOOL                                m_bSDPInitiated;
> >     BOOL                                m_bMulticast;
> >+    BOOL                                m_bIsLive;
> >     IHXValues*                          m_pSDPFileHeader;
> >     CHXSimpleList*                      m_pSDPStreamHeaders;
> >
> >@@ -1074,6 +1077,7 @@
> >     UINT32                              m_ulServerTimeOut;
> >     UINT32                              m_ulCurrentTimeOut;
> >     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> >+    HXNetSourceBufStats*                m_pSrcBufStats;
> >
> > #if defined(_MACINTOSH)
> >     RTSPClientProtocolCallback*                m_pCallback;
> >
> >Index: rtsptran.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> >retrieving revision 1.26
> >diff -u -r1.26 rtsptran.cpp
> >--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
> >+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
> >@@ -526,8 +526,17 @@
> >     }
> > }
> >
> >+HX_RESULT
> >+RTSPTransport::getPacket(UINT16 uStreamNumber,
> >+                         IHXPacket*& pPacket)
> >+{
> >+    UINT32 uSeqNum;
> >+    return getPacket(uStreamNumber, pPacket, uSeqNum);
> >+}
> >+
> > HX_RESULT
> >-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> >+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
> >+                         REF(UINT32) uSeqNum)
> > {
> >     RTSPTransportBuffer* pTransportBuffer = 
> >getTransportBuffer(uStreamNumber);
> >     RTSPStreamData* pStreamData = 
> >m_pStreamHandler->getStreamData(uStreamNumber);
> >@@ -547,6 +556,7 @@
> >     }
> >
> >     pPacket = clientPacket->GetPacket();
> >+    uSeqNum = clientPacket->GetSequenceNumber();
> >
> >     if (!pPacket)
> >     {
> >Index: pub/rtsptran.h
> >===================================================================
> >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> >retrieving revision 1.19
> >diff -u -r1.19 rtsptran.h
> >--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
> >+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
> >@@ -259,6 +259,9 @@
> >     HX_RESULT resetFlags               (UINT16 streamNumber);
> >     HX_RESULT getPacket                        (UINT16 uStreamNumber,
> >                                        IHXPacket*& pPacket);
> >+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
> >+                                       IHXPacket*& pPacket,
> >+                                         REF(UINT32) uSeqNum);
> >     virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
> >     virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
> >
> >Index: Umakefil
> >===================================================================
> >RCS file: /cvsroot/client/common/util/Umakefil,v
> >retrieving revision 1.3
> >diff -u -r1.3 Umakefil
> >--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
> >+++ Umakefil    22 Jun 2004 22:53:43 -0000
> >@@ -53,6 +53,7 @@
> >                   'chxphook.cpp',
> >                   'xnetchck.cpp',
> >                   'littobig.cpp',
> >-                  'hxunicod.cpp')
> >+                  'hxunicod.cpp',
> >+                   'hxsrcbufstats.cpp')
> >
> > LibraryTarget('utlclntlib')
> >Index: hxcore.h
> >===================================================================
> >RCS file: /cvsroot/common/include/hxcore.h,v
> >retrieving revision 1.5
> >diff -u -r1.5 hxcore.h
> >--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
> >+++ hxcore.h    22 Jun 2004 23:00:23 -0000
> >@@ -2060,7 +2060,50 @@
> >
> > // $EndPrivate.
> >
> >+// $Private:
> >
> >+/****************************************************************************
> >+ *
> >+ *  Interface:
> >+ *
> >+ *     IID_IHXTransportOnTimeSync
> >+ *
> >+ *  Purpose:
> >+ *
> >+ *     This interface is used to send OnTimeSync() calls down
> >+ *      to the transport layer. Note that the value passed to
> >+ *      OnTimeSync() MUST be in the same units and have the same
> >+ *      offset as the packets coming from the transport. This means
> >+ *      that any offets caused by SMIL or live playback must be
> >+ *      removed before calling OnTimeSync() on this interface
> >+ *
> >+ *      IID_IHXTransportOnTimeSync
> >+ *
> >+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> >+ *
> >+ */
> >+DEFINE_GUID(IID_IHXTransportOnTimeSync,
> >+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 
> >0xc1);
> >+
> >+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> >+{
> >+    /*
> >+     * IUnknown methods
> >+     */
> >+
> >+    STDMETHOD(QueryInterface)  (THIS_
> >+                               REFIID riid,
> >+                               void** ppvObj) PURE;
> >+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> >+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
> >+
> >+    /*
> >+     * IHXTransportOnTimeSync methods
> >+     */
> >+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> >+};
> >+
> >+// $EndPrivate.
> >
> > #endif /* _HXCORE_H_ */
> >
> >Index: hxpiids.h
> >===================================================================
> >RCS file: /cvsroot/common/include/hxpiids.h,v
> >retrieving revision 1.28.2.1
> >diff -u -r1.28.2.1 hxpiids.h
> >--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
> >+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
> >@@ -533,6 +533,7 @@
> > DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 
> >0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
> > DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 
> >0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
> > DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 
> >0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 
> >0xa9,  0x69,  0x37,  0x3b,  0x4d)
> >+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 
> >0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
> > #endif /* _HXCORE_H_ */
> >
> > /*
> >
> >
> >
> >
> >_______________________________________________
> >Client-dev mailing list
> >Client-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/client-dev
> 

From acolwell at real.com  Wed Jun 23 10:34:07 2004
From: acolwell at real.com (Aaron Colwell)
Date: Wed Jun 23 10:36:10 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Moving
	IHXSourceBufferingStats2implementation
In-Reply-To: <0a4601c45944$13118520$ff8317ac@gwright5>
References: <20040622235202.GA5152@real.com>
	<0a4601c45944$13118520$ff8317ac@gwright5>
Message-ID: <20040623173407.GD7758@real.com>

On Wed, Jun 23, 2004 at 10:03:57AM -0700, Greg Wright wrote:
> Is this not needed on 130NepX?

This is for 3GPP-Rel6 features so it doesn't need to go on 130NepX. I should
fix the bugs I found in the existing code on that branch. I'll send out a
code review for those later today.

> 
> Also, there was a new interface added called IHXTimelineWatcher
> that provides OnTimeSync calls from the auido services. If that
> is the same time you are after you can just use that. However,
> if this is a different based time then maybe we should not 
> call it OnTimeSync. At least in my mind, OnTimeSync means the
> current audio timeline position whenever I see it.

It is a different timebase than audio services. How about I call the
new interface IHXTransportTimeSink and rename the method to OnTransportTime().
I think that will make it clear that something is different than the normal
OnTimeSync() call.

> 
> --greg.
> 
> 
> ----- Original Message ----- 
> From: "Aaron Colwell" 
> To: ; ; 
> Sent: Tuesday, June 22, 2004 4:52 PM
> Subject: [Client-dev] CR-Client: Moving IHXSourceBufferingStats2implementation
> 
> 
> > Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> >           number information can be maintained as well.
> > 
> > Overview: These changes move the IHXSourceBufferingStats2 implementation
> >           out of HXBufferingState and into a new class called 
> >           HXSourceBufferStats. This was done because the client needs to
> >           track packet sequence numbers for 3GPP-Rel6 OBSN support.
> >           There was no good way to get the sequence number information to
> >           the HXBufferingState class so the IHXSourceBufferingStats2 logic
> >           was moved to where this information is available.
> > 
> >           A new interface called IHXTransportOnTimeSync was created to
> >           propagate OnTimeSync() like calls to HXSourceBufferStats. The
> >           time passed to the OnTimeSync() call in this interface MUST
> >           NOT have any offsets created by SMIL or live playback. The time
> >           should be in the same time frame as the packets coming from the
> >           transport. If someone wants to rename this interface that is fine
> >           by me.
> > 
> > 
> >           - Created HXSourceBufferStats to contain the base 
> >             IHXSourceBufferingStats2 implementation. This class is
> >             used by HXFileSource.
> >  
> >           - Created HXNetSourceBufStats which derives from HXSourceBufferStats.
> >             This class just overloads the GetCurrentBuffering() so that it
> >             returns the amount of data in the transport buffer. This is
> >             used by RTSPClientProtocol.
> > 
> >           - Removed IHXSourceBufferingStats2 code from HXSource
> > 
> >           - Removed packet tracking code from HXBufferingState. This 
> >             functionality is implemented by HXSourceBufferStats now
> > 
> >           - Added code to HXSource to provide OnTimeSync() calls to the
> >             IHXTransportOnTimeSync interface. 
> > 
> >           - HXSource now exposes IHXSourceBufferingStats functionality through
> >             it's m_pSrcBufStats member variable instead of implementing it
> >             itself. The file and network sources are expected to provide an
> >             IHXSourceBufferingStats2 interface via a
> >             HXSource::SetSrcBufStats() call.
> > 
> >           - Added code to HXFileSource to use HXSourceBufferStats
> > 
> >           - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> > 
> >           - Fixed some code in CBufferManager that was expecting HXSource
> >             to implement IHXSourceBufferingStats. This code now QI's for
> >             IHXSourceBufferingStats and uses that interface.
> >       
> >              
> > 
> > Files Modified:
> > client/core/buffmgr.cpp
> > client/core/hxbsrc.h
> > client/core/hxbufstate.h
> > client/core/hxbufstate.cpp
> > client/core/hxflsrc.cpp
> > client/core/hxflsrc.h
> > client/core/hxntsrc.cpp
> > client/core/hxntsrc.h
> > client/core/hxsrc.cpp
> > client/core/rtspprotocol.cpp
> > protocol/rtsp/Umakefil
> > protocol/rtsp/rtspclnt.cpp
> > protocol/rtsp/pub/rtspclnt.h
> > protocol/transport/common/system/rtsptran.cpp
> > protocol/transport/common/system/pub/rtsptran.h
> > client/common/util/Umakefil
> > common/include/hxcore.h
> > common/include/hxpiids.h
> > 
> > Files Added:
> > client/common/util/pub/hxsrcbufstats.h
> > client/common/util/hxsrcbufstats.cpp
> > protocol/rtsp/ntsrcbufstats.h
> > protocol/rtsp/ntsrcbufstats.cpp
> > 
> > Image Size and Heap Use impact:
> > 
> > Platforms and Profiles affected: all
> > 
> > Distribution Libraries affected: rdtclntlib
> > 
> > Distribution library impact and planned action: 
> > m_bIsLive and m_pSrcBufStats member variables were added to 
> > RTSPClientProtocol so any derived objects will need to be
> > recompiled
> > 
> > Platforms and Profiles Build Verified: win32
> > 
> > Platforms and Profiles Functionality verified: win32
> > 
> > Branch: HEAD
> > 
> > QA Instructions: none
> > 
> > Index: buffmgr.cpp
> > ===================================================================
> > RCS file: /cvsroot/client/core/buffmgr.cpp,v
> > retrieving revision 1.21
> > diff -u -r1.21 buffmgr.cpp
> > --- buffmgr.cpp 11 Mar 2004 19:44:10 -0000 1.21
> > +++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> > @@ -610,6 +610,11 @@
> >       * - Keep track of the stream with the lowest timestamp and is 
> >       *   buffering data
> >       */
> > +    IHXSourceBufferingStats* pSrcBufStats = NULL;
> > +    
> > +    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> > +                              (void**)&pSrcBufStats);
> > +
> >      for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
> >      {
> >   pStreamInfo = (STREAM_INFO*) (*i);
> > @@ -619,12 +624,15 @@
> >   ULONG32 ulNumBytesAtTransport = 0;
> >   BOOL bDoneAtTransport = FALSE;
> >  
> > - m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
> > -        llLowestTimestampAtTransport,
> > -        llHighestTimestampAtTransport,
> > -        ulNumBytesAtTransport,
> > -        bDoneAtTransport);
> > -
> > +        if (pSrcBufStats)
> > +        {
> > +            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
> > +                                              llLowestTimestampAtTransport,
> > +                                              llHighestTimestampAtTransport,
> > +                                              ulNumBytesAtTransport,
> > +                                              bDoneAtTransport);
> > +        }
> > +            
> >   pStreamInfo->BufferingState().UpdateTransportStats(
> >       llLowestTimestampAtTransport,
> >       llHighestTimestampAtTransport,
> > @@ -658,6 +666,7 @@
> >  
> >   }
> >      }
> > +    HX_RELEASE(pSrcBufStats);
> >  
> >      /* If none of the streams have any data buffered at the transport layer,
> >       * return.
> > Index: hxbsrc.h
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxbsrc.h,v
> > retrieving revision 1.18.2.1
> > diff -u -r1.18.2.1 hxbsrc.h
> > --- hxbsrc.h 15 Jun 2004 16:26:43 -0000 1.18.2.1
> > +++ hxbsrc.h 22 Jun 2004 22:52:26 -0000
> > @@ -233,12 +233,11 @@
> >     public IHXPrivateStreamSource,
> >     public IHXBackChannel,
> >     public IHXASMSource,
> > -                  public IHXClientRateAdaptControl,
> > +                  public IHXClientRateAdaptControl
> >  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> > -   public IHXHyperNavigate,
> > -   public IHXHyperNavigate2,
> > +   , public IHXHyperNavigate,
> > +   public IHXHyperNavigate2
> >  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > -                  public IHXSourceBufferingStats2
> >  {
> >  protected:
> >      LONG32 m_lRefCount;
> > @@ -487,35 +486,6 @@
> >       IHXValues* pParams);
> >  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >  
> > -    /************************************************************************
> > -     * Method:
> > -     *     IHXSourceBufferingStats2::GetCurrentBuffering
> > -     * Purpose:
> > -     *     Get the current buffering information
> > -     */
> > -
> > -    STDMETHOD(GetCurrentBuffering) (THIS_ 
> > -                                    UINT16  uStreamNumber,
> > -                                    REF(INT64)  llLowestTimestamp, 
> > -                                    REF(INT64)  llHighestTimestamp,
> > -                                    REF(UINT32) ulNumBytes,
> > -                                    REF(BOOL)   bDone) PURE;
> > -    /************************************************************************
> > -     * Method:
> > -     *     IHXSourceBufferingStats2::GetTotalBuffering
> > -     * Purpose:
> > -     *     Get the total amount of data buffered for a stream.
> > -     *      This includes what is in the transport buffer and in
> > -     *      the renderer
> > -     */
> > -    
> > -    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> > -    REF(INT64)  llLowestTimestamp, 
> > -    REF(INT64)  llHighestTimestamp,
> > -    REF(UINT32) ulNumBytes,
> > -    REF(BOOL)   bDone);
> > -
> > -
> >      /*
> >       * IHXClientRateAdaptControl Methods
> >       */
> > @@ -731,7 +701,7 @@
> >       virtual HX_RESULT FillRecordControl() = 0;
> >       BOOL IsPlayingFromRecordControl() { return m_bPlayFromRecordControl; };
> >  
> > -            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > +            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >  
> >              const char*         GetRedirectURL() { return (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
> >              const char*         GetSDPURL() { return (m_pSDPURL ? m_pSDPURL->GetURL() : NULL); };
> > @@ -769,6 +739,8 @@
> >              void        ProcessFileHeader(void);
> >              HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, STREAM_INFO*& pStreamInfo);
> >  
> > +    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> > +
> >      HX_RESULT mLastError;
> >      CHXMapLongToObj*            mStreamInfoTable;
> >      
> > @@ -868,6 +840,8 @@
> >      CHXURL*                     m_pRedirectURL;
> >      CHXURL*                     m_pSDPURL;
> >      BOOL                        m_bRedirectPending;
> > +    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> > +    IHXSourceBufferingStats2*   m_pSrcBufStats;
> >  };
> >  
> >  // Defined flags
> > Index: hxbufstate.cpp
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> > retrieving revision 1.7
> > diff -u -r1.7 hxbufstate.cpp
> > --- hxbufstate.cpp 9 Mar 2004 19:51:11 -0000 1.7
> > +++ hxbufstate.cpp 22 Jun 2004 22:52:26 -0000
> > @@ -83,18 +83,11 @@
> >      , m_ulLastPacketTimeStamp(0)
> >      , m_ulAvgBandwidth(0)
> >      , m_pASMProps(NULL)
> > -    , m_llCurrentPlaybackTime(0)
> > -    , m_ulBufferedData(0)
> > -    , m_ulLastTimeSync(0)
> > -    , m_llFirstLivePacketTimestamp(0)
> > -    , m_ulTimeSyncRollOver(0)
> >  {}
> >  
> >  HXBufferingState::~HXBufferingState()
> >  {
> >      HX_RELEASE(m_pASMProps);
> > -
> > -    ClearPktInfo();
> >  }
> >  
> >  void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> > @@ -179,8 +172,6 @@
> >      m_ulLastPacketTimeStamp = 0;
> >      m_bIsFirstPacket = TRUE;
> >  
> > -    ClearPktInfo();
> > -
> >      if (bIsSeeking)
> >      {
> >   m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> > @@ -288,11 +279,6 @@
> >      return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
> >  }
> >  
> > -INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> > -{
> > -    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
> > -}
> > -
> >  void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> >   UINT32 ulElapsedTime,
> >   BOOL bIsLive, BOOL bIsBufferedPlayMode)
> > @@ -318,16 +304,12 @@
> >   if (bIsLive)
> >   {
> >       m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> > -            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
> >          }
> >  
> >   m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >   m_bIsFirstPacket = FALSE;
> >      }
> >  
> > -    // Add this packet to our packet info statistics
> > -    AddPktInfo(llActualTimeStamp, ulPacketSize);
> > -
> >      // data based preroll
> >      if (DataBasedPreroll())
> >      {
> > @@ -451,47 +433,6 @@
> >      m_bDoneAtTransport = bDoneAtTransport;
> >  }
> >  
> > -HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp, 
> > -       REF(INT64) llHighTimestamp,
> > -       REF(UINT32) ulBytesBuffered,
> > -       BOOL bUseTransportStats)
> > -{
> > -    HX_RESULT res = HXR_NO_DATA;
> > -
> > -    if (!m_bIsFirstPacket)
> > -    {
> > - if (!m_pktInfo.IsEmpty())
> > - {
> > -     HXBufferedPktInfo* pPktInfo = 
> > - (HXBufferedPktInfo*)m_pktInfo.GetHead();
> > -
> > -     llLowTimestamp = pPktInfo->Timestamp();
> > - }
> > - else
> > - {
> > -     llLowTimestamp = m_llHighestTimeStamp;
> > - }
> > -
> > - llHighTimestamp = m_llHighestTimeStamp;
> > - ulBytesBuffered = GetBufferedData();
> > - 
> > -
> > - if (bUseTransportStats)
> > - {
> > -     if (m_llHighestTimestampAtTransport > llHighTimestamp)
> > -     {
> > - llHighTimestamp = m_llHighestTimestampAtTransport;
> > -     }
> > -
> > -     ulBytesBuffered += m_ulNumBytesAtTransport;
> > - }
> > -
> > - res = HXR_OK;
> > -    }
> > -
> > -    return res;
> > -}
> > -
> >  void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
> >      INT64 llTheHighestTS,
> >      BOOL bIsSeekPerformed,
> > @@ -569,19 +510,6 @@
> >  
> >  }
> >  
> > -void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> > -{
> > -    //  0xFA .. 0xFF [roll over] (0x01)
> > -    if (m_ulLastTimeSync > ulCurrentTime &&
> > -       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> > -    {
> > -       m_ulTimeSyncRollOver++;
> > -    }
> > -    m_ulLastTimeSync = ulCurrentTime;
> > -
> > -    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> > -}
> > -
> >  void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs, 
> >   ULONG32 ulMinBufferingInMs)
> >  {
> > @@ -771,62 +699,4 @@
> >      {
> >   m_ulAvgBandwidth = ulBandwidth;
> >      }
> > -}
> > -
> > -void HXBufferingState::ClearPktInfo()
> > -{
> > -    m_ulBufferedData = 0;
> > -    while(!m_pktInfo.IsEmpty())
> > -    {
> > - HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> > - delete pInfo;
> > -    }
> > -}
> > -
> > -void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
> > -{
> > -    // Subtract off the first live packet timestamp.
> > -    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> > -    llTimestamp -= m_llFirstLivePacketTimestamp;
> > -    // Create the HXBufferedPktInfo class
> > -    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp, 
> > - ulPacketSize);
> > -    if (pPktInfo)
> > -    {
> > - m_pktInfo.AddTail(pPktInfo);
> > - m_ulBufferedData += ulPacketSize;
> > -    }
> > -
> > -    // purge the old packet info data
> > -    //  this keeps the list short and prevents the Symbian
> > -    //  allocator from freaking out
> > -    (void)GetBufferedData();
> > -}
> > -
> > -UINT32 HXBufferingState::GetBufferedData()
> > -{
> > -    BOOL bDone = m_pktInfo.IsEmpty();
> > -    
> > -    // Remove all packet info that is past due
> > -    // and subtract their sizes from our buffering total
> > -    while(!bDone)
> > -    {
> > - HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
> > - 
> > - if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> > - {
> > -     m_ulBufferedData -= pPktInfo->Size();
> > -     
> > -     m_pktInfo.RemoveHead();
> > -     delete pPktInfo;
> > -     
> > -     bDone = m_pktInfo.IsEmpty();
> > - }
> > - else
> > - {
> > -     bDone = TRUE;
> > - }
> > -    }
> > -
> > -    return m_ulBufferedData;
> >  }
> > Index: hxbufstate.h
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxbufstate.h,v
> > retrieving revision 1.4
> > diff -u -r1.4 hxbufstate.h
> > --- hxbufstate.h 19 May 2004 19:37:33 -0000 1.4
> > +++ hxbufstate.h 22 Jun 2004 22:52:26 -0000
> > @@ -81,7 +81,6 @@
> >      BOOL HasPredata(BOOL bIsSeekPerformed);
> >  
> >      INT64 CreateINT64Timestamp(UINT32 ulTime);
> > -    INT64 CreateINT64Timesync(UINT32 ulTime);
> >  
> >      void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize, 
> >     UINT32 ulElapsedTime, BOOL bIsLive,
> > @@ -98,11 +97,6 @@
> >         ULONG32 ulBytesAtTransport,
> >         BOOL bDoneAtTransport);
> >  
> > -    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp, 
> > - REF(INT64) llHighTimestamp,
> > - REF(UINT32) ulBytesBuffered,
> > - BOOL bUseTransportStats);
> > -
> >      void GetExcessBufferInfo(INT64 llTheLowestTS,
> >        INT64 llTheHighestTS,
> >        BOOL bIsSeekPerformed,
> > @@ -119,8 +113,6 @@
> >  
> >      UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
> >  
> > -    void OnTimeSync(UINT32 ulCurrentTime);
> > -
> >      // Should remove
> >      void SetAvgBWToASMBw();
> >      BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> > @@ -149,19 +141,6 @@
> >   UINT32 ulCurrentBuffering,
> >   UINT32 ulMinimumPreroll,
> >   UINT32 ulDenom) const;
> > -    
> > -    /* Functions for tracking the amount of data
> > -     * buffered in the renderer
> > -     */
> > -    void ClearPktInfo(); /* Clears out information about buffered packets */
> > -    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
> > -       * a packet is 
> > -       * sent to the
> > -       * renderer 
> > -       */
> > -    UINT32 GetBufferedData(); /* Get the current amount of data buffered
> > -        * in the renderer
> > -        */
> >  
> >      ULONG32 m_ulPreroll;
> >      ULONG32 m_ulPredata;
> > @@ -196,20 +175,6 @@
> >      ULONG32 m_ulLastPacketTimeStamp;
> >      ULONG32 m_ulAvgBandwidth;
> >      IHXASMProps* m_pASMProps;
> > -    UINT32              m_ulLastTimeSync;
> > -    INT64               m_llFirstLivePacketTimestamp;
> > -    UINT32              m_ulTimeSyncRollOver;    
> > -    // These variable keep track of the amount of
> > -    // data buffered in the renderer
> > -    INT64               m_llCurrentPlaybackTime; /* Cached value of last
> > -   * OnTimeSync() call
> > -   */
> > -
> > -    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> > -    * Always use GetBufferedData()
> > -    * to retreive the value
> > -    */
> > -    CHXSimpleList       m_pktInfo; /* List of packet information */
> >  };
> >  
> >  inline
> > Index: hxflsrc.cpp
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> > retrieving revision 1.54
> > diff -u -r1.54 hxflsrc.cpp
> > --- hxflsrc.cpp 19 May 2004 19:37:33 -0000 1.54
> > +++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> > @@ -76,6 +76,7 @@
> >  #include "uri_schemes.h"
> >  #include "stream_desc_hlpr.h"
> >  #include "findfile.h"
> > +#include "hxsrcbufstats.h"
> >  
> >  #include "hxheap.h"
> >  #ifdef _DEBUG
> > @@ -115,6 +116,7 @@
> >      , m_bValidateMetaDone(FALSE)
> >      , m_pFileRecognizer(NULL)
> >      , m_pFileReader(NULL)
> > +    , m_pSrcBufStats(NULL)
> >  {
> >      m_bAltURL = FALSE;
> >      m_bPerfectPlay = TRUE;
> > @@ -306,6 +308,13 @@
> >  
> >      HX_VECTOR_DELETE(m_pszURL);
> >      HX_DELETE(m_pURL);
> > +    
> > +    HX_RELEASE(m_pSrcBufStats);
> > +    m_pSrcBufStats = new HXSourceBufferStats();
> > +    if (m_pSrcBufStats)
> > +    {
> > +        m_pSrcBufStats->AddRef();
> > +    }
> >  
> >      if (!theErr && pURL)
> >      {
> > @@ -938,6 +947,7 @@
> >      }
> >  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
> >  
> > +    HX_RELEASE(m_pSrcBufStats);
> >      HXSource::DoCleanup();
> >  
> >      return HXR_OK;
> > @@ -1068,6 +1078,11 @@
> >  
> >      m_llLastFillEndTime = 0;   
> >  
> > +    if (m_pSrcBufStats)
> > +    {
> > +        m_pSrcBufStats->Reset();
> > +    }
> > +
> >  cleanup:
> >  
> >      return HXR_OK;
> > @@ -1442,6 +1457,11 @@
> >  
> >       if(m_pBufferManager)
> >   m_pBufferManager->UpdateCounters(pPacket, 0);
> > +            
> > +            if (m_pSrcBufStats && !pPacket->IsLost())
> > +            {
> > +                m_pSrcBufStats->OnPacket(pPacket);
> > +            }
> >  
> >       HX_RELEASE(pPacket);
> >   }
> > @@ -2103,6 +2123,13 @@
> >   }
> >   HX_RELEASE(pszParentName);
> >  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> > +
> > +        if (pStreamInfo && m_pSrcBufStats)
> > +        {
> > +            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> > +                                 mLiveStream);
> > +        }
> > +
> >          m_ulStreamIndex++;
> >          m_uNumStreams++;
> >      }
> > @@ -2115,6 +2142,11 @@
> >  
> >   theErr = AdjustClipTime();
> >   m_pBufferManager->Init();
> > +
> > +        if (m_pSrcBufStats)
> > +        {
> > +            SetSrcBufStats(m_pSrcBufStats);
> > +        }
> >      }
> >  
> >      return theErr;
> > @@ -2313,6 +2345,11 @@
> >   {
> >       m_pBufferManager->UpdateCounters(pPacket, 0);
> >   }
> > +
> > +        if (m_pSrcBufStats && !pPacket->IsLost())
> > +        {
> > +            m_pSrcBufStats->OnPacket(pPacket);
> > +        }
> >      }
> >  
> >      m_llLastFillEndTime = llActualPacketTime;
> > Index: hxflsrc.h
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxflsrc.h,v
> > retrieving revision 1.12
> > diff -u -r1.12 hxflsrc.h
> > --- hxflsrc.h 3 May 2004 18:59:30 -0000 1.12
> > +++ hxflsrc.h 22 Jun 2004 22:52:26 -0000
> > @@ -52,6 +52,8 @@
> >  #include "hxfiles.h"
> >  #include "recognizer.h"
> >  
> > +class HXSourceBufferStats;
> > +
> >  class HXFileSource : public HXSource, 
> >         public IHXFormatResponse,
> >                        public IHXHTTPRedirectResponse
> > @@ -349,6 +351,7 @@
> >  
> >      CFileReader*                m_pFileReader;
> >      CHXFileRecognizer*          m_pFileRecognizer;
> > +    HXSourceBufferStats*        m_pSrcBufStats;
> >  };
> >  
> >  #endif // _HX_FILE_SOURCE
> > Index: hxntsrc.cpp
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> > retrieving revision 1.90
> > diff -u -r1.90 hxntsrc.cpp
> > --- hxntsrc.cpp 19 May 2004 19:37:33 -0000 1.90
> > +++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> > @@ -675,6 +675,7 @@
> >      HX_RESULT   rc = HXR_OK;
> >      BOOL        bSDPInitiated = FALSE;
> >      CHXString   pString;
> > +    IHXSourceBufferingStats2* pSrcBufStats = NULL;
> >  
> >      // start off with the preferred protocol
> >      rc = CreateProtocol();
> > @@ -722,6 +723,14 @@
> >          goto cleanup;
> >      }
> >  
> > +    // Setup source buffer stats 
> > +    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> > +                                           (void**)&pSrcBufStats))
> > +    {
> > +        SetSrcBufStats(pSrcBufStats);
> > +        HX_RELEASE(pSrcBufStats);
> > +    }
> > +
> >      // create log info list
> >      m_pLogInfoList = new CHXSimpleList;
> >      m_ulLogInfoLength = 0;
> > @@ -6295,6 +6304,12 @@
> >  #else
> >      return HXR_NOTIMPL;
> >  #endif /* HELIX_FEATURE_RECORDCONTROL */
> > +}
> > +
> > +HX_RESULT 
> > +HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> > +{
> > +    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
> >  }
> >  
> >  ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> > Index: hxntsrc.h
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxntsrc.h,v
> > retrieving revision 1.24
> > diff -u -r1.24 hxntsrc.h
> > --- hxntsrc.h 3 May 2004 18:59:30 -0000 1.24
> > +++ hxntsrc.h 22 Jun 2004 22:52:26 -0000
> > @@ -282,6 +282,7 @@
> >  
> >   virtual HX_RESULT FillRecordControl();
> >  
> > +        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >  protected:
> >  
> >   virtual ~HXNetSource(void);
> > @@ -470,7 +471,6 @@
> >  private:
> >          IHXBufferControl*                m_pBufferCtl;
> >          IHXWatermarkBufferControl*       m_pWMBufferCtl;
> > -
> >  public:
> >   HX_RESULT FinishSetup();
> >   void ReSetup();
> > Index: hxsrc.cpp
> > ===================================================================
> > RCS file: /cvsroot/client/core/hxsrc.cpp,v
> > retrieving revision 1.44.2.1
> > diff -u -r1.44.2.1 hxsrc.cpp
> > --- hxsrc.cpp 15 Jun 2004 16:26:43 -0000 1.44.2.1
> > +++ hxsrc.cpp 22 Jun 2004 22:52:26 -0000
> > @@ -213,6 +213,8 @@
> >          , m_pRedirectURL(NULL)
> >          , m_pSDPURL(NULL)
> >          , m_bRedirectPending(FALSE)
> > +        , m_pTransOnTimeSync(NULL)
> > +        , m_pSrcBufStats(NULL)
> >  {
> >      mStreamInfoTable = new CHXMapLongToObj;
> >  }
> > @@ -313,6 +315,8 @@
> >      HX_DELETE(m_pRedirectURL);
> >      HX_DELETE(m_pSDPURL);
> >      m_bRedirectPending  = FALSE;
> > +    HX_RELEASE(m_pTransOnTimeSync);
> > +    HX_RELEASE(m_pSrcBufStats);
> >  
> >  #if defined(HELIX_FEATURE_RECORDCONTROL)
> >      if(m_pRecordControl)
> > @@ -340,8 +344,6 @@
> >              { GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*)this },
> >              { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
> >              { GET_IIDHANDLE(IID_IHXPrivateStreamSource), (IHXPrivateStreamSource*)this },
> > -            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*)this },
> > -            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*)this },
> >              { GET_IIDHANDLE(IID_IHXClientRateAdaptControl), 
> >                (IHXClientRateAdaptControl*)this },
> >  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> > @@ -388,6 +390,14 @@
> >       return HXR_NOINTERFACE;
> >   }
> >      }
> > +    else if (m_pSrcBufStats &&
> > +             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> > +              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> > +    {
> > +        m_pSrcBufStats->AddRef();
> > +        *ppvObj = m_pSrcBufStats;
> > +        return HXR_OK;
> > +    }
> >  
> >  #if defined(HELIX_FEATURE_AUTOUPGRADE)
> >      else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> > @@ -2250,59 +2260,6 @@
> >  }
> >  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >  
> > -STDMETHODIMP
> > -HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> > -     REF(INT64)  llLowestTimestamp, 
> > -     REF(INT64)  llHighestTimestamp,
> > -     REF(UINT32) ulNumBytes,
> > -     REF(BOOL)   bDone)
> > -{
> > -    HX_RESULT res = HXR_NO_DATA;
> > -    
> > -    llLowestTimestamp = 0;
> > -    llHighestTimestamp = 0;
> > -    ulNumBytes = 0;
> > -    bDone = FALSE;
> > -
> > -    STREAM_INFO* pStreamInfo;
> > -    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
> > -    {
> > - HXBufferingState& bufState = pStreamInfo->BufferingState();
> > - BOOL   bUseTransportStats = FALSE;
> > -
> > - INT64  llTransportLowTS = 0;
> > - INT64  llTransportHighTS = 0;
> > - UINT32 ulTransportBytes = 0;
> > - BOOL   bTransportDone = FALSE;
> > -
> > - if (!IsLocalSource() &&
> > -     (HXR_OK == GetCurrentBuffering(uStreamNumber,
> > -    llTransportLowTS,
> > -    llTransportHighTS,
> > -    ulTransportBytes,
> > -    bTransportDone)))
> > - {
> > -     bufState.UpdateTransportStats(llTransportLowTS,
> > -   llTransportHighTS,
> > -   ulTransportBytes,
> > -   bTransportDone);
> > -
> > -     bUseTransportStats = TRUE;
> > -
> > -     // Update bDone with what the transport says.
> > -     bDone = bTransportDone;
> > - }
> > -
> > - res = bufState.GetBufferingStats(llLowestTimestamp,
> > - llHighestTimestamp,
> > - ulNumBytes,
> > - bUseTransportStats);
> > -    }
> > -
> > -
> > -    return res;
> > -}
> > -
> >  /*
> >   * IHXClientRateAdaptControl Methods
> >   */
> > @@ -2948,13 +2905,34 @@
> >  {
> >      HX_RESULT res = HXR_OK;
> >  
> > -    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> > -         i != mStreamInfoTable->End(); ++i) 
> > -    {    
> > - STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> > -
> > - pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> > +    // Convert presentation time to transport time
> > +    if (m_pTransOnTimeSync)
> > +    {
> > +        ULONG32 ulOffset = m_ulDelay;
> > +        ULONG32 ulTransportTime = m_ulStartTime;
> > +        
> > +        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> > +        {
> > +            ulTransportTime += ulCurrentTime - ulOffset;
> > +        }
> > +    
> > +        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
> >      }
> >  
> >      return res;
> > +}
> > +
> > +void 
> > +HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> > +{
> > +    HX_RELEASE(m_pSrcBufStats);
> > +    HX_RELEASE(m_pTransOnTimeSync);
> > +
> > +    if (pSrcBufStats)
> > +    {
> > +        m_pSrcBufStats = pSrcBufStats;
> > +        m_pSrcBufStats->AddRef();
> > +        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> > +                                       (void**)&m_pTransOnTimeSync);
> > +    }
> >  }
> > Index: rtspprotocol.cpp
> > ===================================================================
> > RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> > retrieving revision 1.39
> > diff -u -r1.39 rtspprotocol.cpp
> > --- rtspprotocol.cpp 11 May 2004 00:55:19 -0000 1.39
> > +++ rtspprotocol.cpp 22 Jun 2004 22:52:26 -0000
> > @@ -2626,12 +2626,12 @@
> >      UINT16 seekFrom
> >  )
> >  {
> > +    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> > +
> >      if (IsLive())
> >      {
> > -        return m_pProtocolLib->SeekFlush();
> > +        return theErr;
> >      }
> > -
> > -    HX_RESULT theErr = HXR_OK;
> >  
> >      m_uCurrentStreamCount = m_uStreamCount;
> >  
> > 
> > Index: Umakefil
> > ===================================================================
> > RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> > retrieving revision 1.9.2.1
> > diff -u -r1.9.2.1 Umakefil
> > --- Umakefil 16 Jun 2004 18:44:01 -0000 1.9.2.1
> > +++ Umakefil 22 Jun 2004 22:52:32 -0000
> > @@ -46,6 +46,7 @@
> >     'common/runtime/pub',
> >     'common/lang/xml/pub',
> >     'client/common/container/pub',
> > +                          'client/common/util/pub',
> >     'protocol/transport/rtp/include',
> >             'server/include', 
> >                            'server/common/struct/pub',
> > @@ -65,7 +66,7 @@
> >      'rtspmsg.cpp', 'rtspmdsc.cpp',
> >      'rtsppars.cpp', 'mhprop.cpp',
> >      'servrsnd.cpp', '3gpadapthdr.cpp',
> > -                   'rateadaptinfo.cpp')
> > +                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
> >  
> >  if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
> >      project.AddSources('pipelinedesc.cpp')
> > Index: rtspclnt.cpp
> > ===================================================================
> > RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> > retrieving revision 1.79.2.1
> > diff -u -r1.79.2.1 rtspclnt.cpp
> > --- rtspclnt.cpp 17 Jun 2004 04:32:09 -0000 1.79.2.1
> > +++ rtspclnt.cpp 22 Jun 2004 22:52:32 -0000
> > @@ -95,6 +95,7 @@
> >  #include "pipelinedesc.h"
> >  #include "errdbg.h"
> >  #include "rateadaptinfo.h"
> > +#include "ntsrcbufstats.h"
> >  
> >  #include "hxheap.h"
> >  #ifdef _DEBUG
> > @@ -302,6 +303,12 @@
> >      {
> >          return HXR_OK;
> >      }
> > +    else if (m_pSrcBufStats &&
> > +             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> > +                                                       ppvObj)))
> > +    {
> > +        return HXR_OK;
> > +    }
> >      *ppvObj = NULL;
> >      return HXR_NOINTERFACE;
> >  }
> > @@ -388,6 +395,7 @@
> >      m_bReportedSuccessfulTransport(FALSE),
> >      m_bSDPInitiated(FALSE),
> >      m_bMulticast(FALSE),
> > +    m_bIsLive(FALSE),
> >      m_pSDPFileHeader(NULL),
> >      m_pSDPStreamHeaders(NULL),
> >      m_bSessionSucceeded(FALSE),
> > @@ -404,7 +412,8 @@
> >      m_ulCurrentTimeOut(0),
> >      m_pUAProfURI(NULL),
> >      m_pUAProfDiff(NULL),
> > -    m_pRateAdaptInfo(NULL)
> > +    m_pRateAdaptInfo(NULL),
> > +    m_pSrcBufStats(NULL)
> >  #if defined(_MACINTOSH)
> >      , m_pCallback(NULL)
> >  #endif /* _MACINTOSH */
> > @@ -460,6 +469,8 @@
> >          m_pRateAdaptInfo->Close();
> >          HX_DELETE(m_pRateAdaptInfo);
> >      }
> > +
> > +    HX_RELEASE(m_pSrcBufStats);
> >  }
> >  
> >  /*
> > @@ -810,6 +821,21 @@
> >          }
> >      }
> >  
> > +    if (HXR_OK == hresult)
> > +    {
> > +        HX_RELEASE(m_pSrcBufStats);
> > +        m_pSrcBufStats = new HXNetSourceBufStats(this);
> > +        
> > +        if (m_pSrcBufStats)
> > +        {
> > +            m_pSrcBufStats->AddRef();
> > +        }
> > +        else
> > +        {
> > +            hresult = HXR_OUTOFMEMORY;
> > +        }
> > +    }
> > +
> >  #if defined(_MACINTOSH)
> >      if (m_pCallback &&
> >          m_pCallback->m_bIsCallbackPending &&
> > @@ -2191,7 +2217,14 @@
> >          (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> >      if (pTrans)
> >      {
> > -        rc = pTrans->getPacket(uStreamNumber, pPacket);
> > +        UINT32 uSeqNum;
> > +        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> > +
> > +        if ((HXR_OK == rc) && m_pSrcBufStats &&
> > +            (!pPacket->IsLost()))
> > +        {
> > +            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> > +        }
> >      }
> >  
> >      m_pMutex->Unlock();
> > @@ -3291,16 +3324,24 @@
> >      HX_RESULT rc = HXR_OK;
> >      m_pMutex->Lock();
> >  
> > -    CHXMapLongToObj::Iterator i;
> > -    for(i=m_pTransportStreamMap->Begin();
> > -            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> > +    if (m_bIsLive)
> >      {
> > -        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> > -        UINT16 streamNumber = (UINT16)i.get_key();
> > -
> > -        HX_ASSERT(pTransport);
> > +        CHXMapLongToObj::Iterator i;
> > +        for(i=m_pTransportStreamMap->Begin();
> > +            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> > +        {
> > +            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> > +            UINT16 streamNumber = (UINT16)i.get_key();
> > +            
> > +            HX_ASSERT(pTransport);
> > +            
> > +            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> > +        }
> > +    }
> >  
> > -        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> > +    if (m_pSrcBufStats)
> > +    {
> > +        m_pSrcBufStats->Reset();
> >      }
> >  
> >      m_pMutex->Unlock();
> > @@ -6964,6 +7005,11 @@
> >          // Get session level RTP bandwidth modifiers
> >          ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
> >          ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> > +        
> > +        if (ulIsSessionLive)
> > +        {
> > +            m_bIsLive = TRUE;
> > +        }
> >  
> >          // get multicast address from the session description
> >          if (HXR_OK == ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> > @@ -7187,6 +7233,11 @@
> >              pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
> >              pInfo->m_bRealMedia = bRealMedia;
> >  
> > +            if (m_pSrcBufStats)
> > +            {
> > +                m_pSrcBufStats->Init((UINT16)streamNumber, pInfo->m_bIsLive);
> > +            }
> > +
> >              if (m_pRateAdaptInfo)
> >              {
> >                  m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> > @@ -7222,6 +7273,7 @@
> >          if (m_bMulticast)
> >          {
> >              m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> > +            m_bIsLive = TRUE;
> >          }
> >      }
> >  
> > Index: pub/rtspclnt.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> > retrieving revision 1.30.2.1
> > diff -u -r1.30.2.1 rtspclnt.h
> > --- pub/rtspclnt.h 17 Jun 2004 04:32:09 -0000 1.30.2.1
> > +++ pub/rtspclnt.h 22 Jun 2004 22:52:32 -0000
> > @@ -46,6 +46,7 @@
> >  #include "hxbufctl.h" // IHXTransportBufferLimit
> >  #include "hxrtsp2.h"
> >  #include "hxrsdbf.h" // IHXResendBufferControl
> > +#include "hxprefs.h" // IHXPreferences
> >  
> >  class RTSPClientState;
> >  class RTSPOptionsMessage;
> > @@ -63,6 +64,7 @@
> >  class MIMEHeader;
> >  class PipelinedDescribeLogic;
> >  class CHXRateAdaptationInfo;
> > +class HXNetSourceBufStats;
> >  
> >  struct IHXKeyValueList;
> >  struct IHXValues;
> > @@ -1039,6 +1041,7 @@
> >      
> >      BOOL                                m_bSDPInitiated;
> >      BOOL                                m_bMulticast;
> > +    BOOL                                m_bIsLive;
> >      IHXValues*                          m_pSDPFileHeader;
> >      CHXSimpleList*                      m_pSDPStreamHeaders;
> >  
> > @@ -1074,6 +1077,7 @@
> >      UINT32                              m_ulServerTimeOut;
> >      UINT32                              m_ulCurrentTimeOut;
> >      CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> > +    HXNetSourceBufStats*                m_pSrcBufStats;
> >  
> >  #if defined(_MACINTOSH)
> >      RTSPClientProtocolCallback* m_pCallback;
> > 
> > Index: rtsptran.cpp
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> > retrieving revision 1.26
> > diff -u -r1.26 rtsptran.cpp
> > --- rtsptran.cpp 21 Apr 2004 19:16:30 -0000 1.26
> > +++ rtsptran.cpp 22 Jun 2004 22:53:16 -0000
> > @@ -526,8 +526,17 @@
> >      }
> >  }
> >  
> > +HX_RESULT 
> > +RTSPTransport::getPacket(UINT16 uStreamNumber,
> > +                         IHXPacket*& pPacket)
> > +{
> > +    UINT32 uSeqNum;
> > +    return getPacket(uStreamNumber, pPacket, uSeqNum);
> > +}
> > +
> >  HX_RESULT
> > -RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> > +RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket, 
> > +                         REF(UINT32) uSeqNum)
> >  {
> >      RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
> >      RTSPStreamData* pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);
> > @@ -547,6 +556,7 @@
> >      }
> >  
> >      pPacket = clientPacket->GetPacket();
> > +    uSeqNum = clientPacket->GetSequenceNumber();
> >  
> >      if (!pPacket)
> >      {
> > Index: pub/rtsptran.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> > retrieving revision 1.19
> > diff -u -r1.19 rtsptran.h
> > --- pub/rtsptran.h 20 Apr 2004 18:33:22 -0000 1.19
> > +++ pub/rtsptran.h 22 Jun 2004 22:53:16 -0000
> > @@ -259,6 +259,9 @@
> >      HX_RESULT resetFlags (UINT16 streamNumber);
> >      HX_RESULT getPacket (UINT16 uStreamNumber,
> >   IHXPacket*& pPacket);
> > +    HX_RESULT getPacket (UINT16 uStreamNumber,
> > + IHXPacket*& pPacket,
> > +                                         REF(UINT32) uSeqNum);
> >      virtual HX_RESULT startPackets (UINT16 uStreamNumber);
> >      virtual HX_RESULT stopPackets (UINT16 uStreamNumber);
> >  
> > Index: Umakefil
> > ===================================================================
> > RCS file: /cvsroot/client/common/util/Umakefil,v
> > retrieving revision 1.3
> > diff -u -r1.3 Umakefil
> > --- Umakefil 7 Feb 2003 22:37:08 -0000 1.3
> > +++ Umakefil 22 Jun 2004 22:53:43 -0000
> > @@ -53,6 +53,7 @@
> >      'chxphook.cpp',
> >      'xnetchck.cpp',
> >      'littobig.cpp',
> > -    'hxunicod.cpp')
> > +    'hxunicod.cpp', 
> > +                   'hxsrcbufstats.cpp')
> >  
> >  LibraryTarget('utlclntlib')
> > Index: hxcore.h
> > ===================================================================
> > RCS file: /cvsroot/common/include/hxcore.h,v
> > retrieving revision 1.5
> > diff -u -r1.5 hxcore.h
> > --- hxcore.h 19 May 2004 19:38:28 -0000 1.5
> > +++ hxcore.h 22 Jun 2004 23:00:23 -0000
> > @@ -2060,7 +2060,50 @@
> >  
> >  // $EndPrivate.
> >  
> > +// $Private:
> >  
> > +/****************************************************************************
> > + * 
> > + *  Interface:
> > + *
> > + * IID_IHXTransportOnTimeSync
> > + *
> > + *  Purpose:
> > + *
> > + * This interface is used to send OnTimeSync() calls down
> > + *      to the transport layer. Note that the value passed to
> > + *      OnTimeSync() MUST be in the same units and have the same
> > + *      offset as the packets coming from the transport. This means
> > + *      that any offets caused by SMIL or live playback must be
> > + *      removed before calling OnTimeSync() on this interface
> > + *
> > + *      IID_IHXTransportOnTimeSync
> > + *
> > + * {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> > + *
> > + */
> > +DEFINE_GUID(IID_IHXTransportOnTimeSync, 
> > +0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1);
> > +
> > +DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> > +{
> > +    /*
> > +     * IUnknown methods
> > +     */
> > +
> > +    STDMETHOD(QueryInterface) (THIS_
> > + REFIID riid,
> > + void** ppvObj) PURE;
> > +    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> > +    STDMETHOD_(ULONG32,Release) (THIS) PURE;
> > +
> > +    /*
> > +     * IHXTransportOnTimeSync methods
> > +     */
> > +    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> > +};
> > +
> > +// $EndPrivate.
> >  
> >  #endif /* _HXCORE_H_ */
> >  
> > Index: hxpiids.h
> > ===================================================================
> > RCS file: /cvsroot/common/include/hxpiids.h,v
> > retrieving revision 1.28.2.1
> > diff -u -r1.28.2.1 hxpiids.h
> > --- hxpiids.h 15 Jun 2004 16:38:55 -0000 1.28.2.1
> > +++ hxpiids.h 22 Jun 2004 23:00:23 -0000
> > @@ -533,6 +533,7 @@
> >  DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
> >  DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
> >  DEFINE_GUID_ENUM(IID_IHXMacBlitMutex, 0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95, 0xa9,  0x69,  0x37,  0x3b,  0x4d)
> > +DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
> >  #endif /* _HXCORE_H_ */
> >  
> >  /*
> > 
> 
> 
> --------------------------------------------------------------------------------
> 
> 
> > _______________________________________________
> > Client-dev mailing list
> > Client-dev@lists.helixcommunity.org
> > http://lists.helixcommunity.org/mailman/listinfo/client-dev
> > 

From ping at real.com  Wed Jun 23 10:37:01 2004
From: ping at real.com (Henry Ping)
Date: Wed Jun 23 10:37:28 2004
Subject: [Protocol-dev] Re: [Common-dev] CR-Client: Moving
	IHXSourceBufferingStats2 implementation
In-Reply-To: <20040623164825.GB7758@real.com>
References: <5.1.0.14.2.20040623095240.02bead80@mailone.real.com>
	<20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623095240.02bead80@mailone.real.com>
Message-ID: <5.1.0.14.2.20040623101601.0395b580@mailone.real.com>

At 09:48 AM 6/23/2004 -0700, Aaron Colwell wrote:
>On Wed, Jun 23, 2004 at 09:55:46AM -0400, Eric Hyche wrote:
> >
> > This is a pretty complicated change, so I doubt I'm
> > hitting any of the subtleties, but after a cursory examination,
> > these changes look good to me.
>
>Thanks for taking a look. This is basically just moving code from one place to
>another, but the diffs don't show that the call flow is basically equivalent.
>
> >
> > Just wondering though, why do we need the
> >
> > >+// $Private:
> >
> > and
> >
> > >+// $EndPrivate.
>
>I just put them in there because I noticed them around other "private"
>interfaces. I just wanted to mark this interface as something that the general
>public shouldn't use because it could cause "bad things" to happen.

What "bad things"? All interfaces defined in public are "vulnerable" and 
can be used by the public. If we want to add a notion that this interface 
is new and still underdevelopment, then we probably can add a more explicit 
tag and deprecate "$Private" tag.

>Perhaps hxcore.h isn't the right place for this interface. Any suggestions?

I suggest to put it in a separate new file. I also suggest to move 
hxsrcbufstats.* from client/common to common/util, since protocol/rtsp is 
also built by the server and it should not depend on client/common

-->Henry

> >
> > around the new interface definition? Seems like since
> > hxcore.h is out in the public anyway, that our
> > Private/EndPrivate stuff is moot.
> >
> > I'm not suggesting we go through and remove them from
> > all header files, but it seems to me we shouldn't be
> > adding any *more* of them.
> >
> > Eric
> >
> > At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
> > >Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> > >          number information can be maintained as well.
> > >
> > >Overview: These changes move the IHXSourceBufferingStats2 implementation
> > >          out of HXBufferingState and into a new class called
> > >          HXSourceBufferStats. This was done because the client needs to
> > >          track packet sequence numbers for 3GPP-Rel6 OBSN support.
> > >          There was no good way to get the sequence number information to
> > >          the HXBufferingState class so the IHXSourceBufferingStats2 logic
> > >          was moved to where this information is available.
> > >
> > >          A new interface called IHXTransportOnTimeSync was created to
> > >          propagate OnTimeSync() like calls to HXSourceBufferStats. The
> > >          time passed to the OnTimeSync() call in this interface MUST
> > >          NOT have any offsets created by SMIL or live playback. The time
> > >          should be in the same time frame as the packets coming from the
> > >          transport. If someone wants to rename this interface that is 
> fine
> > >          by me.
> > >
> > >
> > >          - Created HXSourceBufferStats to contain the base
> > >            IHXSourceBufferingStats2 implementation. This class is
> > >            used by HXFileSource.
> > >
> > >          - Created HXNetSourceBufStats which derives from
> > >HXSourceBufferStats.
> > >            This class just overloads the GetCurrentBuffering() so that it
> > >            returns the amount of data in the transport buffer. This is
> > >            used by RTSPClientProtocol.
> > >
> > >          - Removed IHXSourceBufferingStats2 code from HXSource
> > >
> > >          - Removed packet tracking code from HXBufferingState. This
> > >            functionality is implemented by HXSourceBufferStats now
> > >
> > >          - Added code to HXSource to provide OnTimeSync() calls to the
> > >            IHXTransportOnTimeSync interface.
> > >
> > >          - HXSource now exposes IHXSourceBufferingStats functionality
> > >through
> > >            it's m_pSrcBufStats member variable instead of implementing it
> > >            itself. The file and network sources are expected to 
> provide an
> > >            IHXSourceBufferingStats2 interface via a
> > >            HXSource::SetSrcBufStats() call.
> > >
> > >          - Added code to HXFileSource to use HXSourceBufferStats
> > >
> > >          - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> > >
> > >          - Fixed some code in CBufferManager that was expecting HXSource
> > >            to implement IHXSourceBufferingStats. This code now QI's for
> > >            IHXSourceBufferingStats and uses that interface.
> > >
> > >
> > >
> > >Files Modified:
> > >client/core/buffmgr.cpp
> > >client/core/hxbsrc.h
> > >client/core/hxbufstate.h
> > >client/core/hxbufstate.cpp
> > >client/core/hxflsrc.cpp
> > >client/core/hxflsrc.h
> > >client/core/hxntsrc.cpp
> > >client/core/hxntsrc.h
> > >client/core/hxsrc.cpp
> > >client/core/rtspprotocol.cpp
> > >protocol/rtsp/Umakefil
> > >protocol/rtsp/rtspclnt.cpp
> > >protocol/rtsp/pub/rtspclnt.h
> > >protocol/transport/common/system/rtsptran.cpp
> > >protocol/transport/common/system/pub/rtsptran.h
> > >client/common/util/Umakefil
> > >common/include/hxcore.h
> > >common/include/hxpiids.h
> > >
> > >Files Added:
> > >client/common/util/pub/hxsrcbufstats.h
> > >client/common/util/hxsrcbufstats.cpp
> > >protocol/rtsp/ntsrcbufstats.h
> > >protocol/rtsp/ntsrcbufstats.cpp
> > >
> > >Image Size and Heap Use impact:
> > >
> > >Platforms and Profiles affected: all
> > >
> > >Distribution Libraries affected: rdtclntlib
> > >
> > >Distribution library impact and planned action:
> > >m_bIsLive and m_pSrcBufStats member variables were added to
> > >RTSPClientProtocol so any derived objects will need to be
> > >recompiled
> > >
> > >Platforms and Profiles Build Verified: win32
> > >
> > >Platforms and Profiles Functionality verified: win32
> > >
> > >Branch: HEAD
> > >
> > >QA Instructions: none
> > >
> > >Index: buffmgr.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/buffmgr.cpp,v
> > >retrieving revision 1.21
> > >diff -u -r1.21 buffmgr.cpp
> > >--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
> > >+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> > >@@ -610,6 +610,11 @@
> > >      * - Keep track of the stream with the lowest timestamp and is
> > >      *   buffering data
> > >      */
> > >+    IHXSourceBufferingStats* pSrcBufStats = NULL;
> > >+
> > >+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> > >+                              (void**)&pSrcBufStats);
> > >+
> > >     for (i = m_pStreamInfoTable->Begin(); i !=
> > >m_pStreamInfoTable->End(); ++i)
> > >     {
> > >        pStreamInfo = (STREAM_INFO*) (*i);
> > >@@ -619,12 +624,15 @@
> > >        ULONG32 ulNumBytesAtTransport = 0;
> > >        BOOL bDoneAtTransport = FALSE;
> > >
> > >-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> > >-                                      llLowestTimestampAtTransport,
> > >-                                      llHighestTimestampAtTransport,
> > >-                                      ulNumBytesAtTransport,
> > >-                                      bDoneAtTransport);
> > >-
> > >+        if (pSrcBufStats)
> > >+        {
> > >+
> > >pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> > >+
> > >llLowestTimestampAtTransport,
> > >+
> > >llHighestTimestampAtTransport,
> > >+                                              ulNumBytesAtTransport,
> > >+                                              bDoneAtTransport);
> > >+        }
> > >+
> > >        pStreamInfo->BufferingState().UpdateTransportStats(
> > >            llLowestTimestampAtTransport,
> > >            llHighestTimestampAtTransport,
> > >@@ -658,6 +666,7 @@
> > >
> > >        }
> > >     }
> > >+    HX_RELEASE(pSrcBufStats);
> > >
> > >     /* If none of the streams have any data buffered at the transport
> > >     layer,
> > >      * return.
> > >Index: hxbsrc.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxbsrc.h,v
> > >retrieving revision 1.18.2.1
> > >diff -u -r1.18.2.1 hxbsrc.h
> > >--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
> > >+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
> > >@@ -233,12 +233,11 @@
> > >                  public IHXPrivateStreamSource,
> > >                  public IHXBackChannel,
> > >                  public IHXASMSource,
> > >-                  public IHXClientRateAdaptControl,
> > >+                  public IHXClientRateAdaptControl
> > > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> > >-                 public IHXHyperNavigate,
> > >-                 public IHXHyperNavigate2,
> > >+                 , public IHXHyperNavigate,
> > >+                 public IHXHyperNavigate2
> > > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > >-                  public IHXSourceBufferingStats2
> > > {
> > > protected:
> > >     LONG32                     m_lRefCount;
> > >@@ -487,35 +486,6 @@
> > >                            IHXValues* pParams);
> > > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > >
> > >-
> > >/************************************************************************
> > >-     * Method:
> > >-     *     IHXSourceBufferingStats2::GetCurrentBuffering
> > >-     * Purpose:
> > >-     *     Get the current buffering information
> > >-     */
> > >-
> > >-    STDMETHOD(GetCurrentBuffering) (THIS_
> > >-                                    UINT16  uStreamNumber,
> > >-                                    REF(INT64)  llLowestTimestamp,
> > >-                                    REF(INT64)  llHighestTimestamp,
> > >-                                    REF(UINT32) ulNumBytes,
> > >-                                    REF(BOOL)   bDone) PURE;
> > >-
> > >/************************************************************************
> > >-     * Method:
> > >-     *     IHXSourceBufferingStats2::GetTotalBuffering
> > >-     * Purpose:
> > >-     *     Get the total amount of data buffered for a stream.
> > >-     *      This includes what is in the transport buffer and in
> > >-     *      the renderer
> > >-     */
> > >-
> > >-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> > >-                                  REF(INT64)  llLowestTimestamp,
> > >-                                  REF(INT64)  llHighestTimestamp,
> > >-                                  REF(UINT32) ulNumBytes,
> > >-                                  REF(BOOL)   bDone);
> > >-
> > >-
> > >     /*
> > >      * IHXClientRateAdaptControl Methods
> > >      */
> > >@@ -731,7 +701,7 @@
> > >            virtual HX_RESULT   FillRecordControl() = 0;
> > >                    BOOL        IsPlayingFromRecordControl() { return
> > >m_bPlayFromRecordControl; };
> > >
> > >-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > >+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > >
> > >             const char*         GetRedirectURL() { return
> > >(m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
> > >             const char*         GetSDPURL() { return (m_pSDPURL ?
> > >m_pSDPURL->GetURL() : NULL); };
> > >@@ -769,6 +739,8 @@
> > >             void        ProcessFileHeader(void);
> > >             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader,
> > >STREAM_INFO*& pStreamInfo);
> > >
> > >+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> > >+
> > >     HX_RESULT                  mLastError;
> > >     CHXMapLongToObj*            mStreamInfoTable;
> > >
> > >@@ -868,6 +840,8 @@
> > >     CHXURL*                     m_pRedirectURL;
> > >     CHXURL*                     m_pSDPURL;
> > >     BOOL                        m_bRedirectPending;
> > >+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> > >+    IHXSourceBufferingStats2*   m_pSrcBufStats;
> > > };
> > >
> > > // Defined flags
> > >Index: hxbufstate.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> > >retrieving revision 1.7
> > >diff -u -r1.7 hxbufstate.cpp
> > >--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
> > >+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
> > >@@ -83,18 +83,11 @@
> > >     , m_ulLastPacketTimeStamp(0)
> > >     , m_ulAvgBandwidth(0)
> > >     , m_pASMProps(NULL)
> > >-    , m_llCurrentPlaybackTime(0)
> > >-    , m_ulBufferedData(0)
> > >-    , m_ulLastTimeSync(0)
> > >-    , m_llFirstLivePacketTimestamp(0)
> > >-    , m_ulTimeSyncRollOver(0)
> > > {}
> > >
> > > HXBufferingState::~HXBufferingState()
> > > {
> > >     HX_RELEASE(m_pASMProps);
> > >-
> > >-    ClearPktInfo();
> > > }
> > >
> > > void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> > >@@ -179,8 +172,6 @@
> > >     m_ulLastPacketTimeStamp = 0;
> > >     m_bIsFirstPacket = TRUE;
> > >
> > >-    ClearPktInfo();
> > >-
> > >     if (bIsSeeking)
> > >     {
> > >        m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> > >@@ -288,11 +279,6 @@
> > >     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 +
> > >CAST_TO_INT64 ulTime;
> > > }
> > >
> > >-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> > >-{
> > >-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64
> > >MAX_UINT32 + CAST_TO_INT64 ulTime;
> > >-}
> > >-
> > > void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> > >                                UINT32 ulElapsedTime,
> > >                                BOOL bIsLive, BOOL bIsBufferedPlayMode)
> > >@@ -318,16 +304,12 @@
> > >        if (bIsLive)
> > >        {
> > >            m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> > >-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
> > >         }
> > >
> > >        m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
> > >        m_bIsFirstPacket = FALSE;
> > >     }
> > >
> > >-    // Add this packet to our packet info statistics
> > >-    AddPktInfo(llActualTimeStamp, ulPacketSize);
> > >-
> > >     // data based preroll
> > >     if (DataBasedPreroll())
> > >     {
> > >@@ -451,47 +433,6 @@
> > >     m_bDoneAtTransport = bDoneAtTransport;
> > > }
> > >
> > >-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
> > >-                                             REF(INT64) llHighTimestamp,
> > >-                                             REF(UINT32) ulBytesBuffered,
> > >-                                             BOOL bUseTransportStats)
> > >-{
> > >-    HX_RESULT res = HXR_NO_DATA;
> > >-
> > >-    if (!m_bIsFirstPacket)
> > >-    {
> > >-       if (!m_pktInfo.IsEmpty())
> > >-       {
> > >-           HXBufferedPktInfo* pPktInfo =
> > >-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
> > >-
> > >-           llLowTimestamp = pPktInfo->Timestamp();
> > >-       }
> > >-       else
> > >-       {
> > >-           llLowTimestamp = m_llHighestTimeStamp;
> > >-       }
> > >-
> > >-       llHighTimestamp = m_llHighestTimeStamp;
> > >-       ulBytesBuffered = GetBufferedData();
> > >-
> > >-
> > >-       if (bUseTransportStats)
> > >-       {
> > >-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
> > >-           {
> > >-               llHighTimestamp = m_llHighestTimestampAtTransport;
> > >-           }
> > >-
> > >-           ulBytesBuffered += m_ulNumBytesAtTransport;
> > >-       }
> > >-
> > >-       res = HXR_OK;
> > >-    }
> > >-
> > >-    return res;
> > >-}
> > >-
> > > void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
> > >                                           INT64 llTheHighestTS,
> > >                                           BOOL bIsSeekPerformed,
> > >@@ -569,19 +510,6 @@
> > >
> > > }
> > >
> > >-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> > >-{
> > >-    //  0xFA .. 0xFF [roll over] (0x01)
> > >-    if (m_ulLastTimeSync > ulCurrentTime &&
> > >-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> > >-    {
> > >-       m_ulTimeSyncRollOver++;
> > >-    }
> > >-    m_ulLastTimeSync = ulCurrentTime;
> > >-
> > >-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> > >-}
> > >-
> > > void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
> > >                                        ULONG32 ulMinBufferingInMs)
> > > {
> > >@@ -771,62 +699,4 @@
> > >     {
> > >        m_ulAvgBandwidth = ulBandwidth;
> > >     }
> > >-}
> > >-
> > >-void HXBufferingState::ClearPktInfo()
> > >-{
> > >-    m_ulBufferedData = 0;
> > >-    while(!m_pktInfo.IsEmpty())
> > >-    {
> > >-       HXBufferedPktInfo* pInfo =
> > >(HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> > >-       delete pInfo;
> > >-    }
> > >-}
> > >-
> > >-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
> > >-{
> > >-    // Subtract off the first live packet timestamp.
> > >-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> > >-    llTimestamp -= m_llFirstLivePacketTimestamp;
> > >-    // Create the HXBufferedPktInfo class
> > >-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
> > >-                                                       ulPacketSize);
> > >-    if (pPktInfo)
> > >-    {
> > >-       m_pktInfo.AddTail(pPktInfo);
> > >-       m_ulBufferedData += ulPacketSize;
> > >-    }
> > >-
> > >-    // purge the old packet info data
> > >-    //  this keeps the list short and prevents the Symbian
> > >-    //  allocator from freaking out
> > >-    (void)GetBufferedData();
> > >-}
> > >-
> > >-UINT32 HXBufferingState::GetBufferedData()
> > >-{
> > >-    BOOL bDone = m_pktInfo.IsEmpty();
> > >-
> > >-    // Remove all packet info that is past due
> > >-    // and subtract their sizes from our buffering total
> > >-    while(!bDone)
> > >-    {
> > >-       HXBufferedPktInfo* pPktInfo =
> > >(HXBufferedPktInfo*)m_pktInfo.GetHead();
> > >-
> > >-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> > >-       {
> > >-           m_ulBufferedData -= pPktInfo->Size();
> > >-
> > >-           m_pktInfo.RemoveHead();
> > >-           delete pPktInfo;
> > >-
> > >-           bDone = m_pktInfo.IsEmpty();
> > >-       }
> > >-       else
> > >-       {
> > >-           bDone = TRUE;
> > >-       }
> > >-    }
> > >-
> > >-    return m_ulBufferedData;
> > > }
> > >Index: hxbufstate.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxbufstate.h,v
> > >retrieving revision 1.4
> > >diff -u -r1.4 hxbufstate.h
> > >--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
> > >+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
> > >@@ -81,7 +81,6 @@
> > >     BOOL HasPredata(BOOL bIsSeekPerformed);
> > >
> > >     INT64 CreateINT64Timestamp(UINT32 ulTime);
> > >-    INT64 CreateINT64Timesync(UINT32 ulTime);
> > >
> > >     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> > >                  UINT32 ulElapsedTime, BOOL bIsLive,
> > >@@ -98,11 +97,6 @@
> > >                              ULONG32 ulBytesAtTransport,
> > >                              BOOL bDoneAtTransport);
> > >
> > >-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
> > >-                               REF(INT64) llHighTimestamp,
> > >-                               REF(UINT32) ulBytesBuffered,
> > >-                               BOOL bUseTransportStats);
> > >-
> > >     void GetExcessBufferInfo(INT64 llTheLowestTS,
> > >                             INT64 llTheHighestTS,
> > >                             BOOL bIsSeekPerformed,
> > >@@ -119,8 +113,6 @@
> > >
> > >     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
> > >
> > >-    void OnTimeSync(UINT32 ulCurrentTime);
> > >-
> > >     // Should remove
> > >     void SetAvgBWToASMBw();
> > >     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> > >@@ -149,19 +141,6 @@
> > >                        UINT32 ulCurrentBuffering,
> > >                        UINT32 ulMinimumPreroll,
> > >                        UINT32 ulDenom) const;
> > >-
> > >-    /* Functions for tracking the amount of data
> > >-     * buffered in the renderer
> > >-     */
> > >-    void ClearPktInfo(); /* Clears out information about buffered 
> packets
> > >*/
> > >-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called
> > >when
> > >-                                                             * a 
> packet is
> > >-                                                             * sent 
> to the
> > >-                                                             * renderer
> > >-                                                             */
> > >-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
> > >-                              * in the renderer
> > >-                              */
> > >
> > >     ULONG32            m_ulPreroll;
> > >     ULONG32            m_ulPredata;
> > >@@ -196,20 +175,6 @@
> > >     ULONG32            m_ulLastPacketTimeStamp;
> > >     ULONG32            m_ulAvgBandwidth;
> > >     IHXASMProps*       m_pASMProps;
> > >-    UINT32              m_ulLastTimeSync;
> > >-    INT64               m_llFirstLivePacketTimestamp;
> > >-    UINT32              m_ulTimeSyncRollOver;
> > >-    // These variable keep track of the amount of
> > >-    // data buffered in the renderer
> > >-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
> > >-                                                 * OnTimeSync() call
> > >-                                                 */
> > >-
> > >-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> > >-                                          * Always use GetBufferedData()
> > >-                                          * to retreive the value
> > >-                                          */
> > >-    CHXSimpleList       m_pktInfo; /* List of packet information */
> > > };
> > >
> > > inline
> > >Index: hxflsrc.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> > >retrieving revision 1.54
> > >diff -u -r1.54 hxflsrc.cpp
> > >--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
> > >+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> > >@@ -76,6 +76,7 @@
> > > #include "uri_schemes.h"
> > > #include "stream_desc_hlpr.h"
> > > #include "findfile.h"
> > >+#include "hxsrcbufstats.h"
> > >
> > > #include "hxheap.h"
> > > #ifdef _DEBUG
> > >@@ -115,6 +116,7 @@
> > >     , m_bValidateMetaDone(FALSE)
> > >     , m_pFileRecognizer(NULL)
> > >     , m_pFileReader(NULL)
> > >+    , m_pSrcBufStats(NULL)
> > > {
> > >     m_bAltURL = FALSE;
> > >     m_bPerfectPlay = TRUE;
> > >@@ -306,6 +308,13 @@
> > >
> > >     HX_VECTOR_DELETE(m_pszURL);
> > >     HX_DELETE(m_pURL);
> > >+
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >+    m_pSrcBufStats = new HXSourceBufferStats();
> > >+    if (m_pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats->AddRef();
> > >+    }
> > >
> > >     if (!theErr && pURL)
> > >     {
> > >@@ -938,6 +947,7 @@
> > >     }
> > > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
> > >
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >     HXSource::DoCleanup();
> > >
> > >     return HXR_OK;
> > >@@ -1068,6 +1078,11 @@
> > >
> > >     m_llLastFillEndTime = 0;
> > >
> > >+    if (m_pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats->Reset();
> > >+    }
> > >+
> > > cleanup:
> > >
> > >     return HXR_OK;
> > >@@ -1442,6 +1457,11 @@
> > >
> > >            if(m_pBufferManager)
> > >                m_pBufferManager->UpdateCounters(pPacket, 0);
> > >+
> > >+            if (m_pSrcBufStats && !pPacket->IsLost())
> > >+            {
> > >+                m_pSrcBufStats->OnPacket(pPacket);
> > >+            }
> > >
> > >            HX_RELEASE(pPacket);
> > >        }
> > >@@ -2103,6 +2123,13 @@
> > >        }
> > >        HX_RELEASE(pszParentName);
> > > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> > >+
> > >+        if (pStreamInfo && m_pSrcBufStats)
> > >+        {
> > >+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> > >+                                 mLiveStream);
> > >+        }
> > >+
> > >         m_ulStreamIndex++;
> > >         m_uNumStreams++;
> > >     }
> > >@@ -2115,6 +2142,11 @@
> > >
> > >        theErr = AdjustClipTime();
> > >        m_pBufferManager->Init();
> > >+
> > >+        if (m_pSrcBufStats)
> > >+        {
> > >+            SetSrcBufStats(m_pSrcBufStats);
> > >+        }
> > >     }
> > >
> > >     return theErr;
> > >@@ -2313,6 +2345,11 @@
> > >        {
> > >            m_pBufferManager->UpdateCounters(pPacket, 0);
> > >        }
> > >+
> > >+        if (m_pSrcBufStats && !pPacket->IsLost())
> > >+        {
> > >+            m_pSrcBufStats->OnPacket(pPacket);
> > >+        }
> > >     }
> > >
> > >     m_llLastFillEndTime = llActualPacketTime;
> > >Index: hxflsrc.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxflsrc.h,v
> > >retrieving revision 1.12
> > >diff -u -r1.12 hxflsrc.h
> > >--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
> > >+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
> > >@@ -52,6 +52,8 @@
> > > #include "hxfiles.h"
> > > #include "recognizer.h"
> > >
> > >+class HXSourceBufferStats;
> > >+
> > > class HXFileSource : public HXSource,
> > >                      public IHXFormatResponse,
> > >                       public IHXHTTPRedirectResponse
> > >@@ -349,6 +351,7 @@
> > >
> > >     CFileReader*                m_pFileReader;
> > >     CHXFileRecognizer*          m_pFileRecognizer;
> > >+    HXSourceBufferStats*        m_pSrcBufStats;
> > > };
> > >
> > > #endif // _HX_FILE_SOURCE
> > >Index: hxntsrc.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> > >retrieving revision 1.90
> > >diff -u -r1.90 hxntsrc.cpp
> > >--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
> > >+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> > >@@ -675,6 +675,7 @@
> > >     HX_RESULT   rc = HXR_OK;
> > >     BOOL        bSDPInitiated = FALSE;
> > >     CHXString   pString;
> > >+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
> > >
> > >     // start off with the preferred protocol
> > >     rc = CreateProtocol();
> > >@@ -722,6 +723,14 @@
> > >         goto cleanup;
> > >     }
> > >
> > >+    // Setup source buffer stats
> > >+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> > >+                                           (void**)&pSrcBufStats))
> > >+    {
> > >+        SetSrcBufStats(pSrcBufStats);
> > >+        HX_RELEASE(pSrcBufStats);
> > >+    }
> > >+
> > >     // create log info list
> > >     m_pLogInfoList = new CHXSimpleList;
> > >     m_ulLogInfoLength = 0;
> > >@@ -6295,6 +6304,12 @@
> > > #else
> > >     return HXR_NOTIMPL;
> > > #endif /* HELIX_FEATURE_RECORDCONTROL */
> > >+}
> > >+
> > >+HX_RESULT
> > >+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> > >+{
> > >+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
> > > }
> > >
> > > ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> > >Index: hxntsrc.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxntsrc.h,v
> > >retrieving revision 1.24
> > >diff -u -r1.24 hxntsrc.h
> > >--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
> > >+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
> > >@@ -282,6 +282,7 @@
> > >
> > >        virtual HX_RESULT       FillRecordControl();
> > >
> > >+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > > protected:
> > >
> > >        virtual                         ~HXNetSource(void);
> > >@@ -470,7 +471,6 @@
> > > private:
> > >         IHXBufferControl*                m_pBufferCtl;
> > >         IHXWatermarkBufferControl*       m_pWMBufferCtl;
> > >-
> > > public:
> > >        HX_RESULT       FinishSetup();
> > >        void            ReSetup();
> > >Index: hxsrc.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxsrc.cpp,v
> > >retrieving revision 1.44.2.1
> > >diff -u -r1.44.2.1 hxsrc.cpp
> > >--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
> > >+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
> > >@@ -213,6 +213,8 @@
> > >         , m_pRedirectURL(NULL)
> > >         , m_pSDPURL(NULL)
> > >         , m_bRedirectPending(FALSE)
> > >+        , m_pTransOnTimeSync(NULL)
> > >+        , m_pSrcBufStats(NULL)
> > > {
> > >     mStreamInfoTable = new CHXMapLongToObj;
> > > }
> > >@@ -313,6 +315,8 @@
> > >     HX_DELETE(m_pRedirectURL);
> > >     HX_DELETE(m_pSDPURL);
> > >     m_bRedirectPending  = FALSE;
> > >+    HX_RELEASE(m_pTransOnTimeSync);
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >
> > > #if defined(HELIX_FEATURE_RECORDCONTROL)
> > >     if(m_pRecordControl)
> > >@@ -340,8 +344,6 @@
> > >             { GET_IIDHANDLE(IID_IHXPendingStatus),
> > >(IHXPendingStatus*)this },
> > >             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
> > >             { GET_IIDHANDLE(IID_IHXPrivateStreamSource),
> > >(IHXPrivateStreamSource*)this },
> > >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats),
> > >(IHXSourceBufferingStats*)this },
> > >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2),
> > >(IHXSourceBufferingStats2*)this },
> > >             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
> > >               (IHXClientRateAdaptControl*)this },
> > > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> > >@@ -388,6 +390,14 @@
> > >            return HXR_NOINTERFACE;
> > >        }
> > >     }
> > >+    else if (m_pSrcBufStats &&
> > >+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> > >+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> > >+    {
> > >+        m_pSrcBufStats->AddRef();
> > >+        *ppvObj = m_pSrcBufStats;
> > >+        return HXR_OK;
> > >+    }
> > >
> > > #if defined(HELIX_FEATURE_AUTOUPGRADE)
> > >     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> > >@@ -2250,59 +2260,6 @@
> > > }
> > > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > >
> > >-STDMETHODIMP
> > >-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> > >-                           REF(INT64)  llLowestTimestamp,
> > >-                           REF(INT64)  llHighestTimestamp,
> > >-                           REF(UINT32) ulNumBytes,
> > >-                           REF(BOOL)   bDone)
> > >-{
> > >-    HX_RESULT res = HXR_NO_DATA;
> > >-
> > >-    llLowestTimestamp = 0;
> > >-    llHighestTimestamp = 0;
> > >-    ulNumBytes = 0;
> > >-    bDone = FALSE;
> > >-
> > >-    STREAM_INFO* pStreamInfo;
> > >-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*&
> > >)pStreamInfo))
> > >-    {
> > >-       HXBufferingState& bufState = pStreamInfo->BufferingState();
> > >-       BOOL   bUseTransportStats = FALSE;
> > >-
> > >-       INT64  llTransportLowTS = 0;
> > >-       INT64  llTransportHighTS = 0;
> > >-       UINT32 ulTransportBytes = 0;
> > >-       BOOL   bTransportDone = FALSE;
> > >-
> > >-       if (!IsLocalSource() &&
> > >-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
> > >-                                          llTransportLowTS,
> > >-                                          llTransportHighTS,
> > >-                                          ulTransportBytes,
> > >-                                          bTransportDone)))
> > >-       {
> > >-           bufState.UpdateTransportStats(llTransportLowTS,
> > >-                                         llTransportHighTS,
> > >-                                         ulTransportBytes,
> > >-                                         bTransportDone);
> > >-
> > >-           bUseTransportStats = TRUE;
> > >-
> > >-           // Update bDone with what the transport says.
> > >-           bDone = bTransportDone;
> > >-       }
> > >-
> > >-       res = bufState.GetBufferingStats(llLowestTimestamp,
> > >-                                       llHighestTimestamp,
> > >-                                       ulNumBytes,
> > >-                                       bUseTransportStats);
> > >-    }
> > >-
> > >-
> > >-    return res;
> > >-}
> > >-
> > > /*
> > >  * IHXClientRateAdaptControl Methods
> > >  */
> > >@@ -2948,13 +2905,34 @@
> > > {
> > >     HX_RESULT res = HXR_OK;
> > >
> > >-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> > >-         i != mStreamInfoTable->End(); ++i)
> > >-    {
> > >-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> > >-
> > >-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> > >+    // Convert presentation time to transport time
> > >+    if (m_pTransOnTimeSync)
> > >+    {
> > >+        ULONG32 ulOffset = m_ulDelay;
> > >+        ULONG32 ulTransportTime = m_ulStartTime;
> > >+
> > >+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> > >+        {
> > >+            ulTransportTime += ulCurrentTime - ulOffset;
> > >+        }
> > >+
> > >+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
> > >     }
> > >
> > >     return res;
> > >+}
> > >+
> > >+void
> > >+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> > >+{
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >+    HX_RELEASE(m_pTransOnTimeSync);
> > >+
> > >+    if (pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats = pSrcBufStats;
> > >+        m_pSrcBufStats->AddRef();
> > >+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> > >+                                       (void**)&m_pTransOnTimeSync);
> > >+    }
> > > }
> > >Index: rtspprotocol.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> > >retrieving revision 1.39
> > >diff -u -r1.39 rtspprotocol.cpp
> > >--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
> > >+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
> > >@@ -2626,12 +2626,12 @@
> > >     UINT16 seekFrom
> > > )
> > > {
> > >+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> > >+
> > >     if (IsLive())
> > >     {
> > >-        return m_pProtocolLib->SeekFlush();
> > >+        return theErr;
> > >     }
> > >-
> > >-    HX_RESULT theErr = HXR_OK;
> > >
> > >     m_uCurrentStreamCount = m_uStreamCount;
> > >
> > >
> > >Index: Umakefil
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> > >retrieving revision 1.9.2.1
> > >diff -u -r1.9.2.1 Umakefil
> > >--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
> > >+++ Umakefil    22 Jun 2004 22:52:32 -0000
> > >@@ -46,6 +46,7 @@
> > >                          'common/runtime/pub',
> > >                          'common/lang/xml/pub',
> > >                          'client/common/container/pub',
> > >+                          'client/common/util/pub',
> > >                          'protocol/transport/rtp/include',
> > >                          'server/include',
> > >                           'server/common/struct/pub',
> > >@@ -65,7 +66,7 @@
> > >                   'rtspmsg.cpp', 'rtspmdsc.cpp',
> > >                   'rtsppars.cpp', 'mhprop.cpp',
> > >                   'servrsnd.cpp', '3gpadapthdr.cpp',
> > >-                   'rateadaptinfo.cpp')
> > >+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
> > >
> > > if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
> > >     project.AddSources('pipelinedesc.cpp')
> > >Index: rtspclnt.cpp
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> > >retrieving revision 1.79.2.1
> > >diff -u -r1.79.2.1 rtspclnt.cpp
> > >--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
> > >+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
> > >@@ -95,6 +95,7 @@
> > > #include "pipelinedesc.h"
> > > #include "errdbg.h"
> > > #include "rateadaptinfo.h"
> > >+#include "ntsrcbufstats.h"
> > >
> > > #include "hxheap.h"
> > > #ifdef _DEBUG
> > >@@ -302,6 +303,12 @@
> > >     {
> > >         return HXR_OK;
> > >     }
> > >+    else if (m_pSrcBufStats &&
> > >+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> > >+                                                       ppvObj)))
> > >+    {
> > >+        return HXR_OK;
> > >+    }
> > >     *ppvObj = NULL;
> > >     return HXR_NOINTERFACE;
> > > }
> > >@@ -388,6 +395,7 @@
> > >     m_bReportedSuccessfulTransport(FALSE),
> > >     m_bSDPInitiated(FALSE),
> > >     m_bMulticast(FALSE),
> > >+    m_bIsLive(FALSE),
> > >     m_pSDPFileHeader(NULL),
> > >     m_pSDPStreamHeaders(NULL),
> > >     m_bSessionSucceeded(FALSE),
> > >@@ -404,7 +412,8 @@
> > >     m_ulCurrentTimeOut(0),
> > >     m_pUAProfURI(NULL),
> > >     m_pUAProfDiff(NULL),
> > >-    m_pRateAdaptInfo(NULL)
> > >+    m_pRateAdaptInfo(NULL),
> > >+    m_pSrcBufStats(NULL)
> > > #if defined(_MACINTOSH)
> > >     , m_pCallback(NULL)
> > > #endif /* _MACINTOSH */
> > >@@ -460,6 +469,8 @@
> > >         m_pRateAdaptInfo->Close();
> > >         HX_DELETE(m_pRateAdaptInfo);
> > >     }
> > >+
> > >+    HX_RELEASE(m_pSrcBufStats);
> > > }
> > >
> > > /*
> > >@@ -810,6 +821,21 @@
> > >         }
> > >     }
> > >
> > >+    if (HXR_OK == hresult)
> > >+    {
> > >+        HX_RELEASE(m_pSrcBufStats);
> > >+        m_pSrcBufStats = new HXNetSourceBufStats(this);
> > >+
> > >+        if (m_pSrcBufStats)
> > >+        {
> > >+            m_pSrcBufStats->AddRef();
> > >+        }
> > >+        else
> > >+        {
> > >+            hresult = HXR_OUTOFMEMORY;
> > >+        }
> > >+    }
> > >+
> > > #if defined(_MACINTOSH)
> > >     if (m_pCallback &&
> > >         m_pCallback->m_bIsCallbackPending &&
> > >@@ -2191,7 +2217,14 @@
> > >         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> > >     if (pTrans)
> > >     {
> > >-        rc = pTrans->getPacket(uStreamNumber, pPacket);
> > >+        UINT32 uSeqNum;
> > >+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> > >+
> > >+        if ((HXR_OK == rc) && m_pSrcBufStats &&
> > >+            (!pPacket->IsLost()))
> > >+        {
> > >+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> > >+        }
> > >     }
> > >
> > >     m_pMutex->Unlock();
> > >@@ -3291,16 +3324,24 @@
> > >     HX_RESULT rc = HXR_OK;
> > >     m_pMutex->Lock();
> > >
> > >-    CHXMapLongToObj::Iterator i;
> > >-    for(i=m_pTransportStreamMap->Begin();
> > >-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> > >+    if (m_bIsLive)
> > >     {
> > >-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> > >-        UINT16 streamNumber = (UINT16)i.get_key();
> > >-
> > >-        HX_ASSERT(pTransport);
> > >+        CHXMapLongToObj::Iterator i;
> > >+        for(i=m_pTransportStreamMap->Begin();
> > >+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> > >+        {
> > >+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> > >+            UINT16 streamNumber = (UINT16)i.get_key();
> > >+
> > >+            HX_ASSERT(pTransport);
> > >+
> > >+            rc = pTransport ? pTransport->SeekFlush(streamNumber) :
> > >HXR_OK;
> > >+        }
> > >+    }
> > >
> > >-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> > >+    if (m_pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats->Reset();
> > >     }
> > >
> > >     m_pMutex->Unlock();
> > >@@ -6964,6 +7005,11 @@
> > >         // Get session level RTP bandwidth modifiers
> > >         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
> > >         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> > >+
> > >+        if (ulIsSessionLive)
> > >+        {
> > >+            m_bIsLive = TRUE;
> > >+        }
> > >
> > >         // get multicast address from the session description
> > >         if (HXR_OK ==
> > >ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> > >@@ -7187,6 +7233,11 @@
> > >             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
> > >             pInfo->m_bRealMedia = bRealMedia;
> > >
> > >+            if (m_pSrcBufStats)
> > >+            {
> > >+                m_pSrcBufStats->Init((UINT16)streamNumber,
> > >pInfo->m_bIsLive);
> > >+            }
> > >+
> > >             if (m_pRateAdaptInfo)
> > >             {
> > >                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> > >@@ -7222,6 +7273,7 @@
> > >         if (m_bMulticast)
> > >         {
> > >             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> > >+            m_bIsLive = TRUE;
> > >         }
> > >     }
> > >
> > >Index: pub/rtspclnt.h
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> > >retrieving revision 1.30.2.1
> > >diff -u -r1.30.2.1 rtspclnt.h
> > >--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
> > >+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
> > >@@ -46,6 +46,7 @@
> > > #include "hxbufctl.h" // IHXTransportBufferLimit
> > > #include "hxrtsp2.h"
> > > #include "hxrsdbf.h" // IHXResendBufferControl
> > >+#include "hxprefs.h" // IHXPreferences
> > >
> > > class RTSPClientState;
> > > class RTSPOptionsMessage;
> > >@@ -63,6 +64,7 @@
> > > class MIMEHeader;
> > > class PipelinedDescribeLogic;
> > > class CHXRateAdaptationInfo;
> > >+class HXNetSourceBufStats;
> > >
> > > struct IHXKeyValueList;
> > > struct IHXValues;
> > >@@ -1039,6 +1041,7 @@
> > >
> > >     BOOL                                m_bSDPInitiated;
> > >     BOOL                                m_bMulticast;
> > >+    BOOL                                m_bIsLive;
> > >     IHXValues*                          m_pSDPFileHeader;
> > >     CHXSimpleList*                      m_pSDPStreamHeaders;
> > >
> > >@@ -1074,6 +1077,7 @@
> > >     UINT32                              m_ulServerTimeOut;
> > >     UINT32                              m_ulCurrentTimeOut;
> > >     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> > >+    HXNetSourceBufStats*                m_pSrcBufStats;
> > >
> > > #if defined(_MACINTOSH)
> > >     RTSPClientProtocolCallback*                m_pCallback;
> > >
> > >Index: rtsptran.cpp
> > >===================================================================
> > >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> > >retrieving revision 1.26
> > >diff -u -r1.26 rtsptran.cpp
> > >--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
> > >+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
> > >@@ -526,8 +526,17 @@
> > >     }
> > > }
> > >
> > >+HX_RESULT
> > >+RTSPTransport::getPacket(UINT16 uStreamNumber,
> > >+                         IHXPacket*& pPacket)
> > >+{
> > >+    UINT32 uSeqNum;
> > >+    return getPacket(uStreamNumber, pPacket, uSeqNum);
> > >+}
> > >+
> > > HX_RESULT
> > >-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> > >+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
> > >+                         REF(UINT32) uSeqNum)
> > > {
> > >     RTSPTransportBuffer* pTransportBuffer =
> > >getTransportBuffer(uStreamNumber);
> > >     RTSPStreamData* pStreamData =
> > >m_pStreamHandler->getStreamData(uStreamNumber);
> > >@@ -547,6 +556,7 @@
> > >     }
> > >
> > >     pPacket = clientPacket->GetPacket();
> > >+    uSeqNum = clientPacket->GetSequenceNumber();
> > >
> > >     if (!pPacket)
> > >     {
> > >Index: pub/rtsptran.h
> > >===================================================================
> > >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> > >retrieving revision 1.19
> > >diff -u -r1.19 rtsptran.h
> > >--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
> > >+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
> > >@@ -259,6 +259,9 @@
> > >     HX_RESULT resetFlags               (UINT16 streamNumber);
> > >     HX_RESULT getPacket                        (UINT16 uStreamNumber,
> > >                                        IHXPacket*& pPacket);
> > >+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
> > >+                                       IHXPacket*& pPacket,
> > >+                                         REF(UINT32) uSeqNum);
> > >     virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
> > >     virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
> > >
> > >Index: Umakefil
> > >===================================================================
> > >RCS file: /cvsroot/client/common/util/Umakefil,v
> > >retrieving revision 1.3
> > >diff -u -r1.3 Umakefil
> > >--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
> > >+++ Umakefil    22 Jun 2004 22:53:43 -0000
> > >@@ -53,6 +53,7 @@
> > >                   'chxphook.cpp',
> > >                   'xnetchck.cpp',
> > >                   'littobig.cpp',
> > >-                  'hxunicod.cpp')
> > >+                  'hxunicod.cpp',
> > >+                   'hxsrcbufstats.cpp')
> > >
> > > LibraryTarget('utlclntlib')
> > >Index: hxcore.h
> > >===================================================================
> > >RCS file: /cvsroot/common/include/hxcore.h,v
> > >retrieving revision 1.5
> > >diff -u -r1.5 hxcore.h
> > >--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
> > >+++ hxcore.h    22 Jun 2004 23:00:23 -0000
> > >@@ -2060,7 +2060,50 @@
> > >
> > > // $EndPrivate.
> > >
> > >+// $Private:
> > >
> > >+/********************************************************************* 
> *******
> > >+ *
> > >+ *  Interface:
> > >+ *
> > >+ *     IID_IHXTransportOnTimeSync
> > >+ *
> > >+ *  Purpose:
> > >+ *
> > >+ *     This interface is used to send OnTimeSync() calls down
> > >+ *      to the transport layer. Note that the value passed to
> > >+ *      OnTimeSync() MUST be in the same units and have the same
> > >+ *      offset as the packets coming from the transport. This means
> > >+ *      that any offets caused by SMIL or live playback must be
> > >+ *      removed before calling OnTimeSync() on this interface
> > >+ *
> > >+ *      IID_IHXTransportOnTimeSync
> > >+ *
> > >+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> > >+ *
> > >+ */
> > >+DEFINE_GUID(IID_IHXTransportOnTimeSync,
> > >+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84,
> > >0xc1);
> > >+
> > >+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> > >+{
> > >+    /*
> > >+     * IUnknown methods
> > >+     */
> > >+
> > >+    STDMETHOD(QueryInterface)  (THIS_
> > >+                               REFIID riid,
> > >+                               void** ppvObj) PURE;
> > >+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> > >+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
> > >+
> > >+    /*
> > >+     * IHXTransportOnTimeSync methods
> > >+     */
> > >+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> > >+};
> > >+
> > >+// $EndPrivate.
> > >
> > > #endif /* _HXCORE_H_ */
> > >
> > >Index: hxpiids.h
> > >===================================================================
> > >RCS file: /cvsroot/common/include/hxpiids.h,v
> > >retrieving revision 1.28.2.1
> > >diff -u -r1.28.2.1 hxpiids.h
> > >--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
> > >+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
> > >@@ -533,6 +533,7 @@
> > > DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b,
> > >0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
> > > DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93,
> > >0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
> > > DEFINE_GUID_ENUM(IID_IHXMacBlitMutex,
> > >0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95,
> > >0xa9,  0x69,  0x37,  0x3b,  0x4d)
> > >+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0,
> > >0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
> > > #endif /* _HXCORE_H_ */
> > >
> > > /*
> > >
> > >
> > >
> > >
> > >_______________________________________________
> > >Common-dev mailing list
> > >Common-dev@lists.helixcommunity.org
> > >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> >
> > ======================================
> > M. Eric Hyche (ehyche@real.com)
> > Core Technologies
> > RealNetworks, Inc.
> >
>
>_______________________________________________
>Protocol-dev mailing list
>Protocol-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev


From ping at real.com  Wed Jun 23 10:45:14 2004
From: ping at real.com (Henry Ping)
Date: Wed Jun 23 10:45:40 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Moving
 IHXSourceBufferingStats2 implementation
In-Reply-To: <20040623173116.GC7758@real.com>
References: <5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
Message-ID: <5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>

At 10:31 AM 6/23/2004 -0700, Aaron Colwell wrote:
>On Wed, Jun 23, 2004 at 10:06:30AM -0700, Henry Ping wrote:
> > - m_pSrcBufStats in hxflsrc.cpp needs to take a closer look, it's a bit
> > confusing:
> > 1. its definition is different from the base class, HXSourceBufferStats*
> > instead of IHXSourceBufferingStats2*
> > hxbsrc.h: +    IHXSourceBufferingStats2*   m_pSrcBufStats;
> > hxflsrc.h: +    HXSourceBufferStats*        m_pSrcBufStats;
>
>Good catch. The HXSource member variable is used to provide the
>IHXSourceBufferingStats2 interface to the rest of the core. The HXFileSource
>member variable is used to pass in the packet information.
>
>
> > 2. it's first assigned with "new HXSourceBufferStats()", but then is
> > re-assigned in SetSrcBufStats()
>
>They are 2 seperate member variables. I just happened to name them the same
>which makes things confusing. I've renamed the one in HXFileSource to
>m_pHXSrcBufStats so that it is easier to see that they are 2 different member
>variables.
>
> >
> > - do you think we need to addref the m_pProto in HXNetSourceBufStats?
>
>Yes your right. I forgot that someone else could have a handle to this object
>even after m_pProto gets destroyed. I'll make the appropriate fixes.
>
> >
> > - do you think we need to return error if Init() is not called beforehand
> > in HXSourceBufferStats?
>
>Are you suggesting that GetCurrentBuffering() and GetTotalBuffering() should
>return an error if Init() has not been called for the requested stream? If so,
>then I am ok with that idea.

Yes, so the caller can be alerted about the data returned from these 2 
calls are not valid unless Init() is called first.

-->Henry


> >
> > -->Henry
> >
> > At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
> > >Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> > >          number information can be maintained as well.
> > >
> > >Overview: These changes move the IHXSourceBufferingStats2 implementation
> > >          out of HXBufferingState and into a new class called
> > >          HXSourceBufferStats. This was done because the client needs to
> > >          track packet sequence numbers for 3GPP-Rel6 OBSN support.
> > >          There was no good way to get the sequence number information to
> > >          the HXBufferingState class so the IHXSourceBufferingStats2 logic
> > >          was moved to where this information is available.
> > >
> > >          A new interface called IHXTransportOnTimeSync was created to
> > >          propagate OnTimeSync() like calls to HXSourceBufferStats. The
> > >          time passed to the OnTimeSync() call in this interface MUST
> > >          NOT have any offsets created by SMIL or live playback. The time
> > >          should be in the same time frame as the packets coming from the
> > >          transport. If someone wants to rename this interface that is 
> fine
> > >          by me.
> > >
> > >
> > >          - Created HXSourceBufferStats to contain the base
> > >            IHXSourceBufferingStats2 implementation. This class is
> > >            used by HXFileSource.
> > >
> > >          - Created HXNetSourceBufStats which derives from
> > >HXSourceBufferStats.
> > >            This class just overloads the GetCurrentBuffering() so that it
> > >            returns the amount of data in the transport buffer. This is
> > >            used by RTSPClientProtocol.
> > >
> > >          - Removed IHXSourceBufferingStats2 code from HXSource
> > >
> > >          - Removed packet tracking code from HXBufferingState. This
> > >            functionality is implemented by HXSourceBufferStats now
> > >
> > >          - Added code to HXSource to provide OnTimeSync() calls to the
> > >            IHXTransportOnTimeSync interface.
> > >
> > >          - HXSource now exposes IHXSourceBufferingStats functionality
> > >through
> > >            it's m_pSrcBufStats member variable instead of implementing it
> > >            itself. The file and network sources are expected to 
> provide an
> > >            IHXSourceBufferingStats2 interface via a
> > >            HXSource::SetSrcBufStats() call.
> > >
> > >          - Added code to HXFileSource to use HXSourceBufferStats
> > >
> > >          - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> > >
> > >          - Fixed some code in CBufferManager that was expecting HXSource
> > >            to implement IHXSourceBufferingStats. This code now QI's for
> > >            IHXSourceBufferingStats and uses that interface.
> > >
> > >
> > >
> > >Files Modified:
> > >client/core/buffmgr.cpp
> > >client/core/hxbsrc.h
> > >client/core/hxbufstate.h
> > >client/core/hxbufstate.cpp
> > >client/core/hxflsrc.cpp
> > >client/core/hxflsrc.h
> > >client/core/hxntsrc.cpp
> > >client/core/hxntsrc.h
> > >client/core/hxsrc.cpp
> > >client/core/rtspprotocol.cpp
> > >protocol/rtsp/Umakefil
> > >protocol/rtsp/rtspclnt.cpp
> > >protocol/rtsp/pub/rtspclnt.h
> > >protocol/transport/common/system/rtsptran.cpp
> > >protocol/transport/common/system/pub/rtsptran.h
> > >client/common/util/Umakefil
> > >common/include/hxcore.h
> > >common/include/hxpiids.h
> > >
> > >Files Added:
> > >client/common/util/pub/hxsrcbufstats.h
> > >client/common/util/hxsrcbufstats.cpp
> > >protocol/rtsp/ntsrcbufstats.h
> > >protocol/rtsp/ntsrcbufstats.cpp
> > >
> > >Image Size and Heap Use impact:
> > >
> > >Platforms and Profiles affected: all
> > >
> > >Distribution Libraries affected: rdtclntlib
> > >
> > >Distribution library impact and planned action:
> > >m_bIsLive and m_pSrcBufStats member variables were added to
> > >RTSPClientProtocol so any derived objects will need to be
> > >recompiled
> > >
> > >Platforms and Profiles Build Verified: win32
> > >
> > >Platforms and Profiles Functionality verified: win32
> > >
> > >Branch: HEAD
> > >
> > >QA Instructions: none
> > >
> > >Index: buffmgr.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/buffmgr.cpp,v
> > >retrieving revision 1.21
> > >diff -u -r1.21 buffmgr.cpp
> > >--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
> > >+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> > >@@ -610,6 +610,11 @@
> > >      * - Keep track of the stream with the lowest timestamp and is
> > >      *   buffering data
> > >      */
> > >+    IHXSourceBufferingStats* pSrcBufStats = NULL;
> > >+
> > >+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> > >+                              (void**)&pSrcBufStats);
> > >+
> > >     for (i = m_pStreamInfoTable->Begin(); i !=
> > >m_pStreamInfoTable->End(); ++i)
> > >     {
> > >        pStreamInfo = (STREAM_INFO*) (*i);
> > >@@ -619,12 +624,15 @@
> > >        ULONG32 ulNumBytesAtTransport = 0;
> > >        BOOL bDoneAtTransport = FALSE;
> > >
> > >-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> > >-                                      llLowestTimestampAtTransport,
> > >-                                      llHighestTimestampAtTransport,
> > >-                                      ulNumBytesAtTransport,
> > >-                                      bDoneAtTransport);
> > >-
> > >+        if (pSrcBufStats)
> > >+        {
> > >+
> > >pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> > >+
> > >llLowestTimestampAtTransport,
> > >+
> > >llHighestTimestampAtTransport,
> > >+                                              ulNumBytesAtTransport,
> > >+                                              bDoneAtTransport);
> > >+        }
> > >+
> > >        pStreamInfo->BufferingState().UpdateTransportStats(
> > >            llLowestTimestampAtTransport,
> > >            llHighestTimestampAtTransport,
> > >@@ -658,6 +666,7 @@
> > >
> > >        }
> > >     }
> > >+    HX_RELEASE(pSrcBufStats);
> > >
> > >     /* If none of the streams have any data buffered at the transport
> > >     layer,
> > >      * return.
> > >Index: hxbsrc.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxbsrc.h,v
> > >retrieving revision 1.18.2.1
> > >diff -u -r1.18.2.1 hxbsrc.h
> > >--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
> > >+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
> > >@@ -233,12 +233,11 @@
> > >                  public IHXPrivateStreamSource,
> > >                  public IHXBackChannel,
> > >                  public IHXASMSource,
> > >-                  public IHXClientRateAdaptControl,
> > >+                  public IHXClientRateAdaptControl
> > > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> > >-                 public IHXHyperNavigate,
> > >-                 public IHXHyperNavigate2,
> > >+                 , public IHXHyperNavigate,
> > >+                 public IHXHyperNavigate2
> > > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > >-                  public IHXSourceBufferingStats2
> > > {
> > > protected:
> > >     LONG32                     m_lRefCount;
> > >@@ -487,35 +486,6 @@
> > >                            IHXValues* pParams);
> > > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > >
> > >-
> > >/************************************************************************
> > >-     * Method:
> > >-     *     IHXSourceBufferingStats2::GetCurrentBuffering
> > >-     * Purpose:
> > >-     *     Get the current buffering information
> > >-     */
> > >-
> > >-    STDMETHOD(GetCurrentBuffering) (THIS_
> > >-                                    UINT16  uStreamNumber,
> > >-                                    REF(INT64)  llLowestTimestamp,
> > >-                                    REF(INT64)  llHighestTimestamp,
> > >-                                    REF(UINT32) ulNumBytes,
> > >-                                    REF(BOOL)   bDone) PURE;
> > >-
> > >/************************************************************************
> > >-     * Method:
> > >-     *     IHXSourceBufferingStats2::GetTotalBuffering
> > >-     * Purpose:
> > >-     *     Get the total amount of data buffered for a stream.
> > >-     *      This includes what is in the transport buffer and in
> > >-     *      the renderer
> > >-     */
> > >-
> > >-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> > >-                                  REF(INT64)  llLowestTimestamp,
> > >-                                  REF(INT64)  llHighestTimestamp,
> > >-                                  REF(UINT32) ulNumBytes,
> > >-                                  REF(BOOL)   bDone);
> > >-
> > >-
> > >     /*
> > >      * IHXClientRateAdaptControl Methods
> > >      */
> > >@@ -731,7 +701,7 @@
> > >            virtual HX_RESULT   FillRecordControl() = 0;
> > >                    BOOL        IsPlayingFromRecordControl() { return
> > >m_bPlayFromRecordControl; };
> > >
> > >-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > >+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > >
> > >             const char*         GetRedirectURL() { return
> > >(m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
> > >             const char*         GetSDPURL() { return (m_pSDPURL ?
> > >m_pSDPURL->GetURL() : NULL); };
> > >@@ -769,6 +739,8 @@
> > >             void        ProcessFileHeader(void);
> > >             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader,
> > >STREAM_INFO*& pStreamInfo);
> > >
> > >+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> > >+
> > >     HX_RESULT                  mLastError;
> > >     CHXMapLongToObj*            mStreamInfoTable;
> > >
> > >@@ -868,6 +840,8 @@
> > >     CHXURL*                     m_pRedirectURL;
> > >     CHXURL*                     m_pSDPURL;
> > >     BOOL                        m_bRedirectPending;
> > >+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> > >+    IHXSourceBufferingStats2*   m_pSrcBufStats;
> > > };
> > >
> > > // Defined flags
> > >Index: hxbufstate.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> > >retrieving revision 1.7
> > >diff -u -r1.7 hxbufstate.cpp
> > >--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
> > >+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
> > >@@ -83,18 +83,11 @@
> > >     , m_ulLastPacketTimeStamp(0)
> > >     , m_ulAvgBandwidth(0)
> > >     , m_pASMProps(NULL)
> > >-    , m_llCurrentPlaybackTime(0)
> > >-    , m_ulBufferedData(0)
> > >-    , m_ulLastTimeSync(0)
> > >-    , m_llFirstLivePacketTimestamp(0)
> > >-    , m_ulTimeSyncRollOver(0)
> > > {}
> > >
> > > HXBufferingState::~HXBufferingState()
> > > {
> > >     HX_RELEASE(m_pASMProps);
> > >-
> > >-    ClearPktInfo();
> > > }
> > >
> > > void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> > >@@ -179,8 +172,6 @@
> > >     m_ulLastPacketTimeStamp = 0;
> > >     m_bIsFirstPacket = TRUE;
> > >
> > >-    ClearPktInfo();
> > >-
> > >     if (bIsSeeking)
> > >     {
> > >        m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> > >@@ -288,11 +279,6 @@
> > >     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 +
> > >CAST_TO_INT64 ulTime;
> > > }
> > >
> > >-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> > >-{
> > >-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64
> > >MAX_UINT32 + CAST_TO_INT64 ulTime;
> > >-}
> > >-
> > > void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> > >                                UINT32 ulElapsedTime,
> > >                                BOOL bIsLive, BOOL bIsBufferedPlayMode)
> > >@@ -318,16 +304,12 @@
> > >        if (bIsLive)
> > >        {
> > >            m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> > >-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
> > >         }
> > >
> > >        m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
> > >        m_bIsFirstPacket = FALSE;
> > >     }
> > >
> > >-    // Add this packet to our packet info statistics
> > >-    AddPktInfo(llActualTimeStamp, ulPacketSize);
> > >-
> > >     // data based preroll
> > >     if (DataBasedPreroll())
> > >     {
> > >@@ -451,47 +433,6 @@
> > >     m_bDoneAtTransport = bDoneAtTransport;
> > > }
> > >
> > >-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
> > >-                                             REF(INT64) llHighTimestamp,
> > >-                                             REF(UINT32) ulBytesBuffered,
> > >-                                             BOOL bUseTransportStats)
> > >-{
> > >-    HX_RESULT res = HXR_NO_DATA;
> > >-
> > >-    if (!m_bIsFirstPacket)
> > >-    {
> > >-       if (!m_pktInfo.IsEmpty())
> > >-       {
> > >-           HXBufferedPktInfo* pPktInfo =
> > >-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
> > >-
> > >-           llLowTimestamp = pPktInfo->Timestamp();
> > >-       }
> > >-       else
> > >-       {
> > >-           llLowTimestamp = m_llHighestTimeStamp;
> > >-       }
> > >-
> > >-       llHighTimestamp = m_llHighestTimeStamp;
> > >-       ulBytesBuffered = GetBufferedData();
> > >-
> > >-
> > >-       if (bUseTransportStats)
> > >-       {
> > >-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
> > >-           {
> > >-               llHighTimestamp = m_llHighestTimestampAtTransport;
> > >-           }
> > >-
> > >-           ulBytesBuffered += m_ulNumBytesAtTransport;
> > >-       }
> > >-
> > >-       res = HXR_OK;
> > >-    }
> > >-
> > >-    return res;
> > >-}
> > >-
> > > void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
> > >                                           INT64 llTheHighestTS,
> > >                                           BOOL bIsSeekPerformed,
> > >@@ -569,19 +510,6 @@
> > >
> > > }
> > >
> > >-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> > >-{
> > >-    //  0xFA .. 0xFF [roll over] (0x01)
> > >-    if (m_ulLastTimeSync > ulCurrentTime &&
> > >-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> > >-    {
> > >-       m_ulTimeSyncRollOver++;
> > >-    }
> > >-    m_ulLastTimeSync = ulCurrentTime;
> > >-
> > >-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> > >-}
> > >-
> > > void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
> > >                                        ULONG32 ulMinBufferingInMs)
> > > {
> > >@@ -771,62 +699,4 @@
> > >     {
> > >        m_ulAvgBandwidth = ulBandwidth;
> > >     }
> > >-}
> > >-
> > >-void HXBufferingState::ClearPktInfo()
> > >-{
> > >-    m_ulBufferedData = 0;
> > >-    while(!m_pktInfo.IsEmpty())
> > >-    {
> > >-       HXBufferedPktInfo* pInfo =
> > >(HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> > >-       delete pInfo;
> > >-    }
> > >-}
> > >-
> > >-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
> > >-{
> > >-    // Subtract off the first live packet timestamp.
> > >-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> > >-    llTimestamp -= m_llFirstLivePacketTimestamp;
> > >-    // Create the HXBufferedPktInfo class
> > >-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
> > >-                                                       ulPacketSize);
> > >-    if (pPktInfo)
> > >-    {
> > >-       m_pktInfo.AddTail(pPktInfo);
> > >-       m_ulBufferedData += ulPacketSize;
> > >-    }
> > >-
> > >-    // purge the old packet info data
> > >-    //  this keeps the list short and prevents the Symbian
> > >-    //  allocator from freaking out
> > >-    (void)GetBufferedData();
> > >-}
> > >-
> > >-UINT32 HXBufferingState::GetBufferedData()
> > >-{
> > >-    BOOL bDone = m_pktInfo.IsEmpty();
> > >-
> > >-    // Remove all packet info that is past due
> > >-    // and subtract their sizes from our buffering total
> > >-    while(!bDone)
> > >-    {
> > >-       HXBufferedPktInfo* pPktInfo =
> > >(HXBufferedPktInfo*)m_pktInfo.GetHead();
> > >-
> > >-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> > >-       {
> > >-           m_ulBufferedData -= pPktInfo->Size();
> > >-
> > >-           m_pktInfo.RemoveHead();
> > >-           delete pPktInfo;
> > >-
> > >-           bDone = m_pktInfo.IsEmpty();
> > >-       }
> > >-       else
> > >-       {
> > >-           bDone = TRUE;
> > >-       }
> > >-    }
> > >-
> > >-    return m_ulBufferedData;
> > > }
> > >Index: hxbufstate.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxbufstate.h,v
> > >retrieving revision 1.4
> > >diff -u -r1.4 hxbufstate.h
> > >--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
> > >+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
> > >@@ -81,7 +81,6 @@
> > >     BOOL HasPredata(BOOL bIsSeekPerformed);
> > >
> > >     INT64 CreateINT64Timestamp(UINT32 ulTime);
> > >-    INT64 CreateINT64Timesync(UINT32 ulTime);
> > >
> > >     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> > >                  UINT32 ulElapsedTime, BOOL bIsLive,
> > >@@ -98,11 +97,6 @@
> > >                              ULONG32 ulBytesAtTransport,
> > >                              BOOL bDoneAtTransport);
> > >
> > >-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
> > >-                               REF(INT64) llHighTimestamp,
> > >-                               REF(UINT32) ulBytesBuffered,
> > >-                               BOOL bUseTransportStats);
> > >-
> > >     void GetExcessBufferInfo(INT64 llTheLowestTS,
> > >                             INT64 llTheHighestTS,
> > >                             BOOL bIsSeekPerformed,
> > >@@ -119,8 +113,6 @@
> > >
> > >     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
> > >
> > >-    void OnTimeSync(UINT32 ulCurrentTime);
> > >-
> > >     // Should remove
> > >     void SetAvgBWToASMBw();
> > >     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> > >@@ -149,19 +141,6 @@
> > >                        UINT32 ulCurrentBuffering,
> > >                        UINT32 ulMinimumPreroll,
> > >                        UINT32 ulDenom) const;
> > >-
> > >-    /* Functions for tracking the amount of data
> > >-     * buffered in the renderer
> > >-     */
> > >-    void ClearPktInfo(); /* Clears out information about buffered 
> packets
> > >*/
> > >-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called
> > >when
> > >-                                                             * a 
> packet is
> > >-                                                             * sent 
> to the
> > >-                                                             * renderer
> > >-                                                             */
> > >-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
> > >-                              * in the renderer
> > >-                              */
> > >
> > >     ULONG32            m_ulPreroll;
> > >     ULONG32            m_ulPredata;
> > >@@ -196,20 +175,6 @@
> > >     ULONG32            m_ulLastPacketTimeStamp;
> > >     ULONG32            m_ulAvgBandwidth;
> > >     IHXASMProps*       m_pASMProps;
> > >-    UINT32              m_ulLastTimeSync;
> > >-    INT64               m_llFirstLivePacketTimestamp;
> > >-    UINT32              m_ulTimeSyncRollOver;
> > >-    // These variable keep track of the amount of
> > >-    // data buffered in the renderer
> > >-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
> > >-                                                 * OnTimeSync() call
> > >-                                                 */
> > >-
> > >-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> > >-                                          * Always use GetBufferedData()
> > >-                                          * to retreive the value
> > >-                                          */
> > >-    CHXSimpleList       m_pktInfo; /* List of packet information */
> > > };
> > >
> > > inline
> > >Index: hxflsrc.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> > >retrieving revision 1.54
> > >diff -u -r1.54 hxflsrc.cpp
> > >--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
> > >+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> > >@@ -76,6 +76,7 @@
> > > #include "uri_schemes.h"
> > > #include "stream_desc_hlpr.h"
> > > #include "findfile.h"
> > >+#include "hxsrcbufstats.h"
> > >
> > > #include "hxheap.h"
> > > #ifdef _DEBUG
> > >@@ -115,6 +116,7 @@
> > >     , m_bValidateMetaDone(FALSE)
> > >     , m_pFileRecognizer(NULL)
> > >     , m_pFileReader(NULL)
> > >+    , m_pSrcBufStats(NULL)
> > > {
> > >     m_bAltURL = FALSE;
> > >     m_bPerfectPlay = TRUE;
> > >@@ -306,6 +308,13 @@
> > >
> > >     HX_VECTOR_DELETE(m_pszURL);
> > >     HX_DELETE(m_pURL);
> > >+
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >+    m_pSrcBufStats = new HXSourceBufferStats();
> > >+    if (m_pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats->AddRef();
> > >+    }
> > >
> > >     if (!theErr && pURL)
> > >     {
> > >@@ -938,6 +947,7 @@
> > >     }
> > > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
> > >
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >     HXSource::DoCleanup();
> > >
> > >     return HXR_OK;
> > >@@ -1068,6 +1078,11 @@
> > >
> > >     m_llLastFillEndTime = 0;
> > >
> > >+    if (m_pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats->Reset();
> > >+    }
> > >+
> > > cleanup:
> > >
> > >     return HXR_OK;
> > >@@ -1442,6 +1457,11 @@
> > >
> > >            if(m_pBufferManager)
> > >                m_pBufferManager->UpdateCounters(pPacket, 0);
> > >+
> > >+            if (m_pSrcBufStats && !pPacket->IsLost())
> > >+            {
> > >+                m_pSrcBufStats->OnPacket(pPacket);
> > >+            }
> > >
> > >            HX_RELEASE(pPacket);
> > >        }
> > >@@ -2103,6 +2123,13 @@
> > >        }
> > >        HX_RELEASE(pszParentName);
> > > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> > >+
> > >+        if (pStreamInfo && m_pSrcBufStats)
> > >+        {
> > >+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> > >+                                 mLiveStream);
> > >+        }
> > >+
> > >         m_ulStreamIndex++;
> > >         m_uNumStreams++;
> > >     }
> > >@@ -2115,6 +2142,11 @@
> > >
> > >        theErr = AdjustClipTime();
> > >        m_pBufferManager->Init();
> > >+
> > >+        if (m_pSrcBufStats)
> > >+        {
> > >+            SetSrcBufStats(m_pSrcBufStats);
> > >+        }
> > >     }
> > >
> > >     return theErr;
> > >@@ -2313,6 +2345,11 @@
> > >        {
> > >            m_pBufferManager->UpdateCounters(pPacket, 0);
> > >        }
> > >+
> > >+        if (m_pSrcBufStats && !pPacket->IsLost())
> > >+        {
> > >+            m_pSrcBufStats->OnPacket(pPacket);
> > >+        }
> > >     }
> > >
> > >     m_llLastFillEndTime = llActualPacketTime;
> > >Index: hxflsrc.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxflsrc.h,v
> > >retrieving revision 1.12
> > >diff -u -r1.12 hxflsrc.h
> > >--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
> > >+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
> > >@@ -52,6 +52,8 @@
> > > #include "hxfiles.h"
> > > #include "recognizer.h"
> > >
> > >+class HXSourceBufferStats;
> > >+
> > > class HXFileSource : public HXSource,
> > >                      public IHXFormatResponse,
> > >                       public IHXHTTPRedirectResponse
> > >@@ -349,6 +351,7 @@
> > >
> > >     CFileReader*                m_pFileReader;
> > >     CHXFileRecognizer*          m_pFileRecognizer;
> > >+    HXSourceBufferStats*        m_pSrcBufStats;
> > > };
> > >
> > > #endif // _HX_FILE_SOURCE
> > >Index: hxntsrc.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> > >retrieving revision 1.90
> > >diff -u -r1.90 hxntsrc.cpp
> > >--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
> > >+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> > >@@ -675,6 +675,7 @@
> > >     HX_RESULT   rc = HXR_OK;
> > >     BOOL        bSDPInitiated = FALSE;
> > >     CHXString   pString;
> > >+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
> > >
> > >     // start off with the preferred protocol
> > >     rc = CreateProtocol();
> > >@@ -722,6 +723,14 @@
> > >         goto cleanup;
> > >     }
> > >
> > >+    // Setup source buffer stats
> > >+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> > >+                                           (void**)&pSrcBufStats))
> > >+    {
> > >+        SetSrcBufStats(pSrcBufStats);
> > >+        HX_RELEASE(pSrcBufStats);
> > >+    }
> > >+
> > >     // create log info list
> > >     m_pLogInfoList = new CHXSimpleList;
> > >     m_ulLogInfoLength = 0;
> > >@@ -6295,6 +6304,12 @@
> > > #else
> > >     return HXR_NOTIMPL;
> > > #endif /* HELIX_FEATURE_RECORDCONTROL */
> > >+}
> > >+
> > >+HX_RESULT
> > >+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> > >+{
> > >+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
> > > }
> > >
> > > ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> > >Index: hxntsrc.h
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxntsrc.h,v
> > >retrieving revision 1.24
> > >diff -u -r1.24 hxntsrc.h
> > >--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
> > >+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
> > >@@ -282,6 +282,7 @@
> > >
> > >        virtual HX_RESULT       FillRecordControl();
> > >
> > >+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> > > protected:
> > >
> > >        virtual                         ~HXNetSource(void);
> > >@@ -470,7 +471,6 @@
> > > private:
> > >         IHXBufferControl*                m_pBufferCtl;
> > >         IHXWatermarkBufferControl*       m_pWMBufferCtl;
> > >-
> > > public:
> > >        HX_RESULT       FinishSetup();
> > >        void            ReSetup();
> > >Index: hxsrc.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/hxsrc.cpp,v
> > >retrieving revision 1.44.2.1
> > >diff -u -r1.44.2.1 hxsrc.cpp
> > >--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
> > >+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
> > >@@ -213,6 +213,8 @@
> > >         , m_pRedirectURL(NULL)
> > >         , m_pSDPURL(NULL)
> > >         , m_bRedirectPending(FALSE)
> > >+        , m_pTransOnTimeSync(NULL)
> > >+        , m_pSrcBufStats(NULL)
> > > {
> > >     mStreamInfoTable = new CHXMapLongToObj;
> > > }
> > >@@ -313,6 +315,8 @@
> > >     HX_DELETE(m_pRedirectURL);
> > >     HX_DELETE(m_pSDPURL);
> > >     m_bRedirectPending  = FALSE;
> > >+    HX_RELEASE(m_pTransOnTimeSync);
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >
> > > #if defined(HELIX_FEATURE_RECORDCONTROL)
> > >     if(m_pRecordControl)
> > >@@ -340,8 +344,6 @@
> > >             { GET_IIDHANDLE(IID_IHXPendingStatus),
> > >(IHXPendingStatus*)this },
> > >             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
> > >             { GET_IIDHANDLE(IID_IHXPrivateStreamSource),
> > >(IHXPrivateStreamSource*)this },
> > >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats),
> > >(IHXSourceBufferingStats*)this },
> > >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2),
> > >(IHXSourceBufferingStats2*)this },
> > >             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
> > >               (IHXClientRateAdaptControl*)this },
> > > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> > >@@ -388,6 +390,14 @@
> > >            return HXR_NOINTERFACE;
> > >        }
> > >     }
> > >+    else if (m_pSrcBufStats &&
> > >+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> > >+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> > >+    {
> > >+        m_pSrcBufStats->AddRef();
> > >+        *ppvObj = m_pSrcBufStats;
> > >+        return HXR_OK;
> > >+    }
> > >
> > > #if defined(HELIX_FEATURE_AUTOUPGRADE)
> > >     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> > >@@ -2250,59 +2260,6 @@
> > > }
> > > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> > >
> > >-STDMETHODIMP
> > >-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> > >-                           REF(INT64)  llLowestTimestamp,
> > >-                           REF(INT64)  llHighestTimestamp,
> > >-                           REF(UINT32) ulNumBytes,
> > >-                           REF(BOOL)   bDone)
> > >-{
> > >-    HX_RESULT res = HXR_NO_DATA;
> > >-
> > >-    llLowestTimestamp = 0;
> > >-    llHighestTimestamp = 0;
> > >-    ulNumBytes = 0;
> > >-    bDone = FALSE;
> > >-
> > >-    STREAM_INFO* pStreamInfo;
> > >-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*&
> > >)pStreamInfo))
> > >-    {
> > >-       HXBufferingState& bufState = pStreamInfo->BufferingState();
> > >-       BOOL   bUseTransportStats = FALSE;
> > >-
> > >-       INT64  llTransportLowTS = 0;
> > >-       INT64  llTransportHighTS = 0;
> > >-       UINT32 ulTransportBytes = 0;
> > >-       BOOL   bTransportDone = FALSE;
> > >-
> > >-       if (!IsLocalSource() &&
> > >-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
> > >-                                          llTransportLowTS,
> > >-                                          llTransportHighTS,
> > >-                                          ulTransportBytes,
> > >-                                          bTransportDone)))
> > >-       {
> > >-           bufState.UpdateTransportStats(llTransportLowTS,
> > >-                                         llTransportHighTS,
> > >-                                         ulTransportBytes,
> > >-                                         bTransportDone);
> > >-
> > >-           bUseTransportStats = TRUE;
> > >-
> > >-           // Update bDone with what the transport says.
> > >-           bDone = bTransportDone;
> > >-       }
> > >-
> > >-       res = bufState.GetBufferingStats(llLowestTimestamp,
> > >-                                       llHighestTimestamp,
> > >-                                       ulNumBytes,
> > >-                                       bUseTransportStats);
> > >-    }
> > >-
> > >-
> > >-    return res;
> > >-}
> > >-
> > > /*
> > >  * IHXClientRateAdaptControl Methods
> > >  */
> > >@@ -2948,13 +2905,34 @@
> > > {
> > >     HX_RESULT res = HXR_OK;
> > >
> > >-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> > >-         i != mStreamInfoTable->End(); ++i)
> > >-    {
> > >-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> > >-
> > >-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> > >+    // Convert presentation time to transport time
> > >+    if (m_pTransOnTimeSync)
> > >+    {
> > >+        ULONG32 ulOffset = m_ulDelay;
> > >+        ULONG32 ulTransportTime = m_ulStartTime;
> > >+
> > >+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> > >+        {
> > >+            ulTransportTime += ulCurrentTime - ulOffset;
> > >+        }
> > >+
> > >+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
> > >     }
> > >
> > >     return res;
> > >+}
> > >+
> > >+void
> > >+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> > >+{
> > >+    HX_RELEASE(m_pSrcBufStats);
> > >+    HX_RELEASE(m_pTransOnTimeSync);
> > >+
> > >+    if (pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats = pSrcBufStats;
> > >+        m_pSrcBufStats->AddRef();
> > >+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> > >+                                       (void**)&m_pTransOnTimeSync);
> > >+    }
> > > }
> > >Index: rtspprotocol.cpp
> > >===================================================================
> > >RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> > >retrieving revision 1.39
> > >diff -u -r1.39 rtspprotocol.cpp
> > >--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
> > >+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
> > >@@ -2626,12 +2626,12 @@
> > >     UINT16 seekFrom
> > > )
> > > {
> > >+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> > >+
> > >     if (IsLive())
> > >     {
> > >-        return m_pProtocolLib->SeekFlush();
> > >+        return theErr;
> > >     }
> > >-
> > >-    HX_RESULT theErr = HXR_OK;
> > >
> > >     m_uCurrentStreamCount = m_uStreamCount;
> > >
> > >
> > >Index: Umakefil
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> > >retrieving revision 1.9.2.1
> > >diff -u -r1.9.2.1 Umakefil
> > >--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
> > >+++ Umakefil    22 Jun 2004 22:52:32 -0000
> > >@@ -46,6 +46,7 @@
> > >                          'common/runtime/pub',
> > >                          'common/lang/xml/pub',
> > >                          'client/common/container/pub',
> > >+                          'client/common/util/pub',
> > >                          'protocol/transport/rtp/include',
> > >                          'server/include',
> > >                           'server/common/struct/pub',
> > >@@ -65,7 +66,7 @@
> > >                   'rtspmsg.cpp', 'rtspmdsc.cpp',
> > >                   'rtsppars.cpp', 'mhprop.cpp',
> > >                   'servrsnd.cpp', '3gpadapthdr.cpp',
> > >-                   'rateadaptinfo.cpp')
> > >+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
> > >
> > > if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
> > >     project.AddSources('pipelinedesc.cpp')
> > >Index: rtspclnt.cpp
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> > >retrieving revision 1.79.2.1
> > >diff -u -r1.79.2.1 rtspclnt.cpp
> > >--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
> > >+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
> > >@@ -95,6 +95,7 @@
> > > #include "pipelinedesc.h"
> > > #include "errdbg.h"
> > > #include "rateadaptinfo.h"
> > >+#include "ntsrcbufstats.h"
> > >
> > > #include "hxheap.h"
> > > #ifdef _DEBUG
> > >@@ -302,6 +303,12 @@
> > >     {
> > >         return HXR_OK;
> > >     }
> > >+    else if (m_pSrcBufStats &&
> > >+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> > >+                                                       ppvObj)))
> > >+    {
> > >+        return HXR_OK;
> > >+    }
> > >     *ppvObj = NULL;
> > >     return HXR_NOINTERFACE;
> > > }
> > >@@ -388,6 +395,7 @@
> > >     m_bReportedSuccessfulTransport(FALSE),
> > >     m_bSDPInitiated(FALSE),
> > >     m_bMulticast(FALSE),
> > >+    m_bIsLive(FALSE),
> > >     m_pSDPFileHeader(NULL),
> > >     m_pSDPStreamHeaders(NULL),
> > >     m_bSessionSucceeded(FALSE),
> > >@@ -404,7 +412,8 @@
> > >     m_ulCurrentTimeOut(0),
> > >     m_pUAProfURI(NULL),
> > >     m_pUAProfDiff(NULL),
> > >-    m_pRateAdaptInfo(NULL)
> > >+    m_pRateAdaptInfo(NULL),
> > >+    m_pSrcBufStats(NULL)
> > > #if defined(_MACINTOSH)
> > >     , m_pCallback(NULL)
> > > #endif /* _MACINTOSH */
> > >@@ -460,6 +469,8 @@
> > >         m_pRateAdaptInfo->Close();
> > >         HX_DELETE(m_pRateAdaptInfo);
> > >     }
> > >+
> > >+    HX_RELEASE(m_pSrcBufStats);
> > > }
> > >
> > > /*
> > >@@ -810,6 +821,21 @@
> > >         }
> > >     }
> > >
> > >+    if (HXR_OK == hresult)
> > >+    {
> > >+        HX_RELEASE(m_pSrcBufStats);
> > >+        m_pSrcBufStats = new HXNetSourceBufStats(this);
> > >+
> > >+        if (m_pSrcBufStats)
> > >+        {
> > >+            m_pSrcBufStats->AddRef();
> > >+        }
> > >+        else
> > >+        {
> > >+            hresult = HXR_OUTOFMEMORY;
> > >+        }
> > >+    }
> > >+
> > > #if defined(_MACINTOSH)
> > >     if (m_pCallback &&
> > >         m_pCallback->m_bIsCallbackPending &&
> > >@@ -2191,7 +2217,14 @@
> > >         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> > >     if (pTrans)
> > >     {
> > >-        rc = pTrans->getPacket(uStreamNumber, pPacket);
> > >+        UINT32 uSeqNum;
> > >+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> > >+
> > >+        if ((HXR_OK == rc) && m_pSrcBufStats &&
> > >+            (!pPacket->IsLost()))
> > >+        {
> > >+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> > >+        }
> > >     }
> > >
> > >     m_pMutex->Unlock();
> > >@@ -3291,16 +3324,24 @@
> > >     HX_RESULT rc = HXR_OK;
> > >     m_pMutex->Lock();
> > >
> > >-    CHXMapLongToObj::Iterator i;
> > >-    for(i=m_pTransportStreamMap->Begin();
> > >-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> > >+    if (m_bIsLive)
> > >     {
> > >-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> > >-        UINT16 streamNumber = (UINT16)i.get_key();
> > >-
> > >-        HX_ASSERT(pTransport);
> > >+        CHXMapLongToObj::Iterator i;
> > >+        for(i=m_pTransportStreamMap->Begin();
> > >+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> > >+        {
> > >+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> > >+            UINT16 streamNumber = (UINT16)i.get_key();
> > >+
> > >+            HX_ASSERT(pTransport);
> > >+
> > >+            rc = pTransport ? pTransport->SeekFlush(streamNumber) :
> > >HXR_OK;
> > >+        }
> > >+    }
> > >
> > >-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> > >+    if (m_pSrcBufStats)
> > >+    {
> > >+        m_pSrcBufStats->Reset();
> > >     }
> > >
> > >     m_pMutex->Unlock();
> > >@@ -6964,6 +7005,11 @@
> > >         // Get session level RTP bandwidth modifiers
> > >         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
> > >         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> > >+
> > >+        if (ulIsSessionLive)
> > >+        {
> > >+            m_bIsLive = TRUE;
> > >+        }
> > >
> > >         // get multicast address from the session description
> > >         if (HXR_OK ==
> > >ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> > >@@ -7187,6 +7233,11 @@
> > >             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
> > >             pInfo->m_bRealMedia = bRealMedia;
> > >
> > >+            if (m_pSrcBufStats)
> > >+            {
> > >+                m_pSrcBufStats->Init((UINT16)streamNumber,
> > >pInfo->m_bIsLive);
> > >+            }
> > >+
> > >             if (m_pRateAdaptInfo)
> > >             {
> > >                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> > >@@ -7222,6 +7273,7 @@
> > >         if (m_bMulticast)
> > >         {
> > >             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> > >+            m_bIsLive = TRUE;
> > >         }
> > >     }
> > >
> > >Index: pub/rtspclnt.h
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> > >retrieving revision 1.30.2.1
> > >diff -u -r1.30.2.1 rtspclnt.h
> > >--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
> > >+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
> > >@@ -46,6 +46,7 @@
> > > #include "hxbufctl.h" // IHXTransportBufferLimit
> > > #include "hxrtsp2.h"
> > > #include "hxrsdbf.h" // IHXResendBufferControl
> > >+#include "hxprefs.h" // IHXPreferences
> > >
> > > class RTSPClientState;
> > > class RTSPOptionsMessage;
> > >@@ -63,6 +64,7 @@
> > > class MIMEHeader;
> > > class PipelinedDescribeLogic;
> > > class CHXRateAdaptationInfo;
> > >+class HXNetSourceBufStats;
> > >
> > > struct IHXKeyValueList;
> > > struct IHXValues;
> > >@@ -1039,6 +1041,7 @@
> > >
> > >     BOOL                                m_bSDPInitiated;
> > >     BOOL                                m_bMulticast;
> > >+    BOOL                                m_bIsLive;
> > >     IHXValues*                          m_pSDPFileHeader;
> > >     CHXSimpleList*                      m_pSDPStreamHeaders;
> > >
> > >@@ -1074,6 +1077,7 @@
> > >     UINT32                              m_ulServerTimeOut;
> > >     UINT32                              m_ulCurrentTimeOut;
> > >     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> > >+    HXNetSourceBufStats*                m_pSrcBufStats;
> > >
> > > #if defined(_MACINTOSH)
> > >     RTSPClientProtocolCallback*                m_pCallback;
> > >
> > >Index: rtsptran.cpp
> > >===================================================================
> > >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> > >retrieving revision 1.26
> > >diff -u -r1.26 rtsptran.cpp
> > >--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
> > >+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
> > >@@ -526,8 +526,17 @@
> > >     }
> > > }
> > >
> > >+HX_RESULT
> > >+RTSPTransport::getPacket(UINT16 uStreamNumber,
> > >+                         IHXPacket*& pPacket)
> > >+{
> > >+    UINT32 uSeqNum;
> > >+    return getPacket(uStreamNumber, pPacket, uSeqNum);
> > >+}
> > >+
> > > HX_RESULT
> > >-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> > >+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
> > >+                         REF(UINT32) uSeqNum)
> > > {
> > >     RTSPTransportBuffer* pTransportBuffer =
> > >getTransportBuffer(uStreamNumber);
> > >     RTSPStreamData* pStreamData =
> > >m_pStreamHandler->getStreamData(uStreamNumber);
> > >@@ -547,6 +556,7 @@
> > >     }
> > >
> > >     pPacket = clientPacket->GetPacket();
> > >+    uSeqNum = clientPacket->GetSequenceNumber();
> > >
> > >     if (!pPacket)
> > >     {
> > >Index: pub/rtsptran.h
> > >===================================================================
> > >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> > >retrieving revision 1.19
> > >diff -u -r1.19 rtsptran.h
> > >--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
> > >+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
> > >@@ -259,6 +259,9 @@
> > >     HX_RESULT resetFlags               (UINT16 streamNumber);
> > >     HX_RESULT getPacket                        (UINT16 uStreamNumber,
> > >                                        IHXPacket*& pPacket);
> > >+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
> > >+                                       IHXPacket*& pPacket,
> > >+                                         REF(UINT32) uSeqNum);
> > >     virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
> > >     virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
> > >
> > >Index: Umakefil
> > >===================================================================
> > >RCS file: /cvsroot/client/common/util/Umakefil,v
> > >retrieving revision 1.3
> > >diff -u -r1.3 Umakefil
> > >--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
> > >+++ Umakefil    22 Jun 2004 22:53:43 -0000
> > >@@ -53,6 +53,7 @@
> > >                   'chxphook.cpp',
> > >                   'xnetchck.cpp',
> > >                   'littobig.cpp',
> > >-                  'hxunicod.cpp')
> > >+                  'hxunicod.cpp',
> > >+                   'hxsrcbufstats.cpp')
> > >
> > > LibraryTarget('utlclntlib')
> > >Index: hxcore.h
> > >===================================================================
> > >RCS file: /cvsroot/common/include/hxcore.h,v
> > >retrieving revision 1.5
> > >diff -u -r1.5 hxcore.h
> > >--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
> > >+++ hxcore.h    22 Jun 2004 23:00:23 -0000
> > >@@ -2060,7 +2060,50 @@
> > >
> > > // $EndPrivate.
> > >
> > >+// $Private:
> > >
> > >+/********************************************************************* 
> *******
> > >+ *
> > >+ *  Interface:
> > >+ *
> > >+ *     IID_IHXTransportOnTimeSync
> > >+ *
> > >+ *  Purpose:
> > >+ *
> > >+ *     This interface is used to send OnTimeSync() calls down
> > >+ *      to the transport layer. Note that the value passed to
> > >+ *      OnTimeSync() MUST be in the same units and have the same
> > >+ *      offset as the packets coming from the transport. This means
> > >+ *      that any offets caused by SMIL or live playback must be
> > >+ *      removed before calling OnTimeSync() on this interface
> > >+ *
> > >+ *      IID_IHXTransportOnTimeSync
> > >+ *
> > >+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> > >+ *
> > >+ */
> > >+DEFINE_GUID(IID_IHXTransportOnTimeSync,
> > >+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84,
> > >0xc1);
> > >+
> > >+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> > >+{
> > >+    /*
> > >+     * IUnknown methods
> > >+     */
> > >+
> > >+    STDMETHOD(QueryInterface)  (THIS_
> > >+                               REFIID riid,
> > >+                               void** ppvObj) PURE;
> > >+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> > >+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
> > >+
> > >+    /*
> > >+     * IHXTransportOnTimeSync methods
> > >+     */
> > >+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> > >+};
> > >+
> > >+// $EndPrivate.
> > >
> > > #endif /* _HXCORE_H_ */
> > >
> > >Index: hxpiids.h
> > >===================================================================
> > >RCS file: /cvsroot/common/include/hxpiids.h,v
> > >retrieving revision 1.28.2.1
> > >diff -u -r1.28.2.1 hxpiids.h
> > >--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
> > >+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
> > >@@ -533,6 +533,7 @@
> > > DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b,
> > >0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
> > > DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93,
> > >0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
> > > DEFINE_GUID_ENUM(IID_IHXMacBlitMutex,
> > >0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95,
> > >0xa9,  0x69,  0x37,  0x3b,  0x4d)
> > >+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 0x41e0,
> > >0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
> > > #endif /* _HXCORE_H_ */
> > >
> > > /*
> > >
> > >
> > >
> > >
> > >_______________________________________________
> > >Client-dev mailing list
> > >Client-dev@lists.helixcommunity.org
> > >http://lists.helixcommunity.org/mailman/listinfo/client-dev
> >


From acolwell at real.com  Wed Jun 23 10:44:37 2004
From: acolwell at real.com (Aaron Colwell)
Date: Wed Jun 23 10:46:29 2004
Subject: [Protocol-dev] Re: [Common-dev] CR-Client: Moving
	IHXSourceBufferingStats2 implementation
In-Reply-To: <5.1.0.14.2.20040623101601.0395b580@mailone.real.com>
References: <5.1.0.14.2.20040623095240.02bead80@mailone.real.com>
	<20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623095240.02bead80@mailone.real.com>
	<5.1.0.14.2.20040623101601.0395b580@mailone.real.com>
Message-ID: <20040623174437.GA8188@real.com>

On Wed, Jun 23, 2004 at 10:37:01AM -0700, Henry Ping wrote:
> At 09:48 AM 6/23/2004 -0700, Aaron Colwell wrote:
> >On Wed, Jun 23, 2004 at 09:55:46AM -0400, Eric Hyche wrote:
> >>
> >> This is a pretty complicated change, so I doubt I'm
> >> hitting any of the subtleties, but after a cursory examination,
> >> these changes look good to me.
> >
> >Thanks for taking a look. This is basically just moving code from one 
> >place to
> >another, but the diffs don't show that the call flow is basically 
> >equivalent.
> >
> >>
> >> Just wondering though, why do we need the
> >>
> >> >+// $Private:
> >>
> >> and
> >>
> >> >+// $EndPrivate.
> >
> >I just put them in there because I noticed them around other "private"
> >interfaces. I just wanted to mark this interface as something that the 
> >general
> >public shouldn't use because it could cause "bad things" to happen.
> 
> What "bad things"? All interfaces defined in public are "vulnerable" and 
> can be used by the public. If we want to add a notion that this interface 
> is new and still underdevelopment, then we probably can add a more explicit 
> tag and deprecate "$Private" tag.

ok. "bad things" won't result in a crash or anything. If the interface is 
called with incorrect data though, it will cause the information reported by
the IHXSourceBufferingStats2 interface to be incorrect.


> 
> >Perhaps hxcore.h isn't the right place for this interface. Any suggestions?
> 
> I suggest to put it in a separate new file. I also suggest to move 
> hxsrcbufstats.* from client/common to common/util, since protocol/rtsp is 
> also built by the server and it should not depend on client/common

Ok. I'll move the code there and put the interface in a new file.

> 
> -->Henry
> 
> >>
> >> around the new interface definition? Seems like since
> >> hxcore.h is out in the public anyway, that our
> >> Private/EndPrivate stuff is moot.
> >>
> >> I'm not suggesting we go through and remove them from
> >> all header files, but it seems to me we shouldn't be
> >> adding any *more* of them.
> >>
> >> Eric
> >>
> >> At 04:52 PM 6/22/2004 -0700, Aaron Colwell wrote:
> >> >Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> >> >          number information can be maintained as well.
> >> >
> >> >Overview: These changes move the IHXSourceBufferingStats2 implementation
> >> >          out of HXBufferingState and into a new class called
> >> >          HXSourceBufferStats. This was done because the client needs to
> >> >          track packet sequence numbers for 3GPP-Rel6 OBSN support.
> >> >          There was no good way to get the sequence number information 
> >to
> >> >          the HXBufferingState class so the IHXSourceBufferingStats2 
> >logic
> >> >          was moved to where this information is available.
> >> >
> >> >          A new interface called IHXTransportOnTimeSync was created to
> >> >          propagate OnTimeSync() like calls to HXSourceBufferStats. The
> >> >          time passed to the OnTimeSync() call in this interface MUST
> >> >          NOT have any offsets created by SMIL or live playback. The 
> >time
> >> >          should be in the same time frame as the packets coming from 
> >the
> >> >          transport. If someone wants to rename this interface that is 
> >fine
> >> >          by me.
> >> >
> >> >
> >> >          - Created HXSourceBufferStats to contain the base
> >> >            IHXSourceBufferingStats2 implementation. This class is
> >> >            used by HXFileSource.
> >> >
> >> >          - Created HXNetSourceBufStats which derives from
> >> >HXSourceBufferStats.
> >> >            This class just overloads the GetCurrentBuffering() so that 
> >it
> >> >            returns the amount of data in the transport buffer. This is
> >> >            used by RTSPClientProtocol.
> >> >
> >> >          - Removed IHXSourceBufferingStats2 code from HXSource
> >> >
> >> >          - Removed packet tracking code from HXBufferingState. This
> >> >            functionality is implemented by HXSourceBufferStats now
> >> >
> >> >          - Added code to HXSource to provide OnTimeSync() calls to the
> >> >            IHXTransportOnTimeSync interface.
> >> >
> >> >          - HXSource now exposes IHXSourceBufferingStats functionality
> >> >through
> >> >            it's m_pSrcBufStats member variable instead of implementing 
> >it
> >> >            itself. The file and network sources are expected to 
> >provide an
> >> >            IHXSourceBufferingStats2 interface via a
> >> >            HXSource::SetSrcBufStats() call.
> >> >
> >> >          - Added code to HXFileSource to use HXSourceBufferStats
> >> >
> >> >          - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> >> >
> >> >          - Fixed some code in CBufferManager that was expecting 
> >HXSource
> >> >            to implement IHXSourceBufferingStats. This code now QI's for
> >> >            IHXSourceBufferingStats and uses that interface.
> >> >
> >> >
> >> >
> >> >Files Modified:
> >> >client/core/buffmgr.cpp
> >> >client/core/hxbsrc.h
> >> >client/core/hxbufstate.h
> >> >client/core/hxbufstate.cpp
> >> >client/core/hxflsrc.cpp
> >> >client/core/hxflsrc.h
> >> >client/core/hxntsrc.cpp
> >> >client/core/hxntsrc.h
> >> >client/core/hxsrc.cpp
> >> >client/core/rtspprotocol.cpp
> >> >protocol/rtsp/Umakefil
> >> >protocol/rtsp/rtspclnt.cpp
> >> >protocol/rtsp/pub/rtspclnt.h
> >> >protocol/transport/common/system/rtsptran.cpp
> >> >protocol/transport/common/system/pub/rtsptran.h
> >> >client/common/util/Umakefil
> >> >common/include/hxcore.h
> >> >common/include/hxpiids.h
> >> >
> >> >Files Added:
> >> >client/common/util/pub/hxsrcbufstats.h
> >> >client/common/util/hxsrcbufstats.cpp
> >> >protocol/rtsp/ntsrcbufstats.h
> >> >protocol/rtsp/ntsrcbufstats.cpp
> >> >
> >> >Image Size and Heap Use impact:
> >> >
> >> >Platforms and Profiles affected: all
> >> >
> >> >Distribution Libraries affected: rdtclntlib
> >> >
> >> >Distribution library impact and planned action:
> >> >m_bIsLive and m_pSrcBufStats member variables were added to
> >> >RTSPClientProtocol so any derived objects will need to be
> >> >recompiled
> >> >
> >> >Platforms and Profiles Build Verified: win32
> >> >
> >> >Platforms and Profiles Functionality verified: win32
> >> >
> >> >Branch: HEAD
> >> >
> >> >QA Instructions: none
> >> >
> >> >Index: buffmgr.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/buffmgr.cpp,v
> >> >retrieving revision 1.21
> >> >diff -u -r1.21 buffmgr.cpp
> >> >--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
> >> >+++ buffmgr.cpp 22 Jun 2004 22:52:26 -0000
> >> >@@ -610,6 +610,11 @@
> >> >      * - Keep track of the stream with the lowest timestamp and is
> >> >      *   buffering data
> >> >      */
> >> >+    IHXSourceBufferingStats* pSrcBufStats = NULL;
> >> >+
> >> >+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
> >> >+                              (void**)&pSrcBufStats);
> >> >+
> >> >     for (i = m_pStreamInfoTable->Begin(); i !=
> >> >m_pStreamInfoTable->End(); ++i)
> >> >     {
> >> >        pStreamInfo = (STREAM_INFO*) (*i);
> >> >@@ -619,12 +624,15 @@
> >> >        ULONG32 ulNumBytesAtTransport = 0;
> >> >        BOOL bDoneAtTransport = FALSE;
> >> >
> >> >-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> >> >-                                      llLowestTimestampAtTransport,
> >> >-                                      llHighestTimestampAtTransport,
> >> >-                                      ulNumBytesAtTransport,
> >> >-                                      bDoneAtTransport);
> >> >-
> >> >+        if (pSrcBufStats)
> >> >+        {
> >> >+
> >> >pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
> >> >+
> >> >llLowestTimestampAtTransport,
> >> >+
> >> >llHighestTimestampAtTransport,
> >> >+                                              ulNumBytesAtTransport,
> >> >+                                              bDoneAtTransport);
> >> >+        }
> >> >+
> >> >        pStreamInfo->BufferingState().UpdateTransportStats(
> >> >            llLowestTimestampAtTransport,
> >> >            llHighestTimestampAtTransport,
> >> >@@ -658,6 +666,7 @@
> >> >
> >> >        }
> >> >     }
> >> >+    HX_RELEASE(pSrcBufStats);
> >> >
> >> >     /* If none of the streams have any data buffered at the transport
> >> >     layer,
> >> >      * return.
> >> >Index: hxbsrc.h
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxbsrc.h,v
> >> >retrieving revision 1.18.2.1
> >> >diff -u -r1.18.2.1 hxbsrc.h
> >> >--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
> >> >+++ hxbsrc.h    22 Jun 2004 22:52:26 -0000
> >> >@@ -233,12 +233,11 @@
> >> >                  public IHXPrivateStreamSource,
> >> >                  public IHXBackChannel,
> >> >                  public IHXASMSource,
> >> >-                  public IHXClientRateAdaptControl,
> >> >+                  public IHXClientRateAdaptControl
> >> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >> >-                 public IHXHyperNavigate,
> >> >-                 public IHXHyperNavigate2,
> >> >+                 , public IHXHyperNavigate,
> >> >+                 public IHXHyperNavigate2
> >> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >> >-                  public IHXSourceBufferingStats2
> >> > {
> >> > protected:
> >> >     LONG32                     m_lRefCount;
> >> >@@ -487,35 +486,6 @@
> >> >                            IHXValues* pParams);
> >> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >> >
> >> >-
> >> 
> >>/************************************************************************
> >> >-     * Method:
> >> >-     *     IHXSourceBufferingStats2::GetCurrentBuffering
> >> >-     * Purpose:
> >> >-     *     Get the current buffering information
> >> >-     */
> >> >-
> >> >-    STDMETHOD(GetCurrentBuffering) (THIS_
> >> >-                                    UINT16  uStreamNumber,
> >> >-                                    REF(INT64)  llLowestTimestamp,
> >> >-                                    REF(INT64)  llHighestTimestamp,
> >> >-                                    REF(UINT32) ulNumBytes,
> >> >-                                    REF(BOOL)   bDone) PURE;
> >> >-
> >> 
> >>/************************************************************************
> >> >-     * Method:
> >> >-     *     IHXSourceBufferingStats2::GetTotalBuffering
> >> >-     * Purpose:
> >> >-     *     Get the total amount of data buffered for a stream.
> >> >-     *      This includes what is in the transport buffer and in
> >> >-     *      the renderer
> >> >-     */
> >> >-
> >> >-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
> >> >-                                  REF(INT64)  llLowestTimestamp,
> >> >-                                  REF(INT64)  llHighestTimestamp,
> >> >-                                  REF(UINT32) ulNumBytes,
> >> >-                                  REF(BOOL)   bDone);
> >> >-
> >> >-
> >> >     /*
> >> >      * IHXClientRateAdaptControl Methods
> >> >      */
> >> >@@ -731,7 +701,7 @@
> >> >            virtual HX_RESULT   FillRecordControl() = 0;
> >> >                    BOOL        IsPlayingFromRecordControl() { return
> >> >m_bPlayFromRecordControl; };
> >> >
> >> >-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >> >+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >> >
> >> >             const char*         GetRedirectURL() { return
> >> >(m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
> >> >             const char*         GetSDPURL() { return (m_pSDPURL ?
> >> >m_pSDPURL->GetURL() : NULL); };
> >> >@@ -769,6 +739,8 @@
> >> >             void        ProcessFileHeader(void);
> >> >             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader,
> >> >STREAM_INFO*& pStreamInfo);
> >> >
> >> >+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
> >> >+
> >> >     HX_RESULT                  mLastError;
> >> >     CHXMapLongToObj*            mStreamInfoTable;
> >> >
> >> >@@ -868,6 +840,8 @@
> >> >     CHXURL*                     m_pRedirectURL;
> >> >     CHXURL*                     m_pSDPURL;
> >> >     BOOL                        m_bRedirectPending;
> >> >+    IHXTransportOnTimeSync*     m_pTransOnTimeSync;
> >> >+    IHXSourceBufferingStats2*   m_pSrcBufStats;
> >> > };
> >> >
> >> > // Defined flags
> >> >Index: hxbufstate.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxbufstate.cpp,v
> >> >retrieving revision 1.7
> >> >diff -u -r1.7 hxbufstate.cpp
> >> >--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
> >> >+++ hxbufstate.cpp      22 Jun 2004 22:52:26 -0000
> >> >@@ -83,18 +83,11 @@
> >> >     , m_ulLastPacketTimeStamp(0)
> >> >     , m_ulAvgBandwidth(0)
> >> >     , m_pASMProps(NULL)
> >> >-    , m_llCurrentPlaybackTime(0)
> >> >-    , m_ulBufferedData(0)
> >> >-    , m_ulLastTimeSync(0)
> >> >-    , m_llFirstLivePacketTimestamp(0)
> >> >-    , m_ulTimeSyncRollOver(0)
> >> > {}
> >> >
> >> > HXBufferingState::~HXBufferingState()
> >> > {
> >> >     HX_RELEASE(m_pASMProps);
> >> >-
> >> >-    ClearPktInfo();
> >> > }
> >> >
> >> > void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
> >> >@@ -179,8 +172,6 @@
> >> >     m_ulLastPacketTimeStamp = 0;
> >> >     m_bIsFirstPacket = TRUE;
> >> >
> >> >-    ClearPktInfo();
> >> >-
> >> >     if (bIsSeeking)
> >> >     {
> >> >        m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
> >> >@@ -288,11 +279,6 @@
> >> >     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 +
> >> >CAST_TO_INT64 ulTime;
> >> > }
> >> >
> >> >-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
> >> >-{
> >> >-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64
> >> >MAX_UINT32 + CAST_TO_INT64 ulTime;
> >> >-}
> >> >-
> >> > void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 
> >ulPacketSize,
> >> >                                UINT32 ulElapsedTime,
> >> >                                BOOL bIsLive, BOOL bIsBufferedPlayMode)
> >> >@@ -318,16 +304,12 @@
> >> >        if (bIsLive)
> >> >        {
> >> >            m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >> >-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
> >> >         }
> >> >
> >> >        m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
> >> >        m_bIsFirstPacket = FALSE;
> >> >     }
> >> >
> >> >-    // Add this packet to our packet info statistics
> >> >-    AddPktInfo(llActualTimeStamp, ulPacketSize);
> >> >-
> >> >     // data based preroll
> >> >     if (DataBasedPreroll())
> >> >     {
> >> >@@ -451,47 +433,6 @@
> >> >     m_bDoneAtTransport = bDoneAtTransport;
> >> > }
> >> >
> >> >-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) 
> >llLowTimestamp,
> >> >-                                             REF(INT64) 
> >llHighTimestamp,
> >> >-                                             REF(UINT32) 
> >ulBytesBuffered,
> >> >-                                             BOOL bUseTransportStats)
> >> >-{
> >> >-    HX_RESULT res = HXR_NO_DATA;
> >> >-
> >> >-    if (!m_bIsFirstPacket)
> >> >-    {
> >> >-       if (!m_pktInfo.IsEmpty())
> >> >-       {
> >> >-           HXBufferedPktInfo* pPktInfo =
> >> >-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
> >> >-
> >> >-           llLowTimestamp = pPktInfo->Timestamp();
> >> >-       }
> >> >-       else
> >> >-       {
> >> >-           llLowTimestamp = m_llHighestTimeStamp;
> >> >-       }
> >> >-
> >> >-       llHighTimestamp = m_llHighestTimeStamp;
> >> >-       ulBytesBuffered = GetBufferedData();
> >> >-
> >> >-
> >> >-       if (bUseTransportStats)
> >> >-       {
> >> >-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
> >> >-           {
> >> >-               llHighTimestamp = m_llHighestTimestampAtTransport;
> >> >-           }
> >> >-
> >> >-           ulBytesBuffered += m_ulNumBytesAtTransport;
> >> >-       }
> >> >-
> >> >-       res = HXR_OK;
> >> >-    }
> >> >-
> >> >-    return res;
> >> >-}
> >> >-
> >> > void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
> >> >                                           INT64 llTheHighestTS,
> >> >                                           BOOL bIsSeekPerformed,
> >> >@@ -569,19 +510,6 @@
> >> >
> >> > }
> >> >
> >> >-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
> >> >-{
> >> >-    //  0xFA .. 0xFF [roll over] (0x01)
> >> >-    if (m_ulLastTimeSync > ulCurrentTime &&
> >> >-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
> >> >-    {
> >> >-       m_ulTimeSyncRollOver++;
> >> >-    }
> >> >-    m_ulLastTimeSync = ulCurrentTime;
> >> >-
> >> >-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
> >> >-}
> >> >-
> >> > void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
> >> >                                        ULONG32 ulMinBufferingInMs)
> >> > {
> >> >@@ -771,62 +699,4 @@
> >> >     {
> >> >        m_ulAvgBandwidth = ulBandwidth;
> >> >     }
> >> >-}
> >> >-
> >> >-void HXBufferingState::ClearPktInfo()
> >> >-{
> >> >-    m_ulBufferedData = 0;
> >> >-    while(!m_pktInfo.IsEmpty())
> >> >-    {
> >> >-       HXBufferedPktInfo* pInfo =
> >> >(HXBufferedPktInfo*)m_pktInfo.RemoveHead();
> >> >-       delete pInfo;
> >> >-    }
> >> >-}
> >> >-
> >> >-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 
> >ulPacketSize)
> >> >-{
> >> >-    // Subtract off the first live packet timestamp.
> >> >-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
> >> >-    llTimestamp -= m_llFirstLivePacketTimestamp;
> >> >-    // Create the HXBufferedPktInfo class
> >> >-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
> >> >-                                                       ulPacketSize);
> >> >-    if (pPktInfo)
> >> >-    {
> >> >-       m_pktInfo.AddTail(pPktInfo);
> >> >-       m_ulBufferedData += ulPacketSize;
> >> >-    }
> >> >-
> >> >-    // purge the old packet info data
> >> >-    //  this keeps the list short and prevents the Symbian
> >> >-    //  allocator from freaking out
> >> >-    (void)GetBufferedData();
> >> >-}
> >> >-
> >> >-UINT32 HXBufferingState::GetBufferedData()
> >> >-{
> >> >-    BOOL bDone = m_pktInfo.IsEmpty();
> >> >-
> >> >-    // Remove all packet info that is past due
> >> >-    // and subtract their sizes from our buffering total
> >> >-    while(!bDone)
> >> >-    {
> >> >-       HXBufferedPktInfo* pPktInfo =
> >> >(HXBufferedPktInfo*)m_pktInfo.GetHead();
> >> >-
> >> >-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
> >> >-       {
> >> >-           m_ulBufferedData -= pPktInfo->Size();
> >> >-
> >> >-           m_pktInfo.RemoveHead();
> >> >-           delete pPktInfo;
> >> >-
> >> >-           bDone = m_pktInfo.IsEmpty();
> >> >-       }
> >> >-       else
> >> >-       {
> >> >-           bDone = TRUE;
> >> >-       }
> >> >-    }
> >> >-
> >> >-    return m_ulBufferedData;
> >> > }
> >> >Index: hxbufstate.h
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxbufstate.h,v
> >> >retrieving revision 1.4
> >> >diff -u -r1.4 hxbufstate.h
> >> >--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
> >> >+++ hxbufstate.h        22 Jun 2004 22:52:26 -0000
> >> >@@ -81,7 +81,6 @@
> >> >     BOOL HasPredata(BOOL bIsSeekPerformed);
> >> >
> >> >     INT64 CreateINT64Timestamp(UINT32 ulTime);
> >> >-    INT64 CreateINT64Timesync(UINT32 ulTime);
> >> >
> >> >     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
> >> >                  UINT32 ulElapsedTime, BOOL bIsLive,
> >> >@@ -98,11 +97,6 @@
> >> >                              ULONG32 ulBytesAtTransport,
> >> >                              BOOL bDoneAtTransport);
> >> >
> >> >-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
> >> >-                               REF(INT64) llHighTimestamp,
> >> >-                               REF(UINT32) ulBytesBuffered,
> >> >-                               BOOL bUseTransportStats);
> >> >-
> >> >     void GetExcessBufferInfo(INT64 llTheLowestTS,
> >> >                             INT64 llTheHighestTS,
> >> >                             BOOL bIsSeekPerformed,
> >> >@@ -119,8 +113,6 @@
> >> >
> >> >     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
> >> >
> >> >-    void OnTimeSync(UINT32 ulCurrentTime);
> >> >-
> >> >     // Should remove
> >> >     void SetAvgBWToASMBw();
> >> >     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
> >> >@@ -149,19 +141,6 @@
> >> >                        UINT32 ulCurrentBuffering,
> >> >                        UINT32 ulMinimumPreroll,
> >> >                        UINT32 ulDenom) const;
> >> >-
> >> >-    /* Functions for tracking the amount of data
> >> >-     * buffered in the renderer
> >> >-     */
> >> >-    void ClearPktInfo(); /* Clears out information about buffered 
> >packets
> >> >*/
> >> >-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called
> >> >when
> >> >-                                                             * a 
> >packet is
> >> >-                                                             * sent 
> >to the
> >> >-                                                             * renderer
> >> >-                                                             */
> >> >-    UINT32 GetBufferedData(); /* Get the current amount of data 
> >buffered
> >> >-                              * in the renderer
> >> >-                              */
> >> >
> >> >     ULONG32            m_ulPreroll;
> >> >     ULONG32            m_ulPredata;
> >> >@@ -196,20 +175,6 @@
> >> >     ULONG32            m_ulLastPacketTimeStamp;
> >> >     ULONG32            m_ulAvgBandwidth;
> >> >     IHXASMProps*       m_pASMProps;
> >> >-    UINT32              m_ulLastTimeSync;
> >> >-    INT64               m_llFirstLivePacketTimestamp;
> >> >-    UINT32              m_ulTimeSyncRollOver;
> >> >-    // These variable keep track of the amount of
> >> >-    // data buffered in the renderer
> >> >-    INT64               m_llCurrentPlaybackTime; /* Cached value of 
> >last
> >> >-                                                 * OnTimeSync() call
> >> >-                                                 */
> >> >-
> >> >-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
> >> >-                                          * Always use 
> >GetBufferedData()
> >> >-                                          * to retreive the value
> >> >-                                          */
> >> >-    CHXSimpleList       m_pktInfo; /* List of packet information */
> >> > };
> >> >
> >> > inline
> >> >Index: hxflsrc.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxflsrc.cpp,v
> >> >retrieving revision 1.54
> >> >diff -u -r1.54 hxflsrc.cpp
> >> >--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
> >> >+++ hxflsrc.cpp 22 Jun 2004 22:52:26 -0000
> >> >@@ -76,6 +76,7 @@
> >> > #include "uri_schemes.h"
> >> > #include "stream_desc_hlpr.h"
> >> > #include "findfile.h"
> >> >+#include "hxsrcbufstats.h"
> >> >
> >> > #include "hxheap.h"
> >> > #ifdef _DEBUG
> >> >@@ -115,6 +116,7 @@
> >> >     , m_bValidateMetaDone(FALSE)
> >> >     , m_pFileRecognizer(NULL)
> >> >     , m_pFileReader(NULL)
> >> >+    , m_pSrcBufStats(NULL)
> >> > {
> >> >     m_bAltURL = FALSE;
> >> >     m_bPerfectPlay = TRUE;
> >> >@@ -306,6 +308,13 @@
> >> >
> >> >     HX_VECTOR_DELETE(m_pszURL);
> >> >     HX_DELETE(m_pURL);
> >> >+
> >> >+    HX_RELEASE(m_pSrcBufStats);
> >> >+    m_pSrcBufStats = new HXSourceBufferStats();
> >> >+    if (m_pSrcBufStats)
> >> >+    {
> >> >+        m_pSrcBufStats->AddRef();
> >> >+    }
> >> >
> >> >     if (!theErr && pURL)
> >> >     {
> >> >@@ -938,6 +947,7 @@
> >> >     }
> >> > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
> >> >
> >> >+    HX_RELEASE(m_pSrcBufStats);
> >> >     HXSource::DoCleanup();
> >> >
> >> >     return HXR_OK;
> >> >@@ -1068,6 +1078,11 @@
> >> >
> >> >     m_llLastFillEndTime = 0;
> >> >
> >> >+    if (m_pSrcBufStats)
> >> >+    {
> >> >+        m_pSrcBufStats->Reset();
> >> >+    }
> >> >+
> >> > cleanup:
> >> >
> >> >     return HXR_OK;
> >> >@@ -1442,6 +1457,11 @@
> >> >
> >> >            if(m_pBufferManager)
> >> >                m_pBufferManager->UpdateCounters(pPacket, 0);
> >> >+
> >> >+            if (m_pSrcBufStats && !pPacket->IsLost())
> >> >+            {
> >> >+                m_pSrcBufStats->OnPacket(pPacket);
> >> >+            }
> >> >
> >> >            HX_RELEASE(pPacket);
> >> >        }
> >> >@@ -2103,6 +2123,13 @@
> >> >        }
> >> >        HX_RELEASE(pszParentName);
> >> > #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
> >> >+
> >> >+        if (pStreamInfo && m_pSrcBufStats)
> >> >+        {
> >> >+            m_pSrcBufStats->Init(pStreamInfo->m_uStreamNumber,
> >> >+                                 mLiveStream);
> >> >+        }
> >> >+
> >> >         m_ulStreamIndex++;
> >> >         m_uNumStreams++;
> >> >     }
> >> >@@ -2115,6 +2142,11 @@
> >> >
> >> >        theErr = AdjustClipTime();
> >> >        m_pBufferManager->Init();
> >> >+
> >> >+        if (m_pSrcBufStats)
> >> >+        {
> >> >+            SetSrcBufStats(m_pSrcBufStats);
> >> >+        }
> >> >     }
> >> >
> >> >     return theErr;
> >> >@@ -2313,6 +2345,11 @@
> >> >        {
> >> >            m_pBufferManager->UpdateCounters(pPacket, 0);
> >> >        }
> >> >+
> >> >+        if (m_pSrcBufStats && !pPacket->IsLost())
> >> >+        {
> >> >+            m_pSrcBufStats->OnPacket(pPacket);
> >> >+        }
> >> >     }
> >> >
> >> >     m_llLastFillEndTime = llActualPacketTime;
> >> >Index: hxflsrc.h
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxflsrc.h,v
> >> >retrieving revision 1.12
> >> >diff -u -r1.12 hxflsrc.h
> >> >--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
> >> >+++ hxflsrc.h   22 Jun 2004 22:52:26 -0000
> >> >@@ -52,6 +52,8 @@
> >> > #include "hxfiles.h"
> >> > #include "recognizer.h"
> >> >
> >> >+class HXSourceBufferStats;
> >> >+
> >> > class HXFileSource : public HXSource,
> >> >                      public IHXFormatResponse,
> >> >                       public IHXHTTPRedirectResponse
> >> >@@ -349,6 +351,7 @@
> >> >
> >> >     CFileReader*                m_pFileReader;
> >> >     CHXFileRecognizer*          m_pFileRecognizer;
> >> >+    HXSourceBufferStats*        m_pSrcBufStats;
> >> > };
> >> >
> >> > #endif // _HX_FILE_SOURCE
> >> >Index: hxntsrc.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxntsrc.cpp,v
> >> >retrieving revision 1.90
> >> >diff -u -r1.90 hxntsrc.cpp
> >> >--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
> >> >+++ hxntsrc.cpp 22 Jun 2004 22:52:26 -0000
> >> >@@ -675,6 +675,7 @@
> >> >     HX_RESULT   rc = HXR_OK;
> >> >     BOOL        bSDPInitiated = FALSE;
> >> >     CHXString   pString;
> >> >+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
> >> >
> >> >     // start off with the preferred protocol
> >> >     rc = CreateProtocol();
> >> >@@ -722,6 +723,14 @@
> >> >         goto cleanup;
> >> >     }
> >> >
> >> >+    // Setup source buffer stats
> >> >+    if (HXR_OK == 
> >m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
> >> >+                                           (void**)&pSrcBufStats))
> >> >+    {
> >> >+        SetSrcBufStats(pSrcBufStats);
> >> >+        HX_RELEASE(pSrcBufStats);
> >> >+    }
> >> >+
> >> >     // create log info list
> >> >     m_pLogInfoList = new CHXSimpleList;
> >> >     m_ulLogInfoLength = 0;
> >> >@@ -6295,6 +6304,12 @@
> >> > #else
> >> >     return HXR_NOTIMPL;
> >> > #endif /* HELIX_FEATURE_RECORDCONTROL */
> >> >+}
> >> >+
> >> >+HX_RESULT
> >> >+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
> >> >+{
> >> >+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
> >> > }
> >> >
> >> > ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
> >> >Index: hxntsrc.h
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxntsrc.h,v
> >> >retrieving revision 1.24
> >> >diff -u -r1.24 hxntsrc.h
> >> >--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
> >> >+++ hxntsrc.h   22 Jun 2004 22:52:26 -0000
> >> >@@ -282,6 +282,7 @@
> >> >
> >> >        virtual HX_RESULT       FillRecordControl();
> >> >
> >> >+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
> >> > protected:
> >> >
> >> >        virtual                         ~HXNetSource(void);
> >> >@@ -470,7 +471,6 @@
> >> > private:
> >> >         IHXBufferControl*                m_pBufferCtl;
> >> >         IHXWatermarkBufferControl*       m_pWMBufferCtl;
> >> >-
> >> > public:
> >> >        HX_RESULT       FinishSetup();
> >> >        void            ReSetup();
> >> >Index: hxsrc.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/hxsrc.cpp,v
> >> >retrieving revision 1.44.2.1
> >> >diff -u -r1.44.2.1 hxsrc.cpp
> >> >--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
> >> >+++ hxsrc.cpp   22 Jun 2004 22:52:26 -0000
> >> >@@ -213,6 +213,8 @@
> >> >         , m_pRedirectURL(NULL)
> >> >         , m_pSDPURL(NULL)
> >> >         , m_bRedirectPending(FALSE)
> >> >+        , m_pTransOnTimeSync(NULL)
> >> >+        , m_pSrcBufStats(NULL)
> >> > {
> >> >     mStreamInfoTable = new CHXMapLongToObj;
> >> > }
> >> >@@ -313,6 +315,8 @@
> >> >     HX_DELETE(m_pRedirectURL);
> >> >     HX_DELETE(m_pSDPURL);
> >> >     m_bRedirectPending  = FALSE;
> >> >+    HX_RELEASE(m_pTransOnTimeSync);
> >> >+    HX_RELEASE(m_pSrcBufStats);
> >> >
> >> > #if defined(HELIX_FEATURE_RECORDCONTROL)
> >> >     if(m_pRecordControl)
> >> >@@ -340,8 +344,6 @@
> >> >             { GET_IIDHANDLE(IID_IHXPendingStatus),
> >> >(IHXPendingStatus*)this },
> >> >             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
> >> >             { GET_IIDHANDLE(IID_IHXPrivateStreamSource),
> >> >(IHXPrivateStreamSource*)this },
> >> >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats),
> >> >(IHXSourceBufferingStats*)this },
> >> >-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2),
> >> >(IHXSourceBufferingStats2*)this },
> >> >             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
> >> >               (IHXClientRateAdaptControl*)this },
> >> > #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
> >> >@@ -388,6 +390,14 @@
> >> >            return HXR_NOINTERFACE;
> >> >        }
> >> >     }
> >> >+    else if (m_pSrcBufStats &&
> >> >+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
> >> >+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
> >> >+    {
> >> >+        m_pSrcBufStats->AddRef();
> >> >+        *ppvObj = m_pSrcBufStats;
> >> >+        return HXR_OK;
> >> >+    }
> >> >
> >> > #if defined(HELIX_FEATURE_AUTOUPGRADE)
> >> >     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
> >> >@@ -2250,59 +2260,6 @@
> >> > }
> >> > #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
> >> >
> >> >-STDMETHODIMP
> >> >-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
> >> >-                           REF(INT64)  llLowestTimestamp,
> >> >-                           REF(INT64)  llHighestTimestamp,
> >> >-                           REF(UINT32) ulNumBytes,
> >> >-                           REF(BOOL)   bDone)
> >> >-{
> >> >-    HX_RESULT res = HXR_NO_DATA;
> >> >-
> >> >-    llLowestTimestamp = 0;
> >> >-    llHighestTimestamp = 0;
> >> >-    ulNumBytes = 0;
> >> >-    bDone = FALSE;
> >> >-
> >> >-    STREAM_INFO* pStreamInfo;
> >> >-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*&
> >> >)pStreamInfo))
> >> >-    {
> >> >-       HXBufferingState& bufState = pStreamInfo->BufferingState();
> >> >-       BOOL   bUseTransportStats = FALSE;
> >> >-
> >> >-       INT64  llTransportLowTS = 0;
> >> >-       INT64  llTransportHighTS = 0;
> >> >-       UINT32 ulTransportBytes = 0;
> >> >-       BOOL   bTransportDone = FALSE;
> >> >-
> >> >-       if (!IsLocalSource() &&
> >> >-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
> >> >-                                          llTransportLowTS,
> >> >-                                          llTransportHighTS,
> >> >-                                          ulTransportBytes,
> >> >-                                          bTransportDone)))
> >> >-       {
> >> >-           bufState.UpdateTransportStats(llTransportLowTS,
> >> >-                                         llTransportHighTS,
> >> >-                                         ulTransportBytes,
> >> >-                                         bTransportDone);
> >> >-
> >> >-           bUseTransportStats = TRUE;
> >> >-
> >> >-           // Update bDone with what the transport says.
> >> >-           bDone = bTransportDone;
> >> >-       }
> >> >-
> >> >-       res = bufState.GetBufferingStats(llLowestTimestamp,
> >> >-                                       llHighestTimestamp,
> >> >-                                       ulNumBytes,
> >> >-                                       bUseTransportStats);
> >> >-    }
> >> >-
> >> >-
> >> >-    return res;
> >> >-}
> >> >-
> >> > /*
> >> >  * IHXClientRateAdaptControl Methods
> >> >  */
> >> >@@ -2948,13 +2905,34 @@
> >> > {
> >> >     HX_RESULT res = HXR_OK;
> >> >
> >> >-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
> >> >-         i != mStreamInfoTable->End(); ++i)
> >> >-    {
> >> >-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
> >> >-
> >> >-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
> >> >+    // Convert presentation time to transport time
> >> >+    if (m_pTransOnTimeSync)
> >> >+    {
> >> >+        ULONG32 ulOffset = m_ulDelay;
> >> >+        ULONG32 ulTransportTime = m_ulStartTime;
> >> >+
> >> >+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
> >> >+        {
> >> >+            ulTransportTime += ulCurrentTime - ulOffset;
> >> >+        }
> >> >+
> >> >+        res = m_pTransOnTimeSync->OnTimeSync(ulTransportTime);
> >> >     }
> >> >
> >> >     return res;
> >> >+}
> >> >+
> >> >+void
> >> >+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
> >> >+{
> >> >+    HX_RELEASE(m_pSrcBufStats);
> >> >+    HX_RELEASE(m_pTransOnTimeSync);
> >> >+
> >> >+    if (pSrcBufStats)
> >> >+    {
> >> >+        m_pSrcBufStats = pSrcBufStats;
> >> >+        m_pSrcBufStats->AddRef();
> >> >+        m_pSrcBufStats->QueryInterface(IID_IHXTransportOnTimeSync,
> >> >+                                       (void**)&m_pTransOnTimeSync);
> >> >+    }
> >> > }
> >> >Index: rtspprotocol.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
> >> >retrieving revision 1.39
> >> >diff -u -r1.39 rtspprotocol.cpp
> >> >--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
> >> >+++ rtspprotocol.cpp    22 Jun 2004 22:52:26 -0000
> >> >@@ -2626,12 +2626,12 @@
> >> >     UINT16 seekFrom
> >> > )
> >> > {
> >> >+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
> >> >+
> >> >     if (IsLive())
> >> >     {
> >> >-        return m_pProtocolLib->SeekFlush();
> >> >+        return theErr;
> >> >     }
> >> >-
> >> >-    HX_RESULT theErr = HXR_OK;
> >> >
> >> >     m_uCurrentStreamCount = m_uStreamCount;
> >> >
> >> >
> >> >Index: Umakefil
> >> >===================================================================
> >> >RCS file: /cvsroot/protocol/rtsp/Umakefil,v
> >> >retrieving revision 1.9.2.1
> >> >diff -u -r1.9.2.1 Umakefil
> >> >--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
> >> >+++ Umakefil    22 Jun 2004 22:52:32 -0000
> >> >@@ -46,6 +46,7 @@
> >> >                          'common/runtime/pub',
> >> >                          'common/lang/xml/pub',
> >> >                          'client/common/container/pub',
> >> >+                          'client/common/util/pub',
> >> >                          'protocol/transport/rtp/include',
> >> >                          'server/include',
> >> >                           'server/common/struct/pub',
> >> >@@ -65,7 +66,7 @@
> >> >                   'rtspmsg.cpp', 'rtspmdsc.cpp',
> >> >                   'rtsppars.cpp', 'mhprop.cpp',
> >> >                   'servrsnd.cpp', '3gpadapthdr.cpp',
> >> >-                   'rateadaptinfo.cpp')
> >> >+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
> >> >
> >> > if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
> >> >     project.AddSources('pipelinedesc.cpp')
> >> >Index: rtspclnt.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> >> >retrieving revision 1.79.2.1
> >> >diff -u -r1.79.2.1 rtspclnt.cpp
> >> >--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
> >> >+++ rtspclnt.cpp        22 Jun 2004 22:52:32 -0000
> >> >@@ -95,6 +95,7 @@
> >> > #include "pipelinedesc.h"
> >> > #include "errdbg.h"
> >> > #include "rateadaptinfo.h"
> >> >+#include "ntsrcbufstats.h"
> >> >
> >> > #include "hxheap.h"
> >> > #ifdef _DEBUG
> >> >@@ -302,6 +303,12 @@
> >> >     {
> >> >         return HXR_OK;
> >> >     }
> >> >+    else if (m_pSrcBufStats &&
> >> >+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
> >> >+                                                       ppvObj)))
> >> >+    {
> >> >+        return HXR_OK;
> >> >+    }
> >> >     *ppvObj = NULL;
> >> >     return HXR_NOINTERFACE;
> >> > }
> >> >@@ -388,6 +395,7 @@
> >> >     m_bReportedSuccessfulTransport(FALSE),
> >> >     m_bSDPInitiated(FALSE),
> >> >     m_bMulticast(FALSE),
> >> >+    m_bIsLive(FALSE),
> >> >     m_pSDPFileHeader(NULL),
> >> >     m_pSDPStreamHeaders(NULL),
> >> >     m_bSessionSucceeded(FALSE),
> >> >@@ -404,7 +412,8 @@
> >> >     m_ulCurrentTimeOut(0),
> >> >     m_pUAProfURI(NULL),
> >> >     m_pUAProfDiff(NULL),
> >> >-    m_pRateAdaptInfo(NULL)
> >> >+    m_pRateAdaptInfo(NULL),
> >> >+    m_pSrcBufStats(NULL)
> >> > #if defined(_MACINTOSH)
> >> >     , m_pCallback(NULL)
> >> > #endif /* _MACINTOSH */
> >> >@@ -460,6 +469,8 @@
> >> >         m_pRateAdaptInfo->Close();
> >> >         HX_DELETE(m_pRateAdaptInfo);
> >> >     }
> >> >+
> >> >+    HX_RELEASE(m_pSrcBufStats);
> >> > }
> >> >
> >> > /*
> >> >@@ -810,6 +821,21 @@
> >> >         }
> >> >     }
> >> >
> >> >+    if (HXR_OK == hresult)
> >> >+    {
> >> >+        HX_RELEASE(m_pSrcBufStats);
> >> >+        m_pSrcBufStats = new HXNetSourceBufStats(this);
> >> >+
> >> >+        if (m_pSrcBufStats)
> >> >+        {
> >> >+            m_pSrcBufStats->AddRef();
> >> >+        }
> >> >+        else
> >> >+        {
> >> >+            hresult = HXR_OUTOFMEMORY;
> >> >+        }
> >> >+    }
> >> >+
> >> > #if defined(_MACINTOSH)
> >> >     if (m_pCallback &&
> >> >         m_pCallback->m_bIsCallbackPending &&
> >> >@@ -2191,7 +2217,14 @@
> >> >         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> >> >     if (pTrans)
> >> >     {
> >> >-        rc = pTrans->getPacket(uStreamNumber, pPacket);
> >> >+        UINT32 uSeqNum;
> >> >+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
> >> >+
> >> >+        if ((HXR_OK == rc) && m_pSrcBufStats &&
> >> >+            (!pPacket->IsLost()))
> >> >+        {
> >> >+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
> >> >+        }
> >> >     }
> >> >
> >> >     m_pMutex->Unlock();
> >> >@@ -3291,16 +3324,24 @@
> >> >     HX_RESULT rc = HXR_OK;
> >> >     m_pMutex->Lock();
> >> >
> >> >-    CHXMapLongToObj::Iterator i;
> >> >-    for(i=m_pTransportStreamMap->Begin();
> >> >-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> >> >+    if (m_bIsLive)
> >> >     {
> >> >-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
> >> >-        UINT16 streamNumber = (UINT16)i.get_key();
> >> >-
> >> >-        HX_ASSERT(pTransport);
> >> >+        CHXMapLongToObj::Iterator i;
> >> >+        for(i=m_pTransportStreamMap->Begin();
> >> >+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
> >> >+        {
> >> >+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
> >> >+            UINT16 streamNumber = (UINT16)i.get_key();
> >> >+
> >> >+            HX_ASSERT(pTransport);
> >> >+
> >> >+            rc = pTransport ? pTransport->SeekFlush(streamNumber) :
> >> >HXR_OK;
> >> >+        }
> >> >+    }
> >> >
> >> >-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
> >> >+    if (m_pSrcBufStats)
> >> >+    {
> >> >+        m_pSrcBufStats->Reset();
> >> >     }
> >> >
> >> >     m_pMutex->Unlock();
> >> >@@ -6964,6 +7005,11 @@
> >> >         // Get session level RTP bandwidth modifiers
> >> >         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
> >> >         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
> >> >+
> >> >+        if (ulIsSessionLive)
> >> >+        {
> >> >+            m_bIsLive = TRUE;
> >> >+        }
> >> >
> >> >         // get multicast address from the session description
> >> >         if (HXR_OK ==
> >> >ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
> >> >@@ -7187,6 +7233,11 @@
> >> >             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
> >> >             pInfo->m_bRealMedia = bRealMedia;
> >> >
> >> >+            if (m_pSrcBufStats)
> >> >+            {
> >> >+                m_pSrcBufStats->Init((UINT16)streamNumber,
> >> >pInfo->m_bIsLive);
> >> >+            }
> >> >+
> >> >             if (m_pRateAdaptInfo)
> >> >             {
> >> >                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
> >> >@@ -7222,6 +7273,7 @@
> >> >         if (m_bMulticast)
> >> >         {
> >> >             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
> >> >+            m_bIsLive = TRUE;
> >> >         }
> >> >     }
> >> >
> >> >Index: pub/rtspclnt.h
> >> >===================================================================
> >> >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> >> >retrieving revision 1.30.2.1
> >> >diff -u -r1.30.2.1 rtspclnt.h
> >> >--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
> >> >+++ pub/rtspclnt.h      22 Jun 2004 22:52:32 -0000
> >> >@@ -46,6 +46,7 @@
> >> > #include "hxbufctl.h" // IHXTransportBufferLimit
> >> > #include "hxrtsp2.h"
> >> > #include "hxrsdbf.h" // IHXResendBufferControl
> >> >+#include "hxprefs.h" // IHXPreferences
> >> >
> >> > class RTSPClientState;
> >> > class RTSPOptionsMessage;
> >> >@@ -63,6 +64,7 @@
> >> > class MIMEHeader;
> >> > class PipelinedDescribeLogic;
> >> > class CHXRateAdaptationInfo;
> >> >+class HXNetSourceBufStats;
> >> >
> >> > struct IHXKeyValueList;
> >> > struct IHXValues;
> >> >@@ -1039,6 +1041,7 @@
> >> >
> >> >     BOOL                                m_bSDPInitiated;
> >> >     BOOL                                m_bMulticast;
> >> >+    BOOL                                m_bIsLive;
> >> >     IHXValues*                          m_pSDPFileHeader;
> >> >     CHXSimpleList*                      m_pSDPStreamHeaders;
> >> >
> >> >@@ -1074,6 +1077,7 @@
> >> >     UINT32                              m_ulServerTimeOut;
> >> >     UINT32                              m_ulCurrentTimeOut;
> >> >     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
> >> >+    HXNetSourceBufStats*                m_pSrcBufStats;
> >> >
> >> > #if defined(_MACINTOSH)
> >> >     RTSPClientProtocolCallback*                m_pCallback;
> >> >
> >> >Index: rtsptran.cpp
> >> >===================================================================
> >> >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> >> >retrieving revision 1.26
> >> >diff -u -r1.26 rtsptran.cpp
> >> >--- rtsptran.cpp        21 Apr 2004 19:16:30 -0000      1.26
> >> >+++ rtsptran.cpp        22 Jun 2004 22:53:16 -0000
> >> >@@ -526,8 +526,17 @@
> >> >     }
> >> > }
> >> >
> >> >+HX_RESULT
> >> >+RTSPTransport::getPacket(UINT16 uStreamNumber,
> >> >+                         IHXPacket*& pPacket)
> >> >+{
> >> >+    UINT32 uSeqNum;
> >> >+    return getPacket(uStreamNumber, pPacket, uSeqNum);
> >> >+}
> >> >+
> >> > HX_RESULT
> >> >-RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
> >> >+RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket,
> >> >+                         REF(UINT32) uSeqNum)
> >> > {
> >> >     RTSPTransportBuffer* pTransportBuffer =
> >> >getTransportBuffer(uStreamNumber);
> >> >     RTSPStreamData* pStreamData =
> >> >m_pStreamHandler->getStreamData(uStreamNumber);
> >> >@@ -547,6 +556,7 @@
> >> >     }
> >> >
> >> >     pPacket = clientPacket->GetPacket();
> >> >+    uSeqNum = clientPacket->GetSequenceNumber();
> >> >
> >> >     if (!pPacket)
> >> >     {
> >> >Index: pub/rtsptran.h
> >> >===================================================================
> >> >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> >> >retrieving revision 1.19
> >> >diff -u -r1.19 rtsptran.h
> >> >--- pub/rtsptran.h      20 Apr 2004 18:33:22 -0000      1.19
> >> >+++ pub/rtsptran.h      22 Jun 2004 22:53:16 -0000
> >> >@@ -259,6 +259,9 @@
> >> >     HX_RESULT resetFlags               (UINT16 streamNumber);
> >> >     HX_RESULT getPacket                        (UINT16 uStreamNumber,
> >> >                                        IHXPacket*& pPacket);
> >> >+    HX_RESULT getPacket                        (UINT16 uStreamNumber,
> >> >+                                       IHXPacket*& pPacket,
> >> >+                                         REF(UINT32) uSeqNum);
> >> >     virtual HX_RESULT startPackets     (UINT16 uStreamNumber);
> >> >     virtual HX_RESULT stopPackets      (UINT16 uStreamNumber);
> >> >
> >> >Index: Umakefil
> >> >===================================================================
> >> >RCS file: /cvsroot/client/common/util/Umakefil,v
> >> >retrieving revision 1.3
> >> >diff -u -r1.3 Umakefil
> >> >--- Umakefil    7 Feb 2003 22:37:08 -0000       1.3
> >> >+++ Umakefil    22 Jun 2004 22:53:43 -0000
> >> >@@ -53,6 +53,7 @@
> >> >                   'chxphook.cpp',
> >> >                   'xnetchck.cpp',
> >> >                   'littobig.cpp',
> >> >-                  'hxunicod.cpp')
> >> >+                  'hxunicod.cpp',
> >> >+                   'hxsrcbufstats.cpp')
> >> >
> >> > LibraryTarget('utlclntlib')
> >> >Index: hxcore.h
> >> >===================================================================
> >> >RCS file: /cvsroot/common/include/hxcore.h,v
> >> >retrieving revision 1.5
> >> >diff -u -r1.5 hxcore.h
> >> >--- hxcore.h    19 May 2004 19:38:28 -0000      1.5
> >> >+++ hxcore.h    22 Jun 2004 23:00:23 -0000
> >> >@@ -2060,7 +2060,50 @@
> >> >
> >> > // $EndPrivate.
> >> >
> >> >+// $Private:
> >> >
> >> >+/********************************************************************* 
> >*******
> >> >+ *
> >> >+ *  Interface:
> >> >+ *
> >> >+ *     IID_IHXTransportOnTimeSync
> >> >+ *
> >> >+ *  Purpose:
> >> >+ *
> >> >+ *     This interface is used to send OnTimeSync() calls down
> >> >+ *      to the transport layer. Note that the value passed to
> >> >+ *      OnTimeSync() MUST be in the same units and have the same
> >> >+ *      offset as the packets coming from the transport. This means
> >> >+ *      that any offets caused by SMIL or live playback must be
> >> >+ *      removed before calling OnTimeSync() on this interface
> >> >+ *
> >> >+ *      IID_IHXTransportOnTimeSync
> >> >+ *
> >> >+ *     {DB838AB3-4637-41e0-BC3F-ED03B6A684C1}
> >> >+ *
> >> >+ */
> >> >+DEFINE_GUID(IID_IHXTransportOnTimeSync,
> >> >+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84,
> >> >0xc1);
> >> >+
> >> >+DECLARE_INTERFACE_(IHXTransportOnTimeSync, IUnknown)
> >> >+{
> >> >+    /*
> >> >+     * IUnknown methods
> >> >+     */
> >> >+
> >> >+    STDMETHOD(QueryInterface)  (THIS_
> >> >+                               REFIID riid,
> >> >+                               void** ppvObj) PURE;
> >> >+    STDMETHOD_(ULONG32,AddRef) (THIS) PURE;
> >> >+    STDMETHOD_(ULONG32,Release)        (THIS) PURE;
> >> >+
> >> >+    /*
> >> >+     * IHXTransportOnTimeSync methods
> >> >+     */
> >> >+    STDMETHOD(OnTimeSync) (THIS_ UINT32 ulCurrentTime) PURE;
> >> >+};
> >> >+
> >> >+// $EndPrivate.
> >> >
> >> > #endif /* _HXCORE_H_ */
> >> >
> >> >Index: hxpiids.h
> >> >===================================================================
> >> >RCS file: /cvsroot/common/include/hxpiids.h,v
> >> >retrieving revision 1.28.2.1
> >> >diff -u -r1.28.2.1 hxpiids.h
> >> >--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
> >> >+++ hxpiids.h   22 Jun 2004 23:00:23 -0000
> >> >@@ -533,6 +533,7 @@
> >> > DEFINE_GUID_ENUM(IID_IHXPlayerPresentation, 0x6de011a7, 0xef05, 0x417b,
> >> >0x93, 0x67, 0x6f, 0xe0, 0xe5, 0x43, 0x2, 0xd3)
> >> > DEFINE_GUID_ENUM(IID_IHXCoreMutex, 0x6de011a7, 0xef05, 0x417b, 0x93,
> >> >0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd4)
> >> > DEFINE_GUID_ENUM(IID_IHXMacBlitMutex,
> >> >0x294e6de4,  0xfbc6,  0x4c06,  0xbb,  0x94,  0x95,
> >> >0xa9,  0x69,  0x37,  0x3b,  0x4d)
> >> >+DEFINE_GUID_ENUM(IID_IHXTransportOnTimeSync, 0xdb838ab3, 0x4637, 
> >0x41e0,
> >> >0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
> >> > #endif /* _HXCORE_H_ */
> >> >
> >> > /*
> >> >
> >> >
> >> >
> >> >
> >> >_______________________________________________
> >> >Common-dev mailing list
> >> >Common-dev@lists.helixcommunity.org
> >> >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> >>
> >> ======================================
> >> M. Eric Hyche (ehyche@real.com)
> >> Core Technologies
> >> RealNetworks, Inc.
> >>
> >
> >_______________________________________________
> >Protocol-dev mailing list
> >Protocol-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> 

From gwright at real.com  Wed Jun 23 11:06:09 2004
From: gwright at real.com (Greg Wright)
Date: Wed Jun 23 11:03:58 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client:
	MovingIHXSourceBufferingStats2implementation
References: <20040622235202.GA5152@real.com><0a4601c45944$13118520$ff8317ac@gwright5>
	<20040623173407.GD7758@real.com>
Message-ID: <0b5901c4594c$c398e3e0$ff8317ac@gwright5>

> > Also, there was a new interface added called IHXTimelineWatcher
> > that provides OnTimeSync calls from the auido services. If that
> > is the same time you are after you can just use that. However,
> > if this is a different based time then maybe we should not 
> > call it OnTimeSync. At least in my mind, OnTimeSync means the
> > current audio timeline position whenever I see it.
> 
> It is a different timebase than audio services. How about I call the
> new interface IHXTransportTimeSink and rename the method to OnTransportTime().
> I think that will make it clear that something is different than the normal
> OnTimeSync() call.

Sounds good to me.
--greg.



From acolwell at real.com  Wed Jun 23 13:14:27 2004
From: acolwell at real.com (Aaron Colwell)
Date: Wed Jun 23 13:29:04 2004
Subject: [Common-dev] CR-Client: Moving IHXSourceBufferingStats2
	implementation [Take 2]
In-Reply-To: <5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>
References: <5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>
Message-ID: <20040623201427.GA8668@real.com>

- I've integrated all of the suggested changes. 

- I also added a new interface called IHXTransportTimeManager that allows you
  to register the IHXTransportTimeSink object. This registration process 
  allows the code to detect whether it will actually be able to get 
  OnTransportTime() calls or not. This allows the code to avoid accumulating
  packet information when it is run on the server/proxy.



Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
          number information can be maintained as well.

Overview: These changes move the IHXSourceBufferingStats2 implementation
          out of HXBufferingState and into a new class called
          HXSourceBufferStats. This was done because the client needs to
          track packet sequence numbers for 3GPP-Rel6 OBSN support.
          There was no good way to get the sequence number information to
          the HXBufferingState class so the IHXSourceBufferingStats2 logic
          was moved to where this information is available.

          Two new interfaces were created.

          IHXTransportTimeSink was created to propagate OnTimeSync() like calls
          to HXSourceBufferStats. The time passed to the OnTransportTime() call
          in this interface MUST NOT have any offsets created by SMIL or live 
          playback. The time should be in the same time frame as the packets 
          coming from the transports. 

          IHXTransportTimeManager was created to allow HXSourceBufferStats to
          notify the core that it wants to receive OnTransportTime() calls.
          This registration process allows HXSourceBufferStats to know if it
          is able to receive OnTransportTime() calls. If the interface is not
          available then it won't keep track of packet data. This prevents
          a "memory leak" when the code is used in an environment where
          OnTransportTime() won't ever get called(ie in the server).
          
          - Created HXSourceBufferStats to contain the base
            IHXSourceBufferingStats2 implementation. This class is
            used by HXFileSource.

          - Created HXNetSourceBufStats which derives from HXSourceBufferStats.
            This class just overloads the GetCurrentBuffering() so that it
            returns the amount of data in the transport buffer. This is
            used by RTSPClientProtocol.

          - Removed IHXSourceBufferingStats2 code from HXSource

          - Removed packet tracking code from HXBufferingState. This
            functionality is implemented by HXSourceBufferStats now

          - Added code to HXSource to provide OnTimeSync() calls to the
            IHXTransportOnTimeSync interface.

          - HXSource now exposes IHXSourceBufferingStats functionality through
            it's m_pSrcBufStats member variable instead of implementing it
            itself. The file and network sources are expected to provide an
            IHXSourceBufferingStats2 interface via a
            HXSource::SetSrcBufStats() call.

          - Added code to HXFileSource to use HXSourceBufferStats

          - Added code to RTSPClientProtocol to use HXNetSourceBufStats

          - Fixed some code in CBufferManager that was expecting HXSource
            to implement IHXSourceBufferingStats. This code now QI's for
            IHXSourceBufferingStats and uses that interface.

          - Added code IHXTransportTimeManager implementation to HXSource


Files Modified:
client/core/buffmgr.cpp
client/core/hxbsrc.h
client/core/hxbufstate.cpp
client/core/hxbufstate.h
client/core/hxflsrc.cpp
client/core/hxflsrc.h
client/core/hxntsrc.cpp
client/core/hxntsrc.h
client/core/hxsrc.cpp
client/core/rtspprotocol.cpp
protocol/rtsp/Umakefil
protocol/rtsp/rtspclnt.cpp
protocol/rtsp/pub/rtspclnt.h
common/util/Umakefil
common/include/hxpiids.h


Files Added:
common/include/ihxtranstime.h
common/util/pub/hxsrcbufstats.h
common/util/hxsrcbufstats.cpp
protocol/rtsp/ntsrcbufstats.h
protocol/rtsp/ntsrcbufstats.cpp

Image Size and Heap Use impact:

Platforms and Profiles affected: all

Distribution Libraries affected: rdtclntlib

Distribution library impact and planned action:
Added member variables to RTSPClientProtocol. This will
effect any derived classes

Platforms and Profiles Build Verified: win32

Platforms and Profiles Functionality verified: win32

Branch: HEAD

QA Instructions: none

Index: buffmgr.cpp
===================================================================
RCS file: /cvsroot/client/core/buffmgr.cpp,v
retrieving revision 1.21
diff -u -r1.21 buffmgr.cpp
--- buffmgr.cpp	11 Mar 2004 19:44:10 -0000	1.21
+++ buffmgr.cpp	23 Jun 2004 19:50:10 -0000
@@ -610,6 +610,11 @@
      * - Keep track of the stream with the lowest timestamp and is 
      *   buffering data
      */
+    IHXSourceBufferingStats* pSrcBufStats = NULL;
+    
+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
+                              (void**)&pSrcBufStats);
+
     for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
     {
 	pStreamInfo = (STREAM_INFO*) (*i);
@@ -619,12 +624,15 @@
 	ULONG32 ulNumBytesAtTransport = 0;
 	BOOL bDoneAtTransport = FALSE;
 
-	m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
-				       llLowestTimestampAtTransport,
-				       llHighestTimestampAtTransport,
-				       ulNumBytesAtTransport,
-				       bDoneAtTransport);
-
+        if (pSrcBufStats)
+        {
+            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, 
+                                              llLowestTimestampAtTransport,
+                                              llHighestTimestampAtTransport,
+                                              ulNumBytesAtTransport,
+                                              bDoneAtTransport);
+        }
+            
 	pStreamInfo->BufferingState().UpdateTransportStats(
 	    llLowestTimestampAtTransport,
 	    llHighestTimestampAtTransport,
@@ -658,6 +666,7 @@
 
 	}
     }
+    HX_RELEASE(pSrcBufStats);
 
     /* If none of the streams have any data buffered at the transport layer,
      * return.
Index: hxbsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxbsrc.h,v
retrieving revision 1.18.2.1
diff -u -r1.18.2.1 hxbsrc.h
--- hxbsrc.h	15 Jun 2004 16:26:43 -0000	1.18.2.1
+++ hxbsrc.h	23 Jun 2004 19:50:10 -0000
@@ -60,6 +60,7 @@
 #include "recordctl.h"
 #include "hxcore.h"
 #include "ihxrateadaptctl.h"
+#include "ihxtranstime.h"
 
 // need to go in hxresult.h
 #define HX_INVALID_HEADER			HXR_INVALID_PARAMETER
@@ -234,11 +235,11 @@
 		  public IHXBackChannel,
 		  public IHXASMSource,
                   public IHXClientRateAdaptControl,
+                  public IHXTransportTimeManager
 #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
-		  public IHXHyperNavigate,
-		  public IHXHyperNavigate2,
+		  , public IHXHyperNavigate,
+		  public IHXHyperNavigate2
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
-                  public IHXSourceBufferingStats2
 {
 protected:
     LONG32			m_lRefCount;
@@ -487,35 +488,6 @@
 			    IHXValues* pParams);
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
 
-    /************************************************************************
-     *	Method:
-     *	    IHXSourceBufferingStats2::GetCurrentBuffering
-     *	Purpose:
-     *	    Get the current buffering information
-     */
-
-    STDMETHOD(GetCurrentBuffering) (THIS_ 
-                                    UINT16  uStreamNumber,
-                                    REF(INT64)  llLowestTimestamp, 
-                                    REF(INT64)  llHighestTimestamp,
-                                    REF(UINT32) ulNumBytes,
-                                    REF(BOOL)   bDone) PURE;
-    /************************************************************************
-     *	Method:
-     *	    IHXSourceBufferingStats2::GetTotalBuffering
-     *	Purpose:
-     *	    Get the total amount of data buffered for a stream.
-     *      This includes what is in the transport buffer and in
-     *      the renderer
-     */
-    
-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
-				   REF(INT64)  llLowestTimestamp, 
-				   REF(INT64)  llHighestTimestamp,
-				   REF(UINT32) ulNumBytes,
-				   REF(BOOL)   bDone);
-
-
     /*
      * IHXClientRateAdaptControl Methods
      */
@@ -548,6 +520,12 @@
     STDMETHOD(IsEnabled) (THIS_ UINT16 uStreamNum,
                           REF(BOOL) bEnabled);
 
+    /*
+     * IHXTransportTimeManager methods
+     */
+    STDMETHOD(AddSink) (THIS_ IHXTransportTimeSink* pSink);
+    STDMETHOD(RemoveSink) (THIS_ IHXTransportTimeSink* pSink);
+
     HX_RESULT		Init(HXPlayer * player, UINT32 unRegistryID);
     HX_RESULT		SetupRegistry(void);
     virtual HX_RESULT	UpdateRegistry(UINT32 ulRegistryID) = 0;
@@ -731,7 +709,7 @@
 	    virtual HX_RESULT	FillRecordControl() = 0;
 		    BOOL	IsPlayingFromRecordControl() { return m_bPlayFromRecordControl; };
 
-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
 
             const char*         GetRedirectURL() { return (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
             const char*         GetSDPURL() { return (m_pSDPURL ? m_pSDPURL->GetURL() : NULL); };
@@ -769,6 +747,8 @@
             void        ProcessFileHeader(void);
             HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, STREAM_INFO*& pStreamInfo);
 
+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
+
     HX_RESULT			mLastError;
     CHXMapLongToObj*            mStreamInfoTable;
     
@@ -868,6 +848,8 @@
     CHXURL*                     m_pRedirectURL;
     CHXURL*                     m_pSDPURL;
     BOOL                        m_bRedirectPending;
+    IHXTransportTimeSink*       m_pTransportTimeSink;
+    IHXSourceBufferingStats2*   m_pSrcBufStats;
 };
 
 // Defined flags
Index: hxbufstate.cpp
===================================================================
RCS file: /cvsroot/client/core/hxbufstate.cpp,v
retrieving revision 1.7
diff -u -r1.7 hxbufstate.cpp
--- hxbufstate.cpp	9 Mar 2004 19:51:11 -0000	1.7
+++ hxbufstate.cpp	23 Jun 2004 19:50:10 -0000
@@ -83,18 +83,11 @@
     , m_ulLastPacketTimeStamp(0)
     , m_ulAvgBandwidth(0)
     , m_pASMProps(NULL)
-    , m_llCurrentPlaybackTime(0)
-    , m_ulBufferedData(0)
-    , m_ulLastTimeSync(0)
-    , m_llFirstLivePacketTimestamp(0)
-    , m_ulTimeSyncRollOver(0)
 {}
 
 HXBufferingState::~HXBufferingState()
 {
     HX_RELEASE(m_pASMProps);
-
-    ClearPktInfo();
 }
 
 void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
@@ -179,8 +172,6 @@
     m_ulLastPacketTimeStamp = 0;
     m_bIsFirstPacket = TRUE;
 
-    ClearPktInfo();
-
     if (bIsSeeking)
     {
 	m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
@@ -288,11 +279,6 @@
     return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
 }
 
-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
-{
-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;
-}
-
 void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
 				UINT32 ulElapsedTime,
 				BOOL bIsLive, BOOL bIsBufferedPlayMode)
@@ -318,16 +304,12 @@
 	if (bIsLive)
 	{
 	    m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
         }
 
 	m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
 	m_bIsFirstPacket = FALSE;
     }
 
-    // Add this packet to our packet info statistics
-    AddPktInfo(llActualTimeStamp, ulPacketSize);
-
     // data based preroll
     if (DataBasedPreroll())
     {
@@ -451,47 +433,6 @@
     m_bDoneAtTransport = bDoneAtTransport;
 }
 
-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp, 
-					      REF(INT64) llHighTimestamp,
-					      REF(UINT32) ulBytesBuffered,
-					      BOOL bUseTransportStats)
-{
-    HX_RESULT res = HXR_NO_DATA;
-
-    if (!m_bIsFirstPacket)
-    {
-	if (!m_pktInfo.IsEmpty())
-	{
-	    HXBufferedPktInfo* pPktInfo = 
-		(HXBufferedPktInfo*)m_pktInfo.GetHead();
-
-	    llLowTimestamp = pPktInfo->Timestamp();
-	}
-	else
-	{
-	    llLowTimestamp = m_llHighestTimeStamp;
-	}
-
-	llHighTimestamp = m_llHighestTimeStamp;
-	ulBytesBuffered = GetBufferedData();
-	
-
-	if (bUseTransportStats)
-	{
-	    if (m_llHighestTimestampAtTransport > llHighTimestamp)
-	    {
-		llHighTimestamp = m_llHighestTimestampAtTransport;
-	    }
-
-	    ulBytesBuffered += m_ulNumBytesAtTransport;
-	}
-
-	res = HXR_OK;
-    }
-
-    return res;
-}
-
 void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
 					   INT64 llTheHighestTS,
 					   BOOL bIsSeekPerformed,
@@ -569,19 +510,6 @@
 
 }
 
-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
-{
-    //  0xFA .. 0xFF [roll over] (0x01)
-    if (m_ulLastTimeSync > ulCurrentTime &&
-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
-    {
-       m_ulTimeSyncRollOver++;
-    }
-    m_ulLastTimeSync = ulCurrentTime;
-
-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
-}
-
 void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs, 
 					 ULONG32 ulMinBufferingInMs)
 {
@@ -771,62 +699,4 @@
     {
 	m_ulAvgBandwidth = ulBandwidth;
     }
-}
-
-void HXBufferingState::ClearPktInfo()
-{
-    m_ulBufferedData = 0;
-    while(!m_pktInfo.IsEmpty())
-    {
-	HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
-	delete pInfo;
-    }
-}
-
-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
-{
-    // Subtract off the first live packet timestamp.
-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
-    llTimestamp -= m_llFirstLivePacketTimestamp;
-    // Create the HXBufferedPktInfo class
-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp, 
-							ulPacketSize);
-    if (pPktInfo)
-    {
-	m_pktInfo.AddTail(pPktInfo);
-	m_ulBufferedData += ulPacketSize;
-    }
-
-    // purge the old packet info data
-    //  this keeps the list short and prevents the Symbian
-    //  allocator from freaking out
-    (void)GetBufferedData();
-}
-
-UINT32 HXBufferingState::GetBufferedData()
-{
-    BOOL bDone = m_pktInfo.IsEmpty();
-    
-    // Remove all packet info that is past due
-    // and subtract their sizes from our buffering total
-    while(!bDone)
-    {
-	HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
-	
-	if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
-	{
-	    m_ulBufferedData -= pPktInfo->Size();
-	    
-	    m_pktInfo.RemoveHead();
-	    delete pPktInfo;
-	    
-	    bDone = m_pktInfo.IsEmpty();
-	}
-	else
-	{
-	    bDone = TRUE;
-	}
-    }
-
-    return m_ulBufferedData;
 }
Index: hxbufstate.h
===================================================================
RCS file: /cvsroot/client/core/hxbufstate.h,v
retrieving revision 1.4
diff -u -r1.4 hxbufstate.h
--- hxbufstate.h	19 May 2004 19:37:33 -0000	1.4
+++ hxbufstate.h	23 Jun 2004 19:50:10 -0000
@@ -81,7 +81,6 @@
     BOOL HasPredata(BOOL bIsSeekPerformed);
 
     INT64 CreateINT64Timestamp(UINT32 ulTime);
-    INT64 CreateINT64Timesync(UINT32 ulTime);
 
     void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize, 
 		  UINT32 ulElapsedTime, BOOL bIsLive,
@@ -98,11 +97,6 @@
 			      ULONG32 ulBytesAtTransport,
 			      BOOL bDoneAtTransport);
 
-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp, 
-				REF(INT64) llHighTimestamp,
-				REF(UINT32) ulBytesBuffered,
-				BOOL bUseTransportStats);
-
     void GetExcessBufferInfo(INT64 llTheLowestTS,
 			     INT64 llTheHighestTS,
 			     BOOL bIsSeekPerformed,
@@ -119,8 +113,6 @@
 
     UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
 
-    void OnTimeSync(UINT32 ulCurrentTime);
-
     // Should remove
     void SetAvgBWToASMBw();
     BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
@@ -149,19 +141,6 @@
 			 UINT32 ulCurrentBuffering,
 			 UINT32 ulMinimumPreroll,
 			 UINT32 ulDenom) const;
-    
-    /* Functions for tracking the amount of data
-     * buffered in the renderer
-     */
-    void ClearPktInfo(); /* Clears out information about buffered packets */
-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
-							      * a packet is 
-							      * sent to the
-							      * renderer 
-							      */
-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
-			       * in the renderer
-			       */
 
     ULONG32		m_ulPreroll;
     ULONG32		m_ulPredata;
@@ -196,20 +175,6 @@
     ULONG32		m_ulLastPacketTimeStamp;
     ULONG32		m_ulAvgBandwidth;
     IHXASMProps*	m_pASMProps;
-    UINT32              m_ulLastTimeSync;
-    INT64               m_llFirstLivePacketTimestamp;
-    UINT32              m_ulTimeSyncRollOver;    
-    // These variable keep track of the amount of
-    // data buffered in the renderer
-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
-						  * OnTimeSync() call
-						  */
-
-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
-					   * Always use GetBufferedData()
-					   * to retreive the value
-					   */
-    CHXSimpleList       m_pktInfo; /* List of packet information */
 };
 
 inline
Index: hxflsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxflsrc.cpp,v
retrieving revision 1.54
diff -u -r1.54 hxflsrc.cpp
--- hxflsrc.cpp	19 May 2004 19:37:33 -0000	1.54
+++ hxflsrc.cpp	23 Jun 2004 19:50:10 -0000
@@ -76,6 +76,7 @@
 #include "uri_schemes.h"
 #include "stream_desc_hlpr.h"
 #include "findfile.h"
+#include "hxsrcbufstats.h"
 
 #include "hxheap.h"
 #ifdef _DEBUG
@@ -115,6 +116,7 @@
     , m_bValidateMetaDone(FALSE)
     , m_pFileRecognizer(NULL)
     , m_pFileReader(NULL)
+    , m_pHXSrcBufStats(NULL)
 {
     m_bAltURL = FALSE;
     m_bPerfectPlay = TRUE;
@@ -306,6 +308,18 @@
 
     HX_VECTOR_DELETE(m_pszURL);
     HX_DELETE(m_pURL);
+    
+    HX_RELEASE(m_pHXSrcBufStats);
+    m_pHXSrcBufStats = new HXSourceBufferStats();
+    if (m_pHXSrcBufStats)
+    {
+        m_pHXSrcBufStats->AddRef();
+
+        if (HXR_OK != m_pHXSrcBufStats->Init((IUnknown*)(IHXStreamSource*)this))
+        {
+            HX_RELEASE(m_pHXSrcBufStats);
+        }
+    }
 
     if (!theErr && pURL)
     {
@@ -938,6 +952,7 @@
     }
 #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
 
+    HX_RELEASE(m_pHXSrcBufStats);
     HXSource::DoCleanup();
 
     return HXR_OK;
@@ -1068,6 +1083,11 @@
 
     m_llLastFillEndTime = 0;   
 
+    if (m_pHXSrcBufStats)
+    {
+        m_pHXSrcBufStats->Reset();
+    }
+
 cleanup:
 
     return HXR_OK;
@@ -1442,6 +1462,11 @@
 
 	    if(m_pBufferManager)
 		m_pBufferManager->UpdateCounters(pPacket, 0);
+            
+            if (m_pHXSrcBufStats && !pPacket->IsLost())
+            {
+                m_pHXSrcBufStats->OnPacket(pPacket);
+            }
 
 	    HX_RELEASE(pPacket);
 	}
@@ -2103,6 +2128,13 @@
 	}
 	HX_RELEASE(pszParentName);
 #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
+
+        if (pStreamInfo && m_pHXSrcBufStats)
+        {
+            m_pHXSrcBufStats->InitStream(pStreamInfo->m_uStreamNumber,
+                                         mLiveStream);
+        }
+
         m_ulStreamIndex++;
         m_uNumStreams++;
     }
@@ -2115,6 +2147,11 @@
 
 	theErr = AdjustClipTime();
 	m_pBufferManager->Init();
+
+        if (m_pHXSrcBufStats)
+        {
+            SetSrcBufStats(m_pHXSrcBufStats);
+        }
     }
 
     return theErr;
@@ -2313,6 +2350,11 @@
 	{
 	    m_pBufferManager->UpdateCounters(pPacket, 0);
 	}
+
+        if (m_pHXSrcBufStats && !pPacket->IsLost())
+        {
+            m_pHXSrcBufStats->OnPacket(pPacket);
+        }
     }
 
     m_llLastFillEndTime = llActualPacketTime;
Index: hxflsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxflsrc.h,v
retrieving revision 1.12
diff -u -r1.12 hxflsrc.h
--- hxflsrc.h	3 May 2004 18:59:30 -0000	1.12
+++ hxflsrc.h	23 Jun 2004 19:50:10 -0000
@@ -52,6 +52,8 @@
 #include "hxfiles.h"
 #include "recognizer.h"
 
+class HXSourceBufferStats;
+
 class HXFileSource : public HXSource, 
 		      public IHXFormatResponse,
                       public IHXHTTPRedirectResponse
@@ -349,6 +351,7 @@
 
     CFileReader*                m_pFileReader;
     CHXFileRecognizer*          m_pFileRecognizer;
+    HXSourceBufferStats*        m_pHXSrcBufStats;
 };
 
 #endif // _HX_FILE_SOURCE
Index: hxntsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxntsrc.cpp,v
retrieving revision 1.90
diff -u -r1.90 hxntsrc.cpp
--- hxntsrc.cpp	19 May 2004 19:37:33 -0000	1.90
+++ hxntsrc.cpp	23 Jun 2004 19:50:10 -0000
@@ -675,6 +675,7 @@
     HX_RESULT   rc = HXR_OK;
     BOOL        bSDPInitiated = FALSE;
     CHXString   pString;
+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
 
     // start off with the preferred protocol
     rc = CreateProtocol();
@@ -722,6 +723,14 @@
         goto cleanup;
     }
 
+    // Setup source buffer stats 
+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
+                                           (void**)&pSrcBufStats))
+    {
+        SetSrcBufStats(pSrcBufStats);
+        HX_RELEASE(pSrcBufStats);
+    }
+
     // create log info list
     m_pLogInfoList = new CHXSimpleList;
     m_ulLogInfoLength = 0;
@@ -6295,6 +6304,12 @@
 #else
     return HXR_NOTIMPL;
 #endif /* HELIX_FEATURE_RECORDCONTROL */
+}
+
+HX_RESULT 
+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
+{
+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
 }
 
 ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
Index: hxntsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxntsrc.h,v
retrieving revision 1.24
diff -u -r1.24 hxntsrc.h
--- hxntsrc.h	3 May 2004 18:59:30 -0000	1.24
+++ hxntsrc.h	23 Jun 2004 19:50:10 -0000
@@ -282,6 +282,7 @@
 
 	virtual HX_RESULT	FillRecordControl();
 
+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
 protected:
 
 	virtual 			~HXNetSource(void);
@@ -470,7 +471,6 @@
 private:
         IHXBufferControl*                m_pBufferCtl;
         IHXWatermarkBufferControl*       m_pWMBufferCtl;
-
 public:
 	HX_RESULT	FinishSetup();
 	void		ReSetup();
Index: hxsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxsrc.cpp,v
retrieving revision 1.44.2.1
diff -u -r1.44.2.1 hxsrc.cpp
--- hxsrc.cpp	15 Jun 2004 16:26:43 -0000	1.44.2.1
+++ hxsrc.cpp	23 Jun 2004 19:50:10 -0000
@@ -213,6 +213,8 @@
         , m_pRedirectURL(NULL)
         , m_pSDPURL(NULL)
         , m_bRedirectPending(FALSE)
+        , m_pTransportTimeSink(NULL)
+        , m_pSrcBufStats(NULL)
 {
     mStreamInfoTable = new CHXMapLongToObj;
 }
@@ -313,6 +315,8 @@
     HX_DELETE(m_pRedirectURL);
     HX_DELETE(m_pSDPURL);
     m_bRedirectPending  = FALSE;
+    HX_RELEASE(m_pTransportTimeSink);
+    HX_RELEASE(m_pSrcBufStats);
 
 #if defined(HELIX_FEATURE_RECORDCONTROL)
     if(m_pRecordControl)
@@ -340,8 +344,6 @@
             { GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*)this },
             { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
             { GET_IIDHANDLE(IID_IHXPrivateStreamSource), (IHXPrivateStreamSource*)this },
-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*)this },
-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*)this },
             { GET_IIDHANDLE(IID_IHXClientRateAdaptControl), 
               (IHXClientRateAdaptControl*)this },
 #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
@@ -349,6 +351,7 @@
             { GET_IIDHANDLE(IID_IHXHyperNavigate2), (IHXHyperNavigate2*)this },
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXStreamSource*)this },
+            { GET_IIDHANDLE(IID_IHXTransportTimeManager), (IHXTransportTimeManager*)this}
         };
     
     HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
@@ -388,6 +391,14 @@
 	    return HXR_NOINTERFACE;
 	}
     }
+    else if (m_pSrcBufStats &&
+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
+    {
+        m_pSrcBufStats->AddRef();
+        *ppvObj = m_pSrcBufStats;
+        return HXR_OK;
+    }
 
 #if defined(HELIX_FEATURE_AUTOUPGRADE)
     else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
@@ -2250,59 +2261,6 @@
 }
 #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
 
-STDMETHODIMP
-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
-			    REF(INT64)  llLowestTimestamp, 
-			    REF(INT64)  llHighestTimestamp,
-			    REF(UINT32) ulNumBytes,
-			    REF(BOOL)   bDone)
-{
-    HX_RESULT res = HXR_NO_DATA;
-    
-    llLowestTimestamp = 0;
-    llHighestTimestamp = 0;
-    ulNumBytes = 0;
-    bDone = FALSE;
-
-    STREAM_INFO* pStreamInfo;
-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
-    {
-	HXBufferingState& bufState = pStreamInfo->BufferingState();
-	BOOL   bUseTransportStats = FALSE;
-
-	INT64  llTransportLowTS = 0;
-	INT64  llTransportHighTS = 0;
-	UINT32 ulTransportBytes = 0;
-	BOOL   bTransportDone = FALSE;
-
-	if (!IsLocalSource() &&
-	    (HXR_OK == GetCurrentBuffering(uStreamNumber,
-					   llTransportLowTS,
-					   llTransportHighTS,
-					   ulTransportBytes,
-					   bTransportDone)))
-	{
-	    bufState.UpdateTransportStats(llTransportLowTS,
-					  llTransportHighTS,
-					  ulTransportBytes,
-					  bTransportDone);
-
-	    bUseTransportStats = TRUE;
-
-	    // Update bDone with what the transport says.
-	    bDone = bTransportDone;
-	}
-
-	res = bufState.GetBufferingStats(llLowestTimestamp,
-					 llHighestTimestamp,
-					 ulNumBytes,
-					 bUseTransportStats);
-    }
-
-
-    return res;
-}
-
 /*
  * IHXClientRateAdaptControl Methods
  */
@@ -2444,6 +2402,40 @@
     return res;
 }
 
+/*
+ * IHXTransportTimeManager methods
+ */
+STDMETHODIMP
+HXSource::AddSink(THIS_ IHXTransportTimeSink* pSink)
+{
+    HX_RESULT res = HXR_FAILED;
+
+    // Currently we only support one transport time sink
+    if (pSink && !m_pTransportTimeSink)
+    {
+        m_pTransportTimeSink = pSink;
+        m_pTransportTimeSink->AddRef();
+
+        res = HXR_OK;
+    }
+
+    return res;
+}
+
+STDMETHODIMP
+HXSource::RemoveSink(THIS_ IHXTransportTimeSink* pSink)
+{
+    HX_RESULT res = HXR_FAILED;
+
+    if (pSink && (pSink == m_pTransportTimeSink))
+    {
+        HX_RELEASE(m_pTransportTimeSink);
+        res = HXR_OK;
+    }
+
+    return res;
+}
+
 /* 
  * All relative URLs are converted to absolute URLs unless the 
  * original request (ram/smil) passed in OpenRequest/OpenURL()
@@ -2948,13 +2940,31 @@
 {
     HX_RESULT res = HXR_OK;
 
-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
-         i != mStreamInfoTable->End(); ++i) 
-    {    
-	STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
-
-	pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
+    // Convert presentation time to transport time
+    if (m_pTransportTimeSink)
+    {
+        ULONG32 ulOffset = m_ulDelay;
+        ULONG32 ulTransportTime = m_ulStartTime;
+        
+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
+        {
+            ulTransportTime += ulCurrentTime - ulOffset;
+        }
+    
+        res = m_pTransportTimeSink->OnTransportTime(ulTransportTime);
     }
 
     return res;
+}
+
+void 
+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
+{
+    HX_RELEASE(m_pSrcBufStats);
+
+    if (pSrcBufStats)
+    {
+        m_pSrcBufStats = pSrcBufStats;
+        m_pSrcBufStats->AddRef();
+    }
 }
Index: rtspprotocol.cpp
===================================================================
RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
retrieving revision 1.39
diff -u -r1.39 rtspprotocol.cpp
--- rtspprotocol.cpp	11 May 2004 00:55:19 -0000	1.39
+++ rtspprotocol.cpp	23 Jun 2004 19:50:10 -0000
@@ -2626,12 +2626,12 @@
     UINT16 seekFrom
 )
 {
+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
+
     if (IsLive())
     {
-        return m_pProtocolLib->SeekFlush();
+        return theErr;
     }
-
-    HX_RESULT theErr = HXR_OK;
 
     m_uCurrentStreamCount = m_uStreamCount;
 
Index: Umakefil
===================================================================
RCS file: /cvsroot/protocol/rtsp/Umakefil,v
retrieving revision 1.9.2.1
diff -u -r1.9.2.1 Umakefil
--- Umakefil	16 Jun 2004 18:44:01 -0000	1.9.2.1
+++ Umakefil	23 Jun 2004 19:50:17 -0000
@@ -46,6 +46,7 @@
 			  'common/runtime/pub',
 			  'common/lang/xml/pub',
 			  'client/common/container/pub',
+                          'client/common/util/pub',
 			  'protocol/transport/rtp/include',
 		          'server/include',	
                           'server/common/struct/pub',
@@ -65,7 +66,7 @@
 		   'rtspmsg.cpp', 'rtspmdsc.cpp',
 		   'rtsppars.cpp', 'mhprop.cpp',
 		   'servrsnd.cpp', '3gpadapthdr.cpp',
-                   'rateadaptinfo.cpp')
+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
 
 if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
     project.AddSources('pipelinedesc.cpp')
Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.79.2.1
diff -u -r1.79.2.1 rtspclnt.cpp
--- rtspclnt.cpp	17 Jun 2004 04:32:09 -0000	1.79.2.1
+++ rtspclnt.cpp	23 Jun 2004 19:50:17 -0000
@@ -95,6 +95,7 @@
 #include "pipelinedesc.h"
 #include "errdbg.h"
 #include "rateadaptinfo.h"
+#include "ntsrcbufstats.h"
 
 #include "hxheap.h"
 #ifdef _DEBUG
@@ -302,6 +303,12 @@
     {
         return HXR_OK;
     }
+    else if (m_pSrcBufStats &&
+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
+                                                       ppvObj)))
+    {
+        return HXR_OK;
+    }
     *ppvObj = NULL;
     return HXR_NOINTERFACE;
 }
@@ -388,6 +395,7 @@
     m_bReportedSuccessfulTransport(FALSE),
     m_bSDPInitiated(FALSE),
     m_bMulticast(FALSE),
+    m_bIsLive(FALSE),
     m_pSDPFileHeader(NULL),
     m_pSDPStreamHeaders(NULL),
     m_bSessionSucceeded(FALSE),
@@ -404,7 +412,8 @@
     m_ulCurrentTimeOut(0),
     m_pUAProfURI(NULL),
     m_pUAProfDiff(NULL),
-    m_pRateAdaptInfo(NULL)
+    m_pRateAdaptInfo(NULL),
+    m_pSrcBufStats(NULL)
 #if defined(_MACINTOSH)
     , m_pCallback(NULL)
 #endif /* _MACINTOSH */
@@ -810,6 +819,26 @@
         }
     }
 
+    if (HXR_OK == hresult)
+    {
+        HX_RELEASE(m_pSrcBufStats);
+        m_pSrcBufStats = new HXNetSourceBufStats(this);
+        
+        if (m_pSrcBufStats)
+        {
+            m_pSrcBufStats->AddRef();
+
+            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
+            {
+                HX_RELEASE(m_pSrcBufStats);
+            }
+        }
+        else
+        {
+            hresult = HXR_OUTOFMEMORY;
+        }
+    }
+
 #if defined(_MACINTOSH)
     if (m_pCallback &&
         m_pCallback->m_bIsCallbackPending &&
@@ -2191,7 +2220,14 @@
         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
     if (pTrans)
     {
-        rc = pTrans->getPacket(uStreamNumber, pPacket);
+        UINT32 uSeqNum;
+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
+
+        if ((HXR_OK == rc) && m_pSrcBufStats &&
+            (!pPacket->IsLost()))
+        {
+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
+        }
     }
 
     m_pMutex->Unlock();
@@ -3291,16 +3327,24 @@
     HX_RESULT rc = HXR_OK;
     m_pMutex->Lock();
 
-    CHXMapLongToObj::Iterator i;
-    for(i=m_pTransportStreamMap->Begin();
-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
+    if (m_bIsLive)
     {
-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
-        UINT16 streamNumber = (UINT16)i.get_key();
-
-        HX_ASSERT(pTransport);
+        CHXMapLongToObj::Iterator i;
+        for(i=m_pTransportStreamMap->Begin();
+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
+        {
+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
+            UINT16 streamNumber = (UINT16)i.get_key();
+            
+            HX_ASSERT(pTransport);
+            
+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
+        }
+    }
 
-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
+    if (m_pSrcBufStats)
+    {
+        m_pSrcBufStats->Reset();
     }
 
     m_pMutex->Unlock();
@@ -5811,6 +5855,13 @@
 
     HX_RELEASE(m_pTimeoutCallback);
     HX_DELETE(m_pSessionTimeout);
+
+    if (m_pSrcBufStats)
+    {
+        m_pSrcBufStats->Close();
+        
+        HX_RELEASE(m_pSrcBufStats);
+    }
 }
 
 void
@@ -6964,6 +7015,11 @@
         // Get session level RTP bandwidth modifiers
         ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
         ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
+        
+        if (ulIsSessionLive)
+        {
+            m_bIsLive = TRUE;
+        }
 
         // get multicast address from the session description
         if (HXR_OK == ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
@@ -7187,6 +7243,12 @@
             pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
             pInfo->m_bRealMedia = bRealMedia;
 
+            if (m_pSrcBufStats)
+            {
+                m_pSrcBufStats->InitStream((UINT16)streamNumber, 
+                                           pInfo->m_bIsLive);
+            }
+
             if (m_pRateAdaptInfo)
             {
                 m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
@@ -7222,6 +7284,7 @@
         if (m_bMulticast)
         {
             m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
+            m_bIsLive = TRUE;
         }
     }
 
Index: pub/rtspclnt.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.30.2.1
diff -u -r1.30.2.1 rtspclnt.h
--- pub/rtspclnt.h	17 Jun 2004 04:32:09 -0000	1.30.2.1
+++ pub/rtspclnt.h	23 Jun 2004 19:50:17 -0000
@@ -46,6 +46,7 @@
 #include "hxbufctl.h" // IHXTransportBufferLimit
 #include "hxrtsp2.h"
 #include "hxrsdbf.h" // IHXResendBufferControl
+#include "hxprefs.h" // IHXPreferences
 
 class RTSPClientState;
 class RTSPOptionsMessage;
@@ -63,6 +64,7 @@
 class MIMEHeader;
 class PipelinedDescribeLogic;
 class CHXRateAdaptationInfo;
+class HXNetSourceBufStats;
 
 struct IHXKeyValueList;
 struct IHXValues;
@@ -1039,6 +1041,7 @@
     
     BOOL                                m_bSDPInitiated;
     BOOL                                m_bMulticast;
+    BOOL                                m_bIsLive;
     IHXValues*                          m_pSDPFileHeader;
     CHXSimpleList*                      m_pSDPStreamHeaders;
 
@@ -1074,6 +1077,7 @@
     UINT32                              m_ulServerTimeOut;
     UINT32                              m_ulCurrentTimeOut;
     CHXRateAdaptationInfo*              m_pRateAdaptInfo;
+    HXNetSourceBufStats*                m_pSrcBufStats;
 
 #if defined(_MACINTOSH)
     RTSPClientProtocolCallback*		m_pCallback;

Index: Umakefil
===================================================================
RCS file: /cvsroot/common/util/Umakefil,v
retrieving revision 1.20
diff -u -r1.20 Umakefil
--- Umakefil	16 Mar 2004 23:01:44 -0000	1.20
+++ Umakefil	23 Jun 2004 19:50:31 -0000
@@ -109,7 +109,8 @@
                    "hxprefutil.cpp",
                    "stream_desc_hlpr.cpp",
                    "hxcbobj.cpp",
-                   "clone_values.cpp")
+                   "clone_values.cpp",
+                   "hxsrcbufstats.cpp")
 
 project.AddSources("tconverter/fxpoint/tconverter_fxp.cpp")
     
? ihxtranstime.h
Index: hxpiids.h
===================================================================
RCS file: /cvsroot/common/include/hxpiids.h,v
retrieving revision 1.28.2.1
diff -u -r1.28.2.1 hxpiids.h
--- hxpiids.h	15 Jun 2004 16:38:55 -0000	1.28.2.1
+++ hxpiids.h	23 Jun 2004 19:50:44 -0000
@@ -998,5 +998,17 @@
 DEFINE_GUID_ENUM(IID_IHXClientRateAdaptControl, 0x44f5ac8c, 0x654c, 0x414e, 0x9d, 
                  0x18, 0xe7, 0xa4, 0x80, 0x90, 0x70, 0x9)
 
+/* File:
+ *      ihxtranstime.h
+ *
+ * Description:
+ *      Transport time interfaces
+ */
+DEFINE_GUID_ENUM(IID_IHXTransportTimeSink, 
+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
+
+DEFINE_GUID_ENUM(IID_IHXTransportTimeManager, 
+0xd0a5ba01, 0xedfb, 0x4741, 0xb7, 0x9, 0x88, 0x4e, 0x68, 0x5d, 0x2d, 0x8)
+
 #endif /* _HXPRIVATEIIDS_H_ */

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ihxtranstime.h
Type: text/x-chdr
Size: 3837 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040623/f448f9dd/ihxtranstime-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hxsrcbufstats.h
Type: text/x-chdr
Size: 3571 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040623/f448f9dd/hxsrcbufstats-0002.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hxsrcbufstats.cpp
Type: text/x-c++src
Size: 14658 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040623/f448f9dd/hxsrcbufstats-0003.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ntsrcbufstats.h
Type: text/x-chdr
Size: 2513 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040623/f448f9dd/ntsrcbufstats-0002.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ntsrcbufstats.cpp
Type: text/x-c++src
Size: 3373 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040623/f448f9dd/ntsrcbufstats-0003.bin
From ping at real.com  Wed Jun 23 14:11:35 2004
From: ping at real.com (Henry Ping)
Date: Wed Jun 23 14:12:01 2004
Subject: [Common-dev] Re: [Protocol-dev] CR-Client: Moving
 IHXSourceBufferingStats2 implementation [Take 2]
In-Reply-To: <20040623201427.GA8668@real.com>
References: <5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>
Message-ID: <5.1.0.14.2.20040623141120.03a77740@mailone.real.com>

looks good to me

-->Henry

At 01:14 PM 6/23/2004 -0700, Aaron Colwell wrote:
>- I've integrated all of the suggested changes.
>
>- I also added a new interface called IHXTransportTimeManager that allows you
>   to register the IHXTransportTimeSink object. This registration process
>   allows the code to detect whether it will actually be able to get
>   OnTransportTime() calls or not. This allows the code to avoid accumulating
>   packet information when it is run on the server/proxy.
>
>
>
>Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
>           number information can be maintained as well.
>
>Overview: These changes move the IHXSourceBufferingStats2 implementation
>           out of HXBufferingState and into a new class called
>           HXSourceBufferStats. This was done because the client needs to
>           track packet sequence numbers for 3GPP-Rel6 OBSN support.
>           There was no good way to get the sequence number information to
>           the HXBufferingState class so the IHXSourceBufferingStats2 logic
>           was moved to where this information is available.
>
>           Two new interfaces were created.
>
>           IHXTransportTimeSink was created to propagate OnTimeSync() like 
> calls
>           to HXSourceBufferStats. The time passed to the 
> OnTransportTime() call
>           in this interface MUST NOT have any offsets created by SMIL or 
> live
>           playback. The time should be in the same time frame as the packets
>           coming from the transports.
>
>           IHXTransportTimeManager was created to allow HXSourceBufferStats to
>           notify the core that it wants to receive OnTransportTime() calls.
>           This registration process allows HXSourceBufferStats to know if it
>           is able to receive OnTransportTime() calls. If the interface is not
>           available then it won't keep track of packet data. This prevents
>           a "memory leak" when the code is used in an environment where
>           OnTransportTime() won't ever get called(ie in the server).
>
>           - Created HXSourceBufferStats to contain the base
>             IHXSourceBufferingStats2 implementation. This class is
>             used by HXFileSource.
>
>           - Created HXNetSourceBufStats which derives from 
> HXSourceBufferStats.
>             This class just overloads the GetCurrentBuffering() so that it
>             returns the amount of data in the transport buffer. This is
>             used by RTSPClientProtocol.
>
>           - Removed IHXSourceBufferingStats2 code from HXSource
>
>           - Removed packet tracking code from HXBufferingState. This
>             functionality is implemented by HXSourceBufferStats now
>
>           - Added code to HXSource to provide OnTimeSync() calls to the
>             IHXTransportOnTimeSync interface.
>
>           - HXSource now exposes IHXSourceBufferingStats functionality 
> through
>             it's m_pSrcBufStats member variable instead of implementing it
>             itself. The file and network sources are expected to provide an
>             IHXSourceBufferingStats2 interface via a
>             HXSource::SetSrcBufStats() call.
>
>           - Added code to HXFileSource to use HXSourceBufferStats
>
>           - Added code to RTSPClientProtocol to use HXNetSourceBufStats
>
>           - Fixed some code in CBufferManager that was expecting HXSource
>             to implement IHXSourceBufferingStats. This code now QI's for
>             IHXSourceBufferingStats and uses that interface.
>
>           - Added code IHXTransportTimeManager implementation to HXSource
>
>
>Files Modified:
>client/core/buffmgr.cpp
>client/core/hxbsrc.h
>client/core/hxbufstate.cpp
>client/core/hxbufstate.h
>client/core/hxflsrc.cpp
>client/core/hxflsrc.h
>client/core/hxntsrc.cpp
>client/core/hxntsrc.h
>client/core/hxsrc.cpp
>client/core/rtspprotocol.cpp
>protocol/rtsp/Umakefil
>protocol/rtsp/rtspclnt.cpp
>protocol/rtsp/pub/rtspclnt.h
>common/util/Umakefil
>common/include/hxpiids.h
>
>
>Files Added:
>common/include/ihxtranstime.h
>common/util/pub/hxsrcbufstats.h
>common/util/hxsrcbufstats.cpp
>protocol/rtsp/ntsrcbufstats.h
>protocol/rtsp/ntsrcbufstats.cpp
>
>Image Size and Heap Use impact:
>
>Platforms and Profiles affected: all
>
>Distribution Libraries affected: rdtclntlib
>
>Distribution library impact and planned action:
>Added member variables to RTSPClientProtocol. This will
>effect any derived classes
>
>Platforms and Profiles Build Verified: win32
>
>Platforms and Profiles Functionality verified: win32
>
>Branch: HEAD
>
>QA Instructions: none
>
>Index: buffmgr.cpp
>===================================================================
>RCS file: /cvsroot/client/core/buffmgr.cpp,v
>retrieving revision 1.21
>diff -u -r1.21 buffmgr.cpp
>--- buffmgr.cpp 11 Mar 2004 19:44:10 -0000      1.21
>+++ buffmgr.cpp 23 Jun 2004 19:50:10 -0000
>@@ -610,6 +610,11 @@
>       * - Keep track of the stream with the lowest timestamp and is
>       *   buffering data
>       */
>+    IHXSourceBufferingStats* pSrcBufStats = NULL;
>+
>+    m_pParent->QueryInterface(IID_IHXSourceBufferingStats,
>+                              (void**)&pSrcBufStats);
>+
>      for (i = m_pStreamInfoTable->Begin(); i != 
> m_pStreamInfoTable->End(); ++i)
>      {
>         pStreamInfo = (STREAM_INFO*) (*i);
>@@ -619,12 +624,15 @@
>         ULONG32 ulNumBytesAtTransport = 0;
>         BOOL bDoneAtTransport = FALSE;
>
>-       m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
>-                                      llLowestTimestampAtTransport,
>-                                      llHighestTimestampAtTransport,
>-                                      ulNumBytesAtTransport,
>-                                      bDoneAtTransport);
>-
>+        if (pSrcBufStats)
>+        {
>+            pSrcBufStats->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
>+                                              llLowestTimestampAtTransport,
>+                                              llHighestTimestampAtTransport,
>+                                              ulNumBytesAtTransport,
>+                                              bDoneAtTransport);
>+        }
>+
>         pStreamInfo->BufferingState().UpdateTransportStats(
>             llLowestTimestampAtTransport,
>             llHighestTimestampAtTransport,
>@@ -658,6 +666,7 @@
>
>         }
>      }
>+    HX_RELEASE(pSrcBufStats);
>
>      /* If none of the streams have any data buffered at the transport layer,
>       * return.
>Index: hxbsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbsrc.h,v
>retrieving revision 1.18.2.1
>diff -u -r1.18.2.1 hxbsrc.h
>--- hxbsrc.h    15 Jun 2004 16:26:43 -0000      1.18.2.1
>+++ hxbsrc.h    23 Jun 2004 19:50:10 -0000
>@@ -60,6 +60,7 @@
>  #include "recordctl.h"
>  #include "hxcore.h"
>  #include "ihxrateadaptctl.h"
>+#include "ihxtranstime.h"
>
>  // need to go in hxresult.h
>  #define HX_INVALID_HEADER                      HXR_INVALID_PARAMETER
>@@ -234,11 +235,11 @@
>                   public IHXBackChannel,
>                   public IHXASMSource,
>                    public IHXClientRateAdaptControl,
>+                  public IHXTransportTimeManager
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>-                 public IHXHyperNavigate,
>-                 public IHXHyperNavigate2,
>+                 , public IHXHyperNavigate,
>+                 public IHXHyperNavigate2
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>-                  public IHXSourceBufferingStats2
>  {
>  protected:
>      LONG32                     m_lRefCount;
>@@ -487,35 +488,6 @@
>                             IHXValues* pParams);
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>
>-    /************************************************************************
>-     * Method:
>-     *     IHXSourceBufferingStats2::GetCurrentBuffering
>-     * Purpose:
>-     *     Get the current buffering information
>-     */
>-
>-    STDMETHOD(GetCurrentBuffering) (THIS_
>-                                    UINT16  uStreamNumber,
>-                                    REF(INT64)  llLowestTimestamp,
>-                                    REF(INT64)  llHighestTimestamp,
>-                                    REF(UINT32) ulNumBytes,
>-                                    REF(BOOL)   bDone) PURE;
>-    /************************************************************************
>-     * Method:
>-     *     IHXSourceBufferingStats2::GetTotalBuffering
>-     * Purpose:
>-     *     Get the total amount of data buffered for a stream.
>-     *      This includes what is in the transport buffer and in
>-     *      the renderer
>-     */
>-
>-    STDMETHOD(GetTotalBuffering)  (THIS_ UINT16  uStreamNumber,
>-                                  REF(INT64)  llLowestTimestamp,
>-                                  REF(INT64)  llHighestTimestamp,
>-                                  REF(UINT32) ulNumBytes,
>-                                  REF(BOOL)   bDone);
>-
>-
>      /*
>       * IHXClientRateAdaptControl Methods
>       */
>@@ -548,6 +520,12 @@
>      STDMETHOD(IsEnabled) (THIS_ UINT16 uStreamNum,
>                            REF(BOOL) bEnabled);
>
>+    /*
>+     * IHXTransportTimeManager methods
>+     */
>+    STDMETHOD(AddSink) (THIS_ IHXTransportTimeSink* pSink);
>+    STDMETHOD(RemoveSink) (THIS_ IHXTransportTimeSink* pSink);
>+
>      HX_RESULT          Init(HXPlayer * player, UINT32 unRegistryID);
>      HX_RESULT          SetupRegistry(void);
>      virtual HX_RESULT  UpdateRegistry(UINT32 ulRegistryID) = 0;
>@@ -731,7 +709,7 @@
>             virtual HX_RESULT   FillRecordControl() = 0;
>                     BOOL        IsPlayingFromRecordControl() { return 
> m_bPlayFromRecordControl; };
>
>-            HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>+            virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>
>              const char*         GetRedirectURL() { return 
> (m_pRedirectURL ? m_pRedirectURL->GetURL() : NULL); };
>              const char*         GetSDPURL() { return (m_pSDPURL ? 
> m_pSDPURL->GetURL() : NULL); };
>@@ -769,6 +747,8 @@
>              void        ProcessFileHeader(void);
>              HX_RESULT   ProcessStreamHeaders(IHXValues* pHeader, 
> STREAM_INFO*& pStreamInfo);
>
>+    void SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats);
>+
>      HX_RESULT                  mLastError;
>      CHXMapLongToObj*            mStreamInfoTable;
>
>@@ -868,6 +848,8 @@
>      CHXURL*                     m_pRedirectURL;
>      CHXURL*                     m_pSDPURL;
>      BOOL                        m_bRedirectPending;
>+    IHXTransportTimeSink*       m_pTransportTimeSink;
>+    IHXSourceBufferingStats2*   m_pSrcBufStats;
>  };
>
>  // Defined flags
>Index: hxbufstate.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxbufstate.cpp,v
>retrieving revision 1.7
>diff -u -r1.7 hxbufstate.cpp
>--- hxbufstate.cpp      9 Mar 2004 19:51:11 -0000       1.7
>+++ hxbufstate.cpp      23 Jun 2004 19:50:10 -0000
>@@ -83,18 +83,11 @@
>      , m_ulLastPacketTimeStamp(0)
>      , m_ulAvgBandwidth(0)
>      , m_pASMProps(NULL)
>-    , m_llCurrentPlaybackTime(0)
>-    , m_ulBufferedData(0)
>-    , m_ulLastTimeSync(0)
>-    , m_llFirstLivePacketTimestamp(0)
>-    , m_ulTimeSyncRollOver(0)
>  {}
>
>  HXBufferingState::~HXBufferingState()
>  {
>      HX_RELEASE(m_pASMProps);
>-
>-    ClearPktInfo();
>  }
>
>  void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,
>@@ -179,8 +172,6 @@
>      m_ulLastPacketTimeStamp = 0;
>      m_bIsFirstPacket = TRUE;
>
>-    ClearPktInfo();
>-
>      if (bIsSeeking)
>      {
>         m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;
>@@ -288,11 +279,6 @@
>      return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + 
> CAST_TO_INT64 ulTime;
>  }
>
>-INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime)
>-{
>-    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 
>MAX_UINT32 + CAST_TO_INT64 ulTime;
>-}
>-
>  void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>                                 UINT32 ulElapsedTime,
>                                 BOOL bIsLive, BOOL bIsBufferedPlayMode)
>@@ -318,16 +304,12 @@
>         if (bIsLive)
>         {
>             m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;
>-            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;
>          }
>
>         m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;
>         m_bIsFirstPacket = FALSE;
>      }
>
>-    // Add this packet to our packet info statistics
>-    AddPktInfo(llActualTimeStamp, ulPacketSize);
>-
>      // data based preroll
>      if (DataBasedPreroll())
>      {
>@@ -451,47 +433,6 @@
>      m_bDoneAtTransport = bDoneAtTransport;
>  }
>
>-HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp,
>-                                             REF(INT64) llHighTimestamp,
>-                                             REF(UINT32) ulBytesBuffered,
>-                                             BOOL bUseTransportStats)
>-{
>-    HX_RESULT res = HXR_NO_DATA;
>-
>-    if (!m_bIsFirstPacket)
>-    {
>-       if (!m_pktInfo.IsEmpty())
>-       {
>-           HXBufferedPktInfo* pPktInfo =
>-               (HXBufferedPktInfo*)m_pktInfo.GetHead();
>-
>-           llLowTimestamp = pPktInfo->Timestamp();
>-       }
>-       else
>-       {
>-           llLowTimestamp = m_llHighestTimeStamp;
>-       }
>-
>-       llHighTimestamp = m_llHighestTimeStamp;
>-       ulBytesBuffered = GetBufferedData();
>-
>-
>-       if (bUseTransportStats)
>-       {
>-           if (m_llHighestTimestampAtTransport > llHighTimestamp)
>-           {
>-               llHighTimestamp = m_llHighestTimestampAtTransport;
>-           }
>-
>-           ulBytesBuffered += m_ulNumBytesAtTransport;
>-       }
>-
>-       res = HXR_OK;
>-    }
>-
>-    return res;
>-}
>-
>  void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS,
>                                            INT64 llTheHighestTS,
>                                            BOOL bIsSeekPerformed,
>@@ -569,19 +510,6 @@
>
>  }
>
>-void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime)
>-{
>-    //  0xFA .. 0xFF [roll over] (0x01)
>-    if (m_ulLastTimeSync > ulCurrentTime &&
>-       ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP))
>-    {
>-       m_ulTimeSyncRollOver++;
>-    }
>-    m_ulLastTimeSync = ulCurrentTime;
>-
>-    m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime);
>-}
>-
>  void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs,
>                                         ULONG32 ulMinBufferingInMs)
>  {
>@@ -771,62 +699,4 @@
>      {
>         m_ulAvgBandwidth = ulBandwidth;
>      }
>-}
>-
>-void HXBufferingState::ClearPktInfo()
>-{
>-    m_ulBufferedData = 0;
>-    while(!m_pktInfo.IsEmpty())
>-    {
>-       HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead();
>-       delete pInfo;
>-    }
>-}
>-
>-void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize)
>-{
>-    // Subtract off the first live packet timestamp.
>-    // If not live, then m_llFirstLivePacketTimeStamp is 0.
>-    llTimestamp -= m_llFirstLivePacketTimestamp;
>-    // Create the HXBufferedPktInfo class
>-    HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp,
>-                                                       ulPacketSize);
>-    if (pPktInfo)
>-    {
>-       m_pktInfo.AddTail(pPktInfo);
>-       m_ulBufferedData += ulPacketSize;
>-    }
>-
>-    // purge the old packet info data
>-    //  this keeps the list short and prevents the Symbian
>-    //  allocator from freaking out
>-    (void)GetBufferedData();
>-}
>-
>-UINT32 HXBufferingState::GetBufferedData()
>-{
>-    BOOL bDone = m_pktInfo.IsEmpty();
>-
>-    // Remove all packet info that is past due
>-    // and subtract their sizes from our buffering total
>-    while(!bDone)
>-    {
>-       HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead();
>-
>-       if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime)
>-       {
>-           m_ulBufferedData -= pPktInfo->Size();
>-
>-           m_pktInfo.RemoveHead();
>-           delete pPktInfo;
>-
>-           bDone = m_pktInfo.IsEmpty();
>-       }
>-       else
>-       {
>-           bDone = TRUE;
>-       }
>-    }
>-
>-    return m_ulBufferedData;
>  }
>Index: hxbufstate.h
>===================================================================
>RCS file: /cvsroot/client/core/hxbufstate.h,v
>retrieving revision 1.4
>diff -u -r1.4 hxbufstate.h
>--- hxbufstate.h        19 May 2004 19:37:33 -0000      1.4
>+++ hxbufstate.h        23 Jun 2004 19:50:10 -0000
>@@ -81,7 +81,6 @@
>      BOOL HasPredata(BOOL bIsSeekPerformed);
>
>      INT64 CreateINT64Timestamp(UINT32 ulTime);
>-    INT64 CreateINT64Timesync(UINT32 ulTime);
>
>      void OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,
>                   UINT32 ulElapsedTime, BOOL bIsLive,
>@@ -98,11 +97,6 @@
>                               ULONG32 ulBytesAtTransport,
>                               BOOL bDoneAtTransport);
>
>-    HX_RESULT GetBufferingStats(REF(INT64) llLowTimestamp,
>-                               REF(INT64) llHighTimestamp,
>-                               REF(UINT32) ulBytesBuffered,
>-                               BOOL bUseTransportStats);
>-
>      void GetExcessBufferInfo(INT64 llTheLowestTS,
>                              INT64 llTheHighestTS,
>                              BOOL bIsSeekPerformed,
>@@ -119,8 +113,6 @@
>
>      UINT32 AvgBandwidth() { return m_ulAvgBandwidth;}
>
>-    void OnTimeSync(UINT32 ulCurrentTime);
>-
>      // Should remove
>      void SetAvgBWToASMBw();
>      BOOL DoneAtTransport() { return ((m_ulNumBytesAtTransport == 0) &&
>@@ -149,19 +141,6 @@
>                         UINT32 ulCurrentBuffering,
>                         UINT32 ulMinimumPreroll,
>                         UINT32 ulDenom) const;
>-
>-    /* Functions for tracking the amount of data
>-     * buffered in the renderer
>-     */
>-    void ClearPktInfo(); /* Clears out information about buffered packets */
>-    void AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize); /* Called when
>-                                                             * a packet is
>-                                                             * sent to the
>-                                                             * renderer
>-                                                             */
>-    UINT32 GetBufferedData(); /* Get the current amount of data buffered
>-                              * in the renderer
>-                              */
>
>      ULONG32            m_ulPreroll;
>      ULONG32            m_ulPredata;
>@@ -196,20 +175,6 @@
>      ULONG32            m_ulLastPacketTimeStamp;
>      ULONG32            m_ulAvgBandwidth;
>      IHXASMProps*       m_pASMProps;
>-    UINT32              m_ulLastTimeSync;
>-    INT64               m_llFirstLivePacketTimestamp;
>-    UINT32              m_ulTimeSyncRollOver;
>-    // These variable keep track of the amount of
>-    // data buffered in the renderer
>-    INT64               m_llCurrentPlaybackTime; /* Cached value of last
>-                                                 * OnTimeSync() call
>-                                                 */
>-
>-    UINT32              m_ulBufferedData; /* Data buffered in renderer.
>-                                          * Always use GetBufferedData()
>-                                          * to retreive the value
>-                                          */
>-    CHXSimpleList       m_pktInfo; /* List of packet information */
>  };
>
>  inline
>Index: hxflsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxflsrc.cpp,v
>retrieving revision 1.54
>diff -u -r1.54 hxflsrc.cpp
>--- hxflsrc.cpp 19 May 2004 19:37:33 -0000      1.54
>+++ hxflsrc.cpp 23 Jun 2004 19:50:10 -0000
>@@ -76,6 +76,7 @@
>  #include "uri_schemes.h"
>  #include "stream_desc_hlpr.h"
>  #include "findfile.h"
>+#include "hxsrcbufstats.h"
>
>  #include "hxheap.h"
>  #ifdef _DEBUG
>@@ -115,6 +116,7 @@
>      , m_bValidateMetaDone(FALSE)
>      , m_pFileRecognizer(NULL)
>      , m_pFileReader(NULL)
>+    , m_pHXSrcBufStats(NULL)
>  {
>      m_bAltURL = FALSE;
>      m_bPerfectPlay = TRUE;
>@@ -306,6 +308,18 @@
>
>      HX_VECTOR_DELETE(m_pszURL);
>      HX_DELETE(m_pURL);
>+
>+    HX_RELEASE(m_pHXSrcBufStats);
>+    m_pHXSrcBufStats = new HXSourceBufferStats();
>+    if (m_pHXSrcBufStats)
>+    {
>+        m_pHXSrcBufStats->AddRef();
>+
>+        if (HXR_OK != 
>m_pHXSrcBufStats->Init((IUnknown*)(IHXStreamSource*)this))
>+        {
>+            HX_RELEASE(m_pHXSrcBufStats);
>+        }
>+    }
>
>      if (!theErr && pURL)
>      {
>@@ -938,6 +952,7 @@
>      }
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
>
>+    HX_RELEASE(m_pHXSrcBufStats);
>      HXSource::DoCleanup();
>
>      return HXR_OK;
>@@ -1068,6 +1083,11 @@
>
>      m_llLastFillEndTime = 0;
>
>+    if (m_pHXSrcBufStats)
>+    {
>+        m_pHXSrcBufStats->Reset();
>+    }
>+
>  cleanup:
>
>      return HXR_OK;
>@@ -1442,6 +1462,11 @@
>
>             if(m_pBufferManager)
>                 m_pBufferManager->UpdateCounters(pPacket, 0);
>+
>+            if (m_pHXSrcBufStats && !pPacket->IsLost())
>+            {
>+                m_pHXSrcBufStats->OnPacket(pPacket);
>+            }
>
>             HX_RELEASE(pPacket);
>         }
>@@ -2103,6 +2128,13 @@
>         }
>         HX_RELEASE(pszParentName);
>  #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
>+
>+        if (pStreamInfo && m_pHXSrcBufStats)
>+        {
>+            m_pHXSrcBufStats->InitStream(pStreamInfo->m_uStreamNumber,
>+                                         mLiveStream);
>+        }
>+
>          m_ulStreamIndex++;
>          m_uNumStreams++;
>      }
>@@ -2115,6 +2147,11 @@
>
>         theErr = AdjustClipTime();
>         m_pBufferManager->Init();
>+
>+        if (m_pHXSrcBufStats)
>+        {
>+            SetSrcBufStats(m_pHXSrcBufStats);
>+        }
>      }
>
>      return theErr;
>@@ -2313,6 +2350,11 @@
>         {
>             m_pBufferManager->UpdateCounters(pPacket, 0);
>         }
>+
>+        if (m_pHXSrcBufStats && !pPacket->IsLost())
>+        {
>+            m_pHXSrcBufStats->OnPacket(pPacket);
>+        }
>      }
>
>      m_llLastFillEndTime = llActualPacketTime;
>Index: hxflsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxflsrc.h,v
>retrieving revision 1.12
>diff -u -r1.12 hxflsrc.h
>--- hxflsrc.h   3 May 2004 18:59:30 -0000       1.12
>+++ hxflsrc.h   23 Jun 2004 19:50:10 -0000
>@@ -52,6 +52,8 @@
>  #include "hxfiles.h"
>  #include "recognizer.h"
>
>+class HXSourceBufferStats;
>+
>  class HXFileSource : public HXSource,
>                       public IHXFormatResponse,
>                        public IHXHTTPRedirectResponse
>@@ -349,6 +351,7 @@
>
>      CFileReader*                m_pFileReader;
>      CHXFileRecognizer*          m_pFileRecognizer;
>+    HXSourceBufferStats*        m_pHXSrcBufStats;
>  };
>
>  #endif // _HX_FILE_SOURCE
>Index: hxntsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxntsrc.cpp,v
>retrieving revision 1.90
>diff -u -r1.90 hxntsrc.cpp
>--- hxntsrc.cpp 19 May 2004 19:37:33 -0000      1.90
>+++ hxntsrc.cpp 23 Jun 2004 19:50:10 -0000
>@@ -675,6 +675,7 @@
>      HX_RESULT   rc = HXR_OK;
>      BOOL        bSDPInitiated = FALSE;
>      CHXString   pString;
>+    IHXSourceBufferingStats2* pSrcBufStats = NULL;
>
>      // start off with the preferred protocol
>      rc = CreateProtocol();
>@@ -722,6 +723,14 @@
>          goto cleanup;
>      }
>
>+    // Setup source buffer stats
>+    if (HXR_OK == m_pProto->QueryInterface(IID_IHXSourceBufferingStats2,
>+                                           (void**)&pSrcBufStats))
>+    {
>+        SetSrcBufStats(pSrcBufStats);
>+        HX_RELEASE(pSrcBufStats);
>+    }
>+
>      // create log info list
>      m_pLogInfoList = new CHXSimpleList;
>      m_ulLogInfoLength = 0;
>@@ -6295,6 +6304,12 @@
>  #else
>      return HXR_NOTIMPL;
>  #endif /* HELIX_FEATURE_RECORDCONTROL */
>+}
>+
>+HX_RESULT
>+HXNetSource::OnTimeSync(ULONG32 ulCurrentTime)
>+{
>+    return HXSource::OnTimeSync(ulCurrentTime + m_lPacketTimeOffSet);
>  }
>
>  ReconnectCallback::ReconnectCallback(HXNetSource*       pSource,
>Index: hxntsrc.h
>===================================================================
>RCS file: /cvsroot/client/core/hxntsrc.h,v
>retrieving revision 1.24
>diff -u -r1.24 hxntsrc.h
>--- hxntsrc.h   3 May 2004 18:59:30 -0000       1.24
>+++ hxntsrc.h   23 Jun 2004 19:50:10 -0000
>@@ -282,6 +282,7 @@
>
>         virtual HX_RESULT       FillRecordControl();
>
>+        virtual HX_RESULT OnTimeSync(ULONG32 ulCurrentTime);
>  protected:
>
>         virtual                         ~HXNetSource(void);
>@@ -470,7 +471,6 @@
>  private:
>          IHXBufferControl*                m_pBufferCtl;
>          IHXWatermarkBufferControl*       m_pWMBufferCtl;
>-
>  public:
>         HX_RESULT       FinishSetup();
>         void            ReSetup();
>Index: hxsrc.cpp
>===================================================================
>RCS file: /cvsroot/client/core/hxsrc.cpp,v
>retrieving revision 1.44.2.1
>diff -u -r1.44.2.1 hxsrc.cpp
>--- hxsrc.cpp   15 Jun 2004 16:26:43 -0000      1.44.2.1
>+++ hxsrc.cpp   23 Jun 2004 19:50:10 -0000
>@@ -213,6 +213,8 @@
>          , m_pRedirectURL(NULL)
>          , m_pSDPURL(NULL)
>          , m_bRedirectPending(FALSE)
>+        , m_pTransportTimeSink(NULL)
>+        , m_pSrcBufStats(NULL)
>  {
>      mStreamInfoTable = new CHXMapLongToObj;
>  }
>@@ -313,6 +315,8 @@
>      HX_DELETE(m_pRedirectURL);
>      HX_DELETE(m_pSDPURL);
>      m_bRedirectPending  = FALSE;
>+    HX_RELEASE(m_pTransportTimeSink);
>+    HX_RELEASE(m_pSrcBufStats);
>
>  #if defined(HELIX_FEATURE_RECORDCONTROL)
>      if(m_pRecordControl)
>@@ -340,8 +344,6 @@
>              { GET_IIDHANDLE(IID_IHXPendingStatus), 
> (IHXPendingStatus*)this },
>              { GET_IIDHANDLE(IID_IHXInfoLogger), (IHXInfoLogger*)this },
>              { GET_IIDHANDLE(IID_IHXPrivateStreamSource), 
> (IHXPrivateStreamSource*)this },
>-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
>(IHXSourceBufferingStats*)this },
>-            { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
>(IHXSourceBufferingStats2*)this },
>              { GET_IIDHANDLE(IID_IHXClientRateAdaptControl),
>                (IHXClientRateAdaptControl*)this },
>  #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
>@@ -349,6 +351,7 @@
>              { GET_IIDHANDLE(IID_IHXHyperNavigate2), 
> (IHXHyperNavigate2*)this },
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>              { GET_IIDHANDLE(IID_IUnknown), 
> (IUnknown*)(IHXStreamSource*)this },
>+            { GET_IIDHANDLE(IID_IHXTransportTimeManager), 
>(IHXTransportTimeManager*)this}
>          };
>
>      HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
>@@ -388,6 +391,14 @@
>             return HXR_NOINTERFACE;
>         }
>      }
>+    else if (m_pSrcBufStats &&
>+             (IsEqualIID(riid, IID_IHXSourceBufferingStats) ||
>+              IsEqualIID(riid, IID_IHXSourceBufferingStats2)))
>+    {
>+        m_pSrcBufStats->AddRef();
>+        *ppvObj = m_pSrcBufStats;
>+        return HXR_OK;
>+    }
>
>  #if defined(HELIX_FEATURE_AUTOUPGRADE)
>      else if (IsEqualIID(riid, IID_IHXUpgradeCollection))
>@@ -2250,59 +2261,6 @@
>  }
>  #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
>
>-STDMETHODIMP
>-HXSource::GetTotalBuffering(UINT16  uStreamNumber,
>-                           REF(INT64)  llLowestTimestamp,
>-                           REF(INT64)  llHighestTimestamp,
>-                           REF(UINT32) ulNumBytes,
>-                           REF(BOOL)   bDone)
>-{
>-    HX_RESULT res = HXR_NO_DATA;
>-
>-    llLowestTimestamp = 0;
>-    llHighestTimestamp = 0;
>-    ulNumBytes = 0;
>-    bDone = FALSE;
>-
>-    STREAM_INFO* pStreamInfo;
>-    if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& 
>)pStreamInfo))
>-    {
>-       HXBufferingState& bufState = pStreamInfo->BufferingState();
>-       BOOL   bUseTransportStats = FALSE;
>-
>-       INT64  llTransportLowTS = 0;
>-       INT64  llTransportHighTS = 0;
>-       UINT32 ulTransportBytes = 0;
>-       BOOL   bTransportDone = FALSE;
>-
>-       if (!IsLocalSource() &&
>-           (HXR_OK == GetCurrentBuffering(uStreamNumber,
>-                                          llTransportLowTS,
>-                                          llTransportHighTS,
>-                                          ulTransportBytes,
>-                                          bTransportDone)))
>-       {
>-           bufState.UpdateTransportStats(llTransportLowTS,
>-                                         llTransportHighTS,
>-                                         ulTransportBytes,
>-                                         bTransportDone);
>-
>-           bUseTransportStats = TRUE;
>-
>-           // Update bDone with what the transport says.
>-           bDone = bTransportDone;
>-       }
>-
>-       res = bufState.GetBufferingStats(llLowestTimestamp,
>-                                       llHighestTimestamp,
>-                                       ulNumBytes,
>-                                       bUseTransportStats);
>-    }
>-
>-
>-    return res;
>-}
>-
>  /*
>   * IHXClientRateAdaptControl Methods
>   */
>@@ -2444,6 +2402,40 @@
>      return res;
>  }
>
>+/*
>+ * IHXTransportTimeManager methods
>+ */
>+STDMETHODIMP
>+HXSource::AddSink(THIS_ IHXTransportTimeSink* pSink)
>+{
>+    HX_RESULT res = HXR_FAILED;
>+
>+    // Currently we only support one transport time sink
>+    if (pSink && !m_pTransportTimeSink)
>+    {
>+        m_pTransportTimeSink = pSink;
>+        m_pTransportTimeSink->AddRef();
>+
>+        res = HXR_OK;
>+    }
>+
>+    return res;
>+}
>+
>+STDMETHODIMP
>+HXSource::RemoveSink(THIS_ IHXTransportTimeSink* pSink)
>+{
>+    HX_RESULT res = HXR_FAILED;
>+
>+    if (pSink && (pSink == m_pTransportTimeSink))
>+    {
>+        HX_RELEASE(m_pTransportTimeSink);
>+        res = HXR_OK;
>+    }
>+
>+    return res;
>+}
>+
>  /*
>   * All relative URLs are converted to absolute URLs unless the
>   * original request (ram/smil) passed in OpenRequest/OpenURL()
>@@ -2948,13 +2940,31 @@
>  {
>      HX_RESULT res = HXR_OK;
>
>-    for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
>-         i != mStreamInfoTable->End(); ++i)
>-    {
>-       STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
>-
>-       pStreamInfo->BufferingState().OnTimeSync(ulCurrentTime);
>+    // Convert presentation time to transport time
>+    if (m_pTransportTimeSink)
>+    {
>+        ULONG32 ulOffset = m_ulDelay;
>+        ULONG32 ulTransportTime = m_ulStartTime;
>+
>+        if (IsTimeGreaterOrEqual(ulCurrentTime, ulOffset))
>+        {
>+            ulTransportTime += ulCurrentTime - ulOffset;
>+        }
>+
>+        res = m_pTransportTimeSink->OnTransportTime(ulTransportTime);
>      }
>
>      return res;
>+}
>+
>+void
>+HXSource::SetSrcBufStats(IHXSourceBufferingStats2* pSrcBufStats)
>+{
>+    HX_RELEASE(m_pSrcBufStats);
>+
>+    if (pSrcBufStats)
>+    {
>+        m_pSrcBufStats = pSrcBufStats;
>+        m_pSrcBufStats->AddRef();
>+    }
>  }
>Index: rtspprotocol.cpp
>===================================================================
>RCS file: /cvsroot/client/core/rtspprotocol.cpp,v
>retrieving revision 1.39
>diff -u -r1.39 rtspprotocol.cpp
>--- rtspprotocol.cpp    11 May 2004 00:55:19 -0000      1.39
>+++ rtspprotocol.cpp    23 Jun 2004 19:50:10 -0000
>@@ -2626,12 +2626,12 @@
>      UINT16 seekFrom
>  )
>  {
>+    HX_RESULT theErr = m_pProtocolLib->SeekFlush();
>+
>      if (IsLive())
>      {
>-        return m_pProtocolLib->SeekFlush();
>+        return theErr;
>      }
>-
>-    HX_RESULT theErr = HXR_OK;
>
>      m_uCurrentStreamCount = m_uStreamCount;
>
>Index: Umakefil
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/Umakefil,v
>retrieving revision 1.9.2.1
>diff -u -r1.9.2.1 Umakefil
>--- Umakefil    16 Jun 2004 18:44:01 -0000      1.9.2.1
>+++ Umakefil    23 Jun 2004 19:50:17 -0000
>@@ -46,6 +46,7 @@
>                           'common/runtime/pub',
>                           'common/lang/xml/pub',
>                           'client/common/container/pub',
>+                          'client/common/util/pub',
>                           'protocol/transport/rtp/include',
>                           'server/include',
>                            'server/common/struct/pub',
>@@ -65,7 +66,7 @@
>                    'rtspmsg.cpp', 'rtspmdsc.cpp',
>                    'rtsppars.cpp', 'mhprop.cpp',
>                    'servrsnd.cpp', '3gpadapthdr.cpp',
>-                   'rateadaptinfo.cpp')
>+                   'rateadaptinfo.cpp', 'ntsrcbufstats.cpp')
>
>  if (project.IsDefined('HELIX_FEATURE_PIPELINED_DESCRIBE')):
>      project.AddSources('pipelinedesc.cpp')
>Index: rtspclnt.cpp
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
>retrieving revision 1.79.2.1
>diff -u -r1.79.2.1 rtspclnt.cpp
>--- rtspclnt.cpp        17 Jun 2004 04:32:09 -0000      1.79.2.1
>+++ rtspclnt.cpp        23 Jun 2004 19:50:17 -0000
>@@ -95,6 +95,7 @@
>  #include "pipelinedesc.h"
>  #include "errdbg.h"
>  #include "rateadaptinfo.h"
>+#include "ntsrcbufstats.h"
>
>  #include "hxheap.h"
>  #ifdef _DEBUG
>@@ -302,6 +303,12 @@
>      {
>          return HXR_OK;
>      }
>+    else if (m_pSrcBufStats &&
>+             (HXR_OK == m_pSrcBufStats->QueryInterface(riid,
>+                                                       ppvObj)))
>+    {
>+        return HXR_OK;
>+    }
>      *ppvObj = NULL;
>      return HXR_NOINTERFACE;
>  }
>@@ -388,6 +395,7 @@
>      m_bReportedSuccessfulTransport(FALSE),
>      m_bSDPInitiated(FALSE),
>      m_bMulticast(FALSE),
>+    m_bIsLive(FALSE),
>      m_pSDPFileHeader(NULL),
>      m_pSDPStreamHeaders(NULL),
>      m_bSessionSucceeded(FALSE),
>@@ -404,7 +412,8 @@
>      m_ulCurrentTimeOut(0),
>      m_pUAProfURI(NULL),
>      m_pUAProfDiff(NULL),
>-    m_pRateAdaptInfo(NULL)
>+    m_pRateAdaptInfo(NULL),
>+    m_pSrcBufStats(NULL)
>  #if defined(_MACINTOSH)
>      , m_pCallback(NULL)
>  #endif /* _MACINTOSH */
>@@ -810,6 +819,26 @@
>          }
>      }
>
>+    if (HXR_OK == hresult)
>+    {
>+        HX_RELEASE(m_pSrcBufStats);
>+        m_pSrcBufStats = new HXNetSourceBufStats(this);
>+
>+        if (m_pSrcBufStats)
>+        {
>+            m_pSrcBufStats->AddRef();
>+
>+            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
>+            {
>+                HX_RELEASE(m_pSrcBufStats);
>+            }
>+        }
>+        else
>+        {
>+            hresult = HXR_OUTOFMEMORY;
>+        }
>+    }
>+
>  #if defined(_MACINTOSH)
>      if (m_pCallback &&
>          m_pCallback->m_bIsCallbackPending &&
>@@ -2191,7 +2220,14 @@
>          (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
>      if (pTrans)
>      {
>-        rc = pTrans->getPacket(uStreamNumber, pPacket);
>+        UINT32 uSeqNum;
>+        rc = pTrans->getPacket(uStreamNumber, pPacket, uSeqNum);
>+
>+        if ((HXR_OK == rc) && m_pSrcBufStats &&
>+            (!pPacket->IsLost()))
>+        {
>+            m_pSrcBufStats->OnPacket(pPacket, uSeqNum);
>+        }
>      }
>
>      m_pMutex->Unlock();
>@@ -3291,16 +3327,24 @@
>      HX_RESULT rc = HXR_OK;
>      m_pMutex->Lock();
>
>-    CHXMapLongToObj::Iterator i;
>-    for(i=m_pTransportStreamMap->Begin();
>-            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
>+    if (m_bIsLive)
>      {
>-        RTSPTransport* pTransport = (RTSPTransport*)(*i);
>-        UINT16 streamNumber = (UINT16)i.get_key();
>-
>-        HX_ASSERT(pTransport);
>+        CHXMapLongToObj::Iterator i;
>+        for(i=m_pTransportStreamMap->Begin();
>+            (rc == HXR_OK) &&  i!=m_pTransportStreamMap->End(); ++i)
>+        {
>+            RTSPTransport* pTransport = (RTSPTransport*)(*i);
>+            UINT16 streamNumber = (UINT16)i.get_key();
>+
>+            HX_ASSERT(pTransport);
>+
>+            rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
>+        }
>+    }
>
>-        rc = pTransport ? pTransport->SeekFlush(streamNumber) : HXR_OK;
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->Reset();
>      }
>
>      m_pMutex->Unlock();
>@@ -5811,6 +5855,13 @@
>
>      HX_RELEASE(m_pTimeoutCallback);
>      HX_DELETE(m_pSessionTimeout);
>+
>+    if (m_pSrcBufStats)
>+    {
>+        m_pSrcBufStats->Close();
>+
>+        HX_RELEASE(m_pSrcBufStats);
>+    }
>  }
>
>  void
>@@ -6964,6 +7015,11 @@
>          // Get session level RTP bandwidth modifiers
>          ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
>          ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
>+
>+        if (ulIsSessionLive)
>+        {
>+            m_bIsLive = TRUE;
>+        }
>
>          // get multicast address from the session description
>          if (HXR_OK == 
> ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
>@@ -7187,6 +7243,12 @@
>              pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
>              pInfo->m_bRealMedia = bRealMedia;
>
>+            if (m_pSrcBufStats)
>+            {
>+                m_pSrcBufStats->InitStream((UINT16)streamNumber,
>+                                           pInfo->m_bIsLive);
>+            }
>+
>              if (m_pRateAdaptInfo)
>              {
>                  m_pRateAdaptInfo->OnStreamHeader((UINT16)streamNumber,
>@@ -7222,6 +7284,7 @@
>          if (m_bMulticast)
>          {
>              m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
>+            m_bIsLive = TRUE;
>          }
>      }
>
>Index: pub/rtspclnt.h
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
>retrieving revision 1.30.2.1
>diff -u -r1.30.2.1 rtspclnt.h
>--- pub/rtspclnt.h      17 Jun 2004 04:32:09 -0000      1.30.2.1
>+++ pub/rtspclnt.h      23 Jun 2004 19:50:17 -0000
>@@ -46,6 +46,7 @@
>  #include "hxbufctl.h" // IHXTransportBufferLimit
>  #include "hxrtsp2.h"
>  #include "hxrsdbf.h" // IHXResendBufferControl
>+#include "hxprefs.h" // IHXPreferences
>
>  class RTSPClientState;
>  class RTSPOptionsMessage;
>@@ -63,6 +64,7 @@
>  class MIMEHeader;
>  class PipelinedDescribeLogic;
>  class CHXRateAdaptationInfo;
>+class HXNetSourceBufStats;
>
>  struct IHXKeyValueList;
>  struct IHXValues;
>@@ -1039,6 +1041,7 @@
>
>      BOOL                                m_bSDPInitiated;
>      BOOL                                m_bMulticast;
>+    BOOL                                m_bIsLive;
>      IHXValues*                          m_pSDPFileHeader;
>      CHXSimpleList*                      m_pSDPStreamHeaders;
>
>@@ -1074,6 +1077,7 @@
>      UINT32                              m_ulServerTimeOut;
>      UINT32                              m_ulCurrentTimeOut;
>      CHXRateAdaptationInfo*              m_pRateAdaptInfo;
>+    HXNetSourceBufStats*                m_pSrcBufStats;
>
>  #if defined(_MACINTOSH)
>      RTSPClientProtocolCallback*                m_pCallback;
>
>Index: Umakefil
>===================================================================
>RCS file: /cvsroot/common/util/Umakefil,v
>retrieving revision 1.20
>diff -u -r1.20 Umakefil
>--- Umakefil    16 Mar 2004 23:01:44 -0000      1.20
>+++ Umakefil    23 Jun 2004 19:50:31 -0000
>@@ -109,7 +109,8 @@
>                     "hxprefutil.cpp",
>                     "stream_desc_hlpr.cpp",
>                     "hxcbobj.cpp",
>-                   "clone_values.cpp")
>+                   "clone_values.cpp",
>+                   "hxsrcbufstats.cpp")
>
>  project.AddSources("tconverter/fxpoint/tconverter_fxp.cpp")
>
>? ihxtranstime.h
>Index: hxpiids.h
>===================================================================
>RCS file: /cvsroot/common/include/hxpiids.h,v
>retrieving revision 1.28.2.1
>diff -u -r1.28.2.1 hxpiids.h
>--- hxpiids.h   15 Jun 2004 16:38:55 -0000      1.28.2.1
>+++ hxpiids.h   23 Jun 2004 19:50:44 -0000
>@@ -998,5 +998,17 @@
>  DEFINE_GUID_ENUM(IID_IHXClientRateAdaptControl, 0x44f5ac8c, 0x654c, 
> 0x414e, 0x9d,
>                   0x18, 0xe7, 0xa4, 0x80, 0x90, 0x70, 0x9)
>
>+/* File:
>+ *      ihxtranstime.h
>+ *
>+ * Description:
>+ *      Transport time interfaces
>+ */
>+DEFINE_GUID_ENUM(IID_IHXTransportTimeSink,
>+0xdb838ab3, 0x4637, 0x41e0, 0xbc, 0x3f, 0xed, 0x3, 0xb6, 0xa6, 0x84, 0xc1)
>+
>+DEFINE_GUID_ENUM(IID_IHXTransportTimeManager,
>+0xd0a5ba01, 0xedfb, 0x4741, 0xb7, 0x9, 0x88, 0x4e, 0x68, 0x5d, 0x2d, 0x8)
>+
>  #endif /* _HXPRIVATEIIDS_H_ */
>
>
>
>
>
>
>_______________________________________________
>Protocol-dev mailing list
>Protocol-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev


From acolwell at real.com  Wed Jun 23 17:17:05 2004
From: acolwell at real.com (Aaron Colwell)
Date: Wed Jun 23 17:18:41 2004
Subject: [Common-dev] CN-Client: Moving IHXSourceBufferingStats2
	implementation [Take 2]
In-Reply-To: <5.1.0.14.2.20040623141120.03a77740@mailone.real.com>
References: <5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<20040622235202.GA5152@real.com>
	<5.1.0.14.2.20040623094647.039c0a60@mailone.real.com>
	<5.1.0.14.2.20040623103749.039ebce8@mailone.real.com>
	<5.1.0.14.2.20040623141120.03a77740@mailone.real.com>
Message-ID: <20040624001705.GA9636@real.com>

Modified by: acolwell@real.com

Reviewed by: ping@real.com

Date: 06:23:2004

Project: HEAD

On Wed, Jun 23, 2004 at 02:11:35PM -0700, Henry Ping wrote:
> looks good to me
> 
> -->Henry
> 
> At 01:14 PM 6/23/2004 -0700, Aaron Colwell wrote:
> >- I've integrated all of the suggested changes.
> >
> >- I also added a new interface called IHXTransportTimeManager that allows 
> >you
> >  to register the IHXTransportTimeSink object. This registration process
> >  allows the code to detect whether it will actually be able to get
> >  OnTransportTime() calls or not. This allows the code to avoid 
> >  accumulating
> >  packet information when it is run on the server/proxy.
> >
> >
> >
> >Synopsis: Move IHXSourceBufferingStats2 implementation so that sequence
> >          number information can be maintained as well.
> >
> >Overview: These changes move the IHXSourceBufferingStats2 implementation
> >          out of HXBufferingState and into a new class called
> >          HXSourceBufferStats. This was done because the client needs to
> >          track packet sequence numbers for 3GPP-Rel6 OBSN support.
> >          There was no good way to get the sequence number information to
> >          the HXBufferingState class so the IHXSourceBufferingStats2 logic
> >          was moved to where this information is available.
> >
> >          Two new interfaces were created.
> >
> >          IHXTransportTimeSink was created to propagate OnTimeSync() like 
> >calls
> >          to HXSourceBufferStats. The time passed to the 
> >OnTransportTime() call
> >          in this interface MUST NOT have any offsets created by SMIL or 
> >live
> >          playback. The time should be in the same time frame as the 
> >          packets
> >          coming from the transports.
> >
> >          IHXTransportTimeManager was created to allow HXSourceBufferStats 
> >          to
> >          notify the core that it wants to receive OnTransportTime() calls.
> >          This registration process allows HXSourceBufferStats to know if 
> >          it
> >          is able to receive OnTransportTime() calls. If the interface is 
> >          not
> >          available then it won't keep track of packet data. This prevents
> >          a "memory leak" when the code is used in an environment where
> >          OnTransportTime() won't ever get called(ie in the server).
> >
> >          - Created HXSourceBufferStats to contain the base
> >            IHXSourceBufferingStats2 implementation. This class is
> >            used by HXFileSource.
> >
> >          - Created HXNetSourceBufStats which derives from 
> >HXSourceBufferStats.
> >            This class just overloads the GetCurrentBuffering() so that it
> >            returns the amount of data in the transport buffer. This is
> >            used by RTSPClientProtocol.
> >
> >          - Removed IHXSourceBufferingStats2 code from HXSource
> >
> >          - Removed packet tracking code from HXBufferingState. This
> >            functionality is implemented by HXSourceBufferStats now
> >
> >          - Added code to HXSource to provide OnTimeSync() calls to the
> >            IHXTransportOnTimeSync interface.
> >
> >          - HXSource now exposes IHXSourceBufferingStats functionality 
> >through
> >            it's m_pSrcBufStats member variable instead of implementing it
> >            itself. The file and network sources are expected to provide an
> >            IHXSourceBufferingStats2 interface via a
> >            HXSource::SetSrcBufStats() call.
> >
> >          - Added code to HXFileSource to use HXSourceBufferStats
> >
> >          - Added code to RTSPClientProtocol to use HXNetSourceBufStats
> >
> >          - Fixed some code in CBufferManager that was expecting HXSource
> >            to implement IHXSourceBufferingStats. This code now QI's for
> >            IHXSourceBufferingStats and uses that interface.
> >
> >          - Added code IHXTransportTimeManager implementation to HXSource
> >
> >
> >Files Modified:
> >client/core/buffmgr.cpp
> >client/core/hxbsrc.h
> >client/core/hxbufstate.cpp
> >client/core/hxbufstate.h
> >client/core/hxflsrc.cpp
> >client/core/hxflsrc.h
> >client/core/hxntsrc.cpp
> >client/core/hxntsrc.h
> >client/core/hxsrc.cpp
> >client/core/rtspprotocol.cpp
> >protocol/rtsp/Umakefil
> >protocol/rtsp/rtspclnt.cpp
> >protocol/rtsp/pub/rtspclnt.h
> >common/util/Umakefil
> >common/include/hxpiids.h
> >
> >
> >Files Added:
> >common/include/ihxtranstime.h
> >common/util/pub/hxsrcbufstats.h
> >common/util/hxsrcbufstats.cpp
> >protocol/rtsp/ntsrcbufstats.h
> >protocol/rtsp/ntsrcbufstats.cpp
> >
> >Image Size and Heap Use impact:
> >
> >Platforms and Profiles affected: all
> >
> >Distribution Libraries affected: rdtclntlib
> >
> >Distribution library impact and planned action:
> >Added member variables to RTSPClientProtocol. This will
> >effect any derived classes
> >
> >Platforms and Profiles Build Verified: win32
> >
> >Platforms and Profiles Functionality verified: win32
> >
> >Branch: HEAD
> >
> >QA Instructions: none

From dcollins at real.com  Thu Jun 24 00:17:25 2004
From: dcollins at real.com (Dean Collins)
Date: Thu Jun 24 00:17:28 2004
Subject: [Common-dev] adjustment to linux-2.2-libc6-gcc32-i586.cf
Message-ID: <20040624071725.GP4694@jedi.dev.prognet.com>

To better support some other umakecf changes I need to make,
I'd like to move the contents of linux-2.2-libc6-gcc32-i586.cf to
linux-2.2-libc6-gcc32.cf, removing the -march=pentium and -mcpu=pentium
flags.  Then replace linux-2.2-libc6-gcc32-i586.cf with a simple wrapper
that includes the non-processor-specific config file, adding the necessary
-march flags.

The diff shows the differences between the existing
linux-2.2-libc6-gcc32-i586.cf and the new generic
linux-2.2-libc6-gcc32.cf.

The change will be transparent, and anyone using
linux-2.2-libc6-gcc32-i586.cf or its derivitives will be unaffected.

This will go in tomorrow unless someone raises concerns.

Tested by building the server with a Linux/AMD64 config file (yet to be
checked in) which inherits from the above.

Dean

-- 
Dean Collins
Server Technical Lead, RealNetworks, Inc. -- http://www.realnetworks.com
Helix Server Project Owner -- http://helix-server.helixcommunity.org
-------------- next part --------------
# 
# ***** BEGIN LICENSE BLOCK *****
# Version: RCSL 1.0/RPSL 1.0
# 
# Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file, are
# subject to the current version of the RealNetworks Public Source License
# Version 1.0 (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the RealNetworks Community Source License Version 1.0
# (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
# in which case the RCSL will apply. You may also obtain the license terms
# directly from RealNetworks.  You may not use this file except in
# compliance with the RPSL or, if you have a valid RCSL with RealNetworks
# applicable to this file, the RCSL.  Please see the applicable RPSL or
# RCSL for the rights, obligations and limitations governing use of the
# contents of the file.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the portions
# it created.
# 
# This file, and the files included with this file, is distributed and made
# available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 
"""Linux 2.x using GCC 3.2 libc6 (glibc2) on pentium+ ."""

exec_config_file('linux-2.2-libc6-gcc32.cf')

## list of PCF files to run
platform.pcf_prefix_list = ["unix", "linux2", "linux-2.2-libc6-gcc32-i586"]


platform.cxx.args["default"] = platform.cxx.args["default"] + " " + \
    "-march=pentium -mcpu=pentium " 
platform.cc.args["default"] = platform.cc.args["default"] + " " + \
    "-march=pentium -mcpu=pentium " 

-------------- next part --------------
# 
# ***** BEGIN LICENSE BLOCK *****
# Version: RCSL 1.0/RPSL 1.0
# 
# Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file, are
# subject to the current version of the RealNetworks Public Source License
# Version 1.0 (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the RealNetworks Community Source License Version 1.0
# (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
# in which case the RCSL will apply. You may also obtain the license terms
# directly from RealNetworks.  You may not use this file except in
# compliance with the RPSL or, if you have a valid RCSL with RealNetworks
# applicable to this file, the RCSL.  Please see the applicable RPSL or
# RCSL for the rights, obligations and limitations governing use of the
# contents of the file.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the portions
# it created.
# 
# This file, and the files included with this file, is distributed and made
# available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 
"""Linux 2.x using GCC 3.2 libc6 (glibc2)."""

exec_config_file('linux-common.cf')

## list of PCF files to run
platform.pcf_prefix_list = ["unix", "linux2", "linux-2.2-libc6-gcc32"]

## platform defines 
project.AddDefines("_LITTLE_ENDIAN")

## Turn on Threaded Network IO 
project.AddDefines("_UNIX_THREADED_NETWORK_IO")

## This define used on platforms that have native recursive mutexes.
project.AddDefines("_TIMEDWAITS_RECURSIVE_MUTEXES")

## This turns on the non portable ( _NP) thread directives.
project.AddDefines("_GNU_SOURCE")

## Turn on threads for all areas.
project.AddDefines("THREADS_SUPPORTED")

## This define enables compiling of the UnixThreads file.
## It means that that platform has a working threads lib
## that does everything we need.
project.AddDefines("_UNIX_THREADS_SUPPORTED")

## Turn off exceptions, rtti and turn on pentium ops.   Set warning options.
platform.cxx.args["default"] = platform.cxx.args["default"] + " " + \
    "-Wall -Wreturn-type -fno-exceptions " + \
    "--permissive -fno-rtti -Wno-ctor-dtor-privacy"

platform.cc.args["default"] = platform.cc.args["default"] + " " + \
    "-Wall -Wreturn-type -fno-exceptions"

## For now we will link everything against libstdc++ for the
## new/delete operators.  gcc 2.95 didn't need it, but it looks like
## gcc 3.2 needs it; at least sometimes.
project.AddSystemLibraries("stdc++")

class LinuxLinker(Linker2):
    def __init__(self):
        Linker2.__init__(self)
        self.linker=platform.cc.cmd
        self.extra_arguments=[]

    def add_argument(self, arg):
        self.extra_arguments.append(arg)
    
    def link_paths(self):
        return string.join(platform.system_paths +
                           project.system_paths)

    def link_script_path(self):
        return "%s.exp" % (project.TargetName())

    def armerge_lib_path(self):
        libname = "%s_libs.%s" % (project.target_name, platform.library_suffix)
        return os.path.join(project.output_dir, libname)
    
    def armerge_tmp_path(self):
        return os.path.join(project.object_dir, "lib")

    def write_link_script(self, path):
        ## if there are no exported functions, die here
        if len(project.exported_func) == 0:
            umake_lib.fatal("dll target without exported functions") 
        
        ## create a gcc link script
        fil = open(path, "w")
        fil.write("VERSION\n")
        fil.write("{\n")
        fil.write("  G2 {\n")
        fil.write("    global:\n")

        for export in project.exported_func:
            fil.write("      %s;\n" % (export))

        fil.write("    local:\n")
        fil.write("      *;\n")
        fil.write("  };\n")
        fil.write("}\n")
        fil.close()

    def LinkLIB(self, target_path, objects):
        cmd_list = []
        
        cmd = "%s %s %s" % (make_lib.cmd, target_path, objects)
        cmd_list.append(cmd)

        cmd = "ranlib %s" % (target_path)
        cmd_list.append(cmd)

        return cmd_list

    def CleanLIB(self, target_path):
        return [target_path]

    def LinkDLL(self, target_path, objects, static_libs, dynamic_libs):
        cmd_list = []

        armerge_cmd = os.path.join(BUILD_ROOT, "bin", "armerge")
        tmp_path = self.armerge_tmp_path()
        libpath = self.armerge_lib_path()
        cmd = "%s -d %s %s %s" % (armerge_cmd, tmp_path, libpath, static_libs)
        cmd_list.append(cmd)

        lspath = self.link_script_path()
        self.write_link_script(lspath)
        if project.exported_func:
            undefinedSymbols="-u "+string.join(project.exported_func," -u ")
        else:
            undefinedSymbols=""

        cmd = "%s -shared %s -o %s %s %s %s %s %s %s " % (
            self.linker,
            lspath, target_path,
            undefinedSymbols,
            objects, libpath,
            self.link_paths(),
            string.join(self.extra_arguments),
            dynamic_libs)
        cmd_list.append(cmd)

        cmd = 'rm "%s"' % (libpath)
        cmd_list.append(cmd)

        return cmd_list

    def CleanDLL(self, target_path):
        list = []
        list.append(target_path)
        list.append(self.armerge_tmp_path())
        list.append(self.armerge_lib_path())
        return list

    def LinkEXE(self, target_path, objects, static_libs, dynamic_libs):
        cmd_list = []

        armerge_cmd = os.path.join(BUILD_ROOT, "bin", "armerge")
        tmp_path = self.armerge_tmp_path()
        libpath = self.armerge_lib_path()
        cmd = "%s -d %s %s %s" % (armerge_cmd, tmp_path, libpath, static_libs)
        cmd_list.append(cmd)

        cmd = "%s -o %s %s %s %s %s %s" % (
            self.linker,
            target_path, objects, libpath,
            self.link_paths(),
            string.join(self.extra_arguments),
            dynamic_libs)
        cmd_list.append(cmd)

        cmd = 'rm "%s"' % (libpath)
        cmd_list.append(cmd)

        return cmd_list
    
    def CleanEXE(self, target_path):
        list = []
        list.append(target_path)
        list.append(self.armerge_tmp_path())
        list.append(self.armerge_lib_path())
        return list
    
    def make_lib_static(self, lib):
        return "-Wl,-Bstatic %s -Wl,-Bdynamic" % lib
    
platform.link = LinuxLinker()




def verify_gcc_callback():
    ccver=get_compiler_version(cc)
    cxxver=get_compiler_version(cxx)
    w=[]
    if ccver[:2] != "3.":
        w.append("gcc version is %s, not 3.* as expected." % ccver)

    if cxxver[:2] != "3.":
        w.append("g++ version is %s, not 3.* as expected." % cxxver)


    if w:
        print " **WARNING**"
        for m in w:
            print m
        print
        print "Compilation will continue in 10 seconds"
        import time
        time.sleep(10)
        
AddIdentifyCallback(verify_gcc_callback)
-------------- next part --------------
--- linux-2.2-libc6-gcc32-i586.cf.old	2004-06-23 23:42:03.666066216 -0700
+++ linux-2.2-libc6-gcc32.cf	2004-06-20 00:21:21.000000000 -0700
@@ -34,12 +34,12 @@
 # 
 # ***** END LICENSE BLOCK *****
 # 
-"""Linux 2.x using GCC 3.2 libc6 (glibc2) on pentium+ ."""
+"""Linux 2.x using GCC 3.2 libc6 (glibc2)."""
 
 exec_config_file('linux-common.cf')
 
 ## list of PCF files to run
-platform.pcf_prefix_list = ["unix", "linux2", "linux-2.2-libc6-gcc32-i586"]
+platform.pcf_prefix_list = ["unix", "linux2", "linux-2.2-libc6-gcc32"]
 
 ## platform defines 
 project.AddDefines("_LITTLE_ENDIAN")
@@ -63,11 +63,11 @@
 
 ## Turn off exceptions, rtti and turn on pentium ops.   Set warning options.
 platform.cxx.args["default"] = platform.cxx.args["default"] + " " + \
-    "-Wall -Wreturn-type -fno-exceptions -march=pentium -mcpu=pentium " + \
+    "-Wall -Wreturn-type -fno-exceptions " + \
     "--permissive -fno-rtti -Wno-ctor-dtor-privacy"
 
 platform.cc.args["default"] = platform.cc.args["default"] + " " + \
-    "-Wall -Wreturn-type -fno-exceptions -march=pentium -mcpu=pentium"
+    "-Wall -Wreturn-type -fno-exceptions"
 
 ## For now we will link everything against libstdc++ for the
 ## new/delete operators.  gcc 2.95 didn't need it, but it looks like
From hubbe at real.com  Thu Jun 24 09:58:05 2004
From: hubbe at real.com (Fredrik Hubinette)
Date: Thu Jun 24 09:58:07 2004
Subject: [Common-dev] Re: [Ribosome-dev] adjustment to
	linux-2.2-libc6-gcc32-i586.cf
In-Reply-To: Dean Collins's message of "Thu, 24 Jun 2004 00:17:25 -0700"
References: <20040624071725.GP4694@jedi.dev.prognet.com>
Message-ID: <200406241658.i5OGw5fg014544@xianghua.dev.prognet.com>


Looks good to me.

      /Hubbe

Dean Collins  writes:

> To better support some other umakecf changes I need to make,
> I'd like to move the contents of linux-2.2-libc6-gcc32-i586.cf to
> linux-2.2-libc6-gcc32.cf, removing the -march=pentium and -mcpu=pentium
> flags.  Then replace linux-2.2-libc6-gcc32-i586.cf with a simple wrapper
> that includes the non-processor-specific config file, adding the necessary
> -march flags.
> 
> The diff shows the differences between the existing
> linux-2.2-libc6-gcc32-i586.cf and the new generic
> linux-2.2-libc6-gcc32.cf.
> 
> The change will be transparent, and anyone using
> linux-2.2-libc6-gcc32-i586.cf or its derivitives will be unaffected.
> 
> This will go in tomorrow unless someone raises concerns.
> 
> Tested by building the server with a Linux/AMD64 config file (yet to be
> checked in) which inherits from the above.
> 
> Dean
> 
> -- 
> Dean Collins
> Server Technical Lead, RealNetworks, Inc. -- http://www.realnetworks.com
> Helix Server Project Owner -- http://helix-server.helixcommunity.org
> 
> 
> 
> _______________________________________________
> Ribosome-dev mailing list
> Ribosome-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/ribosome-dev

From gwright at real.com  Thu Jun 24 11:43:54 2004
From: gwright at real.com (Greg Wright)
Date: Thu Jun 24 11:43:56 2004
Subject: [Common-dev] Re: [Ribosome-dev] adjustment to
	linux-2.2-libc6-gcc32-i586.cf
References: <20040624071725.GP4694@jedi.dev.prognet.com>
Message-ID: <103701c45a1b$352599d0$ff8317ac@gwright5>

Looks like a good idea to me.
--greg.


----- Original Message ----- 
From: "Dean Collins" 
To: "common-dev" ; "ribosome-dev" ;

Sent: Thursday, June 24, 2004 12:17 AM
Subject: [Ribosome-dev] adjustment to linux-2.2-libc6-gcc32-i586.cf


> To better support some other umakecf changes I need to make,
> I'd like to move the contents of linux-2.2-libc6-gcc32-i586.cf to
> linux-2.2-libc6-gcc32.cf, removing the -march=pentium and -mcpu=pentium
> flags.  Then replace linux-2.2-libc6-gcc32-i586.cf with a simple wrapper
> that includes the non-processor-specific config file, adding the necessary
> -march flags.
>
> The diff shows the differences between the existing
> linux-2.2-libc6-gcc32-i586.cf and the new generic
> linux-2.2-libc6-gcc32.cf.
>
> The change will be transparent, and anyone using
> linux-2.2-libc6-gcc32-i586.cf or its derivitives will be unaffected.
>
> This will go in tomorrow unless someone raises concerns.
>
> Tested by building the server with a Linux/AMD64 config file (yet to be
> checked in) which inherits from the above.
>
> Dean
>
> -- 
> Dean Collins
> Server Technical Lead, RealNetworks, Inc. -- http://www.realnetworks.com
> Helix Server Project Owner -- http://helix-server.helixcommunity.org
>


--------------------------------------------------------------------------------


> _______________________________________________
> Ribosome-dev mailing list
> Ribosome-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/ribosome-dev
>


From liamm at real.com  Thu Jun 24 14:47:25 2004
From: liamm at real.com (Liam Murray)
Date: Thu Jun 24 14:45:29 2004
Subject: [Common-dev] CR: CBigByteGrowingQueue and stlport
Message-ID: <6.1.1.1.0.20040624142059.069ddae0@mailone.real.com>

Here a couple of miscellaneous changes I would like to check in on HEAD 
(along with my other rtsp updates).

1) CBigByteGrowingQueue (common/container/cbbqueue.cpp) was passing around 
void* rather than const void*. This makes it unnecessarily restrictive 
since it doesn't need to modify the data. (In my rtsp client code which 
uses this there were some cases where the data I have is const.)

2) I noticed that stlport was updated. This generates a TON of warning 
messages when compiling with the new platform sdk (msvc60) or .NET (C4103 
"used #pragma pack to change alignment"). This warning is issued if 
alignment is changed vai pragma pack but isn't restore by the end of the 
file and a packing is specified on the command line via /Zp (in which case 
the /Zp is overriden for declarations in other headers). The stlport 
replacement headers do this:

//in stl header
#include "stl/_prolog.h"
#include {native header}
#include "stl/_epilog.h"

so I think it is safe to silence the warning.

Liam


Index: container/cbbqueue.cpp
===================================================================
RCS file: /cvsroot/common/container/cbbqueue.cpp,v
retrieving revision 1.5
diff -u -w -r1.5 cbbqueue.cpp
--- container/cbbqueue.cpp	2 May 2003 16:40:19 -0000	1.5
+++ container/cbbqueue.cpp	24 Jun 2004 21:13:22 -0000
@@ -436,7 +436,7 @@
   *		room for ALL data
   */
  UINT32
-CBigByteQueue::Base_EnQueueBytes( void *pInBuffer, UINT32 ulByteCount )
+CBigByteQueue::Base_EnQueueBytes( const void *pInBuffer, UINT32 ulByteCount )
  {
  	HX_ASSERT( this );
  	HX_ASSERT( IsQueueValid() );
Index: container/cbqueue.cpp
===================================================================
RCS file: /cvsroot/common/container/cbqueue.cpp,v
retrieving revision 1.6
diff -u -w -r1.6 cbqueue.cpp
--- container/cbqueue.cpp	16 Jun 2003 20:35:34 -0000	1.6
+++ container/cbqueue.cpp	24 Jun 2004 21:13:22 -0000
@@ -465,7 +465,7 @@
   *		Should be nByteCount or 0 because we fail if we don't have
   *		room for ALL data
   */
-UINT16 CByteQueue::Base_EnQueueBytes( void *pInBuffer, UINT16 nByteCount )
+UINT16 CByteQueue::Base_EnQueueBytes( const void *pInBuffer, UINT16 
nByteCount )
  {
  	HX_ASSERT( this );
  	HX_ASSERT( IsQueueValid() );
Index: container/pub/cbbqueue.h
===================================================================
RCS file: /cvsroot/common/container/pub/cbbqueue.h,v
retrieving revision 1.2
diff -u -w -r1.2 cbbqueue.h
--- container/pub/cbbqueue.h	4 Mar 2003 18:25:58 -0000	1.2
+++ container/pub/cbbqueue.h	24 Jun 2004 21:13:22 -0000
@@ -386,7 +386,7 @@
  	*	Non-Zero 	To indicate that all items specified were enqueue'd.
  	*
  	*/
-	virtual UINT32 EnQueue( void *pInBuffer, UINT32 ulItemCount )
+	virtual UINT32 EnQueue( const void *pInBuffer, UINT32 ulItemCount )
  	{
  		HX_ASSERT( this );
  		HX_ASSERT( IsQueueValid() );
@@ -537,7 +537,7 @@
  	*	Number of bytes enqueued.
  	*
  	*/
-	UINT32 Base_EnQueueBytes( void *pInBuffer, UINT32 ulByteCount );
+	UINT32 Base_EnQueueBytes( const void *pInBuffer, UINT32 ulByteCount );

     /*
  	** UINT32 Base_DeQueueBytes( pOutBuffer, ulByteCount )
Index: container/pub/cbqueue.h
===================================================================
RCS file: /cvsroot/common/container/pub/cbqueue.h,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 cbqueue.h
--- container/pub/cbqueue.h	18 Oct 2002 01:40:47 -0000	1.1.1.1
+++ container/pub/cbqueue.h	24 Jun 2004 21:13:22 -0000
@@ -428,7 +428,7 @@
  	*	Non-Zero 	To indicate that all items specified were enqueue'd.
  	*
  	*/
-	virtual UINT16 EnQueue( void *pInBuffer, UINT16 nItemCount )
+	virtual UINT16 EnQueue( const void *pInBuffer, UINT16 nItemCount )
  	{
  		HX_ASSERT( this );
  		HX_ASSERT( IsQueueValid() );
@@ -585,7 +585,7 @@
  	*	Number of bytes enqueued.
  	*
  	*/
-	UINT16 Base_EnQueueBytes( void *pInBuffer, UINT16 nByteCount );
+	UINT16 Base_EnQueueBytes( const void *pInBuffer, UINT16 nByteCount );

     /*
  	** UINT16 Base_DeQueueBytes( pOutBuffer, nByteCount )
Index: container/pub/growingq.h
===================================================================
RCS file: /cvsroot/common/container/pub/growingq.h,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 growingq.h
--- container/pub/growingq.h	18 Oct 2002 01:40:48 -0000	1.1.1.1
+++ container/pub/growingq.h	24 Jun 2004 21:13:22 -0000
@@ -58,7 +58,7 @@
      CBigByteGrowingQueue(UINT32 ulSize) :
  	CBigByteQueue(ulSize) {}

-    UINT32 EnQueue( void *pInBuffer, UINT32 ulItemCount )
+    UINT32 EnQueue( const void *pInBuffer, UINT32 ulItemCount )
      {
  	if ( GetAvailableElements() < ulItemCount )
  	{
@@ -79,7 +79,7 @@
      CByteGrowingQueue(UINT16 nSize, UINT16 nGranularity = 1) :
  	CByteQueue(nSize, nGranularity) {}

-    UINT16 EnQueue( void *pInBuffer, UINT16 nItemCount )
+    UINT16 EnQueue( const void *pInBuffer, UINT16 nItemCount )
      {
  	if (GetAvailableElements() < nItemCount)
  	{





Index: import/stlport/stl/_epilog.h
===================================================================
RCS file: /cvsroot/common/import/stlport/stl/_epilog.h,v
retrieving revision 1.4
diff -u -w -r1.4 _epilog.h
--- import/stlport/stl/_epilog.h	4 Jun 2004 20:45:59 -0000	1.4
+++ import/stlport/stl/_epilog.h	24 Jun 2004 21:13:24 -0000
@@ -32,6 +32,11 @@
  #   include 
  #  endif

+//XXXLCM undo warning state and un-disable 4103 (see _prolog.h)
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif
+
  # endif /* __cplusplus */
  # endif

Index: import/stlport/stl/_prolog.h
===================================================================
RCS file: /cvsroot/common/import/stlport/stl/_prolog.h,v
retrieving revision 1.4
diff -u -w -r1.4 _prolog.h
--- import/stlport/stl/_prolog.h	4 Jun 2004 20:45:59 -0000	1.4
+++ import/stlport/stl/_prolog.h	24 Jun 2004 21:13:24 -0000
@@ -6,6 +6,13 @@
  /* We undef "std" on entry , as STLport headers may include native ones. */
  # undef std

+//XXXLCM save warning state and disable 4103 (warning state restored in 
_epilog.h)
+#if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning( disable : 4103) // used #pragma pack to change alignment
+#endif
+
  # ifndef _STLP_CONFIG_H
  #  include 
  # endif


From liamm at real.com  Thu Jun 24 15:18:30 2004
From: liamm at real.com (Liam Murray)
Date: Thu Jun 24 15:16:31 2004
Subject: [Common-dev] CR: updates to common/netio for rtsp client
Message-ID: <6.1.1.1.0.20040624144729.04a89e70@mailone.real.com>

Branch: HEAD only

Summary:

I want to check in some further rtsp client fixes and updates so that rtsp 
client networking works (udp and tcp transport at least).

These are updates to netio/common mainly to get multicast support for the 
multicast transport in the rtsp protocol code.

Overview:

1) Add the following to IHXSocket (in hxnet.h)


STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface) PURE;

STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface) PURE;

This is intended as an interim change and subject to change. I want this 
support now in order to test multicast transport in the rtsp client code.

People had differing opinions about whether these should be here (in 
IHXSocket) or in a separate interface (e.g., IHXMulticastSocket derived 
from IHXSocket) or if we should just expose multicast configuration via the 
existing Set/GetOption and do away with convenience interfaces altogether. 
(The derivation idea seems weird given these are com, not c++, interfaces, 
btw.)

Since Avijit is working on multicast and will suggest IGMPv3 changes, we 
can settle on a better solution at that time.


2) Update common/netio/posix/chxsockimp.cpp so it implements working 
versions of the multicast methods. To do this chxsockimp requires access to 
the underlying setsockopt via hx_setsockopt (netdrv.cpp). I therefore 
updated common/netio/posix/netdrv.{h,cpp} so it offers an hx_setsockopt 
taking a const void* for implementing the multicast join/leave.

3) Added some asserts to the address class methods where set methods are 
called for addresses and ports to ensure there is only one ref. Almost 
always a call to alter the address/port when the ref count is greater than 
1 indicates an error.

(I seem to vaguely recall we treat an IHXBuffer object with a ref count > 1 
as a const buffer and fail if Set is called. Do we in fact do this?)


Files modified:

common/include/hxnet.h
common/netio/platform/posix/netdrv.cpp
common/netio/platform/posix/sockimp.cpp
common/netio/pub/platform/posix/netdrv.h
common/netio/pub/platform/posix/sockimp.h

Liam


Index: include/hxnet.h
===================================================================
RCS file: /cvsroot/common/include/hxnet.h,v
retrieving revision 1.8
diff -u -w -r1.8 hxnet.h
--- include/hxnet.h	18 Jun 2004 19:41:41 -0000	1.8
+++ include/hxnet.h	24 Jun 2004 21:13:25 -0000
@@ -542,6 +542,23 @@
      STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) 
PURE;
      STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;

+    /* NULL may be passed for pInterface to indicate INADDR_ANY */
+    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface) PURE;
+    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface) PURE;
+
+
      STDMETHOD_(INT32,ReadV)         (THIS_ UINT32 nVecLen, IHXBuffer** 
ppVec) PURE;
      STDMETHOD_(INT32,ReadFrom)      (THIS_ IHXBuffer* pBuf, IHXSockAddr* 
pAddr) PURE;
      STDMETHOD_(INT32,ReadFromV)     (THIS_ UINT32 nVecLen, IHXBuffer** ppVec,
@@ -553,18 +570,9 @@
                                             IHXSockAddr* pAddr) PURE;
  };

-/******************************************************************************
- *
- * WARNING: Everything below here is particularly volatile:
- *
- *   - Multicast work has not really started yet for the new API.
- *   - The listening socket is redundant (but we'll probably keep it).
- *   - The AddrInfo flags need Helix-ized.
- *   - Net services may need tweaked.
- *
- 
******************************************************************************/

-DEFINE_GUID(IID_IHXMulticastSocket, 0xa9561368, 0x7c47, 0x11d8, 0x8b, 
0xcb, 0x00,
+
+/*DEFINE_GUID(IID_IHXMulticastSocket, 0xa9561368, 0x7c47, 0x11d8, 0x8b, 
0xcb, 0x00,
              0x02, 0xb3, 0x65, 0x87, 0x20);
  #undef INTERFACE
  #define INTERFACE IHXMulticastSocket
@@ -574,9 +582,10 @@
      STDMETHOD_(ULONG32,AddRef)      (THIS) PURE;
      STDMETHOD_(ULONG32,Release)     (THIS) PURE;

-    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
-    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
-};
+    // NULL may be passed for pInterface to indicate INADDR_ANY
+    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface, UINT32 ttl) PURE;
+    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface, UINT32 ttl) PURE;
+};*/

  DEFINE_GUID(IID_IHXListeningSocketResponse, 0xa95686b8, 0x7c47, 0x11d8, 
0x8b, 0xcb, 0x00,
              0x02, 0xb3, 0x65, 0x87, 0x20);



Index: netio/pub/platform/posix/netdrv.h
===================================================================
RCS file: /cvsroot/common/netio/pub/platform/posix/netdrv.h,v
retrieving revision 1.4
diff -u -w -r1.4 netdrv.h
--- netio/pub/platform/posix/netdrv.h	27 May 2004 03:30:53 -0000	1.4
+++ netio/pub/platform/posix/netdrv.h	24 Jun 2004 21:13:25 -0000
@@ -86,6 +86,10 @@
  int         hx_getsockopt(HX_SOCK* s, UINT32 name, UINT32* valp);
  int         hx_setsockopt(HX_SOCK* s, UINT32 name, UINT32 val);

+int         hx_setsockopt(HX_SOCK* s, UINT32 name, const void* data, 
UINT32 len);
+//int         hx_getsockopt(HX_SOCK* s, UINT32 name, const void* data)
+
+
  ssize_t     hx_peek(HX_SOCK* s, void* buf, size_t len);
  ssize_t     hx_read(HX_SOCK* s, void* buf, size_t len);
  ssize_t     hx_readv(HX_SOCK* s, UINT32 vlen, const hx_iov* iov);
Index: netio/pub/platform/posix/sockimp.h
===================================================================
RCS file: /cvsroot/common/netio/pub/platform/posix/sockimp.h,v
retrieving revision 1.6
diff -u -w -r1.6 sockimp.h
--- netio/pub/platform/posix/sockimp.h	18 Jun 2004 19:41:41 -0000	1.6
+++ netio/pub/platform/posix/sockimp.h	24 Jun 2004 21:13:26 -0000
@@ -264,6 +264,9 @@
      STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval);
      STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val);

+    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface);
+    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
IHXSockAddr* pInterface);
+
      STDMETHOD_(INT32,ReadV)         (THIS_ UINT32 nVecLen, IHXBuffer** 
ppVec);
      STDMETHOD_(INT32,ReadFrom)      (THIS_ IHXBuffer* pBuf, IHXSockAddr* 
pAddr);
      STDMETHOD_(INT32,ReadFromV)     (THIS_ UINT32 nVecLen, IHXBuffer** ppVec,
@@ -276,7 +279,10 @@

      STDMETHOD(Func)                 (THIS);

+
  protected:
+    STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl);
+
      INT32                       m_nRefCount;
      CHXNetServices*             m_pNetSvc;
      IHXScheduler*               m_pScheduler;
@@ -293,28 +299,6 @@
      CHXSocketConnectEnumerator* m_pEnumerator;
  };

-class CHXMulticastSocket : public CHXSocket,
-                           public IHXMulticastSocket
-{
-private:    // Unimplemented
-    CHXMulticastSocket(const CHXMulticastSocket&);
-    CHXMulticastSocket& operator=(const CHXMulticastSocket&);
-
-public:
-    CHXMulticastSocket(void);
-    // No need for a dtor
-    // virtual ~CHXMulticastSocket(void);
-
-    STDMETHOD(QueryInterface)       (THIS_ REFIID riid, void** ppvObj);
-    STDMETHOD_(ULONG32,AddRef)      (THIS);
-    STDMETHOD_(ULONG32,Release)     (THIS);
-
-    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr);
-    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr);
-
-protected:
-    INT32                       m_nRefCount;
-};

  /*
   * The listening socket is just a wrapper around an IHXSocket.

Index: netio/platform/posix/netdrv.cpp
===================================================================
RCS file: /cvsroot/common/netio/platform/posix/netdrv.cpp,v
retrieving revision 1.10
diff -u -w -r1.10 netdrv.cpp
--- netio/platform/posix/netdrv.cpp	23 Jun 2004 22:35:08 -0000	1.10
+++ netio/platform/posix/netdrv.cpp	24 Jun 2004 21:13:25 -0000
@@ -828,14 +828,11 @@
  }

  int
-hx_setsockopt(HX_SOCK* s, UINT32 name, UINT32 val)
+hx_setsockopt(HX_SOCK* s, UINT32 name, const void* data, UINT32 len)
  {
-    int rc;
-    int optlevel;
-    int optname;
-    const char* vp;
-    socklen_t vlen;
-    linger ling;
+    HX_ASSERT(s);
+    HX_ASSERT(data);
+
      if (name >= HX_SOCKOPT_LAST)
      {
          return -1;
@@ -852,23 +849,33 @@
          return -1;
      }
  #endif
-    optlevel = g_hxopttbl[name].level;
-    optname = g_hxopttbl[name].name;
-    vp = (const char*)&val;
-    vlen = sizeof(val);
+
+    int optlevel = g_hxopttbl[name].level;
+    int optname = g_hxopttbl[name].name;
+
+    linger ling;
      if (name == (UINT32)HX_SOCKOPT_LINGER)
      {
          memset(&ling, 0, sizeof(ling));
+
+        int val = *((int*)data);
          if (val != (UINT32)(~0))
          {
              ling.l_onoff = 1;
              ling.l_linger = (int)val;
          }
-        vp = (const char*)&ling;
-        vlen = sizeof(ling);
+
+        data = &ling;
+        len = sizeof(ling);
      }
-    rc = ::setsockopt(s->sock, optlevel, optname, vp, vlen);
-    return rc;
+
+    return ::setsockopt(s->sock, optlevel, optname, (const char*)data, len);
+}
+
+int
+hx_setsockopt(HX_SOCK* s, UINT32 name, UINT32 val)
+{
+    return hx_setsockopt(s, name, &val, sizeof(val));
  }

  ssize_t
Index: netio/platform/posix/sockimp.cpp
===================================================================
RCS file: /cvsroot/common/netio/platform/posix/sockimp.cpp,v
retrieving revision 1.11
diff -u -w -r1.11 sockimp.cpp
--- netio/platform/posix/sockimp.cpp	18 Jun 2004 19:41:41 -0000	1.11
+++ netio/platform/posix/sockimp.cpp	24 Jun 2004 21:13:25 -0000
@@ -375,6 +375,7 @@
  STDMETHODIMP
  CHXSockAddrIN4::SetAddr(const char* pBuf)
  {
+    HX_ASSERT(m_nRefCount == 1);
      HX_RESULT rc = HXR_OK;
      if (hx_inet_aton(pBuf, &m_addr.sin_addr) <= 0)
      {
@@ -406,6 +407,7 @@
  STDMETHODIMP
  CHXSockAddrIN4::SetPort(const char* pBuf)
  {
+    HX_ASSERT(m_nRefCount == 1);
      m_addr.sin_port = hx_htons((in_port_t)atoi(pBuf));
      return HXR_OK;
  }
@@ -440,6 +442,7 @@
  STDMETHODIMP
  CHXSockAddrIN4::AddPort(UINT16 n)
  {
+    HX_ASSERT(m_nRefCount == 1);
      m_addr.sin_port = hx_htons(hx_ntohs(m_addr.sin_port)+n);
      return HXR_OK;
  }
@@ -447,6 +450,7 @@
  STDMETHODIMP
  CHXSockAddrIN4::SubPort(UINT16 n)
  {
+    HX_ASSERT(m_nRefCount == 1);
      m_addr.sin_port = hx_htons(hx_ntohs(m_addr.sin_port)-n);
      return HXR_OK;
  }
@@ -631,6 +635,7 @@
  STDMETHODIMP
  CHXSockAddrIN6::SetAddr(const char* pBuf)
  {
+    HX_ASSERT(m_nRefCount == 1);
      HX_RESULT rc = HXR_OK;

      if (hx_inet_pton(AF_INET6, pBuf, &m_addr.sin6_addr) <= 0)
@@ -663,6 +668,7 @@
  STDMETHODIMP
  CHXSockAddrIN6::SetPort(const char* pBuf)
  {
+    HX_ASSERT(m_nRefCount == 1);
      m_addr.sin6_port = hx_htons((in_port_t)atoi(pBuf));
      return HXR_OK;
  }
@@ -697,6 +703,7 @@
  STDMETHODIMP
  CHXSockAddrIN6::AddPort(UINT16 n)
  {
+    HX_ASSERT(m_nRefCount == 1);
      m_addr.sin6_port = hx_htons(hx_ntohs(m_addr.sin6_port)+n);
      return HXR_OK;
  }
@@ -704,6 +711,7 @@
  STDMETHODIMP
  CHXSockAddrIN6::SubPort(UINT16 n)
  {
+    HX_ASSERT(m_nRefCount == 1);
      m_addr.sin6_port = hx_htons(hx_ntohs(m_addr.sin6_port)-n);
      return HXR_OK;
  }
@@ -719,6 +727,7 @@
  STDMETHODIMP_(BOOL)
  CHXSockAddrIN6::Set(void* src)
  {
+    HX_ASSERT(m_nRefCount == 1);
      sockaddr_storage* psa = (sockaddr_storage*)src;
      if (psa->ss_family != AF_INET6)
      {
@@ -1149,6 +1158,12 @@
          *ppvObj = (IHXSocket*)this;
          return HXR_OK;
      }
+    /*if (IsEqualIID(riid, IID_IHXMulticastSocket))
+    {
+        AddRef();
+        *ppvObj = (IHXMulticastSocket*)this;
+        return HXR_OK;
+    }*/
      *ppvObj = NULL;
      return HXR_NOINTERFACE;
  }
@@ -1762,115 +1777,206 @@
      return HXR_OK;
  }

-/*** CHXMulticastSocket ***/
+// HELIX_FEATURE_MULTICAST

-CHXMulticastSocket::CHXMulticastSocket(void) :
-    /* XXTDM: fixme */
-    CHXSocket(NULL, NULL),
-    m_nRefCount(0)
+/*
+ * IHXMulticastSocket
+ */
+
+static
+HX_RESULT SetMulticastInfoIPV6(IHXSockAddr* pGroupAddr,
+                               IHXSockAddr* pInterface,
+                               ipv6_mreq& req)
  {
-    // Empty
-}
+    HX_ASSERT(pGroupAddr);
+    HX_ASSERT(HX_SOCK_FAMILY_IN6 == pGroupAddr->GetFamily());

-STDMETHODIMP
-CHXMulticastSocket::QueryInterface(REFIID riid, void** ppvObj)
+    memset(&req, 0, sizeof(req));
+
+    sockaddr_in6 sa;
+    memset(&sa, 0, sizeof(sa));
+    pGroupAddr->Get(&sa);
+
+    req.ipv6mr_multiaddr = sa.sin6_addr; // mcast group address to join
+
+    if(pInterface)
  {
-    if (IsEqualIID(riid, IID_IUnknown))
+        HX_ASSERT(false); // XXXLCM see below; ipv6mr_interface is index, 
not address
+
+        // Windows uses GetAdaptersAddresses() for index; Linux netdevice 
(net/if.h)
+        if(pInterface->GetFamily() == HX_SOCK_FAMILY_IN6)
      {
-        AddRef();
-        *ppvObj = (IUnknown*)(IHXSocket*)this;
-        return HXR_OK;
+            memset(&sa, 0, sizeof(sa));
+            pGroupAddr->Get(&sa);
+            req.ipv6mr_interface = 0; //sa.sin_addr; // interface to join on
      }
-    if (IsEqualIID(riid, IID_IHXSocket))
+        else
      {
-        AddRef();
-        *ppvObj = (IHXSocket*)this;
-        return HXR_OK;
+            // interface family does not match group family
+            HX_ASSERT(false);
+            return HXR_INVALID_PARAMETER;
+        }
      }
-    if (IsEqualIID(riid, IID_IHXMulticastSocket))
+    else
      {
-        AddRef();
-        *ppvObj = (IHXMulticastSocket*)this;
-        return HXR_OK;
+        req.ipv6mr_interface = 0;
      }
-    *ppvObj = NULL;
-    return HXR_NOINTERFACE;
+
+    return HXR_OK;
  }

-STDMETHODIMP_(ULONG32)
-CHXMulticastSocket::AddRef(void)
+static
+HX_RESULT SetMulticastInfoIPV4(IHXSockAddr* pGroupAddr,
+                               IHXSockAddr* pInterface,
+                               ip_mreq& req)
  {
-    return InterlockedIncrement(&m_nRefCount);
-}
+    HX_ASSERT(pGroupAddr);
+    HX_ASSERT(HX_SOCK_FAMILY_IN4 == pGroupAddr->GetFamily());

-STDMETHODIMP_(ULONG32)
-CHXMulticastSocket::Release(void)
+    memset(&req, 0, sizeof(req));
+
+    sockaddr_in sa;
+    memset(&sa, 0, sizeof(sa));
+    pGroupAddr->Get(&sa);
+
+    req.imr_multiaddr = sa.sin_addr; // mcast group address to join
+
+    if(pInterface)
  {
-    HX_ASSERT(m_nRefCount > 0);
-    INT32 rc = InterlockedDecrement(&m_nRefCount);
-    if (rc == 0)
+        if(pInterface->GetFamily() == HX_SOCK_FAMILY_IN4)
      {
-        delete this;
+            memset(&sa, 0, sizeof(sa));
+            pGroupAddr->Get(&sa);
+            req.imr_interface = sa.sin_addr; // interface to join on
+        }
+        else
+        {
+            // interface family does not match group family
+            HX_ASSERT(false);
+            return HXR_INVALID_PARAMETER;
      }
-    return rc;
  }

-// For BeOS etc.
-#if defined(HELIX_FEATURE_MULTICAST)
-
+    return HXR_OK;
+}
+// private helper
  STDMETHODIMP
-CHXMulticastSocket::JoinMulticastGroup(IHXSockAddr* pAddr)
+CHXSocket::SetMulticastTTL(UINT32 ttl)
  {
-    UINT32 val;
-    ip_mreq req;
-    val = 254; //XXXTDM: hardcoded in unix_net
-    if (setsockopt(m_sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) != 0)
+    int name = HX_SOCKOPT_NONE;
+    if(m_family == HX_SOCK_FAMILY_IN4)
      {
-        return HXR_FAIL;
+        name = HX_SOCKOPT_IN4_MULTICAST_TTL;
      }
-    memset(&req, 0, sizeof(req));
-    req.imr_multiaddr = pAddr->m_addr;
-#ifdef _UNIX
-    req.imr_interface = INADDR_ANY;
-#else
-    req.imr_interface = pIfAddr->m_addr;
-#endif
-    if (setsockopt(m_sock, SOL_IP, IP_ADD_MEMBERSHIP, (const char*)req, 
sizeof(req)) != 0)
+    else if(m_family == HX_SOCK_FAMILY_IN6)
+    {
+        name = HX_SOCKOPT_IN6_MULTICAST_HOPS;
+    }
+    else
+    {
+        return HXR_UNEXPECTED; //'invalid family'
+    }
+
+    if (hx_setsockopt(&m_sock, name, &ttl, sizeof(ttl)) != 0)
      {
          return HXR_FAIL;
      }
+
      return HXR_OK;
  }

+
  STDMETHODIMP
-CHXMulticastSocket::LeaveMulticastGroup(IHXSockAddr* pAddr)
+CHXSocket::JoinMulticastGroup(IHXSockAddr* pGroupAddr,
+                              IHXSockAddr* pInterface)
+{
+    HX_ASSERT(pGroupAddr);
+    if(!pGroupAddr)
+    {
+        return HXR_INVALID_PARAMETER;
+    }
+
+    HX_RESULT hr = HXR_FAIL;
+
+    SetMulticastTTL(254); //XXXLCM hardcode for now
+
+    HXSockFamily family = pGroupAddr->GetFamily();
+
+    if (HX_SOCK_FAMILY_IN4 == family)
  {
      ip_mreq req;
-    memset(&req, 0, sizeof(req));
-    req.imr_multiaddr = pAddr->m_addr;
-    req.imr_interface = pIfAddr->m_addr;
-    if (setsockopt(m_sock, SOL_IP, IP_DROP_MEMBERSHIP, (const char*)req, 
sizeof(req)) != 0)
+        hr = SetMulticastInfoIPV4(pGroupAddr, pInterface, req);
+        if(SUCCEEDED(hr))
      {
-        return HXR_FAIL;
+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN4_ADD_MEMBERSHIP, 
&req, sizeof(req)) != 0)
+            {
+                hr = HXR_FAIL;
+            }
+        }
+    }
+    else if (HX_SOCK_FAMILY_IN6 == family)
+    {
+        ipv6_mreq req;
+        hr = SetMulticastInfoIPV6(pGroupAddr, pInterface, req);
+        if(SUCCEEDED(hr))
+        {
+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN6_JOIN_GROUP, &req, 
sizeof(req)) != 0)
+            {
+                hr = HXR_FAIL;
+            }
      }
-    return HXR_OK;
+    }
+    else
+    {
+        HX_ASSERT(false);
+        hr = HXR_UNEXPECTED; // 'unsupported family'
+    }
+
+    return hr;
  }

-#else /* !defined(HELIX_FEATURE_MULTICAST) */

  STDMETHODIMP
-CHXMulticastSocket::JoinMulticastGroup(IHXSockAddr* pAddr)
+CHXSocket::LeaveMulticastGroup(IHXSockAddr* pGroupAddr,
+                               IHXSockAddr* pInterface)
  {
-    return HXR_NOTIMPL;
-}
+    HX_RESULT hr = HXR_FAIL;

-STDMETHODIMP
-CHXMulticastSocket::LeaveMulticastGroup(IHXSockAddr* pAddr)
+    HXSockFamily family = pGroupAddr->GetFamily();
+
+    if (HX_SOCK_FAMILY_IN4 == family)
+    {
+        ip_mreq req;
+        hr = SetMulticastInfoIPV4(pGroupAddr, pInterface, req);
+        if(SUCCEEDED(hr))
+        {
+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN4_DROP_MEMBERSHIP, 
&req, sizeof(req)) != 0)
+            {
+                hr = HXR_FAIL;
+            }
+        }
+    }
+    else if (HX_SOCK_FAMILY_IN6 == family)
+    {
+        ipv6_mreq req;
+        hr = SetMulticastInfoIPV6(pGroupAddr, pInterface, req);
+        if(SUCCEEDED(hr))
+        {
+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN6_LEAVE_GROUP, &req, 
sizeof(req)) != 0)
+            {
+                hr = HXR_FAIL;
+            }
+        }
+    }
+    else
  {
-    return HXR_NOTIMPL;
+        HX_ASSERT(false);
+        hr = HXR_FAIL; // 'unsupported family'
+    }
+
+    return hr;
  }

-#endif /* defined(HELIX_FEATURE_MULTICAST) */

  /*** CHXListeningSocket ***/


From dhedbor at real.com  Thu Jun 24 18:24:21 2004
From: dhedbor at real.com (David Hedbor)
Date: Thu Jun 24 18:24:25 2004
Subject: [Common-dev] CR: Cast from int to CPUArchitecture enum
Message-ID: <1088126661.2986.359.camel@atlantis.prognet.com>

Branch: HEAD and hxclient_1_3_0_neptunex

Description: 

In the ARM cpu ident code the CPUArchitecture enum (pInfo->architecture)
is assigned an integer value without a cast. This breaks when compiling
with gcc 3.x. 

Fix: 

Added an explicit cast.

Files modified:

common/util/cpuident.c

--
David Hedbor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cpuident.patch
Type: text/x-patch
Size: 903 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040624/96f0c89a/cpuident.bin
From liamm at real.com  Thu Jun 24 18:57:25 2004
From: liamm at real.com (Liam Murray)
Date: Thu Jun 24 18:55:26 2004
Subject: [Common-dev] CN: updates to common/netio for rtsp client
In-Reply-To: <6.1.1.1.0.20040624144729.04a89e70@mailone.real.com>
References: <6.1.1.1.0.20040624144729.04a89e70@mailone.real.com>
Message-ID: <6.1.1.1.0.20040624184413.045c1c20@mailone.real.com>

I went ahead and checked this in along with updates and fixes to the rtsp 
client code so the HEAD should now function (to some degree) with respect 
to network streaming.

Both tcp or udp transport should work (but I'm not sure about performance 
or simultaneous sessions e.g. via smil). Multicast transport probably won't 
work yet.  HTTP cloaking won't work.

(I'm sure Tom will want to comment when he gets back from vacation.)

Liam

At 03:18 PM 6/24/2004, Liam Murray wrote:
>Branch: HEAD only
>
>Summary:
>
>I want to check in some further rtsp client fixes and updates so that rtsp 
>client networking works (udp and tcp transport at least).
>
>These are updates to netio/common mainly to get multicast support for the 
>multicast transport in the rtsp protocol code.
>
>Overview:
>
>1) Add the following to IHXSocket (in hxnet.h)
>
>
>STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface) PURE;
>
>STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface) PURE;
>
>This is intended as an interim change and subject to change. I want this 
>support now in order to test multicast transport in the rtsp client code.
>
>People had differing opinions about whether these should be here (in 
>IHXSocket) or in a separate interface (e.g., IHXMulticastSocket derived 
>from IHXSocket) or if we should just expose multicast configuration via 
>the existing Set/GetOption and do away with convenience interfaces 
>altogether. (The derivation idea seems weird given these are com, not c++, 
>interfaces, btw.)
>
>Since Avijit is working on multicast and will suggest IGMPv3 changes, we 
>can settle on a better solution at that time.
>
>
>2) Update common/netio/posix/chxsockimp.cpp so it implements working 
>versions of the multicast methods. To do this chxsockimp requires access 
>to the underlying setsockopt via hx_setsockopt (netdrv.cpp). I therefore 
>updated common/netio/posix/netdrv.{h,cpp} so it offers an hx_setsockopt 
>taking a const void* for implementing the multicast join/leave.
>
>3) Added some asserts to the address class methods where set methods are 
>called for addresses and ports to ensure there is only one ref. Almost 
>always a call to alter the address/port when the ref count is greater than 
>1 indicates an error.
>
>(I seem to vaguely recall we treat an IHXBuffer object with a ref count > 
>1 as a const buffer and fail if Set is called. Do we in fact do this?)
>
>
>Files modified:
>
>common/include/hxnet.h
>common/netio/platform/posix/netdrv.cpp
>common/netio/platform/posix/sockimp.cpp
>common/netio/pub/platform/posix/netdrv.h
>common/netio/pub/platform/posix/sockimp.h
>
>Liam
>
>
>Index: include/hxnet.h
>===================================================================
>RCS file: /cvsroot/common/include/hxnet.h,v
>retrieving revision 1.8
>diff -u -w -r1.8 hxnet.h
>--- include/hxnet.h     18 Jun 2004 19:41:41 -0000      1.8
>+++ include/hxnet.h     24 Jun 2004 21:13:25 -0000
>@@ -542,6 +542,23 @@
>      STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval) 
> PURE;
>      STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val) PURE;
>
>+    /* NULL may be passed for pInterface to indicate INADDR_ANY */
>+    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface) PURE;
>+    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface) PURE;
>+
>+
>      STDMETHOD_(INT32,ReadV)         (THIS_ UINT32 nVecLen, IHXBuffer** 
> ppVec) PURE;
>      STDMETHOD_(INT32,ReadFrom)      (THIS_ IHXBuffer* pBuf, IHXSockAddr* 
> pAddr) PURE;
>      STDMETHOD_(INT32,ReadFromV)     (THIS_ UINT32 nVecLen, IHXBuffer** 
> ppVec,
>@@ -553,18 +570,9 @@
>                                             IHXSockAddr* pAddr) PURE;
>  };
>
>-/******************************************************************************
>- *
>- * WARNING: Everything below here is particularly volatile:
>- *
>- *   - Multicast work has not really started yet for the new API.
>- *   - The listening socket is redundant (but we'll probably keep it).
>- *   - The AddrInfo flags need Helix-ized.
>- *   - Net services may need tweaked.
>- *
>- 
>******************************************************************************/
>
>-DEFINE_GUID(IID_IHXMulticastSocket, 0xa9561368, 0x7c47, 0x11d8, 0x8b, 
>0xcb, 0x00,
>+
>+/*DEFINE_GUID(IID_IHXMulticastSocket, 0xa9561368, 0x7c47, 0x11d8, 0x8b, 
>0xcb, 0x00,
>              0x02, 0xb3, 0x65, 0x87, 0x20);
>  #undef INTERFACE
>  #define INTERFACE IHXMulticastSocket
>@@ -574,9 +582,10 @@
>      STDMETHOD_(ULONG32,AddRef)      (THIS) PURE;
>      STDMETHOD_(ULONG32,Release)     (THIS) PURE;
>
>-    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr) PURE;
>-    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr) PURE;
>-};
>+    // NULL may be passed for pInterface to indicate INADDR_ANY
>+    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface, UINT32 ttl) PURE;
>+    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface, UINT32 ttl) PURE;
>+};*/
>
>  DEFINE_GUID(IID_IHXListeningSocketResponse, 0xa95686b8, 0x7c47, 0x11d8, 
> 0x8b, 0xcb, 0x00,
>              0x02, 0xb3, 0x65, 0x87, 0x20);
>
>
>
>Index: netio/pub/platform/posix/netdrv.h
>===================================================================
>RCS file: /cvsroot/common/netio/pub/platform/posix/netdrv.h,v
>retrieving revision 1.4
>diff -u -w -r1.4 netdrv.h
>--- netio/pub/platform/posix/netdrv.h   27 May 2004 03:30:53 -0000      1.4
>+++ netio/pub/platform/posix/netdrv.h   24 Jun 2004 21:13:25 -0000
>@@ -86,6 +86,10 @@
>  int         hx_getsockopt(HX_SOCK* s, UINT32 name, UINT32* valp);
>  int         hx_setsockopt(HX_SOCK* s, UINT32 name, UINT32 val);
>
>+int         hx_setsockopt(HX_SOCK* s, UINT32 name, const void* data, 
>UINT32 len);
>+//int         hx_getsockopt(HX_SOCK* s, UINT32 name, const void* data)
>+
>+
>  ssize_t     hx_peek(HX_SOCK* s, void* buf, size_t len);
>  ssize_t     hx_read(HX_SOCK* s, void* buf, size_t len);
>  ssize_t     hx_readv(HX_SOCK* s, UINT32 vlen, const hx_iov* iov);
>Index: netio/pub/platform/posix/sockimp.h
>===================================================================
>RCS file: /cvsroot/common/netio/pub/platform/posix/sockimp.h,v
>retrieving revision 1.6
>diff -u -w -r1.6 sockimp.h
>--- netio/pub/platform/posix/sockimp.h  18 Jun 2004 19:41:41 -0000      1.6
>+++ netio/pub/platform/posix/sockimp.h  24 Jun 2004 21:13:26 -0000
>@@ -264,6 +264,9 @@
>      STDMETHOD(GetOption)            (THIS_ HXSockOpt name, UINT32* pval);
>      STDMETHOD(SetOption)            (THIS_ HXSockOpt name, UINT32 val);
>
>+    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface);
>+    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pGroupAddr, 
>IHXSockAddr* pInterface);
>+
>      STDMETHOD_(INT32,ReadV)         (THIS_ UINT32 nVecLen, IHXBuffer** 
> ppVec);
>      STDMETHOD_(INT32,ReadFrom)      (THIS_ IHXBuffer* pBuf, IHXSockAddr* 
> pAddr);
>      STDMETHOD_(INT32,ReadFromV)     (THIS_ UINT32 nVecLen, IHXBuffer** 
> ppVec,
>@@ -276,7 +279,10 @@
>
>      STDMETHOD(Func)                 (THIS);
>
>+
>  protected:
>+    STDMETHOD(SetMulticastTTL)      (THIS_ UINT32 ttl);
>+
>      INT32                       m_nRefCount;
>      CHXNetServices*             m_pNetSvc;
>      IHXScheduler*               m_pScheduler;
>@@ -293,28 +299,6 @@
>      CHXSocketConnectEnumerator* m_pEnumerator;
>  };
>
>-class CHXMulticastSocket : public CHXSocket,
>-                           public IHXMulticastSocket
>-{
>-private:    // Unimplemented
>-    CHXMulticastSocket(const CHXMulticastSocket&);
>-    CHXMulticastSocket& operator=(const CHXMulticastSocket&);
>-
>-public:
>-    CHXMulticastSocket(void);
>-    // No need for a dtor
>-    // virtual ~CHXMulticastSocket(void);
>-
>-    STDMETHOD(QueryInterface)       (THIS_ REFIID riid, void** ppvObj);
>-    STDMETHOD_(ULONG32,AddRef)      (THIS);
>-    STDMETHOD_(ULONG32,Release)     (THIS);
>-
>-    STDMETHOD(JoinMulticastGroup)   (THIS_ IHXSockAddr* pAddr);
>-    STDMETHOD(LeaveMulticastGroup)  (THIS_ IHXSockAddr* pAddr);
>-
>-protected:
>-    INT32                       m_nRefCount;
>-};
>
>  /*
>   * The listening socket is just a wrapper around an IHXSocket.
>
>Index: netio/platform/posix/netdrv.cpp
>===================================================================
>RCS file: /cvsroot/common/netio/platform/posix/netdrv.cpp,v
>retrieving revision 1.10
>diff -u -w -r1.10 netdrv.cpp
>--- netio/platform/posix/netdrv.cpp     23 Jun 2004 22:35:08 -0000      1.10
>+++ netio/platform/posix/netdrv.cpp     24 Jun 2004 21:13:25 -0000
>@@ -828,14 +828,11 @@
>  }
>
>  int
>-hx_setsockopt(HX_SOCK* s, UINT32 name, UINT32 val)
>+hx_setsockopt(HX_SOCK* s, UINT32 name, const void* data, UINT32 len)
>  {
>-    int rc;
>-    int optlevel;
>-    int optname;
>-    const char* vp;
>-    socklen_t vlen;
>-    linger ling;
>+    HX_ASSERT(s);
>+    HX_ASSERT(data);
>+
>      if (name >= HX_SOCKOPT_LAST)
>      {
>          return -1;
>@@ -852,23 +849,33 @@
>          return -1;
>      }
>  #endif
>-    optlevel = g_hxopttbl[name].level;
>-    optname = g_hxopttbl[name].name;
>-    vp = (const char*)&val;
>-    vlen = sizeof(val);
>+
>+    int optlevel = g_hxopttbl[name].level;
>+    int optname = g_hxopttbl[name].name;
>+
>+    linger ling;
>      if (name == (UINT32)HX_SOCKOPT_LINGER)
>      {
>          memset(&ling, 0, sizeof(ling));
>+
>+        int val = *((int*)data);
>          if (val != (UINT32)(~0))
>          {
>              ling.l_onoff = 1;
>              ling.l_linger = (int)val;
>          }
>-        vp = (const char*)&ling;
>-        vlen = sizeof(ling);
>+
>+        data = &ling;
>+        len = sizeof(ling);
>      }
>-    rc = ::setsockopt(s->sock, optlevel, optname, vp, vlen);
>-    return rc;
>+
>+    return ::setsockopt(s->sock, optlevel, optname, (const char*)data, len);
>+}
>+
>+int
>+hx_setsockopt(HX_SOCK* s, UINT32 name, UINT32 val)
>+{
>+    return hx_setsockopt(s, name, &val, sizeof(val));
>  }
>
>  ssize_t
>Index: netio/platform/posix/sockimp.cpp
>===================================================================
>RCS file: /cvsroot/common/netio/platform/posix/sockimp.cpp,v
>retrieving revision 1.11
>diff -u -w -r1.11 sockimp.cpp
>--- netio/platform/posix/sockimp.cpp    18 Jun 2004 19:41:41 -0000      1.11
>+++ netio/platform/posix/sockimp.cpp    24 Jun 2004 21:13:25 -0000
>@@ -375,6 +375,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN4::SetAddr(const char* pBuf)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      HX_RESULT rc = HXR_OK;
>      if (hx_inet_aton(pBuf, &m_addr.sin_addr) <= 0)
>      {
>@@ -406,6 +407,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN4::SetPort(const char* pBuf)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      m_addr.sin_port = hx_htons((in_port_t)atoi(pBuf));
>      return HXR_OK;
>  }
>@@ -440,6 +442,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN4::AddPort(UINT16 n)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      m_addr.sin_port = hx_htons(hx_ntohs(m_addr.sin_port)+n);
>      return HXR_OK;
>  }
>@@ -447,6 +450,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN4::SubPort(UINT16 n)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      m_addr.sin_port = hx_htons(hx_ntohs(m_addr.sin_port)-n);
>      return HXR_OK;
>  }
>@@ -631,6 +635,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN6::SetAddr(const char* pBuf)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      HX_RESULT rc = HXR_OK;
>
>      if (hx_inet_pton(AF_INET6, pBuf, &m_addr.sin6_addr) <= 0)
>@@ -663,6 +668,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN6::SetPort(const char* pBuf)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      m_addr.sin6_port = hx_htons((in_port_t)atoi(pBuf));
>      return HXR_OK;
>  }
>@@ -697,6 +703,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN6::AddPort(UINT16 n)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      m_addr.sin6_port = hx_htons(hx_ntohs(m_addr.sin6_port)+n);
>      return HXR_OK;
>  }
>@@ -704,6 +711,7 @@
>  STDMETHODIMP
>  CHXSockAddrIN6::SubPort(UINT16 n)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      m_addr.sin6_port = hx_htons(hx_ntohs(m_addr.sin6_port)-n);
>      return HXR_OK;
>  }
>@@ -719,6 +727,7 @@
>  STDMETHODIMP_(BOOL)
>  CHXSockAddrIN6::Set(void* src)
>  {
>+    HX_ASSERT(m_nRefCount == 1);
>      sockaddr_storage* psa = (sockaddr_storage*)src;
>      if (psa->ss_family != AF_INET6)
>      {
>@@ -1149,6 +1158,12 @@
>          *ppvObj = (IHXSocket*)this;
>          return HXR_OK;
>      }
>+    /*if (IsEqualIID(riid, IID_IHXMulticastSocket))
>+    {
>+        AddRef();
>+        *ppvObj = (IHXMulticastSocket*)this;
>+        return HXR_OK;
>+    }*/
>      *ppvObj = NULL;
>      return HXR_NOINTERFACE;
>  }
>@@ -1762,115 +1777,206 @@
>      return HXR_OK;
>  }
>
>-/*** CHXMulticastSocket ***/
>+// HELIX_FEATURE_MULTICAST
>
>-CHXMulticastSocket::CHXMulticastSocket(void) :
>-    /* XXTDM: fixme */
>-    CHXSocket(NULL, NULL),
>-    m_nRefCount(0)
>+/*
>+ * IHXMulticastSocket
>+ */
>+
>+static
>+HX_RESULT SetMulticastInfoIPV6(IHXSockAddr* pGroupAddr,
>+                               IHXSockAddr* pInterface,
>+                               ipv6_mreq& req)
>  {
>-    // Empty
>-}
>+    HX_ASSERT(pGroupAddr);
>+    HX_ASSERT(HX_SOCK_FAMILY_IN6 == pGroupAddr->GetFamily());
>
>-STDMETHODIMP
>-CHXMulticastSocket::QueryInterface(REFIID riid, void** ppvObj)
>+    memset(&req, 0, sizeof(req));
>+
>+    sockaddr_in6 sa;
>+    memset(&sa, 0, sizeof(sa));
>+    pGroupAddr->Get(&sa);
>+
>+    req.ipv6mr_multiaddr = sa.sin6_addr; // mcast group address to join
>+
>+    if(pInterface)
>  {
>-    if (IsEqualIID(riid, IID_IUnknown))
>+        HX_ASSERT(false); // XXXLCM see below; ipv6mr_interface is index, 
>not address
>+
>+        // Windows uses GetAdaptersAddresses() for index; Linux netdevice 
>(net/if.h)
>+        if(pInterface->GetFamily() == HX_SOCK_FAMILY_IN6)
>      {
>-        AddRef();
>-        *ppvObj = (IUnknown*)(IHXSocket*)this;
>-        return HXR_OK;
>+            memset(&sa, 0, sizeof(sa));
>+            pGroupAddr->Get(&sa);
>+            req.ipv6mr_interface = 0; //sa.sin_addr; // interface to join on
>      }
>-    if (IsEqualIID(riid, IID_IHXSocket))
>+        else
>      {
>-        AddRef();
>-        *ppvObj = (IHXSocket*)this;
>-        return HXR_OK;
>+            // interface family does not match group family
>+            HX_ASSERT(false);
>+            return HXR_INVALID_PARAMETER;
>+        }
>      }
>-    if (IsEqualIID(riid, IID_IHXMulticastSocket))
>+    else
>      {
>-        AddRef();
>-        *ppvObj = (IHXMulticastSocket*)this;
>-        return HXR_OK;
>+        req.ipv6mr_interface = 0;
>      }
>-    *ppvObj = NULL;
>-    return HXR_NOINTERFACE;
>+
>+    return HXR_OK;
>  }
>
>-STDMETHODIMP_(ULONG32)
>-CHXMulticastSocket::AddRef(void)
>+static
>+HX_RESULT SetMulticastInfoIPV4(IHXSockAddr* pGroupAddr,
>+                               IHXSockAddr* pInterface,
>+                               ip_mreq& req)
>  {
>-    return InterlockedIncrement(&m_nRefCount);
>-}
>+    HX_ASSERT(pGroupAddr);
>+    HX_ASSERT(HX_SOCK_FAMILY_IN4 == pGroupAddr->GetFamily());
>
>-STDMETHODIMP_(ULONG32)
>-CHXMulticastSocket::Release(void)
>+    memset(&req, 0, sizeof(req));
>+
>+    sockaddr_in sa;
>+    memset(&sa, 0, sizeof(sa));
>+    pGroupAddr->Get(&sa);
>+
>+    req.imr_multiaddr = sa.sin_addr; // mcast group address to join
>+
>+    if(pInterface)
>  {
>-    HX_ASSERT(m_nRefCount > 0);
>-    INT32 rc = InterlockedDecrement(&m_nRefCount);
>-    if (rc == 0)
>+        if(pInterface->GetFamily() == HX_SOCK_FAMILY_IN4)
>      {
>-        delete this;
>+            memset(&sa, 0, sizeof(sa));
>+            pGroupAddr->Get(&sa);
>+            req.imr_interface = sa.sin_addr; // interface to join on
>+        }
>+        else
>+        {
>+            // interface family does not match group family
>+            HX_ASSERT(false);
>+            return HXR_INVALID_PARAMETER;
>      }
>-    return rc;
>  }
>
>-// For BeOS etc.
>-#if defined(HELIX_FEATURE_MULTICAST)
>-
>+    return HXR_OK;
>+}
>+// private helper
>  STDMETHODIMP
>-CHXMulticastSocket::JoinMulticastGroup(IHXSockAddr* pAddr)
>+CHXSocket::SetMulticastTTL(UINT32 ttl)
>  {
>-    UINT32 val;
>-    ip_mreq req;
>-    val = 254; //XXXTDM: hardcoded in unix_net
>-    if (setsockopt(m_sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) != 0)
>+    int name = HX_SOCKOPT_NONE;
>+    if(m_family == HX_SOCK_FAMILY_IN4)
>      {
>-        return HXR_FAIL;
>+        name = HX_SOCKOPT_IN4_MULTICAST_TTL;
>      }
>-    memset(&req, 0, sizeof(req));
>-    req.imr_multiaddr = pAddr->m_addr;
>-#ifdef _UNIX
>-    req.imr_interface = INADDR_ANY;
>-#else
>-    req.imr_interface = pIfAddr->m_addr;
>-#endif
>-    if (setsockopt(m_sock, SOL_IP, IP_ADD_MEMBERSHIP, (const char*)req, 
>sizeof(req)) != 0)
>+    else if(m_family == HX_SOCK_FAMILY_IN6)
>+    {
>+        name = HX_SOCKOPT_IN6_MULTICAST_HOPS;
>+    }
>+    else
>+    {
>+        return HXR_UNEXPECTED; //'invalid family'
>+    }
>+
>+    if (hx_setsockopt(&m_sock, name, &ttl, sizeof(ttl)) != 0)
>      {
>          return HXR_FAIL;
>      }
>+
>      return HXR_OK;
>  }
>
>+
>  STDMETHODIMP
>-CHXMulticastSocket::LeaveMulticastGroup(IHXSockAddr* pAddr)
>+CHXSocket::JoinMulticastGroup(IHXSockAddr* pGroupAddr,
>+                              IHXSockAddr* pInterface)
>+{
>+    HX_ASSERT(pGroupAddr);
>+    if(!pGroupAddr)
>+    {
>+        return HXR_INVALID_PARAMETER;
>+    }
>+
>+    HX_RESULT hr = HXR_FAIL;
>+
>+    SetMulticastTTL(254); //XXXLCM hardcode for now
>+
>+    HXSockFamily family = pGroupAddr->GetFamily();
>+
>+    if (HX_SOCK_FAMILY_IN4 == family)
>  {
>      ip_mreq req;
>-    memset(&req, 0, sizeof(req));
>-    req.imr_multiaddr = pAddr->m_addr;
>-    req.imr_interface = pIfAddr->m_addr;
>-    if (setsockopt(m_sock, SOL_IP, IP_DROP_MEMBERSHIP, (const char*)req, 
>sizeof(req)) != 0)
>+        hr = SetMulticastInfoIPV4(pGroupAddr, pInterface, req);
>+        if(SUCCEEDED(hr))
>      {
>-        return HXR_FAIL;
>+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN4_ADD_MEMBERSHIP, 
>&req, sizeof(req)) != 0)
>+            {
>+                hr = HXR_FAIL;
>+            }
>+        }
>+    }
>+    else if (HX_SOCK_FAMILY_IN6 == family)
>+    {
>+        ipv6_mreq req;
>+        hr = SetMulticastInfoIPV6(pGroupAddr, pInterface, req);
>+        if(SUCCEEDED(hr))
>+        {
>+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN6_JOIN_GROUP, &req, 
>sizeof(req)) != 0)
>+            {
>+                hr = HXR_FAIL;
>+            }
>      }
>-    return HXR_OK;
>+    }
>+    else
>+    {
>+        HX_ASSERT(false);
>+        hr = HXR_UNEXPECTED; // 'unsupported family'
>+    }
>+
>+    return hr;
>  }
>
>-#else /* !defined(HELIX_FEATURE_MULTICAST) */
>
>  STDMETHODIMP
>-CHXMulticastSocket::JoinMulticastGroup(IHXSockAddr* pAddr)
>+CHXSocket::LeaveMulticastGroup(IHXSockAddr* pGroupAddr,
>+                               IHXSockAddr* pInterface)
>  {
>-    return HXR_NOTIMPL;
>-}
>+    HX_RESULT hr = HXR_FAIL;
>
>-STDMETHODIMP
>-CHXMulticastSocket::LeaveMulticastGroup(IHXSockAddr* pAddr)
>+    HXSockFamily family = pGroupAddr->GetFamily();
>+
>+    if (HX_SOCK_FAMILY_IN4 == family)
>+    {
>+        ip_mreq req;
>+        hr = SetMulticastInfoIPV4(pGroupAddr, pInterface, req);
>+        if(SUCCEEDED(hr))
>+        {
>+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN4_DROP_MEMBERSHIP, 
>&req, sizeof(req)) != 0)
>+            {
>+                hr = HXR_FAIL;
>+            }
>+        }
>+    }
>+    else if (HX_SOCK_FAMILY_IN6 == family)
>+    {
>+        ipv6_mreq req;
>+        hr = SetMulticastInfoIPV6(pGroupAddr, pInterface, req);
>+        if(SUCCEEDED(hr))
>+        {
>+            if (hx_setsockopt(&m_sock, HX_SOCKOPT_IN6_LEAVE_GROUP, &req, 
>sizeof(req)) != 0)
>+            {
>+                hr = HXR_FAIL;
>+            }
>+        }
>+    }
>+    else
>  {
>-    return HXR_NOTIMPL;
>+        HX_ASSERT(false);
>+        hr = HXR_FAIL; // 'unsupported family'
>+    }
>+
>+    return hr;
>  }
>
>-#endif /* defined(HELIX_FEATURE_MULTICAST) */
>
>  /*** CHXListeningSocket ***/
>
>
>_______________________________________________
>Helix-client-dev mailing list
>Helix-client-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev


From wschildbach at helixcommunity.org  Thu Jun 24 22:41:29 2004
From: wschildbach at helixcommunity.org (Wolfgang Schildbach)
Date: Thu Jun 24 22:41:41 2004
Subject: [Common-dev] CR: Cast from int to CPUArchitecture enum
In-Reply-To: <1088126661.2986.359.camel@atlantis.prognet.com>
Message-ID: <5.1.0.14.2.20040625074112.02cb5540@mailone.real.com>

Looks good.

- Wolfgang

At 06:24 PM 6/24/2004 -0700, David Hedbor wrote:
>Branch: HEAD and hxclient_1_3_0_neptunex
>
>Description:
>
>In the ARM cpu ident code the CPUArchitecture enum (pInfo->architecture)
>is assigned an integer value without a cast. This breaks when compiling
>with gcc 3.x.
>
>Fix:
>
>Added an explicit cast.
>
>Files modified:
>
>common/util/cpuident.c
>
>--
>David Hedbor
>
>Index: common/util/cpuident.c
>===================================================================
>RCS file: /cvsroot/common/util/cpuident.c,v
>retrieving revision 1.12
>diff -u -r1.12 cpuident.c
>--- common/util/cpuident.c      12 May 2003 17:17:39 -0000      1.12
>+++ common/util/cpuident.c      25 Jun 2004 01:21:14 -0000
>@@ -350,7 +350,7 @@
>         pInfo->specific.m_arm.family        = ulFamily_POSTARM7 ;
>         pInfo->specific.m_arm.implementor   = id >> 24 ;
>         pInfo->specific.m_arm.variant       = (id >> 20) & 0xf ;
>-       pInfo->architecture  = ((id >> 16) & 0xf) - 1 + 
>ulArchitectureARM_ARCH4 ;
>+       pInfo->architecture  = (CPUArchitecture)(((id >> 16) & 0xf) - 1 + 
>ulArchitectureARM_ARCH4);
>         pInfo->specific.m_arm.primaryPartNo = (id >> 4) & 0xfff ;
>         pInfo->specific.m_arm.revision      = id & 0xf ;
>         if (pInfo->specific.m_arm.implementor == ARM_IMPL_Intel &&
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

-
- Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
- email wschildbach@helixcommunity.org



From acolwell at real.com  Fri Jun 25 15:33:11 2004
From: acolwell at real.com (Aaron Colwell)
Date: Fri Jun 25 15:34:59 2004
Subject: [Common-dev] CR-Client: Added 3GPP-Rel6 OBSN packet generation
Message-ID: <20040625223311.GA17041@real.com>

Synopsis: Add 3GPP-Rel6 OBSN packet generation code

Overview: These changes bring together all the pieces needed to generate
          3GPP-Rel6 OBSN packets. A new interface, IHX3gppOBSN was created
          to allow access to OBSN related info. HXSourceBufferStats implements
          this interface because it has all the relevent info for OBSN reports.
          The server rate adaptation negotiation code uses this interface to
          specify the negotiated OBSN report interval. The RTCP transport code
          uses this interface to get the OBSN report interval and the 
          information needed for the OBSN packets. Here is a list of the
          required changes.

          - Added code to CHXRateAdaptationInfo to set the OBSN report
            frequency once 3GPP-Rel6 rate adaptation has been negotiated.
           
          - Swapped the initialization order of m_pSrcBufStats and
            m_pRateAdaptInfo in RTSPClientProtocol. This was needed because
            m_pRateAdaptInfo relies on interfaces supplied by m_pSrcBufStats.

          - Added code to RTCPPacket so that it could pack more than 1 APP
            packet in an RTCP datagram. I just replaced m_pAPP with a list and
            updated the appropriate logic.

          - Added code to ReportHandler that generates the OBSN APP packet

          - Added code to the RTCPBaseTransport to use the new IHX3gppOBSN
            interface to get the data for the OBSN packet. RTCPBaseTransport
            also uses this interface to get the OBSN report frequency.
            OBSN packets are sent every Nth receiver report. I added a member
            variable to count the receiver reports and send the OBSN packets
            at the appropriate time.

          - Created a new method RTCPPacket::SetAPPData() that allows you to
            generate APP packets that don't follow the RN APP packet format.
            RTCPPacket::pack() function need to be slightly modified to handle
            this addition. The m_bAPPDataSet member variable was added to
            prevent RTCPPacket::pack() from deleting app_data and looking for
            RN style APPItem objects to pack. SetAPPData() specifies app_data
            directly and sets m_bAPPDataSet to TRUE so that pack doesn't delete
            app_data.

          - Removed LowestSeqNumber() methods from HXSourceBufferStats code
            since it is not needed

          - Added an IHX3gppOBSN interface implementation to the
            HXSourceBufferStats code

Files Modified:
protocol/rtsp/rateadaptinfo.cpp
protocol/rtsp/rateadaptinfo.h
protocol/rtsp/rtspclnt.cpp
protocol/transport/rtp/pkthndlr.cpp
protocol/transport/rtp/rtcputil.cpp
protocol/transport/rtp/rtptran.cpp
protocol/transport/rtp/pub/pkthndlr.h
protocol/transport/rtp/pub/rtcputil.h
protocol/transport/rtp/pub/rtptran.h
protocol/transport/rtp/pub/rtpwrap.h
common/util/hxsrcbufstats.cpp
common/util/pub/hxsrcbufstats.h
common/include/hxpiids.h

Files Added:
common/include/ihx3gpp.h

Image Size and Heap Use impact:

Platforms and Profiles affected: all

Distribution Libraries affected:  rdtclntlib

Distribution library impact and planned action:
Member variables added to RTCPBaseTransport

Platforms and Profiles Build Verified: win32

Platforms and Profiles Functionality verified: win32

Branch: HEAD

QA Instructions: none


===================================================================
RCS file: /cvsroot/protocol/rtsp/rateadaptinfo.cpp,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 rateadaptinfo.cpp
--- rateadaptinfo.cpp	16 Jun 2004 18:44:01 -0000	1.1.2.1
+++ rateadaptinfo.cpp	25 Jun 2004 22:03:29 -0000
@@ -136,7 +136,9 @@
 }
 
 CHXRateAdaptationInfo::CHXRateAdaptationInfo() :
-    m_pRateAdaptCtl(NULL)
+    m_pRateAdaptCtl(NULL),
+    m_pCCF(NULL),
+    m_pOBSN(NULL)
 {}
 
 CHXRateAdaptationInfo::~CHXRateAdaptationInfo()
@@ -158,6 +160,12 @@
             res = pContext->QueryInterface(IID_IHXCommonClassFactory,
                                            (void**)&m_pCCF);
         }
+
+        if (HXR_OK == res)
+        {
+            res = pContext->QueryInterface(IID_IHX3gppOBSN,
+                                           (void**)&m_pOBSN);
+        }
     }
 
     return res;
@@ -174,6 +182,7 @@
     
     HX_RELEASE(m_pRateAdaptCtl);
     HX_RELEASE(m_pCCF);
+    HX_RELEASE(m_pOBSN);
 
     return HXR_OK;
 }
@@ -190,7 +199,7 @@
     {
         res = HXR_POINTER;
     }
-    else if (m_pRateAdaptCtl &&
+    else if (m_pRateAdaptCtl && m_pOBSN &&
              (HXR_OK == pHdr->GetPropertyULONG32("3GPP-Adaptation-Support",
                                                  ulReportFreq)))
     {
@@ -286,6 +295,13 @@
         {
             // Disable client rate adaptation for this stream
             res = m_pRateAdaptCtl->Disable(uStreamNumber);
+
+            if (HXR_OK == res)
+            {
+                // Set OBSN report frequency
+                res = m_pOBSN->SetOBSNFrequency(uStreamNumber,
+                                                pInfo->Get3gpReportFreq());
+            }
         }
         else
         {
Index: rateadaptinfo.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/rateadaptinfo.h,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 rateadaptinfo.h
--- rateadaptinfo.h	16 Jun 2004 18:44:01 -0000	1.1.2.1
+++ rateadaptinfo.h	25 Jun 2004 22:03:29 -0000
@@ -43,6 +43,7 @@
 #include "ihxpckts.h"
 #include "hxccf.h"
 #include "hxslist.h"
+#include "ihx3gpp.h"
 
 class HXRAIStreamInfo;
 
@@ -83,5 +84,6 @@
     IHXClientRateAdaptControl* m_pRateAdaptCtl;
     IHXCommonClassFactory* m_pCCF;
     CHXSimpleList m_streamInfo;
+    IHX3gppOBSN* m_pOBSN;
 };
 #endif /* RATEADAPTINFO_H */
Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.79.2.2
diff -u -r1.79.2.2 rtspclnt.cpp
--- rtspclnt.cpp	24 Jun 2004 18:16:35 -0000	1.79.2.2
+++ rtspclnt.cpp	25 Jun 2004 22:03:29 -0000
@@ -800,17 +800,21 @@
         m_pPreferences->ReadPref("XWapProfileDiff", m_pUAProfDiff);
     }
 
+    // m_pSrcBufStats MUST be initialized before m_pRateAdaptInfo
+    // because it provides interfaces that m_pRateAdaptInfo needs
+    // for initialization.
     if (HXR_OK == hresult)
     {
-        m_pRateAdaptInfo = new CHXRateAdaptationInfo();
-
-        if (m_pRateAdaptInfo)
+        HX_RELEASE(m_pSrcBufStats);
+        m_pSrcBufStats = new HXNetSourceBufStats(this);
+        
+        if (m_pSrcBufStats)
         {
-            if (HXR_OK != m_pRateAdaptInfo->Init(pContext))
+            m_pSrcBufStats->AddRef();
+
+            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
             {
-                // This is not a critical error. It just means
-                // that we can't negotiate server rate adaptation.
-                HX_DELETE(m_pRateAdaptInfo);
+                HX_RELEASE(m_pSrcBufStats);
             }
         }
         else
@@ -821,16 +825,15 @@
 
     if (HXR_OK == hresult)
     {
-        HX_RELEASE(m_pSrcBufStats);
-        m_pSrcBufStats = new HXNetSourceBufStats(this);
-        
-        if (m_pSrcBufStats)
-        {
-            m_pSrcBufStats->AddRef();
+        m_pRateAdaptInfo = new CHXRateAdaptationInfo();
 
-            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
+        if (m_pRateAdaptInfo)
+        {
+            if (HXR_OK != m_pRateAdaptInfo->Init(pContext))
             {
-                HX_RELEASE(m_pSrcBufStats);
+                // This is not a critical error. It just means
+                // that we can't negotiate server rate adaptation.
+                HX_DELETE(m_pRateAdaptInfo);
             }
         }
         else

Index: pkthndlr.cpp
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/pkthndlr.cpp,v
retrieving revision 1.4
diff -u -r1.4 pkthndlr.cpp
--- pkthndlr.cpp	10 Sep 2003 23:29:35 -0000	1.4
+++ pkthndlr.cpp	25 Jun 2004 22:03:41 -0000
@@ -46,7 +46,6 @@
     : m_pReport(NULL)
     , m_pSDES(NULL)
     , m_pBYE(NULL)
-    , m_pAPP(NULL)
 {
 }
 
@@ -72,7 +71,7 @@
 	m_pBYE = pPkt;
 	break;
     case RTCP_APP:
-	m_pAPP = pPkt;
+        m_APPList.AddTail(pPkt);
 	break;
     default:
 	HX_ASSERT(!"RTCPPacker::Set():  Don't know this packet type");
@@ -108,9 +107,13 @@
     {
 	ulBufSize += (m_pBYE->length + 1) * 4;
     }
-    if (m_pAPP)
+
+    LISTPOSITION pos = m_APPList.GetHeadPosition();
+    while (pos)
     {
-	ulBufSize += (m_pAPP->length + 1) * 4;
+        RTCPPacket* pAPP = 
+            (RTCPPacket*)m_APPList.GetNext(pos);
+	ulBufSize += (pAPP->length + 1) * 4;
     }
 
     // now pack!
@@ -125,10 +128,13 @@
     PackOne(m_pSDES, pc, ulPackedLen);
     HX_ASSERT((((UINT32)m_pSDES->length + 1) * 4) == ulPackedLen);
 
-    if (m_pAPP)
+    pos = m_APPList.GetHeadPosition();
+    while (pos)
     {
-	PackOne(m_pAPP, pc, ulPackedLen);
-	HX_ASSERT((((UINT32)m_pAPP->length + 1) * 4) == ulPackedLen);		
+        RTCPPacket* pAPP = 
+            (RTCPPacket*)m_APPList.GetNext(pos);
+	PackOne(pAPP, pc, ulPackedLen);
+	HX_ASSERT((((UINT32)pAPP->length + 1) * 4) == ulPackedLen);		
     }
 
     /* BYE pkt needs to be the last pkt! */
Index: rtcputil.cpp
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/rtcputil.cpp,v
retrieving revision 1.10
diff -u -r1.10 rtcputil.cpp
--- rtcputil.cpp	17 Feb 2004 20:08:52 -0000	1.10
+++ rtcputil.cpp	25 Jun 2004 22:03:41 -0000
@@ -40,6 +40,7 @@
 #include "hxtick.h"
 #include "hxengin.h"
 #include "tconverter.h"
+#include "netbyte.h"
 
 #include "interval.h"
 #include "ntptime.h"
@@ -507,6 +508,44 @@
 	item.padding0 = 0;
 	pPkt->SetAPPItem(&item, 1);
 	pPkt->length += 4;
+	res = HXR_OK;
+    }
+
+    return res;
+}
+
+HX_RESULT 
+ReportHandler::MakeOBSN(RTCPPacket* pPkt, 
+                        UINT16 uSequenceNum,
+                        UINT16 uPlayoutDelay)
+{
+    HX_RESULT res = HXR_UNEXPECTED;
+
+    // We only handle the 1 sender case for
+    // right now.
+    if (pPkt && (m_mapSenders.GetCount() == 1))
+    {
+        CHXMapLongToObj::Iterator i = m_mapSenders.Begin();
+        UINT32 ulSSRC = (UINT32)i.get_key();
+
+	pPkt->version_flag = 0x02;
+	pPkt->padding_flag = 0;    
+	pPkt->packet_type = RTCP_APP;
+	pPkt->count = 0;
+	pPkt->app_ssrc = m_pReceiverMe->m_ulSsrc;
+	memcpy(pPkt->app_name, "PSS0", 4);
+        pPkt->length = 2;
+
+        UINT8 obsnBuf[8];
+        UINT32* pSSRC = (UINT32*)&obsnBuf[0];
+        UINT16* pDelay = (UINT16*)&obsnBuf[4];
+        UINT16* pSeq = (UINT16*)&obsnBuf[6];
+
+        *pSSRC = DwToNet(ulSSRC);
+        *pDelay = WToNet(uPlayoutDelay);
+        *pSeq = WToNet(uSequenceNum);
+
+        pPkt->SetAPPData(obsnBuf, sizeof(obsnBuf));
 	res = HXR_OK;
     }
 
Index: rtptran.cpp
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/rtptran.cpp,v
retrieving revision 1.60
diff -u -r1.60 rtptran.cpp
--- rtptran.cpp	10 Mar 2004 20:05:22 -0000	1.60
+++ rtptran.cpp	25 Jun 2004 22:03:41 -0000
@@ -69,6 +69,7 @@
 #include "hxqossig.h"
 #include "hxqos.h"
 //#include "hxcorgui.h"
+#include "ihx3gpp.h"
 
 #include "ntptime.h"
 
@@ -2403,7 +2404,9 @@
     m_ulLastSeq (0),
     m_ulLastLoss (0),
     m_ulLastRate (0),
-    m_pTSScheduler (NULL)
+    m_pTSScheduler (NULL),
+    m_pOBSN(NULL),
+    m_ulOBSNRRCount(0)
 {
 }
 
@@ -2462,6 +2465,8 @@
     HX_RELEASE(m_pQoSSignal_APP);
     HX_RELEASE(m_pSignalBus);
     HX_RELEASE(m_pSessionId);
+
+    HX_RELEASE(m_pOBSN);
 }
 
 HX_RESULT
@@ -2481,6 +2486,15 @@
     itoa(random32(HX_GET_TICKCOUNT()), cname, 10);    
     m_pcCNAME = (BYTE*)new_string(cname);
     HX_ASSERT(m_pcCNAME);
+
+    HX_RELEASE(m_pOBSN);
+    if (m_pContext)
+    {
+        m_pContext->QueryInterface(IID_IHX3gppOBSN,
+                                   (void**)&m_pOBSN);
+        m_ulOBSNRRCount = 0;
+    }
+    
     return HXR_OK;
 }
 
@@ -3240,6 +3254,7 @@
 //    IHXBuffer* pSendBuf = NULL;
     RTCPPacket* pPktSDES = NULL;
     RTCPPacket* pPktBufInfo = NULL;
+    RTCPPacket* pPktOBSN = NULL;
 
     HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
     UINT32 ulNow = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
@@ -3300,6 +3315,59 @@
 	HX_DELETE(pPktBufInfo);
     }
 
+    if (m_pOBSN && m_pReportHandler)
+    {
+        UINT32 uFreq = 0;
+
+        // increment RR counter
+        m_ulOBSNRRCount++;
+
+        // Get OBSN report frequency
+        m_pOBSN->GetOBSNFrequency(m_streamNumber, uFreq);
+        
+        if (uFreq && (m_ulOBSNRRCount >= uFreq))
+        {
+            // Time to send an OBSN packet
+
+            UINT16 uSequenceNum = 0;
+            UINT16 uPlayoutDelay = 0;
+
+            pPktOBSN = new RTCPPacket();
+
+            if ((HXR_OK ==  m_pOBSN->GetOBSNInfo(m_streamNumber,
+                                                 uSequenceNum, 
+                                                 uPlayoutDelay)) &&
+                (HXR_OK == m_pReportHandler->MakeOBSN(pPktOBSN, 
+                                                      uSequenceNum, 
+                                                      uPlayoutDelay)))
+            {
+                // We successfully created an OBSN
+                // packet.
+
+                // Reset our RR counter to 0
+                m_ulOBSNRRCount = 0;
+            }
+            else
+            {
+                // If we failed for some reason,
+                // just delete the packet so that
+                // it doesn't get included in the
+                // compound packet. Failing to
+                // send an OBSN is not a 
+                // critical error
+                HX_DELETE(pPktOBSN);
+            }
+        }
+    }
+
     // pack them up!
     theErr = m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
 						   (void**)&pSendBuf);
@@ -3317,6 +3385,11 @@
 	packer.Set(pPktBufInfo);
     }
 
+    if (pPktOBSN)
+    {
+        packer.Set(pPktOBSN);
+    }
+
     theErr = packer.Pack(pSendBuf);
     
     if (HXR_OK != theErr)
@@ -3333,6 +3406,7 @@
     HX_DELETE(pPktRR);
     HX_DELETE(pPktSDES);
     HX_DELETE(pPktBufInfo);
+    HX_DELETE(pPktOBSN);
 //    HX_RELEASE(pSendBuf);
     return theErr;
 }
Index: pub/pkthndlr.h
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/pub/pkthndlr.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pkthndlr.h
--- pub/pkthndlr.h	18 Oct 2002 01:59:17 -0000	1.1.1.1
+++ pub/pkthndlr.h	25 Jun 2004 22:03:41 -0000
@@ -73,7 +73,7 @@
     RTCPPacket*	    m_pReport;
     RTCPPacket*	    m_pSDES;
     RTCPPacket*	    m_pBYE;        
-    RTCPPacket*	    m_pAPP;        
+    CHXSimpleList   m_APPList;
 };
 
 
Index: pub/rtcputil.h
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/pub/rtcputil.h,v
retrieving revision 1.5
diff -u -r1.5 rtcputil.h
--- pub/rtcputil.h	11 Nov 2003 01:20:41 -0000	1.5
+++ pub/rtcputil.h	25 Jun 2004 22:03:41 -0000
@@ -241,6 +241,9 @@
     HX_RESULT MakeBufInfoApp	    (RTCPPacket* pPkt, 
 				     UINT32 ulLowTS, UINT32 ulHighTS,
 				     UINT32 ulBytesBuffered);
+    HX_RESULT MakeOBSN	             (RTCPPacket* pPkt, 
+				     UINT16 uSequenceNum,
+				     UINT16 uPlayoutDelay);
 
     /* for RTCP interval calc */
     void    UpdateAvgRTCPSize	    (UINT32 ulCompoundRTCPSize)
Index: pub/rtptran.h
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/pub/rtptran.h,v
retrieving revision 1.28
diff -u -r1.28 rtptran.h
--- pub/rtptran.h	3 May 2004 19:01:40 -0000	1.28
+++ pub/rtptran.h	25 Jun 2004 22:03:41 -0000
@@ -46,6 +46,7 @@
 #include "ntptime.h"
 #include "tconverter.h"
 #include "chxkeepalive.h"
+#include "ihx3gpp.h"
 
 // GCC won't let me forward declare CHXMapLongToObj::Iterator, 
 // so I have to include this. -JR
@@ -592,6 +593,9 @@
     UINT32                              m_ulLastLoss;
     UINT32                              m_ulLastRate;
     UINT32                              m_ulRRIntvl;
+
+    IHX3gppOBSN*                        m_pOBSN;
+    UINT32                              m_ulOBSNRRCount;
 
     friend class RTPBaseTransport;
     friend class RTPUDPTransport;
Index: pub/rtpwrap.h
===================================================================
RCS file: /cvsroot/protocol/transport/rtp/pub/rtpwrap.h,v
retrieving revision 1.8
diff -u -r1.8 rtpwrap.h
--- pub/rtpwrap.h	30 Sep 2003 16:15:42 -0000	1.8
+++ pub/rtpwrap.h	25 Jun 2004 22:03:41 -0000
@@ -124,6 +124,7 @@
     //    app_name = 0;  // not a pointer...
         app_data = 0;
         m_pAPPItems = 0;
+        m_bAPPDataSet = FALSE;
     }
 
     ~RTCPPacket()
@@ -195,9 +196,36 @@
     void SetAPPItem (APPItem* item, UINT32 ulCount)
     {
         HX_VECTOR_DELETE(m_pAPPItems);
+        m_bAPPDataSet = FALSE;
 
         m_pAPPItems = new APPItem[ulCount];
         memcpy(m_pAPPItems, item, ulCount * sizeof (APPItem)); /* Flawfinder: ignore */
+
+    }
+    
+    void SetAPPData(const UINT8* pData, UINT32 ulLength)
+    {
+        // The data length MUST be a multiple of 4
+        UINT32 ulAPPDataLen = ((ulLength + 3) & ~0x3);
+
+        // Update the length member variable
+        length = 2 + ((ulAPPDataLen) >> 2);
+
+        HX_VECTOR_DELETE(app_data);
+        app_data = new UINT8[ulAPPDataLen];
+
+        if (app_data)
+        {
+            if (ulAPPDataLen != ulLength)
+            {
+                // Zero out the extra bytes
+                memset(app_data + ulLength, 0,
+                       ulAPPDataLen - ulLength);
+                           
+            }
+            memcpy(app_data, pData, ulLength);
+            m_bAPPDataSet = TRUE;
+        }
     }
     
     // keys off of source id and contains a pointer to a list 
@@ -205,6 +233,7 @@
     CHXMapLongToObj	m_mapSDESSources;    
     // array of APPItem
     APPItem*		m_pAPPItems;
+    BOOL                m_bAPPDataSet;
     void CleanBuffers();
 };
 
@@ -227,7 +256,10 @@
 	delete [] bye_src;
 
     if (app_data)
+    {
 	delete [] app_data;
+        m_bAPPDataSet = FALSE;
+    }
 	
     CHXMapLongToObj::Iterator	i;
     for (i = m_mapSDESSources.Begin(); i != m_mapSDESSources.End(); ++i)
@@ -420,23 +452,26 @@
      	* revert the m_mapSDESSources back to blob form
      	*/
     
-    	if (app_data != NULL)
-    	{
-	    delete [] app_data;
-    	}	
-        
-    	UINT8*  pBuf = new UINT8[0x1000];
-    	UINT8*  pOff = pBuf;
-	UINT32  ulDammy = 0;
-	for (UINT32 i = 0; i < count; i++)
-	{
-	    pOff = m_pAPPItems[i].pack(pOff, ulDammy);
-	}
-
-	app_data = new UINT8[pOff - pBuf];
-	memcpy(app_data, pBuf, (pOff - pBuf) * sizeof(UINT8)); /* Flawfinder: ignore */
-
-	delete [] pBuf;
+        if (!m_bAPPDataSet)
+        {
+            if (app_data != NULL)
+            {
+                delete [] app_data;
+            }	
+            
+            UINT8*  pBuf = new UINT8[0x1000];
+            UINT8*  pOff = pBuf;
+            UINT32  ulDammy = 0;
+            for (UINT32 i = 0; i < count; i++)
+            {
+                pOff = m_pAPPItems[i].pack(pOff, ulDammy);
+            }
+
+            app_data = new UINT8[pOff - pBuf];
+            memcpy(app_data, pBuf, (pOff - pBuf) * sizeof(UINT8)); /* Flawfinder: ignore */
+            
+            delete [] pBuf;
+        }
     }
 
     
Index: hxsrcbufstats.cpp
===================================================================
RCS file: /cvsroot/common/util/hxsrcbufstats.cpp,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 hxsrcbufstats.cpp
--- hxsrcbufstats.cpp	24 Jun 2004 21:21:46 -0000	1.1.2.2
+++ hxsrcbufstats.cpp	25 Jun 2004 22:03:59 -0000
@@ -78,12 +78,17 @@
                   UINT16 uSeqNum);
     void OnTimeSync(UINT32 ulCurrentTime);
 
-    HX_RESULT LowestSeqNumber(REF(UINT32) nLowestSeq);
-
     HX_RESULT GetBufferingStats(REF(INT64) llLowTS,
                                 REF(INT64) llHighTS,
                                 REF(UINT32) uNumBytes);
     
+    HX_RESULT GetOBSNInfo(REF(UINT16) uSequenceNum,
+                          REF(UINT16) uPlayoutDelay);
+
+    HX_RESULT SetOBSNFrequency(UINT32 uFrequency);
+
+    HX_RESULT GetOBSNFrequency(REF(UINT32) uFrequency);
+
 private:
 
     void UpdateBufferInfo();
@@ -105,7 +110,7 @@
     BOOL m_bFirstPkt;
     INT64 m_llFirstLivePacketTS;
     INT64 m_llHighestTimestamp;
-    UINT32 m_uLowestSeq;
+    UINT32 m_uOBSNFreq;
 };
 
 
@@ -120,7 +125,7 @@
     m_bIsLive(FALSE),
     m_bFirstPkt(TRUE),
     m_llFirstLivePacketTS(0),
-    m_uLowestSeq(InvalidSeqNum)
+    m_uOBSNFreq(0)
 {}
 
 HXStreamPktBufInfo::~HXStreamPktBufInfo()
@@ -151,7 +156,6 @@
     if (m_bFirstPkt)
     {
         m_llHighestTimestamp = llActualTS;
-        m_uLowestSeq = uSeqNum;
 
         if (m_bIsLive)
         {
@@ -224,7 +228,6 @@
     m_bFirstPkt = TRUE;
     m_llFirstLivePacketTS = 0;
     m_llHighestTimestamp = 0;
-    m_uLowestSeq = InvalidSeqNum;
 }
 
 HX_RESULT 
@@ -257,20 +260,75 @@
     return res;
 }
 
-HX_RESULT 
-HXStreamPktBufInfo::LowestSeqNumber(REF(UINT32) nLowestSeq)
+HX_RESULT
+HXStreamPktBufInfo::GetOBSNInfo(REF(UINT16) uSequenceNum,
+                                REF(UINT16) uPlayoutDelay)
 {
-    HX_RESULT res = HXR_NO_DATA;
-    
+    HX_RESULT res = HXR_FAILED;
+
     UpdateBufferInfo();
 
-    if (!m_bFirstPkt && (InvalidSeqNum != m_uLowestSeq))
+    if (m_pktInfo.IsEmpty())
     {
-        nLowestSeq = m_uLowestSeq;
-        res = HXR_OK;
+        // Our buffer is empty
+        res = HXR_NO_DATA;
+    }
+    else
+    {
+        // We have packets buffered
+        HXPktInfo* pPktInfo = (HXPktInfo*)m_pktInfo.GetHead();
+        
+        if (pPktInfo->SequenceNum() != InvalidSeqNum)
+        {
+            // This packet info has a valid sequence number
+
+            uSequenceNum = (UINT16)pPktInfo->SequenceNum();
+
+            if (m_bCurrentTimeValid)
+            {
+                
+                UINT32 uDelay = 
+                    INT64_TO_UINT32(pPktInfo->Timestamp() - m_llCurrentTime);
+
+                
+                if (uDelay > 0xfffe)
+                {
+                    // The delay is too large. Use
+                    // the reserved value
+                    uPlayoutDelay = 0xffff;
+                }
+                else
+                {
+                    uPlayoutDelay = (UINT16)uDelay;
+                }
+            }
+            else
+            {
+                // We don't know what the delay is
+                // so just report the reserved value.
+                uPlayoutDelay = 0xffff;
+            }
+
+            res = HXR_OK;
+        }
     }
+    
+    return res;
+}
+
+HX_RESULT
+HXStreamPktBufInfo::SetOBSNFrequency(UINT32 uFrequency)
+{
+    m_uOBSNFreq = uFrequency;
+    return HXR_OK;
+}
+
+HX_RESULT
+HXStreamPktBufInfo::GetOBSNFrequency(REF(UINT32) uFrequency)
+{
+    uFrequency = m_uOBSNFreq;
 
-    return nLowestSeq;
+    return HXR_OK;
 }
 
 void HXStreamPktBufInfo::UpdateBufferInfo()
@@ -284,7 +342,6 @@
         {
             m_pktInfo.RemoveHead();
             m_uBytesBuffered -= pPktInfo->PacketSize();
-            m_uLowestSeq = pPktInfo->SequenceNum();
 
             HX_DELETE(pPktInfo);
 
@@ -436,21 +493,6 @@
     }
 }
 
-HX_RESULT 
-HXSourceBufferStats::LowestSeqNumber(UINT16  uStreamNumber, 
-                                     REF(UINT32) nLowestSeq)
-{
-    HX_RESULT res = HXR_FAILED;
-
-    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
-    
-    if (pBufInfo)
-    {
-        res = pBufInfo->LowestSeqNumber(nLowestSeq);
-    }
-
-    return res;
-}
 /*
  * IUnknown methods
  */
@@ -464,7 +506,8 @@
         { GET_IIDHANDLE(IID_IUnknown), this },
         { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*) this },
         { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*) this },
-        { GET_IIDHANDLE(IID_IHXTransportTimeSink), (IHXTransportTimeSink*) this }
+        { GET_IIDHANDLE(IID_IHXTransportTimeSink), (IHXTransportTimeSink*) this },
+        { GET_IIDHANDLE(IID_IHX3gppOBSN), (IHX3gppOBSN*)this}
     };
     return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
 }
@@ -560,6 +603,59 @@
         }
     }
 
+    return res;
+}
+
+/*
+ * IHX3gppOBSN Methods
+ */
+
+STDMETHODIMP 
+HXSourceBufferStats::GetOBSNInfo(THIS_ UINT16 uStreamNumber,
+                                 REF(UINT16) uSequenceNum,
+                                 REF(UINT16) uPlayoutDelay)
+{
+    HX_RESULT res = HXR_INVALID_PARAMETER;
+
+    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
+
+    if (pBufInfo)
+    {
+        res = pBufInfo->GetOBSNInfo(uSequenceNum, uPlayoutDelay);
+    }
+    
+    return res;
+}
+
+STDMETHODIMP
+HXSourceBufferStats::SetOBSNFrequency(THIS_ UINT16 uStreamNumber,
+                                        UINT32 uFrequency)
+{
+    HX_RESULT res = HXR_INVALID_PARAMETER;
+
+    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
+    
+    if (pBufInfo)
+    {
+        res = pBufInfo->SetOBSNFrequency(uFrequency);
+    }
+    
+    return res;
+}
+
+STDMETHODIMP
+HXSourceBufferStats::GetOBSNFrequency(THIS_ UINT16 uStreamNumber,
+                                      REF(UINT32) uFrequency)
+{
+    HX_RESULT res = HXR_INVALID_PARAMETER;
+
+    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
+
+    if (pBufInfo)
+    {
+        res = pBufInfo->GetOBSNFrequency(uFrequency);
+    }
+    
     return res;
 }
 
Index: pub/hxsrcbufstats.h
===================================================================
RCS file: /cvsroot/common/util/pub/hxsrcbufstats.h,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 hxsrcbufstats.h
--- pub/hxsrcbufstats.h	24 Jun 2004 18:16:08 -0000	1.1.2.1
+++ pub/hxsrcbufstats.h	25 Jun 2004 22:03:59 -0000
@@ -42,11 +42,13 @@
 #include "hxmap.h"
 #include "hxcore.h"
 #include "ihxtranstime.h"
+#include "ihx3gpp.h"
 
 class HXStreamPktBufInfo;
 
 class HXSourceBufferStats : public IHXSourceBufferingStats2,
-                            public IHXTransportTimeSink
+                            public IHXTransportTimeSink,
+                            public IHX3gppOBSN
 {
 public:
     HXSourceBufferStats();
@@ -97,6 +99,20 @@
      * IHXTransportTimeSink methods
      */
     STDMETHOD(OnTransportTime) (THIS_ UINT32 ulCurrentTime);
+
+    /*
+     * IHX3gppOBSN Methods
+     */
+
+    STDMETHOD(GetOBSNInfo) (THIS_ UINT16 uStreamNumber,
+                            REF(UINT16) uSequenceNum,
+                            REF(UINT16) uPlayoutDelay);
+    
+    STDMETHOD(SetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
+                                   UINT32 uFrequency);
+
+    STDMETHOD(GetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
+                                   REF(UINT32) uFrequency);
 
 protected:
     ~HXSourceBufferStats();


Index: hxpiids.h
===================================================================
RCS file: /cvsroot/common/include/hxpiids.h,v
retrieving revision 1.28.2.2
diff -u -r1.28.2.2 hxpiids.h
--- hxpiids.h   24 Jun 2004 18:13:18 -0000      1.28.2.2
+++ hxpiids.h   25 Jun 2004 22:14:00 -0000
@@ -1010,5 +1010,14 @@
 DEFINE_GUID_ENUM(IID_IHXTransportTimeManager,
 0xd0a5ba01, 0xedfb, 0x4741, 0xb7, 0x9, 0x88, 0x4e, 0x68, 0x5d, 0x2d, 0x8)
  
+/* File:
+ *      ihx3gpp.h
+ *
+ * Description:
+ *      Interfaces for 3GPP functionality
+ */
+DEFINE_GUID_ENUM(IID_IHX3gppOBSN,
+0x8069baaf, 0x777a, 0x4cf0, 0x90, 0x3, 0xd2, 0x6d, 0x68, 0xb8, 0xd7, 0x86)
+
 #endif /* _HXPRIVATEIIDS_H_ */
  
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ihx3gpp.h
Type: text/x-chdr
Size: 3550 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040625/9bdee88d/ihx3gpp-0001.bin
From gstacey at atico.com  Mon Jun 28 11:44:59 2004
From: gstacey at atico.com (Greg Stacey)
Date: Mon Jun 28 11:45:37 2004
Subject: [Common-dev] Build issue
Message-ID: 

I seem to have gotten only part of a recent change.  Today, when I build I
get the following error:

ERROR: UNIXCompile(common/netio) ERROR: could not find object file for
missing source="platform/posix/netdrv.cpp"

 

The unix.pcf file in common/netio tries to do a project.AddSources for two
files in the platform/posix directory but I don't have such a directory and
updating from cvs doesn't create one.

 

My configuration is:

BIF branch => helix-player-restricted

Target => player_inst

Profile => helix-client-all-defines

SYSTEM_ID => hpux-11.0-parisc

 

Is this something that needs to be fixed for my system_id? Or is there
something I can do on my side?

 

Thanks,

 

Greg Stacey

Principal Consultant

Advanced Technologies Integration

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040628/09113446/attachment.htm
From jgordon at real.com  Mon Jun 28 12:05:55 2004
From: jgordon at real.com (Jamie Gordon)
Date: Mon Jun 28 12:08:56 2004
Subject: [Common-dev] Build issue
In-Reply-To: <200406281845.i5SIjbp3014571@maytag02.real.com>
References: <200406281845.i5SIjbp3014571@maytag02.real.com>
Message-ID: <40E06C13.5070706@real.com>

If you are doing a cvs update by hand you have to pass it
the -d flag to get new directories (cvs up -d).

Jamie

Greg Stacey wrote:
> I seem to have gotten only part of a recent change.  Today, when I build 
> I get the following error:
> 
> ERROR: UNIXCompile(common/netio) ERROR: could not find object file for 
> missing source="platform/posix/netdrv.cpp"
> 
>  
> 
> The unix.pcf file in common/netio tries to do a project.AddSources for 
> two files in the platform/posix directory but I don?t have such a 
> directory and updating from cvs doesn?t create one.
> 
>  
> 
> My configuration is:
> 
> BIF branch => helix-player-restricted
> 
> Target => player_inst
> 
> Profile => helix-client-all-defines
> 
> SYSTEM_ID => hpux-11.0-parisc
> 
>  
> 
> Is this something that needs to be fixed for my system_id? Or is there 
> something I can do on my side?
> 
>  
> 
> Thanks,
> 
>  
> 
> Greg Stacey
> 
> Principal Consultant
> 
> Advanced Technologies Integration

From gstacey at atico.com  Mon Jun 28 12:23:47 2004
From: gstacey at atico.com (Greg Stacey)
Date: Mon Jun 28 12:24:21 2004
Subject: [Common-dev] Build issue
In-Reply-To: <40E06C13.5070706@real.com>
Message-ID: 

Actually I was using the build system to get the latest code but either I
hit the wrong option or it didn't create the directories for some reason.

Anyway, I forgot the -d when I did it by hand. My bad.

Thanks,

Greg Stacey
Principal Consultant
Advanced Technologies Integration

-----Original Message-----
From: Jamie Gordon [mailto:jgordon@real.com] 
Sent: Monday, June 28, 2004 2:06 PM
To: Greg Stacey
Cc: common-dev@lists.helixcommunity.org
Subject: Re: [Common-dev] Build issue

If you are doing a cvs update by hand you have to pass it
the -d flag to get new directories (cvs up -d).

Jamie

Greg Stacey wrote:
> I seem to have gotten only part of a recent change.  Today, when I build 
> I get the following error:
> 
> ERROR: UNIXCompile(common/netio) ERROR: could not find object file for 
> missing source="platform/posix/netdrv.cpp"
> 
>  
> 
> The unix.pcf file in common/netio tries to do a project.AddSources for 
> two files in the platform/posix directory but I don't have such a 
> directory and updating from cvs doesn't create one.
> 
>  
> 
> My configuration is:
> 
> BIF branch => helix-player-restricted
> 
> Target => player_inst
> 
> Profile => helix-client-all-defines
> 
> SYSTEM_ID => hpux-11.0-parisc
> 
>  
> 
> Is this something that needs to be fixed for my system_id? Or is there 
> something I can do on my side?
> 
>  
> 
> Thanks,
> 
>  
> 
> Greg Stacey
> 
> Principal Consultant
> 
> Advanced Technologies Integration




From acolwell at real.com  Mon Jun 28 13:36:15 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon Jun 28 13:37:56 2004
Subject: [Common-dev] CR-Client-Resend: Added 3GPP-Rel6 OBSN packet
	generation
In-Reply-To: <20040625223311.GA17041@real.com>
References: <20040625223311.GA17041@real.com>
Message-ID: <20040628203615.GA25059@real.com>

Sending again

On Fri, Jun 25, 2004 at 03:33:11PM -0700, Aaron Colwell wrote:
> Synopsis: Add 3GPP-Rel6 OBSN packet generation code
> 
> Overview: These changes bring together all the pieces needed to generate
>           3GPP-Rel6 OBSN packets. A new interface, IHX3gppOBSN was created
>           to allow access to OBSN related info. HXSourceBufferStats implements
>           this interface because it has all the relevent info for OBSN reports.
>           The server rate adaptation negotiation code uses this interface to
>           specify the negotiated OBSN report interval. The RTCP transport code
>           uses this interface to get the OBSN report interval and the 
>           information needed for the OBSN packets. Here is a list of the
>           required changes.
> 
>           - Added code to CHXRateAdaptationInfo to set the OBSN report
>             frequency once 3GPP-Rel6 rate adaptation has been negotiated.
>            
>           - Swapped the initialization order of m_pSrcBufStats and
>             m_pRateAdaptInfo in RTSPClientProtocol. This was needed because
>             m_pRateAdaptInfo relies on interfaces supplied by m_pSrcBufStats.
> 
>           - Added code to RTCPPacket so that it could pack more than 1 APP
>             packet in an RTCP datagram. I just replaced m_pAPP with a list and
>             updated the appropriate logic.
> 
>           - Added code to ReportHandler that generates the OBSN APP packet
> 
>           - Added code to the RTCPBaseTransport to use the new IHX3gppOBSN
>             interface to get the data for the OBSN packet. RTCPBaseTransport
>             also uses this interface to get the OBSN report frequency.
>             OBSN packets are sent every Nth receiver report. I added a member
>             variable to count the receiver reports and send the OBSN packets
>             at the appropriate time.
> 
>           - Created a new method RTCPPacket::SetAPPData() that allows you to
>             generate APP packets that don't follow the RN APP packet format.
>             RTCPPacket::pack() function need to be slightly modified to handle
>             this addition. The m_bAPPDataSet member variable was added to
>             prevent RTCPPacket::pack() from deleting app_data and looking for
>             RN style APPItem objects to pack. SetAPPData() specifies app_data
>             directly and sets m_bAPPDataSet to TRUE so that pack doesn't delete
>             app_data.
> 
>           - Removed LowestSeqNumber() methods from HXSourceBufferStats code
>             since it is not needed
> 
>           - Added an IHX3gppOBSN interface implementation to the
>             HXSourceBufferStats code
> 
> Files Modified:
> protocol/rtsp/rateadaptinfo.cpp
> protocol/rtsp/rateadaptinfo.h
> protocol/rtsp/rtspclnt.cpp
> protocol/transport/rtp/pkthndlr.cpp
> protocol/transport/rtp/rtcputil.cpp
> protocol/transport/rtp/rtptran.cpp
> protocol/transport/rtp/pub/pkthndlr.h
> protocol/transport/rtp/pub/rtcputil.h
> protocol/transport/rtp/pub/rtptran.h
> protocol/transport/rtp/pub/rtpwrap.h
> common/util/hxsrcbufstats.cpp
> common/util/pub/hxsrcbufstats.h
> common/include/hxpiids.h
> 
> Files Added:
> common/include/ihx3gpp.h
> 
> Image Size and Heap Use impact:
> 
> Platforms and Profiles affected: all
> 
> Distribution Libraries affected:  rdtclntlib
> 
> Distribution library impact and planned action:
> Member variables added to RTCPBaseTransport
> 
> Platforms and Profiles Build Verified: win32
> 
> Platforms and Profiles Functionality verified: win32
> 
> Branch: HEAD
> 
> QA Instructions: none
> 
> 
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/rateadaptinfo.cpp,v
> retrieving revision 1.1.2.1
> diff -u -r1.1.2.1 rateadaptinfo.cpp
> --- rateadaptinfo.cpp	16 Jun 2004 18:44:01 -0000	1.1.2.1
> +++ rateadaptinfo.cpp	25 Jun 2004 22:03:29 -0000
> @@ -136,7 +136,9 @@
>  }
>  
>  CHXRateAdaptationInfo::CHXRateAdaptationInfo() :
> -    m_pRateAdaptCtl(NULL)
> +    m_pRateAdaptCtl(NULL),
> +    m_pCCF(NULL),
> +    m_pOBSN(NULL)
>  {}
>  
>  CHXRateAdaptationInfo::~CHXRateAdaptationInfo()
> @@ -158,6 +160,12 @@
>              res = pContext->QueryInterface(IID_IHXCommonClassFactory,
>                                             (void**)&m_pCCF);
>          }
> +
> +        if (HXR_OK == res)
> +        {
> +            res = pContext->QueryInterface(IID_IHX3gppOBSN,
> +                                           (void**)&m_pOBSN);
> +        }
>      }
>  
>      return res;
> @@ -174,6 +182,7 @@
>      
>      HX_RELEASE(m_pRateAdaptCtl);
>      HX_RELEASE(m_pCCF);
> +    HX_RELEASE(m_pOBSN);
>  
>      return HXR_OK;
>  }
> @@ -190,7 +199,7 @@
>      {
>          res = HXR_POINTER;
>      }
> -    else if (m_pRateAdaptCtl &&
> +    else if (m_pRateAdaptCtl && m_pOBSN &&
>               (HXR_OK == pHdr->GetPropertyULONG32("3GPP-Adaptation-Support",
>                                                   ulReportFreq)))
>      {
> @@ -286,6 +295,13 @@
>          {
>              // Disable client rate adaptation for this stream
>              res = m_pRateAdaptCtl->Disable(uStreamNumber);
> +
> +            if (HXR_OK == res)
> +            {
> +                // Set OBSN report frequency
> +                res = m_pOBSN->SetOBSNFrequency(uStreamNumber,
> +                                                pInfo->Get3gpReportFreq());
> +            }
>          }
>          else
>          {
> Index: rateadaptinfo.h
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/rateadaptinfo.h,v
> retrieving revision 1.1.2.1
> diff -u -r1.1.2.1 rateadaptinfo.h
> --- rateadaptinfo.h	16 Jun 2004 18:44:01 -0000	1.1.2.1
> +++ rateadaptinfo.h	25 Jun 2004 22:03:29 -0000
> @@ -43,6 +43,7 @@
>  #include "ihxpckts.h"
>  #include "hxccf.h"
>  #include "hxslist.h"
> +#include "ihx3gpp.h"
>  
>  class HXRAIStreamInfo;
>  
> @@ -83,5 +84,6 @@
>      IHXClientRateAdaptControl* m_pRateAdaptCtl;
>      IHXCommonClassFactory* m_pCCF;
>      CHXSimpleList m_streamInfo;
> +    IHX3gppOBSN* m_pOBSN;
>  };
>  #endif /* RATEADAPTINFO_H */
> Index: rtspclnt.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> retrieving revision 1.79.2.2
> diff -u -r1.79.2.2 rtspclnt.cpp
> --- rtspclnt.cpp	24 Jun 2004 18:16:35 -0000	1.79.2.2
> +++ rtspclnt.cpp	25 Jun 2004 22:03:29 -0000
> @@ -800,17 +800,21 @@
>          m_pPreferences->ReadPref("XWapProfileDiff", m_pUAProfDiff);
>      }
>  
> +    // m_pSrcBufStats MUST be initialized before m_pRateAdaptInfo
> +    // because it provides interfaces that m_pRateAdaptInfo needs
> +    // for initialization.
>      if (HXR_OK == hresult)
>      {
> -        m_pRateAdaptInfo = new CHXRateAdaptationInfo();
> -
> -        if (m_pRateAdaptInfo)
> +        HX_RELEASE(m_pSrcBufStats);
> +        m_pSrcBufStats = new HXNetSourceBufStats(this);
> +        
> +        if (m_pSrcBufStats)
>          {
> -            if (HXR_OK != m_pRateAdaptInfo->Init(pContext))
> +            m_pSrcBufStats->AddRef();
> +
> +            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
>              {
> -                // This is not a critical error. It just means
> -                // that we can't negotiate server rate adaptation.
> -                HX_DELETE(m_pRateAdaptInfo);
> +                HX_RELEASE(m_pSrcBufStats);
>              }
>          }
>          else
> @@ -821,16 +825,15 @@
>  
>      if (HXR_OK == hresult)
>      {
> -        HX_RELEASE(m_pSrcBufStats);
> -        m_pSrcBufStats = new HXNetSourceBufStats(this);
> -        
> -        if (m_pSrcBufStats)
> -        {
> -            m_pSrcBufStats->AddRef();
> +        m_pRateAdaptInfo = new CHXRateAdaptationInfo();
>  
> -            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
> +        if (m_pRateAdaptInfo)
> +        {
> +            if (HXR_OK != m_pRateAdaptInfo->Init(pContext))
>              {
> -                HX_RELEASE(m_pSrcBufStats);
> +                // This is not a critical error. It just means
> +                // that we can't negotiate server rate adaptation.
> +                HX_DELETE(m_pRateAdaptInfo);
>              }
>          }
>          else
> 
> Index: pkthndlr.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/pkthndlr.cpp,v
> retrieving revision 1.4
> diff -u -r1.4 pkthndlr.cpp
> --- pkthndlr.cpp	10 Sep 2003 23:29:35 -0000	1.4
> +++ pkthndlr.cpp	25 Jun 2004 22:03:41 -0000
> @@ -46,7 +46,6 @@
>      : m_pReport(NULL)
>      , m_pSDES(NULL)
>      , m_pBYE(NULL)
> -    , m_pAPP(NULL)
>  {
>  }
>  
> @@ -72,7 +71,7 @@
>  	m_pBYE = pPkt;
>  	break;
>      case RTCP_APP:
> -	m_pAPP = pPkt;
> +        m_APPList.AddTail(pPkt);
>  	break;
>      default:
>  	HX_ASSERT(!"RTCPPacker::Set():  Don't know this packet type");
> @@ -108,9 +107,13 @@
>      {
>  	ulBufSize += (m_pBYE->length + 1) * 4;
>      }
> -    if (m_pAPP)
> +
> +    LISTPOSITION pos = m_APPList.GetHeadPosition();
> +    while (pos)
>      {
> -	ulBufSize += (m_pAPP->length + 1) * 4;
> +        RTCPPacket* pAPP = 
> +            (RTCPPacket*)m_APPList.GetNext(pos);
> +	ulBufSize += (pAPP->length + 1) * 4;
>      }
>  
>      // now pack!
> @@ -125,10 +128,13 @@
>      PackOne(m_pSDES, pc, ulPackedLen);
>      HX_ASSERT((((UINT32)m_pSDES->length + 1) * 4) == ulPackedLen);
>  
> -    if (m_pAPP)
> +    pos = m_APPList.GetHeadPosition();
> +    while (pos)
>      {
> -	PackOne(m_pAPP, pc, ulPackedLen);
> -	HX_ASSERT((((UINT32)m_pAPP->length + 1) * 4) == ulPackedLen);		
> +        RTCPPacket* pAPP = 
> +            (RTCPPacket*)m_APPList.GetNext(pos);
> +	PackOne(pAPP, pc, ulPackedLen);
> +	HX_ASSERT((((UINT32)pAPP->length + 1) * 4) == ulPackedLen);		
>      }
>  
>      /* BYE pkt needs to be the last pkt! */
> Index: rtcputil.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/rtcputil.cpp,v
> retrieving revision 1.10
> diff -u -r1.10 rtcputil.cpp
> --- rtcputil.cpp	17 Feb 2004 20:08:52 -0000	1.10
> +++ rtcputil.cpp	25 Jun 2004 22:03:41 -0000
> @@ -40,6 +40,7 @@
>  #include "hxtick.h"
>  #include "hxengin.h"
>  #include "tconverter.h"
> +#include "netbyte.h"
>  
>  #include "interval.h"
>  #include "ntptime.h"
> @@ -507,6 +508,44 @@
>  	item.padding0 = 0;
>  	pPkt->SetAPPItem(&item, 1);
>  	pPkt->length += 4;
> +	res = HXR_OK;
> +    }
> +
> +    return res;
> +}
> +
> +HX_RESULT 
> +ReportHandler::MakeOBSN(RTCPPacket* pPkt, 
> +                        UINT16 uSequenceNum,
> +                        UINT16 uPlayoutDelay)
> +{
> +    HX_RESULT res = HXR_UNEXPECTED;
> +
> +    // We only handle the 1 sender case for
> +    // right now.
> +    if (pPkt && (m_mapSenders.GetCount() == 1))
> +    {
> +        CHXMapLongToObj::Iterator i = m_mapSenders.Begin();
> +        UINT32 ulSSRC = (UINT32)i.get_key();
> +
> +	pPkt->version_flag = 0x02;
> +	pPkt->padding_flag = 0;    
> +	pPkt->packet_type = RTCP_APP;
> +	pPkt->count = 0;
> +	pPkt->app_ssrc = m_pReceiverMe->m_ulSsrc;
> +	memcpy(pPkt->app_name, "PSS0", 4);
> +        pPkt->length = 2;
> +
> +        UINT8 obsnBuf[8];
> +        UINT32* pSSRC = (UINT32*)&obsnBuf[0];
> +        UINT16* pDelay = (UINT16*)&obsnBuf[4];
> +        UINT16* pSeq = (UINT16*)&obsnBuf[6];
> +
> +        *pSSRC = DwToNet(ulSSRC);
> +        *pDelay = WToNet(uPlayoutDelay);
> +        *pSeq = WToNet(uSequenceNum);
> +
> +        pPkt->SetAPPData(obsnBuf, sizeof(obsnBuf));
>  	res = HXR_OK;
>      }
>  
> Index: rtptran.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/rtptran.cpp,v
> retrieving revision 1.60
> diff -u -r1.60 rtptran.cpp
> --- rtptran.cpp	10 Mar 2004 20:05:22 -0000	1.60
> +++ rtptran.cpp	25 Jun 2004 22:03:41 -0000
> @@ -69,6 +69,7 @@
>  #include "hxqossig.h"
>  #include "hxqos.h"
>  //#include "hxcorgui.h"
> +#include "ihx3gpp.h"
>  
>  #include "ntptime.h"
>  
> @@ -2403,7 +2404,9 @@
>      m_ulLastSeq (0),
>      m_ulLastLoss (0),
>      m_ulLastRate (0),
> -    m_pTSScheduler (NULL)
> +    m_pTSScheduler (NULL),
> +    m_pOBSN(NULL),
> +    m_ulOBSNRRCount(0)
>  {
>  }
>  
> @@ -2462,6 +2465,8 @@
>      HX_RELEASE(m_pQoSSignal_APP);
>      HX_RELEASE(m_pSignalBus);
>      HX_RELEASE(m_pSessionId);
> +
> +    HX_RELEASE(m_pOBSN);
>  }
>  
>  HX_RESULT
> @@ -2481,6 +2486,15 @@
>      itoa(random32(HX_GET_TICKCOUNT()), cname, 10);    
>      m_pcCNAME = (BYTE*)new_string(cname);
>      HX_ASSERT(m_pcCNAME);
> +
> +    HX_RELEASE(m_pOBSN);
> +    if (m_pContext)
> +    {
> +        m_pContext->QueryInterface(IID_IHX3gppOBSN,
> +                                   (void**)&m_pOBSN);
> +        m_ulOBSNRRCount = 0;
> +    }
> +    
>      return HXR_OK;
>  }
>  
> @@ -3240,6 +3254,7 @@
>  //    IHXBuffer* pSendBuf = NULL;
>      RTCPPacket* pPktSDES = NULL;
>      RTCPPacket* pPktBufInfo = NULL;
> +    RTCPPacket* pPktOBSN = NULL;
>  
>      HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
>      UINT32 ulNow = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
> @@ -3300,6 +3315,59 @@
>  	HX_DELETE(pPktBufInfo);
>      }
>  
> +    if (m_pOBSN && m_pReportHandler)
> +    {
> +        UINT32 uFreq = 0;
> +
> +        // increment RR counter
> +        m_ulOBSNRRCount++;
> +
> +        // Get OBSN report frequency
> +        m_pOBSN->GetOBSNFrequency(m_streamNumber, uFreq);
> +        
> +        if (uFreq && (m_ulOBSNRRCount >= uFreq))
> +        {
> +            // Time to send an OBSN packet
> +
> +            UINT16 uSequenceNum = 0;
> +            UINT16 uPlayoutDelay = 0;
> +
> +            pPktOBSN = new RTCPPacket();
> +
> +            if ((HXR_OK ==  m_pOBSN->GetOBSNInfo(m_streamNumber,
> +                                                 uSequenceNum, 
> +                                                 uPlayoutDelay)) &&
> +                (HXR_OK == m_pReportHandler->MakeOBSN(pPktOBSN, 
> +                                                      uSequenceNum, 
> +                                                      uPlayoutDelay)))
> +            {
> +                // We successfully created an OBSN
> +                // packet.
> +
> +                // Reset our RR counter to 0
> +                m_ulOBSNRRCount = 0;
> +            }
> +            else
> +            {
> +                // If we failed for some reason,
> +                // just delete the packet so that
> +                // it doesn't get included in the
> +                // compound packet. Failing to
> +                // send an OBSN is not a 
> +                // critical error
> +                HX_DELETE(pPktOBSN);
> +            }
> +        }
> +    }
> +
>      // pack them up!
>      theErr = m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, 
>  						   (void**)&pSendBuf);
> @@ -3317,6 +3385,11 @@
>  	packer.Set(pPktBufInfo);
>      }
>  
> +    if (pPktOBSN)
> +    {
> +        packer.Set(pPktOBSN);
> +    }
> +
>      theErr = packer.Pack(pSendBuf);
>      
>      if (HXR_OK != theErr)
> @@ -3333,6 +3406,7 @@
>      HX_DELETE(pPktRR);
>      HX_DELETE(pPktSDES);
>      HX_DELETE(pPktBufInfo);
> +    HX_DELETE(pPktOBSN);
>  //    HX_RELEASE(pSendBuf);
>      return theErr;
>  }
> Index: pub/pkthndlr.h
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/pub/pkthndlr.h,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 pkthndlr.h
> --- pub/pkthndlr.h	18 Oct 2002 01:59:17 -0000	1.1.1.1
> +++ pub/pkthndlr.h	25 Jun 2004 22:03:41 -0000
> @@ -73,7 +73,7 @@
>      RTCPPacket*	    m_pReport;
>      RTCPPacket*	    m_pSDES;
>      RTCPPacket*	    m_pBYE;        
> -    RTCPPacket*	    m_pAPP;        
> +    CHXSimpleList   m_APPList;
>  };
>  
>  
> Index: pub/rtcputil.h
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/pub/rtcputil.h,v
> retrieving revision 1.5
> diff -u -r1.5 rtcputil.h
> --- pub/rtcputil.h	11 Nov 2003 01:20:41 -0000	1.5
> +++ pub/rtcputil.h	25 Jun 2004 22:03:41 -0000
> @@ -241,6 +241,9 @@
>      HX_RESULT MakeBufInfoApp	    (RTCPPacket* pPkt, 
>  				     UINT32 ulLowTS, UINT32 ulHighTS,
>  				     UINT32 ulBytesBuffered);
> +    HX_RESULT MakeOBSN	             (RTCPPacket* pPkt, 
> +				     UINT16 uSequenceNum,
> +				     UINT16 uPlayoutDelay);
>  
>      /* for RTCP interval calc */
>      void    UpdateAvgRTCPSize	    (UINT32 ulCompoundRTCPSize)
> Index: pub/rtptran.h
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/pub/rtptran.h,v
> retrieving revision 1.28
> diff -u -r1.28 rtptran.h
> --- pub/rtptran.h	3 May 2004 19:01:40 -0000	1.28
> +++ pub/rtptran.h	25 Jun 2004 22:03:41 -0000
> @@ -46,6 +46,7 @@
>  #include "ntptime.h"
>  #include "tconverter.h"
>  #include "chxkeepalive.h"
> +#include "ihx3gpp.h"
>  
>  // GCC won't let me forward declare CHXMapLongToObj::Iterator, 
>  // so I have to include this. -JR
> @@ -592,6 +593,9 @@
>      UINT32                              m_ulLastLoss;
>      UINT32                              m_ulLastRate;
>      UINT32                              m_ulRRIntvl;
> +
> +    IHX3gppOBSN*                        m_pOBSN;
> +    UINT32                              m_ulOBSNRRCount;
>  
>      friend class RTPBaseTransport;
>      friend class RTPUDPTransport;
> Index: pub/rtpwrap.h
> ===================================================================
> RCS file: /cvsroot/protocol/transport/rtp/pub/rtpwrap.h,v
> retrieving revision 1.8
> diff -u -r1.8 rtpwrap.h
> --- pub/rtpwrap.h	30 Sep 2003 16:15:42 -0000	1.8
> +++ pub/rtpwrap.h	25 Jun 2004 22:03:41 -0000
> @@ -124,6 +124,7 @@
>      //    app_name = 0;  // not a pointer...
>          app_data = 0;
>          m_pAPPItems = 0;
> +        m_bAPPDataSet = FALSE;
>      }
>  
>      ~RTCPPacket()
> @@ -195,9 +196,36 @@
>      void SetAPPItem (APPItem* item, UINT32 ulCount)
>      {
>          HX_VECTOR_DELETE(m_pAPPItems);
> +        m_bAPPDataSet = FALSE;
>  
>          m_pAPPItems = new APPItem[ulCount];
>          memcpy(m_pAPPItems, item, ulCount * sizeof (APPItem)); /* Flawfinder: ignore */
> +
> +    }
> +    
> +    void SetAPPData(const UINT8* pData, UINT32 ulLength)
> +    {
> +        // The data length MUST be a multiple of 4
> +        UINT32 ulAPPDataLen = ((ulLength + 3) & ~0x3);
> +
> +        // Update the length member variable
> +        length = 2 + ((ulAPPDataLen) >> 2);
> +
> +        HX_VECTOR_DELETE(app_data);
> +        app_data = new UINT8[ulAPPDataLen];
> +
> +        if (app_data)
> +        {
> +            if (ulAPPDataLen != ulLength)
> +            {
> +                // Zero out the extra bytes
> +                memset(app_data + ulLength, 0,
> +                       ulAPPDataLen - ulLength);
> +                           
> +            }
> +            memcpy(app_data, pData, ulLength);
> +            m_bAPPDataSet = TRUE;
> +        }
>      }
>      
>      // keys off of source id and contains a pointer to a list 
> @@ -205,6 +233,7 @@
>      CHXMapLongToObj	m_mapSDESSources;    
>      // array of APPItem
>      APPItem*		m_pAPPItems;
> +    BOOL                m_bAPPDataSet;
>      void CleanBuffers();
>  };
>  
> @@ -227,7 +256,10 @@
>  	delete [] bye_src;
>  
>      if (app_data)
> +    {
>  	delete [] app_data;
> +        m_bAPPDataSet = FALSE;
> +    }
>  	
>      CHXMapLongToObj::Iterator	i;
>      for (i = m_mapSDESSources.Begin(); i != m_mapSDESSources.End(); ++i)
> @@ -420,23 +452,26 @@
>       	* revert the m_mapSDESSources back to blob form
>       	*/
>      
> -    	if (app_data != NULL)
> -    	{
> -	    delete [] app_data;
> -    	}	
> -        
> -    	UINT8*  pBuf = new UINT8[0x1000];
> -    	UINT8*  pOff = pBuf;
> -	UINT32  ulDammy = 0;
> -	for (UINT32 i = 0; i < count; i++)
> -	{
> -	    pOff = m_pAPPItems[i].pack(pOff, ulDammy);
> -	}
> -
> -	app_data = new UINT8[pOff - pBuf];
> -	memcpy(app_data, pBuf, (pOff - pBuf) * sizeof(UINT8)); /* Flawfinder: ignore */
> -
> -	delete [] pBuf;
> +        if (!m_bAPPDataSet)
> +        {
> +            if (app_data != NULL)
> +            {
> +                delete [] app_data;
> +            }	
> +            
> +            UINT8*  pBuf = new UINT8[0x1000];
> +            UINT8*  pOff = pBuf;
> +            UINT32  ulDammy = 0;
> +            for (UINT32 i = 0; i < count; i++)
> +            {
> +                pOff = m_pAPPItems[i].pack(pOff, ulDammy);
> +            }
> +
> +            app_data = new UINT8[pOff - pBuf];
> +            memcpy(app_data, pBuf, (pOff - pBuf) * sizeof(UINT8)); /* Flawfinder: ignore */
> +            
> +            delete [] pBuf;
> +        }
>      }
>  
>      
> Index: hxsrcbufstats.cpp
> ===================================================================
> RCS file: /cvsroot/common/util/hxsrcbufstats.cpp,v
> retrieving revision 1.1.2.2
> diff -u -r1.1.2.2 hxsrcbufstats.cpp
> --- hxsrcbufstats.cpp	24 Jun 2004 21:21:46 -0000	1.1.2.2
> +++ hxsrcbufstats.cpp	25 Jun 2004 22:03:59 -0000
> @@ -78,12 +78,17 @@
>                    UINT16 uSeqNum);
>      void OnTimeSync(UINT32 ulCurrentTime);
>  
> -    HX_RESULT LowestSeqNumber(REF(UINT32) nLowestSeq);
> -
>      HX_RESULT GetBufferingStats(REF(INT64) llLowTS,
>                                  REF(INT64) llHighTS,
>                                  REF(UINT32) uNumBytes);
>      
> +    HX_RESULT GetOBSNInfo(REF(UINT16) uSequenceNum,
> +                          REF(UINT16) uPlayoutDelay);
> +
> +    HX_RESULT SetOBSNFrequency(UINT32 uFrequency);
> +
> +    HX_RESULT GetOBSNFrequency(REF(UINT32) uFrequency);
> +
>  private:
>  
>      void UpdateBufferInfo();
> @@ -105,7 +110,7 @@
>      BOOL m_bFirstPkt;
>      INT64 m_llFirstLivePacketTS;
>      INT64 m_llHighestTimestamp;
> -    UINT32 m_uLowestSeq;
> +    UINT32 m_uOBSNFreq;
>  };
>  
>  
> @@ -120,7 +125,7 @@
>      m_bIsLive(FALSE),
>      m_bFirstPkt(TRUE),
>      m_llFirstLivePacketTS(0),
> -    m_uLowestSeq(InvalidSeqNum)
> +    m_uOBSNFreq(0)
>  {}
>  
>  HXStreamPktBufInfo::~HXStreamPktBufInfo()
> @@ -151,7 +156,6 @@
>      if (m_bFirstPkt)
>      {
>          m_llHighestTimestamp = llActualTS;
> -        m_uLowestSeq = uSeqNum;
>  
>          if (m_bIsLive)
>          {
> @@ -224,7 +228,6 @@
>      m_bFirstPkt = TRUE;
>      m_llFirstLivePacketTS = 0;
>      m_llHighestTimestamp = 0;
> -    m_uLowestSeq = InvalidSeqNum;
>  }
>  
>  HX_RESULT 
> @@ -257,20 +260,75 @@
>      return res;
>  }
>  
> -HX_RESULT 
> -HXStreamPktBufInfo::LowestSeqNumber(REF(UINT32) nLowestSeq)
> +HX_RESULT
> +HXStreamPktBufInfo::GetOBSNInfo(REF(UINT16) uSequenceNum,
> +                                REF(UINT16) uPlayoutDelay)
>  {
> -    HX_RESULT res = HXR_NO_DATA;
> -    
> +    HX_RESULT res = HXR_FAILED;
> +
>      UpdateBufferInfo();
>  
> -    if (!m_bFirstPkt && (InvalidSeqNum != m_uLowestSeq))
> +    if (m_pktInfo.IsEmpty())
>      {
> -        nLowestSeq = m_uLowestSeq;
> -        res = HXR_OK;
> +        // Our buffer is empty
> +        res = HXR_NO_DATA;
> +    }
> +    else
> +    {
> +        // We have packets buffered
> +        HXPktInfo* pPktInfo = (HXPktInfo*)m_pktInfo.GetHead();
> +        
> +        if (pPktInfo->SequenceNum() != InvalidSeqNum)
> +        {
> +            // This packet info has a valid sequence number
> +
> +            uSequenceNum = (UINT16)pPktInfo->SequenceNum();
> +
> +            if (m_bCurrentTimeValid)
> +            {
> +                
> +                UINT32 uDelay = 
> +                    INT64_TO_UINT32(pPktInfo->Timestamp() - m_llCurrentTime);
> +
> +                
> +                if (uDelay > 0xfffe)
> +                {
> +                    // The delay is too large. Use
> +                    // the reserved value
> +                    uPlayoutDelay = 0xffff;
> +                }
> +                else
> +                {
> +                    uPlayoutDelay = (UINT16)uDelay;
> +                }
> +            }
> +            else
> +            {
> +                // We don't know what the delay is
> +                // so just report the reserved value.
> +                uPlayoutDelay = 0xffff;
> +            }
> +
> +            res = HXR_OK;
> +        }
>      }
> +    
> +    return res;
> +}
> +
> +HX_RESULT
> +HXStreamPktBufInfo::SetOBSNFrequency(UINT32 uFrequency)
> +{
> +    m_uOBSNFreq = uFrequency;
> +    return HXR_OK;
> +}
> +
> +HX_RESULT
> +HXStreamPktBufInfo::GetOBSNFrequency(REF(UINT32) uFrequency)
> +{
> +    uFrequency = m_uOBSNFreq;
>  
> -    return nLowestSeq;
> +    return HXR_OK;
>  }
>  
>  void HXStreamPktBufInfo::UpdateBufferInfo()
> @@ -284,7 +342,6 @@
>          {
>              m_pktInfo.RemoveHead();
>              m_uBytesBuffered -= pPktInfo->PacketSize();
> -            m_uLowestSeq = pPktInfo->SequenceNum();
>  
>              HX_DELETE(pPktInfo);
>  
> @@ -436,21 +493,6 @@
>      }
>  }
>  
> -HX_RESULT 
> -HXSourceBufferStats::LowestSeqNumber(UINT16  uStreamNumber, 
> -                                     REF(UINT32) nLowestSeq)
> -{
> -    HX_RESULT res = HXR_FAILED;
> -
> -    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> -    
> -    if (pBufInfo)
> -    {
> -        res = pBufInfo->LowestSeqNumber(nLowestSeq);
> -    }
> -
> -    return res;
> -}
>  /*
>   * IUnknown methods
>   */
> @@ -464,7 +506,8 @@
>          { GET_IIDHANDLE(IID_IUnknown), this },
>          { GET_IIDHANDLE(IID_IHXSourceBufferingStats), (IHXSourceBufferingStats*) this },
>          { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), (IHXSourceBufferingStats2*) this },
> -        { GET_IIDHANDLE(IID_IHXTransportTimeSink), (IHXTransportTimeSink*) this }
> +        { GET_IIDHANDLE(IID_IHXTransportTimeSink), (IHXTransportTimeSink*) this },
> +        { GET_IIDHANDLE(IID_IHX3gppOBSN), (IHX3gppOBSN*)this}
>      };
>      return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
>  }
> @@ -560,6 +603,59 @@
>          }
>      }
>  
> +    return res;
> +}
> +
> +/*
> + * IHX3gppOBSN Methods
> + */
> +
> +STDMETHODIMP 
> +HXSourceBufferStats::GetOBSNInfo(THIS_ UINT16 uStreamNumber,
> +                                 REF(UINT16) uSequenceNum,
> +                                 REF(UINT16) uPlayoutDelay)
> +{
> +    HX_RESULT res = HXR_INVALID_PARAMETER;
> +
> +    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> +
> +    if (pBufInfo)
> +    {
> +        res = pBufInfo->GetOBSNInfo(uSequenceNum, uPlayoutDelay);
> +    }
> +    
> +    return res;
> +}
> +
> +STDMETHODIMP
> +HXSourceBufferStats::SetOBSNFrequency(THIS_ UINT16 uStreamNumber,
> +                                        UINT32 uFrequency)
> +{
> +    HX_RESULT res = HXR_INVALID_PARAMETER;
> +
> +    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> +    
> +    if (pBufInfo)
> +    {
> +        res = pBufInfo->SetOBSNFrequency(uFrequency);
> +    }
> +    
> +    return res;
> +}
> +
> +STDMETHODIMP
> +HXSourceBufferStats::GetOBSNFrequency(THIS_ UINT16 uStreamNumber,
> +                                      REF(UINT32) uFrequency)
> +{
> +    HX_RESULT res = HXR_INVALID_PARAMETER;
> +
> +    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> +
> +    if (pBufInfo)
> +    {
> +        res = pBufInfo->GetOBSNFrequency(uFrequency);
> +    }
> +    
>      return res;
>  }
>  
> Index: pub/hxsrcbufstats.h
> ===================================================================
> RCS file: /cvsroot/common/util/pub/hxsrcbufstats.h,v
> retrieving revision 1.1.2.1
> diff -u -r1.1.2.1 hxsrcbufstats.h
> --- pub/hxsrcbufstats.h	24 Jun 2004 18:16:08 -0000	1.1.2.1
> +++ pub/hxsrcbufstats.h	25 Jun 2004 22:03:59 -0000
> @@ -42,11 +42,13 @@
>  #include "hxmap.h"
>  #include "hxcore.h"
>  #include "ihxtranstime.h"
> +#include "ihx3gpp.h"
>  
>  class HXStreamPktBufInfo;
>  
>  class HXSourceBufferStats : public IHXSourceBufferingStats2,
> -                            public IHXTransportTimeSink
> +                            public IHXTransportTimeSink,
> +                            public IHX3gppOBSN
>  {
>  public:
>      HXSourceBufferStats();
> @@ -97,6 +99,20 @@
>       * IHXTransportTimeSink methods
>       */
>      STDMETHOD(OnTransportTime) (THIS_ UINT32 ulCurrentTime);
> +
> +    /*
> +     * IHX3gppOBSN Methods
> +     */
> +
> +    STDMETHOD(GetOBSNInfo) (THIS_ UINT16 uStreamNumber,
> +                            REF(UINT16) uSequenceNum,
> +                            REF(UINT16) uPlayoutDelay);
> +    
> +    STDMETHOD(SetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
> +                                   UINT32 uFrequency);
> +
> +    STDMETHOD(GetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
> +                                   REF(UINT32) uFrequency);
>  
>  protected:
>      ~HXSourceBufferStats();
> 
> 
> Index: hxpiids.h
> ===================================================================
> RCS file: /cvsroot/common/include/hxpiids.h,v
> retrieving revision 1.28.2.2
> diff -u -r1.28.2.2 hxpiids.h
> --- hxpiids.h   24 Jun 2004 18:13:18 -0000      1.28.2.2
> +++ hxpiids.h   25 Jun 2004 22:14:00 -0000
> @@ -1010,5 +1010,14 @@
>  DEFINE_GUID_ENUM(IID_IHXTransportTimeManager,
>  0xd0a5ba01, 0xedfb, 0x4741, 0xb7, 0x9, 0x88, 0x4e, 0x68, 0x5d, 0x2d, 0x8)
>   
> +/* File:
> + *      ihx3gpp.h
> + *
> + * Description:
> + *      Interfaces for 3GPP functionality
> + */
> +DEFINE_GUID_ENUM(IID_IHX3gppOBSN,
> +0x8069baaf, 0x777a, 0x4cf0, 0x90, 0x3, 0xd2, 0x6d, 0x68, 0xb8, 0xd7, 0x86)
> +
>  #endif /* _HXPRIVATEIIDS_H_ */
>   

> /* ***** BEGIN LICENSE BLOCK *****  
>  * Source last modified: $Id:$ 
>  *   
>  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.  
>  *       
>  * The contents of this file, and the files included with this file, 
>  * are subject to the current version of the RealNetworks Public 
>  * Source License (the "RPSL") available at 
>  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
>  * the file under the current version of the RealNetworks Community 
>  * Source License (the "RCSL") available at 
>  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL 
>  * will apply. You may also obtain the license terms directly from 
>  * RealNetworks.  You may not use this file except in compliance with 
>  * the RPSL or, if you have a valid RCSL with RealNetworks applicable 
>  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for 
>  * the rights, obligations and limitations governing use of the 
>  * contents of the file. 
>  *   
>  * This file is part of the Helix DNA Technology. RealNetworks is the 
>  * developer of the Original Code and owns the copyrights in the 
>  * portions it created. 
>  *   
>  * This file, and the files included with this file, is distributed 
>  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY 
>  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS 
>  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES 
>  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET 
>  * ENJOYMENT OR NON-INFRINGEMENT. 
>  *  
>  * Technology Compatibility Kit Test Suite(s) Location:  
>  *    http://www.helixcommunity.org/content/tck  
>  *  
>  * Contributor(s):  
>  *   
>  * ***** END LICENSE BLOCK ***** */ 
> #ifndef IHX3GPP_H
> #define IHX3GPP_H
> 
> /****************************************************************************
>  * 
>  *  Interface:
>  * 
>  *	IHX3gppOBSN
>  * 
>  *  Purpose:
>  * 
>  *	Provides information for 3GPP-Rel6 OBSN packets
>  * 
>  *  IID_IHX3gppOBSN:
>  * 
>  *	{8069BAAF-777A-4cf0-9003-D26D68B8D786}
>  * 
>  */
> DEFINE_GUID(IID_IHX3gppOBSN, 
> 0x8069baaf, 0x777a, 0x4cf0, 0x90, 0x3, 0xd2, 0x6d, 0x68, 0xb8, 0xd7, 0x86);
> 
> #undef  INTERFACE
> #define INTERFACE   IHX3gppOBSN
> 
> DECLARE_INTERFACE_(IHX3gppOBSN, IUnknown)
> {
>     /*
>      * IUnknown methods
>      */
>     STDMETHOD(QueryInterface)	(THIS_
> 				REFIID riid,
> 				void** ppvObj) PURE;
> 
>     STDMETHOD_(ULONG32,AddRef)	(THIS) PURE;
> 
>     STDMETHOD_(ULONG32,Release)	(THIS) PURE;
> 
>     /*
>      * IHX3gppOBSN Methods
>      */
> 
>     /************************************************************************
>      *	Method:
>      *	    IHX3gppOBSN::GetOBSNInfo
>      *	Purpose:
>      *	    Get OBSN information for the specified stream
>      *
>      */
>     STDMETHOD(GetOBSNInfo) (THIS_ UINT16 uStreamNumber,
>                               REF(UINT16) uSequenceNum,
>                               REF(UINT16) uPlayoutDelay) PURE;
> 
>     /************************************************************************
>      *	Method:
>      *	    IHX3gppOBSN::SetOBSNFrequency
>      *	Purpose:
>      *	    Set the frequency of OBSN reports
>      *
>      */
>     STDMETHOD(SetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
>                                  UINT32 uFrequency) PURE;
> 
>     /************************************************************************
>      *	Method:
>      *	    IHX3gppOBSN::GetOBSNFrequency
>      *	Purpose:
>      *	    Get the frequency of OBSN reports
>      *
>      */
>     STDMETHOD(GetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
>                                  REF(UINT32) uFrequency) PURE;
> };
> 
> #endif /* IHX3GPP_H */

> _______________________________________________
> Common-dev mailing list
> Common-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/common-dev

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ihx3gpp.h
Type: text/x-chdr
Size: 3550 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040628/20481333/ihx3gpp-0001.bin
From dhedbor at real.com  Mon Jun 28 14:41:01 2004
From: dhedbor at real.com (dhedbor@real.com)
Date: Mon Jun 28 14:41:07 2004
Subject: [Common-dev] CN: Cast from int to CPUArchitecture enum
References: <5.1.0.14.2.20040625074112.02cb5540@mailone.real.com>
Message-ID: <87oen38ioi.fsf@real.com>

Modified by: dhedbor@real.com

Reviewed by: wschildbach@real.com

Date: 06-23-2004

Project: HEAD, hxclient_1_3_0_neptunex

Wolfgang Schildbach  writes:

> Looks good.
>
> - Wolfgang
>
> At 06:24 PM 6/24/2004 -0700, David Hedbor wrote:
>>Branch: HEAD and hxclient_1_3_0_neptunex
>>
>>Description:
>>
>>In the ARM cpu ident code the CPUArchitecture enum (pInfo->architecture)
>>is assigned an integer value without a cast. This breaks when compiling
>>with gcc 3.x.
>>
>>Fix:
>>
>>Added an explicit cast.
>>
>>Files modified:
>>
>>common/util/cpuident.c
>>
>>--
>>David Hedbor
>>
>>Index: common/util/cpuident.c
>>===================================================================
>>RCS file: /cvsroot/common/util/cpuident.c,v
>>retrieving revision 1.12
>>diff -u -r1.12 cpuident.c
>>--- common/util/cpuident.c      12 May 2003 17:17:39 -0000      1.12
>>+++ common/util/cpuident.c      25 Jun 2004 01:21:14 -0000
>>@@ -350,7 +350,7 @@
>>         pInfo->specific.m_arm.family        = ulFamily_POSTARM7 ;
>>         pInfo->specific.m_arm.implementor   = id >> 24 ;
>>         pInfo->specific.m_arm.variant       = (id >> 20) & 0xf ;
>> -       pInfo->architecture  = ((id >> 16) & 0xf) - 1 +
>> ulArchitectureARM_ARCH4 ;
>> +       pInfo->architecture  = (CPUArchitecture)(((id >> 16) & 0xf)
>> - 1 + ulArchitectureARM_ARCH4);
>>         pInfo->specific.m_arm.primaryPartNo = (id >> 4) & 0xfff ;
>>         pInfo->specific.m_arm.revision      = id & 0xf ;
>>         if (pInfo->specific.m_arm.implementor == ARM_IMPL_Intel &&
>>
>>_______________________________________________
>>Common-dev mailing list
>>Common-dev@lists.helixcommunity.org
>>http://lists.helixcommunity.org/mailman/listinfo/common-dev
>
> -
> - Wolfgang Schildbach, Principal Codec Engineer, RealNetworks Codec Group
> - email wschildbach@helixcommunity.org

-- 
David Hedbor, Software Development Engineer - Real Networks
Helix Community: http://helixcommunity.org


From milko at real.com  Mon Jun 28 17:24:56 2004
From: milko at real.com (milko)
Date: Mon Jun 28 17:25:18 2004
Subject: [Common-dev] CR-Client-Resend: Added 3GPP-Rel6 OBSN packet
	generation
In-Reply-To: <20040628203615.GA25059@real.com>
References: <20040625223311.GA17041@real.com> <20040625223311.GA17041@real.com>
Message-ID: <5.1.0.14.2.20040628172350.0330bb90@mailone.real.com>


Looks good.

At 01:36 PM 6/28/2004, Aaron Colwell wrote:
>Sending again
>
>On Fri, Jun 25, 2004 at 03:33:11PM -0700, Aaron Colwell wrote:
> > Synopsis: Add 3GPP-Rel6 OBSN packet generation code
> >
> > Overview: These changes bring together all the pieces needed to generate
> >           3GPP-Rel6 OBSN packets. A new interface, IHX3gppOBSN was created
> >           to allow access to OBSN related info. HXSourceBufferStats 
> implements
> >           this interface because it has all the relevent info for OBSN 
> reports.
> >           The server rate adaptation negotiation code uses this 
> interface to
> >           specify the negotiated OBSN report interval. The RTCP 
> transport code
> >           uses this interface to get the OBSN report interval and the
> >           information needed for the OBSN packets. Here is a list of the
> >           required changes.
> >
> >           - Added code to CHXRateAdaptationInfo to set the OBSN report
> >             frequency once 3GPP-Rel6 rate adaptation has been negotiated.
> >
> >           - Swapped the initialization order of m_pSrcBufStats and
> >             m_pRateAdaptInfo in RTSPClientProtocol. This was needed because
> >             m_pRateAdaptInfo relies on interfaces supplied by 
> m_pSrcBufStats.
> >
> >           - Added code to RTCPPacket so that it could pack more than 1 APP
> >             packet in an RTCP datagram. I just replaced m_pAPP with a 
> list and
> >             updated the appropriate logic.
> >
> >           - Added code to ReportHandler that generates the OBSN APP packet
> >
> >           - Added code to the RTCPBaseTransport to use the new IHX3gppOBSN
> >             interface to get the data for the OBSN packet. 
> RTCPBaseTransport
> >             also uses this interface to get the OBSN report frequency.
> >             OBSN packets are sent every Nth receiver report. I added a 
> member
> >             variable to count the receiver reports and send the OBSN 
> packets
> >             at the appropriate time.
> >
> >           - Created a new method RTCPPacket::SetAPPData() that allows 
> you to
> >             generate APP packets that don't follow the RN APP packet 
> format.
> >             RTCPPacket::pack() function need to be slightly modified to 
> handle
> >             this addition. The m_bAPPDataSet member variable was added to
> >             prevent RTCPPacket::pack() from deleting app_data and 
> looking for
> >             RN style APPItem objects to pack. SetAPPData() specifies 
> app_data
> >             directly and sets m_bAPPDataSet to TRUE so that pack 
> doesn't delete
> >             app_data.
> >
> >           - Removed LowestSeqNumber() methods from HXSourceBufferStats code
> >             since it is not needed
> >
> >           - Added an IHX3gppOBSN interface implementation to the
> >             HXSourceBufferStats code
> >
> > Files Modified:
> > protocol/rtsp/rateadaptinfo.cpp
> > protocol/rtsp/rateadaptinfo.h
> > protocol/rtsp/rtspclnt.cpp
> > protocol/transport/rtp/pkthndlr.cpp
> > protocol/transport/rtp/rtcputil.cpp
> > protocol/transport/rtp/rtptran.cpp
> > protocol/transport/rtp/pub/pkthndlr.h
> > protocol/transport/rtp/pub/rtcputil.h
> > protocol/transport/rtp/pub/rtptran.h
> > protocol/transport/rtp/pub/rtpwrap.h
> > common/util/hxsrcbufstats.cpp
> > common/util/pub/hxsrcbufstats.h
> > common/include/hxpiids.h
> >
> > Files Added:
> > common/include/ihx3gpp.h
> >
> > Image Size and Heap Use impact:
> >
> > Platforms and Profiles affected: all
> >
> > Distribution Libraries affected:  rdtclntlib
> >
> > Distribution library impact and planned action:
> > Member variables added to RTCPBaseTransport
> >
> > Platforms and Profiles Build Verified: win32
> >
> > Platforms and Profiles Functionality verified: win32
> >
> > Branch: HEAD
> >
> > QA Instructions: none
> >
> >
> > ===================================================================
> > RCS file: /cvsroot/protocol/rtsp/rateadaptinfo.cpp,v
> > retrieving revision 1.1.2.1
> > diff -u -r1.1.2.1 rateadaptinfo.cpp
> > --- rateadaptinfo.cpp 16 Jun 2004 18:44:01 -0000      1.1.2.1
> > +++ rateadaptinfo.cpp 25 Jun 2004 22:03:29 -0000
> > @@ -136,7 +136,9 @@
> >  }
> >
> >  CHXRateAdaptationInfo::CHXRateAdaptationInfo() :
> > -    m_pRateAdaptCtl(NULL)
> > +    m_pRateAdaptCtl(NULL),
> > +    m_pCCF(NULL),
> > +    m_pOBSN(NULL)
> >  {}
> >
> >  CHXRateAdaptationInfo::~CHXRateAdaptationInfo()
> > @@ -158,6 +160,12 @@
> >              res = pContext->QueryInterface(IID_IHXCommonClassFactory,
> >                                             (void**)&m_pCCF);
> >          }
> > +
> > +        if (HXR_OK == res)
> > +        {
> > +            res = pContext->QueryInterface(IID_IHX3gppOBSN,
> > +                                           (void**)&m_pOBSN);
> > +        }
> >      }
> >
> >      return res;
> > @@ -174,6 +182,7 @@
> >
> >      HX_RELEASE(m_pRateAdaptCtl);
> >      HX_RELEASE(m_pCCF);
> > +    HX_RELEASE(m_pOBSN);
> >
> >      return HXR_OK;
> >  }
> > @@ -190,7 +199,7 @@
> >      {
> >          res = HXR_POINTER;
> >      }
> > -    else if (m_pRateAdaptCtl &&
> > +    else if (m_pRateAdaptCtl && m_pOBSN &&
> >               (HXR_OK == 
> pHdr->GetPropertyULONG32("3GPP-Adaptation-Support",
> >                                                   ulReportFreq)))
> >      {
> > @@ -286,6 +295,13 @@
> >          {
> >              // Disable client rate adaptation for this stream
> >              res = m_pRateAdaptCtl->Disable(uStreamNumber);
> > +
> > +            if (HXR_OK == res)
> > +            {
> > +                // Set OBSN report frequency
> > +                res = m_pOBSN->SetOBSNFrequency(uStreamNumber,
> > 
> +                                                pInfo->Get3gpReportFreq());
> > +            }
> >          }
> >          else
> >          {
> > Index: rateadaptinfo.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/rtsp/rateadaptinfo.h,v
> > retrieving revision 1.1.2.1
> > diff -u -r1.1.2.1 rateadaptinfo.h
> > --- rateadaptinfo.h   16 Jun 2004 18:44:01 -0000      1.1.2.1
> > +++ rateadaptinfo.h   25 Jun 2004 22:03:29 -0000
> > @@ -43,6 +43,7 @@
> >  #include "ihxpckts.h"
> >  #include "hxccf.h"
> >  #include "hxslist.h"
> > +#include "ihx3gpp.h"
> >
> >  class HXRAIStreamInfo;
> >
> > @@ -83,5 +84,6 @@
> >      IHXClientRateAdaptControl* m_pRateAdaptCtl;
> >      IHXCommonClassFactory* m_pCCF;
> >      CHXSimpleList m_streamInfo;
> > +    IHX3gppOBSN* m_pOBSN;
> >  };
> >  #endif /* RATEADAPTINFO_H */
> > Index: rtspclnt.cpp
> > ===================================================================
> > RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> > retrieving revision 1.79.2.2
> > diff -u -r1.79.2.2 rtspclnt.cpp
> > --- rtspclnt.cpp      24 Jun 2004 18:16:35 -0000      1.79.2.2
> > +++ rtspclnt.cpp      25 Jun 2004 22:03:29 -0000
> > @@ -800,17 +800,21 @@
> >          m_pPreferences->ReadPref("XWapProfileDiff", m_pUAProfDiff);
> >      }
> >
> > +    // m_pSrcBufStats MUST be initialized before m_pRateAdaptInfo
> > +    // because it provides interfaces that m_pRateAdaptInfo needs
> > +    // for initialization.
> >      if (HXR_OK == hresult)
> >      {
> > -        m_pRateAdaptInfo = new CHXRateAdaptationInfo();
> > -
> > -        if (m_pRateAdaptInfo)
> > +        HX_RELEASE(m_pSrcBufStats);
> > +        m_pSrcBufStats = new HXNetSourceBufStats(this);
> > +
> > +        if (m_pSrcBufStats)
> >          {
> > -            if (HXR_OK != m_pRateAdaptInfo->Init(pContext))
> > +            m_pSrcBufStats->AddRef();
> > +
> > +            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
> >              {
> > -                // This is not a critical error. It just means
> > -                // that we can't negotiate server rate adaptation.
> > -                HX_DELETE(m_pRateAdaptInfo);
> > +                HX_RELEASE(m_pSrcBufStats);
> >              }
> >          }
> >          else
> > @@ -821,16 +825,15 @@
> >
> >      if (HXR_OK == hresult)
> >      {
> > -        HX_RELEASE(m_pSrcBufStats);
> > -        m_pSrcBufStats = new HXNetSourceBufStats(this);
> > -
> > -        if (m_pSrcBufStats)
> > -        {
> > -            m_pSrcBufStats->AddRef();
> > +        m_pRateAdaptInfo = new CHXRateAdaptationInfo();
> >
> > -            if (HXR_OK != m_pSrcBufStats->Init(m_pContext))
> > +        if (m_pRateAdaptInfo)
> > +        {
> > +            if (HXR_OK != m_pRateAdaptInfo->Init(pContext))
> >              {
> > -                HX_RELEASE(m_pSrcBufStats);
> > +                // This is not a critical error. It just means
> > +                // that we can't negotiate server rate adaptation.
> > +                HX_DELETE(m_pRateAdaptInfo);
> >              }
> >          }
> >          else
> >
> > Index: pkthndlr.cpp
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/pkthndlr.cpp,v
> > retrieving revision 1.4
> > diff -u -r1.4 pkthndlr.cpp
> > --- pkthndlr.cpp      10 Sep 2003 23:29:35 -0000      1.4
> > +++ pkthndlr.cpp      25 Jun 2004 22:03:41 -0000
> > @@ -46,7 +46,6 @@
> >      : m_pReport(NULL)
> >      , m_pSDES(NULL)
> >      , m_pBYE(NULL)
> > -    , m_pAPP(NULL)
> >  {
> >  }
> >
> > @@ -72,7 +71,7 @@
> >       m_pBYE = pPkt;
> >       break;
> >      case RTCP_APP:
> > -     m_pAPP = pPkt;
> > +        m_APPList.AddTail(pPkt);
> >       break;
> >      default:
> >       HX_ASSERT(!"RTCPPacker::Set():  Don't know this packet type");
> > @@ -108,9 +107,13 @@
> >      {
> >       ulBufSize += (m_pBYE->length + 1) * 4;
> >      }
> > -    if (m_pAPP)
> > +
> > +    LISTPOSITION pos = m_APPList.GetHeadPosition();
> > +    while (pos)
> >      {
> > -     ulBufSize += (m_pAPP->length + 1) * 4;
> > +        RTCPPacket* pAPP =
> > +            (RTCPPacket*)m_APPList.GetNext(pos);
> > +     ulBufSize += (pAPP->length + 1) * 4;
> >      }
> >
> >      // now pack!
> > @@ -125,10 +128,13 @@
> >      PackOne(m_pSDES, pc, ulPackedLen);
> >      HX_ASSERT((((UINT32)m_pSDES->length + 1) * 4) == ulPackedLen);
> >
> > -    if (m_pAPP)
> > +    pos = m_APPList.GetHeadPosition();
> > +    while (pos)
> >      {
> > -     PackOne(m_pAPP, pc, ulPackedLen);
> > -     HX_ASSERT((((UINT32)m_pAPP->length + 1) * 4) == 
> ulPackedLen);
> > +        RTCPPacket* pAPP =
> > +            (RTCPPacket*)m_APPList.GetNext(pos);
> > +     PackOne(pAPP, pc, ulPackedLen);
> > +     HX_ASSERT((((UINT32)pAPP->length + 1) * 4) == 
> ulPackedLen);
> >      }
> >
> >      /* BYE pkt needs to be the last pkt! */
> > Index: rtcputil.cpp
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/rtcputil.cpp,v
> > retrieving revision 1.10
> > diff -u -r1.10 rtcputil.cpp
> > --- rtcputil.cpp      17 Feb 2004 20:08:52 -0000      1.10
> > +++ rtcputil.cpp      25 Jun 2004 22:03:41 -0000
> > @@ -40,6 +40,7 @@
> >  #include "hxtick.h"
> >  #include "hxengin.h"
> >  #include "tconverter.h"
> > +#include "netbyte.h"
> >
> >  #include "interval.h"
> >  #include "ntptime.h"
> > @@ -507,6 +508,44 @@
> >       item.padding0 = 0;
> >       pPkt->SetAPPItem(&item, 1);
> >       pPkt->length += 4;
> > +     res = HXR_OK;
> > +    }
> > +
> > +    return res;
> > +}
> > +
> > +HX_RESULT
> > +ReportHandler::MakeOBSN(RTCPPacket* pPkt,
> > +                        UINT16 uSequenceNum,
> > +                        UINT16 uPlayoutDelay)
> > +{
> > +    HX_RESULT res = HXR_UNEXPECTED;
> > +
> > +    // We only handle the 1 sender case for
> > +    // right now.
> > +    if (pPkt && (m_mapSenders.GetCount() == 1))
> > +    {
> > +        CHXMapLongToObj::Iterator i = m_mapSenders.Begin();
> > +        UINT32 ulSSRC = (UINT32)i.get_key();
> > +
> > +     pPkt->version_flag = 0x02;
> > +     pPkt->padding_flag = 0;
> > +     pPkt->packet_type = RTCP_APP;
> > +     pPkt->count = 0;
> > +     pPkt->app_ssrc = m_pReceiverMe->m_ulSsrc;
> > +     memcpy(pPkt->app_name, "PSS0", 4);
> > +        pPkt->length = 2;
> > +
> > +        UINT8 obsnBuf[8];
> > +        UINT32* pSSRC = (UINT32*)&obsnBuf[0];
> > +        UINT16* pDelay = (UINT16*)&obsnBuf[4];
> > +        UINT16* pSeq = (UINT16*)&obsnBuf[6];
> > +
> > +        *pSSRC = DwToNet(ulSSRC);
> > +        *pDelay = WToNet(uPlayoutDelay);
> > +        *pSeq = WToNet(uSequenceNum);
> > +
> > +        pPkt->SetAPPData(obsnBuf, sizeof(obsnBuf));
> >       res = HXR_OK;
> >      }
> >
> > Index: rtptran.cpp
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/rtptran.cpp,v
> > retrieving revision 1.60
> > diff -u -r1.60 rtptran.cpp
> > --- rtptran.cpp       10 Mar 2004 20:05:22 -0000      1.60
> > +++ rtptran.cpp       25 Jun 2004 22:03:41 -0000
> > @@ -69,6 +69,7 @@
> >  #include "hxqossig.h"
> >  #include "hxqos.h"
> >  //#include "hxcorgui.h"
> > +#include "ihx3gpp.h"
> >
> >  #include "ntptime.h"
> >
> > @@ -2403,7 +2404,9 @@
> >      m_ulLastSeq (0),
> >      m_ulLastLoss (0),
> >      m_ulLastRate (0),
> > -    m_pTSScheduler (NULL)
> > +    m_pTSScheduler (NULL),
> > +    m_pOBSN(NULL),
> > +    m_ulOBSNRRCount(0)
> >  {
> >  }
> >
> > @@ -2462,6 +2465,8 @@
> >      HX_RELEASE(m_pQoSSignal_APP);
> >      HX_RELEASE(m_pSignalBus);
> >      HX_RELEASE(m_pSessionId);
> > +
> > +    HX_RELEASE(m_pOBSN);
> >  }
> >
> >  HX_RESULT
> > @@ -2481,6 +2486,15 @@
> >      itoa(random32(HX_GET_TICKCOUNT()), cname, 10);
> >      m_pcCNAME = (BYTE*)new_string(cname);
> >      HX_ASSERT(m_pcCNAME);
> > +
> > +    HX_RELEASE(m_pOBSN);
> > +    if (m_pContext)
> > +    {
> > +        m_pContext->QueryInterface(IID_IHX3gppOBSN,
> > +                                   (void**)&m_pOBSN);
> > +        m_ulOBSNRRCount = 0;
> > +    }
> > +
> >      return HXR_OK;
> >  }
> >
> > @@ -3240,6 +3254,7 @@
> >  //    IHXBuffer* pSendBuf = NULL;
> >      RTCPPacket* pPktSDES = NULL;
> >      RTCPPacket* pPktBufInfo = NULL;
> > +    RTCPPacket* pPktOBSN = NULL;
> >
> >      HXTimeval rmatv = m_pScheduler->GetCurrentSchedulerTime();
> >      UINT32 ulNow = rmatv.tv_sec*1000 + rmatv.tv_usec/1000;
> > @@ -3300,6 +3315,59 @@
> >       HX_DELETE(pPktBufInfo);
> >      }
> >
> > +    if (m_pOBSN && m_pReportHandler)
> > +    {
> > +        UINT32 uFreq = 0;
> > +
> > +        // increment RR counter
> > +        m_ulOBSNRRCount++;
> > +
> > +        // Get OBSN report frequency
> > +        m_pOBSN->GetOBSNFrequency(m_streamNumber, uFreq);
> > +
> > +        if (uFreq && (m_ulOBSNRRCount >= uFreq))
> > +        {
> > +            // Time to send an OBSN packet
> > +
> > +            UINT16 uSequenceNum = 0;
> > +            UINT16 uPlayoutDelay = 0;
> > +
> > +            pPktOBSN = new RTCPPacket();
> > +
> > +            if ((HXR_OK ==  m_pOBSN->GetOBSNInfo(m_streamNumber,
> > +                                                 uSequenceNum,
> > +                                                 uPlayoutDelay)) &&
> > +                (HXR_OK == m_pReportHandler->MakeOBSN(pPktOBSN,
> > +                                                      uSequenceNum,
> > +                                                      uPlayoutDelay)))
> > +            {
> > +                // We successfully created an OBSN
> > +                // packet.
> > +
> > +                // Reset our RR counter to 0
> > +                m_ulOBSNRRCount = 0;
> > +            }
> > +            else
> > +            {
> > +                // If we failed for some reason,
> > +                // just delete the packet so that
> > +                // it doesn't get included in the
> > +                // compound packet. Failing to
> > +                // send an OBSN is not a
> > +                // critical error
> > +                HX_DELETE(pPktOBSN);
> > +            }
> > +        }
> > +    }
> > +
> >      // pack them up!
> >      theErr = m_pCommonClassFactory->CreateInstance(IID_IHXBuffer,
> >                                                  (void**)&pSendBuf);
> > @@ -3317,6 +3385,11 @@
> >       packer.Set(pPktBufInfo);
> >      }
> >
> > +    if (pPktOBSN)
> > +    {
> > +        packer.Set(pPktOBSN);
> > +    }
> > +
> >      theErr = packer.Pack(pSendBuf);
> >
> >      if (HXR_OK != theErr)
> > @@ -3333,6 +3406,7 @@
> >      HX_DELETE(pPktRR);
> >      HX_DELETE(pPktSDES);
> >      HX_DELETE(pPktBufInfo);
> > +    HX_DELETE(pPktOBSN);
> >  //    HX_RELEASE(pSendBuf);
> >      return theErr;
> >  }
> > Index: pub/pkthndlr.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/pub/pkthndlr.h,v
> > retrieving revision 1.1.1.1
> > diff -u -r1.1.1.1 pkthndlr.h
> > --- pub/pkthndlr.h    18 Oct 2002 01:59:17 -0000      1.1.1.1
> > +++ pub/pkthndlr.h    25 Jun 2004 22:03:41 -0000
> > @@ -73,7 +73,7 @@
> >      RTCPPacket*          m_pReport;
> >      RTCPPacket*          m_pSDES;
> >      RTCPPacket*          m_pBYE;
> > -    RTCPPacket*          m_pAPP;
> > +    CHXSimpleList   m_APPList;
> >  };
> >
> >
> > Index: pub/rtcputil.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/pub/rtcputil.h,v
> > retrieving revision 1.5
> > diff -u -r1.5 rtcputil.h
> > --- pub/rtcputil.h    11 Nov 2003 01:20:41 -0000      1.5
> > +++ pub/rtcputil.h    25 Jun 2004 22:03:41 -0000
> > @@ -241,6 +241,9 @@
> >      HX_RESULT MakeBufInfoApp     (RTCPPacket* pPkt,
> >                                    UINT32 ulLowTS, UINT32 ulHighTS,
> >                                    UINT32 ulBytesBuffered);
> > +    HX_RESULT MakeOBSN                    (RTCPPacket* pPkt,
> > +                                  UINT16 uSequenceNum,
> > +                                  UINT16 uPlayoutDelay);
> >
> >      /* for RTCP interval calc */
> >      void    UpdateAvgRTCPSize            (UINT32 ulCompoundRTCPSize)
> > Index: pub/rtptran.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/pub/rtptran.h,v
> > retrieving revision 1.28
> > diff -u -r1.28 rtptran.h
> > --- pub/rtptran.h     3 May 2004 19:01:40 -0000       1.28
> > +++ pub/rtptran.h     25 Jun 2004 22:03:41 -0000
> > @@ -46,6 +46,7 @@
> >  #include "ntptime.h"
> >  #include "tconverter.h"
> >  #include "chxkeepalive.h"
> > +#include "ihx3gpp.h"
> >
> >  // GCC won't let me forward declare CHXMapLongToObj::Iterator,
> >  // so I have to include this. -JR
> > @@ -592,6 +593,9 @@
> >      UINT32                              m_ulLastLoss;
> >      UINT32                              m_ulLastRate;
> >      UINT32                              m_ulRRIntvl;
> > +
> > +    IHX3gppOBSN*                        m_pOBSN;
> > +    UINT32                              m_ulOBSNRRCount;
> >
> >      friend class RTPBaseTransport;
> >      friend class RTPUDPTransport;
> > Index: pub/rtpwrap.h
> > ===================================================================
> > RCS file: /cvsroot/protocol/transport/rtp/pub/rtpwrap.h,v
> > retrieving revision 1.8
> > diff -u -r1.8 rtpwrap.h
> > --- pub/rtpwrap.h     30 Sep 2003 16:15:42 -0000      1.8
> > +++ pub/rtpwrap.h     25 Jun 2004 22:03:41 -0000
> > @@ -124,6 +124,7 @@
> >      //    app_name = 0;  // not a pointer...
> >          app_data = 0;
> >          m_pAPPItems = 0;
> > +        m_bAPPDataSet = FALSE;
> >      }
> >
> >      ~RTCPPacket()
> > @@ -195,9 +196,36 @@
> >      void SetAPPItem (APPItem* item, UINT32 ulCount)
> >      {
> >          HX_VECTOR_DELETE(m_pAPPItems);
> > +        m_bAPPDataSet = FALSE;
> >
> >          m_pAPPItems = new APPItem[ulCount];
> >          memcpy(m_pAPPItems, item, ulCount * sizeof (APPItem)); /* 
> Flawfinder: ignore */
> > +
> > +    }
> > +
> > +    void SetAPPData(const UINT8* pData, UINT32 ulLength)
> > +    {
> > +        // The data length MUST be a multiple of 4
> > +        UINT32 ulAPPDataLen = ((ulLength + 3) & ~0x3);
> > +
> > +        // Update the length member variable
> > +        length = 2 + ((ulAPPDataLen) >> 2);
> > +
> > +        HX_VECTOR_DELETE(app_data);
> > +        app_data = new UINT8[ulAPPDataLen];
> > +
> > +        if (app_data)
> > +        {
> > +            if (ulAPPDataLen != ulLength)
> > +            {
> > +                // Zero out the extra bytes
> > +                memset(app_data + ulLength, 0,
> > +                       ulAPPDataLen - ulLength);
> > +
> > +            }
> > +            memcpy(app_data, pData, ulLength);
> > +            m_bAPPDataSet = TRUE;
> > +        }
> >      }
> >
> >      // keys off of source id and contains a pointer to a list
> > @@ -205,6 +233,7 @@
> >      CHXMapLongToObj  m_mapSDESSources;
> >      // array of APPItem
> >      APPItem*         m_pAPPItems;
> > +    BOOL                m_bAPPDataSet;
> >      void CleanBuffers();
> >  };
> >
> > @@ -227,7 +256,10 @@
> >       delete [] bye_src;
> >
> >      if (app_data)
> > +    {
> >       delete [] app_data;
> > +        m_bAPPDataSet = FALSE;
> > +    }
> >
> >      CHXMapLongToObj::Iterator        i;
> >      for (i = m_mapSDESSources.Begin(); i != m_mapSDESSources.End(); ++i)
> > @@ -420,23 +452,26 @@
> >               * revert the m_mapSDESSources back to blob form
> >               */
> >
> > -     if (app_data != NULL)
> > -     {
> > -         delete [] app_data;
> > -     }
> > -
> > -     UINT8*  pBuf = new UINT8[0x1000];
> > -     UINT8*  pOff = pBuf;
> > -     UINT32  ulDammy = 0;
> > -     for (UINT32 i = 0; i < count; i++)
> > -     {
> > -         pOff = m_pAPPItems[i].pack(pOff, ulDammy);
> > -     }
> > -
> > -     app_data = new UINT8[pOff - pBuf];
> > -     memcpy(app_data, pBuf, (pOff - pBuf) * sizeof(UINT8)); /* 
> Flawfinder: ignore */
> > -
> > -     delete [] pBuf;
> > +        if (!m_bAPPDataSet)
> > +        {
> > +            if (app_data != NULL)
> > +            {
> > +                delete [] app_data;
> > +            }
> > +
> > +            UINT8*  pBuf = new UINT8[0x1000];
> > +            UINT8*  pOff = pBuf;
> > +            UINT32  ulDammy = 0;
> > +            for (UINT32 i = 0; i < count; i++)
> > +            {
> > +                pOff = m_pAPPItems[i].pack(pOff, ulDammy);
> > +            }
> > +
> > +            app_data = new UINT8[pOff - pBuf];
> > +            memcpy(app_data, pBuf, (pOff - pBuf) * sizeof(UINT8)); /* 
> Flawfinder: ignore */
> > +
> > +            delete [] pBuf;
> > +        }
> >      }
> >
> >
> > Index: hxsrcbufstats.cpp
> > ===================================================================
> > RCS file: /cvsroot/common/util/hxsrcbufstats.cpp,v
> > retrieving revision 1.1.2.2
> > diff -u -r1.1.2.2 hxsrcbufstats.cpp
> > --- hxsrcbufstats.cpp 24 Jun 2004 21:21:46 -0000      1.1.2.2
> > +++ hxsrcbufstats.cpp 25 Jun 2004 22:03:59 -0000
> > @@ -78,12 +78,17 @@
> >                    UINT16 uSeqNum);
> >      void OnTimeSync(UINT32 ulCurrentTime);
> >
> > -    HX_RESULT LowestSeqNumber(REF(UINT32) nLowestSeq);
> > -
> >      HX_RESULT GetBufferingStats(REF(INT64) llLowTS,
> >                                  REF(INT64) llHighTS,
> >                                  REF(UINT32) uNumBytes);
> >
> > +    HX_RESULT GetOBSNInfo(REF(UINT16) uSequenceNum,
> > +                          REF(UINT16) uPlayoutDelay);
> > +
> > +    HX_RESULT SetOBSNFrequency(UINT32 uFrequency);
> > +
> > +    HX_RESULT GetOBSNFrequency(REF(UINT32) uFrequency);
> > +
> >  private:
> >
> >      void UpdateBufferInfo();
> > @@ -105,7 +110,7 @@
> >      BOOL m_bFirstPkt;
> >      INT64 m_llFirstLivePacketTS;
> >      INT64 m_llHighestTimestamp;
> > -    UINT32 m_uLowestSeq;
> > +    UINT32 m_uOBSNFreq;
> >  };
> >
> >
> > @@ -120,7 +125,7 @@
> >      m_bIsLive(FALSE),
> >      m_bFirstPkt(TRUE),
> >      m_llFirstLivePacketTS(0),
> > -    m_uLowestSeq(InvalidSeqNum)
> > +    m_uOBSNFreq(0)
> >  {}
> >
> >  HXStreamPktBufInfo::~HXStreamPktBufInfo()
> > @@ -151,7 +156,6 @@
> >      if (m_bFirstPkt)
> >      {
> >          m_llHighestTimestamp = llActualTS;
> > -        m_uLowestSeq = uSeqNum;
> >
> >          if (m_bIsLive)
> >          {
> > @@ -224,7 +228,6 @@
> >      m_bFirstPkt = TRUE;
> >      m_llFirstLivePacketTS = 0;
> >      m_llHighestTimestamp = 0;
> > -    m_uLowestSeq = InvalidSeqNum;
> >  }
> >
> >  HX_RESULT
> > @@ -257,20 +260,75 @@
> >      return res;
> >  }
> >
> > -HX_RESULT
> > -HXStreamPktBufInfo::LowestSeqNumber(REF(UINT32) nLowestSeq)
> > +HX_RESULT
> > +HXStreamPktBufInfo::GetOBSNInfo(REF(UINT16) uSequenceNum,
> > +                                REF(UINT16) uPlayoutDelay)
> >  {
> > -    HX_RESULT res = HXR_NO_DATA;
> > -
> > +    HX_RESULT res = HXR_FAILED;
> > +
> >      UpdateBufferInfo();
> >
> > -    if (!m_bFirstPkt && (InvalidSeqNum != m_uLowestSeq))
> > +    if (m_pktInfo.IsEmpty())
> >      {
> > -        nLowestSeq = m_uLowestSeq;
> > -        res = HXR_OK;
> > +        // Our buffer is empty
> > +        res = HXR_NO_DATA;
> > +    }
> > +    else
> > +    {
> > +        // We have packets buffered
> > +        HXPktInfo* pPktInfo = (HXPktInfo*)m_pktInfo.GetHead();
> > +
> > +        if (pPktInfo->SequenceNum() != InvalidSeqNum)
> > +        {
> > +            // This packet info has a valid sequence number
> > +
> > +            uSequenceNum = (UINT16)pPktInfo->SequenceNum();
> > +
> > +            if (m_bCurrentTimeValid)
> > +            {
> > +
> > +                UINT32 uDelay =
> > +                    INT64_TO_UINT32(pPktInfo->Timestamp() - 
> m_llCurrentTime);
> > +
> > +
> > +                if (uDelay > 0xfffe)
> > +                {
> > +                    // The delay is too large. Use
> > +                    // the reserved value
> > +                    uPlayoutDelay = 0xffff;
> > +                }
> > +                else
> > +                {
> > +                    uPlayoutDelay = (UINT16)uDelay;
> > +                }
> > +            }
> > +            else
> > +            {
> > +                // We don't know what the delay is
> > +                // so just report the reserved value.
> > +                uPlayoutDelay = 0xffff;
> > +            }
> > +
> > +            res = HXR_OK;
> > +        }
> >      }
> > +
> > +    return res;
> > +}
> > +
> > +HX_RESULT
> > +HXStreamPktBufInfo::SetOBSNFrequency(UINT32 uFrequency)
> > +{
> > +    m_uOBSNFreq = uFrequency;
> > +    return HXR_OK;
> > +}
> > +
> > +HX_RESULT
> > +HXStreamPktBufInfo::GetOBSNFrequency(REF(UINT32) uFrequency)
> > +{
> > +    uFrequency = m_uOBSNFreq;
> >
> > -    return nLowestSeq;
> > +    return HXR_OK;
> >  }
> >
> >  void HXStreamPktBufInfo::UpdateBufferInfo()
> > @@ -284,7 +342,6 @@
> >          {
> >              m_pktInfo.RemoveHead();
> >              m_uBytesBuffered -= pPktInfo->PacketSize();
> > -            m_uLowestSeq = pPktInfo->SequenceNum();
> >
> >              HX_DELETE(pPktInfo);
> >
> > @@ -436,21 +493,6 @@
> >      }
> >  }
> >
> > -HX_RESULT
> > -HXSourceBufferStats::LowestSeqNumber(UINT16  uStreamNumber,
> > -                                     REF(UINT32) nLowestSeq)
> > -{
> > -    HX_RESULT res = HXR_FAILED;
> > -
> > -    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> > -
> > -    if (pBufInfo)
> > -    {
> > -        res = pBufInfo->LowestSeqNumber(nLowestSeq);
> > -    }
> > -
> > -    return res;
> > -}
> >  /*
> >   * IUnknown methods
> >   */
> > @@ -464,7 +506,8 @@
> >          { GET_IIDHANDLE(IID_IUnknown), this },
> >          { GET_IIDHANDLE(IID_IHXSourceBufferingStats), 
> (IHXSourceBufferingStats*) this },
> >          { GET_IIDHANDLE(IID_IHXSourceBufferingStats2), 
> (IHXSourceBufferingStats2*) this },
> > -        { GET_IIDHANDLE(IID_IHXTransportTimeSink), 
> (IHXTransportTimeSink*) this }
> > +        { GET_IIDHANDLE(IID_IHXTransportTimeSink), 
> (IHXTransportTimeSink*) this },
> > +        { GET_IIDHANDLE(IID_IHX3gppOBSN), (IHX3gppOBSN*)this}
> >      };
> >      return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
> >  }
> > @@ -560,6 +603,59 @@
> >          }
> >      }
> >
> > +    return res;
> > +}
> > +
> > +/*
> > + * IHX3gppOBSN Methods
> > + */
> > +
> > +STDMETHODIMP
> > +HXSourceBufferStats::GetOBSNInfo(THIS_ UINT16 uStreamNumber,
> > +                                 REF(UINT16) uSequenceNum,
> > +                                 REF(UINT16) uPlayoutDelay)
> > +{
> > +    HX_RESULT res = HXR_INVALID_PARAMETER;
> > +
> > +    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> > +
> > +    if (pBufInfo)
> > +    {
> > +        res = pBufInfo->GetOBSNInfo(uSequenceNum, uPlayoutDelay);
> > +    }
> > +
> > +    return res;
> > +}
> > +
> > +STDMETHODIMP
> > +HXSourceBufferStats::SetOBSNFrequency(THIS_ UINT16 uStreamNumber,
> > +                                        UINT32 uFrequency)
> > +{
> > +    HX_RESULT res = HXR_INVALID_PARAMETER;
> > +
> > +    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> > +
> > +    if (pBufInfo)
> > +    {
> > +        res = pBufInfo->SetOBSNFrequency(uFrequency);
> > +    }
> > +
> > +    return res;
> > +}
> > +
> > +STDMETHODIMP
> > +HXSourceBufferStats::GetOBSNFrequency(THIS_ UINT16 uStreamNumber,
> > +                                      REF(UINT32) uFrequency)
> > +{
> > +    HX_RESULT res = HXR_INVALID_PARAMETER;
> > +
> > +    HXStreamPktBufInfo* pBufInfo = GetPktBufInfo(uStreamNumber);
> > +
> > +    if (pBufInfo)
> > +    {
> > +        res = pBufInfo->GetOBSNFrequency(uFrequency);
> > +    }
> > +
> >      return res;
> >  }
> >
> > Index: pub/hxsrcbufstats.h
> > ===================================================================
> > RCS file: /cvsroot/common/util/pub/hxsrcbufstats.h,v
> > retrieving revision 1.1.2.1
> > diff -u -r1.1.2.1 hxsrcbufstats.h
> > --- pub/hxsrcbufstats.h       24 Jun 2004 18:16:08 -0000      1.1.2.1
> > +++ pub/hxsrcbufstats.h       25 Jun 2004 22:03:59 -0000
> > @@ -42,11 +42,13 @@
> >  #include "hxmap.h"
> >  #include "hxcore.h"
> >  #include "ihxtranstime.h"
> > +#include "ihx3gpp.h"
> >
> >  class HXStreamPktBufInfo;
> >
> >  class HXSourceBufferStats : public IHXSourceBufferingStats2,
> > -                            public IHXTransportTimeSink
> > +                            public IHXTransportTimeSink,
> > +                            public IHX3gppOBSN
> >  {
> >  public:
> >      HXSourceBufferStats();
> > @@ -97,6 +99,20 @@
> >       * IHXTransportTimeSink methods
> >       */
> >      STDMETHOD(OnTransportTime) (THIS_ UINT32 ulCurrentTime);
> > +
> > +    /*
> > +     * IHX3gppOBSN Methods
> > +     */
> > +
> > +    STDMETHOD(GetOBSNInfo) (THIS_ UINT16 uStreamNumber,
> > +                            REF(UINT16) uSequenceNum,
> > +                            REF(UINT16) uPlayoutDelay);
> > +
> > +    STDMETHOD(SetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
> > +                                   UINT32 uFrequency);
> > +
> > +    STDMETHOD(GetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
> > +                                   REF(UINT32) uFrequency);
> >
> >  protected:
> >      ~HXSourceBufferStats();
> >
> >
> > Index: hxpiids.h
> > ===================================================================
> > RCS file: /cvsroot/common/include/hxpiids.h,v
> > retrieving revision 1.28.2.2
> > diff -u -r1.28.2.2 hxpiids.h
> > --- hxpiids.h   24 Jun 2004 18:13:18 -0000      1.28.2.2
> > +++ hxpiids.h   25 Jun 2004 22:14:00 -0000
> > @@ -1010,5 +1010,14 @@
> >  DEFINE_GUID_ENUM(IID_IHXTransportTimeManager,
> >  0xd0a5ba01, 0xedfb, 0x4741, 0xb7, 0x9, 0x88, 0x4e, 0x68, 0x5d, 0x2d, 0x8)
> >
> > +/* File:
> > + *      ihx3gpp.h
> > + *
> > + * Description:
> > + *      Interfaces for 3GPP functionality
> > + */
> > +DEFINE_GUID_ENUM(IID_IHX3gppOBSN,
> > +0x8069baaf, 0x777a, 0x4cf0, 0x90, 0x3, 0xd2, 0x6d, 0x68, 0xb8, 0xd7, 0x86)
> > +
> >  #endif /* _HXPRIVATEIIDS_H_ */
> >
>
> > /* ***** BEGIN LICENSE BLOCK *****
> >  * Source last modified: $Id:$
> >  *
> >  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights 
> Reserved.
> >  *
> >  * The contents of this file, and the files included with this file,
> >  * are subject to the current version of the RealNetworks Public
> >  * Source License (the "RPSL") available at
> >  * http://www.helixcommunity.org/content/rpsl unless you have licensed
> >  * the file under the current version of the RealNetworks Community
> >  * Source License (the "RCSL") available at
> >  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
> >  * will apply. You may also obtain the license terms directly from
> >  * RealNetworks.  You may not use this file except in compliance with
> >  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
> >  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
> >  * the rights, obligations and limitations governing use of the
> >  * contents of the file.
> >  *
> >  * This file is part of the Helix DNA Technology. RealNetworks is the
> >  * developer of the Original Code and owns the copyrights in the
> >  * portions it created.
> >  *
> >  * This file, and the files included with this file, is distributed
> >  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
> >  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
> >  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
> >  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
> >  * ENJOYMENT OR NON-INFRINGEMENT.
> >  *
> >  * Technology Compatibility Kit Test Suite(s) Location:
> >  *    http://www.helixcommunity.org/content/tck
> >  *
> >  * Contributor(s):
> >  *
> >  * ***** END LICENSE BLOCK ***** */
> > #ifndef IHX3GPP_H
> > #define IHX3GPP_H
> >
> > 
> /****************************************************************************
> >  *
> >  *  Interface:
> >  *
> >  *    IHX3gppOBSN
> >  *
> >  *  Purpose:
> >  *
> >  *    Provides information for 3GPP-Rel6 OBSN packets
> >  *
> >  *  IID_IHX3gppOBSN:
> >  *
> >  *    {8069BAAF-777A-4cf0-9003-D26D68B8D786}
> >  *
> >  */
> > DEFINE_GUID(IID_IHX3gppOBSN,
> > 0x8069baaf, 0x777a, 0x4cf0, 0x90, 0x3, 0xd2, 0x6d, 0x68, 0xb8, 0xd7, 0x86);
> >
> > #undef  INTERFACE
> > #define INTERFACE   IHX3gppOBSN
> >
> > DECLARE_INTERFACE_(IHX3gppOBSN, IUnknown)
> > {
> >     /*
> >      * IUnknown methods
> >      */
> >     STDMETHOD(QueryInterface) (THIS_
> >                               REFIID riid,
> >                               void** ppvObj) PURE;
> >
> >     STDMETHOD_(ULONG32,AddRef)        (THIS) PURE;
> >
> >     STDMETHOD_(ULONG32,Release)       (THIS) PURE;
> >
> >     /*
> >      * IHX3gppOBSN Methods
> >      */
> >
> > 
> /************************************************************************
> >      *        Method:
> >      *            IHX3gppOBSN::GetOBSNInfo
> >      *        Purpose:
> >      *            Get OBSN information for the specified stream
> >      *
> >      */
> >     STDMETHOD(GetOBSNInfo) (THIS_ UINT16 uStreamNumber,
> >                               REF(UINT16) uSequenceNum,
> >                               REF(UINT16) uPlayoutDelay) PURE;
> >
> > 
> /************************************************************************
> >      *        Method:
> >      *            IHX3gppOBSN::SetOBSNFrequency
> >      *        Purpose:
> >      *            Set the frequency of OBSN reports
> >      *
> >      */
> >     STDMETHOD(SetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
> >                                  UINT32 uFrequency) PURE;
> >
> > 
> /************************************************************************
> >      *        Method:
> >      *            IHX3gppOBSN::GetOBSNFrequency
> >      *        Purpose:
> >      *            Get the frequency of OBSN reports
> >      *
> >      */
> >     STDMETHOD(GetOBSNFrequency) (THIS_ UINT16 uStreamNumber,
> >                                  REF(UINT32) uFrequency) PURE;
> > };
> >
> > #endif /* IHX3GPP_H */
>
> > _______________________________________________
> > Common-dev mailing list
> > Common-dev@lists.helixcommunity.org
> > http://lists.helixcommunity.org/mailman/listinfo/common-dev
>
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev



From ehyche at real.com  Tue Jun 29 11:29:33 2004
From: ehyche at real.com (Eric Hyche)
Date: Tue Jun 29 11:31:02 2004
Subject: [Common-dev] CR-Client: Initial checkin of new-using-old network
 services shim
Message-ID: <5.1.0.14.2.20040629141521.00bcdac8@mailone.real.com>


[Milko: should we do a code walk-through on this, or is it
not necessary since this is almost entirely new code?]

Synopsis: Initial checkin of new-using-old network services shim,
           and accompanying tests

Overview: This shim layer implements the new network services interfaces
           in hxnet.h using the old network services interfaces in
           hxengin.h. There may still be some changes and/or bug fixes
           in this shim, but this is the initial checkin. The second
           .zip file also includes a command-line unittest application.
           Note: this diff does not hook up the shim into the client
           engine. That will be later after the shim has been tested
           against httpfsys and viewsource changes.

Files Added:
client/common/netio/platform/posix/shim_utils.cpp
client/common/netio/platform/posix/shim_net_services.cpp
client/common/netio/platform/posix/shim_socket.cpp
client/common/netio/platform/posix/shim_resolve.cpp
client/common/netio/platform/posix/shim_listening_socket.cpp
client/common/netio/pub/platform/posix/shim_utils.h
client/common/netio/pub/platform/posix/shim_net_services.h
client/common/netio/pub/platform/posix/shim_socket.h
client/common/netio/pub/platform/posix/shim_resolve.h
client/common/netio/pub/platform/posix/shim_listening_socket.h

Files Modified:
client/common/netio/win.pcf - Add shim files
client/common/netio/platform/posix/hxclientsockimp.cpp - Change SetContext 
to return HX_RESULT
client/common/netio/pub/platform/posix/hxclientsockimp.h - Change 
SetContext to return HX_RESULT
common/include/hxnet.h - Add HX_SOCK_EVENT_LAST definition
common/netio/hxsockutil.cpp - Add GetIN4Address and GetIN4Port utility 
functions
common/netio/pub/hxsockutil.h - Add GetIN4Address and GetIN4Port utility 
functions
helix.bif - Add client_common_netio_unittest target

Image Size and Heap Use impact: addition

Platforms and Profiles Affected: win32 only for now, will later turn on 
other platforms

Distribution Libraries affected: none

Distribution library impact and planned action: n/a

Platforms and Profiles Build Verified: win32

Platforms and Profiles Functionality verified: win32

Branch: HEAD only

QA Instructions: none


======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: client_common_netio_unittest.zip
Type: application/zip
Size: 22533 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040629/a64955fa/client_common_netio_unittest-0001.zip
-------------- next part --------------
A non-text attachment was scrubbed...
Name: client_common_netio_shim.zip
Type: application/zip
Size: 25161 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/common-dev/attachments/20040629/a64955fa/client_common_netio_shim-0001.zip
-------------- next part --------------
Index: win.pcf
===================================================================
RCS file: /cvsroot/client/common/netio/win.pcf,v
retrieving revision 1.6
diff -u -w -u -w -r1.6 win.pcf
--- win.pcf	4 Jun 2004 02:14:54 -0000	1.6
+++ win.pcf	29 Jun 2004 18:12:44 -0000
@@ -35,12 +35,18 @@
 # ***** END LICENSE BLOCK ***** 
 # 
 
-project.AddDefines('WIN32_LEAN_AND_MEAN')
-project.AddSources('platform/win/hxnetif.cpp',
-		   'platform/posix/chxresolver.cpp',
-		   'platform/posix/hxclientsockimp.cpp')
+project.AddDefines("WIN32_LEAN_AND_MEAN")
 
-project.AddModuleIncludes('common/netio/pub/platform/posix',
-			  'client/common/netio/pub/platform/posix',
-			  'common/netio/pub/platform/win',
-			  'common/util/pub/platform/win')
+project.AddSources("platform/win/hxnetif.cpp",
+                   "platform/posix/chxresolver.cpp",
+                   "platform/posix/hxclientsockimp.cpp",
+                   "platform/posix/shim_utils.cpp",
+                   "platform/posix/shim_net_services.cpp",
+                   "platform/posix/shim_socket.cpp",
+                   "platform/posix/shim_resolve.cpp",
+                   "platform/posix/shim_listening_socket.cpp")
+
+project.AddModuleIncludes("common/netio/pub/platform/posix",
+                          "client/common/netio/pub/platform/posix",
+                          "common/netio/pub/platform/win",
+                          "common/util/pub/platform/win")
Index: platform/posix/hxclientsockimp.cpp
===================================================================
RCS file: /cvsroot/client/common/netio/platform/posix/hxclientsockimp.cpp,v
retrieving revision 1.3
diff -u -w -u -w -r1.3 hxclientsockimp.cpp
--- platform/posix/hxclientsockimp.cpp	24 Jun 2004 23:44:10 -0000	1.3
+++ platform/posix/hxclientsockimp.cpp	29 Jun 2004 18:12:44 -0000
@@ -111,13 +111,22 @@
     HX_RELEASE(m_pScheduler);
 }
 
-void CHXClientNetServices::SetContext(IUnknown* pContext)
+HX_RESULT CHXClientNetServices::SetContext(IUnknown* pContext)
 {
+    HX_RESULT retVal = HXR_FAIL;
+
     HX_ASSERT(pContext);
-    pContext->QueryInterface(IID_IHXScheduler, reinterpret_cast(&m_pScheduler));
+    if (pContext)
+    {
+        HX_RELEASE(m_pScheduler);
+        retVal = pContext->QueryInterface(IID_IHXScheduler,
+                                          reinterpret_cast(&m_pScheduler));
     HX_ASSERT(m_pScheduler);
 }
 
+    return retVal;
+}
+
 STDMETHODIMP
 CHXClientSocket::SelectEvents(UINT32 uEventMask)
 {
Index: pub/platform/posix/hxclientsockimp.h
===================================================================
RCS file: /cvsroot/client/common/netio/pub/platform/posix/hxclientsockimp.h,v
retrieving revision 1.3
diff -u -w -u -w -r1.3 hxclientsockimp.h
--- pub/platform/posix/hxclientsockimp.h	24 Jun 2004 23:44:10 -0000	1.3
+++ pub/platform/posix/hxclientsockimp.h	29 Jun 2004 18:12:44 -0000
@@ -69,7 +69,7 @@
 {
 public:
   
-    CHXClientSocket(CHXNetServices* pNetSvc, IHXScheduler* pScheduler, HXSockFamily f, HXSockType t, HXSockProtocol p, HX_SOCK sock = HX_SOCK_NONE);
+    CHXClientSocket(CHXNetServices* pNetSvc, IHXScheduler* pScheduler, HXSockFamily f, HXSockType t, HXSockProtocol p, HX_SOCK s = HX_SOCK_NONE);
     CHXClientSocket(CHXNetServices* pNetSvc, IHXScheduler* pScheduler);
     ~CHXClientSocket();
 
@@ -90,18 +90,18 @@
 {
 public:
     CHXClientNetServices();
-    ~CHXClientNetServices();
+    virtual ~CHXClientNetServices();
 
-    void SetContext(IUnknown* pContext);
     STDMETHOD(CreateResolver)       (THIS_ IHXResolve** ppResolver);
     STDMETHOD(CreateSocket)         (THIS_ IHXSocket** ppSock);
 
+    virtual HX_RESULT SetContext(IUnknown* pContext);
     virtual HX_RESULT CreateSocket  (HXSockFamily f,
                                      HXSockType t,
                                      HXSockProtocol p,
                                      HX_SOCK s,
                                      IHXSocket** ppSock);
-private:
+protected:
     IHXScheduler* m_pScheduler;
 };
 
Index: hxnet.h
===================================================================
RCS file: /cvsroot/common/include/hxnet.h,v
retrieving revision 1.9
diff -u -w -u -w -r1.9 hxnet.h
--- hxnet.h	24 Jun 2004 23:53:23 -0000	1.9
+++ hxnet.h	29 Jun 2004 18:13:08 -0000
@@ -415,6 +415,9 @@
 #define HX_SOCK_EVENT_CONNECT   (1<<4)
 #define HX_SOCK_EVENT_CLOSE     (1<<5)
 #define HX_SOCK_EVENT_TIMEOUT   (1<<6)
+/* If another HX_SOCK_EVENT_xxx event is added,
+   then make sure and update HX_SOCK_EVENT_LAST */
+#define HX_SOCK_EVENT_LAST      HX_SOCK_EVENT_TIMEOUT
 
 /* Initially for MaskEvents but makes a good general purpose enum */
 enum HXMaskOp
Index: hxsockutil.cpp
===================================================================
RCS file: /cvsroot/common/netio/hxsockutil.cpp,v
retrieving revision 1.5
diff -u -w -u -w -r1.5 hxsockutil.cpp
--- hxsockutil.cpp	25 Jun 2004 00:31:15 -0000	1.5
+++ hxsockutil.cpp	29 Jun 2004 18:13:20 -0000
@@ -556,15 +556,48 @@
 
 }
 
+HX_RESULT HXSockUtil::GetIN4Address(IHXSockAddr* pAddr, REF(UINT32) rulAddr)
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+    if (pAddr && pAddr->GetFamily() == HX_SOCK_FAMILY_IN4)
+    {
+        char szAddr[HX_ADDRSTRLEN];
+        retVal = pAddr->GetAddr(szAddr);
+        if (SUCCEEDED(retVal))
+        {
+            UINT32 ulVal[4] = {0, 0, 0, 0};
+            INT32  lNumArg  = sscanf(szAddr, "%u.%u.%u.%u",
+                                     &ulVal[0], &ulVal[1],
+                                     &ulVal[2], &ulVal[3]);
+            if (lNumArg == 4)
+            {
+                rulAddr = (ulVal[0] << 24) | (ulVal[1] << 16) | (ulVal[2] << 8) | ulVal[3];
+            }
+            else
+            {
+                retVal = HXR_FAIL;
+            }
+        }
+    }
+
+    return retVal;
+}
+
+HX_RESULT HXSockUtil::GetIN4Port(IHXSockAddr* pAddr, REF(UINT16) rusPort)
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+    if (pAddr && pAddr->GetFamily() == HX_SOCK_FAMILY_IN4)
+    {
+        char szPort[HX_PORTSTRLEN];
+        retVal = pAddr->GetPort(szPort);
+        if (SUCCEEDED(retVal))
+        {
+            rusPort = (UINT16) atol(szPort);
+        }
+    }
 
-
-
-
-
-
-
-
-
-
-
+    return retVal;
+}
 
Index: pub/hxsockutil.h
===================================================================
RCS file: /cvsroot/common/netio/pub/hxsockutil.h,v
retrieving revision 1.5
diff -u -w -u -w -r1.5 hxsockutil.h
--- pub/hxsockutil.h	28 Jun 2004 16:32:17 -0000	1.5
+++ pub/hxsockutil.h	29 Jun 2004 18:13:20 -0000
@@ -83,6 +83,8 @@
                                           HXSockType t, HXSockProtocol p,
                                           IHXSocket*& pSock);
 
+    static HX_RESULT GetIN4Address(IHXSockAddr* pAddr, REF(UINT32) rulAddr);
+    static HX_RESULT GetIN4Port(IHXSockAddr* pAddr, REF(UINT16) rusPort);
 };
 #endif //HX_SOCKUTIL_H__
 
Index: helix.bif
===================================================================
RCS file: /cvsroot/common/build/BIF/helix.bif,v
retrieving revision 1.435
diff -u -w -u -w -r1.435 helix.bif
--- helix.bif	28 Jun 2004 21:32:15 -0000	1.435
+++ helix.bif	29 Jun 2004 18:28:35 -0000
@@ -1200,6 +1200,33 @@
       
     
 
+    
+    
+      
+
+      
+          common_include
+      
+        
+      
+         common_util
+         common_system
+         common_container
+         common_dbgtool
+         common_runtime
+         common_netio
+         common_fileio
+         client_common_netio
+         client_common_system
+         client_common_container
+         datatype_tools_minicntx
+         client_netwksvc
+         protocol_http
+         protocol_common_util
+         common_umake_mspsdk
+      
+    
+
     
     
       
From acolwell at real.com  Tue Jun 29 12:29:44 2004
From: acolwell at real.com (Aaron Colwell)
Date: Tue Jun 29 12:31:23 2004
Subject: [Common-dev] CR-Client: Fix RTP streaming on HEAD
Message-ID: <20040629192944.GA28548@real.com>

Synopsis: Fix RTP streaming on HEAD

Overview: - Changed RTSP code so that it creates a new IHXSockAddr object
            for the second transport port. The original code passes in an
            interface and then assumes that the callee copies the value.
            This is not valid assumption since the callee is free to just
            hold onto a reference. The caller ends up changing the port
            number and handing the object to another transport object. Since
            the same interface was used, both transports now have the second
            port number as their port number. This is not equivalent to the
            original code. I've added code to copy the address into a new
            object, increment the port, and hand the new object into the second
            transport. 

          - Removed the socket_reuseaddr(s->sock); from hx_bind(). You should
            be able to determine if a port is already used by using hx_bind().
            socket_reuseaddr(s->sock) prevents that from happening and causes
            bind to assume that you ALWAYS want to reuse the port. Any code
            that wants to reuse a port should explicitly call 
            socket_reuseaddr() if they want this semantic.

Files Modified:
protocol/rtsp/rtspclnt.cpp
common/netio/platform/posix/netdrv.cpp

Files Added: none

Image Size and Heap Use impact:

Platforms and Profiles affected: all

Distribution Libraries affected: none

Distribution library impact and planned action: none

Platforms and Profiles Build Verified: win32

Platforms and Profiles Functionality verified: win32

Branch: HEAD

QA Instructions: none

Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.92
diff -u -r1.92 rtspclnt.cpp
--- rtspclnt.cpp	29 Jun 2004 16:58:54 -0000	1.92
+++ rtspclnt.cpp	29 Jun 2004 19:18:33 -0000
@@ -6472,8 +6472,15 @@
                 mapControlToStreamNo(pStreamInfo->m_streamControl, pStreamInfo->m_streamNumber);
 
                 pRtpTran->setPeerAddr(pResendAddr);
+
+                IHXSockAddr* pResendAddr2 = NULL;
+                pResendAddr->Clone(&pResendAddr2);
                 pResendAddr->AddPort(1); //XXXTDM
-                pRtcpTran->setPeerAddr(pResendAddr);
+
+                pRtcpTran->setPeerAddr(pResendAddr2);
+
+                HX_RELEASE(pResendAddr2);
+
                 if (!m_sessionID.IsEmpty())
                 {
                     pTrans->setSessionID(m_sessionID);

Index: platform/posix/netdrv.cpp
===================================================================
RCS file: /cvsroot/common/netio/platform/posix/netdrv.cpp,v
retrieving revision 1.11
diff -u -r1.11 netdrv.cpp
--- platform/posix/netdrv.cpp	24 Jun 2004 23:49:25 -0000	1.11
+++ platform/posix/netdrv.cpp	29 Jun 2004 19:18:51 -0000
@@ -732,7 +732,7 @@
 {
     int rc;
     socklen_t addrlen = socklen_of_family(addr->ss_family);
-    socket_reuseaddr(s->sock);
+
     rc = ::bind(s->sock, (sockaddr*)addr, addrlen);
     if (rc == 0)
     {

From nhart at real.com  Tue Jun 29 17:06:39 2004
From: nhart at real.com (Nicholas Hart)
Date: Tue Jun 29 17:06:41 2004
Subject: [Common-dev] CR: common/dbgtool/pub/errdbg.h
Message-ID: <1088553998.5241.5.camel@linicks.dev.prognet.com>


I've been dealing with a bunch of nasty crashes on linux and narrowed it
down to an ugly bug in errdbg.h.  It seems that we only use vsnprintf on
windows & openwave.  On other systems (like linux) we just used
vsprintf.  So, on these systems every time we try to log a message
larger than 2k it corrupts the heap and kills the player sooner or
later.

Since errdbg.h includes hlxclib/stdio.h and that header defines
vsnprintf for every platform (either mapping it to _vsnprintf for
windows, leaving it alone for systems that have it, or mapping it to
__helix_vsnprintf, which unfortunately uses vsprintf and still has this
overflow bug) this should be a pretty safe fix.

I think that someone should implement a better __helix_vsnprintf, or
else this will continue to be a problem on systems that don't have
vsnprintf.

I wish to check this in to hxclient_1_3_0_neptunex and HEAD.  Assuming
it's accepted I'd recommend that others consider merging it to their own
branches.



-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com
-------------- next part --------------
? errdbg.h.patch
Index: errdbg.h
===================================================================
RCS file: /cvsroot/common/dbgtool/pub/errdbg.h,v
retrieving revision 1.11
diff -u -w -r1.11 errdbg.h
--- errdbg.h	4 Oct 2003 01:30:23 -0000	1.11
+++ errdbg.h	30 Jun 2004 00:04:11 -0000
@@ -39,32 +39,28 @@
 extern const char* g_pDebugOutLevels[];
 extern const BOOL  g_bDebugOutDefaults[];
 
-#if defined(_WINDOWS) || defined(_OPENWAVE)
-#define VSNPRINTF_SUPPORT
-#endif
+#define DEBUG_OUT_BUF_SZ 2048
 
-#ifdef VSNPRINTF_SUPPORT
 #include "hlxclib/stdio.h"
 inline int debug_out_sprintf(char* pBuffer, const char* pFormatString, ...)
 {
     va_list argptr;
     va_start(argptr, pFormatString);
-    int nCharsWritten = _vsnprintf(pBuffer, 2048, pFormatString, argptr);
-    pBuffer[2047] = '\0';
+    int nCharsWritten = vsnprintf(pBuffer, DEBUG_OUT_BUF_SZ, 
+				  pFormatString, argptr);
+    pBuffer[DEBUG_OUT_BUF_SZ-1] = '\0';
     va_end(argptr);
 
     return nCharsWritten;
 }
 #define DEBUG_OUT_SPRINTF debug_out_sprintf
-#else
-#define DEBUG_OUT_SPRINTF sprintf /* Flawfinder: ignore */
-#endif // VSNPRINTF_SUPPORT
+
 
 #if defined(HELIX_FEATURE_DBG_LOG) && !defined(GOLD)
 #include "hxerror.h"
 #define DEBUG_OUT(x, l, y) {						\
 			    char* s;					\
-			    s = new char[2048];				\
+			    s = new char[DEBUG_OUT_BUF_SZ];		\
 			    if(s){                                      \
 			    DEBUG_OUT_SPRINTF y;			\
 			    x ? x->Report(HXLOG_DEBUG, 0, l, s, 0) : 0;	\
@@ -79,7 +75,7 @@
 #define DEBUG_OUTF(x, y)	{						\
 			    char* s;					\
 			    FILE* f1;					\
-			    s = new char[2048];				\
+			    s = new char[DEBUG_OUT_BUF_SZ];		\
 			    if(s){                                      \
 			    DEBUG_OUT_SPRINTF y;			\
 			    f1 = (x)?(::fopen(x, "a+")):(NULL);			\
@@ -100,7 +96,7 @@
 			    char* p_dbgx;								\
 			    FILE* f1_dbgx;								\
 			    int i_dbgx = (idx > 0)?(DEBUG_OUTF_IDX_COL_WIDTH * idx):0;			\
-			    p_dbgx = s = new char[2048 + i_dbgx];					\
+			    p_dbgx = s = new char[DEBUG_OUT_BUF_SZ + i_dbgx];				\
 			    if(s){ \
 			    if (i_dbgx < 1024)								\
 				for (; i_dbgx > 0; i_dbgx--)						\
From milko at real.com  Tue Jun 29 20:56:41 2004
From: milko at real.com (milko)
Date: Tue Jun 29 20:56:53 2004
Subject: [Common-dev] Re: [Client-dev] CR-Client: Initial checkin of
 new-using-old network services shim
In-Reply-To: <5.1.0.14.2.20040629141521.00bcdac8@mailone.real.com>
Message-ID: <5.1.0.14.2.20040629203050.03118680@mailone.real.com>

At 11:29 AM 6/29/2004, Eric Hyche wrote:

>[Milko: should we do a code walk-through on this, or is it
>not necessary since this is almost entirely new code?]

Not required.  Generally this amount of code would require a code 
walk-through but given that code is additive and deals with well known 
interfaces it is not necessary.  It is at your option and at the option of 
the reviewers.

Milko



>Synopsis: Initial checkin of new-using-old network services shim,
>           and accompanying tests
>
>Overview: This shim layer implements the new network services interfaces
>           in hxnet.h using the old network services interfaces in
>           hxengin.h. There may still be some changes and/or bug fixes
>           in this shim, but this is the initial checkin. The second
>           .zip file also includes a command-line unittest application.
>           Note: this diff does not hook up the shim into the client
>           engine. That will be later after the shim has been tested
>           against httpfsys and viewsource changes.
>
>Files Added:
>client/common/netio/platform/posix/shim_utils.cpp
>client/common/netio/platform/posix/shim_net_services.cpp
>client/common/netio/platform/posix/shim_socket.cpp
>client/common/netio/platform/posix/shim_resolve.cpp
>client/common/netio/platform/posix/shim_listening_socket.cpp
>client/common/netio/pub/platform/posix/shim_utils.h
>client/common/netio/pub/platform/posix/shim_net_services.h
>client/common/netio/pub/platform/posix/shim_socket.h
>client/common/netio/pub/platform/posix/shim_resolve.h
>client/common/netio/pub/platform/posix/shim_listening_socket.h
>
>Files Modified:
>client/common/netio/win.pcf - Add shim files
>client/common/netio/platform/posix/hxclientsockimp.cpp - Change SetContext 
>to return HX_RESULT
>client/common/netio/pub/platform/posix/hxclientsockimp.h - Change 
>SetContext to return HX_RESULT
>common/include/hxnet.h - Add HX_SOCK_EVENT_LAST definition
>common/netio/hxsockutil.cpp - Add GetIN4Address and GetIN4Port utility 
>functions
>common/netio/pub/hxsockutil.h - Add GetIN4Address and GetIN4Port utility 
>functions
>helix.bif - Add client_common_netio_unittest target
>
>Image Size and Heap Use impact: addition
>
>Platforms and Profiles Affected: win32 only for now, will later turn on 
>other platforms
>
>Distribution Libraries affected: none
>
>Distribution library impact and planned action: n/a
>
>Platforms and Profiles Build Verified: win32
>
>Platforms and Profiles Functionality verified: win32
>
>Branch: HEAD only
>
>QA Instructions: none
>
>
>======================================
>M. Eric Hyche (ehyche@real.com)
>Core Technologies
>RealNetworks, Inc.
>
>
>
>
>_______________________________________________
>Client-dev mailing list
>Client-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/client-dev



From ehyche at real.com  Wed Jun 30 06:00:45 2004
From: ehyche at real.com (Eric Hyche)
Date: Wed Jun 30 06:00:54 2004
Subject: [Common-dev] CR: common/dbgtool/pub/errdbg.h
In-Reply-To: <1088553998.5241.5.camel@linicks.dev.prognet.com>
Message-ID: <5.1.0.14.2.20040630090018.00bae940@mailone.real.com>


This looks good to me.

Eric

At 05:06 PM 6/29/2004 -0700, Nicholas Hart wrote:

>I've been dealing with a bunch of nasty crashes on linux and narrowed it
>down to an ugly bug in errdbg.h.  It seems that we only use vsnprintf on
>windows & openwave.  On other systems (like linux) we just used
>vsprintf.  So, on these systems every time we try to log a message
>larger than 2k it corrupts the heap and kills the player sooner or
>later.
>
>Since errdbg.h includes hlxclib/stdio.h and that header defines
>vsnprintf for every platform (either mapping it to _vsnprintf for
>windows, leaving it alone for systems that have it, or mapping it to
>__helix_vsnprintf, which unfortunately uses vsprintf and still has this
>overflow bug) this should be a pretty safe fix.
>
>I think that someone should implement a better __helix_vsnprintf, or
>else this will continue to be a problem on systems that don't have
>vsnprintf.
>
>I wish to check this in to hxclient_1_3_0_neptunex and HEAD.  Assuming
>it's accepted I'd recommend that others consider merging it to their own
>branches.
>
>
>
>--
>Nicholas Hart
>nhart@real.com
>Technical Lead, Helix Player
>https://player.helixcommunity.org
>http://www.real.com
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.


From liamm at real.com  Wed Jun 30 12:27:26 2004
From: liamm at real.com (Liam Murray)
Date: Wed Jun 30 12:27:30 2004
Subject: [Common-dev] CR: move posix-dependent code from hxsockutil
Message-ID: <6.1.1.1.0.20040630120927.0427e920@mailone.real.com>

Overview

In common/netio there is a file hxsockutil.cpp that provides some utility 
functions for working with the new net api. Currently these are used by the 
windows client sock implementation and the protocol/protocol-restricted 
implementation that works with the new net api. This is intended to a) 
reduce redundant code in code that uses the new net api; b) make the code 
using the new net api easier to read in some cases; c) provide a temporary 
place for code that we might expose via the interface (e.g., 
HXSockUtil::AddrSetPort(UINT16) may become the controversial 
IHXSockAddr::SetPort(UINT16)); and d) hide some of the volatility going on 
with the interfaces at the time I added this so I wasn't continually having 
to update other code.


Some of these convert from posix structures and datatypes (e.g., struct 
sockaddr_in, struct hostent) to new net api objects. These should not be in 
this file so I created the new files hxposixsockutil.{cpp,h} in the posix/ 
subdirs and moved posix-dependent utility functions here.

There ultimately may be a better place for these files (common/util, e.g.) 
and some of the helpers may be unnecessary as the net api interfaces 
change. My plan is to revisit this and discuss (particularly with Tom) at a 
later point once we feel the new net API interfaces are in final form.

For now however I just want to get rid of the posix-specific code from the 
current file since it breaks non bsd-socket-api platforms.

Branch:

HEAD

Files Modified:

common/netio/hxsockutil.cpp
common/netio/pub/hxsockutil.cpp

Files Added

common/netio/posix/hxposixsockutil.cpp
common/netio/pub/posix/hxposixsockutil.h

Liam

Index: hxsockutil.cpp
===================================================================
RCS file: /cvsroot/common/netio/hxsockutil.cpp,v
retrieving revision 1.5
diff -u -w -r1.5 hxsockutil.cpp
--- hxsockutil.cpp	25 Jun 2004 00:31:15 -0000	1.5
+++ hxsockutil.cpp	30 Jun 2004 19:08:27 -0000
@@ -35,7 +35,6 @@


  #include "hxtypes.h"
-#include "nettypes.h"
  #include "hxnet.h"
  #include "netdrv.h"
  #include "hxslist.h"
@@ -55,332 +54,6 @@



-void HXSockUtil::SetAddr(IHXSockAddr* pAddr /*modified*/,
-                                short family,
-                                const void* const pAddrData,
-                                UINT16 port)
-{
-    HX_ASSERT(pAddr);
-    HX_ASSERT(pAddrData);
-
-    char szAddr[HX_ADDRSTRLEN]; // big enough for ipv6 and ipv4
-    hx_inet_ntop(family, pAddrData, szAddr, HX_ADDRSTRLEN);
-
-    char szPort[HX_PORTSTRLEN];
-    SafeSprintf(szPort, HX_PORTSTRLEN, "%u", hx_ntohs(port));
-
-    pAddr->SetAddr(szAddr);
-    pAddr->SetPort(szPort);
-}
-
-void HXSockUtil::AddrSetPort(IHXSockAddr* pAddr, UINT16 port)
-{
-    HX_ASSERT(pAddr);
-
-    char szPort[HX_PORTSTRLEN];
-    SafeSprintf(szPort, HX_PORTSTRLEN, "%u", port);
-    pAddr->SetPort(szPort);
-}
-
-UINT16 HXSockUtil::AddrGetPort(IHXSockAddr* pAddr)
-{
-    char szPort[HX_PORTSTRLEN];
-    pAddr->GetPort(szPort);
-
-    return (UINT16)atoi(szPort);
-}
-
-HX_RESULT HXSockUtil::CreateAddrIN6(IHXNetServices* pNetServices,
-                     const SOCKADDR_IN6* pRaw,
-                     IHXSockAddr*& pAddrOut /*out*/)
-{
-
-    HX_ASSERT(pNetServices);
-    HX_ASSERT(pRaw);
-
-    HX_RESULT hr = pNetServices->CreateSockAddr(HX_SOCK_FAMILY_IN6, 
&pAddrOut);
-    if(SUCCEEDED(hr))
-    {
-        SetAddr(pAddrOut, AF_INET6, &pRaw->sin6_addr, pRaw->sin6_port);
-    }
-
-    return hr;
-
-}
-
-HX_RESULT HXSockUtil::CreateAddrIN4(IHXNetServices* pNetServices,
-                     UINT32 addr /*net order*/,
-                     UINT16 port /*net order*/,
-                     IHXSockAddr*& pAddrOut /*out*/)
-{
-    HX_ASSERT(pNetServices);
-
-    pAddrOut = 0;
-    HX_RESULT hr = pNetServices->CreateSockAddr(HX_SOCK_FAMILY_IN4, 
&pAddrOut);
-    if(SUCCEEDED(hr))
-    {
-        SetAddr(pAddrOut, AF_INET, &addr, port);
-    }
-
-    return hr;
-}
-
-
-
-HX_RESULT HXSockUtil::CreateAddrIN4(IHXNetServices* pNetServices,
-                     const SOCKADDR_IN* pRaw,
-                     IHXSockAddr*& pAddrOut /*out*/)
-{
-    HX_ASSERT(pNetServices);
-    HX_ASSERT(pRaw);
-    return CreateAddrIN4(pNetServices, pRaw->sin_addr.s_addr, 
pRaw->sin_port, pAddrOut);
-}
-
-HX_RESULT HXSockUtil::CreateAddr(IHXNetServices* pNetServices,
-                     const SOCKADDR* pAddr,
-                     IHXSockAddr*& pAddrOut /*out*/)
-{
-    HX_ASSERT(pNetServices);
-    HX_ASSERT(pAddr);
-
-    HX_RESULT hr = HXR_FAIL;
-    switch(pAddr->sa_family)
-    {
-    case AF_INET:
-        {
-            const SOCKADDR_IN* pRawAddr = reinterpret_cast(pAddr);
-            hr = CreateAddrIN4(pNetServices, pRawAddr, pAddrOut);
-        }
-        break;
-    case AF_INET6:
-        {
-            const SOCKADDR_IN6* pRawAddr = reinterpret_cast(pAddr);
-            hr = CreateAddrIN6(pNetServices, pRawAddr, pAddrOut);
-        }
-        break;
-    default:
-        HX_ASSERT(false); //XXXLCM
-        DPRINTF(D_SOCKUTIL, ("CreateAddrInfo(): unknown family = %u\n", 
pAddr->sa_family));
-    }
-
-    return hr;
-}
-
-//
-// for creating IPv6 addr (HX_IN6_CLASS_V4MAPPED) from IPv4 and vice-versa
-//
-HX_RESULT HXSockUtil::ConvertAddr(IHXNetServices* pNetServices,
-                                    HXSockFamily familyOut,
-                                    IHXSockAddr* pOld,
-                                    IHXSockAddr*& pAddrOut /*out*/)
-{
-    HX_ASSERT(pNetServices);
-    HX_ASSERT(pOld);
-
-    HXSockFamily oldFamily = pOld->GetFamily();
-    if(oldFamily != HX_SOCK_FAMILY_IN6 && oldFamily != HX_SOCK_FAMILY_IN4)
-    {
-        // we only convert from IPv6 or IPv4
-        return HXR_FAIL;
-    }
-
-    HX_RESULT hr = HXR_FAIL;
-
-    if(oldFamily != familyOut)
-    {
-        switch(familyOut)
-        {
-            case HX_SOCK_FAMILY_IN4:
-                {
-                    HX_ASSERT(oldFamily == HX_SOCK_FAMILY_IN6);
-                    //
-                    // convert to IPv4
-                    //
-                    IHXSockAddrIN6* pAddr6 = 0;
-                    hr = pOld->QueryInterface(IID_IHXSockAddrIN6, 
reinterpret_cast(&pAddr6));
-                    HX_ASSERT(SUCCEEDED(hr));
-                    if(SUCCEEDED(hr))
-                    {
-                        if(pAddr6->GetAddrClass() == HX_IN6_CLASS_V4MAPPED)
-                        {
-                            IHXSockAddrIN4* pAddr4 = 0;
-                            hr = pAddr6->ExtractIN4Addr(&pAddr4);
-                            HX_ASSERT(SUCCEEDED(hr));
-                            if(SUCCEEDED(hr))
-                            {
-                                hr = 
pAddr4->QueryInterface(IID_IHXSockAddr, reinterpret_cast(&pAddrOut));
-                                HX_RELEASE(pAddr4);
-                            }
-                        }
-                        else
-                        {
-                            hr = HXR_FAIL;
-                        }
-                        HX_RELEASE(pAddr6);
-                    }
-                }
-                break;
-            case HX_SOCK_FAMILY_IN6:
-                {
-                    HX_ASSERT(oldFamily == HX_SOCK_FAMILY_IN4);
-                    //
-                    // convert to IPv6 (as HX_IN6_CLASS_V4MAPPED)
-                    //
-                    hr = pNetServices->CreateSockAddr(HX_SOCK_FAMILY_IN6, 
&pAddrOut);
-                    if(SUCCEEDED(hr))
-                    {
-                        char addr[HX_ADDRSTRLEN];
-                        char port[HX_PORTSTRLEN];
-                        pOld->GetAddr(addr);
-                        pOld->GetPort(port);
-
-                        char mapped[HX_ADDRSTRLEN];
-
-                        SafeSprintf(mapped, HX_ADDRSTRLEN, "::ffff:%s", 
addr); // ipv4 mapped
-                        //SafeSprintf(mapped, HX_ADDRSTRLEN, "::%s", 
addr); // ipv4 compatible
-                        pAddrOut->SetAddr(mapped);
-                        pAddrOut->SetPort(port);
-                    }
-                }
-                break;
-            default:
-                HX_ASSERT(false);
-                break;
-        }
-
-    }
-    else
-    {
-        pAddrOut = pOld;
-        pAddrOut->AddRef();
-    }
-
-    return hr;
-}
-
-HX_RESULT HXSockUtil::CreateAnyAddr(IHXNetServices* pServices,
-                                 HXSockFamily family,
-                                 const char* pszPort,
-                                 IHXSockAddr*& pAddrOut /*out*/)
-{
-    const char* pszAddr = 0;
-    if(family == HX_SOCK_FAMILY_IN4)
-    {
-        const char* const IPV4_ANY = "0.0.0.0";
-        pszAddr = IPV4_ANY;
-    }
-    else if(family == HX_SOCK_FAMILY_IN6)
-    {
-        const char* const IPV6_ANY = "::";
-        pszAddr = IPV6_ANY;
-    }
-    return CreateAddr(pServices, family, pszAddr, pszPort, pAddrOut);
-}
-
-
-HX_RESULT HXSockUtil::CreateAddr(IHXNetServices* pServices, HXSockFamily 
family,
-                                                 const char* pszAddr, 
const char* pszPort,
-                                                 IHXSockAddr*& pAddrOut 
/*out*/)
-{
-    HX_ASSERT(pServices);
-    HX_RESULT hr = pServices->CreateSockAddr(family, &pAddrOut);
-    if(SUCCEEDED(hr))
-    {
-        if(pszAddr)
-        {
-            pAddrOut->SetAddr(pszAddr);
-        }
-        if(pszPort)
-        {
-            pAddrOut->SetPort(pszPort);
-        }
-    }
-
-    return hr;
-
-}
-
-//
-// build list of IHSockAddr* from ADDRINFO
-//
-HX_RESULT HXSockUtil::CreateAddrInfo(IHXNetServices* pNetServices,
-                         const struct hostent* pHostInfo,
-                         CHXSimpleList& list /*modified*/)
-{
-    HX_RESULT hr = HXR_FAIL;
-
-    HX_ASSERT(pNetServices);
-    HX_ASSERT(pHostInfo);
-    HX_ASSERT(list.IsEmpty());
-
-
-    for(UINT32 idx = 0; /* nothing*/; ++idx)
-    {
-
-        IHXSockAddr* pAddr = 0;
-
-        const char* psz = pHostInfo->h_addr_list[idx];
-        if(!psz)
-        {
-            // end of list
-            break;
-        }
-
-        HX_ASSERT(pHostInfo->h_length == sizeof(UINT32));
-
-        UINT32 addr = *(reinterpret_cast(psz));
-
-        hr = CreateAddrIN4(pNetServices, addr, 0, pAddr);
-        if(HXR_OK == hr)
-        {
-            HX_ASSERT(pAddr != 0);
-            list.AddTail(pAddr);
-        }
-        else
-        {
-            break;
-        }
-    }
-
-    return hr;
-}
-
-//
-// build list of IHSockAddr* from 'hostent'
-//
-HX_RESULT HXSockUtil::CreateAddrInfo(IHXNetServices* pNetServices,
-                         const ADDRINFO* pHostInfo,
-                         CHXSimpleList& list /*modified*/)
-{
-    HX_RESULT hr = HXR_FAIL;
-
-    HX_ASSERT(pNetServices);
-    HX_ASSERT(pHostInfo);
-    HX_ASSERT(list.IsEmpty());
-
-    const struct addrinfo* pHead = pHostInfo;
-    while(pHostInfo)
-    {
-        IHXSockAddr* pAddr = 0;
-        hr = CreateAddr(pNetServices, pHostInfo->ai_addr, pAddr);
-
-        if(HXR_OK == hr)
-        {
-            HX_ASSERT(pAddr != 0);
-            list.AddTail(pAddr);
-        }
-        else
-        {
-            break;
-        }
-
-        pHostInfo = pHostInfo->ai_next;
-    }
-    return hr;
-}
-
-
-
  //
  // For copying sock addr collection info passed back by IHXResolveResponse.
  // Use FreeAddrVec() when you are done.
@@ -537,7 +210,6 @@

  }

-// helper
  HX_RESULT HXSockUtil::CreateSocket(IHXNetServices* pNetSvc, 
IHXSocketResponse* pResp, HXSockFamily f,
                                            HXSockType t, HXSockProtocol p,
                                            IHXSocket*& pSock)
@@ -556,11 +228,193 @@

  }

+HX_RESULT HXSockUtil::CreateAddr(IHXNetServices* pServices, HXSockFamily 
family,
+                                                 const char* pszAddr, 
const char* pszPort,
+                                                 IHXSockAddr*& pAddrOut 
/*out*/)
+{
+    HX_ASSERT(pServices);
+    HX_RESULT hr = pServices->CreateSockAddr(family, &pAddrOut);
+    if(SUCCEEDED(hr))
+    {
+        if(pszAddr)
+        {
+            pAddrOut->SetAddr(pszAddr);
+        }
+        if(pszPort)
+        {
+            pAddrOut->SetPort(pszPort);
+        }
+    }
+
+    return hr;
+
+}
+
+
+void HXSockUtil::SetAddr(IHXSockAddr* pAddr /*modified*/,
+                                short family,
+                                const void* const pAddrData /*net-order 
octets/hextets*/,
+                                UINT16 port)
+{
+    HX_ASSERT(pAddr);
+    HX_ASSERT(pAddrData);
+
+    char szAddr[HX_ADDRSTRLEN]; // big enough for ipv6 and ipv4
+    hx_inet_ntop(family, pAddrData, szAddr, HX_ADDRSTRLEN);
+
+    char szPort[HX_PORTSTRLEN];
+    SafeSprintf(szPort, HX_PORTSTRLEN, "%u", hx_ntohs(port));
+
+    pAddr->SetAddr(szAddr);
+    pAddr->SetPort(szPort);
+}
+
+void HXSockUtil::AddrSetPort(IHXSockAddr* pAddr, UINT16 port)
+{
+    HX_ASSERT(pAddr);
+
+    char szPort[HX_PORTSTRLEN];
+    SafeSprintf(szPort, HX_PORTSTRLEN, "%u", port);
+    pAddr->SetPort(szPort);
+}
+
+UINT16 HXSockUtil::AddrGetPort(IHXSockAddr* pAddr)
+{
+    char szPort[HX_PORTSTRLEN];
+    pAddr->GetPort(szPort);
+
+    return (UINT16)atoi(szPort);
+}
+
+//
+// for creating IPv6 addr (HX_IN6_CLASS_V4MAPPED) from IPv4 and vice-versa
+//
+HX_RESULT HXSockUtil::ConvertAddr(IHXNetServices* pNetServices,
+                                    HXSockFamily familyOut,
+                                    IHXSockAddr* pOld,
+                                    IHXSockAddr*& pAddrOut /*out*/)
+{
+    HX_ASSERT(pNetServices);
+    HX_ASSERT(pOld);
+
+    HXSockFamily oldFamily = pOld->GetFamily();
+    if(oldFamily != HX_SOCK_FAMILY_IN6 && oldFamily != HX_SOCK_FAMILY_IN4)
+    {
+        // we only convert from IPv6 or IPv4
+        return HXR_FAIL;
+    }
+
+    HX_RESULT hr = HXR_FAIL;

+    if(oldFamily != familyOut)
+    {
+        switch(familyOut)
+        {
+            case HX_SOCK_FAMILY_IN4:
+                {
+                    HX_ASSERT(oldFamily == HX_SOCK_FAMILY_IN6);
+                    //
+                    // convert to IPv4
+                    //
+                    IHXSockAddrIN6* pAddr6 = 0;
+                    hr = pOld->QueryInterface(IID_IHXSockAddrIN6, 
reinterpret_cast(&pAddr6));
+                    HX_ASSERT(SUCCEEDED(hr));
+                    if(SUCCEEDED(hr))
+                    {
+                        if(pAddr6->GetAddrClass() == HX_IN6_CLASS_V4MAPPED)
+                        {
+                            IHXSockAddrIN4* pAddr4 = 0;
+                            hr = pAddr6->ExtractIN4Addr(&pAddr4);
+                            HX_ASSERT(SUCCEEDED(hr));
+                            if(SUCCEEDED(hr))
+                            {
+                                hr = 
pAddr4->QueryInterface(IID_IHXSockAddr, reinterpret_cast(&pAddrOut));
+                                HX_RELEASE(pAddr4);
+                            }
+                        }
+                        else
+                        {
+                            hr = HXR_FAIL;
+                        }
+                        HX_RELEASE(pAddr6);
+                    }
+                }
+                break;
+            case HX_SOCK_FAMILY_IN6:
+                {
+                    HX_ASSERT(oldFamily == HX_SOCK_FAMILY_IN4);
+                    //
+                    // convert to IPv6 (as HX_IN6_CLASS_V4MAPPED)
+                    //
+                    hr = pNetServices->CreateSockAddr(HX_SOCK_FAMILY_IN6, 
&pAddrOut);
+                    if(SUCCEEDED(hr))
+                    {
+                        char addr[HX_ADDRSTRLEN];
+                        char port[HX_PORTSTRLEN];
+                        pOld->GetAddr(addr);
+                        pOld->GetPort(port);

+                        char mapped[HX_ADDRSTRLEN];

+                        SafeSprintf(mapped, HX_ADDRSTRLEN, "::ffff:%s", 
addr); // ipv4 mapped
+                        //SafeSprintf(mapped, HX_ADDRSTRLEN, "::%s", 
addr); // ipv4 compatible
+                        pAddrOut->SetAddr(mapped);
+                        pAddrOut->SetPort(port);
+                    }
+                }
+                break;
+            default:
+                HX_ASSERT(false);
+                break;
+        }

+    }
+    else
+    {
+        pAddrOut = pOld;
+        pAddrOut->AddRef();
+    }

+    return hr;
+}
+
+HX_RESULT HXSockUtil::CreateAnyAddr(IHXNetServices* pServices,
+                                 HXSockFamily family,
+                                 const char* pszPort,
+                                 IHXSockAddr*& pAddrOut /*out*/)
+{
+    const char* pszAddr = 0;
+    if(family == HX_SOCK_FAMILY_IN4)
+    {
+        const char* const IPV4_ANY = "0.0.0.0";
+        pszAddr = IPV4_ANY;
+    }
+    else if(family == HX_SOCK_FAMILY_IN6)
+    {
+        const char* const IPV6_ANY = "::";
+        pszAddr = IPV6_ANY;
+    }
+    return CreateAddr(pServices, family, pszAddr, pszPort, pAddrOut);
+}
+
+
+
+HX_RESULT HXSockUtil::CreateAddrIN4(IHXNetServices* pNetServices,
+                     UINT32 addr /*net order*/,
+                     UINT16 port /*net order*/,
+                     IHXSockAddr*& pAddrOut /*out*/)
+{
+    HX_ASSERT(pNetServices);
+
+    pAddrOut = 0;
+    HX_RESULT hr = pNetServices->CreateSockAddr(HX_SOCK_FAMILY_IN4, 
&pAddrOut);
+    if(SUCCEEDED(hr))
+    {
+        SetAddr(pAddrOut, AF_INET, &addr, port);
+    }
+
+    return hr;
+}



Index: unix.pcf
===================================================================
RCS file: /cvsroot/common/netio/unix.pcf,v
retrieving revision 1.3
diff -u -w -r1.3 unix.pcf
--- unix.pcf	12 May 2004 05:12:15 -0000	1.3
+++ unix.pcf	30 Jun 2004 19:08:27 -0000
@@ -41,4 +41,5 @@
  project.AddSources('platform/unix/unix_net.cpp',
  		'platform/unix/unix_conn.cpp',
  		'platform/posix/netdrv.cpp',
-		'platform/posix/sockimp.cpp')
+		'platform/posix/sockimp.cpp',
+		'platform/posix/hxposixsockutil.cpp')
Index: win.pcf
===================================================================
RCS file: /cvsroot/common/netio/win.pcf,v
retrieving revision 1.9
diff -u -w -r1.9 win.pcf
--- win.pcf	24 Jun 2004 23:49:25 -0000	1.9
+++ win.pcf	30 Jun 2004 19:08:27 -0000
@@ -46,6 +46,7 @@
  		   'platform/win/hxwinsocklib.cpp',
             'platform/win/hxsocketselector.cpp',
             'platform/posix/netdrv.cpp',
-		   'platform/posix/sockimp.cpp')
+		   'platform/posix/sockimp.cpp',
+		   'platform/posix/hxposixsockutil.cpp')


Index: pub/chxbufferedsocket.h
===================================================================
RCS file: /cvsroot/common/netio/pub/chxbufferedsocket.h,v
retrieving revision 1.1
diff -u -w -r1.1 chxbufferedsocket.h
--- pub/chxbufferedsocket.h	24 Jun 2004 23:49:26 -0000	1.1
+++ pub/chxbufferedsocket.h	30 Jun 2004 19:08:28 -0000
@@ -41,7 +41,7 @@
  #include "hxnet.h"

  //
-// CHXBufferedSocket adapts CHXSocket so writes and reads are buffered at 
the application layer.
+// CHXBufferedSocket adapts CHXSocket so writes are buffered.
  //
  // This alters CHXSocket semantics as follows:
  //
@@ -55,19 +55,14 @@
  //
  // Read behavior:
  //
-// 1) Reads will be buffered once SelectEvents() is called with 
HX_SOCK_EVENT_READ
-// 2) User of this class will get HX_SOCK_EVENT_READ. This indicates there 
are application
-//    layer buffers (maintained in this class) available.
+// 1) Read behavior unchanged
  //
  //
  // XXXLCM
  // Current limitations:
  //
-// must call ConnectToOne for udp sockets
+// WriteV not supported
  //
-// Write() is currently only write method supported
-//
-// Read part not implemented (data buffered only at network layer)
  //
  //

@@ -148,8 +143,17 @@

  private:

+    class Data
+    {
+    public:
+        Data(IHXBuffer* pBuf, IHXSockAddr* pPeerAddr = 0);
+        ~Data();
+
+        IHXBuffer* m_pBuf;
+        IHXSockAddr* m_pPeerAddr;
+    };
+
      CHXSimpleList           m_outbound;
-    CHXSimpleList           m_inbound;

      INT32                   m_nRefCount;
      IHXSocket*              m_pSock;
Index: pub/hxsockutil.h
===================================================================
RCS file: /cvsroot/common/netio/pub/hxsockutil.h,v
retrieving revision 1.5
diff -u -w -r1.5 hxsockutil.h
--- pub/hxsockutil.h	28 Jun 2004 16:32:17 -0000	1.5
+++ pub/hxsockutil.h	30 Jun 2004 19:08:28 -0000
@@ -5,17 +5,10 @@
  // helpers for working with API defined in hxnet.h
  //

-#include "platform/posix/nettypes.h"
  #include "hxnet.h"

  class CHXSimpleList;

-#if !defined(_WIN32)
-typedef struct sockaddr SOCKADDR;
-typedef struct sockaddr_in SOCKADDR_IN;
-typedef struct sockaddr_in6 SOCKADDR_IN6;
-#endif
-typedef struct addrinfo ADDRINFO;

  struct HXSockUtil // namespace
  {
@@ -28,20 +21,6 @@
      static UINT16 /*host order*/ AddrGetPort(IHXSockAddr* pAddr);


-    static HX_RESULT CreateAddrIN6(IHXNetServices* pNetServices,
-                     const SOCKADDR_IN6* pRaw,IHXSockAddr*& pAddrOut /*out*/);
-
-    static HX_RESULT CreateAddrIN4(IHXNetServices* pNetServices,
-                     const SOCKADDR_IN* pRaw, IHXSockAddr*& pAddrOut /*out*/);
-
-    static HX_RESULT CreateAddrIN4(IHXNetServices* pNetServices,
-                     UINT32 addr /*net order*/, UINT16 port /*net order*/,
-                     IHXSockAddr*& pAddrOut /*out*/);
-
-    static HX_RESULT CreateAddr(IHXNetServices* pNetServices,
-                     const SOCKADDR* pAddr,
-                     IHXSockAddr*& pAddrOut /*out*/);
-
      static HX_RESULT CreateAnyAddr(IHXNetServices* pServices,
                                   HXSockFamily family,
                                   const char* pszPort,
@@ -51,19 +30,19 @@
                                   const char* pszAddr, const char* pszPort,
                                   IHXSockAddr*& pAddrOut /*out*/);

+
+    static HX_RESULT CreateAddrIN4(IHXNetServices* pNetServices,
+                     UINT32 addr /*net order*/,
+                     UINT16 port /*net order*/,
+                     IHXSockAddr*& pAddrOut /*out*/);
+
+
      // for creating IPv6 addr from IPv4 and vice-versa
      static HX_RESULT ConvertAddr(IHXNetServices* pNetServices,
                                      HXSockFamily familyOut,
                                      IHXSockAddr* pOld,
                                      IHXSockAddr*& pAddrOut /*out*/);

-    static HX_RESULT CreateAddrInfo(IHXNetServices* pNetServices,
-                         const ADDRINFO* pInfo,
-                         CHXSimpleList& list /*modified*/);
-
-    static HX_RESULT CreateAddrInfo(IHXNetServices* pNetServices,
-                         const struct hostent* pHostInfo,
-                         CHXSimpleList& list /*modified*/);

      static HX_RESULT AllocAddrVec(IHXSockAddr** ppAddrVec,
                                      UINT32& nVecLen /*in/out*/, 
-------------- next part --------------
#if !defined(HX_POSIXSOCKUTIL_H__)
#define HX_POSIXSOCKUTIL_H__

//
// helpers for working with posix data in conjunction with API defined in hxnet.h
//

#include "nettypes.h"
#include "hxnet.h"

class CHXSimpleList;


struct HXPosixSockUtil // namespace
{

    static HX_RESULT CreateAddrIN6(IHXNetServices* pNetServices,
                     const struct sockaddr_in6* psa,IHXSockAddr*& pAddrOut /*out*/);

    static HX_RESULT CreateAddrIN4(IHXNetServices* pNetServices,
                     const struct sockaddr_in* psa, IHXSockAddr*& pAddrOut /*out*/);

    static HX_RESULT CreateAddr(IHXNetServices* pNetServices,
                     const struct sockaddr* psa, 
                     IHXSockAddr*& pAddrOut /*out*/);

    static HX_RESULT CreateAddrInfo(IHXNetServices* pNetServices, 
                         const struct hostent* phe,
                         CHXSimpleList& list /*modified*/);

    static HX_RESULT CreateAddrInfo(IHXNetServices* pNetServices, 
                         const struct addrinfo* pai,
                         CHXSimpleList& list /*modified*/);

    

};
#endif //HX_POSIXSOCKUTIL_H__


-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 


#include "hxtypes.h"
#include "nettypes.h"
#include "hxnet.h"
#include "hxslist.h"
#include "safestring.h"
#include "debug.h"
#include "hxassert.h"
#include "hxheap.h"
#include "hxsockutil.h"
#include "hxposixsockutil.h"

#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif									 


#define D_SOCKUTIL D_INFO //XXXLCM


HX_RESULT HXPosixSockUtil::CreateAddrIN6(IHXNetServices* pNetServices,
                     const struct sockaddr_in6* psa,
                     IHXSockAddr*& pAddrOut /*out*/)
{

    HX_ASSERT(pNetServices);
    HX_ASSERT(psa);

    HX_RESULT hr = pNetServices->CreateSockAddr(HX_SOCK_FAMILY_IN6, &pAddrOut);
    if (SUCCEEDED(hr))
    {
        HXSockUtil::SetAddr(pAddrOut, AF_INET6, &psa->sin6_addr, psa->sin6_port);
    }

    return hr;

}


HX_RESULT HXPosixSockUtil::CreateAddrIN4(IHXNetServices* pNetServices,
                     const struct sockaddr_in* psa,
                     IHXSockAddr*& pAddrOut /*out*/)
{
    HX_ASSERT(pNetServices);
    HX_ASSERT(psa);
    return HXSockUtil::CreateAddrIN4(pNetServices, psa->sin_addr.s_addr, psa->sin_port, pAddrOut);
}



HX_RESULT HXPosixSockUtil::CreateAddr(IHXNetServices* pNetServices,
                     const struct sockaddr* pAddr, 
                     IHXSockAddr*& pAddrOut /*out*/)
{
    HX_ASSERT(pNetServices);
    HX_ASSERT(pAddr);

    HX_RESULT hr = HXR_FAIL;
    switch (pAddr->sa_family)
    {
    case AF_INET:
        {
            const struct sockaddr_in* psa = reinterpret_cast(pAddr);
            hr = CreateAddrIN4(pNetServices, psa, pAddrOut);
        }
        break;
    case AF_INET6:
        {
            const SOCKADDR_IN6* psa = reinterpret_cast(pAddr);
            hr = CreateAddrIN6(pNetServices, psa, pAddrOut);
        }
        break;
    default:
        HX_ASSERT(false); //XXXLCM
        DPRINTF(D_SOCKUTIL, ("CreateAddr(): unknown family = %u\n", pAddr->sa_family));
    }

    return hr;
}


//
// build list of IHSockAddr* from struct addrinfo
//
HX_RESULT HXPosixSockUtil::CreateAddrInfo(IHXNetServices* pNetServices, 
                         const struct hostent* phe,
                         CHXSimpleList& list /*modified*/)
{
    HX_RESULT hr = HXR_FAIL;

    HX_ASSERT(pNetServices);
    HX_ASSERT(phe);
    HX_ASSERT(list.IsEmpty());
    
     
    for (UINT32 idx = 0; /* nothing*/; ++idx)
    {
   
        IHXSockAddr* pAddr = 0;

        const char* psz = phe->h_addr_list[idx];
        if (!psz)
        {
            // end of list
            break;
        }

        HX_ASSERT(phe->h_length == sizeof(UINT32));

        UINT32 addr = *(reinterpret_cast(psz));

        hr = HXSockUtil::CreateAddrIN4(pNetServices,  addr, 0, pAddr);
        if (HXR_OK == hr)
        {
            HX_ASSERT(pAddr != 0);
            list.AddTail(pAddr);
        }
        else
        {
            // error - give up
            break;
        }
    }

    return hr;
}

//
// build list of IHSockAddr* from 'addrinfo'
//
HX_RESULT HXPosixSockUtil::CreateAddrInfo(IHXNetServices* pNetServices, 
                         const struct addrinfo* pai,
                         CHXSimpleList& list /*modified*/)
{
    HX_RESULT hr = HXR_FAIL;

    HX_ASSERT(pNetServices);
    HX_ASSERT(pai);
    HX_ASSERT(list.IsEmpty());

    const struct addrinfo* pHead = pai;
    while (pai)
    {
        IHXSockAddr* pAddr = 0;
        hr = CreateAddr(pNetServices, pai->ai_addr, pAddr);

        if (HXR_OK == hr)
        {
            HX_ASSERT(pAddr != 0);
            list.AddTail(pAddr);
        }
        else
        {
            break;
        }

        pai = pai->ai_next;
    }
    return hr;
}












From nhart at real.com  Wed Jun 30 12:53:13 2004
From: nhart at real.com (Nicholas Hart)
Date: Wed Jun 30 12:53:15 2004
Subject: [Common-dev] CN: common/dbgtool/pub/errdbg.h
In-Reply-To: <5.1.0.14.2.20040630090018.00bae940@mailone.real.com>
References: <5.1.0.14.2.20040630090018.00bae940@mailone.real.com>
Message-ID: <1088625192.7652.15.camel@linicks.dev.prognet.com>

Committed to HEAD and hxclient_1_3_0_neptunex.  I will fire off a couple
builds on the HEAD to make sure it didn't break any platforms.


On Wed, 2004-06-30 at 06:00, Eric Hyche wrote:
> This looks good to me.
> 
> Eric
> 
> At 05:06 PM 6/29/2004 -0700, Nicholas Hart wrote:
> 
> >I've been dealing with a bunch of nasty crashes on linux and narrowed it
> >down to an ugly bug in errdbg.h.  It seems that we only use vsnprintf on
> >windows & openwave.  On other systems (like linux) we just used
> >vsprintf.  So, on these systems every time we try to log a message
> >larger than 2k it corrupts the heap and kills the player sooner or
> >later.
> >
> >Since errdbg.h includes hlxclib/stdio.h and that header defines
> >vsnprintf for every platform (either mapping it to _vsnprintf for
> >windows, leaving it alone for systems that have it, or mapping it to
> >__helix_vsnprintf, which unfortunately uses vsprintf and still has this
> >overflow bug) this should be a pretty safe fix.
> >
> >I think that someone should implement a better __helix_vsnprintf, or
> >else this will continue to be a problem on systems that don't have
> >vsnprintf.
> >
> >I wish to check this in to hxclient_1_3_0_neptunex and HEAD.  Assuming
> >it's accepted I'd recommend that others consider merging it to their own
> >branches.
> >
> >
> >
> >--
> >Nicholas Hart
> >nhart@real.com
> >Technical Lead, Helix Player
> >https://player.helixcommunity.org
> >http://www.real.com
> >
> >_______________________________________________
> >Common-dev mailing list
> >Common-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 
> ======================================
> M. Eric Hyche (ehyche@real.com)
> Core Technologies
> RealNetworks, Inc.
-- 
Nicholas Hart
nhart@real.com
Technical Lead, Helix Player
https://player.helixcommunity.org
http://www.real.com


From ping at real.com  Wed Jun 30 14:52:21 2004
From: ping at real.com (Henry Ping)
Date: Wed Jun 30 14:52:26 2004
Subject: [Common-dev] Fwd: helix code review
Message-ID: <5.1.0.14.2.20040630144937.03a207a8@mailone.real.com>

Forwarded it to proper Helix community alias for CR.

Looks good to me

-->Henry

>Delivered-To: ping@real.com
>Date: Wed, 30 Jun 2004 14:42:33 -0700
>From: Jeremy Chaney 
>User-Agent: Mozilla Thunderbird 0.6 (Windows/20040502)
>X-Accept-Language: en-us, en
>To: Henry Ping 
>Subject: helix code review
>
>The following change is require in common\dbgtool to prevent a linker 
>error when common/dbgtool[debuglib] and pndebug are both linked to a DLL. 
>The global variable 'g_trace_log_enabled' is multiply defined. This change 
>renames it the variable to include the HX prefix.
>
>
>Index: hxassert.cpp
>===================================================================
>RCS file: /cvsroot/common/dbgtool/hxassert.cpp,v
>retrieving revision 1.18
>diff -c -r1.18 hxassert.cpp
>*** hxassert.cpp    19 May 2004 11:20:30 -0000    1.18
>--- hxassert.cpp    30 Jun 2004 21:39:04 -0000
>***************
>*** 268,274 ****
>  }
>  #if !defined(HELIX_CONFIG_NOSTATICS)
>! int g_trace_log_enabled = 0;
>  #endif
> 
>/////////////////////////////////////////////////////////////////////////////
>--- 268,274 ----
>  }
>  #if !defined(HELIX_CONFIG_NOSTATICS)
>! int g_hxtrace_log_enabled = 0;
>  #endif
> 
>/////////////////////////////////////////////////////////////////////////////
>***************
>*** 278,284 ****
>  void STDMETHODVCALLTYPE HXTrace(const char* pszFormat, ...)
>  {
>  #if !defined(HELIX_CONFIG_NOSTATICS)
>!     if(!g_trace_log_enabled)
>      return;
>      static char z_szDebugBuffer[MAX_TRACE_OUTPUT]; /* Flawfinder: ignore */
>--- 278,284 ----
>  void STDMETHODVCALLTYPE HXTrace(const char* pszFormat, ...)
>  {
>  #if !defined(HELIX_CONFIG_NOSTATICS)
>!     if(!g_hxtrace_log_enabled)
>      return;
>      static char z_szDebugBuffer[MAX_TRACE_OUTPUT]; /* Flawfinder: ignore */
>
>
>


 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.