[MPlayer-dev-eng] [PATCH] smil params support is added.

Clément Bœsch ubitux at gmail.com
Sat Jan 29 13:16:04 CET 2011


On Fri, Jan 28, 2011 at 10:23:23AM +0600, Andrei Katsuk wrote:
> Hi,
> Currently, when parsing a SMIL playlist file, MPlayer is
> support only <media>, <video> <audio> src tags.
> 
> Attached patch adds support of param tag like:
> 
> <video src="test.avi" >
> <param name="additional-param1" value="additional-value1"/>
> <param name="additional-param2" value="additional-value2"/>
> </video>
> 
> Also paramGroup support is added:
> 
> <paramGroup xml:id="testgroup">
> <param name="additional-param1" value="additional-value1"/>
> <param name="additional-param2" value="additional-value2"/>
> </paramGroup>
> </head>
> <body>
> <ref src="test.avi" paramGroup="tesgroup">
> 
> 
> Andrei

> Index: Makefile
> ===================================================================
> --- Makefile	(revision 32825)
> +++ Makefile	(working copy)
> @@ -304,6 +304,7 @@
>                mpcommon.c \
>                parser-cfg.c \
>                path.c \
> +              grouplist.c \
>                playtree.c \
>                playtreeparser.c \
>                subopt-helper.c \

Alphabetic order would be welcome.

> Index: grouplist.c
> ===================================================================
> --- grouplist.c	(revision 0)
> +++ grouplist.c	(revision 0)

Same goes for the style of this file: since it's a new file, could you
reindent it to K&R, 4-spaces indent, no pointless { }, etc?

> @@ -0,0 +1,193 @@
> +
> +#include "config.h"
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#ifdef MP_DEBUG
> +#include <assert.h>
> +#endif

This ifdef should not be necessary. Though, I see it in use in a few places, with
the use around assert calls too… I personally think it's worth the effort,
but maybe someone agree with this method.

> +#include "m_config.h"
> +#include "mp_msg.h"
> +#include "grouplist.h"
> +
> +/// Create a new empty playtree item.
> +param_list_t*
> +param_list_new(void) {
> +  param_list_t* r = calloc(1,sizeof(param_list_t));
> +  if(r == NULL) {
> +    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",(int)sizeof(param_list_t));
> +    return NULL;
> +  }
> +  return r;
> +}
> +
> +/// Free a playtree item.
> +/** \param pt Item to free.
> + *  \param children If non-zero the item's children are recursively freed.
> + */

Use @ instead of \, and use @brief for the first sentence.

> +void
> +param_list_free(param_list_t* pt) {
> +
> +    while(pt) {
> +       param_list_t* r = pt;
> +       pt = pt->next;
> +       free(r->params->name);
> +       free(r->params->value);
> +       free(r);
> +       
> +    }
> +}
> +
> +/// Append an item after its siblings.
> +void
> +param_list_insert_entry(param_list_t* pl, param_list_t* entry) {
> +
> +  param_list_t* iter;
> +
> +#ifdef MP_DEBUG
> +  assert(pl != NULL);
> +  assert(entry != NULL);
> +#endif
> +
> +  if(pl == entry)
> +    return;
> +
> +  for(iter = pl ; iter->next != NULL ; iter = iter->next)
> +    /* NOTHING */;
> +
> +  entry->prev = iter;
> +  entry->next = NULL;
> +  iter->next = entry;
> +
> +}
> +
> +/// Add a config paramter to an item.
> +void
> +param_list_set_param(param_list_t* pl, char* name, char* val) {
> +  int n = 0;
> +
> +#ifdef MP_DEBUG
> +  assert(pl != NULL);
> +  assert(name != NULL);
> +#endif
> +
> +  if(pl->params)
> +    for ( ; pl->params[n].name != NULL ; n++ ) { }
> +
> +  pl->params = realloc(pl->params, (n + 2) * sizeof(param_list_param_t));
> +  if(pl->params == NULL) {
> +      mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't realloc params (%d bytes of memory)\n",(n+2)*(int)sizeof(param_list_param_t));
> +      return;
> +  }

pl->params is not free on failure; use a temporary pointer.

> +  pl->params[n].name = strdup(name);
> +  pl->params[n].value = val != NULL ? strdup(val) : NULL;
> +  memset(&pl->params[n+1],0,sizeof(param_list_param_t));

sizeof(*p) instead of sizeof(p_type)

> +
> +  return;

Pointless.

> +}
> +
> +char * 
> +param_list_get_param(param_list_t* pl, char* name) {
> +
> +int n = 0;
> +#ifdef MP_DEBUG
> +  assert(pl != NULL);
> +  assert(name != NULL);
> +#endif
> +
> +  char * value = NULL;
> +
> +  if(pl->params)
> +    for ( ; pl->params[n].name != NULL ; n++ ) { 
> +       if(!strcasecmp(pl->params[n].name, name)) {
> +         value = pl->params[n].value;
> +         break;
> +       }
> +    }
> +  return value;
> +}
> +
> +/// Create a new empty playtree item.
> +group_list_t*
> +group_list_new(void) {
> +  group_list_t* r = calloc(1,sizeof(group_list_t));

ditto sizeof

> +  if(r == NULL) {
> +    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",(int)sizeof(group_list_t));
> +    return NULL;
> +  }
> +  return r;
> +}
> +
> +/// Free a playtree item.
> +/** \param pt Item to free.
> + *  \param children If non-zero the item's children are recursively freed.
> + */
> +void
> +group_list_free(group_list_t* pt) {
> +
> +    while(pt) {
> +       group_list_t* r = pt;
> +       pt = pt->next;
> +       param_list_free(r->param_ref);
> +       free(r);
> +    }
> +}
> +
> +/// Append an item after its siblings.
> +void
> +group_list_insert_entry(group_list_t* pl, group_list_t* entry) {
> +
> + param_list_t* iter;
> +
> +#ifdef MP_DEBUG
> +  assert(pl != NULL);
> +  assert(entry != NULL);
> +#endif
> +
> +  if(pl == entry)
> +    return;
> +
> +  for(iter = pl ; iter->next != NULL ; iter = iter->next)
> +    /* NOTHING */;
> +
> +  entry->prev = iter;
> +  entry->next = NULL;
> +  iter->next = entry;
> +}
> +
> +/// Add a config paramter to an item.
> +void
> +group_list_set_info(group_list_t* pl, char* val) {
> +  int n = 0;
> +
> +#ifdef MP_DEBUG
> +  assert(pl != NULL);
> +  assert(val != NULL);
> +#endif
> +
> +  strcpy(pl->info.name, val);

Are you sure this does not need a strncpy/strlcpy?

> +}
> +
> +/// Add a config paramter to an item.
> +char *
> +group_list_get_info(group_list_t* pl) {
> +
> +  return pl->info.name;
> +}
> +
> +/// Get item by name.
> +group_list_t *
> +group_list_get_by_name(group_list_t * start_group, char * name) {
> +
> +  while(start_group) {
> +    if(!strcmp(name, start_group->info.name)) {
> +      break;
> +    }
> +    start_group = start_group->next;
> +  }
> +  return start_group;
> +}
> +
> +
> Index: grouplist.h
> ===================================================================
> --- grouplist.h	(revision 0)
> +++ grouplist.h	(revision 0)
> @@ -0,0 +1,93 @@
> +#ifndef MPLAYER_GROUPLIST_H
> +#define MPLAYER_GROUPLIST_H
> +
> +/// \file
> +/// \ingroup Grouplist
> +
> +#define CAN_SEEK "canSeek"
> +#define CAN_SKIP_FORWARD "canSkipForward"
> +#define CAN_SKIP_BACK "canSkipBack"
> +
> +/// \defgroup Grouplist
> +///@{
> +typedef struct param_list param_list_t;
> +typedef struct param_list_iter param_list_iter_t;
> +typedef struct param_list_param param_list_param_t;
> +
> +typedef struct group_list group_list_t;
> +typedef struct group_list_info group_list_info_t;

Please use struct foo instead of typedef when using structures. Use
typedef for aliases like typedef uint8_t u8. Also, _t is reserved to
POSIX.

> +///@}
> +
> +struct param_list_param {
> +  char* name;
> +  char* value;
> +};
> +

When restyling the file, don't forget to char *s instead of char* s.

> +struct group_list_info {
> +  char name[256];
> +};
> +
> +/// params item
> +struct param_list {
> +  param_list_t* next;
> +  param_list_t* prev;
> +  param_list_param_t* params;
> +};
> +
> +struct group_list {
> +  group_list_t* next;
> +  group_list_t* prev;
> +  param_list_t* param_ref;
> +  group_list_info_t info;
> +};
> +
> +/// Create a new empty param item.
> +param_list_t*
> +param_list_new(void);
> +
> +/// Free a playtree items.
> +/** \param pt Item to free.
> + */
> +void
> +param_list_free(param_list_t* pt);
> +
> +/// insert an item after its siblings.
> +void
> +param_list_insert_entry(param_list_t* pl, param_list_t* entry);
> +
> +/// Add a  parameter to an item.
> +void
> +param_list_set_param(param_list_t* pl, char* name, char* val);
> +
> +/// Get parameter from item.
> +char * 
> +param_list_get_param(param_list_t* pl, char* name);
> +
> +/// Create a new empty group list item.
> +group_list_t*
> +group_list_new(void);
> +
> +/// Free a group list  items.
> +/** \param pt Item to free.
> + */
> +void
> +group_list_free(group_list_t* pt);
> +
> +/// Insert an item after its siblings.
> +void
> +group_list_insert_entry(group_list_t* pl, group_list_t* entry);
> +
> +/// Add a name to an item.
> +void
> +group_list_set_info(group_list_t* pl, char* val);
> +
> +/// Get name from item.
> +char *
> +group_list_get_info(group_list_t* pl);
> +
> +/// Get item by name.
> +group_list_t *
> +group_list_get_by_name(group_list_t * start_group, char * name);
> +
> +
> +#endif
> Index: playtreeparser.c
> ===================================================================
> --- playtreeparser.c	(revision 32825)
> +++ playtreeparser.c	(working copy)
> @@ -33,6 +33,7 @@
>  #include <limits.h>
>  #include "asxparser.h"
>  #include "m_config.h"
> +#include "grouplist.h"
>  #include "playtree.h"
>  #include "playtreeparser.h"
>  #include "stream/stream.h"
> @@ -464,14 +465,182 @@
>    return entry;
>  }
>  
> +static char *
> +replace_str(char *str, char* out)
> +{
> +  static char *spec[] = {"&amp;", "&quot;", "&lt;", "&gt;", "&nbsp;",
> +                        "&iexcl;", "&cent;", "&pound;", "&curren;", "&yen;",
> +                        "&brvbar;", "&sect;", "&uml;", "&copy;", "&ordf;", 
> +                        "&laquo;", "&not;", "&shy;", "&reg;", "&macr;" ,
> +                        "&deg;", "&plusmn;", "&sup2;", "&sup3;", "&acute;",
> +                        "&micro;", "&para;", "&middot;", "&cedil;", "&sup1;",
> +                        "&ordm;", "&raquo;", "&frac14;", "&frac12;", "&frac34;",
> +                        "&iquest;","&Agrave;", "&Aacute;", "&Acirc;", "&Atilde;",
> +                        "&Auml;", "&Aring;", "&AElig;", "&Ccedil;", "&Egrave;",
> +                        "&Eacute;", "&Ecirc;", "&Euml;", "&Igrave;", "&Iacute;",
> +                        "&Icirc;", "&Iuml;", "&ETH;", "&Ntilde;", "&Ograve;",
> +                        "&Oacute;", "&Ocirc;", "&Otilde;", "&Ouml;", "&times;",
> +                        "&Oslash;", "&Ugrave;" , "&Uacute;", "&Ucirc;",
> +                        "&Uuml;", "&Yacute;", "&THORN;", "&szlig;", "&agrave;",
> +                        "&aacute;", "&acirc;", "&atilde;","&auml;", "&aring;",
> +                        "&aelig;", "&ccedil;", "&egrave;", "&eacute;", "&ecirc;", 
> +                        "&euml;", "&igrave;", "&iacute;", "&iacute;", "&iuml;", 
> +                        "&eth;", "&ntilde;", "&ograve;", "&oacute;", "&ocirc;",
> +                        "&otilde;", "&ouml;", "&divide;", "&oslash;",
> +                        "&ugrave;", "&uacute;", "&ucirc;", "&uuml;", "&yacute;",
> +                        "&thorn;", "&yuml;", NULL};
> +  char orig[] = {38, 34, 60, 62, 160, 161, 162, 163, 164, 165, 166, 167,
> +                 168, 169, 170, 171, 172, 173, 174, 175,176, 177, 178,
> +                179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
> +                190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200,
> +                201, 202, 203, 204, 205, 206, 207,208, 209, 210, 211,
> +                212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 221,   
> +                222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 
> +                233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 
> +                244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 
> +                255, NULL};
> +

Maybe you can do something like:

const char * const t[] = {
    [38] = "&amp;",
    [34] = "&quot;",
    ...
}

> +  char temp_dst[512];
> +  char temp_src[512];
> +  char *start, *end;
> +  int i, len;
> +
> +  strcpy(temp_src, str);

strdup? Or the spec says it's 512 max? Use strncpy/strlcpy in that case.

> +  i = 0;
> +  while(spec[i]) {
> +

for (i = 0; ...

> +    temp_dst[0] = '\0';
> +    start = temp_src;
> +    end = strstr(temp_src, spec[i]);
> +
> +    while(end) {
> +
> +      len = strlen(temp_dst);
> +      len += end-start;
> +      strncat(temp_dst, start, end-start);
> +
> +      temp_dst[len] = '\0';
> +
> +      strcat(temp_dst, "_");
> +      temp_dst[len] = orig[i];
> +      start = end + strlen(spec[i]);
> +
> +      end = strstr(start, spec[i]);
> +    }
> +    end = temp_src + strlen(temp_src);
> +    len = strlen(temp_dst);
> +    len += end-start;
> +
> +    strncat(temp_dst, start, end - start);
> +    temp_dst[len] = '\0';
> +
> +    strcpy(temp_src, temp_dst);
> +    i++;
> +  }
> +  strcpy(out, temp_dst);
> +
> +  return out;
> +}

This whole code can certainly be simplified with a snprintf

> +
> +
> +static int
> +get_smil_tag(const char *line, const char *tag, char** pos, char *dst) {
> +  char *s_start, *s_end;
> +  const int len = strlen(tag);
> +
> +  *pos = strstr(*pos,tag);   // Is source present on this line
> +   char * cur_pos = *pos;
> +
> +  if (cur_pos != NULL) {
> +    if (cur_pos[len] != '"' && cur_pos[len] != '\'') {
> +       mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Unknown delimiter %c in source line %s\n", cur_pos[len], line);
> +       return -1;
> +    }
> +    s_start=(cur_pos)+len+1;
> +
> +    s_end=strchr(s_start,cur_pos[len]);
> +    if (s_end == NULL) {
> +      mp_msg(MSGT_PLAYTREE,MSGL_V,"Error parsing this source line %s\n",line);
> +      return -1;
> +    }
> +    if (s_end-s_start> 511) {
> +      mp_msg(MSGT_PLAYTREE,MSGL_V,"Cannot store such a large source %s\n",line);
> +      return -1;
> +    }
> +    strncpy(dst,s_start,s_end-s_start);
> +    dst[(s_end-s_start)]='\0'; // Null terminate
> +    *pos = s_end;
> +    return 0;
> +  }
> +  return -1;
> +}
> +
> +static param_list_t *
> +parse_param_group(const char* end_tag, play_tree_parser_t* p) {
> +
> +  char* line, name[512], value[512],*pos,*s_start,*s_end,*src_line;
> +  int entrymode=0, res=0;
> +  param_list_t *list = NULL, *entry = NULL, *last_entry = NULL;
> +
> +  entry = param_list_new();
> +
> +  while((line = play_tree_parser_get_line(p)) != NULL) {
> +    strstrip(line);
> +    if(line[0] == '\0') // Ignore empties
> +      continue;
> +
> +    pos = line;
> +    while (pos) {
> +      if (!entrymode) { // all entries filled so far
> +        while (pos=strchr(pos, '<') ) {
> +          if (strncasecmp(pos,"<param",6)==0 ) {
> +            entrymode=1;
> +            break; // Got a valid tag, exit '<' search loop
> +          }
> +          if (strncasecmp(pos,end_tag,strlen(end_tag))==0 ) {
> +            entrymode=2;
> +            break; // Got a valid tag, exit '<' search loop
> +          }
> +          pos++;
> +        }
> +      }
> +      if(entrymode == 1) {
> +        entrymode=0;
> +        res = get_smil_tag(line, "name=", &pos, name);
> +        if(res == -1) {
> +          break;
> +        }
> +
> +        res = get_smil_tag(line, "value=", &pos, value);
> +        if(res == -1) {
> +          break;
> +        }
> +        param_list_set_param(entry, name, value);
> +      }
> +
> +      if(entrymode == 2) {
> +        return entry;
> +      }
> +    }
> +  }
> +  return NULL;
> +}
> +
>  static play_tree_t*
>  parse_smil(play_tree_parser_t* p) {
> -  int entrymode=0;
> -  char* line,source[512],*pos,*s_start,*s_end,*src_line;
> +  int entrymode=0,res=0,index_tag=0;
> +  char* line,source[512],dst[512],*pos,*s_start,*s_end,*src_line;
>    play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL;
> +  group_list_t *group_start = NULL, *group_current = NULL, *group_last = NULL;
> +  group_list_t *group_noname_start = NULL, *group_noname_last = NULL;
> +  param_list_t *param_current = NULL;
> +
>    int is_rmsmil = 0;
>    unsigned int npkt, ttlpkt;
>  
> +  static char *ref_begin_tags[] = {"<video","<audio","<media","<ref",NULL};
> +  static char *ref_end_tags[] = {"</video","</audio","</media","</ref",NULL};
> +
>    mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n");
>  
>    // Check if smil
> @@ -551,47 +720,83 @@
>              line[j] = line[j+1];
>      }
>      pos = line;
> -   while (pos) {
> -    if (!entrymode) { // all entries filled so far
> -     while ((pos=strchr(pos, '<'))) {
> -      if (strncasecmp(pos,"<video",6)==0  || strncasecmp(pos,"<audio",6)==0 || strncasecmp(pos,"<media",6)==0) {
> -          entrymode=1;
> -          break; // Got a valid tag, exit '<' search loop
> -      }
> -      pos++;
> -     }
> -    }
> -    if (entrymode) { //Entry found but not yet filled
> -      pos = strstr(pos,"src=");   // Is source present on this line
> -      if (pos != NULL) {
> -        entrymode=0;
> -        if (pos[4] != '"' && pos[4] != '\'') {
> -          mp_msg(MSGT_PLAYTREE,MSGL_V,"Unknown delimiter %c in source line %s\n", pos[4], line);
> -          break;
> +    while (pos) {
> +      if (!entrymode) { // all entries filled so far
> +        while ((pos=strchr(pos, '<'))) {
> +          index_tag=0;
> +          while(ref_begin_tags[index_tag]) {
> +            if(strncasecmp(pos,ref_begin_tags[index_tag],strlen(ref_begin_tags[index_tag]))==0) {
> +               entrymode=1;
> +               break; // Got a valid tag
> +             }
> +             index_tag++;
> +          }
> +          if (strncasecmp(pos,"<paramGroup",11)==0 ) {
> +            entrymode=2;
> +          }
> +          if(entrymode) {
> +            break; // Got a valid tag, exit '<' search loop
> +          }
> +          pos++;
>          }
> -        s_start=pos+5;
> -        s_end=strchr(s_start,pos[4]);
> -        if (s_end == NULL) {
> -          mp_msg(MSGT_PLAYTREE,MSGL_V,"Error parsing this source line %s\n",line);
> -          break;
> -        }
> -        if (s_end-s_start> 511) {
> -          mp_msg(MSGT_PLAYTREE,MSGL_V,"Cannot store such a large source %s\n",line);
> -          break;
> -        }
> -        strncpy(source,s_start,s_end-s_start);
> -        source[(s_end-s_start)]='\0'; // Null terminate
> -        entry = play_tree_new();
> -        play_tree_add_file(entry,source);
> -        if(!list)  //Insert new entry
> -          list = entry;
> -        else
> -          play_tree_append_entry(last_entry,entry);
> -        last_entry = entry;
> -        pos = s_end;
>        }
> +      ///video & audio
> +      if (entrymode == 1) { //Entry found but not yet filled
> +          res = get_smil_tag(line, "src=", &pos, source);
> +          replace_str(source, dst);
> +          if(res == -1) {
> +            break;
> +          }
> + 
> +          entrymode = 0;
> +          entry = play_tree_new();
> +          play_tree_add_file(entry,dst);
> +          if(!list)  //Insert new entry
> +            list = entry;
> +          else
> +            play_tree_append_entry(last_entry,entry);
> +
> +          last_entry = entry;
> +
> +          res = get_smil_tag(line, "paramGroup=", &pos, source);
> +          if(res == -1) {
> +            break;
> +          }
> +          strcpy(entry->info.paramGroup, source);
> +          res = get_smil_tag(line, "/>", &pos, source);
> +          if(res == -1) {
> +              group_current = group_list_new();
> +              if(!group_noname_start)  //Insert new entry
> +                group_noname_start = group_current;
> +              else
> +                group_list_insert_entry(group_noname_last, group_current);
> +              group_noname_last = group_current;
> +
> +              param_current = parse_param_group(ref_end_tags[index_tag],p);
> +              group_current->param_ref = param_current;
> +          }
> +
> +      }/// end video & audio src
> +
> +      ///group param
> +      if (entrymode == 2) { //Entry found but not yet filled
> +          int res = get_smil_tag(line, "xml:id=", &pos, source);
> +          if(res == -1) {
> +            break;
> +          }
> +          entrymode = 0;
> +          group_current = group_list_new();
> +          group_list_set_info(group_current,source);
> +          if(!group_start)  //Insert new entry
> +            group_start = group_current;
> +          else
> +            group_list_insert_entry(group_last, group_current);
> +  
> +          group_last = group_current;
> +          param_current = parse_param_group("</paramGroup",p);
> +          group_current->param_ref = param_current;
> +      }/// end paramGroup
>      }
> -   }
>    } while((src_line = play_tree_parser_get_line(p)) != NULL);
>  
>    free(line);
> @@ -600,6 +805,9 @@
>  
>    entry = play_tree_new();
>    play_tree_set_child(entry,list);
> +  entry->info.groups = group_start;
> +  entry->info.noname_groups = group_noname_start;
> +
>    return entry;
>  }
>  
> Index: command.c
> ===================================================================
> --- command.c	(revision 32825)
> +++ command.c	(working copy)
> @@ -39,6 +39,7 @@
>  #include "libvo/video_out.h"
>  #include "sub/font_load.h"
>  #include "playtree.h"
> +#include "grouplist.h"
>  #include "libao2/audio_out.h"
>  #include "mpcommon.h"
>  #include "mixer.h"
> @@ -2601,6 +2602,31 @@
>      }
>  }
>  
> +static int approve_command(MPContext *mpctx, int cmd)
> +{
> +    char *param_group = NULL;
> +    group_list_t * start_group,*noname_group;
> +    char * value =  NULL;
> +    param_group = mpctx->playtree_iter->tree->info.paramGroup;
> +    start_group = mpctx->playtree_iter->tree->parent->info.groups;
> +    start_group = group_list_get_by_name(start_group, param_group);
> +    noname_group = mpctx->playtree_iter->tree->parent->info.noname_groups;
> +
> +    if(noname_group) {
> +        value = param_list_get_param(noname_group->param_ref, cmd);
> +    }
> +
> +    if(start_group && !value) {
> +        value = param_list_get_param(start_group->param_ref, cmd);
> +    }
> +
> +    if(value) {
> +        if(!strcasecmp(value,"false"))
> +            return -1;
> +    }                        

Trailing whitespaces on this line.

> +    return 0;
> +}
> +
>  int run_command(MPContext *mpctx, mp_cmd_t *cmd)
>  {
>      sh_audio_t * const sh_audio = mpctx->sh_audio;
> @@ -2611,6 +2637,11 @@
>          case MP_CMD_SEEK:{
>                  float v;
>                  int abs;
> +
> +                int approve = approve_command(mpctx, CAN_SEEK);
> +                if(approve == -1)
> +                    return -1; 
> +
>                  if (sh_video)
>                      mpctx->osd_show_percentage = sh_video->fps;
>                  v = cmd->args[0].v.f;
> @@ -2783,6 +2814,14 @@
>                  int n = cmd->args[0].v.i == 0 ? 1 : cmd->args[0].v.i;
>                  int force = cmd->args[1].v.i;
>  
> +                int approve = approve_command(mpctx, CAN_SKIP_FORWARD);
> +                if(approve == -1 && n > 0)
> +                    return -1; 
> +
> +                approve = approve_command(mpctx, CAN_SKIP_BACK);
> +                if(approve == -1 && n < 0)
> +                    return -1; 
> +
>  #ifdef CONFIG_GUI
>                  if (use_gui) {
>                      int i = 0;
> Index: playtree.c
> ===================================================================
> --- playtree.c	(revision 32825)
> +++ playtree.c	(working copy)
> @@ -31,6 +31,7 @@
>  #include "m_config.h"
>  #include "playtree.h"
>  #include "mp_msg.h"
> +#include "grouplist.h"
>  
>  static int
>  play_tree_is_valid(play_tree_t* pt);
> @@ -43,6 +44,8 @@
>      return NULL;
>    }
>    r->entry_type = PLAY_TREE_ENTRY_NODE;
> +  r->info.groups = NULL;
> +  r->info.noname_groups = NULL;
>    return r;
>  }
>  
> @@ -68,6 +71,7 @@
>    for(iter = pt->child ; iter != NULL ; iter = iter->next)
>      iter->parent = NULL;
>  
> +
>    //free(pt->params);
>    if(pt->files) {
>      int i;
> Index: playtree.h
> ===================================================================
> --- playtree.h	(revision 32825)
> +++ playtree.h	(working copy)
> @@ -24,6 +24,7 @@
>  
>  struct stream;
>  struct m_config;
> +struct group_list_t;
>  
>  /// \defgroup PlaytreeIterReturn Playtree iterator return code
>  /// \ingroup PlaytreeIter
> @@ -70,7 +71,6 @@
>  typedef struct play_tree_param play_tree_param_t;
>  
>  
> -#if 0
>  typedef struct play_tree_info play_tree_info_t;
>  // TODO : a attrib,val pair system and not something hardcoded
>  struct play_tree_info {
> @@ -78,9 +78,11 @@
>    char* author;
>    char* copyright;
>    char* abstract;
> +  char  paramGroup[256];
> +  struct group_list_t * groups;
> +  struct group_list_t * noname_groups;
>    // Some more ??
> -}
> -#endif
> +};
>  
>  struct play_tree_param {
>    char* name;
> @@ -95,7 +97,7 @@
>    play_tree_t* next;
>    play_tree_t* prev;
>  
> -  //play_tree_info_t info;
> +  play_tree_info_t info;
>    play_tree_param_t* params;
>    int loop;
>    char** files;

I didn't test it, but I wonder if you could split it so it's easier to see
functionnal changes?

-- 
Clément B.


More information about the MPlayer-dev-eng mailing list