rtpvp8: remove and move to -good

https://bugzilla.gnome.org/show_bug.cgi?id=687263
This commit is contained in:
Tim-Philipp Müller 2012-11-01 20:50:56 +00:00
parent 1f6944efc1
commit 854626c908
14 changed files with 2 additions and 1150 deletions

View file

@ -67,7 +67,6 @@ GST_PLUGINS_BAD_BUILT_SOURCES := \
gst/invtelecine/Android.mk \
gst/hdvparse/Android.mk \
gst/stereo/Android.mk \
gst/rtpvp8/Android.mk \
gst/mpegdemux/Android.mk \
gst/ivfparse/Android.mk
@ -161,6 +160,5 @@ CONFIGURE_TARGETS += gst-plugins-bad-configure
-include $(GST_PLUGINS_BAD_TOP)/gst/invtelecine/Android.mk
-include $(GST_PLUGINS_BAD_TOP)/gst/hdvparse/Android.mk
-include $(GST_PLUGINS_BAD_TOP)/gst/stereo/Android.mk
-include $(GST_PLUGINS_BAD_TOP)/gst/rtpvp8/Android.mk
-include $(GST_PLUGINS_BAD_TOP)/gst/mpegdemux/Android.mk
-include $(GST_PLUGINS_BAD_TOP)/gst/ivfparse/Android.mk

View file

@ -54,6 +54,7 @@ CRUFT_FILES = \
$(top_builddir)/gst/imagefreeze/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/mpeg4videoparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/qtmux/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/rtpvp8/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/selector/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/shapewipe/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/valve/.libs/*.{so,dll,DLL,dylib} \
@ -82,6 +83,7 @@ CRUFT_DIRS = \
$(top_srcdir)/gst/invtelecine \
$(top_srcdir)/gst/mpeg4videoparse \
$(top_srcdir)/gst/qtmux \
$(top_srcdir)/gst/rtpvp8 \
$(top_srcdir)/gst/selector \
$(top_srcdir)/gst/shapewipe \
$(top_srcdir)/gst/valve \

View file

@ -379,7 +379,6 @@ AG_GST_CHECK_PLUGIN(rawparse)
AG_GST_CHECK_PLUGIN(real)
AG_GST_CHECK_PLUGIN(removesilence)
AG_GST_CHECK_PLUGIN(rtpmux)
AG_GST_CHECK_PLUGIN(rtpvp8)
AG_GST_CHECK_PLUGIN(scaletempo)
AG_GST_CHECK_PLUGIN(sdi)
AG_GST_CHECK_PLUGIN(sdp)
@ -2065,7 +2064,6 @@ gst/rawparse/Makefile
gst/real/Makefile
gst/removesilence/Makefile
gst/rtpmux/Makefile
gst/rtpvp8/Makefile
gst/scaletempo/Makefile
gst/sdi/Makefile
gst/sdp/Makefile

View file

@ -1,55 +0,0 @@
<plugin>
<name>rtpvp8</name>
<description>rtpvp8</description>
<filename>../../gst/rtpvp8/.libs/libgstrtpvp8.so</filename>
<basename>libgstrtpvp8.so</basename>
<version>1.1.0.1</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>GStreamer Bad Plug-ins git</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>rtpvp8depay</name>
<longname>RTP VP8 depayloader</longname>
<class>Codec/Depayloader/Network/RTP</class>
<description>Extracts VP8 video from RTP packets)</description>
<author>Sjoerd Simons &lt;sjoerd@luon.net&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>application/x-rtp, payload=(int)[ 96, 127 ], clock-rate=(int)90000, media=(string)video, encoding-name=(string)VP8-DRAFT-IETF-01</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-vp8</details>
</caps>
</pads>
</element>
<element>
<name>rtpvp8pay</name>
<longname>RTP VP8 payloader</longname>
<class>Codec/Payloader/Network/RTP</class>
<description>Puts VP8 video in RTP packets)</description>
<author>Sjoerd Simons &lt;sjoerd@luon.net&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-vp8</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>application/x-rtp, payload=(int)[ 96, 127 ], clock-rate=(int)90000, encoding-name=(string)VP8-DRAFT-IETF-01</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View file

@ -317,7 +317,6 @@ make ERROR_CFLAGS='' ERROR_CXXFLAGS=''
# %{_libdir}/gstreamer-%{majorminor}/libgstsndfile.so
%{_libdir}/gstreamer-%{majorminor}/libgstfrei0r.so
%{_libdir}/gstreamer-%{majorminor}/libgstopencv.so
%{_libdir}/gstreamer-%{majorminor}/libgstrtpvp8.so
%{_libdir}/gstreamer-%{majorminor}/libgstvoamrwbenc.so
%{_datadir}/gstreamer-%{majorminor}/presets/*.prs

View file

@ -1,32 +0,0 @@
plugin_LTLIBRARIES = libgstrtpvp8.la
libgstrtpvp8_la_SOURCES = gstrtpvp8.c \
gstrtpvp8depay.c \
gstrtpvp8pay.c \
dboolhuff.c
noinst_HEADERS = gstrtpvp8depay.h \
gstrtpvp8pay.h \
dboolhuff.h
libgstrtpvp8_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) $(GST_CFLAGS) \
-Dvp8_norm=gst_rtpvp8_vp8_norm
libgstrtpvp8_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-@GST_API_VERSION@ \
$(GST_BASE_LIBS) $(GST_LIBS)
libgstrtpvp8_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstrtpvp8_la_LIBTOOLFLAGS = --tag=disable-static
Android.mk: Makefile.am $(BUILT_SOURCES)
androgenizer \
-:PROJECT libgstrtpvp8 -:SHARED libgstrtpvp8 \
-:TAGS eng debug \
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-:SOURCES $(libgstrtpvp8_la_SOURCES) \
-:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrtpvp8_la_CFLAGS) \
-:LDFLAGS $(libgstrtpvp8_la_LDFLAGS) \
$(libgstrtpvp8_la_LIBADD) \
-ldl \
-:PASSTHROUGH LOCAL_ARM_MODE:=arm \
LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-@GST_API_VERSION@' \
> $@

View file

@ -1,30 +0,0 @@
Copyright (c) 2010, Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Google nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,68 +0,0 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the dboolhuff.LICENSE file in this directory.
* See the libvpx original distribution for more information,
* including patent information, and author information.
*/
#include "dboolhuff.h"
const unsigned char vp8_norm[256] __attribute__ ((aligned (16))) = {
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int
vp8dx_start_decode (BOOL_DECODER * br,
const unsigned char *source, unsigned int source_sz)
{
br->user_buffer_end = source + source_sz;
br->user_buffer = source;
br->value = 0;
br->count = -8;
br->range = 255;
if (source_sz && !source)
return 1;
/* Populate the buffer */
vp8dx_bool_decoder_fill (br);
return 0;
}
void
vp8dx_bool_decoder_fill (BOOL_DECODER * br)
{
const unsigned char *bufptr;
const unsigned char *bufend;
VP8_BD_VALUE value;
int count;
bufend = br->user_buffer_end;
bufptr = br->user_buffer;
value = br->value;
count = br->count;
VP8DX_BOOL_DECODER_FILL (count, value, bufptr, bufend);
br->user_buffer = bufptr;
br->value = value;
br->count = count;
}

View file

@ -1,151 +0,0 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the dboolhuff.LICENSE file in this directory.
* See the libvpx original distribution for more information,
* including patent information, and author information.
*/
#ifndef DBOOLHUFF_H
#define DBOOLHUFF_H
#include <stddef.h>
#include <limits.h>
#include <glib.h>
typedef size_t VP8_BD_VALUE;
# define VP8_BD_VALUE_SIZE ((int)sizeof(VP8_BD_VALUE)*CHAR_BIT)
/*This is meant to be a large, positive constant that can still be efficiently
loaded as an immediate (on platforms like ARM, for example).
Even relatively modest values like 100 would work fine.*/
# define VP8_LOTS_OF_BITS (0x40000000)
typedef struct
{
const unsigned char *user_buffer_end;
const unsigned char *user_buffer;
VP8_BD_VALUE value;
int count;
unsigned int range;
} BOOL_DECODER;
extern const unsigned char vp8_norm[256] __attribute__((aligned(16)));
int vp8dx_start_decode(BOOL_DECODER *br,
const unsigned char *source,
unsigned int source_sz);
void vp8dx_bool_decoder_fill(BOOL_DECODER *br);
/*The refill loop is used in several places, so define it in a macro to make
sure they're all consistent.
An inline function would be cleaner, but has a significant penalty, because
multiple BOOL_DECODER fields must be modified, and the compiler is not smart
enough to eliminate the stores to those fields and the subsequent reloads
from them when inlining the function.*/
#define VP8DX_BOOL_DECODER_FILL(_count,_value,_bufptr,_bufend) \
do \
{ \
int shift = VP8_BD_VALUE_SIZE - 8 - ((_count) + 8); \
int loop_end, x; \
size_t bits_left = ((_bufend)-(_bufptr))*CHAR_BIT; \
\
x = shift + CHAR_BIT - bits_left; \
loop_end = 0; \
if(x >= 0) \
{ \
(_count) += VP8_LOTS_OF_BITS; \
loop_end = x; \
if(!bits_left) break; \
} \
while(shift >= loop_end) \
{ \
(_count) += CHAR_BIT; \
(_value) |= (VP8_BD_VALUE)*(_bufptr)++ << shift; \
shift -= CHAR_BIT; \
} \
} \
while(0) \
static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
unsigned int bit = 0;
VP8_BD_VALUE value;
unsigned int split;
VP8_BD_VALUE bigsplit;
int count;
unsigned int range;
split = 1 + (((br->range - 1) * probability) >> 8);
if(br->count < 0)
vp8dx_bool_decoder_fill(br);
value = br->value;
count = br->count;
bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8);
range = split;
if (value >= bigsplit)
{
range = br->range - split;
value = value - bigsplit;
bit = 1;
}
{
register unsigned int shift = vp8_norm[range];
range <<= shift;
value <<= shift;
count -= shift;
}
br->value = value;
br->count = count;
br->range = range;
return bit;
}
static G_GNUC_UNUSED int vp8_decode_value(BOOL_DECODER *br, int bits)
{
int z = 0;
int bit;
for (bit = bits - 1; bit >= 0; bit--)
{
z |= (vp8dx_decode_bool(br, 0x80) << bit);
}
return z;
}
static G_GNUC_UNUSED int vp8dx_bool_error(BOOL_DECODER *br)
{
/* Check if we have reached the end of the buffer.
*
* Variable 'count' stores the number of bits in the 'value' buffer, minus
* 8. The top byte is part of the algorithm, and the remainder is buffered
* to be shifted into it. So if count == 8, the top 16 bits of 'value' are
* occupied, 8 for the algorithm and 8 in the buffer.
*
* When reading a byte from the user's buffer, count is filled with 8 and
* one byte is filled into the value buffer. When we reach the end of the
* data, count is additionally filled with VP8_LOTS_OF_BITS. So when
* count == VP8_LOTS_OF_BITS - 1, the user's data has been exhausted.
*/
if ((br->count > VP8_BD_VALUE_SIZE) && (br->count < VP8_LOTS_OF_BITS))
{
/* We have tried to decode bits after the end of
* stream was encountered.
*/
return 1;
}
/* No error. */
return 0;
}
#endif

View file

@ -1,21 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstrtpvp8pay.h"
#include "gstrtpvp8depay.h"
static gboolean
plugin_init (GstPlugin * plugin)
{
gst_rtp_vp8_depay_plugin_init (plugin);
gst_rtp_vp8_pay_plugin_init (plugin);
return TRUE;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
rtpvp8,
"rtpvp8",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)

View file

@ -1,209 +0,0 @@
/*
* gstrtpvp8depay.c - Source for GstRtpVP8Depay
* Copyright (C) 2011 Sjoerd Simons <sjoerd@luon.net>
* Copyright (C) 2011 Collabora Ltd.
* Contact: Youness Alaoui <youness.alaoui@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "gstrtpvp8depay.h"
GST_DEBUG_CATEGORY_STATIC (gst_rtp_vp8_depay_debug);
#define GST_CAT_DEFAULT gst_rtp_vp8_depay_debug
G_DEFINE_TYPE (GstRtpVP8Depay, gst_rtp_vp8_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);
static GstStaticPadTemplate gst_rtp_vp8_depay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-vp8"));
static GstStaticPadTemplate gst_rtp_vp8_depay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, "
"payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ","
"clock-rate = (int) 90000,"
"media = (string) \"video\","
"encoding-name = (string) \"VP8-DRAFT-IETF-01\""));
static void
gst_rtp_vp8_depay_init (GstRtpVP8Depay * self)
{
self->adapter = gst_adapter_new ();
self->started = FALSE;
}
static void gst_rtp_vp8_depay_dispose (GObject * object);
static GstBuffer *gst_rtp_vp8_depay_process (GstRTPBaseDepayload * depayload,
GstBuffer * buf);
static gboolean gst_rtp_vp8_depay_set_caps (GstRTPBaseDepayload * depayload,
GstCaps * caps);
static void
gst_rtp_vp8_depay_class_init (GstRtpVP8DepayClass * gst_rtp_vp8_depay_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (gst_rtp_vp8_depay_class);
GstElementClass *element_class = GST_ELEMENT_CLASS (gst_rtp_vp8_depay_class);
GstRTPBaseDepayloadClass *depay_class =
(GstRTPBaseDepayloadClass *) (gst_rtp_vp8_depay_class);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_rtp_vp8_depay_sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_rtp_vp8_depay_src_template));
gst_element_class_set_static_metadata (element_class, "RTP VP8 depayloader",
"Codec/Depayloader/Network/RTP",
"Extracts VP8 video from RTP packets)",
"Sjoerd Simons <sjoerd@luon.net>");
object_class->dispose = gst_rtp_vp8_depay_dispose;
depay_class->process = gst_rtp_vp8_depay_process;
depay_class->set_caps = gst_rtp_vp8_depay_set_caps;
GST_DEBUG_CATEGORY_INIT (gst_rtp_vp8_depay_debug, "rtpvp8depay", 0,
"VP8 Video RTP Depayloader");
}
static void
gst_rtp_vp8_depay_dispose (GObject * object)
{
GstRtpVP8Depay *self = GST_RTP_VP8_DEPAY (object);
if (self->adapter != NULL)
g_object_unref (self->adapter);
self->adapter = NULL;
/* release any references held by the object here */
if (G_OBJECT_CLASS (gst_rtp_vp8_depay_parent_class)->dispose)
G_OBJECT_CLASS (gst_rtp_vp8_depay_parent_class)->dispose (object);
}
static GstBuffer *
gst_rtp_vp8_depay_process (GstRTPBaseDepayload * depay, GstBuffer * buf)
{
GstRtpVP8Depay *self = GST_RTP_VP8_DEPAY (depay);
GstBuffer *payload;
guint8 *data;
guint offset;
guint size;
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buf))) {
GST_LOG_OBJECT (self, "Discontinuity, flushing adapter");
gst_adapter_clear (self->adapter);
self->started = FALSE;
}
gst_rtp_buffer_map (buf, GST_MAP_READ, &rtpbuffer);
size = gst_rtp_buffer_get_payload_len (&rtpbuffer);
/* At least one header and one vp8 byte */
if (G_UNLIKELY (size < 2))
goto too_small;
data = gst_rtp_buffer_get_payload (&rtpbuffer);
if (G_UNLIKELY (!self->started)) {
/* Check if this is the start of a VP8 frame, otherwise bail */
/* S=1 and PartID= 0 */
if ((data[0] & 0x1F) != 0x10)
goto done;
self->started = TRUE;
}
offset = 1;
/* Check X optional header */
if ((data[0] & 0x80) != 0) {
offset++;
/* Check I optional header */
if ((data[1] & 0x80) != 0) {
offset++;
if (G_UNLIKELY (offset + 2 >= size))
goto too_small;
/* Check for 16 bits PictureID */
if ((data[2] & 0x80) != 0)
offset++;
}
/* Check L optional header */
if ((data[1] & 0x40) != 0)
offset++;
/* Check T or K optional headers */
if ((data[1] & 0x20) != 0 || (data[1] & 0x10) != 0)
offset++;
}
if (G_UNLIKELY (offset >= size))
goto too_small;
payload = gst_rtp_buffer_get_payload_subbuffer (&rtpbuffer, offset, -1);
gst_adapter_push (self->adapter, payload);
/* Marker indicates that it was the last rtp packet for this frame */
if (gst_rtp_buffer_get_marker (&rtpbuffer)) {
GstBuffer *out;
out = gst_adapter_take_buffer (self->adapter,
gst_adapter_available (self->adapter));
self->started = FALSE;
gst_rtp_buffer_unmap (&rtpbuffer);
return out;
}
done:
gst_rtp_buffer_unmap (&rtpbuffer);
return NULL;
too_small:
GST_LOG_OBJECT (self, "Invalid rtp packet (too small), ignoring");
gst_adapter_clear (self->adapter);
self->started = FALSE;
goto done;
}
static gboolean
gst_rtp_vp8_depay_set_caps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
GstCaps *srccaps = gst_caps_new_simple ("video/x-vp8",
"framerate", GST_TYPE_FRACTION, 0, 1,
NULL);
gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (depayload), srccaps);
gst_caps_unref (srccaps);
return TRUE;
}
gboolean
gst_rtp_vp8_depay_plugin_init (GstPlugin * plugin)
{
return gst_element_register (plugin, "rtpvp8depay",
GST_RANK_MARGINAL, GST_TYPE_RTP_VP8_DEPAY);
}

View file

@ -1,63 +0,0 @@
/*
* gstrtpvp8depay.h - Header for GstRtpVP8Depay
* Copyright (C) 2011 Sjoerd Simons <sjoerd@luon.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __GST_RTP_VP8_DEPAY_H__
#define __GST_RTP_VP8_DEPAY_H__
#include <glib-object.h>
#include <gst/base/gstadapter.h>
#include <gst/rtp/gstrtpbasedepayload.h>
G_BEGIN_DECLS typedef struct _GstRtpVP8Depay GstRtpVP8Depay;
typedef struct _GstRtpVP8DepayClass GstRtpVP8DepayClass;
struct _GstRtpVP8DepayClass
{
GstRTPBaseDepayloadClass parent_class;
};
struct _GstRtpVP8Depay
{
GstRTPBaseDepayload parent;
GstAdapter *adapter;
gboolean started;
};
GType gst_rtp_vp8_depay_get_type (void);
/* TYPE MACROS */
#define GST_TYPE_RTP_VP8_DEPAY \
(gst_rtp_vp8_depay_get_type())
#define GST_RTP_VP8_DEPAY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_RTP_VP8_DEPAY, GstRtpVP8Depay))
#define GST_RTP_VP8_DEPAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_RTP_VP8_DEPAY, \
GstRtpVP8DepayClass))
#define GST_IS_RTP_VP8_DEPAY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_RTP_VP8_DEPAY))
#define GST_IS_RTP_VP8_DEPAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_RTP_VP8_DEPAY))
#define GST_RTP_VP8_DEPAY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTP_VP8_DEPAY, \
GstRtpVP8DepayClass))
gboolean gst_rtp_vp8_depay_plugin_init (GstPlugin * plugin);
G_END_DECLS
#endif /* #ifndef __GST_RTP_VP8_DEPAY_H__ */

View file

@ -1,442 +0,0 @@
/*
* gstrtpvp8pay.c - Source for GstRtpVP8Pay
* Copyright (C) 2011 Sjoerd Simons <sjoerd@luon.net>
* Copyright (C) 2011 Collabora Ltd.
* Contact: Youness Alaoui <youness.alaoui@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gst/base/gstbitreader.h>
#include <gst/rtp/gstrtppayloads.h>
#include <gst/rtp/gstrtpbuffer.h>
#include "dboolhuff.h"
#include "gstrtpvp8pay.h"
GST_DEBUG_CATEGORY_STATIC (gst_rtp_vp8_pay_debug);
#define GST_CAT_DEFAULT gst_rtp_vp8_pay_debug
#define DEFAULT_PICTURE_ID_MODE VP8_PAY_PICTURE_ID_7BITS
G_DEFINE_TYPE (GstRtpVP8Pay, gst_rtp_vp8_pay, GST_TYPE_RTP_BASE_PAYLOAD);
static GstStaticPadTemplate gst_rtp_vp8_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, "
"payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ","
"clock-rate = (int) 90000, encoding-name = (string) \"VP8-DRAFT-IETF-01\""));
static GstStaticPadTemplate gst_rtp_vp8_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-vp8"));
static void
gst_rtp_vp8_pay_init (GstRtpVP8Pay * obj)
{
/* TODO: Make it configurable */
obj->picture_id_mode = DEFAULT_PICTURE_ID_MODE;
if (obj->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS)
obj->picture_id = g_random_int_range (0, G_MAXUINT8) & 0x7F;
else if (obj->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS)
obj->picture_id = g_random_int_range (0, G_MAXUINT16) & 0x7FFF;
}
static GstFlowReturn gst_rtp_vp8_pay_handle_buffer (GstRTPBasePayload * payload,
GstBuffer * buffer);
static gboolean gst_rtp_vp8_pay_sink_event (GstRTPBasePayload * payload,
GstEvent * event);
static gboolean gst_rtp_vp8_pay_set_caps (GstRTPBasePayload * payload,
GstCaps * caps);
static void
gst_rtp_vp8_pay_class_init (GstRtpVP8PayClass * gst_rtp_vp8_pay_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gst_rtp_vp8_pay_class);
GstRTPBasePayloadClass *pay_class =
GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_vp8_pay_class);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_rtp_vp8_pay_sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_rtp_vp8_pay_src_template));
gst_element_class_set_static_metadata (element_class, "RTP VP8 payloader",
"Codec/Payloader/Network/RTP",
"Puts VP8 video in RTP packets)", "Sjoerd Simons <sjoerd@luon.net>");
pay_class->handle_buffer = gst_rtp_vp8_pay_handle_buffer;
pay_class->sink_event = gst_rtp_vp8_pay_sink_event;
pay_class->set_caps = gst_rtp_vp8_pay_set_caps;
GST_DEBUG_CATEGORY_INIT (gst_rtp_vp8_pay_debug, "rtpvp8pay", 0,
"VP8 Video RTP Payloader");
}
static gboolean
gst_rtp_vp8_pay_parse_frame (GstRtpVP8Pay * self, GstBuffer * buffer)
{
GstBitReader *reader = NULL;
guint8 *data;
gsize size;
GstMapInfo map;
int i;
gboolean keyframe;
guint32 partition0_size;
guint8 version;
guint8 tmp8 = 0;
guint8 partitions;
guint offset;
BOOL_DECODER bc;
guint8 *pdata;
if (G_UNLIKELY (gst_buffer_get_size (buffer) < 3))
goto error;
if (!gst_buffer_map (buffer, &map, GST_MAP_READ) || !map.data)
goto error;
data = map.data;
size = map.size;
reader = gst_bit_reader_new (data, size);
self->is_keyframe = keyframe = ((data[0] & 0x1) == 0);
version = (data[0] >> 1) & 0x7;
if (G_UNLIKELY (version > 3)) {
GST_ERROR_OBJECT (self, "Unknown VP8 version %u", version);
goto error;
}
/* keyframe, version and show_frame use 5 bits */
partition0_size = data[2] << 11 | data[1] << 3 | (data[0] >> 5);
/* Include the uncompressed data blob in the first partition */
offset = keyframe ? 10 : 3;
partition0_size += offset;
if (!gst_bit_reader_skip (reader, 24))
goto error;
if (keyframe) {
/* check start tag: 0x9d 0x01 0x2a */
if (!gst_bit_reader_get_bits_uint8 (reader, &tmp8, 8) || tmp8 != 0x9d)
goto error;
if (!gst_bit_reader_get_bits_uint8 (reader, &tmp8, 8) || tmp8 != 0x01)
goto error;
if (!gst_bit_reader_get_bits_uint8 (reader, &tmp8, 8) || tmp8 != 0x2a)
goto error;
/* Skip horizontal size code (16 bits) vertical size code (16 bits) */
if (!gst_bit_reader_skip (reader, 32))
goto error;
}
offset = keyframe ? 10 : 3;
vp8dx_start_decode (&bc, data + offset, size - offset);
if (keyframe) {
/* color space (1 bit) and clamping type (1 bit) */
vp8dx_decode_bool (&bc, 0x80);
vp8dx_decode_bool (&bc, 0x80);
}
/* segmentation_enabled */
if (vp8dx_decode_bool (&bc, 0x80)) {
guint8 update_mb_segmentation_map = vp8dx_decode_bool (&bc, 0x80);
guint8 update_segment_feature_data = vp8dx_decode_bool (&bc, 0x80);
if (update_segment_feature_data) {
/* skip segment feature mode */
vp8dx_decode_bool (&bc, 0x80);
/* quantizer update */
for (i = 0; i < 4; i++) {
/* skip flagged quantizer value (7 bits) and sign (1 bit) */
if (vp8dx_decode_bool (&bc, 0x80))
vp8_decode_value (&bc, 8);
}
/* loop filter update */
for (i = 0; i < 4; i++) {
/* skip flagged lf update value (6 bits) and sign (1 bit) */
if (vp8dx_decode_bool (&bc, 0x80))
vp8_decode_value (&bc, 7);
}
}
if (update_mb_segmentation_map) {
/* segment prob update */
for (i = 0; i < 3; i++) {
/* skip flagged segment prob */
if (vp8dx_decode_bool (&bc, 0x80))
vp8_decode_value (&bc, 8);
}
}
}
/* skip filter type (1 bit), loop filter level (6 bits) and
* sharpness level (3 bits) */
vp8_decode_value (&bc, 1);
vp8_decode_value (&bc, 6);
vp8_decode_value (&bc, 3);
/* loop_filter_adj_enabled */
if (vp8dx_decode_bool (&bc, 0x80)) {
/* delta update */
if (vp8dx_decode_bool (&bc, 0x80)) {
for (i = 0; i < 8; i++) {
/* 8 updates, 1 bit indicate whether there is one and if follow by a
* 7 bit update */
if (vp8dx_decode_bool (&bc, 0x80))
vp8_decode_value (&bc, 7);
}
}
}
if (vp8dx_bool_error (&bc))
goto error;
tmp8 = vp8_decode_value (&bc, 2);
partitions = 1 << tmp8;
/* Check if things are still sensible */
if (partition0_size + (partitions - 1) * 3 >= size)
goto error;
/* partition data is right after the mode partition */
pdata = data + partition0_size;
/* Set up mapping */
self->n_partitions = partitions + 1;
self->partition_offset[0] = 0;
self->partition_size[0] = partition0_size + (partitions - 1) * 3;
self->partition_offset[1] = self->partition_size[0];
for (i = 1; i < partitions; i++) {
guint psize = (pdata[2] << 16 | pdata[1] << 8 | pdata[0]);
pdata += 3;
self->partition_size[i] = psize;
self->partition_offset[i + 1] = self->partition_offset[i] + psize;
}
/* Check that our partition offsets and sizes don't go outsize the buffer
* size. */
if (self->partition_offset[i] >= size)
goto error;
self->partition_size[i] = size - self->partition_offset[i];
self->partition_offset[i + 1] = size;
gst_bit_reader_free (reader);
gst_buffer_unmap (buffer, &map);
return TRUE;
error:
GST_DEBUG ("Failed to parse frame");
if (reader) {
gst_bit_reader_free (reader);
gst_buffer_unmap (buffer, &map);
}
return FALSE;
}
static guint
gst_rtp_vp8_offset_to_partition (GstRtpVP8Pay * self, guint offset)
{
int i;
for (i = 0; i < self->n_partitions; i++) {
if (offset >= self->partition_offset[i] &&
offset < self->partition_offset[i + 1])
return i;
}
return i;
}
static gsize
gst_rtp_vp8_calc_header_len (GstRtpVP8Pay * self)
{
switch (self->picture_id_mode) {
case VP8_PAY_PICTURE_ID_7BITS:
return 3;
case VP8_PAY_PICTURE_ID_15BITS:
return 4;
case VP8_PAY_NO_PICTURE_ID:
default:
return 1;
}
}
static gsize
gst_rtp_vp8_calc_payload_len (GstRtpVP8Pay * self)
{
GstRTPBasePayload *payload = GST_RTP_BASE_PAYLOAD (self);
return gst_rtp_buffer_calc_payload_len (GST_RTP_BASE_PAYLOAD_MTU (payload) -
gst_rtp_vp8_calc_header_len (self), 0, 0);
}
/* When growing the vp8 header keep gst_rtp_vp8_calc_payload_len in sync */
static GstBuffer *
gst_rtp_vp8_create_header_buffer (GstRtpVP8Pay * self, guint8 partid,
gboolean start, gboolean mark, GstBuffer * in)
{
GstBuffer *out;
guint8 *p;
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
out = gst_rtp_buffer_new_allocate (gst_rtp_vp8_calc_header_len (self), 0, 0);
gst_rtp_buffer_map (out, GST_MAP_READWRITE, &rtpbuffer);
p = gst_rtp_buffer_get_payload (&rtpbuffer);
/* X=0,R=0,N=0,S=start,PartID=partid */
p[0] = (start << 4) | partid;
if (self->picture_id_mode != VP8_PAY_NO_PICTURE_ID) {
/* Enable X=1 */
p[0] |= 0x80;
/* X: I=1,L=0,T=0,K=0,RSV=0 */
p[1] = 0x80;
if (self->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS) {
/* I: 7 bit picture_id */
p[2] = self->picture_id & 0x7F;
} else {
/* I: 15 bit picture_id */
p[2] = 0x80 | ((self->picture_id & 0x7FFF) >> 8);
p[3] = self->picture_id & 0xFF;
}
}
gst_rtp_buffer_set_marker (&rtpbuffer, mark);
gst_rtp_buffer_unmap (&rtpbuffer);
GST_BUFFER_DURATION (out) = GST_BUFFER_DURATION (in);
GST_BUFFER_PTS (out) = GST_BUFFER_PTS (in);
return out;
}
static guint
gst_rtp_vp8_payload_next (GstRtpVP8Pay * self,
GstBufferList * list, guint offset, GstBuffer * buffer)
{
guint partition;
GstBuffer *header;
GstBuffer *sub;
GstBuffer *out;
gboolean mark;
gsize remaining;
gsize available;
remaining = gst_buffer_get_size (buffer) - offset;
available = gst_rtp_vp8_calc_payload_len (self);
if (available > remaining)
available = remaining;
partition = gst_rtp_vp8_offset_to_partition (self, offset);
g_assert (partition < self->n_partitions);
mark = (remaining == available);
/* whole set of partitions, payload them and done */
header = gst_rtp_vp8_create_header_buffer (self, partition,
offset == self->partition_offset[partition], mark, buffer);
sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, available);
out = gst_buffer_append (header, sub);
gst_buffer_list_insert (list, -1, out);
return available;
}
static GstFlowReturn
gst_rtp_vp8_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
{
GstRtpVP8Pay *self = GST_RTP_VP8_PAY (payload);
GstFlowReturn ret;
GstBufferList *list;
guint offset;
if (G_UNLIKELY (!gst_rtp_vp8_pay_parse_frame (self, buffer))) {
g_message ("Failed to parse frame");
return GST_FLOW_ERROR;
}
list = gst_buffer_list_new ();
for (offset = 0; offset < gst_buffer_get_size (buffer);)
offset += gst_rtp_vp8_payload_next (self, list, offset, buffer);
ret = gst_rtp_base_payload_push_list (payload, list);
/* Incremenent and wrap the picture id if it overflows */
if ((self->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS &&
++self->picture_id >= 0x80) ||
(self->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS &&
++self->picture_id >= 0x8000))
self->picture_id = 0;
return ret;
}
static gboolean
gst_rtp_vp8_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
{
GstRtpVP8Pay *self = GST_RTP_VP8_PAY (payload);
if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
if (self->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS)
self->picture_id = g_random_int_range (0, G_MAXUINT8) & 0x7F;
else if (self->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS)
self->picture_id = g_random_int_range (0, G_MAXUINT16) & 0x7FFF;
}
return GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_vp8_pay_parent_class)->sink_event
(payload, event);
}
static gboolean
gst_rtp_vp8_pay_set_caps (GstRTPBasePayload * payload, GstCaps * caps)
{
gst_rtp_base_payload_set_options (payload, "video", TRUE,
"VP8-DRAFT-IETF-01", 90000);
return gst_rtp_base_payload_set_outcaps (payload, NULL);
}
gboolean
gst_rtp_vp8_pay_plugin_init (GstPlugin * plugin)
{
return gst_element_register (plugin, "rtpvp8pay",
GST_RANK_MARGINAL, GST_TYPE_RTP_VP8_PAY);
}

View file

@ -1,74 +0,0 @@
/*
* gstrtpvp8pay.h - Header for GstRtpVP8Pay
* Copyright (C) 2011 Sjoerd Simons <sjoerd@luon.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __GST_RTP_VP8_PAY_H__
#define __GST_RTP_VP8_PAY_H__
#include <glib-object.h>
#include <gst/base/gstadapter.h>
#include <gst/rtp/gstrtpbasepayload.h>
G_BEGIN_DECLS typedef struct _GstRtpVP8Pay GstRtpVP8Pay;
typedef struct _GstRtpVP8PayClass GstRtpVP8PayClass;
typedef enum _PictureIDMode PictureIDMode;
enum _PictureIDMode {
VP8_PAY_NO_PICTURE_ID,
VP8_PAY_PICTURE_ID_7BITS,
VP8_PAY_PICTURE_ID_15BITS,
};
struct _GstRtpVP8PayClass
{
GstRTPBasePayloadClass parent_class;
};
struct _GstRtpVP8Pay
{
GstRTPBasePayload parent;
gboolean is_keyframe;
gint n_partitions;
/* Treat frame header & tag & partition size block as the first partition,
* folowed by max. 8 data partitions. last offset is the end of the buffer */
guint partition_offset[10];
guint partition_size[9];
PictureIDMode picture_id_mode;
guint16 picture_id;
};
GType gst_rtp_vp8_pay_get_type (void);
/* TYPE MACROS */
#define GST_TYPE_RTP_VP8_PAY \
(gst_rtp_vp8_pay_get_type())
#define GST_RTP_VP8_PAY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_RTP_VP8_PAY, GstRtpVP8Pay))
#define GST_RTP_VP8_PAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_RTP_VP8_PAY, GstRtpVP8PayClass))
#define GST_IS_RTP_VP8_PAY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_RTP_VP8_PAY))
#define GST_IS_RTP_VP8_PAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_RTP_VP8_PAY))
#define GST_RTP_VP8_PAY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTP_VP8_PAY, GstRtpVP8PayClass))
gboolean gst_rtp_vp8_pay_plugin_init (GstPlugin * plugin);
G_END_DECLS
#endif /* #ifndef __GST_RTP_VP8_PAY_H__ */