[vlc-devel] Dash Access Plugin status ?

Rémi Denis-Courmont remi at remlab.net
Wed Aug 24 09:40:39 CEST 2011


diff --git a/modules/stream_filter/Modules.am
b/modules/stream_filter/Modules.am
index bdc2e69..dc0e886 100644
--- a/modules/stream_filter/Modules.am
+++ b/modules/stream_filter/Modules.am
@@ -1,3 +1,11 @@
+LIBTOOL=@LIBTOOL@ --tag=CC

What is this??

+BASE_SUBDIRS = dash
+EXTRA_SUBDIRS =
+SUBDIRS = $(BASE_SUBDIRS)
+DIST_SUBDIRS = $(BASE_SUBDIRS) $(EXTRA_SUBDIRS)

SUBDIRS = dash

should be enough

diff --git a/modules/stream_filter/dash/DASHManager.cpp
b/modules/stream_filter/dash/DASHManager.cpp
new file mode 100644
index 0000000..160182e
--- /dev/null
+++ b/modules/stream_filter/dash/DASHManager.cpp
@@ -0,0 +1,96 @@
+/*
+ * DASHManager.cpp
+
*****************************************************************************
+ * Copyright (C) 2010 - 2011 Klagenfurt University
+ *
+ * Created on: Aug 10, 2010
+ * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
+ *          Christian Timmerer  <christian.timmerer at itec.uni-klu.ac.at>
+ *
+ * This program 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 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 Lesser 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.
+
*****************************************************************************/
+
+#include "DASHManager.h"

You really should have the standard <config.h> boiler plate at the
beginning of every .c(pp) file.

(...)
+    if(DEBUG)
+    {
+        std::cout << "------------------------------------" << std::endl;
+        std::cout << "New chunk bitrate: " << bitrate << std::endl;
+    }

Either you use CPP conditional:
#ifdef DEBUG
or you use the VLC infrastructure:
msg_Dbg(...)

(...)
diff --git a/modules/stream_filter/dash/dash.cpp
b/modules/stream_filter/dash/dash.cpp
new file mode 100644
index 0000000..34e93c2
--- /dev/null
+++ b/modules/stream_filter/dash/dash.cpp
@@ -0,0 +1,260 @@
+/*****************************************************************************
+ * dash.cpp: DASH module
+
*****************************************************************************
+ * Copyright (C) 2010 - 2011 Klagenfurt University
+ *
+ * Created on: Aug 10, 2010
+ * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
+ *          Christian Timmerer  <christian.timmerer at itec.uni-klu.ac.at>
+ *
+ * This program 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 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 Lesser 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
+
*****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <limits.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_demux.h>
+#include <vlc_stream.h>
+#include <vlc_modules.h>
+#include <vlc_input.h>
+
+#include <errno.h>
+#include <string>
+#include <map>
+#include <fcntl.h>
+#include <iostream>
+#include <stdio.h>
+
+#include "DASHManager.h"
+#include "xml/DOMParser.h"
+#include "http/HTTPConnectionManager.h"
+#include "adaptationlogic/IAdaptationLogic.h"
+
+#define SEEK 0
+
+static int count = 0;

Any global variable is suspicious in multi-thread environment

+/*****************************************************************************
+ * Module descriptor
+
*****************************************************************************/
+static int  Open    (vlc_object_t *);
+static void Close   (vlc_object_t *);
+
+vlc_module_begin ()
+        set_shortname( N_("DASH"))
+        set_description( N_("Dynamic Adaptive Streaming over HTTP") )
+        set_capability( "stream_filter", 20 )
+        set_category( CAT_INPUT )
+        set_subcategory( SUBCAT_INPUT_STREAM_FILTER )
+        set_callbacks( Open, Close )
+vlc_module_end ()
+/*****************************************************************************
+ * Local prototypes
+
*****************************************************************************/
+struct stream_sys_t
+{
+        dash::DASHManager                   *p_dashManager;
+        dash::http::HTTPConnectionManager   *p_conManager;
+        dash::xml::Node                     *p_node;
+        int                                 position;
+        bool                                isLive;
+};
+
+static int  Read            (stream_t *p_stream, void *p_buffer, unsigned
int i_len);
+static int  Peek            (stream_t *p_stream, const uint8_t **pp_peek,
unsigned int i_peek);
+static int  Control         (stream_t *p_stream, int i_query, va_list
args);
+static bool IsFilterLoop    (stream_t *p_stream);
+static bool IsDash          (stream_t *p_stream, dash::xml::DOMParser
*p_parser);
+static void SetCacheSize    (stream_t *p_stream);
+/*****************************************************************************
+ * Open:
+
*****************************************************************************/
+static int Open(vlc_object_t *p_this)
+{
+    stream_t *p_stream = (stream_t*) p_this;
+
+    /* HACK */
+    if(IsFilterLoop(p_stream))
+        return VLC_EGENERIC;
+
+    msg_Dbg(p_this,"DASH filter: open (%s)", p_stream->psz_path);

Please don't print debug until after the plug-in probed successfully. This
will fill clutter the logs.

+    dash::xml::DOMParser *p_parser = new
dash::xml::DOMParser(p_stream->p_source);
+
+    if(!IsDash(p_stream, p_parser))
+    {
+        delete(p_parser);
+        return VLC_EGENERIC;
+    }
+
+    stream_sys_t *p_sys = (stream_sys_t *) malloc(sizeof(stream_sys_t));
+    if (unlikely(p_sys == NULL))
+        return VLC_ENOMEM;

That's OK; but maybe the new operator would be simpler here.

+    dash::http::HTTPConnectionManager   *p_conManager   = new
dash::http::HTTPConnectionManager(p_stream);
+    dash::xml::Node                     *p_node         =
p_parser->getRootNode();
+    dash::DASHManager                   *p_dashManager  = new
dash::DASHManager(p_conManager,
+                                                                         
     p_node,
+                                                                         
     dash::logic::IAdaptationLogic::RateBased,
+                                                                         
     p_parser->getProfile(p_node));
+    delete(p_parser);
+
+    p_sys->p_dashManager    = p_dashManager;
+    p_sys->p_node           = p_node;
+    p_sys->p_conManager     = p_conManager;
+    p_sys->position         = 0;
+    p_sys->isLive           = true;
+    p_stream->p_sys         = p_sys;
+    p_stream->pf_read       = Read;
+    p_stream->pf_peek       = Peek;
+    p_stream->pf_control    = Control;
+
+    SetCacheSize(p_stream);
+
+    msg_Dbg(p_this,"DASH filter: success");

Not needed. The module subsystem already prints a generic debug message
for this.

+
+    return VLC_SUCCESS;
+}
+/*****************************************************************************
+ * Close:
+
*****************************************************************************/
+static void Close(vlc_object_t *p_this)
+{
+    stream_t                            *p_stream       = (stream_t*)
p_this;
+    stream_sys_t                        *p_sys          = (stream_sys_t
*) p_stream->p_sys;
+    dash::DASHManager                   *p_dashManager  =
p_sys->p_dashManager;
+    dash::http::HTTPConnectionManager   *p_conManager   =
p_sys->p_conManager;
+    dash::xml::Node                     *p_node         = p_sys->p_node;
+
+    delete(p_conManager);
+    delete(p_dashManager);
+    delete(p_node);
+    free(p_sys);
+}
+/*****************************************************************************
+ * Callbacks:
+
*****************************************************************************/
+static int  Read            (stream_t *p_stream, void *p_buffer, unsigned
int i_len)
+{
+    stream_sys_t        *p_sys          = (stream_sys_t *)
p_stream->p_sys;
+    dash::DASHManager   *p_dashManager  = p_sys->p_dashManager;
+    int                 i_ret           = 0;
+
+    i_ret = p_dashManager->read(p_buffer, i_len);
+
+    if (i_ret < 0)
+    {
+        switch (errno)
+        {
+            case EINTR:
+            case EAGAIN:
+                break;
+            default:
+                msg_Dbg(p_stream, "DASH Read: failed to read");

"%m" maybe?

+                return 0;
+        }
+        return 0;
+    }
+
+    p_sys->position += i_ret;
+
+    return i_ret;
+}
+static int  Peek            (stream_t *p_stream, const uint8_t **pp_peek,
unsigned int i_peek)
+{
+    stream_sys_t        *p_sys          = (stream_sys_t *)
p_stream->p_sys;
+    dash::DASHManager   *p_dashManager  = p_sys->p_dashManager;
+
+    return p_dashManager->peek(pp_peek, i_peek);
+}
+static int  Control         (stream_t *p_stream, int i_query, va_list
args)
+{
+    stream_sys_t *p_sys = p_stream->p_sys;
+
+    switch (i_query)
+    {
+        case STREAM_CAN_SEEK:
+        case STREAM_CAN_FASTSEEK:
+            /*TODO Support Seek */
+            *(va_arg (args, bool *)) = SEEK;
+            break;
+        case STREAM_GET_POSITION:
+            *(va_arg (args, uint64_t *)) = p_sys->position;
+            break;
+        case STREAM_SET_POSITION:
+            return VLC_EGENERIC;
+        case STREAM_GET_SIZE:
+            if(p_sys->isLive)
+                *(va_arg (args, uint64_t *)) = 0;
+            break;

Returning VLC_SUCCESS w/o setting the size does not look right.

+        default:
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+/*****************************************************************************
+ * Helpers:
+
*****************************************************************************/
+static bool IsFilterLoop    (stream_t *p_stream)
+{
+    vlc_object_t *parent = p_stream->p_parent;
+    while(parent != NULL)
+    {
+        if(!strcmp(parent->psz_object_type, "stream"))
+            if(((stream_t *)parent)->p_module != NULL)
+                if(!strcmp(module_get_name(((stream_t
*)parent)->p_module, false), "DASH"))
+                    return true;
+
+        parent = parent->p_parent;
+    }
+
+    return false;
+}

You are not allowed to read p_parent->p_module from here.
Besides, you should never use p_parent at all.

And anyway, you should be able to detect this transparently in IsDash().

+static bool IsDash          (stream_t *p_stream, dash::xml::DOMParser
*p_parser)
+{
+    if(!p_parser->isDash())
+    {
+        msg_Dbg(p_stream,"DASH filter: file is no mpd");
+        return false;
+    }
+
+    if(!p_parser->parse())
+    {
+        msg_Dbg(p_stream,"DASH filter: could not parse file");
+        return false;
+    }
+
+    return true;
+}
+static void SetCacheSize    (stream_t *p_stream)
+{
+    vlc_object_t *parent = p_stream->p_parent;
+    while(parent != NULL)
+    {
+        if(!strcmp(parent->psz_object_type, "access"))
+            var_SetInteger(parent, "http-caching", 10000);
+
+        parent = parent->p_parent;
+    }
+}

Same problem as IsLoop(). Just don't do this.


And last note: you will probably break compilations w/o libxml2. You
should either only enable the module when libxml2 is available, or (better)
use the VLC XML API (include/vlc_xml.h).

-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list