Ok, I have been researching a bit, and I found a plugin that you put into VLC Player to stream Slingbox on VLC without having to use Sling Player. The person that made it, gave all the files to do it, maybe someone can adapt it to CF?
I have attached a RAR file that has all the instructions to set it up in VLC, but there is also a txt pad that has how he made the .dll file..... Maybe someone can adapt it?
Code:
/*****************************************************************************
* slingbox.c: HTTP input module
*****************************************************************************
*
* Authors: ChecksumCoder <checksumcoder@users.sourceforge.net
*
* This is a modification (maybe a very big but...) of http.c then ...
*
*****************************************************************************
* http.c: HTTP input module
*****************************************************************************
* Copyright (C) 2001-2005 the VideoLAN team
* $Id: http.c 15169 2006-04-11 09:27:46Z zorglub $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
* Rémi Denis-Courmont <rem # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include "vlc_interaction.h"
#include "network.h"
#include "vlc_url.h"
#include "vlc_tls.h"
#include "vlc_keys.h"
#include "vlc_osd.h"
#define LOG_COMM
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close( vlc_object_t * );
static int Read( access_t *p_access, uint8_t *p_buffer, int i_len );
static int ReadCommand( vlc_object_t *p_this );
static int KeyHandler (vlc_object_t *obj, char const *varname, vlc_value_t oldval, vlc_value_t newval, void *data);
int m_strnicmp(const char *a,const char *b, int s)
{
int i;
for ( i = 0 ; i < s && *a && *b ; i ++ ) {
if ( *a != *b ) return *a > *b ? 1:-1;
a++;
b++;
}
return 0;
}
vlc_module_begin();
set_description( _("Slingbox") );
set_capability( "access2", 0 );
set_shortname( _( "Slingbox" ) );
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_ACCESS );
set_section( N_("Control") , NULL );
add_integer( "slingbox-channel", 0,NULL, N_("Channel"), N_( "Channel (0 = kept last channel)" ), VLC_FALSE );
add_integer( "slingbox-input", 0,NULL, N_("Input"), N_( "Channel (-1 = kept last input)" ), VLC_FALSE );
set_section( N_("Connection") , NULL );
add_string( "slingbox-user", "VLC" , NULL, N_("User name") , N_("Not used") , VLC_TRUE );
add_string( "slingbox-password", "" , NULL, N_("Password") , N_("Password used to log on Slingbox") , VLC_FALSE );
add_bool ( "slingbox-admin",VLC_TRUE , NULL,N_("Admin"), N_("Log as administrator") , VLC_FALSE );
add_string( "slingbox-adrs", "192.168.1.237" , NULL, N_("Adress") , N_("Default adress if not specified") , VLC_TRUE );
add_integer( "slingbox-port", 5001,NULL, N_("Port"), N_( "Default port if not specified" ), VLC_TRUE );
add_integer( "slingbox-caching", 8 * DEFAULT_PTS_DELAY / 1000, NULL, N_("Caching value in ms"), N_( "Caching value for slingbox streams. This value should be set in milliseconds." ), VLC_TRUE );
set_section( N_("Video") , NULL );
add_string( "slingbox-resolution", "1" , NULL, "Resolution", "Video resolution", VLC_TRUE );
static char *resolution_list[] = { "8", "2", "4", "9", "11", "1", "7", "3", "6", "5"};
static char *resolution_list_text[] = { N_("128 X 96"), N_("160 X 120"), N_("176 X 120"),N_("224 X 176"),N_("256 X 192"), N_("320 X 240"), N_("352 X 480"), N_("352 X 240"),N_("640 X 240"),N_("640 X 480") };
change_string_list( resolution_list, resolution_list_text, 0 );
add_integer_with_range( "slingbox-videobitrate", 1000, 50, 8000, NULL, N_("Video Bitrate"), N_("Bitrate of the Video stream in Kbps") , VLC_TRUE );
add_string( "slingbox-framerate", "30" , NULL, "Framerate", "Video framerate", VLC_TRUE );
static char *framerate_list[] = { "1","6","10","15","20","30"};
static char *framerate_list_text[] = { N_("1 f/s"), N_("6 f/s"), N_("10 f/s"),N_("15 f/s"), N_("20 f/s"),N_("30 f/s") };
change_string_list( framerate_list, framerate_list_text, 0 );
add_integer_with_range( "slingbox-videosmoothness", 32, 1, 64, NULL,N_("Video smoothness"), N_("high val = sharper") , VLC_TRUE );
add_integer_with_range( "slingbox-iframe", 10, 1, 30, NULL,N_("I-Frame"), N_("I-Frame interval in seconds") , VLC_TRUE );
add_string( "slingbox-audio", "96" , NULL, "Audio bitrate", "Bitrate of the audio in Kbps", VLC_TRUE );
static char *audiobitrate_list[] = { "16","20","32","40","48","64","96"};
static char *audiobitrate_list_text[] = { N_("16 Kbps"), N_("20 Kbps"), N_("32 Kbps"),N_("40 Kbps"), N_("48 Kbps"),N_("64 Kbps"),N_("96 Kbps") };
change_string_list( audiobitrate_list, audiobitrate_list_text, 0 );
set_section( N_("Log") , NULL );
add_bool ( "slingbox-log",VLC_FALSE , NULL,N_("Log"), N_("Log communiction in Message") , VLC_FALSE );
add_shortcut( "slingbox" );
add_shortcut( "sling" );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
struct access_sys_t
{
int fdCommand,fd;
vlc_bool_t VideoSupplementChange;
v_socket_t *p_vs;
v_socket_t *p_vsCommand;
/* From uri */
vlc_url_t url;
char *psz_slingbox;
time_t endtime;
vlc_bool_t b_die;
int ch;
int input;
int default_ch;
int default_input;
};
/* */
static int Read( access_t *, uint8_t *, int );
static int Control( access_t *, int, va_list );
/* */
static int Connect( access_t *, int64_t );
static void Disconnect( access_t * );
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
access_t *p_access = (access_t*)p_this;
// intf_thread_t *p_intf = (intf_thread_t *)p_this;
access_sys_t *p_sys;
char *psz, *p;
int i,j;
//vlc_value_t val;
/* Set up p_access */
p_access->pf_read = Read;
p_access->pf_block = NULL;
p_access->pf_control = Control;
p_access->pf_seek = NULL;
p_access->info.i_update = 0;
p_access->info.i_size = 0;
p_access->info.i_pos = 0;
p_access->info.b_eof = VLC_FALSE;
p_access->info.i_title = 0;
p_access->info.i_seekpoint = 0;
p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
memset( p_sys, 0, sizeof( access_sys_t ) );
p_sys->fdCommand = -1;
p_sys->fd = -1;
p_sys->psz_slingbox = NULL;
p_sys->VideoSupplementChange = VLC_FALSE;
p_sys->b_die = VLC_FALSE;
var_Create( p_access, "slingbox-user", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-password", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-admin", VLC_VAR_BOOL |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-port", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-adrs", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-caching", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-channel", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-input", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access,"slingbox-resolution", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
var_Create( p_access,"slingbox-videobitrate", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access,"slingbox-framerate", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
var_Create( p_access,"slingbox-videosmoothness", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access,"slingbox-audio", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
var_Create( p_access,"slingbox-iframe", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
var_Create( p_access, "slingbox-log", VLC_VAR_BOOL |VLC_VAR_DOINHERIT );
/* Parse URI - remove spaces */
p = psz = strdup( p_access->psz_path );
while( (p = strchr( p, ' ' )) != NULL )
*p = '+';
vlc_UrlParse( &p_sys->url, psz, 0 );
free( psz );
if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
{
msg_Warn( p_access, "invalid host -> take %s",var_GetString(p_access,"slingbox-adrs") );
p_sys->url.psz_host = var_GetString(p_access,"slingbox-adrs");
}
if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
{
msg_Err( p_access, "invalid host -> take %s",var_GetString(p_access,"slingbox-adrs") );
return VLC_EGENERIC;
}
if( p_sys->url.i_port <= 0 )
p_sys->url.i_port = var_GetInteger( p_access, "slingbox-port" );
var_AddCallback (p_access->p_vlc, "key-pressed", KeyHandler, p_access);
p_sys->endtime = 0;
p_sys->default_ch = 0;
p_sys->default_input = -1;
if ( p_sys->url.psz_path ) {
msg_Dbg( p_access ,"Parameter : %s",p_sys->url.psz_path);
p = p_sys->url.psz_path;
while( (p = strchr( p, '/' )) != NULL ) {
p++;
if (*p) {
if (!m_strnicmp(p,"time",4)) {
i = 0;
j = 0;
p+= 4;
while (j < 3 ) {
i *= 60;
i += atoi(p);
j++;
while ( *p >= '0' && *p <= '9' ) p++;
if ( *p != ':' ) break;
p++;
}
if ( j == 2 ) i *= 60; // No second then it hour:min
p_sys->endtime = time( NULL ) + i;
msg_Info( p_access, "Exit in %d second", i );
}
if (!m_strnicmp(p,"channel",7)) {
p_sys->default_ch = atoi(&p[7]);
msg_Info(p_access, "Def channel %d",p_sys->default_ch);
p++;
}
if (!m_strnicmp(p,"input",5)) {
p_sys->default_input = atoi(&p[5]);
msg_Info(p_access, "Def input %d",p_sys->default_input);
p++;
}
}
}
}
msg_Dbg( p_access, "slingbox: server='%s' port=%d file='%s", p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path );
if( Connect( p_access, 0 ) )
{
msg_Err( p_access, "slingbox: server='%s' port=%d file='%s", p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path );
return VLC_EGENERIC;
}
msg_Dbg( p_access ,"Start Read Command Thread");
vlc_thread_create( p_access, "Slingbox Command thread", ReadCommand, VLC_THREAD_PRIORITY_LOW, VLC_FALSE );
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys = p_access->p_sys;
p_sys->b_die = VLC_TRUE;
vlc_UrlClean( &p_sys->url );
//if( p_sys->psz_slingbox ) free( p_sys->psz_slingbox );
var_DelCallback (p_access->p_vlc, "key-pressed", KeyHandler, p_access);
Disconnect( p_access );
free( p_sys );
}
/*****************************************************************************
* Control:
*****************************************************************************/
static int Control( access_t *p_access, int i_query, va_list args )
{
// access_sys_t *p_sys = p_access->p_sys;
vlc_bool_t *pb_bool;
int *pi_int;
int64_t *pi_64;
// vlc_meta_t **pp_meta;
switch( i_query )
{
/* */
case ACCESS_CAN_SEEK:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = VLC_FALSE;
break;
case ACCESS_CAN_FASTSEEK:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = VLC_FALSE;
break;
case ACCESS_CAN_PAUSE:
case ACCESS_CAN_CONTROL_PACE:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
#if 0 /* Disable for now until we have a clock synchro algo
* which works with something else than MPEG over UDP */
*pb_bool = p_sys->b_pace_control;
#endif
*pb_bool = VLC_TRUE;
break;
/* */
case ACCESS_GET_MTU:
pi_int = (int*)va_arg( args, int * );
*pi_int = 0;
break;
case ACCESS_GET_PTS_DELAY:
pi_64 = (int64_t*)va_arg( args, int64_t * );
*pi_64 = (int64_t)var_GetInteger( p_access, "slingbox-caching" ) * 1000;
msg_Dbg( p_access, "slingbox-caching %dms",(int)var_GetInteger( p_access, "slingbox-caching" ));
break;
/* */
case ACCESS_SET_PAUSE_STATE:
break;
case ACCESS_GET_META:
/* pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
*pp_meta = vlc_meta_New();
if( p_sys->psz_icy_name )
vlc_meta_Add( *pp_meta, VLC_META_TITLE,
p_sys->psz_icy_name );
if( p_sys->psz_icy_genre )
vlc_meta_Add( *pp_meta, VLC_META_GENRE,
p_sys->psz_icy_genre );
if( p_sys->psz_icy_title )
vlc_meta_Add( *pp_meta, VLC_META_NOW_PLAYING,
p_sys->psz_icy_title );
break;
*/
case ACCESS_GET_TITLE_INFO:
case ACCESS_SET_TITLE:
case ACCESS_SET_SEEKPOINT:
case ACCESS_SET_PRIVATE_ID_STATE:
return VLC_EGENERIC;
default:
msg_Warn( p_access, "unimplemented query in control" );
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
unsigned short SlingBoxMessageCode = 0;
unsigned short SlingBoxMessageSeq = 0x6F;
struct SlingBoxMessage
{
unsigned short Header; // 0x0101
unsigned short Code; // This is a number that is grab from the first packet from the slingbox then always kept the same number
unsigned short MessageId; // Unique number to identify the message
unsigned short Var4; // Always 0
unsigned short Sequence; // Sequencial number (answer will have the same number)
unsigned short Direction; // 0 from slingbox and 0x8000 from software (maybe direction)
unsigned short Var7;
unsigned short Var8;
unsigned short Size; // Size of the buffer (without header)
unsigned short Encode; // 2000 -> Encoded buffer
unsigned short Var11;
unsigned short Var12;
unsigned short Var13;
unsigned short Var14;
unsigned short Var15;
unsigned short Var16;
};
static inline void _crypt(unsigned long*in ,unsigned long*out)
{
const unsigned long key[] = {0xBCDEAAAA,0x87FBBBBA,0x7CCCCFFA,0xDDDDAABC};
unsigned long v1 = in[0];
unsigned long v2 = in[1];
unsigned long z = 0;
int i;
for ( i = 0 ; i < 32 ; i ++ ) {
z -= 0x61C88647;
v1 += ((v2 >> 5) + key[1] ) ^ ((v2 << 4) + key[0]) ^ (z+v2);
v2 += ((v1 >> 5) + key[3] ) ^ ((v1 << 4) + key[2]) ^ (z+v1);
}
out[0] = v1;
out[1] = v2;
}
static inline void _uncrypt(unsigned long*in ,unsigned long*out)
{
const unsigned long key[] = {0xBCDEAAAA,0x87FBBBBA,0x7CCCCFFA,0xDDDDAABC};
unsigned long v1 = in[0];
unsigned long v2 = in[1];
unsigned long z = 0xc6ef3720;
int i;
for ( i = 0 ; i < 32 ; i ++ ) {
v2 -= ((v1 >> 5) + key[3] ) ^ ((v1 << 4) + key[2] ) ^ (z+v1);
v1 -= ((v2 >> 5) + key[1] ) ^ ((v2 << 4) + key[0] ) ^ (z+v2);
z += 0x61C88647;
}
out[0] = v1;
out[1] = v2;
}
void crypt(void*in ,void*out, int Size)
{
int i;
for ( i = 0 ; i < Size ;i += 8 )
_crypt((unsigned long*)&((unsigned char*)in)[i],(unsigned long*)&((unsigned char*)out)[i]);
}
void uncrypt(void *in ,void *out, int Size)
{
int i;
for ( i = 0 ; i < Size ;i += 8 )
_uncrypt((unsigned long*)&((unsigned char*)in)[i],(unsigned long*)&((unsigned char*)out)[i]);
}
void CopyStr( short *target , const char *source , int size)
{
if ( size > 0 ) memset(target,0,size*2);
while(size && *source) {
*target++ = *source++;
if ( size > 0 ) size--;
}
if ( size < 0 ) *target = 0;
}
void _DumpHex(access_t *p_access,void *buffer,unsigned long size )
{
unsigned long i,j;
char Line[1024];
for ( i = 0 ; i < size ; i += 16 ) {
Line[0] = 0;
for ( j = i ; j < size && j < i + 16 ; j ++ ) {
sprintf(&Line[strlen(Line)],"%02X%c",((unsigned char*)buffer)[j],j%4 != 3?' ':'-');
}
for ( ; j < i + 16 ; j ++ ) {
strcat(Line," ");
}
/*
for ( j = i ; j < size && j < i + 16 ; j ++ ) {
char str[2];
str[0] = ((BYTE*)buffer)[j];
if ( !isprint(str[0]) || str[0] == '\n' || str[0] == 'r' ) {
str[0] = '.';
}
str[1] = (char)NULL;
strcat(Line,str);
}
*/
msg_Dbg(p_access,"%04X> %s",(int)i,Line);
}
}
void ShowInfo(access_t *p_access)
{
access_sys_t *p_sys = p_access->p_sys;
vout_OSDMessage( p_access, 0, "Channel %d\nInput %d", p_sys->ch, p_sys->input );
}
void SendSlingBoxMessage( access_t *p_access, unsigned short MessageId,unsigned short Size, void *Buffer, vlc_bool_t Encode)
{
access_sys_t *p_sys = p_access->p_sys;
unsigned short _Encode = Encode?0x2000:0;
unsigned short Seq = SlingBoxMessageCode?SlingBoxMessageSeq:0;
unsigned short dir = SlingBoxMessageCode?0x8000:0;
struct SlingBoxMessage Header = { 0x0101, SlingBoxMessageCode,MessageId,0,Seq,dir,0,0,Size,_Encode,0,0,0,0,0,0 };
if ( var_GetBool( p_access, "slingbox-log" ) ) {
struct SlingBoxMessage *s = &Header;
msg_Dbg(p_access,"Send command");
msg_Dbg(p_access,"Head %04X Code %04X MgsId %04X ????? %04X",s->Header,s->Code,s->MessageId,s->Var4);
msg_Dbg(p_access,"Sequ %04X dir %04X ????? %04X ????? %04X",s->Sequence,s->Direction,s->Var7,s->Var8);
msg_Dbg(p_access,"Size %04X Enc %04X ????? %04X ????? %04X",s->Size,s->Encode,s->Var11,s->Var12);
msg_Dbg(p_access,"????? %04X ????? %04X ????? %04X ????? %04X",s->Var13,s->Var14,s->Var15,s->Var16);
_DumpHex(p_access,Buffer,Size);
}
if ( Encode ) {
crypt(Buffer,Buffer,Size);
}
net_Write(VLC_OBJECT(p_access), p_sys->fdCommand, p_sys->p_vsCommand ,(void*)&Header ,32);
net_Write(VLC_OBJECT(p_access), p_sys->fdCommand, p_sys->p_vsCommand ,Buffer,Size);
}
void ReceiveSlingBoxMessage(access_t *p_access , vlc_bool_t block)
{
access_sys_t *p_sys = p_access->p_sys;
uint8_t *buf[1024];
int i_read;
if ( block ) {
i_read = net_Read( p_access, p_sys->fdCommand, p_sys->p_vsCommand, (void*)buf, 1024 , VLC_FALSE );
}
else {
i_read = net_ReadNonBlock( p_access, p_sys->fdCommand, p_sys->p_vsCommand, (void*)buf, 1024 , VLC_FALSE );
}
if ( i_read > 0 ) {
if ( i_read >= (int)sizeof(struct SlingBoxMessage) ) {
struct SlingBoxMessage *s = (struct SlingBoxMessage*) buf;
if ( block ) SlingBoxMessageCode = s->Code;
if ( (int)sizeof(struct SlingBoxMessage) + s->Size > i_read ) {
msg_Err(p_access,"Receive short buffer %d (%d,%d)", i_read , (int)sizeof(struct SlingBoxMessage) , s->Size);
msg_Err(p_access,"Head %04X Code %04X MgsId %04X ????? %04X",s->Header,s->Code,s->MessageId,s->Var4);
msg_Err(p_access,"Sequ %04X dir %04X ????? %04X ????? %04X",s->Sequence,s->Direction,s->Var7,s->Var8);
msg_Err(p_access,"Size %04X Enc %04X ????? %04X ????? %04X",s->Size,s->Encode,s->Var11,s->Var12);
msg_Err(p_access,"????? %04X ????? %04X ????? %04X ????? %04X",s->Var13,s->Var14,s->Var15,s->Var16);
}
else {
if ( s->Encode == 0x2000 ) uncrypt(&s[1],&s[1],s->Size);
if ( s->MessageId == 0x0065 && s->Size == 0x0078 ) {
short *d = (short*)&s[1];
p_sys->ch = d[0];
ShowInfo(p_access);
}
if ( s->MessageId == 0x0065 && s->Size == 0x0008 ) {
short *d = (short*)&s[1];
p_sys->input = d[0];
ShowInfo(p_access);
}
if (var_GetBool( p_access, "slingbox-log" )) {
msg_Dbg(p_access,"Receive command (buf size %d)",i_read);
msg_Dbg(p_access,"Head %04X Code %04X MgsId %04X ????? %04X",s->Header,s->Code,s->MessageId,s->Var4);
msg_Dbg(p_access,"Sequ %04X dir %04X ????? %04X ????? %04X",s->Sequence,s->Direction,s->Var7,s->Var8);
msg_Dbg(p_access,"Size %04X Enc %04X ????? %04X ????? %04X",s->Size,s->Encode,s->Var11,s->Var12);
msg_Dbg(p_access,"????? %04X ????? %04X ????? %04X ????? %04X",s->Var13,s->Var14,s->Var15,s->Var16);
_DumpHex(p_access,&s[1],s->Size);
}
}
}
else {
msg_Err(p_access, "Receive short buffer %d (%d)", i_read,(int)sizeof(struct SlingBoxMessage) );
if ( i_read > 0 ) _DumpHex(p_access,buf,i_read);
}
}
else if ( block ) {
msg_Err(p_access, "Receive short buffer %d on block", i_read );
}
}
void slingbox_Log(access_t *p_access)
{
access_sys_t *p_sys = p_access->p_sys;
msg_Dbg( p_access, "Login" );
net_Printf( VLC_OBJECT(p_access), p_sys->fdCommand, p_sys->p_vsCommand ,"GET /stream.asf HTTP/1.1\r\nAccept: */*\r\nPragma: Sling-Connection-Type=Control, Session-Id=0\r\n\r\n");
struct {
unsigned unknow;
short Access[16];
short Password[16];
short Id[66];
} buf;
memset(&buf,0,sizeof(buf));
CopyStr(buf.Access,var_GetBool( p_access, "slingbox-admin" )?"admin":"user",16);
CopyStr(buf.Password,var_GetString( p_access, "slingbox-password" ) ,16);
CopyStr(buf.Id,var_GetString( p_access, "slingbox-user" ),66);
SendSlingBoxMessage(p_access,0x0067,200,&buf,VLC_TRUE);
ReceiveSlingBoxMessage(p_access,VLC_TRUE);
}
void slingbox_SetStream(access_t *p_access)
{
int i;
unsigned Data[24];
unsigned Size = atoi(var_GetString(p_access,"slingbox-resolution"));
unsigned vb = var_GetInteger(p_access,"slingbox-videobitrate");
unsigned fr = atoi(var_GetString(p_access,"slingbox-framerate"));
unsigned vs = var_GetInteger(p_access,"slingbox-videosmoothness");
unsigned ab = atoi(var_GetString(p_access,"slingbox-audio"));
unsigned ifr = var_GetInteger(p_access,"slingbox-iframe");
if ( vb < 50 ) vb = 50;
if (vb > 8000 ) vb = 8000;
// if (Size > 4 ) Size = 4;
// if (Size < 1 ) Size = 1;
if ( fr < 1 ) fr = 1;
else if ( fr < 6 ) fr = 1;
else if ( fr < 10 ) fr = 6;
else if ( fr < 15 ) fr = 10;
else if ( fr < 20 ) fr = 15;
else if ( fr < 30 ) fr = 20;
else fr = 30;
if ( vs > 64 ) vs = 64;
if ( ab < 16 ) ab = 16;
else if ( ab < 20 ) ab = 16;
else if ( ab < 32 ) ab = 20;
else if ( ab < 40 ) ab = 32;
else if ( ab < 48 ) ab = 40;
else if ( ab < 64 ) ab = 48;
else if ( ab < 96 ) ab = 64;
else ab = 96;
if ( ifr > 30 ) ifr = 30;
msg_Dbg( p_access,"Set Video Bitrate %d Frame rate %d I-Frame(sec) %d Video smoothness %d Size %s Audio Bitrate %d",vb,fr,ifr,vs, var_GetString(p_access,"slingbox-resolution"),ab);
Data[0] = 0x000000FF; Data[1] = 0x000000FF; Data[2] = Size; Data[3] = 1;
Data[4] = vb + (fr << 16) + (ifr << 24);
Data[5] = 1 + (vs << 8);
Data[6] = 3;
Data[7] = 1;
Data[8] = ab; Data[9] = 3; Data[10] = 1;
Data[11] = 0x46d4f252; Data[12] = 0x4c5d03e4;Data[13] = 0x04ca1f8d; Data[14] = 0xf1090089;
for ( i = 15; i < 24 ; i ++ ) Data[i] = 0;
SendSlingBoxMessage(p_access,0x00b5,24 * sizeof(unsigned),(void*)&Data,VLC_FALSE);
ReceiveSlingBoxMessage(p_access,VLC_TRUE);
}
void slingbox_input(access_t *p_access , int input )
{
unsigned char Data[8];
access_sys_t *p_sys = p_access->p_sys;
if ( input == -1 ) {
input = p_sys->default_input;
}
if ( input == -1 ) {
input = var_GetInteger(p_access,"slingbox-input");
}
if ( input != -1 ) {
msg_Dbg( p_access, "Input %d", input );
memset(Data,0,8);
Data[0]=input;
SendSlingBoxMessage(p_access,0x0085,8,(void*)&Data,VLC_FALSE);
}
}
void slingbox_channel(access_t *p_access , int _channel )
{
struct {
unsigned long up_down; // 0 == up, 1 = down (channel = 0)
unsigned long channel;
unsigned long unknow2;
unsigned long unknow3;
} Data;
access_sys_t *p_sys = p_access->p_sys;
if ( _channel == 0 ) {
_channel = p_sys->default_ch;
}
if ( _channel == 0 ) {
_channel = var_GetInteger( p_access, "slingbox-channel" );
}
if ( _channel != 0 ) {
msg_Dbg( p_access, "Channel %d", _channel );
Data.channel = _channel;
Data.up_down = 2;
Data.unknow2 = 0xFF000000;
Data.unknow3 = 0;
SendSlingBoxMessage(p_access,0x0089,4 * sizeof(unsigned long),(void*)&Data,VLC_FALSE);
}
}
void slingbox_channel_up(access_t *p_access )
{
struct {
unsigned long up_down; // 0 == up, 1 = down (channel = 0)
unsigned long channel;
unsigned long unknow2;
unsigned long unknow3;
} Data;
msg_Dbg( p_access, "Channel up" );
Data.channel = 0;
Data.up_down = 0;
Data.unknow2 = 0x000000FF;
Data.unknow3 = 0;
SendSlingBoxMessage(p_access,0x0089,4 * sizeof(unsigned long),(void*)&Data,VLC_FALSE);
}
void slingbox_channel_down(access_t *p_access )
{
struct {
unsigned long up_down; // 0 == up, 1 = down (channel = 0)
unsigned long channel;
unsigned long unknow2;
unsigned long unknow3;
} Data;
msg_Dbg( p_access, "Channel Down" );
Data.channel = 0;
Data.up_down = 1;
Data.unknow2 = 0x000000FF;
Data.unknow3 = 0;
SendSlingBoxMessage(p_access,0x0089,4 * sizeof(unsigned long),(void*)&Data,VLC_FALSE);
}
void slingbox_unblock(access_t *p_access)
{
/*
> Head 0101 Code 4616 MgsId 00A6 ????? 0000
> Sequ 006B dir 8000 ????? 0000 ????? 0000
> Size 0060 Enc 2000 ????? 0000 ????? 0000
> ????? 0000 ????? 0000 ????? 0000 ????? 0000
00 01 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
00 00 1D 00-00 00 00 00-00 00 00 00-00 00 00 00-................
00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
*/
msg_Dbg( p_access, "Unlock" );
unsigned char Data[0x60];
Data[1] = 1;
Data[18] = 0x1D;
SendSlingBoxMessage(p_access,0x00A6,0x60,(void*)&Data,VLC_FALSE);
}
void slingbox_startstream( access_t *p_access )
{
msg_Dbg( p_access, "Start Stream" );
unsigned char mes[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
SendSlingBoxMessage(p_access,0x007E,8,mes,VLC_TRUE);
}
/*****************************************************************************
* Connect:
*****************************************************************************/
static int Connect( access_t *p_access, int64_t i_tell )
{
access_sys_t *p_sys = p_access->p_sys;
p_access->info.i_size = 0;
p_access->info.i_pos = i_tell;
p_access->info.b_eof = VLC_FALSE;
/* Open control connection */
p_sys->fdCommand = net_ConnectTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port );
if( p_sys->fdCommand < 0 )
{
msg_Err( p_access, "cannot connect to %s:%d (Command)", p_sys->url.psz_host, p_sys->url.i_port );
return VLC_EGENERIC;
}
else {
msg_Dbg( p_access, "Connected to %s:%d (Command)", p_sys->url.psz_host, p_sys->url.i_port );
}
slingbox_Log( p_access );
//slingbox_input(p_access,-1);
slingbox_channel(p_access,0);
//slingbox_unblock(p_access);
slingbox_startstream( p_access );
slingbox_SetStream( p_access );
slingbox_input(p_access,-1);
// Open stream connection
p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port );
if( p_sys->fd < 0 )
{
msg_Err( p_access, "cannot connect to %s:%d (Stream)", p_sys->url.psz_host, p_sys->url.i_port );
return VLC_EGENERIC;
}
else {
msg_Dbg( p_access, "Connected to %s:%d (Stream)", p_sys->url.psz_host, p_sys->url.i_port );
}
net_Printf( VLC_OBJECT(p_access), p_sys->fd, p_sys->p_vs ,"GET /stream.asf HTTP/1.1\r\nAccept: */*\r\nPragma: Sling-Connection-Type=Stream, Session-Id=%d\r\n\r\n",SlingBoxMessageCode);
return VLC_SUCCESS;
}
/*****************************************************************************
* Read: Read up to i_len bytes from the http connection and place in
* p_buffer. Return the actual number of bytes read
*****************************************************************************/
static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
{
const unsigned long VideoHeader[] = {
0xbc19efc0,
0x11cf5b4d,
0x8000fda8,
0x2b445c5f
};
unsigned i;
uint8_t *h;
access_sys_t *p_sys = p_access->p_sys;
if ( p_sys->endtime != 0 && p_sys->endtime < time( NULL ) )
{
msg_Dbg( p_access,"Exit VLC");
p_access->p_vlc->b_die = VLC_TRUE;
//ClearChannels( p_intf, p_vout );
}
int i_read = net_Read( p_access, p_sys->fd, p_sys->p_vs, p_buffer, i_len , VLC_FALSE );
// Change a little bit the video header because VLC decoder don't like the way slingbox do
if ( p_sys->VideoSupplementChange == VLC_FALSE) {
for ( i = 0 ; i < i_len - 4*sizeof(unsigned) + 1 ; i ++ ) {
// Search for UID of video stream
if ( ((unsigned long*)(&p_buffer[i]))[0] == VideoHeader[0] &&
((unsigned long*)(&p_buffer[i]))[1] == VideoHeader[1] &&
((unsigned long*)(&p_buffer[i]))[2] == VideoHeader[2] &&
((unsigned long*)(&p_buffer[i]))[3] == VideoHeader[3] ) {
// h <- Extra data
if ( i + 105 < i_len - 4*sizeof(unsigned) ) {
h = &p_buffer[i];
h += 105;
msg_Dbg( p_access,"Make correction for WMV3 %02X%02X%02X%02X",
(int)h[0],
(int)h[1],
(int)h[2],
(int)h[3]
);
h[3] += 1; // Last bit of the 4th byte must be 1 to kept ffmpeg happy
p_sys->VideoSupplementChange = VLC_TRUE;
}
}
}
}
return i_read;
}
static int ReadCommand( vlc_object_t *p_this )
{
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys = p_access->p_sys;
vlc_thread_ready( p_this );
while( !p_sys->b_die )
{
ReceiveSlingBoxMessage(p_access,VLC_FALSE);
msleep( INPUT_ERROR_SLEEP );
}
return VLC_SUCCESS;
}
/*****************************************************************************
* Disconnect:
*****************************************************************************/
static void Disconnect( access_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
if( p_sys->fd != -1)
{
net_Close(p_sys->fd);
p_sys->fd = -1;
}
if( p_sys->fdCommand != -1)
{
net_Close(p_sys->fdCommand);
p_sys->fdCommand = -1;
}
}
static int KeyHandler (vlc_object_t *obj, char const *varname,
vlc_value_t oldval, vlc_value_t newval, void *data)
{
access_t *p_access = data;
struct hotkey *key;
(void)oldval;
(void)obj;
for (key = p_access->p_vlc->p_hotkeys; key->psz_action != NULL; key++)
{
if (key->i_key == newval.i_int)
{
/*
if (key->i_action == ACTIONID_NAV_LEFT)
slingbox_input(p_access,0);
if (key->i_action == ACTIONID_NAV_RIGHT)
slingbox_input(p_access,2);
*/
if (key->i_action == ACTIONID_NAV_UP)
slingbox_channel_up(p_access);
if (key->i_action == ACTIONID_NAV_DOWN)
slingbox_channel_down(p_access);
if (key->i_action == ACTIONID_NAV_ACTIVATE) {
ShowInfo(p_access);
}
break;
}
}
return VLC_SUCCESS;
}