コード例 #1
0
/* Derives the minimum level from the current configuration */
static gboolean
ensure_level (GstVaapiEncoderMpeg2 * encoder)
{
  const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
  const guint fps = (vip->fps_n + vip->fps_d - 1) / vip->fps_d;
  const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
  const GstVaapiMPEG2LevelLimits *limits_table;
  guint i, num_limits, num_samples;

  num_samples = gst_util_uint64_scale_int_ceil (vip->width * vip->height,
      vip->fps_n, vip->fps_d);

  limits_table = gst_vaapi_utils_mpeg2_get_level_limits_table (&num_limits);
  for (i = 0; i < num_limits; i++) {
    const GstVaapiMPEG2LevelLimits *const limits = &limits_table[i];
    if (vip->width <= limits->horizontal_size_value &&
        vip->height <= limits->vertical_size_value &&
        fps <= limits->frame_rate_value &&
        num_samples <= limits->sample_rate &&
        (!bitrate || bitrate <= limits->bit_rate))
      break;
  }
  if (i == num_limits)
    goto error_unsupported_level;

  encoder->level = limits_table[i].level;
  encoder->level_idc = limits_table[i].level_idc;
  return TRUE;

  /* ERRORS */
error_unsupported_level:
  {
    GST_ERROR ("failed to find a suitable level matching codec config");
    return FALSE;
  }
}
コード例 #2
0
void
rg_analysis_analyze (RgAnalysisCtx * ctx, const gfloat * samples_l,
    const gfloat * samples_r, guint n_samples)
{
  const gfloat *input_l, *input_r;
  guint n_samples_done;
  gint i;

  g_return_if_fail (ctx != NULL);
  g_return_if_fail (samples_l != NULL);
  g_return_if_fail (ctx->sample_rate != 0);

  if (n_samples == 0)
    return;

  if (samples_r == NULL)
    /* Mono. */
    samples_r = samples_l;

  memcpy (ctx->inpre_l, samples_l,
      MIN (n_samples, MAX_ORDER) * sizeof (gfloat));
  memcpy (ctx->inpre_r, samples_r,
      MIN (n_samples, MAX_ORDER) * sizeof (gfloat));

  n_samples_done = 0;
  while (n_samples_done < n_samples) {
    /* Limit number of samples to be processed in this iteration to
     * the number needed to complete the next window: */
    guint n_samples_current = MIN (n_samples - n_samples_done,
        ctx->window_n_samples - ctx->window_n_samples_done);

    if (n_samples_done < MAX_ORDER) {
      input_l = ctx->inpre_l + n_samples_done;
      input_r = ctx->inpre_r + n_samples_done;
      n_samples_current = MIN (n_samples_current, MAX_ORDER - n_samples_done);
    } else {
      input_l = samples_l + n_samples_done;
      input_r = samples_r + n_samples_done;
    }

    apply_filters (ctx, input_l, input_r, n_samples_current);

    /* Update the square sum. */
    for (i = 0; i < n_samples_current; i++)
      ctx->window_square_sum += ctx->out_l[ctx->window_n_samples_done + i]
          * ctx->out_l[ctx->window_n_samples_done + i]
          + ctx->out_r[ctx->window_n_samples_done + i]
          * ctx->out_r[ctx->window_n_samples_done + i];

    ctx->window_n_samples_done += n_samples_current;
    ctx->buffer_n_samples_done += n_samples_current;

    g_return_if_fail (ctx->window_n_samples_done <= ctx->window_n_samples);

    if (ctx->window_n_samples_done == ctx->window_n_samples) {
      /* Get the Root Mean Square (RMS) for this set of samples. */
      gdouble val = STEPS_PER_DB * 10. * log10 (ctx->window_square_sum /
          ctx->window_n_samples * 0.5 + 1.e-37);
      gint ival = CLAMP ((gint) val, 0,
          (gint) G_N_ELEMENTS (ctx->track.histogram) - 1);
      /* Compute the per-window gain */
      const gdouble gain = PINK_REF - (gdouble) ival / STEPS_PER_DB;
      const GstClockTime timestamp = ctx->buffer_timestamp
          + gst_util_uint64_scale_int_ceil (GST_SECOND,
          ctx->buffer_n_samples_done,
          ctx->sample_rate)
          - RMS_WINDOW_MSECS * GST_MSECOND;

      ctx->post_message (ctx->analysis, timestamp,
          RMS_WINDOW_MSECS * GST_MSECOND, -gain);


      ctx->track.histogram[ival]++;
      ctx->window_square_sum = 0.;
      ctx->window_n_samples_done = 0;

      /* No need for memmove here, the areas never overlap: Even for
       * the smallest sample rate, the number of samples needed for
       * the window is greater than MAX_ORDER. */

      memcpy (ctx->stepbuf_l, ctx->stepbuf_l + ctx->window_n_samples,
          MAX_ORDER * sizeof (gfloat));
      memcpy (ctx->outbuf_l, ctx->outbuf_l + ctx->window_n_samples,
          MAX_ORDER * sizeof (gfloat));

      memcpy (ctx->stepbuf_r, ctx->stepbuf_r + ctx->window_n_samples,
          MAX_ORDER * sizeof (gfloat));
      memcpy (ctx->outbuf_r, ctx->outbuf_r + ctx->window_n_samples,
          MAX_ORDER * sizeof (gfloat));
    }

    n_samples_done += n_samples_current;
  }

  if (n_samples >= MAX_ORDER) {

    memcpy (ctx->inprebuf_l, samples_l + n_samples - MAX_ORDER,
        MAX_ORDER * sizeof (gfloat));

    memcpy (ctx->inprebuf_r, samples_r + n_samples - MAX_ORDER,
        MAX_ORDER * sizeof (gfloat));

  } else {

    memmove (ctx->inprebuf_l, ctx->inprebuf_l + n_samples,
        (MAX_ORDER - n_samples) * sizeof (gfloat));
    memcpy (ctx->inprebuf_l + MAX_ORDER - n_samples, samples_l,
        n_samples * sizeof (gfloat));

    memmove (ctx->inprebuf_r, ctx->inprebuf_r + n_samples,
        (MAX_ORDER - n_samples) * sizeof (gfloat));
    memcpy (ctx->inprebuf_r + MAX_ORDER - n_samples, samples_r,
        n_samples * sizeof (gfloat));

  }
}