mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
vdpau: create VdpDecoder in set_caps add more functions for parsing mpeg
This commit is contained in:
parent
584b000583
commit
f70ddb6605
6 changed files with 275 additions and 47 deletions
|
@ -26,10 +26,8 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/controller/gstcontroller.h>
|
#include <gst/controller/gstcontroller.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <vdpau/vdpau_x11.h>
|
|
||||||
|
|
||||||
#include "gstvdpaudecoder.h"
|
#include "gstvdpaudecoder.h"
|
||||||
|
#include <vdpau/vdpau_x11.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug);
|
||||||
#define GST_CAT_DEFAULT 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) {
|
if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) {
|
||||||
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
|
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
|
||||||
("Could not get VDPAU capabilites"),
|
("Could not get query VDPAU video surface capabilites"),
|
||||||
("Could not query video surface capabilities"));
|
("Error returned from vdpau was: %s",
|
||||||
|
f->vdp_get_error_string (status)));
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -191,8 +190,9 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec)
|
||||||
if (status != VDP_STATUS_OK
|
if (status != VDP_STATUS_OK
|
||||||
&& status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) {
|
&& status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) {
|
||||||
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
|
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
|
||||||
("Could not get VDPAU capabilites"),
|
("Could not query VDPAU YCbCr capabilites"),
|
||||||
("Could not query video surface ycbcr capabilities"));
|
("Error returned from vdpau was: %s",
|
||||||
|
f->vdp_get_error_string (status)));
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -220,15 +220,45 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec)
|
gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec)
|
||||||
{
|
{
|
||||||
Display *display;
|
gint screen;
|
||||||
int screen;
|
|
||||||
VdpauFunctions *f;
|
|
||||||
VdpStatus status;
|
VdpStatus status;
|
||||||
|
gint i;
|
||||||
|
VdpauFunctions *f;
|
||||||
GstCaps *caps;
|
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 */
|
/* FIXME: We probably want to use the same VdpDevice for every VDPAU element */
|
||||||
display = XOpenDisplay (dec->display);
|
dec->display = XOpenDisplay (dec->display_name);
|
||||||
if (!display) {
|
if (!dec->display) {
|
||||||
GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"),
|
GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"),
|
||||||
("Could not open display"));
|
("Could not open display"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -236,55 +266,78 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec)
|
||||||
|
|
||||||
f = dec->functions;
|
f = dec->functions;
|
||||||
|
|
||||||
screen = DefaultScreen (display);
|
screen = DefaultScreen (dec->display);
|
||||||
status =
|
status =
|
||||||
vdp_device_create_x11 (display, screen, &dec->device,
|
vdp_device_create_x11 (dec->display, screen, &dec->device,
|
||||||
&f->vdp_get_proc_address);
|
&f->vdp_get_proc_address);
|
||||||
if (status != VDP_STATUS_OK) {
|
if (status != VDP_STATUS_OK) {
|
||||||
GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"),
|
GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"),
|
||||||
("Could not create VDPAU device"));
|
("Could not create VDPAU device"));
|
||||||
XCloseDisplay (display);
|
XCloseDisplay (dec->display);
|
||||||
|
dec->display = NULL;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
XCloseDisplay (display);
|
|
||||||
|
|
||||||
f->vdp_get_proc_address (dec->device,
|
status = f->vdp_get_proc_address (dec->device,
|
||||||
VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES,
|
VDP_FUNC_ID_GET_ERROR_STRING, (void **) &f->vdp_get_error_string);
|
||||||
(void **) &f->vdp_video_surface_query_capabilities);
|
if (status != VDP_STATUS_OK) {
|
||||||
f->vdp_get_proc_address (dec->device,
|
GST_ELEMENT_ERROR (dec, RESOURCE, READ,
|
||||||
VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
|
("Could'nt get function pointer from vdpau"),
|
||||||
(void **) &f->vdp_video_surface_query_ycbcr_capabilities);
|
("Couldn't get vdp_get_error_string function pointer"));
|
||||||
f->vdp_get_proc_address (dec->device,
|
goto error;
|
||||||
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,
|
for (i = 0; vdp_function[i].func != NULL; i++) {
|
||||||
(void **) &f->vdp_video_surface_get_bits_ycbcr);
|
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);
|
caps = gst_vdpaudecoder_get_vdpau_support (dec);
|
||||||
if (!caps) {
|
if (!caps)
|
||||||
f->vdp_device_destroy (dec->device);
|
goto error;
|
||||||
dec->device = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
dec->src_caps = caps;
|
dec->src_caps = caps;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
f->vdp_device_destroy (dec->device);
|
||||||
|
dec->device = VDP_INVALID_HANDLE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition)
|
gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstVdpauDecoder *dec;
|
GstVdpauDecoder *dec;
|
||||||
|
VdpauFunctions *f;
|
||||||
|
|
||||||
dec = GST_VDPAU_DECODER (element);
|
dec = GST_VDPAU_DECODER (element);
|
||||||
|
f = dec->functions;
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
if (!gst_vdpaudecoder_init_vdpau (dec))
|
if (!gst_vdpaudecoder_init_vdpau (dec))
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -403,8 +456,9 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass)
|
gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass)
|
||||||
{
|
{
|
||||||
|
dec->display_name = NULL;
|
||||||
dec->display = NULL;
|
dec->display = NULL;
|
||||||
dec->device = 0;
|
dec->device = VDP_INVALID_HANDLE;
|
||||||
dec->silent = FALSE;
|
dec->silent = FALSE;
|
||||||
dec->src_caps = NULL;
|
dec->src_caps = NULL;
|
||||||
|
|
||||||
|
@ -433,8 +487,8 @@ gst_vdpaudecoder_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_DISPLAY:
|
case PROP_DISPLAY:
|
||||||
g_free (dec->display);
|
g_free (dec->display_name);
|
||||||
dec->display = g_value_dup_string (value);
|
dec->display_name = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
case PROP_SILENT:
|
case PROP_SILENT:
|
||||||
dec->silent = g_value_get_boolean (value);
|
dec->silent = g_value_get_boolean (value);
|
||||||
|
@ -453,7 +507,7 @@ gst_vdpaudecoder_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_DISPLAY:
|
case PROP_DISPLAY:
|
||||||
g_value_set_string (value, dec->display);
|
g_value_set_string (value, dec->display_name);
|
||||||
break;
|
break;
|
||||||
case PROP_SILENT:
|
case PROP_SILENT:
|
||||||
g_value_set_boolean (value, dec->silent);
|
g_value_set_boolean (value, dec->silent);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstbasetransform.h>
|
#include <gst/base/gstbasetransform.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
#include <vdpau/vdpau.h>
|
#include <vdpau/vdpau.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
@ -43,7 +44,8 @@ typedef struct _VdpauFunctions VdpauFunctions;
|
||||||
struct _GstVdpauDecoder {
|
struct _GstVdpauDecoder {
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
gchar *display;
|
gchar *display_name;
|
||||||
|
Display *display;
|
||||||
VdpDevice device;
|
VdpDevice device;
|
||||||
|
|
||||||
VdpauFunctions *functions;
|
VdpauFunctions *functions;
|
||||||
|
@ -66,17 +68,22 @@ struct _GstVdpauDecoderClass {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _VdpauFunctions {
|
struct _VdpauFunctions {
|
||||||
|
VdpDeviceDestroy *vdp_device_destroy;
|
||||||
VdpGetProcAddress *vdp_get_proc_address;
|
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;
|
VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities;
|
||||||
VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities;
|
VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities;
|
||||||
|
VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters;
|
||||||
VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr;
|
VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr;
|
||||||
|
|
||||||
VdpDeviceDestroy *vdp_device_destroy;
|
|
||||||
|
|
||||||
VdpDecoderCreate *vdp_decoder_create;
|
VdpDecoderCreate *vdp_decoder_create;
|
||||||
VdpDecoderDestroy *vdp_decoder_destroy;
|
VdpDecoderDestroy *vdp_decoder_destroy;
|
||||||
VdpDecoderRender *vdp_decoder_render;
|
VdpDecoderRender *vdp_decoder_render;
|
||||||
|
VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities;
|
||||||
|
VdpDecoderGetParameters *vdp_decoder_get_parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_vdpaudecoder_get_type (void);
|
GType gst_vdpaudecoder_get_type (void);
|
||||||
|
|
|
@ -104,13 +104,16 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps)
|
||||||
GstVdpauMpegDecoder *mpeg_dec;
|
GstVdpauMpegDecoder *mpeg_dec;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
gint version;
|
gint version;
|
||||||
|
VdpDecoderProfile profile;
|
||||||
|
VdpauFunctions *f;
|
||||||
|
VdpStatus status;
|
||||||
|
|
||||||
mpeg_dec = GST_VDPAU_MPEG_DECODER (dec);
|
mpeg_dec = GST_VDPAU_MPEG_DECODER (dec);
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
gst_structure_get_int (structure, "mpegversion", &version);
|
gst_structure_get_int (structure, "mpegversion", &version);
|
||||||
if (version == 1)
|
if (version == 1)
|
||||||
mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG1;
|
profile = VDP_DECODER_PROFILE_MPEG1;
|
||||||
|
|
||||||
else {
|
else {
|
||||||
const GValue *value;
|
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));
|
GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data));
|
||||||
switch (hdr.profile) {
|
switch (hdr.profile) {
|
||||||
case 5:
|
case 5:
|
||||||
mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
|
profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
|
profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
|
||||||
break;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,10 +187,12 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * filter,
|
gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec,
|
||||||
GstVdpauMpegDecoderClass * gclass)
|
GstVdpauMpegDecoderClass * gclass)
|
||||||
{
|
{
|
||||||
filter->silent = FALSE;
|
mpeg_dec->silent = FALSE;
|
||||||
|
|
||||||
|
mpeg_dec->decoder = VDP_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct _GstVdpauMpegDecoder
|
||||||
|
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
|
|
||||||
VdpDecoderProfile profile;
|
VdpDecoder decoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstVdpauMpegDecoderClass
|
struct _GstVdpauMpegDecoderClass
|
||||||
|
|
|
@ -18,8 +18,41 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "mpegutil.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 };
|
guint8 bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||||
|
|
||||||
guint32
|
guint32
|
||||||
|
@ -133,6 +166,7 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end)
|
||||||
/* Parse a Sequence Extension */
|
/* Parse a Sequence Extension */
|
||||||
guint8 horiz_size_ext, vert_size_ext;
|
guint8 horiz_size_ext, vert_size_ext;
|
||||||
guint8 fps_n_ext, fps_d_ext;
|
guint8 fps_n_ext, fps_d_ext;
|
||||||
|
gint i, offset;
|
||||||
|
|
||||||
if (G_UNLIKELY ((end - data) < 6))
|
if (G_UNLIKELY ((end - data) < 6))
|
||||||
/* need at least 10 bytes, minus 4 for the start code 000001b5 */
|
/* 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->fps_d *= (fps_d_ext + 1);
|
||||||
hdr->width += (horiz_size_ext << 12);
|
hdr->width += (horiz_size_ext << 12);
|
||||||
hdr->height += (vert_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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -225,3 +276,67 @@ mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end)
|
||||||
|
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
typedef struct MPEGSeqHdr MPEGSeqHdr;
|
typedef struct MPEGSeqHdr MPEGSeqHdr;
|
||||||
|
typedef struct MPEGPictureHdr MPEGPictureHdr;
|
||||||
|
typedef struct MPEGPictureExt MPEGPictureExt;
|
||||||
|
|
||||||
/* Packet ID codes for different packet types we
|
/* Packet ID codes for different packet types we
|
||||||
* care about */
|
* care about */
|
||||||
|
@ -40,6 +42,12 @@ typedef struct MPEGSeqHdr MPEGSeqHdr;
|
||||||
#define MPEG_PACKET_EXT_SEQUENCE 0x01
|
#define MPEG_PACKET_EXT_SEQUENCE 0x01
|
||||||
#define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02
|
#define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02
|
||||||
#define MPEG_PACKET_EXT_QUANT_MATRIX 0x03
|
#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
|
struct MPEGSeqHdr
|
||||||
{
|
{
|
||||||
|
@ -55,9 +63,38 @@ struct MPEGSeqHdr
|
||||||
|
|
||||||
/* mpeg2 decoder profile */
|
/* mpeg2 decoder profile */
|
||||||
gint 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,
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue