+/*****************************************************************************
+ *
+ *****************************************************************************/
+static int b64_decode( char *dest, char *src );
+
+static int ParseASF( demux_t *p_demux )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
+ const char *psz_marker = "a=pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,";
+ char *psz_asf = strcasestr( p_sys->p_sdp, psz_marker );
+ char *psz_end;
+ block_t *p_header;
+
+ /* Parse the asf header */
+ if( psz_asf == NULL )
+ return VLC_EGENERIC;
+
+ psz_asf += strlen( psz_marker );
+ psz_asf = strdup( psz_asf ); /* Duplicate it */
+ psz_end = strchr( psz_asf, '\n' );
+
+ while( psz_end > psz_asf && ( *psz_end == '\n' || *psz_end == '\r' ) )
+ *psz_end-- = '\0';
+
+ if( psz_asf >= psz_end )
+ {
+ free( psz_asf );
+ return VLC_EGENERIC;
+ }
+
+ /* Always smaller */
+ p_header = block_New( p_demux, psz_end - psz_asf );
+ p_header->i_buffer = b64_decode( (char*)p_header->p_buffer, psz_asf );
+ fprintf( stderr, "Size=%d Hdrb64=%s\n", p_header->i_buffer, psz_asf );
+ if( p_header->i_buffer <= 0 )
+ {
+ free( psz_asf );
+ return VLC_EGENERIC;
+ }
+
+ /* Parse it to get packet size */
+ E_(asf_HeaderParse)( &p_sys->asfh, p_header->p_buffer, p_header->i_buffer );
+
+ /* Send it to demuxer */
+ stream_DemuxSend( p_sys->p_out_asf, p_header );
+
+ free( psz_asf );
+ return VLC_SUCCESS;
+}
+
+#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1117756800
+static unsigned char* parseH264ConfigStr( char const* configStr,
+ unsigned int& configSize )
+{
+ char *dup, *psz;
+
+ if( configSize )
+ configSize = 0;
+
+ if( configStr == NULL || *configStr == '\0' )
+ return NULL;
+
+ psz = dup = strdup( configStr );
+
+ unsigned char *cfg = new unsigned char[5 * strlen(psz)];
+ for( ;; )
+ {
+ char *p = strchr( psz, ',' );
+ if( p )
+ *p++ = '\0';
+
+ cfg[configSize++] = 0x00;
+ cfg[configSize++] = 0x00;
+ cfg[configSize++] = 0x00;
+ cfg[configSize++] = 0x01;
+ configSize += b64_decode( (char*)&cfg[configSize], psz );
+
+ if( p == NULL )
+ break;
+ psz = p;
+ }
+
+ if( dup ) free( dup );
+ return cfg;
+}
+#endif
+
+/*char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";*/
+static int b64_decode( char *dest, char *src )
+{
+ const char *dest_start = dest;
+ int i_level;
+ int last = 0;
+ int b64[256] = {
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 00-0F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 10-1F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, /* 20-2F */
+ 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, /* 30-3F */
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 40-4F */
+ 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, /* 50-5F */
+ -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, /* 60-6F */
+ 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, /* 70-7F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-8F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 90-9F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A0-AF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* B0-BF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* C0-CF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* D0-DF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* E0-EF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 /* F0-FF */
+ };
+
+ for( i_level = 0; *src != '\0'; src++ )
+ {
+ int c;
+
+ c = b64[(unsigned int)*src];
+ if( c == -1 )
+ {
+ continue;
+ }
+
+ switch( i_level )
+ {
+ case 0:
+ i_level++;
+ break;
+ case 1:
+ *dest++ = ( last << 2 ) | ( ( c >> 4)&0x03 );
+ i_level++;
+ break;
+ case 2:
+ *dest++ = ( ( last << 4 )&0xf0 ) | ( ( c >> 2 )&0x0f );
+ i_level++;
+ break;
+ case 3:
+ *dest++ = ( ( last &0x03 ) << 6 ) | c;
+ i_level = 0;
+ }
+ last = c;
+ }
+
+ *dest = '\0';
+
+ return dest - dest_start;
+}