mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
ext/theora/theoraenc.c (theora_enc_sink_setcaps)
Original commit message from CVS: 2006-01-30 Andy Wingo <wingo@pobox.com> * ext/theora/theoraenc.c (theora_enc_sink_setcaps) (gst_theora_enc_init): Pull the granule shift out of the encoder. (granulepos_add): New function, handles the messiness of adjusting granulepos values. (theora_buffer_from_packet): (theora_enc_chain): (theora_enc_sink_event): Use granulepos_add, not +. * tests/check/pipelines/theoraenc.c (check_buffer_granulepos_from_starttime): Just check the frame count, not the actual granulepos -- we can't dictate to the encoder when it should be placing keyframes.
This commit is contained in:
parent
3f905bd710
commit
f2476d444b
4 changed files with 68 additions and 9 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2006-01-30 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* ext/theora/theoraenc.c (theora_enc_sink_setcaps)
|
||||
(gst_theora_enc_init): Pull the granule shift out of the encoder.
|
||||
(granulepos_add): New function, handles the messiness of adjusting
|
||||
granulepos values.
|
||||
(theora_buffer_from_packet):
|
||||
(theora_enc_chain):
|
||||
(theora_enc_sink_event): Use granulepos_add, not +.
|
||||
|
||||
* tests/check/pipelines/theoraenc.c
|
||||
(check_buffer_granulepos_from_starttime): Just check the frame
|
||||
count, not the actual granulepos -- we can't dictate to the
|
||||
encoder when it should be placing keyframes.
|
||||
|
||||
2006-01-30 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnome_vfs_src_start):
|
||||
|
|
|
@ -84,6 +84,7 @@ struct _GstTheoraEnc
|
|||
guint64 bytes_out;
|
||||
guint64 granulepos_offset;
|
||||
guint64 timestamp_offset;
|
||||
gint granule_shift;
|
||||
};
|
||||
|
||||
struct _GstTheoraEncClass
|
||||
|
|
|
@ -82,6 +82,19 @@ gst_border_mode_get_type (void)
|
|||
#define THEORA_DEF_NOISE_SENSITIVITY 1
|
||||
#define THEORA_DEF_SHARPNESS 0
|
||||
|
||||
/* taken from theora/lib/toplevel.c */
|
||||
static int
|
||||
_ilog (unsigned int v)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (v) {
|
||||
ret++;
|
||||
v >>= 1;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
|
@ -236,6 +249,11 @@ gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
|
|||
enc->keyframe_mindistance = THEORA_DEF_KEYFRAME_MINDISTANCE;
|
||||
enc->noise_sensitivity = THEORA_DEF_NOISE_SENSITIVITY;
|
||||
enc->sharpness = THEORA_DEF_SHARPNESS;
|
||||
|
||||
enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1);
|
||||
GST_DEBUG_OBJECT (enc,
|
||||
"keyframe_frequency_force is %d, granule shift is %d",
|
||||
enc->info.keyframe_frequency_force, enc->granule_shift);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -298,11 +316,29 @@ theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
enc->info.noise_sensitivity = enc->noise_sensitivity;
|
||||
enc->info.sharpness = enc->sharpness;
|
||||
|
||||
/* as done in theora */
|
||||
enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1);
|
||||
GST_DEBUG_OBJECT (enc,
|
||||
"keyframe_frequency_force is %d, granule shift is %d",
|
||||
enc->info.keyframe_frequency_force, enc->granule_shift);
|
||||
|
||||
theora_encode_init (&enc->state, &enc->info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint64
|
||||
granulepos_add (guint64 granulepos, guint64 addend, gint shift)
|
||||
{
|
||||
GstClockTime iframe, pframe;
|
||||
|
||||
iframe = granulepos >> shift;
|
||||
pframe = granulepos - (iframe << shift);
|
||||
iframe += addend;
|
||||
|
||||
return (iframe << shift) + pframe;
|
||||
}
|
||||
|
||||
/* prepare a buffer for transmission by passing data through libtheora */
|
||||
static GstFlowReturn
|
||||
theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
|
||||
|
@ -318,7 +354,9 @@ theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
|
|||
|
||||
memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
|
||||
GST_BUFFER_OFFSET (buf) = enc->bytes_out;
|
||||
GST_BUFFER_OFFSET_END (buf) = packet->granulepos + enc->granulepos_offset;
|
||||
GST_BUFFER_OFFSET_END (buf) =
|
||||
granulepos_add (packet->granulepos, enc->granulepos_offset,
|
||||
enc->granule_shift);
|
||||
GST_BUFFER_TIMESTAMP (buf) = timestamp + enc->timestamp_offset;
|
||||
GST_BUFFER_DURATION (buf) = duration;
|
||||
|
||||
|
@ -418,8 +456,8 @@ theora_enc_sink_event (GstPad * pad, GstEvent * event)
|
|||
/* push last packet with eos flag */
|
||||
while (theora_encode_packetout (&enc->state, 1, &op)) {
|
||||
/* See comment in the chain function */
|
||||
GstClockTime next_time =
|
||||
theora_granule_time (&enc->state, op.granulepos + 1) * GST_SECOND;
|
||||
GstClockTime next_time = theora_granule_time (&enc->state,
|
||||
granulepos_add (op.granulepos, 1, enc->granule_shift)) * GST_SECOND;
|
||||
|
||||
theora_push_packet (enc, &op, enc->next_ts, next_time - enc->next_ts);
|
||||
enc->next_ts = next_time;
|
||||
|
@ -675,8 +713,8 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
|
|||
theora starts with 0 instead of 1... */
|
||||
GstClockTime next_time;
|
||||
|
||||
next_time =
|
||||
theora_granule_time (&enc->state, op.granulepos + 1) * GST_SECOND;
|
||||
next_time = theora_granule_time (&enc->state,
|
||||
granulepos_add (op.granulepos, 1, enc->granule_shift)) * GST_SECOND;
|
||||
ret =
|
||||
theora_push_packet (enc, &op, enc->next_ts, next_time - enc->next_ts);
|
||||
enc->next_ts = next_time;
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#define TIMESTAMP_OFFSET 3249870963
|
||||
#define FRAMERATE 10
|
||||
|
||||
/* I know all of these have a shift of 6 bits */
|
||||
#define GRANULEPOS_SHIFT 6
|
||||
|
||||
static GCond *cond = NULL;
|
||||
static GMutex *lock = NULL;
|
||||
static GstBuffer *buf = NULL;
|
||||
|
@ -143,15 +146,17 @@ static void
|
|||
check_buffer_granulepos_from_starttime (GstBuffer * buffer,
|
||||
GstClockTime starttime)
|
||||
{
|
||||
GstClockTime granulepos, expected;
|
||||
GstClockTime granulepos, expected, framecount;
|
||||
|
||||
granulepos = GST_BUFFER_OFFSET_END (buffer);
|
||||
framecount = granulepos >> GRANULEPOS_SHIFT;
|
||||
framecount += granulepos & ((1 << GRANULEPOS_SHIFT) - 1);
|
||||
expected = gst_util_uint64_scale (starttime, FRAMERATE, GST_SECOND);
|
||||
|
||||
fail_unless (granulepos == expected || granulepos == expected + 1,
|
||||
"expected granulepos %" G_GUINT64_FORMAT
|
||||
fail_unless (framecount == expected || framecount == expected + 1,
|
||||
"expected frame count %" G_GUINT64_FORMAT
|
||||
" or %" G_GUINT64_FORMAT
|
||||
", but got granulepos %" G_GUINT64_FORMAT,
|
||||
", but got frame count %" G_GUINT64_FORMAT,
|
||||
expected, expected + 1, granulepos);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue