1.1 --- a/MozillaFirefox/MozillaFirefox.changes Thu Feb 28 23:13:27 2013 +0100
1.2 +++ b/MozillaFirefox/MozillaFirefox.changes Thu Feb 28 23:25:28 2013 +0100
1.3 @@ -2,6 +2,7 @@
1.4 Thu Feb 28 22:12:37 UTC 2013 - wr@rosenauer.org
1.5
1.6 - update to Firefox 20.0b2
1.7 +- use GStreamer 1.0 starting with 12.3 (mozilla-gstreamer-1.patch)
1.8
1.9 -------------------------------------------------------------------
1.10 Thu Feb 28 22:06:36 UTC 2013 - wr@rosenauer.org
2.1 --- a/MozillaFirefox/MozillaFirefox.spec Thu Feb 28 23:13:27 2013 +0100
2.2 +++ b/MozillaFirefox/MozillaFirefox.spec Thu Feb 28 23:25:28 2013 +0100
2.3 @@ -98,6 +98,7 @@
2.4 Patch13: mozilla-ppc.patch
2.5 Patch14: mozilla-gstreamer-760140.patch
2.6 Patch15: mozilla-libproxy-compat.patch
2.7 +Patch16: mozilla-gstreamer-1.patch
2.8 # Firefox/browser
2.9 Patch30: firefox-browser-css.patch
2.10 Patch31: firefox-kde.patch
2.11 @@ -232,6 +233,7 @@
2.12 %patch13 -p1
2.13 %patch14 -p1
2.14 %patch15 -p1
2.15 +%patch16 -p1
2.16 #
2.17 %patch30 -p1
2.18 %if %suse_version >= 1110
2.19 @@ -302,11 +304,17 @@
2.20 ac_add_options --enable-gio
2.21 EOF
2.22 %endif
2.23 +%if %suse_version > 1220
2.24 +cat << EOF >> $MOZCONFIG
2.25 +ac_add_options --enable-gstreamer=1.0
2.26 +EOF
2.27 +%else
2.28 %if %suse_version > 1140
2.29 cat << EOF >> $MOZCONFIG
2.30 ac_add_options --enable-gstreamer
2.31 EOF
2.32 %endif
2.33 +%endif
2.34 %if %branding
2.35 cat << EOF >> $MOZCONFIG
2.36 ac_add_options --enable-official-branding
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/MozillaFirefox/mozilla-gstreamer-1.patch Thu Feb 28 23:25:28 2013 +0100
3.3 @@ -0,0 +1,1 @@
3.4 +../mozilla-gstreamer-1.patch
3.5 \ No newline at end of file
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/mozilla-gstreamer-1.patch Thu Feb 28 23:25:28 2013 +0100
4.3 @@ -0,0 +1,667 @@
4.4 +# HG changeset patch
4.5 +# Parent fb80f99ca86bacbcddaf203f7183e0456f194811
4.6 +# User Mike Gorse <mgorse@suse.com>
4.7 +
4.8 +Bug 806917 - support GStreamer 1.0
4.9 +
4.10 +diff --git a/configure.in b/configure.in
4.11 +--- a/configure.in
4.12 ++++ b/configure.in
4.13 +@@ -5758,28 +5758,36 @@ fi
4.14 +
4.15 + AC_SUBST(MOZ_PULSEAUDIO)
4.16 + AC_SUBST(MOZ_PULSEAUDIO_CFLAGS)
4.17 + AC_SUBST(MOZ_PULSEAUDIO_LIBS)
4.18 +
4.19 + dnl ========================================================
4.20 + dnl = Enable GStreamer
4.21 + dnl ========================================================
4.22 +-MOZ_ARG_ENABLE_BOOL(gstreamer,
4.23 +-[ --enable-gstreamer Enable GStreamer support],
4.24 +-MOZ_GSTREAMER=1,
4.25 +-MOZ_GSTREAMER=)
4.26 ++MOZ_ARG_ENABLE_STRING(gstreamer,
4.27 ++[ --enable-gstreamer[=1.0] Enable GStreamer support],
4.28 ++[ MOZ_GSTREAMER=1
4.29 ++ # API version, eg 0.10, 1.0 etc
4.30 ++ if test -n "$enableval" ]; then
4.31 ++ GST_API_VERSION=$enableval
4.32 ++ else
4.33 ++ GST_API_VERSION=0.10
4.34 ++ fi]
4.35 ++[ MOZ_GSTREAMER=])
4.36 +
4.37 + if test "$MOZ_GSTREAMER"; then
4.38 +- # API version, eg 0.10, 1.0 etc
4.39 +- GST_API_VERSION=0.10
4.40 + # core/base release number
4.41 + # depend on >= 0.10.33 as that's when the playbin2 source-setup signal was
4.42 + # introduced
4.43 +- GST_VERSION=0.10.33
4.44 ++ if test "$GST_API_VERSION" = "1.0"; then
4.45 ++ GST_VERSION=1.0
4.46 ++ else
4.47 ++ GST_VERSION=0.10.33
4.48 ++ fi
4.49 + PKG_CHECK_MODULES(GSTREAMER,
4.50 + gstreamer-$GST_API_VERSION >= $GST_VERSION
4.51 + gstreamer-app-$GST_API_VERSION
4.52 + gstreamer-plugins-base-$GST_API_VERSION)
4.53 + if test -n "$GSTREAMER_LIBS"; then
4.54 + _SAVE_LDFLAGS=$LDFLAGS
4.55 + LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
4.56 + AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
4.57 +diff --git a/content/media/gstreamer/GStreamerReader.cpp b/content/media/gstreamer/GStreamerReader.cpp
4.58 +--- a/content/media/gstreamer/GStreamerReader.cpp
4.59 ++++ b/content/media/gstreamer/GStreamerReader.cpp
4.60 +@@ -69,18 +69,22 @@ GStreamerReader::GStreamerReader(Abstrac
4.61 + MOZ_COUNT_CTOR(GStreamerReader);
4.62 +
4.63 + mSrcCallbacks.need_data = GStreamerReader::NeedDataCb;
4.64 + mSrcCallbacks.enough_data = GStreamerReader::EnoughDataCb;
4.65 + mSrcCallbacks.seek_data = GStreamerReader::SeekDataCb;
4.66 +
4.67 + mSinkCallbacks.eos = GStreamerReader::EosCb;
4.68 + mSinkCallbacks.new_preroll = GStreamerReader::NewPrerollCb;
4.69 ++#if GST_VERSION_MAJOR == 1
4.70 ++ mSinkCallbacks.new_sample = GStreamerReader::NewBufferCb;
4.71 ++#else
4.72 + mSinkCallbacks.new_buffer = GStreamerReader::NewBufferCb;
4.73 + mSinkCallbacks.new_buffer_list = NULL;
4.74 ++#endif
4.75 +
4.76 + gst_segment_init(&mVideoSegment, GST_FORMAT_UNDEFINED);
4.77 + gst_segment_init(&mAudioSegment, GST_FORMAT_UNDEFINED);
4.78 + }
4.79 +
4.80 + GStreamerReader::~GStreamerReader()
4.81 + {
4.82 + MOZ_COUNT_DTOR(GStreamerReader);
4.83 +@@ -120,19 +124,26 @@ nsresult GStreamerReader::Init(MediaDeco
4.84 + mVideoSink = gst_parse_bin_from_description("capsfilter name=filter ! "
4.85 + "appsink name=videosink sync=true max-buffers=1 "
4.86 + "caps=video/x-raw-yuv,format=(fourcc)I420"
4.87 + , TRUE, NULL);
4.88 + mVideoAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mVideoSink),
4.89 + "videosink"));
4.90 + gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks,
4.91 + (gpointer) this, NULL);
4.92 +- GstPad *sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink");
4.93 ++ GstPad *sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
4.94 ++#if GST_VERSION_MAJOR == 1
4.95 ++ // TODO: Figure out whether we need UPSTREAM or DOWNSTREAM, or both
4.96 ++ gst_pad_add_probe(sinkpad,
4.97 ++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_UPSTREAM),
4.98 ++ &GStreamerReader::EventProbeCb, this, NULL);
4.99 ++#else
4.100 + gst_pad_add_event_probe(sinkpad,
4.101 + G_CALLBACK(&GStreamerReader::EventProbeCb), this);
4.102 ++#endif
4.103 + gst_object_unref(sinkpad);
4.104 +
4.105 + mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
4.106 + #ifdef MOZ_SAMPLE_TYPE_FLOAT32
4.107 + "appsink name=audiosink sync=true caps=audio/x-raw-float,"
4.108 + #ifdef IS_LITTLE_ENDIAN
4.109 + "channels={1,2},rate=44100,width=32,endianness=1234", TRUE, NULL);
4.110 + #else
4.111 +@@ -145,19 +156,25 @@ nsresult GStreamerReader::Init(MediaDeco
4.112 + #else
4.113 + "channels={1,2},rate=48000,width=16,endianness=4321", TRUE, NULL);
4.114 + #endif
4.115 + #endif
4.116 + mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink),
4.117 + "audiosink"));
4.118 + gst_app_sink_set_callbacks(mAudioAppSink, &mSinkCallbacks,
4.119 + (gpointer) this, NULL);
4.120 +- sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink");
4.121 ++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
4.122 ++#if GST_VERSION_MAJOR == 1
4.123 ++ gst_pad_add_probe(sinkpad,
4.124 ++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_UPSTREAM),
4.125 ++ &GStreamerReader::EventProbeCb, this, NULL);
4.126 ++#else
4.127 + gst_pad_add_event_probe(sinkpad,
4.128 + G_CALLBACK(&GStreamerReader::EventProbeCb), this);
4.129 ++#endif
4.130 + gst_object_unref(sinkpad);
4.131 +
4.132 + g_object_set(mPlayBin, "uri", "appsrc://",
4.133 + "video-sink", mVideoSink,
4.134 + "audio-sink", mAudioSink,
4.135 + NULL);
4.136 +
4.137 + g_object_connect(mPlayBin, "signal::source-setup",
4.138 +@@ -231,17 +248,17 @@ nsresult GStreamerReader::ReadMetadata(V
4.139 + filter = gst_bin_get_by_name(GST_BIN(mAudioSink), "filter");
4.140 + else if (!(current_flags & GST_PLAY_FLAG_VIDEO))
4.141 + filter = gst_bin_get_by_name(GST_BIN(mVideoSink), "filter");
4.142 +
4.143 + if (filter) {
4.144 + /* Little trick: set the target caps to "skip" so that playbin2 fails to
4.145 + * find a decoder for the stream we want to skip.
4.146 + */
4.147 +- GstCaps *filterCaps = gst_caps_new_simple ("skip", NULL);
4.148 ++ GstCaps *filterCaps = gst_caps_new_simple ("skip", NULL, NULL);
4.149 + g_object_set(filter, "caps", filterCaps, NULL);
4.150 + gst_caps_unref(filterCaps);
4.151 + gst_object_unref(filter);
4.152 + }
4.153 +
4.154 + /* start the pipeline */
4.155 + gst_element_set_state(mPlayBin, GST_STATE_PAUSED);
4.156 +
4.157 +@@ -284,19 +301,24 @@ nsresult GStreamerReader::ReadMetadata(V
4.158 + gst_element_set_state(mPlayBin, GST_STATE_NULL);
4.159 + gst_message_unref(message);
4.160 + return NS_ERROR_FAILURE;
4.161 + }
4.162 + }
4.163 +
4.164 + /* report the duration */
4.165 + gint64 duration;
4.166 ++#if GST_VERSION_MAJOR == 1
4.167 ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
4.168 ++ GST_FORMAT_TIME, &duration)) {
4.169 ++#else
4.170 + GstFormat format = GST_FORMAT_TIME;
4.171 + if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
4.172 + &format, &duration) && format == GST_FORMAT_TIME) {
4.173 ++#endif
4.174 + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
4.175 + LOG(PR_LOG_DEBUG, ("returning duration %" GST_TIME_FORMAT,
4.176 + GST_TIME_ARGS (duration)));
4.177 + duration = GST_TIME_AS_USECONDS (duration);
4.178 + mDecoder->SetMediaDuration(duration);
4.179 + }
4.180 +
4.181 + int n_video = 0, n_audio = 0;
4.182 +@@ -365,59 +387,87 @@ bool GStreamerReader::DecodeAudioData()
4.183 + {
4.184 + NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
4.185 +
4.186 + if (!WaitForDecodedData(&mAudioSinkBufferCount)) {
4.187 + mAudioQueue.Finish();
4.188 + return false;
4.189 + }
4.190 +
4.191 ++#if GST_VERSION_MAJOR == 1
4.192 ++ GstSample *sample = gst_app_sink_pull_sample(mAudioAppSink);
4.193 ++ GstBuffer *buffer = gst_sample_get_buffer(sample);
4.194 ++#else
4.195 + GstBuffer *buffer = gst_app_sink_pull_buffer(mAudioAppSink);
4.196 ++#endif
4.197 + int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer);
4.198 + timestamp = gst_segment_to_stream_time(&mAudioSegment,
4.199 + GST_FORMAT_TIME, timestamp);
4.200 + timestamp = GST_TIME_AS_USECONDS(timestamp);
4.201 + int64_t duration = 0;
4.202 + if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
4.203 + duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
4.204 +
4.205 + int64_t offset = GST_BUFFER_OFFSET(buffer);
4.206 ++#if GST_VERSION_MAJOR == 1
4.207 ++ GstMapInfo info;
4.208 ++ gst_buffer_map(buffer, &info, GST_MAP_READ);
4.209 ++ unsigned int size = info.size;
4.210 ++#else
4.211 + unsigned int size = GST_BUFFER_SIZE(buffer);
4.212 ++#endif
4.213 + int32_t frames = (size / sizeof(AudioDataValue)) / mInfo.mAudioChannels;
4.214 + ssize_t outSize = static_cast<size_t>(size / sizeof(AudioDataValue));
4.215 + nsAutoArrayPtr<AudioDataValue> data(new AudioDataValue[outSize]);
4.216 ++#if GST_VERSION_MAJOR == 1
4.217 ++ memcpy(data, info.data, info.size);
4.218 ++ gst_buffer_unmap(buffer, &info);
4.219 ++#else
4.220 + memcpy(data, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
4.221 ++#endif
4.222 + AudioData *audio = new AudioData(offset, timestamp, duration,
4.223 + frames, data.forget(), mInfo.mAudioChannels);
4.224 +
4.225 + mAudioQueue.Push(audio);
4.226 + gst_buffer_unref(buffer);
4.227 +
4.228 + return true;
4.229 + }
4.230 +
4.231 + bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
4.232 + int64_t aTimeThreshold)
4.233 + {
4.234 + NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
4.235 +
4.236 ++#if GST_VERSION_MAJOR == 1
4.237 ++ GstSample *sample = NULL;
4.238 ++#endif
4.239 + GstBuffer *buffer = NULL;
4.240 + int64_t timestamp, nextTimestamp;
4.241 + while (true)
4.242 + {
4.243 + if (!WaitForDecodedData(&mVideoSinkBufferCount)) {
4.244 + mVideoQueue.Finish();
4.245 + break;
4.246 + }
4.247 + mDecoder->NotifyDecodedFrames(0, 1);
4.248 +
4.249 ++#if GST_VERSION_MAJOR == 1
4.250 ++ sample = gst_app_sink_pull_sample(mVideoAppSink);
4.251 ++ buffer = gst_sample_get_buffer(sample);
4.252 ++#else
4.253 + buffer = gst_app_sink_pull_buffer(mVideoAppSink);
4.254 ++#endif
4.255 + bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT);
4.256 + if ((aKeyFrameSkip && !isKeyframe)) {
4.257 ++#if GST_VERSION_MAJOR == 1
4.258 ++ gst_sample_unref(sample);
4.259 ++#else
4.260 + gst_buffer_unref(buffer);
4.261 ++#endif
4.262 + buffer = NULL;
4.263 + continue;
4.264 + }
4.265 +
4.266 + timestamp = GST_BUFFER_TIMESTAMP(buffer);
4.267 + {
4.268 + ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
4.269 + timestamp = gst_segment_to_stream_time(&mVideoSegment,
4.270 +@@ -431,62 +481,90 @@ bool GStreamerReader::DecodeVideoFrame(b
4.271 + else if (fpsNum && fpsDen)
4.272 + /* add 1-frame duration */
4.273 + nextTimestamp += gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
4.274 +
4.275 + if (timestamp < aTimeThreshold) {
4.276 + LOG(PR_LOG_DEBUG, ("skipping frame %" GST_TIME_FORMAT
4.277 + " threshold %" GST_TIME_FORMAT,
4.278 + GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)));
4.279 ++#if GST_VERSION_MAJOR == 1
4.280 ++ gst_sample_unref(sample);
4.281 ++#else
4.282 + gst_buffer_unref(buffer);
4.283 ++#endif
4.284 + buffer = NULL;
4.285 + continue;
4.286 + }
4.287 +
4.288 + break;
4.289 + }
4.290 +
4.291 + if (buffer == NULL)
4.292 + /* no more frames */
4.293 + return false;
4.294 +
4.295 ++#if GST_VERSION_MAJOR == 1
4.296 ++ GstMapInfo info;
4.297 ++ gst_buffer_map(buffer, &info, GST_MAP_READ);
4.298 ++ guint8 *data = info.data;
4.299 ++#else
4.300 + guint8 *data = GST_BUFFER_DATA(buffer);
4.301 ++#endif
4.302 +
4.303 + int width = mPicture.width;
4.304 + int height = mPicture.height;
4.305 + GstVideoFormat format = mFormat;
4.306 +
4.307 + VideoData::YCbCrBuffer b;
4.308 ++#if GST_VERSION_MAJOR == 1
4.309 ++ GstVideoInfo *video_info;
4.310 ++ gst_video_info_set_format(video_info, format, width, height);
4.311 ++ for(int i = 0; i < 3; i++) {
4.312 ++ b.mPlanes[i].mData = data + GST_VIDEO_INFO_COMP_OFFSET(video_info, i);
4.313 ++ b.mPlanes[i].mStride = GST_VIDEO_INFO_COMP_STRIDE(video_info, i);
4.314 ++ b.mPlanes[i].mHeight = GST_VIDEO_INFO_COMP_HEIGHT(video_info, i);
4.315 ++ b.mPlanes[i].mWidth = GST_VIDEO_INFO_COMP_WIDTH(video_info, i);
4.316 ++ b.mPlanes[i].mOffset = 0;
4.317 ++ b.mPlanes[i].mSkip = 0;
4.318 ++ }
4.319 ++#else
4.320 + for(int i = 0; i < 3; i++) {
4.321 + b.mPlanes[i].mData = data + gst_video_format_get_component_offset(format, i,
4.322 + width, height);
4.323 + b.mPlanes[i].mStride = gst_video_format_get_row_stride(format, i, width);
4.324 + b.mPlanes[i].mHeight = gst_video_format_get_component_height(format,
4.325 + i, height);
4.326 + b.mPlanes[i].mWidth = gst_video_format_get_component_width(format,
4.327 + i, width);
4.328 + b.mPlanes[i].mOffset = 0;
4.329 + b.mPlanes[i].mSkip = 0;
4.330 + }
4.331 ++#endif
4.332 +
4.333 + bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer,
4.334 + GST_BUFFER_FLAG_DELTA_UNIT);
4.335 + /* XXX ? */
4.336 + int64_t offset = 0;
4.337 + VideoData *video = VideoData::Create(mInfo,
4.338 + mDecoder->GetImageContainer(),
4.339 + offset,
4.340 + timestamp,
4.341 + nextTimestamp,
4.342 + b,
4.343 + isKeyframe,
4.344 + -1,
4.345 + mPicture);
4.346 + mVideoQueue.Push(video);
4.347 ++#if GST_VERSION_MAJOR == 1
4.348 ++ gst_buffer_unmap(buffer, &info);
4.349 ++ gst_sample_unref(sample);
4.350 ++#else
4.351 + gst_buffer_unref(buffer);
4.352 ++#endif
4.353 +
4.354 + return true;
4.355 + }
4.356 +
4.357 + nsresult GStreamerReader::Seek(int64_t aTarget,
4.358 + int64_t aStartTime,
4.359 + int64_t aEndTime,
4.360 + int64_t aCurrentTime)
4.361 +@@ -509,52 +587,62 @@ nsresult GStreamerReader::Seek(int64_t a
4.362 +
4.363 + nsresult GStreamerReader::GetBuffered(nsTimeRanges* aBuffered,
4.364 + int64_t aStartTime)
4.365 + {
4.366 + if (!mInfo.mHasVideo && !mInfo.mHasAudio) {
4.367 + return NS_OK;
4.368 + }
4.369 +
4.370 +- GstFormat format = GST_FORMAT_TIME;
4.371 ++#if GST_VERSION_MAJOR == 0
4.372 ++ GstFormat format = GST_FORMAT_TIME;
4.373 ++#endif
4.374 ++
4.375 + MediaResource* resource = mDecoder->GetResource();
4.376 + gint64 resourceLength = resource->GetLength();
4.377 + nsTArray<MediaByteRange> ranges;
4.378 + resource->GetCachedRanges(ranges);
4.379 +
4.380 + if (mDecoder->OnStateMachineThread())
4.381 + /* Report the position from here while buffering as we can't report it from
4.382 + * the gstreamer threads that are actually reading from the resource
4.383 + */
4.384 + NotifyBytesConsumed();
4.385 +
4.386 + if (resource->IsDataCachedToEndOfResource(0)) {
4.387 + /* fast path for local or completely cached files */
4.388 + gint64 duration = 0;
4.389 +- GstFormat format = GST_FORMAT_TIME;
4.390 +-
4.391 + duration = QueryDuration();
4.392 + double end = (double) duration / GST_MSECOND;
4.393 + LOG(PR_LOG_DEBUG, ("complete range [0, %f] for [0, %li]",
4.394 + end, resourceLength));
4.395 + aBuffered->Add(0, end);
4.396 + return NS_OK;
4.397 + }
4.398 +
4.399 + for(uint32_t index = 0; index < ranges.Length(); index++) {
4.400 + int64_t startOffset = ranges[index].mStart;
4.401 + int64_t endOffset = ranges[index].mEnd;
4.402 + gint64 startTime, endTime;
4.403 +
4.404 ++#if GST_VERSION_MAJOR == 1
4.405 ++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
4.406 ++ startOffset, GST_FORMAT_TIME, &startTime))
4.407 ++ continue;
4.408 ++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
4.409 ++ endOffset, GST_FORMAT_TIME, &endTime))
4.410 ++ continue;
4.411 ++#else
4.412 + if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
4.413 + startOffset, &format, &startTime) || format != GST_FORMAT_TIME)
4.414 + continue;
4.415 + if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
4.416 + endOffset, &format, &endTime) || format != GST_FORMAT_TIME)
4.417 + continue;
4.418 ++#endif
4.419 +
4.420 + double start = start = (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND;
4.421 + double end = (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND;
4.422 + LOG(PR_LOG_DEBUG, ("adding range [%f, %f] for [%li %li] size %li",
4.423 + start, end, startOffset, endOffset, resourceLength));
4.424 + aBuffered->Add(start, end);
4.425 + }
4.426 +
4.427 +@@ -563,48 +651,64 @@ nsresult GStreamerReader::GetBuffered(ns
4.428 +
4.429 + void GStreamerReader::ReadAndPushData(guint aLength)
4.430 + {
4.431 + MediaResource* resource = mDecoder->GetResource();
4.432 + NS_ASSERTION(resource, "Decoder has no media resource");
4.433 + nsresult rv = NS_OK;
4.434 +
4.435 + GstBuffer *buffer = gst_buffer_new_and_alloc(aLength);
4.436 ++#if GST_VERSION_MAJOR == 1
4.437 ++ GstMapInfo info;
4.438 ++ gst_buffer_map(buffer, &info, GST_MAP_WRITE);
4.439 ++ guint8 *data = info.data;
4.440 ++#else
4.441 + guint8 *data = GST_BUFFER_DATA(buffer);
4.442 ++#endif
4.443 + uint32_t size = 0, bytesRead = 0;
4.444 + while(bytesRead < aLength) {
4.445 + rv = resource->Read(reinterpret_cast<char*>(data + bytesRead),
4.446 + aLength - bytesRead, &size);
4.447 + if (NS_FAILED(rv) || size == 0)
4.448 + break;
4.449 +
4.450 + bytesRead += size;
4.451 + }
4.452 +
4.453 ++#if GST_VERSION_MAJOR == 1
4.454 ++ info.size = bytesRead;
4.455 ++ gst_buffer_unmap(buffer, &info);
4.456 ++#else
4.457 + GST_BUFFER_SIZE(buffer) = bytesRead;
4.458 ++#endif
4.459 + mByteOffset += bytesRead;
4.460 +
4.461 + GstFlowReturn ret = gst_app_src_push_buffer(mSource, gst_buffer_ref(buffer));
4.462 + if (ret != GST_FLOW_OK)
4.463 + LOG(PR_LOG_ERROR, ("ReadAndPushData push ret %s", gst_flow_get_name(ret)));
4.464 +
4.465 +- if (GST_BUFFER_SIZE (buffer) < aLength)
4.466 ++ if (bytesRead < aLength)
4.467 + /* If we read less than what we wanted, we reached the end */
4.468 + gst_app_src_end_of_stream(mSource);
4.469 +
4.470 + gst_buffer_unref(buffer);
4.471 + }
4.472 +
4.473 + int64_t GStreamerReader::QueryDuration()
4.474 + {
4.475 + gint64 duration = 0;
4.476 + GstFormat format = GST_FORMAT_TIME;
4.477 +
4.478 ++#if GST_VERSION_MAJOR == 1
4.479 ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
4.480 ++ format, &duration)) {
4.481 ++#else
4.482 + if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
4.483 + &format, &duration)) {
4.484 ++#endif
4.485 + if (format == GST_FORMAT_TIME) {
4.486 + LOG(PR_LOG_DEBUG, ("pipeline duration %" GST_TIME_FORMAT,
4.487 + GST_TIME_ARGS (duration)));
4.488 + duration = GST_TIME_AS_USECONDS (duration);
4.489 + }
4.490 + }
4.491 +
4.492 + /*if (mDecoder->mDuration != -1 &&
4.493 +@@ -668,60 +772,95 @@ gboolean GStreamerReader::SeekData(GstAp
4.494 + if (NS_SUCCEEDED(rv))
4.495 + mByteOffset = mLastReportedByteOffset = aOffset;
4.496 + else
4.497 + LOG(PR_LOG_ERROR, ("seek at %lu failed", aOffset));
4.498 +
4.499 + return NS_SUCCEEDED(rv);
4.500 + }
4.501 +
4.502 ++#if GST_VERSION_MAJOR == 1
4.503 ++GstPadProbeReturn GStreamerReader::EventProbeCb(GstPad *aPad,
4.504 ++ GstPadProbeInfo *aInfo,
4.505 ++ gpointer aUserData)
4.506 ++{
4.507 ++ GStreamerReader *reader = (GStreamerReader *) aUserData;
4.508 ++ GstEvent *aEvent = (GstEvent *)aInfo->data;
4.509 ++ return reader->EventProbe(aPad, aEvent);
4.510 ++}
4.511 ++#else
4.512 + gboolean GStreamerReader::EventProbeCb(GstPad *aPad,
4.513 + GstEvent *aEvent,
4.514 + gpointer aUserData)
4.515 + {
4.516 + GStreamerReader *reader = (GStreamerReader *) aUserData;
4.517 + return reader->EventProbe(aPad, aEvent);
4.518 + }
4.519 ++#endif
4.520 +
4.521 ++#if GST_VERSION_MAJOR == 1
4.522 ++GstPadProbeReturn GStreamerReader::EventProbe(GstPad *aPad, GstEvent *aEvent)
4.523 ++#else
4.524 + gboolean GStreamerReader::EventProbe(GstPad *aPad, GstEvent *aEvent)
4.525 ++#endif
4.526 + {
4.527 + GstElement *parent = GST_ELEMENT(gst_pad_get_parent(aPad));
4.528 + switch(GST_EVENT_TYPE(aEvent)) {
4.529 ++#if GST_VERSION_MAJOR == 1
4.530 ++ case GST_EVENT_SEGMENT:
4.531 ++#else
4.532 + case GST_EVENT_NEWSEGMENT:
4.533 ++#endif
4.534 + {
4.535 ++#if GST_VERSION_MAJOR == 1
4.536 ++ const GstSegment *newSegment;
4.537 ++#else
4.538 + gboolean update;
4.539 + gdouble rate;
4.540 + GstFormat format;
4.541 + gint64 start, stop, position;
4.542 ++#endif
4.543 + GstSegment *segment;
4.544 +
4.545 + /* Store the segments so we can convert timestamps to stream time, which
4.546 + * is what the upper layers sync on.
4.547 + */
4.548 + ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
4.549 ++#if GST_VERSION_MAJOR == 1
4.550 ++ gst_event_parse_segment(aEvent, &newSegment);
4.551 ++#else
4.552 + gst_event_parse_new_segment(aEvent, &update, &rate, &format,
4.553 + &start, &stop, &position);
4.554 ++#endif
4.555 + if (parent == GST_ELEMENT(mVideoAppSink))
4.556 + segment = &mVideoSegment;
4.557 + else
4.558 + segment = &mAudioSegment;
4.559 ++#if GST_VERSION_MAJOR == 1
4.560 ++ gst_segment_copy_into (newSegment, segment);
4.561 ++#else
4.562 + gst_segment_set_newsegment(segment, update, rate, format,
4.563 + start, stop, position);
4.564 ++#endif
4.565 + break;
4.566 + }
4.567 + case GST_EVENT_FLUSH_STOP:
4.568 + /* Reset on seeks */
4.569 + ResetDecode();
4.570 + break;
4.571 + default:
4.572 + break;
4.573 + }
4.574 + gst_object_unref(parent);
4.575 +
4.576 ++#if GST_VERSION_MAJOR == 1
4.577 ++ return GST_PAD_PROBE_OK;
4.578 ++#else
4.579 + return TRUE;
4.580 ++#endif
4.581 + }
4.582 +
4.583 + GstFlowReturn GStreamerReader::NewPrerollCb(GstAppSink *aSink,
4.584 + gpointer aUserData)
4.585 + {
4.586 + GStreamerReader *reader = (GStreamerReader *) aUserData;
4.587 +
4.588 + if (aSink == reader->mVideoAppSink)
4.589 +@@ -730,18 +869,22 @@ GstFlowReturn GStreamerReader::NewPrerol
4.590 + reader->AudioPreroll();
4.591 + return GST_FLOW_OK;
4.592 + }
4.593 +
4.594 + void GStreamerReader::AudioPreroll()
4.595 + {
4.596 + /* The first audio buffer has reached the audio sink. Get rate and channels */
4.597 + LOG(PR_LOG_DEBUG, ("Audio preroll"));
4.598 +- GstPad *sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink");
4.599 ++ GstPad *sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
4.600 ++#if GST_VERSION_MAJOR == 1
4.601 ++ GstCaps *caps = gst_pad_get_current_caps(sinkpad);
4.602 ++#else
4.603 + GstCaps *caps = gst_pad_get_negotiated_caps(sinkpad);
4.604 ++#endif
4.605 + GstStructure *s = gst_caps_get_structure(caps, 0);
4.606 + mInfo.mAudioRate = mInfo.mAudioChannels = 0;
4.607 + gst_structure_get_int(s, "rate", (gint *) &mInfo.mAudioRate);
4.608 + gst_structure_get_int(s, "channels", (gint *) &mInfo.mAudioChannels);
4.609 + NS_ASSERTION(mInfo.mAudioRate != 0, ("audio rate is zero"));
4.610 + NS_ASSERTION(mInfo.mAudioChannels != 0, ("audio channels is zero"));
4.611 + NS_ASSERTION(mInfo.mAudioChannels > 0 && mInfo.mAudioChannels <= MAX_CHANNELS,
4.612 + "invalid audio channels number");
4.613 +@@ -749,19 +892,29 @@ void GStreamerReader::AudioPreroll()
4.614 + gst_caps_unref(caps);
4.615 + gst_object_unref(sinkpad);
4.616 + }
4.617 +
4.618 + void GStreamerReader::VideoPreroll()
4.619 + {
4.620 + /* The first video buffer has reached the video sink. Get width and height */
4.621 + LOG(PR_LOG_DEBUG, ("Video preroll"));
4.622 +- GstPad *sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink");
4.623 ++ GstPad *sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
4.624 ++#if GST_VERSION_MAJOR == 1
4.625 ++ GstCaps *caps = gst_pad_get_current_caps(sinkpad);
4.626 ++ GstVideoInfo info;
4.627 ++ memset (&info, 0, sizeof (info));
4.628 ++ gst_video_info_from_caps(&info, caps);
4.629 ++ mFormat = info.finfo->format;
4.630 ++ mPicture.width = info.width;
4.631 ++ mPicture.height = info.height;
4.632 ++#else
4.633 + GstCaps *caps = gst_pad_get_negotiated_caps(sinkpad);
4.634 + gst_video_format_parse_caps(caps, &mFormat, &mPicture.width, &mPicture.height);
4.635 ++#endif
4.636 + GstStructure *structure = gst_caps_get_structure(caps, 0);
4.637 + gst_structure_get_fraction(structure, "framerate", &fpsNum, &fpsDen);
4.638 + NS_ASSERTION(mPicture.width && mPicture.height, "invalid video resolution");
4.639 + mInfo.mDisplay = nsIntSize(mPicture.width, mPicture.height);
4.640 + mInfo.mHasVideo = true;
4.641 + gst_caps_unref(caps);
4.642 + gst_object_unref(sinkpad);
4.643 + }
4.644 +diff --git a/content/media/gstreamer/GStreamerReader.h b/content/media/gstreamer/GStreamerReader.h
4.645 +--- a/content/media/gstreamer/GStreamerReader.h
4.646 ++++ b/content/media/gstreamer/GStreamerReader.h
4.647 +@@ -71,18 +71,23 @@ private:
4.648 +
4.649 + /* Called when a seek is issued on the pipeline */
4.650 + static gboolean SeekDataCb(GstAppSrc *aSrc,
4.651 + guint64 aOffset,
4.652 + gpointer aUserData);
4.653 + gboolean SeekData(GstAppSrc *aSrc, guint64 aOffset);
4.654 +
4.655 + /* Called when events reach the sinks. See inline comments */
4.656 ++#if GST_VERSION_MAJOR == 1
4.657 ++ static GstPadProbeReturn EventProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
4.658 ++ GstPadProbeReturn EventProbe(GstPad *aPad, GstEvent *aEvent);
4.659 ++#else
4.660 + static gboolean EventProbeCb(GstPad *aPad, GstEvent *aEvent, gpointer aUserData);
4.661 + gboolean EventProbe(GstPad *aPad, GstEvent *aEvent);
4.662 ++#endif
4.663 +
4.664 + /* Called when the pipeline is prerolled, that is when at start or after a
4.665 + * seek, the first audio and video buffers are queued in the sinks.
4.666 + */
4.667 + static GstFlowReturn NewPrerollCb(GstAppSink *aSink, gpointer aUserData);
4.668 + void VideoPreroll();
4.669 + void AudioPreroll();
4.670 +
5.1 --- a/series Thu Feb 28 23:13:27 2013 +0100
5.2 +++ b/series Thu Feb 28 23:25:28 2013 +0100
5.3 @@ -18,6 +18,7 @@
5.4 mozilla-ppc.patch
5.5 mozilla-idldir.patch
5.6 mozilla-libproxy-compat.patch
5.7 +mozilla-gstreamer-1.patch
5.8 #mozilla-disable-neon-option.patch
5.9
5.10 # Firefox patches