[M47_2526] Chromium upversion to m47_2526 branch
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / media / base / efl / media_source_player_gstreamer.cc
1 // Copyright 2014 Samsung Electronics Inc. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/base/efl/media_source_player_gstreamer.h"
6
7 #include <gst/app/gstappsink.h>
8 #include <gst/app/gstappsrc.h>
9 #include <gst/video/video.h>
10 #include <gst/video/videooverlay.h>
11
12 #include "base/process/process.h"
13 #include "media/base/efl/media_player_manager_efl.h"
14 #include "media/base/efl/media_player_util_efl.h"
15
16 namespace {
17
18 // Pipeline element name
19 const char* kPipelineName = "gst_pipeline";
20
21 // Update duration every 100ms.
22 const int kDurationUpdateInterval = 100;
23
24 // For smooth playback, seeking will be done to I-Frame + kSixteenMilliSeconds
25 // Reason to choose kSixteenMilliSeconds is duration of each video frame at
26 // 60 fps video will be ~16 milliseconds.
27 const int64 kSixteenMilliSeconds = 16000000;
28 const int kMaxBufPercent = 100;
29
30 const int kBytesPerMegabyte = 1048576;
31
32 const char* h264elements[] = {
33     "h264parse",
34 #if defined(TIZEN_MULTIMEDIA_USE_HW_CODEC)
35     "omx_h264dec",
36 #else
37     "avdec_h264"
38 #endif
39 };
40
41 const char* aacelements[] = {
42     "aacparse",
43 #if defined(TIZEN_MULTIMEDIA_USE_HW_CODEC)
44     "omx_aacdec", "autoaudiosink",
45 #else
46     "avdec_aac", "autoaudiosink"
47 #endif
48 };
49
50 const char* mp3elements[] = {
51     "mpegaudioparse",
52     "avdec_mp3",
53     "autoaudiosink"
54 };
55
56 const AudioCodecGstElementsMapping AudioMapping[] = {
57     {media::kCodecAAC, aacelements},
58     {media::kCodecMP3, mp3elements},
59     {media::kUnknownAudioCodec, NULL}
60 };
61
62 const VideoCodecGstElementsMapping VideoMapping[] = {
63     {media::kCodecH264, h264elements},
64     {media::kUnknownVideoCodec, NULL}
65 };
66
67 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
68 // Generating Unique integer for given height / width.
69 int GetUniqueKey(int x, int y) {
70   return ((x << 16) | y);
71 }
72 #endif
73
74 }  // namespace
75
76 namespace media {
77
78 static GstBusSyncReply GstPipelineMessageCB(
79     GstBus* bus,
80     GstMessage* message,
81     gpointer user_data) {
82   MediaSourcePlayerGstreamer* player =
83       static_cast<MediaSourcePlayerGstreamer*>(user_data);
84   if (!player || player->IsPlayerDestructing())
85     return GST_BUS_PASS;
86
87   player->HandleMessage(message);
88   gst_message_unref(message);
89   return GST_BUS_DROP;
90 }
91
92 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
93 static Eina_Bool NotifyDamageUpdatedCB(
94     void* user_data,
95     int type,
96     void* event) {
97   MediaSourcePlayerGstreamer* player =
98       static_cast<MediaSourcePlayerGstreamer*>(user_data);
99   if (!player || player->IsPlayerDestructing())
100     return ECORE_CALLBACK_PASS_ON;
101   player->PlatformSurfaceUpdated();
102   return ECORE_CALLBACK_PASS_ON;
103 }
104
105 #if defined(OS_TIZEN_TV)
106 static int GetPixmapIdCB(void* user_data) {
107   MediaSourcePlayerGstreamer* player =
108       static_cast<MediaSourcePlayerGstreamer*>(user_data);
109   return player->GetSurfaceID();
110 }
111 #endif
112 #endif
113
114 static void  OnGstStartVideoFeedCB(
115     GstAppSrc* pipeline,
116     guint size,
117     void* user_data) {
118   MediaSourcePlayerGstreamer* player =
119       static_cast<MediaSourcePlayerGstreamer*>(user_data);
120   if (!player || player->IsPlayerDestructing())
121     return;
122   player->OnReadDemuxedData(media::DemuxerStream::VIDEO);
123   return;
124 }
125
126 static void OnGstStopVideoFeedCB(GstAppSrc* pipeline, void* user_data) {
127   MediaSourcePlayerGstreamer* player =
128       static_cast<MediaSourcePlayerGstreamer*>(user_data);
129   if (!player || player->IsPlayerDestructing())
130     return;
131   player->OnStopDemuxedData(media::DemuxerStream::VIDEO);
132 }
133
134 static gboolean OnGstSeekVideoFeedCB(
135     GstAppSrc* pipeline,
136     guint64 offset,
137     void* user_data) {
138
139   MediaSourcePlayerGstreamer* player =
140       static_cast<MediaSourcePlayerGstreamer*>(user_data);
141   if (!player || player->IsPlayerDestructing())
142     return FALSE;
143   player->UpdateVideoSeekOffset(offset);
144   return TRUE;
145 }
146
147 static GstFlowReturn OnGstAppsinkPreroll(
148     GstAppSink* sink,
149     gpointer user_data) {
150   MediaSourcePlayerGstreamer* player =
151       static_cast<MediaSourcePlayerGstreamer*>(user_data);
152   if (!player || player->IsPlayerDestructing())
153     return GST_FLOW_ERROR;
154   player->GetFrameDetails();
155   return GST_FLOW_OK;
156 }
157
158 static GstFlowReturn OnGstAppsinkBuffer(GstAppSink* sink, gpointer user_data) {
159   MediaSourcePlayerGstreamer* player =
160       static_cast<MediaSourcePlayerGstreamer*>(user_data);
161   if (!player || player->IsPlayerDestructing())
162     return GST_FLOW_ERROR;
163   player->OnNewFrameAvailable(player->PullSample());
164   return GST_FLOW_OK;
165 }
166
167 gboolean OnGstSeekAudioFeedCB(
168     GstAppSrc* pipeline,
169     guint64 offset,
170     void* user_data) {
171   MediaSourcePlayerGstreamer* player =
172       static_cast<MediaSourcePlayerGstreamer*>(user_data);
173   if (!player || player->IsPlayerDestructing())
174     return FALSE;
175   player->UpdateAudioSeekOffset(offset);
176   return TRUE;
177 }
178
179 static void OnGstStartAudioFeedCB(
180     GstAppSrc* pipeline,
181     guint size,
182     void* user_data) {
183   MediaSourcePlayerGstreamer* player =
184       static_cast<MediaSourcePlayerGstreamer*>(user_data);
185   if (!player || player->IsPlayerDestructing())
186     return;
187   player->OnReadDemuxedData(media::DemuxerStream::AUDIO);
188 }
189
190 static void OnGstStopAudioFeedCB(GstAppSrc* pipeline, void* user_data) {
191   MediaSourcePlayerGstreamer* player =
192       static_cast<MediaSourcePlayerGstreamer*>(user_data);
193   if (!player || player->IsPlayerDestructing())
194     return;
195   player->OnStopDemuxedData(media::DemuxerStream::AUDIO);
196 }
197
198 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
199 static void OnVideoSinkCapsChangedCB(
200     GObject* gobject,
201     GParamSpec* gparamspec,
202     void* user_data) {
203   MediaSourcePlayerGstreamer* player =
204       static_cast<MediaSourcePlayerGstreamer*>(user_data);
205   if (!player || player->IsPlayerDestructing())
206     return;
207   player->OnVideoConfigsChanged();
208 }
209 #endif
210
211 MediaSourcePlayerGstreamer::MediaSourcePlayerGstreamer(
212     int player_id,
213     scoped_ptr<DemuxerEfl> demuxer,
214     MediaPlayerManager* manager)
215     : MediaPlayerEfl(player_id, manager),
216       demuxer_(demuxer.Pass()),
217       task_runner_(base::ThreadTaskRunnerHandle::Get()),
218       playing_(false),
219       weak_this_(this),
220 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
221       pixmap_id_(0),
222       efl_pixmap_(NULL),
223       m_damage_(0),
224       m_damage_handler_(0),
225 #endif
226       is_xwindow_handle_set_(false),
227       pipeline_(NULL),
228       video_appsrc_(NULL),
229       video_queue_(NULL),
230       video_sink_(NULL),
231       audio_appsrc_(NULL),
232       audio_queue_(NULL),
233       audio_volume_(NULL),
234       should_feed_audio_(true),
235       should_feed_video_(false),
236       width_(0),
237       height_(0),
238       video_format_(0),
239       media_type_(0),
240       play_rate_(1.0f),
241       duration_(0),
242       is_paused_due_underflow_(false),
243       buffered_(0),
244       is_paused_(false),
245       is_seeking_(false),
246       is_demuxer_seeking_(false),
247       audio_buffered_(0),
248       video_buffered_(0),
249       is_download_finished_(false),
250       is_end_reached_(false),
251       error_occured_(false),
252       raw_video_frame_size_(0),
253       video_seek_offset_(0),
254       audio_seek_offset_(0),
255       is_seeking_iframe_(false) {
256   demuxer_->Initialize(this);
257   audio_buffer_queue_.clear();
258   video_buffer_queue_.clear();
259 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
260   efl_pixmaps_map_.clear();
261 #endif
262 }
263
264 void MediaSourcePlayerGstreamer::Destroy() {
265   if (IsPlayerDestructing())
266     return;
267
268   destructing_ = true;
269   Release();
270   task_runner_->DeleteSoon(FROM_HERE, this);
271 }
272
273 void MediaSourcePlayerGstreamer::Play() {
274   if (!pipeline_ || error_occured_)
275     return;
276   if (play_rate_ == 0.0) {
277     playing_ = true;
278     return;
279   }
280 #if defined(OS_TIZEN_MOBILE)
281   WakeUpDisplayAndAcquireDisplayLock();
282 #endif
283
284   gst_element_set_state(pipeline_, GST_STATE_PLAYING);
285   StartCurrentTimeUpdateTimer();
286   playing_ = true;
287   is_paused_due_underflow_ = false;
288 }
289
290 void MediaSourcePlayerGstreamer::Pause(bool is_media_related_action) {
291   if (!pipeline_ || error_occured_)
292     return;
293
294   gst_element_set_state(pipeline_, GST_STATE_PAUSED);
295   StopCurrentTimeUpdateTimer();
296   if (!is_media_related_action) {
297 #if defined(OS_TIZEN_MOBILE)
298     ReleaseDisplayLock();
299 #endif
300     is_paused_due_underflow_ = false;
301     playing_ = false;
302   }
303 }
304
305 void MediaSourcePlayerGstreamer::SetRate(double rate) {
306   if (play_rate_ == rate)
307     return;
308   if (rate == 0.0) {
309     play_rate_ = rate;
310     Pause(true);
311     return;
312   }
313
314   // If rate was zero and requested rate is non-zero, change the paused state
315   if (play_rate_ == 0.0 && rate != 0.0) {
316     Play();
317     StartCurrentTimeUpdateTimer();
318   }
319
320   play_rate_ = rate;
321
322   RequestPlayerSeek(GetCurrentTime());
323 }
324
325 void MediaSourcePlayerGstreamer::RequestPlayerSeek(double seekTime) {
326   if (is_demuxer_seeking_)
327     return;
328   GstState state = GST_STATE_VOID_PENDING;
329   gst_element_get_state(pipeline_, &state, NULL, 250 * GST_NSECOND);
330   is_demuxer_seeking_ = true;
331   if (state == GST_STATE_PLAYING)
332     Pause(true);
333   manager()->OnRequestSeek(GetPlayerId(), seekTime);
334 }
335
336 void MediaSourcePlayerGstreamer::Seek(const double time) {
337   GstState state = GST_STATE_VOID_PENDING;
338   gst_element_get_state(pipeline_, &state, NULL, 250 * GST_NSECOND);
339
340   is_seeking_iframe_ = false;
341   is_demuxer_seeking_ = true;
342   if (state == GST_STATE_PLAYING)
343     Pause(true);
344
345   // Input to |FromMicroseconds| is |int64|. Additional multiplication
346   // is done to avoid data loss.
347   base::TimeDelta seek_time = base::TimeDelta::FromMicroseconds(
348       static_cast<int64>(time * base::Time::kMicrosecondsPerSecond));
349   demuxer_->RequestDemuxerSeek(seek_time);
350 }
351
352 void MediaSourcePlayerGstreamer::SeekInternal(const GstClockTime position) {
353   if (!pipeline_ || error_occured_)
354     return;
355
356   GstClockTime startTime = 0, endTime = position;
357
358   is_demuxer_seeking_ = false;
359
360   if (play_rate_ > 0) {
361     startTime = position;
362     endTime = GST_CLOCK_TIME_NONE;
363   }
364
365   UpdateSeekState(true);
366   audio_buffer_queue_.clear();
367   video_buffer_queue_.clear();
368   if (!gst_element_seek(pipeline_, play_rate_, GST_FORMAT_TIME,
369                         static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH |
370                                                   GST_SEEK_FLAG_ACCURATE),
371                         GST_SEEK_TYPE_SET, startTime, GST_SEEK_TYPE_SET,
372                         endTime)) {
373     LOG(ERROR) << "Seek to " << position << " failed";
374     HandleError(MediaPlayerEfl::NetworkStateDecodeError);
375   }
376 }
377
378 double MediaSourcePlayerGstreamer::GetCurrentTime() {
379   if (!pipeline_ || error_occured_)
380     return 0.0;
381
382   gint64 current_time = 0;
383   GstFormat format = GST_FORMAT_TIME;
384   gst_element_query_position(pipeline_, format, &current_time);
385   return ConvertNanoSecondsToSeconds(current_time);
386 }
387
388 void MediaSourcePlayerGstreamer::Release() {
389   DCHECK(IsPlayerDestructing());
390   playing_ = false;
391   StopCurrentTimeUpdateTimer();
392   audio_buffer_queue_.clear();
393   video_buffer_queue_.clear();
394
395   if (pipeline_) {
396     GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_));
397     if (bus) {
398       g_signal_handlers_disconnect_by_func(
399           bus,
400           reinterpret_cast<gpointer>(GstPipelineMessageCB),
401           this);
402       gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
403       gst_object_unref(bus);
404     }
405
406     gst_element_set_state(pipeline_, GST_STATE_NULL);
407     gst_object_unref(pipeline_);
408     pipeline_ = NULL;
409   }
410
411 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
412   UnregisterDamageHandler();
413   efl_pixmaps_map_.clear();
414 #endif
415 }
416
417 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
418 void MediaSourcePlayerGstreamer::UnregisterDamageHandler() {
419   if (m_damage_) {
420     ecore_x_damage_free(m_damage_);
421     m_damage_ = 0;
422   }
423   if (m_damage_handler_) {
424     ecore_event_handler_del(m_damage_handler_);
425     m_damage_handler_ = 0;
426   }
427 }
428 #endif
429
430 void MediaSourcePlayerGstreamer::SetVolume(double volume) {
431   if (audio_volume_)
432     g_object_set(G_OBJECT(audio_volume_), "volume", volume, NULL);
433 }
434
435 void MediaSourcePlayerGstreamer::OnDemuxerConfigsAvailable(
436     const DemuxerConfigs& configs) {
437   if (IsPlayerDestructing())
438     return;
439
440   // Video elements
441   GstElement* video_parse = NULL;
442   GstElement* video_decoder = NULL;
443
444   // Audio elements
445   GstElement* audio_decoder = NULL;
446   GstElement* audio_parse = NULL;
447   GstElement* audio_convert = NULL;
448   GstElement* audio_resampler = NULL;
449   GstElement* audio_sink = NULL;
450
451   if ((configs.video_codec == kUnknownVideoCodec ||
452       configs.video_codec != kCodecH264) &&
453       (configs.audio_codec == kUnknownAudioCodec ||
454       (configs.audio_codec != kCodecAAC &&
455       configs.audio_codec != kCodecMP3))) {
456     LOG(ERROR) << "Audio and Video codecs not supported for MediaSource";
457     HandleError(MediaPlayerEfl::NetworkStateFormatError);
458     return;
459   }
460
461   width_ = configs.video_size.width();
462   height_ = configs.video_size.height();
463
464   if (pipeline_ != NULL)
465     return;
466
467   if (!gst_is_initialized())
468     gst_init_check(NULL, NULL, 0);
469
470   if (!gst_is_initialized()) {
471     LOG(ERROR) << "Unable to initialize GST";
472     HandleError(MediaPlayerEfl::NetworkStateDecodeError);
473     return;
474   }
475
476   pipeline_ = gst_pipeline_new(kPipelineName);
477   if (!pipeline_) {
478     LOG(ERROR) << "Unable to Create |Pipeline|";
479     HandleError(MediaPlayerEfl::NetworkStateDecodeError);
480     return;
481   }
482
483   for (int i = 0; VideoMapping[i].codec != kUnknownVideoCodec; i++) {
484     if (configs.video_codec == VideoMapping[i].codec) {
485       media_type_ |= MEDIA_VIDEO_MASK;
486       video_appsrc_ = gst_element_factory_make("appsrc", "video-source");
487       if (video_appsrc_ && !gst_bin_add(GST_BIN(pipeline_), video_appsrc_)) {
488         gst_object_unref(video_appsrc_);
489         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
490         return;
491       }
492       video_parse = gst_element_factory_make(VideoMapping[i].elements[0],
493                                              "video-parse");
494       if (video_parse && !gst_bin_add(GST_BIN(pipeline_), video_parse)) {
495         gst_object_unref(video_parse);
496         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
497         return;
498       }
499       video_queue_ = gst_element_factory_make("queue2", "video-queue");
500       if (video_queue_ && !gst_bin_add(GST_BIN(pipeline_), video_queue_)) {
501         gst_object_unref(video_queue_);
502         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
503         return;
504       }
505       video_decoder = gst_element_factory_make(VideoMapping[i].elements[1],
506                                                "video-decoder");
507       if (video_decoder && !gst_bin_add(GST_BIN(pipeline_), video_decoder)) {
508         gst_object_unref(video_decoder);
509         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
510         return;
511       }
512 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
513       PrepareForVideoSink();
514       CreatePixmap();
515 #else
516       PrepareForVideoFrame();
517 #endif
518       if (video_sink_ && !gst_bin_add(GST_BIN(pipeline_), video_sink_)) {
519         gst_object_unref(video_sink_);
520         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
521         return;
522       }
523
524       g_object_set(GST_OBJECT(video_appsrc_), "format", GST_FORMAT_TIME,
525                    NULL);
526       g_object_set(GST_OBJECT(video_appsrc_), "stream-type",
527                    GST_APP_STREAM_TYPE_SEEKABLE, NULL);
528       g_object_set(GST_OBJECT(video_appsrc_), "do-timestamp", false, NULL);
529
530       // Will make the queue to send GST_MESSAGE_BUFFERING
531       g_object_set(G_OBJECT(video_queue_), "use-buffering", true, NULL);
532
533       // Why |video_queue_| is placed after |video_appsrc_|?
534       // For understanding puprose consider http://tinyurl.com/qos-iron url.
535       // For 1080p resolution of the video in above url, each decoded frame
536       // is of size 2304000 bytes ~ 2.19 MB. If video_queue_ is placed before
537       // |video_sink_| then queue will buffer decoded frames, so to buffer
538       // two second worth of data queue will require 2304000*24(fps)*2 ~ 96MB
539       // of queue size. This property can't be set for pixmap backed playback
540       // as frame size won't be available for pixmap backed |video_sink|. And
541       // this size varies from video to video.
542       //
543       // But if |video_queue_| is placed after |video_appsrc_|, queue will
544       // buffer encoded data. For the same video of 1080p, maximum encoded
545       // frame is of 115398byte ~ 0.110052109 MB. So for 2 sec data, queue
546       // need to buffer 5308308bytes in queue ~ 5MB, this can be set
547       // dynamically. Refer |OnDemuxerDataAvailable| for setting queue size.
548
549       if (!gst_element_link_many(video_appsrc_, video_queue_, video_parse,
550                                  video_decoder, video_sink_, NULL)) {
551         LOG(ERROR) << "Video pipeline couldn't be created / linked";
552         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
553         return;
554       }
555
556       GstAppSrcCallbacks video_callbacks = {
557           OnGstStartVideoFeedCB,
558           OnGstStopVideoFeedCB,
559           OnGstSeekVideoFeedCB,
560           {NULL}};
561
562       gst_app_src_set_callbacks(GST_APP_SRC(video_appsrc_), &video_callbacks,
563                                 this, NULL);
564       break;
565     }
566   }
567
568   for (int i = 0; AudioMapping[i].codec != kUnknownAudioCodec; i++) {
569     if (configs.audio_codec == AudioMapping[i].codec) {
570       media_type_ |= MEDIA_AUDIO_MASK;
571       audio_appsrc_ = gst_element_factory_make("appsrc", "audio-source");
572       if (audio_appsrc_ && !gst_bin_add(GST_BIN(pipeline_), audio_appsrc_)) {
573         gst_object_unref(audio_appsrc_);
574         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
575         return;
576       }
577
578       audio_queue_ = gst_element_factory_make("queue2", "audio-queue");
579       if (audio_queue_ && !gst_bin_add(GST_BIN(pipeline_), audio_queue_)) {
580         gst_object_unref(audio_queue_);
581         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
582         return;
583       }
584
585       audio_parse = gst_element_factory_make(AudioMapping[i].elements[0],
586                                              "audio-parse");
587       if (audio_parse && !gst_bin_add(GST_BIN(pipeline_), audio_parse)) {
588         gst_object_unref(audio_parse);
589         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
590         return;
591       }
592
593       audio_decoder = gst_element_factory_make(AudioMapping[i].elements[1],
594                                                "audio-decoder");
595       if (audio_decoder && !gst_bin_add(GST_BIN(pipeline_), audio_decoder)) {
596         gst_object_unref(audio_decoder);
597         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
598         return;
599       }
600
601       audio_convert = gst_element_factory_make("audioconvert",
602                                                "audio-convert");
603       if (audio_convert && !gst_bin_add(GST_BIN(pipeline_), audio_convert)) {
604         gst_object_unref(audio_convert);
605         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
606         return;
607       }
608
609       audio_resampler = gst_element_factory_make("audioresample",
610                                                  "audio-resample");
611       if (audio_resampler &&
612           !gst_bin_add(GST_BIN(pipeline_), audio_resampler)) {
613         gst_object_unref(audio_resampler);
614         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
615         return;
616       }
617
618       audio_volume_ = gst_element_factory_make("volume", "volume");
619       if (audio_volume_ && !gst_bin_add(GST_BIN(pipeline_), audio_volume_)) {
620         gst_object_unref(audio_volume_);
621         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
622         return;
623       }
624
625       audio_sink = gst_element_factory_make(AudioMapping[i].elements[2],
626                                             "audio-sink");
627       if (audio_sink && !gst_bin_add(GST_BIN(pipeline_), audio_sink)) {
628         gst_object_unref(audio_sink);
629         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
630         return;
631       }
632
633       g_object_set(GST_OBJECT(audio_appsrc_), "format", GST_FORMAT_TIME,
634                    NULL);
635       g_object_set(GST_OBJECT(audio_appsrc_), "stream-type",
636                    GST_APP_STREAM_TYPE_SEEKABLE, NULL);
637       g_object_set(GST_OBJECT(audio_appsrc_), "do-timestamp", false, NULL);
638       g_object_set(G_OBJECT(audio_queue_), "use-buffering", true, NULL);
639       g_object_set(G_OBJECT(audio_volume_), "mute", false, NULL);
640
641       if (!gst_element_link_many(audio_appsrc_, audio_queue_, audio_parse,
642                                  audio_decoder, audio_convert,
643                                  audio_resampler, audio_volume_,
644                                  audio_sink, NULL)) {
645         LOG(ERROR) << "Not all elements of audio pipeline could be linked";
646         HandleError(MediaPlayerEfl::NetworkStateDecodeError);
647       }
648
649       GstAppSrcCallbacks audio_callbacks = {
650           OnGstStartAudioFeedCB,
651           OnGstStopAudioFeedCB,
652           OnGstSeekAudioFeedCB,
653           {NULL}};
654       gst_app_src_set_callbacks(GST_APP_SRC(audio_appsrc_),
655                                 &audio_callbacks, this, NULL);
656       break;
657     }
658   }
659
660   GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_));
661   if (!bus) {
662     LOG(ERROR) << "GStreamer bus creation failed";
663     HandleError(MediaPlayerEfl::NetworkStateDecodeError);
664     return;
665   }
666   gst_bus_set_sync_handler(
667       bus,
668       static_cast<GstBusSyncHandler>(GstPipelineMessageCB),
669       this,
670       NULL);
671   gst_object_unref(bus);
672
673   manager()->OnMediaDataChange(GetPlayerId(), video_format_, height_,
674                                width_, media_type_);
675   manager()->OnReadyStateChange(GetPlayerId(),
676                                 MediaPlayerEfl::ReadyStateHaveMetadata);
677
678   if (gst_element_set_state(pipeline_, GST_STATE_PAUSED) ==
679           GST_STATE_CHANGE_FAILURE) {
680     LOG(ERROR) << "GStreamer state change failed";
681   }
682 }
683
684 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
685 void MediaSourcePlayerGstreamer::PrepareForVideoSink() {
686   video_sink_ = gst_element_factory_make("xvimagesink", "sink");
687   DCHECK(video_sink_ != NULL) << "Failed to initialize xvimagesink.";
688   if (video_sink_ != NULL) {
689     GstPad* video_sink_pad = gst_element_get_static_pad(video_sink_, "sink");
690     if (!video_sink_pad) {
691       LOG(ERROR) << "GStreamer sink could not be obtained";
692       HandleError(MediaPlayerEfl::NetworkStateDecodeError);
693       return;
694     }
695     g_signal_connect(video_sink_pad, "notify::caps",
696                      G_CALLBACK(OnVideoSinkCapsChangedCB), this);
697     gst_object_unref(video_sink_pad);
698   }
699 }
700 #endif
701
702 void MediaSourcePlayerGstreamer::PrepareForVideoFrame() {
703   is_xwindow_handle_set_ = true;
704   video_sink_ = gst_element_factory_make("appsink", "sink");
705   GstAppSinkCallbacks callbacks = {
706       NULL,
707       OnGstAppsinkPreroll,
708       OnGstAppsinkBuffer};
709   gst_app_sink_set_callbacks(GST_APP_SINK(video_sink_),
710                              &callbacks, this, NULL);
711   g_object_set(G_OBJECT(video_sink_), "max-buffers",
712                static_cast<guint>(1), NULL);
713 }
714
715 void MediaSourcePlayerGstreamer::ReadDemuxedData(
716     media::DemuxerStream::Type type) {
717   if (IsPlayerDestructing())
718     return;
719
720   if (type == media::DemuxerStream::AUDIO) {
721     should_feed_audio_ = true;
722   } else if (type == media::DemuxerStream::VIDEO) {
723     should_feed_video_ = true;
724   } else {
725     LOG(ERROR) << "Unknown Media Type";
726     return;
727   }
728   demuxer_->RequestDemuxerData(type);
729 }
730
731 void MediaSourcePlayerGstreamer::OnReadDemuxedData(
732     media::DemuxerStream::Type type) {
733   if (IsPlayerDestructing()) {
734     LOG(ERROR) << "GST is deinitializing. Just return";
735     return;
736   }
737   task_runner_->PostTask(
738       FROM_HERE, base::Bind(&MediaSourcePlayerGstreamer::ReadDemuxedData,
739                             base::Unretained(this),
740                             type));
741 }
742
743 void MediaSourcePlayerGstreamer::OnStopDemuxedData(
744     media::DemuxerStream::Type type) {
745   if (type == media::DemuxerStream::AUDIO)
746     should_feed_audio_ = false;
747   else if (type == media::DemuxerStream::VIDEO)
748     should_feed_video_ = false;
749   else
750     LOG(ERROR) << "Unknown media stream!";
751 }
752
753 void MediaSourcePlayerGstreamer::OnDemuxerDataAvailable(
754     base::SharedMemoryHandle foreign_memory_handle,
755     const media::DemuxedBufferMetaData& meta_data) {
756   if (!pipeline_ || error_occured_) {
757     LOG(ERROR) << "Pipeline_ null or error occured";
758     return;
759   }
760   if (meta_data.status != media::DemuxerStream::kOk ||
761       meta_data.end_of_stream)
762     BufferMetaDataAvailable(meta_data);
763   if (meta_data.size <= 0) {
764     LOG(ERROR) << "ERROR : Size of shared memory is Zero";
765     return;
766   }
767
768   int64 metadata_timestamp_in_ms = meta_data.timestamp.InMicroseconds() * 1000;
769   if (is_seeking_ && !is_seeking_iframe_) {
770     if (meta_data.type == media::DemuxerStream::VIDEO) {
771       is_seeking_iframe_ = true;
772       if (video_seek_offset_ >
773               static_cast<guint64>(metadata_timestamp_in_ms)) {
774         int64 time = metadata_timestamp_in_ms + kSixteenMilliSeconds;
775         RequestPlayerSeek(ConvertNanoSecondsToSeconds(time));
776         return;
777       }
778     } else if (meta_data.type == media::DemuxerStream::AUDIO) {
779         if (audio_seek_offset_ >
780                 static_cast<guint64>(metadata_timestamp_in_ms))
781           return;
782     }
783   }
784
785   ReadFromQueueIfAny(meta_data.type);
786   if (meta_data.type == media::DemuxerStream::VIDEO) {
787     if (meta_data.size != raw_video_frame_size_) {
788       // Dynamically Changing Video Queue Size for Smooth Playback.
789       // The default queue size limits are 100 buffers, 2MB of data,
790       // or two seconds worth of data, whichever is reached first.
791       // Adjust queue to contain two seconds worth of data for smooth playback.
792       // So need to adjust number of buffers (max-size-buffers >= 2*fps) and
793       // maximum size of queue (max-size-bytes >= 2*fps*meta_data.size).
794       //
795       // 1000000 micro seconds = 1 second.
796       // 2097152 bytes = 2 MB.
797       int no_frames_per_two_second , queue_size_for_two_sec;
798       raw_video_frame_size_ = meta_data.size;
799       no_frames_per_two_second = 2 * (1000000 /
800           (meta_data.time_duration.InMicroseconds()));
801       queue_size_for_two_sec =
802           raw_video_frame_size_ * no_frames_per_two_second;
803       if (no_frames_per_two_second > 100) {
804         g_object_set(G_OBJECT(video_queue_), "max-size-buffers",
805                      static_cast<guint>(no_frames_per_two_second), NULL);
806       }
807       if (queue_size_for_two_sec > 2 * kBytesPerMegabyte) {
808         g_object_set(G_OBJECT(video_queue_), "max-size-bytes",
809                      static_cast<guint>(queue_size_for_two_sec), NULL);
810       }
811     }
812   }
813   if (meta_data.type == media::DemuxerStream::AUDIO && !should_feed_audio_) {
814     // Why store the DecoderBuffer? we have requested for buffer
815     // from demuxer but gstreamer asked to stop. So need to save
816     // this buffer and use it on next |need_data| call.
817     SaveDecoderBuffer(foreign_memory_handle, meta_data);
818     return;
819   }
820   if (meta_data.type == media::DemuxerStream::VIDEO && !should_feed_video_) {
821     SaveDecoderBuffer(foreign_memory_handle, meta_data);
822     return;
823   }
824
825   // Wrapping each frame and deleting shared memory using callback
826   // will not work as possibility of Gstreamer retaining frames (such as
827   // 'i' frames) is high. In that case shared memory will crash. So, we
828   // copy frames and release shared memory right away.
829
830   base::SharedMemory shared_memory(foreign_memory_handle, false);
831   if (!shared_memory.Map(meta_data.size)) {
832     LOG(ERROR) << "Failed to map shared memory of size " << meta_data.size;
833     return;
834   }
835   gint size = meta_data.size;
836   GstFlowReturn ret = GST_FLOW_OK;
837   GstBuffer* buffer = gst_buffer_new_allocate(NULL, size, NULL);
838   gst_buffer_fill(buffer, 0, shared_memory.memory(), size);
839
840   GST_BUFFER_TIMESTAMP(buffer) =
841       static_cast<guint64>(metadata_timestamp_in_ms);
842   GST_BUFFER_DURATION(buffer) =
843       static_cast<guint64>(meta_data.time_duration.InMicroseconds() * 1000);
844
845   if (meta_data.type == media::DemuxerStream::AUDIO)
846     ret = gst_app_src_push_buffer(GST_APP_SRC(audio_appsrc_),
847                                   buffer);
848   else if (meta_data.type == media::DemuxerStream::VIDEO)
849     ret = gst_app_src_push_buffer(GST_APP_SRC(video_appsrc_),
850                                   buffer);
851
852   // gst_app_src_push_buffer() takes ownership of the buffer.
853   // Hence no need to unref buffer.
854   if (ret != GST_FLOW_OK) {
855     LOG(ERROR) << "Gstreamer appsrc push failed : " << ret;
856     return;
857   }
858
859   if (meta_data.type == media::DemuxerStream::AUDIO && should_feed_audio_)
860     OnReadDemuxedData(media::DemuxerStream::AUDIO);
861   else if (meta_data.type == media::DemuxerStream::VIDEO && should_feed_video_)
862     OnReadDemuxedData(media::DemuxerStream::VIDEO);
863   return;
864 }
865
866 void MediaSourcePlayerGstreamer::BufferMetaDataAvailable(
867     const media::DemuxedBufferMetaData& meta_data) {
868   if (!pipeline_ || error_occured_) {
869     LOG(ERROR) << "Pipeline_ null or error occured";
870     return;
871   }
872
873   switch (meta_data.status) {
874     case media::DemuxerStream::kAborted:
875       if (meta_data.type == media::DemuxerStream::AUDIO && should_feed_audio_)
876         OnReadDemuxedData(media::DemuxerStream::AUDIO);
877       else if (meta_data.type == media::DemuxerStream::VIDEO &&
878                should_feed_video_)
879         OnReadDemuxedData(media::DemuxerStream::VIDEO);
880       break;
881
882     case media::DemuxerStream::kConfigChanged:
883       if (meta_data.type == media::DemuxerStream::AUDIO && should_feed_audio_)
884         OnReadDemuxedData(media::DemuxerStream::AUDIO);
885       else if (meta_data.type == media::DemuxerStream::VIDEO &&
886                should_feed_video_)
887         OnReadDemuxedData(media::DemuxerStream::VIDEO);
888       break;
889
890     case media::DemuxerStream::kOk:
891       if (meta_data.end_of_stream) {
892         ReadFromQueueIfAny(meta_data.type);
893         LOG(ERROR) <<"[BROWSER] : DemuxerStream::kOk but |end_of_stream|";
894         if (meta_data.type == media::DemuxerStream::AUDIO)
895           gst_app_src_end_of_stream(GST_APP_SRC(audio_appsrc_));
896         if (meta_data.type == media::DemuxerStream::VIDEO)
897           gst_app_src_end_of_stream(GST_APP_SRC(video_appsrc_));
898         if (playing_)
899           Play();
900       }
901       break;
902
903     default:
904       NOTREACHED();
905   }
906 }
907
908 void MediaSourcePlayerGstreamer::ReadFromQueueIfAny(
909     DemuxerStream::Type type) {
910   if (!pipeline_ || error_occured_) {
911     LOG(ERROR) << "Pipeline_ null or error occured";
912     return;
913   }
914
915   if (type == media::DemuxerStream::AUDIO) {
916     if (audio_buffer_queue_.empty() || !should_feed_audio_)
917       return;
918   }
919
920   if (type == media::DemuxerStream::VIDEO) {
921     if (video_buffer_queue_.empty() || !should_feed_video_)
922       return;
923   }
924
925   scoped_refptr<DecoderBuffer> decoder_buffer;
926   if (type == media::DemuxerStream::AUDIO) {
927     decoder_buffer = audio_buffer_queue_.front();
928     audio_buffer_queue_.pop_front();
929   } else {
930     decoder_buffer = video_buffer_queue_.front();
931     video_buffer_queue_.pop_front();
932   }
933
934   // Wrapping each frame and deleting shared memory using callback
935   // will not work as possibility of Gstreamer retaining frames (such as
936   // 'i' frames) is high. In that case shared memory will crash. So, we
937   // copy frames and release shared memory right away.
938
939   GstFlowReturn ret;
940   gint size = decoder_buffer.get()->data_size();
941   GstBuffer* buffer = gst_buffer_new_allocate(NULL, size, NULL);
942   if (!buffer)
943     return;
944
945   gst_buffer_fill(buffer, 0, decoder_buffer.get()->writable_data(), size);
946
947   GST_BUFFER_TIMESTAMP(buffer) =
948       static_cast<guint64>(decoder_buffer.get()->timestamp().InMicroseconds() *
949                            1000);
950   GST_BUFFER_DURATION(buffer) =
951       static_cast<guint64>(decoder_buffer.get()->duration().InMicroseconds() *
952                            1000);
953
954   if (type == media::DemuxerStream::AUDIO)
955     ret = gst_app_src_push_buffer(GST_APP_SRC(audio_appsrc_), buffer);
956   else
957     ret = gst_app_src_push_buffer(GST_APP_SRC(video_appsrc_), buffer);
958   if (ret != GST_FLOW_OK)
959     return;
960
961   // Empty the Buffer before reading the new buffer from render process.
962   ReadFromQueueIfAny(type);
963   return;
964 }
965
966 void MediaSourcePlayerGstreamer::SaveDecoderBuffer(
967     base::SharedMemoryHandle foreign_memory_handle,
968     const media::DemuxedBufferMetaData& meta_data) {
969   if (!pipeline_ || error_occured_) {
970     LOG(ERROR) << "Pipeline_ null or error occured";
971     return;
972   }
973
974   base::SharedMemory shared_memory(foreign_memory_handle, false);
975   if (!shared_memory.Map(meta_data.size)) {
976     LOG(ERROR) << "Failed to map shared memory of size " << meta_data.size;
977     return;
978   }
979   scoped_refptr<DecoderBuffer> buffer;
980   buffer = DecoderBuffer::CopyFrom(static_cast<const uint8*> (
981       shared_memory.memory()), meta_data.size);
982
983   if (!buffer.get()) {
984     LOG(ERROR) << "DecoderBuffer::CopyFrom failed";
985     return;
986   }
987
988   buffer->set_timestamp(meta_data.timestamp);
989   buffer->set_duration(meta_data.time_duration);
990
991   if (meta_data.type == media::DemuxerStream::AUDIO)
992     audio_buffer_queue_.push_back(buffer);
993   else
994     video_buffer_queue_.push_back(buffer);
995 }
996
997 void MediaSourcePlayerGstreamer::GetFrameDetails() {
998   if (!pipeline_ || error_occured_)
999     return;
1000
1001   GstState state = GST_STATE_VOID_PENDING;
1002   GstState pending = GST_STATE_VOID_PENDING;
1003   gst_element_get_state(pipeline_, &state, &pending, 250 * GST_NSECOND);
1004
1005   // Get details only after prerolling.
1006   if (pending >= GST_STATE_PAUSED)
1007     task_runner_->PostTask(
1008         FROM_HERE,
1009         base::Bind(&MediaSourcePlayerGstreamer::OnGetFrameDetails,
1010                    base::Unretained(this)));
1011 }
1012
1013 void MediaSourcePlayerGstreamer::OnGetFrameDetails() {
1014   if (!pipeline_ || IsPlayerDestructing() || error_occured_)
1015     return;
1016
1017   GstSample* sample = gst_app_sink_pull_preroll(GST_APP_SINK(video_sink_));
1018   if (!sample)
1019     return;
1020
1021   if (!GetGstVideoBufferMetaData(sample, &width_,
1022                                  &height_, &video_format_)) {
1023     gst_sample_unref(sample);
1024     return;
1025   }
1026
1027   gst_sample_unref(sample);
1028
1029   if (video_format_ == GST_VIDEO_SN12)
1030     sn12_bufsize_ = GetSN12BufferSize(width_, height_);
1031
1032   manager()->OnMediaDataChange(GetPlayerId(), video_format_, height_,
1033                                width_, media_type_);
1034 }
1035
1036 GstSample* MediaSourcePlayerGstreamer::PullSample() {
1037   return gst_app_sink_pull_sample(GST_APP_SINK(video_sink_));
1038 }
1039
1040 void MediaSourcePlayerGstreamer::OnNewFrameAvailable(GstSample* sample) {
1041   if (!sample)
1042     return;
1043
1044   if (!pipeline_ || error_occured_) {
1045     gst_sample_unref(sample);
1046     return;
1047   }
1048
1049   GstMapInfo map;
1050   GstBuffer* buffer = gst_sample_get_buffer(sample);
1051   if (!gst_buffer_map(buffer, &map, GST_MAP_READ)) {
1052     LOG(ERROR) << "Sample contains invalid or no info!";
1053     return;
1054   }
1055
1056   if (!width_ || !height_)
1057     GetFrameDetails();
1058   int width;
1059   int height;
1060   if (!GetGstVideoBufferMetaData(sample, &width,
1061                                  &height, NULL)) {
1062     gst_sample_unref(sample);
1063     return;
1064   }
1065
1066   if (width != width_ || height != height_) {
1067     width_ = width;
1068     height_ = height;
1069     manager()->OnMediaDataChange(GetPlayerId(), video_format_, height_,
1070                                  width_, media_type_);
1071   }
1072   base::SharedMemory shared_memory;
1073   uint32 shared_memory_size = 0;
1074   base::SharedMemoryHandle foreign_memory_handle;
1075
1076   base::TimeDelta timestamp =
1077       base::TimeDelta::FromMicroseconds(
1078           GST_BUFFER_TIMESTAMP(buffer) /
1079           base::Time::kNanosecondsPerMicrosecond);
1080
1081   if (video_format_ == GST_VIDEO_SN12)
1082     shared_memory_size = (sn12_bufsize_);
1083   else
1084     shared_memory_size = (map.size);
1085
1086   if (!shared_memory.CreateAndMapAnonymous(shared_memory_size)) {
1087     LOG(ERROR) << "Shared Memory creation failed.";
1088     gst_buffer_unmap(buffer, &map);
1089     gst_sample_unref(sample);
1090     return;
1091   }
1092
1093   if (!shared_memory.ShareToProcess(base::Process::Current().Handle(),
1094       &foreign_memory_handle)) {
1095     LOG(ERROR) << "Shared Memory handle could not be obtained";
1096     gst_buffer_unmap(buffer, &map);
1097     gst_sample_unref(sample);
1098     return;
1099   }
1100
1101   memcpy(shared_memory.memory(), map.data, shared_memory_size);
1102   manager()->OnNewFrameAvailable(
1103       GetPlayerId(), foreign_memory_handle, shared_memory_size, timestamp);
1104
1105   gst_buffer_unmap(buffer, &map);
1106   gst_sample_unref(sample);
1107 }
1108
1109 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
1110 void MediaSourcePlayerGstreamer::XWindowIdPrepared(GstMessage* message) {
1111   const GstStructure* structure = gst_message_get_structure(message);
1112
1113   gst_structure_get_int(structure, "video-width", &width_);
1114   gst_structure_get_int(structure, "video-height", &height_);
1115   SetPixmap();
1116   manager()->OnMediaDataChange(GetPlayerId(), video_format_, height_,
1117                                width_, media_type_);
1118 }
1119
1120 void MediaSourcePlayerGstreamer::PlatformSurfaceUpdated() {
1121   gint64 current_time = 0;
1122   GstFormat format = GST_FORMAT_TIME;
1123   gst_element_query_position(pipeline_, format, &current_time);
1124   base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
1125       current_time / base::Time::kNanosecondsPerMicrosecond);
1126   manager()->OnPlatformSurfaceUpdated(GetPlayerId(), pixmap_id_, timestamp);
1127 }
1128
1129 int MediaSourcePlayerGstreamer::GetSurfaceID() const {
1130   return pixmap_id_;
1131 }
1132
1133 void MediaSourcePlayerGstreamer::SetPixmap() {
1134 #if defined(OS_TIZEN_TV)
1135   // Using below statements on mobile to set pixmap was causing two issue.
1136   // 1. Video size was different than the required one whenever configaration
1137   // changed
1138   // 2. Sometime black screen was appearing, while video was playing.
1139   // Hence for mobile keeping implementation which uses
1140   // |gst_x_overlay_set_window_handle|to sep Pixmap.
1141   g_object_set(video_sink_, "pixmap-id-callback", GetPixmapIdCB, NULL);
1142   g_object_set(video_sink_, "pixmap-id-callback-userdata", this, NULL);
1143 #else
1144   gst_x_overlay_set_window_handle(GST_X_OVERLAY(video_sink_), pixmap_id_);
1145 #endif
1146   m_damage_ = ecore_x_damage_new(pixmap_id_,
1147                                  ECORE_X_DAMAGE_REPORT_RAW_RECTANGLES);
1148   m_damage_handler_ = ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY,
1149                                               NotifyDamageUpdatedCB, this);
1150   g_object_set(video_sink_, "rotate", 0, NULL);
1151   is_xwindow_handle_set_ = true;
1152 }
1153
1154 void MediaSourcePlayerGstreamer::OnVideoConfigsChanged() {
1155   if (!pipeline_ || error_occured_)
1156     return;
1157   task_runner_->PostTask(
1158       FROM_HERE,
1159       base::Bind(&MediaSourcePlayerGstreamer::VideoConfigsChanged,
1160                  base::Unretained(this)));
1161 }
1162
1163 void MediaSourcePlayerGstreamer::VideoConfigsChanged() {
1164   if (!pipeline_ || IsPlayerDestructing() || error_occured_)
1165     return;
1166
1167   GstPad* video_sink_pad = gst_element_get_static_pad(video_sink_, "sink");
1168   GstCaps* caps = gst_pad_get_current_caps(GST_PAD(video_sink_pad));
1169   if (!caps) {
1170     LOG(ERROR) << "Cannot get CAPS!";
1171     gst_object_unref(video_sink_pad);
1172     return;
1173   }
1174
1175   GstVideoInfo info;
1176   gst_video_info_init(&info);
1177   if (!gst_video_info_from_caps(&info, caps)) {
1178     LOG(ERROR) << "Cannot get information from CAPS!";
1179     gst_caps_unref(caps);
1180     gst_object_unref(video_sink_pad);
1181     return;
1182   }
1183
1184   if ((width_ != info.width) || (height_ != info.height)) {
1185     LOG(ERROR) << "Demuxer Video Configs and Gstreamer Video Configs doesn't"
1186                <<" match.From Demuxer : width : " << width_
1187                << " and height :" << height_
1188                << " | From Gstreamer width : " << info.width
1189                << " and Height : " << info.height;
1190     width_ = info.width;
1191     height_ = info.height;
1192     UnregisterDamageHandler();
1193     CreatePixmap();
1194     SetPixmap();
1195     manager()->OnMediaDataChange(
1196         GetPlayerId(), video_format_, height_, width_, media_type_);
1197   }
1198   gst_caps_unref(caps);
1199   gst_object_unref(video_sink_pad);
1200 }
1201
1202 void MediaSourcePlayerGstreamer::CreatePixmap() {
1203   bool is_create_new = efl_pixmaps_map_.empty();
1204   int int_wh = GetUniqueKey(width_, height_);
1205
1206   if (!is_create_new) {
1207     EflPixmapMap::iterator it = efl_pixmaps_map_.find(int_wh);
1208     if (it != efl_pixmaps_map_.end()) {
1209       is_create_new = false;
1210       efl_pixmap_ = it->second;
1211       pixmap_id_ = efl_pixmap_->GetId();
1212     } else {
1213       is_create_new = true;
1214     }
1215   }
1216
1217   if (is_create_new) {
1218     efl_pixmap_ = gfx::EflPixmap::Create(gfx::EflPixmap::SURFACE,
1219                                          gfx::Size(width_, height_));
1220     if (!efl_pixmap_.get()) {
1221       LOG(ERROR) << "gfx::EflPixmap::Create() failed to create Pixmap";
1222       return;
1223     }
1224     pixmap_id_ = efl_pixmap_->GetId();
1225     efl_pixmaps_map_[int_wh] = efl_pixmap_;
1226   }
1227 }
1228 #endif
1229
1230 void MediaSourcePlayerGstreamer::OnDemuxerDurationChanged(
1231     base::TimeDelta duration) {
1232   duration_ = duration.InSecondsF();
1233 }
1234
1235 void MediaSourcePlayerGstreamer::OnDemuxerSeekDone(
1236     const base::TimeDelta& actual_browser_seek_time) {
1237   SeekInternal(ConvertToGstClockTime(actual_browser_seek_time.InSecondsF()));
1238 }
1239
1240 bool MediaSourcePlayerGstreamer::HasVideo() {
1241   return media_type_ & MEDIA_VIDEO_MASK;
1242 }
1243
1244 bool MediaSourcePlayerGstreamer::HasAudio() {
1245   return media_type_ & MEDIA_AUDIO_MASK;
1246 }
1247
1248 void MediaSourcePlayerGstreamer::OnCurrentTimeUpdateTimerFired() {
1249   manager()->OnTimeUpdate(GetPlayerId(), GetCurrentTime());
1250 }
1251
1252 void MediaSourcePlayerGstreamer::StartCurrentTimeUpdateTimer() {
1253   if (!current_time_update_timer_.IsRunning()) {
1254     current_time_update_timer_.Start(
1255         FROM_HERE,
1256         base::TimeDelta::FromMilliseconds(kDurationUpdateInterval),
1257         this,
1258         &MediaSourcePlayerGstreamer::OnCurrentTimeUpdateTimerFired);
1259   }
1260 }
1261
1262 void MediaSourcePlayerGstreamer::StopCurrentTimeUpdateTimer() {
1263   if (current_time_update_timer_.IsRunning())
1264     current_time_update_timer_.Stop();
1265 }
1266
1267 void MediaSourcePlayerGstreamer::HandleMessage(GstMessage* message) {
1268   if (!pipeline_ || error_occured_)
1269     return;
1270
1271   switch (GST_MESSAGE_TYPE(message)) {
1272     case GST_MESSAGE_ERROR: {
1273       GError* error = NULL;
1274       MediaPlayerEfl::NetworkState network_state_error =
1275           MediaPlayerEfl::NetworkStateEmpty;
1276       gst_message_parse_error(message, &error, NULL);
1277       if (error->code == GST_STREAM_ERROR_CODEC_NOT_FOUND ||
1278           error->code == GST_STREAM_ERROR_WRONG_TYPE ||
1279           error->code == GST_STREAM_ERROR_FAILED ||
1280           error->code == GST_RESOURCE_ERROR_NOT_FOUND) {
1281         network_state_error = MediaPlayerEfl::NetworkStateFormatError;
1282       } else if (error->domain == GST_RESOURCE_ERROR) {
1283         network_state_error = MediaPlayerEfl::NetworkStateNetworkError;
1284       } else {
1285         network_state_error = MediaPlayerEfl::NetworkStateDecodeError;
1286       }
1287
1288       LOG(ERROR) << "Error Message : " << error->message << " Recieved From : "
1289                  << GST_MESSAGE_SRC_NAME(message)
1290                  << ", and Blink Error Code  = " << network_state_error;
1291       g_error_free(error);
1292       HandleError(network_state_error);
1293       break;
1294     }
1295     case GST_MESSAGE_EOS:
1296       task_runner_->PostTask(FROM_HERE, base::Bind(
1297           &MediaSourcePlayerGstreamer::OnPlaybackComplete,
1298           base::Unretained(this)));
1299       break;
1300     case GST_MESSAGE_ASYNC_DONE:
1301       if (is_seeking_) {
1302         is_seeking_iframe_ = false;
1303         task_runner_->PostTask(
1304             FROM_HERE,
1305             base::Bind(&MediaSourcePlayerGstreamer::UpdateSeekState,
1306                        base::Unretained(this),
1307                        false));
1308
1309         // Initiate play for internal seeks.
1310         if (playing_)
1311           task_runner_->PostTask(FROM_HERE,
1312                                  base::Bind(&MediaSourcePlayerGstreamer::Play,
1313                                  base::Unretained(this)));
1314
1315         manager()->OnTimeUpdate(GetPlayerId(), GetCurrentTime());
1316         task_runner_->PostTask(
1317             FROM_HERE,
1318             base::Bind(&MediaSourcePlayerGstreamer::OnTimeChanged,
1319                        base::Unretained(this)));
1320       }
1321       break;
1322     case GST_MESSAGE_STATE_CHANGED:
1323       if (strcmp(kPipelineName, GST_MESSAGE_SRC_NAME(message)))
1324         break;
1325       task_runner_->PostTask(
1326             FROM_HERE,
1327             base::Bind(&MediaSourcePlayerGstreamer::OnUpdateStates,
1328                        base::Unretained(this)));
1329       break;
1330     case GST_MESSAGE_BUFFERING: {
1331       int buffered = 0;
1332       gst_message_parse_buffering(message, &buffered);
1333
1334       if (audio_queue_ && GST_MESSAGE_SRC(message) ==
1335               GST_OBJECT(audio_queue_))
1336         audio_buffered_ = buffered;
1337       else if (video_queue_ && GST_MESSAGE_SRC(message) ==
1338                    GST_OBJECT(video_queue_))
1339         video_buffered_ = buffered;
1340
1341       if (playing_) {
1342         task_runner_->PostTask(
1343             FROM_HERE,
1344             base::Bind(&MediaSourcePlayerGstreamer::HandleBufferingMessage,
1345                        base::Unretained(this)));
1346       }
1347       break;
1348     }
1349     case GST_MESSAGE_ELEMENT:
1350 #if defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
1351       if (!IsXWindowHandleSet() &&
1352           gst_is_video_overlay_prepare_window_handle_message(message)) {
1353         XWindowIdPrepared(message);
1354       }
1355       break;
1356 #endif
1357     default:
1358       break;
1359   }
1360 }
1361
1362 void MediaSourcePlayerGstreamer::OnUpdateStates() {
1363   DCHECK(task_runner_->BelongsToCurrentThread());
1364   if (!pipeline_ || IsPlayerDestructing() || error_occured_)
1365     return;
1366
1367   GstState state = GST_STATE_VOID_PENDING;
1368   GstState pending = GST_STATE_VOID_PENDING;
1369   GstStateChangeReturn ret = gst_element_get_state(
1370       pipeline_, &state, &pending, 250 * GST_NSECOND);
1371
1372   switch (ret) {
1373   case GST_STATE_CHANGE_SUCCESS:
1374     switch (state) {
1375     case GST_STATE_PAUSED:
1376       manager()->OnReadyStateChange(
1377           GetPlayerId(),
1378           MediaPlayerEfl::ReadyStateHaveEnoughData);
1379       break;
1380     default:
1381       break;
1382     }
1383     break;
1384   case GST_STATE_CHANGE_FAILURE:
1385     LOG(ERROR) << "Failure: State: "
1386                << gst_element_state_get_name(state)
1387                << " pending: "
1388                << gst_element_state_get_name(pending);
1389     HandleError(MediaPlayerEfl::NetworkStateDecodeError);
1390     break;
1391   case GST_STATE_CHANGE_NO_PREROLL:
1392   default:
1393     break;
1394   }
1395 }
1396
1397 void MediaSourcePlayerGstreamer::HandleBufferingMessage() {
1398   if (IsPlayerDestructing())
1399     return;
1400   if (!is_paused_due_underflow_ &&
1401       ((HasAudio() && audio_buffered_ < kMaxBufPercent) ||
1402         (HasVideo() && video_buffered_ < kMaxBufPercent))) {
1403     is_paused_due_underflow_ = true;
1404     Pause(true);
1405     manager()->OnReadyStateChange(
1406         GetPlayerId(),
1407         MediaPlayerEfl::ReadyStateHaveCurrentData);
1408     manager()->OnNetworkStateChange(
1409         GetPlayerId(),
1410         MediaPlayerEfl::NetworkStateLoading);
1411   } else if (is_paused_due_underflow_ &&
1412              (!HasAudio() || audio_buffered_ == kMaxBufPercent) &&
1413              (!HasVideo() || video_buffered_ == kMaxBufPercent)) {
1414     is_paused_due_underflow_ = false;
1415     Play();
1416     manager()->OnReadyStateChange(
1417         GetPlayerId(),
1418         MediaPlayerEfl::ReadyStateHaveEnoughData);
1419     manager()->OnNetworkStateChange(
1420         GetPlayerId(),
1421         MediaPlayerEfl::NetworkStateLoaded);
1422   }
1423 }
1424
1425 void MediaSourcePlayerGstreamer::OnPlaybackComplete() {
1426   // GStreamer pipeline EOS time and media duration doesnt match.
1427   double time = GetCurrentTime() != duration_ ? duration_ : GetCurrentTime();
1428   is_end_reached_ = true;
1429   is_download_finished_ = false;
1430   StopCurrentTimeUpdateTimer();
1431   manager()->OnTimeUpdate(GetPlayerId(), time);
1432   manager()->OnTimeChanged(GetPlayerId());
1433 #if defined(OS_TIZEN_MOBILE)
1434   ReleaseDisplayLock();
1435 #endif
1436 }
1437
1438 void MediaSourcePlayerGstreamer::UpdateSeekState(bool state) {
1439   manager()->OnSeekStateChange(GetPlayerId(), state);
1440   is_seeking_ = state;
1441 }
1442
1443 void MediaSourcePlayerGstreamer::OnTimeChanged() {
1444   DCHECK(task_runner_->BelongsToCurrentThread());
1445   manager()->OnTimeChanged(GetPlayerId());
1446 }
1447
1448 void MediaSourcePlayerGstreamer::HandleError(
1449     media::MediaPlayerEfl::NetworkState state) {
1450   error_occured_ = true;
1451   manager()->OnNetworkStateChange(GetPlayerId(), state);
1452 #if defined(OS_TIZEN_MOBILE)
1453   ReleaseDisplayLock();
1454 #endif
1455 }
1456
1457 }  // namespace media