[M49_2623] Chromium upversion to m49_2623 branch.
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / media / base / tizen / media_source_player_capi.cc
1 // Copyright 2015 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 "base/process/process.h"
6 #include "base/thread_task_runner_handle.h"
7 #include "content/browser/media/efl/browser_demuxer_efl.h"
8 #include "media/base/efl/media_player_manager_efl.h"
9 #include "media/base/tizen/media_source_player_capi.h"
10 #include "third_party/libyuv/include/libyuv.h"
11
12 namespace {
13 const int kDurationUpdateInterval = 100;
14
15 // Waiting time for buffering while seeking.
16 const double kSeekBufferingWaitInSec = 2;
17
18 // CAPI internal appsrc buffer size.
19 const uint64 max_size = 2097152;  // 2MB
20
21 // Appsrc minimum buffering level
22 const unsigned int min_threshold = 30;
23
24 }  // namespace
25
26 namespace media {
27 void OnCapiPlayerPreparedCB(void* user_data) {
28   MediaSourcePlayerCapi* player =
29       static_cast<MediaSourcePlayerCapi*>(user_data);
30   player->OnPrepareComplete();
31 }
32
33 void OnSeekCompleteCB(void* user_data) {
34   MediaSourcePlayerCapi* player =
35       static_cast<MediaSourcePlayerCapi*>(user_data);
36   player->OnSeekComplete();
37 }
38
39 void OnHandleBufferingMessageCB(int percent, void* user_data) {
40   MediaSourcePlayerCapi* player =
41       static_cast<MediaSourcePlayerCapi*>(user_data);
42   player->OnHandleBufferingMessage(percent);
43 }
44
45 void OnCapiAudioBufStatusCB(player_media_stream_buffer_status_e status,
46                             void* user_data) {
47   MediaSourcePlayerCapi* player =
48       static_cast<MediaSourcePlayerCapi*>(user_data);
49   if (status == PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN) {
50     player->OnUpdateDataStatus(media::DemuxerStream::AUDIO, true);
51   } else if (status == PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW) {
52     player->OnUpdateDataStatus(media::DemuxerStream::AUDIO, false);
53   }
54 }
55
56 void OnCapiVideoBufStatusCB(player_media_stream_buffer_status_e status,
57                             void* user_data) {
58   MediaSourcePlayerCapi* player =
59       static_cast<MediaSourcePlayerCapi*>(user_data);
60   if (status == PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN) {
61     player->OnUpdateDataStatus(media::DemuxerStream::VIDEO, true);
62   } else if (status == PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW) {
63     player->OnUpdateDataStatus(media::DemuxerStream::VIDEO, false);
64   }
65 }
66
67 static void OnMediaPacketDecoded(media_packet_h packet, void* data) {
68   if (!packet) {
69     LOG(ERROR) << "media_packet handle is null";
70     return;
71   }
72
73   MediaSourcePlayerCapi* player = static_cast<MediaSourcePlayerCapi*>(data);
74   player->OnMediaPacketUpdated(packet);
75 }
76
77 void OnPlaybackCompleteCB(void* user_data) {
78   LOG(INFO) << "On playback complete Call back";
79   MediaSourcePlayerCapi* player =
80     static_cast<MediaSourcePlayerCapi*>(user_data);
81
82   if (!player)
83     return;
84
85   player->OnPlaybackComplete();
86 }
87
88 void OnPlayerErrorCB(int error_code, void* user_data) {
89   MediaSourcePlayerCapi* player =
90     static_cast<MediaSourcePlayerCapi*>(user_data);
91
92   if (!player)
93     return;
94
95   player->OnHandlePlayerError(error_code, FROM_HERE);
96 }
97
98 void MediaSourcePlayerCapi::PrepareComplete() {
99   player_prepared_ = true;
100   manager()->OnReadyStateChange(
101       GetPlayerId(), blink::WebMediaPlayer::ReadyStateHaveEnoughData);
102   manager()->OnNetworkStateChange(
103       GetPlayerId(), blink::WebMediaPlayer::NetworkStateLoaded);
104 }
105
106 MediaPlayerEfl* MediaPlayerEfl::CreatePlayer(
107     int player_id, content::BrowserDemuxerEfl* demuxer,
108     int demuxer_id, MediaPlayerManager* manager) {
109   LOG(INFO) << "MediaSourceElement is using |CAPI| to play media";
110   return new MediaSourcePlayerCapi(player_id,
111                                    demuxer->CreateDemuxer(demuxer_id),
112                                    manager);
113 }
114
115 MediaSourcePlayerCapi::MediaSourcePlayerCapi(int player_id,
116                                              scoped_ptr<DemuxerEfl> demuxer,
117                                              MediaPlayerManager* manager)
118     : MediaPlayerEfl(player_id, manager),
119       demuxer_(std::move(demuxer)),
120       task_runner_(base::ThreadTaskRunnerHandle::Get()),
121       weak_this_(this),
122       player_(NULL),
123       media_type_(0),
124       duration_(0),
125       play_rate_(1.0f),
126       player_prepared_(false),
127       playing_(false),
128       is_end_reached_(false),
129       eos_audio_(false),
130       eos_video_(false),
131       error_occured_(false),
132       should_feed_audio_(false),
133       should_feed_video_(false),
134       seek_offset_(0),
135       seek_state_(MEDIA_SEEK_NONE),
136       media_packet_(NULL),
137       audio_format_(NULL),
138       video_format_(NULL),
139       weak_factory_(this) {
140   demuxer_->Initialize(this);
141   audio_buffer_queue_.clear();
142   video_buffer_queue_.clear();
143
144   /*Init Player*/
145   int ret = player_create(&player_);
146   if (ret != PLAYER_ERROR_NONE) {
147     OnHandlePlayerError(ret, FROM_HERE);
148     return;
149   }
150
151   ret = player_set_buffering_cb(player_, OnHandleBufferingMessageCB, this);
152   if (ret != PLAYER_ERROR_NONE) {
153     OnHandlePlayerError(ret, FROM_HERE);
154     return;
155   }
156
157   ret = player_set_sound_type(player_, SOUND_TYPE_MEDIA);
158   if (ret != PLAYER_ERROR_NONE) {
159     OnHandlePlayerError(ret, FROM_HERE);
160     return;
161   }
162   ret = player_set_error_cb(player_, OnPlayerErrorCB, this);
163   if (ret != PLAYER_ERROR_NONE) {
164     OnHandlePlayerError(ret, FROM_HERE);
165     return;
166   }
167   ret = player_set_completed_cb(player_, OnPlaybackCompleteCB, this);
168   if (ret != PLAYER_ERROR_NONE) {
169     OnHandlePlayerError(ret, FROM_HERE);
170     return;
171   }
172
173   ret = player_set_media_packet_video_frame_decoded_cb(
174             player_, OnMediaPacketDecoded, this);
175   if (ret != PLAYER_ERROR_NONE) {
176     OnHandlePlayerError(ret, FROM_HERE);
177     return;
178   }
179
180   player_set_display_visible(player_, true);
181
182   ret = player_set_uri(player_, "es_buff://push_mode");
183   if (ret != PLAYER_ERROR_NONE) {
184     OnHandlePlayerError(ret, FROM_HERE);
185     return;
186   }
187 }
188
189 MediaSourcePlayerCapi::~MediaSourcePlayerCapi() {
190   Release();
191   player_destroy(player_);
192 }
193
194 void MediaSourcePlayerCapi::SeekComplete() {
195   DCHECK(task_runner_->BelongsToCurrentThread());
196   UpdateSeekState(MEDIA_SEEK_NONE);
197
198   // Initiate play for internal seeks.
199   if (GetPlayerState() != PLAYER_STATE_PLAYING)
200     Play();
201
202   manager()->OnTimeUpdate(GetPlayerId(), GetCurrentTime());
203   manager()->OnTimeChanged(GetPlayerId());
204 }
205
206
207 void MediaSourcePlayerCapi::UpdateSeekState(MediaSeekState state) {
208   switch (state) {
209     // Notify manager about player seek complete.
210     case MEDIA_SEEK_NONE:
211       manager()->OnSeekStateChange(GetPlayerId(), false);
212       break;
213
214     // Notify manager about player seek start.
215     case MEDIA_SEEK_PLAYER:
216       manager()->OnSeekStateChange(GetPlayerId(), true);
217       break;
218
219     // No need to notify manager about seek state change.
220     case MEDIA_SEEK_DEMUXER:
221     case MEDIA_SEEK_DEMUXER_DONE:
222       break;
223
224     default:
225       NOTREACHED();
226       break;
227   }
228
229   seek_state_ = state;
230 }
231
232 void MediaSourcePlayerCapi::SetRate(double rate) {
233   if (play_rate_ == rate)
234     return;
235
236   if (rate == 0.0) {
237     play_rate_ = rate;
238     Pause(true);
239     return;
240   }
241
242   // FIXME: |player_set_playback_rate| is always failing.
243   int err = player_set_playback_rate(player_, static_cast<float>(rate));
244   if (err != PLAYER_ERROR_NONE) {
245     OnHandlePlayerError(err, FROM_HERE);
246     return;
247   } else {
248     // If previous rate was zero and requested rate is non-zero, change the
249     // playback rate and call play.
250     if (play_rate_ == 0.0) {
251       play_rate_ = rate;
252       Play();
253     } else {
254       play_rate_ = rate;
255     }
256   }
257 }
258
259 void MediaSourcePlayerCapi::Seek(const double time) {
260   UpdateSeekState(MEDIA_SEEK_DEMUXER);
261   if (GetPlayerState() == PLAYER_STATE_PLAYING)
262     Pause(true);
263
264   seek_offset_ = time;
265
266   base::TimeDelta seek_time = base::TimeDelta::FromSecondsD(time);
267   demuxer_->RequestDemuxerSeek(seek_time);
268 }
269
270 player_state_e MediaSourcePlayerCapi::GetPlayerState() {
271   player_state_e state = PLAYER_STATE_NONE;
272   player_get_state(player_, &state);
273   LOG(INFO) << __FUNCTION__ << " state " << state;
274   return state;
275 }
276
277 void MediaSourcePlayerCapi::SeekInternal() {
278   if (error_occured_)
279     return;
280
281   int ret = PLAYER_ERROR_NONE;
282   ret = player_set_play_position(
283       player_, ConvertSecondsToMilliSeconds(seek_offset_),
284       true, OnSeekCompleteCB, this);
285
286   seek_offset_ = 0.0;
287
288   MediaSeekState state = MEDIA_SEEK_PLAYER;
289   if (ret != PLAYER_ERROR_NONE) {
290     LOG(ERROR) << "Seek to " << " failed";
291     OnHandlePlayerError(ret, FROM_HERE);
292     state = MEDIA_SEEK_NONE;
293   }
294   UpdateSeekState(state);
295 }
296
297 void MediaSourcePlayerCapi::OnDemuxerDurationChanged(
298     base::TimeDelta duration) {
299   duration_ = duration.InSecondsF();
300 }
301
302 void MediaSourcePlayerCapi::OnDemuxerSeekDone(
303     const base::TimeDelta& actual_browser_seek_time) {
304   if (error_occured_)
305     return;
306
307   seek_offset_ = actual_browser_seek_time.InSecondsF();
308   UpdateSeekState(MEDIA_SEEK_DEMUXER_DONE);
309
310   audio_buffer_queue_.clear();
311   video_buffer_queue_.clear();
312
313   OnReadDemuxedData(media::DemuxerStream::AUDIO);
314   OnReadDemuxedData(media::DemuxerStream::VIDEO);
315 }
316
317 void MediaSourcePlayerCapi::OnMediaPacketUpdated(media_packet_h packet) {
318   ScopedMediaPacket packet_proxy(packet);
319   task_runner_->PostTask(
320       FROM_HERE, base::Bind(
321           &MediaSourcePlayerCapi::DeliverMediaPacket,
322           weak_factory_.GetWeakPtr(), base::Passed(&packet_proxy)));
323 }
324
325 void MediaSourcePlayerCapi::SetVolume(double volume) {
326   if (GetPlayerState() <= PLAYER_STATE_IDLE)
327     return;
328
329   if (player_set_volume(player_, volume, volume) != PLAYER_ERROR_NONE)
330     LOG(ERROR) << "|player_set_volume| failed";
331 }
332
333 double MediaSourcePlayerCapi::GetCurrentTime() {
334   if (error_occured_)
335     return 0.0;
336
337   int position = 0;
338   player_get_play_position(player_, &position);
339   return ConvertMilliSecondsToSeconds(position);
340 }
341
342 void MediaSourcePlayerCapi::OnCurrentTimeUpdateTimerFired() {
343   manager()->OnTimeUpdate(GetPlayerId(), GetCurrentTime());
344 }
345
346 void MediaSourcePlayerCapi::StartCurrentTimeUpdateTimer() {
347   if (current_time_update_timer_.IsRunning())
348     return;
349
350   current_time_update_timer_.Start(
351       FROM_HERE,
352       base::TimeDelta::FromMilliseconds(kDurationUpdateInterval),
353       this,
354       &MediaSourcePlayerCapi::OnCurrentTimeUpdateTimerFired);
355 }
356
357 void MediaSourcePlayerCapi::StopCurrentTimeUpdateTimer() {
358   if (current_time_update_timer_.IsRunning())
359     current_time_update_timer_.Stop();
360 }
361
362 void MediaSourcePlayerCapi::Play() {
363   if (error_occured_ || playing_ || !player_prepared_)
364     return;
365
366   if (play_rate_ == 0.0) {
367     playing_ = true;
368     return;
369   }
370
371 #if defined(OS_TIZEN_MOBILE)
372   WakeUpDisplayAndAcquireDisplayLock();
373 #endif
374   int ret = player_start(player_);
375   if (ret != PLAYER_ERROR_NONE) {
376     OnHandlePlayerError(ret, FROM_HERE);
377     return;
378   }
379   playing_ = true;
380   StartCurrentTimeUpdateTimer();
381 }
382
383 void MediaSourcePlayerCapi::Pause(bool is_media_related_action) {
384   if (error_occured_ || !playing_)
385     return;
386
387   if (GetPlayerState() != PLAYER_STATE_PLAYING) {
388     LOG(WARNING) << "Can't PAUSE player";
389     return;
390   }
391
392   int ret = player_pause(player_);
393   if (ret != PLAYER_ERROR_NONE) {
394     OnHandlePlayerError(ret, FROM_HERE);
395     return;
396   }
397   StopCurrentTimeUpdateTimer();
398   if (!is_media_related_action) {
399 #if defined(OS_TIZEN_MOBILE)
400     ReleaseDisplayLock();
401 #endif
402   }
403   playing_ = false;
404 }
405
406 void MediaSourcePlayerCapi::PlaybackComplete() {
407   double time = GetCurrentTime() != duration_ ? duration_ : GetCurrentTime();
408   is_end_reached_ = true;
409   StopCurrentTimeUpdateTimer();
410   manager()->OnTimeUpdate(GetPlayerId(), time);
411   manager()->OnTimeChanged(GetPlayerId());
412 #if defined(OS_TIZEN_MOBILE)
413   ReleaseDisplayLock();
414 #endif
415 }
416
417 // TODO(sam) : It's worked as bypass now. Need Suspend/Resume/Initialize
418 // implementation for MSE multiple instance.
419 void MediaSourcePlayerCapi::Initialize() {
420   manager()->OnInitComplete(GetPlayerId(), true);
421 }
422
423 void MediaSourcePlayerCapi::Release() {
424   playing_ = false;
425   StopCurrentTimeUpdateTimer();
426   audio_buffer_queue_.clear();
427   video_buffer_queue_.clear();
428   if (player_) {
429     player_unset_completed_cb(player_);
430     player_unset_media_packet_video_frame_decoded_cb(player_);
431     player_unprepare(player_);
432   }
433   manager()->OnSuspendComplete(GetPlayerId());
434   if (media_packet_)
435     media_packet_destroy(media_packet_);
436   media_packet_ = NULL;
437 }
438
439 void MediaSourcePlayerCapi::OnDemuxerConfigsAvailable(
440     const DemuxerConfigs& configs) {
441
442   if (!player_)
443     return;
444   LOG(INFO) << "New width " << configs.video_size.width()
445             << " height " << configs.video_size.height();
446   if (GetPlayerState() > PLAYER_STATE_IDLE) {
447     media_format_set_video_width(video_format_, configs.video_size.width());
448     media_format_set_video_height(video_format_, configs.video_size.height());
449     return;
450   }
451   int ret = PLAYER_ERROR_NONE;
452
453   if ((configs.video_codec == kUnknownVideoCodec ||
454       configs.video_codec != kCodecH264) &&
455       (configs.audio_codec == kUnknownAudioCodec ||
456       (configs.audio_codec != kCodecAAC &&
457       configs.audio_codec != kCodecMP3))) {
458     LOG(ERROR) << "Audio and Video codecs not supported for MediaSource";
459     OnHandlePlayerError(PLAYER_ERROR_NOT_SUPPORTED_FILE, FROM_HERE);
460     return;
461   }
462   int samplerate = configs.audio_sampling_rate;
463   int channel = configs.audio_channels;
464   width_ = configs.video_size.width();
465   height_ = configs.video_size.height();
466
467   ret = media_format_create(&audio_format_);
468   if (ret != MEDIA_FORMAT_ERROR_NONE) {
469     LOG(ERROR) << "media_format_create : 0x" << ret;
470     return;
471   }
472
473   media_format_mimetype_e audiomimeType = MEDIA_FORMAT_MP3;
474   if (configs.audio_codec == kCodecAAC)
475     audiomimeType = MEDIA_FORMAT_AAC;
476
477   LOG(INFO) << "samplerate: " << samplerate
478             << ", channel: " << channel
479             << ", audiomimeType: " << audiomimeType;
480
481   media_format_set_audio_mime(audio_format_, audiomimeType);
482   media_format_set_audio_channel(audio_format_, channel);
483   media_format_set_audio_samplerate(audio_format_, samplerate);
484
485   ret = player_set_media_stream_info(player_, PLAYER_STREAM_TYPE_AUDIO,
486                                      audio_format_);
487   if (ret != PLAYER_ERROR_NONE) {
488     LOG(ERROR) << "player_set_audio_stream_info Error: " << ret;
489     return;
490   }
491   ret = player_set_media_stream_buffer_status_cb(player_,
492                                                  PLAYER_STREAM_TYPE_AUDIO,
493                                                  OnCapiAudioBufStatusCB,
494                                                  this);
495   if (ret != PLAYER_ERROR_NONE) {
496     LOG(ERROR) << "player set audio buffer status cb failed :" << ret;
497     return;
498   }
499
500   ret = media_format_create(&video_format_);
501   if (ret != MEDIA_FORMAT_ERROR_NONE) {
502     LOG(ERROR) << "media_format_create : 0x" << ret;
503     return;
504   }
505
506   media_format_mimetype_e videomimeType = MEDIA_FORMAT_H264_SP;
507
508   media_format_set_video_mime(video_format_, videomimeType);
509   media_format_set_video_width(video_format_, width_);
510   media_format_set_video_height(video_format_, height_);
511
512   LOG(INFO) << "width: " << width_
513             << ", height: " << height_
514             << ", videomimeType: " << videomimeType;
515
516   ret = player_set_media_stream_info(player_,
517                                      PLAYER_STREAM_TYPE_VIDEO,
518                                      video_format_);
519   if (ret != PLAYER_ERROR_NONE) {
520     LOG(ERROR) << "player_set_video_stream_info Error: " << ret;
521     return;
522   }
523
524   // FIXME(Kodam): This property should be updated based on dynamic
525   // resolution change
526   player_set_media_stream_buffer_max_size(
527       player_, PLAYER_STREAM_TYPE_VIDEO, max_size);
528   player_set_media_stream_buffer_min_threshold(
529       player_, PLAYER_STREAM_TYPE_VIDEO, min_threshold);
530   ret = player_set_media_stream_buffer_status_cb(player_,
531                                                  PLAYER_STREAM_TYPE_VIDEO,
532                                                  OnCapiVideoBufStatusCB,
533                                                  this);
534   if (ret != PLAYER_ERROR_NONE) {
535     LOG(ERROR) << "player set video buffer status cb failed : 0x" << ret;
536     return;
537   }
538
539   // Audio stream is present if sample rate is valid.
540   if (samplerate > 0)
541     media_type_ |= MEDIA_AUDIO_MASK;
542
543   // Video stream is present if both video width and height are valid.
544   if (width_ > 0 && height_ > 0)
545     media_type_ |= MEDIA_VIDEO_MASK;
546
547   manager()->OnMediaDataChange(GetPlayerId(), width_, height_, media_type_);
548   manager()->OnReadyStateChange(
549       GetPlayerId(), blink::WebMediaPlayer::ReadyStateHaveMetadata);
550
551   if (GetPlayerState() == PLAYER_STATE_IDLE) {
552     ret = player_prepare_async(player_, OnCapiPlayerPreparedCB, this);
553     if (ret != PLAYER_ERROR_NONE) {
554       LOG(ERROR) <<"player prepare failed : 0x " <<  ret;
555       return;
556     }
557   }
558
559   // TODO(Venu): Need to check where is the exact place for this code.
560   // For make it work added this below code
561   // TODO(max): We have a contradiction here.
562   // To Complete preparing the capi-player, we have to get the first frame
563   // But to get the first frame we have to set readyState to EnoughData,
564   // even we are not ready for play(Setting the Enoughdata make HTML
565   // think that player is ready for play)
566   // We have to make some hack to get/set the first frame without notifying
567   // to HTML.
568   manager()->OnReadyStateChange(
569       GetPlayerId(), blink::WebMediaPlayer::ReadyStateHaveEnoughData);
570 }
571
572 // Helper method that prints error occured with CAPI.
573 void MediaSourcePlayerCapi::OnMediaError(MediaError error_type) {
574   StopCurrentTimeUpdateTimer();
575   MediaPlayerEfl::OnMediaError(error_type);
576 }
577
578 void MediaSourcePlayerCapi::ReadDemuxedData(
579     media::DemuxerStream::Type type) {
580   demuxer_->RequestDemuxerData(type);
581 }
582
583 void MediaSourcePlayerCapi::HandleBufferingMessage(int percent) {
584   // FIXME: add code if required
585   return;
586 }
587
588 void MediaSourcePlayerCapi::HandleUnderFlowStatus(
589     media::DemuxerStream::Type type, bool underflow_status) {
590   if (underflow_status) {
591     if (type == media::DemuxerStream::VIDEO) {
592       should_feed_video_ = underflow_status;
593       LOG(INFO) << "Video Underflow " << should_feed_video_
594                 << " call CAPI Pause";
595     } else if (type == media::DemuxerStream::AUDIO) {
596       should_feed_audio_ = underflow_status;
597       LOG(INFO) << "Audio Underflow " << should_feed_audio_
598                 << " call CAPI Pause";
599     }
600     if (player_prepared_) {
601       task_runner_->PostTask(
602           FROM_HERE, base::Bind(&MediaSourcePlayerCapi::Pause,
603                                 weak_factory_.GetWeakPtr(), true));
604     }
605     task_runner_->PostTask(
606         FROM_HERE, base::Bind(&MediaSourcePlayerCapi::ReadDemuxedData,
607                               weak_factory_.GetWeakPtr(), type));
608   } else if (!underflow_status) {
609     if (type == media::DemuxerStream::VIDEO) {
610       should_feed_video_ = underflow_status;
611       LOG(INFO) << "Video Overflow " << should_feed_video_
612                 << " call CAPI Play";
613     } else if (type == media::DemuxerStream::AUDIO) {
614       should_feed_audio_ = underflow_status;
615       LOG(INFO) << "Audio Overflow " << should_feed_audio_
616                 << " call CAPI Play";
617     }
618
619     // FIXME(Kodam): Distinguish from user triggered PAUSE.
620     if ((!should_feed_audio_ || eos_audio_) &&
621         (!should_feed_video_ || eos_video_)) {
622       task_runner_->PostTask(
623           FROM_HERE, base::Bind(&MediaSourcePlayerCapi::Play,
624                                 weak_factory_.GetWeakPtr()));
625     }
626   }
627 }
628
629
630 void MediaSourcePlayerCapi::OnDemuxerDataAvailable(
631     base::SharedMemoryHandle foreign_memory_handle,
632     const media::DemuxedBufferMetaData& meta_data) {
633   if (error_occured_) {
634     LOG(ERROR) << "error occured";
635     return;
636   }
637
638   if (meta_data.status != media::DemuxerStream::kOk ||
639       meta_data.end_of_stream)
640     BufferMetaDataAvailable(meta_data);
641
642   if (seek_state_ == MEDIA_SEEK_DEMUXER_DONE) {
643     // Seek either reached to eos or buffered enough data to seek.
644     if (meta_data.end_of_stream ||
645         (seek_offset_ + kSeekBufferingWaitInSec) <=
646              meta_data.timestamp.InSecondsF()) {
647       SeekInternal();
648     }
649   }
650
651   if (meta_data.size <= 0) {
652     LOG(ERROR) << "ERROR : Size of shared memory is Zero";
653     return;
654   }
655   ReadFromQueueIfAny(meta_data.type);
656
657   if (meta_data.type == media::DemuxerStream::AUDIO && !should_feed_audio_) {
658     // Why store the DecoderBuffer? we have requested for buffer
659     // from demuxer but gstreamer asked to stop. So need to save
660     // this buffer and use it on next |need_data| call.
661     SaveDecoderBuffer(foreign_memory_handle, meta_data);
662     return;
663   }
664   if (meta_data.type == media::DemuxerStream::VIDEO && !should_feed_video_) {
665     SaveDecoderBuffer(foreign_memory_handle, meta_data);
666     return;
667   }
668
669   // Wrapping each frame and deleting shared memory using callback
670   // will not work as possibility of Gstreamer retaining frames (such as
671   // 'i' frames) is high. In that case shared memory will crash. So, we
672   // copy frames and release shared memory right away.
673
674   base::SharedMemory shared_memory(foreign_memory_handle, false);
675   if (!shared_memory.Map(meta_data.size)) {
676     LOG(ERROR) << "Failed to map shared memory of size " << meta_data.size;
677     return;
678   }
679
680   if (meta_data.type == media::DemuxerStream::AUDIO) {
681     if (media_packet_create_from_external_memory(
682         audio_format_, static_cast<void*>(shared_memory.memory()),
683         meta_data.size, NULL, NULL, &media_packet_)
684             != MEDIA_PACKET_ERROR_NONE) {
685       LOG(ERROR) << "Audio media_packet_create_from_external_memory failed";
686       return;
687     }
688   } else if (meta_data.type == media::DemuxerStream::VIDEO) {
689     if (media_packet_create_from_external_memory(
690         video_format_, static_cast<void*>(shared_memory.memory()),
691         meta_data.size, NULL, NULL, &media_packet_)
692             != MEDIA_PACKET_ERROR_NONE) {
693       LOG(ERROR) << "Video media_packet_create_from_external_memory failed";
694       return;
695     }
696   }
697
698   if (media_packet_set_pts(media_packet_, meta_data.timestamp.InMilliseconds())
699           != MEDIA_PACKET_ERROR_NONE) {
700     LOG(ERROR) << "media_packet_set_pts failed";
701     return;
702   }
703   if (player_push_media_stream(player_, media_packet_)
704           != MEDIA_PACKET_ERROR_NONE)
705     LOG(ERROR) << "player_push_media_stream failed";
706
707   if (meta_data.type == media::DemuxerStream::AUDIO)
708     media_format_unref(audio_format_);
709   else if (meta_data.type == media::DemuxerStream::VIDEO)
710     media_format_unref(video_format_);
711
712   if (media_packet_)
713     media_packet_destroy(media_packet_);
714   media_packet_ = NULL;
715
716   if (meta_data.type == media::DemuxerStream::AUDIO)
717     OnReadDemuxedData(media::DemuxerStream::AUDIO);
718   else if (meta_data.type == media::DemuxerStream::VIDEO)
719     OnReadDemuxedData(media::DemuxerStream::VIDEO);
720   return;
721 }
722
723 void MediaSourcePlayerCapi::BufferMetaDataAvailable(
724     const media::DemuxedBufferMetaData& meta_data) {
725   LOG(INFO) << __FUNCTION__ << " meta_data.type " << meta_data.type;
726   if (error_occured_) {
727     LOG(ERROR) << "Pipeline_ null or error occured";
728     return;
729   }
730
731   switch (meta_data.status) {
732     case media::DemuxerStream::kAborted:
733       LOG(WARNING) << "[BROWSER] : DemuxerStream::kAborted, Stream type = "
734                    << meta_data.type;
735     case media::DemuxerStream::kConfigChanged:
736       if (meta_data.type == media::DemuxerStream::AUDIO)
737         OnReadDemuxedData(media::DemuxerStream::AUDIO);
738       else if (meta_data.type == media::DemuxerStream::VIDEO)
739         OnReadDemuxedData(media::DemuxerStream::VIDEO);
740       break;
741
742     case media::DemuxerStream::kOk:
743       if (meta_data.end_of_stream) {
744         ReadFromQueueIfAny(meta_data.type);
745         LOG(INFO) <<"[BROWSER] : DemuxerStream::kOk but |end_of_stream|";
746         SendEosToCapi(meta_data);
747         if (!playing_)
748           Play();
749       }
750       break;
751
752     default:
753       NOTREACHED();
754   }
755 }
756
757 void MediaSourcePlayerCapi::SendEosToCapi(
758     const media::DemuxedBufferMetaData& meta_data) {
759   if (meta_data.type == media::DemuxerStream::AUDIO) {
760     if (!eos_audio_) {
761       if (media_packet_create(audio_format_, NULL, NULL, &media_packet_)
762               != MEDIA_PACKET_ERROR_NONE) {
763         LOG(ERROR) << "Audio media_packet_create failed";
764         return;
765       }
766       eos_audio_ = true;
767     } else {
768       LOG(ERROR) << "Audio EOS Already Pushed";
769       return;
770     }
771   } else if (meta_data.type == media::DemuxerStream::VIDEO) {
772     if (!eos_video_) {
773       if (media_packet_create(video_format_, NULL, NULL, &media_packet_)
774               != MEDIA_PACKET_ERROR_NONE) {
775         LOG(ERROR) << "Video media_packet_create failed";
776         return;
777       }
778       eos_video_ = true;
779     } else {
780       LOG(ERROR) << "Video EOS Already Pushed";
781       return;
782     }
783   }
784
785   if (media_packet_set_flags(media_packet_, MEDIA_PACKET_END_OF_STREAM)
786           != MEDIA_PACKET_ERROR_NONE)
787     LOG(ERROR) << "media_packet_set_flags failed";
788
789   if (player_push_media_stream(player_, media_packet_)
790           != MEDIA_PACKET_ERROR_NONE)
791     LOG(ERROR) << "player_push_media_stream failed";
792
793   if (meta_data.type == media::DemuxerStream::AUDIO)
794     media_format_unref(audio_format_);
795   else if (meta_data.type == media::DemuxerStream::VIDEO)
796     media_format_unref(video_format_);
797
798   if (media_packet_)
799     media_packet_destroy(media_packet_);
800   media_packet_ = NULL;
801 }
802
803 void MediaSourcePlayerCapi::ReadFromQueueIfAny(
804     DemuxerStream::Type type) {
805   if (error_occured_) {
806     LOG(ERROR) << "error occured in capi";
807     return;
808   }
809
810   if (type == media::DemuxerStream::AUDIO) {
811     if (audio_buffer_queue_.empty() || !should_feed_audio_)
812       return;
813   }
814
815   if (type == media::DemuxerStream::VIDEO) {
816     if (video_buffer_queue_.empty() || !should_feed_video_)
817       return;
818   }
819
820   scoped_refptr<DecoderBuffer> decoder_buffer;
821
822   if (type == media::DemuxerStream::AUDIO) {
823     decoder_buffer = audio_buffer_queue_.front();
824     audio_buffer_queue_.pop_front();
825   } else if (type == media::DemuxerStream::VIDEO) {
826     decoder_buffer = video_buffer_queue_.front();
827     video_buffer_queue_.pop_front();
828   }
829   uint64 size = static_cast<uint64>(decoder_buffer.get()->data_size());
830
831   uint64 timestamp =
832       static_cast<uint64>(decoder_buffer.get()->timestamp().InMilliseconds());
833   if (type == media::DemuxerStream::AUDIO) {
834     if (media_packet_create_from_external_memory(
835         audio_format_,
836         static_cast<void*>(decoder_buffer.get()->writable_data()),
837         size, NULL, NULL, &media_packet_)
838             != MEDIA_PACKET_ERROR_NONE) {
839       LOG(ERROR) << "Audio media_packet_create_from_external_memory failed";
840       return;
841     }
842   } else if (type == media::DemuxerStream::VIDEO) {
843     if (media_packet_create_from_external_memory(
844         video_format_,
845         static_cast<void*>(decoder_buffer.get()->writable_data()),
846         size, NULL, NULL, &media_packet_)
847             != MEDIA_PACKET_ERROR_NONE) {
848       LOG(ERROR) << "Video media_packet_create_from_external_memory failed";
849       return;
850     }
851   }
852
853   if (media_packet_set_pts(media_packet_, timestamp)
854           != MEDIA_PACKET_ERROR_NONE) {
855     LOG(ERROR) << "media_packet_set_pts failed";
856     return;
857   }
858
859   if (player_push_media_stream(player_, media_packet_)
860           != MEDIA_PACKET_ERROR_NONE)
861     LOG(ERROR) << "player_push_media_stream failed";
862
863   if (type == media::DemuxerStream::AUDIO)
864     media_format_unref(audio_format_);
865   else if (type == media::DemuxerStream::VIDEO)
866     media_format_unref(video_format_);
867
868   // Empty the Buffer before reading the new buffer from render process.
869   if (media_packet_)
870     media_packet_destroy(media_packet_);
871   media_packet_ = NULL;
872
873   ReadFromQueueIfAny(type);
874   return;
875 }
876
877 void MediaSourcePlayerCapi::SaveDecoderBuffer(
878     base::SharedMemoryHandle foreign_memory_handle,
879     const media::DemuxedBufferMetaData& meta_data) {
880   if (error_occured_) {
881     LOG(ERROR) << "Error occured in capi";
882     return;
883   }
884
885   base::SharedMemory shared_memory(foreign_memory_handle, false);
886   if (!shared_memory.Map(meta_data.size)) {
887     LOG(ERROR) << "Failed to map shared memory of size " << meta_data.size;
888     return;
889   }
890   scoped_refptr<DecoderBuffer> buffer;
891   buffer = DecoderBuffer::CopyFrom(static_cast<const uint8*> (
892       shared_memory.memory()), meta_data.size);
893
894   if (!buffer.get()) {
895     LOG(ERROR) << "DecoderBuffer::CopyFrom failed";
896     return;
897   }
898
899   buffer->set_timestamp(meta_data.timestamp);
900   buffer->set_duration(meta_data.time_duration);
901
902   if (meta_data.type == media::DemuxerStream::AUDIO)
903     audio_buffer_queue_.push_back(buffer);
904   else if (meta_data.type == media::DemuxerStream::VIDEO)
905     video_buffer_queue_.push_back(buffer);
906 }
907
908 void MediaSourcePlayerCapi::OnPrepareComplete() {
909   task_runner_->PostTask(
910       FROM_HERE, base::Bind(&MediaSourcePlayerCapi::PrepareComplete,
911                             weak_factory_.GetWeakPtr()));
912 }
913
914 void MediaSourcePlayerCapi::OnPlaybackComplete() {
915   task_runner_->PostTask(
916       FROM_HERE, base::Bind(&MediaSourcePlayerCapi::PlaybackComplete,
917                             weak_factory_.GetWeakPtr()));
918 }
919
920 void MediaSourcePlayerCapi::OnSeekComplete() {
921   task_runner_->PostTask(
922       FROM_HERE, base::Bind(&MediaSourcePlayerCapi::SeekComplete,
923                             weak_factory_.GetWeakPtr()));
924 }
925
926 void MediaSourcePlayerCapi::OnHandleBufferingMessage(int percent) {
927   task_runner_->PostTask(
928       FROM_HERE, base::Bind(&MediaSourcePlayerCapi::HandleBufferingMessage,
929                             weak_factory_.GetWeakPtr(),
930                             percent));
931 }
932
933 void MediaSourcePlayerCapi::OnReadDemuxedData(
934     media::DemuxerStream::Type type) {
935   task_runner_->PostTask(
936       FROM_HERE, base::Bind(&MediaSourcePlayerCapi::ReadDemuxedData,
937                             weak_factory_.GetWeakPtr(), type));
938 }
939
940 void MediaSourcePlayerCapi::OnUpdateDataStatus(
941     media::DemuxerStream::Type type, bool underflow_status) {
942   task_runner_->PostTask(
943       FROM_HERE, base::Bind(&MediaSourcePlayerCapi::HandleUnderFlowStatus,
944                             weak_factory_.GetWeakPtr(),
945                             type,
946                             underflow_status));
947 }
948
949 void MediaSourcePlayerCapi::OnHandlePlayerError(
950     int player_error_code, const tracked_objects::Location& location) {
951
952   LOG(ERROR) << GetErrorString(player_error_code) << " from "
953              << location.ToString();
954
955   OnMediaError(GetMediaError(player_error_code));
956 }
957
958 }  // namespace media