This is a quick work-in-progress for fixing gstschroenc's timestamp
handling. I'll post a commentry in a followup. This example also
includes my reworked granule pos (which i'm still to poke xiph about)
..david
diff --git a/schroedinger/schroencoder.c b/schroedinger/schroencoder.c
index 8c64a5c..5f523f7 100644
--- a/schroedinger/schroencoder.c
+++ b/schroedinger/schroencoder.c
@@ -484,6 +484,10 @@ schro_encoder_pull_full (SchroEncoder *encoder, int
*presentation_frame,
SCHRO_DEBUG("pulling slot %d", encoder->output_slot);
+ if (priv) {
+ *priv = NULL;
+ }
+
schro_async_lock (encoder->async);
for(i=0;i<encoder->frame_queue->n;i++){
SchroEncoderFrame *frame;
@@ -493,7 +497,7 @@ schro_encoder_pull_full (SchroEncoder *encoder, int
*presentation_frame,
int is_picture = FALSE;
if (presentation_frame) {
- *presentation_frame = frame->presentation_frame;
+ *presentation_frame = frame->frame_number;
}
if (frame->sequence_header_buffer) {
buffer = frame->sequence_header_buffer;
diff --git a/gst/gstschroenc.c b/gst/gstschroenc.c
index 7cb0535..f88acf7 100644
--- a/gst/gstschroenc.c
+++ b/gst/gstschroenc.c
@@ -69,14 +69,11 @@ struct _GstSchroEnc
gint64 segment_position;
/* state */
- gboolean got_offset;
- gboolean update_granulepos;
- uint64_t granulepos_offset;
- uint64_t granulepos_low;
- uint64_t granulepos_hi;
gboolean started;
- gint64 timestamp_offset;
- int picture_number;
+ /* all of this tat is for ogg */
+ uint32_t num_coded_pics; /* number of codec pictures output */
+ uint32_t last_sync_dpn; /* last picnum (in display order) that is a sync
point */
+ uint32_t last_sync_cpn; /* value of num_coded_pictures at last sync point */
SchroEncoder *encoder;
SchroVideoFormat *video_format;
@@ -87,6 +84,12 @@ struct _GstSchroEncClass
GstElementClass parent_class;
};
+/* private structure passed through encoder from input picture
+ * to output coded bits */
+struct _GstSchroEncFrameTag
+{
+ GstClockTime pts;
+};
enum
{
@@ -673,19 +676,6 @@ gst_schro_enc_chain (GstPad *pad, GstBuffer *buf)
GST_DEBUG("dropping early buffer");
return GST_FLOW_OK;
}
- if (!schro_enc->got_offset) {
- schro_enc->granulepos_offset =
- gst_util_uint64_scale (GST_BUFFER_TIMESTAMP(buf), schro_enc->fps_n,
- GST_SECOND * schro_enc->fps_d);
-
- GST_DEBUG("using granulepos offset %lld", schro_enc->granulepos_offset);
- schro_enc->granulepos_hi = 0;
- schro_enc->granulepos_low = 0;
- schro_enc->got_offset = TRUE;
-
- schro_enc->timestamp_offset = GST_BUFFER_TIMESTAMP(buf);
- schro_enc->picture_number = 0;
- }
if (!schro_enc->started) {
schro_encoder_start (schro_enc->encoder);
schro_enc->started = TRUE;
@@ -693,8 +683,11 @@ gst_schro_enc_chain (GstPad *pad, GstBuffer *buf)
frame = gst_schro_buffer_wrap (schro_enc, buf, schro_enc->width,
schro_enc->height);
- GST_DEBUG ("pushing frame");
- schro_encoder_push_frame (schro_enc->encoder, frame);
+ struct _GstSchroEncFrameTag *tag = malloc(sizeof(struct
_GstSchroEncFrameTag));
+ tag->pts = GST_BUFFER_TIMESTAMP(buf);
+
+ GST_DEBUG ("pushing frame timestamp=%lld", tag->pts);
+ schro_encoder_push_frame_full (schro_enc->encoder, frame, tag);
ret = gst_schro_enc_process (schro_enc);
@@ -711,6 +704,7 @@ gst_schro_enc_process (GstSchroEnc *schro_enc)
GstFlowReturn ret;
int presentation_frame;
int parse_code;
+ void *tag;
while (1) {
switch (schro_encoder_wait (schro_enc->encoder)) {
@@ -718,8 +712,9 @@ gst_schro_enc_process (GstSchroEnc *schro_enc)
case SCHRO_STATE_END_OF_STREAM:
return GST_FLOW_OK;
case SCHRO_STATE_HAVE_BUFFER:
- encoded_buffer = schro_encoder_pull (schro_enc->encoder,
- &presentation_frame);
+ tag = NULL;
+ encoded_buffer = schro_encoder_pull_full (schro_enc->encoder,
+ &presentation_frame, &tag);
if (encoded_buffer == NULL) {
GST_ERROR("encoder_pull returned NULL");
/* FIXME This shouldn't happen */
@@ -728,16 +723,8 @@ gst_schro_enc_process (GstSchroEnc *schro_enc)
parse_code = encoded_buffer->data[4];
if (SCHRO_PARSE_CODE_IS_SEQ_HEADER(parse_code)) {
- schro_enc->update_granulepos = TRUE;
- }
- if (SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) {
- if (schro_enc->update_granulepos) {
- schro_enc->granulepos_hi = schro_enc->granulepos_offset +
- presentation_frame + 1;
- schro_enc->update_granulepos = FALSE;
- }
- schro_enc->granulepos_low = schro_enc->granulepos_offset +
- presentation_frame + 1 - schro_enc->granulepos_hi;
+ schro_enc->last_sync_dpn = presentation_frame;
+ schro_enc->last_sync_cpn = schro_enc->num_coded_pics;
}
outbuf = gst_buffer_new_and_alloc (encoded_buffer->length);
@@ -745,19 +732,19 @@ gst_schro_enc_process (GstSchroEnc *schro_enc)
encoded_buffer->length);
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (schro_enc->srcpad));
- GST_BUFFER_OFFSET_END (outbuf) =
- (schro_enc->granulepos_hi<<OGG_DIRAC_GRANULE_SHIFT) +
- schro_enc->granulepos_low;
- GST_BUFFER_OFFSET (outbuf) = gst_util_uint64_scale (
- (schro_enc->granulepos_hi + schro_enc->granulepos_low),
- schro_enc->fps_d * GST_SECOND, schro_enc->fps_n);
+ /* ogg uses offset_end as granulepos (urgh!) */
+ uint16_t dist = schro_enc->num_coded_pics - schro_enc->last_sync_cpn;
+ uint32_t sync_off = presentation_frame - schro_enc->last_sync_dpn;
+ uint32_t gp_hi = (sync_off << 16) | dist;
+ uint32_t gp_low = presentation_frame - gp_hi;
+ GST_BUFFER_OFFSET_END (outbuf) = ((uint64_t) gp_hi << 32) | gp_low;
+ GST_BUFFER_OFFSET (outbuf) = schro_enc->num_coded_pics;
+
if (SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) {
+ schro_enc->num_coded_pics++;
GST_BUFFER_DURATION (outbuf) = schro_enc->duration;
- GST_BUFFER_TIMESTAMP (outbuf) =
- schro_enc->timestamp_offset + gst_util_uint64_scale (
- schro_enc->picture_number,
- schro_enc->fps_d * GST_SECOND, schro_enc->fps_n);
- schro_enc->picture_number++;
+ GST_BUFFER_TIMESTAMP (outbuf) = ((struct
_GstSchroEncFrameTag*)tag)->pts;
+
if (!SCHRO_PARSE_CODE_IS_INTRA(parse_code)) {
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
} else {
@@ -765,14 +752,11 @@ gst_schro_enc_process (GstSchroEnc *schro_enc)
}
} else {
GST_BUFFER_DURATION (outbuf) = -1;
- GST_BUFFER_TIMESTAMP (outbuf) =
- schro_enc->timestamp_offset + gst_util_uint64_scale (
- schro_enc->picture_number,
- schro_enc->fps_d * GST_SECOND, schro_enc->fps_n);
+ GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
}
- GST_INFO("size %d offset %lld granulepos %llu:%llu timestamp %lld
duration %lld",
+ GST_INFO("size %d offset %lld granulepos %ll08x:%ll08x timestamp %lld
duration %lld",
GST_BUFFER_SIZE (outbuf),
GST_BUFFER_OFFSET (outbuf),
GST_BUFFER_OFFSET_END (outbuf)>>OGG_DIRAC_GRANULE_SHIFT,
@@ -780,6 +764,9 @@ gst_schro_enc_process (GstSchroEnc *schro_enc)
GST_BUFFER_TIMESTAMP (outbuf),
GST_BUFFER_DURATION (outbuf));
+ if (tag)
+ free(tag);
+
schro_buffer_unref (encoded_buffer);
ret = gst_pad_push (schro_enc->srcpad, outbuf);
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Schrodinger-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/schrodinger-devel