summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
m---------common0
-rw-r--r--sys/dshowdecwrapper/gstdshowaudiodec.cpp48
-rw-r--r--sys/dshowdecwrapper/gstdshowvideodec.cpp24
4 files changed, 65 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index f3de9b47..4257453f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-20 Michael Smith <msmith@songbirdnest.com>
+
+ * sys/dshowdecwrapper/gstdshowaudiodec.cpp:
+ Fix flushing/seeking problems returning error code.
+ Fix mp3 decoding with winXP (crashed randomly, occasionally).
+ * sys/dshowdecwrapper/gstdshowvideodec.cpp:
+ Fix problems when framerate is missing from video.
+
2008-11-20 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/rtpmanager/gstrtpsession.c: (get_current_times),
diff --git a/common b/common
-Subproject edfb4b44ea433b0b83b8a2f27a6e0bcbccdc3f2
+Subproject e4b2fe44724e1c1a6e816ae4fbbae43d7f68f1e
diff --git a/sys/dshowdecwrapper/gstdshowaudiodec.cpp b/sys/dshowdecwrapper/gstdshowaudiodec.cpp
index 11183572..ad6586b6 100644
--- a/sys/dshowdecwrapper/gstdshowaudiodec.cpp
+++ b/sys/dshowdecwrapper/gstdshowaudiodec.cpp
@@ -619,7 +619,9 @@ gst_dshowaudiodec_flush (GstDshowAudioDec * adec)
/* flush dshow decoder and reset timestamp */
adec->fakesrc->GetOutputPin()->Flush();
+
adec->timestamp = GST_CLOCK_TIME_NONE;
+ adec->last_ret = GST_FLOW_OK;
return TRUE;
}
@@ -651,7 +653,7 @@ dshowaudiodec_set_input_format (GstDshowAudioDec *adec, GstCaps *caps)
* decoder which doesn't need this */
if (adec->layer == 1 || adec->layer == 2) {
MPEG1WAVEFORMAT *mpeg1_format;
- int version, samples;
+ int samples, version;
GstStructure *structure = gst_caps_get_structure (caps, 0);
size = sizeof (MPEG1WAVEFORMAT);
@@ -702,12 +704,44 @@ dshowaudiodec_set_input_format (GstDshowAudioDec *adec, GstCaps *caps)
{
size = sizeof (WAVEFORMATEX) +
(adec->codec_data ? GST_BUFFER_SIZE (adec->codec_data) : 0);
- format = (WAVEFORMATEX *)g_malloc0 (size);
- if (adec->codec_data) { /* Codec data is appended after our header */
- memcpy (((guchar *) format) + sizeof (WAVEFORMATEX),
- GST_BUFFER_DATA (adec->codec_data),
- GST_BUFFER_SIZE (adec->codec_data));
- format->cbSize = GST_BUFFER_SIZE (adec->codec_data);
+
+ if (adec->layer == 3) {
+ MPEGLAYER3WAVEFORMAT *mp3format;
+
+ /* The WinXP mp3 decoder doesn't actually check the size of this structure,
+ * but requires that this be allocated and filled out (or we get obscure
+ * random crashes)
+ */
+ size = sizeof (MPEGLAYER3WAVEFORMAT);
+ mp3format = (MPEGLAYER3WAVEFORMAT *)g_malloc0 (size);
+ format = (WAVEFORMATEX *)mp3format;
+ format->cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
+
+ mp3format->wID = MPEGLAYER3_ID_MPEG;
+ mp3format->fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO; /* No idea what this means for a decoder */
+
+ /* The XP decoder divides by nBlockSize, so we must set this to a
+ non-zero value, but it doesn't matter what - this is meaningless
+ for VBR mp3 anyway */
+ mp3format->nBlockSize = 1;
+ mp3format->nFramesPerBlock = 1;
+ mp3format->nCodecDelay = 0;
+
+ /* The XP decoder also has problems with some MP3 frames. If it tries
+ * to decode one, then forever after it outputs silence.
+ * If we recognise such a frame, just skip decoding it.
+ */
+ if (adec->decoder_is_xp_mp3)
+ adec->check_mp3_frames = TRUE;
+ }
+ else {
+ format = (WAVEFORMATEX *)g_malloc0 (size);
+ if (adec->codec_data) { /* Codec data is appended after our header */
+ memcpy (((guchar *) format) + sizeof (WAVEFORMATEX),
+ GST_BUFFER_DATA (adec->codec_data),
+ GST_BUFFER_SIZE (adec->codec_data));
+ format->cbSize = GST_BUFFER_SIZE (adec->codec_data);
+ }
}
format->wFormatTag = codec_entry->format;
diff --git a/sys/dshowdecwrapper/gstdshowvideodec.cpp b/sys/dshowdecwrapper/gstdshowvideodec.cpp
index e16de6f6..600bfa81 100644
--- a/sys/dshowdecwrapper/gstdshowvideodec.cpp
+++ b/sys/dshowdecwrapper/gstdshowvideodec.cpp
@@ -539,13 +539,16 @@ gst_dshowvideodec_sink_setcaps (GstPad * pad, GstCaps * caps)
goto end;
}
fps = gst_structure_get_value (s, "framerate");
- if (!fps) {
- GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION,
- ("error getting video framerate from caps"), (NULL));
- goto end;
+ if (fps) {
+ vdec->fps_n = gst_value_get_fraction_numerator (fps);
+ vdec->fps_d = gst_value_get_fraction_denominator (fps);
+ }
+ else {
+ /* Invent a sane default framerate; the timestamps matter
+ * more anyway. */
+ vdec->fps_n = 25;
+ vdec->fps_d = 1;
}
- vdec->fps_n = gst_value_get_fraction_numerator (fps);
- vdec->fps_d = gst_value_get_fraction_denominator (fps);
if ((v = gst_structure_get_value (s, "codec_data")))
extradata = gst_value_get_buffer (v);
@@ -691,8 +694,13 @@ gst_dshowvideodec_sink_setcaps (GstPad * pad, GstCaps * caps)
caps_out = gst_caps_from_string (klass->entry->srccaps);
gst_caps_set_simple (caps_out,
"width", G_TYPE_INT, vdec->width,
- "height", G_TYPE_INT, vdec->height,
- "framerate", GST_TYPE_FRACTION, vdec->fps_n, vdec->fps_d, NULL);
+ "height", G_TYPE_INT, vdec->height, NULL);
+
+ if (vdec->fps_n && vdec->fps_d) {
+ gst_caps_set_simple (caps_out,
+ "framerate", GST_TYPE_FRACTION, vdec->fps_n, vdec->fps_d, NULL);
+ }
+
if (!gst_pad_set_caps (vdec->srcpad, caps_out)) {
gst_caps_unref (caps_out);
GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION,