~ubuntu-branches/ubuntu/vivid/gstreamer-vaapi/vivid

« back to all changes in this revision

Viewing changes to gst-libs/gst/vaapi/gstvaapidecoder.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2014-08-06 23:56:00 UTC
  • mfrom: (0.1.4 sid) (1.1.3)
  • Revision ID: package-import@ubuntu.com-20140806235600-fg1kcmiu67k315q5
Tags: 0.5.9-2
* Remove spurious build-deps: libva-drm1, libavcodec-dev. (Closes: #757283)
* Drop Build-Depends-Indep and build docs unconditionally on all archs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5
5
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6
 
 *  Copyright (C) 2011-2013 Intel Corporation
 
6
 *  Copyright (C) 2011-2014 Intel Corporation
7
7
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8
8
 *
9
9
 *  This library is free software; you can redistribute it and/or
39
39
#include "gstvaapidebug.h"
40
40
 
41
41
static void
42
 
drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame);
 
42
drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame);
43
43
 
44
44
static void
45
 
parser_state_finalize(GstVaapiParserState *ps)
 
45
parser_state_finalize (GstVaapiParserState * ps)
46
46
{
47
 
    if (ps->input_adapter) {
48
 
        gst_adapter_clear(ps->input_adapter);
49
 
        g_object_unref(ps->input_adapter);
50
 
        ps->input_adapter = NULL;
51
 
    }
52
 
 
53
 
    if (ps->output_adapter) {
54
 
        gst_adapter_clear(ps->output_adapter);
55
 
        g_object_unref(ps->output_adapter);
56
 
        ps->output_adapter = NULL;
57
 
    }
58
 
 
59
 
    if (ps->next_unit_pending) {
60
 
        gst_vaapi_decoder_unit_clear(&ps->next_unit);
61
 
        ps->next_unit_pending = FALSE;
62
 
    }
 
47
  if (ps->input_adapter) {
 
48
    gst_adapter_clear (ps->input_adapter);
 
49
    g_object_unref (ps->input_adapter);
 
50
    ps->input_adapter = NULL;
 
51
  }
 
52
 
 
53
  if (ps->output_adapter) {
 
54
    gst_adapter_clear (ps->output_adapter);
 
55
    g_object_unref (ps->output_adapter);
 
56
    ps->output_adapter = NULL;
 
57
  }
 
58
 
 
59
  if (ps->next_unit_pending) {
 
60
    gst_vaapi_decoder_unit_clear (&ps->next_unit);
 
61
    ps->next_unit_pending = FALSE;
 
62
  }
63
63
}
64
64
 
65
65
static gboolean
66
 
parser_state_init(GstVaapiParserState *ps)
 
66
parser_state_init (GstVaapiParserState * ps)
67
67
{
68
 
    memset(ps, 0, sizeof(*ps));
69
 
 
70
 
    ps->input_adapter = gst_adapter_new();
71
 
    if (!ps->input_adapter)
72
 
        return FALSE;
73
 
 
74
 
    ps->output_adapter = gst_adapter_new();
75
 
    if (!ps->output_adapter)
76
 
        return FALSE;
77
 
    return TRUE;
 
68
  memset (ps, 0, sizeof (*ps));
 
69
 
 
70
  ps->input_adapter = gst_adapter_new ();
 
71
  if (!ps->input_adapter)
 
72
    return FALSE;
 
73
 
 
74
  ps->output_adapter = gst_adapter_new ();
 
75
  if (!ps->output_adapter)
 
76
    return FALSE;
 
77
  return TRUE;
78
78
}
79
79
 
80
80
static void
81
 
parser_state_prepare(GstVaapiParserState *ps, GstAdapter *adapter)
 
81
parser_state_prepare (GstVaapiParserState * ps, GstAdapter * adapter)
82
82
{
83
 
    /* XXX: check we really have a continuity from the previous call */
84
 
    if (ps->current_adapter != adapter)
85
 
        goto reset;
86
 
    return;
 
83
  /* XXX: check we really have a continuity from the previous call */
 
84
  if (ps->current_adapter != adapter)
 
85
    goto reset;
 
86
  return;
87
87
 
88
88
reset:
89
 
    ps->current_adapter = adapter;
90
 
    ps->input_offset1 = -1;
91
 
    ps->input_offset2 = -1;
 
89
  ps->current_adapter = adapter;
 
90
  ps->input_offset1 = -1;
 
91
  ps->input_offset2 = -1;
92
92
}
93
93
 
94
94
static gboolean
95
 
push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer)
 
95
push_buffer (GstVaapiDecoder * decoder, GstBuffer * buffer)
96
96
{
97
 
    if (!buffer) {
98
 
        buffer = gst_buffer_new();
99
 
        if (!buffer)
100
 
            return FALSE;
101
 
        GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_EOS);
102
 
    }
103
 
 
104
 
    GST_DEBUG("queue encoded data buffer %p (%d bytes)",
105
 
              buffer, gst_buffer_get_size(buffer));
106
 
 
107
 
    g_async_queue_push(decoder->buffers, buffer);
108
 
    return TRUE;
 
97
  if (!buffer) {
 
98
    buffer = gst_buffer_new ();
 
99
    if (!buffer)
 
100
      return FALSE;
 
101
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_EOS);
 
102
  }
 
103
 
 
104
  GST_DEBUG ("queue encoded data buffer %p (%zu bytes)",
 
105
      buffer, gst_buffer_get_size (buffer));
 
106
 
 
107
  g_async_queue_push (decoder->buffers, buffer);
 
108
  return TRUE;
109
109
}
110
110
 
111
111
static GstBuffer *
112
 
pop_buffer(GstVaapiDecoder *decoder)
 
112
pop_buffer (GstVaapiDecoder * decoder)
113
113
{
114
 
    GstBuffer *buffer;
115
 
 
116
 
    buffer = g_async_queue_try_pop(decoder->buffers);
117
 
    if (!buffer)
118
 
        return NULL;
119
 
 
120
 
    GST_DEBUG("dequeue buffer %p for decoding (%d bytes)",
121
 
              buffer, gst_buffer_get_size(buffer));
122
 
 
123
 
    return buffer;
 
114
  GstBuffer *buffer;
 
115
 
 
116
  buffer = g_async_queue_try_pop (decoder->buffers);
 
117
  if (!buffer)
 
118
    return NULL;
 
119
 
 
120
  GST_DEBUG ("dequeue buffer %p for decoding (%zu bytes)",
 
121
      buffer, gst_buffer_get_size (buffer));
 
122
 
 
123
  return buffer;
124
124
}
125
125
 
126
126
static GstVaapiDecoderStatus
127
 
do_parse(GstVaapiDecoder *decoder,
128
 
    GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos,
129
 
    guint *got_unit_size_ptr, gboolean *got_frame_ptr)
 
127
do_parse (GstVaapiDecoder * decoder,
 
128
    GstVideoCodecFrame * base_frame, GstAdapter * adapter, gboolean at_eos,
 
129
    guint * got_unit_size_ptr, gboolean * got_frame_ptr)
130
130
{
131
 
    GstVaapiParserState * const ps = &decoder->parser_state;
132
 
    GstVaapiParserFrame *frame;
133
 
    GstVaapiDecoderUnit *unit;
134
 
    GstVaapiDecoderStatus status;
135
 
 
136
 
    *got_unit_size_ptr = 0;
137
 
    *got_frame_ptr = FALSE;
138
 
 
139
 
    frame = gst_video_codec_frame_get_user_data(base_frame);
140
 
    if (!frame) {
141
 
        GstVideoCodecState * const codec_state = decoder->codec_state;
142
 
        frame = gst_vaapi_parser_frame_new(codec_state->info.width,
143
 
            codec_state->info.height);
144
 
        if (!frame)
145
 
            return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
146
 
        gst_video_codec_frame_set_user_data(base_frame,
147
 
            frame, (GDestroyNotify)gst_vaapi_mini_object_unref);
148
 
    }
149
 
 
150
 
    parser_state_prepare(ps, adapter);
151
 
 
152
 
    unit = &ps->next_unit;
153
 
    if (ps->next_unit_pending) {
154
 
        ps->next_unit_pending = FALSE;
155
 
        goto got_unit;
156
 
    }
157
 
    gst_vaapi_decoder_unit_init(unit);
158
 
 
159
 
    ps->current_frame = base_frame;
160
 
    status = GST_VAAPI_DECODER_GET_CLASS(decoder)->parse(decoder,
161
 
        adapter, at_eos, unit);
162
 
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
163
 
        if (at_eos && frame->units->len > 0 &&
164
 
            status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) {
165
 
            /* XXX: assume the frame is complete at <EOS> */
166
 
            *got_frame_ptr = TRUE;
167
 
            return GST_VAAPI_DECODER_STATUS_SUCCESS;
168
 
        }
169
 
        return status;
170
 
    }
171
 
 
172
 
    if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->units->len > 0) {
173
 
        ps->next_unit_pending = TRUE;
174
 
        *got_frame_ptr = TRUE;
175
 
        return GST_VAAPI_DECODER_STATUS_SUCCESS;
176
 
    }
 
131
  GstVaapiParserState *const ps = &decoder->parser_state;
 
132
  GstVaapiParserFrame *frame;
 
133
  GstVaapiDecoderUnit *unit;
 
134
  GstVaapiDecoderStatus status;
 
135
 
 
136
  *got_unit_size_ptr = 0;
 
137
  *got_frame_ptr = FALSE;
 
138
 
 
139
  frame = gst_video_codec_frame_get_user_data (base_frame);
 
140
  if (!frame) {
 
141
    GstVideoCodecState *const codec_state = decoder->codec_state;
 
142
    frame = gst_vaapi_parser_frame_new (codec_state->info.width,
 
143
        codec_state->info.height);
 
144
    if (!frame)
 
145
      return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
 
146
    gst_video_codec_frame_set_user_data (base_frame,
 
147
        frame, (GDestroyNotify) gst_vaapi_mini_object_unref);
 
148
  }
 
149
 
 
150
  parser_state_prepare (ps, adapter);
 
151
 
 
152
  unit = &ps->next_unit;
 
153
  if (ps->next_unit_pending) {
 
154
    ps->next_unit_pending = FALSE;
 
155
    goto got_unit;
 
156
  }
 
157
  gst_vaapi_decoder_unit_init (unit);
 
158
 
 
159
  ps->current_frame = base_frame;
 
160
  status = GST_VAAPI_DECODER_GET_CLASS (decoder)->parse (decoder,
 
161
      adapter, at_eos, unit);
 
162
  if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
 
163
    if (at_eos && frame->units->len > 0 &&
 
164
        status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) {
 
165
      /* XXX: assume the frame is complete at <EOS> */
 
166
      *got_frame_ptr = TRUE;
 
167
      return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
168
    }
 
169
    return status;
 
170
  }
 
171
 
 
172
  if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START (unit) && frame->units->len > 0) {
 
173
    ps->next_unit_pending = TRUE;
 
174
    *got_frame_ptr = TRUE;
 
175
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
176
  }
177
177
 
178
178
got_unit:
179
 
    gst_vaapi_parser_frame_append_unit(frame, unit);
180
 
    *got_unit_size_ptr = unit->size;
181
 
    *got_frame_ptr = GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit);
182
 
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
183
 
}
184
 
 
185
 
static GstVaapiDecoderStatus
186
 
do_decode_units(GstVaapiDecoder *decoder, GArray *units)
187
 
{
188
 
    GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder);
189
 
    GstVaapiDecoderStatus status;
190
 
    guint i;
191
 
 
192
 
    for (i = 0; i < units->len; i++) {
193
 
        GstVaapiDecoderUnit * const unit =
194
 
            &g_array_index(units, GstVaapiDecoderUnit, i);
195
 
        if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit))
196
 
            continue;
197
 
        status = klass->decode(decoder, unit);
198
 
        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
199
 
            return status;
200
 
    }
201
 
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
202
 
}
203
 
 
204
 
static GstVaapiDecoderStatus
205
 
do_decode_1(GstVaapiDecoder *decoder, GstVaapiParserFrame *frame)
206
 
{
207
 
    GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder);
208
 
    GstVaapiDecoderStatus status;
209
 
 
210
 
    if (frame->pre_units->len > 0) {
211
 
        status = do_decode_units(decoder, frame->pre_units);
212
 
        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
213
 
            return status;
214
 
    }
215
 
 
216
 
    if (frame->units->len > 0) {
217
 
        if (klass->start_frame) {
218
 
            GstVaapiDecoderUnit * const unit =
219
 
                &g_array_index(frame->units, GstVaapiDecoderUnit, 0);
220
 
            status = klass->start_frame(decoder, unit);
221
 
            if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
222
 
                return status;
223
 
        }
224
 
 
225
 
        status = do_decode_units(decoder, frame->units);
226
 
        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
227
 
            return status;
228
 
 
229
 
        if (klass->end_frame) {
230
 
            status = klass->end_frame(decoder);
231
 
            if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
232
 
                return status;
233
 
        }
234
 
    }
235
 
 
236
 
    if (frame->post_units->len > 0) {
237
 
        status = do_decode_units(decoder, frame->post_units);
238
 
        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
239
 
            return status;
240
 
    }
241
 
 
242
 
    /* Drop frame if there is no slice data unit in there */
243
 
    if (G_UNLIKELY(frame->units->len == 0))
244
 
        return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
245
 
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
179
  gst_vaapi_parser_frame_append_unit (frame, unit);
 
180
  *got_unit_size_ptr = unit->size;
 
181
  *got_frame_ptr = GST_VAAPI_DECODER_UNIT_IS_FRAME_END (unit);
 
182
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
183
}
 
184
 
 
185
static GstVaapiDecoderStatus
 
186
do_decode_units (GstVaapiDecoder * decoder, GArray * units)
 
187
{
 
188
  GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder);
 
189
  GstVaapiDecoderStatus status;
 
190
  guint i;
 
191
 
 
192
  for (i = 0; i < units->len; i++) {
 
193
    GstVaapiDecoderUnit *const unit =
 
194
        &g_array_index (units, GstVaapiDecoderUnit, i);
 
195
    if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED (unit))
 
196
      continue;
 
197
    status = klass->decode (decoder, unit);
 
198
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
 
199
      return status;
 
200
  }
 
201
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
202
}
 
203
 
 
204
static GstVaapiDecoderStatus
 
205
do_decode_1 (GstVaapiDecoder * decoder, GstVaapiParserFrame * frame)
 
206
{
 
207
  GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder);
 
208
  GstVaapiDecoderStatus status;
 
209
 
 
210
  if (frame->pre_units->len > 0) {
 
211
    status = do_decode_units (decoder, frame->pre_units);
 
212
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
 
213
      return status;
 
214
  }
 
215
 
 
216
  if (frame->units->len > 0) {
 
217
    if (klass->start_frame) {
 
218
      GstVaapiDecoderUnit *const unit =
 
219
          &g_array_index (frame->units, GstVaapiDecoderUnit, 0);
 
220
      status = klass->start_frame (decoder, unit);
 
221
      if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
 
222
        return status;
 
223
    }
 
224
 
 
225
    status = do_decode_units (decoder, frame->units);
 
226
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
 
227
      return status;
 
228
 
 
229
    if (klass->end_frame) {
 
230
      status = klass->end_frame (decoder);
 
231
      if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
 
232
        return status;
 
233
    }
 
234
  }
 
235
 
 
236
  if (frame->post_units->len > 0) {
 
237
    status = do_decode_units (decoder, frame->post_units);
 
238
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
 
239
      return status;
 
240
  }
 
241
 
 
242
  /* Drop frame if there is no slice data unit in there */
 
243
  if (G_UNLIKELY (frame->units->len == 0))
 
244
    return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
 
245
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
246
246
}
247
247
 
248
248
static inline GstVaapiDecoderStatus
249
 
do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame)
 
249
do_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * base_frame)
250
250
{
251
 
    GstVaapiParserState * const ps = &decoder->parser_state;
252
 
    GstVaapiParserFrame * const frame = base_frame->user_data;
253
 
    GstVaapiDecoderStatus status;
254
 
 
255
 
    ps->current_frame = base_frame;
256
 
 
257
 
    gst_vaapi_parser_frame_ref(frame);
258
 
    status = do_decode_1(decoder, frame);
259
 
    gst_vaapi_parser_frame_unref(frame);
260
 
 
261
 
    switch ((guint)status) {
 
251
  GstVaapiParserState *const ps = &decoder->parser_state;
 
252
  GstVaapiParserFrame *const frame = base_frame->user_data;
 
253
  GstVaapiDecoderStatus status;
 
254
 
 
255
  ps->current_frame = base_frame;
 
256
 
 
257
  gst_vaapi_parser_frame_ref (frame);
 
258
  status = do_decode_1 (decoder, frame);
 
259
  gst_vaapi_parser_frame_unref (frame);
 
260
 
 
261
  switch ((guint) status) {
262
262
    case GST_VAAPI_DECODER_STATUS_DROP_FRAME:
263
 
        drop_frame(decoder, base_frame);
264
 
        status = GST_VAAPI_DECODER_STATUS_SUCCESS;
265
 
        break;
266
 
    }
267
 
    return status;
 
263
      drop_frame (decoder, base_frame);
 
264
      status = GST_VAAPI_DECODER_STATUS_SUCCESS;
 
265
      break;
 
266
  }
 
267
  return status;
268
268
}
269
269
 
270
270
static inline GstVaapiDecoderStatus
271
 
do_flush(GstVaapiDecoder *decoder)
 
271
do_flush (GstVaapiDecoder * decoder)
272
272
{
273
 
    GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder);
 
273
  GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder);
274
274
 
275
 
    if (klass->flush)
276
 
        return klass->flush(decoder);
277
 
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
275
  if (klass->flush)
 
276
    return klass->flush (decoder);
 
277
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
278
278
}
279
279
 
280
280
static GstVaapiDecoderStatus
281
 
decode_step(GstVaapiDecoder *decoder)
 
281
decode_step (GstVaapiDecoder * decoder)
282
282
{
283
 
    GstVaapiParserState * const ps = &decoder->parser_state;
284
 
    GstVaapiDecoderStatus status;
285
 
    GstBuffer *buffer;
286
 
    gboolean got_frame;
287
 
    guint got_unit_size, input_size;
288
 
 
289
 
    status = gst_vaapi_decoder_check_status(decoder);
290
 
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
291
 
        return status;
292
 
 
293
 
    /* Fill adapter with all buffers we have in the queue */
294
 
    for (;;) {
295
 
        buffer = pop_buffer(decoder);
296
 
        if (!buffer)
297
 
            break;
298
 
 
299
 
        ps->at_eos = GST_BUFFER_IS_EOS(buffer);
300
 
        if (!ps->at_eos)
301
 
            gst_adapter_push(ps->input_adapter, buffer);
302
 
    }
303
 
 
304
 
    /* Parse and decode all decode units */
305
 
    input_size = gst_adapter_available(ps->input_adapter);
306
 
    if (input_size == 0) {
307
 
        if (ps->at_eos)
308
 
            return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
309
 
        return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
310
 
    }
311
 
 
312
 
    do {
313
 
        if (!ps->current_frame) {
314
 
            ps->current_frame = g_slice_new0(GstVideoCodecFrame);
315
 
            if (!ps->current_frame)
316
 
                return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
317
 
            ps->current_frame->ref_count = 1;
318
 
        }
319
 
 
320
 
        status = do_parse(decoder, ps->current_frame, ps->input_adapter,
321
 
            ps->at_eos, &got_unit_size, &got_frame);
322
 
        GST_DEBUG("parse frame (status = %d)", status);
323
 
        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
324
 
            if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA && ps->at_eos)
325
 
                status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
326
 
            break;
327
 
        }
328
 
 
329
 
        if (got_unit_size > 0) {
330
 
            buffer = gst_adapter_take_buffer(ps->input_adapter, got_unit_size);
331
 
            input_size -= got_unit_size;
332
 
 
333
 
            if (gst_adapter_available(ps->output_adapter) == 0) {
334
 
                ps->current_frame->pts =
335
 
                    gst_adapter_prev_timestamp(ps->input_adapter, NULL);
336
 
            }
337
 
            gst_adapter_push(ps->output_adapter, buffer);
338
 
        }
339
 
 
340
 
        if (got_frame) {
341
 
            ps->current_frame->input_buffer = gst_adapter_take_buffer(
342
 
                ps->output_adapter,
343
 
                gst_adapter_available(ps->output_adapter));
344
 
 
345
 
            status = do_decode(decoder, ps->current_frame);
346
 
            GST_DEBUG("decode frame (status = %d)", status);
347
 
 
348
 
            gst_video_codec_frame_unref(ps->current_frame);
349
 
            ps->current_frame = NULL;
350
 
            break;
351
 
        }
352
 
    } while (input_size > 0);
 
283
  GstVaapiParserState *const ps = &decoder->parser_state;
 
284
  GstVaapiDecoderStatus status;
 
285
  GstBuffer *buffer;
 
286
  gboolean got_frame;
 
287
  guint got_unit_size, input_size;
 
288
 
 
289
  status = gst_vaapi_decoder_check_status (decoder);
 
290
  if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
353
291
    return status;
 
292
 
 
293
  /* Fill adapter with all buffers we have in the queue */
 
294
  for (;;) {
 
295
    buffer = pop_buffer (decoder);
 
296
    if (!buffer)
 
297
      break;
 
298
 
 
299
    ps->at_eos = GST_BUFFER_IS_EOS (buffer);
 
300
    if (!ps->at_eos)
 
301
      gst_adapter_push (ps->input_adapter, buffer);
 
302
  }
 
303
 
 
304
  /* Parse and decode all decode units */
 
305
  input_size = gst_adapter_available (ps->input_adapter);
 
306
  if (input_size == 0) {
 
307
    if (ps->at_eos)
 
308
      return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
 
309
    return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
 
310
  }
 
311
 
 
312
  do {
 
313
    if (!ps->current_frame) {
 
314
      ps->current_frame = g_slice_new0 (GstVideoCodecFrame);
 
315
      if (!ps->current_frame)
 
316
        return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
 
317
      ps->current_frame->ref_count = 1;
 
318
      ps->current_frame->system_frame_number = ps->current_frame_number++;
 
319
    }
 
320
 
 
321
    status = do_parse (decoder, ps->current_frame, ps->input_adapter,
 
322
        ps->at_eos, &got_unit_size, &got_frame);
 
323
    GST_DEBUG ("parse frame (status = %d)", status);
 
324
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
 
325
      if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA && ps->at_eos)
 
326
        status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
 
327
      break;
 
328
    }
 
329
 
 
330
    if (got_unit_size > 0) {
 
331
      buffer = gst_adapter_take_buffer (ps->input_adapter, got_unit_size);
 
332
      input_size -= got_unit_size;
 
333
 
 
334
      if (gst_adapter_available (ps->output_adapter) == 0) {
 
335
        ps->current_frame->pts =
 
336
            gst_adapter_prev_timestamp (ps->input_adapter, NULL);
 
337
      }
 
338
      gst_adapter_push (ps->output_adapter, buffer);
 
339
    }
 
340
 
 
341
    if (got_frame) {
 
342
      ps->current_frame->input_buffer =
 
343
          gst_adapter_take_buffer (ps->output_adapter,
 
344
          gst_adapter_available (ps->output_adapter));
 
345
 
 
346
      status = do_decode (decoder, ps->current_frame);
 
347
      GST_DEBUG ("decode frame (status = %d)", status);
 
348
 
 
349
      gst_video_codec_frame_unref (ps->current_frame);
 
350
      ps->current_frame = NULL;
 
351
      break;
 
352
    }
 
353
  } while (input_size > 0);
 
354
  return status;
354
355
}
355
356
 
356
357
static void
357
 
drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
 
358
drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame)
358
359
{
359
 
    GST_DEBUG("drop frame %d", frame->system_frame_number);
360
 
 
361
 
    /* no surface proxy */
362
 
    gst_video_codec_frame_set_user_data(frame, NULL, NULL);
363
 
 
364
 
    frame->pts = GST_CLOCK_TIME_NONE;
365
 
    GST_VIDEO_CODEC_FRAME_FLAG_SET(frame,
366
 
        GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
367
 
 
368
 
    g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame));
 
360
  GST_DEBUG ("drop frame %d", frame->system_frame_number);
 
361
 
 
362
  /* no surface proxy */
 
363
  gst_video_codec_frame_set_user_data (frame, NULL, NULL);
 
364
 
 
365
  frame->pts = GST_CLOCK_TIME_NONE;
 
366
  GST_VIDEO_CODEC_FRAME_FLAG_SET (frame,
 
367
      GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
 
368
 
 
369
  g_async_queue_push (decoder->frames, gst_video_codec_frame_ref (frame));
369
370
}
370
371
 
371
372
static inline void
372
 
push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
 
373
push_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame)
373
374
{
374
 
    GstVaapiSurfaceProxy * const proxy = frame->user_data;
375
 
 
376
 
    GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT,
377
 
              GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)));
378
 
 
379
 
    g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame));
 
375
  GstVaapiSurfaceProxy *const proxy = frame->user_data;
 
376
 
 
377
  GST_DEBUG ("push frame %d (surface 0x%08x)", frame->system_frame_number,
 
378
      (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID (proxy));
 
379
 
 
380
  g_async_queue_push (decoder->frames, gst_video_codec_frame_ref (frame));
380
381
}
381
382
 
382
383
static inline GstVideoCodecFrame *
383
 
pop_frame(GstVaapiDecoder *decoder, guint64 timeout)
 
384
pop_frame (GstVaapiDecoder * decoder, guint64 timeout)
384
385
{
385
 
    GstVideoCodecFrame *frame;
386
 
    GstVaapiSurfaceProxy *proxy;
387
 
 
388
 
    if (G_LIKELY(timeout > 0))
389
 
        frame = g_async_queue_timeout_pop(decoder->frames, timeout);
390
 
    else
391
 
        frame = g_async_queue_try_pop(decoder->frames);
392
 
    if (!frame)
393
 
        return NULL;
394
 
 
395
 
    proxy = frame->user_data;
396
 
    GST_DEBUG("dequeue decoded surface %" GST_VAAPI_ID_FORMAT,
397
 
              GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)));
398
 
 
399
 
    return frame;
 
386
  GstVideoCodecFrame *frame;
 
387
  GstVaapiSurfaceProxy *proxy;
 
388
 
 
389
  if (G_LIKELY (timeout > 0))
 
390
    frame = g_async_queue_timeout_pop (decoder->frames, timeout);
 
391
  else
 
392
    frame = g_async_queue_try_pop (decoder->frames);
 
393
  if (!frame)
 
394
    return NULL;
 
395
 
 
396
  proxy = frame->user_data;
 
397
  GST_DEBUG ("pop frame %d (surface 0x%08x)", frame->system_frame_number,
 
398
      (proxy ? (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID (proxy) :
 
399
          VA_INVALID_ID));
 
400
 
 
401
  return frame;
400
402
}
401
403
 
402
404
static gboolean
403
 
set_caps(GstVaapiDecoder *decoder, const GstCaps *caps)
 
405
set_caps (GstVaapiDecoder * decoder, const GstCaps * caps)
404
406
{
405
 
    GstVideoCodecState * const codec_state = decoder->codec_state;
406
 
    GstStructure * const structure = gst_caps_get_structure(caps, 0);
407
 
    GstVaapiProfile profile;
408
 
    const GValue *v_codec_data;
409
 
 
410
 
    profile = gst_vaapi_profile_from_caps(caps);
411
 
    if (!profile)
412
 
        return FALSE;
413
 
 
414
 
    decoder->codec = gst_vaapi_profile_get_codec(profile);
415
 
    if (!decoder->codec)
416
 
        return FALSE;
417
 
 
418
 
    if (!gst_video_info_from_caps(&codec_state->info, caps))
419
 
        return FALSE;
420
 
 
421
 
    codec_state->caps = gst_caps_copy(caps);
422
 
 
423
 
    v_codec_data = gst_structure_get_value(structure, "codec_data");
424
 
    if (v_codec_data)
425
 
        gst_buffer_replace(&codec_state->codec_data,
426
 
            gst_value_get_buffer(v_codec_data));
427
 
    return TRUE;
 
407
  GstVideoCodecState *const codec_state = decoder->codec_state;
 
408
  GstStructure *const structure = gst_caps_get_structure (caps, 0);
 
409
  GstVaapiProfile profile;
 
410
  const GValue *v_codec_data;
 
411
 
 
412
  profile = gst_vaapi_profile_from_caps (caps);
 
413
  if (!profile)
 
414
    return FALSE;
 
415
 
 
416
  decoder->codec = gst_vaapi_profile_get_codec (profile);
 
417
  if (!decoder->codec)
 
418
    return FALSE;
 
419
 
 
420
  if (!gst_video_info_from_caps (&codec_state->info, caps))
 
421
    return FALSE;
 
422
 
 
423
  codec_state->caps = gst_caps_copy (caps);
 
424
 
 
425
  v_codec_data = gst_structure_get_value (structure, "codec_data");
 
426
  if (v_codec_data)
 
427
    gst_buffer_replace (&codec_state->codec_data,
 
428
        gst_value_get_buffer (v_codec_data));
 
429
  return TRUE;
428
430
}
429
431
 
430
432
static inline GstCaps *
431
 
get_caps(GstVaapiDecoder *decoder)
 
433
get_caps (GstVaapiDecoder * decoder)
432
434
{
433
 
    return GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps;
 
435
  return GST_VAAPI_DECODER_CODEC_STATE (decoder)->caps;
434
436
}
435
437
 
436
438
static void
437
 
notify_codec_state_changed(GstVaapiDecoder *decoder)
 
439
notify_codec_state_changed (GstVaapiDecoder * decoder)
438
440
{
439
 
    if (decoder->codec_state_changed_func)
440
 
        decoder->codec_state_changed_func(decoder, decoder->codec_state,
441
 
            decoder->codec_state_changed_data);
 
441
  if (decoder->codec_state_changed_func)
 
442
    decoder->codec_state_changed_func (decoder, decoder->codec_state,
 
443
        decoder->codec_state_changed_data);
442
444
}
443
445
 
444
446
void
445
 
gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder)
 
447
gst_vaapi_decoder_finalize (GstVaapiDecoder * decoder)
446
448
{
447
 
    const GstVaapiDecoderClass * const klass =
448
 
        GST_VAAPI_DECODER_GET_CLASS(decoder);
449
 
 
450
 
    if (klass->destroy)
451
 
        klass->destroy(decoder);
452
 
 
453
 
    gst_video_codec_state_unref(decoder->codec_state);
454
 
    decoder->codec_state = NULL;
455
 
 
456
 
    parser_state_finalize(&decoder->parser_state);
457
 
 
458
 
    if (decoder->buffers) {
459
 
        g_async_queue_unref(decoder->buffers);
460
 
        decoder->buffers = NULL;
461
 
    }
462
 
 
463
 
    if (decoder->frames) {
464
 
        g_async_queue_unref(decoder->frames);
465
 
        decoder->frames = NULL;
466
 
    }
467
 
 
468
 
    gst_vaapi_object_replace(&decoder->context, NULL);
469
 
    decoder->va_context = VA_INVALID_ID;
470
 
 
471
 
    gst_vaapi_display_replace(&decoder->display, NULL);
472
 
    decoder->va_display = NULL;
 
449
  const GstVaapiDecoderClass *const klass =
 
450
      GST_VAAPI_DECODER_GET_CLASS (decoder);
 
451
 
 
452
  if (klass->destroy)
 
453
    klass->destroy (decoder);
 
454
 
 
455
  gst_video_codec_state_unref (decoder->codec_state);
 
456
  decoder->codec_state = NULL;
 
457
 
 
458
  parser_state_finalize (&decoder->parser_state);
 
459
 
 
460
  if (decoder->buffers) {
 
461
    g_async_queue_unref (decoder->buffers);
 
462
    decoder->buffers = NULL;
 
463
  }
 
464
 
 
465
  if (decoder->frames) {
 
466
    g_async_queue_unref (decoder->frames);
 
467
    decoder->frames = NULL;
 
468
  }
 
469
 
 
470
  gst_vaapi_object_replace (&decoder->context, NULL);
 
471
  decoder->va_context = VA_INVALID_ID;
 
472
 
 
473
  gst_vaapi_display_replace (&decoder->display, NULL);
 
474
  decoder->va_display = NULL;
473
475
}
474
476
 
475
477
static gboolean
476
 
gst_vaapi_decoder_init(GstVaapiDecoder *decoder, GstVaapiDisplay *display,
477
 
    GstCaps *caps)
 
478
gst_vaapi_decoder_init (GstVaapiDecoder * decoder, GstVaapiDisplay * display,
 
479
    GstCaps * caps)
478
480
{
479
 
    const GstVaapiDecoderClass * const klass =
480
 
        GST_VAAPI_DECODER_GET_CLASS(decoder);
481
 
    GstVideoCodecState *codec_state;
482
 
    guint sub_size;
483
 
 
484
 
    parser_state_init(&decoder->parser_state);
485
 
 
486
 
    codec_state = g_slice_new0(GstVideoCodecState);
487
 
    codec_state->ref_count = 1;
488
 
    gst_video_info_init(&codec_state->info);
489
 
 
490
 
    decoder->user_data   = NULL;
491
 
    decoder->display     = gst_vaapi_display_ref(display);
492
 
    decoder->va_display  = GST_VAAPI_DISPLAY_VADISPLAY(display);
493
 
    decoder->context     = NULL;
494
 
    decoder->va_context  = VA_INVALID_ID;
495
 
    decoder->codec       = 0;
496
 
    decoder->codec_state = codec_state;
497
 
    decoder->codec_state_changed_func = NULL;
498
 
    decoder->codec_state_changed_data = NULL;
499
 
 
500
 
    decoder->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref);
501
 
    decoder->frames  = g_async_queue_new_full((GDestroyNotify)
502
 
        gst_video_codec_frame_unref);
503
 
 
504
 
    if (!set_caps(decoder, caps))
505
 
        return FALSE;
506
 
 
507
 
    sub_size = GST_VAAPI_MINI_OBJECT_CLASS(klass)->size - sizeof(*decoder);
508
 
    if (sub_size > 0)
509
 
        memset(((guchar *)decoder) + sizeof(*decoder), 0, sub_size);
510
 
 
511
 
    if (klass->create && !klass->create(decoder))
512
 
        return FALSE;
513
 
    return TRUE;
 
481
  const GstVaapiDecoderClass *const klass =
 
482
      GST_VAAPI_DECODER_GET_CLASS (decoder);
 
483
  GstVideoCodecState *codec_state;
 
484
  guint sub_size;
 
485
 
 
486
  parser_state_init (&decoder->parser_state);
 
487
 
 
488
  codec_state = g_slice_new0 (GstVideoCodecState);
 
489
  codec_state->ref_count = 1;
 
490
  gst_video_info_init (&codec_state->info);
 
491
 
 
492
  decoder->user_data = NULL;
 
493
  decoder->display = gst_vaapi_display_ref (display);
 
494
  decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display);
 
495
  decoder->context = NULL;
 
496
  decoder->va_context = VA_INVALID_ID;
 
497
  decoder->codec = 0;
 
498
  decoder->codec_state = codec_state;
 
499
  decoder->codec_state_changed_func = NULL;
 
500
  decoder->codec_state_changed_data = NULL;
 
501
 
 
502
  decoder->buffers = g_async_queue_new_full ((GDestroyNotify) gst_buffer_unref);
 
503
  decoder->frames = g_async_queue_new_full ((GDestroyNotify)
 
504
      gst_video_codec_frame_unref);
 
505
 
 
506
  if (!set_caps (decoder, caps))
 
507
    return FALSE;
 
508
 
 
509
  sub_size = GST_VAAPI_MINI_OBJECT_CLASS (klass)->size - sizeof (*decoder);
 
510
  if (sub_size > 0)
 
511
    memset (((guchar *) decoder) + sizeof (*decoder), 0, sub_size);
 
512
 
 
513
  if (klass->create && !klass->create (decoder))
 
514
    return FALSE;
 
515
  return TRUE;
514
516
}
515
517
 
516
518
GstVaapiDecoder *
517
 
gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass,
518
 
    GstVaapiDisplay *display, GstCaps *caps)
 
519
gst_vaapi_decoder_new (const GstVaapiDecoderClass * klass,
 
520
    GstVaapiDisplay * display, GstCaps * caps)
519
521
{
520
 
    GstVaapiDecoder *decoder;
521
 
 
522
 
    g_return_val_if_fail(display != NULL, NULL);
523
 
    g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
524
 
 
525
 
    decoder = (GstVaapiDecoder *)
526
 
        gst_vaapi_mini_object_new(GST_VAAPI_MINI_OBJECT_CLASS(klass));
527
 
    if (!decoder)
528
 
        return NULL;
529
 
 
530
 
    if (!gst_vaapi_decoder_init(decoder, display, caps))
531
 
        goto error;
532
 
    return decoder;
 
522
  GstVaapiDecoder *decoder;
 
523
 
 
524
  g_return_val_if_fail (display != NULL, NULL);
 
525
  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
526
 
 
527
  decoder = (GstVaapiDecoder *)
 
528
      gst_vaapi_mini_object_new (GST_VAAPI_MINI_OBJECT_CLASS (klass));
 
529
  if (!decoder)
 
530
    return NULL;
 
531
 
 
532
  if (!gst_vaapi_decoder_init (decoder, display, caps))
 
533
    goto error;
 
534
  return decoder;
533
535
 
534
536
error:
535
 
    gst_vaapi_decoder_unref(decoder);
536
 
    return NULL;
 
537
  gst_vaapi_decoder_unref (decoder);
 
538
  return NULL;
537
539
}
538
540
 
539
541
/**
545
547
 * Returns: The same @decoder argument
546
548
 */
547
549
GstVaapiDecoder *
548
 
gst_vaapi_decoder_ref(GstVaapiDecoder *decoder)
 
550
gst_vaapi_decoder_ref (GstVaapiDecoder * decoder)
549
551
{
550
 
    return gst_vaapi_object_ref(decoder);
 
552
  return gst_vaapi_object_ref (decoder);
551
553
}
552
554
 
553
555
/**
558
560
 * the reference count reaches zero, the decoder will be free'd.
559
561
 */
560
562
void
561
 
gst_vaapi_decoder_unref(GstVaapiDecoder *decoder)
 
563
gst_vaapi_decoder_unref (GstVaapiDecoder * decoder)
562
564
{
563
 
    gst_vaapi_object_unref(decoder);
 
565
  gst_vaapi_object_unref (decoder);
564
566
}
565
567
 
566
568
/**
573
575
 * a valid decoder. However, @new_decoder can be NULL.
574
576
 */
575
577
void
576
 
gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr,
577
 
    GstVaapiDecoder *new_decoder)
 
578
gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr,
 
579
    GstVaapiDecoder * new_decoder)
578
580
{
579
 
    gst_vaapi_object_replace(old_decoder_ptr, new_decoder);
 
581
  gst_vaapi_object_replace (old_decoder_ptr, new_decoder);
580
582
}
581
583
 
582
584
/**
588
590
 * Return value: the user-defined data associated with the @decoder
589
591
 */
590
592
gpointer
591
 
gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder)
 
593
gst_vaapi_decoder_get_user_data (GstVaapiDecoder * decoder)
592
594
{
593
 
    g_return_val_if_fail(decoder != NULL, NULL);
 
595
  g_return_val_if_fail (decoder != NULL, NULL);
594
596
 
595
 
    return decoder->user_data;
 
597
  return decoder->user_data;
596
598
}
597
599
 
598
600
/**
604
606
 * attached value with gst_vaapi_decoder_get_user_data() function.
605
607
 */
606
608
void
607
 
gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data)
 
609
gst_vaapi_decoder_set_user_data (GstVaapiDecoder * decoder, gpointer user_data)
608
610
{
609
 
    g_return_if_fail(decoder != NULL);
 
611
  g_return_if_fail (decoder != NULL);
610
612
 
611
 
    decoder->user_data = user_data;
 
613
  decoder->user_data = user_data;
612
614
}
613
615
 
614
616
/**
620
622
 * Return value: the #GstVaapiCodec type for @decoder
621
623
 */
622
624
GstVaapiCodec
623
 
gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder)
 
625
gst_vaapi_decoder_get_codec (GstVaapiDecoder * decoder)
624
626
{
625
 
    g_return_val_if_fail(decoder != NULL, (GstVaapiCodec)0);
 
627
  g_return_val_if_fail (decoder != NULL, (GstVaapiCodec) 0);
626
628
 
627
 
    return decoder->codec;
 
629
  return decoder->codec;
628
630
}
629
631
 
630
632
/**
638
640
 * Return value: the #GstVideoCodecState object for @decoder
639
641
 */
640
642
GstVideoCodecState *
641
 
gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder)
 
643
gst_vaapi_decoder_get_codec_state (GstVaapiDecoder * decoder)
642
644
{
643
 
    g_return_val_if_fail(decoder != NULL, NULL);
 
645
  g_return_val_if_fail (decoder != NULL, NULL);
644
646
 
645
 
    return GST_VAAPI_DECODER_CODEC_STATE(decoder);
 
647
  return GST_VAAPI_DECODER_CODEC_STATE (decoder);
646
648
}
647
649
 
648
650
/**
655
657
 * state changes.
656
658
 */
657
659
void
658
 
gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder,
 
660
gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder,
659
661
    GstVaapiDecoderStateChangedFunc func, gpointer user_data)
660
662
{
661
 
    g_return_if_fail(decoder != NULL);
 
663
  g_return_if_fail (decoder != NULL);
662
664
 
663
 
    decoder->codec_state_changed_func = func;
664
 
    decoder->codec_state_changed_data = user_data;
 
665
  decoder->codec_state_changed_func = func;
 
666
  decoder->codec_state_changed_data = user_data;
665
667
}
666
668
 
667
669
/**
674
676
 * Return value: the @decoder caps
675
677
 */
676
678
GstCaps *
677
 
gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder)
 
679
gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder)
678
680
{
679
 
    return get_caps(decoder);
 
681
  return get_caps (decoder);
680
682
}
681
683
 
682
684
/**
695
697
 * Return value: %TRUE on success
696
698
 */
697
699
gboolean
698
 
gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf)
 
700
gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf)
699
701
{
700
 
    g_return_val_if_fail(decoder != NULL, FALSE);
 
702
  g_return_val_if_fail (decoder != NULL, FALSE);
701
703
 
702
 
    if (buf) {
703
 
        if (gst_buffer_get_size(buf) == 0)
704
 
            return TRUE;
705
 
        buf = gst_buffer_ref(buf);
706
 
    }
707
 
    return push_buffer(decoder, buf);
 
704
  if (buf) {
 
705
    if (gst_buffer_get_size (buf) == 0)
 
706
      return TRUE;
 
707
    buf = gst_buffer_ref (buf);
 
708
  }
 
709
  return push_buffer (decoder, buf);
708
710
}
709
711
 
710
712
/**
722
724
 * Return value: a #GstVaapiDecoderStatus
723
725
 */
724
726
GstVaapiDecoderStatus
725
 
gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder,
726
 
    GstVaapiSurfaceProxy **out_proxy_ptr)
 
727
gst_vaapi_decoder_get_surface (GstVaapiDecoder * decoder,
 
728
    GstVaapiSurfaceProxy ** out_proxy_ptr)
727
729
{
728
 
    GstVideoCodecFrame *frame;
729
 
    GstVaapiDecoderStatus status;
730
 
 
731
 
    g_return_val_if_fail(decoder != NULL,
732
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
733
 
    g_return_val_if_fail(out_proxy_ptr != NULL,
734
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
735
 
 
736
 
    do {
737
 
        frame = pop_frame(decoder, 0);
738
 
        while (frame) {
739
 
            if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(frame)) {
740
 
                GstVaapiSurfaceProxy * const proxy = frame->user_data;
741
 
                proxy->timestamp = frame->pts;
742
 
                proxy->duration = frame->duration;
743
 
                *out_proxy_ptr = gst_vaapi_surface_proxy_ref(proxy);
744
 
                gst_video_codec_frame_unref(frame);
745
 
                return GST_VAAPI_DECODER_STATUS_SUCCESS;
746
 
            }
747
 
            gst_video_codec_frame_unref(frame);
748
 
            frame = pop_frame(decoder, 0);
749
 
        }
750
 
        status = decode_step(decoder);
751
 
    } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
752
 
 
753
 
    *out_proxy_ptr = NULL;
754
 
    return status;
 
730
  GstVideoCodecFrame *frame;
 
731
  GstVaapiDecoderStatus status;
 
732
 
 
733
  g_return_val_if_fail (decoder != NULL,
 
734
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
735
  g_return_val_if_fail (out_proxy_ptr != NULL,
 
736
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
737
 
 
738
  do {
 
739
    frame = pop_frame (decoder, 0);
 
740
    while (frame) {
 
741
      if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (frame)) {
 
742
        GstVaapiSurfaceProxy *const proxy = frame->user_data;
 
743
        proxy->timestamp = frame->pts;
 
744
        proxy->duration = frame->duration;
 
745
        *out_proxy_ptr = gst_vaapi_surface_proxy_ref (proxy);
 
746
        gst_video_codec_frame_unref (frame);
 
747
        return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
748
      }
 
749
      gst_video_codec_frame_unref (frame);
 
750
      frame = pop_frame (decoder, 0);
 
751
    }
 
752
    status = decode_step (decoder);
 
753
  } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
 
754
 
 
755
  *out_proxy_ptr = NULL;
 
756
  return status;
755
757
}
756
758
 
757
759
/**
775
777
 * Return value: a #GstVaapiDecoderStatus
776
778
 */
777
779
GstVaapiDecoderStatus
778
 
gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder,
779
 
    GstVideoCodecFrame **out_frame_ptr)
 
780
gst_vaapi_decoder_get_frame (GstVaapiDecoder * decoder,
 
781
    GstVideoCodecFrame ** out_frame_ptr)
780
782
{
781
 
    return gst_vaapi_decoder_get_frame_with_timeout(decoder, out_frame_ptr, 0);
 
783
  return gst_vaapi_decoder_get_frame_with_timeout (decoder, out_frame_ptr, 0);
782
784
}
783
785
 
784
786
/**
800
802
 * Return value: a #GstVaapiDecoderStatus
801
803
 */
802
804
GstVaapiDecoderStatus
803
 
gst_vaapi_decoder_get_frame_with_timeout(GstVaapiDecoder *decoder,
804
 
    GstVideoCodecFrame **out_frame_ptr, guint64 timeout)
 
805
gst_vaapi_decoder_get_frame_with_timeout (GstVaapiDecoder * decoder,
 
806
    GstVideoCodecFrame ** out_frame_ptr, guint64 timeout)
805
807
{
806
 
    GstVideoCodecFrame *out_frame;
807
 
 
808
 
    g_return_val_if_fail(decoder != NULL,
809
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
810
 
    g_return_val_if_fail(out_frame_ptr != NULL,
811
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
812
 
 
813
 
    out_frame = pop_frame(decoder, timeout);
814
 
    if (!out_frame)
815
 
        return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
 
808
  GstVideoCodecFrame *out_frame;
 
809
 
 
810
  g_return_val_if_fail (decoder != NULL,
 
811
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
812
  g_return_val_if_fail (out_frame_ptr != NULL,
 
813
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
814
 
 
815
  out_frame = pop_frame (decoder, timeout);
 
816
  if (!out_frame)
 
817
    return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
816
818
 
817
819
#if !GST_CHECK_VERSION(1,0,0)
818
 
    if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) {
819
 
        const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS(out_frame->user_data);
820
 
        guint out_flags = 0;
 
820
  if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) {
 
821
    const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS (out_frame->user_data);
 
822
    guint out_flags = 0;
821
823
 
822
 
        if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF)
823
 
            out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF;
824
 
        if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF)
825
 
            out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF;
826
 
        if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD)
827
 
            out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD;
828
 
        GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, out_flags);
829
 
    }
 
824
    if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF)
 
825
      out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF;
 
826
    if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF)
 
827
      out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF;
 
828
    if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD)
 
829
      out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD;
 
830
    GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame, out_flags);
 
831
  }
830
832
#endif
831
833
 
832
 
    *out_frame_ptr = out_frame;
833
 
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
834
 
}
835
 
 
836
 
void
837
 
gst_vaapi_decoder_set_picture_size(
838
 
    GstVaapiDecoder    *decoder,
839
 
    guint               width,
840
 
    guint               height
841
 
)
842
 
{
843
 
    GstVideoCodecState * const codec_state = decoder->codec_state;
844
 
    gboolean size_changed = FALSE;
845
 
 
846
 
    if (codec_state->info.width != width) {
847
 
        GST_DEBUG("picture width changed to %d", width);
848
 
        codec_state->info.width = width;
849
 
        gst_caps_set_simple(codec_state->caps,
850
 
            "width", G_TYPE_INT, width, NULL);
851
 
        size_changed = TRUE;
852
 
    }
853
 
 
854
 
    if (codec_state->info.height != height) {
855
 
        GST_DEBUG("picture height changed to %d", height);
856
 
        codec_state->info.height = height;
857
 
        gst_caps_set_simple(codec_state->caps,
858
 
            "height", G_TYPE_INT, height, NULL);
859
 
        size_changed = TRUE;
860
 
    }
861
 
 
862
 
    if (size_changed)
863
 
        notify_codec_state_changed(decoder);
864
 
}
865
 
 
866
 
void
867
 
gst_vaapi_decoder_set_framerate(
868
 
    GstVaapiDecoder    *decoder,
869
 
    guint               fps_n,
870
 
    guint               fps_d
871
 
)
872
 
{
873
 
    GstVideoCodecState * const codec_state = decoder->codec_state;
874
 
 
875
 
    if (!fps_n || !fps_d)
876
 
        return;
877
 
 
878
 
    if (codec_state->info.fps_n != fps_n || codec_state->info.fps_d != fps_d) {
879
 
        GST_DEBUG("framerate changed to %u/%u", fps_n, fps_d);
880
 
        codec_state->info.fps_n = fps_n;
881
 
        codec_state->info.fps_d = fps_d;
882
 
        gst_caps_set_simple(codec_state->caps,
883
 
            "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
884
 
        notify_codec_state_changed(decoder);
885
 
    }
886
 
}
887
 
 
888
 
void
889
 
gst_vaapi_decoder_set_pixel_aspect_ratio(
890
 
    GstVaapiDecoder    *decoder,
891
 
    guint               par_n,
892
 
    guint               par_d
893
 
)
894
 
{
895
 
    GstVideoCodecState * const codec_state = decoder->codec_state;
896
 
 
897
 
    if (!par_n || !par_d)
898
 
        return;
899
 
 
900
 
    if (codec_state->info.par_n != par_n || codec_state->info.par_d != par_d) {
901
 
        GST_DEBUG("pixel-aspect-ratio changed to %u/%u", par_n, par_d);
902
 
        codec_state->info.par_n = par_n;
903
 
        codec_state->info.par_d = par_d;
904
 
        gst_caps_set_simple(codec_state->caps,
905
 
            "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
906
 
        notify_codec_state_changed(decoder);
907
 
    }
 
834
  *out_frame_ptr = out_frame;
 
835
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
836
}
 
837
 
 
838
void
 
839
gst_vaapi_decoder_set_picture_size (GstVaapiDecoder * decoder,
 
840
    guint width, guint height)
 
841
{
 
842
  GstVideoCodecState *const codec_state = decoder->codec_state;
 
843
  gboolean size_changed = FALSE;
 
844
 
 
845
  if (codec_state->info.width != width) {
 
846
    GST_DEBUG ("picture width changed to %d", width);
 
847
    codec_state->info.width = width;
 
848
    gst_caps_set_simple (codec_state->caps, "width", G_TYPE_INT, width, NULL);
 
849
    size_changed = TRUE;
 
850
  }
 
851
 
 
852
  if (codec_state->info.height != height) {
 
853
    GST_DEBUG ("picture height changed to %d", height);
 
854
    codec_state->info.height = height;
 
855
    gst_caps_set_simple (codec_state->caps, "height", G_TYPE_INT, height, NULL);
 
856
    size_changed = TRUE;
 
857
  }
 
858
 
 
859
  if (size_changed)
 
860
    notify_codec_state_changed (decoder);
 
861
}
 
862
 
 
863
void
 
864
gst_vaapi_decoder_set_framerate (GstVaapiDecoder * decoder,
 
865
    guint fps_n, guint fps_d)
 
866
{
 
867
  GstVideoCodecState *const codec_state = decoder->codec_state;
 
868
 
 
869
  if (!fps_n || !fps_d)
 
870
    return;
 
871
 
 
872
  if (codec_state->info.fps_n != fps_n || codec_state->info.fps_d != fps_d) {
 
873
    GST_DEBUG ("framerate changed to %u/%u", fps_n, fps_d);
 
874
    codec_state->info.fps_n = fps_n;
 
875
    codec_state->info.fps_d = fps_d;
 
876
    gst_caps_set_simple (codec_state->caps,
 
877
        "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
 
878
    notify_codec_state_changed (decoder);
 
879
  }
 
880
}
 
881
 
 
882
void
 
883
gst_vaapi_decoder_set_pixel_aspect_ratio (GstVaapiDecoder * decoder,
 
884
    guint par_n, guint par_d)
 
885
{
 
886
  GstVideoCodecState *const codec_state = decoder->codec_state;
 
887
 
 
888
  if (!par_n || !par_d)
 
889
    return;
 
890
 
 
891
  if (codec_state->info.par_n != par_n || codec_state->info.par_d != par_d) {
 
892
    GST_DEBUG ("pixel-aspect-ratio changed to %u/%u", par_n, par_d);
 
893
    codec_state->info.par_n = par_n;
 
894
    codec_state->info.par_d = par_d;
 
895
    gst_caps_set_simple (codec_state->caps,
 
896
        "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
 
897
    notify_codec_state_changed (decoder);
 
898
  }
908
899
}
909
900
 
910
901
static const gchar *
911
 
gst_interlace_mode_to_string(GstVideoInterlaceMode mode)
 
902
gst_interlace_mode_to_string (GstVideoInterlaceMode mode)
912
903
{
913
 
    switch (mode) {
914
 
    case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE:  return "progressive";
915
 
    case GST_VIDEO_INTERLACE_MODE_INTERLEAVED:  return "interleaved";
916
 
    case GST_VIDEO_INTERLACE_MODE_MIXED:        return "mixed";
917
 
    }
918
 
    return "<unknown>";
 
904
  switch (mode) {
 
905
    case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE:
 
906
      return "progressive";
 
907
    case GST_VIDEO_INTERLACE_MODE_INTERLEAVED:
 
908
      return "interleaved";
 
909
    case GST_VIDEO_INTERLACE_MODE_MIXED:
 
910
      return "mixed";
 
911
  }
 
912
  return "<unknown>";
919
913
}
920
914
 
921
915
void
922
 
gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder,
 
916
gst_vaapi_decoder_set_interlace_mode (GstVaapiDecoder * decoder,
923
917
    GstVideoInterlaceMode mode)
924
918
{
925
 
    GstVideoCodecState * const codec_state = decoder->codec_state;
 
919
  GstVideoCodecState *const codec_state = decoder->codec_state;
926
920
 
927
 
    if (codec_state->info.interlace_mode != mode) {
928
 
        GST_DEBUG("interlace mode changed to %s",
929
 
                  gst_interlace_mode_to_string(mode));
930
 
        codec_state->info.interlace_mode = mode;
931
 
        gst_caps_set_simple(codec_state->caps, "interlaced",
932
 
            G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL);
933
 
        notify_codec_state_changed(decoder);
934
 
    }
 
921
  if (codec_state->info.interlace_mode != mode) {
 
922
    GST_DEBUG ("interlace mode changed to %s",
 
923
        gst_interlace_mode_to_string (mode));
 
924
    codec_state->info.interlace_mode = mode;
 
925
    gst_caps_set_simple (codec_state->caps, "interlaced",
 
926
        G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL);
 
927
    notify_codec_state_changed (decoder);
 
928
  }
935
929
}
936
930
 
937
931
void
938
 
gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced)
 
932
gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder,
 
933
    gboolean interlaced)
939
934
{
940
 
    gst_vaapi_decoder_set_interlace_mode(decoder,
941
 
        (interlaced ?
942
 
         GST_VIDEO_INTERLACE_MODE_INTERLEAVED :
943
 
         GST_VIDEO_INTERLACE_MODE_PROGRESSIVE));
 
935
  gst_vaapi_decoder_set_interlace_mode (decoder,
 
936
      (interlaced ?
 
937
          GST_VIDEO_INTERLACE_MODE_INTERLEAVED :
 
938
          GST_VIDEO_INTERLACE_MODE_PROGRESSIVE));
944
939
}
945
940
 
946
941
gboolean
947
 
gst_vaapi_decoder_ensure_context(
948
 
    GstVaapiDecoder     *decoder,
949
 
    GstVaapiContextInfo *cip
950
 
)
 
942
gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder,
 
943
    GstVaapiContextInfo * cip)
951
944
{
952
 
    gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height);
 
945
  gst_vaapi_decoder_set_picture_size (decoder, cip->width, cip->height);
953
946
 
954
 
    if (decoder->context) {
955
 
        if (!gst_vaapi_context_reset_full(decoder->context, cip))
956
 
            return FALSE;
957
 
    }
958
 
    else {
959
 
        decoder->context = gst_vaapi_context_new_full(decoder->display, cip);
960
 
        if (!decoder->context)
961
 
            return FALSE;
962
 
    }
963
 
    decoder->va_context = gst_vaapi_context_get_id(decoder->context);
964
 
    return TRUE;
 
947
  cip->usage = GST_VAAPI_CONTEXT_USAGE_DECODE;
 
948
  if (decoder->context) {
 
949
    if (!gst_vaapi_context_reset (decoder->context, cip))
 
950
      return FALSE;
 
951
  } else {
 
952
    decoder->context = gst_vaapi_context_new (decoder->display, cip);
 
953
    if (!decoder->context)
 
954
      return FALSE;
 
955
  }
 
956
  decoder->va_context = gst_vaapi_context_get_id (decoder->context);
 
957
  return TRUE;
965
958
}
966
959
 
967
960
void
968
 
gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder,
969
 
    GstVideoCodecFrame *frame)
970
 
{
971
 
    push_frame(decoder, frame);
972
 
}
973
 
 
974
 
GstVaapiDecoderStatus
975
 
gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder)
976
 
{
977
 
    if (decoder->context &&
978
 
        gst_vaapi_context_get_surface_count(decoder->context) < 1)
979
 
        return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE;
980
 
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
981
 
}
982
 
 
983
 
GstVaapiDecoderStatus
984
 
gst_vaapi_decoder_parse(GstVaapiDecoder *decoder,
985
 
    GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos,
986
 
    guint *got_unit_size_ptr, gboolean *got_frame_ptr)
987
 
{
988
 
    g_return_val_if_fail(decoder != NULL,
989
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
990
 
    g_return_val_if_fail(base_frame != NULL,
991
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
992
 
    g_return_val_if_fail(adapter != NULL,
993
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
994
 
    g_return_val_if_fail(got_unit_size_ptr != NULL,
995
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
996
 
    g_return_val_if_fail(got_frame_ptr != NULL,
997
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
998
 
 
999
 
    return do_parse(decoder, base_frame, adapter, at_eos,
1000
 
        got_unit_size_ptr, got_frame_ptr);
1001
 
}
1002
 
 
1003
 
GstVaapiDecoderStatus
1004
 
gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
1005
 
{
1006
 
    GstVaapiDecoderStatus status;
1007
 
 
1008
 
    g_return_val_if_fail(decoder != NULL,
1009
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
1010
 
    g_return_val_if_fail(frame != NULL,
1011
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
1012
 
    g_return_val_if_fail(frame->user_data != NULL,
1013
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
1014
 
 
1015
 
    status = gst_vaapi_decoder_check_status(decoder);
1016
 
    if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1017
 
        return status;
1018
 
    return do_decode(decoder, frame);
1019
 
}
1020
 
 
1021
 
GstVaapiDecoderStatus
1022
 
gst_vaapi_decoder_flush(GstVaapiDecoder *decoder)
1023
 
{
1024
 
    g_return_val_if_fail(decoder != NULL,
1025
 
        GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
1026
 
 
1027
 
    return do_flush(decoder);
1028
 
}
1029
 
 
1030
 
GstVaapiDecoderStatus
1031
 
gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder)
1032
 
{
1033
 
    GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder);
1034
 
    GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1035
 
    GstVaapiDecoderStatus status;
1036
 
    GstMapInfo map_info;
1037
 
    const guchar *buf;
1038
 
    guint buf_size;
1039
 
 
1040
 
    if (!codec_data)
1041
 
        return GST_VAAPI_DECODER_STATUS_SUCCESS;
1042
 
 
1043
 
    /* FIXME: add a meaningful error code? */
1044
 
    if (!klass->decode_codec_data)
1045
 
        return GST_VAAPI_DECODER_STATUS_SUCCESS;
1046
 
 
1047
 
    if (!gst_buffer_map(codec_data, &map_info, GST_MAP_READ)) {
1048
 
        GST_ERROR("failed to map buffer");
1049
 
        return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1050
 
    }
1051
 
 
1052
 
    buf      = map_info.data;
1053
 
    buf_size = map_info.size;
1054
 
    if (G_LIKELY(buf && buf_size > 0))
1055
 
        status = klass->decode_codec_data(decoder, buf, buf_size);
1056
 
    else
1057
 
        status = GST_VAAPI_DECODER_STATUS_SUCCESS;
1058
 
    gst_buffer_unmap(codec_data, &map_info);
 
961
gst_vaapi_decoder_push_frame (GstVaapiDecoder * decoder,
 
962
    GstVideoCodecFrame * frame)
 
963
{
 
964
  push_frame (decoder, frame);
 
965
}
 
966
 
 
967
GstVaapiDecoderStatus
 
968
gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder)
 
969
{
 
970
  if (decoder->context &&
 
971
      gst_vaapi_context_get_surface_count (decoder->context) < 1)
 
972
    return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE;
 
973
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
974
}
 
975
 
 
976
GstVaapiDecoderStatus
 
977
gst_vaapi_decoder_parse (GstVaapiDecoder * decoder,
 
978
    GstVideoCodecFrame * base_frame, GstAdapter * adapter, gboolean at_eos,
 
979
    guint * got_unit_size_ptr, gboolean * got_frame_ptr)
 
980
{
 
981
  g_return_val_if_fail (decoder != NULL,
 
982
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
983
  g_return_val_if_fail (base_frame != NULL,
 
984
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
985
  g_return_val_if_fail (adapter != NULL,
 
986
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
987
  g_return_val_if_fail (got_unit_size_ptr != NULL,
 
988
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
989
  g_return_val_if_fail (got_frame_ptr != NULL,
 
990
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
991
 
 
992
  return do_parse (decoder, base_frame, adapter, at_eos,
 
993
      got_unit_size_ptr, got_frame_ptr);
 
994
}
 
995
 
 
996
GstVaapiDecoderStatus
 
997
gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame)
 
998
{
 
999
  GstVaapiDecoderStatus status;
 
1000
 
 
1001
  g_return_val_if_fail (decoder != NULL,
 
1002
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
1003
  g_return_val_if_fail (frame != NULL,
 
1004
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
1005
  g_return_val_if_fail (frame->user_data != NULL,
 
1006
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
1007
 
 
1008
  status = gst_vaapi_decoder_check_status (decoder);
 
1009
  if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1059
1010
    return status;
 
1011
  return do_decode (decoder, frame);
 
1012
}
 
1013
 
 
1014
GstVaapiDecoderStatus
 
1015
gst_vaapi_decoder_flush (GstVaapiDecoder * decoder)
 
1016
{
 
1017
  g_return_val_if_fail (decoder != NULL,
 
1018
      GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER);
 
1019
 
 
1020
  return do_flush (decoder);
 
1021
}
 
1022
 
 
1023
GstVaapiDecoderStatus
 
1024
gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder)
 
1025
{
 
1026
  GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder);
 
1027
  GstBuffer *const codec_data = GST_VAAPI_DECODER_CODEC_DATA (decoder);
 
1028
  GstVaapiDecoderStatus status;
 
1029
  GstMapInfo map_info;
 
1030
  const guchar *buf;
 
1031
  guint buf_size;
 
1032
 
 
1033
  if (!codec_data)
 
1034
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
1035
 
 
1036
  /* FIXME: add a meaningful error code? */
 
1037
  if (!klass->decode_codec_data)
 
1038
    return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
1039
 
 
1040
  if (!gst_buffer_map (codec_data, &map_info, GST_MAP_READ)) {
 
1041
    GST_ERROR ("failed to map buffer");
 
1042
    return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
 
1043
  }
 
1044
 
 
1045
  buf = map_info.data;
 
1046
  buf_size = map_info.size;
 
1047
  if (G_LIKELY (buf && buf_size > 0))
 
1048
    status = klass->decode_codec_data (decoder, buf, buf_size);
 
1049
  else
 
1050
    status = GST_VAAPI_DECODER_STATUS_SUCCESS;
 
1051
  gst_buffer_unmap (codec_data, &map_info);
 
1052
  return status;
1060
1053
}