diff options
-rw-r--r-- | ChangeLog | 8 | ||||
m--------- | common | 0 | ||||
-rw-r--r-- | sys/dshowdecwrapper/gstdshowaudiodec.cpp | 48 | ||||
-rw-r--r-- | sys/dshowdecwrapper/gstdshowvideodec.cpp | 24 |
4 files changed, 65 insertions, 15 deletions
@@ -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, |