gmyth/src/gmyth_vlc.c
author leo_sobral
Sat Mar 10 15:01:25 2007 +0000 (2007-03-10)
branchtrunk
changeset 411 2127788267bd
parent 350 ff82d527d26a
child 698 9019388af980
permissions -rw-r--r--
[svn r416] added static to socket_send function from gmyth_vlc.c
     1 /**
     2  * GMyth Library
     3  *
     4  * @file gmyth/gmyth_vlc.c
     5  *
     6  * @brief <p> GMythVLC library provides functions that
     7  * interact with a VLC server running telnet interface.
     8  *
     9  * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
    10  * @author Artur Duque de Souza <artur.souza@indt.org.br>
    11  *
    12  * 
    13  * This program is free software; you can redistribute it and/or modify
    14  * it under the terms of the GNU Lesser General Public License as published by
    15  * the Free Software Foundation; either version 2 of the License, or
    16  * (at your option) any later version.
    17  *
    18  * This program is distributed in the hope that it will be useful,
    19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    21  * GNU General Public License for more details.
    22  *
    23  * You should have received a copy of the GNU Lesser General Public License
    24  * along with this program; if not, write to the Free Software
    25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    26  */
    27  
    28 #ifdef HAVE_CONFIG_H
    29 #include "config.h"
    30 #endif
    31 
    32 #include <assert.h>
    33 
    34 #include "gmyth_vlc.h"
    35 #include "gmyth_debug.h"
    36 #include "gmyth_socket.h"
    37 
    38 /* static functions */
    39 static int _socket_send(int socket, gchar* msg);
    40 static int _socket_recv(int socket, gchar* buf);
    41 
    42 /** Primitive function to send a message through the socket
    43  *
    44  * @param socket 
    45  * @param msg the message itself
    46  * @return 0 if success
    47  */
    48 static int 
    49 _socket_send(int socket, gchar* msg)
    50 {  
    51   size_t size = strlen(msg) + 2; // (\n + \0)
    52     gchar* final = (gchar *)g_malloc0(sizeof(gchar) * size);
    53     g_snprintf(final, size, "%s\n", msg);
    54 
    55     if (send(socket, final, strlen(final), 0) == -1)
    56       perror("GMyth_VLC: send error");
    57 
    58     g_free(final);
    59     return 0;
    60 }
    61 
    62 
    63 /** Primitive function to receive a message through the socket
    64  *
    65  * @param socket 
    66  * @param buf Buffer to put the message
    67  * @return 0 if success
    68  */
    69 static int 
    70 _socket_recv(int socket, gchar* buf)
    71 {
    72   int numbytes = 0;
    73 
    74   if ((numbytes=recv(socket, buf, BUFFER-1, 0)) == -1) 
    75   {
    76     perror("GMyth_VLC: recv error");
    77     return -1;
    78   }
    79 
    80   buf[numbytes-1] = '\0';
    81   return numbytes;
    82 }
    83 
    84 
    85 /** Function that adds options to the output media
    86  *
    87  * @param vlc structure with options for vlc
    88  * @param output the number of the output media
    89  * @param kind the type of option we'll change
    90  * @param the params for the option
    91  * @return 0 if success
    92  */
    93 int 
    94 gmyth_vlc_setup_output(GMythVlc *vlc, int output, \
    95                            gchar* kind, gchar* opts)
    96 {
    97     int ret;
    98 
    99     size_t size = strlen(opts) + 25;
   100     gchar* msg = g_malloc0(sizeof(gchar) * size);
   101     g_snprintf(msg, size, "setup output%d %s %s", output,\
   102                kind, opts);
   103 
   104     ret = _socket_send(vlc->sockfd, msg);
   105 
   106     g_free(msg);
   107     return ret;
   108 }
   109 
   110 
   111 /** Function to clean the playlist
   112  *
   113  * @param vlc structure with options for vlc
   114  * @param output the number of the output media
   115  * @param file the file we want to insert in the playlist
   116  * @return 0 if success
   117  */
   118 int 
   119 gmyth_vlc_clean_playlist(GMythVlc *vlc)
   120 {
   121   return _socket_send(vlc->sockfd, "del all");
   122 }
   123 
   124 
   125 /** Function to control the playlist
   126  *
   127  * @param vlc structure with options for vlc
   128  * @param output the number of the output media
   129  * @param command play, stop or pause(just for vod)
   130  * @return 0 if success
   131  */
   132 int 
   133 gmyth_vlc_control_input(GMythVlc *vlc, int output, \
   134                            gchar* command)
   135 {
   136     size_t size = 25;
   137     gchar* msg = g_malloc0(sizeof(gchar) * size);
   138     g_snprintf(msg, size, "control output%d %s", output,\
   139                command);
   140 
   141     int ret = _socket_send(vlc->sockfd, msg);
   142     
   143     g_free(msg);
   144     return ret;
   145 }
   146 
   147 
   148 
   149 /** Function to insert an item in the playlist
   150  *
   151  * @param vlc structure with options for vlc
   152  * @param output the number of the output media
   153  * @param file the file we want to insert in the playlist
   154  * @return 0 if success
   155  */
   156 int 
   157 gmyth_vlc_create_input(GMythVlc *vlc, int output,\
   158                            gchar* file)
   159 {
   160     return gmyth_vlc_setup_output(vlc, output, "input",\
   161                                   file);
   162 }
   163 
   164 
   165 /** Function to create a channel in vlc
   166  *
   167  * @param vlc structure with options for vlc
   168  * @param type the type of channel (broadcast, vod...)
   169  * @param port
   170  * @return 0 if success
   171  */
   172 int 
   173 gmyth_vlc_create_channel(GMythVlc *vlc, gchar* type,\
   174                              int port, int vcodec)
   175 {
   176     int ret;
   177     size_t size = 40;
   178     gchar* msg = (gchar *)g_malloc0(sizeof(gchar) * size);
   179     g_snprintf(msg, size, "new output%d %s enabled loop", \
   180              vlc->n_outputs, type);
   181 
   182     ret = _socket_send(vlc->sockfd, msg);
   183 
   184     if (ret > -1)
   185     {
   186       gmyth_vlc_setup_output(vlc, vlc->n_outputs, "option", \
   187                            "sout-keep=1");
   188     
   189       g_free(msg);
   190       size = 256;
   191       msg = (gchar *)g_malloc0(sizeof(gchar) * size);
   192 
   193       if ( vcodec == MPEG1 )
   194 
   195         // Best transcode option for N800 (MP1V)
   196         g_snprintf(msg, size, "#transcode{vcodec=mp1v,vb=384,"
   197                               "fps=25.0,scale=1,acodec=mpga,"
   198                               "ab=64,channels=1}:duplicate{dst="
   199                               "std{access=http,mux=mpeg1,dst="
   200                               ":%d}}", port);
   201       else
   202 
   203         // Best transcode option for N800 (THEORA)
   204         g_snprintf(msg, size, "#transcode{vcodec=theo,vb=384,"
   205                               "fps=25.0,scale=1,acodec=vorb,"
   206                               "ab=64,channels=1}:duplicate{dst="
   207                               "std{access=http,mux=ogg,dst="
   208                               ":%d}}", port);
   209 
   210       ret = gmyth_vlc_setup_output(vlc, vlc->n_outputs, "output", \
   211                                    msg);
   212       
   213       vlc->n_outputs++;
   214     }
   215 
   216     g_free(msg);
   217 
   218     return ret;
   219 }
   220 
   221 
   222 /** Function to connect to vlc on the backend
   223  *
   224  * @param vlc structure with options for vlc
   225  * @param backend_info infos about the backend
   226  * @param passwd the password for telnet interface
   227  * @return 0 if success
   228  */
   229 int 
   230 gmyth_vlc_connect(GMythVlc *vlc, GMythBackendInfo *backend_info,\
   231                       gchar* passwd, int port)
   232 {
   233     int numbytes;  
   234     
   235     if ((vlc->he=gethostbyname(backend_info->hostname)) == NULL) 
   236     { 
   237       herror("GMyth_VLC: gethostbyname error");
   238       return -1;
   239     }
   240       
   241     if ((vlc->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) 
   242     {
   243         perror("GMyth_VLC: socket error");
   244         return -1;
   245     }
   246       
   247     // Socket properties
   248     vlc->their_addr.sin_family = AF_INET; 
   249     vlc->their_addr.sin_port = htons(port); 
   250     vlc->their_addr.sin_addr = *((struct in_addr *)vlc->he->h_addr);
   251     memset(&(vlc->their_addr.sin_zero), '\0', 8);
   252     
   253     if (connect(vlc->sockfd, (struct sockaddr *)&(vlc->their_addr),
   254                 sizeof(struct sockaddr)) == -1) 
   255     {
   256       perror("GMyth_VLC: connect error. Check VLC's telnet interface");
   257       return -1;
   258     }
   259 
   260 
   261     // Receive the Password's Prompt
   262     numbytes = _socket_recv(vlc->sockfd, vlc->buf);
   263 
   264     // Send the Password. We don't have to
   265     // care about passwords being sent in plain text
   266     // because telnet protocol does it.
   267     _socket_send(vlc->sockfd, passwd);
   268 
   269     // Receive the Welcome msg
   270     numbytes = _socket_recv(vlc->sockfd, vlc->buf);
   271     if (numbytes > -1)
   272       if (strncmp(vlc->buf,"\r\nWrong password.", 17) == 0)
   273       {
   274         perror("Gmyth_VLC: passwd error. Check your passwd");
   275         return -2;
   276       }
   277     
   278     
   279     return 0;
   280 } 
   281 
   282 
   283 /** Function to disconnect from vlc
   284  *
   285  * @param vlc structure with options for vlc
   286  * @param backend_info infos about the backend
   287  * @return 0 if success
   288  */
   289 int 
   290 gmyth_vlc_disconnect(GMythVlc *vlc)
   291 {
   292 
   293     int ret;
   294 
   295     ret = gmyth_vlc_clean_playlist(vlc);
   296 
   297     if (ret > -1)
   298     {
   299       vlc->n_outputs = 0;
   300       vlc->n_inputs = 0;
   301     }
   302 
   303     return close(vlc->sockfd);
   304 }