decoder.c 5.2 KB
Newer Older
1 2 3 4
/*
 *  decoder.h - Decoder utilities for the tests
 *
 *  Copyright (C) 2013 Intel Corporation
5
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

23
#include "gst/vaapi/sysdeps.h"
24 25 26 27 28 29 30 31 32 33 34 35
#include <gst/vaapi/gstvaapidecoder_h264.h>
#include <gst/vaapi/gstvaapidecoder_jpeg.h>
#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
#include <gst/vaapi/gstvaapidecoder_mpeg4.h>
#include <gst/vaapi/gstvaapidecoder_vc1.h>
#include "decoder.h"
#include "test-jpeg.h"
#include "test-mpeg2.h"
#include "test-mpeg4.h"
#include "test-h264.h"
#include "test-vc1.h"

36
typedef void (*GetVideoInfoFunc) (VideoDecodeInfo * info);
37 38

typedef struct _CodecDefs CodecDefs;
39 40 41 42
struct _CodecDefs
{
  const gchar *codec_str;
  GetVideoInfoFunc get_video_info;
43 44 45 46
};

static const CodecDefs g_codec_defs[] = {
#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info }
47 48 49 50 51
  INIT_FUNCS (jpeg),
  INIT_FUNCS (mpeg2),
  INIT_FUNCS (mpeg4),
  INIT_FUNCS (h264),
  INIT_FUNCS (vc1),
52
#undef INIT_FUNCS
53
  {NULL,}
54 55 56
};

static const CodecDefs *
57
find_codec_defs (const gchar * codec_str)
58
{
59 60 61 62 63
  const CodecDefs *c;
  for (c = g_codec_defs; c->codec_str; c++)
    if (strcmp (codec_str, c->codec_str) == 0)
      return c;
  return NULL;
64 65 66
}

static inline const CodecDefs *
67
get_codec_defs (GstVaapiDecoder * decoder)
68
{
69
  return gst_vaapi_decoder_get_user_data (decoder);
70 71 72
}

static inline void
73
set_codec_defs (GstVaapiDecoder * decoder, const CodecDefs * c)
74
{
75
  gst_vaapi_decoder_set_user_data (decoder, (gpointer) c);
76 77 78
}

GstVaapiDecoder *
79
decoder_new (GstVaapiDisplay * display, const gchar * codec_name)
80
{
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
  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)) {
108
    case GST_VAAPI_CODEC_H264:
109 110
      decoder = gst_vaapi_decoder_h264_new (display, caps);
      break;
111
    case GST_VAAPI_CODEC_JPEG:
112 113
      decoder = gst_vaapi_decoder_jpeg_new (display, caps);
      break;
114
    case GST_VAAPI_CODEC_MPEG2:
115 116
      decoder = gst_vaapi_decoder_mpeg2_new (display, caps);
      break;
117
    case GST_VAAPI_CODEC_MPEG4:
118 119
      decoder = gst_vaapi_decoder_mpeg4_new (display, caps);
      break;
120
    case GST_VAAPI_CODEC_VC1:
121 122
      decoder = gst_vaapi_decoder_vc1_new (display, caps);
      break;
123
    default:
124 125 126 127 128 129 130 131 132 133 134
      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;
135 136 137
}

gboolean
138
decoder_put_buffers (GstVaapiDecoder * decoder)
139
{
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
  const CodecDefs *codec;
  VideoDecodeInfo info;
  GstBuffer *buffer;
  gboolean success;

  g_return_val_if_fail (decoder != NULL, FALSE);

  codec = get_codec_defs (decoder);
  g_return_val_if_fail (codec != NULL, FALSE);

  codec->get_video_info (&info);
  buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
      (guchar *) info.data, info.data_size, 0, info.data_size, NULL, NULL);
  if (!buffer) {
    GST_ERROR ("failed to create encoded data buffer");
    return FALSE;
  }

  success = gst_vaapi_decoder_put_buffer (decoder, buffer);
  gst_buffer_unref (buffer);
  if (!success) {
    GST_ERROR ("failed to send video data to the decoder");
    return FALSE;
  }

  if (!gst_vaapi_decoder_put_buffer (decoder, NULL)) {
    GST_ERROR ("failed to submit <end-of-stream> to the decoder");
    return FALSE;
  }
  return TRUE;
170 171
}

172
GstVaapiSurfaceProxy *
173
decoder_get_surface (GstVaapiDecoder * decoder)
174
{
175 176
  GstVaapiSurfaceProxy *proxy;
  GstVaapiDecoderStatus status;
177

178
  g_return_val_if_fail (decoder != NULL, NULL);
179

180 181 182 183 184 185
  status = gst_vaapi_decoder_get_surface (decoder, &proxy);
  if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
    GST_ERROR ("failed to get decoded surface (decoder status %d)", status);
    return NULL;
  }
  return proxy;
186 187 188
}

const gchar *
189
decoder_get_codec_name (GstVaapiDecoder * decoder)
190
{
191
  const CodecDefs *codec;
192

193
  g_return_val_if_fail (decoder != NULL, NULL);
194

195 196
  codec = get_codec_defs (decoder);
  g_return_val_if_fail (codec != NULL, FALSE);
197

198
  return codec->codec_str;
199
}