h264encoder: auto-detect stream-format: avc/byte-stream by next linked-pad's caps
authorWind Yuan <feng.yuan@intel.com>
Thu, 21 Jun 2012 06:46:43 +0000 (14:46 +0800)
committerZhong Cong <congx.zhong@intel.com>
Tue, 5 Feb 2013 07:37:11 +0000 (15:37 +0800)
gst/vaapiencode/gstvaapiencode.c
gst/vaapiencode/gstvaapiencoder.h
gst/vaapiencode/gstvaapih264encode.c
gst/vaapiencode/gstvaapih264encoder.c
gst/vaapiencode/gstvaapih264encoder.h

index 7724418..8968097 100644 (file)
@@ -312,6 +312,10 @@ gst_vaapi_encode_set_caps(GstPad *sink_pad, GstCaps *caps)
   gst_structure_set(src_struct, "width", G_TYPE_INT, width,
                     "height", G_TYPE_INT, height,
                     "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
+  GstVaapiEncodeClass *encode_class = GST_VAAPI_ENCODE_GET_CLASS(encode);
+  if (encode_class->set_encoder_src_caps) {
+    encode_class->set_encoder_src_caps(encode, encode->srcpad_caps);
+  }
 
   /*set display and initialize encoder*/
   ENCODER_CHECK_STATUS(gst_vaapi_ensure_display(encode, &ENCODER_DISPLAY(encode->encoder)),
@@ -378,7 +382,6 @@ gst_vaapi_encode_chain(GstPad *sink_pad, GstBuffer *buf)
 {
   GstFlowReturn ret = GST_FLOW_OK;
   GstVaapiEncode *encode = GST_VAAPI_ENCODE(GST_OBJECT_PARENT(sink_pad));
-  GstVaapiEncodeClass *encode_class = GST_VAAPI_ENCODE_GET_CLASS(encode);
   EncoderStatus encoder_ret = ENCODER_NO_ERROR;
   GList *out_buffers = NULL;
   GstBuffer *tmp_buffer = NULL;
@@ -415,9 +418,6 @@ gst_vaapi_encode_chain(GstPad *sink_pad, GstBuffer *buf)
       if (ENCODER_NO_ERROR == gst_vaapi_encoder_get_codec_data(encode->encoder, &codec_data) && codec_data) {
         gst_caps_set_simple(encode->srcpad_caps, "codec_data",GST_TYPE_BUFFER, codec_data, NULL);
       }
-      if (encode_class->set_encoder_src_caps) {
-        encode_class->set_encoder_src_caps(encode, encode->srcpad_caps);
-      }
       gst_pad_set_caps (encode->srcpad, encode->srcpad_caps);
       GST_BUFFER_CAPS(tmp_buffer) = gst_caps_ref(encode->srcpad_caps);
       ENCODER_LOG_INFO("gst_vaapi_encode_chain 1st push-buffer caps,\n%s", _encode_dump_caps(encode->srcpad_caps));
index db97580..530e4f7 100644 (file)
@@ -33,8 +33,9 @@
 G_BEGIN_DECLS
 
 #define ENCODER_NO_ERROR       0
-#define ENCODER_BUFFER_WAITING 1
-#define ENCODER_BUFFER_EMPTY   2
+#define ENCODER_NO_DATA        1
+#define ENCODER_BUFFER_WAITING 2
+#define ENCODER_BUFFER_EMPTY   3
 
 
 #define ENCODER_MEM_ERR       -1
index c79597a..6d8b7bb 100644 (file)
@@ -22,6 +22,8 @@
 #include "gstvaapih264encode.h"
 #include "gstvaapih264encoder.h"
 
+#include <string.h>
+
 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug);
 #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug
 
@@ -369,8 +371,34 @@ _h264_check_valid_level(guint level)
 static gboolean
 gst_h264encode_set_src_caps(GstVaapiEncode* encode, GstCaps *caps)
 {
+  GstH264Encoder *h264encoder = GST_H264_ENCODER(encode->encoder);
+  GstCaps *peer_caps, *allowed_caps;
+  GstStructure *s;
+  const gchar *stream_format;
+
   g_return_val_if_fail(caps,FALSE);
-  gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "avc",
+  peer_caps = gst_pad_peer_get_caps_reffed(encode->srcpad);
+  if (peer_caps) {
+    allowed_caps = gst_caps_intersect(peer_caps, caps);
+    if (allowed_caps) {
+      allowed_caps = gst_caps_make_writable(allowed_caps);
+      gst_pad_fixate_caps(encode->srcpad, caps);
+      s = gst_caps_get_structure (allowed_caps, 0);
+      stream_format = gst_structure_get_string (s, "stream-format");
+      if (stream_format) {
+        if (!strcmp (stream_format, "avc")) {
+            gst_h264_encoder_set_avc_flag(h264encoder, TRUE);
+        } else if (!strcmp (stream_format, "byte-stream")) {
+            gst_h264_encoder_set_avc_flag(h264encoder, FALSE);
+        }
+      }
+      gst_caps_unref(allowed_caps);
+    }
+    gst_caps_unref(peer_caps);
+  }
+  gst_caps_set_simple(caps, "stream-format",
+                            G_TYPE_STRING,
+                            (gst_h264_encoder_get_avc_flag(h264encoder) ? "avc" : "byte-stream"),
                             "alignment", G_TYPE_STRING, "au",
                             NULL);
   return TRUE;
index 71b3e63..3b4e622 100644 (file)
@@ -86,7 +86,7 @@ typedef enum {
 struct _GstH264EncoderPrivate {
   GstH264Encoder   *public;
   guint32           format;   /*NV12, I420,*/
-  gboolean          es_flag;  /*elementary flag*/
+  gboolean          avc_flag;  /*elementary flag*/
 
   /* private data*/
   GQueue           *video_buffer_caches; /*not used for baseline*/
@@ -146,10 +146,9 @@ static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDi
                                     GstVaapiContext *context, GList **coded_pics);
 
 /*other functions*/
-static EncoderStatus gst_h264_encoder_get_avcC_codec_data(
+/*other functions*/
+static EncoderStatus gst_h264_encoder_get_codec_data(
                                     GstVaapiEncoder* encoder, GstBuffer **buffer);
-static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
-
 static gboolean      gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
 static void          gst_h264_encoder_finalize(GObject *object);
 static void          gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
@@ -217,8 +216,7 @@ gst_h264_encoder_class_init(GstH264EncoderClass *klass)
 
   encoder_class->flush = gst_h264_encoder_flush;
 
-  encoder_class->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
-  /* encoder_class->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
+  encoder_class->get_codec_data = gst_h264_encoder_get_codec_data;
 
   /*
   object_class->set_property = gst_h264_encoder_set_property;
@@ -258,8 +256,7 @@ gst_h264_encoder_init(GstH264Encoder *encoder)
 
   /* init private values*/
   h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
-  h264_prv->es_flag = TRUE;
-  //h264_prv->es_flag = FALSE;
+  h264_prv->avc_flag = FALSE;
 
   h264_prv->ref_surface1 = NULL;
   h264_prv->ref_surface2 = NULL;
@@ -342,12 +339,18 @@ gst_h264_encoder_init_public_values(GstH264Encoder* encoder)
 }
 
 void
-gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es)
+gst_h264_encoder_set_avc_flag(GstH264Encoder* encoder, gboolean avc)
 {
   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
-  h264_prv->es_flag = es;
+  h264_prv->avc_flag = avc;
 }
 
+gboolean
+gst_h264_encoder_get_avc_flag(GstH264Encoder* encoder)
+{
+  GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
+  return h264_prv->avc_flag;
+}
 
 gboolean
 gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
@@ -1219,7 +1222,7 @@ gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
   h264_bitstream_align(&bitstream, 0);
   ENCODER_ASSERT(bitstream.bit_size == 0);
 
-  if (!h264_prv->es_flag) { /*nal format*/
+  if (!h264_prv->avc_flag) { /*nal format*/
     h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
     ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
   } else { /* elementary format */
@@ -1443,9 +1446,8 @@ int main_test(int argc, char* argv[])
 }
 
 EncoderStatus
-gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
+gst_h264_encoder_get_avcC_codec_data(GstH264Encoder *h264_encoder, GstBuffer **buffer)
 {
-  GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
   GstBuffer *avc_codec;
   const guint32 configuration_version = 0x01;
@@ -1502,6 +1504,18 @@ gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffe
   return ENCODER_NO_ERROR;
 }
 
+static EncoderStatus
+gst_h264_encoder_get_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer)
+{
+  GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
+  GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
+
+  if (h264_prv->avc_flag)
+    return gst_h264_encoder_get_avcC_codec_data(h264_encoder, buffer);
+  return ENCODER_NO_DATA;
+}
+
+#if 0
 EncoderStatus
 gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
 {
@@ -1535,6 +1549,7 @@ gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer
   *buffer = nal_sps_pps;
   return ENCODER_NO_ERROR;
 }
+#endif
 
 static void
 h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
index befcb89..c67b297 100644 (file)
@@ -105,7 +105,9 @@ static inline void gst_h264_encoder_unref (GstH264Encoder * encoder)
   g_object_unref (encoder);
 }
 
-void     gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es);
+void     gst_h264_encoder_set_avc_flag(GstH264Encoder* encoder, gboolean avc);
+gboolean gst_h264_encoder_get_avc_flag(GstH264Encoder* encoder);
+
 
 
 G_END_DECLS