mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 18:51:11 +00:00
96690aa992
Original commit message from CVS: * configure.ac: * gst/rawparse/Makefile.am: * gst/rawparse/README: * gst/rawparse/gstaudioparse.c: (gst_audio_parse_format_get_type), (gst_audio_parse_endianness_get_type), (gst_audio_parse_base_init), (gst_audio_parse_class_init), (gst_audio_parse_init), (gst_audio_parse_set_property), (gst_audio_parse_get_property), (gst_audio_parse_update_frame_size), (gst_audio_parse_get_caps): * gst/rawparse/gstaudioparse.h: * gst/rawparse/gstrawparse.c: (gst_raw_parse_base_init), (gst_raw_parse_class_init), (gst_raw_parse_init), (gst_raw_parse_dispose), (gst_raw_parse_class_set_src_pad_template), (gst_raw_parse_class_set_multiple_frames_per_buffer), (gst_raw_parse_reset), (gst_raw_parse_chain), (gst_raw_parse_convert), (gst_raw_parse_sink_event), (gst_raw_parse_src_event), (gst_raw_parse_src_query_type), (gst_raw_parse_src_query), (gst_raw_parse_set_framesize), (gst_raw_parse_set_fps), (gst_raw_parse_get_fps), (gst_raw_parse_is_negotiated): * gst/rawparse/gstrawparse.h: * gst/rawparse/gstvideoparse.c: (gst_video_parse_format_get_type), (gst_video_parse_endianness_get_type), (gst_video_parse_base_init), (gst_video_parse_class_init), (gst_video_parse_init), (gst_video_parse_set_property), (gst_video_parse_get_property), (gst_video_parse_format_to_fourcc), (gst_video_parse_update_frame_size), (gst_video_parse_get_caps): * gst/rawparse/gstvideoparse.h: * gst/rawparse/plugin.c: (plugin_init): Add new plugin rawparse that contains a base class for raw data parsers and the two elements audioparse and videoparse that can be used to parse raw audio and video. These are inspired by the old videoparse element which the new rawparse plugin deprecates.
319 lines
9.2 KiB
C
319 lines
9.2 KiB
C
/* GStreamer
|
|
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
|
|
*
|
|
* gstaudioparse.c:
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
/**
|
|
* SECTION:element-audioparse
|
|
* @short_description: parses a byte stream into audio frames
|
|
*
|
|
* Converts a byte stream into audio frames.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include "gstaudioparse.h"
|
|
|
|
typedef enum
|
|
{
|
|
GST_AUDIO_PARSE_FORMAT_INT,
|
|
GST_AUDIO_PARSE_FORMAT_FLOAT
|
|
} GstAudioParseFormat;
|
|
|
|
typedef enum
|
|
{
|
|
GST_AUDIO_PARSE_ENDIANNESS_LITTLE = 1234,
|
|
GST_AUDIO_PARSE_ENDIANNESS_BIG = 4321
|
|
} GstAudioParseEndianness;
|
|
|
|
static void gst_audio_parse_set_property (GObject * object, guint prop_id,
|
|
const GValue * value, GParamSpec * pspec);
|
|
static void gst_audio_parse_get_property (GObject * object, guint prop_id,
|
|
GValue * value, GParamSpec * pspec);
|
|
|
|
static GstCaps *gst_audio_parse_get_caps (GstRawParse * rp);
|
|
|
|
static void gst_audio_parse_update_frame_size (GstAudioParse * ap);
|
|
|
|
GST_DEBUG_CATEGORY_STATIC (gst_audio_parse_debug);
|
|
#define GST_CAT_DEFAULT gst_audio_parse_debug
|
|
|
|
static const GstElementDetails gst_audio_parse_details =
|
|
GST_ELEMENT_DETAILS ("Audio Parse",
|
|
"Filter/Audio",
|
|
"Converts stream into audio frames",
|
|
"Sebastian Dröge <slomo@circular-chaos.org>");
|
|
|
|
enum
|
|
{
|
|
ARG_0,
|
|
ARG_FORMAT,
|
|
ARG_RATE,
|
|
ARG_CHANNELS,
|
|
ARG_ENDIANNESS,
|
|
ARG_WIDTH,
|
|
ARG_DEPTH,
|
|
ARG_SIGNED,
|
|
};
|
|
|
|
|
|
#define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ())
|
|
static GType
|
|
gst_audio_parse_format_get_type (void)
|
|
{
|
|
static GType audio_parse_format_type = 0;
|
|
static const GEnumValue format_types[] = {
|
|
{GST_AUDIO_PARSE_FORMAT_INT, "Integer", "int"},
|
|
{GST_AUDIO_PARSE_FORMAT_FLOAT, "Floating Point", "float"},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
if (!audio_parse_format_type) {
|
|
audio_parse_format_type =
|
|
g_enum_register_static ("GstAudioParseFormat", format_types);
|
|
}
|
|
|
|
return audio_parse_format_type;
|
|
}
|
|
|
|
#define GST_AUDIO_PARSE_ENDIANNESS (gst_audio_parse_endianness_get_type ())
|
|
static GType
|
|
gst_audio_parse_endianness_get_type (void)
|
|
{
|
|
static GType audio_parse_endianness_type = 0;
|
|
static const GEnumValue endian_types[] = {
|
|
{GST_AUDIO_PARSE_ENDIANNESS_LITTLE, "Little Endian", "little"},
|
|
{GST_AUDIO_PARSE_ENDIANNESS_BIG, "Big Endian", "big"},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
if (!audio_parse_endianness_type) {
|
|
audio_parse_endianness_type =
|
|
g_enum_register_static ("GstAudioParseEndianness", endian_types);
|
|
}
|
|
|
|
return audio_parse_endianness_type;
|
|
}
|
|
|
|
GST_BOILERPLATE (GstAudioParse, gst_audio_parse, GstRawParse,
|
|
GST_TYPE_RAW_PARSE);
|
|
|
|
static void
|
|
gst_audio_parse_base_init (gpointer g_class)
|
|
{
|
|
GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class);
|
|
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
|
|
GstCaps *caps;
|
|
|
|
GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
|
|
"audioparse element");
|
|
|
|
gst_element_class_set_details (gstelement_class, &gst_audio_parse_details);
|
|
|
|
caps =
|
|
gst_caps_from_string ("audio/x-raw-int,"
|
|
" depth=(int) [ 1, 32 ],"
|
|
" width=(int) { 8, 16, 24, 32 },"
|
|
" endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
|
|
" signed=(bool) { TRUE, FALSE },"
|
|
" rate=(int) [ 1, MAX ],"
|
|
" channels=(int) [ 1, MAX ]; "
|
|
"audio/x-raw-float,"
|
|
" width=(int) { 32, 64 },"
|
|
" endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
|
|
" rate=(int)[1,MAX]," " channels=(int)[1,MAX]");
|
|
|
|
gst_raw_parse_class_set_src_pad_template (rp_class, caps);
|
|
gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE);
|
|
gst_caps_unref (caps);
|
|
}
|
|
|
|
static void
|
|
gst_audio_parse_class_init (GstAudioParseClass * klass)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass);
|
|
|
|
gobject_class->set_property = gst_audio_parse_set_property;
|
|
gobject_class->get_property = gst_audio_parse_get_property;
|
|
|
|
rp_class->get_caps = gst_audio_parse_get_caps;
|
|
|
|
g_object_class_install_property (gobject_class, ARG_FORMAT,
|
|
g_param_spec_enum ("format", "Format",
|
|
"Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
|
|
GST_AUDIO_PARSE_FORMAT_INT, G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (gobject_class, ARG_RATE,
|
|
g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
|
|
1, INT_MAX, 44100, G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (gobject_class, ARG_CHANNELS,
|
|
g_param_spec_int ("channels", "Channels",
|
|
"Number of channels in raw stream", 1, INT_MAX, 2,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (gobject_class, ARG_WIDTH,
|
|
g_param_spec_int ("width", "Width",
|
|
"Width of audio samples in raw stream", 1, INT_MAX, 16,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (gobject_class, ARG_DEPTH,
|
|
g_param_spec_int ("depth", "Depth",
|
|
"Depth of audio samples in raw stream", 1, INT_MAX, 16,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (gobject_class, ARG_SIGNED,
|
|
g_param_spec_boolean ("signed", "signed",
|
|
"Sign of audio samples in raw stream", TRUE, G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (gobject_class, ARG_ENDIANNESS,
|
|
g_param_spec_enum ("endianness", "Endianness",
|
|
"Endianness of audio samples in raw stream",
|
|
GST_AUDIO_PARSE_ENDIANNESS, G_BYTE_ORDER, G_PARAM_READWRITE));
|
|
}
|
|
|
|
static void
|
|
gst_audio_parse_init (GstAudioParse * ap, GstAudioParseClass * g_class)
|
|
{
|
|
ap->format = GST_AUDIO_PARSE_FORMAT_INT;
|
|
ap->channels = 2;
|
|
ap->width = 16;
|
|
ap->depth = 16;
|
|
ap->signedness = TRUE;
|
|
ap->endianness = G_BYTE_ORDER;
|
|
|
|
gst_audio_parse_update_frame_size (ap);
|
|
gst_raw_parse_set_fps (GST_RAW_PARSE (ap), 44100, 1);
|
|
}
|
|
|
|
static void
|
|
gst_audio_parse_set_property (GObject * object, guint prop_id,
|
|
const GValue * value, GParamSpec * pspec)
|
|
{
|
|
GstAudioParse *ap = GST_AUDIO_PARSE (object);
|
|
|
|
g_return_if_fail (!gst_raw_parse_is_negotiated (GST_RAW_PARSE (ap)));
|
|
|
|
switch (prop_id) {
|
|
case ARG_FORMAT:
|
|
ap->format = g_value_get_enum (value);
|
|
break;
|
|
case ARG_RATE:
|
|
gst_raw_parse_set_fps (GST_RAW_PARSE (ap), g_value_get_int (value), 1);
|
|
break;
|
|
case ARG_CHANNELS:
|
|
ap->channels = g_value_get_int (value);
|
|
break;
|
|
case ARG_WIDTH:
|
|
ap->width = g_value_get_int (value);
|
|
break;
|
|
case ARG_DEPTH:
|
|
ap->depth = g_value_get_int (value);
|
|
break;
|
|
case ARG_SIGNED:
|
|
ap->signedness = g_value_get_boolean (value);
|
|
break;
|
|
case ARG_ENDIANNESS:
|
|
ap->endianness = g_value_get_enum (value);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
|
|
gst_audio_parse_update_frame_size (ap);
|
|
}
|
|
|
|
static void
|
|
gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
|
|
GParamSpec * pspec)
|
|
{
|
|
GstAudioParse *ap = GST_AUDIO_PARSE (object);
|
|
|
|
switch (prop_id) {
|
|
case ARG_FORMAT:
|
|
g_value_set_enum (value, ap->format);
|
|
break;
|
|
case ARG_RATE:{
|
|
gint fps_n, fps_d;
|
|
|
|
gst_raw_parse_get_fps (GST_RAW_PARSE (ap), &fps_n, &fps_d);
|
|
g_value_set_int (value, fps_n);
|
|
break;
|
|
}
|
|
case ARG_CHANNELS:
|
|
g_value_set_int (value, ap->channels);
|
|
break;
|
|
case ARG_WIDTH:
|
|
g_value_set_int (value, ap->width);
|
|
break;
|
|
case ARG_DEPTH:
|
|
g_value_set_int (value, ap->depth);
|
|
break;
|
|
case ARG_SIGNED:
|
|
g_value_set_boolean (value, ap->signedness);
|
|
break;
|
|
case ARG_ENDIANNESS:
|
|
g_value_set_enum (value, ap->endianness);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
gst_audio_parse_update_frame_size (GstAudioParse * ap)
|
|
{
|
|
gint framesize;
|
|
|
|
framesize = (ap->width / 8) * ap->channels;
|
|
|
|
gst_raw_parse_set_framesize (GST_RAW_PARSE (ap), framesize);
|
|
}
|
|
|
|
static GstCaps *
|
|
gst_audio_parse_get_caps (GstRawParse * rp)
|
|
{
|
|
GstAudioParse *ap = GST_AUDIO_PARSE (rp);
|
|
GstCaps *caps;
|
|
|
|
gint fps_n, fps_d;
|
|
|
|
gst_raw_parse_get_fps (rp, &fps_n, &fps_d);
|
|
|
|
if (ap->format == GST_AUDIO_PARSE_FORMAT_INT) {
|
|
caps = gst_caps_new_simple ("audio/x-raw-int",
|
|
"rate", G_TYPE_INT, fps_n,
|
|
"channels", G_TYPE_INT, ap->channels,
|
|
"width", G_TYPE_INT, ap->width,
|
|
"depth", G_TYPE_INT, ap->depth,
|
|
"signed", G_TYPE_BOOLEAN, ap->signedness,
|
|
"endianness", G_TYPE_INT, ap->endianness, NULL);
|
|
} else {
|
|
caps = gst_caps_new_simple ("audio/x-raw-float",
|
|
"rate", G_TYPE_INT, fps_n,
|
|
"channels", G_TYPE_INT, ap->channels,
|
|
"width", G_TYPE_INT, ap->width,
|
|
"endianness", G_TYPE_INT, ap->endianness, NULL);
|
|
}
|
|
return caps;
|
|
}
|