mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
pnmenc: Tidy up code, support BE/LE GRAY16 properly
Remove code that dealt with odd strides separately - there's not really any overhead to just using 1 codepath for both matched and unmatched stride output. Add separate codepaths for BE vs LE GRAY16 input so they're handled properly
This commit is contained in:
parent
30503f07ae
commit
fa2d98afe2
1 changed files with 98 additions and 108 deletions
|
@ -189,12 +189,6 @@ gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
|
|||
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;
|
||||
|
||||
|
@ -253,120 +247,116 @@ gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
|
|||
ret = GST_FLOW_ERROR;
|
||||
goto done;
|
||||
}
|
||||
memcpy (omap.data, header, strlen (header));
|
||||
|
||||
/* Copy out the header first */
|
||||
head_size = strlen (header);
|
||||
memcpy (omap.data, header, head_size);
|
||||
|
||||
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 */
|
||||
if (pnmenc->info.type == GST_PNM_TYPE_PIXMAP) {
|
||||
o_rowstride = 3 * pnmenc->info.width;
|
||||
} else {
|
||||
o_rowstride = pnmenc->info.width;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/* Convert from gstreamer rowstride to PNM rowstride as we go */
|
||||
if (pnmenc->info.type == GST_PNM_TYPE_PIXMAP) {
|
||||
o_rowstride = 3 * pnmenc->info.width;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
o_rowstride = pnmenc->info.width;
|
||||
}
|
||||
} 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 * bytesize;
|
||||
} else {
|
||||
o_rowstride = pnmenc->info.width * bytesize;
|
||||
}
|
||||
i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);
|
||||
i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);
|
||||
|
||||
for (i = 0; i < pnmenc->info.height; i++)
|
||||
memcpy (omap.data + head_size + o_rowstride * i,
|
||||
imap.data + i_rowstride * i, o_rowstride);
|
||||
switch (GST_VIDEO_INFO_FORMAT (info)) {
|
||||
case GST_VIDEO_FORMAT_RGB:
|
||||
case GST_VIDEO_FORMAT_GRAY8:
|
||||
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, imap.data[index]);
|
||||
head_size += str_len;
|
||||
omap.data[head_size++] = ' ';
|
||||
/* Add new line so that file will not end up with single big line */
|
||||
if (!((bytes + 1) % 20))
|
||||
omap.data[head_size++] = '\n';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_GRAY16_BE:
|
||||
for (i = 0; i < pnmenc->info.height; i++) {
|
||||
index = i * i_rowstride;
|
||||
for (j = 0; j < o_rowstride; j++, bytes++, index += 2) {
|
||||
g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
|
||||
format_str, GST_READ_UINT16_BE (imap.data + index));
|
||||
head_size += str_len;
|
||||
omap.data[head_size++] = ' ';
|
||||
/* Add new line so that file will not end up with single big line */
|
||||
if (!((bytes + 1) % 20))
|
||||
omap.data[head_size++] = '\n';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_GRAY16_LE:
|
||||
for (i = 0; i < pnmenc->info.height; i++) {
|
||||
index = i * i_rowstride;
|
||||
for (j = 0; j < o_rowstride; j++, bytes++, index += 2) {
|
||||
g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
|
||||
format_str, GST_READ_UINT16_LE (imap.data + index));
|
||||
head_size += str_len;
|
||||
omap.data[head_size++] = ' ';
|
||||
/* Add new line so that file will not end up with single 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;
|
||||
}
|
||||
|
||||
gst_buffer_set_size (frame->output_buffer, head_size);
|
||||
} else {
|
||||
guint out_index = head_size;
|
||||
|
||||
/* Binary output. 8-bit, or 16-bit BE */
|
||||
if (pnmenc->info.type == GST_PNM_TYPE_PIXMAP) {
|
||||
o_rowstride = 3 * pnmenc->info.width * bytesize;
|
||||
} else {
|
||||
/* size contains complete image size inlcuding header size,
|
||||
Exclude header size while copying data */
|
||||
memcpy (omap.data + head_size, imap.data, (size - head_size));
|
||||
o_rowstride = pnmenc->info.width * bytesize;
|
||||
}
|
||||
i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);
|
||||
|
||||
switch (GST_VIDEO_INFO_FORMAT (info)) {
|
||||
case GST_VIDEO_FORMAT_GRAY16_BE:
|
||||
for (i = 0; i < pnmenc->info.height; i++) {
|
||||
index = i * i_rowstride;
|
||||
for (j = 0; j < o_rowstride; j += 2, index += 2) {
|
||||
guint16 val = GST_READ_UINT16_LE (imap.data + index);
|
||||
GST_WRITE_UINT16_BE (omap.data + out_index, val);
|
||||
out_index += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_GRAY16_LE:
|
||||
for (i = 0; i < pnmenc->info.height; i++) {
|
||||
index = i * i_rowstride;
|
||||
for (j = 0; j < o_rowstride; j += 2, index += 2) {
|
||||
guint16 val = GST_READ_UINT16_LE (imap.data + index);
|
||||
GST_WRITE_UINT16_BE (omap.data + out_index, val);
|
||||
out_index += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < pnmenc->info.height; i++) {
|
||||
memcpy (omap.data + head_size + o_rowstride * i,
|
||||
imap.data + i_rowstride * i, o_rowstride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue