mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
schro: Add support for video metadata and arbitrary strides
This commit is contained in:
parent
47546ab2df
commit
a7ae20305a
4 changed files with 102 additions and 33 deletions
|
@ -24,6 +24,8 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstadapter.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
#include <gst/video/gstvideometa.h>
|
||||||
|
#include <gst/video/gstvideopool.h>
|
||||||
#include <gst/video/gstvideodecoder.h>
|
#include <gst/video/gstvideodecoder.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <schroedinger/schro.h>
|
#include <schroedinger/schro.h>
|
||||||
|
@ -89,6 +91,8 @@ static GstFlowReturn gst_schro_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
GstVideoCodecFrame * frame);
|
GstVideoCodecFrame * frame);
|
||||||
static gboolean gst_schro_dec_finish (GstVideoDecoder * base_video_decoder);
|
static gboolean gst_schro_dec_finish (GstVideoDecoder * base_video_decoder);
|
||||||
static void gst_schrodec_send_tags (GstSchroDec * schro_dec);
|
static void gst_schrodec_send_tags (GstSchroDec * schro_dec);
|
||||||
|
static gboolean gst_schro_dec_decide_allocation (GstVideoDecoder * decoder,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_schro_dec_sink_template =
|
static GstStaticPadTemplate gst_schro_dec_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
@ -136,6 +140,8 @@ gst_schro_dec_class_init (GstSchroDecClass * klass)
|
||||||
base_video_decoder_class->handle_frame =
|
base_video_decoder_class->handle_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_schro_dec_handle_frame);
|
GST_DEBUG_FUNCPTR (gst_schro_dec_handle_frame);
|
||||||
base_video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_schro_dec_finish);
|
base_video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_schro_dec_finish);
|
||||||
|
base_video_decoder_class->decide_allocation =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_schro_dec_decide_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -457,10 +463,7 @@ gst_schro_dec_process (GstSchroDec * schro_dec, gboolean eos)
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER
|
gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER
|
||||||
(schro_dec));
|
(schro_dec));
|
||||||
schro_frame =
|
schro_frame = gst_schro_buffer_wrap (outbuf, TRUE, &state->info);
|
||||||
gst_schro_buffer_wrap (outbuf, TRUE,
|
|
||||||
GST_VIDEO_INFO_FORMAT (&state->info), state->info.width,
|
|
||||||
state->info.height);
|
|
||||||
schro_decoder_add_output_picture (schro_dec->decoder, schro_frame);
|
schro_decoder_add_output_picture (schro_dec->decoder, schro_frame);
|
||||||
gst_video_codec_state_unref (state);
|
gst_video_codec_state_unref (state);
|
||||||
break;
|
break;
|
||||||
|
@ -552,3 +555,26 @@ gst_schro_dec_finish (GstVideoDecoder * base_video_decoder)
|
||||||
|
|
||||||
return gst_schro_dec_process (schro_dec, TRUE);
|
return gst_schro_dec_process (schro_dec, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_schro_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
|
{
|
||||||
|
GstBufferPool *pool;
|
||||||
|
GstStructure *config;
|
||||||
|
|
||||||
|
if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder,
|
||||||
|
query))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
|
||||||
|
gst_buffer_pool_config_add_option (config,
|
||||||
|
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_unref (pool);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
#include <gst/video/gstvideometa.h>
|
||||||
#include <gst/video/gstvideoencoder.h>
|
#include <gst/video/gstvideoencoder.h>
|
||||||
#include <gst/video/gstvideoutils.h>
|
#include <gst/video/gstvideoutils.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -104,6 +105,8 @@ static GstFlowReturn gst_schro_enc_handle_frame (GstVideoEncoder *
|
||||||
static GstFlowReturn gst_schro_enc_pre_push (GstVideoEncoder *
|
static GstFlowReturn gst_schro_enc_pre_push (GstVideoEncoder *
|
||||||
base_video_encoder, GstVideoCodecFrame * frame);
|
base_video_encoder, GstVideoCodecFrame * frame);
|
||||||
static void gst_schro_enc_finalize (GObject * object);
|
static void gst_schro_enc_finalize (GObject * object);
|
||||||
|
static gboolean gst_schro_enc_propose_allocation (GstVideoEncoder * encoder,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_schro_enc_sink_template =
|
static GstStaticPadTemplate gst_schro_enc_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
@ -214,6 +217,8 @@ gst_schro_enc_class_init (GstSchroEncClass * klass)
|
||||||
basevideocoder_class->handle_frame =
|
basevideocoder_class->handle_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_schro_enc_handle_frame);
|
GST_DEBUG_FUNCPTR (gst_schro_enc_handle_frame);
|
||||||
basevideocoder_class->pre_push = GST_DEBUG_FUNCPTR (gst_schro_enc_pre_push);
|
basevideocoder_class->pre_push = GST_DEBUG_FUNCPTR (gst_schro_enc_pre_push);
|
||||||
|
basevideocoder_class->propose_allocation =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_schro_enc_propose_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -525,9 +530,7 @@ gst_schro_enc_handle_frame (GstVideoEncoder * base_video_encoder,
|
||||||
|
|
||||||
/* FIXME : We could make that method just take GstVideoInfo ... */
|
/* FIXME : We could make that method just take GstVideoInfo ... */
|
||||||
schro_frame = gst_schro_buffer_wrap (gst_buffer_ref (frame->input_buffer),
|
schro_frame = gst_schro_buffer_wrap (gst_buffer_ref (frame->input_buffer),
|
||||||
FALSE,
|
FALSE, info);
|
||||||
GST_VIDEO_INFO_FORMAT (info),
|
|
||||||
GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
|
|
||||||
|
|
||||||
GST_DEBUG ("pushing frame %p", frame);
|
GST_DEBUG ("pushing frame %p", frame);
|
||||||
schro_encoder_push_frame_full (schro_enc->encoder, schro_frame, frame);
|
schro_encoder_push_frame_full (schro_enc->encoder, schro_frame, frame);
|
||||||
|
@ -580,6 +583,16 @@ gst_schro_enc_pre_push (GstVideoEncoder * base_video_encoder,
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_schro_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
|
||||||
|
{
|
||||||
|
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||||
|
|
||||||
|
return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
|
||||||
|
query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_schro_enc_process (GstSchroEnc * schro_enc)
|
gst_schro_enc_process (GstSchroEnc * schro_enc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,8 +38,7 @@ GST_DEBUG_CATEGORY_EXTERN (schro_debug);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstBuffer *buf;
|
GstVideoFrame frame;
|
||||||
GstMapInfo info;
|
|
||||||
} FrameData;
|
} FrameData;
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,8 +47,7 @@ gst_schro_frame_free (SchroFrame * frame, void *priv)
|
||||||
{
|
{
|
||||||
FrameData *data = priv;
|
FrameData *data = priv;
|
||||||
|
|
||||||
gst_buffer_unmap (data->buf, &data->info);
|
gst_video_frame_unmap (&data->frame);
|
||||||
gst_buffer_unref (data->buf);
|
|
||||||
|
|
||||||
g_slice_free (FrameData, data);
|
g_slice_free (FrameData, data);
|
||||||
}
|
}
|
||||||
|
@ -58,58 +56,62 @@ GstBuffer *
|
||||||
gst_schro_frame_get_buffer (SchroFrame * frame)
|
gst_schro_frame_get_buffer (SchroFrame * frame)
|
||||||
{
|
{
|
||||||
if (frame->priv)
|
if (frame->priv)
|
||||||
return gst_buffer_ref (((FrameData *) frame->priv)->buf);
|
return gst_buffer_ref (((FrameData *) frame->priv)->frame.buffer);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SchroFrame *
|
SchroFrame *
|
||||||
gst_schro_buffer_wrap (GstBuffer * buf, gboolean write, GstVideoFormat format,
|
gst_schro_buffer_wrap (GstBuffer * buf, gboolean write, GstVideoInfo * vinfo)
|
||||||
int width, int height)
|
|
||||||
{
|
{
|
||||||
SchroFrame *frame;
|
SchroFrame *frame;
|
||||||
GstMapInfo info;
|
GstVideoFrame vframe;
|
||||||
FrameData *data;
|
FrameData *data;
|
||||||
|
gint i;
|
||||||
|
|
||||||
if (!gst_buffer_map (buf, &info, (write ? GST_MAP_READWRITE : GST_MAP_READ)))
|
if (!gst_video_frame_map (&vframe, vinfo, buf,
|
||||||
|
(write ? GST_MAP_READWRITE : GST_MAP_READ)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch (format) {
|
frame = schro_frame_new ();
|
||||||
|
|
||||||
|
frame->width = GST_VIDEO_FRAME_WIDTH (&vframe);
|
||||||
|
frame->height = GST_VIDEO_FRAME_HEIGHT (&vframe);
|
||||||
|
|
||||||
|
switch (GST_VIDEO_FRAME_FORMAT (&vframe)) {
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
frame = schro_frame_new_from_data_I420 (info.data, width, height);
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_FORMAT_YV12:
|
case GST_VIDEO_FORMAT_YV12:
|
||||||
frame = schro_frame_new_from_data_YV12 (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_U8_420;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
frame = schro_frame_new_from_data_YUY2 (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_YUYV;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
frame = schro_frame_new_from_data_UYVY (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_UYVY;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_AYUV:
|
case GST_VIDEO_FORMAT_AYUV:
|
||||||
frame = schro_frame_new_from_data_AYUV (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_AYUV;
|
||||||
break;
|
break;
|
||||||
#if SCHRO_CHECK_VERSION(1,0,12)
|
#if SCHRO_CHECK_VERSION(1,0,12)
|
||||||
case GST_VIDEO_FORMAT_ARGB:
|
case GST_VIDEO_FORMAT_ARGB:
|
||||||
frame = schro_frame_new_from_data_ARGB (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_ARGB;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if SCHRO_CHECK_VERSION(1,0,11)
|
#if SCHRO_CHECK_VERSION(1,0,11)
|
||||||
case GST_VIDEO_FORMAT_Y42B:
|
case GST_VIDEO_FORMAT_Y42B:
|
||||||
frame = schro_frame_new_from_data_Y42B (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_U8_422;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_Y444:
|
case GST_VIDEO_FORMAT_Y444:
|
||||||
frame = schro_frame_new_from_data_Y444 (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_U8_444;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_v210:
|
case GST_VIDEO_FORMAT_v210:
|
||||||
frame = schro_frame_new_from_data_v210 (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_v210;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_v216:
|
case GST_VIDEO_FORMAT_v216:
|
||||||
frame = schro_frame_new_from_data_v216 (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_v216;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_AYUV64:
|
case GST_VIDEO_FORMAT_AYUV64:
|
||||||
frame = schro_frame_new_from_data_AY64 (info.data, width, height);
|
frame->format = SCHRO_FRAME_FORMAT_AY64;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -117,9 +119,38 @@ gst_schro_buffer_wrap (GstBuffer * buf, gboolean write, GstVideoFormat format,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCHRO_FRAME_IS_PACKED (frame->format)) {
|
||||||
|
frame->components[0].format = frame->format;
|
||||||
|
frame->components[0].width = frame->width;
|
||||||
|
frame->components[0].height = frame->height;
|
||||||
|
frame->components[0].stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
|
||||||
|
frame->components[0].length = frame->components[0].stride * frame->height;
|
||||||
|
frame->components[0].data = vframe.data[0];
|
||||||
|
frame->components[0].v_shift = 0;
|
||||||
|
frame->components[0].h_shift = 0;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < GST_VIDEO_FRAME_N_COMPONENTS (&vframe); i++) {
|
||||||
|
frame->components[i].format = frame->format;
|
||||||
|
frame->components[i].width = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, i);
|
||||||
|
frame->components[i].height = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, i);
|
||||||
|
frame->components[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, i);
|
||||||
|
frame->components[i].length =
|
||||||
|
frame->components[i].stride * frame->components[i].height;
|
||||||
|
frame->components[i].data = GST_VIDEO_FRAME_COMP_DATA (&vframe, i);
|
||||||
|
if (i == 0) {
|
||||||
|
frame->components[i].v_shift = 0;
|
||||||
|
frame->components[i].h_shift = 0;
|
||||||
|
} else {
|
||||||
|
frame->components[i].v_shift =
|
||||||
|
SCHRO_FRAME_FORMAT_H_SHIFT (frame->format);
|
||||||
|
frame->components[i].h_shift =
|
||||||
|
SCHRO_FRAME_FORMAT_H_SHIFT (frame->format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data = g_slice_new0 (FrameData);
|
data = g_slice_new0 (FrameData);
|
||||||
data->buf = buf;
|
data->frame = vframe;
|
||||||
data->info = info;
|
|
||||||
schro_frame_set_free_callback (frame, gst_schro_frame_free, data);
|
schro_frame_set_free_callback (frame, gst_schro_frame_free, data);
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
|
|
|
@ -35,8 +35,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SchroFrame *
|
SchroFrame *
|
||||||
gst_schro_buffer_wrap (GstBuffer *buf, gboolean write, GstVideoFormat format, int width,
|
gst_schro_buffer_wrap (GstBuffer *buf, gboolean write, GstVideoInfo * vinfo);
|
||||||
int height);
|
|
||||||
GstBuffer * gst_schro_frame_get_buffer (SchroFrame * frame);
|
GstBuffer * gst_schro_frame_get_buffer (SchroFrame * frame);
|
||||||
|
|
||||||
GstBuffer * gst_schro_wrap_schro_buffer (SchroBuffer *buffer);
|
GstBuffer * gst_schro_wrap_schro_buffer (SchroBuffer *buffer);
|
||||||
|
|
Loading…
Reference in a new issue