Commit 5bf01e70 authored by Frédéric Yhuel's avatar Frédéric Yhuel Committed by Jean-Baptiste Kempf
parent 5a72f814
...@@ -92,6 +92,15 @@ libdash_plugin_la_CXXFLAGS = $(AM_CFLAGS) -I$(srcdir)/dash ...@@ -92,6 +92,15 @@ libdash_plugin_la_CXXFLAGS = $(AM_CFLAGS) -I$(srcdir)/dash
libdash_plugin_la_LIBADD = $(AM_LIBADD) $(SOCKET_LIBS) libdash_plugin_la_LIBADD = $(AM_LIBADD) $(SOCKET_LIBS)
libvlc_LTLIBRARIES += libdash_plugin.la libvlc_LTLIBRARIES += libdash_plugin.la
libsmooth_plugin_la_SOURCES = \
smooth/smooth.c \
smooth/utils.c \
smooth/downloader.c \
smooth/smooth.h
libsmooth_plugin_la_CFLAGS = $(AM_CFLAGS)
libvlc_LTLIBRARIES += libsmooth_plugin.la
libhttplive_plugin_la_SOURCES = httplive.c libhttplive_plugin_la_SOURCES = httplive.c
libhttplive_plugin_la_CFLAGS = $(AM_CFLAGS) $(GCRYPT_CFLAGS) libhttplive_plugin_la_CFLAGS = $(AM_CFLAGS) $(GCRYPT_CFLAGS)
libhttplive_plugin_la_LIBADD = $(AM_LIBADD) $(GCRYPT_LIBS) -lgpg-error libhttplive_plugin_la_LIBADD = $(AM_LIBADD) $(GCRYPT_LIBS) -lgpg-error
......
This diff is collapsed.
This diff is collapsed.
/*****************************************************************************
* smooth.h: misc. stuff
*****************************************************************************
* Copyright (C) 1996-2012 VLC authors and VideoLAN
* $Id$
*
* Author: Frédéric Yhuel <fyhuel _AT_ viotech _DOT_ net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#ifndef _VLC_SMOOTH_H
#define _VLC_SMOOTH_H 1
//#define DISABLE_BANDWIDTH_ADAPTATION
typedef struct item_s
{
uint64_t value;
struct item_s *next;
} item_t;
typedef struct sms_queue_s
{
int length;
item_t *first;
} sms_queue_t;
typedef struct chunk_s
{
int64_t duration; /* chunk duration (seconds / TimeScale) */
int64_t start_time; /* PTS (seconds / TimeScale) */
int size; /* chunk size in bytes */
unsigned sequence; /* unique sequence number */
uint64_t offset; /* offset in the media */
int read_pos; /* position in the chunk */
int type; /* video, audio, or subtitles */
block_t *data;
} chunk_t;
typedef struct quality_level_s
{
int Index;
uint32_t FourCC;
unsigned Bitrate;
unsigned MaxWidth;
unsigned MaxHeight;
unsigned SamplingRate;
unsigned AvgBytesPerSec;
unsigned Channels;
unsigned BitsPerSample;
unsigned PacketSize;
unsigned AudioTag;
unsigned nBlockAlign;
unsigned id;
char *CodecPrivateData; /* hex encoded string */
} quality_level_t;
typedef struct sms_stream_s
{
vlc_array_t *qlevels; /* list of available Quality Levels */
vlc_array_t *chunks; /* list of chunks */
unsigned vod_chunks_nb; /* total num of chunks of the VOD stream */
unsigned timescale;
unsigned qlevel_nb; /* number of quality levels */
unsigned id; /* track id, will be set arbitrarily */
char *name;
char *url_template;
int type;
unsigned download_qlvl; /* current quality level ID for Download() */
} sms_stream_t;
struct stream_sys_t
{
char *base_url; /* URL common part for chunks */
vlc_thread_t thread; /* SMS chunk download thread */
vlc_array_t *sms_streams; /* array of sms_stream_t */
sms_stream_t *vstream; /* current video stream */
sms_stream_t *astream; /* current audio stream */
sms_stream_t *tstream; /* current text stream */
unsigned i_tracks; /* Total number of tracks in the Manifest */
unsigned i_selected_tracks;
sms_queue_t *bws; /* Measured bandwidths of the N last chunks */
uint64_t vod_duration; /* total duration of the VOD media */
int64_t time_pos;
unsigned timescale;
/* Download */
struct sms_download_s
{
uint64_t alead; // how much audio/video/text data is
uint64_t vlead; // available (downloaded),
uint64_t tlead; // in seconds / TimeScale
unsigned aindex; /* current audio chunk for download */
unsigned vindex; /* video */
unsigned sindex; /* spu */
uint64_t next_chunk_offset;
vlc_array_t *chunks; /* chunks that have been downloaded */
vlc_mutex_t lock_wait; /* protect chunk download counter. */
vlc_cond_t wait; /* some condition to wait on */
} download;
/* Playback */
struct sms_playback_s
{
uint64_t boffset; /* current byte offset in media */
uint64_t toffset; /* current time offset in media */
unsigned index; /* current chunk for playback */
} playback;
/* state */
bool b_cache; /* can cache files */
bool b_live; /* live stream? or vod? */
bool b_error; /* parsing error */
bool b_close; /* set by Close() */
bool b_tseek; /* time seeking */
};
#define SMS_GET4BYTES( dst ) do { \
dst = U32_AT( slice ); \
slice += 4; \
} while(0)
#define SMS_GET1BYTE( dst ) do { \
dst = *slice; \
slice += 1; \
} while(0)
#define SMS_GET3BYTES( dst ) do { \
dst = Get24bBE( slice ); \
slice += 3; \
} while(0)
#define SMS_GET8BYTES( dst ) do { \
dst = U64_AT( slice ); \
slice += 8; \
} while(0)
#define SMS_GET4or8BYTES( dst ) \
if( (version) == 0 ) \
SMS_GET4BYTES( dst ); \
else \
SMS_GET8BYTES( dst ); \
#define SMS_GETFOURCC( dst ) do { \
memcpy( &dst, slice, 4 ); \
slice += 4; \
} while(0)
sms_queue_t *sms_queue_init( const int );
int sms_queue_put( sms_queue_t *, const uint64_t );
uint64_t sms_queue_avg( sms_queue_t *);
quality_level_t *get_qlevel( sms_stream_t *, const unsigned );
void* sms_Thread( void *);
quality_level_t * ql_New( void );
void ql_Free( quality_level_t *);
chunk_t *chunk_New( sms_stream_t* , uint64_t , uint64_t );
void chunk_Free( chunk_t *);
sms_stream_t * sms_New( void );
void sms_Free( sms_stream_t *);
uint8_t *decode_string_hex_to_binary( const char * );
#endif
/*****************************************************************************
* utils.c: misc. stuff
*****************************************************************************
* Copyright (C) 1996-2012 VLC authors and VideoLAN
* $Id$
*
* Author: Frédéric Yhuel <fyhuel _AT_ viotech _DOT_ net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_es.h>
#include <vlc_block.h>
#include <assert.h>
#include "smooth.h"
static int hex_digit( const char c )
{
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else if (c >= '0' && c<= '9')
return c - '0';
else
return -1;
}
uint8_t *decode_string_hex_to_binary( const char *psz_src )
{
int i = 0, j = 0, first_digit, second_digit;
int i_len = strlen( psz_src );
assert( i_len % 2 == 0 );
uint8_t *p_data = malloc( i_len / 2 );
if( !p_data )
return NULL;
while( i < i_len )
{
first_digit = hex_digit( psz_src[i++] );
second_digit = hex_digit( psz_src[i++] );
assert( first_digit >= 0 && second_digit >= 0 );
p_data[j++] = ( first_digit << 4 ) | second_digit;
}
return p_data;
}
quality_level_t * ql_New( void )
{
quality_level_t *ql = calloc( 1, sizeof( quality_level_t ) );
if( unlikely( !ql ) ) return NULL;
ql->Index = -1;
return ql;
}
void ql_Free( quality_level_t *qlevel )
{
free( qlevel->CodecPrivateData );
free( qlevel );
qlevel = NULL;
}
chunk_t *chunk_New( sms_stream_t* sms, uint64_t duration,\
uint64_t start_time )
{
chunk_t *chunk = calloc( 1, sizeof( chunk_t ) );
if( unlikely( chunk == NULL ) )
return NULL;
chunk->duration = duration;
chunk->start_time = start_time;
chunk->type = UNKNOWN_ES;
chunk->sequence = vlc_array_count( sms->chunks );
vlc_array_append( sms->chunks, chunk );
return chunk;
}
void chunk_Free( chunk_t *chunk )
{
if( chunk->data )
block_Release( chunk->data );
free( chunk );
chunk = NULL;
}
sms_stream_t * sms_New( void )
{
sms_stream_t *sms = calloc( 1, sizeof( sms_stream_t ) );
if( unlikely( !sms ) ) return NULL;
sms->qlevels = vlc_array_new();
sms->chunks = vlc_array_new();
sms->type = UNKNOWN_ES;
return sms;
}
void sms_Free( sms_stream_t *sms )
{
if( sms->qlevels )
{
for( int n = 0; n < vlc_array_count( sms->qlevels ); n++ )
{
quality_level_t *qlevel = vlc_array_item_at_index( sms->qlevels, n );
if( qlevel ) ql_Free( qlevel );
}
vlc_array_destroy( sms->qlevels );
}
if( sms->chunks )
{
for( int n = 0; n < vlc_array_count( sms->chunks ); n++ )
{
chunk_t *chunk = vlc_array_item_at_index( sms->chunks, n );
if( chunk) chunk_Free( chunk );
}
vlc_array_destroy( sms->chunks );
}
free( sms );
sms = NULL;
}
quality_level_t *get_qlevel( sms_stream_t *sms, const unsigned qid )
{
quality_level_t *qlevel = NULL;
for( unsigned i = 0; i < sms->qlevel_nb; i++ )
{
qlevel = vlc_array_item_at_index( sms->qlevels, i );
if( qlevel->id == qid )
return qlevel;
}
return NULL;
}
sms_queue_t *sms_queue_init( const int length )
{
sms_queue_t *ret = malloc( sizeof( sms_queue_t ) );
if( unlikely( !ret ) )
return NULL;
ret->length = length;
ret->first = NULL;
return ret;
}
int sms_queue_put( sms_queue_t *queue, const uint64_t value )
{
item_t *last = queue->first;
int i = 0;
for( i = 0; i < queue->length - 1; i++ )
{
if( last )
last = last->next;
}
if( i == queue->length - 1 )
FREENULL( last );
item_t *new = malloc( sizeof( item_t ) );
if( unlikely( !new ) )
return VLC_ENOMEM;
new->value = value;
new->next = queue->first;
queue->first = new;
return VLC_SUCCESS;
}
uint64_t sms_queue_avg( sms_queue_t *queue )
{
item_t *last = queue->first;
if( last == NULL )
return 0;
uint64_t sum = queue->first->value;
for( int i = 0; i < queue->length - 1; i++ )
{
if( last )
{
last = last->next;
if( last )
sum += last->value;
}
}
return sum / queue->length;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment