Пример #1
0
GstVaapiDecoder *
decoder_new (GstVaapiDisplay * display, const gchar * codec_name)
{
  GstVaapiDecoder *decoder;
  const CodecDefs *codec;
  GstCaps *caps;
  VideoDecodeInfo info;

  if (!codec_name)
    codec_name = "h264";

  codec = find_codec_defs (codec_name);
  if (!codec) {
    GST_ERROR ("failed to find %s codec data", codec_name);
    return NULL;
  }

  codec->get_video_info (&info);
  caps = gst_vaapi_profile_get_caps (info.profile);
  if (!caps) {
    GST_ERROR ("failed to create decoder caps");
    return NULL;
  }

  if (info.width > 0 && info.height > 0)
    gst_caps_set_simple (caps,
        "width", G_TYPE_INT, info.width,
        "height", G_TYPE_INT, info.height, NULL);

  switch (gst_vaapi_profile_get_codec (info.profile)) {
    case GST_VAAPI_CODEC_H264:
      decoder = gst_vaapi_decoder_h264_new (display, caps);
      break;
#if USE_JPEG_DECODER
    case GST_VAAPI_CODEC_JPEG:
      decoder = gst_vaapi_decoder_jpeg_new (display, caps);
      break;
#endif
    case GST_VAAPI_CODEC_MPEG2:
      decoder = gst_vaapi_decoder_mpeg2_new (display, caps);
      break;
    case GST_VAAPI_CODEC_MPEG4:
      decoder = gst_vaapi_decoder_mpeg4_new (display, caps);
      break;
    case GST_VAAPI_CODEC_VC1:
      decoder = gst_vaapi_decoder_vc1_new (display, caps);
      break;
    default:
      decoder = NULL;
      break;
  }
  gst_caps_unref (caps);
  if (!decoder) {
    GST_ERROR ("failed to create %s decoder", codec->codec_str);
    return NULL;
  }

  set_codec_defs (decoder, codec);
  return decoder;
}
Пример #2
0
static gboolean
set_caps (GstVaapiDecoder * decoder, const GstCaps * caps)
{
  GstVideoCodecState *const codec_state = decoder->codec_state;
  GstStructure *const structure = gst_caps_get_structure (caps, 0);
  GstVaapiProfile profile;
  const GValue *v_codec_data;

  profile = gst_vaapi_profile_from_caps (caps);
  if (!profile)
    return FALSE;

  decoder->codec = gst_vaapi_profile_get_codec (profile);
  if (!decoder->codec)
    return FALSE;

  if (!gst_video_info_from_caps (&codec_state->info, caps))
    return FALSE;

  codec_state->caps = gst_caps_copy (caps);

  v_codec_data = gst_structure_get_value (structure, "codec_data");
  if (v_codec_data)
    gst_buffer_replace (&codec_state->codec_data,
        gst_value_get_buffer (v_codec_data));
  return TRUE;
}
/* Gets a compatible profile for the active codec */
static GstVaapiProfile
get_compatible_profile (GstVaapiEncoder * encoder)
{
  const GstVaapiEncoderClassData *const cdata =
      GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data;
  GstVaapiProfile profile;
  GArray *profiles;
  guint i;

  profiles = gst_vaapi_display_get_encode_profiles (encoder->display);
  if (!profiles)
    return GST_VAAPI_PROFILE_UNKNOWN;

  // Pick a profile matching the class codec
  for (i = 0; i < profiles->len; i++) {
    profile = g_array_index (profiles, GstVaapiProfile, i);
    if (gst_vaapi_profile_get_codec (profile) == cdata->codec)
      break;
  }
  if (i == profiles->len)
    profile = GST_VAAPI_PROFILE_UNKNOWN;

  g_array_unref (profiles);
  return profile;
}
Пример #4
0
static void
print_profiles(GArray *profiles, const gchar *name)
{
    GstVaapiCodec codec;
    const gchar *codec_name, *profile_name;
    guint i;

    g_print("%u %s caps\n", profiles->len, name);

    for (i = 0; i < profiles->len; i++) {
        const GstVaapiProfile profile =
            g_array_index(profiles, GstVaapiProfile, i);

        codec = gst_vaapi_profile_get_codec(profile);
        if (!codec)
            continue;

        codec_name = gst_vaapi_codec_get_name(codec);
        if (!codec_name)
            continue;

        profile_name = gst_vaapi_profile_get_name(profile);
        if (!profile_name)
            continue;

        g_print("  %s: %s profile\n", codec_name, profile_name);
    }
}
Пример #5
0
/**
 * gst_vaapi_profile_from_caps:
 * @caps: a #GstCaps
 *
 * Converts @caps into the corresponding #GstVaapiProfile. If the
 * profile cannot be represented by #GstVaapiProfile, then zero is
 * returned.
 *
 * Return value: the #GstVaapiProfile describing the @caps
 */
GstVaapiProfile
gst_vaapi_profile_from_caps(const GstCaps *caps)
{
    const GstVaapiProfileMap *m;
    GstCaps *caps_test;
    GstStructure *structure;
    const gchar *profile_str;
    GstVaapiProfile profile, best_profile;
    GstBuffer *codec_data = NULL;
    const gchar *name;
    gsize namelen;

    if (!caps)
        return 0;

    structure = gst_caps_get_structure(caps, 0);
    if (!structure)
        return 0;

    name    = gst_structure_get_name(structure);
    namelen = strlen(name);

    profile_str = gst_structure_get_string(structure, "profile");
    if (!profile_str) {
        const GValue *v_codec_data;
        v_codec_data = gst_structure_get_value(structure, "codec_data");
        if (v_codec_data)
            codec_data = gst_value_get_buffer(v_codec_data);
    }

    profile = 0;
    best_profile = 0;
    for (m = gst_vaapi_profiles; !profile && m->profile; m++) {
        if (strncmp(name, m->media_str, namelen) != 0)
            continue;
        caps_test = gst_caps_from_string(m->media_str);
        if (gst_caps_is_always_compatible(caps, caps_test)) {
            best_profile = m->profile;
            if (profile_str && m->profile_str &&
                strcmp(profile_str, m->profile_str) == 0)
                profile = best_profile;
        }
        if (!profile) {
            profile = gst_vaapi_profile_from_codec_data(
                gst_vaapi_profile_get_codec(m->profile),
                codec_data
            );
            if (!profile &&
                WORKAROUND_QTDEMUX_NO_H263_PROFILES &&
                strncmp(name, "video/x-h263", namelen) == 0) {
                /* HACK: qtdemux does not report profiles for h263 */
                profile = m->profile;
            }
        }
        gst_caps_unref(caps_test);
    }
    return profile ? profile : best_profile;
}
Пример #6
0
static gboolean
gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state)
{
  GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc);
  gboolean ret;

  g_return_val_if_fail (state->caps != NULL, FALSE);

  if (!set_codec_state (encode, state))
    return FALSE;

  if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (encode),
          state->caps, NULL))
    return FALSE;

  if (encode->input_state)
    gst_video_codec_state_unref (encode->input_state);
  encode->input_state = gst_video_codec_state_ref (state);
  encode->input_state_changed = TRUE;

  ret = gst_pad_start_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode),
      (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL);

  if (!ret)
    return FALSE;

  /* Store some tags */
  {
    GstTagList *tags = gst_tag_list_new_empty ();
    const gchar *encoder, *codec;
    guint bitrate = 0;

    g_object_get (encode, "bitrate", &bitrate, NULL);
    gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_NOMINAL_BITRATE,
        bitrate, NULL);

    if ((encoder =
            gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (encode),
                GST_ELEMENT_METADATA_LONGNAME)))
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, encoder,
          NULL);

    if ((codec =
            gst_vaapi_codec_get_name (gst_vaapi_profile_get_codec
                (gst_vaapi_profile_from_caps (state->caps)))))
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_CODEC, codec,
          NULL);

    gst_video_encoder_merge_tags (venc, tags, GST_TAG_MERGE_REPLACE);
    gst_tag_list_unref (tags);
  }

  return TRUE;
}
Пример #7
0
static GArray *
profiles_get_codecs (GArray * profiles)
{
  guint i;
  GArray *codecs;
  GstVaapiProfile profile;
  GstVaapiCodec codec;

  codecs = g_array_new (FALSE, FALSE, sizeof (GstVaapiCodec));
  if (!codecs)
    return NULL;

  for (i = 0; i < profiles->len; i++) {
    profile = g_array_index (profiles, GstVaapiProfile, i);
    codec = gst_vaapi_profile_get_codec (profile);
    if (gst_vaapi_codecs_has_codec (codecs, codec))
      continue;
    g_array_append_val (codecs, codec);
  }

  return codecs;
}
Пример #8
0
static inline guint
gst_vaapi_codec_from_caps (GstCaps * caps)
{
  return gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (caps));
}