Various changes to AC3->IEC958 framer. Mostly to make our IEC958 headers and dump the frame (as a probable sync failu...

Original commit message from CVS:
Various changes to AC3->IEC958 framer. Mostly to make our IEC958 headers
more accurate, and to check AC3 checksums (both of them in each frame),
and dump the frame (as a probable sync failure) if they don't match.
General code cleanup, improved comments. Changed to not construct the
header backwards, and not byteswap everything else. If we end up needing
to do little-endian output, we should swap in the element doing the
output (AC3 is big-endian).
This commit is contained in:
Michael Smith 2005-09-21 16:21:45 +00:00
parent d865cbd0f2
commit 5e1a50c7f0
4 changed files with 234 additions and 88 deletions

View file

@ -1,3 +1,19 @@
2005-09-21 Michael Smith <msmith@fluendo.com>
* gst/ac3parse/gstac3parse.c: (gst_ac3parse_class_init),
(gst_ac3parse_init), (gst_ac3parse_chain):
* gst/iec958/ac3_padder.c: (ac3_crc_init), (ac3_crc_update),
(ac3_crc_validate), (ac3p_init), (ac3p_parse):
* gst/iec958/ac3_padder.h:
* gst/iec958/ac3iec.c:
Various changes to AC3->IEC958 framer. Mostly to make our IEC958
headers more accurate, and to check AC3 checksums (both of them in
each frame), and dump the frame (as a probable sync failure) if they
don't match. General code cleanup, improved comments. Changed to not
construct the header backwards, and not byteswap everything else.
If we end up needing to do little-endian output, we should swap in
the element doing the output (AC3 is big-endian).
2005-09-20 Thomas Vander Stichele <thomas at apestaart dot org> 2005-09-20 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/plugins/gst-plugins-ugly-plugins.args: * docs/plugins/gst-plugins-ugly-plugins.args:

View file

@ -1,5 +1,6 @@
/* GStreamer /* GStreamer
* Copyright (C) 2003, 2004 Martin Soto <martinsoto@users.sourceforge.net> * Copyright (C) 2003, 2004 Martin Soto <martinsoto@users.sourceforge.net>
* 2005 Michael Smith <msmith@fluendo.com>
* *
* ac3_padder.c: Pad AC3 frames for use with an SPDIF interface. * ac3_padder.c: Pad AC3 frames for use with an SPDIF interface.
* *
@ -24,16 +25,13 @@
#include "ac3_padder.h" #include "ac3_padder.h"
#define IEC61937_DATA_TYPE_AC3 1
struct frmsize_s struct frmsize_s
{ {
unsigned short bit_rate; unsigned short bit_rate;
unsigned short frm_size[3]; unsigned short frm_size[3];
}; };
static const struct frmsize_s frmsizecod_tbl[] = {
static const struct frmsize_s frmsizecod_tbl[64] = {
{32, {64, 69, 96}}, {32, {64, 69, 96}},
{32, {64, 70, 96}}, {32, {64, 70, 96}},
{40, {80, 87, 120}}, {40, {80, 87, 120}},
@ -74,14 +72,63 @@ static const struct frmsize_s frmsizecod_tbl[64] = {
{640, {1280, 1394, 1920}} {640, {1280, 1394, 1920}}
}; };
static const guint16 ac3_crc_lut[256] = {
0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
};
typedef guint16 ac3_crc_state;
/* Go one byte forward in the input buffer. */ static void
#define ac3p_in_fw(padder) ((padder)->in_ptr++, (padder)->remaining--) ac3_crc_init (ac3_crc_state * state)
{
*state = 0;
}
/* Go one byte forward in the output buffer. */ static void
#define ac3p_out_fw(padder) ((padder)->out_ptr++, (padder)->bytes_to_copy--) ac3_crc_update (ac3_crc_state * state, guint8 * data, guint32 num_bytes)
{
int i;
for (i = 0; i < num_bytes; i++)
*state = ac3_crc_lut[data[i] ^ (*state >> 8)] ^ (*state << 8);
}
static int
ac3_crc_validate (ac3_crc_state * state)
{
return (*state == 0);
}
/** /**
* ac3p_init * ac3p_init
@ -91,20 +138,47 @@ static const struct frmsize_s frmsizecod_tbl[64] = {
* subsequently used to parse an AC3 stream and convert it to IEC958 * subsequently used to parse an AC3 stream and convert it to IEC958
* (S/PDIF) padded packets. * (S/PDIF) padded packets.
*/ */
extern void void
ac3p_init (ac3_padder * padder) ac3p_init (ac3_padder * padder)
{ {
const char sync[4] = { 0x72, 0xF8, 0x1F, 0x4E }; const char sync[4] = { 0xF8, 0x72, 0x4E, 0x1F };
padder->state = AC3P_STATE_SYNC1; padder->state = AC3P_STATE_SYNC1;
padder->skipped = 0;
/* No material to read yet. */ /* No material to read yet. */
padder->remaining = 0; padder->buffer = NULL;
padder->buffer_end = 0;
padder->buffer_cur = 0;
padder->buffer_size = 0;
/* Initialize the sync bytes in the frame. */ /* Initialize the sync bytes in the frame. */
memcpy (padder->frame.header, sync, 4); memcpy (padder->frame.header, sync, 4);
} }
void
ac3p_clear (ac3_padder * padder)
{
g_free (padder->buffer);
}
static void
resync (ac3_padder * padder, int offset, int skipped)
{
padder->buffer_cur -= offset;
padder->state = AC3P_STATE_SYNC1;
padder->skipped += skipped;
/* We don't want our buffer to grow unboundedly if we fail to find sync, but
* nor do we want to do this every time we call resync() */
if (padder->buffer_cur > 4096) {
memmove (padder->buffer, padder->buffer + padder->buffer_cur,
padder->buffer_end - padder->buffer_cur);
padder->buffer_end -= padder->buffer_cur;
padder->buffer_cur = 0;
}
}
/** /**
* ac3_push_data * ac3_push_data
@ -122,10 +196,14 @@ ac3p_init (ac3_padder * padder)
extern void extern void
ac3p_push_data (ac3_padder * padder, guchar * data, guint size) ac3p_push_data (ac3_padder * padder, guchar * data, guint size)
{ {
padder->in_ptr = data; if (padder->buffer_end + size > padder->buffer_size) {
padder->remaining = size; padder->buffer_size = padder->buffer_end + size;
padder->buffer = g_realloc (padder->buffer, padder->buffer_size);
} }
memcpy (padder->buffer + padder->buffer_end, data, size);
padder->buffer_end += size;
}
/** /**
* ac3p_parse * ac3p_parse
@ -141,31 +219,31 @@ ac3p_push_data (ac3_padder * padder, guchar * data, guint size)
* the input stream must be pushed into the padder using * the input stream must be pushed into the padder using
* ac3p_push_data(). This function should be called again after * ac3p_push_data(). This function should be called again after
* pushing the data. * pushing the data.
*
* Note that the returned data (which naturally comes in 16 bit sub-frames) is
* big-endian, and may need to be byte-swapped for little-endian output.
*/ */
extern int extern int
ac3p_parse (ac3_padder * padder) ac3p_parse (ac3_padder * padder)
{ {
while (padder->remaining > 0) { while (padder->buffer_cur < padder->buffer_end) {
switch (padder->state) { switch (padder->state) {
case AC3P_STATE_SYNC1: case AC3P_STATE_SYNC1:
if (*(padder->in_ptr) == 0x0b) { if (padder->buffer[padder->buffer_cur++] == 0x0b) {
/* The first sync byte was found. Go to the next state. */ /* The first sync byte was found. Go to the next state. */
padder->frame.sync_byte1 = 0x0b; padder->frame.sync_byte1 = 0x0b;
padder->state = AC3P_STATE_SYNC2; padder->state = AC3P_STATE_SYNC2;
} } else
ac3p_in_fw (padder); resync (padder, 0, 1);
break; break;
case AC3P_STATE_SYNC2: case AC3P_STATE_SYNC2:
if (*(padder->in_ptr) == 0x77) { if (padder->buffer[padder->buffer_cur++] == 0x77) {
/* The second sync byte was seen right after the first. Go to /* The second sync byte was seen right after the first. Go to
the next state. */ the next state. */
padder->frame.sync_byte2 = 0x77; padder->frame.sync_byte2 = 0x77;
padder->state = AC3P_STATE_HEADER; padder->state = AC3P_STATE_HEADER;
/* Skip one byte. */
ac3p_in_fw (padder);
/* Prepare for reading the header. */ /* Prepare for reading the header. */
padder->out_ptr = (guchar *) & (padder->frame.crc1); padder->out_ptr = (guchar *) & (padder->frame.crc1);
/* Discount the 2 sync bytes from the header size. */ /* Discount the 2 sync bytes from the header size. */
@ -173,16 +251,15 @@ ac3p_parse (ac3_padder * padder)
} else { } else {
/* The second sync byte was not seen. Go back to the /* The second sync byte was not seen. Go back to the
first state. */ first state. */
padder->state = AC3P_STATE_SYNC1; resync (padder, 0, 2);
} }
break; break;
case AC3P_STATE_HEADER: case AC3P_STATE_HEADER:
if (padder->bytes_to_copy > 0) { if (padder->bytes_to_copy > 0) {
/* Copy one byte. */ /* Copy one byte. */
*(padder->out_ptr) = *(padder->in_ptr); *(padder->out_ptr++) = padder->buffer[padder->buffer_cur++];
ac3p_in_fw (padder); padder->bytes_to_copy--;
ac3p_out_fw (padder);
} else { } else {
int fscod; int fscod;
@ -190,24 +267,25 @@ ac3p_parse (ac3_padder * padder)
fscod = (padder->frame.code >> 6) & 0x03; fscod = (padder->frame.code >> 6) & 0x03;
/* Calculate the frame size. */ /* fscod == 3 is a reserved code, we're not meant to do playback in
padder->ac3_frame_size = * this case. frmsizecod being out-of-range (there are 38 entries)
2 * frmsizecod_tbl[padder->frame.code & 0x3f].frm_size[fscod]; * doesn't appear to be well-defined, but treat the same.
* The likely cause of both of these is false sync, so skip back to
/* Set up the IEC header. */ * just in front of the previous sync word and start looking again.
if (padder->ac3_frame_size > 0) { */
padder->frame.header[4] = IEC61937_DATA_TYPE_AC3; if (fscod == 3 || (padder->frame.code & 0x3f) >= 38) {
} else { resync (padder, AC3P_AC3_HEADER_SIZE - 2, 2);
/* Don't know what it is, better be careful. */ continue;
padder->state = AC3P_STATE_SYNC1;
break;
} }
padder->frame.header[5] = 0x00;
padder->frame.header[6] = (padder->ac3_frame_size * 8) & 0xFF; /* Calculate the frame size (in 16 bit units). */
padder->frame.header[7] = ((padder->ac3_frame_size * 8) >> 8) & 0xFF; padder->ac3_frame_size =
frmsizecod_tbl[padder->frame.code & 0x3f].frm_size[fscod];
/* Prepare for reading the body. */ /* Prepare for reading the body. */
padder->bytes_to_copy = padder->ac3_frame_size - AC3P_AC3_HEADER_SIZE; padder->bytes_to_copy = padder->ac3_frame_size * 2
- AC3P_AC3_HEADER_SIZE;
padder->state = AC3P_STATE_CONTENT; padder->state = AC3P_STATE_CONTENT;
} }
break; break;
@ -215,36 +293,98 @@ ac3p_parse (ac3_padder * padder)
case AC3P_STATE_CONTENT: case AC3P_STATE_CONTENT:
if (padder->bytes_to_copy > 0) { if (padder->bytes_to_copy > 0) {
/* Copy one byte. */ /* Copy one byte. */
*(padder->out_ptr) = *(padder->in_ptr); *(padder->out_ptr++) = padder->buffer[padder->buffer_cur++];
ac3p_in_fw (padder); padder->bytes_to_copy--;
ac3p_out_fw (padder);
} else { } else {
guint16 *ptr, i; int framesize;
int crclen1, crclen2;
guint8 *tmp;
ac3_crc_state state;
/* Frame ready. Prepare for output: */ /* Frame ready. Prepare for output: */
/* Zero the non AC3 portion of the padded frame. */ /* Zero the non AC3 portion of the padded frame. */
memset (&(padder->frame.sync_byte1) + padder->ac3_frame_size, 0, memset (&(padder->frame.sync_byte1) + padder->ac3_frame_size * 2, 0,
AC3P_IEC_FRAME_SIZE - AC3P_IEC_HEADER_SIZE - AC3P_IEC_FRAME_SIZE - AC3P_IEC_HEADER_SIZE -
padder->ac3_frame_size); padder->ac3_frame_size * 2);
/* Fix the byte order in the AC3 portion: */ /* Now checking the two CRCs. If either fails, then we re-feed all
ptr = (guint16 *) & (padder->frame.sync_byte1); * the data starting immediately after the 16-bit syncword (which we
i = padder->ac3_frame_size / 2; * can now assume was a false sync) */
while (i > 0) {
*ptr = GUINT16_TO_BE (*ptr); /* Length of CRC1 is defined as
ptr++; truncate(framesize/2) + truncate(framesize/8)
i--; units (each of which is 16 bit, as is 'framesize'), but this
includes the syncword, which is NOT calculated as part of
the CRC.
*/
framesize = padder->ac3_frame_size;
crclen1 = (framesize / 2 + framesize / 8) * 2 - 2;
tmp = (guint8 *) (&(padder->frame.crc1));
ac3_crc_init (&state);
ac3_crc_update (&state, tmp, crclen1);
if (!ac3_crc_validate (&state)) {
/* Rewind current stream pointer to immediately following the last
* attempted sync point, then continue parsing in initial state */
resync (padder, padder->ac3_frame_size - 2, 2);
continue;
} }
/* Start over again. */ /* Now check CRC2, which covers the entire frame other than the
* 16-bit syncword */
crclen2 = padder->ac3_frame_size * 2 - 2;
ac3_crc_init (&state);
ac3_crc_update (&state, tmp, crclen2);
if (!ac3_crc_validate (&state)) {
/* Rewind current stream pointer to immediately following the last
* attempted sync point, then continue parsing in initial state */
resync (padder, padder->ac3_frame_size - 2, 2);
continue;
}
/* Now set up the rest of the IEC header (we already filled in the
32 bit sync word. */
/* Byte 5 has:
bits 0-4: data type dependent. For AC3, the bottom 3 of these bits
are copied from the AC3 frame (bsmod value), the top 2
bits are reserved, and set to zero.
bits 5-7: data stream number. We only do one data stream, so it's
zero.
*/
padder->frame.header[4] = padder->frame.bsidmod & 0x07;
/* Byte 6:
bits 0-4: data type. 1 for AC3.
bits 5-6: reserved, zero.
bit 7: error_flag. Zero if frame contains no errors
*/
padder->frame.header[5] = 1; /* AC3 is defined as datatype 1 */
/* Now, 16 bit frame size, in bits. */
padder->frame.header[6] = ((padder->ac3_frame_size * 16) >> 8) & 0xFF;
padder->frame.header[7] = (padder->ac3_frame_size * 16) & 0xFF;
/* We're done, reset state and signal that we have a frame */
padder->skipped = 0;
padder->state = AC3P_STATE_SYNC1; padder->state = AC3P_STATE_SYNC1;
memmove (padder->buffer, padder->buffer + padder->buffer_cur,
padder->buffer_end - padder->buffer_cur);
padder->buffer_end -= padder->buffer_cur;
padder->buffer_cur = 0;
return AC3P_EVENT_FRAME; return AC3P_EVENT_FRAME;
} }
break; break;
} }
} }
return AC3P_EVENT_PUSH; return AC3P_EVENT_PUSH;
} }

View file

@ -77,22 +77,28 @@ typedef struct {
typedef struct { typedef struct {
guint state; /* State of the reading automaton. */ guint state; /* State of the reading automaton. */
guchar *in_ptr; /* Input pointer, marking the current guchar *buffer; /* Input buffer */
postion in the input buffer. */
guint remaining; /* The number of bytes remaining in the current gint buffer_end; /* End offset, in bytes, of currently valid data in
reading buffer. */ buffer */
gint buffer_size; /* Allocated size of buffer */
gint buffer_cur; /* Current position in buffer */
guchar *out_ptr; /* Output pointer, marking the current guchar *out_ptr; /* Output pointer, marking the current
position in the output frame. */ position in the output frame. */
guint bytes_to_copy; gint bytes_to_copy;
/* Number of bytes that still must be copied /* Number of bytes that still must be copied
to the output frame *during this reading to the output frame *during this reading
stage*. */ stage*. */
guint ac3_frame_size; gint ac3_frame_size;
/* The size in bytes of the pure AC3 portion /* The size in 16-bit units of the pure AC3 portion
of the current frame. */ of the current frame. */
gint skipped; /* Number of bytes skipped while trying to find sync */
ac3p_iec958_burst_frame frame; ac3p_iec958_burst_frame frame;
/* The current output frame. */ /* The current output frame. */
} ac3_padder; } ac3_padder;
@ -102,6 +108,9 @@ typedef struct {
extern void extern void
ac3p_init(ac3_padder *padder); ac3p_init(ac3_padder *padder);
extern void
ac3p_clear(ac3_padder *padder);
extern void extern void
ac3p_push_data(ac3_padder *padder, guchar *data, guint size); ac3p_push_data(ac3_padder *padder, guchar *data, guint size);
@ -123,16 +132,6 @@ ac3p_parse(ac3_padder *padder);
* *
* Returns the length in bytes of the last read raw AC3 frame. * Returns the length in bytes of the last read raw AC3 frame.
*/ */
#define ac3p_frame_size(padder) ((padder)->ac3_frame_size) #define ac3p_frame_size(padder) ((padder)->ac3_frame_size * 2)
/**
* ac3p_pending
* @padder: The padder structure.
*
* Returns a boolean value telling if there are pending material in
* the padder.
*/
#define ac3p_pending(padder) ((padder)->remaining > 0)
#endif #endif

View file

@ -1,7 +1,8 @@
/* GStreamer /* GStreamer
* Copyright (C) 2004 Martin Soto <martinsoto@users.sourceforge.net> * Copyright (C) 2004 Martin Soto <martinsoto@users.sourceforge.net>
2005 Michael Smith <msmith@fluendo.com>
* *
* ac3iec.c: Pad AC3 frames into IEC958 frames for the SP/DIF interface. * ac3iec.c: Pad AC3 frames into IEC958 frames for the S/PDIF interface.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -42,7 +43,7 @@ GST_DEBUG_CATEGORY_STATIC (ac3iec_debug);
static GstElementDetails ac3iec_details = { static GstElementDetails ac3iec_details = {
"AC3 to IEC958 filter", "AC3 to IEC958 filter",
"audio/x-private1-ac3", "audio/x-private1-ac3",
"Pads AC3 frames into IEC958 frames suitable for a raw SP/DIF interface", "Pads AC3 frames into IEC958 frames suitable for a raw S/PDIF interface",
"Martin Soto <martinsoto@users.sourceforge.net>" "Martin Soto <martinsoto@users.sourceforge.net>"
}; };
@ -70,20 +71,9 @@ static GstStaticPadTemplate ac3iec_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
#if 0
GST_STATIC_CAPS ("audio/x-raw-int, "
"law = (int) 0, "
"endianness = (int) " G_STRINGIFY (G_LITTLE_ENDIAN) ", "
"signed = (boolean) true, "
"width = (int) 16, "
"depth = (int) 16, " "rate = (int) 48000, " "channels = (int) 2")
#endif
#if 1
GST_STATIC_CAPS ("audio/x-iec958") GST_STATIC_CAPS ("audio/x-iec958")
#endif
); );
static void ac3iec_base_init (gpointer g_class); static void ac3iec_base_init (gpointer g_class);
static void ac3iec_class_init (AC3IECClass * klass); static void ac3iec_class_init (AC3IECClass * klass);
static void ac3iec_init (AC3IEC * ac3iec); static void ac3iec_init (AC3IEC * ac3iec);
@ -384,6 +374,7 @@ ac3iec_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
ac3p_clear (ac3iec->padder);
break; break;
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
break; break;
@ -412,5 +403,5 @@ plugin_init (GstPlugin * plugin)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR, GST_VERSION_MINOR,
"iec958", "iec958",
"Conversion elements to the iec958 SP/DIF format", "Convert raw AC3 into IEC958 (S/PDIF) frames",
plugin_init, VERSION, "LGPL", PACKAGE, "http://seamless.sourceforge.net"); plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN);