summaryrefslogtreecommitdiff
path: root/gst/pnm
diff options
context:
space:
mode:
authorDimitrios Katsaros <patcherwork@gmail.com>2015-10-19 17:15:30 +0200
committerJan Schmidt <jan@centricular.com>2016-05-24 07:21:44 +1000
commit61440e58c1e3197227d2337576586b0d699f2cd4 (patch)
tree32d67d383b3a9d878af4d510c9b38b04197e43c8 /gst/pnm
parentf778a3f19a905d6ea80f1e30003bbfbd91f18db6 (diff)
downloadgstreamer-plugins-bad-61440e58c1e3197227d2337576586b0d699f2cd4.tar.gz
pnmenc: Implementation of GRAY16 handling
https://bugzilla.gnome.org/show_bug.cgi?id=757022
Diffstat (limited to 'gst/pnm')
-rw-r--r--gst/pnm/gstpnmenc.c146
1 files changed, 117 insertions, 29 deletions
diff --git a/gst/pnm/gstpnmenc.c b/gst/pnm/gstpnmenc.c
index cba456bf3..8437499d5 100644
--- a/gst/pnm/gstpnmenc.c
+++ b/gst/pnm/gstpnmenc.c
@@ -53,10 +53,12 @@ enum
/* Add here. */
};
+
+
static GstStaticPadTemplate sink_pad_template =
- GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB") "; "
- GST_VIDEO_CAPS_MAKE ("GRAY8")));
+GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
+ ("{ RGB, GRAY8, GRAY16_BE, GRAY16_LE }")));
static GstStaticPadTemplate src_pad_template =
@@ -140,9 +142,16 @@ gst_pnmenc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
switch (GST_VIDEO_INFO_FORMAT (info)) {
case GST_VIDEO_FORMAT_RGB:
+ pnmenc->info.max = 255;
pnmenc->info.type = GST_PNM_TYPE_PIXMAP;
break;
case GST_VIDEO_FORMAT_GRAY8:
+ pnmenc->info.max = 255;
+ pnmenc->info.type = GST_PNM_TYPE_GRAYMAP;
+ break;
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ pnmenc->info.max = 65535;
pnmenc->info.type = GST_PNM_TYPE_GRAYMAP;
break;
default:
@@ -152,8 +161,6 @@ gst_pnmenc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
pnmenc->info.width = GST_VIDEO_INFO_WIDTH (info);
pnmenc->info.height = GST_VIDEO_INFO_HEIGHT (info);
- /* Supported max value is only one, that is 255 */
- pnmenc->info.max = 255;
if (pnmenc->input_state)
gst_video_codec_state_unref (pnmenc->input_state);
@@ -172,7 +179,7 @@ static GstFlowReturn
gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
{
GstPnmenc *pnmenc;
- guint size, pixels;
+ guint size, pixels, bytesize;
GstMapInfo omap, imap;
gchar *header = NULL;
GstVideoInfo *info;
@@ -180,16 +187,40 @@ gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
guint i_rowstride, o_rowstride;
guint bytes = 0, index, head_size;
guint i, j;
-
+ guint maxbytes_per_pixel, str_len;
+ gchar format_str[4];
+ union
+ {
+ guint8 *ui8;
+ guint16 *ui16;
+ gpointer ptr;
+ } data;
pnmenc = GST_PNMENC (encoder);
info = &pnmenc->input_state->info;
switch (GST_VIDEO_INFO_FORMAT (info)) {
case GST_VIDEO_FORMAT_RGB:
pixels = size = pnmenc->info.width * pnmenc->info.height * 3;
+ bytesize = 1;
+ maxbytes_per_pixel = 4;
+ str_len = 3;
+ g_strlcpy (format_str, "%3i", 4);
break;
case GST_VIDEO_FORMAT_GRAY8:
pixels = size = pnmenc->info.width * pnmenc->info.height * 1;
+ bytesize = 1;
+ maxbytes_per_pixel = 4;
+ str_len = 3;
+ g_strlcpy (format_str, "%3i", 4);
+ break;
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ pixels = pnmenc->info.width * pnmenc->info.height * 1;
+ bytesize = 2;
+ size = pixels * bytesize;
+ maxbytes_per_pixel = 6;
+ str_len = 5;
+ g_strlcpy (format_str, "%5i", 4);
break;
default:
ret = FALSE;
@@ -226,6 +257,7 @@ gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
head_size = strlen (header);
if (pnmenc->info.encoding == GST_PNM_ENCODING_ASCII) {
+ data.ptr = imap.data;
/* We need to convert to ASCII */
if (pnmenc->info.width % 4 != 0) {
/* Convert from gstreamer rowstride to PNM rowstride */
@@ -234,36 +266,91 @@ gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
} else {
o_rowstride = pnmenc->info.width;
}
- i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);
- for (i = 0; i < pnmenc->info.height; i++) {
- index = i * i_rowstride;
- for (j = 0; j < o_rowstride; j++, bytes++, index++) {
- g_snprintf ((char *) omap.data + head_size, 4, "%3i",
- imap.data[index]);
- head_size += 3;
- omap.data[head_size++] = ' ';
- /* Add new line so that file will not end up with sinle big line */
- if (!((bytes + 1) % 20))
- omap.data[head_size++] = '\n';
+ switch GST_VIDEO_INFO_FORMAT
+ (info) {
+ case GST_VIDEO_FORMAT_RGB:
+ case GST_VIDEO_FORMAT_GRAY8:
+ i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);
+ for (i = 0; i < pnmenc->info.height; i++) {
+ index = i * i_rowstride;
+ for (j = 0; j < o_rowstride; j++, bytes++, index++) {
+ g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
+ format_str, data.ui8[index]);
+ head_size += str_len;
+ omap.data[head_size++] = ' ';
+ /* Add new line so that file will not end up with sinle big line */
+ if (!((bytes + 1) % 20))
+ omap.data[head_size++] = '\n';
+ }
+ }
+ break;
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ i_rowstride =
+ GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0) / 2;
+ for (i = 0; i < pnmenc->info.height; i++) {
+ index = i * i_rowstride;
+ for (j = 0; j < o_rowstride; j++, bytes++, index++) {
+ g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
+ format_str, data.ui16[index]);
+ head_size += str_len;
+ omap.data[head_size++] = ' ';
+ /* Add new line so that file will not end up with sinle big line */
+ if (!((bytes + 1) % 20))
+ omap.data[head_size++] = '\n';
+ }
+ }
+ break;
+ default:
+ GST_ERROR_OBJECT (encoder, "Unhandled format %s",
+ gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info)));
+ gst_buffer_unmap (frame->output_buffer, &omap);
+ gst_buffer_unmap (frame->input_buffer, &imap);
+ g_free (header);
+ return GST_FLOW_ERROR;
}
- }
} else {
- for (i = 0; i < pixels; i++) {
- g_snprintf ((char *) omap.data + head_size, 4, "%3i", imap.data[i]);
- head_size += 3;
- omap.data[head_size++] = ' ';
- if (!((i + 1) % 20))
- omap.data[head_size++] = '\n';
- }
+ switch GST_VIDEO_INFO_FORMAT
+ (info) {
+ case GST_VIDEO_FORMAT_RGB:
+ case GST_VIDEO_FORMAT_GRAY8:
+ for (i = 0; i < pixels; i++) {
+ g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
+ format_str, data.ui8[i]);
+ head_size += str_len;
+ omap.data[head_size++] = ' ';
+ if (!((i + 1) % 20))
+ omap.data[head_size++] = '\n';
+ }
+ break;
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ for (i = 0; i < pixels; i++) {
+ g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
+ format_str, data.ui16[i]);
+ head_size += str_len;
+ omap.data[head_size++] = ' ';
+ if (!((i + 1) % 20))
+ omap.data[head_size++] = '\n';
+ }
+ break;
+ default:
+ GST_ERROR_OBJECT (encoder, "Unhandled format %s",
+ gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info)));
+ gst_buffer_unmap (frame->output_buffer, &omap);
+ gst_buffer_unmap (frame->input_buffer, &imap);
+ g_free (header);
+ return GST_FLOW_ERROR;
+ }
}
} else {
/* Need to convert from GStreamer rowstride to PNM rowstride */
if (pnmenc->info.width % 4 != 0) {
if (pnmenc->info.type == GST_PNM_TYPE_PIXMAP) {
- o_rowstride = 3 * pnmenc->info.width;
+ o_rowstride = 3 * pnmenc->info.width * bytesize;
} else {
- o_rowstride = pnmenc->info.width;
+ o_rowstride = pnmenc->info.width * bytesize;
}
i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);
@@ -273,12 +360,13 @@ gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
} else {
/* size contains complete image size inlcuding header size,
Exclude header size while copying data */
- memcpy (omap.data + strlen (header), imap.data, (size - head_size));
+ memcpy (omap.data + head_size, imap.data, (size - head_size));
}
}
gst_buffer_unmap (frame->output_buffer, &omap);
gst_buffer_unmap (frame->input_buffer, &imap);
+ g_free (header);
if ((ret = gst_video_encoder_finish_frame (encoder, frame)) != GST_FLOW_OK)
goto done;