Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 7 Dec 2011 23:23:37 +0000 (00:23 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 7 Dec 2011 23:23:37 +0000 (00:23 +0100)
* qatar/master:
  drawtext: remove typo
  pcm-mpeg: implement new audio decoding api
  w32thread: port fixes to pthread_cond_broadcast() from x264.
  doc: add editor configuration section with Vim and Emacs settings
  dxva2.h: include d3d9.h to define LPDIRECT3DSURFACE9
  avformat/utils: Drop unused goto label.
  doxygen: Replace '\' by '@' in Doxygen markup tags.
  cosmetics: drop some completely pointless parentheses
  cljr: simplify CLJRContext
  drawtext: introduce rand(min, max)
  drawtext: introduce explicit draw/hide variable
  rtmp: Use nb_invokes for all invoke commands

Conflicts:
libavcodec/mpegvideo.c
libavfilter/vf_drawtext.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
17 files changed:
1  2 
doc/developer.texi
libavcodec/atrac3.c
libavcodec/cljr.c
libavcodec/dxva2.h
libavcodec/mpegvideo.c
libavcodec/mpegvideo_common.h
libavcodec/msrledec.c
libavcodec/pcm-mpeg.c
libavcodec/ppc/h264_altivec.c
libavcodec/ppc/util_altivec.h
libavcodec/tableprint.h
libavcodec/vc1dec.c
libavdevice/libdc1394.c
libavfilter/vf_drawtext.c
libavformat/rtmpproto.c
libavformat/utils.c
libavutil/lzo.h

Simple merge
Simple merge
Simple merge
Simple merge
@@@ -837,19 -880,27 +837,23 @@@ av_cold int MPV_common_init(MpegEncCont
          /* init macroblock skip table */
          FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail);
          // Note the + 1 is for  a quicker mpeg4 slice_end detection
 -        FF_ALLOCZ_OR_GOTO(s->avctx, s->prev_pict_types,
 -                          PREV_PICT_TYPES_BUFFER_SIZE, fail);
 +        FF_ALLOCZ_OR_GOTO(s->avctx, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE, fail);
  
          s->parse_context.state = -1;
-         if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)) {
-             s->visualization_buffer[0] = av_malloc((s->mb_width * 16 + 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-             s->visualization_buffer[1] = av_malloc((s->mb_width * 16 + 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-             s->visualization_buffer[2] = av_malloc((s->mb_width * 16 + 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
+         if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
+             s->avctx->debug_mv) {
+             s->visualization_buffer[0] = av_malloc((s->mb_width * 16 +
+                         2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
+             s->visualization_buffer[1] = av_malloc((s->mb_width * 16 +
+                         2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
+             s->visualization_buffer[2] = av_malloc((s->mb_width * 16 +
+                         2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
          }
 -    }
  
 -    s->context_initialized = 1;
 -    s->thread_context[0]   = s;
 +        s->context_initialized = 1;
 +        s->thread_context[0]   = s;
  
 -    if (s->width && s->height) {
 -        if (s->encoding || (HAVE_THREADS &&
 -                            s->avctx->active_thread_type&FF_THREAD_SLICE)) {
 +        if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) {
              for (i = 1; i < threads; i++) {
                  s->thread_context[i] = av_malloc(sizeof(MpegEncContext));
                  memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -33,6 -33,8 +33,7 @@@
  #include "libavutil/file.h"
  #include "libavutil/eval.h"
  #include "libavutil/opt.h"
 -#include "libavutil/mathematics.h"
+ #include "libavutil/random_seed.h"
  #include "libavutil/parseutils.h"
  #include "libavutil/pixdesc.h"
  #include "libavutil/tree.h"
@@@ -67,20 -64,30 +69,36 @@@ static const char * const var_names[] 
      NULL
  };
  
+ static const char *fun2_names[] = {
+     "rand",
+ };
+ static double drand(void *opaque, double min, double max)
+ {
+     return min + (max-min) / UINT_MAX * av_lfg_get(opaque);
+ }
+ typedef double (*eval_func2)(void *, double a, double b);
+ static const eval_func2 fun2[] = {
+     drand,
+     NULL
+ };
  enum var_name {
 -    VAR_E,
 -    VAR_PHI,
 -    VAR_PI,
 -    VAR_MAIN_W, VAR_MW,
 -    VAR_MAIN_H, VAR_MH,
 -    VAR_TEXT_W, VAR_TW,
 -    VAR_TEXT_H, VAR_TH,
 +    VAR_MAIN_W, VAR_w, VAR_W,
 +    VAR_MAIN_H, VAR_h, VAR_H,
 +    VAR_TW, VAR_TEXT_W,
 +    VAR_TH, VAR_TEXT_H,
 +    VAR_MAX_GLYPH_W,
 +    VAR_MAX_GLYPH_H,
 +    VAR_MAX_GLYPH_A, VAR_ASCENT,
 +    VAR_MAX_GLYPH_D, VAR_DESCENT,
 +    VAR_LINE_H, VAR_LH,
 +    VAR_SAR,
 +    VAR_DAR,
 +    VAR_HSUB,
 +    VAR_VSUB,
      VAR_X,
      VAR_Y,
      VAR_N,
@@@ -127,11 -131,13 +145,15 @@@ typedef struct 
      int pixel_step[4];              ///< distance in bytes between the component of each pixel
      uint8_t rgba_map[4];            ///< map RGBA offsets to the positions in the packed RGBA format
      uint8_t *box_line[4];           ///< line used for filling the box background
 -    char   *x_expr, *y_expr;
 +    char *x_expr;                   ///< expression for x position
 +    char *y_expr;                   ///< expression for y position
      AVExpr *x_pexpr, *y_pexpr;      ///< parsed expressions for x and y
 +    int64_t basetime;               ///< base pts time in the real world for display
      double var_values[VAR_VARS_NB];
+     char   *d_expr;
+     AVExpr *d_pexpr;
+     int draw;                       ///< set to zero to prevent drawing
+     AVLFG  prng;                    ///< random
  } DrawTextContext;
  
  #define OFFSET(x) offsetof(DrawTextContext, x)
@@@ -150,8 -156,7 +172,8 @@@ static const AVOption drawtext_options[
  {"shadowx",  "set x",                OFFSET(shadowx),            AV_OPT_TYPE_INT,    {.dbl=0},     INT_MIN,  INT_MAX  },
  {"shadowy",  "set y",                OFFSET(shadowy),            AV_OPT_TYPE_INT,    {.dbl=0},     INT_MIN,  INT_MAX  },
  {"tabsize",  "set tab size",         OFFSET(tabsize),            AV_OPT_TYPE_INT,    {.dbl=4},     0,        INT_MAX  },
 +{"basetime", "set base time",        OFFSET(basetime),           AV_OPT_TYPE_INT64,  {.dbl=AV_NOPTS_VALUE},     INT64_MIN,        INT64_MAX  },
+ {"draw",     "if false do not draw", OFFSET(d_expr),             AV_OPT_TYPE_STRING, {.str="1"},   CHAR_MIN, CHAR_MAX },
  
  /* FT_LOAD_* flags */
  {"ft_load_flags", "set font loading flags for libfreetype",   OFFSET(ft_load_flags),  AV_OPT_TYPE_FLAGS,  {.dbl=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" },
@@@ -458,41 -608,9 +480,46 @@@ static int config_input(AVFilterLink *i
          dtext->shadowcolor[3] = rgba[3];
      }
  
 -    dtext->draw = 1;
 +    dtext->var_values[VAR_w]     = dtext->var_values[VAR_W]     = dtext->var_values[VAR_MAIN_W] = inlink->w;
 +    dtext->var_values[VAR_h]     = dtext->var_values[VAR_H]     = dtext->var_values[VAR_MAIN_H] = inlink->h;
 +    dtext->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
 +    dtext->var_values[VAR_DAR]   = (double)inlink->w / inlink->h * dtext->var_values[VAR_SAR];
 +    dtext->var_values[VAR_HSUB]  = 1<<pix_desc->log2_chroma_w;
 +    dtext->var_values[VAR_VSUB]  = 1<<pix_desc->log2_chroma_h;
 +    dtext->var_values[VAR_X]     = NAN;
 +    dtext->var_values[VAR_Y]     = NAN;
 +    if (!dtext->reinit)
 +        dtext->var_values[VAR_N] = 0;
 +    dtext->var_values[VAR_T]     = NAN;
  
 -    return dtext_prepare_text(ctx);
++    av_lfg_init(&dtext->prng, av_get_random_seed());
++
 +    if ((ret = av_expr_parse(&dtext->x_pexpr, dtext->x_expr, var_names,
-                              NULL, NULL, NULL, NULL, 0, ctx)) < 0 ||
++                             NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
 +        (ret = av_expr_parse(&dtext->y_pexpr, dtext->y_expr, var_names,
-                              NULL, NULL, NULL, NULL, 0, ctx)) < 0)
++                             NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
++        (ret = av_expr_parse(&dtext->d_pexpr, dtext->d_expr, var_names,
++                             NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
++
 +        return AVERROR(EINVAL);
 +
 +    return 0;
 +}
 +
 +static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
 +{
 +    DrawTextContext *dtext = ctx->priv;
 +
 +    if (!strcmp(cmd, "reinit")) {
 +        int ret;
 +        uninit(ctx);
 +        dtext->reinit = 1;
 +        if ((ret = init(ctx, arg, NULL)) < 0)
 +            return ret;
 +        return config_input(ctx->inputs[0]);
 +    }
 +
 +    return AVERROR(ENOSYS);
  }
  
  #define GET_BITMAP_VAL(r, c)                                            \
@@@ -642,128 -753,83 +669,132 @@@ static int draw_text(AVFilterContext *c
                       int width, int height)
  {
      DrawTextContext *dtext = ctx->priv;
 -    int ret;
 +    uint32_t code = 0, prev_code = 0;
 +    int x = 0, y = 0, i = 0, ret;
 +    int max_text_line_w = 0, len;
 +    int box_w, box_h;
 +    char *text = dtext->text;
 +    uint8_t *p;
 +    int y_min = 32000, y_max = -32000;
 +    int x_min = 32000, x_max = -32000;
 +    FT_Vector delta;
 +    Glyph *glyph = NULL, *prev_glyph = NULL;
 +    Glyph dummy = { 0 };
  
 -    /* draw box */
 -    if (dtext->draw_box)
 -        drawbox(picref, dtext->x, dtext->y, dtext->w, dtext->h,
 -                dtext->box_line, dtext->pixel_step, dtext->boxcolor,
 -                dtext->hsub, dtext->vsub, dtext->is_packed_rgb,
 -                dtext->rgba_map);
 +    time_t now = time(0);
 +    struct tm ltime;
 +    uint8_t *buf = dtext->expanded_text;
 +    int buf_size = dtext->expanded_text_size;
  
 -    if (dtext->shadowx || dtext->shadowy) {
 -        if ((ret = draw_glyphs(dtext, picref, width, height,
 -                               dtext->shadowcolor_rgba,
 -                               dtext->shadowcolor,
 -                               dtext->x + dtext->shadowx,
 -                               dtext->y + dtext->shadowy)) < 0)
 -            return ret;
 +    if(dtext->basetime != AV_NOPTS_VALUE)
 +        now= picref->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
 +
 +    if (!buf) {
 +        buf_size = 2*strlen(dtext->text)+1;
 +        buf = av_malloc(buf_size);
      }
  
 -    if ((ret = draw_glyphs(dtext, picref, width, height,
 -                           dtext->fontcolor_rgba,
 -                           dtext->fontcolor,
 -                           dtext->x,
 -                           dtext->y)) < 0)
 -        return ret;
 +#if HAVE_LOCALTIME_R
 +    localtime_r(&now, &ltime);
 +#else
 +    if(strchr(dtext->text, '%'))
 +        ltime= *localtime(&now);
 +#endif
  
 -    return 0;
 -}
 +    do {
 +        *buf = 1;
 +        if (strftime(buf, buf_size, dtext->text, &ltime) != 0 || *buf == 0)
 +            break;
 +        buf_size *= 2;
 +    } while ((buf = av_realloc(buf, buf_size)));
  
 -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
 +    if (!buf)
 +        return AVERROR(ENOMEM);
 +    text = dtext->expanded_text = buf;
 +    dtext->expanded_text_size = buf_size;
 +    if ((len = strlen(text)) > dtext->nb_positions) {
 +        if (!(dtext->positions =
 +              av_realloc(dtext->positions, len*sizeof(*dtext->positions))))
 +            return AVERROR(ENOMEM);
 +        dtext->nb_positions = len;
 +    }
  
 -static inline int normalize_double(int *n, double d)
 -{
 -    int ret = 0;
 +    x = 0;
 +    y = 0;
  
 -    if (isnan(d)) {
 -        ret = AVERROR(EINVAL);
 -    } else if (d > INT_MAX || d < INT_MIN) {
 -        *n = d > INT_MAX ? INT_MAX : INT_MIN;
 -        ret = AVERROR(EINVAL);
 -    } else
 -        *n = round(d);
 +    /* load and cache glyphs */
 +    for (i = 0, p = text; *p; i++) {
 +        GET_UTF8(code, *p++, continue;);
  
 -    return ret;
 -}
 +        /* get glyph */
 +        dummy.code = code;
 +        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
 +        if (!glyph)
 +            load_glyph(ctx, &glyph, code);
  
 -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
 -{
 -    AVFilterContext *ctx = inlink->dst;
 -    DrawTextContext *dtext = ctx->priv;
 -    int fail = 0;
 +        y_min = FFMIN(glyph->bbox.yMin, y_min);
 +        y_max = FFMAX(glyph->bbox.yMax, y_max);
 +        x_min = FFMIN(glyph->bbox.xMin, x_min);
 +        x_max = FFMAX(glyph->bbox.xMax, x_max);
 +    }
 +    dtext->max_glyph_h = y_max - y_min;
 +    dtext->max_glyph_w = x_max - x_min;
 +
 +    /* compute and save position for each glyph */
 +    glyph = NULL;
 +    for (i = 0, p = text; *p; i++) {
 +        GET_UTF8(code, *p++, continue;);
 +
 +        /* skip the \n in the sequence \r\n */
 +        if (prev_code == '\r' && code == '\n')
 +            continue;
 +
 +        prev_code = code;
 +        if (is_newline(code)) {
 +            max_text_line_w = FFMAX(max_text_line_w, x);
 +            y += dtext->max_glyph_h;
 +            x = 0;
 +            continue;
 +        }
  
 -    if (dtext_prepare_text(ctx) < 0) {
 -        av_log(ctx, AV_LOG_ERROR, "Can't draw text\n");
 -        fail = 1;
 +        /* get glyph */
 +        prev_glyph = glyph;
 +        dummy.code = code;
 +        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
 +
 +        /* kerning */
 +        if (dtext->use_kerning && prev_glyph && glyph->code) {
 +            FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
 +                           ft_kerning_default, &delta);
 +            x += delta.x >> 6;
 +        }
 +
 +        /* save position */
 +        dtext->positions[i].x = x + glyph->bitmap_left;
 +        dtext->positions[i].y = y - glyph->bitmap_top + y_max;
 +        if (code == '\t') x  = (x / dtext->tabsize + 1)*dtext->tabsize;
 +        else              x += glyph->advance;
      }
  
 -    dtext->var_values[VAR_T] = inpicref->pts == AV_NOPTS_VALUE ?
 -        NAN : inpicref->pts * av_q2d(inlink->time_base);
 -    dtext->var_values[VAR_X] =
 -        av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
 -    dtext->var_values[VAR_Y] =
 -        av_expr_eval(dtext->y_pexpr, dtext->var_values, &dtext->prng);
 -    dtext->var_values[VAR_X] =
 -        av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
 +    max_text_line_w = FFMAX(x, max_text_line_w);
 +
 +    dtext->var_values[VAR_TW] = dtext->var_values[VAR_TEXT_W] = max_text_line_w;
 +    dtext->var_values[VAR_TH] = dtext->var_values[VAR_TEXT_H] = y + dtext->max_glyph_h;
  
 -    dtext->draw = fail ? 0 :
 -        av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng);
 +    dtext->var_values[VAR_MAX_GLYPH_W] = dtext->max_glyph_w;
 +    dtext->var_values[VAR_MAX_GLYPH_H] = dtext->max_glyph_h;
 +    dtext->var_values[VAR_MAX_GLYPH_A] = dtext->var_values[VAR_ASCENT ] = y_max;
 +    dtext->var_values[VAR_MAX_GLYPH_D] = dtext->var_values[VAR_DESCENT] = y_min;
  
 -    normalize_double(&dtext->x, dtext->var_values[VAR_X]);
 -    normalize_double(&dtext->y, dtext->var_values[VAR_Y]);
 +    dtext->var_values[VAR_LINE_H] = dtext->var_values[VAR_LH] = dtext->max_glyph_h;
  
-     dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, NULL);
-     dtext->y = dtext->var_values[VAR_Y] = av_expr_eval(dtext->y_pexpr, dtext->var_values, NULL);
-     dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, NULL);
 -    if (dtext->x < 0) dtext->x = 0;
 -    if (dtext->y < 0) dtext->y = 0;
 -    if ((unsigned)dtext->x + (unsigned)dtext->w > inlink->w)
 -        dtext->x = inlink->w - dtext->w;
 -    if ((unsigned)dtext->y + (unsigned)dtext->h > inlink->h)
 -        dtext->y = inlink->h - dtext->h;
++    dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
++    dtext->y = dtext->var_values[VAR_Y] = av_expr_eval(dtext->y_pexpr, dtext->var_values, &dtext->prng);
++    dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
++    dtext->draw = av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng);
++
++    if(!dtext->draw)
++        return 0;
  
      dtext->x &= ~((1 << dtext->hsub) - 1);
      dtext->y &= ~((1 << dtext->vsub) - 1);
Simple merge
Simple merge
diff --cc libavutil/lzo.h
Simple merge