mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-28 23:02:22 +00:00
webpenc: fix naming and libwebp API calls
- uniformize parameters naming - call symetric init and clear functions systematically from libwebp API Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5994>
This commit is contained in:
parent
a6409525ef
commit
9fe504c423
1 changed files with 72 additions and 66 deletions
|
@ -21,7 +21,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h> /* free */
|
|
||||||
|
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/video/gstvideometa.h>
|
#include <gst/video/gstvideometa.h>
|
||||||
|
@ -51,15 +50,15 @@ static void gst_webp_enc_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
static void gst_webp_enc_get_property (GObject * object, guint prop_id,
|
static void gst_webp_enc_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static gboolean gst_webp_enc_start (GstVideoEncoder * benc);
|
static gboolean gst_webp_enc_start (GstVideoEncoder * encoder);
|
||||||
static gboolean gst_webp_enc_stop (GstVideoEncoder * benc);
|
static gboolean gst_webp_enc_stop (GstVideoEncoder * encoder);
|
||||||
static gboolean gst_webp_enc_set_format (GstVideoEncoder * encoder,
|
static gboolean gst_webp_enc_set_format (GstVideoEncoder * encoder,
|
||||||
GstVideoCodecState * state);
|
GstVideoCodecState * state);
|
||||||
static GstFlowReturn gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
|
static GstFlowReturn gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
GstVideoCodecFrame * frame);
|
GstVideoCodecFrame * frame);
|
||||||
static gboolean gst_webp_enc_propose_allocation (GstVideoEncoder * encoder,
|
static gboolean gst_webp_enc_propose_allocation (GstVideoEncoder * encoder,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
static GstFlowReturn gst_webp_enc_finish (GstVideoEncoder * benc);
|
static GstFlowReturn gst_webp_enc_finish (GstVideoEncoder * encoder);
|
||||||
|
|
||||||
static GstStaticPadTemplate webp_enc_sink_factory =
|
static GstStaticPadTemplate webp_enc_sink_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
@ -223,8 +222,7 @@ gst_webp_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enc->animated) {
|
if (enc->animated) {
|
||||||
WebPAnimEncoderOptions enc_options = { {0}
|
WebPAnimEncoderOptions enc_options = { 0 };
|
||||||
};
|
|
||||||
WebPAnimEncoderOptionsInit (&enc_options);
|
WebPAnimEncoderOptionsInit (&enc_options);
|
||||||
enc->anim_enc =
|
enc->anim_enc =
|
||||||
WebPAnimEncoderNew (info->width, info->height, &enc_options);
|
WebPAnimEncoderNew (info->width, info->height, &enc_options);
|
||||||
|
@ -239,16 +237,13 @@ gst_webp_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_webp_set_picture_params (GstWebpEnc * enc)
|
gst_webp_enc_init_picture (GstWebpEnc * enc)
|
||||||
{
|
{
|
||||||
GstVideoInfo *info;
|
GstVideoInfo *info = &enc->input_state->info;
|
||||||
gboolean ret = TRUE;
|
|
||||||
|
|
||||||
info = &enc->input_state->info;
|
|
||||||
|
|
||||||
if (!WebPPictureInit (&enc->webp_picture)) {
|
if (!WebPPictureInit (&enc->webp_picture)) {
|
||||||
ret = FALSE;
|
GST_ERROR_OBJECT (enc, "Failed to Initialize WebPPicture !");
|
||||||
goto failed_pic_init;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enc->webp_picture.use_argb = enc->use_argb;
|
enc->webp_picture.use_argb = enc->use_argb;
|
||||||
|
@ -262,13 +257,14 @@ gst_webp_set_picture_params (GstWebpEnc * enc)
|
||||||
enc->webp_picture.writer = WebPMemoryWrite;
|
enc->webp_picture.writer = WebPMemoryWrite;
|
||||||
enc->webp_picture.custom_ptr = &enc->webp_writer;
|
enc->webp_picture.custom_ptr = &enc->webp_writer;
|
||||||
|
|
||||||
return ret;
|
return TRUE;
|
||||||
|
|
||||||
failed_pic_init:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (enc, "Failed to Initialize WebPPicture !");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_webp_enc_clear_picture (GstWebpEnc * enc)
|
||||||
|
{
|
||||||
|
WebPMemoryWriterClear (&enc->webp_writer);
|
||||||
|
WebPPictureFree (&enc->webp_picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -280,11 +276,14 @@ gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
|
|
||||||
GST_LOG_OBJECT (enc, "got new frame");
|
GST_LOG_OBJECT (enc, "got new frame");
|
||||||
|
|
||||||
gst_webp_set_picture_params (enc);
|
if (!gst_webp_enc_init_picture (enc))
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
if (!gst_video_frame_map (&vframe, &enc->input_state->info,
|
if (!gst_video_frame_map (&vframe, &enc->input_state->info,
|
||||||
frame->input_buffer, GST_MAP_READ))
|
frame->input_buffer, GST_MAP_READ)) {
|
||||||
|
gst_webp_enc_clear_picture (enc);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!enc->use_argb) {
|
if (!enc->use_argb) {
|
||||||
enc->webp_picture.y = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
|
enc->webp_picture.y = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
|
||||||
|
@ -311,10 +310,9 @@ gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enc->animated) {
|
if (enc->anim_enc) {
|
||||||
/* in milliseconds */
|
/* Webp timestamps are in milliseconds */
|
||||||
int timestamp = frame->pts / 1000000;
|
int timestamp = frame->pts / 1000000;
|
||||||
|
|
||||||
enc->next_timestamp = (frame->pts + frame->duration) / 1000000;
|
enc->next_timestamp = (frame->pts + frame->duration) / 1000000;
|
||||||
|
|
||||||
if (!WebPAnimEncoderAdd (enc->anim_enc, &enc->webp_picture,
|
if (!WebPAnimEncoderAdd (enc->anim_enc, &enc->webp_picture,
|
||||||
|
@ -322,34 +320,35 @@ gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
GST_ERROR_OBJECT (enc, "Failed to add WebPPicture: %d (%s)",
|
GST_ERROR_OBJECT (enc, "Failed to add WebPPicture: %d (%s)",
|
||||||
enc->webp_picture.error_code,
|
enc->webp_picture.error_code,
|
||||||
WebPAnimEncoderGetError (enc->anim_enc));
|
WebPAnimEncoderGetError (enc->anim_enc));
|
||||||
gst_video_frame_unmap (&vframe);
|
goto error;
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
WebPPictureFree (&enc->webp_picture);
|
} else {
|
||||||
} else if (WebPEncode (&enc->webp_config, &enc->webp_picture)) {
|
|
||||||
GstBuffer *out_buffer;
|
GstBuffer *out_buffer;
|
||||||
|
|
||||||
WebPPictureFree (&enc->webp_picture);
|
if (!WebPEncode (&enc->webp_config, &enc->webp_picture)) {
|
||||||
|
GST_ERROR_OBJECT (enc, "Failed to encode WebPPicture");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
out_buffer = gst_buffer_new_allocate (NULL, enc->webp_writer.size, NULL);
|
out_buffer = gst_buffer_new_allocate (NULL, enc->webp_writer.size, NULL);
|
||||||
if (!out_buffer) {
|
if (!out_buffer) {
|
||||||
GST_ERROR_OBJECT (enc, "Failed to create output buffer");
|
GST_ERROR_OBJECT (enc, "Failed to create output buffer");
|
||||||
gst_video_frame_unmap (&vframe);
|
goto error;
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_fill (out_buffer, 0, enc->webp_writer.mem,
|
gst_buffer_fill (out_buffer, 0, enc->webp_writer.mem,
|
||||||
enc->webp_writer.size);
|
enc->webp_writer.size);
|
||||||
free (enc->webp_writer.mem);
|
|
||||||
frame->output_buffer = out_buffer;
|
frame->output_buffer = out_buffer;
|
||||||
} else {
|
|
||||||
GST_ERROR_OBJECT (enc, "Failed to encode WebPPicture");
|
|
||||||
gst_video_frame_unmap (&vframe);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_video_frame_unmap (&vframe);
|
gst_video_frame_unmap (&vframe);
|
||||||
|
gst_webp_enc_clear_picture (enc);
|
||||||
return gst_video_encoder_finish_frame (encoder, frame);
|
return gst_video_encoder_finish_frame (encoder, frame);
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_video_frame_unmap (&vframe);
|
||||||
|
gst_webp_enc_clear_picture (enc);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -387,7 +386,6 @@ gst_webp_enc_set_property (GObject * object, guint prop_id,
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -419,9 +417,9 @@ gst_webp_enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_webp_enc_start (GstVideoEncoder * benc)
|
gst_webp_enc_start (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstWebpEnc *enc = (GstWebpEnc *) benc;
|
GstWebpEnc *enc = (GstWebpEnc *) encoder;
|
||||||
|
|
||||||
if (!WebPConfigPreset (&enc->webp_config, enc->preset, enc->quality)) {
|
if (!WebPConfigPreset (&enc->webp_config, enc->preset, enc->quality)) {
|
||||||
GST_ERROR_OBJECT (enc, "Failed to Initialize WebPConfig ");
|
GST_ERROR_OBJECT (enc, "Failed to Initialize WebPConfig ");
|
||||||
|
@ -435,17 +433,22 @@ gst_webp_enc_start (GstVideoEncoder * benc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enc->next_timestamp = 0;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_webp_enc_finish (GstVideoEncoder * benc)
|
gst_webp_enc_finish (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstWebpEnc *enc = (GstWebpEnc *) benc;
|
GstWebpEnc *enc = GST_WEBP_ENC (encoder);
|
||||||
WebPData data = { 0 };
|
WebPData data = { 0 };
|
||||||
|
GstBuffer *out;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
if (enc->animated) {
|
if (!enc->anim_enc)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!WebPAnimEncoderAdd (enc->anim_enc, NULL, enc->next_timestamp,
|
if (!WebPAnimEncoderAdd (enc->anim_enc, NULL, enc->next_timestamp,
|
||||||
&enc->webp_config)) {
|
&enc->webp_config)) {
|
||||||
GST_ERROR_OBJECT (enc, "Failed to flush animation encoder");
|
GST_ERROR_OBJECT (enc, "Failed to flush animation encoder");
|
||||||
|
@ -453,34 +456,37 @@ gst_webp_enc_finish (GstVideoEncoder * benc)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WebPAnimEncoderAssemble (enc->anim_enc, &data)) {
|
if (!WebPAnimEncoderAssemble (enc->anim_enc, &data)) {
|
||||||
GstBuffer *out = gst_buffer_new_allocate (NULL, data.size, NULL);
|
|
||||||
|
|
||||||
gst_buffer_fill (out, 0, data.bytes, data.size);
|
|
||||||
|
|
||||||
WebPDataClear (&data);
|
|
||||||
|
|
||||||
ret = gst_pad_push (benc->srcpad, out);
|
|
||||||
} else {
|
|
||||||
GST_ERROR_OBJECT (enc, "Failed to assemble output animation");
|
GST_ERROR_OBJECT (enc, "Failed to assemble output animation");
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
out = gst_buffer_new_allocate (NULL, data.size, NULL);
|
||||||
|
gst_buffer_fill (out, 0, data.bytes, data.size);
|
||||||
|
WebPDataClear (&data);
|
||||||
|
ret = gst_pad_push (encoder->srcpad, out);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
WebPAnimEncoderDelete (enc->anim_enc);
|
||||||
|
enc->anim_enc = NULL;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_webp_enc_stop (GstVideoEncoder * benc)
|
gst_webp_enc_stop (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstWebpEnc *enc = GST_WEBP_ENC (benc);
|
GstWebpEnc *enc = GST_WEBP_ENC (encoder);
|
||||||
if (enc->input_state)
|
if (enc->input_state) {
|
||||||
gst_video_codec_state_unref (enc->input_state);
|
gst_video_codec_state_unref (enc->input_state);
|
||||||
|
enc->input_state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (enc->anim_enc)
|
if (enc->anim_enc) {
|
||||||
WebPAnimEncoderDelete (enc->anim_enc);
|
WebPAnimEncoderDelete (enc->anim_enc);
|
||||||
|
enc->anim_enc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue