summaryrefslogtreecommitdiffstats
path: root/sys/vdpau
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2009-03-29 15:28:06 +0200
committerJan Schmidt <thaytan@noraisin.net>2009-06-20 15:21:22 +0100
commitf70ddb66050244bdc0833d7cdc6c1b2e64f425ff (patch)
treec410ebd1299781df75d7e1a4dfa5fd25a6f763e4 /sys/vdpau
parent584b000583c7050689d7a93e5d6dc7083bbdfcbd (diff)
downloadgst-plugins-bad-f70ddb66050244bdc0833d7cdc6c1b2e64f425ff.tar.gz
gst-plugins-bad-f70ddb66050244bdc0833d7cdc6c1b2e64f425ff.tar.bz2
gst-plugins-bad-f70ddb66050244bdc0833d7cdc6c1b2e64f425ff.zip
vdpau: create VdpDecoder in set_caps add more functions for parsing mpeg
Diffstat (limited to 'sys/vdpau')
-rw-r--r--sys/vdpau/gstvdpaudecoder.c128
-rw-r--r--sys/vdpau/gstvdpaudecoder.h15
-rw-r--r--sys/vdpau/gstvdpaumpegdecoder.c25
-rw-r--r--sys/vdpau/gstvdpaumpegdecoder.h2
-rw-r--r--sys/vdpau/mpegutil.c115
-rw-r--r--sys/vdpau/mpegutil.h39
6 files changed, 276 insertions, 48 deletions
diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c
index 007837f4..c13b0173 100644
--- a/sys/vdpau/gstvdpaudecoder.c
+++ b/sys/vdpau/gstvdpaudecoder.c
@@ -26,10 +26,8 @@
#include <gst/gst.h>
#include <gst/controller/gstcontroller.h>
-#include <X11/Xlib.h>
-#include <vdpau/vdpau_x11.h>
-
#include "gstvdpaudecoder.h"
+#include <vdpau/vdpau_x11.h>
GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug);
#define GST_CAT_DEFAULT gst_vdpaudecoder_debug
@@ -173,8 +171,9 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec)
if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) {
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
- ("Could not get VDPAU capabilites"),
- ("Could not query video surface capabilities"));
+ ("Could not get query VDPAU video surface capabilites"),
+ ("Error returned from vdpau was: %s",
+ f->vdp_get_error_string (status)));
return NULL;
}
@@ -191,8 +190,9 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec)
if (status != VDP_STATUS_OK
&& status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) {
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
- ("Could not get VDPAU capabilites"),
- ("Could not query video surface ycbcr capabilities"));
+ ("Could not query VDPAU YCbCr capabilites"),
+ ("Error returned from vdpau was: %s",
+ f->vdp_get_error_string (status)));
return NULL;
}
@@ -220,15 +220,45 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec)
static gboolean
gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec)
{
- Display *display;
- int screen;
- VdpauFunctions *f;
+ gint screen;
VdpStatus status;
+ gint i;
+ VdpauFunctions *f;
GstCaps *caps;
+ typedef struct
+ {
+ int id;
+ void *func;
+ } VdpFunction;
+
+ VdpFunction vdp_function[] = {
+ {VDP_FUNC_ID_DEVICE_DESTROY, &dec->functions->vdp_device_destroy},
+ {VDP_FUNC_ID_VIDEO_SURFACE_CREATE,
+ &dec->functions->vdp_video_surface_create},
+ {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY,
+ &dec->functions->vdp_video_surface_destroy},
+ {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES,
+ &dec->functions->vdp_video_surface_query_capabilities},
+ {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
+ &dec->functions->vdp_video_surface_query_ycbcr_capabilities},
+ {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR,
+ &dec->functions->vdp_video_surface_get_bits_ycbcr},
+ {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS,
+ &dec->functions->vdp_video_surface_get_parameters},
+ {VDP_FUNC_ID_DECODER_CREATE, &dec->functions->vdp_decoder_create},
+ {VDP_FUNC_ID_DECODER_RENDER, &dec->functions->vdp_decoder_render},
+ {VDP_FUNC_ID_DECODER_DESTROY, &dec->functions->vdp_decoder_destroy},
+ {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES,
+ &dec->functions->vdp_decoder_query_capabilities},
+ {VDP_FUNC_ID_DECODER_GET_PARAMETERS,
+ &dec->functions->vdp_decoder_get_parameters},
+ {0, NULL}
+ };
+
/* FIXME: We probably want to use the same VdpDevice for every VDPAU element */
- display = XOpenDisplay (dec->display);
- if (!display) {
+ dec->display = XOpenDisplay (dec->display_name);
+ if (!dec->display) {
GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"),
("Could not open display"));
return FALSE;
@@ -236,55 +266,78 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec)
f = dec->functions;
- screen = DefaultScreen (display);
+ screen = DefaultScreen (dec->display);
status =
- vdp_device_create_x11 (display, screen, &dec->device,
+ vdp_device_create_x11 (dec->display, screen, &dec->device,
&f->vdp_get_proc_address);
if (status != VDP_STATUS_OK) {
GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"),
("Could not create VDPAU device"));
- XCloseDisplay (display);
+ XCloseDisplay (dec->display);
+ dec->display = NULL;
return FALSE;
}
- XCloseDisplay (display);
-
- f->vdp_get_proc_address (dec->device,
- VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES,
- (void **) &f->vdp_video_surface_query_capabilities);
- f->vdp_get_proc_address (dec->device,
- VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
- (void **) &f->vdp_video_surface_query_ycbcr_capabilities);
- f->vdp_get_proc_address (dec->device,
- VDP_FUNC_ID_DEVICE_DESTROY, (void **) &f->vdp_device_destroy);
- f->vdp_get_proc_address (dec->device,
- VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR,
- (void **) &f->vdp_video_surface_get_bits_ycbcr);
- caps = gst_vdpaudecoder_get_vdpau_support (dec);
- if (!caps) {
- f->vdp_device_destroy (dec->device);
- dec->device = 0;
- return FALSE;
+ status = f->vdp_get_proc_address (dec->device,
+ VDP_FUNC_ID_GET_ERROR_STRING, (void **) &f->vdp_get_error_string);
+ if (status != VDP_STATUS_OK) {
+ GST_ELEMENT_ERROR (dec, RESOURCE, READ,
+ ("Could'nt get function pointer from vdpau"),
+ ("Couldn't get vdp_get_error_string function pointer"));
+ goto error;
}
+ for (i = 0; vdp_function[i].func != NULL; i++) {
+ status = f->vdp_get_proc_address (dec->device,
+ vdp_function[i].id, vdp_function[i].func);
+
+ if (status != VDP_STATUS_OK) {
+ GST_ELEMENT_ERROR (dec, RESOURCE, READ,
+ ("Could not get function pointer from vdpau"),
+ ("Error returned from vdpau was: %s",
+ f->vdp_get_error_string (status)));
+ goto error;
+ }
+ }
+
+ caps = gst_vdpaudecoder_get_vdpau_support (dec);
+ if (!caps)
+ goto error;
+
dec->src_caps = caps;
return TRUE;
+
+error:
+ f->vdp_device_destroy (dec->device);
+ dec->device = VDP_INVALID_HANDLE;
+
+ return FALSE;
+
}
static GstStateChangeReturn
gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition)
{
GstVdpauDecoder *dec;
+ VdpauFunctions *f;
dec = GST_VDPAU_DECODER (element);
+ f = dec->functions;
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
if (!gst_vdpaudecoder_init_vdpau (dec))
return GST_STATE_CHANGE_FAILURE;
break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ f->vdp_device_destroy (dec->device);
+ XCloseDisplay (dec->display);
+
+ dec->device = VDP_INVALID_HANDLE;
+ dec->display = NULL;
+ break;
default:
break;
}
@@ -403,8 +456,9 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass)
static void
gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass)
{
+ dec->display_name = NULL;
dec->display = NULL;
- dec->device = 0;
+ dec->device = VDP_INVALID_HANDLE;
dec->silent = FALSE;
dec->src_caps = NULL;
@@ -433,8 +487,8 @@ gst_vdpaudecoder_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_DISPLAY:
- g_free (dec->display);
- dec->display = g_value_dup_string (value);
+ g_free (dec->display_name);
+ dec->display_name = g_value_dup_string (value);
break;
case PROP_SILENT:
dec->silent = g_value_get_boolean (value);
@@ -453,7 +507,7 @@ gst_vdpaudecoder_get_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_DISPLAY:
- g_value_set_string (value, dec->display);
+ g_value_set_string (value, dec->display_name);
break;
case PROP_SILENT:
g_value_set_boolean (value, dec->silent);
diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h
index 2c1a274f..5cd83042 100644
--- a/sys/vdpau/gstvdpaudecoder.h
+++ b/sys/vdpau/gstvdpaudecoder.h
@@ -25,6 +25,7 @@
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
+#include <X11/Xlib.h>
#include <vdpau/vdpau.h>
G_BEGIN_DECLS
@@ -43,7 +44,8 @@ typedef struct _VdpauFunctions VdpauFunctions;
struct _GstVdpauDecoder {
GstElement element;
- gchar *display;
+ gchar *display_name;
+ Display *display;
VdpDevice device;
VdpauFunctions *functions;
@@ -66,17 +68,22 @@ struct _GstVdpauDecoderClass {
};
struct _VdpauFunctions {
+ VdpDeviceDestroy *vdp_device_destroy;
VdpGetProcAddress *vdp_get_proc_address;
-
+ VdpGetErrorString *vdp_get_error_string;
+
+ VdpVideoSurfaceCreate *vdp_video_surface_create;
+ VdpVideoSurfaceDestroy *vdp_video_surface_destroy;
VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities;
VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities;
+ VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters;
VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr;
- VdpDeviceDestroy *vdp_device_destroy;
-
VdpDecoderCreate *vdp_decoder_create;
VdpDecoderDestroy *vdp_decoder_destroy;
VdpDecoderRender *vdp_decoder_render;
+ VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities;
+ VdpDecoderGetParameters *vdp_decoder_get_parameters;
};
GType gst_vdpaudecoder_get_type (void);
diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c
index e5da459f..6ff9b42a 100644
--- a/sys/vdpau/gstvdpaumpegdecoder.c
+++ b/sys/vdpau/gstvdpaumpegdecoder.c
@@ -104,13 +104,16 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps)
GstVdpauMpegDecoder *mpeg_dec;
GstStructure *structure;
gint version;
+ VdpDecoderProfile profile;
+ VdpauFunctions *f;
+ VdpStatus status;
mpeg_dec = GST_VDPAU_MPEG_DECODER (dec);
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "mpegversion", &version);
if (version == 1)
- mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG1;
+ profile = VDP_DECODER_PROFILE_MPEG1;
else {
const GValue *value;
@@ -123,14 +126,24 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps)
GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data));
switch (hdr.profile) {
case 5:
- mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
+ profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
break;
default:
- mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
+ profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
break;
}
}
+ f = dec->functions;
+ status = f->vdp_decoder_create (dec->device, profile, dec->width,
+ dec->height, 2, &mpeg_dec->decoder);
+ if (status != VDP_STATUS_OK) {
+ GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ,
+ ("Could not create vdpau decoder"),
+ ("Error returned from vdpau was: %s",
+ f->vdp_get_error_string (status)));
+ return FALSE;
+ }
return TRUE;
}
@@ -174,10 +187,12 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass)
}
static void
-gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * filter,
+gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec,
GstVdpauMpegDecoderClass * gclass)
{
- filter->silent = FALSE;
+ mpeg_dec->silent = FALSE;
+
+ mpeg_dec->decoder = VDP_INVALID_HANDLE;
}
static void
diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h
index 830cc671..0207ce31 100644
--- a/sys/vdpau/gstvdpaumpegdecoder.h
+++ b/sys/vdpau/gstvdpaumpegdecoder.h
@@ -66,7 +66,7 @@ struct _GstVdpauMpegDecoder
gboolean silent;
- VdpDecoderProfile profile;
+ VdpDecoder decoder;
};
struct _GstVdpauMpegDecoderClass
diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c
index 274fa853..aa77a426 100644
--- a/sys/vdpau/mpegutil.c
+++ b/sys/vdpau/mpegutil.c
@@ -18,8 +18,41 @@
* Boston, MA 02111-1307, USA.
*/
+#include <string.h>
+
#include "mpegutil.h"
+/* default intra quant matrix, in zig-zag order */
+static const guint8 default_intra_quantizer_matrix[64] = {
+ 8,
+ 16, 16,
+ 19, 16, 19,
+ 22, 22, 22, 22,
+ 22, 22, 26, 24, 26,
+ 27, 27, 27, 26, 26, 26,
+ 26, 27, 27, 27, 29, 29, 29,
+ 34, 34, 34, 29, 29, 29, 27, 27,
+ 29, 29, 32, 32, 34, 34, 37,
+ 38, 37, 35, 35, 34, 35,
+ 38, 38, 40, 40, 40,
+ 48, 48, 46, 46,
+ 56, 56, 58,
+ 69, 69,
+ 83
+};
+
+guint8 mpeg2_scan[64] = {
+ /* Zig-Zag scan pattern */
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
guint8 bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
guint32
@@ -133,6 +166,7 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end)
/* Parse a Sequence Extension */
guint8 horiz_size_ext, vert_size_ext;
guint8 fps_n_ext, fps_d_ext;
+ gint i, offset;
if (G_UNLIKELY ((end - data) < 6))
/* need at least 10 bytes, minus 4 for the start code 000001b5 */
@@ -148,6 +182,23 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end)
hdr->fps_d *= (fps_d_ext + 1);
hdr->width += (horiz_size_ext << 12);
hdr->height += (vert_size_ext << 12);
+
+ if (read_bits (data + 7, 6, 1)) {
+ for (i = 0; i < 64; i++)
+ hdr->intra_quantizer_matrix[mpeg2_scan[i]] =
+ read_bits (data + 7 + i, 7, 8);
+ offset = 64;
+ } else
+ memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix,
+ 64);
+
+ if (read_bits (data + 7 + offset, 7, 1)) {
+ for (i = 0; i < 64; i++)
+ hdr->non_intra_quantizer_matrix[mpeg2_scan[i]] =
+ read_bits (data + 8 + offset + i, 0, 8);
+ } else
+ memset (hdr->non_intra_quantizer_matrix, 0, 64);
+
break;
}
default:
@@ -225,3 +276,67 @@ mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end)
return TRUE;
}
+
+gboolean
+mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end)
+{
+ guint32 code;
+
+ if (G_UNLIKELY ((end - data) < 6))
+ return FALSE; /* Packet too small */
+
+ code = GST_READ_UINT32_BE (data);
+ if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_PICTURE)))
+ return FALSE;
+
+ /* Skip the start code */
+ data += 4;
+
+ hdr->pic_type = (data[1] >> 3) & 0x07;
+ if (hdr->pic_type == 0 || hdr->pic_type > 4)
+ return FALSE; /* Corrupted picture packet */
+
+ if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) {
+ if (G_UNLIKELY ((end - data) < 7))
+ return FALSE; /* packet too small */
+
+ hdr->full_pel_forward_vector = read_bits (data + 3, 5, 1);
+ hdr->f_code[0][0] = hdr->f_code[0][1] = read_bits (data + 3, 6, 3);
+
+ if (hdr->pic_type == B_FRAME) {
+ hdr->full_pel_backward_vector = read_bits (data + 4, 1, 1);
+ hdr->f_code[1][0] = hdr->f_code[1][1] = read_bits (data + 4, 2, 3);
+ }
+ } else {
+ hdr->full_pel_forward_vector = 0;
+ hdr->full_pel_backward_vector = 0;
+ }
+
+ return TRUE;
+}
+
+gboolean
+mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data,
+ guint8 * end)
+{
+ if (G_UNLIKELY ((end - data) < 7))
+ return FALSE; /* Packet too small */
+
+ if (G_UNLIKELY (read_bits (data, 0, 4) != MPEG_PACKET_EXT_PICTURE_CODING))
+ return FALSE;
+
+ ext->f_code[0][0] = read_bits (data, 4, 4);
+ ext->f_code[0][1] = read_bits (data + 1, 0, 4);
+ ext->f_code[1][0] = read_bits (data + 1, 4, 4);
+ ext->f_code[1][1] = read_bits (data + 2, 0, 4);
+
+ ext->intra_dc_precision = read_bits (data + 2, 4, 2);
+ ext->picture_structure = read_bits (data + 2, 6, 2);
+ ext->top_field_first = read_bits (data + 3, 0, 1);
+ ext->frame_pred_frame_dct = read_bits (data + 3, 1, 1);
+ ext->concealment_motion_vectors = read_bits (data + 3, 2, 1);
+ ext->q_scale_type = read_bits (data + 3, 3, 1);
+ ext->intra_vlc_format = read_bits (data + 3, 4, 1);
+
+ return TRUE;
+}
diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h
index f0f8aca0..929e4fbb 100644
--- a/sys/vdpau/mpegutil.h
+++ b/sys/vdpau/mpegutil.h
@@ -24,6 +24,8 @@
#include <gst/gst.h>
typedef struct MPEGSeqHdr MPEGSeqHdr;
+typedef struct MPEGPictureHdr MPEGPictureHdr;
+typedef struct MPEGPictureExt MPEGPictureExt;
/* Packet ID codes for different packet types we
* care about */
@@ -40,6 +42,12 @@ typedef struct MPEGSeqHdr MPEGSeqHdr;
#define MPEG_PACKET_EXT_SEQUENCE 0x01
#define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02
#define MPEG_PACKET_EXT_QUANT_MATRIX 0x03
+#define MPEG_PACKET_EXT_PICTURE_CODING 0x08
+
+/* frame types */
+#define I_FRAME 1
+#define P_FRAME 2
+#define B_FRAME 3
struct MPEGSeqHdr
{
@@ -55,9 +63,38 @@ struct MPEGSeqHdr
/* mpeg2 decoder profile */
gint profile;
+
+ guint8 intra_quantizer_matrix[64];
+ guint8 non_intra_quantizer_matrix[64];
+};
+
+struct MPEGPictureHdr
+{
+ guint8 pic_type;
+
+ guint8 full_pel_forward_vector, full_pel_backward_vector;
+
+ guint8 f_code[2][2];
+};
+
+struct MPEGPictureExt
+{
+ guint8 f_code[2][2];
+
+ guint8 intra_dc_precision;
+ guint8 picture_structure;
+ guint8 top_field_first;
+ guint8 frame_pred_frame_dct;
+ guint8 concealment_motion_vectors;
+ guint8 q_scale_type;
+ guint8 intra_vlc_format;
};
gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr,
- guint8 *data, guint8 *end);
+ guint8 *data, guint8 *end);
+
+gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end);
+
+gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt *ext, guint8 *data, guint8 *end);
#endif