summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2019-12-28 19:18:12 +0100
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-15 07:30:15 +0000
commit9da5196b5a5c1e8a4c5023f8ba9d8e7dad108cd5 (patch)
treeac73d3212e8dfa553cc133a0a107c8aedd6d3d65
parent1364070eca040306ea42bfdd59d09c80022d166a (diff)
Remove all FEI related
FEI encoders are not actively mantained neither tested, and it is using infrastructure that is changing and FEI is stopping this effort. Also it is required to rethink how FEI can be used in GStreamer.
-rw-r--r--gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c119
-rw-r--r--gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h27
-rw-r--r--gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h10
-rw-r--r--gst-libs/gst/vaapi/gstvaapicontext.c8
-rw-r--r--gst-libs/gst/vaapi/gstvaapicontext.h2
-rw-r--r--gst-libs/gst/vaapi/gstvaapidisplay.c3
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder.c14
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c4544
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h69
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_objects.c9
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_objects.h12
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_priv.h3
-rw-r--r--gst-libs/gst/vaapi/gstvaapifei_objects.c386
-rw-r--r--gst-libs/gst/vaapi/gstvaapifei_objects.h112
-rw-r--r--gst-libs/gst/vaapi/gstvaapifei_objects_priv.h236
-rw-r--r--gst-libs/gst/vaapi/gstvaapifeienc_h264.c2452
-rw-r--r--gst-libs/gst/vaapi/gstvaapifeienc_h264.h76
-rw-r--r--gst-libs/gst/vaapi/gstvaapifeipak_h264.c1915
-rw-r--r--gst-libs/gst/vaapi/gstvaapifeipak_h264.h94
-rw-r--r--gst-libs/gst/vaapi/gstvaapifeiutils_h264.c222
-rw-r--r--gst-libs/gst/vaapi/gstvaapifeiutils_h264.h215
-rw-r--r--gst-libs/gst/vaapi/gstvaapiprofile.c3
-rw-r--r--gst-libs/gst/vaapi/gstvaapiprofile.h2
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurfaceproxy.c270
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurfaceproxy.h44
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h9
-rw-r--r--gst-libs/gst/vaapi/meson.build17
-rw-r--r--gst/vaapi/gstvaapi.c13
-rw-r--r--gst/vaapi/gstvaapiencode.c21
-rw-r--r--gst/vaapi/gstvaapiencode.h17
-rw-r--r--gst/vaapi/gstvaapiencode_h264_fei.c513
-rw-r--r--gst/vaapi/gstvaapiencode_h264_fei.h72
-rw-r--r--gst/vaapi/gstvaapifeivideometa.c210
-rw-r--r--gst/vaapi/gstvaapifeivideometa.h80
-rw-r--r--gst/vaapi/meson.build7
-rw-r--r--meson.build2
-rw-r--r--tests/internal/meson.build7
-rw-r--r--tests/internal/test-fei-enc-in.c680
-rw-r--r--tests/internal/test-fei-enc-out.c300
39 files changed, 1 insertions, 12794 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c
index c0adfcbf..ececae9c 100644
--- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c
+++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c
@@ -54,19 +54,6 @@ coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy)
/* Notify the user function that the object is now destroyed */
if (proxy->destroy_func)
proxy->destroy_func (proxy->destroy_data);
-
-#if USE_H264_FEI_ENCODER
- if (proxy->mbcode)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mbcode, NULL);
- if (proxy->mv)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mv, NULL);
- if (proxy->dist)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->dist, NULL);
-#endif
-
}
static inline const GstVaapiMiniObjectClass *
@@ -108,11 +95,6 @@ gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool)
proxy->user_data_destroy = NULL;
proxy->pool = gst_vaapi_video_pool_ref (GST_VAAPI_VIDEO_POOL (pool));
proxy->buffer = gst_vaapi_video_pool_get_object (proxy->pool);
-#if USE_H264_FEI_ENCODER
- proxy->mv = NULL;
- proxy->mbcode = NULL;
- proxy->dist = NULL;
-#endif
if (!proxy->buffer)
goto error;
gst_mini_object_ref (GST_MINI_OBJECT_CAST (proxy->buffer));
@@ -272,104 +254,3 @@ gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy,
coded_buffer_proxy_set_user_data (proxy, user_data, destroy_func);
}
-
-#if USE_H264_FEI_ENCODER
-
-/**
- * gst_vaapi_coded_buffer_proxy_get_fei_mb_code:
- * @proxy: a #GstVaapiCodedBufferProxy
- *
- * Returns the #GstVaapiEncFeiMbCode stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiMbcode, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiMbCode *
-gst_vaapi_coded_buffer_proxy_get_fei_mbcode (GstVaapiCodedBufferProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, 0);
- return proxy->mbcode;
-}
-
-/**
- * gst_vaapi_coded_buffer_proxy_get_fei_mv:
- * @proxy: a #GstVaapiCodedBufferProxy
- *
- * Returns the #GstVaapiEncFeiMv stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiMv, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiMv *
-gst_vaapi_coded_buffer_proxy_get_fei_mv (GstVaapiCodedBufferProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, 0);
- return proxy->mv;
-}
-
-/**
- * gst_vaapi_coded_buffer_proxy_get_fei_distortion:
- * @proxy: a #GstVaapiCodedBufferProxy
- *
- * Returns the #GstVaapiEncFeiDistortion stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiDistortion, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiDistortion *
-gst_vaapi_coded_buffer_proxy_get_fei_distortion (GstVaapiCodedBufferProxy *
- proxy)
-{
- g_return_val_if_fail (proxy != NULL, 0);
- return proxy->dist;
-}
-
-/**
- * gst_vaapi_coded_buffer_proxy_set_fei_mb_code:
- * @proxy: #GstVaapiCodedBufferProxy
- * @mbcode: the #GstVaapiEncFeiMbCode to be stored in @proxy
- *
- * Associates the @mbcode with the @proxy
- */
-void
-gst_vaapi_coded_buffer_proxy_set_fei_mb_code (GstVaapiCodedBufferProxy * proxy,
- GstVaapiEncFeiMbCode * mbcode)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mbcode, (GstVaapiFeiCodecObject *) mbcode);
-}
-
-/**
- * gst_vaapi_coded_buffer_proxy_set_fei_mv:
- * @proxy: #GstVaapiCodedBufferProxy
- * @mv: the #GstVaapiEncFeiMv to be stored in @proxy
- *
- * Associates the @mv with the @proxy
- */
-void
-gst_vaapi_coded_buffer_proxy_set_fei_mv (GstVaapiCodedBufferProxy * proxy,
- GstVaapiEncFeiMv * mv)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mv, (GstVaapiFeiCodecObject *) mv);
-}
-
-/**
- * gst_vaapi_coded_buffer_proxy_set_fei_distortion:
- * @proxy: #GstVaapiSurfaceProxy
- * @dist: the #GstVaapiEncFeiDistortion to be stored in @proxy
- *
- * Associates the @dist with the @proxy
- */
-void
-gst_vaapi_coded_buffer_proxy_set_fei_distortion (GstVaapiCodedBufferProxy *
- proxy, GstVaapiEncFeiDistortion * dist)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->dist, (GstVaapiFeiCodecObject *) dist);
-}
-
-#endif
diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h
index 4514db92..4968c630 100644
--- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h
+++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h
@@ -26,10 +26,6 @@
#include <gst/vaapi/gstvaapicodedbuffer.h>
#include <gst/vaapi/gstvaapicodedbufferpool.h>
-#if USE_H264_FEI_ENCODER
-#include <gst/vaapi/gstvaapifei_objects.h>
-#endif
-
G_BEGIN_DECLS
/**
@@ -81,29 +77,6 @@ void
gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy,
gpointer user_data, GDestroyNotify destroy_func);
-#if USE_H264_FEI_ENCODER
-
-GstVaapiEncFeiMbCode *
-gst_vaapi_coded_buffer_proxy_get_fei_mbcode (GstVaapiCodedBufferProxy * proxy);
-
-GstVaapiEncFeiMv *
-gst_vaapi_coded_buffer_proxy_get_fei_mv (GstVaapiCodedBufferProxy * proxy);
-
-GstVaapiEncFeiDistortion *
-gst_vaapi_coded_buffer_proxy_get_fei_distortion (GstVaapiCodedBufferProxy * proxy);
-
-void
-gst_vaapi_coded_buffer_proxy_set_fei_mb_code (GstVaapiCodedBufferProxy * proxy,
- GstVaapiEncFeiMbCode *mbcode);
-void
-gst_vaapi_coded_buffer_proxy_set_fei_mv (GstVaapiCodedBufferProxy * proxy,
- GstVaapiEncFeiMv *mv);
-void
-gst_vaapi_coded_buffer_proxy_set_fei_distortion (GstVaapiCodedBufferProxy * proxy,
- GstVaapiEncFeiDistortion *dist);
-
-#endif
-
G_END_DECLS
#endif /* GST_VAAPI_CODED_BUFFER_PROXY_H */
diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h
index bc91a9cc..6feb8f9c 100644
--- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h
@@ -26,10 +26,6 @@
#include "gstvaapicodedbuffer_priv.h"
#include "gstvaapiminiobject.h"
-#if USE_H264_FEI_ENCODER
-#include <gst/vaapi/gstvaapifei_objects.h>
-#endif
-
G_BEGIN_DECLS
#define GST_VAAPI_CODED_BUFFER_PROXY(proxy) \
@@ -46,12 +42,6 @@ struct _GstVaapiCodedBufferProxy
gpointer destroy_data;
GDestroyNotify user_data_destroy;
gpointer user_data;
-
-#if USE_H264_FEI_ENCODER
- GstVaapiEncFeiMbCode *mbcode;
- GstVaapiEncFeiMv *mv;
- GstVaapiEncFeiDistortion *dist;
-#endif
};
/**
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c
index 7c07cce1..69b7b631 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.c
+++ b/gst-libs/gst/vaapi/gstvaapicontext.c
@@ -318,14 +318,6 @@ config_create (GstVaapiContext * context)
g_assert (attrib_index < G_N_ELEMENTS (attribs));
}
#endif
-#if USE_H264_FEI_ENCODER
- if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) {
- attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType;
- attrib = &attribs[++attrib_index];
- g_assert (attrib_index < G_N_ELEMENTS (attribs));
- /* FIXME: Query the read-only supported MV predictors */
- }
-#endif
break;
}
#endif
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h
index 70281714..26a1dfdc 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.h
+++ b/gst-libs/gst/vaapi/gstvaapicontext.h
@@ -62,7 +62,6 @@ typedef enum {
* @packed_headers: notify encoder that packed headers are submitted (mask).
* @roi_capability: if encoder supports regions-of-interest.
* @roi_num_supported: The number of regions-of-interest supported.
- * @fei_function: The functional mode for FEI Entrypoint (VA_FEI_FUNCTION_*).
*
* Extra configuration for encoding.
*/
@@ -72,7 +71,6 @@ struct _GstVaapiConfigInfoEncoder
guint packed_headers;
gboolean roi_capability;
guint roi_num_supported;
- guint fei_function;
};
/**
diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c
index cee1fce5..b1a61484 100644
--- a/gst-libs/gst/vaapi/gstvaapidisplay.c
+++ b/gst-libs/gst/vaapi/gstvaapidisplay.c
@@ -538,8 +538,7 @@ ensure_profiles (GstVaapiDisplay * display)
g_ptr_array_add (priv->decoders, cfg);
if ((cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE))
|| (cfg->entrypoints & ENTRY_POINT_FLAG (PICTURE_ENCODE))
- || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_LP))
- || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_FEI)))
+ || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_LP)))
g_ptr_array_add (priv->encoders, cfg);
}
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c
index e34db34a..1714707d 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder.c
@@ -730,7 +730,6 @@ set_context_info (GstVaapiEncoder * encoder)
GstVaapiConfigInfoEncoder *const config = &cip->config.encoder;
const GstVideoFormat format =
GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder));
- guint fei_function = config->fei_function;
g_assert (cip->profile != GST_VAAPI_PROFILE_UNKNOWN);
g_assert (cip->entrypoint != GST_VAAPI_ENTRYPOINT_INVALID);
@@ -748,7 +747,6 @@ set_context_info (GstVaapiEncoder * encoder)
config->packed_headers = get_packed_headers (encoder);
config->roi_capability =
get_roi_capability (encoder, &config->roi_num_supported);
- config->fei_function = fei_function;
return TRUE;
@@ -827,13 +825,6 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder)
if (!gst_vaapi_encoder_ensure_context (encoder))
goto error_reset_context;
- /* Currently only FEI entrypoint needed this.
- * FEI ENC+PAK requires two contexts where the first one is for ENC
- * and the second one is for PAK */
- if (klass->ensure_secondary_context
- && !klass->ensure_secondary_context (encoder))
- goto error_reset_secondary_context;
-
#if VA_CHECK_VERSION(0,36,0)
if (get_config_attribute (encoder, VAConfigAttribEncQualityRange,
&quality_level_max) && quality_level_max > 0) {
@@ -888,11 +879,6 @@ error_reset_context:
GST_ERROR ("failed to update VA context");
return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
}
-error_reset_secondary_context:
- {
- GST_ERROR ("failed to create/update secondary VA context");
- return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
- }
}
/**
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c
deleted file mode 100644
index 838c782e..00000000
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c
+++ /dev/null
@@ -1,4544 +0,0 @@
-/*
- * gstvaapiencoder_h264_fei.c - H.264 FEI encoder
- *
- * Copyright (C) 2016-2017 Intel Corporation
- * Author: Yi A Wang <yi.a.wang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-/* GValueArray has deprecated without providing an alternative in glib >= 2.32
- * See https://bugzilla.gnome.org/show_bug.cgi?id=667228
- */
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
-
-#include "sysdeps.h"
-#include <va/va.h>
-#include <va/va_enc_h264.h>
-#include <gst/base/gstbitwriter.h>
-#include <gst/codecparsers/gsth264parser.h>
-#include "gstvaapicompat.h"
-#include "gstvaapiencoder_priv.h"
-#include "gstvaapiutils_h264_priv.h"
-#include "gstvaapicodedbufferproxy_priv.h"
-#include "gstvaapisurfaceproxy_priv.h"
-#include "gstvaapisurface.h"
-#include "gstvaapifeiutils_h264.h"
-#include "gstvaapiencoder_h264_fei.h"
-#include "gstvaapifeienc_h264.h"
-#include "gstvaapifeipak_h264.h"
-#include "gstvaapiutils.h"
-#include "gstvaapiutils_core.h"
-#include "gstvaapifei_objects_priv.h"
-#define DEBUG 1
-#include "gstvaapidebug.h"
-
-static gboolean
-gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder *
- base_encoder);
-
-/* Define the maximum number of views supported */
-#define MAX_NUM_VIEWS 10
-
-/* Define the maximum value for view-id */
-#define MAX_VIEW_ID 1023
-
-/* Default CPB length (in milliseconds) */
-#define DEFAULT_CPB_LENGTH 1500
-
-/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */
-#define SX_CPB_SIZE 4
-
-/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */
-#define SX_BITRATE 6
-
-/* Define default rate control mode ("constant-qp") */
-#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
-
-/* Supported set of VA rate controls, within this implementation */
-#define SUPPORTED_RATECONTROLS \
- (GST_VAAPI_RATECONTROL_MASK (CQP) | \
- GST_VAAPI_RATECONTROL_MASK (CBR) | \
- GST_VAAPI_RATECONTROL_MASK (VBR) | \
- GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
-
-/* Supported set of tuning options, within this implementation */
-#define SUPPORTED_TUNE_OPTIONS \
- (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \
- GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \
- GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER))
-
-/* Supported set of VA packed headers, within this implementation */
-#define SUPPORTED_PACKED_HEADERS \
- (VA_ENC_PACKED_HEADER_SEQUENCE | \
- VA_ENC_PACKED_HEADER_PICTURE | \
- VA_ENC_PACKED_HEADER_SLICE | \
- VA_ENC_PACKED_HEADER_RAW_DATA | \
- VA_ENC_PACKED_HEADER_MISC)
-
-#define GST_H264_NAL_REF_IDC_NONE 0
-#define GST_H264_NAL_REF_IDC_LOW 1
-#define GST_H264_NAL_REF_IDC_MEDIUM 2
-#define GST_H264_NAL_REF_IDC_HIGH 3
-
-/* only for internal usage, values won't be equal to actual payload type */
-typedef enum
-{
- GST_VAAPI_H264_SEI_UNKNOWN = 0,
- GST_VAAPI_H264_SEI_BUF_PERIOD = (1 << 0),
- GST_VAAPI_H264_SEI_PIC_TIMING = (1 << 1)
-} GstVaapiH264SeiPayloadType;
-
-typedef struct
-{
- GstVaapiSurfaceProxy *pic;
- guint poc;
- guint frame_num;
-} GstVaapiEncoderH264FeiRef;
-
-typedef enum
-{
- GST_VAAPI_ENC_H264_REORD_NONE = 0,
- GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
- GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
-} GstVaapiEncH264ReorderState;
-
-typedef struct _GstVaapiH264ViewRefPool
-{
- GQueue ref_list;
- guint max_ref_frames;
- guint max_reflist0_count;
- guint max_reflist1_count;
-} GstVaapiH264ViewRefPool;
-
-typedef struct _GstVaapiH264ViewReorderPool
-{
- GQueue reorder_frame_list;
- guint reorder_state;
- guint frame_index;
- guint frame_count; /* monotonically increasing with in every idr period */
- guint cur_frame_num;
- guint cur_present_index;
-} GstVaapiH264ViewReorderPool;
-
-static inline gboolean
-_poc_greater_than (guint poc1, guint poc2, guint max_poc)
-{
- return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
-}
-
-/* Get slice_type value for H.264 specification */
-static guint8
-h264_get_slice_type (GstVaapiPictureType type)
-{
- switch (type) {
- case GST_VAAPI_PICTURE_TYPE_I:
- return GST_H264_I_SLICE;
- case GST_VAAPI_PICTURE_TYPE_P:
- return GST_H264_P_SLICE;
- case GST_VAAPI_PICTURE_TYPE_B:
- return GST_H264_B_SLICE;
- default:
- break;
- }
- return -1;
-}
-
-/* Get log2_max_frame_num value for H.264 specification */
-static guint
-h264_get_log2_max_frame_num (guint num)
-{
- guint ret = 0;
-
- while (num) {
- ++ret;
- num >>= 1;
- }
- if (ret <= 4)
- ret = 4;
- else if (ret > 10)
- ret = 10;
- /* must be greater than 4 */
- return ret;
-}
-
-/* Determines the cpbBrNalFactor based on the supplied profile */
-static guint
-h264_get_cpb_nal_factor (GstVaapiProfile profile)
-{
- guint f;
-
- /* Table A-2 */
- switch (profile) {
- case GST_VAAPI_PROFILE_H264_HIGH:
- f = 1500;
- break;
- case GST_VAAPI_PROFILE_H264_HIGH10:
- f = 3600;
- break;
- case GST_VAAPI_PROFILE_H264_HIGH_422:
- case GST_VAAPI_PROFILE_H264_HIGH_444:
- f = 4800;
- break;
- case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH:
- case GST_VAAPI_PROFILE_H264_STEREO_HIGH:
- f = 1500; /* H.10.2.1 (r) */
- break;
- default:
- f = 1200;
- break;
- }
- return f;
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- H.264 Bitstream Writer --- */
-/* ------------------------------------------------------------------------- */
-
-#define WRITE_UINT32(bs, val, nbits) do { \
- if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \
- GST_WARNING ("failed to write uint32, nbits: %d", nbits); \
- goto bs_error; \
- } \
- } while (0)
-
-#define WRITE_UE(bs, val) do { \
- if (!bs_write_ue (bs, val)) { \
- GST_WARNING ("failed to write ue(v)"); \
- goto bs_error; \
- } \
- } while (0)
-
-#define WRITE_SE(bs, val) do { \
- if (!bs_write_se (bs, val)) { \
- GST_WARNING ("failed to write se(v)"); \
- goto bs_error; \
- } \
- } while (0)
-
-/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */
-static gboolean
-bs_write_ue (GstBitWriter * bs, guint32 value)
-{
- guint32 size_in_bits = 0;
- guint32 tmp_value = ++value;
-
- while (tmp_value) {
- ++size_in_bits;
- tmp_value >>= 1;
- }
- if (size_in_bits > 1
- && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1))
- return FALSE;
- if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits))
- return FALSE;
- return TRUE;
-}
-
-/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */
-static gboolean
-bs_write_se (GstBitWriter * bs, gint32 value)
-{
- guint32 new_val;
-
- if (value <= 0)
- new_val = -(value << 1);
- else
- new_val = (value << 1) - 1;
-
- if (!bs_write_ue (bs, new_val))
- return FALSE;
- return TRUE;
-}
-
-/* Write the NAL unit header */
-static gboolean
-bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc,
- guint32 nal_unit_type)
-{
- WRITE_UINT32 (bs, 0, 1);
- WRITE_UINT32 (bs, nal_ref_idc, 2);
- WRITE_UINT32 (bs, nal_unit_type, 5);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write NAL unit header");
- return FALSE;
- }
-}
-
-/* Write the MVC NAL unit header extension */
-static gboolean
-bs_write_nal_header_mvc_extension (GstBitWriter * bs,
- GstVaapiEncPicture * picture, guint32 view_id)
-{
- guint32 svc_extension_flag = 0;
- guint32 non_idr_flag = 1;
- guint32 priority_id = 0;
- guint32 temporal_id = 0;
- guint32 anchor_pic_flag = 0;
- guint32 inter_view_flag = 0;
-
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- non_idr_flag = 0;
-
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
- anchor_pic_flag = 1;
- /* svc_extension_flag == 0 for mvc stream */
- WRITE_UINT32 (bs, svc_extension_flag, 1);
-
- WRITE_UINT32 (bs, non_idr_flag, 1);
- WRITE_UINT32 (bs, priority_id, 6);
- WRITE_UINT32 (bs, view_id, 10);
- WRITE_UINT32 (bs, temporal_id, 3);
- WRITE_UINT32 (bs, anchor_pic_flag, 1);
- WRITE_UINT32 (bs, inter_view_flag, 1);
- WRITE_UINT32 (bs, 1, 1);
-
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write NAL unit header");
- return FALSE;
- }
-}
-
-/* Write the NAL unit trailing bits */
-static gboolean
-bs_write_trailing_bits (GstBitWriter * bs)
-{
- if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
- goto bs_error;
- gst_bit_writer_align_bytes_unchecked (bs, 0);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write NAL unit trailing bits");
- return FALSE;
- }
-}
-
-/* Write an SPS NAL unit */
-static gboolean
-bs_write_sps_data (GstBitWriter * bs,
- const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
- const VAEncMiscParameterHRD * hrd_params)
-{
- guint8 profile_idc;
- guint32 constraint_set0_flag, constraint_set1_flag;
- guint32 constraint_set2_flag, constraint_set3_flag;
- guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
- gboolean nal_hrd_parameters_present_flag;
-
- guint32 b_qpprime_y_zero_transform_bypass = 0;
- guint32 residual_color_transform_flag = 0;
- guint32 pic_height_in_map_units =
- (seq_param->seq_fields.bits.frame_mbs_only_flag ?
- seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
- guint32 mb_adaptive_frame_field =
- !seq_param->seq_fields.bits.frame_mbs_only_flag;
- guint32 i = 0;
-
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
- profile == GST_VAAPI_PROFILE_H264_BASELINE ||
- profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
- constraint_set1_flag = /* A.2.2 (main profile constraints) */
- profile == GST_VAAPI_PROFILE_H264_MAIN ||
- profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
- constraint_set2_flag = 0;
- constraint_set3_flag = 0;
-
- /* profile_idc */
- WRITE_UINT32 (bs, profile_idc, 8);
- /* constraint_set0_flag */
- WRITE_UINT32 (bs, constraint_set0_flag, 1);
- /* constraint_set1_flag */
- WRITE_UINT32 (bs, constraint_set1_flag, 1);
- /* constraint_set2_flag */
- WRITE_UINT32 (bs, constraint_set2_flag, 1);
- /* constraint_set3_flag */
- WRITE_UINT32 (bs, constraint_set3_flag, 1);
- /* reserved_zero_4bits */
- WRITE_UINT32 (bs, 0, 4);
- /* level_idc */
- WRITE_UINT32 (bs, seq_param->level_idc, 8);
- /* seq_parameter_set_id */
- WRITE_UE (bs, seq_param->seq_parameter_set_id);
-
- if (profile == GST_VAAPI_PROFILE_H264_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) {
- /* for high profile */
- /* chroma_format_idc = 1, 4:2:0 */
- WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
- if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
- WRITE_UINT32 (bs, residual_color_transform_flag, 1);
- }
- /* bit_depth_luma_minus8 */
- WRITE_UE (bs, seq_param->bit_depth_luma_minus8);
- /* bit_depth_chroma_minus8 */
- WRITE_UE (bs, seq_param->bit_depth_chroma_minus8);
- /* b_qpprime_y_zero_transform_bypass */
- WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1);
-
- /* seq_scaling_matrix_present_flag */
- g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
- WRITE_UINT32 (bs,
- seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
-
-#if 0
- if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
- for (i = 0;
- i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
- i++) {
- gst_bit_writer_put_bits_uint8 (bs,
- seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
- if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
- g_assert (0);
- /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
- }
- }
- }
-#endif
- }
-
- /* log2_max_frame_num_minus4 */
- WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4);
- /* pic_order_cnt_type */
- WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type);
-
- if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
- /* log2_max_pic_order_cnt_lsb_minus4 */
- WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
- } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
- g_assert (0 && "only POC type 0 is supported");
- WRITE_UINT32 (bs,
- seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
- WRITE_SE (bs, seq_param->offset_for_non_ref_pic);
- WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field);
- WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle);
- for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
- WRITE_SE (bs, seq_param->offset_for_ref_frame[i]);
- }
- }
-
- /* num_ref_frames */
- WRITE_UE (bs, seq_param->max_num_ref_frames);
- /* gaps_in_frame_num_value_allowed_flag */
- WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1);
-
- /* pic_width_in_mbs_minus1 */
- WRITE_UE (bs, seq_param->picture_width_in_mbs - 1);
- /* pic_height_in_map_units_minus1 */
- WRITE_UE (bs, pic_height_in_map_units - 1);
- /* frame_mbs_only_flag */
- WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
-
- if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
- g_assert (0 && "only progressive frames encoding is supported");
- WRITE_UINT32 (bs, mb_adaptive_frame_field, 1);
- }
-
- /* direct_8x8_inference_flag */
- WRITE_UINT32 (bs, 0, 1);
- /* frame_cropping_flag */
- WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1);
-
- if (seq_param->frame_cropping_flag) {
- /* frame_crop_left_offset */
- WRITE_UE (bs, seq_param->frame_crop_left_offset);
- /* frame_crop_right_offset */
- WRITE_UE (bs, seq_param->frame_crop_right_offset);
- /* frame_crop_top_offset */
- WRITE_UE (bs, seq_param->frame_crop_top_offset);
- /* frame_crop_bottom_offset */
- WRITE_UE (bs, seq_param->frame_crop_bottom_offset);
- }
-
- /* vui_parameters_present_flag */
- WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
- if (seq_param->vui_parameters_present_flag) {
- /* aspect_ratio_info_present_flag */
- WRITE_UINT32 (bs,
- seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
- if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
- WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
- if (seq_param->aspect_ratio_idc == 0xFF) {
- WRITE_UINT32 (bs, seq_param->sar_width, 16);
- WRITE_UINT32 (bs, seq_param->sar_height, 16);
- }
- }
-
- /* overscan_info_present_flag */
- WRITE_UINT32 (bs, 0, 1);
- /* video_signal_type_present_flag */
- WRITE_UINT32 (bs, 0, 1);
- /* chroma_loc_info_present_flag */
- WRITE_UINT32 (bs, 0, 1);
-
- /* timing_info_present_flag */
- WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1);
- if (seq_param->vui_fields.bits.timing_info_present_flag) {
- WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32);
- WRITE_UINT32 (bs, seq_param->time_scale, 32);
- WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */
- }
-
- /* nal_hrd_parameters_present_flag */
- nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0;
- WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
- if (nal_hrd_parameters_present_flag) {
- /* hrd_parameters */
- /* cpb_cnt_minus1 */
- WRITE_UE (bs, 0);
- WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */
- WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */
-
- for (i = 0; i < 1; ++i) {
- /* bit_rate_value_minus1[0] */
- WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
- /* cpb_size_value_minus1[0] */
- WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
- /* cbr_flag[0] */
- WRITE_UINT32 (bs, 1, 1);
- }
- /* initial_cpb_removal_delay_length_minus1 */
- WRITE_UINT32 (bs, 23, 5);
- /* cpb_removal_delay_length_minus1 */
- WRITE_UINT32 (bs, 23, 5);
- /* dpb_output_delay_length_minus1 */
- WRITE_UINT32 (bs, 23, 5);
- /* time_offset_length */
- WRITE_UINT32 (bs, 23, 5);
- }
-
- /* vcl_hrd_parameters_present_flag */
- WRITE_UINT32 (bs, 0, 1);
-
- if (nal_hrd_parameters_present_flag
- || 0 /*vcl_hrd_parameters_present_flag */ ) {
- /* low_delay_hrd_flag */
- WRITE_UINT32 (bs, 0, 1);
- }
- /* pic_struct_present_flag */
- WRITE_UINT32 (bs, 1, 1);
- /* bs_restriction_flag */
- WRITE_UINT32 (bs, 0, 1);
- }
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SPS NAL unit");
- return FALSE;
- }
-}
-
-static gboolean
-bs_write_sps (GstBitWriter * bs,
- const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
- const VAEncMiscParameterHRD * hrd_params)
-{
- if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
- return FALSE;
-
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (bs);
-
- return FALSE;
-}
-
-static gboolean
-bs_write_subset_sps (GstBitWriter * bs,
- const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
- guint num_views, guint16 * view_ids,
- const VAEncMiscParameterHRD * hrd_params)
-{
- guint32 i, j, k;
-
- if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
- return FALSE;
-
- if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) {
- guint32 num_views_minus1, num_level_values_signalled_minus1;
-
- num_views_minus1 = num_views - 1;
- g_assert (num_views_minus1 < 1024);
-
- /* bit equal to one */
- WRITE_UINT32 (bs, 1, 1);
-
- WRITE_UE (bs, num_views_minus1);
-
- for (i = 0; i <= num_views_minus1; i++)
- WRITE_UE (bs, view_ids[i]);
-
- for (i = 1; i <= num_views_minus1; i++) {
- guint32 num_anchor_refs_l0 = 0;
- guint32 num_anchor_refs_l1 = 0;
-
- WRITE_UE (bs, num_anchor_refs_l0);
- for (j = 0; j < num_anchor_refs_l0; j++)
- WRITE_UE (bs, 0);
-
- WRITE_UE (bs, num_anchor_refs_l1);
- for (j = 0; j < num_anchor_refs_l1; j++)
- WRITE_UE (bs, 0);
- }
-
- for (i = 1; i <= num_views_minus1; i++) {
- guint32 num_non_anchor_refs_l0 = 0;
- guint32 num_non_anchor_refs_l1 = 0;
-
- WRITE_UE (bs, num_non_anchor_refs_l0);
- for (j = 0; j < num_non_anchor_refs_l0; j++)
- WRITE_UE (bs, 0);
-
- WRITE_UE (bs, num_non_anchor_refs_l1);
- for (j = 0; j < num_non_anchor_refs_l1; j++)
- WRITE_UE (bs, 0);
- }
-
- /* num level values signalled minus1 */
- num_level_values_signalled_minus1 = 0;
- g_assert (num_level_values_signalled_minus1 < 64);
- WRITE_UE (bs, num_level_values_signalled_minus1);
-
- for (i = 0; i <= num_level_values_signalled_minus1; i++) {
- guint16 num_applicable_ops_minus1 = 0;
- g_assert (num_applicable_ops_minus1 < 1024);
-
- WRITE_UINT32 (bs, seq_param->level_idc, 8);
- WRITE_UE (bs, num_applicable_ops_minus1);
-
- for (j = 0; j <= num_applicable_ops_minus1; j++) {
- guint8 temporal_id = 0;
- guint16 num_target_views_minus1 = 1;
-
- WRITE_UINT32 (bs, temporal_id, 3);
- WRITE_UE (bs, num_target_views_minus1);
-
- for (k = 0; k <= num_target_views_minus1; k++)
- WRITE_UE (bs, k);
-
- WRITE_UE (bs, num_views_minus1);
- }
- }
-
- /* mvc_vui_parameters_present_flag */
- WRITE_UINT32 (bs, 0, 1);
- }
-
- /* additional_extension2_flag */
- WRITE_UINT32 (bs, 0, 1);
-
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write subset SPS NAL unit");
- return FALSE;
- }
- return FALSE;
-}
-
-/* Write a PPS NAL unit */
-static gboolean
-bs_write_pps (GstBitWriter * bs,
- const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
-{
- guint32 num_slice_groups_minus1 = 0;
- guint32 pic_init_qs_minus26 = 0;
- guint32 redundant_pic_cnt_present_flag = 0;
-
- /* pic_parameter_set_id */
- WRITE_UE (bs, pic_param->pic_parameter_set_id);
- /* seq_parameter_set_id */
- WRITE_UE (bs, pic_param->seq_parameter_set_id);
- /* entropy_coding_mode_flag */
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
- /* pic_order_present_flag */
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1);
- /* slice_groups-1 */
- WRITE_UE (bs, num_slice_groups_minus1);
-
- if (num_slice_groups_minus1 > 0) {
- /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)");
- }
- WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1);
- WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1);
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);
- /* pic_init_qp_minus26 */
- WRITE_SE (bs, pic_param->pic_init_qp - 26);
- /* pic_init_qs_minus26 */
- WRITE_SE (bs, pic_init_qs_minus26);
- /* chroma_qp_index_offset */
- WRITE_SE (bs, pic_param->chroma_qp_index_offset);
-
- WRITE_UINT32 (bs,
- pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
- WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1);
-
- /* more_rbsp_data */
- if (profile == GST_VAAPI_PROFILE_H264_HIGH
- || profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH
- || profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) {
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
- WRITE_UINT32 (bs,
- pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
- if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
- g_assert (0 && "unsupported scaling lists");
- /* FIXME */
- /*
- for (i = 0; i <
- (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
- i++) {
- gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
- }
- */
- }
- WRITE_SE (bs, pic_param->second_chroma_qp_index_offset);
- }
-
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write PPS NAL unit");
- return FALSE;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- H.264 Encoder --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENCODER_H264_FEI_CAST(encoder) \
- ((GstVaapiEncoderH264Fei *)(encoder))
-
-struct _GstVaapiEncoderH264Fei
-{
- GstVaapiEncoder parent_instance;
- GstVaapiFeiEncH264 *feienc;
- GstVaapiFEIPakH264 *feipak;
-
- GstVaapiProfile profile;
- GstVaapiLevelH264 level;
- GstVaapiEntrypoint entrypoint;
- VAConfigID va_config;
- guint8 profile_idc;
- VABufferID coded_buf;
- guint8 max_profile_idc;
- guint8 hw_max_profile_idc;
- guint8 level_idc;
- guint32 idr_period;
- guint32 init_qp;
- guint32 min_qp;
- guint32 max_qp;
- guint32 num_slices;
- guint32 num_bframes;
- guint32 mb_width;
- guint32 mb_height;
- gboolean use_cabac;
- gboolean use_dct8x8;
- GstClockTime cts_offset;
- gboolean config_changed;
-
- /* frame, poc */
- guint32 max_frame_num;
- guint32 log2_max_frame_num;
- guint32 max_pic_order_cnt;
- guint32 log2_max_pic_order_cnt;
- guint32 idr_num;
- guint8 pic_order_cnt_type;
- guint8 delta_pic_order_always_zero_flag;
-
- GstBuffer *sps_data;
- GstBuffer *subset_sps_data;
- GstBuffer *pps_data;
-
- guint bitrate_bits; // bitrate (bits)
- guint cpb_length; // length of CPB buffer (ms)
- guint cpb_length_bits; // length of CPB buffer (bits)
- guint num_ref_frames;
-
- /* MVC */
- gboolean is_mvc;
- guint32 view_idx; /* View Order Index (VOIdx) */
- guint32 num_views;
- guint16 view_ids[MAX_NUM_VIEWS];
- GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS];
- GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS];
- gpointer ref_pool_ptr;
- /*Fei frame level control */
- gboolean is_fei_disabled;
- gboolean is_stats_out_enabled;
- guint search_window;
- guint len_sp;
- guint search_path;
- guint ref_width;
- guint ref_height;
- guint submb_part_mask;
- guint subpel_mode;
- guint intra_part_mask;
- guint intra_sad;
- guint inter_sad;
- guint num_mv_predictors_l0;
- guint num_mv_predictors_l1;
- guint adaptive_search;
- guint multi_predL0;
- guint multi_predL1;
- guint fei_mode;
-
-};
-
-/* Write a SEI buffering period payload */
-static gboolean
-bs_write_sei_buf_period (GstBitWriter * bs,
- GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture)
-{
- guint initial_cpb_removal_delay = 0;
- guint initial_cpb_removal_delay_offset = 0;
- guint8 initial_cpb_removal_delay_length = 24;
-
- /* sequence_parameter_set_id */
- WRITE_UE (bs, encoder->view_idx);
- /* NalHrdBpPresentFlag == TRUE */
- /* cpb_cnt_minus1 == 0 */
-
- /* decoding should start when the CPB fullness reaches half of cpb size
- * initial_cpb_remvoal_delay = (((cpb_length / 2) * 90000) / 1000) */
- initial_cpb_removal_delay = encoder->cpb_length * 45;
-
- /* initial_cpb_remvoal_dealy */
- WRITE_UINT32 (bs, initial_cpb_removal_delay,
- initial_cpb_removal_delay_length);
-
- /* initial_cpb_removal_delay_offset */
- WRITE_UINT32 (bs, initial_cpb_removal_delay_offset,
- initial_cpb_removal_delay_length);
-
- /* VclHrdBpPresentFlag == FALSE */
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Buffering Period SEI message");
- return FALSE;
- }
-}
-
-/* Write a SEI picture timing payload */
-static gboolean
-bs_write_sei_pic_timing (GstBitWriter * bs,
- GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture)
-{
- GstVaapiH264ViewReorderPool *reorder_pool = NULL;
- guint cpb_removal_delay;
- guint dpb_output_delay;
- guint8 cpb_removal_delay_length = 24;
- guint8 dpb_output_delay_length = 24;
- guint pic_struct = 0;
- guint clock_timestamp_flag = 0;
-
- reorder_pool = &encoder->reorder_pools[encoder->view_idx];
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- reorder_pool->frame_count = 0;
- else
- reorder_pool->frame_count++;
-
- /* clock-tick = no_units_in_tick/time_scale (C-1)
- * time_scale = FPS_N * 2 (E.2.1)
- * num_units_in_tick = FPS_D (E.2.1)
- * frame_duration = clock-tick * 2
- * so removal time for one frame is 2 clock-ticks.
- * but adding a tolerance of one frame duration,
- * which is 2 more clock-ticks */
- cpb_removal_delay = (reorder_pool->frame_count * 2 + 2);
-
- if (picture->type == GST_VAAPI_PICTURE_TYPE_B)
- dpb_output_delay = 0;
- else
- dpb_output_delay = picture->poc - reorder_pool->frame_count * 2;
-
- /* CpbDpbDelaysPresentFlag == 1 */
- WRITE_UINT32 (bs, cpb_removal_delay, cpb_removal_delay_length);
- WRITE_UINT32 (bs, dpb_output_delay, dpb_output_delay_length);
-
- /* pic_struct_present_flag == 1 */
- /* pic_struct */
- WRITE_UINT32 (bs, pic_struct, 4);
- /* clock_timestamp_flag */
- WRITE_UINT32 (bs, clock_timestamp_flag, 1);
-
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Picture Timing SEI message");
- return FALSE;
- }
-}
-
-/* Write a Slice NAL unit */
-static gboolean
-bs_write_slice (GstBitWriter * bs,
- const VAEncSliceParameterBufferH264 * slice_param,
- GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture)
-{
- const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- guint32 field_pic_flag = 0;
- guint32 ref_pic_list_modification_flag_l0 = 0;
- guint32 ref_pic_list_modification_flag_l1 = 0;
- guint32 no_output_of_prior_pics_flag = 0;
- guint32 long_term_reference_flag = 0;
- guint32 adaptive_ref_pic_marking_mode_flag = 0;
-
- /* first_mb_in_slice */
- WRITE_UE (bs, slice_param->macroblock_address);
- /* slice_type */
- WRITE_UE (bs, slice_param->slice_type);
- /* pic_parameter_set_id */
- WRITE_UE (bs, slice_param->pic_parameter_set_id);
- /* frame_num */
- WRITE_UINT32 (bs, picture->frame_num, encoder->log2_max_frame_num);
-
- /* XXX: only frames (i.e. non-interlaced) are supported for now */
- /* frame_mbs_only_flag == 0 */
-
- /* idr_pic_id */
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- WRITE_UE (bs, slice_param->idr_pic_id);
-
- /* XXX: only POC type 0 is supported */
- if (!encoder->pic_order_cnt_type) {
- WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb,
- encoder->log2_max_pic_order_cnt);
- /* bottom_field_pic_order_in_frame_present_flag is FALSE */
- if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
- WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom);
- } else if (encoder->pic_order_cnt_type == 1 &&
- !encoder->delta_pic_order_always_zero_flag) {
- WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]);
- if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
- WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]);
- }
- /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */
-
- /* only works for B-frames */
- if (slice_param->slice_type == GST_H264_B_SLICE)
- WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1);
-
- /* not supporting SP slices */
- if (slice_param->slice_type == 0 || slice_param->slice_type == 1) {
- WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1);
- if (slice_param->num_ref_idx_active_override_flag) {
- WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1);
- if (slice_param->slice_type == 1)
- WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1);
- }
- }
- /* XXX: not supporting custom reference picture list modifications */
- if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4))
- WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1);
- if (slice_param->slice_type == 1)
- WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1);
-
- /* we have: weighted_pred_flag == FALSE and */
- /* : weighted_bipred_idc == FALSE */
- if ((pic_param->pic_fields.bits.weighted_pred_flag &&
- (slice_param->slice_type == 0)) ||
- ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) &&
- (slice_param->slice_type == 1))) {
- /* XXXX: add pred_weight_table() */
- }
-
- /* dec_ref_pic_marking() */
- if (slice_param->slice_type == 0 || slice_param->slice_type == 2) {
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
- /* no_output_of_prior_pics_flag = 0 */
- WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1);
- /* long_term_reference_flag = 0 */
- WRITE_UINT32 (bs, long_term_reference_flag, 1);
- } else {
- /* only sliding_window reference picture marking mode is supported */
- /* adpative_ref_pic_marking_mode_flag = 0 */
- WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1);
- }
- }
-
- /* cabac_init_idc */
- if (pic_param->pic_fields.bits.entropy_coding_mode_flag &&
- slice_param->slice_type != 2)
- WRITE_UE (bs, slice_param->cabac_init_idc);
- /*slice_qp_delta */
- WRITE_SE (bs, slice_param->slice_qp_delta);
-
- /* XXX: only supporting I, P and B type slices */
- /* no sp_for_switch_flag and no slice_qs_delta */
-
- if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) {
- /* disable_deblocking_filter_idc */
- WRITE_UE (bs, slice_param->disable_deblocking_filter_idc);
- if (slice_param->disable_deblocking_filter_idc != 1) {
- WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2);
- WRITE_SE (bs, slice_param->slice_beta_offset_div2);
- }
- }
-
- /* XXX: unsupported arbitrary slice ordering (ASO) */
- /* num_slic_groups_minus1 should be zero */
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Slice NAL unit");
- return FALSE;
- }
-}
-
-static inline void
-_check_sps_pps_status (GstVaapiEncoderH264Fei * encoder,
- const guint8 * nal, guint32 size)
-{
- guint8 nal_type;
- G_GNUC_UNUSED gsize ret; /* FIXME */
- gboolean has_subset_sps;
-
- g_assert (size);
-
- has_subset_sps = !encoder->is_mvc || (encoder->subset_sps_data != NULL);
- if (encoder->sps_data && encoder->pps_data && has_subset_sps)
- return;
-
- nal_type = nal[0] & 0x1F;
- switch (nal_type) {
- case GST_H264_NAL_SPS:
- encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
- ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
- g_assert (ret == size);
- break;
- case GST_H264_NAL_SUBSET_SPS:
- encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL);
- ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size);
- g_assert (ret == size);
- break;
- case GST_H264_NAL_PPS:
- encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
- ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
- g_assert (ret == size);
- break;
- default:
- break;
- }
-}
-
-/* Determines the largest supported profile by the underlying hardware */
-static gboolean
-ensure_hw_profile_limits (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
- GArray *profiles;
- guint i, profile_idc, max_profile_idc;
-
- if (encoder->hw_max_profile_idc)
- return TRUE;
-
- profiles = gst_vaapi_display_get_encode_profiles (display);
- if (!profiles)
- return FALSE;
-
- max_profile_idc = 0;
- for (i = 0; i < profiles->len; i++) {
- const GstVaapiProfile profile =
- g_array_index (profiles, GstVaapiProfile, i);
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- if (!profile_idc)
- continue;
- if (max_profile_idc < profile_idc)
- max_profile_idc = profile_idc;
- }
- g_array_unref (profiles);
-
- encoder->hw_max_profile_idc = max_profile_idc;
- return TRUE;
-}
-
-/* Derives the profile supported by the underlying hardware */
-static gboolean
-ensure_hw_profile (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
- GstVaapiEntrypoint entrypoint = encoder->entrypoint;
- GstVaapiProfile profile, profiles[4];
- guint i, num_profiles = 0;
-
- profiles[num_profiles++] = encoder->profile;
- switch (encoder->profile) {
- case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
- profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
- profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
- // fall-through
- case GST_VAAPI_PROFILE_H264_MAIN:
- profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
- break;
- default:
- break;
- }
-
- profile = GST_VAAPI_PROFILE_UNKNOWN;
- for (i = 0; i < num_profiles; i++) {
- if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
- profile = profiles[i];
- break;
- }
- }
- if (profile == GST_VAAPI_PROFILE_UNKNOWN)
- goto error_unsupported_profile;
-
- GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
- return TRUE;
-
- /* ERRORS */
-error_unsupported_profile:
- {
- GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
- return FALSE;
- }
-}
-
-/* Check target decoder constraints */
-static gboolean
-ensure_profile_limits (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiProfile profile;
-
- if (!encoder->max_profile_idc
- || encoder->profile_idc <= encoder->max_profile_idc)
- return TRUE;
-
- GST_WARNING ("lowering coding tools to meet target decoder constraints");
-
- profile = GST_VAAPI_PROFILE_UNKNOWN;
-
- /* Try Main profile coding tools */
- if (encoder->max_profile_idc < 100) {
- encoder->use_dct8x8 = FALSE;
- profile = GST_VAAPI_PROFILE_H264_MAIN;
- }
-
- /* Try Constrained Baseline profile coding tools */
- if (encoder->max_profile_idc < 77) {
- encoder->num_bframes = 0;
- encoder->use_cabac = FALSE;
- profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
- }
-
- if (profile) {
- encoder->profile = profile;
- encoder->profile_idc = encoder->max_profile_idc;
- }
- return TRUE;
-}
-
-/* Derives the minimum profile from the active coding tools */
-static gboolean
-ensure_profile (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiProfile profile;
-
- /* Always start from "constrained-baseline" profile for maximum
- compatibility */
- profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
-
- /* Main profile coding tools */
- if (encoder->num_bframes > 0 || encoder->use_cabac)
- profile = GST_VAAPI_PROFILE_H264_MAIN;
-
- /* High profile coding tools */
- if (encoder->use_dct8x8)
- profile = GST_VAAPI_PROFILE_H264_HIGH;
-
- /* MVC profiles coding tools */
- if (encoder->num_views == 2)
- profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH;
- else if (encoder->num_views > 2)
- profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH;
-
- encoder->profile = profile;
- encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- return TRUE;
-}
-
-/* Derives the level from the currently set limits */
-static gboolean
-ensure_level (GstVaapiEncoderH264Fei * encoder)
-{
- const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile);
- const GstVaapiH264LevelLimits *limits_table;
- guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
-
- PicSizeMbs = encoder->mb_width * encoder->mb_height;
- MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
- MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
- GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
-
- limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
- for (i = 0; i < num_limits; i++) {
- const GstVaapiH264LevelLimits *const limits = &limits_table[i];
- if (PicSizeMbs <= limits->MaxFS &&
- MaxDpbMbs <= limits->MaxDpbMbs &&
- MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits
- || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) &&
- (!encoder->cpb_length_bits ||
- encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor)))
- 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;
- }
-}
-
-/* Enable "high-compression" tuning options */
-static gboolean
-ensure_tuning_high_compression (GstVaapiEncoderH264Fei * encoder)
-{
- guint8 profile_idc;
-
- if (!ensure_hw_profile_limits (encoder))
- return FALSE;
-
- profile_idc = encoder->hw_max_profile_idc;
- if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
- profile_idc = encoder->max_profile_idc;
-
- /* Tuning options to enable Main profile */
- if (profile_idc >= 77 && profile_idc != 88) {
- encoder->use_cabac = TRUE;
- if (!encoder->num_bframes)
- encoder->num_bframes = 1;
- }
-
- /* Tuning options to enable High profile */
- if (profile_idc >= 100) {
- encoder->use_dct8x8 = TRUE;
- }
- return TRUE;
-}
-
-/* Ensure tuning options */
-static gboolean
-ensure_tuning (GstVaapiEncoderH264Fei * encoder)
-{
- gboolean success;
-
- switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
- case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
- success = ensure_tuning_high_compression (encoder);
- break;
- case GST_VAAPI_ENCODER_TUNE_LOW_POWER:
- /* Set low-power encode entry point. If hardware doesn't have
- * support, it will fail in ensure_hw_profile() in later stage.
- * So not duplicating the profile/entrypont query mechanism
- * here as a part of optimization */
- encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
- success = TRUE;
- break;
- default:
- success = TRUE;
- break;
- }
- return success;
-}
-
-/* Handle new GOP starts */
-static void
-reset_gop_start (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[encoder->view_idx];
-
- reorder_pool->frame_index = 1;
- reorder_pool->cur_frame_num = 0;
- reorder_pool->cur_present_index = 0;
- ++encoder->idr_num;
-}
-
-/* Marks the supplied picture as a B-frame */
-static void
-set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[encoder->view_idx];
-
- g_assert (pic && encoder);
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_B;
- pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
-}
-
-/* Marks the supplied picture as a P-frame */
-static void
-set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[encoder->view_idx];
-
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_P;
- pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
-}
-
-/* Marks the supplied picture as an I-frame */
-static void
-set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[encoder->view_idx];
-
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_I;
- pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
-
- g_assert (pic->frame);
- GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
-}
-
-/* Marks the supplied picture as an IDR frame */
-static void
-set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder)
-{
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_I;
- pic->frame_num = 0;
- pic->poc = 0;
- GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
-
- g_assert (pic->frame);
- GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
-}
-
-/* Marks the supplied picture a a key-frame */
-static void
-set_key_frame (GstVaapiEncPicture * picture,
- GstVaapiEncoderH264Fei * encoder, gboolean is_idr)
-{
- if (is_idr) {
- reset_gop_start (encoder);
- set_idr_frame (picture, encoder);
- } else
- set_i_frame (picture, encoder);
-}
-
-/* Fills in VA HRD parameters */
-static void
-fill_hrd_params (GstVaapiEncoderH264Fei * encoder, VAEncMiscParameterHRD * hrd)
-{
- if (encoder->bitrate_bits > 0) {
- hrd->buffer_size = encoder->cpb_length_bits;
- hrd->initial_buffer_fullness = hrd->buffer_size / 2;
- } else {
- hrd->buffer_size = 0;
- hrd->initial_buffer_fullness = 0;
- }
-}
-
-/* Adds the supplied sequence header (SPS) to the list of packed
- headers to pass down as-is to the encoder */
-static gboolean
-add_packed_sequence_header (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
-{
- GstVaapiEncPackedHeader *packed_seq;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
- const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
- GstVaapiProfile profile = encoder->profile;
-
- VAEncMiscParameterHRD hrd_params;
- guint32 data_bit_size;
- guint8 *data;
-
- fill_hrd_params (encoder, &hrd_params);
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS);
-
- /* Set High profile for encoding the MVC base view. Otherwise, some
- traditional decoder cannot recognize MVC profile streams with
- only the base view in there */
- if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH)
- profile = GST_VAAPI_PROFILE_H264_HIGH;
-
- bs_write_sps (&bs, seq_param, profile, &hrd_params);
-
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_seq_param.type = VAEncPackedHeaderSequence;
- packed_seq_param.bit_length = data_bit_size;
- packed_seq_param.has_emulation_bytes = 0;
-
- packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
- &packed_seq_param, sizeof (packed_seq_param),
- data, (data_bit_size + 7) / 8);
- g_assert (packed_seq);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_seq, NULL);
-
- /* store sps data */
- _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SPS NAL unit");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-static gboolean
-add_packed_sequence_header_mvc (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
-{
- GstVaapiEncPackedHeader *packed_seq;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
- const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
- VAEncMiscParameterHRD hrd_params;
- guint32 data_bit_size;
- guint8 *data;
-
- fill_hrd_params (encoder, &hrd_params);
-
- /* non-base layer, pack one subset sps */
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS);
-
- bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views,
- encoder->view_ids, &hrd_params);
-
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_header_param_buffer.type = VAEncPackedHeaderSequence;
- packed_header_param_buffer.bit_length = data_bit_size;
- packed_header_param_buffer.has_emulation_bytes = 0;
-
- packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
- &packed_header_param_buffer, sizeof (packed_header_param_buffer),
- data, (data_bit_size + 7) / 8);
- g_assert (packed_seq);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
- gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL);
-
- /* store subset sps data */
- _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SPS NAL unit");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-/* Adds the supplied picture header (PPS) to the list of packed
- headers to pass down as-is to the encoder */
-static gboolean
-add_packed_picture_header (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture)
-{
- GstVaapiEncPackedHeader *packed_pic;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
- const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- guint32 data_bit_size;
- guint8 *data;
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS);
- bs_write_pps (&bs, pic_param, encoder->profile);
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_pic_param.type = VAEncPackedHeaderPicture;
- packed_pic_param.bit_length = data_bit_size;
- packed_pic_param.has_emulation_bytes = 0;
-
- packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
- &packed_pic_param, sizeof (packed_pic_param),
- data, (data_bit_size + 7) / 8);
- g_assert (packed_pic);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_pic, NULL);
-
- /* store pps data */
- _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write PPS NAL unit");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-static gboolean
-add_packed_sei_header (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiH264SeiPayloadType payloadtype)
-{
- GstVaapiEncPackedHeader *packed_sei;
- GstBitWriter bs, bs_buf_period, bs_pic_timing;
- VAEncPackedHeaderParameterBuffer packed_sei_param = { 0 };
- guint32 data_bit_size;
- guint8 buf_period_payload_size = 0, pic_timing_payload_size = 0;
- guint8 *data, *buf_period_payload = NULL, *pic_timing_payload = NULL;
- gboolean need_buf_period, need_pic_timing;
-
- gst_bit_writer_init_with_size (&bs_buf_period, 128, FALSE);
- gst_bit_writer_init_with_size (&bs_pic_timing, 128, FALSE);
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
-
- need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype;
- need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype;
-
- if (need_buf_period) {
- /* Write a Buffering Period SEI message */
- bs_write_sei_buf_period (&bs_buf_period, encoder, picture);
- /* Write byte alignment bits */
- if (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period) % 8 != 0)
- bs_write_trailing_bits (&bs_buf_period);
- buf_period_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8;
- buf_period_payload = GST_BIT_WRITER_DATA (&bs_buf_period);
- }
-
- if (need_pic_timing) {
- /* Write a Picture Timing SEI message */
- if (GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype)
- bs_write_sei_pic_timing (&bs_pic_timing, encoder, picture);
- /* Write byte alignment bits */
- if (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing) % 8 != 0)
- bs_write_trailing_bits (&bs_pic_timing);
- pic_timing_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8;
- pic_timing_payload = GST_BIT_WRITER_DATA (&bs_pic_timing);
- }
-
- /* Write the SEI message */
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, GST_H264_NAL_SEI);
-
- if (need_buf_period) {
- WRITE_UINT32 (&bs, GST_H264_SEI_BUF_PERIOD, 8);
- WRITE_UINT32 (&bs, buf_period_payload_size, 8);
- /* Add buffering period sei message */
- gst_bit_writer_put_bytes (&bs, buf_period_payload, buf_period_payload_size);
- }
-
- if (need_pic_timing) {
- WRITE_UINT32 (&bs, GST_H264_SEI_PIC_TIMING, 8);
- WRITE_UINT32 (&bs, pic_timing_payload_size, 8);
- /* Add picture timing sei message */
- gst_bit_writer_put_bytes (&bs, pic_timing_payload, pic_timing_payload_size);
- }
-
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (&bs);
-
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_sei_param.type = VA_ENC_PACKED_HEADER_H264_SEI;
- packed_sei_param.bit_length = data_bit_size;
- packed_sei_param.has_emulation_bytes = 0;
-
- packed_sei = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
- &packed_sei_param, sizeof (packed_sei_param),
- data, (data_bit_size + 7) / 8);
- g_assert (packed_sei);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_sei);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_sei, NULL);
-
- gst_bit_writer_reset (&bs_buf_period);
- gst_bit_writer_reset (&bs_pic_timing);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SEI NAL unit");
- gst_bit_writer_reset (&bs_buf_period);
- gst_bit_writer_reset (&bs_pic_timing);
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-static gboolean
-get_nal_hdr_attributes (GstVaapiEncPicture * picture,
- guint8 * nal_ref_idc, guint8 * nal_unit_type)
-{
- switch (picture->type) {
- case GST_VAAPI_PICTURE_TYPE_I:
- *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH;
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- *nal_unit_type = GST_H264_NAL_SLICE_IDR;
- else
- *nal_unit_type = GST_H264_NAL_SLICE;
- break;
- case GST_VAAPI_PICTURE_TYPE_P:
- *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM;
- *nal_unit_type = GST_H264_NAL_SLICE;
- break;
- case GST_VAAPI_PICTURE_TYPE_B:
- *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE;
- *nal_unit_type = GST_H264_NAL_SLICE;
- break;
- default:
- return FALSE;
- }
- return TRUE;
-}
-
-/* Adds the supplied prefix nal header to the list of packed
- headers to pass down as-is to the encoder */
-static gboolean
-add_packed_prefix_nal_header (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
-{
- GstVaapiEncPackedHeader *packed_prefix_nal;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 };
- guint32 data_bit_size;
- guint8 *data;
- guint8 nal_ref_idc, nal_unit_type;
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
-
- if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
- goto bs_error;
- nal_unit_type = GST_H264_NAL_PREFIX_UNIT;
-
- bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
- bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx);
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_prefix_nal_param.type = VAEncPackedHeaderRawData;
- packed_prefix_nal_param.bit_length = data_bit_size;
- packed_prefix_nal_param.has_emulation_bytes = 0;
-
- packed_prefix_nal =
- gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
- &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data,
- (data_bit_size + 7) / 8);
- g_assert (packed_prefix_nal);
-
- gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_prefix_nal,
- NULL);
-
- gst_bit_writer_reset (&bs);
-
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Prefix NAL unit header");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-/* Adds the supplied slice header to the list of packed
- headers to pass down as-is to the encoder */
-static gboolean
-add_packed_slice_header (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
-{
- GstVaapiEncPackedHeader *packed_slice;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 };
- const VAEncSliceParameterBufferH264 *const slice_param = slice->param;
- guint32 data_bit_size;
- guint8 *data;
- guint8 nal_ref_idc, nal_unit_type;
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
-
- if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
- goto bs_error;
- /* pack nal_unit_header_mvc_extension() for the non base view */
- if (encoder->is_mvc && encoder->view_idx) {
- bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT);
- bs_write_nal_header_mvc_extension (&bs, picture,
- encoder->view_ids[encoder->view_idx]);
- } else
- bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
-
- bs_write_slice (&bs, slice_param, encoder, picture);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_slice_param.type = VAEncPackedHeaderSlice;
- packed_slice_param.bit_length = data_bit_size;
- packed_slice_param.has_emulation_bytes = 0;
-
- packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
- &packed_slice_param, sizeof (packed_slice_param),
- data, (data_bit_size + 7) / 8);
- g_assert (packed_slice);
-
- gst_vaapi_enc_slice_add_packed_header (slice, packed_slice);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_slice,
- NULL);
-
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Slice NAL unit header");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-/* Reference picture management */
-static void
-reference_pic_free (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncoderH264FeiRef * ref)
-{
- if (!ref)
- return;
- if (ref->pic)
- gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
- g_slice_free (GstVaapiEncoderH264FeiRef, ref);
-}
-
-static inline GstVaapiEncoderH264FeiRef *
-reference_pic_create (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
-{
- GstVaapiEncoderH264FeiRef *const ref =
- g_slice_new0 (GstVaapiEncoderH264FeiRef);
-
- ref->pic = surface;
- ref->frame_num = picture->frame_num;
- ref->poc = picture->poc;
- return ref;
-}
-
-static gboolean
-reference_list_update (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
-{
- GstVaapiEncoderH264FeiRef *ref;
- GstVaapiH264ViewRefPool *const ref_pool =
- &encoder->ref_pools[encoder->view_idx];
-
- if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
- gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
- return TRUE;
- }
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
- while (!g_queue_is_empty (&ref_pool->ref_list))
- reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
- } else if (g_queue_get_length (&ref_pool->ref_list) >=
- ref_pool->max_ref_frames) {
- reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
- }
- ref = reference_pic_create (encoder, picture, surface);
- g_queue_push_tail (&ref_pool->ref_list, ref);
- g_assert (g_queue_get_length (&ref_pool->ref_list) <=
- ref_pool->max_ref_frames);
- return TRUE;
-}
-
-static gboolean
-reference_list_init (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture,
- GstVaapiEncoderH264FeiRef ** reflist_0,
- guint * reflist_0_count,
- GstVaapiEncoderH264FeiRef ** reflist_1, guint * reflist_1_count)
-{
- GstVaapiEncoderH264FeiRef *tmp;
- GstVaapiH264ViewRefPool *const ref_pool =
- &encoder->ref_pools[encoder->view_idx];
- GList *iter, *list_0_start = NULL, *list_1_start = NULL;
- guint count;
-
- *reflist_0_count = 0;
- *reflist_1_count = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
- return TRUE;
-
- iter = g_queue_peek_tail_link (&ref_pool->ref_list);
- for (; iter; iter = g_list_previous (iter)) {
- tmp = (GstVaapiEncoderH264FeiRef *) iter->data;
- g_assert (tmp && tmp->poc != picture->poc);
- if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) {
- list_0_start = iter;
- list_1_start = g_list_next (iter);
- break;
- }
- }
-
- /* order reflist_0 */
- g_assert (list_0_start);
- iter = list_0_start;
- count = 0;
- for (; iter; iter = g_list_previous (iter)) {
- reflist_0[count] = (GstVaapiEncoderH264FeiRef *) iter->data;
- ++count;
- }
- *reflist_0_count = count;
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
- return TRUE;
-
- /* order reflist_1 */
- count = 0;
- iter = list_1_start;
- for (; iter; iter = g_list_next (iter)) {
- reflist_1[count] = (GstVaapiEncoderH264FeiRef *) iter->data;
- ++count;
- }
- *reflist_1_count = count;
- return TRUE;
-}
-
-/* Fills in VA sequence parameter buffer */
-static gboolean
-fill_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncSequence * sequence)
-{
- VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
- GstVaapiH264ViewRefPool *const ref_pool =
- &encoder->ref_pools[encoder->view_idx];
-
- memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
- seq_param->seq_parameter_set_id = encoder->view_idx;
- seq_param->level_idc = encoder->level_idc;
- seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
- seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
- seq_param->ip_period = seq_param->intra_period > 1 ?
- (1 + encoder->num_bframes) : 0;
- seq_param->bits_per_second = encoder->bitrate_bits;
-
- seq_param->max_num_ref_frames = ref_pool->max_ref_frames;
- seq_param->picture_width_in_mbs = encoder->mb_width;
- seq_param->picture_height_in_mbs = encoder->mb_height;
-
- /*sequence field values */
- seq_param->seq_fields.value = 0;
- seq_param->seq_fields.bits.chroma_format_idc = 1;
- seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
- seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
- seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
- /* direct_8x8_inference_flag default false */
- seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
- g_assert (encoder->log2_max_frame_num >= 4);
- seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
- encoder->log2_max_frame_num - 4;
- /* picture order count */
- encoder->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type =
- 0;
- g_assert (encoder->log2_max_pic_order_cnt >= 4);
- seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
- encoder->log2_max_pic_order_cnt - 4;
-
- seq_param->bit_depth_luma_minus8 = 0;
- seq_param->bit_depth_chroma_minus8 = 0;
-
- /* not used if pic_order_cnt_type == 0 */
- if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
- encoder->delta_pic_order_always_zero_flag =
- seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
- seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
- seq_param->offset_for_non_ref_pic = 0;
- seq_param->offset_for_top_to_bottom_field = 0;
- memset (seq_param->offset_for_ref_frame, 0,
- sizeof (seq_param->offset_for_ref_frame));
- }
-
- /* frame_cropping_flag */
- if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
- (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
- static const guint SubWidthC[] = { 1, 2, 2, 1 };
- static const guint SubHeightC[] = { 1, 2, 1, 1 };
- const guint CropUnitX =
- SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
- const guint CropUnitY =
- SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
- (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
-
- seq_param->frame_cropping_flag = 1;
- seq_param->frame_crop_left_offset = 0;
- seq_param->frame_crop_right_offset =
- (16 * encoder->mb_width -
- GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX;
- seq_param->frame_crop_top_offset = 0;
- seq_param->frame_crop_bottom_offset =
- (16 * encoder->mb_height -
- GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY;
- }
-
- /* VUI parameters are always set, at least for timing_info (framerate) */
- seq_param->vui_parameters_present_flag = TRUE;
- if (seq_param->vui_parameters_present_flag) {
- seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE;
- if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
- const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
- seq_param->aspect_ratio_idc = 0xff;
- seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip);
- seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip);
- }
- seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
- /* if vui_parameters_present_flag is TRUE and sps data belongs to
- * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */
- seq_param->vui_fields.bits.timing_info_present_flag = !encoder->view_idx;
- if (seq_param->vui_fields.bits.timing_info_present_flag) {
- seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
- seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
- }
- }
- return TRUE;
-}
-
-/* Fills in VA picture parameter buffer */
-static gboolean
-fill_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture,
- GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
-{
- VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- GstVaapiH264ViewRefPool *const ref_pool =
- &encoder->ref_pools[encoder->view_idx];
- GstVaapiEncoderH264FeiRef *ref_pic;
- GList *reflist;
- guint i;
-
- memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
-
- /* reference list, */
- pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
- pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
- i = 0;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
- for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
- reflist; reflist = g_list_next (reflist)) {
- ref_pic = reflist->data;
- g_assert (ref_pic && ref_pic->pic &&
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
-
- pic_param->ReferenceFrames[i].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
- pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc;
- pic_param->ReferenceFrames[i].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num;
-
- ++i;
- }
- g_assert (i <= 16 && i <= ref_pool->max_ref_frames);
- }
- for (; i < 16; ++i) {
- pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
- }
- pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
-
- pic_param->pic_parameter_set_id = encoder->view_idx;
- pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0;
- pic_param->last_picture = 0; /* means last encoding picture */
- pic_param->frame_num = picture->frame_num;
- pic_param->pic_init_qp = encoder->init_qp;
- pic_param->num_ref_idx_l0_active_minus1 =
- (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0);
- pic_param->num_ref_idx_l1_active_minus1 =
- (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0);
- pic_param->chroma_qp_index_offset = 0;
- pic_param->second_chroma_qp_index_offset = 0;
-
- /* set picture fields */
- pic_param->pic_fields.value = 0;
- pic_param->pic_fields.bits.idr_pic_flag =
- GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
- pic_param->pic_fields.bits.reference_pic_flag =
- (picture->type != GST_VAAPI_PICTURE_TYPE_B);
- pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
- pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
- pic_param->pic_fields.bits.weighted_bipred_idc = 0;
- pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
- pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
- /* enable debloking */
- pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
- pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
- /* bottom_field_pic_order_in_frame_present_flag */
- pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
- pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
-
- return TRUE;
-}
-
-/* Adds slice headers to picture */
-static gboolean
-add_slice_headers (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiEncoderH264FeiRef ** reflist_0,
- guint reflist_0_count, GstVaapiEncoderH264FeiRef ** reflist_1,
- guint reflist_1_count)
-{
- VAEncSliceParameterBufferH264 *slice_param;
- GstVaapiEncSlice *slice;
- guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
- guint mb_size;
- guint last_mb_index;
- guint i_slice, i_ref;
-
- g_assert (picture);
-
- mb_size = encoder->mb_width * encoder->mb_height;
-
- g_assert (encoder->num_slices && encoder->num_slices < mb_size);
- slice_of_mbs = mb_size / encoder->num_slices;
- slice_mod_mbs = mb_size % encoder->num_slices;
- last_mb_index = 0;
- for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
- cur_slice_mbs = slice_of_mbs;
- if (slice_mod_mbs) {
- ++cur_slice_mbs;
- --slice_mod_mbs;
- }
- slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
- g_assert (slice && slice->param_id != VA_INVALID_ID);
- slice_param = slice->param;
-
- memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
- slice_param->macroblock_address = last_mb_index;
- slice_param->num_macroblocks = cur_slice_mbs;
- slice_param->macroblock_info = VA_INVALID_ID;
- slice_param->slice_type = h264_get_slice_type (picture->type);
- g_assert ((gint8) slice_param->slice_type != -1);
- slice_param->pic_parameter_set_id = encoder->view_idx;
- slice_param->idr_pic_id = encoder->idr_num;
- slice_param->pic_order_cnt_lsb = picture->poc;
-
- /* not used if pic_order_cnt_type = 0 */
- slice_param->delta_pic_order_cnt_bottom = 0;
- memset (slice_param->delta_pic_order_cnt, 0,
- sizeof (slice_param->delta_pic_order_cnt));
-
- /* only works for B frames */
- if (slice_param->slice_type == GST_H264_B_SLICE)
- slice_param->direct_spatial_mv_pred_flag = TRUE;
- /* default equal to picture parameters */
- slice_param->num_ref_idx_active_override_flag = FALSE;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
- slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
- else
- slice_param->num_ref_idx_l0_active_minus1 = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
- slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
- else
- slice_param->num_ref_idx_l1_active_minus1 = 0;
- g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
- g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
-
- i_ref = 0;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
- for (; i_ref < reflist_0_count; ++i_ref) {
- slice_param->RefPicList0[i_ref].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
- slice_param->RefPicList0[i_ref].TopFieldOrderCnt =
- reflist_0[i_ref]->poc;
- slice_param->RefPicList0[i_ref].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num;
- }
- g_assert (i_ref == 1);
- }
- for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
- slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
- }
-
- i_ref = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
- for (; i_ref < reflist_1_count; ++i_ref) {
- slice_param->RefPicList1[i_ref].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
- slice_param->RefPicList1[i_ref].TopFieldOrderCnt =
- reflist_1[i_ref]->poc;
- slice_param->RefPicList1[i_ref].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num;
- }
- g_assert (i_ref == 1);
- }
- for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
- slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
- }
-
- /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
- slice_param->luma_log2_weight_denom = 0;
- slice_param->chroma_log2_weight_denom = 0;
- slice_param->luma_weight_l0_flag = FALSE;
- memset (slice_param->luma_weight_l0, 0,
- sizeof (slice_param->luma_weight_l0));
- memset (slice_param->luma_offset_l0, 0,
- sizeof (slice_param->luma_offset_l0));
- slice_param->chroma_weight_l0_flag = FALSE;
- memset (slice_param->chroma_weight_l0, 0,
- sizeof (slice_param->chroma_weight_l0));
- memset (slice_param->chroma_offset_l0, 0,
- sizeof (slice_param->chroma_offset_l0));
- slice_param->luma_weight_l1_flag = FALSE;
- memset (slice_param->luma_weight_l1, 0,
- sizeof (slice_param->luma_weight_l1));
- memset (slice_param->luma_offset_l1, 0,
- sizeof (slice_param->luma_offset_l1));
- slice_param->chroma_weight_l1_flag = FALSE;
- memset (slice_param->chroma_weight_l1, 0,
- sizeof (slice_param->chroma_weight_l1));
- memset (slice_param->chroma_offset_l1, 0,
- sizeof (slice_param->chroma_offset_l1));
-
- slice_param->cabac_init_idc = 0;
- slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
- if (slice_param->slice_qp_delta > 4)
- slice_param->slice_qp_delta = 4;
- if ((gint) encoder->init_qp + slice_param->slice_qp_delta >
- (gint) encoder->max_qp) {
- slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp;
- }
- slice_param->disable_deblocking_filter_idc = 0;
- slice_param->slice_alpha_c0_offset_div2 = 2;
- slice_param->slice_beta_offset_div2 = 2;
-
- /* set calculation for next slice */
- last_mb_index += cur_slice_mbs;
-
- /* add packed Prefix NAL unit before each Coded slice NAL in base view */
- if (encoder->is_mvc && !encoder->view_idx &&
- (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_RAW_DATA)
- && !add_packed_prefix_nal_header (encoder, picture, slice))
- goto error_create_packed_prefix_nal_hdr;
- if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_SLICE)
- && !add_packed_slice_header (encoder, picture, slice))
- goto error_create_packed_slice_hdr;
-
- gst_vaapi_enc_picture_add_slice (picture, slice);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL);
- }
- g_assert (last_mb_index == mb_size);
- return TRUE;
-
-error_create_packed_slice_hdr:
- {
- GST_ERROR ("failed to create packed slice header buffer");
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL);
- return FALSE;
- }
-error_create_packed_prefix_nal_hdr:
- {
- GST_ERROR ("failed to create packed prefix nal header buffer");
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL);
- return FALSE;
- }
-}
-
-/* Generates and submits SPS header accordingly into the bitstream */
-static gboolean
-ensure_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture)
-{
- GstVaapiEncSequence *sequence = NULL;
-
- /* submit an SPS header before every new I-frame, if codec config changed */
- if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I)
- return TRUE;
-
- sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
- if (!sequence || !fill_sequence (encoder, sequence))
- goto error_create_seq_param;
-
- /* add subset sps for non-base view and sps for base view */
- if (encoder->is_mvc && encoder->view_idx) {
- if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_SEQUENCE)
- && !add_packed_sequence_header_mvc (encoder, picture, sequence))
- goto error_create_packed_seq_hdr;
- } else {
- if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_SEQUENCE)
- && !add_packed_sequence_header (encoder, picture, sequence))
- goto error_create_packed_seq_hdr;
- }
-
- if (sequence) {
- gst_vaapi_enc_picture_set_sequence (picture, sequence);
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL);
- }
-
- if (!encoder->is_mvc || encoder->view_idx > 0)
- encoder->config_changed = FALSE;
- return TRUE;
-
- /* ERRORS */
-error_create_seq_param:
- {
- GST_ERROR ("failed to create sequence parameter buffer (SPS)");
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL);
- return FALSE;
- }
-error_create_packed_seq_hdr:
- {
- GST_ERROR ("failed to create packed sequence header buffer");
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL);
- return FALSE;
- }
-}
-
-/* Generates additional fei control parameters */
-static gboolean
-ensure_fei_misc_params (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy)
-{
- GstVaapiEncMiscParam *misc = NULL;
- GstVaapiSurfaceProxy *surface_proxy = NULL;
-
- VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param;
- guint mbcode_size = 0;
- guint mv_size = 0;
- guint dist_size = 0;
- gboolean enable_out = FALSE;
-
- /* fei pic control params */
- misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, encoder);
- g_assert (misc);
- if (!misc)
- return FALSE;
- misc_fei_pic_control_param = misc->data;
- surface_proxy = picture->proxy;
-
- enable_out = ((encoder->is_stats_out_enabled &&
- (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK)) ||
- (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)) ? TRUE : FALSE;
-
- misc_fei_pic_control_param->function = encoder->fei_mode;
- misc_fei_pic_control_param->search_path = encoder->search_path;
- misc_fei_pic_control_param->num_mv_predictors_l0 =
- encoder->num_mv_predictors_l0;
- misc_fei_pic_control_param->num_mv_predictors_l1 =
- encoder->num_mv_predictors_l1;
- misc_fei_pic_control_param->len_sp = encoder->len_sp;
- misc_fei_pic_control_param->sub_mb_part_mask = encoder->submb_part_mask;
- if (!encoder->use_dct8x8)
- misc_fei_pic_control_param->intra_part_mask = encoder->intra_part_mask | 2;
- misc_fei_pic_control_param->multi_pred_l0 = encoder->multi_predL0;
- misc_fei_pic_control_param->multi_pred_l1 = encoder->multi_predL1;
- misc_fei_pic_control_param->sub_pel_mode = encoder->subpel_mode;
- misc_fei_pic_control_param->inter_sad = encoder->inter_sad;
- misc_fei_pic_control_param->intra_sad = encoder->intra_sad;
- misc_fei_pic_control_param->distortion_type = 0;
- misc_fei_pic_control_param->repartition_check_enable = 0;
- misc_fei_pic_control_param->adaptive_search = encoder->adaptive_search;
- misc_fei_pic_control_param->mb_size_ctrl = 0;
- misc_fei_pic_control_param->ref_width = encoder->ref_width;
- misc_fei_pic_control_param->ref_height = encoder->ref_height;
- misc_fei_pic_control_param->search_window = encoder->search_window;
-
- if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) ||
- (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)) {
-
- /***** ENC_PAK/ENC input: mv_predictor *****/
- if (surface_proxy->mvpred) {
- misc_fei_pic_control_param->mv_predictor =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mvpred)->param_id;
- misc_fei_pic_control_param->mv_predictor_enable = TRUE;
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) &
- picture->mvpred, surface_proxy->mvpred);
- } else {
- misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID;
- misc_fei_pic_control_param->mv_predictor_enable = FALSE;
- picture->mvpred = NULL;
- }
-
- /***** ENC_PAK/ENC input: qp ******/
- if (surface_proxy->qp) {
- misc_fei_pic_control_param->qp =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->qp)->param_id;
- misc_fei_pic_control_param->mb_qp = TRUE;
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) &
- picture->qp, surface_proxy->qp);
- } else {
- misc_fei_pic_control_param->qp = VA_INVALID_ID;
- misc_fei_pic_control_param->mb_qp = FALSE;
- picture->qp = NULL;
- }
-
- /***** ENC_PAK/ENC input: mb_control ******/
- if (surface_proxy->mbcntrl) {
- misc_fei_pic_control_param->mb_ctrl =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcntrl)->param_id;
- misc_fei_pic_control_param->mb_input = TRUE;
- gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) &
- picture->mbcntrl, surface_proxy->mbcntrl);
- } else {
- misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID;
- misc_fei_pic_control_param->mb_input = FALSE;
- picture->mbcntrl = NULL;
- }
- }
-
- if (enable_out) {
-
- mbcode_size = sizeof (VAEncFEIMBCodeH264) *
- encoder->mb_width * encoder->mb_height;
- mv_size = sizeof (VAMotionVector) * 16 *
- encoder->mb_width * encoder->mb_height;
- dist_size = sizeof (VAEncFEIDistortionH264) *
- encoder->mb_width * encoder->mb_height;
-
- /***** ENC_PAK/ENC output: macroblock code buffer *****/
- codedbuf_proxy->mbcode =
- gst_vaapi_enc_fei_mb_code_new (GST_VAAPI_ENCODER_CAST (encoder),
- NULL, mbcode_size);
- misc_fei_pic_control_param->mb_code_data =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id;
- picture->mbcode = gst_vaapi_codec_object_ref (codedbuf_proxy->mbcode);
-
- /***** ENC_PAK/ENC output: motion vector buffer *****/
- codedbuf_proxy->mv =
- gst_vaapi_enc_fei_mv_new (GST_VAAPI_ENCODER_CAST (encoder), NULL,
- mv_size);
- misc_fei_pic_control_param->mv_data =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id;
- picture->mv = gst_vaapi_codec_object_ref (codedbuf_proxy->mv);
-
- /***** ENC_PAK/ENC output: distortion buffer *****/
- codedbuf_proxy->dist =
- gst_vaapi_enc_fei_distortion_new (GST_VAAPI_ENCODER_CAST (encoder),
- NULL, dist_size);
- misc_fei_pic_control_param->distortion =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->dist)->param_id;
- picture->dist = gst_vaapi_codec_object_ref (codedbuf_proxy->dist);
-
- } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) {
-
- g_assert (surface_proxy->mbcode != NULL);
- g_assert (surface_proxy->mv != NULL);
-
- /***** PAK input: macroblock code buffer *****/
- misc_fei_pic_control_param->mb_code_data =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcode)->param_id;
- picture->mbcode = gst_vaapi_codec_object_ref (surface_proxy->mbcode);
-
- /***** PAK input: motion vector buffer *****/
- misc_fei_pic_control_param->mv_data =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mv)->param_id;
- picture->mv = gst_vaapi_codec_object_ref (surface_proxy->mv);
- } else {
-
- codedbuf_proxy->mbcode = picture->mbcode = NULL;
- codedbuf_proxy->mv = picture->mv = NULL;
- codedbuf_proxy->dist = picture->dist = NULL;
- misc_fei_pic_control_param->mb_code_data = VA_INVALID_ID;
- misc_fei_pic_control_param->mv_data = VA_INVALID_ID;
- misc_fei_pic_control_param->distortion = VA_INVALID_ID;
- }
-
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
- return TRUE;
-}
-
-/* Generates additional control parameters */
-static gboolean
-ensure_misc_params (GstVaapiEncoderH264Fei * encoder,
- GstVaapiEncPicture * picture)
-{
- GstVaapiEncMiscParam *misc = NULL;
- VAEncMiscParameterRateControl *rate_control;
-
- /* HRD params */
- misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
- g_assert (misc);
- if (!misc)
- return FALSE;
- fill_hrd_params (encoder, misc->data);
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
-
- /* RateControl params */
- if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
- GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
- misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
- g_assert (misc);
- if (!misc)
- return FALSE;
- rate_control = misc->data;
- memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
- rate_control->bits_per_second = encoder->bitrate_bits;
- rate_control->target_percentage = 70;
- rate_control->window_size = encoder->cpb_length;
- rate_control->initial_qp = encoder->init_qp;
- rate_control->min_qp = encoder->min_qp;
-
-#if VA_CHECK_VERSION(1,1,0)
- rate_control->max_qp = encoder->max_qp;
-#endif
-
- rate_control->basic_unit_size = 0;
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
-
- if (!encoder->view_idx) {
- if ((GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) &&
- (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_MISC) &&
- !add_packed_sei_header (encoder, picture,
- GST_VAAPI_H264_SEI_BUF_PERIOD | GST_VAAPI_H264_SEI_PIC_TIMING))
- goto error_create_packed_sei_hdr;
-
- else if (!GST_VAAPI_ENC_PICTURE_IS_IDR (picture) &&
- (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_MISC) &&
- !add_packed_sei_header (encoder, picture,
- GST_VAAPI_H264_SEI_PIC_TIMING))
- goto error_create_packed_sei_hdr;
- }
-
- }
- return TRUE;
-
-error_create_packed_sei_hdr:
- {
- GST_ERROR ("failed to create packed SEI header");
- return FALSE;
- }
-}
-
-/* Generates and submits PPS header accordingly into the bitstream */
-static gboolean
-ensure_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture,
- GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
-{
- GstVaapiCodedBuffer *const codedbuf =
- GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
- gboolean res = FALSE;
-
- res = fill_picture (encoder, picture, codedbuf, surface);
-
- if (!res)
- return FALSE;
-
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
- (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
- VA_ENC_PACKED_HEADER_PICTURE)
- && !add_packed_picture_header (encoder, picture)) {
- GST_ERROR ("set picture packed header failed");
- return FALSE;
- }
- return TRUE;
-}
-
-/* Generates slice headers */
-static gboolean
-ensure_slices (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture)
-{
- GstVaapiEncoderH264FeiRef *reflist_0[16];
- GstVaapiEncoderH264FeiRef *reflist_1[16];
- GstVaapiH264ViewRefPool *const ref_pool =
- &encoder->ref_pools[encoder->view_idx];
- guint reflist_0_count = 0, reflist_1_count = 0;
-
- g_assert (picture);
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
- !reference_list_init (encoder, picture,
- reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
- GST_ERROR ("reference list reorder failed");
- return FALSE;
- }
-
- g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
- if (reflist_0_count > ref_pool->max_reflist0_count)
- reflist_0_count = ref_pool->max_reflist0_count;
- if (reflist_1_count > ref_pool->max_reflist1_count)
- reflist_1_count = ref_pool->max_reflist1_count;
-
- if (!add_slice_headers (encoder, picture,
- reflist_0, reflist_0_count, reflist_1, reflist_1_count))
- return FALSE;
-
- return TRUE;
-}
-
-/* Normalizes bitrate (and CPB size) for HRD conformance */
-static void
-ensure_bitrate_hrd (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
- guint bitrate, cpb_size;
-
- if (!base_encoder->bitrate) {
- encoder->bitrate_bits = 0;
- return;
- }
-
- /* Round down bitrate. This is a hard limit mandated by the user */
- g_assert (SX_BITRATE >= 6);
- bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
- if (bitrate != encoder->bitrate_bits) {
- GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
- encoder->bitrate_bits = bitrate;
- encoder->config_changed = TRUE;
- }
-
- /* Round up CPB size. This is an HRD compliance detail */
- g_assert (SX_CPB_SIZE >= 4);
- cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) &
- ~((1U << SX_CPB_SIZE) - 1);
- if (cpb_size != encoder->cpb_length_bits) {
- GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
- encoder->cpb_length_bits = cpb_size;
- encoder->config_changed = TRUE;
- }
-}
-
-/* Estimates a good enough bitrate if none was supplied */
-static void
-ensure_bitrate (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
-
- /* Default compression: 48 bits per macroblock in "high-compression" mode */
- switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
- case GST_VAAPI_RATECONTROL_CBR:
- case GST_VAAPI_RATECONTROL_VBR:
- case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
- if (!base_encoder->bitrate) {
- /* According to the literature and testing, CABAC entropy coding
- mode could provide for +10% to +18% improvement in general,
- thus estimating +15% here ; and using adaptive 8x8 transforms
- in I-frames could bring up to +10% improvement. */
- guint bits_per_mb = 48;
- guint64 factor;
-
- if (!encoder->use_cabac)
- bits_per_mb += (bits_per_mb * 15) / 100;
- if (!encoder->use_dct8x8)
- bits_per_mb += (bits_per_mb * 10) / 100;
-
- factor = (guint64) encoder->mb_width * encoder->mb_height * bits_per_mb;
- base_encoder->bitrate =
- gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder),
- GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000;
- GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
- }
- break;
- default:
- base_encoder->bitrate = 0;
- break;
- }
- ensure_bitrate_hrd (encoder);
-}
-
-/* Constructs profile and level information based on user-defined limits */
-static GstVaapiEncoderStatus
-ensure_profile_and_level (GstVaapiEncoderH264Fei * encoder)
-{
- const GstVaapiProfile profile = encoder->profile;
- const GstVaapiLevelH264 level = encoder->level;
-
- if (!ensure_tuning (encoder))
- GST_WARNING ("Failed to set some of the tuning option as expected! ");
-
- if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- /* Check HW constraints */
- if (!ensure_hw_profile_limits (encoder))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
- if (encoder->profile_idc > encoder->hw_max_profile_idc)
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- /* Ensure bitrate if not set already and derive the right level to use */
- ensure_bitrate (encoder);
- if (!ensure_level (encoder))
- return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
-
- if (encoder->profile != profile || encoder->level != level) {
- GST_DEBUG ("selected %s profile at level %s",
- gst_vaapi_utils_h264_get_profile_string (encoder->profile),
- gst_vaapi_utils_h264_get_level_string (encoder->level));
- encoder->config_changed = TRUE;
- }
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static void
-reset_properties (GstVaapiEncoderH264Fei * encoder)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
- guint mb_size, i;
-
- if (encoder->idr_period < base_encoder->keyframe_period)
- encoder->idr_period = base_encoder->keyframe_period;
-
- g_assert (encoder->min_qp <= encoder->max_qp);
- if (encoder->min_qp > encoder->init_qp ||
- (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
- encoder->min_qp < encoder->init_qp))
- encoder->min_qp = encoder->init_qp;
- if (encoder->max_qp < encoder->init_qp)
- encoder->max_qp = encoder->init_qp;
-
- mb_size = encoder->mb_width * encoder->mb_height;
- if (encoder->num_slices > (mb_size + 1) / 2)
- encoder->num_slices = (mb_size + 1) / 2;
- g_assert (encoder->num_slices);
-
- if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
- encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
-
- /* Workaround : vaapi-intel-driver doesn't have support for
- * B-frame encode when utilizing low-power encode hardware block.
- * So Disabling b-frame encoding in low-pwer encode.
- *
- * Fixme :We should query the VAConfigAttribEncMaxRefFrames
- * instead of blindly disabling b-frame support and set b/p frame count,
- * buffer pool size etc based on that.*/
- if ((encoder->num_bframes > 0)
- && (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) {
- GST_WARNING
- ("Disabling b-frame since the driver doesn't supporting it in low-power encode");
- encoder->num_bframes = 0;
- }
-
- if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0)
- encoder->cts_offset = gst_util_uint64_scale (GST_SECOND,
- GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder));
- else
- encoder->cts_offset = 0;
-
- /* init max_frame_num, max_poc */
- encoder->log2_max_frame_num =
- h264_get_log2_max_frame_num (encoder->idr_period);
- g_assert (encoder->log2_max_frame_num >= 4);
- encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
- encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
- encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
- encoder->idr_num = 0;
-
- for (i = 0; i < encoder->num_views; i++) {
- GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[i];
-
- ref_pool->max_reflist0_count = 1;
- ref_pool->max_reflist1_count = encoder->num_bframes > 0;
- ref_pool->max_ref_frames = ref_pool->max_reflist0_count
- + ref_pool->max_reflist1_count;
-
- reorder_pool->frame_index = 0;
- }
-}
-
-static gboolean
-copy_picture_attrib (GstVaapiEncPicture * dst, GstVaapiEncPicture * src)
-{
- if (!dst || !src)
- return FALSE;
-
- dst->proxy = src->proxy;
- dst->surface = src->surface;
- dst->type = src->type;
- dst->surface_id = src->surface_id;
- dst->frame_num = src->frame_num;
- dst->poc = src->poc;
-
- return TRUE;
-}
-
-static GstVaapiEncoderStatus
-gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc);
- GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
- GstVaapiSurfaceProxy *reconstruct = NULL;
- GstVaapiEncPicture *picture2 = NULL;
- GstVaapiFeiInfoToPakH264 info_to_pak = { {0} };
-
- reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
-
- g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
-
- if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK)
- || (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)
- || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) {
-
- if (!ensure_sequence (encoder, picture))
- goto error;
- if (!ensure_misc_params (encoder, picture))
- goto error;
- if (!encoder->is_fei_disabled
- && !ensure_fei_misc_params (encoder, picture, codedbuf))
- goto error;
- if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
- goto error;
- if (!ensure_slices (encoder, picture))
- goto error;
- if (!gst_vaapi_enc_picture_encode (picture))
- goto error;
-
- if (!reference_list_update (encoder, picture, reconstruct))
- goto error;
-
- } else if (encoder->fei_mode ==
- (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) {
- /*
- * ref pool is managed by pak.
- * enc will copy from it.
- */
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I
- && !gst_vaapi_feipak_h264_get_ref_pool (encoder->feipak,
- &encoder->ref_pool_ptr)) {
- GST_ERROR ("failed to get pak ref pool");
- status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
- goto error;
- }
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I
- && !gst_vaapi_feienc_h264_set_ref_pool (encoder->feienc,
- encoder->ref_pool_ptr)) {
- GST_ERROR ("failed to set enc ref pool");
- status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
- goto error;
- }
-
- status =
- gst_vaapi_feienc_h264_encode (enc_base_encoder, picture, reconstruct,
- codedbuf, &info_to_pak);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to process enc class encode");
- goto error;
- }
-
- /* duplicate a picture for pak */
- picture2 = GST_VAAPI_ENC_PICTURE_NEW (H264, base_encoder, picture->frame);
- if (!picture2) {
- GST_WARNING ("create H264 picture failed, frame timestamp:%"
- GST_TIME_FORMAT, GST_TIME_ARGS (picture->frame->pts));
- status = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
- goto error;
- }
- if (!copy_picture_attrib (picture2, picture)) {
- status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
- goto error;
- }
- /* need set picture IDR info for PAK */
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- GST_VAAPI_ENC_PICTURE_FLAG_SET (picture2, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
-
- status =
- gst_vaapi_feipak_h264_encode (encoder->feipak, picture2, codedbuf,
- reconstruct, &info_to_pak);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to process pak class encode");
- goto error;
- }
-
- /* Free the slice array */
- g_array_free (info_to_pak.h264_slice_headers, TRUE);
-
- gst_vaapi_enc_picture_unref (picture2);
- } else {
- GST_ERROR ("invalid FEI mode");
- goto error;
- }
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-
- /* ERRORS */
-error:
- {
- gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
- reconstruct);
- if (picture2)
- gst_vaapi_enc_picture_unref (picture2);
- if (info_to_pak.h264_slice_headers)
- g_array_free (info_to_pak.h264_slice_headers, TRUE);
- return status;
- }
-}
-
-static GstVaapiEncoderStatus
-gst_vaapi_encoder_h264_fei_flush (GstVaapiEncoder * base_encoder)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc);
- GstVaapiH264ViewReorderPool *reorder_pool;
- GstVaapiEncPicture *pic;
- GstVaapiEncoderStatus status;
- guint i;
-
- if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK)
- || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) {
- for (i = 0; i < encoder->num_views; i++) {
- reorder_pool = &encoder->reorder_pools[i];
- reorder_pool->frame_index = 0;
- reorder_pool->cur_frame_num = 0;
- reorder_pool->cur_present_index = 0;
-
- while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- pic = (GstVaapiEncPicture *)
- g_queue_pop_head (&reorder_pool->reorder_frame_list);
- gst_vaapi_enc_picture_unref (pic);
- }
- g_queue_clear (&reorder_pool->reorder_frame_list);
- }
- } else if (encoder->fei_mode ==
- (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) {
-
- status = gst_vaapi_feienc_h264_flush (enc_base_encoder);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to process enc class flush");
- return status;
- }
-
- status = gst_vaapi_feipak_h264_flush (encoder->feipak);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to process pak class flush");
- return status;
- }
- } else {
- g_assert (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC);
- }
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-/* Generate "codec-data" buffer */
-static GstVaapiEncoderStatus
-gst_vaapi_encoder_h264_fei_get_codec_data (GstVaapiEncoder * base_encoder,
- GstBuffer ** out_buffer_ptr)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- const guint32 configuration_version = 0x01;
- const guint32 nal_length_size = 4;
- guint8 profile_idc, profile_comp, level_idc;
- GstMapInfo sps_info, pps_info;
- GstBitWriter bs;
- GstBuffer *buffer;
-
- if (!encoder->sps_data || !encoder->pps_data)
- return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
- if (gst_buffer_get_size (encoder->sps_data) < 4)
- return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
-
- if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
- goto error_map_sps_buffer;
-
- if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
- goto error_map_pps_buffer;
-
- /* skip sps_data[0], which is the nal_unit_type */
- profile_idc = sps_info.data[1];
- profile_comp = sps_info.data[2];
- level_idc = sps_info.data[3];
-
- /* Header */
- gst_bit_writer_init_with_size (&bs, (sps_info.size + pps_info.size + 64),
- FALSE);
- WRITE_UINT32 (&bs, configuration_version, 8);
- WRITE_UINT32 (&bs, profile_idc, 8);
- WRITE_UINT32 (&bs, profile_comp, 8);
- WRITE_UINT32 (&bs, level_idc, 8);
- WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */
- WRITE_UINT32 (&bs, nal_length_size - 1, 2);
- WRITE_UINT32 (&bs, 0x07, 3); /* 111 */
-
- /* Write SPS */
- WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- WRITE_UINT32 (&bs, sps_info.size, 16);
- gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size);
-
- /* Write PPS */
- WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */
- WRITE_UINT32 (&bs, pps_info.size, 16);
- gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size);
-
- gst_buffer_unmap (encoder->pps_data, &pps_info);
- gst_buffer_unmap (encoder->sps_data, &sps_info);
-
- buffer = gst_bit_writer_reset_and_get_buffer (&bs);
- if (!buffer)
- goto error_alloc_buffer;
- *out_buffer_ptr = buffer;
-
- gst_bit_writer_reset (&bs);
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-
- /* ERRORS */
-bs_error:
- {
- GST_ERROR ("failed to write codec-data");
- gst_buffer_unmap (encoder->sps_data, &sps_info);
- gst_buffer_unmap (encoder->pps_data, &pps_info);
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-error_map_sps_buffer:
- {
- GST_ERROR ("failed to map SPS packed header");
- return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
- }
-error_map_pps_buffer:
- {
- GST_ERROR ("failed to map PPS packed header");
- gst_buffer_unmap (encoder->sps_data, &sps_info);
- return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
- }
-error_alloc_buffer:
- {
- GST_ERROR ("failed to allocate codec-data buffer");
- gst_bit_writer_reset (&bs);
- return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
- }
-}
-
-static GstVaapiEncoderStatus
-gst_vaapi_encoder_h264_fei_reordering (GstVaapiEncoder * base_encoder,
- GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVaapiH264ViewReorderPool *reorder_pool = NULL;
- GstVaapiEncPicture *picture;
- gboolean is_idr = FALSE;
-
- *output = NULL;
-
- if ((encoder->fei_mode != GST_VAAPI_FEI_MODE_ENC_PAK)
- && (encoder->fei_mode != GST_VAAPI_FEI_MODE_PAK)) {
- GstVaapiEncoder *enc_base_encoder =
- GST_VAAPI_ENCODER_CAST (encoder->feienc);
- GstVaapiEncoderStatus status;
-
- status = gst_vaapi_feienc_h264_reordering (enc_base_encoder, frame, output);
- if ((status != GST_VAAPI_ENCODER_STATUS_SUCCESS) &&
- (status != GST_VAAPI_ENCODER_STATUS_NO_SURFACE))
- GST_ERROR ("failed to process enc reordering");
-
- return status;
- }
-
- /* encoding views alternatively for MVC */
- if (encoder->is_mvc) {
- /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */
- if (frame)
- encoder->view_idx = frame->system_frame_number % encoder->num_views;
- else
- encoder->view_idx = (encoder->view_idx + 1) % encoder->num_views;
- }
- reorder_pool = &encoder->reorder_pools[encoder->view_idx];
-
- if (!frame) {
- if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
- return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
-
- /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
- dump B frames from queue, sometime, there may also have P frame or I frame */
- g_assert (encoder->num_bframes > 0);
- g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list),
- GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
- picture = g_queue_pop_head (&reorder_pool->reorder_frame_list);
- g_assert (picture);
- if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
- }
- goto end;
- }
-
- /* new frame coming */
- picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
- if (!picture) {
- GST_WARNING ("create H264 picture failed, frame timestamp:%"
- GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
- return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
- }
- ++reorder_pool->cur_present_index;
- picture->poc = ((reorder_pool->cur_present_index * 2) %
- encoder->max_pic_order_cnt);
-
- is_idr = (reorder_pool->frame_index == 0 ||
- reorder_pool->frame_index >= encoder->idr_period);
-
- /* check key frames */
- if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
- (reorder_pool->frame_index %
- GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) {
- ++reorder_pool->cur_frame_num;
- ++reorder_pool->frame_index;
-
- /* b frame enabled, check queue of reorder_frame_list */
- if (encoder->num_bframes
- && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- GstVaapiEncPicture *p_pic;
-
- p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
- set_p_frame (p_pic, encoder);
- g_queue_foreach (&reorder_pool->reorder_frame_list,
- (GFunc) set_b_frame, encoder);
- ++reorder_pool->cur_frame_num;
- set_key_frame (picture, encoder, is_idr);
- g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
- picture = p_pic;
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
- } else { /* no b frames in queue */
- set_key_frame (picture, encoder, is_idr);
- g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list));
- if (encoder->num_bframes)
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
- }
- goto end;
- }
-
- /* new p/b frames coming */
- ++reorder_pool->frame_index;
- if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
- g_queue_get_length (&reorder_pool->reorder_frame_list) <
- encoder->num_bframes) {
- g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
- return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
- }
-
- ++reorder_pool->cur_frame_num;
- set_p_frame (picture, encoder);
-
- if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
- g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame,
- encoder);
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
- g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list));
- }
-
-end:
- g_assert (picture);
- frame = picture->frame;
- if (GST_CLOCK_TIME_IS_VALID (frame->pts))
- frame->pts += encoder->cts_offset;
- *output = picture;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static GstVaapiEncoderStatus
-set_context_info (GstVaapiEncoder * base_encoder)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
- const guint DEFAULT_SURFACES_COUNT = 3;
-
- /* Maximum sizes for common headers (in bits) */
- enum
- {
- MAX_SPS_HDR_SIZE = 16473,
- MAX_VUI_PARAMS_SIZE = 210,
- MAX_HRD_PARAMS_SIZE = 4103,
- MAX_PPS_HDR_SIZE = 101,
- MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
- };
-
- if (!ensure_hw_profile (encoder))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- base_encoder->num_ref_frames =
- ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT)
- * encoder->num_views;
-
- /* Only YUV 4:2:0 formats are supported for now. This means that we
- have a limit of 3200 bits per macroblock. */
- /* XXX: check profile and compute RawMbBits */
- base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
- GST_ROUND_UP_16 (vip->height) / 256) * 400;
-
- /* Account for SPS header */
- /* XXX: exclude scaling lists, MVC/SVC extensions */
- base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
- MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
-
- /* Account for PPS header */
- /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
- base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
-
- /* Account for slice header */
- base_encoder->codedbuf_size += encoder->num_slices * (4 +
- GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
-
- base_encoder->context_info.entrypoint = encoder->entrypoint;
-
- /* Fixme: Add a method to get VA_FEI_FUNCTION_* from GstVaapiFeiMode */
- base_encoder->context_info.config.encoder.fei_function = encoder->fei_mode;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static gboolean
-copy_encoder_common_property (GstVaapiEncoder * dst, GstVaapiEncoder * src)
-{
- if (!dst || !src)
- return FALSE;
-
- dst->tune = src->tune;
- dst->rate_control = src->rate_control;
- dst->rate_control_mask = src->rate_control_mask;
- dst->bitrate = src->bitrate;
- dst->keyframe_period = src->keyframe_period;
-
- return TRUE;
-}
-
-static GstVaapiEncoderStatus
-gst_vaapi_encoder_h264_fei_reconfigure (GstVaapiEncoder * base_encoder)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
- GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc);
- GstVideoInfo *vip_enc = GST_VAAPI_ENCODER_VIDEO_INFO (encoder->feienc);
- GstVaapiEncoderStatus status;
- guint mb_width, mb_height;
- const guint DEFAULT_SURFACES_COUNT = 3;
-
- if (encoder->fei_mode != (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) {
- /* ENC_PAK, ENC and PAK modes doesn't need to care about ENC and PAK
- * abstrct objects */
- mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
- mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
- if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) {
- GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder),
- GST_VAAPI_ENCODER_HEIGHT (encoder));
- encoder->mb_width = mb_width;
- encoder->mb_height = mb_height;
- encoder->config_changed = TRUE;
- }
-
- /* Take number of MVC views from input caps if provided */
- if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) ==
- GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME
- || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) ==
- GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME)
- encoder->num_views = GST_VIDEO_INFO_VIEWS (vip);
-
- encoder->is_mvc = encoder->num_views > 1;
-
- status = ensure_profile_and_level (encoder);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
- return status;
-
- reset_properties (encoder);
- status = set_context_info (base_encoder);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
- return status;
-
- } else {
- /* ENC+PAK mode requires two separate objects
- for ENC and PAK */
-
- /* Maximum sizes for common headers (in bits) */
- enum
- {
- MAX_SPS_HDR_SIZE = 16473,
- MAX_VUI_PARAMS_SIZE = 210,
- MAX_HRD_PARAMS_SIZE = 4103,
- MAX_PPS_HDR_SIZE = 101,
- MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
- };
-
- /* copy encoder-fei common property to feienc */
- if (!copy_encoder_common_property (enc_base_encoder, base_encoder))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
-
- /* copy video info to feienc */
- *vip_enc = *vip;
-
- status = gst_vaapi_feienc_h264_reconfigure (enc_base_encoder);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to process enc reconfigure");
- return status;
- }
-
- if (!gst_vaapi_feienc_h264_get_profile_and_idc (encoder->feienc,
- &encoder->profile, &encoder->profile_idc))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
-
- base_encoder->profile = enc_base_encoder->profile;
-
- mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
- mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
- if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) {
- GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder),
- GST_VAAPI_ENCODER_HEIGHT (encoder));
- encoder->mb_width = mb_width;
- encoder->mb_height = mb_height;
- encoder->config_changed = TRUE;
- }
-
- status =
- gst_vaapi_feipak_h264_reconfigure (encoder->feipak,
- base_encoder->va_context, encoder->profile, encoder->profile_idc,
- encoder->mb_width, encoder->mb_height, encoder->num_views,
- encoder->num_slices, encoder->num_ref_frames);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to process pak reconfigure");
- return status;
- }
-
- base_encoder->num_ref_frames =
- (encoder->num_ref_frames + DEFAULT_SURFACES_COUNT) * encoder->num_views;
-
- /* Only YUV 4:2:0 formats are supported for now. This means that we
- have a limit of 3200 bits per macroblock. */
- /* XXX: check profile and compute RawMbBits */
- base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
- GST_ROUND_UP_16 (vip->height) / 256) * 400;
-
- /* Account for SPS header */
- /* XXX: exclude scaling lists, MVC/SVC extensions */
- base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
- MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
-
- /* Account for PPS header */
- /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
- base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
-
- /* Account for slice header */
- base_encoder->codedbuf_size += encoder->num_slices * (4 +
- GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
-
- base_encoder->context_info.entrypoint = encoder->entrypoint;
-
- /* ENC+PAK mode use the base encoder context for PAK
- * ENC handled separately */
- if (encoder->fei_mode == (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK))
- base_encoder->context_info.config.encoder.fei_function =
- GST_VAAPI_FEI_MODE_PAK;
- }
-
- return status;
-}
-
-struct _GstVaapiEncoderH264FeiClass
-{
- GstVaapiEncoderClass parent_class;
-};
-
-G_DEFINE_TYPE (GstVaapiEncoderH264Fei, gst_vaapi_encoder_h264_fei,
- GST_TYPE_VAAPI_ENCODER);
-
-static void
-gst_vaapi_encoder_h264_fei_init (GstVaapiEncoderH264Fei * encoder)
-{
- guint32 i;
-
- /* Default encoding entrypoint */
- encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
- encoder->is_fei_disabled = FALSE;
- encoder->is_stats_out_enabled = FALSE;
- encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC_PAK;
- encoder->search_path = GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT;
- encoder->len_sp = GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT;
- encoder->ref_width = GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT;
- encoder->ref_height = GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT;
- encoder->intra_part_mask = GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT;
- encoder->submb_part_mask = GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT;
- /* default num ref frames */
- encoder->num_ref_frames = 1;
- /* Multi-view coding information */
- encoder->is_mvc = FALSE;
- encoder->num_views = 1;
- encoder->view_idx = 0;
- memset (encoder->view_ids, 0, sizeof (encoder->view_ids));
-
- /* re-ordering list initialize */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[i];
- g_queue_init (&reorder_pool->reorder_frame_list);
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
- reorder_pool->frame_index = 0;
- reorder_pool->cur_frame_num = 0;
- reorder_pool->cur_present_index = 0;
- }
-
- /* reference list info initialize */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
- g_queue_init (&ref_pool->ref_list);
- ref_pool->max_ref_frames = 0;
- ref_pool->max_reflist0_count = 1;
- ref_pool->max_reflist1_count = 1;
- }
-}
-
-static void
-gst_vaapi_encoder_h264_fei_finalize (GObject * gobject)
-{
- /*free private buffers */
- GstVaapiEncoderH264Fei *const encoder = GST_VAAPI_ENCODER_H264_FEI (gobject);
- GstVaapiEncoder *base_encoder = GST_VAAPI_ENCODER (gobject);
- GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc);
- GstVaapiMiniObject *object = GST_VAAPI_MINI_OBJECT (encoder->feipak);
- GstVaapiEncPicture *pic;
- GstVaapiEncoderH264FeiRef *ref;
- guint32 i;
-
- if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK)
- || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) {
-
- gst_buffer_replace (&encoder->sps_data, NULL);
- gst_buffer_replace (&encoder->subset_sps_data, NULL);
- gst_buffer_replace (&encoder->pps_data, NULL);
-
- /* reference list info de-init */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
- while (!g_queue_is_empty (&ref_pool->ref_list)) {
- ref = (GstVaapiEncoderH264FeiRef *)
- g_queue_pop_head (&ref_pool->ref_list);
- reference_pic_free (encoder, ref);
- }
- g_queue_clear (&ref_pool->ref_list);
- }
-
- /* re-ordering list initialize */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &encoder->reorder_pools[i];
- while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- pic = (GstVaapiEncPicture *)
- g_queue_pop_head (&reorder_pool->reorder_frame_list);
- gst_vaapi_enc_picture_unref (pic);
- }
- g_queue_clear (&reorder_pool->reorder_frame_list);
- }
-
- } else {
- if (encoder->coded_buf != VA_INVALID_ID) {
- GST_VAAPI_DISPLAY_LOCK (base_encoder->display);
- vaapi_destroy_buffer (base_encoder->va_display, &encoder->coded_buf);
- GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display);
- encoder->coded_buf = VA_INVALID_ID;
- }
-
- if (enc_base_encoder->va_context != VA_INVALID_ID) {
- GST_VAAPI_DISPLAY_LOCK (base_encoder->display);
- vaDestroyContext (base_encoder->va_display, enc_base_encoder->va_context);
- GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display);
- enc_base_encoder->va_context = VA_INVALID_ID;
- }
-
- if (encoder->va_config != VA_INVALID_ID) {
- GST_VAAPI_DISPLAY_LOCK (base_encoder->display);
- vaDestroyConfig (base_encoder->va_display, encoder->va_config);
- GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display);
- encoder->va_config = VA_INVALID_ID;
- }
-
- gst_vaapi_encoder_replace (&enc_base_encoder, NULL);
- gst_vaapi_mini_object_replace (&object, NULL);
-
- encoder->ref_pool_ptr = NULL;
- encoder->feienc = NULL;
- }
-
- G_OBJECT_CLASS (gst_vaapi_encoder_h264_fei_parent_class)->finalize (gobject);
-}
-
-static void
-set_view_ids (GstVaapiEncoderH264Fei * const encoder, const GValue * value)
-{
- guint i, j;
- guint len = gst_value_array_get_size (value);
-
- if (len == 0)
- goto set_default_ids;
-
- if (len != encoder->num_views) {
- GST_WARNING ("The view number is %d, but %d view IDs are provided. Just "
- "fallback to use default view IDs.", encoder->num_views, len);
- goto set_default_ids;
- }
-
- for (i = 0; i < len; i++) {
- const GValue *val = gst_value_array_get_value (value, i);
- encoder->view_ids[i] = g_value_get_uint (val);
- }
-
- /* check whether duplicated ID */
- for (i = 0; i < len; i++) {
- for (j = i + 1; j < len; j++) {
- if (encoder->view_ids[i] == encoder->view_ids[j]) {
- GST_WARNING ("The view %d and view %d have same view ID %d. Just "
- "fallback to use default view IDs.", i, j, encoder->view_ids[i]);
- goto set_default_ids;
- }
- }
- }
-
- return;
-
-set_default_ids:
- {
- for (i = 0; i < encoder->num_views; i++)
- encoder->view_ids[i] = i;
- }
-}
-
-static void
-get_view_ids (GstVaapiEncoderH264Fei * const encoder, GValue * value)
-{
- guint i;
- GValue id = G_VALUE_INIT;
-
- g_value_reset (value);
- g_value_init (&id, G_TYPE_UINT);
-
- for (i = 0; i < encoder->num_views; i++) {
- g_value_set_uint (&id, encoder->view_ids[i]);
- gst_value_array_append_value (value, &id);
- }
- g_value_unset (&id);
-}
-
-/**
- * @ENCODER_H264_FEI_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
- * @ENCODER_H264_FEI_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
- * @ENCODER_H264_FEI_PROP_MAX_BFRAMES: Number of B-frames between I
- * and P (uint).
- * @ENCODER_H264_FEI_PROP_INIT_QP: Initial quantizer value (uint).
- * @ENCODER_H264_FEI_PROP_MIN_QP: Minimal quantizer value (uint).
- * @ENCODER_H264_FEI_PROP_NUM_SLICES: Number of slices per frame (uint).
- * @ENCODER_H264_FEI_PROP_CABAC: Enable CABAC entropy coding mode (bool).
- * @ENCODER_H264_FEI_PROP_DCT8X8: Enable adaptive use of 8x8
- * transforms in I-frames (bool).
- * @ENCODER_H264_FEI_PROP_CPB_LENGTH: Length of the CPB buffer
- * in milliseconds (uint).
- * @ENCODER_H264_FEI_PROP_NUM_VIEWS: Number of views per frame.
- * @ENCODER_H264_FEI_PROP_VIEW_IDS: View IDs
- * @ENCODER_H264_FEI_PROP_MAX_QP: Maximal quantizer value (uint).
- *
- * The set of H.264 encoder specific configurable properties.
- */
-enum
-{
- ENCODER_H264_FEI_PROP_RATECONTROL = 1,
- ENCODER_H264_FEI_PROP_TUNE,
- ENCODER_H264_FEI_PROP_MAX_BFRAMES,
- ENCODER_H264_FEI_PROP_INIT_QP,
- ENCODER_H264_FEI_PROP_MIN_QP,
- ENCODER_H264_FEI_PROP_NUM_SLICES,
- ENCODER_H264_FEI_PROP_CABAC,
- ENCODER_H264_FEI_PROP_DCT8X8,
- ENCODER_H264_FEI_PROP_CPB_LENGTH,
- ENCODER_H264_FEI_PROP_NUM_VIEWS,
- ENCODER_H264_FEI_PROP_VIEW_IDS,
- ENCODER_H264_PROP_FEI_DISABLE,
- ENCODER_H264_PROP_NUM_MV_PREDICT_L0,
- ENCODER_H264_PROP_NUM_MV_PREDICT_L1,
- ENCODER_H264_PROP_SEARCH_WINDOW,
- ENCODER_H264_PROP_LEN_SP,
- ENCODER_H264_PROP_SEARCH_PATH,
- ENCODER_H264_PROP_REF_WIDTH,
- ENCODER_H264_PROP_REF_HEIGHT,
- ENCODER_H264_PROP_SUBMB_MASK,
- ENCODER_H264_PROP_SUBPEL_MODE,
- ENCODER_H264_PROP_INTRA_PART_MASK,
- ENCODER_H264_PROP_INTRA_SAD,
- ENCODER_H264_PROP_INTER_SAD,
- ENCODER_H264_PROP_ADAPT_SEARCH,
- ENCODER_H264_PROP_MULTI_PRED_L0,
- ENCODER_H264_PROP_MULTI_PRED_L1,
- ENCODER_H264_PROP_ENABLE_STATS_OUT,
- ENCODER_H264_PROP_FEI_MODE,
- ENCODER_H264_FEI_PROP_MAX_QP,
- ENCODER_H264_FEI_N_PROPERTIES
-};
-
-static GParamSpec *properties[ENCODER_H264_FEI_N_PROPERTIES];
-
-static void
-gst_vaapi_encoder_h264_fei_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc);
- GstVaapiEncoderStatus status;
-
- switch (prop_id) {
- case ENCODER_H264_FEI_PROP_RATECONTROL:
- gst_vaapi_encoder_set_rate_control (base_encoder,
- g_value_get_enum (value));
- break;
- case ENCODER_H264_FEI_PROP_TUNE:
- gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
- break;
- case ENCODER_H264_FEI_PROP_MAX_BFRAMES:
- encoder->num_bframes = g_value_get_uint (value);
- break;
- case ENCODER_H264_FEI_PROP_INIT_QP:
- encoder->init_qp = g_value_get_uint (value);
- break;
- case ENCODER_H264_FEI_PROP_MIN_QP:
- encoder->min_qp = g_value_get_uint (value);
- break;
- case ENCODER_H264_FEI_PROP_NUM_SLICES:
- encoder->num_slices = g_value_get_uint (value);
- break;
- case ENCODER_H264_FEI_PROP_CABAC:
- encoder->use_cabac = g_value_get_boolean (value);
- break;
- case ENCODER_H264_FEI_PROP_DCT8X8:
- encoder->use_dct8x8 = g_value_get_boolean (value);
- break;
- case ENCODER_H264_FEI_PROP_CPB_LENGTH:
- encoder->cpb_length = g_value_get_uint (value);
- break;
- case ENCODER_H264_FEI_PROP_NUM_VIEWS:
- encoder->num_views = g_value_get_uint (value);
- break;
- case ENCODER_H264_FEI_PROP_VIEW_IDS:
- set_view_ids (encoder, value);
- break;
- case ENCODER_H264_PROP_FEI_DISABLE:
- encoder->is_fei_disabled = g_value_get_boolean (value);
- if (!encoder->is_fei_disabled)
- encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI;
- break;
- case ENCODER_H264_PROP_NUM_MV_PREDICT_L0:
- encoder->num_mv_predictors_l0 = g_value_get_uint (value);
- break;
- case ENCODER_H264_PROP_NUM_MV_PREDICT_L1:
- encoder->num_mv_predictors_l1 = g_value_get_uint (value);
- break;
- case ENCODER_H264_PROP_SEARCH_WINDOW:
- encoder->search_window = g_value_get_enum (value);
- break;
- case ENCODER_H264_PROP_LEN_SP:
- encoder->len_sp = g_value_get_uint (value);
- break;
- case ENCODER_H264_PROP_SEARCH_PATH:
- encoder->search_path = g_value_get_enum (value);
- break;
- case ENCODER_H264_PROP_REF_WIDTH:
- encoder->ref_width = g_value_get_uint (value);
- break;
- case ENCODER_H264_PROP_REF_HEIGHT:
- encoder->ref_height = g_value_get_uint (value);
- break;
- case ENCODER_H264_PROP_SUBMB_MASK:
- encoder->submb_part_mask = g_value_get_flags (value);
- break;
- case ENCODER_H264_PROP_SUBPEL_MODE:
- encoder->subpel_mode = g_value_get_enum (value);
- break;
- case ENCODER_H264_PROP_INTRA_PART_MASK:
- encoder->intra_part_mask = g_value_get_flags (value);
- break;
- case ENCODER_H264_PROP_INTRA_SAD:
- encoder->intra_sad = g_value_get_enum (value);
- break;
- case ENCODER_H264_PROP_INTER_SAD:
- encoder->inter_sad = g_value_get_enum (value);
- break;
- case ENCODER_H264_PROP_ADAPT_SEARCH:
- encoder->adaptive_search = g_value_get_boolean (value) ? 1 : 0;
- break;
- case ENCODER_H264_PROP_MULTI_PRED_L0:
- encoder->multi_predL0 = g_value_get_boolean (value) ? 1 : 0;
- break;
- case ENCODER_H264_PROP_MULTI_PRED_L1:
- encoder->multi_predL1 = g_value_get_boolean (value) ? 1 : 0;
- break;
- case ENCODER_H264_PROP_ENABLE_STATS_OUT:
- encoder->is_stats_out_enabled = g_value_get_boolean (value);
- break;
- case ENCODER_H264_PROP_FEI_MODE:
- encoder->fei_mode = g_value_get_flags (value);
- if (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) {
- g_warning ("============= ENC only mode selected ============ \n"
- "We internally run the PAK stage because, the ENC operation requires the reconstructed output of PAK mode. Right now we have no infrastructure to provide reconstructed surfaces to ENC with out running the PAK \n");
- /*Fixme: Support ENC only mode with out running PAK */
- encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK;
- } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) {
- g_warning ("============ PAK only mode selected ============ \n"
- "This mode can work as expected, only if there is a custom user specific upstream element which provides mb_code and mv_vectors. If you are running the pipeline only for verification, We recommand to use the fei-mod ENC+PAK which will run the ENC operation and generate what ever input needed for PAK \n");
- }
-
- break;
- case ENCODER_H264_FEI_PROP_MAX_QP:
- encoder->max_qp = g_value_get_uint (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-
- if ((prop_id != ENCODER_H264_PROP_FEI_MODE) &&
- (prop_id != ENCODER_H264_PROP_FEI_DISABLE) &&
- (prop_id != ENCODER_H264_PROP_ENABLE_STATS_OUT)) {
-
- if (enc_base_encoder) {
- g_object_set_property ((GObject *) enc_base_encoder,
- g_param_spec_get_name (pspec), value);
- }
-
- if ((prop_id == ENCODER_H264_FEI_PROP_MAX_BFRAMES) ||
- (prop_id == ENCODER_H264_FEI_PROP_VIEW_IDS) ||
- (prop_id == ENCODER_H264_FEI_PROP_NUM_VIEWS)) {
- if (encoder->feipak) {
- status =
- gst_vaapi_feipak_h264_set_property (encoder->feipak, prop_id,
- value);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- GST_ERROR ("failed to set pak property");
- return;
- }
- }
- }
- }
-}
-
-static void
-gst_vaapi_encoder_h264_fei_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (object);
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
-
- switch (prop_id) {
- case ENCODER_H264_FEI_PROP_RATECONTROL:
- g_value_set_enum (value, base_encoder->rate_control);
- break;
- case ENCODER_H264_FEI_PROP_TUNE:
- g_value_set_enum (value, base_encoder->tune);
- break;
- case ENCODER_H264_FEI_PROP_MAX_BFRAMES:
- g_value_set_uint (value, encoder->num_bframes);
- break;
- case ENCODER_H264_FEI_PROP_INIT_QP:
- g_value_set_uint (value, encoder->init_qp);
- break;
- case ENCODER_H264_FEI_PROP_MIN_QP:
- g_value_set_uint (value, encoder->min_qp);
- break;
- case ENCODER_H264_FEI_PROP_NUM_SLICES:
- g_value_set_uint (value, encoder->num_slices);
- break;
- case ENCODER_H264_FEI_PROP_CABAC:
- g_value_set_boolean (value, encoder->use_cabac);
- break;
- case ENCODER_H264_FEI_PROP_DCT8X8:
- g_value_set_boolean (value, encoder->use_dct8x8);
- break;
- case ENCODER_H264_FEI_PROP_CPB_LENGTH:
- g_value_set_uint (value, encoder->cpb_length);
- break;
- case ENCODER_H264_FEI_PROP_NUM_VIEWS:
- g_value_set_uint (value, encoder->num_views);
- break;
- case ENCODER_H264_FEI_PROP_VIEW_IDS:
- get_view_ids (encoder, value);
- break;
- case ENCODER_H264_PROP_FEI_DISABLE:
- g_value_set_boolean (value, encoder->is_fei_disabled);
- break;
- case ENCODER_H264_PROP_NUM_MV_PREDICT_L0:
- g_value_set_uint (value, encoder->num_mv_predictors_l0);
- break;
- case ENCODER_H264_PROP_NUM_MV_PREDICT_L1:
- g_value_set_uint (value, encoder->num_mv_predictors_l1);
- break;
- case ENCODER_H264_PROP_SEARCH_WINDOW:
- g_value_set_enum (value, encoder->search_window);
- break;
- case ENCODER_H264_PROP_LEN_SP:
- g_value_set_uint (value, encoder->len_sp);
- break;
- case ENCODER_H264_PROP_SEARCH_PATH:
- g_value_set_enum (value, encoder->search_path);
- break;
- case ENCODER_H264_PROP_REF_WIDTH:
- g_value_set_uint (value, encoder->ref_width);
- break;
- case ENCODER_H264_PROP_REF_HEIGHT:
- g_value_set_uint (value, encoder->ref_height);
- break;
- case ENCODER_H264_PROP_SUBMB_MASK:
- g_value_set_flags (value, encoder->submb_part_mask);
- break;
- case ENCODER_H264_PROP_SUBPEL_MODE:
- g_value_set_enum (value, encoder->subpel_mode);
- break;
- case ENCODER_H264_PROP_INTRA_PART_MASK:
- g_value_set_flags (value, encoder->intra_part_mask);
- break;
- case ENCODER_H264_PROP_INTRA_SAD:
- g_value_set_enum (value, encoder->intra_sad);
- break;
- case ENCODER_H264_PROP_INTER_SAD:
- g_value_set_enum (value, encoder->inter_sad);
- break;
- case ENCODER_H264_PROP_ADAPT_SEARCH:
- g_value_set_boolean (value, encoder->adaptive_search);
- break;
- case ENCODER_H264_PROP_MULTI_PRED_L0:
- g_value_set_boolean (value, encoder->multi_predL0);
- break;
- case ENCODER_H264_PROP_MULTI_PRED_L1:
- g_value_set_boolean (value, encoder->multi_predL1);
- break;
- case ENCODER_H264_PROP_ENABLE_STATS_OUT:
- g_value_set_boolean (value, encoder->is_stats_out_enabled);
- break;
- case ENCODER_H264_PROP_FEI_MODE:
- g_value_set_flags (value, encoder->fei_mode);
- break;
- case ENCODER_H264_FEI_PROP_MAX_QP:
- g_value_set_uint (value, encoder->max_qp);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static inline gboolean
-context_get_attribute (GstVaapiContext * context, VAConfigAttribType type,
- guint * out_value_ptr)
-{
- return gst_vaapi_get_config_attribute (GST_VAAPI_CONTEXT_DISPLAY (context),
- context->va_profile, context->va_entrypoint, type, out_value_ptr);
-}
-
-static gboolean
-create_context_for_enc (GstVaapiEncoder * fei_encoder,
- GstVaapiEncoder * enc_encoder)
-{
- GstVaapiEncoderH264Fei *const feiencoder =
- GST_VAAPI_ENCODER_H264_FEI (fei_encoder);
- GstVaapiContext *context = fei_encoder->context;
- const GstVaapiContextInfo *const cip = &context->info;
- GstVaapiDisplay *const display = fei_encoder->display;
- const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder;
- guint va_rate_control;
- VAConfigAttrib attribs[5], *attrib = attribs;
- VASurfaceID surface_id;
- VAStatus status;
- GArray *surfaces = NULL;
- gboolean success = FALSE;
- guint i, value, va_chroma_format;
-
- if (!context->surfaces)
- goto cleanup;
-
- /* Create VA surfaces list for vaCreateContext() */
- surfaces = g_array_sized_new (FALSE,
- FALSE, sizeof (VASurfaceID), context->surfaces->len);
- if (!surfaces)
- goto cleanup;
-
- for (i = 0; i < context->surfaces->len; i++) {
- GstVaapiSurface *const surface = g_ptr_array_index (context->surfaces, i);
- if (!surface)
- goto cleanup;
- surface_id = GST_VAAPI_SURFACE_ID (surface);
- g_array_append_val (surfaces, surface_id);
- }
- g_assert (surfaces->len == context->surfaces->len);
- if (!cip->profile || !cip->entrypoint)
- goto cleanup;
-
- /* Validate VA surface format */
- va_chroma_format = from_GstVaapiChromaType (cip->chroma_type);
- if (!va_chroma_format)
- goto cleanup;
- attrib->type = VAConfigAttribRTFormat;
- if (!context_get_attribute (context, attrib->type, &value))
- goto cleanup;
- if (!(value & va_chroma_format)) {
- GST_ERROR ("unsupported chroma format (%s)",
- string_of_va_chroma_format (va_chroma_format));
- goto cleanup;
- }
- attrib->value = va_chroma_format;
- attrib++;
-
- /* Rate control */
- va_rate_control = from_GstVaapiRateControl (config->rc_mode);
- if (va_rate_control != VA_RC_NONE) {
- attrib->type = VAConfigAttribRateControl;
- if (!context_get_attribute (context, attrib->type, &value))
- goto cleanup;
-
- if ((value & va_rate_control) != va_rate_control) {
- GST_ERROR ("unsupported %s rate control",
- string_of_VARateControl (va_rate_control));
- goto cleanup;
- }
- attrib->value = va_rate_control;
- attrib++;
- }
-
- /* Packed headers */
- if (config->packed_headers) {
- attrib->type = VAConfigAttribEncPackedHeaders;
- attrib->value = VA_ENC_PACKED_HEADER_NONE;
- attrib++;
- }
-
- if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) {
- attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType;
- attrib->value = VA_FEI_FUNCTION_ENC;
- attrib++;
- attrib->type = (VAConfigAttribType) VAConfigAttribFEIMVPredictors;
- attrib->value = 1;
- attrib++;
- }
-
- GST_VAAPI_DISPLAY_LOCK (display);
- status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display),
- context->va_profile, context->va_entrypoint, attribs, attrib - attribs,
- &feiencoder->va_config);
- GST_VAAPI_DISPLAY_UNLOCK (display);
- if (!vaapi_check_status (status, "vaCreateConfig()"))
- goto cleanup;
-
- GST_VAAPI_DISPLAY_LOCK (display);
- status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display),
- feiencoder->va_config, GST_ROUND_UP_16 (cip->width),
- GST_ROUND_UP_16 (cip->height), VA_PROGRESSIVE,
- (VASurfaceID *) surfaces->data, surfaces->len, &enc_encoder->va_context);
- GST_VAAPI_DISPLAY_UNLOCK (display);
- if (!vaapi_check_status (status, "vaCreateContext()"))
- goto cleanup;
-
- success = TRUE;
-
-cleanup:
- if (surfaces)
- g_array_free (surfaces, TRUE);
- return success;
-}
-
-static const GstVaapiEncoderClassData fei_encoder_class_data = {
- .codec = GST_VAAPI_CODEC_H264,
- .packed_headers = SUPPORTED_PACKED_HEADERS,
- .rate_control_get_type = gst_vaapi_rate_control_get_type,
- .default_rate_control = DEFAULT_RATECONTROL,
- .rate_control_mask = SUPPORTED_RATECONTROLS,
- .encoder_tune_get_type = gst_vaapi_encoder_tune_get_type,
- .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE,
- .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS,
-};
-
-static void
-gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass)
-{
- GObjectClass *const object_class = G_OBJECT_CLASS (klass);
- GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
-
- encoder_class->class_data = &fei_encoder_class_data;
- encoder_class->reconfigure = gst_vaapi_encoder_h264_fei_reconfigure;
- encoder_class->reordering = gst_vaapi_encoder_h264_fei_reordering;
- encoder_class->encode = gst_vaapi_encoder_h264_fei_encode;
- encoder_class->flush = gst_vaapi_encoder_h264_fei_flush;
- encoder_class->get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data;
- encoder_class->ensure_secondary_context =
- gst_vaapi_encoder_h264_fei_ensure_secondary_context;
-
- object_class->set_property = gst_vaapi_encoder_h264_fei_set_property;
- object_class->get_property = gst_vaapi_encoder_h264_fei_get_property;
- object_class->finalize = gst_vaapi_encoder_h264_fei_finalize;
-
- /**
- * GstVaapiEncoderH264Fei:rate-control:
- *
- * The desired rate control mode, expressed as a #GstVaapiRateControl.
- */
- properties[ENCODER_H264_FEI_PROP_RATECONTROL] =
- g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode",
- fei_encoder_class_data.rate_control_get_type (),
- fei_encoder_class_data.default_rate_control,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:tune:
- *
- * The desired encoder tuning option.
- */
- properties[ENCODER_H264_FEI_PROP_TUNE] =
- g_param_spec_enum ("tune",
- "Encoder Tuning",
- "Encoder tuning option",
- fei_encoder_class_data.encoder_tune_get_type (),
- fei_encoder_class_data.default_encoder_tune,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:max-bframes:
- *
- * The number of B-frames between I and P.
- */
- properties[ENCODER_H264_FEI_PROP_MAX_BFRAMES] =
- g_param_spec_uint ("max-bframes",
- "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:init-qp:
- *
- * The initial quantizer value.
- */
- properties[ENCODER_H264_FEI_PROP_INIT_QP] =
- g_param_spec_uint ("init-qp",
- "Initial QP", "Initial quantizer value", 0, 51, 26,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:min-qp:
- *
- * The minimum quantizer value.
- */
- properties[ENCODER_H264_FEI_PROP_MIN_QP] =
- g_param_spec_uint ("min-qp",
- "Minimum QP", "Minimum quantizer value", 0, 51, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:max-qp:
- *
- * The maximum quantizer value.
- *
- * Since: 1.18
- */
- properties[ENCODER_H264_FEI_PROP_MAX_QP] =
- g_param_spec_uint ("max-qp",
- "Maximum QP", "Maximum quantizer value", 0, 51, 51,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:num-slices:
- *
- * The number of slices per frame.
- */
- properties[ENCODER_H264_FEI_PROP_NUM_SLICES] =
- g_param_spec_uint ("num-slices",
- "Number of Slices",
- "Number of slices per frame",
- 1, 200, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:cabac:
- *
- * Enable CABAC entropy coding mode for improved compression ratio,
- * at the expense that the minimum target profile is Main. Default
- * is CAVLC entropy coding mode.
- */
- properties[ENCODER_H264_FEI_PROP_CABAC] =
- g_param_spec_boolean ("cabac",
- "Enable CABAC",
- "Enable CABAC entropy coding mode",
- TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:dct8x8:
- *
- * Enable adaptive use of 8x8 transforms in I-frames. This improves
- * the compression ratio by the minimum target profile is High.
- * Default is to use 4x4 DCT only.
- */
- properties[ENCODER_H264_FEI_PROP_DCT8X8] =
- g_param_spec_boolean ("dct8x8",
- "Enable 8x8 DCT",
- "Enable adaptive use of 8x8 transforms in I-frames",
- TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:cpb-length:
- *
- * The size of the CPB buffer in milliseconds.
- */
- properties[ENCODER_H264_FEI_PROP_CPB_LENGTH] =
- g_param_spec_uint ("cpb-length",
- "CPB Length", "Length of the CPB buffer in milliseconds",
- 1, 10000, DEFAULT_CPB_LENGTH,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei:num-views:
- *
- * The number of views for MVC encoding .
- */
- properties[ENCODER_H264_FEI_PROP_NUM_VIEWS] =
- g_param_spec_uint ("num-views",
- "Number of Views",
- "Number of Views for MVC encoding",
- 1, MAX_NUM_VIEWS, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiEncoderH264Fei:view-ids:
- *
- * The view ids for MVC encoding .
- */
- properties[ENCODER_H264_FEI_PROP_VIEW_IDS] =
- gst_param_spec_array ("view-ids",
- "View IDs", "Set of View Ids used for MVC encoding",
- g_param_spec_uint ("view-id-value", "View id value",
- "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264: disable-fei:
- *
- * Disable FEI mode Encode: disabling fei will results
- * the encoder to use VAEntrypointEncSlice, which means
- * vaapi-intel-driver will be using a different media kerenl.
- * And most of the properties associated with this element
- * will be non functional.
- */
- properties[ENCODER_H264_PROP_FEI_DISABLE] =
- g_param_spec_boolean ("disable-fei",
- "Disable FEI Mode Encode",
- "Disable Flexible Encoding Infrasturcture", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
-
- /**
- * GstVaapiEncoderH264: stats-out:
- *
- * Enable outputting fei buffers MV, MBCode and Distortion.
- * If enabled, encoder will allocate memory for these buffers
- * and submit to the driver even for ENC_PAK mode so that
- * the output data can be extraced for analysis after the
- * complettion of each frame ncode
- */
- properties[ENCODER_H264_PROP_ENABLE_STATS_OUT] =
- g_param_spec_boolean ("stats-out",
- "stats out",
- "Enable stats out for fei",
- TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:num_mv_predictors_l0:
- * Indicate how many mv predictors should be used for l0 frames.
- * Only valid if MVPredictor input has been enabled.
- */
- properties[ENCODER_H264_PROP_NUM_MV_PREDICT_L0] =
- g_param_spec_uint ("num-mvpredict-l0",
- "Num mv predict l0",
- "Indicate how many predictors should be used for l0,"
- "only valid if MVPredictor input enabled",
- 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiEncoderH264:num_mv_predictors_l1:
- * Indicate how many mv predictors should be used for l1 frames.
- * Only valid if MVPredictor input has been enabled.
- *
- */
- properties[ENCODER_H264_PROP_NUM_MV_PREDICT_L1] =
- g_param_spec_uint ("num-mvpredict-l1",
- "Num mv predict l1",
- "Indicate how many predictors should be used for l1,"
- "only valid if MVPredictor input enabled",
- 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiEncoderH264:search-window:
- * Use predefined Search Window
- */
- properties[ENCODER_H264_PROP_SEARCH_WINDOW] =
- g_param_spec_enum ("search-window",
- "search window",
- "Specify one of the predefined search path",
- GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:len-sp:
- * Defines the maximum number of Search Units per reference.
- */
- properties[ENCODER_H264_PROP_LEN_SP] =
- g_param_spec_uint ("len-sp",
- "length of search path",
- "This value defines number of search units in search path",
- 1, 63, 32,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:search-path:
- * SearchPath defines the motion search method.
- * Zero means full search, 1 indicate diamond search.
- */
- properties[ENCODER_H264_PROP_SEARCH_PATH] =
- g_param_spec_enum ("search-path",
- "search path",
- "Specify search path",
- GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH,
- GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:ref-width:
- * Specifies the search region width in pixels.
- */
- properties[ENCODER_H264_PROP_REF_WIDTH] =
- g_param_spec_uint ("ref-width",
- "ref width",
- "Width of search region in pixel, must be multiple of 4",
- 4, 64, 32,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:ref-height:
- * Specifies the search region height in pixels.
- */
- properties[ENCODER_H264_PROP_REF_HEIGHT] =
- g_param_spec_uint ("ref-height",
- "ref height",
- "Height of search region in pixel, must be multiple of 4",
- 4, 32, 32,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiEncoderH264:submb-mask:
- * Defines the bit-mask for disabling sub-partition
- *
- */
- properties[ENCODER_H264_PROP_SUBMB_MASK] =
- g_param_spec_flags ("submbpart-mask",
- "submb part mask",
- "defines the bit-mask for disabling sub mb partition",
- GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK,
- GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:subpel-mode:
- * defines the half/quarter pel modes
- * 00: integer mode searching
- * 01: half-pel mode searching
- * 11: quarter-pel mode searching
- */
- properties[ENCODER_H264_PROP_SUBPEL_MODE] =
- g_param_spec_enum ("subpel-mode",
- "subpel mode",
- "Sub pixel precision for motion estimation",
- GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE,
- GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiEncoderH264:intrapart-mask:
- * Specifies which Luma Intra partition is enabled/disabled
- * for intra mode decision
- */
- properties[ENCODER_H264_PROP_INTRA_PART_MASK] =
- g_param_spec_flags ("intrapart-mask",
- "intra part mask",
- "Specifies which Luma Intra partition is enabled/disabled for"
- "intra mode decision",
- GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK,
- GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:intra-sad:
- * Specifies distortion measure adjustments used for
- * the motion search SAD comparison.
- */
- properties[ENCODER_H264_PROP_INTRA_SAD] =
- g_param_spec_enum ("intra-sad",
- "intra sad",
- "Specifies distortion measure adjustments used"
- "in the motion search SAD comparison for intra MB",
- GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:inter-sad:
- * Specifies distortion measure adjustments used
- * in the motion search SAD comparison for inter MB
- */
- properties[ENCODER_H264_PROP_INTER_SAD] =
- g_param_spec_enum ("inter-sad",
- "inter sad",
- "Specifies distortion measure adjustments used"
- "in the motion search SAD comparison for inter MB",
- GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:adaptive-search:
- * Defines whether adaptive searching is enabled for IME
- */
- properties[ENCODER_H264_PROP_ADAPT_SEARCH] =
- g_param_spec_boolean ("adaptive-search",
- "adaptive-search",
- "Enable adaptive search",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiEncoderH264:multi-predL0:
- * When set to 1, neighbor MV will be used as predictor for list L0,
- * otherwise no neighbor MV will be used as predictor
- */
- properties[ENCODER_H264_PROP_MULTI_PRED_L0] =
- g_param_spec_boolean ("multi-predL0",
- "multi predL0",
- "Enable multi prediction for ref L0 list, when set neighbor MV will be used"
- "as predictor, no neighbor MV will be used otherwise",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264:multi-predL1:
- * When set to 1, neighbor MV will be used as predictor
- * when set to 0, no neighbor MV will be used as predictor.
- */
- properties[ENCODER_H264_PROP_MULTI_PRED_L1] =
- g_param_spec_boolean ("multi-predL1",
- "multi predL1",
- "Enable multi prediction for ref L1 list, when set neighbor MV will be used"
- "as predictor, no neighbor MV will be used otherwise",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiEncoderH264Fei: fei-mode:
- *
- * Cose ENC, PAK, ENC_PAK, or ENC+PAK
- * ENC: Only the Motion Estimation, no transformation or entropy coding
- * PAK: transformation, quantization and entropy coding
- * ENC_PAK: default mode, enc an pak are invoked by driver, middleware has
- control over ENC input only
- * ENC+PAK: enc and pak invoked separately, middleware has control over the ENC input,
- ENC output, and PAK input
- * Encoding mode which can be used for FEI
- */
- properties[ENCODER_H264_PROP_FEI_MODE] =
- g_param_spec_flags ("fei-mode",
- "FEI Encoding Mode",
- "Functional mode of FEI Encoding",
- GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- g_object_class_install_properties (object_class,
- ENCODER_H264_FEI_N_PROPERTIES, properties);
-}
-
-/**
- * gst_vaapi_encoder_h264_fei_set_max_profile:
- * @encoder: a #GstVaapiEncoderH264Fei
- * @profile: an H.264 #GstVaapiProfile
- *
- * Notifies the @encoder to use coding tools from the supplied
- * @profile at most.
- *
- * This means that if the minimal profile derived to
- * support the specified coding tools is greater than this @profile,
- * then an error is returned when the @encoder is configured.
- *
- * Return value: %TRUE on success
- */
-gboolean
-gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei *
- encoder, GstVaapiProfile profile)
-{
- guint8 profile_idc;
-
- g_return_val_if_fail (encoder != NULL, FALSE);
- g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
-
- if (encoder->fei_mode == (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) {
- if (!gst_vaapi_feienc_h264_set_max_profile (encoder->feienc, profile))
- return FALSE;
- return TRUE;
- }
-
- if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
- return FALSE;
-
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- if (!profile_idc)
- return FALSE;
-
- encoder->max_profile_idc = profile_idc;
- return TRUE;
-}
-
-/**
- * gst_vaapi_encoder_h264_fei_get_profile_and_level:
- * @encoder: a #GstVaapiEncoderH264Fei
- * @out_profile_ptr: return location for the #GstVaapiProfile
- * @out_level_ptr: return location for the #GstVaapiLevelH264
- *
- * Queries the H.264 @encoder for the active profile and level. That
- * information is only constructed and valid after the encoder is
- * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
- * function is called.
- *
- * Return value: %TRUE on success
- */
-gboolean
-gst_vaapi_encoder_h264_fei_get_profile_and_level (GstVaapiEncoderH264Fei *
- encoder, GstVaapiProfile * out_profile_ptr,
- GstVaapiLevelH264 * out_level_ptr)
-{
- g_return_val_if_fail (encoder != NULL, FALSE);
-
- if (!encoder->profile || !encoder->level)
- return FALSE;
-
- if (out_profile_ptr)
- *out_profile_ptr = encoder->profile;
- if (out_level_ptr)
- *out_level_ptr = encoder->level;
- return TRUE;
-}
-
-/**
- * gst_vaapi_encoder_h264_is_fei_stats_out_enabled
- * @encoder: a #GstVaapiEncoderH264
- *
- * check if fei output statis is needed
- *
- * Return value: %TRUE if output statistic is needed
- */
-gboolean
-gst_vaapi_encoder_h264_is_fei_stats_out_enabled (GstVaapiEncoderH264Fei *
- encoder)
-{
- return !encoder->is_fei_disabled && encoder->is_stats_out_enabled;
-}
-
-/**
- * gst_vaapi_encoder_h264_fei_get_function_mode
- * @encoder: a #GstVaapiEncoderH264Fei
- *
- * return the configured FEI Encoding mode
- *
- * Return value: a #GstVaapiFeiMode
- */
-GstVaapiFeiMode
-gst_vaapi_encoder_h264_fei_get_function_mode (GstVaapiEncoderH264Fei * encoder)
-{
- return encoder->fei_mode;
-}
-
-/**
- * gst_vaapi_encoder_h264_fei_set_function_mode
- * @encoder: a #GstVaapiEncoderH264Fei
- *
- * set the configured FEI Encoding mode
- *
- */
-void
-gst_vaapi_encoder_h264_fei_set_function_mode (GstVaapiEncoderH264Fei * encoder,
- guint fei_mode)
-{
- encoder->fei_mode = fei_mode;
-}
-
-static gboolean
-gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder *
- base_encoder)
-{
- GstVaapiEncoderH264Fei *const feiencoder =
- GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
- GstVaapiEncoder *enc_base_encoder =
- GST_VAAPI_ENCODER_CAST (feiencoder->feienc);
- gboolean success;
-
- if (feiencoder->fei_mode != (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK))
- return TRUE;
-
- /* Create separate context for ENC */
- if (!create_context_for_enc (base_encoder, enc_base_encoder)) {
- GST_ERROR ("create vacontext for enc failed.\n");
- return FALSE;
- }
-
- /*
- * create coded-buf for ENC.
- * PAK coded-buf is created by parent encoder.
- */
- success =
- vaapi_create_buffer (enc_base_encoder->va_display,
- enc_base_encoder->va_context, VAEncCodedBufferType,
- base_encoder->codedbuf_size, NULL, &feiencoder->coded_buf, NULL);
- if (!success) {
- g_error ("failed to create coded buf for feienc.\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * gst_vaapi_encoder_h264_fei_new:
- * @display: a #GstVaapiDisplay
- *
- * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
- * only supported output stream format is "byte-stream" format.
- *
- * Return value: the newly allocated #GstVaapiEncoder object
- */
-GstVaapiEncoder *
-gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display)
-{
- GstVaapiEncoder *base_encoder;
- GstVaapiEncoderH264Fei *feiencoder = NULL;
- GstVaapiFeiEncH264 *feienc = NULL;
- GstVaapiFEIPakH264 *feipak = NULL;
-
- /* create FEIEncoderObject: Default mode of operation in ENC_PAK */
- base_encoder =
- g_object_new (GST_TYPE_VAAPI_ENCODER_H264_FEI, "display", display, NULL);
- if (!base_encoder)
- return NULL;
- feiencoder = GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder);
-
- /* create an enc object */
- feienc = GST_VAAPI_FEI_ENC_H264 (gst_vaapi_feienc_h264_new (display));
- if (!feienc)
- goto error;
-
- /* create a pak object */
- feipak =
- gst_vaapi_feipak_h264_new (base_encoder, display,
- base_encoder->va_context);
- if (!feipak)
- goto error;
-
- feiencoder->feienc = feienc;
- feiencoder->feipak = feipak;
-
- return base_encoder;
-
-error:
- if (feienc)
- g_object_unref (feienc);
- if (feiencoder)
- g_object_unref (feiencoder);
-
- return NULL;
-}
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h
deleted file mode 100644
index b1c08d9f..00000000
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * gstvaapiencoder_h264_fei.h - H.264 FEI encoder
- *
- * Copyright (C) 2016-2017 Intel Corporation
- * Author: Yi A Wang <yi.a.wang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_ENCODER_H264_FEI_H
-#define GST_VAAPI_ENCODER_H264_FEI_H
-
-#include <gst/vaapi/gstvaapiencoder.h>
-#include <gst/vaapi/gstvaapiutils_h264.h>
-#include <gst/vaapi/gstvaapifeiutils_h264.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_VAAPI_ENCODER_H264_FEI \
- (gst_vaapi_encoder_h264_fei_get_type ())
-#define GST_VAAPI_ENCODER_H264_FEI(encoder) \
- (G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_H264_FEI, GstVaapiEncoderH264Fei))
-#define GST_IS_VAAPI_ENCODER_H264_FEI(encoder) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_H264_FEI))
-
-typedef struct _GstVaapiEncoderH264Fei GstVaapiEncoderH264Fei;
-typedef struct _GstVaapiEncoderH264FeiClass GstVaapiEncoderH264FeiClass;
-
-GType
-gst_vaapi_encoder_h264_fei_get_type (void) G_GNUC_CONST;
-
-GstVaapiEncoder *
-gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display);
-
-gboolean
-gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei * encoder,
- GstVaapiProfile profile);
-
-gboolean
-gst_vaapi_encoder_h264_fei_get_profile_and_level (GstVaapiEncoderH264Fei * encoder,
- GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr);
-
-gboolean
-gst_vaapi_encoder_h264_is_fei_stats_out_enabled (GstVaapiEncoderH264Fei * encoder);
-
-GstVaapiFeiMode
-gst_vaapi_encoder_h264_fei_get_function_mode (GstVaapiEncoderH264Fei *encoder);
-
-void
-gst_vaapi_encoder_h264_fei_set_function_mode (GstVaapiEncoderH264Fei * encoder,
- guint fei_mode);
-
-G_END_DECLS
-
-#endif /*GST_VAAPI_ENCODER_H264_FEI_H */
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c
index 09fcc18a..af1cf61e 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c
@@ -349,15 +349,6 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture)
gst_vaapi_codec_object_replace (&picture->sequence, NULL);
-#if USE_H264_FEI_ENCODER
- gst_vaapi_codec_object_replace (&picture->mvpred, NULL);
- gst_vaapi_codec_object_replace (&picture->mbcntrl, NULL);
- gst_vaapi_codec_object_replace (&picture->qp, NULL);
- gst_vaapi_codec_object_replace (&picture->mbcode, NULL);
- gst_vaapi_codec_object_replace (&picture->mv, NULL);
- gst_vaapi_codec_object_replace (&picture->dist, NULL);
-#endif
-
gst_vaapi_surface_proxy_replace (&picture->proxy, NULL);
picture->surface_id = VA_INVALID_ID;
picture->surface = NULL;
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h
index b8302ee8..8037c184 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h
@@ -27,10 +27,6 @@
#include <gst/vaapi/gstvaapidecoder_objects.h>
#include <gst/vaapi/gstvaapiencoder.h>
-#if USE_H264_FEI_ENCODER
-#include <gst/vaapi/gstvaapifei_objects.h>
-#endif
-
G_BEGIN_DECLS
typedef struct _GstVaapiEncPicture GstVaapiEncPicture;
@@ -270,14 +266,6 @@ struct _GstVaapiEncPicture
guint frame_num;
guint poc;
guint temporal_id;
-#if USE_H264_FEI_ENCODER
- GstVaapiEncFeiMbControl *mbcntrl;
- GstVaapiEncFeiMvPredictor *mvpred;
- GstVaapiEncFeiQp *qp;
- GstVaapiEncFeiMbCode *mbcode;
- GstVaapiEncFeiMv *mv;
- GstVaapiEncFeiDistortion *dist;
-#endif
};
G_GNUC_INTERNAL
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
index 560c7af5..0de0bbfa 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
@@ -334,9 +334,6 @@ struct _GstVaapiEncoderClass
GstVaapiEncoderStatus (*get_codec_data) (GstVaapiEncoder * encoder,
GstBuffer ** codec_data);
- /* To create a secondary context for a single base encoder */
- gboolean (*ensure_secondary_context) (GstVaapiEncoder * encoder);
-
/* Iterator that retrieves the pending pictures in the reordered
* list */
gboolean (*get_pending_reordered) (GstVaapiEncoder * encoder,
diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects.c b/gst-libs/gst/vaapi/gstvaapifei_objects.c
deleted file mode 100644
index fe71dcfb..00000000
--- a/gst-libs/gst/vaapi/gstvaapifei_objects.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * gstvaapifei_objects.c - VA FEI objects abstraction
- *
- * Copyright (C) 2017-2018 Intel Corporation
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#include "sysdeps.h"
-#include "gstvaapiencoder_priv.h"
-#include "gstvaapicompat.h"
-#include "gstvaapiutils.h"
-#include "gstvaapifei_objects.h"
-#include "gstvaapifei_objects_priv.h"
-#define DEBUG 1
-#include "gstvaapidebug.h"
-
-/* ------------------------------------------------------------------------- */
-/* --- Base Codec Object --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_FEI_CODEC_OBJECT_GET_CLASS(object) \
- gst_vaapi_fei_codec_object_get_class(object)
-
-const GstVaapiFeiCodecObjectClass *
-gst_vaapi_fei_codec_object_get_class (GstVaapiFeiCodecObject * object)
-{
- return (const GstVaapiFeiCodecObjectClass *)
- GST_VAAPI_MINI_OBJECT_GET_CLASS (object);
-}
-
-static gboolean
-gst_vaapi_fei_codec_object_create (GstVaapiFeiCodecObject * object,
- const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- const GstVaapiFeiCodecObjectClass *klass;
-
- g_return_val_if_fail (args->param_size > 0, FALSE);
-
- if (GST_VAAPI_MINI_OBJECT_FLAG_IS_SET (object,
- GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED))
- return TRUE;
-
- klass = GST_VAAPI_FEI_CODEC_OBJECT_GET_CLASS (object);
- if (!klass->create || !klass->create (object, args))
- return FALSE;
-
- GST_VAAPI_MINI_OBJECT_FLAG_SET (object,
- GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED);
- return TRUE;
-}
-
-GstVaapiFeiCodecObject *
-gst_vaapi_fei_codec_object_new (const GstVaapiFeiCodecObjectClass *
- object_class, GstVaapiFeiCodecBase * codec, gconstpointer param,
- guint param_size, gconstpointer data, guint data_size, guint flags)
-{
- GstVaapiFeiCodecObject *obj;
- GstVaapiFeiCodecObjectConstructorArgs args;
-
- obj = (GstVaapiFeiCodecObject *)
- gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (object_class));
- if (!obj)
- return NULL;
-
- obj = GST_VAAPI_FEI_CODEC_OBJECT (obj);
- obj->codec = codec;
-
- args.param = param;
- args.param_size = param_size;
- args.data = data;
- args.data_size = data_size;
- args.flags = flags;
-
- if (gst_vaapi_fei_codec_object_create (obj, &args))
- return obj;
-
- gst_vaapi_fei_codec_object_unref (obj);
- return NULL;
-}
-
-GstVaapiFeiCodecObject *
-gst_vaapi_fei_codec_object_ref (GstVaapiFeiCodecObject * object)
-{
- return ((GstVaapiFeiCodecObject *)
- gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (object)));
-}
-
-void
-gst_vaapi_fei_codec_object_unref (GstVaapiFeiCodecObject * object)
-{
- gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (object));
-}
-
-void
-gst_vaapi_fei_codec_object_replace (GstVaapiFeiCodecObject ** old_object_ptr,
- GstVaapiFeiCodecObject * new_object)
-{
- gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_object_ptr),
- GST_VAAPI_MINI_OBJECT (new_object));
-}
-
-/* FeiFixme: map_unlocked and map_lock could be needed */
-gboolean
-gst_vaapi_fei_codec_object_map (GstVaapiFeiCodecObject * object,
- gpointer * data, guint * size)
-{
- g_return_val_if_fail (object != NULL, FALSE);
-
- /*FeiFixme: explicit map if not yet mapped */
- *data = object->param;
- *size = object->param_size;
-
- return TRUE;
-}
-
-void
-gst_vaapi_fei_codec_object_unmap (GstVaapiFeiCodecObject * object)
-{
- g_return_if_fail (object != NULL);
- vaapi_unmap_buffer (GST_VAAPI_ENCODER_CAST (object->codec)->va_display,
- object->param_id, &object->param);
-}
-
-#define GET_ENCODER(obj) GST_VAAPI_ENCODER_CAST((obj)->parent_instance.codec)
-#define GET_VA_DISPLAY(obj) GET_ENCODER(obj)->va_display
-#define GET_VA_CONTEXT(obj) GET_ENCODER(obj)->va_context
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI Mb Code buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMbCode,
- gst_vaapi_enc_fei_mb_code);
-
-void
-gst_vaapi_enc_fei_mb_code_destroy (GstVaapiEncFeiMbCode * fei_mb_code)
-{
- GstVaapiFeiCodecObject *object = &fei_mb_code->parent_instance;
- vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mb_code), &object->param_id);
- object->param = NULL;
-}
-
-gboolean
-gst_vaapi_enc_fei_mb_code_create (GstVaapiEncFeiMbCode *
- fei_mb_code, const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- GstVaapiFeiCodecObject *object = &fei_mb_code->parent_instance;
- object->param_id = VA_INVALID_ID;
- return vaapi_create_buffer (GET_VA_DISPLAY (fei_mb_code),
- GET_VA_CONTEXT (fei_mb_code),
- (VABufferType) VAEncFEIMBCodeBufferType, args->param_size,
- args->param, &object->param_id, &object->param);
-}
-
-GstVaapiEncFeiMbCode *
-gst_vaapi_enc_fei_mb_code_new (GstVaapiEncoder * encoder,
- gconstpointer param, guint param_size)
-{
- GstVaapiFeiCodecObject *object;
-
- object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMbCodeClass,
- GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
- if (!object)
- return NULL;
- object->param_size = param_size;
- return GST_VAAPI_ENC_FEI_MB_CODE_CAST (object);
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI MV buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMv, gst_vaapi_enc_fei_mv);
-
-void
-gst_vaapi_enc_fei_mv_destroy (GstVaapiEncFeiMv * fei_mv)
-{
- GstVaapiFeiCodecObject *object = &fei_mv->parent_instance;
- vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mv), &object->param_id);
- object->param = NULL;
-}
-
-gboolean
-gst_vaapi_enc_fei_mv_create (GstVaapiEncFeiMv *
- fei_mv, const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- GstVaapiFeiCodecObject *object = &fei_mv->parent_instance;
- object->param_id = VA_INVALID_ID;
- return vaapi_create_buffer (GET_VA_DISPLAY (fei_mv),
- GET_VA_CONTEXT (fei_mv),
- (VABufferType) VAEncFEIMVBufferType, args->param_size,
- args->param, &object->param_id, &object->param);
-}
-
-GstVaapiEncFeiMv *
-gst_vaapi_enc_fei_mv_new (GstVaapiEncoder * encoder,
- gconstpointer param, guint param_size)
-{
- GstVaapiFeiCodecObject *object;
-
- object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMvClass,
- GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
- if (!object)
- return NULL;
- object->param_size = param_size;
- return GST_VAAPI_ENC_FEI_NEW_MV_CAST (object);
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI Mv predictor buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMvPredictor,
- gst_vaapi_enc_fei_mv_predictor);
-
-void
-gst_vaapi_enc_fei_mv_predictor_destroy (GstVaapiEncFeiMvPredictor *
- fei_mv_predictor)
-{
- GstVaapiFeiCodecObject *object = &fei_mv_predictor->parent_instance;
- vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mv_predictor), &object->param_id);
- object->param = NULL;
-}
-
-gboolean
-gst_vaapi_enc_fei_mv_predictor_create (GstVaapiEncFeiMvPredictor *
- fei_mv_predictor, const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- GstVaapiFeiCodecObject *object = &fei_mv_predictor->parent_instance;
- object->param_id = VA_INVALID_ID;
- return vaapi_create_buffer (GET_VA_DISPLAY (fei_mv_predictor),
- GET_VA_CONTEXT (fei_mv_predictor),
- (VABufferType) VAEncFEIMVPredictorBufferType, args->param_size,
- args->param, &object->param_id, &object->param);
-}
-
-GstVaapiEncFeiMvPredictor *
-gst_vaapi_enc_fei_mv_predictor_new (GstVaapiEncoder * encoder,
- gconstpointer param, guint param_size)
-{
- GstVaapiFeiCodecObject *object;
-
- object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMvPredictorClass,
- GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
- if (!object)
- return NULL;
- object->param_size = param_size;
- return GST_VAAPI_ENC_FEI_NEW_MV_PREDICTOR_CAST (object);
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI Mb Control buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMbControl,
- gst_vaapi_enc_fei_mb_control);
-
-void
-gst_vaapi_enc_fei_mb_control_destroy (GstVaapiEncFeiMbControl * fei_mb_control)
-{
- GstVaapiFeiCodecObject *object = &fei_mb_control->parent_instance;
- vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mb_control), &object->param_id);
- object->param = NULL;
-}
-
-gboolean
-gst_vaapi_enc_fei_mb_control_create (GstVaapiEncFeiMbControl *
- fei_mb_control, const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- GstVaapiFeiCodecObject *object = &fei_mb_control->parent_instance;
- object->param_id = VA_INVALID_ID;
- return vaapi_create_buffer (GET_VA_DISPLAY (fei_mb_control),
- GET_VA_CONTEXT (fei_mb_control),
- (VABufferType) VAEncFEIMBControlBufferType, args->param_size,
- args->param, &object->param_id, &object->param);
-}
-
-GstVaapiEncFeiMbControl *
-gst_vaapi_enc_fei_mb_control_new (GstVaapiEncoder * encoder,
- gconstpointer param, guint param_size)
-{
- GstVaapiFeiCodecObject *object;
-
- object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMbControlClass,
- GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
- if (!object)
- return NULL;
- object->param_size = param_size;
- return GST_VAAPI_ENC_FEI_NEW_MB_CONTROL_CAST (object);
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI qp buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiQp, gst_vaapi_enc_fei_qp);
-
-void
-gst_vaapi_enc_fei_qp_destroy (GstVaapiEncFeiQp * fei_qp)
-{
- GstVaapiFeiCodecObject *object = &fei_qp->parent_instance;
- vaapi_destroy_buffer (GET_VA_DISPLAY (fei_qp), &object->param_id);
- object->param = NULL;
-}
-
-gboolean
-gst_vaapi_enc_fei_qp_create (GstVaapiEncFeiQp * fei_qp,
- const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- GstVaapiFeiCodecObject *object = &fei_qp->parent_instance;
- object->param_id = VA_INVALID_ID;
- return vaapi_create_buffer (GET_VA_DISPLAY (fei_qp),
- GET_VA_CONTEXT (fei_qp),
- (VABufferType) VAEncQPBufferType, args->param_size,
- args->param, &object->param_id, &object->param);
-}
-
-GstVaapiEncFeiQp *
-gst_vaapi_enc_fei_qp_new (GstVaapiEncoder * encoder,
- gconstpointer param, guint param_size)
-{
- GstVaapiFeiCodecObject *object;
-
- object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiQpClass,
- GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
- if (!object)
- return NULL;
- object->param_size = param_size;
- return GST_VAAPI_ENC_FEI_NEW_QP_CAST (object);
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI Distortion buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiDistortion,
- gst_vaapi_enc_fei_distortion);
-
-void
-gst_vaapi_enc_fei_distortion_destroy (GstVaapiEncFeiDistortion * fei_dist)
-{
- GstVaapiFeiCodecObject *object = &fei_dist->parent_instance;
- vaapi_destroy_buffer (GET_VA_DISPLAY (fei_dist), &object->param_id);
- object->param = NULL;
-}
-
-gboolean
-gst_vaapi_enc_fei_distortion_create (GstVaapiEncFeiDistortion * fei_dist,
- const GstVaapiFeiCodecObjectConstructorArgs * args)
-{
- GstVaapiFeiCodecObject *object = &fei_dist->parent_instance;
- object->param_id = VA_INVALID_ID;
- return vaapi_create_buffer (GET_VA_DISPLAY (fei_dist),
- GET_VA_CONTEXT (fei_dist),
- (VABufferType) VAEncFEIDistortionBufferType, args->param_size,
- args->param, &object->param_id, &object->param);
-}
-
-GstVaapiEncFeiDistortion *
-gst_vaapi_enc_fei_distortion_new (GstVaapiEncoder * encoder,
- gconstpointer param, guint param_size)
-{
- GstVaapiFeiCodecObject *object;
-
- object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiDistortionClass,
- GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
- if (!object)
- return NULL;
- object->param_size = param_size;
- return GST_VAAPI_ENC_FEI_NEW_DISTORTION_CAST (object);
-}
diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects.h b/gst-libs/gst/vaapi/gstvaapifei_objects.h
deleted file mode 100644
index 03aef3da..00000000
--- a/gst-libs/gst/vaapi/gstvaapifei_objects.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * gstvaapifei_objects.h - VA FEI objects abstraction
- *
- * Copyright (C) 2017-2018 Intel Corporation
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_FEI_OBJECTS_H
-#define GST_VAAPI_FEI_OBJECTS_H
-
-G_BEGIN_DECLS
-
-#define GST_VAAPI_FEI_CODEC_OBJECT(obj) \
- ((GstVaapiFeiCodecObject *) (obj))
-
-typedef struct _GstVaapiFeiCodecObject GstVaapiFeiCodecObject;
-
-typedef struct _GstVaapiEncFeiMbCode GstVaapiEncFeiMbCode;
-typedef struct _GstVaapiEncFeiMv GstVaapiEncFeiMv;
-typedef struct _GstVaapiEncFeiMvPredictor GstVaapiEncFeiMvPredictor;
-typedef struct _GstVaapiEncFeiMbControl GstVaapiEncFeiMbControl;
-typedef struct _GstVaapiEncFeiQp GstVaapiEncFeiQp;
-typedef struct _GstVaapiEncFeiDistortion GstVaapiEncFeiDistortion;
-
-struct _GstVaapiEncoder;
-
-/* ----------------- Base Codec Object ---------------------------- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiFeiCodecObject *
-gst_vaapi_fei_codec_object_ref (GstVaapiFeiCodecObject *object);
-
-void
-gst_vaapi_fei_codec_object_unref (GstVaapiFeiCodecObject *object);
-
-void
-gst_vaapi_fei_codec_object_replace (GstVaapiFeiCodecObject **old_object_ptr,
- GstVaapiFeiCodecObject *new_object);
-
-gboolean
-gst_vaapi_fei_codec_object_map (GstVaapiFeiCodecObject *object,
- gpointer *data, guint *size);
-
-void
-gst_vaapi_fei_codec_object_unmap (GstVaapiFeiCodecObject *object);
-
-/* ------------------------------------------------------------------------- */
-/* --- MB Code buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiEncFeiMbCode *
-gst_vaapi_enc_fei_mb_code_new (struct _GstVaapiEncoder * encoder, gconstpointer param,
- guint param_size);
-
-/* ------------------------------------------------------------------------- */
-/* --- MV Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiEncFeiMv *
-gst_vaapi_enc_fei_mv_new (struct _GstVaapiEncoder * encoder, gconstpointer param,
- guint param_size);
-
-/* ------------------------------------------------------------------------- */
-/* --- MV Predictor Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiEncFeiMvPredictor *
-gst_vaapi_enc_fei_mv_predictor_new (struct _GstVaapiEncoder * encoder, gconstpointer param,
- guint param_size);
-
-/* ------------------------------------------------------------------------- */
-/* --- MB Control Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiEncFeiMbControl *
-gst_vaapi_enc_fei_mb_control_new (struct _GstVaapiEncoder * encoder, gconstpointer param,
- guint param_size);
-
-/* ------------------------------------------------------------------------- */
-/* --- QP Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiEncFeiQp *
-gst_vaapi_enc_fei_qp_new (struct _GstVaapiEncoder * encoder, gconstpointer param,
- guint param_size);
-
-/* ------------------------------------------------------------------------- */
-/* --- Distortion Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-GstVaapiEncFeiDistortion *
-gst_vaapi_enc_fei_distortion_new (struct _GstVaapiEncoder * encoder, gconstpointer param,
- guint param_size);
-
-G_END_DECLS
-
-#endif /* GST_VAAPI_FEI_OBJECTS_H */
diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h b/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h
deleted file mode 100644
index 87978775..00000000
--- a/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * gstvaapifei_objects_priv.h - VA FEI objects abstraction (priv definitions)
- *
- * Copyright (C) 2017-2018 Intel Corporation
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_FEI_OBJECTS_PRIV_H
-#define GST_VAAPI_FEI_OBJECTS_PRIV_H
-
-#include <gst/vaapi/gstvaapiencoder.h>
-#include <gst/vaapi/gstvaapifei_objects.h>
-#include <gst/vaapi/gstvaapiencoder_objects.h>
-#include <va/va.h>
-G_BEGIN_DECLS
-
-typedef gpointer GstVaapiFeiCodecBase;
-typedef struct _GstVaapiFeiCodecObjectClass GstVaapiFeiCodecObjectClass;
-
-#define GST_VAAPI_FEI_CODEC_BASE(obj) \
- ((GstVaapiFeiCodecBase *) (obj))
-
-enum
-{
- GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0),
- GST_VAAPI_FEI_CODEC_OBJECT_FLAG_LAST = (1 << 1)
-};
-
-typedef struct
-{
- gconstpointer param;
- guint param_size;
- gconstpointer data;
- guint data_size;
- guint flags;
-} GstVaapiFeiCodecObjectConstructorArgs;
-
-typedef gboolean
-(*GstVaapiFeiCodecObjectCreateFunc)(GstVaapiFeiCodecObject * object,
- const GstVaapiFeiCodecObjectConstructorArgs * args);
-
-typedef GDestroyNotify GstVaapiFeiCodecObjectDestroyFunc;
-
-/**
- * GstVaapiFeiCodecObject:
- *
- * A #GstVaapiMiniObject holding the base codec object data
- */
-struct _GstVaapiFeiCodecObject
-{
- /*< private >*/
- GstVaapiMiniObject parent_instance;
- GstVaapiFeiCodecBase *codec;
- VABufferID param_id;
- gpointer param;
- guint param_size;
-};
-
-/**
- * GstVaapiFeiCodecObjectClass:
- *
- * The #GstVaapiFeiCodecObject base class.
- */
-struct _GstVaapiFeiCodecObjectClass
-{
- /*< private >*/
- GstVaapiMiniObjectClass parent_class;
-
- GstVaapiFeiCodecObjectCreateFunc create;
-};
-
-G_GNUC_INTERNAL
-const GstVaapiFeiCodecObjectClass *
-gst_vaapi_fei_codec_object_get_class (GstVaapiFeiCodecObject * object) G_GNUC_CONST;
-
-G_GNUC_INTERNAL
-GstVaapiFeiCodecObject *
-gst_vaapi_fei_codec_object_new (const GstVaapiFeiCodecObjectClass * object_class,
- GstVaapiFeiCodecBase * codec, gconstpointer param, guint param_size,
- gconstpointer data, guint data_size, guint flags);
-
-
-/* ------------------------------------------------------------------------- */
-/* --- MB Code Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENC_FEI_MB_CODE_CAST(obj) \
- ((GstVaapiEncFeiMbCode *) (obj))
-/**
- * GstVaapiEncFeiMbCode:
- *
- * A #GstVaapiFeiCodecObject holding a mb code buffer.
- */
-struct _GstVaapiEncFeiMbCode
-{
- /*< private >*/
- GstVaapiFeiCodecObject parent_instance;
-};
-
-/* ------------------------------------------------------------------------- */
-/* --- MV Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENC_FEI_NEW_MV_CAST(obj) \
- ((GstVaapiEncFeiMv *) (obj))
-/**
- * GstVaapiEncFeiMv:
- *
- * A #GstVaapiFeiCodecObject holding a mv buffer.
- */
-struct _GstVaapiEncFeiMv
-{
- /*< private >*/
- GstVaapiFeiCodecObject parent_instance;
-};
-
-/* ------------------------------------------------------------------------- */
-/* --- MV Predictor Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENC_FEI_NEW_MV_PREDICTOR_CAST(obj) \
- ((GstVaapiEncFeiMvPredictor *) (obj))
-/**
- * GstVaapiEncFeiMvPredictor:
- *
- * A #GstVaapiFeiCodecObject holding a mv predictor buffer.
- */
-struct _GstVaapiEncFeiMvPredictor
-{
- /*< private >*/
- GstVaapiFeiCodecObject parent_instance;
-};
-
-
-/* ------------------------------------------------------------------------- */
-/* --- MB Control Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENC_FEI_NEW_MB_CONTROL_CAST(obj) \
- ((GstVaapiEncFeiMbControl *) (obj))
-/**
- * GstVaapiEncFeiMbControl:
- *
- * A #GstVaapiFeiCodecObject holding a mb control buffer.
- */
-struct _GstVaapiEncFeiMbControl
-{
- /*< private >*/
- GstVaapiFeiCodecObject parent_instance;
-};
-
-
-/* ------------------------------------------------------------------------- */
-/* --- QP Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENC_FEI_NEW_QP_CAST(obj) \
- ((GstVaapiEncFeiQp *) (obj))
-/**
- * GstVaapiEncFeiQp:
- *
- * A #GstVaapiFeiCodecObject holding a qp buffer.
- */
-struct _GstVaapiEncFeiQp
-{
- /*< private >*/
- GstVaapiFeiCodecObject parent_instance;
-};
-
-
-/* ------------------------------------------------------------------------- */
-/* --- Distortion Buffer --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_ENC_FEI_NEW_DISTORTION_CAST(obj) \
- ((GstVaapiEncFeiDistortion *) (obj))
-/**
- * GstVaapiEncFeiDistortion:
- *
- * A #GstVaapiFeiCodecObject holding a distortion buffer.
- */
-struct _GstVaapiEncFeiDistortion
-{
- /*< private >*/
- GstVaapiFeiCodecObject parent_instance;
-};
-
-
-/* ------------------------------------------------------------------------- */
-/* --- Helpers to create fei objects --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_FEI_CODEC_DEFINE_TYPE(type, prefix) \
-G_GNUC_INTERNAL \
-void \
-G_PASTE (prefix, _destroy) (type *); \
- \
-G_GNUC_INTERNAL \
-gboolean \
-G_PASTE (prefix, _create) (type *, \
- const GstVaapiFeiCodecObjectConstructorArgs * args); \
- \
-static const GstVaapiFeiCodecObjectClass G_PASTE (type, Class) = { \
- .parent_class = { \
- .size = sizeof (type), \
- .finalize = (GstVaapiFeiCodecObjectDestroyFunc) \
- G_PASTE (prefix, _destroy) \
- }, \
- .create = (GstVaapiFeiCodecObjectCreateFunc) \
- G_PASTE (prefix, _create), \
-}
-
-/* GstVaapiEncFeiMiscParam */
-#define GST_VAAPI_ENC_FEI_MISC_PARAM_NEW(codec, encoder) \
- gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \
- VAEncMiscParameterTypeFEIFrameControl, \
- sizeof (G_PASTE (VAEncMiscParameterFEIFrameControl, codec)))
-
-G_END_DECLS
-
-#endif /* GST_VAAPI_FEI_OBJECTS_H */
diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c
deleted file mode 100644
index 60f08c41..00000000
--- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c
+++ /dev/null
@@ -1,2452 +0,0 @@
-/*
- * gstvaapifeienc_h264.c - H264 FEI ENC
- *
- * Copyright (C) 2016-2018 Intel Corporation
- * Author: Leilei Shang <leilei.shang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-/* GValueArray has deprecated without providing an alternative in glib >= 2.32
- * See https://bugzilla.gnome.org/show_bug.cgi?id=667228
- */
-
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
-
-#include "sysdeps.h"
-#include <va/va.h>
-#include <gst/base/gstbitwriter.h>
-#include <gst/codecparsers/gsth264parser.h>
-#include "gstvaapicompat.h"
-#include "gstvaapiencoder_priv.h"
-#include "gstvaapifeienc_h264.h"
-#include "gstvaapiutils_h264_priv.h"
-#include "gstvaapicodedbufferproxy_priv.h"
-#include "gstvaapisurfaceproxy_priv.h"
-#include "gstvaapisurface.h"
-#include "gstvaapiutils.h"
-#include <unistd.h>
-#define DEBUG 1
-#include "gstvaapidebug.h"
-
-/* Define the maximum number of views supported */
-#define MAX_NUM_VIEWS 10
-
-/* Define the maximum value for view-id */
-#define MAX_VIEW_ID 1023
-
-/* Default CPB length (in milliseconds) */
-#define DEFAULT_CPB_LENGTH 1500
-
-/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */
-#define SX_CPB_SIZE 4
-
-/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */
-#define SX_BITRATE 6
-
-/* Define default rate control mode ("constant-qp") */
-#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
-
-/* Supported set of VA rate controls, within this implementation */
-#define SUPPORTED_RATECONTROLS \
- (GST_VAAPI_RATECONTROL_MASK (CQP) | \
- GST_VAAPI_RATECONTROL_MASK (CBR) | \
- GST_VAAPI_RATECONTROL_MASK (VBR) | \
- GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
-
-/* Supported set of tuning options, within this implementation */
-#define SUPPORTED_TUNE_OPTIONS \
- (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \
- GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \
- GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER))
-
-/* Supported set of VA packed headers, within this implementation */
-#define SUPPORTED_PACKED_HEADERS \
- VA_ENC_PACKED_HEADER_NONE
-
-typedef struct
-{
- GstVaapiSurfaceProxy *pic;
- guint poc;
- guint frame_num;
-} GstVaapiFeiEncH264Ref;
-
-typedef enum
-{
- GST_VAAPI_ENC_H264_REORD_NONE = 0,
- GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
- GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
-} GstVaapiEncH264ReorderState;
-
-typedef struct _GstVaapiH264ViewRefPool
-{
- GQueue ref_list;
- guint max_ref_frames;
- guint max_reflist0_count;
- guint max_reflist1_count;
-} GstVaapiH264ViewRefPool;
-
-typedef struct _GstVaapiH264ViewReorderPool
-{
- GQueue reorder_frame_list;
- guint reorder_state;
- guint frame_index;
- guint frame_count; /* monotonically increasing with in every idr period */
- guint cur_frame_num;
- guint cur_present_index;
-} GstVaapiH264ViewReorderPool;
-
-static inline gboolean
-_poc_greater_than (guint poc1, guint poc2, guint max_poc)
-{
- return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
-}
-
-/* Get slice_type value for H.264 specification */
-static guint8
-h264_get_slice_type (GstVaapiPictureType type)
-{
- switch (type) {
- case GST_VAAPI_PICTURE_TYPE_I:
- return GST_H264_I_SLICE;
- case GST_VAAPI_PICTURE_TYPE_P:
- return GST_H264_P_SLICE;
- case GST_VAAPI_PICTURE_TYPE_B:
- return GST_H264_B_SLICE;
- default:
- break;
- }
- return -1;
-}
-
-/* Get log2_max_frame_num value for H.264 specification */
-static guint
-h264_get_log2_max_frame_num (guint num)
-{
- guint ret = 0;
-
- while (num) {
- ++ret;
- num >>= 1;
- }
- if (ret <= 4)
- ret = 4;
- else if (ret > 10)
- ret = 10;
- /* must be greater than 4 */
- return ret;
-}
-
-/* Determines the cpbBrNalFactor based on the supplied profile */
-static guint
-h264_get_cpb_nal_factor (GstVaapiProfile profile)
-{
- guint f;
-
- /* Table A-2 */
- switch (profile) {
- case GST_VAAPI_PROFILE_H264_HIGH:
- f = 1500;
- break;
- case GST_VAAPI_PROFILE_H264_HIGH10:
- f = 3600;
- break;
- case GST_VAAPI_PROFILE_H264_HIGH_422:
- case GST_VAAPI_PROFILE_H264_HIGH_444:
- f = 4800;
- break;
- case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH:
- case GST_VAAPI_PROFILE_H264_STEREO_HIGH:
- f = 1500; /* H.10.2.1 (r) */
- break;
- default:
- f = 1200;
- break;
- }
- return f;
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- FEI Enc --- */
-/* ------------------------------------------------------------------------- */
-
-#define GST_VAAPI_FEI_ENC_H264_CAST(feienc) \
- ((GstVaapiFeiEncH264 *)(feienc))
-
-struct _GstVaapiFeiEncH264
-{
- GstVaapiEncoder parent_instance;
-
- GstVaapiProfile profile;
- GstVaapiLevelH264 level;
- GstVaapiEntrypoint entrypoint;
- guint8 profile_idc;
- guint8 max_profile_idc;
- guint8 hw_max_profile_idc;
- guint8 level_idc;
- guint32 idr_period;
- guint32 init_qp;
- guint32 min_qp;
- guint32 num_slices;
- guint32 num_bframes;
- guint32 mb_width;
- guint32 mb_height;
- gboolean use_cabac;
- gboolean use_dct8x8;
- GstClockTime cts_offset;
- gboolean config_changed;
-
- /* frame, poc */
- guint32 max_frame_num;
- guint32 log2_max_frame_num;
- guint32 max_pic_order_cnt;
- guint32 log2_max_pic_order_cnt;
- guint32 idr_num;
- guint8 pic_order_cnt_type;
- guint8 delta_pic_order_always_zero_flag;
-
- GstBuffer *sps_data;
- GstBuffer *subset_sps_data;
- GstBuffer *pps_data;
-
- guint bitrate_bits; // bitrate (bits)
- guint cpb_length; // length of CPB buffer (ms)
- guint cpb_length_bits; // length of CPB buffer (bits)
- guint32 num_ref_frames; // set reference frame num
-
- /* MVC */
- gboolean is_mvc;
- guint32 view_idx; /* View Order Index (VOIdx) */
- guint32 num_views;
- guint16 view_ids[MAX_NUM_VIEWS];
- GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS];
- GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS];
-
- /*Fei frame level control */
- guint search_window;
- guint len_sp;
- guint search_path;
- guint ref_width;
- guint ref_height;
- guint submb_part_mask;
- guint subpel_mode;
- guint intra_part_mask;
- guint intra_sad;
- guint inter_sad;
- guint num_mv_predictors_l0;
- guint num_mv_predictors_l1;
- guint adaptive_search;
- guint multi_predL0;
- guint multi_predL1;
-};
-
-/* Determines the largest supported profile by the underlying hardware */
-static gboolean
-ensure_hw_profile_limits (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (feienc);
- GArray *profiles;
- guint i, profile_idc, max_profile_idc;
-
- if (feienc->hw_max_profile_idc)
- return TRUE;
-
- profiles = gst_vaapi_display_get_encode_profiles (display);
- if (!profiles)
- return FALSE;
-
- max_profile_idc = 0;
- for (i = 0; i < profiles->len; i++) {
- const GstVaapiProfile profile =
- g_array_index (profiles, GstVaapiProfile, i);
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- if (!profile_idc)
- continue;
- if (max_profile_idc < profile_idc)
- max_profile_idc = profile_idc;
- }
- g_array_unref (profiles);
-
- feienc->hw_max_profile_idc = max_profile_idc;
- return TRUE;
-}
-
-/* Derives the profile supported by the underlying hardware */
-static gboolean
-ensure_hw_profile (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (feienc);
- GstVaapiEntrypoint entrypoint = feienc->entrypoint;
- GstVaapiProfile profile, profiles[4];
- guint i, num_profiles = 0;
-
- profiles[num_profiles++] = feienc->profile;
- switch (feienc->profile) {
- case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
- profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
- profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
- // fall-through
- case GST_VAAPI_PROFILE_H264_MAIN:
- profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
- break;
- default:
- break;
- }
-
- profile = GST_VAAPI_PROFILE_UNKNOWN;
- for (i = 0; i < num_profiles; i++) {
- if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
- profile = profiles[i];
- break;
- }
- }
- if (profile == GST_VAAPI_PROFILE_UNKNOWN)
- goto error_unsupported_profile;
-
- GST_VAAPI_ENCODER_CAST (feienc)->profile = profile;
- return TRUE;
-
- /* ERRORS */
-error_unsupported_profile:
- {
- GST_ERROR ("unsupported HW profile (0x%08x)", feienc->profile);
- return FALSE;
- }
-}
-
-/* Check target decoder constraints */
-static gboolean
-ensure_profile_limits (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiProfile profile;
-
- if (!feienc->max_profile_idc
- || feienc->profile_idc <= feienc->max_profile_idc)
- return TRUE;
-
- GST_WARNING ("lowering coding tools to meet target decoder constraints");
-
- profile = GST_VAAPI_PROFILE_UNKNOWN;
-
- /* Try Main profile coding tools */
- if (feienc->max_profile_idc < 100) {
- feienc->use_dct8x8 = FALSE;
- profile = GST_VAAPI_PROFILE_H264_MAIN;
- }
-
- /* Try Constrained Baseline profile coding tools */
- if (feienc->max_profile_idc < 77) {
- feienc->num_bframes = 0;
- feienc->use_cabac = FALSE;
- profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
- }
-
- if (profile) {
- feienc->profile = profile;
- feienc->profile_idc = feienc->max_profile_idc;
- }
- return TRUE;
-}
-
-/* Derives the minimum profile from the active coding tools */
-static gboolean
-ensure_profile (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiProfile profile;
-
- /* Always start from "constrained-baseline" profile for maximum
- compatibility */
- profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
-
- /* Main profile coding tools */
- if (feienc->num_bframes > 0 || feienc->use_cabac)
- profile = GST_VAAPI_PROFILE_H264_MAIN;
-
- /* High profile coding tools */
- if (feienc->use_dct8x8)
- profile = GST_VAAPI_PROFILE_H264_HIGH;
-
- /* MVC profiles coding tools */
- if (feienc->num_views == 2)
- profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH;
- else if (feienc->num_views > 2)
- profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH;
-
- feienc->profile = profile;
- feienc->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- return TRUE;
-}
-
-/* Derives the level from the currently set limits */
-static gboolean
-ensure_level (GstVaapiFeiEncH264 * feienc)
-{
- const guint cpb_factor = h264_get_cpb_nal_factor (feienc->profile);
- const GstVaapiH264LevelLimits *limits_table;
- guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
-
- PicSizeMbs = feienc->mb_width * feienc->mb_height;
- MaxDpbMbs = PicSizeMbs * ((feienc->num_bframes) ? 2 : 1);
- MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
- GST_VAAPI_ENCODER_FPS_N (feienc), GST_VAAPI_ENCODER_FPS_D (feienc));
-
- limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
- for (i = 0; i < num_limits; i++) {
- const GstVaapiH264LevelLimits *const limits = &limits_table[i];
- if (PicSizeMbs <= limits->MaxFS &&
- MaxDpbMbs <= limits->MaxDpbMbs &&
- MaxMBPS <= limits->MaxMBPS && (!feienc->bitrate_bits
- || feienc->bitrate_bits <= (limits->MaxBR * cpb_factor)) &&
- (!feienc->cpb_length_bits ||
- feienc->cpb_length_bits <= (limits->MaxCPB * cpb_factor)))
- break;
- }
- if (i == num_limits)
- goto error_unsupported_level;
-
- feienc->level = limits_table[i].level;
- feienc->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;
- }
-}
-
-/* Enable "high-compression" tuning options */
-static gboolean
-ensure_tuning_high_compression (GstVaapiFeiEncH264 * feienc)
-{
- guint8 profile_idc;
-
- if (!ensure_hw_profile_limits (feienc))
- return FALSE;
-
- profile_idc = feienc->hw_max_profile_idc;
- if (feienc->max_profile_idc && feienc->max_profile_idc < profile_idc)
- profile_idc = feienc->max_profile_idc;
-
- /* Tuning options to enable Main profile */
- if (profile_idc >= 77 && profile_idc != 88) {
- feienc->use_cabac = TRUE;
- if (!feienc->num_bframes)
- feienc->num_bframes = 1;
- }
-
- /* Tuning options to enable High profile */
- if (profile_idc >= 100) {
- feienc->use_dct8x8 = TRUE;
- }
- return TRUE;
-}
-
-/* Ensure tuning options */
-static gboolean
-ensure_tuning (GstVaapiFeiEncH264 * feienc)
-{
- gboolean success;
-
- switch (GST_VAAPI_ENCODER_TUNE (feienc)) {
- case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
- success = ensure_tuning_high_compression (feienc);
- break;
- case GST_VAAPI_ENCODER_TUNE_LOW_POWER:
- /* Set low-power encode entry point. If hardware doesn't have
- * support, it will fail in ensure_hw_profile() in later stage.
- * So not duplicating the profile/entrypont query mechanism
- * here as a part of optimization */
- feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
- success = TRUE;
- break;
- default:
- success = TRUE;
- break;
- }
- return success;
-}
-
-/* Handle new GOP starts */
-static void
-reset_gop_start (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &feienc->reorder_pools[feienc->view_idx];
-
- reorder_pool->frame_index = 1;
- reorder_pool->cur_frame_num = 0;
- reorder_pool->cur_present_index = 0;
- ++feienc->idr_num;
-}
-
-/* Marks the supplied picture as a B-frame */
-static void
-set_b_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &feienc->reorder_pools[feienc->view_idx];
-
- g_assert (pic && feienc);
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_B;
- pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num);
-}
-
-/* Marks the supplied picture as a P-frame */
-static void
-set_p_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &feienc->reorder_pools[feienc->view_idx];
-
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_P;
- pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num);
-}
-
-/* Marks the supplied picture as an I-frame */
-static void
-set_i_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiH264ViewReorderPool *const reorder_pool =
- &feienc->reorder_pools[feienc->view_idx];
-
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_I;
- pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num);
-
- g_assert (pic->frame);
- GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
-}
-
-/* Marks the supplied picture as an IDR frame */
-static void
-set_idr_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc)
-{
- g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
- pic->type = GST_VAAPI_PICTURE_TYPE_I;
- pic->frame_num = 0;
- pic->poc = 0;
- GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
-
- g_assert (pic->frame);
- GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
-}
-
-/* Marks the supplied picture a a key-frame */
-static void
-set_key_frame (GstVaapiEncPicture * picture,
- GstVaapiFeiEncH264 * feienc, gboolean is_idr)
-{
- if (is_idr) {
- reset_gop_start (feienc);
- set_idr_frame (picture, feienc);
- } else
- set_i_frame (picture, feienc);
-}
-
-/* Fills in VA HRD parameters */
-static void
-fill_hrd_params (GstVaapiFeiEncH264 * feienc, VAEncMiscParameterHRD * hrd)
-{
- if (feienc->bitrate_bits > 0) {
- hrd->buffer_size = feienc->cpb_length_bits;
- hrd->initial_buffer_fullness = hrd->buffer_size / 2;
- } else {
- hrd->buffer_size = 0;
- hrd->initial_buffer_fullness = 0;
- }
-}
-
-/* Reference list */
-static gboolean
-reference_list_init (GstVaapiFeiEncH264 * feienc,
- GstVaapiEncPicture * picture,
- GstVaapiFeiEncH264Ref ** reflist_0,
- guint * reflist_0_count,
- GstVaapiFeiEncH264Ref ** reflist_1, guint * reflist_1_count)
-{
- GstVaapiFeiEncH264Ref *tmp;
- GstVaapiH264ViewRefPool *const ref_pool =
- &feienc->ref_pools[feienc->view_idx];
- GList *iter, *list_0_start = NULL, *list_1_start = NULL;
- guint count;
-
- *reflist_0_count = 0;
- *reflist_1_count = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
- return TRUE;
-
- iter = g_queue_peek_tail_link (&ref_pool->ref_list);
- for (; iter; iter = g_list_previous (iter)) {
- tmp = (GstVaapiFeiEncH264Ref *) iter->data;
- g_assert (tmp && tmp->poc != picture->poc);
- if (_poc_greater_than (picture->poc, tmp->poc, feienc->max_pic_order_cnt)) {
- list_0_start = iter;
- list_1_start = g_list_next (iter);
- break;
- }
- }
-
- /* order reflist_0 */
- g_assert (list_0_start);
- iter = list_0_start;
- count = 0;
- for (; iter; iter = g_list_previous (iter)) {
- reflist_0[count] = (GstVaapiFeiEncH264Ref *) iter->data;
- ++count;
- }
- *reflist_0_count = count;
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
- return TRUE;
-
- /* order reflist_1 */
- count = 0;
- iter = list_1_start;
- for (; iter; iter = g_list_next (iter)) {
- reflist_1[count] = (GstVaapiFeiEncH264Ref *) iter->data;
- ++count;
- }
- *reflist_1_count = count;
- return TRUE;
-}
-
-/* Fills in VA sequence parameter buffer */
-static gboolean
-fill_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncSequence * sequence)
-{
- VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
- GstVaapiH264ViewRefPool *const ref_pool =
- &feienc->ref_pools[feienc->view_idx];
-
- memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
- seq_param->seq_parameter_set_id = feienc->view_idx;
- seq_param->level_idc = feienc->level_idc;
- seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc);
- seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc);
- seq_param->ip_period = seq_param->intra_period > 1 ?
- (1 + feienc->num_bframes) : 0;
- seq_param->bits_per_second = feienc->bitrate_bits;
-
- seq_param->max_num_ref_frames = ref_pool->max_ref_frames;
- seq_param->picture_width_in_mbs = feienc->mb_width;
- seq_param->picture_height_in_mbs = feienc->mb_height;
-
- /*sequence field values */
- seq_param->seq_fields.value = 0;
- seq_param->seq_fields.bits.chroma_format_idc = 1;
- seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
- seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
- seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
- /* direct_8x8_inference_flag default false */
- seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
- g_assert (feienc->log2_max_frame_num >= 4);
- seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
- feienc->log2_max_frame_num - 4;
- /* picture order count */
- feienc->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type =
- 0;
- g_assert (feienc->log2_max_pic_order_cnt >= 4);
- seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
- feienc->log2_max_pic_order_cnt - 4;
-
- seq_param->bit_depth_luma_minus8 = 0;
- seq_param->bit_depth_chroma_minus8 = 0;
-
- /* not used if pic_order_cnt_type == 0 */
- if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
- feienc->delta_pic_order_always_zero_flag =
- seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
- seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
- seq_param->offset_for_non_ref_pic = 0;
- seq_param->offset_for_top_to_bottom_field = 0;
- memset (seq_param->offset_for_ref_frame, 0,
- sizeof (seq_param->offset_for_ref_frame));
- }
-
- /* frame_cropping_flag */
- if ((GST_VAAPI_ENCODER_WIDTH (feienc) & 15) ||
- (GST_VAAPI_ENCODER_HEIGHT (feienc) & 15)) {
- static const guint SubWidthC[] = { 1, 2, 2, 1 };
- static const guint SubHeightC[] = { 1, 2, 1, 1 };
- const guint CropUnitX =
- SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
- const guint CropUnitY =
- SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
- (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
-
- seq_param->frame_cropping_flag = 1;
- seq_param->frame_crop_left_offset = 0;
- seq_param->frame_crop_right_offset =
- (16 * feienc->mb_width - GST_VAAPI_ENCODER_WIDTH (feienc)) / CropUnitX;
- seq_param->frame_crop_top_offset = 0;
- seq_param->frame_crop_bottom_offset =
- (16 * feienc->mb_height -
- GST_VAAPI_ENCODER_HEIGHT (feienc)) / CropUnitY;
- }
-
- /* VUI parameters are always set, at least for timing_info (framerate) */
- seq_param->vui_parameters_present_flag = TRUE;
- if (seq_param->vui_parameters_present_flag) {
- seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE;
- if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
- const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc);
- seq_param->aspect_ratio_idc = 0xff;
- seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip);
- seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip);
- }
- seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
- /* if vui_parameters_present_flag is TRUE and sps data belongs to
- * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */
- seq_param->vui_fields.bits.timing_info_present_flag = !feienc->view_idx;
- if (seq_param->vui_fields.bits.timing_info_present_flag) {
- seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (feienc);
- seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (feienc) * 2;
- }
- }
-
- return TRUE;
-}
-
-/* Fills in VA picture parameter buffer */
-static gboolean
-fill_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture,
- GstVaapiSurfaceProxy * surface, GstVaapiCodedBuffer * const codedbuf)
-{
- VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- GstVaapiH264ViewRefPool *const ref_pool =
- &feienc->ref_pools[feienc->view_idx];
- GstVaapiFeiEncH264Ref *ref_pic;
- GList *reflist;
- guint i;
-
- memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
-
- /* reference list, */
- pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
- pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
- pic_param->CurrPic.frame_idx = picture->frame_num;
- i = 0;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
- for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
- reflist; reflist = g_list_next (reflist)) {
- ref_pic = reflist->data;
- g_assert (ref_pic && ref_pic->pic &&
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
-
- pic_param->ReferenceFrames[i].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
- pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc;
- pic_param->ReferenceFrames[i].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num;
- ++i;
- }
- g_assert (i <= 16 && i <= ref_pool->max_ref_frames);
- }
- for (; i < 16; ++i) {
- pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
- pic_param->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
- }
-
- pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
-
- pic_param->pic_parameter_set_id = feienc->view_idx;
- pic_param->seq_parameter_set_id = feienc->view_idx ? 1 : 0;
- pic_param->last_picture = 0; /* means last encoding picture */
- pic_param->frame_num = picture->frame_num;
- pic_param->pic_init_qp = feienc->init_qp;
- pic_param->num_ref_idx_l0_active_minus1 =
- (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0);
- pic_param->num_ref_idx_l1_active_minus1 =
- (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0);
- pic_param->chroma_qp_index_offset = 0;
- pic_param->second_chroma_qp_index_offset = 0;
-
- /* set picture fields */
- pic_param->pic_fields.value = 0;
- pic_param->pic_fields.bits.idr_pic_flag =
- GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
- pic_param->pic_fields.bits.reference_pic_flag =
- (picture->type != GST_VAAPI_PICTURE_TYPE_B);
- pic_param->pic_fields.bits.entropy_coding_mode_flag = feienc->use_cabac;
- pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
- pic_param->pic_fields.bits.weighted_bipred_idc = 0;
- pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
- pic_param->pic_fields.bits.transform_8x8_mode_flag = feienc->use_dct8x8;
- /* enable debloking */
- pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
- pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
- /* bottom_field_pic_order_in_frame_present_flag */
- pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
- pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
-
- return TRUE;
-}
-
-/* Adds slice headers to picture */
-static gboolean
-add_slice_headers (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture,
- GstVaapiFeiEncH264Ref ** reflist_0, guint reflist_0_count,
- GstVaapiFeiEncH264Ref ** reflist_1, guint reflist_1_count,
- GstVaapiFeiInfoToPakH264 * info_to_pak)
-{
- VAEncSliceParameterBufferH264 *slice_param;
- GstVaapiEncSlice *slice;
- GArray *h264_slice_params;
- guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
- guint mb_size;
- guint last_mb_index;
- guint i_slice, i_ref;
-
- g_assert (picture);
-
- mb_size = feienc->mb_width * feienc->mb_height;
-
- g_assert (feienc->num_slices && feienc->num_slices < mb_size);
- slice_of_mbs = mb_size / feienc->num_slices;
- slice_mod_mbs = mb_size % feienc->num_slices;
- last_mb_index = 0;
- h264_slice_params =
- g_array_new (FALSE, TRUE, sizeof (VAEncSliceParameterBufferH264));
- for (i_slice = 0; i_slice < feienc->num_slices; ++i_slice) {
- cur_slice_mbs = slice_of_mbs;
- if (slice_mod_mbs) {
- ++cur_slice_mbs;
- --slice_mod_mbs;
- }
- slice = GST_VAAPI_ENC_SLICE_NEW (H264, feienc);
- g_assert (slice && slice->param_id != VA_INVALID_ID);
- slice_param = slice->param;
-
- memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
- slice_param->macroblock_address = last_mb_index;
- slice_param->num_macroblocks = cur_slice_mbs;
- slice_param->macroblock_info = VA_INVALID_ID;
- slice_param->slice_type = h264_get_slice_type (picture->type);
- g_assert ((gint8) slice_param->slice_type != -1);
- slice_param->pic_parameter_set_id = feienc->view_idx;
- slice_param->idr_pic_id = feienc->idr_num;
- slice_param->pic_order_cnt_lsb = picture->poc;
-
- /* not used if pic_order_cnt_type = 0 */
- slice_param->delta_pic_order_cnt_bottom = 0;
- memset (slice_param->delta_pic_order_cnt, 0,
- sizeof (slice_param->delta_pic_order_cnt));
-
- /* only works for B frames */
- if (slice_param->slice_type == GST_H264_B_SLICE)
- slice_param->direct_spatial_mv_pred_flag = TRUE;
- /* default equal to picture parameters */
- slice_param->num_ref_idx_active_override_flag = TRUE;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
- slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
- else
- slice_param->num_ref_idx_l0_active_minus1 = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
- slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
- else
- slice_param->num_ref_idx_l1_active_minus1 = 0;
- g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
- g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
-
- i_ref = 0;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
- for (; i_ref < reflist_0_count; ++i_ref) {
- slice_param->RefPicList0[i_ref].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
- slice_param->RefPicList0[i_ref].TopFieldOrderCnt =
- reflist_0[i_ref]->poc;
- slice_param->RefPicList0[i_ref].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num;
- }
- g_assert (i_ref >= 1);
- }
- for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
- slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
- slice_param->RefPicList0[i_ref].flags = VA_PICTURE_H264_INVALID;
- }
-
- i_ref = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
- for (; i_ref < reflist_1_count; ++i_ref) {
- slice_param->RefPicList1[i_ref].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
- slice_param->RefPicList1[i_ref].TopFieldOrderCnt =
- reflist_1[i_ref]->poc;
- slice_param->RefPicList1[i_ref].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num;
- }
- g_assert (i_ref == 1);
- }
- for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
- slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
- slice_param->RefPicList1[i_ref].flags = VA_PICTURE_H264_INVALID;
- }
-
- /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
- slice_param->luma_log2_weight_denom = 0;
- slice_param->chroma_log2_weight_denom = 0;
- slice_param->luma_weight_l0_flag = FALSE;
- memset (slice_param->luma_weight_l0, 0,
- sizeof (slice_param->luma_weight_l0));
- memset (slice_param->luma_offset_l0, 0,
- sizeof (slice_param->luma_offset_l0));
- slice_param->chroma_weight_l0_flag = FALSE;
- memset (slice_param->chroma_weight_l0, 0,
- sizeof (slice_param->chroma_weight_l0));
- memset (slice_param->chroma_offset_l0, 0,
- sizeof (slice_param->chroma_offset_l0));
- slice_param->luma_weight_l1_flag = FALSE;
- memset (slice_param->luma_weight_l1, 0,
- sizeof (slice_param->luma_weight_l1));
- memset (slice_param->luma_offset_l1, 0,
- sizeof (slice_param->luma_offset_l1));
- slice_param->chroma_weight_l1_flag = FALSE;
- memset (slice_param->chroma_weight_l1, 0,
- sizeof (slice_param->chroma_weight_l1));
- memset (slice_param->chroma_offset_l1, 0,
- sizeof (slice_param->chroma_offset_l1));
-
- slice_param->cabac_init_idc = 0;
- slice_param->slice_qp_delta = feienc->init_qp - feienc->min_qp;
- if (slice_param->slice_qp_delta > 4)
- slice_param->slice_qp_delta = 4;
- slice_param->disable_deblocking_filter_idc = 0;
- slice_param->slice_alpha_c0_offset_div2 = 2;
- slice_param->slice_beta_offset_div2 = 2;
-
- /* set calculation for next slice */
- last_mb_index += cur_slice_mbs;
-
- g_array_append_val (h264_slice_params, *slice_param);
-
- gst_vaapi_enc_picture_add_slice (picture, slice);
- gst_vaapi_codec_object_replace (&slice, NULL);
- }
- g_assert (last_mb_index == mb_size);
-
- info_to_pak->h264_slice_headers = h264_slice_params;
-
- return TRUE;
-
-}
-
-/* Generates and submits SPS header accordingly into the bitstream */
-static gboolean
-ensure_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture,
- GstVaapiFeiInfoToPakH264 * info_to_pak)
-{
- GstVaapiEncSequence *sequence = NULL;
- VAEncSequenceParameterBufferH264 *seq_param;
-
- sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, feienc);
- if (!sequence || !fill_sequence (feienc, sequence))
- goto error_create_seq_param;
-
- seq_param = sequence->param;
- info_to_pak->h264_enc_sps = *seq_param;
-
- if (sequence) {
- gst_vaapi_enc_picture_set_sequence (picture, sequence);
- gst_vaapi_codec_object_replace (&sequence, NULL);
- }
-
- if (!feienc->is_mvc || feienc->view_idx > 0)
- feienc->config_changed = FALSE;
- return TRUE;
-
- /* ERRORS */
-error_create_seq_param:
- {
- GST_ERROR ("failed to create sequence parameter buffer (SPS)");
- gst_vaapi_codec_object_replace (&sequence, NULL);
- return FALSE;
- }
-}
-
-/* Generates additional fei control parameters */
-static gboolean
-ensure_fei_misc_params (GstVaapiFeiEncH264 * feienc,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy)
-{
- GstVaapiEncMiscParam *misc = NULL;
- GstVaapiSurfaceProxy *surface_proxy = picture->proxy;
- VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param;
- guint mbcode_size = 0;
- guint mv_size = 0;
- guint dist_size = 0;
-
- /*fei pic control params */
- misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, feienc);
- g_assert (misc);
- if (!misc)
- return FALSE;
- misc_fei_pic_control_param = misc->data;
- surface_proxy = picture->proxy;
-
- misc_fei_pic_control_param->function = VA_FEI_FUNCTION_ENC;
- misc_fei_pic_control_param->search_path = feienc->search_path;
- misc_fei_pic_control_param->num_mv_predictors_l0 =
- feienc->num_mv_predictors_l0;
- misc_fei_pic_control_param->num_mv_predictors_l1 =
- feienc->num_mv_predictors_l1;
- misc_fei_pic_control_param->len_sp = feienc->len_sp;
- misc_fei_pic_control_param->sub_mb_part_mask = feienc->submb_part_mask;
- if (!feienc->use_dct8x8)
- misc_fei_pic_control_param->intra_part_mask = feienc->intra_part_mask | 2;
- misc_fei_pic_control_param->multi_pred_l0 = feienc->multi_predL0;
- misc_fei_pic_control_param->multi_pred_l1 = feienc->multi_predL1;
- misc_fei_pic_control_param->sub_pel_mode = feienc->subpel_mode;
- misc_fei_pic_control_param->inter_sad = feienc->inter_sad;
- misc_fei_pic_control_param->intra_sad = feienc->intra_sad;
- misc_fei_pic_control_param->distortion_type = 0;
- misc_fei_pic_control_param->repartition_check_enable = 0;
- misc_fei_pic_control_param->adaptive_search = feienc->adaptive_search;
- misc_fei_pic_control_param->mb_size_ctrl = 0;
- misc_fei_pic_control_param->ref_width = feienc->ref_width;
- misc_fei_pic_control_param->ref_height = feienc->ref_height;
- misc_fei_pic_control_param->search_window = feienc->search_window;
-
- /***** ENC input: mv_predictor *****/
- if (surface_proxy->mvpred) {
- misc_fei_pic_control_param->mv_predictor =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mvpred)->param_id;
- misc_fei_pic_control_param->mv_predictor_enable = TRUE;
- gst_vaapi_codec_object_replace (&picture->mvpred, surface_proxy->mvpred);
- } else {
- misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID;
- misc_fei_pic_control_param->mv_predictor_enable = FALSE;
- picture->mvpred = NULL;
- }
-
- /***** ENC input: qp ******/
- if (surface_proxy->qp) {
- misc_fei_pic_control_param->qp =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->qp)->param_id;
- misc_fei_pic_control_param->mb_qp = TRUE;
- gst_vaapi_codec_object_replace (&picture->qp, surface_proxy->qp);
- } else {
- misc_fei_pic_control_param->qp = VA_INVALID_ID;
- misc_fei_pic_control_param->mb_qp = FALSE;
- picture->qp = NULL;
- }
- /***** ENC input: mb_control ******/
- if (surface_proxy->mbcntrl) {
- misc_fei_pic_control_param->mb_ctrl =
- GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcntrl)->param_id;
- misc_fei_pic_control_param->mb_input = TRUE;
- gst_vaapi_codec_object_replace (&picture->mbcntrl, surface_proxy->mbcntrl);
- } else {
- misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID;
- misc_fei_pic_control_param->mb_input = FALSE;
- picture->mbcntrl = NULL;
- }
-
- mbcode_size = sizeof (VAEncFEIMBCodeH264) *
- feienc->mb_width * feienc->mb_height;
- mv_size = sizeof (VAMotionVector) * 16 * feienc->mb_width * feienc->mb_height;
- dist_size = sizeof (VAEncFEIDistortionH264) *
- feienc->mb_width * feienc->mb_height;
- /***** ENC_PAK/ENC output: macroblock code buffer *****/
- codedbuf_proxy->mbcode =
- gst_vaapi_enc_fei_mb_code_new (GST_VAAPI_ENCODER_CAST (feienc),
- NULL, mbcode_size);
- misc_fei_pic_control_param->mb_code_data =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id;
- picture->mbcode = gst_vaapi_codec_object_ref (codedbuf_proxy->mbcode);
-
- /***** ENC_PAK/ENC output: motion vector buffer *****/
- codedbuf_proxy->mv =
- gst_vaapi_enc_fei_mv_new (GST_VAAPI_ENCODER_CAST (feienc), NULL, mv_size);
- misc_fei_pic_control_param->mv_data =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id;
- picture->mv = gst_vaapi_codec_object_ref (codedbuf_proxy->mv);
-
- /* Fixme: a copy needed in coded_buf proxy */
- /***** ENC_PAK/ENC output: distortion buffer *****/
- picture->dist =
- gst_vaapi_enc_fei_distortion_new (GST_VAAPI_ENCODER_CAST (feienc),
- NULL, dist_size);
- misc_fei_pic_control_param->distortion =
- GST_VAAPI_FEI_CODEC_OBJECT (picture->dist)->param_id;
- codedbuf_proxy->dist = gst_vaapi_codec_object_ref (picture->dist);
-
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
- return TRUE;
-}
-
-/* Generates additional control parameters */
-static gboolean
-ensure_misc_params (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture)
-{
- GstVaapiEncMiscParam *misc = NULL;
- VAEncMiscParameterRateControl *rate_control;
-
- /* HRD params */
- misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, feienc);
- g_assert (misc);
- if (!misc)
- return FALSE;
- fill_hrd_params (feienc, misc->data);
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
-
- /* RateControl params */
- if (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CBR ||
- GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_VBR) {
- misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, feienc);
- g_assert (misc);
- if (!misc)
- return FALSE;
- rate_control = misc->data;
- memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
- rate_control->bits_per_second = feienc->bitrate_bits;
- rate_control->target_percentage = 70;
- rate_control->window_size = feienc->cpb_length;
- rate_control->initial_qp = feienc->init_qp;
- rate_control->min_qp = feienc->min_qp;
- rate_control->basic_unit_size = 0;
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
-
- }
- return TRUE;
-
-}
-
-/* Generates and submits PPS header accordingly into the bitstream */
-static gboolean
-ensure_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture,
- GstVaapiSurfaceProxy * surface, GstVaapiCodedBufferProxy * codedbuf_proxy,
- GstVaapiFeiInfoToPakH264 * info_to_pak)
-{
- gboolean res = FALSE;
- GstVaapiCodedBuffer *const codedbuf =
- GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
- VAEncPictureParameterBufferH264 *const pic_param = picture->param;
-
- res = fill_picture (feienc, picture, surface, codedbuf);
-
- if (!res)
- return FALSE;
-
- info_to_pak->h264_enc_pps = *pic_param;
-
- return TRUE;
-}
-
-/* Generates slice headers */
-static gboolean
-ensure_slices (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture,
- GstVaapiFeiInfoToPakH264 * info_to_pak)
-{
- GstVaapiFeiEncH264Ref *reflist_0[16];
- GstVaapiFeiEncH264Ref *reflist_1[16];
- GstVaapiH264ViewRefPool *const ref_pool =
- &feienc->ref_pools[feienc->view_idx];
- guint reflist_0_count = 0, reflist_1_count = 0;
-
- g_assert (picture);
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
- !reference_list_init (feienc, picture,
- reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
- GST_ERROR ("reference list reorder failed");
- return FALSE;
- }
-
- g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
- if (reflist_0_count > ref_pool->max_reflist0_count)
- reflist_0_count = ref_pool->max_reflist0_count;
- if (reflist_1_count > ref_pool->max_reflist1_count)
- reflist_1_count = ref_pool->max_reflist1_count;
-
- if (!add_slice_headers (feienc, picture,
- reflist_0, reflist_0_count, reflist_1, reflist_1_count, info_to_pak))
- return FALSE;
-
- return TRUE;
-}
-
-/* Normalizes bitrate (and CPB size) for HRD conformance */
-static void
-ensure_bitrate_hrd (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc);
- guint bitrate, cpb_size;
-
- if (!base_encoder->bitrate) {
- feienc->bitrate_bits = 0;
- return;
- }
-
- /* Round down bitrate. This is a hard limit mandated by the user */
- g_assert (SX_BITRATE >= 6);
- bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
- if (bitrate != feienc->bitrate_bits) {
- GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
- feienc->bitrate_bits = bitrate;
- feienc->config_changed = TRUE;
- }
-
- /* Round up CPB size. This is an HRD compliance detail */
- g_assert (SX_CPB_SIZE >= 4);
- cpb_size = gst_util_uint64_scale (bitrate, feienc->cpb_length, 1000) &
- ~((1U << SX_CPB_SIZE) - 1);
- if (cpb_size != feienc->cpb_length_bits) {
- GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
- feienc->cpb_length_bits = cpb_size;
- feienc->config_changed = TRUE;
- }
-}
-
-/* Estimates a good enough bitrate if none was supplied */
-static void
-ensure_bitrate (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc);
-
- /* Default compression: 48 bits per macroblock in "high-compression" mode */
- switch (GST_VAAPI_ENCODER_RATE_CONTROL (feienc)) {
- case GST_VAAPI_RATECONTROL_CBR:
- case GST_VAAPI_RATECONTROL_VBR:
- case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
- if (!base_encoder->bitrate) {
- /* According to the literature and testing, CABAC entropy coding
- mode could provide for +10% to +18% improvement in general,
- thus estimating +15% here ; and using adaptive 8x8 transforms
- in I-frames could bring up to +10% improvement. */
- guint bits_per_mb = 48;
- if (!feienc->use_cabac)
- bits_per_mb += (bits_per_mb * 15) / 100;
- if (!feienc->use_dct8x8)
- bits_per_mb += (bits_per_mb * 10) / 100;
-
- base_encoder->bitrate =
- feienc->mb_width * feienc->mb_height * bits_per_mb *
- GST_VAAPI_ENCODER_FPS_N (feienc) /
- GST_VAAPI_ENCODER_FPS_D (feienc) / 1000;
- GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
- }
- break;
- default:
- base_encoder->bitrate = 0;
- break;
- }
- ensure_bitrate_hrd (feienc);
-}
-
-/* Constructs profile and level information based on user-defined limits */
-static GstVaapiEncoderStatus
-ensure_profile_and_level (GstVaapiFeiEncH264 * feienc)
-{
- const GstVaapiProfile profile = feienc->profile;
- const GstVaapiLevelH264 level = feienc->level;
-
- if (!ensure_tuning (feienc))
- GST_WARNING ("Failed to set some of the tuning option as expected! ");
-
- if (!ensure_profile (feienc) || !ensure_profile_limits (feienc))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- /* Check HW constraints */
- if (!ensure_hw_profile_limits (feienc))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
- if (feienc->profile_idc > feienc->hw_max_profile_idc)
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- /* Ensure bitrate if not set already and derive the right level to use */
- ensure_bitrate (feienc);
- if (!ensure_level (feienc))
- return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
-
- if (feienc->profile != profile || feienc->level != level) {
- GST_DEBUG ("selected %s profile at level %s",
- gst_vaapi_utils_h264_get_profile_string (feienc->profile),
- gst_vaapi_utils_h264_get_level_string (feienc->level));
- feienc->config_changed = TRUE;
- }
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static void
-reset_properties (GstVaapiFeiEncH264 * feienc)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc);
- guint mb_size, i;
- guint max_reflist0_count;
-
- if (feienc->idr_period < base_encoder->keyframe_period)
- feienc->idr_period = base_encoder->keyframe_period;
-
- if (feienc->min_qp > feienc->init_qp ||
- (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CQP &&
- feienc->min_qp < feienc->init_qp))
- feienc->min_qp = feienc->init_qp;
-
- mb_size = feienc->mb_width * feienc->mb_height;
- if (feienc->num_slices > (mb_size + 1) / 2)
- feienc->num_slices = (mb_size + 1) / 2;
- g_assert (feienc->num_slices);
-
- if (feienc->num_bframes > (base_encoder->keyframe_period + 1) / 2)
- feienc->num_bframes = (base_encoder->keyframe_period + 1) / 2;
-
- /* Workaround : vaapi-intel-driver doesn't have support for
- * B-frame encode when utilizing low-power encode hardware block.
- * So Disabling b-frame encoding in low-pwer encode.
- *
- * Fixme :We should query the VAConfigAttribEncMaxRefFrames
- * instead of blindly disabling b-frame support and set b/p frame count,
- * buffer pool size etc based on that.*/
- if ((feienc->num_bframes > 0)
- && (feienc->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) {
- GST_WARNING
- ("Disabling b-frame since the driver doesn't supporting it in low-power encode");
- feienc->num_bframes = 0;
- }
-
- if (feienc->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (feienc) > 0)
- feienc->cts_offset = gst_util_uint64_scale (GST_SECOND,
- GST_VAAPI_ENCODER_FPS_D (feienc), GST_VAAPI_ENCODER_FPS_N (feienc));
- else
- feienc->cts_offset = 0;
-
- /* init max_frame_num, max_poc */
- feienc->log2_max_frame_num = h264_get_log2_max_frame_num (feienc->idr_period);
- g_assert (feienc->log2_max_frame_num >= 4);
- feienc->max_frame_num = (1 << feienc->log2_max_frame_num);
- feienc->log2_max_pic_order_cnt = feienc->log2_max_frame_num + 1;
- feienc->max_pic_order_cnt = (1 << feienc->log2_max_pic_order_cnt);
- feienc->idr_num = 0;
-
- if (feienc->num_bframes > 0) {
- if (feienc->num_ref_frames == 1) {
- GST_INFO ("num ref frames is modified as 2 as b frame is set");
- feienc->num_ref_frames = 2;
- }
- max_reflist0_count = feienc->num_ref_frames - 1;
- } else {
- max_reflist0_count = feienc->num_ref_frames;
- }
- max_reflist0_count = max_reflist0_count > 5 ? 5 : max_reflist0_count;
-
- for (i = 0; i < feienc->num_views; i++) {
- GstVaapiH264ViewRefPool *const ref_pool = &feienc->ref_pools[i];
- GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i];
-
- ref_pool->max_reflist0_count = max_reflist0_count;
- ref_pool->max_reflist1_count = feienc->num_bframes > 0;
- ref_pool->max_ref_frames = ref_pool->max_reflist0_count
- + ref_pool->max_reflist1_count;
-
- reorder_pool->frame_index = 0;
- }
-
-}
-
-/* only for vaapi encoder framework checking */
-static GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_fake_encode (GstVaapiEncoder * base_encoder,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
-{
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder,
- GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * reconstruct,
- GstVaapiCodedBufferProxy * codedbuf_proxy,
- GstVaapiFeiInfoToPakH264 * info_to_pak)
-{
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder);
- GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
-
- if (!reconstruct || !codedbuf_proxy)
- return ret;
-
- if (!ensure_sequence (feienc, picture, info_to_pak))
- goto error;
- if (!ensure_misc_params (feienc, picture))
- goto error;
- if (!ensure_fei_misc_params (feienc, picture, codedbuf_proxy))
- goto error;
- if (!ensure_picture (feienc, picture, reconstruct, codedbuf_proxy,
- info_to_pak))
- goto error;
- if (!ensure_slices (feienc, picture, info_to_pak))
- goto error;
- if (!gst_vaapi_enc_picture_encode (picture))
- goto error;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-
-error:
- return ret;
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder)
-{
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder);
- GstVaapiH264ViewReorderPool *reorder_pool;
- GstVaapiEncPicture *pic;
- guint i;
-
- for (i = 0; i < feienc->num_views; i++) {
- reorder_pool = &feienc->reorder_pools[i];
- reorder_pool->frame_index = 0;
- reorder_pool->cur_frame_num = 0;
- reorder_pool->cur_present_index = 0;
-
- while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- pic = (GstVaapiEncPicture *)
- g_queue_pop_head (&reorder_pool->reorder_frame_list);
- gst_vaapi_enc_picture_unref (pic);
- }
- g_queue_clear (&reorder_pool->reorder_frame_list);
- }
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-/* Generate "codec-data" buffer */
-static GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_get_codec_data (GstVaapiEncoder * base_encoder,
- GstBuffer ** out_buffer_ptr)
-{
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder,
- GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
-{
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder);
- GstVaapiH264ViewReorderPool *reorder_pool = NULL;
- GstVaapiEncPicture *picture;
- gboolean is_idr = FALSE;
-
- *output = NULL;
-
- /* encoding views alternatively for MVC */
- if (feienc->is_mvc) {
- /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */
- if (frame)
- feienc->view_idx = frame->system_frame_number % feienc->num_views;
- else
- feienc->view_idx = (feienc->view_idx + 1) % feienc->num_views;
- }
- reorder_pool = &feienc->reorder_pools[feienc->view_idx];
-
- if (!frame) {
- if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
- return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
-
- /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
- dump B frames from queue, sometime, there may also have P frame or I frame */
- g_assert (feienc->num_bframes > 0);
- g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list),
- GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
- picture = g_queue_pop_head (&reorder_pool->reorder_frame_list);
- g_assert (picture);
- if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
- }
- goto end;
- }
-
- /* new frame coming */
- picture = GST_VAAPI_ENC_PICTURE_NEW (H264, feienc, frame);
- if (!picture) {
- GST_WARNING ("create H264 picture failed, frame timestamp:%"
- GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
- return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
- }
- ++reorder_pool->cur_present_index;
- picture->poc = ((reorder_pool->cur_present_index * 2) %
- feienc->max_pic_order_cnt);
-
- is_idr = (reorder_pool->frame_index == 0 ||
- reorder_pool->frame_index >= feienc->idr_period);
-
- /* check key frames */
- if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
- (reorder_pool->frame_index %
- GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc)) == 0) {
- ++reorder_pool->cur_frame_num;
- ++reorder_pool->frame_index;
-
- /* b frame enabled, check queue of reorder_frame_list */
- if (feienc->num_bframes
- && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- GstVaapiEncPicture *p_pic;
-
- p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
- set_p_frame (p_pic, feienc);
- g_queue_foreach (&reorder_pool->reorder_frame_list,
- (GFunc) set_b_frame, feienc);
- ++reorder_pool->cur_frame_num;
- set_key_frame (picture, feienc, is_idr);
- g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
- picture = p_pic;
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
- } else { /* no b frames in queue */
- set_key_frame (picture, feienc, is_idr);
- g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list));
- if (feienc->num_bframes)
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
- }
- goto end;
- }
-
- /* new p/b frames coming */
- ++reorder_pool->frame_index;
- if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
- g_queue_get_length (&reorder_pool->reorder_frame_list) <
- feienc->num_bframes) {
- g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
- return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
- }
-
- ++reorder_pool->cur_frame_num;
- set_p_frame (picture, feienc);
-
- if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
- g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame,
- feienc);
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
- g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list));
- }
-
-end:
- g_assert (picture);
- frame = picture->frame;
- if (GST_CLOCK_TIME_IS_VALID (frame->pts))
- frame->pts += feienc->cts_offset;
- *output = picture;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static GstVaapiEncoderStatus
-set_context_info (GstVaapiEncoder * base_encoder)
-{
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder);
- GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc);
- const guint DEFAULT_SURFACES_COUNT = 3;
-
- /* Maximum sizes for common headers (in bits) */
- enum
- {
- MAX_SPS_HDR_SIZE = 16473,
- MAX_VUI_PARAMS_SIZE = 210,
- MAX_HRD_PARAMS_SIZE = 4103,
- MAX_PPS_HDR_SIZE = 101,
- MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
- };
-
- if (!ensure_hw_profile (feienc))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- base_encoder->num_ref_frames =
- (feienc->num_ref_frames + DEFAULT_SURFACES_COUNT) * feienc->num_views;
-
- /* Only YUV 4:2:0 formats are supported for now. This means that we
- have a limit of 3200 bits per macroblock. */
- /* XXX: check profile and compute RawMbBits */
- base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
- GST_ROUND_UP_16 (vip->height) / 256) * 400;
-
- /* Account for SPS header */
- /* XXX: exclude scaling lists, MVC/SVC extensions */
- base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
- MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
-
- /* Account for PPS header */
- /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
- base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
-
- /* Account for slice header */
- base_encoder->codedbuf_size += feienc->num_slices * (4 +
- GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
-
- base_encoder->context_info.entrypoint = feienc->entrypoint;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder)
-{
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder);
- GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc);
- GstVaapiEncoderStatus status;
- guint mb_width, mb_height;
-
- mb_width = (GST_VAAPI_ENCODER_WIDTH (feienc) + 15) / 16;
- mb_height = (GST_VAAPI_ENCODER_HEIGHT (feienc) + 15) / 16;
- if (mb_width != feienc->mb_width || mb_height != feienc->mb_height) {
- GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (feienc),
- GST_VAAPI_ENCODER_HEIGHT (feienc));
- feienc->mb_width = mb_width;
- feienc->mb_height = mb_height;
- feienc->config_changed = TRUE;
- }
-
- /* Take number of MVC views from input caps if provided */
- if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) ==
- GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME
- || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) ==
- GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME)
- feienc->num_views = GST_VIDEO_INFO_VIEWS (vip);
-
- feienc->is_mvc = feienc->num_views > 1;
-
- status = ensure_profile_and_level (feienc);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
- return status;
-
- reset_properties (feienc);
- status = set_context_info (base_encoder);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
- return status;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-struct _GstVaapiFeiEncH264Class
-{
- GstVaapiEncoderClass parent_class;
-};
-
-G_DEFINE_TYPE (GstVaapiFeiEncH264, gst_vaapi_feienc_h264,
- GST_TYPE_VAAPI_ENCODER);
-
-static void
-gst_vaapi_feienc_h264_init (GstVaapiFeiEncH264 * feienc)
-{
- guint32 i;
-
- /* Default encoding entrypoint */
- feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
- feienc->search_path = GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT;
- feienc->len_sp = GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT;
- feienc->ref_width = GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT;
- feienc->ref_height = GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT;
- feienc->intra_part_mask = GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT;
- feienc->submb_part_mask = GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT;
-
- /* Multi-view coding information */
- feienc->is_mvc = FALSE;
- feienc->num_views = 1;
- feienc->view_idx = 0;
-
- /* default num ref frames */
- feienc->num_ref_frames = 1;
- memset (feienc->view_ids, 0, sizeof (feienc->view_ids));
-
- feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI;
-
- /* re-ordering list initialize */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i];
- g_queue_init (&reorder_pool->reorder_frame_list);
- reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
- reorder_pool->frame_index = 0;
- reorder_pool->cur_frame_num = 0;
- reorder_pool->cur_present_index = 0;
- }
-}
-
-static void
-gst_vaapi_feienc_h264_finalize (GObject * object)
-{
- /*free private buffers */
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264 (object);
- GstVaapiEncPicture *pic;
- guint32 i;
-
- gst_buffer_replace (&feienc->sps_data, NULL);
- gst_buffer_replace (&feienc->subset_sps_data, NULL);
- gst_buffer_replace (&feienc->pps_data, NULL);
-
- /* re-ordering list initialize */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i];
- while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
- pic = (GstVaapiEncPicture *)
- g_queue_pop_head (&reorder_pool->reorder_frame_list);
- gst_vaapi_enc_picture_unref (pic);
- }
- g_queue_clear (&reorder_pool->reorder_frame_list);
- }
-
- G_OBJECT_CLASS (gst_vaapi_feienc_h264_parent_class)->finalize (object);
-}
-
-static void
-set_view_ids (GstVaapiFeiEncH264 * const encoder, const GValue * value)
-{
- guint i, j;
- guint len = gst_value_array_get_size (value);
-
- if (len == 0)
- goto set_default_ids;
-
- if (len != encoder->num_views) {
- GST_WARNING ("The view number is %d, but %d view IDs are provided. Just "
- "fallback to use default view IDs.", encoder->num_views, len);
- goto set_default_ids;
- }
-
- for (i = 0; i < len; i++) {
- const GValue *val = gst_value_array_get_value (value, i);
- encoder->view_ids[i] = g_value_get_uint (val);
- }
-
- /* check whether duplicated ID */
- for (i = 0; i < len; i++) {
- for (j = i + 1; j < len; j++) {
- if (encoder->view_ids[i] == encoder->view_ids[j]) {
- GST_WARNING ("The view %d and view %d have same view ID %d. Just "
- "fallback to use default view IDs.", i, j, encoder->view_ids[i]);
- goto set_default_ids;
- }
- }
- }
-
- return;
-
-set_default_ids:
- {
- for (i = 0; i < encoder->num_views; i++)
- encoder->view_ids[i] = i;
- }
-}
-
-static void
-get_view_ids (GstVaapiFeiEncH264 * const encoder, GValue * value)
-{
- guint i;
- GValue id = G_VALUE_INIT;
-
- g_value_reset (value);
- g_value_init (&id, G_TYPE_UINT);
-
- for (i = 0; i < encoder->num_views; i++) {
- g_value_set_uint (&id, encoder->view_ids[i]);
- gst_value_array_append_value (value, &id);
- }
- g_value_unset (&id);
-}
-
-/**
- * @FEI_H264_ENC_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
- * @FEI_H264_ENC_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
- * @FEI_H264_ENC_PROP_MAX_BFRAMES: Number of B-frames between I
- * and P (uint).
- * @FEI_H264_ENC_PROP_INIT_QP: Initial quantizer value (uint).
- * @FEI_H264_ENC_PROP_MIN_QP: Minimal quantizer value (uint).
- * @FEI_H264_ENC_PROP_NUM_SLICES: Number of slices per frame (uint).
- * @FEI_H264_ENC_PROP_CABAC: Enable CABAC entropy coding mode (bool).
- * @FEI_H264_ENC_PROP_DCT8X8: Enable adaptive use of 8x8
- * transforms in I-frames (bool).
- * @FEI_H264_ENC_PROP_CPB_LENGTH: Length of the CPB buffer
- * in milliseconds (uint).
- * @FEI_H264_ENC_PROP_NUM_VIEWS: Number of views per frame.
- * @FEI_H264_ENC_PROP_VIEW_IDS: View IDs
- *
- * The set of FEI Enc specific configurable properties.
- */
-enum
-{
- FEI_H264_ENC_PROP_RATECONTROL = 1,
- FEI_H264_ENC_PROP_TUNE,
- FEI_H264_ENC_PROP_MAX_BFRAMES,
- FEI_H264_ENC_PROP_INIT_QP,
- FEI_H264_ENC_PROP_MIN_QP,
- FEI_H264_ENC_PROP_NUM_SLICES,
- FEI_H264_ENC_PROP_CABAC,
- FEI_H264_ENC_PROP_DCT8X8,
- FEI_H264_ENC_PROP_CPB_LENGTH,
- FEI_H264_ENC_PROP_NUM_VIEWS,
- FEI_H264_ENC_PROP_VIEW_IDS,
- FEI_H264_ENC_PROP_NUM_REF,
- FEI_H264_ENC_PROP_FEI_ENABLE,
- FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0,
- FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1,
- FEI_H264_ENC_PROP_SEARCH_WINDOW,
- FEI_H264_ENC_PROP_LEN_SP,
- FEI_H264_ENC_PROP_SEARCH_PATH,
- FEI_H264_ENC_PROP_REF_WIDTH,
- FEI_H264_ENC_PROP_REF_HEIGHT,
- FEI_H264_ENC_PROP_SUBMB_MASK,
- FEI_H264_ENC_PROP_SUBPEL_MODE,
- FEI_H264_ENC_PROP_INTRA_PART_MASK,
- FEI_H264_ENC_PROP_INTRA_SAD,
- FEI_H264_ENC_PROP_INTER_SAD,
- FEI_H264_ENC_PROP_ADAPT_SEARCH,
- FEI_H264_ENC_PROP_MULTI_PRED_L0,
- FEI_H264_ENC_PROP_MULTI_PRED_L1,
- FEI_H264_ENC_PROP_ENABLE_STATS_OUT,
- FEI_H264_ENC_N_PROPERTIES
-};
-
-static GParamSpec *properties[FEI_H264_ENC_N_PROPERTIES];
-
-static void
-gst_vaapi_feienc_h264_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder);
-
- if (base_encoder->num_codedbuf_queued > 0) {
- GST_ERROR_OBJECT (object,
- "failed to set any property after encoding started");
- return;
- }
-
- switch (prop_id) {
- case FEI_H264_ENC_PROP_RATECONTROL:
- gst_vaapi_encoder_set_rate_control (base_encoder,
- g_value_get_enum (value));
- break;
- case FEI_H264_ENC_PROP_TUNE:
- gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
- break;
- case FEI_H264_ENC_PROP_MAX_BFRAMES:
- feienc->num_bframes = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_INIT_QP:
- feienc->init_qp = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_MIN_QP:
- feienc->min_qp = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_NUM_SLICES:
- feienc->num_slices = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_CABAC:
- feienc->use_cabac = g_value_get_boolean (value);
- break;
- case FEI_H264_ENC_PROP_DCT8X8:
- feienc->use_dct8x8 = g_value_get_boolean (value);
- break;
- case FEI_H264_ENC_PROP_CPB_LENGTH:
- feienc->cpb_length = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_NUM_VIEWS:
- feienc->num_views = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_VIEW_IDS:
- set_view_ids (feienc, value);
- break;
- case FEI_H264_ENC_PROP_NUM_REF:
- feienc->num_ref_frames = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0:
- feienc->num_mv_predictors_l0 = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1:
- feienc->num_mv_predictors_l1 = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_SEARCH_WINDOW:
- feienc->search_window = g_value_get_enum (value);
- break;
- case FEI_H264_ENC_PROP_LEN_SP:
- feienc->len_sp = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_SEARCH_PATH:
- feienc->search_path = g_value_get_enum (value);
- break;
- case FEI_H264_ENC_PROP_REF_WIDTH:
- feienc->ref_width = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_REF_HEIGHT:
- feienc->ref_height = g_value_get_uint (value);
- break;
- case FEI_H264_ENC_PROP_SUBMB_MASK:
- feienc->submb_part_mask = g_value_get_flags (value);
- break;
- case FEI_H264_ENC_PROP_SUBPEL_MODE:
- feienc->subpel_mode = g_value_get_enum (value);
- break;
- case FEI_H264_ENC_PROP_INTRA_PART_MASK:
- feienc->intra_part_mask = g_value_get_flags (value);
- break;
- case FEI_H264_ENC_PROP_INTRA_SAD:
- feienc->intra_sad = g_value_get_enum (value);
- break;
- case FEI_H264_ENC_PROP_INTER_SAD:
- feienc->inter_sad = g_value_get_enum (value);
- break;
- case FEI_H264_ENC_PROP_ADAPT_SEARCH:
- feienc->adaptive_search = g_value_get_boolean (value) ? 1 : 0;
- break;
- case FEI_H264_ENC_PROP_MULTI_PRED_L0:
- feienc->multi_predL0 = g_value_get_boolean (value) ? 1 : 0;
- break;
- case FEI_H264_ENC_PROP_MULTI_PRED_L1:
- feienc->multi_predL1 = g_value_get_boolean (value) ? 1 : 0;
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-gst_vaapi_feienc_h264_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (object);
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
-
- switch (prop_id) {
- case FEI_H264_ENC_PROP_RATECONTROL:
- g_value_set_enum (value, base_encoder->rate_control);
- break;
- case FEI_H264_ENC_PROP_TUNE:
- g_value_set_enum (value, base_encoder->tune);
- break;
- case FEI_H264_ENC_PROP_MAX_BFRAMES:
- g_value_set_uint (value, feienc->num_bframes);
- break;
- case FEI_H264_ENC_PROP_INIT_QP:
- g_value_set_uint (value, feienc->init_qp);
- break;
- case FEI_H264_ENC_PROP_MIN_QP:
- g_value_set_uint (value, feienc->min_qp);
- break;
- case FEI_H264_ENC_PROP_NUM_SLICES:
- g_value_set_uint (value, feienc->num_slices);
- break;
- case FEI_H264_ENC_PROP_CABAC:
- g_value_set_boolean (value, feienc->use_cabac);
- break;
- case FEI_H264_ENC_PROP_DCT8X8:
- g_value_set_boolean (value, feienc->use_dct8x8);
- break;
- case FEI_H264_ENC_PROP_CPB_LENGTH:
- g_value_set_uint (value, feienc->cpb_length);
- break;
- case FEI_H264_ENC_PROP_NUM_VIEWS:
- g_value_set_uint (value, feienc->num_views);
- break;
- case FEI_H264_ENC_PROP_VIEW_IDS:
- get_view_ids (feienc, value);
- break;
- case FEI_H264_ENC_PROP_NUM_REF:
- g_value_set_uint (value, feienc->num_ref_frames);
- break;
- case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0:
- g_value_set_uint (value, feienc->num_mv_predictors_l0);
- break;
- case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1:
- g_value_set_uint (value, feienc->num_mv_predictors_l1);
- break;
- case FEI_H264_ENC_PROP_SEARCH_WINDOW:
- g_value_set_enum (value, feienc->search_window);
- break;
- case FEI_H264_ENC_PROP_LEN_SP:
- g_value_set_uint (value, feienc->len_sp);
- break;
- case FEI_H264_ENC_PROP_SEARCH_PATH:
- g_value_set_enum (value, feienc->search_path);
- break;
- case FEI_H264_ENC_PROP_REF_WIDTH:
- g_value_set_uint (value, feienc->ref_width);
- break;
- case FEI_H264_ENC_PROP_REF_HEIGHT:
- g_value_set_uint (value, feienc->ref_height);
- break;
- case FEI_H264_ENC_PROP_SUBMB_MASK:
- g_value_set_flags (value, feienc->submb_part_mask);
- break;
- case FEI_H264_ENC_PROP_SUBPEL_MODE:
- g_value_set_enum (value, feienc->subpel_mode);
- break;
- case FEI_H264_ENC_PROP_INTRA_PART_MASK:
- g_value_set_flags (value, feienc->intra_part_mask);
- break;
- case FEI_H264_ENC_PROP_INTRA_SAD:
- g_value_set_enum (value, feienc->intra_sad);
- break;
- case FEI_H264_ENC_PROP_INTER_SAD:
- g_value_set_enum (value, feienc->inter_sad);
- break;
- case FEI_H264_ENC_PROP_ADAPT_SEARCH:
- g_value_set_boolean (value, feienc->adaptive_search);
- break;
- case FEI_H264_ENC_PROP_MULTI_PRED_L0:
- g_value_set_boolean (value, feienc->multi_predL0);
- break;
- case FEI_H264_ENC_PROP_MULTI_PRED_L1:
- g_value_set_boolean (value, feienc->multi_predL1);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static const GstVaapiEncoderClassData fei_enc_class_data = {
- .codec = GST_VAAPI_CODEC_H264,
- .packed_headers = SUPPORTED_PACKED_HEADERS,
- .rate_control_get_type = gst_vaapi_rate_control_get_type,
- .default_rate_control = DEFAULT_RATECONTROL,
- .rate_control_mask = SUPPORTED_RATECONTROLS,
- .encoder_tune_get_type = gst_vaapi_encoder_tune_get_type,
- .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE,
- .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS,
-};
-
-static void
-gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass)
-{
- GObjectClass *const object_class = G_OBJECT_CLASS (klass);
- GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
-
- encoder_class->class_data = &fei_enc_class_data;
- encoder_class->reconfigure = gst_vaapi_feienc_h264_reconfigure;
- encoder_class->reordering = gst_vaapi_feienc_h264_reordering;
- encoder_class->encode = gst_vaapi_feienc_h264_fake_encode;
- encoder_class->flush = gst_vaapi_feienc_h264_flush;
- encoder_class->get_codec_data = gst_vaapi_feienc_h264_get_codec_data;
-
- object_class->set_property = gst_vaapi_feienc_h264_set_property;
- object_class->get_property = gst_vaapi_feienc_h264_get_property;
- object_class->finalize = gst_vaapi_feienc_h264_finalize;
-
- /**
- * GstVaapiFeiEncH264:rate-control:
- *
- * The desired rate control mode, expressed as a #GstVaapiRateControl.
- */
- properties[FEI_H264_ENC_PROP_RATECONTROL] =
- g_param_spec_enum ("rate-control",
- "Rate Control", "Rate control mode",
- fei_enc_class_data.rate_control_get_type (),
- fei_enc_class_data.default_rate_control,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:tune:
- *
- * The desired encoder tuning option.
- */
- properties[FEI_H264_ENC_PROP_TUNE] =
- g_param_spec_enum ("tune",
- "Encoder Tuning",
- "Encoder tuning option",
- fei_enc_class_data.encoder_tune_get_type (),
- fei_enc_class_data.default_encoder_tune,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:max-bframes:
- *
- * The number of B-frames between I and P.
- */
- properties[FEI_H264_ENC_PROP_MAX_BFRAMES] =
- g_param_spec_uint ("max-bframes",
- "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:init-qp:
- *
- * The initial quantizer value.
- */
- properties[FEI_H264_ENC_PROP_INIT_QP] =
- g_param_spec_uint ("init-qp",
- "Initial QP", "Initial quantizer value", 1, 51, 26,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:min-qp:
- *
- * The minimum quantizer value.
- */
- properties[FEI_H264_ENC_PROP_MIN_QP] =
- g_param_spec_uint ("min-qp",
- "Minimum QP", "Minimum quantizer value", 1, 51, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:num-slices:
- *
- * The number of slices per frame.
- */
- properties[FEI_H264_ENC_PROP_NUM_SLICES] =
- g_param_spec_uint ("num-slices",
- "Number of Slices",
- "Number of slices per frame",
- 1, 200, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:cabac:
- *
- * Enable CABAC entropy coding mode for improved compression ratio,
- * at the expense that the minimum target profile is Main. Default
- * is CAVLC entropy coding mode.
- */
- properties[FEI_H264_ENC_PROP_CABAC] =
- g_param_spec_boolean ("cabac",
- "Enable CABAC",
- "Enable CABAC entropy coding mode",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:dct8x8:
- *
- * Enable adaptive use of 8x8 transforms in I-frames. This improves
- * the compression ratio by the minimum target profile is High.
- * Default is to use 4x4 DCT only.
- */
- properties[FEI_H264_ENC_PROP_DCT8X8] =
- g_param_spec_boolean ("dct8x8",
- "Enable 8x8 DCT",
- "Enable adaptive use of 8x8 transforms in I-frames",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:cpb-length:
- *
- * The size of the CPB buffer in milliseconds.
- */
- properties[FEI_H264_ENC_PROP_CPB_LENGTH] =
- g_param_spec_uint ("cpb-length",
- "CPB Length", "Length of the CPB buffer in milliseconds",
- 1, 10000, DEFAULT_CPB_LENGTH,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:num-views:
- *
- * The number of views for MVC encoding .
- */
- properties[FEI_H264_ENC_PROP_NUM_VIEWS] =
- g_param_spec_uint ("num-views",
- "Number of Views",
- "Number of Views for MVC encoding",
- 1, MAX_NUM_VIEWS, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:view-ids:
- *
- * The view ids for MVC encoding .
- */
- properties[FEI_H264_ENC_PROP_VIEW_IDS] =
- gst_param_spec_array ("view-ids",
- "View IDs", "Set of View Ids used for MVC encoding",
- g_param_spec_uint ("view-id-value", "View id value",
- "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:num-ref:
- *
- * The number of reference frames.
- */
- properties[FEI_H264_ENC_PROP_NUM_REF] =
- g_param_spec_uint ("num-ref",
- "Num Ref",
- "reference frame number",
- 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:num_mv_predictors_l0:
- *
- * The number of mv predict
- */
- properties[FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0] =
- g_param_spec_uint ("num-mvpredict-l0",
- "Num mv predict l0",
- "Indicate how many predictors should be used for l0",
- 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:num_mv_predictors_l1:
- *
- * The number of mv predict
- */
- properties[FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1] =
- g_param_spec_uint ("num-mvpredict-l1",
- "Num mv predict l1",
- "Indicate how many predictors should be used for l1",
- 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:search-window:
- */
- properties[FEI_H264_ENC_PROP_SEARCH_WINDOW] =
- g_param_spec_enum ("search-window",
- "search window",
- "Specify one of the predefined search path",
- GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:len-sp:
- */
- properties[FEI_H264_ENC_PROP_LEN_SP] =
- g_param_spec_uint ("len-sp",
- "len sp",
- "This value defines number of search units in search path",
- 1, 63, 32,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:search-path:
- */
- properties[FEI_H264_ENC_PROP_SEARCH_PATH] =
- g_param_spec_enum ("search-path",
- "search path",
- "Specify search path",
- GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH,
- GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:ref-width:
- */
- properties[FEI_H264_ENC_PROP_REF_WIDTH] =
- g_param_spec_uint ("ref-width",
- "ref width",
- "Width of search region in pixel, must be multiple of 4",
- 4, 64, 32,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:ref-height:
- */
- properties[FEI_H264_ENC_PROP_REF_HEIGHT] =
- g_param_spec_uint ("ref-height",
- "ref height",
- "Height of search region in pixel, must be multiple of 4",
- 4, 32, 32,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:submb-mask:
- * Defines the bit-mask for disabling sub-partition
- *
- */
- properties[FEI_H264_ENC_PROP_SUBMB_MASK] =
- g_param_spec_flags ("submbpart-mask",
- "submb part mask",
- "defines the bit-mask for disabling sub mb partition",
- GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK,
- GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:subpel-mode:
- */
- properties[FEI_H264_ENC_PROP_SUBPEL_MODE] =
- g_param_spec_enum ("subpel-mode",
- "subpel mode",
- "Sub pixel precision for motion estimation",
- GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE,
- GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:intrapart-mask:
- */
- properties[FEI_H264_ENC_PROP_INTRA_PART_MASK] =
- g_param_spec_flags ("intrapart-mask",
- "intra part mask",
- "What block and sub-block partitions are disabled for intra MBs",
- GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK,
- GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
- /**
- * GstVaapiFeiEncH264:intra-sad:
- */
- properties[FEI_H264_ENC_PROP_INTRA_SAD] =
- g_param_spec_enum ("intra-sad",
- "intra sad",
- "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB",
- GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:inter-sad:
- */
- properties[FEI_H264_ENC_PROP_INTER_SAD] =
- g_param_spec_enum ("inter-sad",
- "inter sad",
- "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB",
- GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:adaptive-search:
- */
- properties[FEI_H264_ENC_PROP_ADAPT_SEARCH] =
- g_param_spec_boolean ("adaptive-search",
- "adaptive-search",
- "Enable adaptive search",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:multi-predL0:
- */
- properties[FEI_H264_ENC_PROP_MULTI_PRED_L0] =
- g_param_spec_boolean ("multi-predL0",
- "multi predL0",
- "Enable multi prediction for ref L0 list",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- /**
- * GstVaapiFeiEncH264:multi-predL0:
- */
- properties[FEI_H264_ENC_PROP_MULTI_PRED_L1] =
- g_param_spec_boolean ("multi-predL1",
- "multi predL1",
- "Enable multi prediction for ref L1 list",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
- GST_VAAPI_PARAM_ENCODER_EXPOSURE);
-
- g_object_class_install_properties (object_class, FEI_H264_ENC_N_PROPERTIES,
- properties);
-}
-
-/**
- * gst_vaapi_feienc_h264_new:
- * @display: a #GstVaapiDisplay
- *
- * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
- * only supported output stream format is "byte-stream" format.
- *
- * Return value: the newly allocated #GstVaapiEncoder object
- */
-GstVaapiEncoder *
-gst_vaapi_feienc_h264_new (GstVaapiDisplay * display)
-{
- return g_object_new (GST_TYPE_VAAPI_FEI_ENC_H264, "display", display, NULL);
-}
-
-/**
- * gst_vaapi_feienc_h264_set_max_profile:
- * @feienc: a #GstVaapiFeiEncH264
- * @profile: an H.264 #GstVaapiProfile
- *
- * Notifies the @feienc to use coding tools from the supplied
- * @profile at most.
- *
- * This means that if the minimal profile derived to
- * support the specified coding tools is greater than this @profile,
- * then an error is returned when the @feienc is configured.
- *
- * Return value: %TRUE on success
- */
-gboolean
-gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc,
- GstVaapiProfile profile)
-{
- guint8 profile_idc;
-
- g_return_val_if_fail (feienc != NULL, FALSE);
- g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
-
- if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
- return FALSE;
-
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- if (!profile_idc)
- return FALSE;
-
- feienc->max_profile_idc = profile_idc;
- return TRUE;
-}
-
-gboolean
-gst_vaapi_feienc_h264_set_ref_pool (GstVaapiFeiEncH264 * feienc,
- gpointer ref_pool_ptr)
-{
- g_return_val_if_fail (feienc != NULL, FALSE);
-
- if (!ref_pool_ptr)
- return FALSE;
-
- memcpy (&feienc->ref_pools[0], ref_pool_ptr,
- sizeof (GstVaapiH264ViewRefPool) * MAX_NUM_VIEWS);
-
- return TRUE;
-}
-
-/**
- * gst_vaapi_feienc_h264_get_profile_and_level
- * @feienc: a #GstVaapiFeiEncH264
- * @out_profile_ptr: return location for the #GstVaapiProfile
- * @out_profile_idc_ptr: return location for the #GstVaapiLevelH264
- *
- * Queries the H.264 @feienc for the active profile and level. That
- * information is only constructed and valid after the feienc is
- * configured, i.e. after the gst_vaapi_feienc_set_codec_state()
- * function is called.
- *
- * Return value: %TRUE on success
- */
-gboolean
-gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc,
- GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr)
-{
- g_return_val_if_fail (feienc != NULL, FALSE);
-
- if (!feienc->profile || !feienc->profile_idc)
- return FALSE;
-
- if (out_profile_ptr)
- *out_profile_ptr = feienc->profile;
- if (out_profile_idc_ptr)
- *out_profile_idc_ptr = feienc->profile_idc;
- return TRUE;
-}
diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h
deleted file mode 100644
index 046056b7..00000000
--- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * gstvaapifeienc_h264.h - FEI Enc abstract
- *
- * Copyright (C) 2016-2018 Intel Corporation
- * Author: Leilei Shang <leilei.shang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_FEI_H264_ENC_H
-#define GST_VAAPI_FEI_H264_ENC_H
-
-#include <gst/vaapi/gstvaapiencoder.h>
-#include <gst/vaapi/gstvaapiutils_h264.h>
-#include <gst/vaapi/gstvaapifeiutils_h264.h>
-#include <gst/vaapi/gstvaapifei_objects_priv.h>
-G_BEGIN_DECLS
-
-#define GST_TYPE_VAAPI_FEI_ENC_H264 \
- (gst_vaapi_feienc_h264_get_type ())
-#define GST_VAAPI_FEI_ENC_H264(encoder) \
- (G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_FEI_ENC_H264, GstVaapiFeiEncH264))
-#define GST_IS_VAAPI_FEI_ENC_H264(encoder) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_FEI_ENC_H264))
-
-typedef struct _GstVaapiFeiEncH264 GstVaapiFeiEncH264;
-typedef struct _GstVaapiFeiEncH264Class GstVaapiFeiEncH264Class;
-
-GType
-gst_vaapi_feienc_h264_get_type (void) G_GNUC_CONST;
-
-GstVaapiEncoder *
-gst_vaapi_feienc_h264_new (GstVaapiDisplay * display);
-
-gboolean
-gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc,
- GstVaapiProfile profile);
-
-gboolean
-gst_vaapi_feienc_h264_set_ref_pool (GstVaapiFeiEncH264 * feienc, gpointer ref_pool_ptr);
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder,
- GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * reconstruct,
- GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiFeiInfoToPakH264 *info_to_pak);
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder);
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder,
- GstVideoCodecFrame * frame, GstVaapiEncPicture ** output);
-
-GstVaapiEncoderStatus
-gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder);
-
-gboolean
-gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc,
- GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr);
-
-G_END_DECLS
-#endif /*GST_VAAPI_FEI_H264_ENC_H */
diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c
deleted file mode 100644
index 575c4f93..00000000
--- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c
+++ /dev/null
@@ -1,1915 +0,0 @@
-/*
- * gstvaapifeipak_h264.c - H.264 FEI PAK
- *
- * Copyright (C) 2012-2016 Intel Corporation
- * Author: Chen, Xiaomin <xiaomin.chen@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-/* GValueArray has deprecated without providing an alternative in glib >= 2.32
- * See https://bugzilla.gnome.org/show_bug.cgi?id=667228
- */
-
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
-
-#include "sysdeps.h"
-#include <va/va.h>
-#include <gst/base/gstbitwriter.h>
-#include <gst/codecparsers/gsth264parser.h>
-#include "gstvaapicompat.h"
-#include "gstvaapiencoder_priv.h"
-#include "gstvaapifeipak_h264.h"
-#include "gstvaapiutils_h264_priv.h"
-#include "gstvaapicodedbufferproxy_priv.h"
-#include "gstvaapisurface.h"
-#define DEBUG 1
-#include "gstvaapidebug.h"
-
-/* Define the maximum number of views supported */
-#define MAX_NUM_VIEWS 10
-
-/* Define the maximum value for view-id */
-#define MAX_VIEW_ID 1023
-
-/* Default CPB length (in milliseconds) */
-#define DEFAULT_CPB_LENGTH 1500
-
-/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */
-#define SX_CPB_SIZE 4
-
-/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */
-#define SX_BITRATE 6
-
-/* Define default rate control mode ("constant-qp") */
-#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
-
-/* Supported set of VA rate controls, within this implementation */
-#define SUPPORTED_RATECONTROLS \
- (GST_VAAPI_RATECONTROL_MASK (CQP) | \
- GST_VAAPI_RATECONTROL_MASK (CBR) | \
- GST_VAAPI_RATECONTROL_MASK (VBR) | \
- GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
-
-/* Supported set of tuning options, within this implementation */
-#define SUPPORTED_TUNE_OPTIONS \
- (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \
- GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \
- GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER))
-
-/* Supported set of VA packed headers, within this implementation */
-#define SUPPORTED_PACKED_HEADERS \
- (VA_ENC_PACKED_HEADER_SEQUENCE | \
- VA_ENC_PACKED_HEADER_PICTURE | \
- VA_ENC_PACKED_HEADER_SLICE | \
- VA_ENC_PACKED_HEADER_RAW_DATA)
-
-#define GST_H264_NAL_REF_IDC_NONE 0
-#define GST_H264_NAL_REF_IDC_LOW 1
-#define GST_H264_NAL_REF_IDC_MEDIUM 2
-#define GST_H264_NAL_REF_IDC_HIGH 3
-
-typedef struct
-{
- GstVaapiSurfaceProxy *pic;
- guint poc;
- guint frame_num;
-} GstVaapiFEIPakH264Ref;
-
-typedef enum
-{
- GST_VAAPI_FEIPAK_H264_REORD_NONE = 0,
- GST_VAAPI_FEIPAK_H264_REORD_DUMP_FRAMES = 1,
- GST_VAAPI_FEIPAK_H264_REORD_WAIT_FRAMES = 2
-} GstVaapiFEIPakH264ReorderState;
-
-typedef struct _GstVaapiH264FEIPakViewRefPool
-{
- GQueue ref_list;
- guint max_ref_frames;
- guint max_reflist0_count;
- guint max_reflist1_count;
-} GstVaapiH264FEIPakViewRefPool;
-
-typedef struct _GstVaapiH264FEIPakViewReorderPool
-{
- GQueue reorder_frame_list;
- guint reorder_state;
- guint frame_index;
- guint frame_count; /* monotonically increasing with in every idr period */
- guint cur_frame_num;
- guint cur_present_index;
-} GstVaapiH264FEIPakViewReorderPool;
-
-/* ------------------------------------------------------------------------- */
-/* --- H.264 FEI PAK --- */
-/* ------------------------------------------------------------------------- */
-
-struct _GstVaapiFEIPakH264
-{
- GstVaapiMiniObject parent_instance;
-
- GstVaapiEncoder *encoder;
-
- VAEncSequenceParameterBufferH264 h264_sps;
- VAEncPictureParameterBufferH264 h264_pps;
- GArray *h264_slice_params;
-
- GstVaapiProfile profile;
- GstVaapiEntrypoint entrypoint;
- GstVaapiDisplay *display;
- VAContextID va_context;
- guint8 profile_idc;
- guint8 hw_max_profile_idc;
- guint32 num_slices;
- guint slice_type;
- gboolean is_idr;
- guint32 num_bframes;
- guint32 mb_width;
- guint32 mb_height;
- gboolean props_reconfigured;
- gboolean config_changed;
-
- guint32 max_pic_order_cnt;
- guint32 log2_max_pic_order_cnt;
-
- GstBuffer *sps_data;
- GstBuffer *subset_sps_data;
- GstBuffer *pps_data;
- guint32 num_ref_frames; // set reference frame num
-
- /* MVC */
- gboolean is_mvc;
- guint32 view_idx; /* View Order Index (VOIdx) */
- guint32 num_views;
- guint16 view_ids[MAX_NUM_VIEWS];
- GstVaapiH264FEIPakViewRefPool ref_pools[MAX_NUM_VIEWS];
-};
-
-static inline gboolean
-_poc_greater_than (guint poc1, guint poc2, guint max_poc)
-{
- return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
-}
-
-/* ------------------------------------------------------------------------- */
-/* --- H.264 Bitstream Writer --- */
-/* ------------------------------------------------------------------------- */
-
-#define WRITE_UINT32(bs, val, nbits) do { \
- if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \
- GST_WARNING ("failed to write uint32, nbits: %d", nbits); \
- goto bs_error; \
- } \
- } while (0)
-
-#define WRITE_UE(bs, val) do { \
- if (!bs_write_ue (bs, val)) { \
- GST_WARNING ("failed to write ue(v)"); \
- goto bs_error; \
- } \
- } while (0)
-
-#define WRITE_SE(bs, val) do { \
- if (!bs_write_se (bs, val)) { \
- GST_WARNING ("failed to write se(v)"); \
- goto bs_error; \
- } \
- } while (0)
-
-/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */
-static gboolean
-bs_write_ue (GstBitWriter * bs, guint32 value)
-{
- guint32 size_in_bits = 0;
- guint32 tmp_value = ++value;
-
- while (tmp_value) {
- ++size_in_bits;
- tmp_value >>= 1;
- }
- if (size_in_bits > 1
- && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1))
- return FALSE;
- if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits))
- return FALSE;
- return TRUE;
-}
-
-/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */
-static gboolean
-bs_write_se (GstBitWriter * bs, gint32 value)
-{
- guint32 new_val;
-
- if (value <= 0)
- new_val = -(value << 1);
- else
- new_val = (value << 1) - 1;
-
- if (!bs_write_ue (bs, new_val))
- return FALSE;
- return TRUE;
-}
-
-/* Write the NAL unit header */
-static gboolean
-bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc,
- guint32 nal_unit_type)
-{
- WRITE_UINT32 (bs, 0, 1);
- WRITE_UINT32 (bs, nal_ref_idc, 2);
- WRITE_UINT32 (bs, nal_unit_type, 5);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write NAL unit header");
- return FALSE;
- }
-}
-
-/* Write the MVC NAL unit header extension */
-static gboolean
-bs_write_nal_header_mvc_extension (GstBitWriter * bs,
- GstVaapiEncPicture * picture, guint32 view_id)
-{
- guint32 svc_extension_flag = 0;
- guint32 non_idr_flag = 1;
- guint32 priority_id = 0;
- guint32 temporal_id = 0;
- guint32 anchor_pic_flag = 0;
- guint32 inter_view_flag = 0;
-
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- non_idr_flag = 0;
-
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
- anchor_pic_flag = 1;
- /* svc_extension_flag == 0 for mvc stream */
- WRITE_UINT32 (bs, svc_extension_flag, 1);
-
- WRITE_UINT32 (bs, non_idr_flag, 1);
- WRITE_UINT32 (bs, priority_id, 6);
- WRITE_UINT32 (bs, view_id, 10);
- WRITE_UINT32 (bs, temporal_id, 3);
- WRITE_UINT32 (bs, anchor_pic_flag, 1);
- WRITE_UINT32 (bs, inter_view_flag, 1);
- WRITE_UINT32 (bs, 1, 1);
-
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write NAL unit header");
- return FALSE;
- }
-}
-
-/* Write the NAL unit trailing bits */
-static gboolean
-bs_write_trailing_bits (GstBitWriter * bs)
-{
- if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
- goto bs_error;
- gst_bit_writer_align_bytes_unchecked (bs, 0);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write NAL unit trailing bits");
- return FALSE;
- }
-}
-
-/* Write an SPS NAL unit */
-static gboolean
-bs_write_sps_data (GstBitWriter * bs,
- const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
- const VAEncMiscParameterHRD * hrd_params)
-{
- guint8 profile_idc;
- guint32 constraint_set0_flag, constraint_set1_flag;
- guint32 constraint_set2_flag, constraint_set3_flag;
- guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
- gboolean nal_hrd_parameters_present_flag;
-
- guint32 b_qpprime_y_zero_transform_bypass = 0;
- guint32 residual_color_transform_flag = 0;
- guint32 pic_height_in_map_units =
- (seq_param->seq_fields.bits.frame_mbs_only_flag ?
- seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
- guint32 mb_adaptive_frame_field =
- !seq_param->seq_fields.bits.frame_mbs_only_flag;
- guint32 i = 0;
-
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
- profile == GST_VAAPI_PROFILE_H264_BASELINE ||
- profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
- constraint_set1_flag = /* A.2.2 (main profile constraints) */
- profile == GST_VAAPI_PROFILE_H264_MAIN ||
- profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
- constraint_set2_flag = 0;
- constraint_set3_flag = 0;
-
- /* profile_idc */
- WRITE_UINT32 (bs, profile_idc, 8);
- /* constraint_set0_flag */
- WRITE_UINT32 (bs, constraint_set0_flag, 1);
- /* constraint_set1_flag */
- WRITE_UINT32 (bs, constraint_set1_flag, 1);
- /* constraint_set2_flag */
- WRITE_UINT32 (bs, constraint_set2_flag, 1);
- /* constraint_set3_flag */
- WRITE_UINT32 (bs, constraint_set3_flag, 1);
- /* reserved_zero_4bits */
- WRITE_UINT32 (bs, 0, 4);
- /* level_idc */
- WRITE_UINT32 (bs, seq_param->level_idc, 8);
- /* seq_parameter_set_id */
- WRITE_UE (bs, seq_param->seq_parameter_set_id);
-
- if (profile == GST_VAAPI_PROFILE_H264_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) {
- /* for high profile */
- /* chroma_format_idc = 1, 4:2:0 */
- WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
- if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
- WRITE_UINT32 (bs, residual_color_transform_flag, 1);
- }
- /* bit_depth_luma_minus8 */
- WRITE_UE (bs, seq_param->bit_depth_luma_minus8);
- /* bit_depth_chroma_minus8 */
- WRITE_UE (bs, seq_param->bit_depth_chroma_minus8);
- /* b_qpprime_y_zero_transform_bypass */
- WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1);
-
- /* seq_scaling_matrix_present_flag */
- g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
- WRITE_UINT32 (bs,
- seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
-
-#if 0
- if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
- for (i = 0;
- i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
- i++) {
- gst_bit_writer_put_bits_uint8 (bs,
- seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
- if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
- g_assert (0);
- /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
- }
- }
- }
-#endif
- }
-
- /* log2_max_frame_num_minus4 */
- WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4);
- /* pic_order_cnt_type */
- WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type);
-
- if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
- /* log2_max_pic_order_cnt_lsb_minus4 */
- WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
- } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
- g_assert (0 && "only POC type 0 is supported");
- WRITE_UINT32 (bs,
- seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
- WRITE_SE (bs, seq_param->offset_for_non_ref_pic);
- WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field);
- WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle);
- for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
- WRITE_SE (bs, seq_param->offset_for_ref_frame[i]);
- }
- }
-
- /* num_ref_frames */
- WRITE_UE (bs, seq_param->max_num_ref_frames);
- /* gaps_in_frame_num_value_allowed_flag */
- WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1);
-
- /* pic_width_in_mbs_minus1 */
- WRITE_UE (bs, seq_param->picture_width_in_mbs - 1);
- /* pic_height_in_map_units_minus1 */
- WRITE_UE (bs, pic_height_in_map_units - 1);
- /* frame_mbs_only_flag */
- WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
-
- if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
- g_assert (0 && "only progressive frames encoding is supported");
- WRITE_UINT32 (bs, mb_adaptive_frame_field, 1);
- }
-
- /* direct_8x8_inference_flag */
- WRITE_UINT32 (bs, 0, 1);
- /* frame_cropping_flag */
- WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1);
-
- if (seq_param->frame_cropping_flag) {
- /* frame_crop_left_offset */
- WRITE_UE (bs, seq_param->frame_crop_left_offset);
- /* frame_crop_right_offset */
- WRITE_UE (bs, seq_param->frame_crop_right_offset);
- /* frame_crop_top_offset */
- WRITE_UE (bs, seq_param->frame_crop_top_offset);
- /* frame_crop_bottom_offset */
- WRITE_UE (bs, seq_param->frame_crop_bottom_offset);
- }
-
- /* vui_parameters_present_flag */
- WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
- if (seq_param->vui_parameters_present_flag) {
- /* aspect_ratio_info_present_flag */
- WRITE_UINT32 (bs,
- seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
- if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
- WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
- if (seq_param->aspect_ratio_idc == 0xFF) {
- WRITE_UINT32 (bs, seq_param->sar_width, 16);
- WRITE_UINT32 (bs, seq_param->sar_height, 16);
- }
- }
-
- /* overscan_info_present_flag */
- WRITE_UINT32 (bs, 0, 1);
- /* video_signal_type_present_flag */
- WRITE_UINT32 (bs, 0, 1);
- /* chroma_loc_info_present_flag */
- WRITE_UINT32 (bs, 0, 1);
-
- /* timing_info_present_flag */
- WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1);
- if (seq_param->vui_fields.bits.timing_info_present_flag) {
- WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32);
- WRITE_UINT32 (bs, seq_param->time_scale, 32);
- WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */
- }
-
- /* nal_hrd_parameters_present_flag */
- nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0;
- WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
- if (nal_hrd_parameters_present_flag) {
- /* hrd_parameters */
- /* cpb_cnt_minus1 */
- WRITE_UE (bs, 0);
- WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */
- WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */
-
- for (i = 0; i < 1; ++i) {
- /* bit_rate_value_minus1[0] */
- WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
- /* cpb_size_value_minus1[0] */
- WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
- /* cbr_flag[0] */
- WRITE_UINT32 (bs, 1, 1);
- }
- /* initial_cpb_removal_delay_length_minus1 */
- WRITE_UINT32 (bs, 23, 5);
- /* cpb_removal_delay_length_minus1 */
- WRITE_UINT32 (bs, 23, 5);
- /* dpb_output_delay_length_minus1 */
- WRITE_UINT32 (bs, 23, 5);
- /* time_offset_length */
- WRITE_UINT32 (bs, 23, 5);
- }
-
- /* vcl_hrd_parameters_present_flag */
- WRITE_UINT32 (bs, 0, 1);
-
- if (nal_hrd_parameters_present_flag
- || 0 /*vcl_hrd_parameters_present_flag */ ) {
- /* low_delay_hrd_flag */
- WRITE_UINT32 (bs, 0, 1);
- }
- /* pic_struct_present_flag */
- WRITE_UINT32 (bs, 1, 1);
- /* bs_restriction_flag */
- WRITE_UINT32 (bs, 0, 1);
- }
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SPS NAL unit");
- return FALSE;
- }
-}
-
-static gboolean
-bs_write_sps (GstVaapiFEIPakH264 * feipak, GstBitWriter * bs,
- const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
- const VAEncMiscParameterHRD * hrd_params)
-{
- if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
- return FALSE;
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (bs);
-
- return FALSE;
-}
-
-static gboolean
-bs_write_subset_sps (GstVaapiFEIPakH264 * feipak, GstBitWriter * bs,
- const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
- guint num_views, guint16 * view_ids,
- const VAEncMiscParameterHRD * hrd_params)
-{
- guint32 i, j, k;
-
- if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
- return FALSE;
-
- if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) {
- guint32 num_views_minus1, num_level_values_signalled_minus1;
-
- num_views_minus1 = num_views - 1;
- g_assert (num_views_minus1 < 1024);
-
- /* bit equal to one */
- WRITE_UINT32 (bs, 1, 1);
-
- WRITE_UE (bs, num_views_minus1);
-
- for (i = 0; i <= num_views_minus1; i++)
- WRITE_UE (bs, view_ids[i]);
-
- for (i = 1; i <= num_views_minus1; i++) {
- guint32 num_anchor_refs_l0 = 0;
- guint32 num_anchor_refs_l1 = 0;
-
- WRITE_UE (bs, num_anchor_refs_l0);
- for (j = 0; j < num_anchor_refs_l0; j++)
- WRITE_UE (bs, 0);
-
- WRITE_UE (bs, num_anchor_refs_l1);
- for (j = 0; j < num_anchor_refs_l1; j++)
- WRITE_UE (bs, 0);
- }
-
- for (i = 1; i <= num_views_minus1; i++) {
- guint32 num_non_anchor_refs_l0 = 0;
- guint32 num_non_anchor_refs_l1 = 0;
-
- WRITE_UE (bs, num_non_anchor_refs_l0);
- for (j = 0; j < num_non_anchor_refs_l0; j++)
- WRITE_UE (bs, 0);
-
- WRITE_UE (bs, num_non_anchor_refs_l1);
- for (j = 0; j < num_non_anchor_refs_l1; j++)
- WRITE_UE (bs, 0);
- }
-
- /* num level values signalled minus1 */
- num_level_values_signalled_minus1 = 0;
- g_assert (num_level_values_signalled_minus1 < 64);
- WRITE_UE (bs, num_level_values_signalled_minus1);
-
- for (i = 0; i <= num_level_values_signalled_minus1; i++) {
- guint16 num_applicable_ops_minus1 = 0;
- g_assert (num_applicable_ops_minus1 < 1024);
-
- WRITE_UINT32 (bs, seq_param->level_idc, 8);
- WRITE_UE (bs, num_applicable_ops_minus1);
-
- for (j = 0; j <= num_applicable_ops_minus1; j++) {
- guint8 temporal_id = 0;
- guint16 num_target_views_minus1 = 1;
-
- WRITE_UINT32 (bs, temporal_id, 3);
- WRITE_UE (bs, num_target_views_minus1);
-
- for (k = 0; k <= num_target_views_minus1; k++)
- WRITE_UE (bs, k);
-
- WRITE_UE (bs, num_views_minus1);
- }
- }
-
- /* mvc_vui_parameters_present_flag */
- WRITE_UINT32 (bs, 0, 1);
- }
-
- /* additional_extension2_flag */
- WRITE_UINT32 (bs, 0, 1);
-
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write subset SPS NAL unit");
- return FALSE;
- }
- return FALSE;
-}
-
-/* Write a PPS NAL unit */
-static gboolean
-bs_write_pps (GstBitWriter * bs,
- const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
-{
- guint32 num_slice_groups_minus1 = 0;
- guint32 pic_init_qs_minus26 = 0;
- guint32 redundant_pic_cnt_present_flag = 0;
-
- /* pic_parameter_set_id */
- WRITE_UE (bs, pic_param->pic_parameter_set_id);
- /* seq_parameter_set_id */
- WRITE_UE (bs, pic_param->seq_parameter_set_id);
- /* entropy_coding_mode_flag */
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
- /* pic_order_present_flag */
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1);
- /* slice_groups-1 */
- WRITE_UE (bs, num_slice_groups_minus1);
-
- if (num_slice_groups_minus1 > 0) {
- /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)");
- }
- WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1);
- WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1);
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);
- /* pic_init_qp_minus26 */
- WRITE_SE (bs, pic_param->pic_init_qp - 26);
- /* pic_init_qs_minus26 */
- WRITE_SE (bs, pic_init_qs_minus26);
- /* chroma_qp_index_offset */
- WRITE_SE (bs, pic_param->chroma_qp_index_offset);
-
- WRITE_UINT32 (bs,
- pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
- WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1);
-
- /* more_rbsp_data */
- if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
- WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
- WRITE_UINT32 (bs,
- pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
- if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
- g_assert (0 && "unsupported scaling lists");
- /* FIXME */
- /*
- for (i = 0; i <
- (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
- i++) {
- gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
- }
- */
- }
- WRITE_SE (bs, pic_param->second_chroma_qp_index_offset);
- }
-
- /* rbsp_trailing_bits */
- bs_write_trailing_bits (bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write PPS NAL unit");
- return FALSE;
- }
-}
-
-/* Write a Slice NAL unit */
-static gboolean
-bs_write_slice (GstBitWriter * bs,
- const VAEncSliceParameterBufferH264 * slice_param,
- GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture)
-{
- const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- guint32 field_pic_flag = 0;
- guint32 ref_pic_list_modification_flag_l0 = 0;
- guint32 ref_pic_list_modification_flag_l1 = 0;
- guint32 no_output_of_prior_pics_flag = 0;
- guint32 long_term_reference_flag = 0;
- guint32 adaptive_ref_pic_marking_mode_flag = 0;
-
- /* first_mb_in_slice */
- WRITE_UE (bs, slice_param->macroblock_address);
- /* slice_type */
- WRITE_UE (bs, slice_param->slice_type);
- /* pic_parameter_set_id */
- WRITE_UE (bs, slice_param->pic_parameter_set_id);
- /* frame_num */
- WRITE_UINT32 (bs, picture->frame_num,
- feipak->h264_sps.seq_fields.bits.log2_max_frame_num_minus4 + 4);
-
- /* XXX: only frames (i.e. non-interlaced) are supported for now */
- /* frame_mbs_only_flag == 0 */
-
- /* idr_pic_id */
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- WRITE_UE (bs, slice_param->idr_pic_id);
-
- /* XXX: only POC type 0 is supported */
- if (!feipak->h264_sps.seq_fields.bits.pic_order_cnt_type) {
- WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb,
- feipak->h264_sps.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
- /* bottom_field_pic_order_in_frame_present_flag is FALSE */
- if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
- WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom);
- } else if (feipak->h264_sps.seq_fields.bits.pic_order_cnt_type == 1 &&
- !feipak->h264_sps.seq_fields.bits.delta_pic_order_always_zero_flag) {
- WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]);
- if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
- WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]);
- }
- /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */
-
- /* only works for B-frames */
- if (slice_param->slice_type == GST_H264_B_SLICE)
- WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1);
-
- /* not supporting SP slices */
- if (slice_param->slice_type == 0 || slice_param->slice_type == 1) {
- WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1);
- if (slice_param->num_ref_idx_active_override_flag) {
- WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1);
- if (slice_param->slice_type == 1)
- WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1);
- }
- }
- /* XXX: not supporting custom reference picture list modifications */
- if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4))
- WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1);
- if (slice_param->slice_type == 1)
- WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1);
-
- /* we have: weighted_pred_flag == FALSE and */
- /* : weighted_bipred_idc == FALSE */
- if ((pic_param->pic_fields.bits.weighted_pred_flag &&
- (slice_param->slice_type == 0)) ||
- ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) &&
- (slice_param->slice_type == 1))) {
- /* XXXX: add pred_weight_table() */
- }
-
- /* dec_ref_pic_marking() */
- if (slice_param->slice_type == 0 || slice_param->slice_type == 2) {
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
- /* no_output_of_prior_pics_flag = 0 */
- WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1);
- /* long_term_reference_flag = 0 */
- WRITE_UINT32 (bs, long_term_reference_flag, 1);
- } else {
- /* only sliding_window reference picture marking mode is supported */
- /* adpative_ref_pic_marking_mode_flag = 0 */
- WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1);
- }
- }
-
- /* cabac_init_idc */
- if (pic_param->pic_fields.bits.entropy_coding_mode_flag &&
- slice_param->slice_type != 2)
- WRITE_UE (bs, slice_param->cabac_init_idc);
- /*slice_qp_delta */
- WRITE_SE (bs, slice_param->slice_qp_delta);
-
- /* XXX: only supporting I, P and B type slices */
- /* no sp_for_switch_flag and no slice_qs_delta */
-
- if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) {
- /* disable_deblocking_filter_idc */
- WRITE_UE (bs, slice_param->disable_deblocking_filter_idc);
- if (slice_param->disable_deblocking_filter_idc != 1) {
- WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2);
- WRITE_SE (bs, slice_param->slice_beta_offset_div2);
- }
- }
-
- /* XXX: unsupported arbitrary slice ordering (ASO) */
- /* num_slic_groups_minus1 should be zero */
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Slice NAL unit");
- return FALSE;
- }
-}
-
-static inline void
-_check_sps_pps_status (GstVaapiFEIPakH264 * feipak,
- const guint8 * nal, guint32 size)
-{
- guint8 nal_type;
- G_GNUC_UNUSED gsize ret; /* FIXME */
- gboolean has_subset_sps;
-
- g_assert (size);
-
- has_subset_sps = !feipak->is_mvc || (feipak->subset_sps_data != NULL);
- if (feipak->sps_data && feipak->pps_data && has_subset_sps)
- return;
-
- nal_type = nal[0] & 0x1F;
- switch (nal_type) {
- case GST_H264_NAL_SPS:
- feipak->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
- ret = gst_buffer_fill (feipak->sps_data, 0, nal, size);
- g_assert (ret == size);
- break;
- case GST_H264_NAL_SUBSET_SPS:
- feipak->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL);
- ret = gst_buffer_fill (feipak->subset_sps_data, 0, nal, size);
- g_assert (ret == size);
- break;
- case GST_H264_NAL_PPS:
- feipak->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
- ret = gst_buffer_fill (feipak->pps_data, 0, nal, size);
- g_assert (ret == size);
- break;
- default:
- break;
- }
-}
-
-/* Determines the largest supported profile by the underlying hardware */
-static gboolean
-ensure_hw_profile_limits (GstVaapiFEIPakH264 * feipak)
-{
- GstVaapiDisplay *const display = feipak->display;
- GArray *profiles;
- guint i, profile_idc, max_profile_idc;
-
- if (feipak->hw_max_profile_idc)
- return TRUE;
-
- profiles = gst_vaapi_display_get_encode_profiles (display);
- if (!profiles)
- return FALSE;
-
- max_profile_idc = 0;
- for (i = 0; i < profiles->len; i++) {
- const GstVaapiProfile profile =
- g_array_index (profiles, GstVaapiProfile, i);
- profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
- if (!profile_idc)
- continue;
- if (max_profile_idc < profile_idc)
- max_profile_idc = profile_idc;
- }
- g_array_unref (profiles);
-
- feipak->hw_max_profile_idc = max_profile_idc;
- return TRUE;
-}
-
-/* Fills in VA HRD parameters */
-static void
-fill_hrd_params (GstVaapiFEIPakH264 * feipak, VAEncMiscParameterHRD * hrd)
-{
- hrd->buffer_size = 0;
- hrd->initial_buffer_fullness = 0;
-}
-
-/* Adds the supplied sequence header (SPS) to the list of packed
- headers to pass down as-is to the feipak */
-static gboolean
-add_packed_sequence_header (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
-{
- GstVaapiEncPackedHeader *packed_seq;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
- const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
- GstVaapiProfile profile = feipak->profile;
-
- VAEncMiscParameterHRD hrd_params;
- guint32 data_bit_size;
- guint8 *data;
-
- fill_hrd_params (feipak, &hrd_params);
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS);
- /* Set High profile for encoding the MVC base view. Otherwise, some
- traditional decoder cannot recognize MVC profile streams with
- only the base view in there */
- if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
- profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH)
- profile = GST_VAAPI_PROFILE_H264_HIGH;
-
- bs_write_sps (feipak, &bs, seq_param, profile, &hrd_params);
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_seq_param.type = VAEncPackedHeaderSequence;
- packed_seq_param.bit_length = data_bit_size;
- packed_seq_param.has_emulation_bytes = 0;
-
- packed_seq =
- gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder),
- &packed_seq_param, sizeof (packed_seq_param), data,
- (data_bit_size + 7) / 8);
- g_assert (packed_seq);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
- gst_vaapi_codec_object_replace (&packed_seq, NULL);
-
- /* store sps data */
- _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SPS NAL unit");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-static gboolean
-add_packed_sequence_header_mvc (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
-{
- GstVaapiEncPackedHeader *packed_seq;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
- const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
- VAEncMiscParameterHRD hrd_params;
- guint32 data_bit_size;
- guint8 *data;
-
- fill_hrd_params (feipak, &hrd_params);
-
- /* non-base layer, pack one subset sps */
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS);
-
- bs_write_subset_sps (feipak, &bs, seq_param, feipak->profile,
- feipak->num_views, feipak->view_ids, &hrd_params);
-
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_header_param_buffer.type = VAEncPackedHeaderSequence;
- packed_header_param_buffer.bit_length = data_bit_size;
- packed_header_param_buffer.has_emulation_bytes = 0;
-
- packed_seq =
- gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder),
- &packed_header_param_buffer, sizeof (packed_header_param_buffer), data,
- (data_bit_size + 7) / 8);
- g_assert (packed_seq);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
- gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL);
-
- /* store subset sps data */
- _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write SPS NAL unit");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-/* Adds the supplied picture header (PPS) to the list of packed
- headers to pass down as-is to the feipak */
-static gboolean
-add_packed_picture_header (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture)
-{
- GstVaapiEncPackedHeader *packed_pic;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
- const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- guint32 data_bit_size;
- guint8 *data;
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
- bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS);
- bs_write_pps (&bs, pic_param, feipak->profile);
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_pic_param.type = VAEncPackedHeaderPicture;
- packed_pic_param.bit_length = data_bit_size;
- packed_pic_param.has_emulation_bytes = 0;
-
- packed_pic =
- gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder),
- &packed_pic_param, sizeof (packed_pic_param), data,
- (data_bit_size + 7) / 8);
- g_assert (packed_pic);
-
- gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
- gst_vaapi_codec_object_replace (&packed_pic, NULL);
-
- /* store pps data */
- _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4);
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write PPS NAL unit");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-static gboolean
-get_nal_hdr_attributes (GstVaapiEncPicture * picture,
- guint8 * nal_ref_idc, guint8 * nal_unit_type)
-{
- switch (picture->type) {
- case GST_VAAPI_PICTURE_TYPE_I:
- *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH;
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
- *nal_unit_type = GST_H264_NAL_SLICE_IDR;
- else
- *nal_unit_type = GST_H264_NAL_SLICE;
- break;
- case GST_VAAPI_PICTURE_TYPE_P:
- *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM;
- *nal_unit_type = GST_H264_NAL_SLICE;
- break;
- case GST_VAAPI_PICTURE_TYPE_B:
- *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE;
- *nal_unit_type = GST_H264_NAL_SLICE;
- break;
- default:
- return FALSE;
- }
- return TRUE;
-}
-
-/* Adds the supplied prefix nal header to the list of packed
- headers to pass down as-is to the feipak */
-static gboolean
-add_packed_prefix_nal_header (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
-{
- GstVaapiEncPackedHeader *packed_prefix_nal;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 };
- guint32 data_bit_size;
- guint8 *data;
- guint8 nal_ref_idc, nal_unit_type;
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
-
- if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
- goto bs_error;
- nal_unit_type = GST_H264_NAL_PREFIX_UNIT;
-
- bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
- bs_write_nal_header_mvc_extension (&bs, picture, feipak->view_idx);
- g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_prefix_nal_param.type = VAEncPackedHeaderRawData;
- packed_prefix_nal_param.bit_length = data_bit_size;
- packed_prefix_nal_param.has_emulation_bytes = 0;
-
- packed_prefix_nal =
- gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder),
- &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data,
- (data_bit_size + 7) / 8);
- g_assert (packed_prefix_nal);
-
- gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal);
- gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL);
-
- gst_bit_writer_reset (&bs);
-
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Prefix NAL unit header");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-/* Adds the supplied slice header to the list of packed
- headers to pass down as-is to the feipak */
-static gboolean
-add_packed_slice_header (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
-{
- GstVaapiEncPackedHeader *packed_slice;
- GstBitWriter bs;
- VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 };
- const VAEncSliceParameterBufferH264 *const slice_param = slice->param;
- guint32 data_bit_size;
- guint8 *data;
- guint8 nal_ref_idc, nal_unit_type;
-
- gst_bit_writer_init_with_size (&bs, 128, FALSE);
- WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
-
- if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
- goto bs_error;
- /* pack nal_unit_header_mvc_extension() for the non base view */
- if (feipak->is_mvc && feipak->view_idx) {
- bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT);
- bs_write_nal_header_mvc_extension (&bs, picture,
- feipak->view_ids[feipak->view_idx]);
- } else
- bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
-
- bs_write_slice (&bs, slice_param, feipak, picture);
- data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
- data = GST_BIT_WRITER_DATA (&bs);
-
- packed_slice_param.type = VAEncPackedHeaderSlice;
- packed_slice_param.bit_length = data_bit_size;
- packed_slice_param.has_emulation_bytes = 0;
-
- packed_slice =
- gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder),
- &packed_slice_param, sizeof (packed_slice_param), data,
- (data_bit_size + 7) / 8);
- g_assert (packed_slice);
-
- gst_vaapi_enc_slice_add_packed_header (slice, packed_slice);
- gst_vaapi_codec_object_replace (&packed_slice, NULL);
-
- gst_bit_writer_reset (&bs);
- return TRUE;
-
- /* ERRORS */
-bs_error:
- {
- GST_WARNING ("failed to write Slice NAL unit header");
- gst_bit_writer_reset (&bs);
- return FALSE;
- }
-}
-
-/* Reference picture management */
-static void
-reference_pic_free (GstVaapiFEIPakH264 * feipak, GstVaapiFEIPakH264Ref * ref)
-{
- if (!ref)
- return;
- if (ref->pic)
- gst_vaapi_surface_proxy_unref (ref->pic);
- g_slice_free (GstVaapiFEIPakH264Ref, ref);
-}
-
-static inline GstVaapiFEIPakH264Ref *
-reference_pic_create (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
-{
- GstVaapiFEIPakH264Ref *const ref = g_slice_new0 (GstVaapiFEIPakH264Ref);
-
- ref->pic = surface;
- ref->frame_num = picture->frame_num;
- ref->poc = picture->poc;
- return ref;
-}
-
-static gboolean
-reference_list_update (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
-{
- GstVaapiFEIPakH264Ref *ref;
- GstVaapiH264FEIPakViewRefPool *const ref_pool =
- &feipak->ref_pools[feipak->view_idx];
-
- if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
- gst_vaapi_surface_proxy_unref (surface);
- return TRUE;
- }
- if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
- while (!g_queue_is_empty (&ref_pool->ref_list))
- reference_pic_free (feipak, g_queue_pop_head (&ref_pool->ref_list));
- } else if (g_queue_get_length (&ref_pool->ref_list) >=
- ref_pool->max_ref_frames) {
- reference_pic_free (feipak, g_queue_pop_head (&ref_pool->ref_list));
- }
- ref = reference_pic_create (feipak, picture, surface);
- g_queue_push_tail (&ref_pool->ref_list, ref);
- g_assert (g_queue_get_length (&ref_pool->ref_list) <=
- ref_pool->max_ref_frames);
- return TRUE;
-}
-
-static gboolean
-reference_list_init (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture,
- GstVaapiFEIPakH264Ref ** reflist_0,
- guint * reflist_0_count,
- GstVaapiFEIPakH264Ref ** reflist_1, guint * reflist_1_count)
-{
- GstVaapiFEIPakH264Ref *tmp;
- GstVaapiH264FEIPakViewRefPool *const ref_pool =
- &feipak->ref_pools[feipak->view_idx];
- GList *iter, *list_0_start = NULL, *list_1_start = NULL;
- guint count;
-
- *reflist_0_count = 0;
- *reflist_1_count = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
- return TRUE;
-
- iter = g_queue_peek_tail_link (&ref_pool->ref_list);
- for (; iter; iter = g_list_previous (iter)) {
- tmp = (GstVaapiFEIPakH264Ref *) iter->data;
- g_assert (tmp && tmp->poc != picture->poc);
- if (_poc_greater_than (picture->poc, tmp->poc,
- 1 << (feipak->h264_sps.seq_fields.bits.
- log2_max_pic_order_cnt_lsb_minus4 + 4))) {
- list_0_start = iter;
- list_1_start = g_list_next (iter);
- break;
- }
- }
-
- /* order reflist_0 */
- g_assert (list_0_start);
- iter = list_0_start;
- count = 0;
- for (; iter; iter = g_list_previous (iter)) {
- reflist_0[count] = (GstVaapiFEIPakH264Ref *) iter->data;
- ++count;
- }
- *reflist_0_count = count;
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
- return TRUE;
-
- /* order reflist_1 */
- count = 0;
- iter = list_1_start;
- for (; iter; iter = g_list_next (iter)) {
- reflist_1[count] = (GstVaapiFEIPakH264Ref *) iter->data;
- ++count;
- }
- *reflist_1_count = count;
- return TRUE;
-}
-
-/* Fills in VA sequence parameter buffer */
-static gboolean
-fill_sequence (GstVaapiFEIPakH264 * feipak, GstVaapiEncSequence * sequence)
-{
- VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
-
- memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
- *seq_param = feipak->h264_sps;
- return TRUE;
-}
-
-/* Fills in VA picture parameter buffer */
-static gboolean
-fill_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture,
- GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
-{
- VAEncPictureParameterBufferH264 *const pic_param = picture->param;
- GstVaapiH264FEIPakViewRefPool *const ref_pool =
- &feipak->ref_pools[feipak->view_idx];
- GstVaapiFEIPakH264Ref *ref_pic;
- GList *reflist;
- guint i;
-
- memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
- *pic_param = feipak->h264_pps;
- feipak->is_idr = feipak->h264_pps.pic_fields.bits.idr_pic_flag;
- /* reference list, */
- pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
- pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
- pic_param->CurrPic.frame_idx = picture->frame_num;
- i = 0;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
- for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
- reflist; reflist = g_list_next (reflist)) {
- ref_pic = reflist->data;
- g_assert (ref_pic && ref_pic->pic &&
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
-
- pic_param->ReferenceFrames[i].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
- pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc;
- pic_param->ReferenceFrames[i].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num;
- ++i;
- }
- g_assert (i <= 16 && i <= ref_pool->max_ref_frames);
- }
- for (; i < 16; ++i) {
- pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
- pic_param->ReferenceFrames[i].frame_idx = VA_PICTURE_H264_INVALID;
- }
- pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
-
- return TRUE;
-}
-
-/* Adds slice headers to picture */
-static gboolean
-add_slice_headers (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture,
- GstVaapiFEIPakH264Ref ** reflist_0, guint reflist_0_count,
- GstVaapiFEIPakH264Ref ** reflist_1, guint reflist_1_count)
-{
- VAEncSliceParameterBufferH264 *slice_param;
- GstVaapiEncSlice *slice;
- guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
- guint mb_size;
- guint last_mb_index;
- guint i_slice, i_ref;
- GArray *h264_slice_params = feipak->h264_slice_params;
-
- g_assert (picture);
-
- mb_size = feipak->mb_width * feipak->mb_height;
-
- g_assert (feipak->num_slices && feipak->num_slices < mb_size);
- slice_of_mbs = mb_size / feipak->num_slices;
- slice_mod_mbs = mb_size % feipak->num_slices;
- last_mb_index = 0;
- for (i_slice = 0; i_slice < feipak->num_slices; ++i_slice) {
- cur_slice_mbs = slice_of_mbs;
- if (slice_mod_mbs) {
- ++cur_slice_mbs;
- --slice_mod_mbs;
- }
- slice = GST_VAAPI_ENC_SLICE_NEW (H264, feipak->encoder);
- g_assert (slice && slice->param_id != VA_INVALID_ID);
- slice_param = slice->param;
-
- memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
- *slice_param =
- g_array_index (h264_slice_params, VAEncSliceParameterBufferH264,
- i_slice);
- g_assert ((gint8) slice_param->slice_type != -1);
- g_assert (slice_param->num_ref_idx_l0_active_minus1 >= 0);
- g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
-
- i_ref = 0;
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
- for (; i_ref < reflist_0_count; ++i_ref) {
- slice_param->RefPicList0[i_ref].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
- slice_param->RefPicList0[i_ref].TopFieldOrderCnt =
- reflist_0[i_ref]->poc;
- slice_param->RefPicList0[i_ref].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num;
- }
- g_assert (i_ref >= 1);
- }
- for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
- slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
- slice_param->RefPicList0[i_ref].frame_idx = VA_PICTURE_H264_INVALID;
- }
-
- i_ref = 0;
- if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
- for (; i_ref < reflist_1_count; ++i_ref) {
- slice_param->RefPicList1[i_ref].picture_id =
- GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
- slice_param->RefPicList1[i_ref].TopFieldOrderCnt =
- reflist_1[i_ref]->poc;
- slice_param->RefPicList1[i_ref].flags |=
- VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num;
- }
- g_assert (i_ref == 1);
- }
- for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
- slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
- slice_param->RefPicList1[i_ref].frame_idx = VA_PICTURE_H264_INVALID;
- }
-
- /* set calculation for next slice */
- last_mb_index += cur_slice_mbs;
-
- /* add packed Prefix NAL unit before each Coded slice NAL in base view */
- if (feipak->is_mvc && !feipak->view_idx
- && !add_packed_prefix_nal_header (feipak, picture, slice))
- goto error_create_packed_prefix_nal_hdr;
- if (!add_packed_slice_header (feipak, picture, slice))
- goto error_create_packed_slice_hdr;
-
- gst_vaapi_enc_picture_add_slice (picture, slice);
- gst_vaapi_codec_object_replace (&slice, NULL);
- }
- g_assert (last_mb_index == mb_size);
- return TRUE;
-
-error_create_packed_slice_hdr:
- {
- GST_ERROR ("failed to create packed slice header buffer");
- gst_vaapi_codec_object_replace (&slice, NULL);
- return FALSE;
- }
-error_create_packed_prefix_nal_hdr:
- {
- GST_ERROR ("failed to create packed prefix nal header buffer");
- gst_vaapi_codec_object_replace (&slice, NULL);
- return FALSE;
- }
-}
-
-/* Generates and submits SPS header accordingly into the bitstream */
-static gboolean
-ensure_sequence (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture)
-{
- GstVaapiEncSequence *sequence = NULL;
-
- if (!feipak->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I)
- return TRUE;
-
- sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, feipak->encoder);
- if (!sequence || !fill_sequence (feipak, sequence))
- goto error_create_seq_param;
-
- /* add subset sps for non-base view and sps for base view */
- if (feipak->is_mvc && feipak->view_idx) {
- if (!add_packed_sequence_header_mvc (feipak, picture, sequence))
- goto error_create_packed_seq_hdr;
- } else {
- if (!add_packed_sequence_header (feipak, picture, sequence))
- goto error_create_packed_seq_hdr;
- }
-
- if (sequence) {
- gst_vaapi_enc_picture_set_sequence (picture, sequence);
- gst_vaapi_codec_object_replace (&sequence, NULL);
- }
-
- if (!feipak->is_mvc || feipak->view_idx > 0)
- feipak->config_changed = FALSE;
- return TRUE;
-
- /* ERRORS */
-error_create_seq_param:
- {
- GST_ERROR ("failed to create sequence parameter buffer (SPS)");
- gst_vaapi_codec_object_replace (&sequence, NULL);
- return FALSE;
- }
-error_create_packed_seq_hdr:
- {
- GST_ERROR ("failed to create packed sequence header buffer");
- gst_vaapi_codec_object_replace (&sequence, NULL);
- return FALSE;
- }
-}
-
-/* Generates additional fei control parameters */
-static gboolean
-ensure_fei_misc_params (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy)
-{
- GstVaapiEncMiscParam *misc = NULL;
- VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param;
-
- /*fei pic control params */
- misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, feipak->encoder);
- g_assert (misc);
- if (!misc)
- return FALSE;
-
- misc_fei_pic_control_param = misc->data;
- misc_fei_pic_control_param->function = VA_FEI_FUNCTION_PAK;
- misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID;
- misc_fei_pic_control_param->qp = VA_INVALID_ID;
- misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID;
-
- g_assert (codedbuf_proxy->mbcode != NULL);
- g_assert (codedbuf_proxy->mv != NULL);
-
- misc_fei_pic_control_param->mb_code_data =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id;
- misc_fei_pic_control_param->mv_data =
- GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id;
-
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
- return TRUE;
-}
-
-/* Generates additional control parameters */
-static gboolean
-ensure_misc_params (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture)
-{
- GstVaapiEncMiscParam *misc = NULL;
-
- /* HRD params */
- misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, feipak->encoder);
- g_assert (misc);
- if (!misc)
- return FALSE;
- fill_hrd_params (feipak, misc->data);
- gst_vaapi_enc_picture_add_misc_param (picture, misc);
- gst_vaapi_codec_object_replace (&misc, NULL);
-
- return TRUE;
-}
-
-/* Generates and submits PPS header accordingly into the bitstream */
-static gboolean
-ensure_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture,
- GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
-{
- GstVaapiCodedBuffer *const codedbuf =
- GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
- gboolean res = FALSE;
- res = fill_picture (feipak, picture, codedbuf, surface);
-
- if (!res)
- return FALSE;
-
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I
- && !add_packed_picture_header (feipak, picture)) {
- GST_ERROR ("set picture packed header failed");
- return FALSE;
- }
- return TRUE;
-}
-
-/* Generates slice headers */
-static gboolean
-ensure_slices (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture)
-{
- GstVaapiFEIPakH264Ref *reflist_0[16];
- GstVaapiFEIPakH264Ref *reflist_1[16];
- GstVaapiH264FEIPakViewRefPool *const ref_pool =
- &feipak->ref_pools[feipak->view_idx];
- guint reflist_0_count = 0, reflist_1_count = 0;
-
- g_assert (picture);
-
- if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
- !reference_list_init (feipak, picture,
- reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
- GST_ERROR ("reference list reorder failed");
- return FALSE;
- }
-
- g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
- if (reflist_0_count > ref_pool->max_reflist0_count)
- reflist_0_count = ref_pool->max_reflist0_count;
- if (reflist_1_count > ref_pool->max_reflist1_count)
- reflist_1_count = ref_pool->max_reflist1_count;
-
- if (!add_slice_headers (feipak, picture,
- reflist_0, reflist_0_count, reflist_1, reflist_1_count))
- return FALSE;
-
- return TRUE;
-}
-
-/* Constructs profile and level information based on user-defined limits */
-static GstVaapiEncoderStatus
-ensure_profile_and_level (GstVaapiFEIPakH264 * feipak)
-{
- const GstVaapiProfile profile = feipak->profile;
-
- /* Check HW constraints */
- if (!ensure_hw_profile_limits (feipak))
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
- if (feipak->profile_idc > feipak->hw_max_profile_idc)
- return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
-
- if (feipak->profile != profile) {
- feipak->config_changed = TRUE;
- }
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static void
-reset_properties (GstVaapiFEIPakH264 * feipak)
-{
- guint i;
- guint max_reflist0_count;
- if (feipak->num_bframes > 0) {
- if (feipak->num_ref_frames == 1) {
- GST_INFO ("num ref frames is modified as 2 as b frame is set");
- feipak->num_ref_frames = 2;
- }
- max_reflist0_count = feipak->num_ref_frames - 1;
- } else {
- max_reflist0_count = feipak->num_ref_frames;
- }
- max_reflist0_count = max_reflist0_count > 5 ? 5 : max_reflist0_count;
-
- for (i = 0; i < feipak->num_views; i++) {
- GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i];
-
- ref_pool->max_reflist0_count = max_reflist0_count;
- ref_pool->max_reflist1_count = feipak->num_bframes > 0;
- ref_pool->max_ref_frames = ref_pool->max_reflist0_count
- + ref_pool->max_reflist1_count;
-
- }
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_encode (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf,
- GstVaapiSurfaceProxy * surface, GstVaapiFeiInfoToPakH264 * info_to_pak)
-{
- GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
- GstVaapiSurfaceProxy *reconstruct = surface;
- GstVaapiSurfaceProxy *proxy = picture->proxy;
- VAEncSliceParameterBufferH264 slice_header;
-
- g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
- g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (proxy));
-
- g_assert (info_to_pak != NULL);
-
- feipak->h264_sps = info_to_pak->h264_enc_sps;
- feipak->h264_pps = info_to_pak->h264_enc_pps;
- feipak->h264_slice_params = info_to_pak->h264_slice_headers;
-
- feipak->mb_width = feipak->h264_sps.picture_width_in_mbs;
- feipak->mb_height = feipak->h264_sps.picture_height_in_mbs;
-
- slice_header =
- g_array_index (feipak->h264_slice_params, VAEncSliceParameterBufferH264,
- 0);
- feipak->slice_type = slice_header.slice_type;
-
- if (!ensure_sequence (feipak, picture))
- goto error;
- if (!ensure_misc_params (feipak, picture))
- goto error;
- if (!ensure_fei_misc_params (feipak, picture, codedbuf))
- goto error;
- if (!ensure_picture (feipak, picture, codedbuf, reconstruct))
- goto error;
- if (!ensure_slices (feipak, picture))
- goto error;
- if (!gst_vaapi_enc_picture_encode (picture))
- goto error;
-
- if (!reference_list_update (feipak, picture, reconstruct))
- goto error;
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-error:
- return ret;
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_flush (GstVaapiFEIPakH264 * feipak)
-{
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_reconfigure (GstVaapiFEIPakH264 * feipak,
- VAContextID va_context, GstVaapiProfile profile,
- guint8 profile_idc, guint mb_width, guint mb_height,
- guint32 num_views, guint slices_num, guint32 num_ref_frames)
-{
- GstVaapiEncoderStatus status;
-
- if (mb_width != feipak->mb_width || mb_height != feipak->mb_height) {
- feipak->mb_width = mb_width;
- feipak->mb_height = mb_height;
- feipak->config_changed = TRUE;
- }
-
- feipak->va_context = va_context;
-
- /* Take number of MVC views from input caps if provided */
- feipak->num_views = num_views;
-
- feipak->is_mvc = feipak->num_views > 1;
-
- feipak->profile_idc = profile_idc;
- feipak->profile = profile;
- feipak->num_slices = slices_num;
- feipak->num_ref_frames = num_ref_frames;
-
- status = ensure_profile_and_level (feipak);
- if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
- return status;
-
- reset_properties (feipak);
-
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static gboolean
-gst_vaapi_feipak_h264_init (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncoder * encoder, GstVaapiDisplay * display,
- VAContextID va_context)
-{
- guint32 i;
-
- feipak->encoder = encoder;
- /* Default encoding entrypoint */
- feipak->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI;
-
- feipak->h264_slice_params = NULL;
-
- /* Multi-view coding information */
- feipak->is_mvc = FALSE;
- feipak->num_views = 1;
- feipak->view_idx = 0;
- feipak->display = display;
- feipak->va_context = va_context;
-
- feipak->num_bframes = 0;
- feipak->is_idr = FALSE;
- /* default num ref frames */
- feipak->num_ref_frames = 1;
- memset (feipak->view_ids, 0, sizeof (feipak->view_ids));
-
- feipak->props_reconfigured = FALSE;
-
- /* reference list info initialize */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i];
- g_queue_init (&ref_pool->ref_list);
- ref_pool->max_ref_frames = 0;
- ref_pool->max_reflist0_count = 1;
- ref_pool->max_reflist1_count = 1;
- }
-
- return TRUE;
-}
-
-static void
-gst_vaapi_feipak_h264_finalize (GstVaapiFEIPakH264 * feipak)
-{
- GstVaapiFEIPakH264Ref *ref;
- guint32 i;
-
- gst_buffer_replace (&feipak->sps_data, NULL);
- gst_buffer_replace (&feipak->subset_sps_data, NULL);
- gst_buffer_replace (&feipak->pps_data, NULL);
-
- /* reference list info de-init */
- for (i = 0; i < MAX_NUM_VIEWS; i++) {
- GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i];
- while (!g_queue_is_empty (&ref_pool->ref_list)) {
- ref = (GstVaapiFEIPakH264Ref *) g_queue_pop_head (&ref_pool->ref_list);
- reference_pic_free (feipak, ref);
- }
- g_queue_clear (&ref_pool->ref_list);
- }
-
-}
-
-static void
-set_view_ids (GstVaapiFEIPakH264 * feipak, const GValue * value)
-{
- guint i, j;
- guint len = gst_value_array_get_size (value);
-
- if (len == 0)
- goto set_default_ids;
-
- if (len != feipak->num_views) {
- GST_WARNING ("The view number is %d, but %d view IDs are provided. Just "
- "fallback to use default view IDs.", feipak->num_views, len);
- goto set_default_ids;
- }
-
- for (i = 0; i < len; i++) {
- const GValue *val = gst_value_array_get_value (value, i);
- feipak->view_ids[i] = g_value_get_uint (val);
- }
-
- /* check whether duplicated ID */
- for (i = 0; i < len; i++) {
- for (j = i + 1; j < len; j++) {
- if (feipak->view_ids[i] == feipak->view_ids[j]) {
- GST_WARNING ("The view %d and view %d have same view ID %d. Just "
- "fallback to use default view IDs.", i, j, feipak->view_ids[i]);
- goto set_default_ids;
- }
- }
- }
-
- return;
-
-set_default_ids:
- {
- for (i = 0; i < feipak->num_views; i++)
- feipak->view_ids[i] = i;
- }
-}
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak,
- gint prop_id, const GValue * value)
-{
-
- switch (prop_id) {
- case GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES:
- feipak->num_bframes = g_value_get_uint (value);
- break;
- case GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS:
- feipak->num_views = g_value_get_uint (value);
- break;
- case GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS:
- set_view_ids (feipak, value);
- break;
- default:
- return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
- }
- return GST_VAAPI_ENCODER_STATUS_SUCCESS;
-}
-
-static inline const GstVaapiMiniObjectClass *
-gst_vaapi_feipak_h264_class (void)
-{
- static const GstVaapiMiniObjectClass GstVaapiFEIPakH264Class = {
- .size = sizeof (GstVaapiFEIPakH264),
- .finalize = (GDestroyNotify) gst_vaapi_feipak_h264_finalize
- };
- return &GstVaapiFEIPakH264Class;
-}
-
-/**
- * gst_vaapi_feipak_h264_new:
- * @display: a #GstVaapiDisplay
- *
- * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
- * only supported output stream format is "byte-stream" format.
- *
- * Return value: the newly allocated #GstVaapiEncoder object
- */
-GstVaapiFEIPakH264 *
-gst_vaapi_feipak_h264_new (GstVaapiEncoder * encoder, GstVaapiDisplay * display,
- VAContextID va_context)
-{
- GstVaapiFEIPakH264 *feipak;
-
- feipak = (GstVaapiFEIPakH264 *)
- gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS
- (gst_vaapi_feipak_h264_class ()));
- if (!feipak)
- return NULL;
-
- if (!gst_vaapi_feipak_h264_init (feipak, encoder, display, va_context))
- goto error;
- return feipak;
-
-error:
- gst_vaapi_object_unref (feipak);
- return NULL;
-}
-
-gboolean
-gst_vaapi_feipak_h264_get_ref_pool (GstVaapiFEIPakH264 * feipak,
- gpointer * ref_pool_ptr)
-{
- g_return_val_if_fail (feipak != NULL, FALSE);
- if (!(&feipak->ref_pools[0]))
- return FALSE;
-
- if (ref_pool_ptr)
- *ref_pool_ptr = (gpointer) (&feipak->ref_pools[0]);
-
- return TRUE;
-}
diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.h b/gst-libs/gst/vaapi/gstvaapifeipak_h264.h
deleted file mode 100644
index f257becc..00000000
--- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * gstvaapifeipak_h264.h - H.264 FEI PAK
- *
- * Copyright (C) 2016-2018 Intel Corporation
- * Author: Chen Xiaomin <xiaomin.chen@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_FEIPAK_H264_H
-#define GST_VAAPI_FEIPAK_H264_H
-
-#include <gst/vaapi/gstvaapiencoder.h>
-#include <gst/vaapi/gstvaapiutils_h264.h>
-#include <gst/vaapi/gstvaapifeiutils_h264.h>
-#include <gst/vaapi/gstvaapifei_objects_priv.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GstVaapiFEIPakH264 GstVaapiFEIPakH264;
-
-/**
- * GstVaapiEncoderH264Prop:
- * @GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES: Number of B-frames between I
- * and P (uint).
- * @GST_VAAPI_FEIPAK_H264_PROP_INIT_QP: Initial quantizer value (uint).
- * @GST_VAAPI_FEIPAK_H264_PROP_MIN_QP: Minimal quantizer value (uint).
- * @GST_VAAPI_FEIPAK_H264_PROP_NUM_SLICES: Number of slices per frame (uint).
- * @GST_VAAPI_FEIPAK_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool).
- * @GST_VAAPI_FEIPAK_H264_PROP_DCT8X8: Enable adaptive use of 8x8
- * transforms in I-frames (bool).
- * @GST_VAAPI_FEIPAK_H264_PROP_CPB_LENGTH: Length of the CPB buffer
- * in milliseconds (uint).
- * @GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS: Number of views per frame.
- * @GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS: View IDs
- *
- * The set of H.264 feipak specific configurable properties.
- */
-typedef enum
-{
- GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES = -1,
- GST_VAAPI_FEIPAK_H264_PROP_INIT_QP = -2,
- GST_VAAPI_FEIPAK_H264_PROP_MIN_QP = -3,
- GST_VAAPI_FEIPAK_H264_PROP_NUM_SLICES = -4,
- GST_VAAPI_FEIPAK_H264_PROP_CABAC = -5,
- GST_VAAPI_FEIPAK_H264_PROP_DCT8X8 = -6,
- GST_VAAPI_FEIPAK_H264_PROP_CPB_LENGTH = -7,
- GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS = -8,
- GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS = -9,
- GST_VAAPI_FEIPAK_H264_PROP_NUM_REF = -10,
-} GstVaapiFEIPakH264Prop;
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_reconfigure (GstVaapiFEIPakH264 * feipak,
- VAContextID va_context, GstVaapiProfile profile, guint8 profile_idc,
- guint mb_width, guint mb_height, guint32 num_views, guint slices_num,
- guint32 num_ref_frames);
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_encode (GstVaapiFEIPakH264 * feipak,
- GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf,
- GstVaapiSurfaceProxy * surface, GstVaapiFeiInfoToPakH264 *info_to_pak);
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_flush (GstVaapiFEIPakH264 * feipak);
-
-GstVaapiFEIPakH264 *gst_vaapi_feipak_h264_new (GstVaapiEncoder * encoder,
- GstVaapiDisplay * display, VAContextID va_context);
-
-GstVaapiEncoderStatus
-gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak,
- gint prop_id, const GValue * value);
-
-gboolean
-gst_vaapi_feipak_h264_get_ref_pool (GstVaapiFEIPakH264 * feipak,
- gpointer * ref_pool_ptr);
-
-G_END_DECLS
-
-#endif /*GST_VAAPI_FEIPAK_H264_H */
diff --git a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c
deleted file mode 100644
index 38411a72..00000000
--- a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * gstvaapifeiutils_h264_fei.c - Fei related utilities for H264
- *
- * Copyright (C) 2016-2018 Intel Corporation
- * Author: Wang, Yi <yi.a.wang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-#include "sysdeps.h"
-#include <gst/codecparsers/gsth264parser.h>
-
-#include "gstvaapifeiutils_h264.h"
-
-/* FeiFixme: This is common fei modes for all codecs,
- * move to a generic header file */
-/* --- GstVaapiFeiMode --- */
-GType
-gst_vaapi_fei_mode_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GFlagsValue encoding_mode_values[] = {
- {GST_VAAPI_FEI_MODE_ENC,
- "ENC Mode", "ENC"},
- {GST_VAAPI_FEI_MODE_PAK,
- "PAK Mode", "PAK"},
- {GST_VAAPI_FEI_MODE_ENC_PAK,
- "ENC_PAK Mode", "ENC_PAK"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type =
- g_flags_register_static ("GstVaapiFeiMode", encoding_mode_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-/* --- GstVaapiFeiH264SearchPath --- */
-GType
-gst_vaapi_fei_h264_search_path_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GEnumValue search_path_values[] = {
- {GST_VAAPI_FEI_H264_FULL_SEARCH_PATH,
- "full search path", "full"},
- {GST_VAAPI_FEI_H264_DIAMOND_SEARCH_PATH,
- "diamond search path", "diamond"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type = g_enum_register_static ("GstVaapiFeiH264SearchPath",
- search_path_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-/* --- GstVaapiFeiH264SearchWindow --- */
-GType
-gst_vaapi_fei_h264_search_window_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GEnumValue search_window_values[] = {
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE,
- "not use predefined search window", "none"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_TINY,
- "4 SUs 24x24 window diamond search", "tiny"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_SMALL,
- "9 SUs 28x28 window diamond search", "small"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_DIAMOND,
- "16 SUs 48x40 window diamond search", "diamond"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_LARGE_DIAMOND,
- "32 SUs 48x40 window diamond search", "large diamond"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_EXHAUSTIVE,
- "48 SUs 48x40 window full search", "exhaustive"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_DIAMOND,
- "16 SUs 64x32 window diamond search", "horizon diamond"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_LARGE_DIAMOND,
- "32 SUs 64x32 window diamond search", "horizon large diamond"},
- {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_EXHAUSTIVE,
- "48 SUs 64x32 window full search", "horizon exhaustive"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type = g_enum_register_static ("GstVaapiFeiH264SearchWindow",
- search_window_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-/* --- GstVaapiFeiH264SubPelMode --- */
-GType
-gst_vaapi_fei_h264_sub_pel_mode_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GEnumValue sub_pel_mode_values[] = {
- {GST_VAAPI_FEI_H264_INTEGER_ME,
- "integer mode searching", "integer"},
- {GST_VAAPI_FEI_H264_HALF_ME,
- "half-pel mode searching", "half"},
- {GST_VAAPI_FEI_H264_QUARTER_ME,
- "quarter-pel mode searching", "quarter"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type = g_enum_register_static ("GstVaapiFeiH264SubPelMode",
- sub_pel_mode_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-/* --- GstVaapiFeiH264SadMode --- */
-GType
-gst_vaapi_fei_h264_sad_mode_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GEnumValue sad_mode_values[] = {
- {GST_VAAPI_FEI_H264_SAD_NONE_TRANS,
- "none transform adjusted", "none"},
- {GST_VAAPI_FEI_H264_SAD_HAAR_TRANS,
- "Haar transform adjusted", "haar"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type =
- g_enum_register_static ("GstVaapiFeiH264SadMode", sad_mode_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-/* --- GstVaapiFeiH264IntraPartMask --- */
-GType
-gst_vaapi_fei_h264_intra_part_mask_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GFlagsValue intra_part_mask_values[] = {
- {GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE,
- "enable all intra mode", "enable all"},
- {GST_VAAPI_FEI_H264_DISABLE_INTRA_16x16,
- "luma_intra_16x16 disabled", "intra16x16 disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_INTRA_8x8,
- "luma_intra_8x8 disabled", "intra8x8 disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_INTRA_4x4,
- "luma_intra_4x4 disabled", "intra4x4 disabled"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type = g_flags_register_static ("GstVaapiFeiH264IntraPartMask",
- intra_part_mask_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-/* --- GstVaapiFeiH264SubMbPartMask --- */
-GType
-gst_vaapi_fei_h264_sub_mb_part_mask_get_type (void)
-{
- static volatile gsize g_type = 0;
-
- static const GFlagsValue sub_mb_part_mask_values[] = {
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE,
- "enable all subpartitions", "enable all"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_16x16,
- "16x16 sub-macroblock disabled", "16x16 submb part disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x16x8,
- "2x(16x8) sub-macroblock within 16x16 disabled",
- "16x8 submb part disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x16,
- "2x(8x16) sub-macroblock within 16x16 disabled",
- "8x16 submb part disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_1x8x8,
- "1x(8x8) sub-partition for 4x(8x8) within 16x16 disabled",
- "8x8 submb part disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x4,
- "2x(8x4) sub-partition for 4x(8x8) within 16x16 disabled",
- "8x4 submb part disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x4x8,
- "2x(4x8) sub-partition for 4x(8x8) within 16x16 disabled",
- "4x8 submb part disabled"},
- {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_4x4x4,
- "4x(4x4) sub-partition for 4x(8x8) within 16x16 disabled",
- "4x4 submb part disabled"},
- {0, NULL, NULL},
- };
-
- if (g_once_init_enter (&g_type)) {
- GType type = g_flags_register_static ("GstVaapiFeiH264SubMbPartMask",
- sub_mb_part_mask_values);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
diff --git a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h
deleted file mode 100644
index a0eeb699..00000000
--- a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * gstvaapifeiutils_h264.h - FEI related utilities for H264
- *
- * Copyright (C) 2016-2018 Intel Corporation
- * Author: Wang, Yi <yi.a.wang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_FEI_UTILS_H264_H
-#define GST_VAAPI_FEI_UTILS_H264_H
-
-#include <va/va.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GstVaapiFeiInfoToPakH264 GstVaapiFeiInfoToPakH264;
-
-/* Structure useful for FEI ENC+PAK mode */
-struct _GstVaapiFeiInfoToPakH264
-{
- VAEncSequenceParameterBufferH264 h264_enc_sps;
- VAEncPictureParameterBufferH264 h264_enc_pps;
- GArray *h264_slice_headers;
- guint h264_slice_num;
-};
-
-/******************* Common FEI enum definition for all codecs ***********/
-/* FeiFixme: This should be a common fei mode for all codecs,
- * move to a common header file */
-#define GST_VAAPI_FEI_MODE_DEFAULT GST_VAAPI_FEI_MODE_ENC_PAK
-typedef enum
-{
- GST_VAAPI_FEI_MODE_ENC = (1 << 0),
- GST_VAAPI_FEI_MODE_PAK = (1 << 1),
- GST_VAAPI_FEI_MODE_ENC_PAK = (1 << 2)
-} GstVaapiFeiMode;
-/**
-* GST_VAAPI_TYPE_FEI_MODE:
-*
-* A type that represents the fei encoding mode.
-*
-* Return value: the #GType of GstVaapiFeiMode
-*/
-#define GST_VAAPI_TYPE_FEI_MODE (gst_vaapi_fei_mode_get_type())
-
-
-/******************* H264 Specific FEI enum definitions ***********/
-
-typedef enum
-{
- GST_VAAPI_FEI_H264_FULL_SEARCH_PATH = 0,
- GST_VAAPI_FEI_H264_DIAMOND_SEARCH_PATH,
-} GstVaapiFeiH264SearchPath;
-
-typedef enum
-{
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE = 0,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_TINY,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_SMALL,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_DIAMOND,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_LARGE_DIAMOND,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_EXHAUSTIVE,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_DIAMOND,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_LARGE_DIAMOND,
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_EXHAUSTIVE,
-} GstVaapiFeiH264SearchWindow;
-
-typedef enum
-{
- GST_VAAPI_FEI_H264_INTEGER_ME = 0,
- GST_VAAPI_FEI_H264_HALF_ME = 1,
- GST_VAAPI_FEI_H264_QUARTER_ME = 3,
-} GstVaapiFeiH264SubPelMode;
-
-typedef enum
-{
- GST_VAAPI_FEI_H264_SAD_NONE_TRANS = 0,
- GST_VAAPI_FEI_H264_SAD_HAAR_TRANS = 2,
-} GstVaapiFeiH264SadMode;
-
-typedef enum
-{
- GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE = 0,
- GST_VAAPI_FEI_H264_DISABLE_INTRA_16x16 = (1 << 0),
- GST_VAAPI_FEI_H264_DISABLE_INTRA_8x8 = (1 << 1),
- GST_VAAPI_FEI_H264_DISABLE_INTRA_4x4 = (1 << 2),
-} GstVaapiFeiH264IntraPartMask;
-
-typedef enum
-{
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE = 0,
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_16x16 = (1 << 1),
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x16x8 = (1 << 2),
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x16 = (1 << 3),
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_1x8x8 = (1 << 4),
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x4 = (1 << 5),
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x4x8 = (1 << 6),
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_4x4x4 = (1 << 7),
-} GstVaapiFeiH264SubMbPartMask;
-
-#define GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT \
- GST_VAAPI_FEI_H264_FULL_SEARCH_PATH
-#define GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT \
- GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE
-#define GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT \
- GST_VAAPI_FEI_H264_INTEGER_ME
-#define GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT \
- GST_VAAPI_FEI_H264_SAD_NONE_TRANS
-#define GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT \
- GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE
-#define GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT \
- GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE
-#define GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT 32
-#define GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT 32
-#define GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT 32
-
-/**
-* GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH:
-*
-* A type that represents the fei control param: search path.
-*
-* Return value: the #GType of GstVaapiFeiSearchPath
-*/
-#define GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH gst_vaapi_fei_h264_search_path_get_type()
-
-/**
-* GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW:
-*
-* A type that represents the fei control param: search window.
-*
-* Return value: the #GType of GstVaapiFeiSearchWindow
-*/
-#define GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW gst_vaapi_fei_h264_search_window_get_type()
-
-/**
-* GST_VAAPI_TYPE_FEI_H264_SAD_MODE:
-*
-* A type that represents the fei control param: sad mode.
-*
-* Return value: the #GType of GstVaapiFeiSadMode
-*/
-#define GST_VAAPI_TYPE_FEI_H264_SAD_MODE gst_vaapi_fei_h264_sad_mode_get_type()
-
-/**
-* GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK:
-*
-* A type that represents the fei control param: intra part mask.
-*
-* Return value: the #GType of GstVaapiFeiIntaPartMask
-*/
-#define GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK gst_vaapi_fei_h264_intra_part_mask_get_type()
-
-/**
-* GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE:
-*
-* A type that represents the fei control param: sub pel mode.
-*
-* Return value: the #GType of GstVaapiFeiSubPelMode
-*/
-#define GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE gst_vaapi_fei_h264_sub_pel_mode_get_type()
-
-/**
-* GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK:
-*
-* A type that represents the fei control param: sub maroclock partition mask.
-*
-* Return value: the #GType of GstVaapiFeiH264SubMbPartMask
-*/
-#define GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK gst_vaapi_fei_h264_sub_mb_part_mask_get_type()
-
-GType
-gst_vaapi_fei_mode_get_type (void)
- G_GNUC_CONST;
-
-GType
-gst_vaapi_fei_h264_search_path_get_type (void)
- G_GNUC_CONST;
-
-GType
-gst_vaapi_fei_h264_search_window_get_type (void)
- G_GNUC_CONST;
-
-GType
-gst_vaapi_fei_h264_sad_mode_get_type (void)
- G_GNUC_CONST;
-
-GType
-gst_vaapi_fei_h264_sub_pel_mode_get_type (void)
- G_GNUC_CONST;
-
-GType
-gst_vaapi_fei_h264_intra_part_mask_get_type (void)
- G_GNUC_CONST;
-
-GType
-gst_vaapi_fei_h264_sub_mb_part_mask_get_type (void)
- G_GNUC_CONST;
-
-G_END_DECLS
-#endif /* GST_VAAPI_UTILS_FEI_H264_H */
diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c
index 234a98b6..539ac9b3 100644
--- a/gst-libs/gst/vaapi/gstvaapiprofile.c
+++ b/gst-libs/gst/vaapi/gstvaapiprofile.c
@@ -150,9 +150,6 @@ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = {
#if VA_CHECK_VERSION(0,39,1)
{GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, VAEntrypointEncSliceLP},
#endif
-#if USE_H264_FEI_ENCODER
- {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI, VAEntrypointFEI},
-#endif
{0,}
};
diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h
index 72ffd55c..b5533ca4 100644
--- a/gst-libs/gst/vaapi/gstvaapiprofile.h
+++ b/gst-libs/gst/vaapi/gstvaapiprofile.h
@@ -196,7 +196,6 @@ typedef enum {
* @GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: Encode Picture
* @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: Encode Slice low power/
* high performace varient
- * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI: FEI Encode
*
* The set of all entrypoints for #GstVaapiEntrypoint
*/
@@ -208,7 +207,6 @@ typedef enum {
GST_VAAPI_ENTRYPOINT_SLICE_ENCODE,
GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE,
GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP,
- GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI
} GstVaapiEntrypoint;
const gchar *
diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c
index b34afed0..729efeb4 100644
--- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c
+++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c
@@ -50,27 +50,6 @@ gst_vaapi_surface_proxy_finalize (GstVaapiSurfaceProxy * proxy)
/* Notify the user function that the object is now destroyed */
if (proxy->destroy_func)
proxy->destroy_func (proxy->destroy_data);
-
-#if USE_H264_FEI_ENCODER
- if (proxy->mvpred)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mvpred, NULL);
- if (proxy->mbcntrl)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mbcntrl, NULL);
- if (proxy->qp)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->qp, NULL);
- if (proxy->mbcode)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mbcode, NULL);
- if (proxy->mv)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mv, NULL);
- if (proxy->dist)
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->dist, NULL);
-#endif
}
static inline const GstVaapiMiniObjectClass *
@@ -90,14 +69,6 @@ gst_vaapi_surface_proxy_init_properties (GstVaapiSurfaceProxy * proxy)
proxy->timestamp = GST_CLOCK_TIME_NONE;
proxy->duration = GST_CLOCK_TIME_NONE;
proxy->has_crop_rect = FALSE;
-#if USE_H264_FEI_ENCODER
- proxy->mvpred = NULL;
- proxy->mbcntrl = NULL;
- proxy->qp = NULL;
- proxy->mbcode = NULL;
- proxy->mv = NULL;
- proxy->dist = NULL;
-#endif
}
/**
@@ -221,51 +192,6 @@ gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy)
if (copy->has_crop_rect)
copy->crop_rect = proxy->crop_rect;
-#if USE_H264_FEI_ENCODER
-
- if (proxy->mv)
- copy->mv = (GstVaapiEncFeiMv *)
- gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT (proxy->mv));
- else
- copy->mv = NULL;
-
- if (proxy->mbcode)
- copy->mbcode = (GstVaapiEncFeiMbCode *)
- gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT
- (proxy->mbcode));
- else
- copy->mbcode = NULL;
-
- if (proxy->mvpred)
- copy->mvpred = (GstVaapiEncFeiMvPredictor *)
- gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT
- (proxy->mvpred));
- else
- copy->mvpred = NULL;
-
- if (proxy->qp)
- copy->qp = (GstVaapiEncFeiQp *)
- gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT (proxy->qp));
- else
- copy->qp = NULL;
-
- if (proxy->mbcntrl)
- copy->mbcntrl = (GstVaapiEncFeiMbControl *)
- gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT
- (proxy->mbcntrl));
- else
- copy->mbcntrl = NULL;
-
- if (proxy->dist)
- copy->dist = (GstVaapiEncFeiDistortion *)
- gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT
- (proxy->dist));
- else
- copy->dist = NULL;
-
-
-#endif
-
return copy;
}
@@ -479,199 +405,3 @@ gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy,
if (proxy->has_crop_rect)
proxy->crop_rect = *crop_rect;
}
-
-#if USE_H264_FEI_ENCODER
-
-/**
- * gst_vaapi_surface_proxy_get_fei_mb_code:
- * @proxy: a #GstVaapiSurfaceProxy
- *
- * Returns the #GstVaapiEncFeiMbCode stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiMbcode, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiMbCode *
-gst_vaapi_surface_proxy_get_fei_mb_code (GstVaapiSurfaceProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, NULL);
- return proxy->mbcode;
-}
-
-/**
- * gst_vaapi_surface_proxy_get_fei_mv:
- * @proxy: a #GstVaapiSurfaceProxy
- *
- * Returns the #GstVaapiEncFeiMv stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiMv, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiMv *
-gst_vaapi_surface_proxy_get_fei_mv (GstVaapiSurfaceProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, NULL);
- return proxy->mv;
-}
-
-/**
- * gst_vaapi_surface_proxy_get_fei_distortion:
- * @proxy: a #GstVaapiSurfaceProxy
- *
- * Returns the #GstVaapiEncFeiDistortion stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiDistortion, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiDistortion *
-gst_vaapi_surface_proxy_get_fei_distortion (GstVaapiSurfaceProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, NULL);
- return proxy->dist;
-}
-
-/**
- * gst_vaapi_surface_proxy_get_fei_qp:
- * @proxy: a #GstVaapiSurfaceProxy
- *
- * Returns the #GstVaapiEncFeiQp stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiQp, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiQp *
-gst_vaapi_surface_proxy_get_fei_qp (GstVaapiSurfaceProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, NULL);
- return proxy->qp;
-}
-
-/**
- * gst_vaapi_surface_proxy_get_fei_mv_predictor:
- * @proxy: a #GstVaapiSurfaceProxy
- *
- * Returns the #GstVaapiEncFeiMvPredictor stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiMvPredictor, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiMvPredictor *
-gst_vaapi_surface_proxy_get_fei_mv_predictor (GstVaapiSurfaceProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, NULL);
- return proxy->mvpred;
-}
-
-/**
- * gst_vaapi_surface_proxy_get_fei_mb_control:
- * @proxy: a #GstVaapiSurfaceProxy
- *
- * Returns the #GstVaapiEncFeiMbControl stored in the @proxy
- *
- * Return value: the #GstVaapiEncFeiMbControl, or %NULL if none was
- * associated with the surface proxy
- */
-GstVaapiEncFeiMbControl *
-gst_vaapi_surface_proxy_get_fei_mb_control (GstVaapiSurfaceProxy * proxy)
-{
- g_return_val_if_fail (proxy != NULL, NULL);
- return proxy->mbcntrl;
-}
-
-/**
- * gst_vaapi_surface_proxy_set_fei_mb_code:
- * @proxy: #GstVaapiSurfaceProxy
- * @mbcode: the #GstVaapiEncFeiMbCode to be stored in @proxy
- *
- * Associates the @mbcode with the @proxy
- */
-void
-gst_vaapi_surface_proxy_set_fei_mb_code (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMbCode * mbcode)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mbcode, (GstVaapiFeiCodecObject *) mbcode);
-}
-
-/**
- * gst_vaapi_surface_proxy_set_fei_mv:
- * @proxy: #GstVaapiSurfaceProxy
- * @mv: the #GstVaapiEncFeiMv to be stored in @proxy
- *
- * Associates the @mv with the @proxy
- */
-void
-gst_vaapi_surface_proxy_set_fei_mv (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMv * mv)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mv, (GstVaapiFeiCodecObject *) mv);
-}
-
-/**
- * gst_vaapi_surface_proxy_set_fei_distortion:
- * @proxy: #GstVaapiSurfaceProxy
- * @dist: the #GstVaapiEncFeiDistortion to be stored in @proxy
- *
- * Associates the @dist with the @proxy
- */
-void
-gst_vaapi_surface_proxy_set_fei_distortion (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiDistortion * dist)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->dist, (GstVaapiFeiCodecObject *) dist);
-}
-
-/**
- * gst_vaapi_surface_proxy_set_fei_qp:
- * @proxy: #GstVaapiSurfaceProxy
- * @qp: the #GstVaapiEncFeiQp to be stored in @proxy
- *
- * Associates the @qp with the @proxy
- */
-void
-gst_vaapi_surface_proxy_set_fei_qp (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiQp * qp)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->qp, (GstVaapiFeiCodecObject *) qp);
-}
-
-/**
- * gst_vaapi_surface_proxy_set_fei_mv_predictor:
- * @proxy: #GstVaapiSurfaceProxy
- * @mvpred: the #GstVaapiEncFeiMvPredictor to be stored in @proxy
- *
- * Associates the @mvpred with the @proxy
- */
-void
-gst_vaapi_surface_proxy_set_fei_mv_predictor (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMvPredictor * mvpred)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mvpred, (GstVaapiFeiCodecObject *) mvpred);
-}
-
-/**
- * gst_vaapi_surface_proxy_set_fei_mb_control:
- * @proxy: #GstVaapiSurfaceProxy
- * @mbcntrl: the #GstVaapiEncFeiMbControl to be stored in @proxy
- *
- * Associates the @mbcntrl with the @proxy
- */
-void
-gst_vaapi_surface_proxy_set_fei_mb_control (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMbControl * mbcntrl)
-{
- g_return_if_fail (proxy != NULL);
- gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) &
- proxy->mbcntrl, (GstVaapiFeiCodecObject *) mbcntrl);
-}
-
-#endif
diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h
index 5f6c16e5..1dc218c4 100644
--- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h
+++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h
@@ -28,10 +28,6 @@
#include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/gstvaapisurfacepool.h>
-#if USE_H264_FEI_ENCODER
-#include <gst/vaapi/gstvaapifei_objects.h>
-#endif
-
G_BEGIN_DECLS
/**
@@ -156,46 +152,6 @@ void
gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy,
const GstVaapiRectangle * crop_rect);
-#if USE_H264_FEI_ENCODER
-
-GstVaapiEncFeiMbCode *
-gst_vaapi_surface_proxy_get_fei_mb_code (GstVaapiSurfaceProxy * proxy);
-
-GstVaapiEncFeiMv *
-gst_vaapi_surface_proxy_get_fei_mv (GstVaapiSurfaceProxy * proxy);
-
-GstVaapiEncFeiDistortion *
-gst_vaapi_surface_proxy_get_fei_distortion (GstVaapiSurfaceProxy * proxy);
-
-GstVaapiEncFeiQp *
-gst_vaapi_surface_proxy_get_fei_qp (GstVaapiSurfaceProxy * proxy);
-
-GstVaapiEncFeiMvPredictor *
-gst_vaapi_surface_proxy_get_fei_mv_predictor (GstVaapiSurfaceProxy * proxy);
-
-GstVaapiEncFeiMbControl *
-gst_vaapi_surface_proxy_get_fei_mb_control (GstVaapiSurfaceProxy * proxy);
-
-void
-gst_vaapi_surface_proxy_set_fei_mb_code (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMbCode *mbcode);
-void
-gst_vaapi_surface_proxy_set_fei_mv (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMv *mv);
-void
-gst_vaapi_surface_proxy_set_fei_distortion (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiDistortion *dist);
-void
-gst_vaapi_surface_proxy_set_fei_qp (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiQp *mbcode);
-void
-gst_vaapi_surface_proxy_set_fei_mv_predictor (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMvPredictor *mvpred);
-void
-gst_vaapi_surface_proxy_set_fei_mb_control (GstVaapiSurfaceProxy * proxy,
- GstVaapiEncFeiMbControl *mbcntrl);
-#endif
-
G_END_DECLS
#endif /* GST_VAAPI_SURFACE_PROXY_H */
diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h
index e43ecbc0..76bfba89 100644
--- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h
@@ -48,15 +48,6 @@ struct _GstVaapiSurfaceProxy
gpointer destroy_data;
GstVaapiRectangle crop_rect;
guint has_crop_rect:1;
-
-#if USE_H264_FEI_ENCODER
- GstVaapiEncFeiMvPredictor *mvpred;
- GstVaapiEncFeiMbControl *mbcntrl;
- GstVaapiEncFeiQp *qp;
- GstVaapiEncFeiMbCode *mbcode;
- GstVaapiEncFeiMv *mv;
- GstVaapiEncFeiDistortion *dist;
-#endif
};
#define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS
diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build
index 83f4a1d5..2630acd6 100644
--- a/gst-libs/gst/vaapi/meson.build
+++ b/gst-libs/gst/vaapi/meson.build
@@ -112,23 +112,6 @@ if USE_VP9_ENCODER
gstlibvaapi_headers += 'gstvaapiencoder_vp9.h'
endif
-if USE_H264_FEI_ENCODER
- gstlibvaapi_sources += [
- 'gstvaapifeiutils_h264.c',
- 'gstvaapifei_objects.c',
- 'gstvaapifeienc_h264.c',
- 'gstvaapifeipak_h264.c',
- 'gstvaapiencoder_h264_fei.c',
- ]
- gstlibvaapi_headers += [
- 'gstvaapifeiutils_h264.h',
- 'gstvaapifei_objects.h',
- 'gstvaapifeienc_h264.h',
- 'gstvaapifeipak_h264.h',
- 'gstvaapiencoder_h264_fei.h',
- ]
-endif
-
if USE_DRM
gstlibvaapi_sources += [
'gstvaapidisplay_drm.c',
diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c
index 8bcf81d2..1c4efff5 100644
--- a/gst/vaapi/gstvaapi.c
+++ b/gst/vaapi/gstvaapi.c
@@ -39,11 +39,6 @@
#if USE_VP9_ENCODER
#include "gstvaapiencode_vp9.h"
#endif
-
-#if USE_H264_FEI_ENCODER
-#include "gstvaapiencode_h264_fei.h"
-#endif
-
#endif
gboolean _gst_vaapi_has_video_processing = FALSE;
@@ -179,14 +174,6 @@ gst_vaapiencode_register (GstPlugin * plugin, GstVaapiDisplay * display)
}
}
-#if USE_H264_FEI_ENCODER
- if (gst_vaapi_display_has_encoder (display,
- GST_VAAPI_PROFILE_H264_MAIN, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI)) {
- gst_element_register (plugin, "vaapih264feienc",
- GST_RANK_SECONDARY, GST_TYPE_VAAPIENCODE_H264_FEI);
- }
-#endif
-
g_array_unref (codecs);
}
#endif
diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c
index 97e8e61b..ccd33569 100644
--- a/gst/vaapi/gstvaapiencode.c
+++ b/gst/vaapi/gstvaapiencode.c
@@ -253,9 +253,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout)
GstVaapiEncoderStatus status;
GstBuffer *out_buffer;
GstFlowReturn ret;
-#if USE_H264_FEI_ENCODER
- GstVaapiFeiVideoMeta *feimeta = NULL;
-#endif
status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder,
&codedbuf_proxy, timeout);
@@ -281,14 +278,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout)
ret = klass->alloc_buffer (encode,
GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy), &out_buffer);
-#if USE_H264_FEI_ENCODER
- if (klass->save_stats_to_meta) {
- feimeta = klass->save_stats_to_meta (encode, codedbuf_proxy);
- if (feimeta != NULL)
- gst_buffer_set_vaapi_fei_video_meta (out_buffer, feimeta);
- }
-#endif
-
gst_vaapi_coded_buffer_proxy_replace (&codedbuf_proxy, NULL);
if (ret != GST_FLOW_OK)
goto error_allocate_buffer;
@@ -675,10 +664,6 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc,
GstFlowReturn ret;
GstBuffer *buf;
GstTaskState task_state;
-#if USE_H264_FEI_ENCODER
- GstVaapiFeiVideoMeta *feimeta = NULL;
- GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (venc);
-#endif
task_state = gst_pad_get_task_state (srcpad);
if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED)
@@ -703,12 +688,6 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc,
if (!proxy)
goto error_buffer_no_surface_proxy;
-#if USE_H264_FEI_ENCODER
- feimeta = gst_buffer_get_vaapi_fei_video_meta (buf);
- if (feimeta && klass->load_control_data)
- klass->load_control_data (encode, feimeta, proxy);
-#endif
-
gst_video_codec_frame_set_user_data (frame,
gst_vaapi_surface_proxy_ref (proxy),
(GDestroyNotify) gst_vaapi_surface_proxy_unref);
diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h
index 9f15f1c1..176f32e6 100644
--- a/gst/vaapi/gstvaapiencode.h
+++ b/gst/vaapi/gstvaapiencode.h
@@ -27,12 +27,6 @@
#include "gstvaapipluginbase.h"
#include <gst/vaapi/gstvaapiencoder.h>
-#if USE_H264_FEI_ENCODER
-#include <gst/vaapi/gstvaapisurface.h>
-#include <gst/vaapi/gstvaapicodedbufferproxy.h>
-#include "gstvaapifeivideometa.h"
-#endif
-
G_BEGIN_DECLS
#define GST_TYPE_VAAPIENCODE \
@@ -84,17 +78,6 @@ struct _GstVaapiEncodeClass
/* Get all possible profiles based on allowed caps */
GArray * (*get_allowed_profiles) (GstVaapiEncode * encode,
GstCaps * allowed);
-
-#if USE_H264_FEI_ENCODER
-
- gboolean (*load_control_data) (GstVaapiEncode *encoder,
- GstVaapiFeiVideoMeta *feimeta,
- GstVaapiSurfaceProxy *proxy);
-
- GstVaapiFeiVideoMeta* (*save_stats_to_meta) (GstVaapiEncode *base_encode,
- GstVaapiCodedBufferProxy *proxy);
-
-#endif
};
GType
diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c
deleted file mode 100644
index 5a998afb..00000000
--- a/gst/vaapi/gstvaapiencode_h264_fei.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * gstvaapiencode_h264_fei.c - VA-API H.264 FEI ncoder
- *
- * Copyright (C) 2016-2019 Intel Corporation
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Author: Yi A Wang <yi.a.wang@intel.com>
- *
- * 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
- */
-
-/**
- * SECTION:element-vaapih264feienc
- * @short_description: A VA-API FEI based H.264 video encoder
- *
- * Encodes raw video streams into H.264 bitstreams.
- *
- * ## Example launch line
- *
- * |[
- * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! vaapih264feienc fei-mode=ENC_PAK ! filesink location=test.264
- * ]|
- */
-
-#include "gstcompat.h"
-#include <gst/vaapi/gstvaapidisplay.h>
-#include <gst/vaapi/gstvaapiencoder_h264_fei.h>
-#include <gst/vaapi/gstvaapiutils_h264.h>
-#include <gst/vaapi/gstvaapifei_objects.h>
-#include <gst/vaapi/gstvaapifeiutils_h264.h>
-#include "gstvaapiencode_h264_fei.h"
-#include "gstvaapipluginutil.h"
-#include "gstvaapivideomemory.h"
-#include "gstvaapifeivideometa.h"
-#include <gst/vaapi/gstvaapicodedbufferproxy.h>
-
-#define GST_VAAPI_ENCODE_FLOW_MEM_ERROR GST_FLOW_CUSTOM_ERROR
-#define GST_PLUGIN_NAME "vaapih264feienc"
-#define GST_PLUGIN_DESC "A VA-API FEI based advanced H264 video encoder"
-
-GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_fei_encode_debug);
-#define GST_CAT_DEFAULT gst_vaapi_h264_fei_encode_debug
-
-#define GST_CODEC_CAPS \
- "video/x-h264, " \
- "stream-format = (string) { avc, byte-stream }, " \
- "alignment = (string) au"
-
-/* *INDENT-OFF* */
-static const char gst_vaapiencode_h264_fei_sink_caps_str[] =
- GST_VAAPI_MAKE_SURFACE_CAPS ", "
- GST_CAPS_INTERLACED_FALSE "; "
- GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", "
- GST_CAPS_INTERLACED_FALSE ";"
- GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) ","
- GST_CAPS_INTERLACED_FALSE;
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-static const char gst_vaapiencode_h264_fei_src_caps_str[] =
- GST_CODEC_CAPS ", "
- "profile = (string) { constrained-baseline, baseline, main, high, multiview-high, stereo-high }";
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-static GstStaticPadTemplate gst_vaapiencode_h264_fei_sink_factory =
- GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (gst_vaapiencode_h264_fei_sink_caps_str));
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-static GstStaticPadTemplate gst_vaapiencode_h264_fei_src_factory =
- GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (gst_vaapiencode_h264_fei_src_caps_str));
-/* *INDENT-ON* */
-
-/* h264 encode */
-G_DEFINE_TYPE (GstVaapiEncodeH264Fei, gst_vaapiencode_h264_fei,
- GST_TYPE_VAAPIENCODE);
-
-static void
-gst_vaapiencode_h264_fei_init (GstVaapiEncodeH264Fei * encode)
-{
- /* nothing to do here */
-}
-
-static void
-gst_vaapiencode_h264_fei_finalize (GObject * object)
-{
- G_OBJECT_CLASS (gst_vaapiencode_h264_fei_parent_class)->finalize (object);
-}
-
-typedef struct
-{
- GstVaapiProfile best_profile;
- guint best_score;
-} FindBestProfileData;
-
-static void
-find_best_profile_value (FindBestProfileData * data, const GValue * value)
-{
- const gchar *str;
- GstVaapiProfile profile;
- guint score;
-
- if (!value || !G_VALUE_HOLDS_STRING (value))
- return;
-
- str = g_value_get_string (value);
- if (!str)
- return;
- profile = gst_vaapi_utils_h264_get_profile_from_string (str);
- if (!profile)
- return;
- score = gst_vaapi_utils_h264_get_profile_score (profile);
- if (score < data->best_score)
- return;
- data->best_profile = profile;
- data->best_score = score;
-}
-
-static GstVaapiProfile
-find_best_profile (GstCaps * caps)
-{
- FindBestProfileData data;
- guint i, j, num_structures, num_values;
-
- data.best_profile = GST_VAAPI_PROFILE_UNKNOWN;
- data.best_score = 0;
-
- num_structures = gst_caps_get_size (caps);
- for (i = 0; i < num_structures; i++) {
- GstStructure *const structure = gst_caps_get_structure (caps, i);
- const GValue *const value = gst_structure_get_value (structure, "profile");
-
- if (!value)
- continue;
- if (G_VALUE_HOLDS_STRING (value))
- find_best_profile_value (&data, value);
- else if (GST_VALUE_HOLDS_LIST (value)) {
- num_values = gst_value_list_get_size (value);
- for (j = 0; j < num_values; j++)
- find_best_profile_value (&data, gst_value_list_get_value (value, j));
- }
- }
- return data.best_profile;
-}
-
-static gboolean
-gst_vaapiencode_h264_fei_set_config (GstVaapiEncode * base_encode)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder);
- GstCaps *allowed_caps;
- GstVaapiProfile profile;
-
- /* Check for the largest profile that is supported */
- allowed_caps =
- gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode));
- if (!allowed_caps)
- return TRUE;
-
- profile = find_best_profile (allowed_caps);
- gst_caps_unref (allowed_caps);
- if (profile) {
- GST_INFO ("using %s profile as target decoder constraints",
- gst_vaapi_utils_h264_get_profile_string (profile));
- if (!gst_vaapi_encoder_h264_fei_set_max_profile (encoder, profile))
- return FALSE;
- }
- return TRUE;
-}
-
-static GstCaps *
-gst_vaapiencode_h264_fei_get_caps (GstVaapiEncode * base_encode)
-{
- GstVaapiEncodeH264Fei *const encode =
- GST_VAAPIENCODE_H264_FEI_CAST (base_encode);
- GstCaps *caps, *allowed_caps;
-
- caps = gst_caps_from_string (GST_CODEC_CAPS);
-
- /* Check whether "stream-format" is avcC mode */
- allowed_caps =
- gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode));
- if (allowed_caps) {
- const char *stream_format = NULL;
- GstStructure *structure;
- guint i, num_structures;
-
- num_structures = gst_caps_get_size (allowed_caps);
- for (i = 0; !stream_format && i < num_structures; i++) {
- structure = gst_caps_get_structure (allowed_caps, i);
- if (!gst_structure_has_field_typed (structure, "stream-format",
- G_TYPE_STRING))
- continue;
- stream_format = gst_structure_get_string (structure, "stream-format");
- }
- encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0;
- gst_caps_unref (allowed_caps);
- }
- gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING,
- encode->is_avc ? "avc" : "byte-stream", NULL);
-
- base_encode->need_codec_data = encode->is_avc;
-
- /* XXX: update profile and level information */
- return caps;
-}
-
-static GstVaapiEncoder *
-gst_vaapiencode_h264_fei_alloc_encoder (GstVaapiEncode * base,
- GstVaapiDisplay * display)
-{
- return gst_vaapi_encoder_h264_fei_new (display);
-}
-
-/* h264 NAL byte stream operations */
-static guint8 *
-_h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size)
-{
- const guint8 *cur = buffer;
- const guint8 *const end = buffer + len;
- guint8 *nal_start = NULL;
- guint32 flag = 0xFFFFFFFF;
- guint32 nal_start_len = 0;
-
- g_assert (buffer && nal_size);
- if (len < 3) {
- *nal_size = len;
- nal_start = (len ? buffer : NULL);
- return nal_start;
- }
-
- /*locate head postion */
- if (!buffer[0] && !buffer[1]) {
- if (buffer[2] == 1) { /* 0x000001 */
- nal_start_len = 3;
- } else if (!buffer[2] && len >= 4 && buffer[3] == 1) { /* 0x00000001 */
- nal_start_len = 4;
- }
- }
- nal_start = buffer + nal_start_len;
- cur = nal_start;
-
- /*find next nal start position */
- while (cur < end) {
- flag = ((flag << 8) | ((*cur++) & 0xFF));
- if ((flag & 0x00FFFFFF) == 0x00000001) {
- if (flag == 0x00000001)
- *nal_size = cur - 4 - nal_start;
- else
- *nal_size = cur - 3 - nal_start;
- break;
- }
- }
- if (cur >= end) {
- *nal_size = end - nal_start;
- if (nal_start >= end) {
- nal_start = NULL;
- }
- }
- return nal_start;
-}
-
-static inline void
-_start_code_to_size (guint8 nal_start_code[4], guint32 nal_size)
-{
- nal_start_code[0] = ((nal_size >> 24) & 0xFF);
- nal_start_code[1] = ((nal_size >> 16) & 0xFF);
- nal_start_code[2] = ((nal_size >> 8) & 0xFF);
- nal_start_code[3] = (nal_size & 0xFF);
-}
-
-static gboolean
-_h264_convert_byte_stream_to_avc (GstBuffer * buf)
-{
- GstMapInfo info;
- guint32 nal_size;
- guint8 *nal_start_code, *nal_body;
- guint8 *frame_end;
-
- g_assert (buf);
-
- if (!gst_buffer_map (buf, &info, GST_MAP_READ | GST_MAP_WRITE))
- return FALSE;
-
- nal_start_code = info.data;
- frame_end = info.data + info.size;
- nal_size = 0;
-
- while ((frame_end > nal_start_code) &&
- (nal_body = _h264_byte_stream_next_nal (nal_start_code,
- frame_end - nal_start_code, &nal_size)) != NULL) {
- if (!nal_size)
- goto error;
-
- g_assert (nal_body - nal_start_code == 4);
- _start_code_to_size (nal_start_code, nal_size);
- nal_start_code = nal_body + nal_size;
- }
- gst_buffer_unmap (buf, &info);
- return TRUE;
-
- /* ERRORS */
-error:
- {
- gst_buffer_unmap (buf, &info);
- return FALSE;
- }
-}
-
-static GstFlowReturn
-alloc_buffer (GstVaapiEncode * encode,
- GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI (encode->encoder);
- GstBuffer *buf;
- gint32 buf_size;
- GstVaapiFeiMode fei_mode;
-
- g_return_val_if_fail (coded_buf != NULL, GST_FLOW_ERROR);
- g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR);
-
- fei_mode = gst_vaapi_encoder_h264_fei_get_function_mode (encoder);
-
- if (fei_mode == GST_VAAPI_FEI_MODE_ENC)
- buf_size = 4; /* just avoid zero size buffer allocation */
- else
- buf_size = gst_vaapi_coded_buffer_get_size (coded_buf);
-
- if (buf_size <= 0)
- goto error_invalid_buffer;
-
- buf =
- gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode),
- buf_size);
- if (!buf)
- goto error_create_buffer;
-
- /* There is no encoded output content in ENC only mode */
- if (fei_mode != GST_VAAPI_FEI_MODE_ENC) {
- if (!gst_vaapi_coded_buffer_copy_into (buf, coded_buf))
- goto error_copy_buffer;
- }
-
- *outbuf_ptr = buf;
- return GST_FLOW_OK;
-
- /* ERRORS */
-error_invalid_buffer:
- {
- GST_ERROR ("invalid GstVaapiCodedBuffer size (%d bytes)", buf_size);
- return GST_VAAPI_ENCODE_FLOW_MEM_ERROR;
- }
-error_create_buffer:
- {
- GST_ERROR ("failed to create output buffer of size %d", buf_size);
- return GST_VAAPI_ENCODE_FLOW_MEM_ERROR;
- }
-error_copy_buffer:
- {
- GST_ERROR ("failed to copy GstVaapiCodedBuffer data");
- gst_buffer_unref (buf);
- return GST_VAAPI_ENCODE_FLOW_MEM_ERROR;
- }
-}
-
-static GstFlowReturn
-gst_vaapiencode_h264_fei_alloc_buffer (GstVaapiEncode * base_encode,
- GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr)
-{
- GstVaapiEncodeH264Fei *const encode =
- GST_VAAPIENCODE_H264_FEI_CAST (base_encode);
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder);
- GstFlowReturn ret;
-
- g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR);
-
- ret = alloc_buffer (base_encode, coded_buf, out_buffer_ptr);
- if (ret != GST_FLOW_OK)
- return ret;
-
- if (!encode->is_avc)
- return GST_FLOW_OK;
-
- /* Convert to avcC format */
- if (!_h264_convert_byte_stream_to_avc (*out_buffer_ptr))
- goto error_convert_buffer;
- return GST_FLOW_OK;
-
- /* ERRORS */
-error_convert_buffer:
- {
- GST_ERROR ("failed to convert from bytestream format to avcC format");
- gst_buffer_replace (out_buffer_ptr, NULL);
- return GST_FLOW_ERROR;
- }
-}
-
-static gboolean
-gst_vaapiencode_h264_load_control_data (GstVaapiEncode * base_encode,
- GstVaapiFeiVideoMeta * feimeta, GstVaapiSurfaceProxy * proxy)
-{
- if (feimeta != NULL) {
- gst_vaapi_surface_proxy_set_fei_mb_code (proxy, feimeta->mbcode);
- gst_vaapi_surface_proxy_set_fei_mv (proxy, feimeta->mv);
- gst_vaapi_surface_proxy_set_fei_mv_predictor (proxy, feimeta->mvpred);
- gst_vaapi_surface_proxy_set_fei_mb_control (proxy, feimeta->mbcntrl);
- gst_vaapi_surface_proxy_set_fei_qp (proxy, feimeta->qp);
- gst_vaapi_surface_proxy_set_fei_distortion (proxy, feimeta->dist);
- }
- return TRUE;
-
-}
-
-static GstVaapiFeiVideoMeta *
-gst_vaapiencode_h264_save_stats_to_meta (GstVaapiEncode * base_encode,
- GstVaapiCodedBufferProxy * proxy)
-{
- GstVaapiEncoderH264Fei *const encoder =
- GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder);
- GstVaapiFeiVideoMeta *feimeta = NULL;
- GstVaapiEncFeiMbCode *mbcode = NULL;
- GstVaapiEncFeiMv *mv = NULL;
- GstVaapiEncFeiDistortion *dist = NULL;
-
- if (!gst_vaapi_encoder_h264_is_fei_stats_out_enabled (encoder))
- return NULL;
-
- feimeta = gst_vaapi_fei_video_meta_new ();
- if (feimeta == NULL)
- return NULL;
-
- mbcode = gst_vaapi_coded_buffer_proxy_get_fei_mbcode (proxy);
- if (mbcode)
- feimeta->mbcode = (GstVaapiEncFeiMbCode *)
- gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) mbcode);
-
- mv = gst_vaapi_coded_buffer_proxy_get_fei_mv (proxy);
- if (mv)
- feimeta->mv = (GstVaapiEncFeiMv *)
- gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) mv);
-
- dist = gst_vaapi_coded_buffer_proxy_get_fei_distortion (proxy);
- if (dist)
- feimeta->dist = (GstVaapiEncFeiDistortion *)
- gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) dist);
-
- return feimeta;
-}
-
-static void
-gst_vaapiencode_h264_fei_class_init (GstVaapiEncodeH264FeiClass * klass)
-{
- GObjectClass *const object_class = G_OBJECT_CLASS (klass);
- GstElementClass *const element_class = GST_ELEMENT_CLASS (klass);
- GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass);
- gpointer encoder_class;
-
- GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_fei_encode_debug,
- GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
-
- object_class->finalize = gst_vaapiencode_h264_fei_finalize;
- object_class->set_property = gst_vaapiencode_set_property_subclass;
- object_class->get_property = gst_vaapiencode_get_property_subclass;
-
- encode_class->set_config = gst_vaapiencode_h264_fei_set_config;
- encode_class->get_caps = gst_vaapiencode_h264_fei_get_caps;
- encode_class->alloc_encoder = gst_vaapiencode_h264_fei_alloc_encoder;
- encode_class->alloc_buffer = gst_vaapiencode_h264_fei_alloc_buffer;
-
- encode_class->load_control_data = gst_vaapiencode_h264_load_control_data;
- encode_class->save_stats_to_meta = gst_vaapiencode_h264_save_stats_to_meta;
-
- gst_element_class_set_static_metadata (element_class,
- "VA-API H264 FEI Advanced encoder (Experimental)",
- "Codec/Encoder/Video/Hardware",
- GST_PLUGIN_DESC,
- "Sreerenj Balachandran <sreerenj.balachandran@intel.com> ,"
- "Yi A Wang <yi.a.wang@intel.com>");
-
- /* sink pad */
- gst_element_class_add_static_pad_template (element_class,
- &gst_vaapiencode_h264_fei_sink_factory);
-
- /* src pad */
- gst_element_class_add_static_pad_template (element_class,
- &gst_vaapiencode_h264_fei_src_factory);
-
- encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H264_FEI);
- g_assert (encoder_class);
- gst_vaapiencode_class_install_properties (encode_class, encoder_class);
- g_type_class_unref (encoder_class);
-}
diff --git a/gst/vaapi/gstvaapiencode_h264_fei.h b/gst/vaapi/gstvaapiencode_h264_fei.h
deleted file mode 100644
index 19501078..00000000
--- a/gst/vaapi/gstvaapiencode_h264_fei.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * gstvaapiencode_h264i_fei.h - VA-API H.264 FEI encoder
- *
- * Copyright (C) 2016-2017 Intel Corporation
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Author: Yi A Wang <yi.a.wang@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPIENCODE_H264_FEI_FEI_H
-#define GST_VAAPIENCODE_H264_FEI_FEI_H
-
-#include <gst/gst.h>
-#include "gstvaapiencode.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_VAAPIENCODE_H264_FEI \
- (gst_vaapiencode_h264_fei_get_type ())
-#define GST_VAAPIENCODE_H264_FEI_CAST(obj) \
- ((GstVaapiEncodeH264Fei *)(obj))
-#define GST_VAAPIENCODE_H264_FEI(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_H264_FEI, \
- GstVaapiEncodeH264Fei))
-#define GST_VAAPIENCODE_H264_FEI_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_H264_FEI, \
- GstVaapiEncodeH264FeiClass))
-#define GST_VAAPIENCODE_H264_FEI_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_H264_FEI, \
- GstVaapiEncodeH264FeiClass))
-#define GST_IS_VAAPIENCODE_H264_FEI(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H264_FEI))
-#define GST_IS_VAAPIENCODE_H264_FEI_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H264_FEI))
-
-typedef struct _GstVaapiEncodeH264Fei GstVaapiEncodeH264Fei;
-typedef struct _GstVaapiEncodeH264FeiClass GstVaapiEncodeH264FeiClass;
-
-struct _GstVaapiEncodeH264Fei
-{
- /*< private >*/
- GstVaapiEncode parent_instance;
-
- guint is_avc:1; /* [FALSE]=byte-stream (default); [TRUE]=avcC */
-};
-
-struct _GstVaapiEncodeH264FeiClass
-{
- /*< private >*/
- GstVaapiEncodeClass parent_class;
-};
-
-GType
-gst_vaapiencode_h264_fei_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* GST_VAAPIENCODE_H264_FEI_FEI_H */
diff --git a/gst/vaapi/gstvaapifeivideometa.c b/gst/vaapi/gstvaapifeivideometa.c
deleted file mode 100644
index eafb7d0c..00000000
--- a/gst/vaapi/gstvaapifeivideometa.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * gstvaapifeivideometa.c - Gst VA FEI video meta
- *
- * Copyright (C) 2016-2017 Intel Corporation
- * Author: Yi A Wang <yi.a.wang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>*
- *
- * 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
- */
-
-/**
- * SECTION:gstvaapifeivideometa
- * @short_description: VA FEI video meta for GStreamer
- */
-#include "gstcompat.h"
-#include "gstvaapifeivideometa.h"
-
-static void
-gst_vaapi_fei_video_meta_finalize (GstVaapiFeiVideoMeta * meta)
-{
- if (meta->mbcode)
- gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mbcode));
- if (meta->mv)
- gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->mv));
- if (meta->mvpred)
- gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mvpred));
- if (meta->mbcntrl)
- gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mbcntrl));
- if (meta->qp)
- gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->qp));
- if (meta->dist)
- gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->dist));
-}
-
-static void
-gst_vaapi_fei_video_meta_init (GstVaapiFeiVideoMeta * meta)
-{
-}
-
-static inline GstVaapiFeiVideoMeta *
-_gst_vaapi_fei_video_meta_create (void)
-{
- return g_slice_new0 (GstVaapiFeiVideoMeta);
-}
-
-static inline void
-_gst_vaapi_fei_video_meta_destroy (GstVaapiFeiVideoMeta * meta)
-{
- g_slice_free1 (sizeof (*meta), meta);
-}
-
-GstVaapiFeiVideoMeta *
-gst_vaapi_fei_video_meta_new (void)
-{
- GstVaapiFeiVideoMeta *meta;
-
- meta = _gst_vaapi_fei_video_meta_create ();
- if (!meta)
- return NULL;
- gst_vaapi_fei_video_meta_init (meta);
- return meta;
-}
-
-static inline void
-_gst_vaapi_fei_video_meta_free (GstVaapiFeiVideoMeta * meta)
-{
- g_atomic_int_inc (&meta->ref_count);
-
- gst_vaapi_fei_video_meta_finalize (meta);
-
- if (G_LIKELY (g_atomic_int_dec_and_test (&meta->ref_count)))
- _gst_vaapi_fei_video_meta_destroy (meta);
-}
-
-/**
- * gst_vaapi_fei_video_meta_ref:
- * @meta: a #GstVaapiFeiVideoMeta
- *
- * Atomically increases the reference count of the given @meta by one.
- *
- * Returns: The same @meta argument
- */
-GstVaapiFeiVideoMeta *
-gst_vaapi_fei_video_meta_ref (GstVaapiFeiVideoMeta * meta)
-{
- g_return_val_if_fail (meta != NULL, NULL);
-
- g_atomic_int_inc (&meta->ref_count);
- return meta;
-}
-
-/**
- * gst_vaapi_fei_video_meta_unref:
- * @meta: a #GstVaapiFeiVideoMeta
- *
- * Atomically decreases the reference count of the @meta by one. If
- * the reference count reaches zero, the object will be free'd.
- */
-void
-gst_vaapi_fei_video_meta_unref (GstVaapiFeiVideoMeta * meta)
-{
- g_return_if_fail (meta != NULL);
- g_return_if_fail (meta->ref_count > 0);
- if (g_atomic_int_dec_and_test (&meta->ref_count))
- _gst_vaapi_fei_video_meta_free (meta);
-}
-
-
-GType
-gst_vaapi_fei_video_meta_api_get_type (void)
-{
- static gsize g_type;
- static const gchar *tags[] = { "memory", NULL };
-
- if (g_once_init_enter (&g_type)) {
- GType type = gst_meta_api_type_register ("GstVaapiFeiVideoMetaAPI", tags);
- g_once_init_leave (&g_type, type);
- }
- return g_type;
-}
-
-
-#define GST_VAAPI_FEI_VIDEO_META_HOLDER(meta) \
- ((GstVaapiFeiVideoMetaHolder *) (meta))
-
-static gboolean
-gst_vaapi_fei_video_meta_holder_init (GstVaapiFeiVideoMetaHolder * meta,
- gpointer params, GstBuffer * buffer)
-{
- meta->meta = NULL;
- return TRUE;
-}
-
-static void
-gst_vaapi_fei_video_meta_holder_free (GstVaapiFeiVideoMetaHolder * meta,
- GstBuffer * buffer)
-{
- if (meta->meta)
- gst_vaapi_fei_video_meta_unref (meta->meta);
-}
-
-
-#define GST_VAAPI_FEI_VIDEO_META_INFO gst_vaapi_fei_video_meta_info_get ()
-static const GstMetaInfo *
-gst_vaapi_fei_video_meta_info_get (void)
-{
- static gsize g_meta_info;
-
- if (g_once_init_enter (&g_meta_info)) {
- gsize meta_info =
- GPOINTER_TO_SIZE (gst_meta_register (GST_VAAPI_FEI_VIDEO_META_API_TYPE,
- "GstVaapiFeiVideoMeta", sizeof (GstVaapiFeiVideoMetaHolder),
- (GstMetaInitFunction) gst_vaapi_fei_video_meta_holder_init,
- (GstMetaFreeFunction) gst_vaapi_fei_video_meta_holder_free,
- NULL));
- g_once_init_leave (&g_meta_info, meta_info);
- }
- return GSIZE_TO_POINTER (g_meta_info);
-}
-
-GstVaapiFeiVideoMeta *
-gst_buffer_get_vaapi_fei_video_meta (GstBuffer * buffer)
-{
- GstVaapiFeiVideoMeta *meta;
- GstMeta *m;
-
- g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-
- m = gst_buffer_get_meta (buffer, GST_VAAPI_FEI_VIDEO_META_API_TYPE);
- if (!m)
- return NULL;
-
- meta = GST_VAAPI_FEI_VIDEO_META_HOLDER (m)->meta;
- if (meta)
- meta->buffer = buffer;
- return meta;
-}
-
-void
-gst_buffer_set_vaapi_fei_video_meta (GstBuffer * buffer,
- GstVaapiFeiVideoMeta * meta)
-{
- GstMeta *m = NULL;
-
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_VAAPI_IS_FEI_VIDEO_META (meta));
-
- m = gst_buffer_add_meta (buffer, GST_VAAPI_FEI_VIDEO_META_INFO, NULL);
-
- if (m)
- GST_VAAPI_FEI_VIDEO_META_HOLDER (m)->meta =
- gst_vaapi_fei_video_meta_ref (meta);
- return;
-}
diff --git a/gst/vaapi/gstvaapifeivideometa.h b/gst/vaapi/gstvaapifeivideometa.h
deleted file mode 100644
index 09d5f68e..00000000
--- a/gst/vaapi/gstvaapifeivideometa.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * gstvaapifeivideometa.h - Gstreamer/VA video meta
- *
- * Copyright (C) 2016-2017 Intel Corporation
- * Author: Yi A Wang <yi.a.wang@intel.com>
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-
-#ifndef GST_VAAPI_FEI_VIDEO_META_H
-#define GST_VAAPI_FEI_VIDEO_META_H
-
-#include <va/va.h>
-#include <gst/vaapi/gstvaapifei_objects.h>
-G_BEGIN_DECLS
-
-typedef struct _GstVaapiFeiVideoMeta GstVaapiFeiVideoMeta;
-typedef struct _GstVaapiFeiVideoMetaHolder GstVaapiFeiVideoMetaHolder;
-
-#define GST_VAAPI_FEI_VIDEO_META(obj) \
- ((GstVaapiFeiVideoMeta *) (obj))
-#define GST_VAAPI_IS_FEI_VIDEO_META(obj) \
- (GST_VAAPI_FEI_VIDEO_META (obj) != NULL)
-
-struct _GstVaapiFeiVideoMetaHolder
-{
- GstMeta base;
- GstVaapiFeiVideoMeta *meta;
-};
-
-struct _GstVaapiFeiVideoMeta {
- GstVaapiEncFeiMbCode *mbcode;
- GstVaapiEncFeiMv *mv;
- GstVaapiEncFeiMvPredictor *mvpred;
- GstVaapiEncFeiMbControl *mbcntrl;
- GstVaapiEncFeiQp *qp;
- GstVaapiEncFeiDistortion *dist;
-
- GstBuffer *buffer;
- gint ref_count;
-};
-
-#define GST_VAAPI_FEI_VIDEO_META_API_TYPE \
- gst_vaapi_fei_video_meta_api_get_type ()
-
-GType
-gst_vaapi_fei_video_meta_api_get_type (void) G_GNUC_CONST;
-
-GstVaapiFeiVideoMeta *
-gst_vaapi_fei_video_meta_new (void);
-
-GstVaapiFeiVideoMeta *
-gst_vaapi_fei_video_meta_ref (GstVaapiFeiVideoMeta * meta);
-
-void
-gst_vaapi_fei_video_meta_unref (GstVaapiFeiVideoMeta * meta);
-
-GstVaapiFeiVideoMeta *
-gst_buffer_get_vaapi_fei_video_meta (GstBuffer * buffer);
-
-void
-gst_buffer_set_vaapi_fei_video_meta (GstBuffer * buffer, GstVaapiFeiVideoMeta * meta);
-
-G_END_DECLS
-
-#endif /* GST_VAAPI_FEI_VIDEO_META_H */
diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build
index c363b00b..d8c24c3b 100644
--- a/gst/vaapi/meson.build
+++ b/gst/vaapi/meson.build
@@ -33,13 +33,6 @@ if USE_VP9_ENCODER
vaapi_sources += 'gstvaapiencode_vp9.c'
endif
-if USE_H264_FEI_ENCODER
- vaapi_sources += [
- 'gstvaapifeivideometa.c',
- 'gstvaapiencode_h264_fei.c',
- ]
-endif
-
gstvaapi = library('gstvaapi',
vaapi_sources,
c_args : gstreamer_vaapi_args + ['-DGST_USE_UNSTABLE_API'],
diff --git a/meson.build b/meson.build
index d1cb310f..3ee4fa61 100644
--- a/meson.build
+++ b/meson.build
@@ -110,7 +110,6 @@ endif
USE_ENCODERS = get_option('with_encoders') != 'no'
USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include <va/va.h>')
-USE_H264_FEI_ENCODER = USE_ENCODERS and cc.has_header('va/va_fei_h264.h', dependencies: libva_dep, prefix: '#include <va/va.h>')
USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no'
USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no'
@@ -141,7 +140,6 @@ cdata.set10('USE_EGL', USE_EGL)
cdata.set10('USE_ENCODERS', USE_ENCODERS)
cdata.set10('USE_GLX', USE_GLX)
cdata.set10('USE_VP9_ENCODER', USE_VP9_ENCODER)
-cdata.set10('USE_H264_FEI_ENCODER', USE_H264_FEI_ENCODER)
cdata.set10('USE_WAYLAND', USE_WAYLAND)
cdata.set10('USE_X11', USE_X11)
cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep))
diff --git a/tests/internal/meson.build b/tests/internal/meson.build
index a118d384..1afd22be 100644
--- a/tests/internal/meson.build
+++ b/tests/internal/meson.build
@@ -46,13 +46,6 @@ if USE_ENCODERS
test_examples += [ 'simple-encoder' ]
endif
-if USE_H264_FEI_ENCODER
- test_examples += [
- 'test-fei-enc-out',
- 'test-fei-enc-in',
- ]
-endif
-
if USE_GLX
test_examples += [ 'test-textures' ]
endif
diff --git a/tests/internal/test-fei-enc-in.c b/tests/internal/test-fei-enc-in.c
deleted file mode 100644
index ad67909e..00000000
--- a/tests/internal/test-fei-enc-in.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * test-fei-enc-in.c - Test FEI input buffer submission
- *
- * Copyright (C) 2016 Intel Corporation
- *
- * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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
- */
-/* sample pipeline: ./test-fei-enc-input -c h264 -o out.264 -e 4 -q 1 sample_i420.y4m */
-
-#include <assert.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "gst/vaapi/sysdeps.h"
-#include <gst/vaapi/gstvaapiencoder.h>
-#include <gst/vaapi/gstvaapiencoder_h264_fei.h>
-#include <gst/vaapi/gstvaapisurfacepool.h>
-#include <gst/vaapi/gstvaapisurfaceproxy.h>
-#include <gst/vaapi/gstvaapifei_objects.h>
-#include "output.h"
-#include "y4mreader.h"
-#include <va/va.h>
-
-static guint g_bitrate = 0;
-static gchar *g_codec_str;
-static gchar *g_output_file_name;
-static char **g_input_files = NULL;
-static gchar *input_mv_name = NULL;
-static gchar *input_mbmode_name = NULL;
-static guint input_mv_size;
-static guint input_mbmode_size;
-static guint input_qp;
-static guint enable_mbcntrl;
-static guint enable_mvpred;
-static guint fei_mode;
-
-#define SURFACE_NUM 16
-
-#define ENC 1
-#define PAK 2
-#define ENC_PLUS_PAK 3
-#define ENC_PAK 4
-
-static GOptionEntry g_options[] = {
- {"codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str,
- "codec to use for video encoding (h264)", NULL},
- {"bitrate", 'b', 0, G_OPTION_ARG_INT, &g_bitrate,
- "desired bitrate expressed in kbps", NULL},
- {"output", 'o', 0, G_OPTION_ARG_FILENAME, &g_output_file_name,
- "output file name", NULL},
- {"imv", 'v', 0, G_OPTION_ARG_STRING, &input_mv_name,
- "pak mv input file", NULL},
- {"imbmode ", 'm', 0, G_OPTION_ARG_STRING, &input_mbmode_name,
- "pak mbmode input file", NULL},
- {"imvsize", 's', 0, G_OPTION_ARG_INT, &input_mv_size,
- "input stream width", NULL},
- {"imbmodesize", 'd', 0, G_OPTION_ARG_INT, &input_mbmode_size,
- "input stream height", NULL},
- {"iqp", 'q', 0, G_OPTION_ARG_INT, &input_qp,
- "input qp val (it will get replicated for each macrobock)", NULL},
- {"imbcntrl", 'l', 0, G_OPTION_ARG_INT, &enable_mbcntrl,
- "enable macroblock control for each macrobock", NULL},
- {"imbpred", 'p', 0, G_OPTION_ARG_INT, &enable_mvpred,
- "enable mv predictor for each macroblock", NULL},
- {"fei-mode", 'e', 0, G_OPTION_ARG_INT, &fei_mode,
- "1:ENC 2:PAK 3:ENC+PAK 4:ENC_PAK", NULL},
-
- {G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY, &g_input_files,
- "input file name", NULL},
- {NULL}
-};
-
-typedef struct
-{
- GstVaapiDisplay *display;
- GstVaapiEncoder *encoder;
- guint read_frames;
- guint encoded_frames;
- guint saved_frames;
- Y4MReader *parser;
- FILE *output_file;
- int mv_fd;
- int mbmode_fd;
- guint input_mv_size;
- guint input_mbmode_size;
- guint input_stopped:1;
- guint encode_failed:1;
-} App;
-
-static inline gchar *
-generate_output_filename (const gchar * ext)
-{
- gchar *fn;
- int i = 0;
-
- while (1) {
- fn = g_strdup_printf ("temp%02d.%s", i, ext);
- if (g_file_test (fn, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
- i++;
- g_free (fn);
- } else {
- break;
- }
- }
-
- return fn;
-}
-
-static gboolean
-parse_options (int *argc, char *argv[])
-{
- GOptionContext *ctx;
- gboolean success;
- GError *error = NULL;
-
- ctx = g_option_context_new (" - encoder test options");
- if (!ctx)
- return FALSE;
-
- g_option_context_add_group (ctx, gst_init_get_option_group ());
- g_option_context_add_main_entries (ctx, g_options, NULL);
- g_option_context_set_help_enabled (ctx, TRUE);
- success = g_option_context_parse (ctx, argc, &argv, &error);
- if (!success) {
- g_printerr ("Option parsing failed: %s\n", error->message);
- g_error_free (error);
- goto bail;
- }
-
- if (!g_codec_str)
- g_codec_str = g_strdup ("h264");
- if (!g_output_file_name)
- g_output_file_name = generate_output_filename (g_codec_str);
-
-bail:
- g_option_context_free (ctx);
- return success;
-}
-
-static void
-print_yuv_info (App * app)
-{
- g_print ("\n");
- g_print ("Encode : %s\n", g_codec_str);
- g_print ("Resolution : %dx%d\n", app->parser->width, app->parser->height);
- g_print ("Source YUV : %s\n", g_input_files ? g_input_files[0] : "stdin");
- g_print ("Frame Rate : %0.1f fps\n",
- 1.0 * app->parser->fps_n / app->parser->fps_d);
- g_print ("Coded file : %s\n", g_output_file_name);
- g_print ("\n");
-}
-
-static void
-print_num_frame (App * app)
-{
- g_print ("\n");
- g_print ("read frames : %d\n", app->read_frames);
- g_print ("encoded frames : %d\n", app->encoded_frames);
- g_print ("saved frames : %d\n", app->saved_frames);
- g_print ("\n");
-}
-
-static GstVaapiEncoder *
-encoder_new (GstVaapiDisplay * display)
-{
- GstVaapiEncoder *encoder = NULL;
-
- if (!g_strcmp0 (g_codec_str, "h264")) {
- encoder = gst_vaapi_encoder_h264_fei_new (display);
- gst_vaapi_encoder_h264_fei_set_function_mode (GST_VAAPI_ENCODER_H264_FEI
- (encoder), fei_mode);
- gst_vaapi_encoder_h264_fei_set_max_profile (GST_VAAPI_ENCODER_H264_FEI
- (encoder), GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE);
- } else
- return NULL;
-
- return encoder;
-}
-
-static inline GstVideoCodecState *
-new_codec_state (gint width, gint height, gint fps_n, gint fps_d)
-{
- GstVideoCodecState *state;
-
- state = g_slice_new0 (GstVideoCodecState);
- state->ref_count = 1;
- gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, width,
- height);
-
- state->info.fps_n = fps_n;
- state->info.fps_d = fps_d;
-
- return state;
-}
-
-static gboolean
-set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n,
- gint fps_d)
-{
- GstVideoCodecState *in_state;
- GstVaapiEncoderStatus status;
-
- in_state = new_codec_state (width, height, fps_n, fps_d);
- status = gst_vaapi_encoder_set_codec_state (encoder, in_state);
- g_slice_free (GstVideoCodecState, in_state);
-
- return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS);
-}
-
-static GstBuffer *
-allocate_buffer (GstVaapiCodedBuffer * vbuf)
-{
- GstBuffer *buf;
- gssize size;
-
- size = gst_vaapi_coded_buffer_get_size (vbuf);
-
- if (size <= 0) {
- g_warning ("Invalid VA buffer size (%zd)", size);
- return NULL;
- }
-
- buf = gst_buffer_new_and_alloc (size);
- if (!buf) {
- g_warning ("Failed to create output buffer of size %zd", size);
- return NULL;
- }
-
- if (!gst_vaapi_coded_buffer_copy_into (buf, vbuf)) {
- g_warning ("Failed to copy VA buffer data");
- gst_buffer_unref (buf);
- return NULL;
- }
-
- return buf;
-}
-
-static GstVaapiEncoderStatus
-get_encoder_buffer (GstVaapiEncoder * encoder, GstBuffer ** buffer)
-{
- GstVaapiCodedBufferProxy *proxy = NULL;
- GstVaapiEncoderStatus status;
-
- status = gst_vaapi_encoder_get_buffer_with_timeout (encoder, &proxy, 50000);
- if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- g_warning ("Failed to get a buffer from encoder: %d", status);
- return status;
- } else if (status > GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- return status;
- }
-
- *buffer = allocate_buffer (GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy));
- gst_vaapi_coded_buffer_proxy_unref (proxy);
-
- return status;
-}
-
-static gboolean
-outputs_to_file (GstBuffer * buffer, FILE * file)
-{
- GstMapInfo info;
- size_t written;
- gboolean ret = FALSE;
-
- if (!gst_buffer_map (buffer, &info, GST_MAP_READ))
- return FALSE;
-
- if (info.size <= 0 || !info.data)
- return FALSE;
-
- written = fwrite (info.data, 1, info.size, file);
- if (written < info.size) {
- g_warning ("write file error.");
- goto bail;
- }
-
- ret = TRUE;
-
-bail:
- gst_buffer_unmap (buffer, &info);
- return ret;
-}
-
-static gpointer
-get_buffer_thread (gpointer data)
-{
- App *app = data;
-
- GstVaapiEncoderStatus ret;
- GstBuffer *obuf;
-
- while (1) {
- obuf = NULL;
- ret = get_encoder_buffer (app->encoder, &obuf);
- if (app->input_stopped && ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) {
- break; /* finished */
- } else if (ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* another chance */
- continue;
- }
- if (ret < GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* fatal error */
- app->encode_failed = TRUE;
- break;
- }
-
- app->encoded_frames++;
- g_debug ("encoded frame %d, buffer = %p", app->encoded_frames, obuf);
-
- if (app->output_file && outputs_to_file (obuf, app->output_file))
- app->saved_frames++;
-
- gst_buffer_unref (obuf);
- }
- if (obuf)
- gst_buffer_replace (&obuf, NULL);
-
- return NULL;
-}
-
-static void
-app_free (App * app)
-{
- g_return_if_fail (app);
-
- if (app->parser)
- y4m_reader_close (app->parser);
-
- if (app->encoder) {
- gst_vaapi_encoder_flush (app->encoder);
- gst_object_unref (app->encoder);
- }
-
- if (app->display)
- gst_object_unref (app->display);
-
- if (app->output_file)
- fclose (app->output_file);
-
- g_slice_free (App, app);
-}
-
-static App *
-app_new (const gchar * input_fn, const gchar * output_fn)
-{
- App *app = g_slice_new0 (App);
- if (!app)
- return NULL;
- app->parser = y4m_reader_open (input_fn);
- if (!app->parser) {
- g_warning ("Could not parse input stream.");
- goto error;
- }
-
- app->output_file = fopen (output_fn, "w");
- if (app->output_file == NULL) {
- g_warning ("Could not open file \"%s\" for writing: %s.", output_fn,
- g_strerror (errno));
- goto error;
- }
-
- /* if PAK only */
- if (fei_mode == 2) {
- if (!input_mv_name || !input_mbmode_name) {
- g_warning ("pak only mode need an mv and mbmode files as input");
- assert (0);
- }
-
- if (input_mv_name)
- app->mv_fd = open (input_mv_name, O_RDONLY, 0);
- if (input_mbmode_name)
- app->mbmode_fd = open (input_mbmode_name, O_RDONLY, 0);
-
- assert (app->mv_fd >= 0);
- assert (app->mbmode_fd >= 0);
- }
-
- app->display = video_output_create_display (NULL);
- if (!app->display) {
- g_warning ("Could not create VA display.");
- goto error;
- }
-
- app->encoder = encoder_new (app->display);
- if (!app->encoder) {
- g_warning ("Could not create encoder.");
- goto error;
- }
-
- if (!set_format (app->encoder, app->parser->width, app->parser->height,
- app->parser->fps_n, app->parser->fps_d)) {
- g_warning ("Could not set format.");
- goto error;
- }
-
- return app;
-
-error:
- app_free (app);
- return NULL;
-}
-
-static gboolean
-upload_frame (GstVaapiEncoder * encoder, GstVaapiSurfaceProxy * proxy)
-{
- GstVideoCodecFrame *frame;
- GstVaapiEncoderStatus ret;
-
- frame = g_slice_new0 (GstVideoCodecFrame);
- gst_video_codec_frame_set_user_data (frame,
- gst_vaapi_surface_proxy_ref (proxy),
- (GDestroyNotify) gst_vaapi_surface_proxy_unref);
-
- ret = gst_vaapi_encoder_put_frame (encoder, frame);
- return (ret == GST_VAAPI_ENCODER_STATUS_SUCCESS);
-}
-
-static gboolean
-load_frame (App * app, GstVaapiImage * image)
-{
- gboolean ret = FALSE;
-
- if (!gst_vaapi_image_map (image))
- return FALSE;
-
- ret = y4m_reader_load_image (app->parser, image);
-
- if (!gst_vaapi_image_unmap (image))
- return FALSE;
-
- return ret;
-}
-
-static int
-app_run (App * app)
-{
- GstVaapiImage *image;
- GstVaapiVideoPool *pool;
- GThread *buffer_thread;
- gsize id;
- gint i;
-
- int ret = EXIT_FAILURE;
- image = gst_vaapi_image_new (app->display, GST_VIDEO_FORMAT_I420,
- app->parser->width, app->parser->height);
-
- {
- GstVideoInfo vi;
- gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED,
- app->parser->width, app->parser->height);
- pool = gst_vaapi_surface_pool_new_full (app->display, &vi, 0);
- }
- buffer_thread = g_thread_new ("get buffer thread", get_buffer_thread, app);
-
- while (1) {
- GstVaapiSurfaceProxy *proxy;
- GstVaapiSurface *surface;
- gpointer data = NULL;
- guint size = 0;
- gint rt = 0;
- guint mb_width, mb_height, mb_size;
-
- if (!load_frame (app, image))
- break;
-
- if (!gst_vaapi_image_unmap (image))
- break;
-
- proxy =
- gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool));
- if (!proxy) {
- g_warning ("Could not get surface proxy from pool.");
- break;
- }
- surface = gst_vaapi_surface_proxy_get_surface (proxy);
- if (!surface) {
- g_warning ("Could not get surface from proxy.");
- break;
- }
-
- if (!gst_vaapi_surface_put_image (surface, image)) {
- g_warning ("Could not update surface");
- break;
- }
-
- mb_width = (app->parser->width + 15) >> 4;
- mb_height = (app->parser->height + 15) >> 4;
- mb_size = mb_width * mb_height;
-
- /* PAK Only */
- if (fei_mode == PAK) {
- GstVaapiEncFeiMbCode *mbcode;
- GstVaapiEncFeiMv *mv;
- guint mv_size, mbmode_size;
-
- mv_size = mb_width * mb_height * 128;
- mbmode_size = mb_width * mb_height * 64;
-
- if (input_mv_size)
- assert (input_mv_size == mv_size);
-
- if (input_mbmode_size)
- assert (input_mbmode_size == mbmode_size);
-
- /* Upload mbmode data */
- mbcode = gst_vaapi_enc_fei_mb_code_new (app->encoder, NULL, mbmode_size);
- rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (mbcode),
- &data, &size);
- assert (rt == 1);
- rt = read (app->mbmode_fd, data, mbmode_size);
- assert (rt >= 0);
-
- /* Upload mv data */
- mv = gst_vaapi_enc_fei_mv_new (app->encoder, NULL, mv_size);
- rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (mv),
- &data, &size);
- assert (rt == 1);
- rt = read (app->mv_fd, data, mv_size);
- assert (rt >= 0);
-
- /* assign mv and mbmode buffers to input surface proxy */
- gst_vaapi_surface_proxy_set_fei_mb_code (proxy, mbcode);
- gst_vaapi_surface_proxy_set_fei_mv (proxy, mv);
-
- } else {
- /* ENC, ENC+PAK and ENC_PAK */
-
- if (input_qp) {
- GstVaapiEncFeiQp *qp = NULL;
- VAEncQPBufferH264 *pqp = NULL;
- guint qp_size = 0;
-
- qp_size = mb_width * mb_height * sizeof (VAEncQPBufferH264);
-
- qp = gst_vaapi_enc_fei_qp_new (app->encoder, NULL, qp_size);
- rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (qp),
- &data, &size);
- assert (rt == 1);
-
- pqp = (VAEncQPBufferH264 *) data;
- for (i = 0; i < mb_size; i++) {
- pqp->qp = input_qp;
- pqp++;
- }
- gst_vaapi_surface_proxy_set_fei_qp (proxy, qp);
- }
-
- if (enable_mbcntrl) {
- GstVaapiEncFeiMbControl *mbcntrl = NULL;
- VAEncFEIMBControlH264 *pmbcntrl = NULL;
- guint mbcntrl_size = 0;
-
- mbcntrl_size = mb_width * mb_height * sizeof (VAEncFEIMBControlH264);
- mbcntrl =
- gst_vaapi_enc_fei_mb_control_new (app->encoder, NULL, mbcntrl_size);
- rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT
- (mbcntrl), &data, &size);
- assert (rt == 1);
-
- pmbcntrl = (VAEncFEIMBControlH264 *) data;
- for (i = 0; i < mb_size; i++) {
- pmbcntrl->force_to_intra = 1;
- pmbcntrl->force_to_skip = 0;
- pmbcntrl->force_to_nonskip = 0;
- pmbcntrl->enable_direct_bias_adjustment = 0;
- pmbcntrl->enable_motion_bias_adjustment = 0;
- pmbcntrl->ext_mv_cost_scaling_factor = 0;
- pmbcntrl->target_size_in_word = 0xff;
- pmbcntrl->max_size_in_word = 0xff;
- pmbcntrl++;
- }
- gst_vaapi_surface_proxy_set_fei_mb_control (proxy, mbcntrl);
- }
-
- if (enable_mvpred) {
- GstVaapiEncFeiMvPredictor *mvpred = NULL;
- VAEncFEIMVPredictorH264 *pmvpred = NULL;
- guint mvpred_size = 0, j;
-
- mvpred_size = mb_width * mb_height * sizeof (VAEncFEIMVPredictorH264);
- mvpred =
- gst_vaapi_enc_fei_mv_predictor_new (app->encoder, NULL,
- mvpred_size);
- rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT
- (mvpred), &data, &size);
- assert (rt == 1);
-
- pmvpred = (VAEncFEIMVPredictorH264 *) data;
- for (i = 0; i < mb_size; i++) {
- for (j = 0; i < 4; i++) {
- pmvpred->ref_idx[j].ref_idx_l0 = 0;
- pmvpred->ref_idx[j].ref_idx_l1 = 0;
-
- pmvpred->mv[j].mv0[0] = 0x8000;
- pmvpred->mv[j].mv0[1] = 0x8000;
- pmvpred->mv[j].mv1[0] = 0x8000;
- pmvpred->mv[j].mv1[1] = 0x8000;
- }
- pmvpred++;
- }
- gst_vaapi_surface_proxy_set_fei_mv_predictor (proxy, mvpred);
- }
- }
-
- if (!upload_frame (app->encoder, proxy)) {
- g_warning ("put frame failed");
- break;
- }
-
- app->read_frames++;
- id = gst_vaapi_surface_get_id (surface);
- g_debug ("input frame %d, surface id = %" G_GSIZE_FORMAT, app->read_frames,
- id);
-
- gst_vaapi_surface_proxy_unref (proxy);
- }
-
- app->input_stopped = TRUE;
-
- g_thread_join (buffer_thread);
-
- if (!app->encode_failed && feof (app->parser->fp))
- ret = EXIT_SUCCESS;
-
- gst_vaapi_video_pool_replace (&pool, NULL);
- gst_vaapi_image_unref (image);
- return ret;
-}
-
-int
-main (int argc, char *argv[])
-{
- App *app;
- int ret = EXIT_FAILURE;
- gchar *input_fn;
-
- if (!parse_options (&argc, argv))
- return EXIT_FAILURE;
-
- /* @TODO: iterate all the input files */
- input_fn = g_input_files ? g_input_files[0] : NULL;
- if (input_fn && !g_file_test (input_fn,
- G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
- g_warning ("input file \"%s\" doesn't exist", input_fn);
- goto bail;
- }
-
- app = app_new (input_fn, g_output_file_name);
- if (!app)
- goto bail;
- print_yuv_info (app);
- ret = app_run (app);
- print_num_frame (app);
-
- app_free (app);
-
-bail:
- g_free (g_codec_str);
- g_free (g_output_file_name);
- g_strfreev (g_input_files);
-
- gst_deinit ();
-
- return ret;
-}
diff --git a/tests/internal/test-fei-enc-out.c b/tests/internal/test-fei-enc-out.c
deleted file mode 100644
index 32326434..00000000
--- a/tests/internal/test-fei-enc-out.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * test-fei-enc-out.c - FEI Encoder Test application to dump output buffers
- *
- * Copyright (C) 2017 Intel Corporation
- *
- * 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
- */
-
-/* ./test-fei-enc -i sample_320x240.nv12 -f nv12 -w 320 -h 240 -o out.264 -v mv.out -d dist.out -m mbcode.out -e 1 */
-
-#include <stdio.h>
-#include <gst/gst.h>
-#include <gst/app/gstappsink.h>
-#include <stdlib.h>
-#include "../gst/vaapi/gstvaapifeivideometa.h"
-#include <gst/video/video.h>
-
-int
-main (int argc, char *argv[])
-{
- GstElement *pipeline, *filesrc, *videoparse, *enc, *capsfilter, *appsink;
- GError *err = NULL;
- GstStateChangeReturn ret;
- GstSample *sample;
- GstVideoFormat raw_format = GST_VIDEO_FORMAT_NV12;
- GOptionContext *ctx;
- FILE *file = NULL;
- FILE *mv_file = NULL;
- FILE *dist_file = NULL;
- FILE *mbcode_file = NULL;
- FILE *fei_stat_file = NULL;
- gchar *input_file_name = NULL;
- gchar *output_file_name = NULL;
- gchar *output_mv_name = NULL;
- gchar *output_distortion_name = NULL;
- gchar *output_mbcode_name = NULL;
- gchar *input_format;
- guint input_width;
- guint input_height;
- guint enc_frame_num = 0;
- guint block_size = 0;
- guint fei_mode = 1;
- guint fei_mode_flag = 0x00000004;
- gboolean link_ok = FALSE;
- guint mv_buffer_size = 0;
- guint mbcode_buffer_size = 0;
- guint dist_buffer_size = 0;
- gpointer mapped_data = NULL;
- guint mapped_data_size = 0;
- const gchar *caps_string = "video/x-h264, profile=constrained-baseline";
- GstCaps *filter_caps = NULL;
-
- GOptionEntry options[] = {
- {"input file", 'i', 0, G_OPTION_ARG_STRING, &input_file_name,
- "file to encode", NULL},
- {"output file", 'o', 0, G_OPTION_ARG_STRING, &output_file_name,
- "encpak output file", NULL},
- {"output mv file", 'v', 0, G_OPTION_ARG_STRING, &output_mv_name,
- "encpak mv output file", NULL},
- {"output distortion file", 'd', 0, G_OPTION_ARG_STRING,
- &output_distortion_name,
- "encpak distortion output file", NULL},
- {"output mbcode file", 'm', 0, G_OPTION_ARG_STRING, &output_mbcode_name,
- "encpak mbcode output file", NULL},
- {"format", 'f', 0, G_OPTION_ARG_STRING, &input_format,
- "input raw format: nv12 or i420", NULL},
- {"width", 'w', 0, G_OPTION_ARG_INT, &input_width,
- "input stream width", NULL},
- {"height", 'h', 0, G_OPTION_ARG_INT, &input_height,
- "input stream height", NULL},
- {"frame-num", 'n', 0, G_OPTION_ARG_INT, &enc_frame_num,
- "numumber of buffers to be encoded", NULL},
- {"blocksize", 's', 0, G_OPTION_ARG_INT, &block_size,
- "single buffer size of input stream", NULL},
- {"fei-mode", 'e', 0, G_OPTION_ARG_INT, &fei_mode,
- "1: ENC_PAK 2: ENC+PAK", NULL},
- {NULL}
- };
-
- ctx =
- g_option_context_new
- ("encpak with element filesrc, videoparse, vaapih264feienc, appsink");
- g_option_context_add_main_entries (ctx, options, NULL);
- g_option_context_add_group (ctx, gst_init_get_option_group ());
-
- if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
- g_print ("Error intializing: %s\n", err->message);
- g_option_context_free (ctx);
- g_clear_error (&err);
- return -1;
- }
-
- if (input_file_name == NULL || output_file_name == NULL) {
- g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL));
- g_option_context_free (ctx);
- return -1;
- }
-
- if (!g_strcmp0 (input_format, "nv12"))
- raw_format = GST_VIDEO_FORMAT_NV12;
- else if (!g_strcmp0 (input_format, "i420"))
- raw_format = GST_VIDEO_FORMAT_I420;
- else
- return -1;
-
- if (!input_width || !input_height) {
- g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL));
- g_option_context_free (ctx);
- return -1;
- }
-
- switch (fei_mode) {
- case 1:
- fei_mode_flag = 0x00000004;
- break;
- case 2:
- fei_mode_flag = 0x00000001 | 0x00000002;
- break;
- default:
- printf ("Unknown fei mode \n");
- g_assert (0);
- break;
- }
-
- g_option_context_free (ctx);
-
- gst_init (&argc, &argv);
-
- /* create pipeline */
- pipeline = gst_pipeline_new ("pipeline");
- filesrc = gst_element_factory_make ("filesrc", "source");
- videoparse = gst_element_factory_make ("videoparse", "videoparse");
- enc = gst_element_factory_make ("vaapih264feienc", "encpak");
- capsfilter = gst_element_factory_make ("capsfilter", "enccaps");
- appsink = gst_element_factory_make ("appsink", "sink");
-
- /* element prop setup */
- g_object_set (G_OBJECT (filesrc), "location", input_file_name, NULL);
- g_object_set (G_OBJECT (videoparse), "format", raw_format,
- "width", input_width, "height", input_height, NULL);
-
- if (enc_frame_num != 0)
- g_object_set (G_OBJECT (filesrc), "num-buffers", enc_frame_num, NULL);
- if (block_size != 0)
- g_object_set (G_OBJECT (filesrc), "blocksize", block_size, NULL);
-
- g_object_set (G_OBJECT (enc), "fei-mode", fei_mode_flag, NULL);
- g_object_set (G_OBJECT (enc), "search-window", 5, NULL);
- g_object_set (G_OBJECT (enc), "max-bframes", 0, NULL);
-
- filter_caps = gst_caps_from_string (caps_string);
- if (filter_caps)
- g_object_set (G_OBJECT (capsfilter), "caps", filter_caps, NULL);
- gst_caps_unref (filter_caps);
-
- gst_bin_add_many (GST_BIN (pipeline), filesrc, videoparse, enc, capsfilter,
- appsink, NULL);
-
- link_ok =
- gst_element_link_many (filesrc, videoparse, enc, capsfilter, appsink,
- NULL);
- if (!link_ok) {
- g_print ("filesrc, enc and appsink link fail");
- return -1;
- }
-
- file = fopen (output_file_name, "wb");
-
- if (output_mv_name != NULL)
- mv_file = fopen (output_mv_name, "wb");
-
- if (output_mbcode_name != NULL)
- mbcode_file = fopen (output_mbcode_name, "wb");
-
- if (output_distortion_name != NULL)
- dist_file = fopen (output_distortion_name, "wb");
-
- ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE) {
- g_printerr ("Unable to set the pipeline to the playing state.\n");
- gst_object_unref (pipeline);
- return -1;
- }
-
- /* pull sample from pipeline */
- while (1) {
- g_signal_emit_by_name (appsink, "pull-sample", &sample, NULL);
- if (sample) {
- GstBuffer *buffer = NULL;
- GstMapInfo map, info;
- GstMemory *mem;
- GstVaapiFeiVideoMeta *meta = NULL;
- GstMeta *m = NULL;
- const GstMetaInfo *meta_info;
- GType api;
-
- g_debug ("appsink received sample.\n");
- buffer = gst_sample_get_buffer (sample);
- if (gst_buffer_map (buffer, &map, GST_MAP_READ)) {
- mem = gst_buffer_peek_memory (buffer, 0);
- if (gst_memory_map (mem, &info, GST_MAP_READ))
- fwrite (info.data, 1, info.size, file);
-
- gst_memory_unmap (mem, &info);
- gst_buffer_unmap (buffer, &map);
- }
-
- meta_info = gst_meta_get_info ("GstVaapiFeiVideoMeta");
- api = meta_info->api;
- m = gst_buffer_get_meta (buffer, api);
- if (m != NULL)
- meta = ((GstVaapiFeiVideoMetaHolder *) (m))->meta;
-
- if (meta != NULL) {
-
- if (mv_file != NULL) {
- mapped_data = NULL;
- mapped_data_size = 0;
- if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mv), &mapped_data, &mapped_data_size)) {
- fwrite (mapped_data, 1, mapped_data_size, mv_file);
- gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mv));
- mv_buffer_size = mapped_data_size;
- }
- }
-
- if (mbcode_file != NULL) {
- mapped_data = NULL;
- mapped_data_size = 0;
- if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mbcode), &mapped_data, &mapped_data_size)) {
- fwrite (mapped_data, 1, mapped_data_size, mbcode_file);
- gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->mbcode));
- mbcode_buffer_size = mapped_data_size;
- }
- }
-
- if (dist_file != NULL) {
- mapped_data = NULL;
- mapped_data_size = 0;
- if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->dist), &mapped_data, &mapped_data_size)) {
- fwrite (mapped_data, 1, mapped_data_size, dist_file);
- gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT
- (meta->dist));
- dist_buffer_size = mapped_data_size;
- }
- }
- }
-
- gst_sample_unref (sample);
- } else {
- g_print ("appsink finished receive sample.\n");
- break;
- }
- }
-
- /* Fixme: Currently assuming the input video has only one resoultion
- * which may not be true */
- /* create a status file for dumping size of each fei output buffer */
- if (output_mv_name || output_mbcode_name || output_distortion_name) {
- fei_stat_file = fopen ("fei_stat.out", "wb");
- fprintf (fei_stat_file, "Frame_MotionVectorData_Buffer_Size => %d \n",
- mv_buffer_size);
- fprintf (fei_stat_file, "Frame_MacroblcokCode_Buffer_Size => %d \n",
- mbcode_buffer_size);
- fprintf (fei_stat_file, "Frame_Distortion_Buffer_Size => %d \n",
- dist_buffer_size);
- }
-
- /* free */
- fclose (file);
- if (mv_file != NULL)
- fclose (mv_file);
- if (mbcode_file != NULL)
- fclose (mbcode_file);
- if (dist_file != NULL)
- fclose (dist_file);
- if (fei_stat_file)
- fclose (fei_stat_file);
-
- gst_element_set_state (pipeline, GST_STATE_NULL);
- gst_object_unref (pipeline);
- return 0;
-}