mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
Merge branch 'master' into 0.11
Conflicts: ext/vorbis/gstvorbisparse.c gst-libs/gst/video/video.c gst/videoscale/gstvideoscale.c sys/v4l/gstv4lxoverlay.c sys/v4l/v4l_calls.c sys/v4l/v4lsrc_calls.c tests/check/libs/video.c
This commit is contained in:
commit
c3478b2da0
14 changed files with 461 additions and 39 deletions
16
autogen.sh
16
autogen.sh
|
@ -1,6 +1,12 @@
|
|||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
test -n "$srcdir" || srcdir=`dirname "$0"`
|
||||
test -n "$srcdir" || srcdir=.
|
||||
|
||||
olddir=`pwd`
|
||||
cd "$srcdir"
|
||||
|
||||
DIE=0
|
||||
package=gst-plugins-base
|
||||
srcfile=gst/audiotestsrc/gstaudiotestsrc.c
|
||||
|
@ -106,13 +112,15 @@ test -n "$NOCONFIGURE" && {
|
|||
exit 0
|
||||
}
|
||||
|
||||
cd "$olddir"
|
||||
|
||||
echo "+ running configure ... "
|
||||
test ! -z "$CONFIGURE_DEF_OPT" && echo " ./configure default flags: $CONFIGURE_DEF_OPT"
|
||||
test ! -z "$CONFIGURE_EXT_OPT" && echo " ./configure external flags: $CONFIGURE_EXT_OPT"
|
||||
test ! -z "$CONFIGURE_FILE_OPT" && echo " ./configure enable/disable flags: $CONFIGURE_FILE_OPT"
|
||||
test ! -z "$CONFIGURE_DEF_OPT" && echo " $srcdir/configure default flags: $CONFIGURE_DEF_OPT"
|
||||
test ! -z "$CONFIGURE_EXT_OPT" && echo " $srcdir/configure external flags: $CONFIGURE_EXT_OPT"
|
||||
test ! -z "$CONFIGURE_FILE_OPT" && echo " $srcdir/configure enable/disable flags: $CONFIGURE_FILE_OPT"
|
||||
echo
|
||||
|
||||
./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
|
||||
"$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
|
||||
echo " configure failed"
|
||||
exit 1
|
||||
}
|
||||
|
|
|
@ -554,6 +554,9 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
|||
pad->current_granule);
|
||||
} else if (ogg->segment.rate > 0.0 && pad->current_granule != -1) {
|
||||
pad->current_granule += duration;
|
||||
if (gst_ogg_stream_packet_is_key_frame (&pad->map, packet)) {
|
||||
pad->keyframe_granule = pad->current_granule;
|
||||
}
|
||||
GST_DEBUG_OBJECT (ogg, "interpolating granule %" G_GUINT64_FORMAT,
|
||||
pad->current_granule);
|
||||
}
|
||||
|
|
|
@ -47,9 +47,13 @@ typedef gint64 (*GstOggMapToGranuleposFunc) (GstOggStream * pad,
|
|||
gint64 granule, gint64 keyframe_granule);
|
||||
|
||||
/* returns TRUE if the granulepos denotes a key frame */
|
||||
typedef gboolean (*GstOggMapIsKeyFrameFunc) (GstOggStream * pad,
|
||||
typedef gboolean (*GstOggMapIsGranuleposKeyFrameFunc) (GstOggStream * pad,
|
||||
gint64 granulepos);
|
||||
|
||||
/* returns TRUE if the packet is a key frame */
|
||||
typedef gboolean (*GstOggMapIsPacketKeyFrameFunc) (GstOggStream * pad,
|
||||
ogg_packet * packet);
|
||||
|
||||
/* returns TRUE if the given packet is a stream header packet */
|
||||
typedef gboolean (*GstOggMapIsHeaderPacketFunc) (GstOggStream * pad,
|
||||
ogg_packet * packet);
|
||||
|
@ -74,7 +78,8 @@ struct _GstOggMap
|
|||
GstOggMapSetupFunc setup_func;
|
||||
GstOggMapToGranuleFunc granulepos_to_granule_func;
|
||||
GstOggMapToGranuleposFunc granule_to_granulepos_func;
|
||||
GstOggMapIsKeyFrameFunc is_key_frame_func;
|
||||
GstOggMapIsGranuleposKeyFrameFunc is_granulepos_key_frame_func;
|
||||
GstOggMapIsPacketKeyFrameFunc is_packet_key_frame_func;
|
||||
GstOggMapIsHeaderPacketFunc is_header_func;
|
||||
GstOggMapPacketDurationFunc packet_duration_func;
|
||||
GstOggMapGranuleposToKeyGranuleFunc granulepos_to_key_granule_func;
|
||||
|
@ -189,13 +194,25 @@ gst_ogg_stream_granulepos_is_key_frame (GstOggStream * pad, gint64 granulepos)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (mappers[pad->map].is_key_frame_func == NULL) {
|
||||
if (mappers[pad->map].is_granulepos_key_frame_func == NULL) {
|
||||
GST_WARNING ("Failed to determine keyframeness for %s granulepos",
|
||||
gst_ogg_stream_get_media_type (pad));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return mappers[pad->map].is_key_frame_func (pad, granulepos);
|
||||
return mappers[pad->map].is_granulepos_key_frame_func (pad, granulepos);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_ogg_stream_packet_is_key_frame (GstOggStream * pad, ogg_packet * packet)
|
||||
{
|
||||
if (mappers[pad->map].is_packet_key_frame_func == NULL) {
|
||||
GST_WARNING ("Failed to determine keyframeness of %s packet",
|
||||
gst_ogg_stream_get_media_type (pad));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return mappers[pad->map].is_packet_key_frame_func (pad, packet);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -250,7 +267,13 @@ gst_ogg_stream_get_media_type (GstOggStream * pad)
|
|||
/* some generic functions */
|
||||
|
||||
static gboolean
|
||||
is_keyframe_true (GstOggStream * pad, gint64 granulepos)
|
||||
is_granulepos_keyframe_true (GstOggStream * pad, gint64 granulepos)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_packet_keyframe_true (GstOggStream * pad, ogg_packet * packet)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -383,6 +406,7 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet)
|
|||
/* 2 bits + 3 bits = 5 bits KFGSHIFT */
|
||||
pad->granuleshift = ((GST_READ_UINT8 (data + 40) & 0x03) << 3) +
|
||||
(GST_READ_UINT8 (data + 41) >> 5);
|
||||
GST_LOG ("granshift: %d", pad->granuleshift);
|
||||
|
||||
pad->is_video = TRUE;
|
||||
pad->n_header_packets = 3;
|
||||
|
@ -439,7 +463,7 @@ granulepos_to_granule_theora (GstOggStream * pad, gint64 granulepos)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
is_keyframe_theora (GstOggStream * pad, gint64 granulepos)
|
||||
is_granulepos_keyframe_theora (GstOggStream * pad, gint64 granulepos)
|
||||
{
|
||||
gint64 frame_mask;
|
||||
|
||||
|
@ -451,6 +475,14 @@ is_keyframe_theora (GstOggStream * pad, gint64 granulepos)
|
|||
return ((granulepos & frame_mask) == 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_packet_keyframe_theora (GstOggStream * pad, ogg_packet * packet)
|
||||
{
|
||||
if (packet->bytes == 0)
|
||||
return FALSE;
|
||||
return (packet->packet[0] & 0xc0) == 0x00;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_header_theora (GstOggStream * pad, ogg_packet * packet)
|
||||
{
|
||||
|
@ -1935,7 +1967,8 @@ const GstOggMap mappers[] = {
|
|||
setup_theora_mapper,
|
||||
granulepos_to_granule_theora,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_theora,
|
||||
is_granulepos_keyframe_theora,
|
||||
is_packet_keyframe_theora,
|
||||
is_header_theora,
|
||||
packet_duration_constant,
|
||||
NULL,
|
||||
|
@ -1947,7 +1980,8 @@ const GstOggMap mappers[] = {
|
|||
setup_vorbis_mapper,
|
||||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_true,
|
||||
is_granulepos_keyframe_true,
|
||||
is_packet_keyframe_true,
|
||||
is_header_vorbis,
|
||||
packet_duration_vorbis,
|
||||
NULL,
|
||||
|
@ -1959,7 +1993,8 @@ const GstOggMap mappers[] = {
|
|||
setup_speex_mapper,
|
||||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_true,
|
||||
is_granulepos_keyframe_true,
|
||||
is_packet_keyframe_true,
|
||||
is_header_count,
|
||||
packet_duration_constant,
|
||||
NULL,
|
||||
|
@ -1972,6 +2007,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_count,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -1984,6 +2020,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_count,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -1996,6 +2033,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_count,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -2008,6 +2046,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_true,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -2019,7 +2058,8 @@ const GstOggMap mappers[] = {
|
|||
setup_fLaC_mapper,
|
||||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_true,
|
||||
is_granulepos_keyframe_true,
|
||||
is_packet_keyframe_true,
|
||||
is_header_fLaC,
|
||||
packet_duration_flac,
|
||||
NULL,
|
||||
|
@ -2031,7 +2071,8 @@ const GstOggMap mappers[] = {
|
|||
setup_flac_mapper,
|
||||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_true,
|
||||
is_granulepos_keyframe_true,
|
||||
is_packet_keyframe_true,
|
||||
is_header_flac,
|
||||
packet_duration_flac,
|
||||
NULL,
|
||||
|
@ -2046,6 +2087,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2055,6 +2097,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_count,
|
||||
packet_duration_constant,
|
||||
NULL,
|
||||
|
@ -2067,6 +2110,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_count,
|
||||
packet_duration_kate,
|
||||
NULL,
|
||||
|
@ -2079,6 +2123,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_dirac,
|
||||
granule_to_granulepos_dirac,
|
||||
is_keyframe_dirac,
|
||||
NULL,
|
||||
is_header_count,
|
||||
packet_duration_constant,
|
||||
granulepos_to_key_granule_dirac,
|
||||
|
@ -2091,6 +2136,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_vp8,
|
||||
granule_to_granulepos_vp8,
|
||||
is_keyframe_vp8,
|
||||
NULL,
|
||||
is_header_vp8,
|
||||
packet_duration_vp8,
|
||||
granulepos_to_key_granule_vp8,
|
||||
|
@ -2103,6 +2149,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_opus,
|
||||
packet_duration_opus,
|
||||
NULL,
|
||||
|
@ -2114,7 +2161,8 @@ const GstOggMap mappers[] = {
|
|||
setup_ogmaudio_mapper,
|
||||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_true,
|
||||
is_granulepos_keyframe_true,
|
||||
is_packet_keyframe_true,
|
||||
is_header_ogm,
|
||||
packet_duration_ogm,
|
||||
NULL,
|
||||
|
@ -2127,6 +2175,7 @@ const GstOggMap mappers[] = {
|
|||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
NULL,
|
||||
NULL,
|
||||
is_header_ogm,
|
||||
packet_duration_constant,
|
||||
NULL,
|
||||
|
@ -2138,7 +2187,8 @@ const GstOggMap mappers[] = {
|
|||
setup_ogmtext_mapper,
|
||||
granulepos_to_granule_default,
|
||||
granule_to_granulepos_default,
|
||||
is_keyframe_true,
|
||||
is_granulepos_keyframe_true,
|
||||
is_packet_keyframe_true,
|
||||
is_header_ogm,
|
||||
packet_duration_ogm,
|
||||
NULL,
|
||||
|
|
|
@ -124,6 +124,7 @@ GstClockTime gst_ogg_stream_get_packet_start_time (GstOggStream *pad,
|
|||
gboolean gst_ogg_stream_granulepos_is_key_frame (GstOggStream *pad,
|
||||
gint64 granulepos);
|
||||
gboolean gst_ogg_stream_packet_is_header (GstOggStream *pad, ogg_packet *packet);
|
||||
gboolean gst_ogg_stream_packet_is_key_frame (GstOggStream *pad, ogg_packet *packet);
|
||||
gint64 gst_ogg_stream_get_packet_duration (GstOggStream * pad, ogg_packet *packet);
|
||||
void gst_ogg_stream_extract_tags (GstOggStream * pad, ogg_packet * packet);
|
||||
const char *gst_ogg_stream_get_media_type (GstOggStream * pad);
|
||||
|
|
|
@ -1338,6 +1338,11 @@ theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
|
|||
goto multipass_read_failed;
|
||||
}
|
||||
}
|
||||
#ifdef TH_ENCCTL_SET_DUPLICATE_FLAG
|
||||
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_GAP)) {
|
||||
th_encode_ctl (enc->encoder, TH_ENCCTL_SET_DUPLICATE_FLAG, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
res = th_encode_ycbcr_in (enc->encoder, ycbcr);
|
||||
/* none of the failure cases can happen here */
|
||||
|
|
|
@ -400,7 +400,7 @@ vorbis_parse_parse_packet (GstVorbisParse * parse, GstBuffer * buf)
|
|||
have_header = FALSE;
|
||||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||
if (map.size >= 1) {
|
||||
if (map.data[0] >= 0x01 && map.data[0] <= 0x05)
|
||||
if (map.data[0] & 1)
|
||||
have_header = TRUE;
|
||||
}
|
||||
gst_buffer_unmap (buf, &map);
|
||||
|
|
|
@ -2402,6 +2402,9 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
/* Stream consists of: a series of sync codes (00 00 00 01) followed
|
||||
* by NALs
|
||||
*/
|
||||
gboolean seen_idr = FALSE;
|
||||
gboolean seen_sps = FALSE;
|
||||
gboolean seen_pps = FALSE;
|
||||
int nut, ref;
|
||||
int good = 0;
|
||||
int bad = 0;
|
||||
|
@ -2426,6 +2429,13 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
((nut == 6 || (nut >= 9 && nut <= 12)) && ref != 0)) {
|
||||
bad++;
|
||||
} else {
|
||||
if (nut == 7)
|
||||
seen_sps = TRUE;
|
||||
else if (nut == 8)
|
||||
seen_pps = TRUE;
|
||||
else if (nut == 5)
|
||||
seen_idr = TRUE;
|
||||
|
||||
good++;
|
||||
}
|
||||
} else if (nut >= 14 && nut <= 33) {
|
||||
|
@ -2439,9 +2449,10 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
/* don't consider these bad */
|
||||
}
|
||||
|
||||
GST_DEBUG ("good %d bad %d", good, bad);
|
||||
GST_LOG ("good:%d, bad:%d, pps:%d, sps:%d, idr:%d", good, bad, seen_pps,
|
||||
seen_sps, seen_idr);
|
||||
|
||||
if (good >= 10 && bad < 4) {
|
||||
if (seen_sps && seen_pps && seen_idr && good >= 10 && bad < 4) {
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H264_VIDEO_CAPS);
|
||||
return;
|
||||
}
|
||||
|
@ -2451,9 +2462,11 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
data_scan_ctx_advance (tf, &c, 1);
|
||||
}
|
||||
|
||||
if (good >= 2 && bad < 1) {
|
||||
GST_LOG ("good:%d, bad:%d, pps:%d, sps:%d, idr:%d", good, bad, seen_pps,
|
||||
seen_sps, seen_idr);
|
||||
|
||||
if (good >= 2 && bad == 0) {
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, H264_VIDEO_CAPS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* Copyright (C) 2005 David Schleef <ds@schleef.org>
|
||||
* Copyright (C) 2005-2012 David Schleef <ds@schleef.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -112,10 +112,10 @@ enum
|
|||
#undef GST_VIDEO_SIZE_RANGE
|
||||
#define GST_VIDEO_SIZE_RANGE "(int) [ 1, 32767]"
|
||||
|
||||
#define GST_VIDEO_FORMATS "{ \"I420\", \"YV12\", \"YUY2\", \"UYVY\", \"AYUV\", \"RGBx\", " \
|
||||
"\"BGRx\", \"xRGB\", \"xBGR\", \"RGBA\", \"BGRA\", \"ARGB\", \"ABGR\", \"RGB\", " \
|
||||
"\"BGR\", \"Y41B\", \"Y42B\", \"YVYU\", \"Y444\", \"GRAY8\", \"GRAY16_BE\", \"GRAY16_LE\", " \
|
||||
"\"v308\", \"Y800\", \"Y16\", \"RGB16\", \"RGB15\", \"ARGB64\", \"AYUV64\" } "
|
||||
#define GST_VIDEO_FORMATS "{ I420, YV12, YUY2, UYVY, AYUV, RGBx, " \
|
||||
"BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, " \
|
||||
"BGR, Y41B, Y42B, YVYU, Y444, GRAY8, GRAY16_BE, GRAY16_LE, " \
|
||||
"v308, Y800, Y16, RGB16, RGB15, ARGB64, AYUV64, NV12 } "
|
||||
|
||||
|
||||
static GstStaticCaps gst_video_scale_format_caps[] = {
|
||||
|
@ -1042,6 +1042,7 @@ _get_black_for_format (GstVideoFormat format)
|
|||
case GST_VIDEO_FORMAT_Y444:
|
||||
case GST_VIDEO_FORMAT_Y42B:
|
||||
case GST_VIDEO_FORMAT_Y41B:
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
return black[4]; /* Y, U, V, 0 */
|
||||
case GST_VIDEO_FORMAT_RGB16:
|
||||
case GST_VIDEO_FORMAT_RGB15:
|
||||
|
@ -1136,6 +1137,11 @@ gst_video_scale_transform_frame (GstVideoFilter * filter,
|
|||
case GST_VIDEO_SCALE_4TAP:
|
||||
vs_image_scale_4tap_AYUV64 (&dest[0], &src[0], videoscale->tmp_buf);
|
||||
break;
|
||||
case GST_VIDEO_SCALE_LANCZOS:
|
||||
vs_image_scale_lanczos_AYUV64 (&dest[0], &src[0], videoscale->tmp_buf,
|
||||
videoscale->sharpness, videoscale->dither, videoscale->submethod,
|
||||
videoscale->envelope, videoscale->sharpen);
|
||||
break;
|
||||
default:
|
||||
goto unknown_mode;
|
||||
}
|
||||
|
@ -1272,6 +1278,20 @@ gst_video_scale_transform_frame (GstVideoFilter * filter,
|
|||
goto unknown_mode;
|
||||
}
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
switch (method) {
|
||||
case GST_VIDEO_SCALE_NEAREST:
|
||||
vs_image_scale_nearest_Y (&dest[0], &src[0], videoscale->tmp_buf);
|
||||
vs_image_scale_nearest_NV12 (&dest[1], &src[1], videoscale->tmp_buf);
|
||||
break;
|
||||
case GST_VIDEO_SCALE_BILINEAR:
|
||||
vs_image_scale_linear_Y (&dest[0], &src[0], videoscale->tmp_buf);
|
||||
vs_image_scale_linear_NV12 (&dest[1], &src[1], videoscale->tmp_buf);
|
||||
break;
|
||||
default:
|
||||
goto unknown_mode;
|
||||
}
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_RGB16:
|
||||
if (add_borders)
|
||||
vs_fill_borders_RGB565 (&dest[0], black);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Image Scaling Functions
|
||||
* Copyright (c) 2005 David A. Schleef <ds@schleef.org>
|
||||
* Copyright (c) 2005-2012 David A. Schleef <ds@schleef.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -522,6 +522,136 @@ vs_image_scale_linear_UYVY (const VSImage * dest, const VSImage * src,
|
|||
}
|
||||
}
|
||||
|
||||
/* NV12 */
|
||||
|
||||
void
|
||||
vs_image_scale_nearest_NV12 (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf)
|
||||
{
|
||||
int acc;
|
||||
int y_increment;
|
||||
int x_increment;
|
||||
int i;
|
||||
int j;
|
||||
int xacc;
|
||||
|
||||
if (dest->height == 1)
|
||||
y_increment = 0;
|
||||
else
|
||||
y_increment = ((src->height - 1) << 16) / (dest->height - 1);
|
||||
|
||||
if (dest->width == 1)
|
||||
x_increment = 0;
|
||||
else
|
||||
x_increment = ((src->width - 1) << 16) / (dest->width - 1);
|
||||
|
||||
acc = 0;
|
||||
for (i = 0; i < dest->height; i++) {
|
||||
j = acc >> 16;
|
||||
|
||||
xacc = 0;
|
||||
vs_scanline_resample_nearest_NV12 (dest->pixels + i * dest->stride,
|
||||
src->pixels + j * src->stride, src->width, dest->width, &xacc,
|
||||
x_increment);
|
||||
|
||||
acc += y_increment;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vs_image_scale_linear_NV12 (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf)
|
||||
{
|
||||
int acc;
|
||||
int y_increment;
|
||||
int x_increment;
|
||||
uint8_t *tmp1;
|
||||
uint8_t *tmp2;
|
||||
int y1;
|
||||
int y2;
|
||||
int i;
|
||||
int j;
|
||||
int x;
|
||||
int dest_size;
|
||||
int xacc;
|
||||
|
||||
if (dest->height == 1)
|
||||
y_increment = 0;
|
||||
else
|
||||
y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
|
||||
|
||||
if (dest->width == 1)
|
||||
x_increment = 0;
|
||||
else
|
||||
x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
|
||||
|
||||
dest_size = ROUND_UP_4 (dest->width * 2);
|
||||
|
||||
tmp1 = tmpbuf;
|
||||
tmp2 = tmpbuf + dest_size;
|
||||
|
||||
acc = 0;
|
||||
xacc = 0;
|
||||
y2 = -1;
|
||||
vs_scanline_resample_linear_NV12 (tmp1, src->pixels, src->width, dest->width,
|
||||
&xacc, x_increment);
|
||||
y1 = 0;
|
||||
for (i = 0; i < dest->height; i++) {
|
||||
j = acc >> 16;
|
||||
x = acc & 0xffff;
|
||||
|
||||
if (x == 0) {
|
||||
if (j == y1) {
|
||||
memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
|
||||
} else if (j == y2) {
|
||||
memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
|
||||
} else {
|
||||
xacc = 0;
|
||||
vs_scanline_resample_linear_NV12 (tmp1, src->pixels + j * src->stride,
|
||||
src->width, dest->width, &xacc, x_increment);
|
||||
y1 = j;
|
||||
memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
|
||||
}
|
||||
} else {
|
||||
if (j == y1) {
|
||||
if (j + 1 != y2) {
|
||||
xacc = 0;
|
||||
vs_scanline_resample_linear_NV12 (tmp2,
|
||||
src->pixels + (j + 1) * src->stride, src->width, dest->width,
|
||||
&xacc, x_increment);
|
||||
y2 = j + 1;
|
||||
}
|
||||
vs_scanline_merge_linear_NV12 (dest->pixels + i * dest->stride,
|
||||
tmp1, tmp2, dest->width, x);
|
||||
} else if (j == y2) {
|
||||
if (j + 1 != y1) {
|
||||
xacc = 0;
|
||||
vs_scanline_resample_linear_NV12 (tmp1,
|
||||
src->pixels + (j + 1) * src->stride, src->width, dest->width,
|
||||
&xacc, x_increment);
|
||||
y1 = j + 1;
|
||||
}
|
||||
vs_scanline_merge_linear_NV12 (dest->pixels + i * dest->stride,
|
||||
tmp2, tmp1, dest->width, x);
|
||||
} else {
|
||||
xacc = 0;
|
||||
vs_scanline_resample_linear_NV12 (tmp1, src->pixels + j * src->stride,
|
||||
src->width, dest->width, &xacc, x_increment);
|
||||
y1 = j;
|
||||
xacc = 0;
|
||||
vs_scanline_resample_linear_NV12 (tmp2,
|
||||
src->pixels + (j + 1) * src->stride, src->width, dest->width,
|
||||
&xacc, x_increment);
|
||||
y2 = (j + 1);
|
||||
vs_scanline_merge_linear_NV12 (dest->pixels + i * dest->stride,
|
||||
tmp1, tmp2, dest->width, x);
|
||||
}
|
||||
}
|
||||
|
||||
acc += y_increment;
|
||||
}
|
||||
}
|
||||
|
||||
/* greyscale */
|
||||
|
||||
void
|
||||
|
|
|
@ -52,6 +52,9 @@ void vs_image_scale_linear_RGBA (const VSImage *dest, const VSImage *src,
|
|||
void vs_image_scale_lanczos_AYUV (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf, double sharpness, gboolean dither, int submethod,
|
||||
double a, double sharpen);
|
||||
void vs_image_scale_lanczos_AYUV64 (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf, double sharpness, gboolean dither, int submethod,
|
||||
double a, double sharpen);
|
||||
|
||||
void vs_image_scale_nearest_RGB (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
|
@ -68,6 +71,11 @@ void vs_image_scale_nearest_UYVY (const VSImage *dest, const VSImage *src,
|
|||
void vs_image_scale_linear_UYVY (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
|
||||
void vs_image_scale_nearest_NV12 (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
void vs_image_scale_linear_NV12 (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
|
||||
void vs_image_scale_nearest_Y (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
void vs_image_scale_linear_Y (const VSImage *dest, const VSImage *src,
|
||||
|
|
|
@ -204,6 +204,9 @@ static void vs_image_scale_lanczos_AYUV_float (const VSImage * dest,
|
|||
static void vs_image_scale_lanczos_AYUV_double (const VSImage * dest,
|
||||
const VSImage * src, uint8_t * tmpbuf, double sharpness, gboolean dither,
|
||||
double a, double sharpen);
|
||||
static void vs_image_scale_lanczos_AYUV64_double (const VSImage * dest,
|
||||
const VSImage * src, uint8_t * tmpbuf, double sharpness, gboolean dither,
|
||||
double a, double sharpen);
|
||||
|
||||
static double
|
||||
sinc (double x)
|
||||
|
@ -590,6 +593,15 @@ vs_image_scale_lanczos_AYUV (const VSImage * dest, const VSImage * src,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
vs_image_scale_lanczos_AYUV64 (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf, double sharpness, gboolean dither, int submethod,
|
||||
double a, double sharpen)
|
||||
{
|
||||
vs_image_scale_lanczos_AYUV64_double (dest, src, tmpbuf, sharpness, dither,
|
||||
a, sharpen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define RESAMPLE_HORIZ_FLOAT(function, dest_type, tap_type, src_type, _n_taps) \
|
||||
|
@ -813,9 +825,9 @@ RESAMPLE_VERT_DITHER (resample_vert_dither_int16_generic, gint16, gint16,
|
|||
n_taps, shift)
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#define RESAMPLE_VERT_FLOAT(function, tap_type, src_type, _n_taps, _shift) \
|
||||
#define RESAMPLE_VERT_FLOAT(function, dest_type, clamp, tap_type, src_type, _n_taps, _shift) \
|
||||
static void \
|
||||
function (guint8 *dest, \
|
||||
function (dest_type *dest, \
|
||||
const tap_type *taps, const src_type *src, int stride, int n_taps, \
|
||||
int shift, int n) \
|
||||
{ \
|
||||
|
@ -828,13 +840,13 @@ function (guint8 *dest, \
|
|||
const src_type *line = PTR_OFFSET(src, stride * l); \
|
||||
sum_y += line[i] * taps[l]; \
|
||||
} \
|
||||
dest[i] = CLAMP (floor(0.5 + sum_y), 0, 255); \
|
||||
dest[i] = CLAMP (floor(0.5 + sum_y), 0, clamp); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define RESAMPLE_VERT_FLOAT_DITHER(function, tap_type, src_type, _n_taps, _shift) \
|
||||
#define RESAMPLE_VERT_FLOAT_DITHER(function, dest_type, clamp, tap_type, src_type, _n_taps, _shift) \
|
||||
static void \
|
||||
function (guint8 *dest, \
|
||||
function (dest_type *dest, \
|
||||
const tap_type *taps, const src_type *src, int stride, int n_taps, \
|
||||
int shift, int n) \
|
||||
{ \
|
||||
|
@ -849,19 +861,24 @@ function (guint8 *dest, \
|
|||
sum_y += line[i] * taps[l]; \
|
||||
} \
|
||||
err_y += sum_y; \
|
||||
dest[i] = CLAMP (floor (err_y), 0, 255); \
|
||||
dest[i] = CLAMP (floor (err_y), 0, clamp); \
|
||||
err_y -= floor (err_y); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
RESAMPLE_VERT_FLOAT (resample_vert_double_generic, double, double, n_taps,
|
||||
RESAMPLE_VERT_FLOAT (resample_vert_double_generic, guint8, 255, double, double, n_taps,
|
||||
shift)
|
||||
RESAMPLE_VERT_FLOAT_DITHER (resample_vert_dither_double_generic, double, double,
|
||||
RESAMPLE_VERT_FLOAT_DITHER (resample_vert_dither_double_generic, guint8, 255, double, double,
|
||||
n_taps, shift)
|
||||
|
||||
RESAMPLE_VERT_FLOAT (resample_vert_float_generic, float, float, n_taps, shift)
|
||||
RESAMPLE_VERT_FLOAT_DITHER (resample_vert_dither_float_generic, float, float,
|
||||
RESAMPLE_VERT_FLOAT (resample_vert_double_generic_u16, guint16, 65535, double, double, n_taps,
|
||||
shift)
|
||||
RESAMPLE_VERT_FLOAT_DITHER (resample_vert_dither_double_generic_u16, guint16, 65535, double, double,
|
||||
n_taps, shift)
|
||||
|
||||
RESAMPLE_VERT_FLOAT (resample_vert_float_generic, guint8, 255, float, float, n_taps, shift)
|
||||
RESAMPLE_VERT_FLOAT_DITHER (resample_vert_dither_float_generic, guint8, 255, float, float,
|
||||
n_taps, shift)
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
@ -1556,3 +1573,77 @@ vs_image_scale_lanczos_AYUV_float (const VSImage * dest, const VSImage * src,
|
|||
scale1d_cleanup (&scale->y_scale1d);
|
||||
g_free (scale->tmpdata);
|
||||
}
|
||||
|
||||
static void
|
||||
vs_scale_lanczos_AYUV64_double (Scale * scale)
|
||||
{
|
||||
int j;
|
||||
int yi;
|
||||
int tmp_yi;
|
||||
|
||||
tmp_yi = 0;
|
||||
|
||||
for (j = 0; j < scale->dest->height; j++) {
|
||||
guint16 *destline;
|
||||
double *taps;
|
||||
|
||||
destline = (guint16 *) (scale->dest->pixels + scale->dest->stride * j);
|
||||
|
||||
yi = scale->y_scale1d.offsets[j];
|
||||
|
||||
while (tmp_yi < yi + scale->y_scale1d.n_taps) {
|
||||
scale->horiz_resample_func (TMP_LINE_DOUBLE_AYUV (tmp_yi),
|
||||
scale->x_scale1d.offsets, scale->x_scale1d.taps, SRC_LINE (tmp_yi),
|
||||
scale->x_scale1d.n_taps, 0, scale->dest->width);
|
||||
tmp_yi++;
|
||||
}
|
||||
|
||||
taps = (double *) scale->y_scale1d.taps + j * scale->y_scale1d.n_taps;
|
||||
if (scale->dither) {
|
||||
resample_vert_dither_double_generic_u16 (destline,
|
||||
taps, TMP_LINE_DOUBLE_AYUV (scale->y_scale1d.offsets[j]),
|
||||
sizeof (double) * 4 * scale->dest->width,
|
||||
scale->y_scale1d.n_taps, 0, scale->dest->width * 4);
|
||||
} else {
|
||||
resample_vert_double_generic_u16 (destline,
|
||||
taps, TMP_LINE_DOUBLE_AYUV (scale->y_scale1d.offsets[j]),
|
||||
sizeof (double) * 4 * scale->dest->width,
|
||||
scale->y_scale1d.n_taps, 0, scale->dest->width * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vs_image_scale_lanczos_AYUV64_double (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf, double sharpness, gboolean dither, double a,
|
||||
double sharpen)
|
||||
{
|
||||
Scale s = { 0 };
|
||||
Scale *scale = &s;
|
||||
int n_taps;
|
||||
|
||||
scale->dest = dest;
|
||||
scale->src = src;
|
||||
|
||||
n_taps = scale1d_get_n_taps (src->width, dest->width, a, sharpness);
|
||||
scale1d_calculate_taps (&scale->x_scale1d,
|
||||
src->width, dest->width, n_taps, a, sharpness, sharpen);
|
||||
|
||||
n_taps = scale1d_get_n_taps (src->height, dest->height, a, sharpness);
|
||||
scale1d_calculate_taps (&scale->y_scale1d,
|
||||
src->height, dest->height, n_taps, a, sharpness, sharpen);
|
||||
|
||||
scale->dither = dither;
|
||||
|
||||
scale->horiz_resample_func =
|
||||
(HorizResampleFunc) resample_horiz_double_ayuv_generic;
|
||||
|
||||
scale->tmpdata =
|
||||
g_malloc (sizeof (double) * scale->dest->width * scale->src->height * 4);
|
||||
|
||||
vs_scale_lanczos_AYUV64_double (scale);
|
||||
|
||||
scale1d_cleanup (&scale->x_scale1d);
|
||||
scale1d_cleanup (&scale->y_scale1d);
|
||||
g_free (scale->tmpdata);
|
||||
}
|
||||
|
|
|
@ -519,6 +519,88 @@ vs_scanline_merge_linear_UYVY (uint8_t * dest, uint8_t * src1,
|
|||
}
|
||||
|
||||
|
||||
/* NV12 */
|
||||
|
||||
/* n is the number of bi-pixels */
|
||||
|
||||
void
|
||||
vs_scanline_downsample_NV12 (uint8_t * dest, uint8_t * src, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
dest[i * 2 + 0] = (src[i * 4 + 0] + src[i * 4 + 2]) / 2;
|
||||
dest[i * 2 + 1] = (src[i * 4 + 1] + src[i * 4 + 3]) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vs_scanline_resample_nearest_NV12 (uint8_t * dest, uint8_t * src, int src_width,
|
||||
int n, int *accumulator, int increment)
|
||||
{
|
||||
int acc = *accumulator;
|
||||
int i;
|
||||
int j;
|
||||
int x;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
j = acc >> 16;
|
||||
x = acc & 0xffff;
|
||||
|
||||
dest[i * 2 + 0] = (x < 32768
|
||||
|| j + 1 >= src_width) ? src[j * 2 + 0] : src[j * 2 + 2];
|
||||
dest[i * 2 + 1] = (x < 32768
|
||||
|| j + 1 >= src_width) ? src[j * 2 + 1] : src[j * 2 + 3];
|
||||
|
||||
acc += increment;
|
||||
}
|
||||
|
||||
*accumulator = acc;
|
||||
}
|
||||
|
||||
void
|
||||
vs_scanline_resample_linear_NV12 (uint8_t * dest, uint8_t * src, int src_width,
|
||||
int n, int *accumulator, int increment)
|
||||
{
|
||||
int acc = *accumulator;
|
||||
int i;
|
||||
int j;
|
||||
int x;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
j = acc >> 16;
|
||||
x = acc & 0xffff;
|
||||
|
||||
if (j + 1 < src_width) {
|
||||
dest[i * 2 + 0] =
|
||||
(src[j * 2 + 0] * (65536 - x) + src[j * 2 + 2] * x) >> 16;
|
||||
dest[i * 2 + 1] =
|
||||
(src[j * 2 + 1] * (65536 - x) + src[j * 2 + 3] * x) >> 16;
|
||||
} else {
|
||||
dest[i * 4 + 0] = src[j * 2 + 0];
|
||||
dest[i * 4 + 1] = src[j * 2 + 1];
|
||||
}
|
||||
|
||||
acc += increment;
|
||||
}
|
||||
|
||||
*accumulator = acc;
|
||||
}
|
||||
|
||||
void
|
||||
vs_scanline_merge_linear_NV12 (uint8_t * dest, uint8_t * src1,
|
||||
uint8_t * src2, int n, int x)
|
||||
{
|
||||
uint32_t value = x >> 8;
|
||||
|
||||
if (value == 0) {
|
||||
memcpy (dest, src1, n * 2);
|
||||
} else {
|
||||
orc_merge_linear_u8 (dest, src1, src2, value, n * 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* RGB565 */
|
||||
|
||||
/* note that src and dest are uint16_t, and thus endian dependent */
|
||||
|
|
|
@ -55,6 +55,11 @@ void vs_scanline_resample_nearest_UYVY (uint8_t *dest, uint8_t *src, int src_wid
|
|||
void vs_scanline_resample_linear_UYVY (uint8_t *dest, uint8_t *src, int src_width, int n, int *accumulator, int increment);
|
||||
void vs_scanline_merge_linear_UYVY (uint8_t *dest, uint8_t *src1, uint8_t *src2, int n, int x);
|
||||
|
||||
void vs_scanline_downsample_NV12 (uint8_t *dest, uint8_t *src, int n);
|
||||
void vs_scanline_resample_nearest_NV12 (uint8_t *dest, uint8_t *src, int src_width, int n, int *accumulator, int increment);
|
||||
void vs_scanline_resample_linear_NV12 (uint8_t *dest, uint8_t *src, int src_width, int n, int *accumulator, int increment);
|
||||
void vs_scanline_merge_linear_NV12 (uint8_t *dest, uint8_t *src1, uint8_t *src2, int n, int x);
|
||||
|
||||
void vs_scanline_downsample_RGB565 (uint8_t *dest, uint8_t *src, int n);
|
||||
void vs_scanline_resample_nearest_RGB565 (uint8_t *dest, uint8_t *src, int src_width, int n, int *accumulator, int increment);
|
||||
void vs_scanline_resample_linear_RGB565 (uint8_t *dest, uint8_t *src, int src_width, int n, int *accumulator, int increment);
|
||||
|
|
|
@ -607,7 +607,13 @@ GST_START_TEST (test_parse_caps_rgb)
|
|||
GST_VIDEO_CAPS_MAKE ("RGBA"), GST_VIDEO_FORMAT_RGBA}, {
|
||||
GST_VIDEO_CAPS_MAKE ("ARGB"), GST_VIDEO_FORMAT_ARGB}, {
|
||||
GST_VIDEO_CAPS_MAKE ("BGRA"), GST_VIDEO_FORMAT_BGRA}, {
|
||||
GST_VIDEO_CAPS_MAKE ("ABGR"), GST_VIDEO_FORMAT_ABGR}
|
||||
GST_VIDEO_CAPS_MAKE ("ABGR"), GST_VIDEO_FORMAT_ABGR},
|
||||
/* 16 bit */
|
||||
{
|
||||
GST_VIDEO_CAPS_MAKE ("RGB16"), GST_VIDEO_FORMAT_RGB16}, {
|
||||
GST_VIDEO_CAPS_MAKE ("BGR16"), GST_VIDEO_FORMAT_BGR16}, {
|
||||
GST_VIDEO_CAPS_MAKE ("RGB15"), GST_VIDEO_FORMAT_RGB15}, {
|
||||
GST_VIDEO_CAPS_MAKE ("BGR15"), GST_VIDEO_FORMAT_BGR15}
|
||||
};
|
||||
gint i;
|
||||
|
||||
|
|
Loading…
Reference in a new issue