mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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:
parent
f11e5be82f
commit
8bad3bd4ac
2 changed files with 65 additions and 78 deletions
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue