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

Clément Bœsch ubitux at gmail.com
Wed Feb 2 19:26:57 CET 2011


On Wed, Feb 02, 2011 at 12:43:46PM +0600, Andrei Katsuk wrote:
> The new patch is attached to this email.

Ok, I'll annoy you just a bit on various stuff and nitpicks, and I'll let
other developers take the relay.

> Index: Makefile
> ===================================================================
> --- Makefile	(revision 32825)
> +++ Makefile	(working copy)
> @@ -297,6 +297,7 @@
>                cpudetect.c \
>                edl.c \
>                fmt-conversion.c \
> +              grouplist.c \
>                m_config.c \
>                m_option.c \
>                m_struct.c \
> Index: grouplist.c
> ===================================================================
> --- grouplist.c	(revision 0)
> +++ grouplist.c	(revision 0)
> @@ -0,0 +1,219 @@
> +/*
> + * This file is part of MPlayer.
> + *
> + * MPlayer 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.
> + *
> + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include "config.h"

Place this after system include, and put a new line between them and
mplayer ones.

> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <assert.h>
> +#include "m_config.h"
> +#include "mp_msg.h"
> +#include "grouplist.h"
> +
> +/**
> + * @brief Create a new empty paramlist item.
> + */
> +struct param_list *param_list_new(void) 
                                          ^
                                        whitespace here and in a few
                                        other places. Try to configure
                                        correctly your editor so you can
                                        see them.
> +{
> +    struct param_list *r = calloc(1, sizeof(*r));
> +    if (r == NULL) {
> +        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",(int)sizeof(*r));
> +        return NULL;
> +    }
> +    return r;
> +}
> +
> +/**
> + * @brief Free a param_list item.
> + * @param pt Item to free.
> + */
> +void param_list_free(struct param_list *pt) 
> +{
> +    struct param_list *r;
> +    while (pt) {
> +       r = pt;
> +       pt = pt->next;
> +       free(r->params->name);
> +       free(r->params->value);
> +       free(r);
> +    }

Weird indent, looks like 3 spaces instead of 4. Yes I know I'm annoying.

> +}
> +
> +/**
> + * @brief Append an item after its siblings.
> + * @param pl param list
> + * @param entry Item to append

Do not forget the period (on other doctypes too).

> + */
> +void param_list_insert_entry(struct param_list *pl, struct param_list *entry) 
> +{
> +    struct param_list *iter;
> +
> +    assert(pl != NULL);
> +    assert(entry != NULL);
> +
> +    if (pl == entry)
> +        return;
> +
> +    for (iter = pl; iter->next != NULL; iter = iter->next)
> +    /* NOTHING */;
> +
> +    entry->prev = iter;
> +    entry->next = NULL;
> +    iter->next = entry;
> +}
> +
> +/**
> + * @brief Add a config parameter to an item.
> + * @param pl parameter list
> + * @param name parameter name 
> + * @param val parameter val
> + */ 
> +void param_list_set_param(struct param_list *pl, char *name, char *val) 
> +{
> +    int n = 0;
> +    struct param_list_param *params;
> +
> +    assert(pl != NULL);
> +    assert(name != NULL);
> +
> +    if (pl->params)
> +        for (; pl->params[n].name != NULL; n++ );
> +
> +    params= realloc(pl->params, (n + 2) * sizeof(*pl->params));

params = ..

> +    if (params == NULL) {
> +        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't realloc params (%d bytes of memory)\n",(n+2)*(int)sizeof(*pl->params));

Missing spaces (and in other mp_msg calls too).

> +        return;
> +    }
> +    pl->params = params;
> +    pl->params[n].name = strdup(name);
> +    pl->params[n].value = val != NULL ? strdup(val) : NULL;
> +    memset(&pl->params[n+1], 0, sizeof(*pl->params));
> +}
> +
> +/**
> + * @brief Get parameter value by name.
> + * @param pl parameter list
> + * @param name parameter name 
> + */ 
> +char *param_list_get_param(struct param_list *pl, char *name) 
> +{
> +    int n = 0;
> +    char * value = NULL;
> +

No space after '*'

> +    assert(pl != NULL);
> +    assert(name != 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;
> +}
> +
> +/**
> + * @brief Create a new empty grouplist item.
> + */ 
> +struct group_list *group_list_new(void) 
> +{
> +    struct group_list *r = calloc(1, sizeof(*r));
> +    if (r == NULL) {
> +        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",(int)sizeof(*r));
> +        return NULL;
> +    }
> +    return r;
> +}
> +
> +/**
> + * @brief  Free a grouplist item.
> + * @param pt Item to free.
> + */
> +void group_list_free(struct group_list *pt) 
> +{
> +    struct group_list *r;
> +    while (pt) {
> +        r = pt;
> +        pt = pt->next;
> +        param_list_free(r->param_ref);
> +        free(r);
> +    }
> +}
> +
> +/**
> + * @brief  Insert an item after its siblings.
> + * @param pl parameter list
> + * @param enry Item to insert

entry

> + */
> +void group_list_insert_entry(struct group_list *pl, struct group_list *entry) 
> +{
> +    struct param_list *iter;
> +
> +    assert(pl != NULL);
> +    assert(entry != NULL);
> +
> +    if (pl == entry) 
> +        return;
> +
> +    for (iter = pl; iter->next != NULL; iter = iter->next)
> +        /* NOTHING */;
> +
> +    entry->prev = iter;
> +    entry->next = NULL;
> +    iter->next = entry;
> +}
> +
> +/**
> + * @brief  Add a config paramter to an item.

parameter

> + * @param pl group list

Group

> + * @param enry Item to insert
> + */
> +void group_list_set_info(struct group_list *pl, char *val) 
> +{
> +    assert(pl != NULL);
> +    assert(val != NULL);
> +
> +    av_strlcpy(pl->info.name, val, sizeof(pl->info.name));
> +}
> +
> +/**
> + * @brief  Get group list name.
> + */
> +char *group_list_get_info(struct group_list *pl) 
> +{
> +    return pl->info.name;
> +}
> +
> +/**
> + * @brief  Get group list item by name.
> + * @param start_group group list
> + * @param name group name
> + */
> +struct group_list *group_list_get_by_name(struct group_list *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,127 @@
> +/*
> + * This file is part of MPlayer.
> + *
> + * MPlayer 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.
> + *
> + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#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
> + * @{
> + */
> +struct param_list;
> +struct param_list_iter;
> +struct param_list_param;
> +
> +struct group_list;
> +struct group_list_info;
> +/** @}
> + */
> +
> +struct param_list_param {
> +    char *name;
> +    char *value;
> +};
> +
> +struct group_list_info {
> +    char name[256];
> +};
> +
> +/**
> + * @brief params item
> + */
> +struct param_list {
> +    struct param_list *next;
> +    struct param_list *prev;
> +    struct param_list_param *params;
> +};
> +
> +struct group_list {
> +    struct group_list *next;
> +    struct group_list *prev;
> +    struct param_list *param_ref;
> +    struct group_list_info info;
> +};
> +
> +/**
> + * @brief Create a new empty param item.
> + */

Are you sure those doxycomments are useful since already in the source?

> +struct param_list *param_list_new(void);
> +
> +/**
> + * @brief Free a paramlist items.
> + * @param pt Item to free.
> + */
> +void param_list_free(struct param_list *pt);
> +
> +/**
> + * @brief insert an item after its siblings.
> + */
> +void param_list_insert_entry(struct param_list *pl, struct param_list *entry);
> +
> +/**
> + * @brief  Add a  parameter to an item.
> + */
> +void param_list_set_param(struct param_list *pl, char *name, char *val);
> +
> +/**
> + * @brief  Get parameter from item.
> + */
> +char *param_list_get_param(struct param_list *pl, char *name);
> +
> +/**
> + * @brief  Create a new empty group list item.
> + */
> +struct group_list *group_list_new(void);
> +
> +/**
> + * @brief Free a group list  items.
> + * @param pt Item to free.
> + */
> +void group_list_free(struct group_list *pt);
> +
> +/**
> + * @brief Insert an item after its siblings.
> + */
> +void group_list_insert_entry(struct group_list *pl, struct group_list *entry);
> +
> +/**
> + * @brief Add a name to an item.
> + */
> +void group_list_set_info(struct group_list *pl, char *val);
> +
> +/**
> + * @brief Get name from item.
> + */
> +char *group_list_get_info(struct group_list *pl);
> +
> +/**
> + * @brief Get item by name.
> + */
> +struct group_list *group_list_get_by_name(struct group_list *start_group, char *name);
> +
> +#endif /* MPLAYER_GROUPLIST_H */
> +
> 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"
> @@ -44,6 +45,8 @@
>  
>  #define WHITES " \n\r\t"
>  
> +#define _COUNTOF(a)	(sizeof(a) / sizeof((a)[0]))
> +

Use FF_ARRAY_ELEMS

>  static void
>  strstrip(char* str) {
>    char* i;
> @@ -464,14 +467,266 @@
>    return entry;
>  }
>  
> +struct unescape_elem {
> +  const char *text;
> +  const char repl;
> +};
> +
> +static int
> +unescape_elem_cmp(const void* a, const void* b)
> +{
> +  const struct unescape_elem *ea = (const struct unescape_elem *) a;
> +  const struct unescape_elem *eb = (const struct unescape_elem *) b;

Is the cast needed?

> +
> +  return strcmp(ea->text, eb->text);
> +}
> +
> +static void
> +unscape(char* p)
> +{
> +  static struct unescape_elem tab[] = {
> +    {"quot",34},
> +    {"amp",38},
> +    {"lt",60},
> +    {"gt",62},
> +    {"ndash",150},
> +    {"mdash",151},
> +    {"nbsp",160},
> +    {"iexcl",161},
> +    {"cent",162},
> +    {"pound",163},
> +    {"curren",164},
> +    {"yen",165},
> +    {"brvbar",166},
> +    {"sect",167},
> +    {"uml",168},
> +    {"copy",169},
> +    {"ordf",170},
> +    {"laquo",171},
> +    {"not",172},
> +    {"shy",173},
> +    {"reg",174},
> +    {"macr",175},
> +    {"deg",176},
> +    {"plusmn",177},
> +    {"sup2",178},
> +    {"sup3",179},
> +    {"acute",180},
> +    {"micro",181},
> +    {"para",182},
> +    {"middot",183},
> +    {"cedil",184},
> +    {"sup1",185},
> +    {"ordm",186},
> +    {"raquo",187},
> +    {"frac14",188},
> +    {"frac12",189},
> +    {"frac34",190},
> +    {"iquest",191},
> +    {"Agrave",192},
> +    {"Aacute",193},
> +    {"Acirc",194},
> +    {"Atilde",195},
> +    {"Auml",196},
> +    {"Aring",197},
> +    {"AElig",198},
> +    {"Ccedil",199},
> +    {"Egrave",200},
> +    {"Eacute",201},
> +    {"Ecirc",202},
> +    {"Euml",203},
> +    {"Igrave",204},
> +    {"Iacute",205},
> +    {"Icirc",206},
> +    {"Iuml",207},
> +    {"ETH",208},
> +    {"Ntilde",209},
> +    {"Ograve",210},
> +    {"Oacute",211},
> +    {"Ocirc",212},
> +    {"Otilde",213},
> +    {"Ouml",214},
> +    {"times",215},
> +    {"Oslash",216},
> +    {"Ugrave",217},
> +    {"Uacute",218},
> +    {"Ucirc",219},
> +    {"Uuml",220},
> +    {"Yacute",221},
> +    {"THORN",222},
> +    {"szlig",223},
> +    {"agrave",224},
> +    {"aacute",225},
> +    {"acirc",226},
> +    {"atilde",227},
> +    {"auml",228},
> +    {"aring",229},
> +    {"aelig",230},
> +    {"ccedil",231},
> +    {"egrave",232},
> +    {"eacute",233},
> +    {"ecirc",234},
> +    {"euml",235},
> +    {"igrave",236},
> +    {"iacute",237},
> +    {"iacute",238},
> +    {"iuml",239},
> +    {"eth",240},
> +    {"ntilde",241},
> +    {"ograve",242},
> +    {"oacute",243},
> +    {"ocirc",244},
> +    {"otilde",245},
> +    {"ouml",246},
> +    {"divide",247},
> +    {"oslash",248},
> +    {"ugrave",249},
> +    {"uacute",250},
> +    {"ucirc",251},
> +    {"uuml",252},
> +    {"yacute",253},
> +    {"thorn",254},
> +    {"yuml",255}
> +  };
> +
> +  char *start, *end;
> +  struct unescape_elem *e;
> +  static int initialized = 0;

static are always filled with zeros.

> +  char *dst = p;
> +
> +  if (!initialized) {
> +    qsort(tab, _COUNTOF(tab), sizeof(tab[0]), unescape_elem_cmp);
> +    initialized = 1;
> +  }
> +
> +  for (;;) {
> +    /* look for starting '&' */
> +    while (*p != '\0' && *p != '&') {
> +      *dst++ = *p++;
> +    }
> +    if (*p == '\0') {
> +      *dst++ = '\0';
> +      break;
> +    }
> +
> +    start = p + 1;
> +    if ((end = strchr(start, ';')) == NULL) {
> +      /* broken XML (no closing ';'), skip to next character */
> +      *dst++ = *p++;
> +      continue;
> +    }
> +
> +    *end = '\0';
> +    e = bsearch(&start, tab, _COUNTOF(tab), sizeof(tab[0]), unescape_elem_cmp);
> +    if (e == NULL) {
> +      /* element not found, restore the input and skip to next character */
> +      *end = ';';
> +      *dst++ = *p++;
> +      continue;
> +    }
> +    *dst++ = e->repl;
> +    p = end + 1;
> +  }
> +}
> +
> +static int
> +get_smil_tag(const char* line, const char* tag, char** pos, char* dst) {
> +  char *s_start, *s_end, *cur_pos;
> +  const int len = strlen(tag);
> +
> +  *pos = strstr(*pos, tag);   // Is source present on this line
> +  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;

Why do you use brackets here?

> +
> +    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'; // NUL-terminate

av_strlcpy? Also, comment is useless.

> +    *pos = s_end;
> +    return 0;
> +  }
> +  return -1;
> +}
> +
> +static struct param_list*
> +parse_param_group(const char* end_tag, play_tree_parser_t* p) {
> +
> +  char *line, name[512], value[512], *pos;
> +  int entrymode = 0,res = 0;
> +  struct param_list *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],*pos,*src_line;
>    play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL;
> +  struct group_list *group_start = NULL, *group_current = NULL, *group_last = NULL;
> +  struct group_list *group_noname_start = NULL, *group_noname_last = NULL;
> +  struct param_list *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 +806,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);
> +          if (res == -1) {
> +            break;
> +          }
> +          unscape(source);
> + 
> +          entrymode = 0;
> +          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;
> +
> +          res = get_smil_tag(line, "paramGroup=", &pos, source);
> +          if (res == -1) {
> +            break;
> +          }
> +          av_strlcpy(entry->info.paramGroup, source, sizeof(entry->info.paramGroup));
> +          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
>      }
> -   }

Try not to reindent to whole block in the first place, even if it breaks
the indent when adding/removing a block around. We/You will fix it after
the patch gets applied. It helps seeing the functionnal changes.

>    } while((src_line = play_tree_parser_get_line(p)) != NULL);
>  
>    free(line);
> @@ -600,6 +891,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,29 @@
>      }
>  }
>  
> +static int approve_command(MPContext *mpctx, int cmd)
> +{
> +    char *param_group = NULL;
> +    struct group_list *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;

Why do you do init in two times?

> +
> +    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;
> +    }
> +    return 0;
> +}
> +
>  int run_command(MPContext *mpctx, mp_cmd_t *cmd)
>  {
>      sh_audio_t * const sh_audio = mpctx->sh_audio;
> @@ -2611,6 +2635,11 @@
>          case MP_CMD_SEEK:{
>                  float v;
>                  int abs;
> +
> +                int approve = approve_command(mpctx, CAN_SEEK);
> +                if(approve == -1)
> +                    return -1; 
> +

Why do you create a temporary variable here?

>                  if (sh_video)
>                      mpctx->osd_show_percentage = sh_video->fps;
>                  v = cmd->args[0].v.f;
> @@ -2783,6 +2812,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; 
> +

Ditto

>  #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;
>  }
>  
> Index: playtree.h
> ===================================================================
> --- playtree.h	(revision 32825)
> +++ playtree.h	(working copy)
> @@ -70,7 +70,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 +77,11 @@
>    char* author;
>    char* copyright;
>    char* abstract;
> +  char  paramGroup[256];
> +  struct group_list* groups;
> +  struct group_list* noname_groups;
>    // Some more ??
> -}
> -#endif
> +};
>  
>  struct play_tree_param {
>    char* name;
> @@ -95,7 +96,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;

-- 
Clément B.


More information about the MPlayer-dev-eng mailing list