From: <bi...@fr...> - 2005-05-24 09:06:14
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Tue May 24 2005 02:06:12 PDT Log message: * ext/ffmpeg/gstffmpegscale.c: (gst_ffmpegscale_chain): Always stamp your buffers ! Modified files: . : ChangeLog ext/ffmpeg : gstffmpegscale.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.162&r2=1.163 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegscale.c.diff?r1=1.2&r2=1.3 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.162 retrieving revision 1.163 diff -u -d -r1.162 -r1.163 --- ChangeLog 17 May 2005 18:29:16 -0000 1.162 +++ ChangeLog 24 May 2005 09:06:00 -0000 1.163 @@ -1,3 +1,8 @@ +2005-05-24 Edward Hervey <bi...@bi...> + + * ext/ffmpeg/gstffmpegscale.c: (gst_ffmpegscale_chain): + Always stamp your buffers ! 2005-05-17 Luca Ognibene <lu...@ti...> * ext/ffmpeg/gstffmpegcodecmap.c (gst_ffmpeg_pixfmt_to_caps): Index: gstffmpegscale.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegscale.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- gstffmpegscale.c 14 May 2005 13:19:31 -0000 1.2 +++ gstffmpegscale.c 24 May 2005 09:06:00 -0000 1.3 @@ -383,6 +383,8 @@ img_resample (scale->res, &scale->to_frame, &scale->from_frame); + gst_buffer_stamp (outbuf, (const GstBuffer *) inbuf); gst_buffer_unref (inbuf); gst_pad_push (scale->srcpad, GST_DATA (outbuf)); |
From: <bi...@fr...> - 2005-11-11 14:43:19
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Nov 11 2005 06:43:13 PST Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_get_buffer), (gst_ffmpegdec_release_buffer), (gst_ffmpegdec_frame), (gst_ffmpegdec_sink_event): Properly unref a buffer if we drop it. Esthetic fixes. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.211&r2=1.212 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.119&r2=1.120 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.211 retrieving revision 1.212 diff -u -d -r1.211 -r1.212 --- ChangeLog 8 Nov 2005 22:27:08 -0000 1.211 +++ ChangeLog 11 Nov 2005 14:43:01 -0000 1.212 @@ -1,3 +1,11 @@ +2005-11-11 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_get_buffer), + (gst_ffmpegdec_release_buffer), (gst_ffmpegdec_frame), + (gst_ffmpegdec_sink_event): + Properly unref a buffer if we drop it. + Esthetic fixes. 2005-11-08 Ronald S. Bultje <rb...@ro...> * TODO: Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.119 retrieving revision 1.120 diff -u -d -r1.119 -r1.120 --- gstffmpegdec.c 26 Oct 2005 17:41:58 -0000 1.119 +++ gstffmpegdec.c 11 Nov 2005 14:43:01 -0000 1.120 @@ -566,7 +566,8 @@ return avcodec_default_get_buffer(context, picture); } - if (gst_pad_alloc_buffer (ffmpegdec->srcpad, GST_BUFFER_OFFSET_NONE, bufsize, GST_PAD_CAPS (ffmpegdec->srcpad), &buf) != GST_FLOW_OK) + if (gst_pad_alloc_buffer (ffmpegdec->srcpad, GST_BUFFER_OFFSET_NONE, + bufsize, GST_PAD_CAPS (ffmpegdec->srcpad), &buf) != GST_FLOW_OK) return -1; ffmpegdec->last_buffer = buf; @@ -592,6 +593,8 @@ picture->opaque = buf; gst_buffer_ref (buf); + GST_LOG_OBJECT (ffmpegdec, "END"); return 0; } @@ -602,6 +605,7 @@ GstBuffer *buf = GST_BUFFER (picture->opaque); GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) context->opaque; g_return_if_fail (buf != NULL); g_return_if_fail (picture->type == FF_BUFFER_TYPE_USER); @@ -727,7 +731,7 @@ len = avcodec_decode_video (ffmpegdec->context, ffmpegdec->picture, &have_data, data, size); GST_DEBUG_OBJECT (ffmpegdec, - "Decode video: len=%d, have_data=%d", len, have_data); + "Decoded video: len=%d, have_data=%d", len, have_data); if (ffmpegdec->waiting_for_key) { if (ffmpegdec->picture->pict_type == FF_I_TYPE) { @@ -758,9 +762,11 @@ ffmpegdec->synctime = GST_CLOCK_TIME_NONE; } else { GST_WARNING_OBJECT (ffmpegdec, - "Dropping frame for synctime %" GST_TIME_FORMAT ", expected %" + "Dropping frame for synctime %" GST_TIME_FORMAT ", expected(next_ts) %" GST_TIME_FORMAT, GST_TIME_ARGS (ffmpegdec->synctime), GST_TIME_ARGS (ffmpegdec->next_ts)); + if (ffmpegdec->last_buffer) + gst_buffer_unref(ffmpegdec->last_buffer); have_data = 0; /* don´t break here! Timestamps are updated below */ } @@ -960,8 +966,8 @@ gst_event_parse_newsegment (event, NULL, &rate, &fmt, &start, &end, &base); if (fmt == GST_FORMAT_TIME) { ffmpegdec->next_ts = start; - GST_DEBUG_OBJECT (ffmpegdec, "Discont to time %" GST_TIME_FORMAT, - GST_TIME_ARGS (start)); + GST_DEBUG_OBJECT (ffmpegdec, "Discont to time (next_ts) %" GST_TIME_FORMAT" -- %"GST_TIME_FORMAT, + GST_TIME_ARGS (start), GST_TIME_ARGS (end)); } else if (ffmpegdec->context->bit_rate && fmt == GST_FORMAT_BYTES) { ffmpegdec->next_ts = start * GST_SECOND / ffmpegdec->context->bit_rate; GST_DEBUG_OBJECT (ffmpegdec, |
From: <bi...@fr...> - 2005-12-07 12:14:52
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Wed Dec 07 2005 04:14:47 PST Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): So, stupid ffmpeg.... Not all [en|de]coders set AVFrame->type. This should handle the case where AVFrame->reference is set to 1 (which is the equivalent of a keyframe). Also fixes #323286. I tried a truckload of other files with this modification and it didn't seem to break playback. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.231&r2=1.232 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.130&r2=1.131 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.231 retrieving revision 1.232 diff -u -d -r1.231 -r1.232 --- ChangeLog 6 Dec 2005 19:57:08 -0000 1.231 +++ ChangeLog 7 Dec 2005 12:14:34 -0000 1.232 @@ -1,3 +1,13 @@ +2005-12-07 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): + So, stupid ffmpeg.... Not all [en|de]coders set AVFrame->type. + This should handle the case where AVFrame->reference is set to 1 (which + is the equivalent of a keyframe). + Also fixes #323286. + I tried a truckload of other files with this modification and it didn't seem + to break playback. 2005-12-06 Thomas Vander Stichele <thomas at apestaart dot org> * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.130 retrieving revision 1.131 diff -u -d -r1.130 -r1.131 --- gstffmpegdec.c 5 Dec 2005 13:04:39 -0000 1.130 +++ gstffmpegdec.c 7 Dec 2005 12:14:34 -0000 1.131 @@ -804,18 +804,23 @@ ffmpegdec->context->frame_number++; switch (oclass->in_plugin->type) { - case CODEC_TYPE_VIDEO: + case CODEC_TYPE_VIDEO: + { + gboolean iskeyframe = FALSE; + ffmpegdec->picture->pict_type = -1; /* in case we skip frames */ ffmpegdec->context->opaque = ffmpegdec; len = avcodec_decode_video (ffmpegdec->context, ffmpegdec->picture, &have_data, data, size); + iskeyframe = ((ffmpegdec->picture->pict_type == FF_I_TYPE) || (ffmpegdec->picture->reference)); GST_DEBUG_OBJECT (ffmpegdec, - "Decoded video: len=%d, have_data=%d", len, have_data); + "Decoded video: len=%d, have_data=%d, is_keyframe:%d", + len, have_data, iskeyframe); if (ffmpegdec->waiting_for_key) { - if (ffmpegdec->picture->pict_type == FF_I_TYPE) { + if (iskeyframe) { ffmpegdec->waiting_for_key = FALSE; } else { GST_WARNING_OBJECT (ffmpegdec, "Dropping non-keyframe (seek/init)"); @@ -823,21 +828,20 @@ break; } } - /* note that ffmpeg sometimes gets the FPS wrong. * For B-frame containing movies, we get all pictures delayed * except for the I frames, so we synchronize only on I frames * and keep an internal counter based on FPS for the others. */ if (!(oclass->in_plugin->capabilities & CODEC_CAP_DELAY) || - ((ffmpegdec->picture->pict_type == FF_I_TYPE || - !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) && - GST_CLOCK_TIME_IS_VALID (*in_ts))) { - GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to %" GST_TIME_FORMAT, - GST_TIME_ARGS (*in_ts)); - ffmpegdec->next_ts = *in_ts; - *in_ts = GST_CLOCK_TIME_NONE; + ((iskeyframe || !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) && + GST_CLOCK_TIME_IS_VALID (*in_ts))) { + GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to %" GST_TIME_FORMAT, + GST_TIME_ARGS (*in_ts)); + ffmpegdec->next_ts = *in_ts; + *in_ts = GST_CLOCK_TIME_NONE; /* precise seeking.... */ if (GST_CLOCK_TIME_IS_VALID (ffmpegdec->synctime)) { if (ffmpegdec->next_ts >= ffmpegdec->synctime) { @@ -859,8 +863,7 @@ - if (ffmpegdec->waiting_for_key && - ffmpegdec->picture->pict_type != FF_I_TYPE) { + if (ffmpegdec->waiting_for_key && !iskeyframe) { have_data = 0; } else if (len >= 0 && have_data > 0) { /* libavcodec constantly crashes on stupid buffer allocation @@ -904,7 +907,7 @@ ffmpegdec->waiting_for_key = FALSE; - if (!ffmpegdec->picture->key_frame) { + if (!iskeyframe) { GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); @@ -935,9 +938,8 @@ } else if (ffmpegdec->picture->pict_type != -1 && oclass->in_plugin->capabilities & CODEC_CAP_DELAY) { /* update time for skip-frame */ - if ((!have_data) - || (ffmpegdec->picture->pict_type == FF_I_TYPE || - !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) + if ((!have_data) || + (iskeyframe || !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) && GST_CLOCK_TIME_IS_VALID (*in_ts)) { GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to *in_ts"); ffmpegdec->next_ts = *in_ts; @@ -961,7 +963,7 @@ break; + } case CODEC_TYPE_AUDIO: if (!ffmpegdec->last_buffer) outbuf = gst_buffer_new_and_alloc (AVCODEC_MAX_AUDIO_FRAME_SIZE); |
From: <bi...@fr...> - 2005-12-19 15:48:04
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Mon Dec 19 2005 07:47:25 PST Log message: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): Update ffmpeg_codec_id <=> mimetype conversions * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): Finer grained keyframe detection Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.234&r2=1.235 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.99&r2=1.100 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.132&r2=1.133 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.234 retrieving revision 1.235 diff -u -d -r1.234 -r1.235 --- ChangeLog 16 Dec 2005 16:23:05 -0000 1.234 +++ ChangeLog 19 Dec 2005 15:47:13 -0000 1.235 @@ -1,3 +1,10 @@ +2005-12-19 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): + Update ffmpeg_codec_id <=> mimetype conversions + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): + Finer grained keyframe detection 2005-12-16 Tim-Philipp Müller <tim at centricular dot net> * ext/ffmpeg/gstffmpeg.c: (gst_ffmpeg_avcodec_open), Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.99 retrieving revision 1.100 diff -u -d -r1.99 -r1.100 --- gstffmpegcodecmap.c 6 Dec 2005 19:57:08 -0000 1.99 +++ gstffmpegcodecmap.c 19 Dec 2005 15:47:13 -0000 1.100 @@ -244,10 +244,13 @@ * MJPEG-B and sp5x decoding...)? */ case CODEC_ID_MJPEG: case CODEC_ID_LJPEG: - case CODEC_ID_SP5X: caps = GST_FF_VID_CAPS_NEW ("image/jpeg", NULL); break; + case CODEC_ID_SP5X: + caps = GST_FF_VID_CAPS_NEW ("video/sp5x", NULL); + break; case CODEC_ID_MJPEGB: caps = GST_FF_VID_CAPS_NEW ("video/x-mjpeg-b", NULL); @@ -378,7 +381,7 @@ case CODEC_ID_CYUV: - buildcaps = TRUE; + caps = GST_FF_VID_CAPS_NEW ("video/x-compressed-yuv", NULL); case CODEC_ID_H264: @@ -410,8 +413,12 @@ case CODEC_ID_ASV1: + caps = GST_FF_VID_CAPS_NEW ("video/x-asus", + "asusversion", G_TYPE_INT, 1, NULL); case CODEC_ID_ASV2: + "asusversion", G_TYPE_INT, 2, NULL); case CODEC_ID_FFV1: @@ -429,15 +436,22 @@ "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL); - case CODEC_ID_FRAPS: - case CODEC_ID_VCR1: case CODEC_ID_CLJR: + caps = GST_FF_VID_CAPS_NEW ("video/x-cirrus-logic-accupak", NULL); + case CODEC_ID_FRAPS: case CODEC_ID_MDEC: case CODEC_ID_ROQ: case CODEC_ID_INTERPLAY_VIDEO: buildcaps = TRUE; + case CODEC_ID_VCR1: + caps = GST_FF_VID_CAPS_NEW ("video/x-ati-vcr", + "vcrversion", G_TYPE_INT, 1, NULL); case CODEC_ID_RPZA: caps = GST_FF_VID_CAPS_NEW ("video/x-apple-video", NULL); @@ -484,27 +498,50 @@ caps = GST_FF_AUD_CAPS_NEW ("audio/x-qdm2", NULL); break; + case CODEC_ID_MSZH: + caps = GST_FF_VID_CAPS_NEW ("video/x-mszh", NULL); + case CODEC_ID_ZLIB: + caps = GST_FF_VID_CAPS_NEW ("video/x-zlib", NULL); + case CODEC_ID_TRUEMOTION1: + caps = GST_FF_VID_CAPS_NEW ("video/x-truemotion", + "trueversion", G_TYPE_INT, 1, NULL); + case CODEC_ID_TRUEMOTION2: + "trueversion", G_TYPE_INT, 2, NULL); + case CODEC_ID_ULTI: + caps = GST_FF_VID_CAPS_NEW ("video/x-ultimotion", + NULL); + case CODEC_ID_TSCC: + caps = GST_FF_VID_CAPS_NEW ("video/x-camtasia", NULL); + case CODEC_ID_PNG: + caps = GST_FF_VID_CAPS_NEW ("image/png", NULL); case CODEC_ID_WS_VQA: case CODEC_ID_IDCIN: case CODEC_ID_8BPS: case CODEC_ID_SMC: case CODEC_ID_FLIC: - case CODEC_ID_TRUEMOTION1: - case CODEC_ID_TRUEMOTION2: case CODEC_ID_VMDVIDEO: case CODEC_ID_VMDAUDIO: - case CODEC_ID_MSZH: - case CODEC_ID_ZLIB: case CODEC_ID_SONIC: case CODEC_ID_SONIC_LS: case CODEC_ID_SNOW: - case CODEC_ID_TSCC: - case CODEC_ID_ULTI: case CODEC_ID_QDRAW: case CODEC_ID_VIXL: case CODEC_ID_QPEG: case CODEC_ID_XVID: - case CODEC_ID_PNG: case CODEC_ID_PPM: case CODEC_ID_PBM: case CODEC_ID_PGM: Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.132 retrieving revision 1.133 diff -u -d -r1.132 -r1.133 --- gstffmpegdec.c 16 Dec 2005 16:23:05 -0000 1.132 +++ gstffmpegdec.c 19 Dec 2005 15:47:13 -0000 1.133 @@ -807,6 +807,8 @@ case CODEC_TYPE_VIDEO: { gboolean iskeyframe = FALSE; + gboolean is_itype = FALSE; + gboolean is_reference = FALSE; ffmpegdec->picture->pict_type = -1; /* in case we skip frames */ @@ -814,10 +816,14 @@ len = avcodec_decode_video (ffmpegdec->context, ffmpegdec->picture, &have_data, data, size); - iskeyframe = ((ffmpegdec->picture->pict_type == FF_I_TYPE) || (ffmpegdec->picture->reference)); + is_itype = (ffmpegdec->picture->pict_type == FF_I_TYPE); + is_reference = (ffmpegdec->picture->reference == 1); + iskeyframe = ( is_itype || is_reference ) + || (oclass->in_plugin->id == CODEC_ID_MSZH) + || (oclass->in_plugin->id == CODEC_ID_ZLIB); GST_DEBUG_OBJECT (ffmpegdec, - "Decoded video: len=%d, have_data=%d, is_keyframe:%d", - len, have_data, iskeyframe); + "Decoded video: len=%d, have_data=%d, is_keyframe:%d, is_itype:%d, is_reference:%d", + len, have_data, iskeyframe, is_itype, is_reference); if (ffmpegdec->waiting_for_key) { if (iskeyframe) { |
From: <bi...@fr...> - 2006-01-12 16:46:56
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Wed Jan 11 2006 07:31:36 PST Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): Add exception for Indeo3 keyframe detection until upstream ffmpeg behaves properly. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.235&r2=1.236 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.133&r2=1.134 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.235 retrieving revision 1.236 diff -u -d -r1.235 -r1.236 --- ChangeLog 19 Dec 2005 15:47:13 -0000 1.235 +++ ChangeLog 11 Jan 2006 15:31:24 -0000 1.236 @@ -1,3 +1,9 @@ +2006-01-11 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): + Add exception for Indeo3 keyframe detection until upstream ffmpeg + behaves properly. 2005-12-19 Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.133 retrieving revision 1.134 diff -u -d -r1.133 -r1.134 --- gstffmpegdec.c 19 Dec 2005 15:47:13 -0000 1.133 +++ gstffmpegdec.c 11 Jan 2006 15:31:24 -0000 1.134 @@ -819,6 +819,7 @@ is_itype = (ffmpegdec->picture->pict_type == FF_I_TYPE); is_reference = (ffmpegdec->picture->reference == 1); iskeyframe = ( is_itype || is_reference ) + || (oclass->in_plugin->id == CODEC_ID_INDEO3) || (oclass->in_plugin->id == CODEC_ID_MSZH) || (oclass->in_plugin->id == CODEC_ID_ZLIB); GST_DEBUG_OBJECT (ffmpegdec, |
From: <bi...@fr...> - 2006-01-17 09:26:48
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Tue Jan 17 2006 01:24:52 PST Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): Memleak fix. Closes #326704 Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.240&r2=1.241 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.134&r2=1.135 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.240 retrieving revision 1.241 diff -u -d -r1.240 -r1.241 --- ChangeLog 17 Jan 2006 09:12:52 -0000 1.240 +++ ChangeLog 17 Jan 2006 09:24:40 -0000 1.241 @@ -1,5 +1,11 @@ 2006-01-17 Edward Hervey <ed...@fl...> + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): + Memleak fix. + Closes #326704 + +2006-01-17 Edward Hervey <ed...@fl...> * configure.ac: Add --with-pkg-config-path argument. Closes #319248 Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.134 retrieving revision 1.135 diff -u -d -r1.134 -r1.135 --- gstffmpegdec.c 11 Jan 2006 15:31:24 -0000 1.134 +++ gstffmpegdec.c 17 Jan 2006 09:24:40 -0000 1.135 @@ -1144,8 +1144,9 @@ /* parse cache joining */ if (ffmpegdec->pcache) { - inbuf = gst_buffer_span (ffmpegdec->pcache, 0, inbuf, - GST_BUFFER_SIZE (ffmpegdec->pcache) + GST_BUFFER_SIZE (inbuf)); + inbuf = gst_buffer_join (ffmpegdec->pcache, inbuf); +/* inbuf = gst_buffer_span (ffmpegdec->pcache, 0, inbuf, */ +/* GST_BUFFER_SIZE (ffmpegdec->pcache) + GST_BUFFER_SIZE (inbuf)); */ ffmpegdec->pcache = NULL; bdata = GST_BUFFER_DATA (inbuf); bsize = GST_BUFFER_SIZE (inbuf); |
From: <bi...@fr...> - 2006-01-20 13:59:17
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Jan 20 2006 05:57:07 PST Log message: Reviewed by : Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_chain_audio): Caps weren't set on outgoing audio buffers. Closes #327861 Modified files: . : ChangeLog ext/ffmpeg : gstffmpegenc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.241&r2=1.242 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegenc.c.diff?r1=1.81&r2=1.82 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.241 retrieving revision 1.242 diff -u -d -r1.241 -r1.242 --- ChangeLog 17 Jan 2006 09:24:40 -0000 1.241 +++ ChangeLog 20 Jan 2006 13:56:55 -0000 1.242 @@ -1,3 +1,11 @@ +2006-01-20 Michal Benes <mic...@xe...> + + Reviewed by : Edward Hervey <ed...@fl...> + * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_chain_audio): + Caps weren't set on outgoing audio buffers. + Closes #327861 2006-01-17 Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): Index: gstffmpegenc.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegenc.c,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- gstffmpegenc.c 16 Dec 2005 16:23:05 -0000 1.81 +++ gstffmpegenc.c 20 Jan 2006 13:56:55 -0000 1.82 @@ -621,6 +621,7 @@ GST_BUFFER_SIZE (outbuf) = ret_size; GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (subbuf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (subbuf); + gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ffmpegenc->srcpad)); gst_buffer_unref (subbuf); ret = gst_pad_push (ffmpegenc->srcpad, outbuf); |
From: <bi...@fr...> - 2006-01-20 14:19:36
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Jan 20 2006 06:17:28 PST Log message: reviewed by: Edward Hervey <ed...@fl...> * ext/ffmpeg/Makefile.am: * ext/ffmpeg/gstffmpeg.c: (plugin_init): * ext/ffmpeg/gstffmpegdeinterlace.c: (gst_ffmpegdeinterlace_base_init), (gst_ffmpegdeinterlace_class_init), (gst_ffmpegdeinterlace_sink_setcaps), (gst_ffmpegdeinterlace_init), (gst_ffmpegdeinterlace_chain), (gst_ffmpegdeinterlace_register): ffdeinterlace port to 0.10. Could be made a subclass of GstBaseTransform later on... Modified files: . : ChangeLog ext/ffmpeg : Makefile.am gstffmpeg.c gstffmpegdeinterlace.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.242&r2=1.243 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am.diff?r1=1.23&r2=1.24 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c.diff?r1=1.28&r2=1.29 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdeinterlace.c.diff?r1=1.6&r2=1.7 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.242 retrieving revision 1.243 diff -u -d -r1.242 -r1.243 --- ChangeLog 20 Jan 2006 13:56:55 -0000 1.242 +++ ChangeLog 20 Jan 2006 14:17:16 -0000 1.243 @@ -1,3 +1,17 @@ +2006-01-20 Martin Zlomek from Itonis (mic...@xe...) + + reviewed by: Edward Hervey <ed...@fl...> + * ext/ffmpeg/Makefile.am: + * ext/ffmpeg/gstffmpeg.c: (plugin_init): + * ext/ffmpeg/gstffmpegdeinterlace.c: + (gst_ffmpegdeinterlace_base_init), + (gst_ffmpegdeinterlace_class_init), + (gst_ffmpegdeinterlace_sink_setcaps), (gst_ffmpegdeinterlace_init), + (gst_ffmpegdeinterlace_chain), (gst_ffmpegdeinterlace_register): + ffdeinterlace port to 0.10. + Could be made a subclass of GstBaseTransform later on... 2006-01-20 Michal Benes <mic...@xe...> Reviewed by : Edward Hervey <ed...@fl...> Index: Makefile.am RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- Makefile.am 22 Nov 2005 23:12:51 -0000 1.23 +++ Makefile.am 20 Jan 2006 14:17:16 -0000 1.24 @@ -3,12 +3,12 @@ libgstffmpeg_la_SOURCES = gstffmpeg.c \ gstffmpegcodecmap.c \ gstffmpegdec.c \ - gstffmpegenc.c + gstffmpegenc.c \ + gstffmpegdeinterlace.c # gstffmpegdemux.c \ # gstffmpegmux.c \ # gstffmpegprotocol.c \ -# gstffmpegscale.c \ -# gstffmpegdeinterlace.c +# gstffmpegscale.c libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \ Index: gstffmpeg.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- gstffmpeg.c 16 Dec 2005 16:23:05 -0000 1.28 +++ gstffmpeg.c 20 Jan 2006 14:17:16 -0000 1.29 @@ -109,12 +109,12 @@ gst_ffmpegenc_register (plugin); gst_ffmpegdec_register (plugin); + gst_ffmpegdeinterlace_register (plugin); #if 0 gst_ffmpegdemux_register (plugin); gst_ffmpegmux_register (plugin); gst_ffmpegcsp_register (plugin); gst_ffmpegscale_register (plugin); - gst_ffmpegdeinterlace_register (plugin); register_protocol (&gstreamer_protocol); #endif Index: gstffmpegdeinterlace.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdeinterlace.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- gstffmpegdeinterlace.c 6 Dec 2005 19:57:08 -0000 1.6 +++ gstffmpegdeinterlace.c 20 Jan 2006 14:17:16 -0000 1.7 @@ -2,6 +2,7 @@ * Copyright (C) <1999> Erik Walthinsen <om...@cs...> * This file: * Copyright (C) 2005 Luca Ognibene <lu...@ti...> + * Copyright (C) 2006 Martin Zlomek <mar...@it...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,348 +21,178 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" -#include <gst/gst.h> #ifdef HAVE_FFMPEG_UNINSTALLED -#include <avcodec.h> +# include <avcodec.h> #else -#include <ffmpeg/avcodec.h> +# include <ffmpeg/avcodec.h> +#include <gst/gst.h> #include <gst/video/video.h> #include "gstffmpeg.h" #include "gstffmpegcodecmap.h" -#define GST_TYPE_FFMPEGDEINTERLACE \ - (gst_ffmpegdeinterlace_get_type()) -#define GST_FFMPEGDEINTERLACE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) -#define GST_FFMPEGDEINTERLACE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) -#define GST_IS_FFMPEGDEINTERLACE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEINTERLACE)) -#define GST_IS_FFMPEGDEINTERLACE_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEINTERLACE)) - -typedef struct _GstFFMpegDeinterlace GstFFMpegDeinterlace; -typedef struct _GstFFMpegDeinterlaceClass GstFFMpegDeinterlaceClass; -struct _GstFFMpegDeinterlace +typedef struct _GstFFMpegDeinterlace { GstElement element; GstPad *sinkpad, *srcpad; gint width, height; + gint to_size; enum PixelFormat pixfmt; AVPicture from_frame, to_frame; - GstCaps *sinkcaps; - - guint to_size; -}; +} GstFFMpegDeinterlace; -struct _GstFFMpegDeinterlaceClass +typedef struct _GstFFMpegDeinterlaceClass GstElementClass parent_class; -/* elementfactory information */ -static GstElementDetails ffmpegdeinterlace_details = { - "FFMPEG Deinterlace element", - "Filter/Converter/Video", - "Deinterlace video", - "Luca Ognibene <lu...@ti...>", -/* Signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL +} GstFFMpegDeinterlaceClass; - ARG_0, +#define GST_TYPE_FFMPEGDEINTERLACE \ + (gst_ffmpegdeinterlace_get_type()) +#define GST_FFMPEGDEINTERLACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) +#define GST_FFMPEGDEINTERLACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) +#define GST_IS_FFMPEGDEINTERLACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEINTERLACE)) +#define GST_IS_FFMPEGDEINTERLACE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEINTERLACE)) -static GstStaticPadTemplate gst_ffmpegdeinterlace_src_template = -GST_STATIC_PAD_TEMPLATE ("src", +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) ); -static GstStaticPadTemplate gst_ffmpegdeinterlace_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, +GST_BOILERPLATE (GstFFMpegDeinterlace, gst_ffmpegdeinterlace, GstElement, + GST_TYPE_ELEMENT); -static GType gst_ffmpegdeinterlace_get_type (void); -static void gst_ffmpegdeinterlace_base_init (GstFFMpegDeinterlaceClass * klass); -static void gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass); -static void gst_ffmpegdeinterlace_init (GstFFMpegDeinterlace * space); -static void gst_ffmpegdeinterlace_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_ffmpegdeinterlace_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); -static GstPadLinkReturn -gst_ffmpegdeinterlace_pad_link (GstPad * pad, const GstCaps * caps); -static void gst_ffmpegdeinterlace_chain (GstPad * pad, GstData * data); -static GstStateChangeReturn gst_ffmpegdeinterlace_change_state (GstElement * element, - GstStateChange transition); -static GstElementClass *parent_class = NULL; -/*static guint gst_ffmpegdeinterlace_signals[LAST_SIGNAL] = { 0 }; */ +static GstFlowReturn gst_ffmpegdeinterlace_chain (GstPad * pad, + GstBuffer * inbuf); -static GstCaps * -gst_ffmpegdeinterlace_getcaps (GstPad * pad) +static void +gst_ffmpegdeinterlace_base_init (gpointer g_class) - GstFFMpegDeinterlace *filter; - GstPad *otherpad; - filter = GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); - otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; + static GstElementDetails plugin_details = { + "FFMPEG Deinterlace element", + "Filter/Converter/Video", + "Deinterlace video", + "Luca Ognibene <lu...@ti...>", + }; + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_factory)); + gst_static_pad_template_get (&sink_factory)); + gst_element_class_set_details (element_class, &plugin_details); +} - return gst_pad_get_allowed_caps (otherpad); +gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass) +{ } -gst_ffmpegdeinterlace_pad_link (GstPad * pad, const GstCaps * caps) +static gboolean +gst_ffmpegdeinterlace_sink_setcaps (GstPad * pad, GstCaps * caps) - GstStructure *structure; + GstFFMpegDeinterlace *deinterlace = + GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); + GstStructure *structure = gst_caps_get_structure (caps, 0); AVCodecContext *ctx; - GstFFMpegDeinterlace *deinterlace; - GstPadLinkReturn ret; - int height, width; - deinterlace = GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); - otherpad = (pad == deinterlace->srcpad) ? deinterlace->sinkpad : - deinterlace->srcpad; - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &width); - ret &= gst_structure_get_int (structure, "height", &height); + if (!gst_structure_get_int (structure, "width", &deinterlace->width)) + return FALSE; + if (!gst_structure_get_int (structure, "height", &deinterlace->height)) ctx = avcodec_alloc_context (); - ctx->width = width; - ctx->height = height; + ctx->width = deinterlace->width; + ctx->height = deinterlace->height; ctx->pix_fmt = PIX_FMT_NB; gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, caps, ctx); if (ctx->pix_fmt == PIX_FMT_NB) { av_free (ctx); - /* we disable ourself here */ - return GST_PAD_LINK_REFUSED; } deinterlace->pixfmt = ctx->pix_fmt; - av_free (ctx); - ret = gst_pad_try_set_caps (otherpad, caps); - if (GST_PAD_LINK_FAILED (ret)) { - return ret; - } - deinterlace->width = width; - deinterlace->height = height; - deinterlace->to_size = avpicture_get_size (deinterlace->pixfmt, - deinterlace->width, deinterlace->height); - return GST_PAD_LINK_OK; -} -static GType -gst_ffmpegdeinterlace_get_type (void) - static GType ffmpegdeinterlace_type = 0; - if (!ffmpegdeinterlace_type) { - static const GTypeInfo ffmpegdeinterlace_info = { - sizeof (GstFFMpegDeinterlaceClass), - (GBaseInitFunc) gst_ffmpegdeinterlace_base_init, - NULL, - (GClassInitFunc) gst_ffmpegdeinterlace_class_init, - sizeof (GstFFMpegDeinterlace), - 0, - (GInstanceInitFunc) gst_ffmpegdeinterlace_init, - }; - ffmpegdeinterlace_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstFFMpegDeinterlace", &ffmpegdeinterlace_info, 0); - return ffmpegdeinterlace_type; -static void -gst_ffmpegdeinterlace_base_init (GstFFMpegDeinterlaceClass * klass) - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_set_details (element_class, &ffmpegdeinterlace_details); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_ffmpegdeinterlace_src_template)); - gst_static_pad_template_get (&gst_ffmpegdeinterlace_sink_template)); -gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass) - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + av_free (ctx); - gobject_class->set_property = gst_ffmpegdeinterlace_set_property; - gobject_class->get_property = gst_ffmpegdeinterlace_get_property; + deinterlace->to_size = + avpicture_get_size (deinterlace->pixfmt, deinterlace->width, + deinterlace->height); - gstelement_class->change_state = gst_ffmpegdeinterlace_change_state; + return gst_pad_set_caps (deinterlace->srcpad, caps); static void -gst_ffmpegdeinterlace_init (GstFFMpegDeinterlace * deinterlace) +gst_ffmpegdeinterlace_init (GstFFMpegDeinterlace * deinterlace, + GstFFMpegDeinterlaceClass * klass) - deinterlace->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get - (&gst_ffmpegdeinterlace_sink_template), - "sink"); - gst_pad_set_link_function (deinterlace->sinkpad, gst_ffmpegdeinterlace_pad_link); - gst_pad_set_getcaps_function (deinterlace->sinkpad, gst_ffmpegdeinterlace_getcaps); - gst_pad_set_chain_function (deinterlace->sinkpad, gst_ffmpegdeinterlace_chain); + deinterlace->sinkpad = + gst_pad_new_from_static_template (&sink_factory, "sink"); + gst_pad_set_setcaps_function (deinterlace->sinkpad, + gst_ffmpegdeinterlace_sink_setcaps); + gst_pad_set_chain_function (deinterlace->sinkpad, + gst_ffmpegdeinterlace_chain); gst_element_add_pad (GST_ELEMENT (deinterlace), deinterlace->sinkpad); - deinterlace->srcpad = gst_pad_new_from_template (gst_static_pad_template_get - (&gst_ffmpegdeinterlace_src_template), - "src"); + deinterlace->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); gst_element_add_pad (GST_ELEMENT (deinterlace), deinterlace->srcpad); - gst_pad_set_link_function (deinterlace->srcpad, gst_ffmpegdeinterlace_pad_link); - gst_pad_set_getcaps_function (deinterlace->srcpad, gst_ffmpegdeinterlace_getcaps); deinterlace->pixfmt = PIX_FMT_NB; -gst_ffmpegdeinterlace_chain (GstPad * pad, GstData * data) +static GstFlowReturn +gst_ffmpegdeinterlace_chain (GstPad * pad, GstBuffer * inbuf) - GstBuffer *inbuf = GST_BUFFER (data); GstBuffer *outbuf = NULL; + GstFlowReturn result; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (inbuf != NULL); - g_return_if_fail (deinterlace != NULL); - g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (deinterlace)); - if (!GST_PAD_IS_USABLE (deinterlace->srcpad)) { - gst_buffer_unref (inbuf); - return; - outbuf = gst_pad_alloc_buffer_and_set_caps (deinterlace->srcpad, - GST_BUFFER_OFFSET_NONE, deinterlace->to_size); - gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, - GST_BUFFER_DATA (inbuf), - deinterlace->pixfmt, - deinterlace->width, deinterlace->height); - gst_ffmpeg_avpicture_fill (&deinterlace->to_frame, - GST_BUFFER_DATA (outbuf), - deinterlace->width, deinterlace->height); - avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame, - deinterlace->pixfmt, deinterlace->width, deinterlace->height); - gst_buffer_stamp (outbuf, (const GstBuffer *) inbuf); - gst_buffer_unref (inbuf); - gst_pad_push (deinterlace->srcpad, GST_DATA (outbuf)); -static GstStateChangeReturn -gst_ffmpegdeinterlace_change_state (GstElement * element, GstStateChange transition) - deinterlace = GST_FFMPEGDEINTERLACE (element); - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - break; - if (parent_class->change_state) - return parent_class->change_state (element, transition); + result = + gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE, + deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf); + if (result == GST_FLOW_OK) { + gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, + GST_BUFFER_DATA (inbuf), deinterlace->pixfmt, deinterlace->width, + deinterlace->height); - return GST_STATE_CHANGE_SUCCESS; + gst_ffmpeg_avpicture_fill (&deinterlace->to_frame, GST_BUFFER_DATA (outbuf), + deinterlace->pixfmt, deinterlace->width, deinterlace->height); -gst_ffmpegdeinterlace_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) + avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame, - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (object)); - deinterlace = GST_FFMPEGDEINTERLACE (object); + gst_buffer_stamp (outbuf, inbuf); - switch (prop_id) { - default: + result = gst_pad_push (deinterlace->srcpad, outbuf); -gst_ffmpegdeinterlace_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) + gst_buffer_unref (inbuf); - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + return result; gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin) return gst_element_register (plugin, "ffdeinterlace", GST_RANK_NONE, GST_TYPE_FFMPEGDEINTERLACE); |
From: <bi...@fr...> - 2006-01-23 15:16:01
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Mon Jan 23 2006 07:13:41 PST Log message: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): Added CODEC_ID_SMC <==> video/x-smc caps * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): I hate ffmpeg... no keyframe information at all for VP3, so we have to assume they're all keyframes :( Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.243&r2=1.244 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.100&r2=1.101 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.135&r2=1.136 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.243 retrieving revision 1.244 diff -u -d -r1.243 -r1.244 --- ChangeLog 20 Jan 2006 14:17:16 -0000 1.243 +++ ChangeLog 23 Jan 2006 15:13:29 -0000 1.244 @@ -1,3 +1,11 @@ +2006-01-23 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): + Added CODEC_ID_SMC <==> video/x-smc caps + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): + I hate ffmpeg... no keyframe information at all for VP3, so we have + to assume they're all keyframes :( 2006-01-20 Martin Zlomek from Itonis (mic...@xe...) reviewed by: Edward Hervey <ed...@fl...> Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.100 retrieving revision 1.101 diff -u -d -r1.100 -r1.101 --- gstffmpegcodecmap.c 19 Dec 2005 15:47:13 -0000 1.100 +++ gstffmpegcodecmap.c 23 Jan 2006 15:13:29 -0000 1.101 @@ -528,10 +528,13 @@ caps = GST_FF_VID_CAPS_NEW ("image/png", NULL); break; + case CODEC_ID_SMC: + caps = GST_FF_VID_CAPS_NEW ("video/x-smc", NULL); + break; case CODEC_ID_WS_VQA: case CODEC_ID_IDCIN: case CODEC_ID_8BPS: - case CODEC_ID_SMC: case CODEC_ID_FLIC: case CODEC_ID_VMDVIDEO: case CODEC_ID_VMDAUDIO: Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.135 retrieving revision 1.136 diff -u -d -r1.135 -r1.136 --- gstffmpegdec.c 17 Jan 2006 09:24:40 -0000 1.135 +++ gstffmpegdec.c 23 Jan 2006 15:13:29 -0000 1.136 @@ -821,7 +821,8 @@ iskeyframe = ( is_itype || is_reference ) || (oclass->in_plugin->id == CODEC_ID_INDEO3) || (oclass->in_plugin->id == CODEC_ID_MSZH) - || (oclass->in_plugin->id == CODEC_ID_ZLIB); + || (oclass->in_plugin->id == CODEC_ID_ZLIB) + || (oclass->in_plugin->id == CODEC_ID_VP3); GST_DEBUG_OBJECT (ffmpegdec, "Decoded video: len=%d, have_data=%d, is_keyframe:%d, is_itype:%d, is_reference:%d", len, have_data, iskeyframe, is_itype, is_reference); |
From: <bi...@fr...> - 2006-02-10 10:59:28
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Feb 10 2006 02:56:18 PST Log message: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): added CODEC_ID_FLV1 <==> 'video/x-flash-video,flvversion=1' conversion. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.253&r2=1.254 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.104&r2=1.105 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.253 retrieving revision 1.254 diff -u -d -r1.253 -r1.254 --- ChangeLog 6 Feb 2006 17:51:40 -0000 1.253 +++ ChangeLog 10 Feb 2006 10:56:05 -0000 1.254 @@ -1,3 +1,8 @@ +2006-02-10 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): + added CODEC_ID_FLV1 <==> 'video/x-flash-video,flvversion=1' conversion. 2006-02-06 Thomas Vander Stichele <thomas at apestaart dot org> * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.104 retrieving revision 1.105 diff -u -d -r1.104 -r1.105 --- gstffmpegcodecmap.c 6 Feb 2006 17:51:40 -0000 1.104 +++ gstffmpegcodecmap.c 10 Feb 2006 10:56:05 -0000 1.105 @@ -320,7 +320,8 @@ break; case CODEC_ID_FLV1: - buildcaps = TRUE; + caps = GST_FF_VID_CAPS_NEW ("video/x-flash-video", + "flvversion", G_TYPE_INT, 1, NULL); case CODEC_ID_SVQ1: |
From: <bi...@fr...> - 2006-02-10 19:45:38
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Feb 10 2006 11:42:31 PST Log message: * ext/ffmpeg/Makefile.am: * ext/ffmpeg/gstffmpeg.c: (plugin_init): * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_base_init), (gst_ffmpegdemux_init), (gst_ffmpegdemux_stream_from_pad), (gst_ffmpegdemux_handle_seek), (gst_ffmpegdemux_src_event), (gst_ffmpegdemux_src_query_list), (gst_ffmpegdemux_src_query), (gst_ffmpegdemux_add), (gst_ffmpegdemux_open), (gst_ffmpegdemux_loop), (gst_ffmpegdemux_sink_activate), (gst_ffmpegdemux_sink_activate_pull), (gst_ffmpegdemux_change_state), (gst_ffmpegdemux_register): * ext/ffmpeg/gstffmpegprotocol.c: (gst_ffmpegdata_open), (gst_ffmpegdata_peek), (gst_ffmpegdata_read), (gst_ffmpegdata_write), (gst_ffmpegdata_seek), (gst_ffmpegdata_close): Welcome the demuxers to 0.10 :) For the time being the demuxers work only pull-based. Seeking, querying works. Modified files: . : ChangeLog ext/ffmpeg : Makefile.am gstffmpeg.c gstffmpegdemux.c gstffmpegprotocol.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.254&r2=1.255 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am.diff?r1=1.24&r2=1.25 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c.diff?r1=1.29&r2=1.30 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdemux.c.diff?r1=1.50&r2=1.51 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegprotocol.c.diff?r1=1.25&r2=1.26 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.254 retrieving revision 1.255 diff -u -d -r1.254 -r1.255 --- ChangeLog 10 Feb 2006 10:56:05 -0000 1.254 +++ ChangeLog 10 Feb 2006 19:42:19 -0000 1.255 @@ -1,5 +1,25 @@ 2006-02-10 Edward Hervey <ed...@fl...> + * ext/ffmpeg/Makefile.am: + * ext/ffmpeg/gstffmpeg.c: (plugin_init): + * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_base_init), + (gst_ffmpegdemux_init), (gst_ffmpegdemux_stream_from_pad), + (gst_ffmpegdemux_handle_seek), (gst_ffmpegdemux_src_event), + (gst_ffmpegdemux_src_query_list), (gst_ffmpegdemux_src_query), + (gst_ffmpegdemux_add), (gst_ffmpegdemux_open), + (gst_ffmpegdemux_loop), (gst_ffmpegdemux_sink_activate), + (gst_ffmpegdemux_sink_activate_pull), + (gst_ffmpegdemux_change_state), (gst_ffmpegdemux_register): + * ext/ffmpeg/gstffmpegprotocol.c: (gst_ffmpegdata_open), + (gst_ffmpegdata_peek), (gst_ffmpegdata_read), + (gst_ffmpegdata_write), (gst_ffmpegdata_seek), + (gst_ffmpegdata_close): + Welcome the demuxers to 0.10 :) + For the time being the demuxers work only pull-based. + Seeking, querying works. + +2006-02-10 Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps): added CODEC_ID_FLV1 <==> 'video/x-flash-video,flvversion=1' conversion. Index: Makefile.am RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- Makefile.am 20 Jan 2006 14:17:16 -0000 1.24 +++ Makefile.am 10 Feb 2006 19:42:19 -0000 1.25 @@ -4,10 +4,10 @@ gstffmpegcodecmap.c \ gstffmpegdec.c \ gstffmpegenc.c \ - gstffmpegdeinterlace.c -# gstffmpegdemux.c \ + gstffmpegdeinterlace.c \ + gstffmpegdemux.c \ + gstffmpegprotocol.c # gstffmpegmux.c \ -# gstffmpegprotocol.c \ # gstffmpegscale.c libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ Index: gstffmpeg.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- gstffmpeg.c 20 Jan 2006 14:17:16 -0000 1.29 +++ gstffmpeg.c 10 Feb 2006 19:42:19 -0000 1.30 @@ -110,14 +110,14 @@ gst_ffmpegenc_register (plugin); gst_ffmpegdec_register (plugin); gst_ffmpegdeinterlace_register (plugin); -#if 0 gst_ffmpegdemux_register (plugin); +#if 0 gst_ffmpegmux_register (plugin); gst_ffmpegcsp_register (plugin); gst_ffmpegscale_register (plugin); +#endif register_protocol (&gstreamer_protocol); -#endif /* Now we can return the pointer to the newly created Plugin object. */ return TRUE; Index: gstffmpegdemux.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdemux.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- gstffmpegdemux.c 5 Sep 2005 14:06:29 -0000 1.50 +++ gstffmpegdemux.c 10 Feb 2006 19:42:19 -0000 1.51 @@ -1,5 +1,6 @@ /* GStreamer - * Copyright (C) <1999> Erik Walthinsen <om...@cs...> + * Copyright (C) <1999> Erik Walthinsen <om...@cs...>, + * <2006> Edward Hervey <bi...@bi...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -51,6 +52,15 @@ gboolean handled[MAX_STREAMS]; guint64 last_ts[MAX_STREAMS]; gint videopads, audiopads; + /* segment stuff */ + /* TODO : replace with GstSegment */ + gdouble segment_rate; + GstSeekFlags segment_flags; + /* GST_FORMAT_TIME */ + gint64 segment_start; + gint64 segment_stop; + GstEvent *seek_event; }; typedef struct _GstFFMpegDemuxClassParams @@ -71,29 +81,6 @@ GstPadTemplate *audiosrctempl; -#define GST_TYPE_FFMPEGDEC \ - (gst_ffmpegdec_get_type()) -#define GST_FFMPEGDEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegDemux)) -#define GST_FFMPEGDEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegDemuxClass)) -#define GST_IS_FFMPEGDEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC)) -#define GST_IS_FFMPEGDEC_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC)) - -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - ARG_0, static GHashTable *global_plugins; /* A number of functon prototypes are given so we can refer to them later. */ @@ -101,15 +88,21 @@ static void gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass); static void gst_ffmpegdemux_init (GstFFMpegDemux * demux); -static void gst_ffmpegdemux_loop (GstElement * element); +static void gst_ffmpegdemux_loop (GstPad * pad); +static gboolean +gst_ffmpegdemux_sink_activate (GstPad * sinkpad); +gst_ffmpegdemux_sink_activate_pull (GstPad * sinkpad, gboolean active); +gst_ffmpegdemux_src_convert (GstPad * pad, + GstFormat src_fmt, + gint64 src_value, GstFormat * dest_fmt, gint64 * dest_value); static GstStateChangeReturn gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition); static GstElementClass *parent_class = NULL; -/*static guint gst_ffmpegdemux_signals[LAST_SIGNAL] = { 0 }; */ static const gchar * gst_ffmpegdemux_averror (gint av_errno) { @@ -162,10 +155,11 @@ details.longname = g_strdup_printf ("FFMPEG %s demuxer", params->in_plugin->long_name); details.klass = "Codec/Demuxer"; - details.description = g_strdup_printf ("FFMPEG %s decoder", + details.description = g_strdup_printf ("FFMPEG %s demuxer", details.author = "Wim Taymans <wim...@ch...>, " - "Ronald Bultje <rb...@ro...>"; + "Ronald Bultje <rb...@ro...>, " + "Edward Hervey <bi...@bi...>"; gst_element_class_set_details (element_class, &details); g_free (details.longname); g_free (details.description); @@ -210,8 +204,10 @@ gint n; demux->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink"); + gst_pad_set_activate_function (demux->sinkpad, gst_ffmpegdemux_sink_activate); + gst_pad_set_activatepull_function (demux->sinkpad, + gst_ffmpegdemux_sink_activate_pull); gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad); - gst_element_set_loop_function (GST_ELEMENT (demux), gst_ffmpegdemux_loop); demux->opened = FALSE; demux->context = NULL; @@ -223,6 +219,12 @@ } demux->videopads = 0; demux->audiopads = 0; + demux->segment_rate = 1.0; + demux->segment_flags = 0; + demux->segment_start = -1; + demux->segment_stop = -1; + demux->seek_event = NULL; } static void @@ -266,18 +268,59 @@ } + gst_object_unref (demux); return stream; -static const GstEventMask * -gst_ffmpegdemux_src_event_mask (GstPad * pad) +gst_ffmpegdemux_handle_seek (GstFFMpegDemux * demux, gboolean update) - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_KEY_UNIT}, - {0,} - }; + gboolean flush, keyframe; + guint stream; - return masks; + GST_DEBUG_OBJECT (demux, "update:%d", update); + flush = demux->segment_flags & GST_SEEK_FLAG_FLUSH; + keyframe = demux->segment_flags & GST_SEEK_FLAG_KEY_UNIT; + if (flush) { + for (stream = 0; stream < demux->context->nb_streams; stream++) { + gst_pad_push_event (demux->srcpads[stream], + gst_event_new_flush_start()); + } + gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ()); + } else + gst_pad_pause_task (demux->sinkpad); + GST_PAD_STREAM_LOCK (demux->sinkpad); + GST_DEBUG_OBJECT (demux, "Creating new segment (%"GST_TIME_FORMAT" / %"GST_TIME_FORMAT, + GST_TIME_ARGS (demux->segment_start), + GST_TIME_ARGS (demux->segment_stop)); + demux->seek_event = gst_event_new_new_segment (!update, demux->segment_rate, GST_FORMAT_TIME, + demux->segment_start, demux->segment_stop, + demux->segment_start); + + for (stream = 0; stream < demux->context->nb_streams; stream++) + gst_event_new_flush_stop ()); + gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ()); + } + if (demux->segment_flags & GST_SEEK_FLAG_SEGMENT) + gst_element_post_message (GST_ELEMENT (demux), + gst_message_new_segment_start (GST_OBJECT (demux), + GST_FORMAT_TIME, + demux->segment_start)); + gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop, + demux->sinkpad); + GST_PAD_STREAM_UNLOCK (demux->sinkpad); + return TRUE; static gboolean @@ -292,59 +335,93 @@ return FALSE; switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - offset = GST_EVENT_SEEK_OFFSET (event); - switch (GST_EVENT_SEEK_FORMAT (event)) { - case GST_FORMAT_DEFAULT: - if (stream->codec->codec_type != CODEC_TYPE_VIDEO) { - res = FALSE; - break; - } else { - GstFormat fmt = GST_FORMAT_TIME; + case GST_EVENT_SEEK: + { + GstFormat format; + GstSeekFlags flags; + gdouble rate; + gint64 start, stop; + gint64 tstart, tstop; + gint64 duration; + GstFormat tformat = GST_FORMAT_TIME; + GstSeekType start_type, stop_type; + gboolean update_start = TRUE; + gboolean update_stop = TRUE; - if (!(res = gst_pad_convert (pad, GST_FORMAT_DEFAULT, offset, - &fmt, &offset))) - break; - } - /* fall-through */ - case GST_FORMAT_TIME: - if (av_seek_frame (demux->context, stream->index, - offset / (GST_SECOND / AV_TIME_BASE) , 0)) + gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, + &stop_type, &stop); + GST_DEBUG_OBJECT (demux, + "seek format %d, flags:%d, start:%lld, stop:%lld", format, + flags, start, stop); + + if (format != GST_FORMAT_TIME) { + res &= gst_ffmpegdemux_src_convert (pad, format, start, &tformat, &tstart); + res &= gst_ffmpegdemux_src_convert (pad, format, stop, &tformat, &tstop); + } else { + tstart = start; + tstop = stop; + } + duration = gst_ffmpeg_time_ff_to_gst (stream->duration, stream->time_base); + switch (start_type) { + case GST_SEEK_TYPE_CUR: + tstart = demux->segment_start + tstart; break; - default: - res = FALSE; + case GST_SEEK_TYPE_END: + tstart = duration + tstart; + break; + case GST_SEEK_TYPE_NONE: + tstart = demux->segment_start; + update_start = FALSE; + case GST_SEEK_TYPE_SET: } - break; - default: - res = FALSE; - } + tstart = CLAMP (tstart, 0, duration); - return res; -} + switch (stop_type) { + tstop = demux->segment_stop + tstop; + tstop = duration + tstop; + tstop = demux->segment_stop; + update_stop = FALSE; + tstop = CLAMP (tstop, 0, duration); -static const GstFormat * -gst_ffmpegdemux_src_format_list (GstPad * pad) - AVStream *stream = gst_ffmpegdemux_stream_from_pad (pad); - static const GstFormat src_v_formats[] = { - GST_FORMAT_TIME, - GST_FORMAT_DEFAULT, - 0 - }, src_a_formats[] = { - GST_FORMAT_TIME, 0}; + /* now store the values */ + demux->segment_rate = rate; + demux->segment_flags = flags; + demux->segment_start = tstart; + demux->segment_stop = tstop; - return (stream->codec->codec_type == CODEC_TYPE_VIDEO) ? - src_v_formats : src_a_formats; + gst_ffmpegdemux_handle_seek (demux, update_start || update_stop); + break; + break; + default: + res = FALSE; + gst_event_unref (event); + return res; static const GstQueryType * gst_ffmpegdemux_src_query_list (GstPad * pad) static const GstQueryType src_types[] = { - GST_QUERY_TOTAL, + GST_QUERY_DURATION, GST_QUERY_POSITION, 0 }; @@ -353,68 +430,80 @@ -gst_ffmpegdemux_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) +gst_ffmpegdemux_src_query (GstPad * pad, GstQuery *query) - GstFFMpegDemux *demux = (GstFFMpegDemux *) gst_pad_get_parent (pad); + GstFFMpegDemux *demux = (GstFFMpegDemux *) GST_PAD_PARENT (pad); AVStream *stream = gst_ffmpegdemux_stream_from_pad (pad); gboolean res = FALSE; - switch (type) { - case GST_QUERY_TOTAL: - switch (*fmt) { - if (stream) { - *value = stream->duration * (GST_SECOND / AV_TIME_BASE); - res = TRUE; - break; - if (stream->codec_info_nb_frames && - stream->codec->codec_type == CODEC_TYPE_VIDEO) { - *value = stream->codec_info_nb_frames; - case GST_FORMAT_BYTES: - if (demux->videopads + demux->audiopads == 1 && - GST_PAD_PEER (demux->sinkpad) != NULL) { - res = gst_pad_query (GST_PAD_PEER (demux->sinkpad), - type, fmt, value); + if (stream == NULL) + return FALSE; + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + gint64 timeposition; + gst_query_parse_position (query, &format, NULL); + timeposition = demux->last_ts[stream->index]; + if (!(GST_CLOCK_TIME_IS_VALID (timeposition))) + break; + switch (format) { + case GST_FORMAT_TIME: + gst_query_set_position (query, GST_FORMAT_TIME, timeposition); + res = TRUE; + case GST_FORMAT_DEFAULT: + gst_query_set_position (query, GST_FORMAT_DEFAULT, + timeposition * stream->r_frame_rate.num / + (GST_SECOND * stream->r_frame_rate.den)); + case GST_FORMAT_BYTES: + if (demux->videopads + demux->audiopads == 1 && + GST_PAD_PEER (demux->sinkpad) != NULL) + res = gst_pad_query_default (pad, query); + default: - case GST_QUERY_POSITION: - if (stream && - GST_CLOCK_TIME_IS_VALID (demux->last_ts[stream->index])) { - *value = demux->last_ts[stream->index]; - if (stream && stream->codec->codec_type == CODEC_TYPE_VIDEO && - res = gst_pad_convert (pad, GST_FORMAT_TIME, - demux->last_ts[stream->index], fmt, value); + case GST_QUERY_DURATION: + gint64 timeduration; + gst_query_parse_duration (query, &format, NULL); + timeduration = gst_ffmpeg_time_ff_to_gst (stream->duration, stream->time_base); + if (!(GST_CLOCK_TIME_IS_VALID (timeduration))) + gst_query_set_duration (query, GST_FORMAT_TIME, timeduration); + gst_query_set_duration (query, GST_FORMAT_DEFAULT, + timeduration * stream->r_frame_rate.num / + /* FIXME : ADD GST_QUERY_CONVERT */ + res = gst_pad_query_default (pad, query); return res; @@ -496,13 +585,11 @@ pad = gst_pad_new_from_template (templ, padname); g_free (padname); - gst_pad_use_explicit_caps (pad); - gst_pad_set_formats_function (pad, gst_ffmpegdemux_src_format_list); - gst_pad_set_event_mask_function (pad, gst_ffmpegdemux_src_event_mask); - gst_pad_set_event_function (pad, gst_ffmpegdemux_src_event); + gst_pad_use_fixed_caps (pad); gst_pad_set_query_type_function (pad, gst_ffmpegdemux_src_query_list); gst_pad_set_query_function (pad, gst_ffmpegdemux_src_query); - gst_pad_set_convert_function (pad, gst_ffmpegdemux_src_convert); + gst_pad_set_event_function (pad, gst_ffmpegdemux_src_event); /* store pad internally */ demux->srcpads[stream->index] = pad; @@ -510,7 +597,7 @@ /* get caps that belongs to this stream */ caps = gst_ffmpeg_codecid_to_caps (stream->codec->codec_id, stream->codec, TRUE); - gst_pad_set_explicit_caps (pad, caps); + gst_pad_set_caps (pad, caps); gst_element_add_pad (GST_ELEMENT (demux), pad); @@ -521,7 +608,7 @@ gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, (stream->codec->codec_type == CODEC_TYPE_VIDEO) ? GST_TAG_VIDEO_CODEC : GST_TAG_AUDIO_CODEC, codec, NULL); - gst_element_found_tags_for_pad (GST_ELEMENT (demux), pad, 0, list); + gst_element_found_tags_for_pad (GST_ELEMENT (demux), pad, list); @@ -540,8 +627,11 @@ /* open via our input protocol hack */ location = g_strdup_printf ("gstreamer://%p", demux->sinkpad); + GST_DEBUG_OBJECT (demux, "about to call av_open_input_file %s", + location); res = av_open_input_file (&demux->context, location, oclass->in_plugin, 0, NULL); + GST_DEBUG_OBJECT (demux, "av_open_input returned %d", res); if (res >= 0) res = av_find_stream_info (demux->context); g_free (location); @@ -588,55 +678,97 @@ +/* Task */ -gst_ffmpegdemux_loop (GstElement * element) +gst_ffmpegdemux_loop (GstPad * pad) - GstFFMpegDemux *demux = (GstFFMpegDemux *) (element); + GstFFMpegDemux *demux = (GstFFMpegDemux*) (GST_PAD_PARENT (pad)); + GstFlowReturn ret = GST_FLOW_OK; gint res; AVPacket pkt; - GstPad *pad; + GstPad *srcpad; /* open file if we didn't so already */ if (!demux->opened) { - if (!gst_ffmpegdemux_open (demux)) - return; - gst_element_no_more_pads (element); - return; - /* read a package */ - res = av_read_frame (demux->context, &pkt); - if (res < 0) { - /* This doesn't work - FIXME */ - if (url_feof (&demux->context->pb)) { - gst_ffmpegdemux_close (demux); - gst_pad_event_default (demux->sinkpad, gst_event_new (GST_EVENT_EOS)); - } else { - GST_ELEMENT_ERROR (demux, LIBRARY, FAILED, (NULL), - (gst_ffmpegdemux_averror (res))); + if (!gst_ffmpegdemux_open (demux)) { + ret = GST_FLOW_ERROR; + goto pause; + gst_element_no_more_pads (GST_ELEMENT (demux)); - /* so, we do it the hacky way. */ - GstData *data = NULL; + /* Calculate min start and maximum end */ + for (res = 0; res < demux->context->nb_streams; res++) { + gint64 start_time, duration, end; + AVStream *stream; + stream = demux->context->streams[res]; - do { - data = gst_pad_pull (demux->sinkpad); + start_time = gst_ffmpeg_time_ff_to_gst (stream->start_time, stream->time_base); + if (start_time == GST_CLOCK_TIME_NONE) + start_time = 0; + if (duration == GST_CLOCK_TIME_NONE) + end = GST_CLOCK_TIME_NONE; + else + end = start_time + duration; - if (!GST_IS_EVENT (data) || - GST_EVENT_TYPE (GST_EVENT (data)) != GST_EVENT_EOS) { - gst_data_unref (data); - data = NULL; - } - } while (!data); + if ((start_time < demux->segment_start) || (demux->segment_start == -1)) + demux->segment_start = start_time; - gst_pad_event_default (demux->sinkpad, GST_EVENT (data)); - //gst_ffmpegdemux_close (demux); + if ((end > demux->segment_stop) || (demux->segment_stop == -1)) + demux->segment_stop = end; + } + /* Send newsegment on all src pads */ + GST_DEBUG_OBJECT (demux, "sending newsegment start:%"GST_TIME_FORMAT" duration:%"GST_TIME_FORMAT, + GST_TIME_ARGS (demux->segment_start), + GST_TIME_ARGS (demux->segment_stop)); + gst_pad_push_event(demux->srcpads[res], + gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, + demux->segment_start, demux->segment_stop, + demux->segment_start)); + if (demux->seek_event) { + /* pending seek */ + GST_DEBUG_OBJECT (demux, "About to call av_seek_frame (context, -1, %lld, 0)", + gst_ffmpeg_time_gst_to_ff (demux->segment_start, demux->context->streams[0]->time_base)); + if ((av_seek_frame (demux->context, -1, + gst_ffmpeg_time_gst_to_ff (demux->segment_start, demux->context->streams[0]->time_base), 0)) < 0) { + GST_WARNING_OBJECT (demux, "Call to av_seek_frame failed"); + /* read a package */ + res = av_read_frame (demux->context, &pkt); + if (res < 0) { + /* something went wrong... */ + GST_WARNING_OBJECT (demux, "av_read_frame returned %d", res); + ret = GST_FLOW_ERROR; + goto pause; + GST_DEBUG_OBJECT (demux, "About to send pending newsegment event (%"GST_TIME_FORMAT"/%"GST_TIME_FORMAT")", + GST_TIME_ARGS (demux->segment_start), + GST_TIME_ARGS (demux->segment_stop)); + gst_event_ref (demux->seek_event); + gst_pad_push_event (demux->srcpads[res], demux->seek_event); + gst_event_unref (demux->seek_event); + demux->seek_event = NULL; + GST_DEBUG_OBJECT (demux, "pkt pts:%lld / dts:%lld / size:%d / stream_index:%d / flags:%d / duration:%d / pos:%lld", + pkt.pts, pkt.dts, pkt.size, pkt.stream_index, pkt.flags, pkt.duration, pkt.pos); /* for stream-generation-while-playing */ if (!demux->handled[pkt.stream_index]) { gst_ffmpegdemux_add (demux, demux->context->streams[pkt.stream_index]); @@ -644,38 +776,92 @@ /* shortcut to pad belonging to this stream */ - pad = demux->srcpads[pkt.stream_index]; + srcpad = demux->srcpads[pkt.stream_index]; - /* and handle the data by pushing it forward... */ - if (pad && GST_PAD_IS_USABLE (pad)) { - AVStream *stream = gst_ffmpegdemux_stream_from_pad (pad); + if (srcpad) { + AVStream *stream = gst_ffmpegdemux_stream_from_pad (srcpad); GstBuffer *outbuf; - outbuf = gst_buffer_new_and_alloc (pkt.size); - memcpy (GST_BUFFER_DATA (outbuf), pkt.data, pkt.size); - GST_BUFFER_SIZE (outbuf) = pkt.size; + ret = gst_pad_alloc_buffer_and_set_caps (srcpad, + GST_CLOCK_TIME_NONE, + pkt.size, + GST_PAD_CAPS (srcpad), + &outbuf); + if (ret != GST_FLOW_OK) { + pkt.destruct (&pkt); + memcpy (GST_BUFFER_DATA (outbuf), pkt.data, pkt.size); GST_BUFFER_TIMESTAMP (outbuf) = - gst_ffmpeg_time_ff_to_gst (pkt.pts, + gst_ffmpeg_time_ff_to_gst (pkt.pts, demux->context->streams[pkt.stream_index]->time_base); if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) demux->last_ts[stream->index] = GST_BUFFER_TIMESTAMP (outbuf); + if (!(pkt.flags & PKT_FLAG_KEY)) + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); - if (pkt.flags & PKT_FLAG_KEY) - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_KEY_UNIT); - else - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DELTA_UNIT); + - gst_pad_push (pad, GST_DATA (outbuf)); + GST_DEBUG_OBJECT (demux, "Sending out buffer time:%"GST_TIME_FORMAT" size:%d offset:%lld", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), + GST_BUFFER_SIZE (outbuf), + GST_BUFFER_OFFSET (outbuf)); + ret = gst_pad_push (srcpad, outbuf); + } else { + GST_WARNING_OBJECT (demux, "No pad from stream %d", + pkt.stream_index); pkt.destruct (&pkt); + return; + pause: + GST_LOG_OBJECT (demux, "pausing task"); + gst_pad_pause_task (demux->sinkpad); + if (GST_FLOW_IS_FATAL (ret)) { + int i; + GST_ELEMENT_ERROR (demux, STREAM, FAILED, + ("Internal data stream error."), + ("streaming stopped, reason %s", gst_flow_get_name (ret))); + for (i = 0; i < MAX_STREAMS; i++) + if (demux->srcpads[i]) + gst_pad_push_event (demux->srcpads[i], gst_event_new_eos()); +} +gst_ffmpegdemux_sink_activate (GstPad * sinkpad) +{ + if (gst_pad_check_pull_range (sinkpad)) + return gst_pad_activate_pull (sinkpad, TRUE); + return FALSE; +gst_ffmpegdemux_sink_activate_pull (GstPad * sinkpad, gboolean active) + if (active) { + /* if we have a scheduler we can start the task */ + gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop, sinkpad); + gst_pad_stop_task (sinkpad); gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition) GstFFMpegDemux *demux = (GstFFMpegDemux *) (element); + GstStateChangeReturn ret; + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: @@ -683,10 +869,7 @@ break; - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - return GST_STATE_CHANGE_SUCCESS; + return ret; gboolean @@ -763,8 +946,8 @@ /* if it's already registered, drop it */ if (g_type_from_name (type_name)) { - gst_caps_free (videosrccaps); - gst_caps_free (audiosrccaps); + gst_caps_unref (videosrccaps); + gst_caps_unref (audiosrccaps); g_free (type_name); goto next; @@ -795,7 +978,7 @@ if (!gst_element_register (plugin, type_name, rank, type) || (register_typefind_func == TRUE && !gst_type_find_register (plugin, typefind_name, rank, - gst_ffmpegdemux_type_find, extensions, sinkcaps, params))) { + gst_ffmpegdemux_type_find, extensions, sinkcaps, params, NULL))) { g_warning ("Register of type ffdemux_%s failed", name); g_free (typefind_name); Index: gstffmpegprotocol.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegprotocol.c,v retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- gstffmpegprotocol.c 6 Dec 2005 19:57:08 -0000 1.25 +++ gstffmpegprotocol.c 10 Feb 2006 19:42:19 -0000 1.26 * Copyright (C) <1999> Erik Walthinsen <om...@cs...> @@ -29,7 +30,6 @@ #endif #include <gst/gst.h> -#include <gst/bytestream/bytestream.h> #include "gstffmpeg.h" @@ -39,9 +39,9 @@ GstPad *pad; - GstByteStream *bs; + guint64 offset; gboolean eos; - gboolean set_streamheader; + gint set_streamheader; static int @@ -60,12 +60,12 @@ /* we don't support R/W together */ if (flags != URL_RDONLY && flags != URL_WRONLY) { - g_warning ("Only read-only or write-only are supported"); + GST_WARNING ("Only read-only or write-only are supported"); return -EINVAL; if (sscanf (&filename[12], "%p", &pad) != 1) { - g_warning ("could not decode pad from %s", filename); + GST_WARNING ("could not decode pad from %s", filename); return -EIO; @@ -75,16 +75,15 @@ switch (flags) { case URL_RDONLY: g_return_val_if_fail (GST_PAD_IS_SINK (pad), -EINVAL); - info->bs = gst_bytestream_new (pad); case URL_WRONLY: g_return_val_if_fail (GST_PAD_IS_SRC (pad), -EINVAL); - info->bs = NULL; info->eos = FALSE; info->pad = pad; + info->offset = 0; h->priv_data = (void *) info; h->is_streamed = FALSE; @@ -96,79 +95,20 @@ gst_ffmpegdata_peek (URLContext * h, unsigned char *buf, int size) - guint32 total, request; - guint8 *data; GstProtocolInfo *info; - gboolean have_event, will_get_eos; - info = (GstProtocolInfo *) h->priv_data; + GstBuffer *inbuf = NULL; + int total; g_return_val_if_fail (h->flags == URL_RDONLY, AVERROR_IO); + info = (GstProtocolInfo *) h->priv_data; - bs = info->bs; - if (info->eos) - return 0; - do { - have_event = FALSE, will_get_eos = FALSE; - /* prevent EOS */ - if (gst_bytestream_tell (bs) + size >= gst_bytestream_length (bs)) { - request = (int) (gst_bytestream_length (bs) - gst_bytestream_tell (bs)); - will_get_eos = TRUE; - request = size; - } - if (request > 0) { - total = gst_bytestream_peek_bytes (bs, &data, request); - total = 0; - if (total < request) { - GstEvent *event; - guint32 remaining; - gst_bytestream_get_status (bs, &remaining, &event); - if (!event) { - g_warning ("gstffmpegprotocol: no bytestream event"); - return total; - GST_LOG ("Reading (req %d, got %d) gave event of type %d", - request, total, GST_EVENT_TYPE (event)); - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_DISCONTINUOUS: - gst_event_unref (event); - case GST_EVENT_EOS: - g_warning ("Unexpected/unwanted eos in data function"); - info->eos = TRUE; - have_event = TRUE; - case GST_EVENT_FLUSH: - case GST_EVENT_INTERRUPT: - gst_pad_event_default (info->pad, event); - GST_DEBUG ("got data (%d bytes)", request); - if (will_get_eos) - info->eos = TRUE; - } while ((!info->eos && total != request) && !have_event); - memcpy (buf, data, total); + if (gst_pad_pull_range(info->pad, info->offset, (guint) size, &inbuf) != GST_FLOW_OK) { + total = 0; + total = (gint) GST_BUFFER_SIZE (inbuf); + memcpy (buf, GST_BUFFER_DATA (inbuf), total); + gst_buffer_unref (inbuf); return total; @@ -177,17 +117,14 @@ gst_ffmpegdata_read (URLContext * h, unsigned char *buf, int size) - GST_DEBUG ("Reading %d bytes of data", size); info = (GstProtocolInfo *) h->priv_data; - res = gst_ffmpegdata_peek (h, buf, size); - if (res > 0) { - gst_bytestream_flush_fast (bs, res); + GST_DEBUG ("Reading %d bytes of data at position %lld", size, info->offset); + res = gst_ffmpegdata_peek(h, buf, size); + info->offset += res; GST_DEBUG ("Returning %d bytes", res); @@ -206,37 +143,18 @@ g_return_val_if_fail (h->flags != URL_RDONLY, -EIO); /* create buffer and push data further */ - outbuf = gst_buffer_new_and_alloc (size); - GST_BUFFER_SIZE (outbuf) = size; + if (gst_pad_alloc_buffer_and_set_caps(info->pad, + info->offset, + size, GST_PAD_CAPS (info->pad), + &outbuf) != GST_FLOW_OK) + return 0; memcpy (GST_BUFFER_DATA (outbuf), buf, size); - if (info->set_streamheader) { - GstCaps *caps = gst_pad_get_caps (info->pad); - GstStructure *structure = gst_caps_get_structure (caps, 0); - GValue list = { 0 }, value = { 0 }; - GST_DEBUG ("Using buffer (size %i) as streamheader", size); - g_value_init (&list, GST_TYPE_FIXED_LIST); - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_IN_CAPS); - - g_value_init (&value, GST_TYPE_BUFFER); - g_value_set_boxed (&value, outbuf); - gst_value_list_append_value (&list, &value); - g_value_unset (&value); - gst_structure_set_value (structure, "streamheader", &list); - g_value_unset (&list); - gst_pad_try_set_caps (info->pad, caps); - /* only set the first buffer */ - info->set_streamheader = FALSE; - - gst_pad_push (info->pad, GST_DATA (outbuf)); + if (gst_pad_push(info->pad, outbuf) != GST_FLOW_OK) + info->offset += size; return size; @@ -251,103 +169,39 @@ - if (h->flags == URL_RDONLY) { - /* get data (typefind hack) */ - if (gst_bytestream_tell (info->bs) != gst_bytestream_length (info->bs)) { - gchar buf; - gst_ffmpegdata_peek (h, &buf, 1); - /* hack in ffmpeg to get filesize... */ - if (whence == SEEK_END && pos == -1) - return gst_bytestream_length (info->bs) - 1; - else if (whence == SEEK_END && pos == 0) - return gst_bytestream_length (info->bs); - /* another hack to get the current position... */ - else if (whence == SEEK_CUR && pos == 0) - return gst_bytestream_tell (info->bs); - switch (whence) { - case SEEK_SET: - seek_type = GST_SEEK_METHOD_SET; - case SEEK_CUR: - seek_type = GST_SEEK_METHOD_CUR; - case SEEK_END: - seek_type = GST_SEEK_METHOD_END; - g_assert (0); switch (h->flags) { - case URL_RDONLY: { - guint8 *data; - /* handle discont */ - gst_bytestream_seek (info->bs, pos, seek_type); - /* prevent eos */ - if (gst_bytestream_tell (info->bs) == - gst_bytestream_length (info->bs)) { - break; - info->eos = FALSE; - while (gst_bytestream_peek_bytes (info->bs, &data, 1) == 0) { - gst_bytestream_get_status (info->bs, &remaining, &event); - if (!event) { - g_warning ("no data, no event - panic!"); - return -1; - } - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - g_warning ("unexpected/unwanted EOS event after seek"); - info->eos = TRUE; - gst_event_unref (event); - return -1; - case GST_EVENT_DISCONTINUOUS: - gst_event_unref (event); /* we expect this */ - case GST_EVENT_FLUSH: - case GST_EVENT_INTERRUPT: - default: - gst_pad_event_default (info->pad, event); + case URL_RDONLY: + /* sinkpad */ + switch (whence) { + case SEEK_SET: + info->offset = (guint64) pos; + case SEEK_CUR: + info->offset += pos; + case SEEK_END: + GST_WARNING ("Can't handle SEEK_END yet"); - newpos = gst_bytestream_tell (info->bs); + /* FIXME : implement case for push-based behaviour */ + newpos = info->offset; - case URL_WRONLY: - gst_pad_push (info->pad, - GST_DATA (gst_event_new_seek (seek_type | GST_FORMAT_BYTES, pos))); - /* this is screwy because there might be queues or scheduler-queued - * buffers... Argh! */ - if (whence == SEEK_SET) { - newpos = pos; - } else { - g_warning ("Writer reposition: implement me\n"); - newpos = 0; + case URL_WRONLY: + /* srcpad */ + /* FIXME : implement */ + g_assert(0); + GST_DEBUG ("Now at offset %lld", info->offset); return newpos; @@ -361,20 +215,15 @@ GST_LOG ("Closing file"); - case URL_WRONLY:{ - /* send EOS - that closes down the stream */ - GstEvent *event = gst_event_new (GST_EVENT_EOS); - gst_pad_push (info->pad, GST_DATA (event)); - case URL_RDONLY: - /* unref bytestream */ - gst_bytestream_destroy (info->bs); + case URL_WRONLY:{ + /* send EOS - that closes down the stream */ + gst_pad_push_event (info->pad, gst_event_new_eos()); /* clean up data */ g_free (info); |
From: <bi...@fr...> - 2006-02-12 16:51:16
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Sun Feb 12 2006 08:48:03 PST Log message: * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_init), (gst_ffmpegdemux_close), (gst_ffmpegdemux_handle_seek), (gst_ffmpegdemux_add), (my_safe_copy), (gst_ffmpegdemux_read_tags), (gst_ffmpegdemux_open), (gst_ffmpegdemux_loop): Add Tag support and keyframe seeking (for those formats where ffmpeg actually fills in the index). * ext/ffmpeg/gstffmpegprotocol.c: (gst_ffmpegdata_peek), (gst_ffmpegdata_read), (gst_ffmpegdata_seek): Add support for size querying. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdemux.c gstffmpegprotocol.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.257&r2=1.258 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdemux.c.diff?r1=1.51&r2=1.52 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegprotocol.c.diff?r1=1.26&r2=1.27 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.257 retrieving revision 1.258 diff -u -d -r1.257 -r1.258 --- ChangeLog 11 Feb 2006 22:16:42 -0000 1.257 +++ ChangeLog 12 Feb 2006 16:47:50 -0000 1.258 @@ -1,3 +1,15 @@ +2006-02-12 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_init), + (gst_ffmpegdemux_close), (gst_ffmpegdemux_handle_seek), + (gst_ffmpegdemux_add), (my_safe_copy), (gst_ffmpegdemux_read_tags), + (gst_ffmpegdemux_open), (gst_ffmpegdemux_loop): + Add Tag support and keyframe seeking (for those formats where ffmpeg + actually fills in the index). + * ext/ffmpeg/gstffmpegprotocol.c: (gst_ffmpegdata_peek), + (gst_ffmpegdata_read), (gst_ffmpegdata_seek): + Add support for size querying. 2006-02-11 Thomas Vander Stichele <thomas at apestaart dot org> * ext/ffmpeg/gstffmpeg.c: Index: gstffmpegdemux.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdemux.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -d -r1.51 -r1.52 --- gstffmpegdemux.c 10 Feb 2006 19:42:19 -0000 1.51 +++ gstffmpegdemux.c 12 Feb 2006 16:47:50 -0000 1.52 @@ -53,6 +53,12 @@ guint64 last_ts[MAX_STREAMS]; gint videopads, audiopads; + /* Id of the first video stream */ + gint videostreamid; + /* time of the first media frame */ + gint64 timeoffset; /* segment stuff */ /* TODO : replace with GstSegment */ gdouble segment_rate; @@ -60,7 +66,9 @@ /* GST_FORMAT_TIME */ gint64 segment_start; gint64 segment_stop; GstEvent *seek_event; + gint64 seek_start; }; typedef struct _GstFFMpegDemuxClassParams @@ -220,11 +228,15 @@ demux->videopads = 0; demux->audiopads = 0; + demux->videostreamid = -1; + demux->timeoffset = 0; demux->segment_rate = 1.0; demux->segment_flags = 0; demux->segment_start = -1; demux->segment_stop = -1; demux->seek_event = NULL; + demux->seek_start = 0; } static void @@ -247,6 +259,16 @@ + demux->segment_rate = 1.0; + demux->segment_flags = 0; + demux->segment_start = -1; + demux->segment_stop = -1; + demux->seek_event = NULL; /* close demuxer context from ffmpeg */ av_close_input_file (demux->context); demux->context = NULL; @@ -284,16 +306,47 @@ keyframe = demux->segment_flags & GST_SEEK_FLAG_KEY_UNIT; if (flush) { + GST_LOG_OBJECT (demux, "sending flush_start"); for (stream = 0; stream < demux->context->nb_streams; stream++) { gst_pad_push_event (demux->srcpads[stream], gst_event_new_flush_start()); } gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ()); - } else + } else { + GST_LOG_OBJECT (demux, "pausing task"); gst_pad_pause_task (demux->sinkpad); + } GST_PAD_STREAM_LOCK (demux->sinkpad); + GST_DEBUG_OBJECT (demux, "after PAD_STREAM_LOCK"); + /* by default, the seek position is the segment_start */ + demux->seek_start = demux->segment_start; + /* if index is available, find previous keyframe */ + if ((demux->videostreamid != -1) && (demux->context->index_built)) { + gint keyframeidx; + GST_LOG_OBJECT (demux, "looking for keyframe in ffmpeg for time %lld", + demux->segment_start / (GST_SECOND / AV_TIME_BASE)); + keyframeidx = av_index_search_timestamp + (demux->context->streams[demux->videostreamid], + demux->segment_start / (GST_SECOND / AV_TIME_BASE), + AVSEEK_FLAG_BACKWARD); + GST_LOG_OBJECT (demux, "keyframeidx:%d", keyframeidx); + if (keyframeidx >= 0) { + gint64 idxtimestamp = demux->context->streams[demux->videostreamid]->index_entries[keyframeidx].timestamp; + GST_LOG_OBJECT (demux, "Found a keyframe at ffmpeg idx:%d timestamp :%lld", + keyframeidx, idxtimestamp); + demux->seek_start = idxtimestamp * (GST_SECOND / AV_TIME_BASE); + } + GST_LOG_OBJECT (demux, "no videostream or index not built"); + if (keyframe) + demux->segment_start = demux->seek_start; GST_DEBUG_OBJECT (demux, "Creating new segment (%"GST_TIME_FORMAT" / %"GST_TIME_FORMAT, GST_TIME_ARGS (demux->segment_start), GST_TIME_ARGS (demux->segment_stop)); @@ -568,6 +621,7 @@ case CODEC_TYPE_VIDEO: templ = oclass->videosrctempl; num = demux->videopads++; + demux->videostreamid = stream->index; break; case CODEC_TYPE_AUDIO: templ = oclass->audiosrctempl; @@ -614,6 +668,92 @@ return TRUE; +static gchar * +my_safe_copy (gchar * input) +{ + gchar * output; + if (!(g_utf8_validate (input, -1, NULL))) { + output = g_convert (input, strlen(input), + "UTF-8", "ISO-8859-1", + NULL, NULL, NULL); + output = g_strdup (input); +} +static GstTagList * +gst_ffmpegdemux_read_tags (GstFFMpegDemux * demux) + GstTagList *tlist; + gboolean hastag = FALSE; + tlist = gst_tag_list_new (); + if (*demux->context->title) { + gst_tag_list_add (tlist, GST_TAG_MERGE_REPLACE, + GST_TAG_TITLE, + my_safe_copy (demux->context->title), + NULL); + hastag = TRUE; + if (*demux->context->author) { + GST_TAG_ARTIST, + my_safe_copy (demux->context->author), + if (*demux->context->copyright) { + GST_TAG_COPYRIGHT, + my_safe_copy (demux->context->copyright), + if (*demux->context->comment) { + GST_TAG_COMMENT, + my_safe_copy (demux->context->comment), + if (*demux->context->album) { + GST_TAG_ALBUM, + my_safe_copy (demux->context->album), + if (demux->context->track) { + GST_TAG_TRACK_NUMBER, + demux->context->track, + if (*demux->context->genre) { + GST_TAG_GENRE, + my_safe_copy (demux->context->genre), + hastag = TRUE; + if (demux->context->year) { + GST_TAG_DATE, + g_date_new_dmy(1, 1, demux->context->year), + if (!hastag) { + gst_tag_list_free (tlist); + tlist = NULL; + return tlist; static gboolean gst_ffmpegdemux_open (GstFFMpegDemux * demux) { @@ -621,6 +761,7 @@ (GstFFMpegDemuxClass *) G_OBJECT_GET_CLASS (demux); gchar *location; gint res; + GstTagList *tags; /* to be sure... */ gst_ffmpegdemux_close (demux); @@ -648,6 +789,36 @@ demux->handled[res] = TRUE; } + gst_element_no_more_pads (GST_ELEMENT (demux)); + + /* grab the tags */ + tags = gst_ffmpegdemux_read_tags(demux); + if (tags) { + gst_element_post_message (GST_ELEMENT (demux), + gst_message_new_tag (GST_OBJECT (demux), + tags)); + /* remember initial start position and shift start/stop */ + demux->timeoffset = demux->context->start_time * (GST_SECOND / AV_TIME_BASE ); + demux->segment_start = 0; + demux->segment_stop = demux->context->duration * (GST_SECOND / AV_TIME_BASE ); + /* Send newsegment on all src pads */ + for (res = 0; res < demux->context->nb_streams; res++) { + AVStream *stream; + + GST_DEBUG_OBJECT (demux, "sending newsegment start:%"GST_TIME_FORMAT" duration:%"GST_TIME_FORMAT, + GST_TIME_ARGS (demux->segment_start), + GST_TIME_ARGS (demux->segment_stop)); + gst_pad_push_event(demux->srcpads[res], + gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, + demux->segment_start, demux->segment_stop, + demux->segment_start)); demux->opened = TRUE; @@ -694,52 +865,20 @@ ret = GST_FLOW_ERROR; goto pause; - gst_element_no_more_pads (GST_ELEMENT (demux)); - - /* Calculate min start and maximum end */ - for (res = 0; res < demux->context->nb_streams; res++) { - gint64 start_time, duration, end; - AVStream *stream; - - stream = demux->context->streams[res]; - start_time = gst_ffmpeg_time_ff_to_gst (stream->start_time, stream->time_base); - duration = gst_ffmpeg_time_ff_to_gst (stream->duration, stream->time_base); - if (start_time == GST_CLOCK_TIME_NONE) - start_time = 0; - if (duration == GST_CLOCK_TIME_NONE) - end = GST_CLOCK_TIME_NONE; - else - end = start_time + duration; - if ((start_time < demux->segment_start) || (demux->segment_start == -1)) - demux->segment_start = start_time; - if ((end > demux->segment_stop) || (demux->segment_stop == -1)) - demux->segment_stop = end; - } - /* Send newsegment on all src pads */ - GST_DEBUG_OBJECT (demux, "sending newsegment start:%"GST_TIME_FORMAT" duration:%"GST_TIME_FORMAT, - GST_TIME_ARGS (demux->segment_start), - GST_TIME_ARGS (demux->segment_stop)); - gst_pad_push_event(demux->srcpads[res], - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, - demux->segment_start, demux->segment_stop, - demux->segment_start)); - } + /* pending seek */ if (demux->seek_event) { - /* pending seek */ - GST_DEBUG_OBJECT (demux, "About to call av_seek_frame (context, -1, %lld, 0)", - gst_ffmpeg_time_gst_to_ff (demux->segment_start, demux->context->streams[0]->time_base)); - if ((av_seek_frame (demux->context, -1, - gst_ffmpeg_time_gst_to_ff (demux->segment_start, demux->context->streams[0]->time_base), 0)) < 0) { - GST_WARNING_OBJECT (demux, "Call to av_seek_frame failed"); + gint seekret; + GST_DEBUG_OBJECT (demux, "About to call av_seek_frame (context, %d, %lld, 0) for time %"GST_TIME_FORMAT, + -1, + gst_ffmpeg_time_gst_to_ff (demux->seek_start + demux->timeoffset, demux->context->streams[0]->time_base), + GST_TIME_ARGS (demux->seek_start + demux->timeoffset)); + if (((seekret = av_seek_frame + (demux->context, -1, + gst_ffmpeg_time_gst_to_ff (demux->seek_start + demux->timeoffset, demux->context->streams[0]->time_base), 0))) < 0) { + GST_WARNING_OBJECT (demux, "Call to av_seek_frame failed : %d", seekret); @@ -795,7 +934,7 @@ memcpy (GST_BUFFER_DATA (outbuf), pkt.data, pkt.size); GST_BUFFER_TIMESTAMP (outbuf) = gst_ffmpeg_time_ff_to_gst (pkt.pts, - demux->context->streams[pkt.stream_index]->time_base); + demux->context->streams[pkt.stream_index]->time_base) - demux->timeoffset; if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) demux->last_ts[stream->index] = GST_BUFFER_TIMESTAMP (outbuf); if (!(pkt.flags & PKT_FLAG_KEY)) @@ -814,7 +953,7 @@ GST_WARNING_OBJECT (demux, "No pad from stream %d", pkt.stream_index); pkt.destruct (&pkt); return; Index: gstffmpegprotocol.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegprotocol.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- gstffmpegprotocol.c 10 Feb 2006 19:42:19 -0000 1.26 +++ gstffmpegprotocol.c 12 Feb 2006 16:47:50 -0000 1.27 @@ -97,17 +97,22 @@ GstProtocolInfo *info; GstBuffer *inbuf = NULL; - int total; + GstFlowReturn ret; + int total = 0; g_return_val_if_fail (h->flags == URL_RDONLY, AVERROR_IO); info = (GstProtocolInfo *) h->priv_data; - if (gst_pad_pull_range(info->pad, info->offset, (guint) size, &inbuf) != GST_FLOW_OK) { - total = 0; + ret = gst_pad_pull_range(info->pad, info->offset, (guint) size, &inbuf); + if ((ret == GST_FLOW_OK) || (ret == GST_FLOW_UNEXPECTED)) { + if (inbuf) { + total = (gint) GST_BUFFER_SIZE (inbuf); + memcpy (buf, GST_BUFFER_DATA (inbuf), total); + gst_buffer_unref (inbuf); } else { - total = (gint) GST_BUFFER_SIZE (inbuf); - memcpy (buf, GST_BUFFER_DATA (inbuf), total); - gst_buffer_unref (inbuf); + return -1; return total; @@ -124,7 +129,8 @@ GST_DEBUG ("Reading %d bytes of data at position %lld", size, info->offset); res = gst_ffmpegdata_peek(h, buf, size); - info->offset += res; + if (res >= 0) + info->offset += res; GST_DEBUG ("Returning %d bytes", res); @@ -169,6 +175,8 @@ + /* TODO : if we are push-based, we need to return sensible info */ switch (h->flags) { case URL_RDONLY: { @@ -181,7 +189,16 @@ info->offset += pos; break; case SEEK_END: - GST_WARNING ("Can't handle SEEK_END yet"); + /* ffmpeg wants to know the current end position in bytes ! */ + { + GstFormat format = GST_FORMAT_BYTES; + gint64 duration; + + if (gst_pad_is_linked (info->pad)) + if (gst_pad_query_duration (GST_PAD_PEER (info->pad), &format, &duration)) + info->offset = ((guint64) duration) + pos; + } + break; default: } |
From: <bi...@fr...> - 2006-02-13 16:05:14
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Mon Feb 13 2006 08:02:02 PST Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_release_buffer), (gst_ffmpegdec_frame): More fixes for keyframe detection in ffmpeg decoders... Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.259&r2=1.260 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.139&r2=1.140 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.259 retrieving revision 1.260 diff -u -d -r1.259 -r1.260 --- ChangeLog 12 Feb 2006 19:54:16 -0000 1.259 +++ ChangeLog 13 Feb 2006 16:01:49 -0000 1.260 @@ -1,3 +1,9 @@ +2006-02-13 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_release_buffer), + (gst_ffmpegdec_frame): + More fixes for keyframe detection in ffmpeg decoders... 2006-02-12 Thomas Vander Stichele <thomas at apestaart dot org> * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_caps_to_pixfmt): Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.139 retrieving revision 1.140 diff -u -d -r1.139 -r1.140 --- gstffmpegdec.c 6 Feb 2006 17:51:41 -0000 1.139 +++ gstffmpegdec.c 13 Feb 2006 16:01:50 -0000 1.140 @@ -623,11 +623,12 @@ GstBuffer *buf; GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) context->opaque; - g_return_if_fail (buf != NULL); g_return_if_fail (picture->type == FF_BUFFER_TYPE_USER); buf = GST_BUFFER (picture->opaque); + g_return_if_fail (buf != NULL); if (buf == ffmpegdec->last_buffer) ffmpegdec->last_buffer = NULL; gst_buffer_unref (buf); @@ -821,11 +822,12 @@ ffmpegdec->picture, &have_data, data, size); is_itype = (ffmpegdec->picture->pict_type == FF_I_TYPE); is_reference = (ffmpegdec->picture->reference == 1); - iskeyframe = (is_itype || is_reference) + iskeyframe = (is_itype || is_reference || ffmpegdec->picture->key_frame) || (oclass->in_plugin->id == CODEC_ID_INDEO3) || (oclass->in_plugin->id == CODEC_ID_MSZH) || (oclass->in_plugin->id == CODEC_ID_ZLIB) - || (oclass->in_plugin->id == CODEC_ID_VP3); + || (oclass->in_plugin->id == CODEC_ID_VP3) + || (oclass->in_plugin->id == CODEC_ID_HUFFYUV); GST_LOG_OBJECT (ffmpegdec, "Decoded video: len=%d, have_data=%d, " "is_keyframe:%d, is_itype:%d, is_reference:%d", |
From: <bi...@fr...> - 2006-02-14 17:16:38
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Tue Feb 14 2006 09:13:23 PST Log message: * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_open): If the duration returned by ffmpeg is 0, it doesn't mean the file has no duration, but that it doesn't know the end. Fixed accordingly for segment_stop. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.260&r2=1.261 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdemux.c.diff?r1=1.52&r2=1.53 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.260 retrieving revision 1.261 diff -u -d -r1.260 -r1.261 --- ChangeLog 13 Feb 2006 16:01:49 -0000 1.260 +++ ChangeLog 14 Feb 2006 17:13:11 -0000 1.261 @@ -1,3 +1,10 @@ +2006-02-14 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_open): + If the duration returned by ffmpeg is 0, it doesn't mean the file has + no duration, but that it doesn't know the end. + Fixed accordingly for segment_stop. 2006-02-13 Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_release_buffer), Index: gstffmpegdemux.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdemux.c,v retrieving revision 1.52 retrieving revision 1.53 diff -u -d -r1.52 -r1.53 --- gstffmpegdemux.c 12 Feb 2006 16:47:50 -0000 1.52 +++ gstffmpegdemux.c 14 Feb 2006 17:13:11 -0000 1.53 @@ -803,7 +803,10 @@ /* remember initial start position and shift start/stop */ demux->timeoffset = demux->context->start_time * (GST_SECOND / AV_TIME_BASE ); demux->segment_start = 0; - demux->segment_stop = demux->context->duration * (GST_SECOND / AV_TIME_BASE ); + if (demux->context->duration > 0) + demux->segment_stop = demux->context->duration * (GST_SECOND / AV_TIME_BASE ); + else + demux->segment_stop = GST_CLOCK_TIME_NONE; /* Send newsegment on all src pads */ for (res = 0; res < demux->context->nb_streams; res++) { |
From: <bi...@ke...> - 2006-02-21 14:14:58
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Tue Feb 21 2006 14:14:51 UTC Log message: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_formatid_to_caps): Added proper formatid to caps conversion for ogg, gif, yuv4mpeg and quicktime formats. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.267&r2=1.268 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.111&r2=1.112 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.267 retrieving revision 1.268 diff -u -d -r1.267 -r1.268 --- ChangeLog 21 Feb 2006 11:30:10 -0000 1.267 +++ ChangeLog 21 Feb 2006 14:14:39 -0000 1.268 @@ -1,3 +1,10 @@ +2006-02-21 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), + (gst_ffmpeg_formatid_to_caps): + Added proper formatid to caps conversion for ogg, gif, yuv4mpeg and + quicktime formats. 2006-02-21 Jan Schmidt <th...@ma...> * configure.ac: Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.111 retrieving revision 1.112 diff -u -d -r1.111 -r1.112 --- gstffmpegcodecmap.c 19 Feb 2006 22:40:16 -0000 1.111 +++ gstffmpegcodecmap.c 21 Feb 2006 14:14:39 -0000 1.112 @@ -845,6 +845,9 @@ (codec = avcodec_find_encoder (codec_id))) { gchar *mime = NULL; + GST_WARNING ("Could not create stream format caps for %s", + codec->name); + switch (codec->type) { case CODEC_TYPE_VIDEO: mime = g_strdup_printf ("video/x-gst_ff-%s", codec->name); @@ -1485,8 +1488,6 @@ caps = gst_caps_new_simple ("application/x-shockwave-flash", NULL); } else if (!strcmp (format_name, "au")) { caps = gst_caps_new_simple ("audio/x-au", NULL); - } else if (!strcmp (format_name, "mov_mp4_m4a_3gp")) { - caps = gst_caps_new_simple ("video/quicktime", NULL); } else if (!strcmp (format_name, "dv")) { caps = gst_caps_new_simple ("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE, NULL); @@ -1507,6 +1508,18 @@ } else if (!strcmp (format_name, "mov_mp4_m4a_3gp_3g2")) { caps = gst_caps_from_string ( "application/x-3gp; video/quicktime; audio/x-m4a"); + } else if (!strcmp (format_name, "aac")) { + caps = gst_caps_new_simple ("audio/mpeg", + "mpegversion", G_TYPE_INT, 4, + NULL); + } else if (!strcmp (format_name, "gif")) { + caps = gst_caps_from_string ("image/gif"); + } else if (!strcmp (format_name, "ogg")) { + caps = gst_caps_from_string ("application/ogg"); + } else if (!strcmp (format_name, "yuv4mpegpipe")) { + caps = gst_caps_new_simple ("application/x-yuv4mpeg", + "y4mversion", G_TYPE_INT, 1, } else { gchar *name; |
From: <bi...@ke...> - 2006-03-01 15:05:20
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Wed Mar 01 2006 15:05:15 UTC Log message: Reviewed by : Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_chain_audio): Fix segmentation fault and memleak. Fixes #332995 and #333001 Modified files: . : ChangeLog ext/ffmpeg : gstffmpegenc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.271&r2=1.272 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegenc.c.diff?r1=1.85&r2=1.86 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.271 retrieving revision 1.272 diff -u -d -r1.271 -r1.272 --- ChangeLog 24 Feb 2006 19:19:01 -0000 1.271 +++ ChangeLog 1 Mar 2006 15:05:03 -0000 1.272 @@ -1,3 +1,11 @@ +2006-03-01 Josef Zlomek <josef dot zlomek at itonis dot tv> + + Reviewed by : Edward Hervey <ed...@fl...> + * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_chain_audio): + Fix segmentation fault and memleak. + Fixes #332995 and #333001 2006-02-24 Tim-Philipp Müller <tim at centricular dot net> * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame): Index: gstffmpegenc.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegenc.c,v retrieving revision 1.85 retrieving revision 1.86 diff -u -d -r1.85 -r1.86 --- gstffmpegenc.c 12 Feb 2006 19:54:16 -0000 1.85 +++ gstffmpegenc.c 1 Mar 2006 15:05:03 -0000 1.86 @@ -578,8 +578,7 @@ if (in_size > size) { /* this is panic! we got a buffer, but still don't have enough * data. Merge them and retry in the next cycle... */ - ffmpegenc->cache = gst_buffer_span (ffmpegenc->cache, 0, inbuf, - GST_BUFFER_SIZE (ffmpegenc->cache) + GST_BUFFER_SIZE (inbuf)); + ffmpegenc->cache = gst_buffer_join (ffmpegenc->cache, inbuf); } else if (in_size == size) { /* exactly the same! how wonderful */ ffmpegenc->cache = inbuf; @@ -605,8 +604,7 @@ subbuf = gst_buffer_create_sub (inbuf, 0, frame_size - (in_size - size)); GST_BUFFER_DURATION (subbuf) = GST_BUFFER_DURATION (inbuf) * GST_BUFFER_SIZE (subbuf) / size; - subbuf = gst_buffer_span (ffmpegenc->cache, 0, subbuf, - GST_BUFFER_SIZE (ffmpegenc->cache) + GST_BUFFER_SIZE (subbuf)); + subbuf = gst_buffer_join (ffmpegenc->cache, subbuf); ffmpegenc->cache = NULL; } else { subbuf = gst_buffer_create_sub (inbuf, size - in_size, frame_size); @@ -617,7 +615,7 @@ (size - in_size) / size); } - outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf)); + outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (subbuf)); ret_size = avcodec_encode_audio (ffmpegenc->context, GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf), (const short int *) |
From: <bi...@ke...> - 2006-03-01 15:08:23
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Wed Mar 01 2006 15:08:20 UTC Log message: Reviewed by : Edward Hervey <ed...@fl...> * ext/ffmpeg/Makefile.am: * ext/ffmpeg/gstffmpeg.c: (plugin_init): * ext/ffmpeg/gstffmpegscale.c: (gst_ffmpegscale_base_init), (gst_ffmpegscale_class_init), (gst_ffmpegscale_init), (gst_ffmpegscale_finalize), (gst_ffmpegscale_transform_caps), (gst_ffmpegscale_fixate_caps), (gst_ffmpegscale_get_unit_size), (gst_ffmpegscale_set_caps), (gst_ffmpegscale_transform), (gst_ffmpegscale_handle_src_event), (gst_ffmpegscale_register): Port of ffvideoscale to 0.10. Closes #332557 Modified files: . : ChangeLog ext/ffmpeg : Makefile.am gstffmpeg.c gstffmpegscale.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.272&r2=1.273 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am.diff?r1=1.25&r2=1.26 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c.diff?r1=1.31&r2=1.32 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegscale.c.diff?r1=1.7&r2=1.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.272 retrieving revision 1.273 diff -u -d -r1.272 -r1.273 --- ChangeLog 1 Mar 2006 15:05:03 -0000 1.272 +++ ChangeLog 1 Mar 2006 15:08:08 -0000 1.273 @@ -1,3 +1,18 @@ +2006-03-01 Michal Benes <michal dot benes at xeris dot cz> + + Reviewed by : Edward Hervey <ed...@fl...> + * ext/ffmpeg/Makefile.am: + * ext/ffmpeg/gstffmpeg.c: (plugin_init): + * ext/ffmpeg/gstffmpegscale.c: (gst_ffmpegscale_base_init), + (gst_ffmpegscale_class_init), (gst_ffmpegscale_init), + (gst_ffmpegscale_finalize), (gst_ffmpegscale_transform_caps), + (gst_ffmpegscale_fixate_caps), (gst_ffmpegscale_get_unit_size), + (gst_ffmpegscale_set_caps), (gst_ffmpegscale_transform), + (gst_ffmpegscale_handle_src_event), (gst_ffmpegscale_register): + Port of ffvideoscale to 0.10. + Closes #332557 2006-03-01 Josef Zlomek <josef dot zlomek at itonis dot tv> Reviewed by : Edward Hervey <ed...@fl...> Index: Makefile.am RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- Makefile.am 10 Feb 2006 19:42:19 -0000 1.25 +++ Makefile.am 1 Mar 2006 15:08:08 -0000 1.26 @@ -1,14 +1,14 @@ plugin_LTLIBRARIES = libgstffmpeg.la -libgstffmpeg_la_SOURCES = gstffmpeg.c \ +libgstffmpeg_la_SOURCES = gstffmpeg.c \ + gstffmpegprotocol.c \ gstffmpegcodecmap.c \ - gstffmpegdec.c \ gstffmpegenc.c \ - gstffmpegdeinterlace.c \ + gstffmpegdec.c \ gstffmpegdemux.c \ - gstffmpegprotocol.c -# gstffmpegmux.c \ -# gstffmpegscale.c + gstffmpegdeinterlace.c \ + gstffmpegscale.c +# gstffmpegmux.c libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \ @@ -16,7 +16,7 @@ -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavcodec libgstffmpeg_la_LIBADD = \ $(top_builddir)/gst-libs/ext/ffmpeg/libavformat/libavformat.la \ - $(GST_LIBS) + $(GST_BASE_LIBS) libgstffmpeg_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) noinst_HEADERS = \ Index: gstffmpeg.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- gstffmpeg.c 11 Feb 2006 22:16:43 -0000 1.31 +++ gstffmpeg.c 1 Mar 2006 15:08:08 -0000 1.32 @@ -109,12 +109,12 @@ gst_ffmpegenc_register (plugin); gst_ffmpegdec_register (plugin); - gst_ffmpegdeinterlace_register (plugin); gst_ffmpegdemux_register (plugin); + gst_ffmpegdeinterlace_register (plugin); + gst_ffmpegscale_register (plugin); #if 0 gst_ffmpegmux_register (plugin); gst_ffmpegcsp_register (plugin); - gst_ffmpegscale_register (plugin); #endif register_protocol (&gstreamer_protocol); Index: gstffmpegscale.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegscale.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gstffmpegscale.c 6 Dec 2005 19:57:08 -0000 1.7 +++ gstffmpegscale.c 1 Mar 2006 15:08:08 -0000 1.8 @@ -2,6 +2,7 @@ * Copyright (C) <1999> Erik Walthinsen <om...@cs...> * This file: * Copyright (C) 2005 Luca Ognibene <lu...@ti...> + * Copyright (C) 2006 Martin Zlomek <mar...@it...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,428 +24,379 @@ #include "config.h" -#include <gst/gst.h> #ifdef HAVE_FFMPEG_UNINSTALLED #include <avcodec.h> #else #include <ffmpeg/avcodec.h> +#include <gst/gst.h> +#include <gst/base/gstbasetransform.h> #include <gst/video/video.h> #include "gstffmpeg.h" #include "gstffmpegcodecmap.h" -#define GST_TYPE_FFMPEGSCALE \ - (gst_ffmpegscale_get_type()) -#define GST_FFMPEGSCALE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGSCALE,GstFFMpegScale)) -#define GST_FFMPEGSCALE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGSCALE,GstFFMpegScale)) -#define GST_IS_FFMPEGSCALE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGSCALE)) -#define GST_IS_FFMPEGSCALE_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGSCALE)) - -typedef struct _GstFFMpegScale GstFFMpegScale; -typedef struct _GstFFMpegScaleClass GstFFMpegScaleClass; -struct _GstFFMpegScale +typedef struct _GstFFMpegScale { - GstElement element; + GstBaseTransform element; GstPad *sinkpad, *srcpad; - gint from_width, from_height; - gint to_width, to_height; + gint in_width, in_height; + gint out_width, out_height; enum PixelFormat pixfmt; - AVPicture from_frame, to_frame; - GstCaps *sinkcaps; - - guint to_size; ImgReSampleContext *res; +} GstFFMpegScale; - gboolean passthru; -}; -struct _GstFFMpegScaleClass -{ - GstElementClass parent_class; -/* elementfactory information */ -static GstElementDetails ffmpegscale_details = { - "FFMPEG Scale element", - "Filter/Converter/Video", - "Converts video from one resolution to another", - "Luca Ognibene <lu...@ti...>", -/* Signals and args */ -enum +typedef struct _GstFFMpegScaleClass - /* FILL ME */ - LAST_SIGNAL + GstBaseTransformClass parent_class; +} GstFFMpegScaleClass; - ARG_0, +#define GST_TYPE_FFMPEGSCALE \ + (gst_ffmpegscale_get_type()) +#define GST_FFMPEGSCALE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGSCALE,GstFFMpegScale)) +#define GST_FFMPEGSCALE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGSCALE,GstFFMpegScaleClass)) +#define GST_IS_FFMPEGSCALE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGSCALE)) +#define GST_IS_FFMPEGSCALE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGSCALE)) -static GstStaticPadTemplate gst_ffmpegscale_src_template = -GST_STATIC_PAD_TEMPLATE ("src", +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) ); -static GstStaticPadTemplate gst_ffmpegscale_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, +GST_BOILERPLATE (GstFFMpegScale, gst_ffmpegscale, GstBaseTransform, + GST_TYPE_BASE_TRANSFORM); -static GType gst_ffmpegscale_get_type (void); -static void gst_ffmpegscale_base_init (GstFFMpegScaleClass * klass); -static void gst_ffmpegscale_class_init (GstFFMpegScaleClass * klass); -static void gst_ffmpegscale_init (GstFFMpegScale * space); -static void gst_ffmpegscale_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_ffmpegscale_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_ffmpegscale_finalize (GObject * object); -static GstPadLinkReturn -gst_ffmpegscale_pad_link (GstPad * pad, const GstCaps * caps); +static GstCaps *gst_ffmpegscale_transform_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps); +static void gst_ffmpegscale_fixate_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * othercaps); +static gboolean gst_ffmpegscale_get_unit_size (GstBaseTransform * trans, + GstCaps * caps, guint * size); +static gboolean gst_ffmpegscale_set_caps (GstBaseTransform * trans, + GstCaps * incaps, GstCaps * outcaps); +static GstFlowReturn gst_ffmpegscale_transform (GstBaseTransform * trans, + GstBuffer * inbuf, GstBuffer * outbuf); -static void gst_ffmpegscale_chain (GstPad * pad, GstData * data); -static GstStateChangeReturn gst_ffmpegscale_change_state (GstElement * element, - GstStateChange transition); +static gboolean gst_ffmpegscale_handle_src_event (GstPad * pad, + GstEvent * event); -static GstElementClass *parent_class = NULL; +static void +gst_ffmpegscale_base_init (gpointer g_class) +{ + static GstElementDetails plugin_details = { + "FFMPEG Scale element", + "Filter/Converter/Video", + "Converts video from one resolution to another", + "Luca Ognibene <lu...@ti...>", + }; + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); -/*static guint gst_ffmpegscale_signals[LAST_SIGNAL] = { 0 }; */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_factory)); + gst_static_pad_template_get (&sink_factory)); + gst_element_class_set_details (element_class, &plugin_details); +} -static GstCaps * -gst_ffmpegscale_getcaps (GstPad * pad) +gst_ffmpegscale_class_init (GstFFMpegScaleClass * klass) - GstFFMpegScale *filter; - GstCaps *othercaps; - GstCaps *caps; - GstPad *otherpad; - gint i; - filter = GST_FFMPEGSCALE (gst_pad_get_parent (pad)); - otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass); - othercaps = gst_pad_get_allowed_caps (otherpad); + gobject_class->finalize = gst_ffmpegscale_finalize; - caps = gst_caps_intersect (othercaps, gst_pad_get_pad_template_caps (pad)); - gst_caps_free (othercaps); + trans_class->transform_caps = + GST_DEBUG_FUNCPTR (gst_ffmpegscale_transform_caps); + trans_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_ffmpegscale_fixate_caps); + trans_class->get_unit_size = + GST_DEBUG_FUNCPTR (gst_ffmpegscale_get_unit_size); + trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_ffmpegscale_set_caps); + trans_class->transform = GST_DEBUG_FUNCPTR (gst_ffmpegscale_transform); - for (i = 0; i < gst_caps_get_size (caps); i++) { - GstStructure *structure = gst_caps_get_structure (caps, i); + trans_class->passthrough_on_same_caps = TRUE; - gst_structure_set (structure, - "width", GST_TYPE_INT_RANGE, 16, 4096, - "height", GST_TYPE_INT_RANGE, 16, 4096, NULL); - gst_structure_remove_field (structure, "pixel-aspect-ratio"); - } +gst_ffmpegscale_init (GstFFMpegScale * scale, GstFFMpegScaleClass * klass) + GstBaseTransform *trans = GST_BASE_TRANSFORM (scale); - GST_DEBUG ("getcaps are: %" GST_PTR_FORMAT, caps); + gst_pad_set_event_function (trans->srcpad, gst_ffmpegscale_handle_src_event); - return caps; + scale->pixfmt = PIX_FMT_NB; + scale->res = NULL; } -gst_ffmpegscale_pad_link (GstPad * pad, const GstCaps * caps) +gst_ffmpegscale_finalize (GObject * object) - GstStructure *structure; - AVCodecContext *ctx; - GstFFMpegScale *scale; - GstPadLinkReturn ret; - int height, width; - gchar *caps_string; + GstFFMpegScale *scale = GST_FFMPEGSCALE (object); - caps_string = gst_caps_to_string (caps); - GST_DEBUG ("ffmpegscale _link %s\n", caps_string); - g_free (caps_string); + if (scale->res != NULL) + img_resample_close (scale->res); - scale = GST_FFMPEGSCALE (gst_pad_get_parent (pad)); + G_OBJECT_CLASS (parent_class)->finalize (object); - otherpad = (pad == scale->srcpad) ? scale->sinkpad : - scale->srcpad; +static GstCaps * +gst_ffmpegscale_transform_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps) + GstFFMpegScale *scale = GST_FFMPEGSCALE (trans); + GstCaps *retcaps; + int i; - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &width); - ret &= gst_structure_get_int (structure, "height", &height); + retcaps = gst_caps_copy (caps); - ctx = avcodec_alloc_context (); - ctx->width = width; - ctx->height = height; - ctx->pix_fmt = PIX_FMT_NB; - gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, caps, ctx); - if (ctx->pix_fmt == PIX_FMT_NB) { - av_free (ctx); + for (i = 0; i < gst_caps_get_size (retcaps); i++) { + GstStructure *structure = gst_caps_get_structure (retcaps, i); - /* we disable ourself here */ - return GST_PAD_LINK_REFUSED; + gst_structure_set (structure, + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, NULL); + gst_structure_remove_field (structure, "pixel-aspect-ratio"); } - scale->pixfmt = ctx->pix_fmt; - av_free (ctx); - ret = gst_pad_try_set_caps (otherpad, caps); - if (ret == GST_PAD_LINK_OK) { - /* cool, we can use passthru */ - scale->to_width = width; - scale->to_height = height; - scale->from_width = width; - scale->from_height = height; - scale->passthru = TRUE; - GST_FLAG_SET (scale, GST_ELEMENT_WORK_IN_PLACE); + return retcaps; - return GST_PAD_LINK_OK; +gst_ffmpegscale_fixate_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) + GstStructure *instructure = gst_caps_get_structure (caps, 0); + GstStructure *outstructure = gst_caps_get_structure (othercaps, 0); + const GValue *in_par, *out_par; - if (gst_pad_is_negotiated (otherpad)) { - GstCaps *newcaps = gst_caps_copy (caps); + in_par = gst_structure_get_value (instructure, "pixel-aspect-ratio"); + out_par = gst_structure_get_value (outstructure, "pixel-aspect-ratio"); - if (pad == scale->srcpad) { - gst_caps_set_simple (newcaps, - "width", G_TYPE_INT, scale->from_width, - "height", G_TYPE_INT, scale->from_height, NULL); - } else { - "width", G_TYPE_INT, scale->to_width, - "height", G_TYPE_INT, scale->to_height, NULL); - } - ret = gst_pad_try_set_caps (otherpad, newcaps); - gst_caps_free (newcaps); + if (in_par && out_par) { + GValue out_ratio = { 0, }; /* w/h of output video */ + int in_w, in_h, in_par_n, in_par_d, out_par_n, out_par_d; + int count = 0, w = 0, h = 0, num, den; - if (GST_PAD_LINK_FAILED (ret)) { - return GST_PAD_LINK_REFUSED; + /* if both width and height are already fixed, we can't do anything + * about it anymore */ + if (gst_structure_get_int (outstructure, "width", &w)) + ++count; + if (gst_structure_get_int (outstructure, "height", &h)) + if (count == 2) { + GST_DEBUG_OBJECT (trans, "dimensions already set to %dx%d, not fixating", + w, h); + return; } - scale->passthru = FALSE; - GST_FLAG_UNSET (scale, GST_ELEMENT_WORK_IN_PLACE); - if (pad == scale->srcpad) { - - } else { - } + gst_structure_get_int (instructure, "width", &in_w); + gst_structure_get_int (instructure, "height", &in_h); + in_par_n = gst_value_get_fraction_numerator (in_par); + in_par_d = gst_value_get_fraction_denominator (in_par); + out_par_n = gst_value_get_fraction_numerator (out_par); + out_par_d = gst_value_get_fraction_denominator (out_par); + g_value_init (&out_ratio, GST_TYPE_FRACTION); + gst_value_set_fraction (&out_ratio, in_w * in_par_n * out_par_d, + in_h * in_par_d * out_par_n); + num = gst_value_get_fraction_numerator (&out_ratio); + den = gst_value_get_fraction_denominator (&out_ratio); + GST_DEBUG_OBJECT (trans, + "scaling input with %dx%d and PAR %d/%d to output PAR %d/%d", + in_w, in_h, in_par_n, in_par_d, out_par_n, out_par_d); + GST_DEBUG_OBJECT (trans, "resulting output should respect ratio of %d/%d", + num, den); - scale->to_size = avpicture_get_size (scale->pixfmt, scale->to_width, scale->to_height); + /* now find a width x height that respects this display ratio. + * prefer those that have one of w/h the same as the incoming video + * using wd / hd = num / den */ - if (scale->res != NULL) img_resample_close (scale->res); + /* start with same height, because of interlaced video */ + /* check hd / den is an integer scale factor, and scale wd with the PAR */ + if (in_h % den == 0) { + GST_DEBUG_OBJECT (trans, "keeping video height"); + h = in_h; + w = h * num / den; + } else if (in_w % num == 0) { + GST_DEBUG_OBJECT (trans, "keeping video width"); + w = in_w; + h = w * den / num; + } else { + GST_DEBUG_OBJECT (trans, "approximating but keeping video height"); + } + GST_DEBUG_OBJECT (trans, "scaling to %dx%d", w, h); - scale->res = img_resample_init (scale->to_width, scale->to_height, - scale->from_width, scale->from_height); + /* now fixate */ + gst_structure_fixate_field_nearest_int (outstructure, "width", w); + gst_structure_fixate_field_nearest_int (outstructure, "height", h); + } else { + gint width, height; + if (gst_structure_get_int (instructure, "width", &width)) { + if (gst_structure_has_field (outstructure, "width")) + gst_structure_fixate_field_nearest_int (outstructure, "width", width); + if (gst_structure_get_int (instructure, "height", &height)) { + if (gst_structure_has_field (outstructure, "height")) + gst_structure_fixate_field_nearest_int (outstructure, "height", height); - return GST_PAD_LINK_OK; -static GType -gst_ffmpegscale_get_type (void) +static gboolean +gst_ffmpegscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps, + guint * size) - static GType ffmpegscale_type = 0; + GstStructure *structure = gst_caps_get_structure (caps, 0); + gint width, height; + AVCodecContext *ctx; - if (!ffmpegscale_type) { - static const GTypeInfo ffmpegscale_info = { - sizeof (GstFFMpegScaleClass), - (GBaseInitFunc) gst_ffmpegscale_base_init, - NULL, - (GClassInitFunc) gst_ffmpegscale_class_init, - sizeof (GstFFMpegScale), - 0, - (GInstanceInitFunc) gst_ffmpegscale_init, - }; + if (!gst_structure_get_int (structure, "width", &width)) + return FALSE; + if (!gst_structure_get_int (structure, "height", &height)) - ffmpegscale_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstFFMpegScale", &ffmpegscale_info, 0); + ctx = avcodec_alloc_context (); + ctx->width = width; + ctx->height = height; + ctx->pix_fmt = PIX_FMT_NB; + gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, caps, ctx); + if (ctx->pix_fmt == PIX_FMT_NB) { + av_free (ctx); - return ffmpegscale_type; -} -static void -gst_ffmpegscale_base_init (GstFFMpegScaleClass * klass) - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + *size = (guint) avpicture_get_size (ctx->pix_fmt, ctx->width, ctx->height); - gst_element_class_set_details (element_class, &ffmpegscale_details); + av_free (ctx); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_ffmpegscale_src_template)); - gst_static_pad_template_get (&gst_ffmpegscale_sink_template)); + return TRUE; -gst_ffmpegscale_class_init (GstFFMpegScaleClass * klass) +gst_ffmpegscale_set_caps (GstBaseTransform * trans, GstCaps * incaps, + GstCaps * outcaps) - GObjectClass *gobject_class; - GstElementClass *gstelement_class; + GstStructure *instructure = gst_caps_get_structure (incaps, 0); + GstStructure *outstructure = gst_caps_get_structure (outcaps, 0); + gint par_num, par_den; - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; + if (!gst_structure_get_int (instructure, "width", &scale->in_width)) + if (!gst_structure_get_int (instructure, "height", &scale->in_height)) - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + if (!gst_structure_get_int (outstructure, "width", &scale->out_width)) + if (!gst_structure_get_int (outstructure, "height", &scale->out_height)) - gobject_class->set_property = gst_ffmpegscale_set_property; - gobject_class->get_property = gst_ffmpegscale_get_property; + if (gst_structure_get_fraction (instructure, "pixel-aspect-ratio", + &par_num, &par_den)) { + gst_structure_set (outstructure, + "pixel-aspect-ratio", GST_TYPE_FRACTION, + par_num * scale->in_width / scale->out_width, + par_den * scale->in_height / scale->out_height, NULL); + } - gstelement_class->change_state = gst_ffmpegscale_change_state; + ctx->width = scale->in_width; + ctx->height = scale->in_height; + gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, incaps, ctx); -gst_ffmpegscale_init (GstFFMpegScale * scale) - scale->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get - (&gst_ffmpegscale_sink_template), - "sink"); - gst_pad_set_link_function (scale->sinkpad, gst_ffmpegscale_pad_link); - gst_pad_set_getcaps_function (scale->sinkpad, gst_ffmpegscale_getcaps); - gst_pad_set_chain_function (scale->sinkpad, gst_ffmpegscale_chain); - gst_element_add_pad (GST_ELEMENT (scale), scale->sinkpad); + scale->pixfmt = ctx->pix_fmt; - scale->srcpad = gst_pad_new_from_template (gst_static_pad_template_get - (&gst_ffmpegscale_src_template), - "src"); - gst_element_add_pad (GST_ELEMENT (scale), scale->srcpad); - gst_pad_set_link_function (scale->srcpad, gst_ffmpegscale_pad_link); - gst_pad_set_getcaps_function (scale->srcpad, gst_ffmpegscale_getcaps); - scale->pixfmt = PIX_FMT_NB; - scale->res = NULL; + scale->res = img_resample_init (scale->out_width, scale->out_height, + scale->in_width, scale->in_height); -gst_ffmpegscale_chain (GstPad * pad, GstData * data) +static GstFlowReturn +gst_ffmpegscale_transform (GstBaseTransform * trans, GstBuffer * inbuf, + GstBuffer * outbuf) - GstBuffer *inbuf = GST_BUFFER (data); - GstBuffer *outbuf = NULL; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (inbuf != NULL); + AVPicture in_frame, out_frame; - g_return_if_fail (scale != NULL); - g_return_if_fail (GST_IS_FFMPEGSCALE (scale)); + gst_buffer_stamp (outbuf, inbuf); - if (!GST_PAD_IS_USABLE (scale->srcpad)) { - gst_buffer_unref (inbuf); - return; - if (scale->passthru == TRUE) { - gst_pad_push (scale->srcpad, GST_DATA (inbuf)); - - return ; - outbuf = gst_pad_alloc_buffer_and_set_caps (scale->srcpad, GST_BUFFER_OFFSET_NONE, scale->to_size); + gst_ffmpeg_avpicture_fill (&in_frame, + GST_BUFFER_DATA (inbuf), + scale->pixfmt, scale->in_width, scale->in_height); - gst_ffmpeg_avpicture_fill (&scale->from_frame, - GST_BUFFER_DATA (inbuf), - scale->pixfmt, - scale->from_width, scale->from_height); + gst_ffmpeg_avpicture_fill (&out_frame, + GST_BUFFER_DATA (outbuf), + scale->pixfmt, scale->out_width, scale->out_height); - gst_ffmpeg_avpicture_fill (&scale->to_frame, - GST_BUFFER_DATA (outbuf), - scale->to_width, scale->to_height); - img_resample (scale->res, &scale->to_frame, &scale->from_frame); - gst_buffer_stamp (outbuf, (const GstBuffer *) inbuf); + img_resample (scale->res, &out_frame, &in_frame); - gst_buffer_unref (inbuf); - gst_pad_push (scale->srcpad, GST_DATA (outbuf)); + return GST_FLOW_OK; -static GstStateChangeReturn -gst_ffmpegscale_change_state (GstElement * element, GstStateChange transition) +gst_ffmpegscale_handle_src_event (GstPad * pad, GstEvent * event) + GstFFMpegScale *scale = GST_FFMPEGSCALE (gst_pad_get_parent (pad)); + GstStructure *structure; + gdouble pointer; - scale = GST_FFMPEGSCALE (element); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_NAVIGATION: + event = + GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event))); - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - if (scale->res != NULL) - img_resample_close (scale->res); + structure = gst_event_get_structure (event); + if (gst_structure_get_double (structure, "pointer_x", &pointer)) { + gst_structure_set (structure, + "pointer_x", G_TYPE_DOUBLE, + pointer * scale->in_width / scale->out_width, NULL); + } + if (gst_structure_get_double (structure, "pointer_y", &pointer)) { + "pointer_y", G_TYPE_DOUBLE, + pointer * scale->in_height / scale->out_height, NULL); break; - if (parent_class->change_state) - return parent_class->change_state (element, transition); - return GST_STATE_CHANGE_SUCCESS; -gst_ffmpegscale_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_FFMPEGSCALE (object)); - scale = GST_FFMPEGSCALE (object); - switch (prop_id) { default: -gst_ffmpegscale_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + return gst_pad_event_default (pad, event); gboolean gst_ffmpegscale_register (GstPlugin * plugin) return gst_element_register (plugin, "ffvideoscale", GST_RANK_NONE, GST_TYPE_FFMPEGSCALE); |
From: <bi...@ke...> - 2006-04-19 15:35:25
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Wed Apr 19 2006 15:35:24 UTC Log message: reviewed by: Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_formatid_to_caps), (gst_ffmpeg_formatid_get_codecids), (gst_ffmpeg_get_codecid_longname): Added proper GstCaps <==> CodecId for Apple QDRaw. Fixed up proper wrapping for GstCaps <==> FormatId. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.288&r2=1.289 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.115&r2=1.116 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.288 retrieving revision 1.289 diff -u -d -r1.288 -r1.289 --- ChangeLog 18 Apr 2006 11:02:04 -0000 1.288 +++ ChangeLog 19 Apr 2006 15:35:12 -0000 1.289 @@ -1,3 +1,13 @@ +2006-04-19 J^ <j...@bo...> + + reviewed by: Edward Hervey <ed...@fl...> + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), + (gst_ffmpeg_formatid_to_caps), (gst_ffmpeg_formatid_get_codecids), + (gst_ffmpeg_get_codecid_longname): + Added proper GstCaps <==> CodecId for Apple QDRaw. + Fixed up proper wrapping for GstCaps <==> FormatId. 2006-04-18 Wim Taymans <wi...@fl...> * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_perform_seek), @@ -128,6 +138,25 @@ 2006-03-01 Michal Benes <michal dot benes at xeris dot cz> + * ext/ffmpeg/Makefile.am: + * ext/ffmpeg/gstffmpeg.c: (plugin_init): + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_formatid_to_caps), + (gst_ffmpeg_formatid_get_codecids): + * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init), + (gst_ffmpegmux_init), (gst_ffmpegmux_finalize), + (gst_ffmpegmux_request_new_pad), (gst_ffmpegmux_setcaps), + (gst_ffmpegmux_collected), (gst_ffmpegmux_change_state), + (gst_ffmpegmux_register): + Port of FFMpeg muxers to 0.10. + Still needs some loving in gstffmpegcodecmap to have them all supported + with correct input formats. + Closes #332339 + +2006-03-01 Michal Benes <michal dot benes at xeris dot cz> Reviewed by : Edward Hervey <ed...@fl...> * ext/ffmpeg/Makefile.am: Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.115 retrieving revision 1.116 diff -u -d -r1.115 -r1.116 --- gstffmpegcodecmap.c 8 Apr 2006 10:51:32 -0000 1.115 +++ gstffmpegcodecmap.c 19 Apr 2006 15:35:12 -0000 1.116 @@ -533,6 +533,10 @@ caps = GST_FF_VID_CAPS_NEW ("video/x-smc", NULL); break; + case CODEC_ID_QDRAW: + caps = GST_FF_VID_CAPS_NEW ("video/x-qdrw", NULL); + break; case CODEC_ID_WS_VQA: case CODEC_ID_IDCIN: case CODEC_ID_8BPS: @@ -542,7 +546,6 @@ case CODEC_ID_SONIC: case CODEC_ID_SONIC_LS: case CODEC_ID_SNOW: - case CODEC_ID_QDRAW: case CODEC_ID_VIXL: case CODEC_ID_QPEG: case CODEC_ID_XVID: @@ -1510,6 +1513,12 @@ } else if (!strcmp (format_name, "mov_mp4_m4a_3gp_3g2")) { caps = gst_caps_from_string ( "application/x-3gp; video/quicktime; audio/x-m4a"); + } else if (!strcmp (format_name, "mov")) { + caps = gst_caps_new_simple ("video/quicktime", NULL); + } else if (!strcmp (format_name, "mp4")) { + } else if ((!strcmp (format_name, "3gp")) || (!strcmp (format_name, "3gp2"))) { + caps = gst_caps_new_simple ("application/x-3gp", NULL); } else if (!strcmp (format_name, "aac")) { caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4, @@ -1538,6 +1547,9 @@ gst_ffmpeg_formatid_get_codecids (const gchar *format_name, enum CodecID ** video_codec_list, enum CodecID ** audio_codec_list) { + GST_LOG ("format_name : %s", format_name); if (!strcmp (format_name, "mp4")) { static enum CodecID mp4_video_list[] = { CODEC_ID_MPEG4, CODEC_ID_H264, CODEC_ID_NONE }; static enum CodecID mp4_audio_list[] = { CODEC_ID_AAC, CODEC_ID_NONE }; @@ -1545,11 +1557,29 @@ *video_codec_list = mp4_video_list; *audio_codec_list = mp4_audio_list; } else if (!strcmp (format_name, "mpeg")) { - static enum CodecID mpeg_video_list[] = { CODEC_ID_MPEG1VIDEO, CODEC_ID_NONE }; - static enum CodecID mpeg_audio_list[] = { CODEC_ID_MP2, CODEC_ID_NONE }; + static enum CodecID mpeg_video_list[] = { CODEC_ID_MPEG1VIDEO, + CODEC_ID_MPEG2VIDEO, + CODEC_ID_H264, + CODEC_ID_NONE }; + static enum CodecID mpeg_audio_list[] = { CODEC_ID_MP2, + CODEC_ID_MP3, *video_codec_list = mpeg_video_list; *audio_codec_list = mpeg_audio_list; + } else if (!strcmp (format_name, "mpegts")) { + static enum CodecID mpegts_video_list[] = { CODEC_ID_MPEG1VIDEO, + static enum CodecID mpegts_audio_list[] = { CODEC_ID_MP2, + CODEC_ID_AC3, + CODEC_ID_AAC, + *video_codec_list = mpegts_video_list; + *audio_codec_list = mpegts_audio_list; } else if (!strcmp (format_name, "vob")) { static enum CodecID vob_video_list[] = { CODEC_ID_MPEG2VIDEO, CODEC_ID_NONE }; static enum CodecID vob_audio_list[] = { CODEC_ID_MP2, CODEC_ID_AC3, CODEC_ID_NONE }; @@ -2278,7 +2308,7 @@ name = "Ultimotion video"; case CODEC_ID_QDRAW: - name = "Applet Quickdraw video"; + name = "Apple Quickdraw video"; name = "Miro VideoXL"; |
From: <bi...@ke...> - 2006-05-26 12:42:21
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri May 26 2006 12:42:18 UTC Log message: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_pixfmt_to_caps), (gst_ffmpeg_smpfmt_to_caps), (gst_ffmpeg_formatid_to_caps), (gst_ffmpeg_formatid_get_codecids), (gst_ffmpeg_get_codecid_longname): Change all GST_WARNING to GST_LOG. None of these warning are really critical issues anyway. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.301&r2=1.302 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.118&r2=1.119 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.301 retrieving revision 1.302 diff -u -d -r1.301 -r1.302 --- ChangeLog 18 May 2006 23:06:30 -0000 1.301 +++ ChangeLog 26 May 2006 12:42:06 -0000 1.302 @@ -1,3 +1,12 @@ +2006-05-26 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), + (gst_ffmpeg_pixfmt_to_caps), (gst_ffmpeg_smpfmt_to_caps), + (gst_ffmpeg_formatid_to_caps), (gst_ffmpeg_formatid_get_codecids), + (gst_ffmpeg_get_codecid_longname): + Change all GST_WARNING to GST_LOG. None of these warning are + really critical issues anyway. + 2006-05-19 Thomas Vander Stichele <thomas at apestaart dot org> * configure.ac: Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.118 retrieving revision 1.119 diff -u -d -r1.118 -r1.119 --- gstffmpegcodecmap.c 16 May 2006 20:03:00 -0000 1.118 +++ gstffmpegcodecmap.c 26 May 2006 12:42:06 -0000 1.119 @@ -869,8 +869,8 @@ (codec = avcodec_find_encoder (codec_id))) { gchar *mime = NULL; - GST_WARNING ("Could not create stream format caps for %s", - codec->name); + GST_LOG ("Could not create stream format caps for %s", + codec->name); switch (codec->type) { case CODEC_TYPE_VIDEO: @@ -914,7 +914,7 @@ GST_LOG ("caps for codec_id=%d: %" GST_PTR_FORMAT, codec_id, caps); } else { - GST_WARNING ("No caps found for codec_id=%d", codec_id); + GST_LOG ("No caps found for codec_id=%d", codec_id); } return caps; @@ -1052,7 +1052,7 @@ GST_DEBUG ("caps for pix_fmt=%d: %s", pix_fmt, str); g_free (str); - GST_WARNING ("No caps found for pix_fmt=%d", pix_fmt); + GST_LOG ("No caps found for pix_fmt=%d", pix_fmt); @@ -1098,7 +1098,7 @@ GST_LOG ("caps for sample_fmt=%d: %s", sample_fmt, str); - GST_WARNING ("No caps found for sample_fmt=%d", sample_fmt); + GST_LOG ("No caps found for sample_fmt=%d", sample_fmt); @@ -1554,7 +1554,7 @@ gchar *name; - GST_WARNING ("Could not create stream format caps for %s", format_name); + GST_LOG ("Could not create stream format caps for %s", format_name); name = g_strdup_printf ("application/x-gst_ff-%s", format_name); caps = gst_caps_new_simple (name, NULL); g_free (name); @@ -1615,7 +1615,7 @@ *video_codec_list = flv_video_list; *audio_codec_list = flv_audio_list; - GST_WARNING ("Format %s not found", format_name); + GST_LOG ("Format %s not found", format_name); return FALSE; @@ -2519,7 +2519,7 @@ name = "3GPP AMR WideBand speech audio codec"; break; default: - GST_WARNING ("Unknown codecID 0x%x", codec_id); + GST_LOG ("Unknown codecID 0x%x", codec_id); |
From: <bi...@ke...> - 2006-06-02 13:41:37
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Jun 02 2006 12:38:49 UTC Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): Nothing to see, pass your way, I didn't screwup the previous commit. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.304&r2=1.305 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.152&r2=1.153 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.304 retrieving revision 1.305 diff -u -d -r1.304 -r1.305 --- ChangeLog 2 Jun 2006 12:29:38 -0000 1.304 +++ ChangeLog 2 Jun 2006 12:38:37 -0000 1.305 @@ -1,5 +1,10 @@ 2006-06-02 Edward Hervey <ed...@fl...> + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): + Nothing to see, pass your way, I didn't screwup the previous commit. + +2006-06-02 Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_init), (gst_ffmpegdec_query), (gst_ffmpegdec_update_qos), (gst_ffmpegdec_reset_qos), (gst_ffmpegdec_read_qos), Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.152 retrieving revision 1.153 diff -u -d -r1.152 -r1.153 --- gstffmpegdec.c 2 Jun 2006 12:29:38 -0000 1.152 +++ gstffmpegdec.c 2 Jun 2006 12:38:37 -0000 1.153 @@ -1679,7 +1679,6 @@ gint res; gint64 ffpts; - dump_parser_context (ffmpegdec->pctx, ffmpegdec->context); GST_LOG_OBJECT (ffmpegdec, "Calling av_parser_parse with ts:%" GST_TIME_FORMAT, GST_TIME_ARGS (in_ts)); @@ -1694,8 +1693,6 @@ "Parsed video frame, res=%d, size=%d, data=%p, in_ts:%" GST_TIME_FORMAT, res, size, data, GST_TIME_ARGS (in_ts)); - if (res == 0 || size == 0) { GST_LOG_OBJECT (ffmpegdec, "parser returned null res or size, breaking"); |
From: <bi...@ke...> - 2006-06-02 13:42:13
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Jun 02 2006 12:29:50 UTC Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_init), (gst_ffmpegdec_query), (gst_ffmpegdec_update_qos), (gst_ffmpegdec_reset_qos), (gst_ffmpegdec_read_qos), (gst_ffmpegdec_open), (gst_ffmpegdec_setcaps), (gst_ffmpegdec_get_buffer), (gst_ffmpegdec_release_buffer), (gst_ffmpegdec_add_pixel_aspect_ratio), (gst_ffmpegdec_negotiate), (gst_ffmpegdec_do_qos), (gst_ffmpegdec_video_frame), (gst_ffmpegdec_audio_frame), (gst_ffmpegdec_frame), (gst_ffmpegdec_flush_pcache), (gst_ffmpegdec_sink_event), (gst_ffmpegdec_chain): Split out audio and video frame decoding. Added dropping/clipping of decoded buffers. Ran gst-indent on code. Small non-invasive code cleanups. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.303&r2=1.304 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.151&r2=1.152 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.303 retrieving revision 1.304 diff -u -d -r1.303 -r1.304 --- ChangeLog 2 Jun 2006 11:50:45 -0000 1.303 +++ ChangeLog 2 Jun 2006 12:29:38 -0000 1.304 @@ -1,3 +1,20 @@ +2006-06-02 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_init), + (gst_ffmpegdec_query), (gst_ffmpegdec_update_qos), + (gst_ffmpegdec_reset_qos), (gst_ffmpegdec_read_qos), + (gst_ffmpegdec_open), (gst_ffmpegdec_setcaps), + (gst_ffmpegdec_get_buffer), (gst_ffmpegdec_release_buffer), + (gst_ffmpegdec_add_pixel_aspect_ratio), (gst_ffmpegdec_negotiate), + (gst_ffmpegdec_do_qos), (gst_ffmpegdec_video_frame), + (gst_ffmpegdec_audio_frame), (gst_ffmpegdec_frame), + (gst_ffmpegdec_flush_pcache), (gst_ffmpegdec_sink_event), + (gst_ffmpegdec_chain): + Split out audio and video frame decoding. + Added dropping/clipping of decoded buffers. + Ran gst-indent on code. + Small non-invasive code cleanups. 2006-06-02 Michael Smith <ms...@fl...> * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_register): Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.151 retrieving revision 1.152 diff -u -d -r1.151 -r1.152 --- gstffmpegdec.c 7 May 2006 01:18:46 -0000 1.151 +++ gstffmpegdec.c 2 Jun 2006 12:29:38 -0000 1.152 @@ -67,7 +67,7 @@ } audio; } format; gboolean waiting_for_key; - guint64 next_ts, synctime; + guint64 next_ts; /* parsing */ AVCodecParserContext *pctx; @@ -79,7 +79,7 @@ gint hurry_up, lowres; [...1228 lines suppressed...] + GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0). bsize:%d , bdata:%p", + bsize, bdata); } while (bsize > 0); + /* keep left-over */ if ((ffmpegdec->pctx || oclass->in_plugin->id == CODEC_ID_MP3) && bsize > 0) { - GST_LOG_OBJECT (ffmpegdec, "Keeping %d bytes of data", bsize); + GST_LOG_OBJECT (ffmpegdec, + "Keeping %d bytes of data with timestamp %" GST_TIME_FORMAT, bsize, + GST_TIME_ARGS (in_ts)); ffmpegdec->pcache = gst_buffer_create_sub (inbuf, GST_BUFFER_SIZE (inbuf) - bsize, bsize); /* we keep timestamp, even though all we really know is that the correct * timestamp is not below the one from inbuf */ - GST_BUFFER_TIMESTAMP (ffmpegdec->pcache) = GST_BUFFER_TIMESTAMP (inbuf); + GST_BUFFER_TIMESTAMP (ffmpegdec->pcache) = in_ts; } else if (bsize > 0) { GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize); } |
From: <bi...@ke...> - 2006-06-06 08:32:05
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Tue Jun 06 2006 08:32:00 UTC Log message: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_open): mpeg4 parsing still utterly broken :( Modified files: . : ChangeLog ext/ffmpeg : gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.305&r2=1.306 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.153&r2=1.154 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.305 retrieving revision 1.306 diff -u -d -r1.305 -r1.306 --- ChangeLog 2 Jun 2006 12:38:37 -0000 1.305 +++ ChangeLog 6 Jun 2006 08:31:47 -0000 1.306 @@ -1,3 +1,8 @@ +2006-06-06 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_open): + mpeg4 parsing still utterly broken :( 2006-06-02 Edward Hervey <ed...@fl...> * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.153 retrieving revision 1.154 diff -u -d -r1.153 -r1.154 --- gstffmpegdec.c 2 Jun 2006 12:38:37 -0000 1.153 +++ gstffmpegdec.c 6 Jun 2006 08:31:48 -0000 1.154 @@ -478,7 +478,8 @@ /* open a parser if we can - exclude mp3 because it doesn't work (?), * and mjpeg because ... */ - if (oclass->in_plugin->id != CODEC_ID_MJPEG && + if (oclass->in_plugin->id != CODEC_ID_MPEG4 && + oclass->in_plugin->id != CODEC_ID_MJPEG && oclass->in_plugin->id != CODEC_ID_MP3 && oclass->in_plugin->id != CODEC_ID_H264) { ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id); |
From: <bi...@ke...> - 2006-09-08 15:26:04
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Sep 08 2006 15:26:03 UTC Log message: Patch by: Michal Benes <michal dot benes at xeris dot cz> * ext/ffmpeg/Makefile.am: * ext/ffmpeg/gstffmpeg.c: (plugin_init): * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_caps_to_codecid): * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init), (gst_ffmpegmux_init), (gst_ffmpegmux_finalize), (gst_ffmpegmux_request_new_pad), (gst_ffmpegmux_setcaps), (gst_ffmpegmux_collected), (gst_ffmpegmux_change_state), (gst_ffmpegmux_register): Port of FFMpeg muxers to 0.10. Still needs some loving in gstffmpegcodecmap to have them all supported with correct input formats. Closes #332339 Modified files: . : ChangeLog ext/ffmpeg : Makefile.am gstffmpeg.c gstffmpegcodecmap.c gstffmpegmux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.319&r2=1.320 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am.diff?r1=1.27&r2=1.28 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c.diff?r1=1.34&r2=1.35 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.121&r2=1.122 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegmux.c.diff?r1=1.36&r2=1.37 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.319 retrieving revision 1.320 diff -u -d -r1.319 -r1.320 --- ChangeLog 6 Sep 2006 15:15:05 -0000 1.319 +++ ChangeLog 8 Sep 2006 15:25:51 -0000 1.320 @@ -1,3 +1,20 @@ +2006-09-08 Edward Hervey <ed...@fl...> + + Patch by: Michal Benes <michal dot benes at xeris dot cz> + + * ext/ffmpeg/Makefile.am: + * ext/ffmpeg/gstffmpeg.c: (plugin_init): + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_caps_to_codecid): + * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init), + (gst_ffmpegmux_init), (gst_ffmpegmux_finalize), + (gst_ffmpegmux_request_new_pad), (gst_ffmpegmux_setcaps), + (gst_ffmpegmux_collected), (gst_ffmpegmux_change_state), + (gst_ffmpegmux_register): + Port of FFMpeg muxers to 0.10. + Still needs some loving in gstffmpegcodecmap to have them all supported + with correct input formats. + Closes #332339 2006-09-06 Wim Taymans <wi...@fl...> Patch by: Sebastien Moutte <sebastien at moutte dot net> Index: Makefile.am RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/Makefile.am,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- Makefile.am 6 Sep 2006 14:51:13 -0000 1.27 +++ Makefile.am 8 Sep 2006 15:25:51 -0000 1.28 @@ -7,9 +7,9 @@ gstffmpegdec.c \ gstffmpegcfg.c \ gstffmpegdemux.c \ + gstffmpegmux.c \ gstffmpegdeinterlace.c \ gstffmpegscale.c -# gstffmpegmux.c libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \ Index: gstffmpeg.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpeg.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- gstffmpeg.c 6 Sep 2006 15:15:05 -0000 1.34 +++ gstffmpeg.c 8 Sep 2006 15:25:51 -0000 1.35 @@ -114,10 +114,10 @@ gst_ffmpegenc_register (plugin); gst_ffmpegdec_register (plugin); gst_ffmpegdemux_register (plugin); + gst_ffmpegmux_register (plugin); gst_ffmpegdeinterlace_register (plugin); gst_ffmpegscale_register (plugin); #if 0 - gst_ffmpegmux_register (plugin); gst_ffmpegcsp_register (plugin); #endif Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.121 retrieving revision 1.122 diff -u -d -r1.121 -r1.122 --- gstffmpegcodecmap.c 6 Sep 2006 15:15:05 -0000 1.121 +++ gstffmpegcodecmap.c 8 Sep 2006 15:25:51 -0000 1.122 @@ -2110,6 +2110,20 @@ } else if (!strcmp (mimetype, "video/x-h264")) { id = CODEC_ID_H264; video = TRUE; + } else if (!strcmp (mimetype, "video/x-flash-video")) { + gint flvversion = 0; + + if ((gst_structure_get_int (structure, "flvversion", &flvversion))) { + switch (flvversion) { + case 1: + id = CODEC_ID_FLV1; + video = TRUE; + break; + default: + } + } } else if (!strncmp (mimetype, "audio/x-gst_ff-", 15) ) { gchar ext[16]; AVCodec *codec; @@ -2151,6 +2165,11 @@ GST_DEBUG ("The id=%d belongs to the caps %s", id, str); g_free (str); + } else { + gchar * str = gst_caps_to_string (caps); + GST_WARNING ("Couldn't figure out the id for caps %s", str); + g_free (str); } return id; Index: gstffmpegmux.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegmux.c,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- gstffmpegmux.c 8 Apr 2006 21:55:22 -0000 1.36 +++ gstffmpegmux.c 8 Sep 2006 15:25:51 -0000 1.37 @@ -29,16 +29,29 @@ #include <gst/gst.h> +#include <gst/base/gstcollectpads.h> #include "gstffmpeg.h" #include "gstffmpegcodecmap.h" typedef struct _GstFFMpegMux GstFFMpegMux; +typedef struct _GstFFMpegMuxPad GstFFMpegMuxPad; +struct _GstFFMpegMuxPad +{ + GstCollectData collect; /* we extend the CollectData */ + gint padnum; + /*< private >*/ + gpointer _gst_reserved[GST_PADDING]; +}; struct _GstFFMpegMux { GstElement element; + GstCollectPads *collect; /* We need to keep track of our pads, so we do so here. */ GstPad *srcpad; @@ -47,10 +60,10 @@ GstTagList *tags; - GstPad *sinkpads[MAX_STREAMS]; gint videopads, audiopads; - GstBuffer *bufferqueue[MAX_STREAMS]; - gboolean eos[MAX_STREAMS]; }; typedef struct _GstFFMpegMuxClassParams @@ -95,15 +108,14 @@ /* A number of functon prototypes are given so we can refer to them later. */ static void gst_ffmpegmux_class_init (GstFFMpegMuxClass * klass); -static void gst_ffmpegmux_base_init (GstFFMpegMuxClass * klass); -static void gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux); +static void gst_ffmpegmux_base_init (gpointer g_class); +static void gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux, GstFFMpegMuxClass * g_class); static void gst_ffmpegmux_finalize (GObject * object); -static GstPadLinkReturn -gst_ffmpegmux_connect (GstPad * pad, const GstCaps * caps); +static gboolean gst_ffmpegmux_setcaps (GstPad * pad, GstCaps * caps); static GstPad *gst_ffmpegmux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name); -static void gst_ffmpegmux_loop (GstElement * element); +static GstFlowReturn gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data); static GstStateChangeReturn gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition); @@ -113,10 +125,11 @@ /*static guint gst_ffmpegmux_signals[LAST_SIGNAL] = { 0 }; */ static void -gst_ffmpegmux_base_init (GstFFMpegMuxClass * klass) +gst_ffmpegmux_base_init (gpointer g_class) - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (g_class); + GstFFMpegMuxClass *klass = (GstFFMpegMuxClass *) g_class; + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstElementDetails details; GstFFMpegMuxClassParams *params; GstPadTemplate *videosinktempl, *audiosinktempl, *srctempl; @@ -172,16 +185,19 @@ } -gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux) +gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux, GstFFMpegMuxClass * g_class) - GstElementClass *klass = GST_ELEMENT_GET_CLASS (ffmpegmux); + GstElementClass *klass = GST_ELEMENT_CLASS (g_class); GstFFMpegMuxClass *oclass = (GstFFMpegMuxClass *) klass; GstPadTemplate *templ = gst_element_class_get_pad_template (klass, "src"); ffmpegmux->srcpad = gst_pad_new_from_template (templ, "src"); - gst_element_set_loop_function (GST_ELEMENT (ffmpegmux), gst_ffmpegmux_loop); gst_element_add_pad (GST_ELEMENT (ffmpegmux), ffmpegmux->srcpad); + ffmpegmux->collect = gst_collect_pads_new (); + gst_collect_pads_set_function (ffmpegmux->collect, + (GstCollectPadsFunction) gst_ffmpegmux_collected, ffmpegmux); ffmpegmux->context = g_new0 (AVFormatContext, 1); ffmpegmux->context->oformat = oclass->in_plugin; ffmpegmux->context->nb_streams = 0; @@ -202,6 +218,7 @@ GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) object; g_free (ffmpegmux->context); + gst_object_unref (ffmpegmux->collect); if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); @@ -214,11 +231,12 @@ GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) element; GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + GstFFMpegMuxPad *collect_pad; gchar *padname; GstPad *pad; AVStream *st; enum CodecType type; - gint padnum, bitrate = 0, framesize = 0; + gint bitrate = 0, framesize = 0; g_return_val_if_fail (templ != NULL, NULL); g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); @@ -241,20 +259,20 @@ /* create pad */ pad = gst_pad_new_from_template (templ, padname); - padnum = ffmpegmux->context->nb_streams; - ffmpegmux->sinkpads[padnum] = pad; - gst_pad_set_link_function (pad, gst_ffmpegmux_connect); + collect_pad = (GstFFMpegMuxPad *) + gst_collect_pads_add_pad (ffmpegmux->collect, pad, sizeof (GstFFMpegMuxPad)); + collect_pad->padnum = ffmpegmux->context->nb_streams; + gst_pad_set_setcaps_function (pad, gst_ffmpegmux_setcaps); gst_element_add_pad (element, pad); /* AVStream needs to be created */ - st = av_new_stream (ffmpegmux->context, padnum); + st = av_new_stream (ffmpegmux->context, collect_pad->padnum); st->codec->codec_type = type; st->codec->codec_id = CODEC_ID_NONE; /* this is a check afterwards */ st->stream_copy = 1; /* we're not the actual encoder */ st->codec->bit_rate = bitrate; st->codec->frame_size = framesize; - st->time_base.den = GST_SECOND; - st->time_base.num = 1; /* we fill in codec during capsnego */ /* we love debug output (c) (tm) (r) */ @@ -265,63 +283,40 @@ return pad; -gst_ffmpegmux_connect (GstPad * pad, const GstCaps * caps) +/** + * gst_ffmpegmux_setcaps + * @pad: #GstPad + * @caps: New caps. + * + * Set caps to pad. + * Returns: #TRUE on success. + */ +static gboolean +gst_ffmpegmux_setcaps (GstPad * pad, GstCaps * caps) GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) (gst_pad_get_parent (pad)); - gint i; - /*g_return_val_if_fail (ffmpegmux->opened == FALSE, - GST_PAD_LINK_REFUSED); */ - for (i = 0; i < ffmpegmux->context->nb_streams; i++) { - if (pad == ffmpegmux->sinkpads[i]) { - break; - } - } - if (i == ffmpegmux->context->nb_streams) { - g_warning ("Unknown pad given during capsnego: %p", pad); - return GST_PAD_LINK_REFUSED; - st = ffmpegmux->context->streams[i]; + collect_pad = (GstFFMpegMuxPad *) gst_pad_get_element_private (pad); + st = ffmpegmux->context->streams[collect_pad->padnum]; /* for the format-specific guesses, we'll go to * our famous codec mapper */ if (gst_ffmpeg_caps_to_codecid (caps, st->codec) != CODEC_ID_NONE) { - ffmpegmux->eos[i] = FALSE; - return GST_PAD_LINK_OK; + return TRUE; - return GST_PAD_LINK_REFUSED; + return FALSE; -static void -gst_ffmpegmux_loop (GstElement * element) -{ - GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) element; - gint i, bufnum; - - /* start by filling an internal queue of buffers */ - GstPad *pad = ffmpegmux->sinkpads[i]; - /* check for "pull'ability" */ - while (pad != NULL && - GST_PAD_IS_USABLE (pad) && - ffmpegmux->eos[i] == FALSE && ffmpegmux->bufferqueue[i] == NULL) { - GstData *data; - /* we can pull a buffer! */ - data = gst_pad_pull (pad); - if (GST_IS_EVENT (data)) { - GstEvent *event = GST_EVENT (data); +/* This is old tags handling code. It is not yet ported to 0.10 because + collectpads do not support events easily. */ - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - /* flag EOS on this stream */ - ffmpegmux->eos[i] = TRUE; - gst_event_unref (event); - break; +#if 0 case GST_EVENT_TAG: if (ffmpegmux->tags) { gst_tag_list_insert (ffmpegmux->tags, @@ -332,41 +327,52 @@ } gst_event_unref (event); break; - default: - gst_pad_event_default (pad, event); - } - } else { - ffmpegmux->bufferqueue[i] = GST_BUFFER (data); - } +#endif +static GstFlowReturn +gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data) + GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) user_data; + GSList *collected; + GstFFMpegMuxPad *best_pad; + GstClockTime best_time; /* open "file" (gstreamer protocol to next element) */ if (!ffmpegmux->opened) { - const GstTagList *iface_tags; int open_flags = URL_WRONLY; /* we do need all streams to have started capsnego, * or things will go horribly wrong */ - for (i = 0; i < ffmpegmux->context->nb_streams; i++) { - AVStream *st = ffmpegmux->context->streams[i]; + for (collected = ffmpegmux->collect->data; collected; + collected = g_slist_next (collected)) { + GstFFMpegMuxPad *collect_pad = (GstFFMpegMuxPad *) collected->data; + AVStream *st = ffmpegmux->context->streams[collect_pad->padnum]; /* check whether the pad has successfully completed capsnego */ if (st->codec->codec_id == CODEC_ID_NONE) { - GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL), - ("no caps set on stream %d (%s)", i, + GST_ELEMENT_ERROR (ffmpegmux, CORE, NEGOTIATION, (NULL), + ("no caps set on stream %d (%s)", collect_pad->padnum, (st->codec->codec_type == CODEC_TYPE_VIDEO) ? "video" : "audio")); - return; + return GST_FLOW_ERROR; } + /* set framerate for audio */ if (st->codec->codec_type == CODEC_TYPE_AUDIO) { - st->codec->frame_size = - st->codec->sample_rate * - GST_BUFFER_DURATION (ffmpegmux->bufferqueue[i]) / GST_SECOND; + GstBuffer *buffer; + buffer = gst_collect_pads_peek (ffmpegmux->collect, + (GstCollectData *)collect_pad); + if (buffer) { + st->codec->frame_size = + st->codec->sample_rate * + GST_BUFFER_DURATION (buffer) / GST_SECOND; + gst_buffer_unref (buffer); + } } + /* TODO: tags not ported to gst 0.10 */ /* tags */ iface_tags = gst_tag_setter_get_list (GST_TAG_SETTER (ffmpegmux)); if (ffmpegmux->tags || iface_tags) { @@ -413,23 +419,24 @@ gst_tag_list_free (tags); - /* set the streamheader flag for gstffmpegprotocol if codec supports it */ - if (!strcmp (ffmpegmux->context->oformat->name, "flv") ) { - open_flags |= GST_FFMPEG_URL_STREAMHEADER; + /* set the streamheader flag for gstffmpegprotocol if codec supports it */ + if (!strcmp (ffmpegmux->context->oformat->name, "flv") ) { + open_flags |= GST_FFMPEG_URL_STREAMHEADER; if (url_fopen (&ffmpegmux->context->pb, ffmpegmux->context->filename, open_flags) < 0) { - GST_ELEMENT_ERROR (element, LIBRARY, TOO_LAZY, (NULL), + GST_ELEMENT_ERROR (ffmpegmux, LIBRARY, TOO_LAZY, (NULL), ("Failed to open stream context in ffmux")); - return; + return GST_FLOW_ERROR; if (av_set_parameters (ffmpegmux->context, NULL) < 0) { - GST_ELEMENT_ERROR (element, LIBRARY, INIT, (NULL), + GST_ELEMENT_ERROR (ffmpegmux, LIBRARY, INIT, (NULL), ("Failed to initialize muxer")); /* we're now opened */ @@ -437,61 +444,74 @@ /* now open the mux format */ if (av_write_header (ffmpegmux->context) < 0) { - GST_ELEMENT_ERROR (element, LIBRARY, SETTINGS, (NULL), + GST_ELEMENT_ERROR (ffmpegmux, LIBRARY, SETTINGS, (NULL), ("Failed to write file header - check codec settings")); - /* flush the header so it will be used as streamheader */ put_flush_packet (&ffmpegmux->context->pb); /* take the one with earliest timestamp, * and push it forward */ - bufnum = -1; + best_pad = NULL; + best_time = GST_CLOCK_TIME_NONE; + for (collected = ffmpegmux->collect->data; collected; + collected = g_slist_next (collected)) { + GstFFMpegMuxPad *collect_pad = (GstFFMpegMuxPad *) collected->data; + GstBuffer *buffer = gst_collect_pads_peek (ffmpegmux->collect, + (GstCollectData *)collect_pad); /* if there's no buffer, just continue */ - if (ffmpegmux->bufferqueue[i] == NULL) { + if (buffer == NULL) { continue; /* if we have no buffer yet, just use the first one */ - if (bufnum == -1) { - bufnum = i; - continue; + if (best_pad == NULL) { + best_pad = collect_pad; + best_time = GST_BUFFER_TIMESTAMP (buffer); + goto next_pad; /* if we do have one, only use this one if it's older */ - if (GST_BUFFER_TIMESTAMP (ffmpegmux->bufferqueue[i]) < - GST_BUFFER_TIMESTAMP (ffmpegmux->bufferqueue[bufnum])) { + if (GST_BUFFER_TIMESTAMP (buffer) < best_time) { +next_pad: + gst_buffer_unref (buffer); + /* Mux buffers with invalid timestamp first */ + if (!GST_CLOCK_TIME_IS_VALID (best_time)) + break; /* now handle the buffer, or signal EOS if we have * no buffers left */ - if (bufnum >= 0) { + if (best_pad != NULL) { GstBuffer *buf; AVPacket pkt; - AVRational bq = { 1, 1000000000 }; /* push out current buffer */ - buf = ffmpegmux->bufferqueue[bufnum]; - ffmpegmux->bufferqueue[bufnum] = NULL; + buf = gst_collect_pads_pop (ffmpegmux->collect, + (GstCollectData *)best_pad); - ffmpegmux->context->streams[bufnum]->codec->frame_number++; + ffmpegmux->context->streams[best_pad->padnum]->codec->frame_number++; /* set time */ pkt.pts = gst_ffmpeg_time_gst_to_ff (GST_BUFFER_TIMESTAMP (buf), - ffmpegmux->context->streams[bufnum]->time_base); + ffmpegmux->context->streams[best_pad->padnum]->time_base); pkt.dts = pkt.pts; pkt.data = GST_BUFFER_DATA (buf); pkt.size = GST_BUFFER_SIZE (buf); - pkt.stream_index = bufnum; + pkt.stream_index = best_pad->padnum; pkt.flags = 0; - if (!(GST_BUFFER_FLAGS (buf) & GST_BUFFER_DELTA_UNIT)) - pkt.flags |= PKT_FLAG_KEY; + if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) + pkt.flags |= PKT_FLAG_KEY; if (GST_BUFFER_DURATION_IS_VALID (buf)) pkt.duration = GST_BUFFER_DURATION (buf) * AV_TIME_BASE / GST_SECOND; @@ -503,18 +523,40 @@ /* close down */ av_write_trailer (ffmpegmux->context); ffmpegmux->opened = FALSE; + put_flush_packet (&ffmpegmux->context->pb); url_fclose (&ffmpegmux->context->pb); - gst_element_set_eos (element); + gst_pad_push_event (ffmpegmux->srcpad, gst_event_new_eos ()); + return GST_FLOW_UNEXPECTED; + return GST_FLOW_OK; static GstStateChangeReturn gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition) + GstFlowReturn ret; GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) (element); switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_collect_pads_start (ffmpegmux->collect); + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + default: + } + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_collect_pads_stop (ffmpegmux->collect); if (ffmpegmux->tags) { gst_tag_list_free (ffmpegmux->tags); ffmpegmux->tags = NULL; @@ -524,12 +566,13 @@ url_fclose (&ffmpegmux->context->pb); break; + case GST_STATE_CHANGE_READY_TO_NULL: - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - return GST_STATE_CHANGE_SUCCESS; + return ret; GstCaps * @@ -585,7 +628,7 @@ if (!gst_ffmpeg_formatid_get_codecids (in_plugin->name, &video_ids, &audio_ids)) { - gst_caps_free (srccaps); + gst_caps_unref (srccaps); goto next; videosinkcaps = video_ids ? gst_ffmpegmux_get_id_caps (video_ids) : NULL; @@ -605,11 +648,11 @@ /* if it's already registered, drop it */ if (g_type_from_name (type_name)) { g_free (type_name); if (audiosinkcaps) - gst_caps_free (audiosinkcaps); + gst_caps_unref (audiosinkcaps); if (videosinkcaps) - gst_caps_free (videosinkcaps); + gst_caps_unref (videosinkcaps); @@ -629,11 +672,11 @@ &tag_setter_info); if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) { return FALSE; |
From: <bi...@ke...> - 2006-09-08 16:52:33
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Fri Sep 08 2006 16:52:31 UTC Log message: * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_request_new_pad), (gst_ffmpegmux_sink_event), (gst_ffmpegmux_collected): Port tag-writing support in the muxers. Modified files: . : ChangeLog ext/ffmpeg : gstffmpegmux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.320&r2=1.321 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegmux.c.diff?r1=1.37&r2=1.38 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.320 retrieving revision 1.321 diff -u -d -r1.320 -r1.321 --- ChangeLog 8 Sep 2006 15:25:51 -0000 1.320 +++ ChangeLog 8 Sep 2006 16:52:19 -0000 1.321 @@ -1,5 +1,11 @@ 2006-09-08 Edward Hervey <ed...@fl...> + * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_request_new_pad), + (gst_ffmpegmux_sink_event), (gst_ffmpegmux_collected): + Port tag-writing support in the muxers. + +2006-09-08 Edward Hervey <ed...@fl...> Patch by: Michal Benes <michal dot benes at xeris dot cz> * ext/ffmpeg/Makefile.am: Index: gstffmpegmux.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegmux.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- gstffmpegmux.c 8 Sep 2006 15:25:51 -0000 1.37 +++ gstffmpegmux.c 8 Sep 2006 16:52:19 -0000 1.38 @@ -42,9 +42,6 @@ GstCollectData collect; /* we extend the CollectData */ gint padnum; - - /*< private >*/ - gpointer _gst_reserved[GST_PADDING]; }; struct _GstFFMpegMux @@ -63,7 +60,8 @@ gint videopads, audiopads; /*< private >*/ + /* event_function is the collectpads default eventfunction */ + GstPadEventFunction event_function; typedef struct _GstFFMpegMuxClassParams @@ -117,6 +115,8 @@ GstPadTemplate * templ, const gchar * name); static GstFlowReturn gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data); +static gboolean gst_ffmpegmux_sink_event (GstPad * pad, GstEvent * event); static GstStateChangeReturn gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition); @@ -263,6 +263,10 @@ gst_collect_pads_add_pad (ffmpegmux->collect, pad, sizeof (GstFFMpegMuxPad)); collect_pad->padnum = ffmpegmux->context->nb_streams; + /* small hack to put our own event pad function and chain up to collect pad */ + ffmpegmux->event_function = GST_PAD_EVENTFUNC(pad); + gst_pad_set_event_function (pad, gst_ffmpegmux_sink_event); gst_pad_set_setcaps_function (pad, gst_ffmpegmux_setcaps); gst_element_add_pad (element, pad); @@ -313,21 +317,32 @@ } -/* This is old tags handling code. It is not yet ported to 0.10 because - collectpads do not support events easily. */ +static gboolean +gst_ffmpegmux_sink_event (GstPad * pad, GstEvent * event) +{ + GstFFMpegMux * ffmpegmux = (GstFFMpegMux*) gst_pad_get_parent(pad); + gboolean res = TRUE; -#if 0 - case GST_EVENT_TAG: - if (ffmpegmux->tags) { - gst_tag_list_insert (ffmpegmux->tags, - gst_event_tag_get_list (event), GST_TAG_MERGE_PREPEND); - } else { - ffmpegmux->tags = - gst_tag_list_copy (gst_event_tag_get_list (event)); - } - gst_event_unref (event); - break; -#endif + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG: { + GstTagList * taglist = NULL; + + gst_event_parse_tag (event, &taglist); + ffmpegmux->tags = gst_tag_list_merge(ffmpegmux->tags, taglist, + GST_TAG_MERGE_PREPEND); + break; + } + default: + /* chaining up to collectpads default event function */ + res = ffmpegmux->event_function (pad, event); + gst_object_unref (ffmpegmux); + return res; +} static GstFlowReturn gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data) @@ -336,6 +351,7 @@ GSList *collected; GstFFMpegMuxPad *best_pad; GstClockTime best_time; + const GstTagList *iface_tags; /* open "file" (gstreamer protocol to next element) */ if (!ffmpegmux->opened) { @@ -371,23 +387,15 @@ } } - /* TODO: tags not ported to gst 0.10 */ /* tags */ - iface_tags = gst_tag_setter_get_list (GST_TAG_SETTER (ffmpegmux)); + iface_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (ffmpegmux)); if (ffmpegmux->tags || iface_tags) { GstTagList *tags; gint i; gchar *s; - if (iface_tags && ffmpegmux->tags) { - gst_tag_list_merge (iface_tags, ffmpegmux->tags, - GST_TAG_MERGE_APPEND); - } else if (iface_tags) { - tags = gst_tag_list_copy (iface_tags); - } else { - tags = gst_tag_list_copy (ffmpegmux->tags); - } + tags = gst_tag_list_merge (iface_tags, ffmpegmux->tags, + GST_TAG_MERGE_APPEND); /* get the interesting ones */ if (gst_tag_list_get_string (tags, GST_TAG_TITLE, &s)) { @@ -414,12 +422,11 @@ strncpy (ffmpegmux->context->genre, s, sizeof (ffmpegmux->context->genre)); - if (gst_tag_list_get_uint (tags, GST_TAG_TRACK_NUMBER, &i)) { + if (gst_tag_list_get_int (tags, GST_TAG_TRACK_NUMBER, &i)) { ffmpegmux->context->track = i; gst_tag_list_free (tags); /* set the streamheader flag for gstffmpegprotocol if codec supports it */ if (!strcmp (ffmpegmux->context->oformat->name, "flv") ) { |
From: <bi...@ke...> - 2006-09-20 19:25:12
|
CVS Root: /cvs/gstreamer Module: gst-ffmpeg Changes by: bilboed Date: Wed Sep 20 2006 19:25:11 UTC Log message: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_get_codecid_longname): * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_register): Seems like the ffmpeg folks finally understood that VC9 does not exist, and that it's in fact VC1 (aka WMV9 or WMV3, but that's yet another debate). Modified files: . : ChangeLog ext/ffmpeg : gstffmpegcodecmap.c gstffmpegdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ChangeLog.diff?r1=1.323&r2=1.324 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.122&r2=1.123 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.163&r2=1.164 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-ffmpeg/ChangeLog,v retrieving revision 1.323 retrieving revision 1.324 diff -u -d -r1.323 -r1.324 --- ChangeLog 16 Sep 2006 22:19:40 -0000 1.323 +++ ChangeLog 20 Sep 2006 19:24:59 -0000 1.324 @@ -1,3 +1,12 @@ +2006-09-20 Edward Hervey <ed...@fl...> + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), + (gst_ffmpeg_get_codecid_longname): + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_register): + Seems like the ffmpeg folks finally understood that VC9 does not + exist, and that it's in fact VC1 (aka WMV9 or WMV3, but that's yet + another debate). 2006-09-17 Stefan Kost <en...@us...> * ext/ffmpeg/gstffmpegdec.c: Index: gstffmpegcodecmap.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.122 retrieving revision 1.123 diff -u -d -r1.122 -r1.123 --- gstffmpegcodecmap.c 8 Sep 2006 15:25:51 -0000 1.122 +++ gstffmpegcodecmap.c 20 Sep 2006 19:24:59 -0000 1.123 @@ -550,7 +550,7 @@ break; case CODEC_ID_WMV3: - case CODEC_ID_VC9: + case CODEC_ID_VC1: caps = gst_ff_vid_caps_new (context, "video/x-wmv", "wmvversion", G_TYPE_INT, 3, NULL); @@ -2253,7 +2253,7 @@ name = "Windows Media Video v9"; name = "Microsoft Video Codec v1"; case CODEC_ID_H263P: Index: gstffmpegdec.c RCS file: /cvs/gstreamer/gst-ffmpeg/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.163 retrieving revision 1.164 diff -u -d -r1.163 -r1.164 --- gstffmpegdec.c 16 Sep 2006 22:19:40 -0000 1.163 +++ gstffmpegdec.c 20 Sep 2006 19:24:59 -0000 1.164 @@ -2135,7 +2135,7 @@ rank = GST_RANK_MARGINAL; break; case CODEC_ID_WMV3: - case CODEC_ID_VC9: + case CODEC_ID_VC1: /* what's that? */ case CODEC_ID_SP5X: /* MP3 and MPEG2 have better alternatives and |