diracparse: make diracparse work correctly
This commit is contained in:
parent
ab1e013bb8
commit
f21e36b54b
@ -36,7 +36,9 @@
|
|||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstbytereader.h>
|
#include <gst/base/gstbytereader.h>
|
||||||
|
#include <string.h>
|
||||||
#include "gstdiracparse.h"
|
#include "gstdiracparse.h"
|
||||||
|
#include "dirac_parse.h"
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
|
||||||
@ -190,6 +192,8 @@ gst_dirac_parse_finalize (GObject * object)
|
|||||||
static gboolean
|
static gboolean
|
||||||
gst_dirac_parse_start (GstBaseParse * parse)
|
gst_dirac_parse_start (GstBaseParse * parse)
|
||||||
{
|
{
|
||||||
|
gst_base_parse_set_min_frame_size (parse, 13);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,32 +210,28 @@ gst_dirac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_dirac_parse_frame_header (GstDiracParse * diracparse,
|
|
||||||
GstBuffer * buffer, guint * framesize)
|
|
||||||
{
|
|
||||||
int next_header;
|
|
||||||
|
|
||||||
next_header = GST_READ_UINT32_BE (GST_BUFFER_DATA (buffer) + 5);
|
|
||||||
|
|
||||||
*framesize = next_header;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
||||||
{
|
{
|
||||||
GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (frame->buffer);
|
GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (frame->buffer);
|
||||||
GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
|
|
||||||
int off;
|
int off;
|
||||||
guint32 next_header;
|
guint32 next_header;
|
||||||
gboolean lost_sync;
|
guint8 *data;
|
||||||
gboolean draining;
|
int size;
|
||||||
|
gboolean have_picture = FALSE;
|
||||||
|
int offset;
|
||||||
|
|
||||||
if (G_UNLIKELY (GST_BUFFER_SIZE (frame->buffer) < 13))
|
data = GST_BUFFER_DATA (frame->buffer);
|
||||||
|
size = GST_BUFFER_SIZE (frame->buffer);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (size < 13))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
GST_DEBUG ("%d: %02x %02x %02x %02x", size, data[0], data[1], data[2],
|
||||||
|
data[3]);
|
||||||
|
|
||||||
|
if (GST_READ_UINT32_BE (data) != 0x42424344) {
|
||||||
off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
|
off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
|
||||||
0x42424344, 0, GST_BUFFER_SIZE (frame->buffer));
|
0x42424344, 0, GST_BUFFER_SIZE (frame->buffer));
|
||||||
|
|
||||||
@ -242,44 +242,48 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
|||||||
|
|
||||||
GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);
|
GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);
|
||||||
|
|
||||||
if (off > 0) {
|
GST_DEBUG ("skipping %d", off);
|
||||||
GST_ERROR ("skipping %d", off);
|
|
||||||
*skipsize = off;
|
*skipsize = off;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_dirac_parse_frame_header (diracparse, frame->buffer, framesize)) {
|
/* have sync, parse chunks */
|
||||||
GST_ERROR ("bad header");
|
|
||||||
|
offset = 0;
|
||||||
|
while (!have_picture) {
|
||||||
|
GST_DEBUG ("offset %d:", offset);
|
||||||
|
|
||||||
|
if (offset + 13 >= size) {
|
||||||
|
*framesize = offset + 13;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("chunk type %02x", data[offset + 4]);
|
||||||
|
|
||||||
|
if (GST_READ_UINT32_BE (data + offset) != 0x42424344) {
|
||||||
|
GST_DEBUG ("bad header");
|
||||||
*skipsize = 3;
|
*skipsize = 3;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG ("framesize %d", *framesize);
|
next_header = GST_READ_UINT32_BE (data + offset + 5);
|
||||||
|
GST_DEBUG ("next_header %d", next_header);
|
||||||
|
if (next_header == 0)
|
||||||
|
next_header = 13;
|
||||||
|
|
||||||
lost_sync = GST_BASE_PARSE_LOST_SYNC (frame);
|
if (SCHRO_PARSE_CODE_IS_PICTURE (data[offset + 4])) {
|
||||||
draining = GST_BASE_PARSE_DRAINING (frame);
|
have_picture = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (lost_sync && !draining) {
|
offset += next_header;
|
||||||
guint32 next_sync_word = 0;
|
if (offset >= size) {
|
||||||
|
*framesize = offset;
|
||||||
next_header = GST_READ_UINT32_BE (GST_BUFFER_DATA (frame->buffer) + 5);
|
|
||||||
GST_LOG ("next header %d", next_header);
|
|
||||||
|
|
||||||
if (!gst_byte_reader_skip (&reader, next_header) ||
|
|
||||||
!gst_byte_reader_get_uint32_be (&reader, &next_sync_word)) {
|
|
||||||
gst_base_parse_set_min_frame_size (parse, next_header + 4);
|
|
||||||
*skipsize = 0;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
}
|
||||||
if (next_sync_word != 0x42424344) {
|
}
|
||||||
*skipsize = 3;
|
|
||||||
return FALSE;
|
|
||||||
} else {
|
|
||||||
gst_base_parse_set_min_frame_size (parse, next_header);
|
|
||||||
|
|
||||||
}
|
*framesize = offset;
|
||||||
}
|
GST_DEBUG ("framesize %d", *framesize);
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -287,20 +291,51 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
|||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
{
|
{
|
||||||
//GstDiracParse * diracparse = GST_DIRAC_PARSE (parse);
|
GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
|
||||||
|
guint8 *data;
|
||||||
|
int size;
|
||||||
|
|
||||||
/* Called when processing incoming buffers. Function should parse
|
/* Called when processing incoming buffers. Function should parse
|
||||||
a checked frame. */
|
a checked frame. */
|
||||||
/* MUST implement */
|
/* MUST implement */
|
||||||
|
|
||||||
if (GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)) == NULL) {
|
data = GST_BUFFER_DATA (frame->buffer);
|
||||||
GstCaps *caps = gst_caps_new_simple ("video/x-dirac", NULL);
|
size = GST_BUFFER_SIZE (frame->buffer);
|
||||||
|
|
||||||
gst_buffer_set_caps (frame->buffer, caps);
|
//GST_ERROR("got here %d", size);
|
||||||
|
|
||||||
|
if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
|
||||||
|
GstCaps *caps;
|
||||||
|
DiracSequenceHeader sequence_header;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dirac_sequence_header_parse (&sequence_header, data + 13, size - 13);
|
||||||
|
if (ret) {
|
||||||
|
memcpy (&diracparse->sequence_header, &sequence_header,
|
||||||
|
sizeof (sequence_header));
|
||||||
|
caps = gst_caps_new_simple ("video/x-dirac",
|
||||||
|
"width", G_TYPE_INT, sequence_header.width,
|
||||||
|
"height", G_TYPE_INT, sequence_header.height,
|
||||||
|
"framerate", GST_TYPE_FRACTION,
|
||||||
|
sequence_header.frame_rate_numerator,
|
||||||
|
sequence_header.frame_rate_denominator,
|
||||||
|
"pixel-aspect-ratio", GST_TYPE_FRACTION,
|
||||||
|
sequence_header.aspect_ratio_numerator,
|
||||||
|
sequence_header.aspect_ratio_denominator,
|
||||||
|
"interlaced", G_TYPE_BOOLEAN, sequence_header.interlaced,
|
||||||
|
"profile", G_TYPE_INT, sequence_header.profile,
|
||||||
|
"level", G_TYPE_INT, sequence_header.level, NULL);
|
||||||
gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
|
gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
gst_base_parse_set_frame_rate (parse,
|
||||||
|
sequence_header.frame_rate_numerator,
|
||||||
|
sequence_header.frame_rate_denominator, 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_set_caps (frame->buffer,
|
||||||
|
GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)));
|
||||||
|
|
||||||
gst_base_parse_set_min_frame_size (parse, 13);
|
gst_base_parse_set_min_frame_size (parse, 13);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstbaseparse.h>
|
#include <gst/base/gstbaseparse.h>
|
||||||
|
#include "dirac_parse.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -38,6 +39,9 @@ struct _GstDiracParse
|
|||||||
{
|
{
|
||||||
GstBaseParse base_diracparse;
|
GstBaseParse base_diracparse;
|
||||||
|
|
||||||
|
DiracSequenceHeader sequence_header;
|
||||||
|
|
||||||
|
guint32 frame_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstDiracParseClass
|
struct _GstDiracParseClass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user