This fixes avimux largely. Sound playback still isn't optimal, but at least we're getting somewhere

Original commit message from CVS:
This fixes avimux largely. Sound playback still isn't optimal, but at least we're getting somewhere
This commit is contained in:
Ronald S. Bultje 2003-06-01 12:23:46 +00:00
parent f11e5be82f
commit 8bad3bd4ac
2 changed files with 65 additions and 78 deletions

View file

@ -248,19 +248,12 @@ gst_avimux_class_init (GstAviMuxClass *klass)
static const GstEventMask *
gst_avimux_get_event_masks (GstPad *pad)
{
static const GstEventMask gst_avimux_src_event_masks[] = {
{ GST_EVENT_NEW_MEDIA, 0 },
{ 0, }
};
static const GstEventMask gst_avimux_sink_event_masks[] = {
{ GST_EVENT_EOS, 0 },
{ 0, }
};
if (GST_PAD_IS_SRC(pad))
return gst_avimux_src_event_masks;
else
return gst_avimux_sink_event_masks;
return gst_avimux_sink_event_masks;
}
static void
@ -271,8 +264,6 @@ gst_avimux_init (GstAviMux *avimux)
gst_element_add_pad (GST_ELEMENT (avimux), avimux->srcpad);
GST_FLAG_SET (GST_ELEMENT(avimux), GST_ELEMENT_EVENT_AWARE);
gst_pad_set_event_function(avimux->srcpad, gst_avimux_handle_event);
gst_pad_set_event_mask_function(avimux->srcpad, gst_avimux_get_event_masks);
avimux->audiosinkpad = NULL;
avimux->audio_pad_connected = FALSE;
@ -293,6 +284,8 @@ gst_avimux_init (GstAviMux *avimux)
avimux->vids_hdr.type = GST_MAKE_FOURCC('v','i','d','s');
avimux->vids_hdr.rate = 1000000;
avimux->auds_hdr.type = GST_MAKE_FOURCC('a','u','d','s');
avimux->vids_hdr.quality = 0xFFFFFFFF;
avimux->auds_hdr.quality = 0xFFFFFFFF;
avimux->idx = NULL;
@ -300,8 +293,6 @@ gst_avimux_init (GstAviMux *avimux)
avimux->enable_large_avi = TRUE;
avimux->framerate = 0;
gst_element_set_loop_function(GST_ELEMENT(avimux), gst_avimux_loop);
}
@ -453,15 +444,27 @@ gst_avimux_sinkconnect (GstPad *pad, GstCaps *vscaps)
avimux->auds.format = (layer == 3?
GST_RIFF_WAVE_FORMAT_MPEGL3 :
GST_RIFF_WAVE_FORMAT_MPEGL12);
avimux->auds_hdr.scale = avimux->auds_hdr.samplesize = 1;
avimux->auds_hdr.scale = avimux->auds_hdr.samplesize =
avimux->auds.blockalign = 1;
avimux->auds_hdr.rate = avimux->auds.av_bps = 0;
avimux->auds.size = 16;
/* nobody cares about this valus, but is has to be set (regardless of
* whether the value is correct) */
avimux->auds.channels = 1;
/* we'll request this later on from the earlier pads */
avimux->auds.rate = 0;
goto done;
}
else if (!strcmp (mimetype, "application/x-ogg"))
{
avimux->auds.format = GST_RIFF_WAVE_FORMAT_VORBIS1;
avimux->auds_hdr.scale = avimux->auds_hdr.samplesize = 1;
avimux->auds_hdr.scale = avimux->auds_hdr.samplesize =
avimux->auds.blockalign = 1;
avimux->auds_hdr.rate = avimux->auds.av_bps = 0;
avimux->auds.size = 16;
/* see above */
avimux->auds.channels = 1;
avimux->auds.rate = 0;
goto done;
}
}
@ -970,6 +973,7 @@ gst_avimux_stop_file (GstAviMux *avimux)
{
GstEvent *event;
GstBuffer *header;
gdouble framerate = 0.;
/* if bigfile, rewrite header, else write indexes */
if (avimux->video_pad_connected)
@ -987,39 +991,50 @@ gst_avimux_stop_file (GstAviMux *avimux)
/* statistics/total_frames/... */
avimux->avi_hdr.tot_frames = avimux->num_frames;
if (avimux->video_pad_connected)
if (avimux->video_pad_connected) {
avimux->vids_hdr.length = avimux->num_frames;
/* get fps */
framerate = gst_video_frame_rate(GST_PAD_PEER(avimux->videosinkpad));
avimux->vids_hdr.scale = 1000000 / framerate;
}
if (avimux->audio_pad_connected)
{
if (avimux->auds_hdr.scale)
avimux->auds_hdr.length = avimux->audio_size/avimux->auds_hdr.scale;
avimux->auds_hdr.length = avimux->audio_size/(avimux->auds.size/8);
else
avimux->auds_hdr.length = 0; /* urm...? FIXME! ;-) */
/* sampling rate, if known - yes this is a hack */
if (!avimux->auds.rate)
avimux->auds.rate = gst_video_frame_rate(GST_PAD_PEER(avimux->audiosinkpad));
}
/* set rate and everything having to do with that */
avimux->avi_hdr.us_frame = avimux->vids_hdr.scale = 1000000/avimux->framerate;
avimux->avi_hdr.us_frame = avimux->vids_hdr.scale;
avimux->avi_hdr.max_bps = 0;
if (avimux->audio_pad_connected) {
/* calculate bps if needed */
if (!avimux->auds.av_bps) {
avimux->auds.av_bps = GST_SECOND * ((1. * avimux->audio_size) / avimux->audio_time);
avimux->auds_hdr.rate = avimux->auds.av_bps * avimux->auds_hdr.scale;
avimux->auds_hdr.rate = (GST_SECOND * avimux->audio_size) / avimux->audio_time;
avimux->auds.av_bps = avimux->auds_hdr.rate * avimux->auds_hdr.scale;
}
avimux->avi_hdr.max_bps += avimux->auds.av_bps;
}
if (avimux->video_pad_connected)
if (avimux->video_pad_connected) {
avimux->avi_hdr.max_bps += ((avimux->vids.bit_cnt+7)/8) *
avimux->framerate *
framerate *
avimux->vids.image_size;
}
/* seek and rewrite the header */
header = gst_avimux_riff_get_avi_header(avimux);
event = gst_event_new_seek (GST_FORMAT_BYTES |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, 0);
GST_SEEK_METHOD_SET, 0);
gst_pad_send_event(GST_PAD_PEER(avimux->srcpad), event);
gst_pad_push(avimux->srcpad, header);
event = gst_event_new_seek (GST_FORMAT_BYTES |
GST_SEEK_METHOD_SET, avimux->total_data);
avimux->write_header = TRUE;
}
@ -1031,7 +1046,7 @@ gst_avimux_restart_file (GstAviMux *avimux)
gst_avimux_stop_file(avimux);
event = gst_event_new(GST_EVENT_NEW_MEDIA);
event = gst_event_new(GST_EVENT_EOS);
gst_pad_send_event(avimux->srcpad, event);
gst_avimux_start_file(avimux);
@ -1049,17 +1064,15 @@ gst_avimux_handle_event (GstPad *pad, GstEvent *event)
type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
switch (type) {
case GST_EVENT_NEW_MEDIA:
avimux->restart = TRUE;
break;
case GST_EVENT_EOS:
/* is this allright? */
if (pad == avimux->videosinkpad)
if (pad == avimux->videosinkpad) {
avimux->video_pad_eos = TRUE;
else if (pad == avimux->audiosinkpad)
} else if (pad == avimux->audiosinkpad) {
avimux->audio_pad_eos = TRUE;
else
} else {
g_warning("Unknown pad for EOS!");
}
break;
default:
break;
@ -1075,47 +1088,33 @@ gst_avimux_fill_queue (GstAviMux *avimux)
{
GstBuffer *buffer;
if (!avimux->audio_buffer_queue &&
avimux->audiosinkpad &&
avimux->audio_pad_connected &&
GST_PAD_IS_USABLE(avimux->audiosinkpad) &&
!avimux->audio_pad_eos)
while (!avimux->audio_buffer_queue &&
avimux->audiosinkpad &&
avimux->audio_pad_connected &&
GST_PAD_IS_USABLE(avimux->audiosinkpad) &&
!avimux->audio_pad_eos)
{
while (1)
{
buffer = gst_pad_pull(avimux->audiosinkpad);
if (GST_IS_EVENT(buffer))
{
gst_avimux_handle_event(avimux->audiosinkpad, GST_EVENT(buffer));
}
else
{
avimux->audio_buffer_queue = buffer;
break;
}
buffer = gst_pad_pull(avimux->audiosinkpad);
if (GST_IS_EVENT(buffer)) {
gst_avimux_handle_event(avimux->audiosinkpad, GST_EVENT(buffer));
} else {
avimux->audio_buffer_queue = buffer;
break;
}
}
if (!avimux->video_buffer_queue &&
avimux->videosinkpad &&
avimux->video_pad_connected &&
GST_PAD_IS_USABLE(avimux->videosinkpad) &&
!avimux->video_pad_eos)
while (!avimux->video_buffer_queue &&
avimux->videosinkpad &&
avimux->video_pad_connected &&
GST_PAD_IS_USABLE(avimux->videosinkpad) &&
!avimux->video_pad_eos)
{
while (1)
{
buffer = gst_pad_pull(avimux->videosinkpad);
if (GST_IS_EVENT(buffer))
{
gst_avimux_handle_event(avimux->videosinkpad, GST_EVENT(buffer));
}
else
{
avimux->video_buffer_queue = buffer;
if (avimux->framerate < 0)
avimux->framerate = gst_video_frame_rate(GST_PAD_PEER(avimux->videosinkpad));
break;
}
buffer = gst_pad_pull(avimux->videosinkpad);
if (GST_IS_EVENT(buffer)) {
gst_avimux_handle_event(avimux->videosinkpad, GST_EVENT(buffer));
} else {
avimux->video_buffer_queue = buffer;
break;
}
}
}
@ -1334,18 +1333,9 @@ gst_avimux_change_state (GstElement *element)
avimux = GST_AVIMUX(element);
switch (transition) {
case GST_STATE_READY_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_PLAYING:
avimux->framerate = -1; /* means that we fill it in later */
avimux->video_pad_eos = avimux->audio_pad_eos = FALSE;
break;
case GST_STATE_PLAYING_TO_PAUSED:
/* this function returns TRUE while it handles buffers */
while (gst_avimux_do_one_buffer(avimux));
break;
case GST_STATE_PAUSED_TO_READY:
break;
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)

View file

@ -56,9 +56,6 @@ struct _GstAviMux {
GstPad *videosinkpad;
gboolean video_pad_connected, video_pad_eos;
/* timestamps of first and current frame + num_frames for fps calculation */
gdouble framerate;
/* the AVI header */
gst_riff_avih avi_hdr;
guint32 total_frames; /* total number of frames */