29 #include "AampUtils.h"
32 #include <gst/app/gstappsrc.h>
33 #include <gst/app/gstappsink.h>
43 #include "gst/video/videooverlay.h"
44 guintptr (*gCbgetWindowContentView)() = NULL;
70 #define GST_ELEMENT_GET_STATE_RETRY_CNT_MAX 5
73 #define GSTPLAYERSINKBIN_EVENT_HAVE_VIDEO 0x01
74 #define GSTPLAYERSINKBIN_EVENT_HAVE_AUDIO 0x02
75 #define GSTPLAYERSINKBIN_EVENT_FIRST_VIDEO_FRAME 0x03
76 #define GSTPLAYERSINKBIN_EVENT_FIRST_AUDIO_FRAME 0x04
77 #define GSTPLAYERSINKBIN_EVENT_ERROR_VIDEO_UNDERFLOW 0x06
78 #define GSTPLAYERSINKBIN_EVENT_ERROR_AUDIO_UNDERFLOW 0x07
79 #define GSTPLAYERSINKBIN_EVENT_ERROR_VIDEO_PTS 0x08
80 #define GSTPLAYERSINKBIN_EVENT_ERROR_AUDIO_PTS 0x09
83 #define INPUT_GAIN_DB_MUTE (gdouble)-145
84 #define INPUT_GAIN_DB_UNMUTE (gdouble)0
86 #define DEFAULT_BUFFERING_TO_MS 10
87 #if defined(REALTEKCE)
88 #define DEFAULT_BUFFERING_QUEUED_FRAMES_MIN (3)
89 #define DEFAULT_AVSYNC_FREERUN_THRESHOLD_SECS 12
91 #define DEFAULT_BUFFERING_QUEUED_FRAMES_MIN (5)
94 #define DEFAULT_BUFFERING_MAX_MS (1000)
95 #define DEFAULT_BUFFERING_MAX_CNT (DEFAULT_BUFFERING_MAX_MS/DEFAULT_BUFFERING_TO_MS)
96 #define AAMP_MIN_PTS_UPDATE_INTERVAL 4000
97 #define AAMP_DELAY_BETWEEN_PTS_CHECK_FOR_EOS_ON_UNDERFLOW 500
98 #define BUFFERING_TIMEOUT_PRIORITY -70
99 #define AAMP_MIN_DECODE_ERROR_INTERVAL 10000
100 #define VIDEO_COORDINATES_SIZE 32
111 {
"ac-3", {
"omxac3dec",
"avdec_ac3",
"avdec_ac3_fixed"}},
112 {
"ac-4", {
"omxac4dec"}}
130 pthread_mutex_t sourceLock;
168 #ifdef INTELCE_USE_VIDRENDSINK
169 GstElement *video_pproc;
210 #if defined(REALTEKCE)
211 bool firstTuneWithWesterosSinkOff;
215 bool progressiveBufferingEnabled;
216 bool progressiveBufferingStatus;
227 #ifdef INTELCE_USE_VIDRENDSINK
239 keepLastFrame(false),
245 #if defined(REALTEKCE)
246 firstTuneWithWesterosSinkOff(false),
249 progressiveBufferingEnabled(false), progressiveBufferingStatus(false)
319 #define PLUGINS_TO_LOWER_RANK_MAX 2
329 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
330 , std::function<
void(uint8_t *,
int,
int,
int) > exportFrames
332 ) : mLogObj(logObj), aamp(NULL) , privateContext(NULL), mBufferingLock(), mProtectionLock(), PipelineSetToReady(false), trickTeardown(false)
333 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
334 , cbExportYUVFrame(NULL)
337 FN_TRACE( __FUNCTION__ );
343 pthread_mutex_init(&mBufferingLock, NULL);
344 pthread_mutex_init(&mProtectionLock, NULL);
346 pthread_mutex_init(&privateContext->stream[i].sourceLock, NULL);
348 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
349 this->cbExportYUVFrame = exportFrames;
355 AAMPLOG_WARN(
"privateContext is null");
364 FN_TRACE( __FUNCTION__ );
367 pthread_mutex_destroy(&privateContext->stream[i].sourceLock);
368 SAFE_DELETE(privateContext);
369 pthread_mutex_destroy(&mBufferingLock);
370 pthread_mutex_destroy(&mProtectionLock);
378 FN_TRACE( __FUNCTION__ );
382 if (0 == taskDetails.taskID)
384 taskDetails.taskIsPending =
false;
387 if(0 != taskDetails.taskID)
389 taskDetails.taskIsPending =
true;
391 AAMPLOG_INFO(
"Task '%.50s' was added with ID = %d.", taskDetails.taskName.c_str(), taskDetails.taskID);
395 AAMPLOG_INFO(
"Task '%.50s' was not added or already ran.", taskDetails.taskName.c_str());
400 AAMPLOG_WARN(
"Task '%.50s' was already pending.", taskDetails.taskName.c_str());
410 FN_TRACE( __FUNCTION__ );
414 if (0 != taskDetails.taskID)
416 AAMPLOG_INFO(
"AAMPGstPlayer: Remove task <%.50s> with ID %d", taskDetails.taskName.c_str(), taskDetails.taskID);
418 taskDetails.taskID = 0;
423 AAMPLOG_TRACE(
"AAMPGstPlayer: Task already removed <%.50s>, with ID %d", taskDetails.taskName.c_str(), taskDetails.taskID);
425 taskDetails.taskIsPending =
false;
435 FN_TRACE( __FUNCTION__ );
437 if ( 0 != taskDetails.taskID )
439 AAMPLOG_INFO(
"AAMPGstPlayer: Clear task control flags <%.50s> with ID %d", taskDetails.taskName.c_str(), taskDetails.taskID);
443 AAMPLOG_TRACE(
"AAMPGstPlayer: Task control flags were already cleared <%.50s> with ID %d", taskDetails.taskName.c_str(), taskDetails.taskID);
445 taskDetails.taskIsPending =
false;
446 taskDetails.taskID = 0;
452 void AAMPGstPlayer::TimerAdd(GSourceFunc funcPtr,
int repeatTimeout, guint& taskId, gpointer user_data,
const char* timerName)
454 FN_TRACE( __FUNCTION__ );
456 if (funcPtr && user_data)
461 taskId = g_timeout_add(repeatTimeout, funcPtr, user_data);
462 AAMPLOG_INFO(
"AAMPGstPlayer: Added timer '%.50s', %d", (
nullptr!=timerName) ? timerName :
"unknown" , taskId);
466 AAMPLOG_INFO(
"AAMPGstPlayer: Timer '%.50s' already added, taskId=%d", (
nullptr!=timerName) ? timerName :
"unknown", taskId);
471 AAMPLOG_ERR(
"Bad pointer.");
480 FN_TRACE( __FUNCTION__ );
484 AAMPLOG_INFO(
"AAMPGstPlayer: Remove timer '%.50s', %d", (
nullptr!=timerName) ? timerName :
"unknown", taskId);
485 g_source_remove(taskId);
490 AAMPLOG_TRACE(
"Timer '%.50s' with taskId = %d already removed.", (
nullptr!=timerName) ? timerName :
"unknown", taskId);
499 FN_TRACE( __FUNCTION__ );
502 return (AAMP_TASK_ID_INVALID != taskId);
511 FN_TRACE( __FUNCTION__ );
512 #ifdef SUPPORT_MULTI_AUDIO
515 g_object_get(sinkbin,
"n-audio", &_this->privateContext->
n_audio, NULL);
517 for (gint i = 0; i < _this->privateContext->
n_audio; i++)
519 GstTagList *tags = NULL;
520 g_signal_emit_by_name(sinkbin,
"get-audio-tags", i, &tags);
526 g_print(
"audio stream %d:\n", i);
527 if (gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &str)) {
528 g_print(
" codec: %s\n", str);
531 if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &str)) {
532 g_print(
" language: %s\n", str);
535 if (gst_tag_list_get_uint(tags, GST_TAG_BITRATE, &rate)) {
536 g_print(
" bitrate: %d\n", rate);
538 gst_tag_list_free(tags);
541 g_object_get(sinkbin,
"current-audio", &_this->privateContext->
current_audio, NULL);
611 AAMPLOG_WARN(
"appsrc %p seek-signal - offset %" G_GUINT64_FORMAT, src, offset);
625 media_stream *stream = &_this->privateContext->stream[mediaType];
626 GstCaps * caps = NULL;
627 g_signal_connect(source,
"need-data", G_CALLBACK(
need_data), _this);
628 g_signal_connect(source,
"enough-data", G_CALLBACK(
enough_data), _this);
629 g_signal_connect(source,
"seek-data", G_CALLBACK(
appsrc_seek), _this);
630 gst_app_src_set_stream_type(GST_APP_SRC(source), GST_APP_STREAM_TYPE_SEEKABLE);
633 int MaxGstVideoBufBytes = 0;
635 AAMPLOG_INFO(
"Setting gst Video buffer max bytes to %d", MaxGstVideoBufBytes);
636 g_object_set(source,
"max-bytes", (guint64)MaxGstVideoBufBytes, NULL);
640 int MaxGstAudioBufBytes = 0;
642 AAMPLOG_INFO(
"Setting gst Audio buffer max bytes to %d", MaxGstAudioBufBytes);
643 g_object_set(source,
"max-bytes", (guint64)MaxGstAudioBufBytes, NULL);
645 g_object_set(source,
"min-percent", 50, NULL);
646 g_object_set(source,
"format", GST_FORMAT_TIME, NULL);
652 gst_app_src_set_caps(GST_APP_SRC(source), caps);
653 gst_caps_unref(caps);
657 g_object_set(source,
"typefind",
TRUE, NULL);
677 AAMPLOG_WARN(
"Found source for video");
682 AAMPLOG_WARN(
"Found source for audio");
687 AAMPLOG_WARN(
"Found source for auxiliary audio");
692 AAMPLOG_WARN(
"Found source for subtitle");
697 AAMPLOG_WARN(
"found_source didn't find a valid source");
702 stream = &_this->privateContext->stream[mediaType];
703 g_object_get(orig, pspec->name, &stream->
source, NULL);
718 if (!strcmp(GST_ELEMENT_NAME(source),
"source"))
721 if(!networkProxyValue.empty())
723 g_object_set(source,
"proxy", networkProxyValue.c_str(), NULL);
724 AAMPLOG_WARN(
"httpsoup -> Set network proxy '%s'", networkProxyValue.c_str());
744 return G_SOURCE_REMOVE;
763 return G_SOURCE_REMOVE;
781 return G_SOURCE_CONTINUE;
801 double reportProgressInterval;
803 reportProgressInterval *= 1000;
807 AAMPLOG_WARN(
"current %d, periodicProgressCallbackIdleTaskId %d", g_source_get_id(g_main_current_source()), _this->privateContext->
periodicProgressCallbackIdleTaskId);
814 return G_SOURCE_REMOVE;
831 return G_SOURCE_REMOVE;
839 FN_TRACE( __FUNCTION__ );
853 AAMPLOG_WARN(
"AAMPGstPlayer_OnFirstVideoFrameCallback. got First Video Frame");
894 AAMPLOG_WARN(
"AAMPGstPlayer_OnAudioFirstFrameAudDecoder. got First Audio Frame");
944 snprintf(buffer,16,
"%d:%d:%d",hours,minutes,seconds);
971 #if defined (REALTEKCE)
987 #if defined (REALTEKCE)
1003 #if defined (REALTEKCE)
1024 bool isAudioOrVideoDecoder =
false;
1028 isAudioOrVideoDecoder =
true;
1030 #if defined (REALTEKCE)
1033 isAudioOrVideoDecoder =
true;
1038 isAudioOrVideoDecoder =
true;
1043 isAudioOrVideoDecoder =
true;
1047 return isAudioOrVideoDecoder;
1064 AAMPLOG_WARN(
"PTS not changed");
1069 AAMPLOG_WARN(
"Video PTS still moving lastKnownPTS %" G_GUINT64_FORMAT
" currentPTS %" G_GUINT64_FORMAT
" ##", privateContext->
lastKnownPTS, currentPTS);
1073 return G_SOURCE_REMOVE;
1076 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
1081 GstFlowReturn AAMPGstPlayer::AAMPGstPlayer_OnVideoSample(GstElement*
object,
AAMPGstPlayer * _this)
1083 FN_TRACE( __FUNCTION__ );
1089 if(_this && _this->cbExportYUVFrame)
1091 sample = gst_app_sink_pull_sample (GST_APP_SINK (
object));
1095 GstCaps *caps = gst_sample_get_caps(sample);
1096 GstStructure *capsStruct = gst_caps_get_structure(caps,0);
1097 gst_structure_get_int(capsStruct,
"width",&width);
1098 gst_structure_get_int(capsStruct,
"height",&height);
1100 buffer = gst_sample_get_buffer (sample);
1103 if (gst_buffer_map(buffer, &map, GST_MAP_READ))
1105 _this->cbExportYUVFrame(map.data, map.size, width, height);
1107 gst_buffer_unmap(buffer, &map);
1111 AAMPLOG_WARN(
"buffer map failed\n");
1116 AAMPLOG_WARN(
"buffer NULL\n");
1118 gst_sample_unref (sample);
1122 AAMPLOG_WARN(
"sample NULL\n");
1141 AAMPLOG_WARN(
"## [WARN] Ignored underflow from %s, disableUnderflow config enabled ##", GST_ELEMENT_NAME(
object));
1162 AAMPLOG_WARN(
"## WARNING!! Underflow message from %s not handled, unmapped underflow!", GST_ELEMENT_NAME(
object));
1166 AAMPLOG_WARN(
"## Got Underflow message from %s type %d ##", GST_ELEMENT_NAME(
object), type);
1168 _this->privateContext->stream[type].bufferUnderrun =
true;
1170 if ((_this->privateContext->stream[type].
eosReached) && (_this->privateContext->
rate > 0))
1186 AAMPLOG_WARN(
"Mediatype %d underrun, when eosReached is %d", type, _this->privateContext->stream[type].
eosReached);
1202 AAMPLOG_WARN(
"## Got PTS error message from %s ##", GST_ELEMENT_NAME(
object));
1241 if (_this && _this->privateContext)
1249 g_object_get(_this->privateContext->
video_dec,
"queued_frames",(uint*)&frames,NULL);
1260 AAMPLOG_WARN(
"Schedule retune. numberOfVideoBuffersSent %d frames %i", privateContext->
numberOfVideoBuffersSent, frames);
1266 #if !defined(__APPLE__)
1270 AAMPLOG_WARN(
"Set pipeline state to %s - buffering_timeout_cnt %u frames %i", gst_element_state_get_name(_this->privateContext->
buffering_target_state), (_this->privateContext->
buffering_timeout_cnt+1), frames);
1288 AAMPLOG_WARN(
"in buffering_timeout got invalid or NULL handle ! _this = %p _this->privateContext = %p ",
1289 _this, (_this? _this->privateContext: NULL) );
1306 bool isPlaybinStateChangeEvent;
1308 switch (GST_MESSAGE_TYPE(msg))
1310 case GST_MESSAGE_ERROR:
1311 gst_message_parse_error(msg, &error, &dbg_info);
1312 g_printerr(
"GST_MESSAGE_ERROR %s: %s\n", GST_OBJECT_NAME(msg->src), error->message);
1313 char errorDesc[MAX_ERROR_DESCRIPTION_LENGTH];
1314 memset(errorDesc,
'\0', MAX_ERROR_DESCRIPTION_LENGTH);
1315 strncpy(errorDesc,
"GstPipeline Error:", 18);
1316 strncat(errorDesc, error->message, MAX_ERROR_DESCRIPTION_LENGTH - 18 - 1);
1317 if (strstr(error->message,
"video decode error") != NULL)
1321 else if(strstr(error->message,
"HDCP Compliance Check Failure") != NULL)
1329 AAMPLOG_WARN(
"Schedule retune for GstPipeline Error");
1336 g_printerr(
"Debug Info: %s\n", (dbg_info) ? dbg_info :
"none");
1337 g_clear_error(&error);
1341 case GST_MESSAGE_WARNING:
1342 gst_message_parse_warning(msg, &error, &dbg_info);
1343 g_printerr(
"GST_MESSAGE_WARNING %s: %s\n", GST_OBJECT_NAME(msg->src), error->message);
1346 char warnDesc[MAX_ERROR_DESCRIPTION_LENGTH];
1347 snprintf( warnDesc, MAX_ERROR_DESCRIPTION_LENGTH,
"GstPipeline Error:%s", error->message );
1352 g_printerr(
"Debug Info: %s\n", (dbg_info) ? dbg_info :
"none");
1353 g_clear_error(&error);
1357 case GST_MESSAGE_EOS:
1362 AAMPLOG_WARN(
"GST_MESSAGE_EOS");
1366 case GST_MESSAGE_STATE_CHANGED:
1367 GstState old_state, new_state, pending_state;
1368 gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
1370 isPlaybinStateChangeEvent = (GST_MESSAGE_SRC(msg) == GST_OBJECT(_this->privateContext->
pipeline));
1374 AAMPLOG_WARN(
"%s %s -> %s (pending %s)",
1375 GST_OBJECT_NAME(msg->src),
1376 gst_element_state_get_name(old_state),
1377 gst_element_state_get_name(new_state),
1378 gst_element_state_get_name(pending_state));
1380 if (isPlaybinStateChangeEvent && new_state == GST_STATE_PLAYING)
1388 #if defined(REALTEKCE)
1392 if(_this->privateContext->firstTuneWithWesterosSinkOff)
1394 _this->privateContext->firstTuneWithWesterosSinkOff =
false;
1400 #if (defined(INTELCE) || defined(RPI) || defined(__APPLE__) || defined(UBUNTU))
1416 GST_DEBUG_BIN_TO_DOT_FILE((GstBin *)_this->privateContext->
pipeline, GST_DEBUG_GRAPH_SHOW_ALL,
"myplayer");
1434 if(_this->aamp->mSetPlayerRateAfterFirstframe
1436 ||((AAMP_SLOWMOTION_RATE == _this->aamp->playerrate) && (_this->aamp->
rate != _this->aamp->playerrate))
1440 if(_this->aamp->mSetPlayerRateAfterFirstframe)
1442 _this->aamp->mSetPlayerRateAfterFirstframe=
false;
1443 if(
false!=_this->aamp->mStreamSink->
SetPlayBackRate(_this->aamp->playerrate))
1445 _this->aamp->
rate=_this->aamp->playerrate;
1454 _this->aamp->playerrate=_this->aamp->
rate;
1472 pInstance->Release();
1478 if ((NULL != msg->src) &&
1479 #
if defined(REALTEKCE)
1486 if (old_state == GST_STATE_NULL && new_state == GST_STATE_READY)
1488 g_signal_connect(msg->src,
"buffer-underflow-callback",
1490 g_signal_connect(msg->src,
"pts-error-callback",
1492 #if !defined(REALTEKCE)
1496 g_signal_connect(msg->src,
"decode-error-callback",
1504 case GST_MESSAGE_TAG:
1507 case GST_MESSAGE_QOS:
1510 guint64 running_time;
1511 guint64 stream_time;
1514 gst_message_parse_qos(msg, &live, &running_time, &stream_time, ×tamp, &duration);
1518 case GST_MESSAGE_CLOCK_LOST:
1521 AAMPLOG_WARN(
"GST_MESSAGE_CLOCK_LOST");
1527 case GST_MESSAGE_RESET_TIME:
1529 GstClockTime running_time;
1530 gst_message_parse_reset_time (msg, &running_time);
1531 printf(
"GST_MESSAGE_RESET_TIME %llu\n", (
unsigned long long)running_time);
1535 case GST_MESSAGE_STREAM_STATUS:
1536 case GST_MESSAGE_ELEMENT:
1537 case GST_MESSAGE_DURATION:
1538 case GST_MESSAGE_LATENCY:
1539 case GST_MESSAGE_NEW_CLOCK:
1541 case GST_MESSAGE_APPLICATION:
1542 const GstStructure *msgS;
1543 msgS = gst_message_get_structure (msg);
1544 if (gst_structure_has_name (msgS,
"HDCPProtectionFailure")) {
1545 AAMPLOG_WARN(
"Received HDCPProtectionFailure event.Schedule Retune ");
1546 _this->
Flush(0, AAMP_NORMAL_PLAY_RATE,
true);
1552 AAMPLOG_WARN(
"msg type: %s", gst_message_type_get_name(msg->type));
1568 switch(GST_MESSAGE_TYPE(msg))
1570 case GST_MESSAGE_STATE_CHANGED:
1571 GstState old_state, new_state;
1572 gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
1574 if (GST_MESSAGE_SRC(msg) == GST_OBJECT(_this->privateContext->
pipeline))
1585 if (new_state == GST_STATE_PAUSED && old_state == GST_STATE_READY)
1595 _this->privateContext->
video_sink = (GstElement *) msg->src;
1598 AAMPLOG_WARN(
"AAMPGstPlayer - using westerossink, setting cached video mute and zoom");
1599 g_object_set(msg->src,
"zoom-mode",
VIDEO_ZOOM_FULL == _this->privateContext->
zoom ? 0 : 1, NULL);
1600 g_object_set(msg->src,
"show-video-window", !_this->privateContext->
videoMuted, NULL);
1604 AAMPLOG_WARN(
"AAMPGstPlayer setting cached rectangle, video mute and zoom");
1605 g_object_set(msg->src,
"rectangle", _this->privateContext->
videoRectangle, NULL);
1606 g_object_set(msg->src,
"zoom-mode",
VIDEO_ZOOM_FULL == _this->privateContext->
zoom ? 0 : 1, NULL);
1607 g_object_set(msg->src,
"show-video-window", !_this->privateContext->
videoMuted, NULL);
1610 else if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"brcmaudiosink") ==
true)
1612 _this->privateContext->
audio_sink = (GstElement *) msg->src;
1616 else if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"amlhalasink") ==
true)
1618 _this->privateContext->
audio_sink = (GstElement *) msg->src;
1620 g_object_set(_this->privateContext->
audio_sink,
"disable-xrun",
TRUE, NULL);
1624 else if (strstr(GST_OBJECT_NAME(msg->src),
"brcmaudiodecoder"))
1627 g_object_set(msg->src,
"limit_buffering_ms", 1500, NULL);
1628 g_object_set(msg->src,
"limit_buffering", 1, NULL);
1629 AAMPLOG_WARN(
"Found audiodecoder, limiting audio decoder buffering");
1635 #if defined (REALTEKCE)
1640 _this->privateContext->
audio_sink = (GstElement *) msg->src;
1650 if (old_state == GST_STATE_NULL && new_state == GST_STATE_READY)
1657 _this->privateContext->
video_dec = (GstElement *) msg->src;
1659 g_signal_connect(_this->privateContext->
video_dec,
"first-video-frame-callback",
1661 #if !defined(REALTEKCE)
1662 g_object_set(msg->src,
"report_decode_errors",
TRUE, NULL);
1668 _this->privateContext->
audio_dec = (GstElement *) msg->src;
1670 #if !defined(REALTEKCE)
1671 g_signal_connect(msg->src,
"first-audio-frame-callback",
1678 AAMPLOG_INFO(
"Selecting AC4 Track Id : %d", trackId);
1679 g_object_set(msg->src,
"ac4-presentation-group-index", trackId, NULL);
1681 AAMPLOG_WARN(
"AC4 support has not done for this platform - track Id: %d", trackId);
1690 g_object_set(msg->src,
"enable-timecode", 1, NULL);
1691 g_signal_connect(msg->src,
"timecode-callback",
1694 #if !defined(REALTEKCE)
1697 g_object_set(msg->src,
"freerun-threshold", DEFAULT_AVSYNC_FREERUN_THRESHOLD_SECS, NULL);
1700 if ((NULL != msg->src) &&
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"rtkaudiosink"))
1701 g_signal_connect(msg->src,
"first-audio-frame",
1705 if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"ismdgstaudiosink") ==
true)
1707 _this->privateContext->
audio_sink = (GstElement *) msg->src;
1709 AAMPLOG_WARN(
"AAMPGstPlayer setting audio-sync");
1710 g_object_set(msg->src,
"sync",
TRUE, NULL);
1716 #ifndef INTELCE_USE_VIDRENDSINK
1717 if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"ismdgstvidsink") ==
true)
1719 if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"ismdgstvidrendsink") ==
true)
1723 privateContext->
video_sink = (GstElement *) msg->src;
1724 AAMPLOG_WARN(
"AAMPGstPlayer setting stop-keep-frame %d", (
int)(privateContext->keepLastFrame));
1725 g_object_set(msg->src,
"stop-keep-frame", privateContext->keepLastFrame, NULL);
1726 #if defined(INTELCE) && !defined(INTELCE_USE_VIDRENDSINK)
1727 AAMPLOG_WARN(
"AAMPGstPlayer setting rectangle %s", privateContext->
videoRectangle);
1728 g_object_set(msg->src,
"rectangle", privateContext->
videoRectangle, NULL);
1729 AAMPLOG_WARN(
"AAMPGstPlayer setting zoom %s", (
VIDEO_ZOOM_FULL == privateContext->
zoom) ?
"FULL" :
"NONE");
1730 g_object_set(msg->src,
"scale-mode", (
VIDEO_ZOOM_FULL == privateContext->
zoom) ? 0 : 3, NULL);
1731 AAMPLOG_WARN(
"AAMPGstPlayer setting crop-lines to FALSE");
1732 g_object_set(msg->src,
"crop-lines", FALSE, NULL);
1734 AAMPLOG_WARN(
"AAMPGstPlayer setting video mute %d", privateContext->
videoMuted);
1735 g_object_set(msg->src,
"mute", privateContext->
videoMuted, NULL);
1737 else if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"ismdgsth264viddec") ==
true)
1739 _this->privateContext->
video_dec = (GstElement *) msg->src;
1741 #ifdef INTELCE_USE_VIDRENDSINK
1742 else if (
aamp_StartsWith(GST_OBJECT_NAME(msg->src),
"ismdgstvidpproc") ==
true)
1744 _this->privateContext->video_pproc = (GstElement *) msg->src;
1745 AAMPLOG_WARN(
"AAMPGstPlayer setting rectangle %s", _this->privateContext->
videoRectangle);
1746 g_object_set(msg->src,
"rectangle", _this->privateContext->
videoRectangle, NULL);
1747 AAMPLOG_WARN(
"AAMPGstPlayer setting zoom %d", _this->privateContext->
zoom);
1748 g_object_set(msg->src,
"scale-mode", (
VIDEO_ZOOM_FULL == _this->privateContext->
zoom) ? 0 : 3, NULL);
1763 AAMPLOG_WARN(
"AAMPGstPlayer setting aamp instance for %s decryptor", GST_OBJECT_NAME(msg->src));
1764 GValue val = { 0, };
1765 g_value_init(&val, G_TYPE_POINTER);
1766 g_value_set_pointer(&val, (gpointer) _this->aamp);
1767 g_object_set_property(G_OBJECT(msg->src),
"aamp",&val);
1771 case GST_MESSAGE_NEED_CONTEXT:
1776 const gchar* contextType;
1777 gst_message_parse_context_type(msg, &contextType);
1778 if (!g_strcmp0(contextType,
"drm-preferred-decryption-system-id"))
1781 GstContext* context = gst_context_new(
"drm-preferred-decryption-system-id", FALSE);
1782 GstStructure* contextStructure = gst_context_writable_structure(context);
1784 gst_element_set_context(GST_ELEMENT(GST_MESSAGE_SRC(msg)), context);
1792 case GST_MESSAGE_ELEMENT:
1794 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
1795 (
nullptr == _this->cbExportYUVFrame) &&
1797 gCbgetWindowContentView && gst_is_video_overlay_prepare_window_handle_message(msg))
1799 AAMPLOG_WARN(
"Received prepare-window-handle. Attaching video to window handle=%lu",(*gCbgetWindowContentView)());
1808 case GST_MESSAGE_ASYNC_DONE:
1809 AAMPLOG_INFO(
"Received GST_MESSAGE_ASYNC_DONE message");
1821 return GST_BUS_PASS;
1829 FN_TRACE( __FUNCTION__ );
1833 if (privateContext->
pipeline || privateContext->
bus)
1840 AAMPLOG_WARN(
"Creating gstreamer pipeline");
1841 privateContext->
pipeline = gst_pipeline_new(
"AAMPGstPlayerPipeline");
1844 privateContext->
bus = gst_pipeline_get_bus(GST_PIPELINE(privateContext->
pipeline));
1845 if (privateContext->
bus)
1849 gst_bus_set_sync_handler(privateContext->
bus, (GstBusSyncHandler)
bus_sync_handler,
this, NULL);
1856 AAMPLOG_WARN(
"%s buffering_enabled forced 0, INTELCE", GST_ELEMENT_NAME(privateContext->
pipeline));
1864 privateContext->
positionQuery = gst_query_new_position(GST_FORMAT_TIME);
1873 AAMPLOG_WARN(
"AAMPGstPlayer - gst_pipeline_get_bus failed");
1878 AAMPLOG_WARN(
"AAMPGstPlayer - gst_pipeline_new failed");
1889 FN_TRACE( __FUNCTION__ );
1894 AAMPLOG_WARN(
"Destroying gstreamer pipeline");
1895 gst_object_unref(privateContext->
pipeline);
1904 if (privateContext->
bus)
1906 gst_object_unref(privateContext->
bus);
1908 privateContext->
bus = NULL;
1928 FN_TRACE( __FUNCTION__ );
1929 gpointer dec_handle = NULL;
1932 AAMPLOG_WARN(
"Querying playersinkbin for handle");
1933 g_object_get(this->privateContext->stream[
eMEDIATYPE_VIDEO].
sinkbin,
"video-decode-handle", &dec_handle, NULL);
1935 else if(this->privateContext->
video_dec != NULL)
1937 AAMPLOG_WARN(
"Querying video decoder for handle");
1939 #if defined (REALTEKCE)
1940 dec_handle = this->privateContext->
video_dec;
1942 g_object_get(this->privateContext->
video_dec,
"videodecoder", &dec_handle, NULL);
1945 g_object_get(privateContext->
video_dec,
"decode-handle", &dec_handle, NULL);
1948 AAMPLOG_WARN(
"video decoder handle received %p for video_dec %p", dec_handle, privateContext->
video_dec);
1949 return (
unsigned long)dec_handle;
1957 FN_TRACE( __FUNCTION__ );
1962 pthread_mutex_lock(&mProtectionLock);
1965 AAMPLOG_WARN(
"Previously cached protection event is present for type(%d), clearing!", type);
1969 pthread_mutex_unlock(&mProtectionLock);
1971 AAMPLOG_WARN(
"Queueing protection event for type(%d) keysystem(%s) initData(%p) initDataSize(%d)", type, protSystemId, initData, initDataSize);
1974 if (initData && initDataSize)
1978 pssi = gst_buffer_new_wrapped(g_memdup (initData, initDataSize), initDataSize);
1979 pthread_mutex_lock(&mProtectionLock);
1982 privateContext->
protectionEvent[type] = gst_event_new_protection (protSystemId, pssi,
"dash/mpd");
1986 privateContext->
protectionEvent[type] = gst_event_new_protection (protSystemId, pssi,
"hls/m3u8");
1988 pthread_mutex_unlock(&mProtectionLock);
1990 gst_buffer_unref (pssi);
2000 FN_TRACE( __FUNCTION__ );
2001 pthread_mutex_lock(&mProtectionLock);
2006 AAMPLOG_WARN(
"removing protection event! ");
2011 pthread_mutex_unlock(&mProtectionLock);
2025 case GSTPLAYERSINKBIN_EVENT_HAVE_VIDEO:
2026 GST_INFO(
"got Video PES.\n");
2028 case GSTPLAYERSINKBIN_EVENT_HAVE_AUDIO:
2029 GST_INFO(
"got Audio PES\n");
2031 case GSTPLAYERSINKBIN_EVENT_FIRST_VIDEO_FRAME:
2032 GST_INFO(
"got First Video Frame\n");
2035 case GSTPLAYERSINKBIN_EVENT_FIRST_AUDIO_FRAME:
2036 GST_INFO(
"got First Audio Sample\n");
2039 case GSTPLAYERSINKBIN_EVENT_ERROR_VIDEO_UNDERFLOW:
2041 AAMPLOG_WARN(
"## Got Underflow message from video pipeline ##");
2043 case GSTPLAYERSINKBIN_EVENT_ERROR_AUDIO_UNDERFLOW:
2045 AAMPLOG_WARN(
"## Got Underflow message from audio pipeline ##");
2047 case GSTPLAYERSINKBIN_EVENT_ERROR_VIDEO_PTS:
2049 AAMPLOG_WARN(
"## Got PTS error message from video pipeline ##");
2051 case GSTPLAYERSINKBIN_EVENT_ERROR_AUDIO_PTS:
2053 AAMPLOG_WARN(
"## Got PTS error message from audio pipeline ##");
2056 GST_INFO(
"%s status = 0x%x (Unknown)\n", __FUNCTION__, status);
2071 source = gst_element_factory_make(
"appsrc", NULL);
2074 AAMPLOG_WARN(
"AAMPGstPlayer_GetAppSrc Cannot create source");
2085 AAMPLOG_INFO(
"Subtitle seeking first PTS %02f", _this->aamp->
GetFirstPTS());
2086 gst_element_seek_simple(GST_ELEMENT(source), GST_FORMAT_TIME, GST_SEEK_FLAG_NONE, _this->aamp->
GetFirstPTS() * GST_SECOND);
2098 FN_TRACE( __FUNCTION__ );
2099 media_stream* stream = &privateContext->stream[mediaType];
2100 stream->bufferUnderrun =
false;
2102 stream->
flush =
false;
2105 pthread_mutex_lock(&stream->sourceLock);
2114 AAMPLOG_WARN(
"AAMPGstPlayer::TearDownStream: Failed to set NULL state for sinkbin");
2116 if (!gst_bin_remove(GST_BIN(privateContext->
pipeline), GST_ELEMENT(stream->
sinkbin)))
2118 AAMPLOG_WARN(
"AAMPGstPlayer::TearDownStream: Unable to remove sinkbin from pipeline");
2123 AAMPLOG_WARN(
"AAMPGstPlayer::TearDownStream: sinkbin = NULL, skip remove sinkbin from pipeline");
2130 AAMPLOG_WARN(
"AAMPGstPlayer::TearDownStream: Failed to set NULL state for source");
2132 if (!gst_bin_remove(GST_BIN(privateContext->
pipeline), GST_ELEMENT(stream->
source)))
2134 AAMPLOG_WARN(
"AAMPGstPlayer::TearDownStream: Unable to remove source from pipeline");
2147 pthread_mutex_unlock(&stream->sourceLock);
2152 #if !defined(INTELCE) || defined(INTELCE_USE_VIDRENDSINK)
2156 #ifdef INTELCE_USE_VIDRENDSINK
2157 privateContext->video_pproc = NULL;
2169 AAMPLOG_WARN(
"AAMPGstPlayer::TearDownStream: exit mediaType = %d", mediaType);
2172 #define NO_PLAYBIN 1
2181 media_stream* stream = &_this->privateContext->stream[streamId];
2191 AAMPLOG_INFO(
"AAMPGstPlayer_SetupStream - subs using subtecbin");
2192 stream->
sinkbin = gst_element_factory_make(
"subtecbin", NULL);
2195 AAMPLOG_WARN(
"Cannot set up subtitle subtecbin");
2198 g_object_set(G_OBJECT(stream->
sinkbin),
"sync", FALSE, NULL);
2203 if (!gst_element_link_many(stream->
source, stream->
sinkbin, NULL))
2205 AAMPLOG_WARN(
"Failed to link subtitle elements");
2209 gst_element_sync_state_with_parent(stream->
source);
2210 gst_element_sync_state_with_parent(stream->
sinkbin);
2216 AAMPLOG_INFO(
"AAMPGstPlayer_SetupStream - subs using playbin");
2217 stream->
sinkbin = gst_element_factory_make(
"playbin", NULL);
2218 auto vipertransform = gst_element_factory_make(
"vipertransform", NULL);
2219 auto textsink = gst_element_factory_make(
"subtecsink", NULL);
2220 auto subtitlebin = gst_bin_new(
"subtitlebin");
2221 gst_bin_add_many(GST_BIN(subtitlebin), vipertransform, textsink, NULL);
2222 gst_element_link(vipertransform, textsink);
2223 gst_element_add_pad(subtitlebin, gst_ghost_pad_new(
"sink", gst_element_get_static_pad(vipertransform,
"sink")));
2225 g_object_set(stream->
sinkbin,
"text-sink", subtitlebin, NULL);
2231 AAMPLOG_INFO(
"AAMPGstPlayer_SetupStream - using playbin");
2232 stream->
sinkbin = gst_element_factory_make(
"playbin", NULL);
2235 AAMPLOG_INFO(
"AAMPGstPlayer_SetupStream - using westerossink");
2236 GstElement* vidsink = gst_element_factory_make(
"westerossink", NULL);
2237 #if defined(BRCM) && defined(CONTENT_4K_SUPPORTED)
2238 g_object_set(vidsink,
"secure-video",
TRUE, NULL);
2240 g_object_set(stream->
sinkbin,
"video-sink", vidsink, NULL);
2244 GstElement* vidsink = gst_element_factory_make(
"brcmvideosink", NULL);
2245 #if defined(BRCM) && defined(CONTENT_4K_SUPPORTED)
2246 g_object_set(vidsink,
"secure-video",
TRUE, NULL);
2248 g_object_set(stream->
sinkbin,
"video-sink", vidsink, NULL);
2250 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
2255 AAMPLOG_WARN(
"AAMPGstPlayer_SetupStream - using appsink\n");
2256 GstElement* appsink = gst_element_factory_make(
"appsink", NULL);
2258 GstCaps *caps = gst_caps_new_simple(
"video/x-raw",
"format", G_TYPE_STRING,
"I420", NULL);
2259 gst_app_sink_set_caps (GST_APP_SINK(appsink), caps);
2260 g_object_set (G_OBJECT (appsink),
"emit-signals",
TRUE,
"sync",
TRUE, NULL);
2261 g_signal_connect (appsink,
"new-sample", G_CALLBACK (AAMPGstPlayer::AAMPGstPlayer_OnVideoSample), _this);
2262 g_object_set(stream->
sinkbin,
"video-sink", appsink, NULL);
2270 GstElement *audiosink = gst_element_factory_make(
"audsrvsink", NULL);
2271 g_object_set(audiosink,
"session-type", 2, NULL );
2272 g_object_set(audiosink,
"session-name",
"btSAP", NULL );
2273 g_object_set(audiosink,
"session-private",
TRUE, NULL );
2275 g_object_set(stream->
sinkbin,
"audio-sink", audiosink, NULL);
2276 AAMPLOG_WARN(
"AAMPGstPlayer_SetupStream - using audsrvsink");
2279 #if defined(INTELCE) && !defined(INTELCE_USE_VIDRENDSINK)
2282 AAMPLOG_WARN(
"using ismd_vidsink");
2283 GstElement* vidsink = _this->privateContext->
video_sink;
2286 vidsink = gst_element_factory_make(
"ismd_vidsink", NULL);
2289 AAMPLOG_WARN(
"Could not create ismd_vidsink element");
2293 _this->privateContext->
video_sink = GST_ELEMENT(gst_object_ref( vidsink));
2298 AAMPLOG_WARN(
"Reusing existing vidsink element");
2300 AAMPLOG_WARN(
"Set video-sink %p to playbin %p", vidsink, stream->
sinkbin);
2301 g_object_set(stream->
sinkbin,
"video-sink", vidsink, NULL);
2304 gst_bin_add(GST_BIN(_this->privateContext->
pipeline), stream->
sinkbin);
2306 g_object_get(stream->
sinkbin,
"flags", &flags, NULL);
2307 AAMPLOG_WARN(
"playbin flags1: 0x%x", flags);
2308 #if (defined(__APPLE__) || defined(NO_NATIVE_AV))
2310 #elif defined (REALTEKCE)
2316 g_object_set(stream->
sinkbin,
"flags", flags, NULL);
2320 g_object_set(stream->
sinkbin,
"uri",
"appsrc://", NULL);
2321 g_signal_connect(stream->
sinkbin,
"deep-notify::source", G_CALLBACK(
found_source), _this);
2329 #if defined(REALTEKCE)
2332 int MaxGstVideoBufBytes = 0;
2334 AAMPLOG_INFO(
"Setting gst Video buffer size bytes to %d", MaxGstVideoBufBytes);
2335 g_object_set(stream->
sinkbin,
"buffer-size", (guint64)MaxGstVideoBufBytes, NULL);
2336 g_object_set(stream->
sinkbin,
"buffer-duration", 3000000000, NULL);
2339 gst_element_sync_state_with_parent(stream->
sinkbin);
2346 gst_bin_add(GST_BIN(_this->privateContext->
pipeline), stream->
source);
2347 gst_element_sync_state_with_parent(stream->
source);
2348 stream->
sinkbin = gst_element_factory_make(
"playersinkbin", NULL);
2351 AAMPLOG_WARN(
"AAMPGstPlayer_SetupStream Cannot create sink");
2355 gst_bin_add(GST_BIN(_this->privateContext->
pipeline), stream->
sinkbin);
2359 AAMPLOG_WARN(
"gst_element_link is error");
2361 gst_element_sync_state_with_parent(stream->
sinkbin);
2363 AAMPLOG_WARN(
"AAMPGstPlayer_SetupStream: Created playersinkbin. Setting rectangle");
2365 g_object_set(stream->
sinkbin,
"zoom", _this->privateContext->
zoom, NULL);
2366 g_object_set(stream->
sinkbin,
"video-mute", _this->privateContext->
videoMuted, NULL);
2381 uint32_t timeScale = 0;
2395 bool bParse =
false;
2400 catch( std::bad_alloc& ba)
2402 AAMPLOG_ERR(
"Bad allocation: %s", ba.what() );
2404 catch( std::exception &e)
2406 AAMPLOG_ERR(
"Unhandled exception: %s", e.what() );
2410 AAMPLOG_ERR(
"Unknown exception");
2412 if(bParse && (0 != timeScale))
2418 ret = fPts/(timeScale*1.0);
2434 media_stream* stream = &privateContext->stream[mediaType];
2435 gboolean enableOverride = FALSE;
2436 GstPad* sourceEleSrcPad = gst_element_get_static_pad(GST_ELEMENT(stream->
source),
"src");
2439 AAMPLOG_WARN(
"flush pipeline");
2440 gboolean ret = gst_pad_push_event(sourceEleSrcPad, gst_event_new_flush_start());
2441 if (!ret) AAMPLOG_WARN(
"flush start error");
2442 GstEvent*
event = gst_event_new_flush_stop(FALSE);
2443 ret = gst_pad_push_event(sourceEleSrcPad, event);
2444 if (!ret) AAMPLOG_WARN(
"flush stop error");
2445 stream->
flush =
false;
2450 #ifdef ENABLE_AAMP_QTDEMUX_OVERRIDE
2451 enableOverride =
TRUE;
2453 enableOverride = (privateContext->
rate != AAMP_NORMAL_PLAY_RATE);
2460 GstStructure * eventStruct = gst_structure_new(
"aamp_override",
"enable", G_TYPE_BOOLEAN, enableOverride,
"rate", G_TYPE_FLOAT, (
float)privateContext->
rate,
"aampplayer", G_TYPE_BOOLEAN,
TRUE, NULL);
2461 #ifdef ENABLE_AAMP_QTDEMUX_OVERRIDE
2462 if ( privateContext->
rate == AAMP_NORMAL_PLAY_RATE )
2464 guint64 basePTS = aamp->
GetFirstPTS() * GST_SECOND;
2469 AAMPLOG_WARN(
"Set override event's basePTS [ %" G_GUINT64_FORMAT
"]", basePTS);
2470 gst_structure_set (eventStruct,
"basePTS", G_TYPE_UINT64, basePTS, NULL);
2473 if (!gst_pad_push_event(sourceEleSrcPad, gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, eventStruct)))
2475 AAMPLOG_WARN(
"Error on sending rate override event");
2518 AAMPLOG_WARN(
"pushing protection event! mediatype: %d", mediaType);
2519 if (!gst_pad_push_event(sourceEleSrcPad, gst_event_ref(event)))
2521 AAMPLOG_WARN(
"push protection event failed!");
2526 if (!gst_pad_push_event(sourceEleSrcPad, gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, gst_structure_new(
"discard-segment-event-with-zero-start",
"enable", G_TYPE_BOOLEAN,
TRUE, NULL))))
2528 AAMPLOG_WARN(
"Error on sending discard-segment-event-with-zero-start custom event");
2532 gst_object_unref(sourceEleSrcPad);
2534 stream->
flush =
false;
2552 if (*data++ ==
'I' && *data++ ==
'D' && *data++ ==
'3' && *data++ >= 2)
2561 #define ID3_HEADER_SIZE 10
2571 uint32_t bufferSize = 0;
2574 memcpy(tagSize, data+6, 4);
2578 if (tagSize[0] > 0x7f || tagSize[1] > 0x7f || tagSize[2] > 0x7f || tagSize[3] > 0x7f)
2580 AAMPLOG_WARN(
"Bad header format");
2584 bufferSize = tagSize[0] << 21;
2585 bufferSize += tagSize[1] << 14;
2586 bufferSize += tagSize[2] << 7;
2587 bufferSize += tagSize[3];
2598 FN_TRACE( __FUNCTION__ );
2599 media_stream* stream = &privateContext->stream[mediaType];
2600 GstPad* sourceEleSrcPad = gst_element_get_static_pad(GST_ELEMENT(stream->
source),
"src");
2604 gst_segment_init(&segment, GST_FORMAT_TIME);
2606 segment.start = startPts;
2607 segment.position = 0;
2608 segment.rate = AAMP_NORMAL_PLAY_RATE;
2609 segment.applied_rate = AAMP_NORMAL_PLAY_RATE;
2610 if(stopPts) segment.stop = stopPts;
2612 #if defined(AMLOGIC)
2615 segment.applied_rate = privateContext->
rate;
2618 AAMPLOG_INFO(
"Sending segment event for mediaType[%d]. start %" G_GUINT64_FORMAT
" stop %" G_GUINT64_FORMAT
" rate %f applied_rate %f", mediaType, segment.start, segment.stop, segment.rate, segment.applied_rate);
2619 GstEvent*
event = gst_event_new_segment (&segment);
2620 if (!gst_pad_push_event(sourceEleSrcPad, event))
2622 AAMPLOG_ERR(
"gst_pad_push_event segment error");
2641 FN_TRACE( __FUNCTION__ );
2642 GstClockTime pts = (GstClockTime)(fpts * GST_SECOND);
2643 GstClockTime dts = (GstClockTime)(fdts * GST_SECOND);
2644 GstClockTime duration = (GstClockTime)(fDuration * 1000000000LL);
2647 hasId3Header(mediaType,
static_cast<const uint8_t*
>(ptr), len))
2649 uint32_t len =
getId3TagSize(
static_cast<const uint8_t*
>(ptr));
2654 AAMPLOG_INFO(
"AAMPGstPlayer: Found new ID3 frame");
2665 media_stream *stream = &privateContext->stream[mediaType];
2671 pthread_mutex_lock(&stream->sourceLock);
2679 pthread_mutex_unlock(&stream->sourceLock);
2683 if (isFirstBuffer && !waitForPtsRestamp)
2693 #if defined(AMLOGIC)
2696 if(!aamp->mbNewSegmentEvtSent[mediaType] || (mediaType ==
eMEDIATYPE_VIDEO && aamp->
rate != AAMP_NORMAL_PLAY_RATE))
2699 aamp->mbNewSegmentEvtSent[mediaType]=
true;
2703 AAMPLOG_TRACE(
"mediaType[%d] SendGstEvents - first buffer received !!! initFragment: %d", mediaType, initFragment);
2710 bool bPushBuffer =
true;
2714 buffer = gst_buffer_new_and_alloc((guint)len);
2719 gst_buffer_map(buffer, &map, GST_MAP_WRITE);
2720 memcpy(map.data, ptr, len);
2721 gst_buffer_unmap(buffer, &map);
2722 GST_BUFFER_PTS(buffer) = pts;
2723 GST_BUFFER_DTS(buffer) = dts;
2724 GST_BUFFER_DURATION(buffer) = duration;
2725 AAMPLOG_TRACE(
"Sending segment for mediaType[%d]. pts %" G_GUINT64_FORMAT
" dts %" G_GUINT64_FORMAT
" ", mediaType, pts, dts);
2729 bPushBuffer =
false;
2734 buffer = gst_buffer_new_wrapped((gpointer)ptr,(gsize)len);
2738 GST_BUFFER_PTS(buffer) = pts;
2739 GST_BUFFER_DTS(buffer) = dts;
2740 GST_BUFFER_DURATION(buffer) = duration;
2741 AAMPLOG_TRACE(
"Sending segment for mediaType[%d]. pts %" G_GUINT64_FORMAT
" dts %" G_GUINT64_FORMAT
" ", mediaType, pts, dts);
2745 bPushBuffer =
false;
2756 GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(stream->
source), buffer);
2758 if (ret != GST_FLOW_OK)
2760 AAMPLOG_WARN(
"gst_app_src_push_buffer error: %d[%s] mediaType %d", ret, gst_flow_get_name (ret), (
int)mediaType);
2761 if (ret != GST_FLOW_EOS && ret != GST_FLOW_FLUSHING)
2764 else if (stream->bufferUnderrun)
2766 stream->bufferUnderrun =
false;
2770 if (isFirstBuffer ==
true && ret == GST_FLOW_OK)
2775 pthread_mutex_unlock(&stream->sourceLock);
2789 #ifdef REALTEKCE // HACK: Have this hack until reakteck Westeros fixes missing first frame call back missing during trick play.
2807 FN_TRACE( __FUNCTION__ );
2808 return SendHelper( mediaType, ptr, len, fpts, fdts, fDuration,
true );
2817 FN_TRACE( __FUNCTION__ );
2818 return SendHelper( mediaType, ptr, len, fpts, fdts, fDuration,
false , initFragment );
2826 FN_TRACE( __FUNCTION__ );
2835 FN_TRACE( __FUNCTION__ );
2836 AAMPLOG_WARN(
"videoFormat %d audioFormat %d auxFormat %d subFormat %d",format, audioFormat, auxFormat, subFormat);
2844 AAMPLOG_WARN(
"Gstreamer subs enabled");
2849 AAMPLOG_WARN(
"Gstreamer subs disabled");
2853 if (forwardAudioToAux)
2855 AAMPLOG_WARN(
"AAMPGstPlayer: Override auxFormat %d -> %d", auxFormat, audioFormat);
2868 #if defined(REALTEKCE)
2869 privateContext->firstTuneWithWesterosSinkOff =
true;
2877 #ifdef AAMP_STOP_SINK_ON_SEEK
2881 if (privateContext->
pipeline == NULL || privateContext->
bus == NULL)
2886 if (setReadyAfterPipelineCreation)
2890 AAMPLOG_ERR(
"AAMPGstPlayer_Configure GST_STATE_READY failed on forceful set");
2894 AAMPLOG_INFO(
"Forcefully set pipeline to ready state due to track_id change");
2900 memset(configureStream, 0,
sizeof(configureStream));
2905 if (stream->
format != newFormat[i])
2909 AAMPLOG_WARN(
"Closing stream %d old format = %d, new format = %d",
2910 i, stream->
format, newFormat[i]);
2911 configureStream[i] =
true;
2916 #if defined(__APPLE__) || defined(UBUNTU)
2917 if (this->privateContext->
rate > 1 || this->privateContext->rate < 0)
2920 configureStream[i] =
true;
2924 configureStream[i] =
false;
2932 AAMPLOG_WARN(
"AudioType Changed. Force configure pipeline");
2933 configureStream[i] =
true;
2950 stream->
format = newFormat[i];
2952 #ifdef USE_PLAYERSINKBIN
2955 AAMPLOG_WARN(
"using playersinkbin, track = %d", i);
2965 AAMPLOG_WARN(
"AAMPGstPlayer: track %d failed", i);
2983 AAMPLOG_WARN(
"AAMPGstPlayer_Configure GST_STATE_PLAUSED failed");
2991 AAMPLOG_WARN(
"AAMPGstPlayer: GST_STATE_PLAYING failed");
2997 privateContext->
paused =
false;
3001 AAMPLOG_WARN(
"exiting AAMPGstPlayer");
3016 g_signal_emit_by_name(source,
"end-of-stream", &ret);
3017 if (ret != GST_FLOW_OK)
3019 AAMPLOG_WARN(
"gst_app_src_push_buffer error: %d", ret);
3029 FN_TRACE( __FUNCTION__ );
3030 AAMPLOG_WARN(
"entering AAMPGstPlayer_EndOfStreamReached type %d", (
int)type);
3036 AAMPLOG_WARN(
"EOS received as first buffer ");
3045 if (AAMP_NORMAL_PLAY_RATE != privateContext->
rate)
3074 FN_TRACE( __FUNCTION__ );
3075 AAMPLOG_WARN(
"entering AAMPGstPlayer_Stop keepLastFrame %d", keepLastFrame);
3078 gst_bus_remove_watch(privateContext->
bus);
3083 privateContext->keepLastFrame = keepLastFrame;
3084 g_object_set(privateContext->
video_sink,
"stop-keep-frame", keepLastFrame, NULL);
3085 #if !defined(INTELCE_USE_VIDRENDSINK)
3088 gst_object_unref(privateContext->
video_sink);
3093 g_object_set(privateContext->
video_sink,
"reuse-vidrend", keepLastFrame, NULL);
3105 this->
IdleTaskRemove(privateContext->firstProgressCallbackIdleTask);
3123 AAMPLOG_WARN(
"AAMPGstPlayer: Remove eosCallbackIdleTaskId %d", privateContext->
eosCallbackIdleTaskId);
3142 if (this->privateContext->
pipeline)
3146 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline state set to null");
3153 pInstance->Release();
3161 privateContext->
rate = AAMP_NORMAL_PLAY_RATE;
3164 privateContext->
paused =
false;
3166 AAMPLOG_WARN(
"exiting AAMPGstPlayer_Stop");
3178 static std::string
StateText(GstState state,
char start,
char end, GstState currentState, GstState parentState = GST_STATE_VOID_PENDING)
3180 if((state == GST_STATE_VOID_PENDING) || ((state == currentState) && ((state == parentState) || (parentState == GST_STATE_VOID_PENDING))))
3186 std::string returnStringBuilder(1, start);
3187 returnStringBuilder += gst_element_state_get_name(state);
3188 returnStringBuilder += end;
3189 return returnStringBuilder;
3201 auto elementName = gst_element_get_name(element);
3205 g_free((
void *)elementName);
3209 name =
"unnamed element";
3226 static std::string
GetStatus(gpointer pElementOrBin,
int& recursionCount, gpointer pParent =
nullptr)
3229 constexpr
int RECURSION_LIMIT = 10;
3230 if(RECURSION_LIMIT < recursionCount)
3232 return "recursion limit exceeded";
3235 std::string returnStringBuilder(
"");
3236 if(
nullptr !=pElementOrBin)
3238 if(GST_IS_ELEMENT(pElementOrBin))
3240 auto pElement =
reinterpret_cast<_GstElement*
>(pElementOrBin);
3242 bool validParent = (pParent !=
nullptr) && GST_IS_ELEMENT(pParent);
3244 returnStringBuilder +=
SafeName(pElement);
3246 GstState statePending;
3247 auto changeStatus = gst_element_get_state(pElement, &state, &statePending, 0);
3248 switch(changeStatus)
3250 case GST_STATE_CHANGE_FAILURE:
3251 returnStringBuilder +=
"!";
3254 case GST_STATE_CHANGE_SUCCESS:
3258 case GST_STATE_CHANGE_ASYNC:
3259 returnStringBuilder +=
"~";
3262 case GST_STATE_CHANGE_NO_PREROLL:
3263 returnStringBuilder +=
"*";
3267 returnStringBuilder +=
"?";
3271 returnStringBuilder +=
":";
3273 returnStringBuilder += gst_element_state_get_name(state);
3274 auto parentState = validParent?GST_STATE(pParent):GST_STATE_VOID_PENDING;
3276 returnStringBuilder +=
StateText(statePending,
'<',
'>', state,
3277 validParent?GST_STATE_PENDING(pParent):GST_STATE_VOID_PENDING);
3278 returnStringBuilder +=
StateText(GST_STATE_TARGET(pElement),
'[',
']', state,
3279 validParent?GST_STATE_TARGET(pParent):GST_STATE_VOID_PENDING);
3280 returnStringBuilder +=
StateText(GST_STATE_NEXT(pElement),
'{',
'}', state,
3281 validParent?GST_STATE_NEXT(pParent):GST_STATE_VOID_PENDING);
3285 if(GST_IS_BIN(pElementOrBin))
3287 returnStringBuilder +=
" (";
3289 auto pBin =
reinterpret_cast<_GstElement*
>(pElementOrBin);
3291 for (
auto currentListItem = GST_BIN_CHILDREN(pBin);
3293 currentListItem = currentListItem->next)
3301 returnStringBuilder +=
", ";
3304 auto currentChildElement = currentListItem->data;
3305 if (
nullptr != currentChildElement)
3307 returnStringBuilder +=
GetStatus(currentChildElement, recursionCount, pBin);
3310 returnStringBuilder +=
")";
3314 return returnStringBuilder;
3319 int recursionCount = 0;
3320 AAMPLOG_WARN(
"AAMPGstPlayer: %s Status: %s",
SafeName(pElementOrBin).c_str(),
GetStatus(pElementOrBin, recursionCount).c_str());
3328 FN_TRACE( __FUNCTION__ );
3338 g_object_get(source,
"block", &rcBool, NULL);
3339 AAMPLOG_WARN(
"\tblock=%d", (
int)rcBool);
3342 g_object_get(source,
"emit-signals", &rcBool, NULL);
3343 AAMPLOG_WARN(
"\temit-signals=%d", (
int)rcBool);
3345 rcFormat = (GstFormat)0;
3346 g_object_get(source,
"format", &rcFormat, NULL);
3347 AAMPLOG_WARN(
"\tformat=%d", (
int)rcFormat);
3350 g_object_get(source,
"is-live", &rcBool, NULL);
3351 AAMPLOG_WARN(
"\tis-live=%d", (
int)rcBool);
3354 g_object_get(source,
"max-bytes", &rcUint64, NULL);
3355 AAMPLOG_WARN(
"\tmax-bytes=%d", (
int)rcUint64);
3358 g_object_get(source,
"max-latency", &rcInt64, NULL);
3359 AAMPLOG_WARN(
"\tmax-latency=%d", (
int)rcInt64);
3362 g_object_get(source,
"min-latency", &rcInt64, NULL);
3363 AAMPLOG_WARN(
"\tmin-latency=%d", (
int)rcInt64);
3366 g_object_get(source,
"size", &rcInt64, NULL);
3367 AAMPLOG_WARN(
"\tsize=%d", (
int)rcInt64);
3370 GstFormat format = GST_FORMAT_TIME;
3371 if (gst_element_query_position(privateContext->
pipeline, format, &pos) &&
3372 gst_element_query_duration(privateContext->
pipeline, format, &len))
3374 AAMPLOG_WARN(
"Position: %" GST_TIME_FORMAT
" / %" GST_TIME_FORMAT
"\r",
3375 GST_TIME_ARGS(pos), GST_TIME_ARGS(len));
3391 GstState gst_current;
3392 GstState gst_pending;
3393 float timeout = 100.0;
3394 gint gstGetStateCnt = GST_ELEMENT_GET_STATE_RETRY_CNT_MAX;
3398 if ((GST_STATE_CHANGE_SUCCESS
3399 == gst_element_get_state(_this->privateContext->
pipeline, &gst_current, &gst_pending, timeout * GST_MSECOND))
3400 && (gst_current == stateToValidate))
3403 "validateStateWithMsTimeout - PIPELINE gst_element_get_state - SUCCESS : State = %d, Pending = %d",
3404 gst_current, gst_pending);
3407 g_usleep (msTimeOut * 1000);
3409 while ((gst_current != stateToValidate) && (gstGetStateCnt-- != 0));
3411 AAMPLOG_WARN(
"validateStateWithMsTimeout - PIPELINE gst_element_get_state - FAILURE : State = %d, Pending = %d",
3412 gst_current, gst_pending);
3425 GstStateChangeReturn rc = GST_STATE_CHANGE_FAILURE;
3429 bool syncOnlyTransition = (targetState==GST_STATE_NULL)||(targetState==GST_STATE_READY);
3434 auto stateChangeReturn = gst_element_get_state(element, ¤t, &pending, 0);
3435 switch(stateChangeReturn)
3437 case GST_STATE_CHANGE_FAILURE:
3438 AAMPLOG_WARN(
"AAMPGstPlayer: %s is in FAILURE state : current %s pending %s",
SafeName(element).c_str(),gst_element_state_get_name(current), gst_element_state_get_name(pending));
3441 case GST_STATE_CHANGE_SUCCESS:
3443 case GST_STATE_CHANGE_ASYNC:
3444 if(syncOnlyTransition)
3446 AAMPLOG_WARN(
"AAMPGstPlayer: %s state is changing asynchronously : current %s pending %s",
SafeName(element).c_str(),gst_element_state_get_name(current), gst_element_state_get_name(pending));
3451 AAMPLOG_ERR(
"AAMPGstPlayer: %s is in an unknown state",
SafeName(element).c_str());
3455 if(syncOnlyTransition)
3457 AAMPLOG_WARN(
"AAMPGstPlayer: Attempting to set %s state to %s",
SafeName(element).c_str(), gst_element_state_get_name(targetState));
3459 rc = gst_element_set_state(element, targetState);
3460 if(syncOnlyTransition)
3462 AAMPLOG_WARN(
"AAMPGstPlayer: %s state set to %s",
SafeName(element).c_str(), gst_element_state_get_name(targetState));
3467 AAMPLOG_ERR(
"AAMPGstPlayer: Attempted to set the state of a null pointer");
3478 FN_TRACE( __FUNCTION__ );
3490 FN_TRACE( __FUNCTION__ );
3492 AAMPLOG_WARN(
"Entering AAMPGstPlayer::PauseAndFlush() pipeline state %s",
3493 gst_element_state_get_name(GST_STATE(privateContext->
pipeline)));
3494 GstStateChangeReturn rc;
3495 GstState stateBeforeFlush = GST_STATE_PAUSED;
3496 #ifndef USE_PLAYERSINKBIN
3498 stateBeforeFlush = GST_STATE_NULL;
3501 if (GST_STATE_CHANGE_ASYNC == rc)
3505 AAMPLOG_WARN(
"AAMPGstPlayer_Flush - validateStateWithMsTimeout - FAILED GstState %d", GST_STATE_PAUSED);
3508 else if (GST_STATE_CHANGE_SUCCESS != rc)
3510 AAMPLOG_WARN(
"AAMPGstPlayer_Flush - gst_element_set_state - FAILED rc %d", rc);
3512 gboolean ret = gst_element_send_event( GST_ELEMENT(privateContext->
pipeline), gst_event_new_flush_start());
3513 if (!ret) AAMPLOG_WARN(
"AAMPGstPlayer_Flush: flush start error");
3514 ret = gst_element_send_event(GST_ELEMENT(privateContext->
pipeline), gst_event_new_flush_stop(
TRUE));
3515 if (!ret) AAMPLOG_WARN(
"AAMPGstPlayer_Flush: flush stop error");
3520 if (GST_STATE_CHANGE_ASYNC == rc)
3522 #ifdef AAMP_WAIT_FOR_PLAYING_STATE
3525 AAMPLOG_WARN(
"AAMPGstPlayer_Flush - validateStateWithMsTimeout - FAILED GstState %d",
3530 else if (GST_STATE_CHANGE_SUCCESS != rc)
3532 AAMPLOG_WARN(
"AAMPGstPlayer_Flush - gst_element_set_state - FAILED rc %d", rc);
3535 this->privateContext->total_bytes = 0;
3538 AAMPLOG_WARN(
"exiting AAMPGstPlayer_FlushEvent");
3547 FN_TRACE( __FUNCTION__ );
3554 privateContext->
durationQuery = gst_query_new_duration(GST_FORMAT_TIME);
3561 gst_query_parse_duration(privateContext->
durationQuery, NULL, &duration);
3562 rc = GST_TIME_AS_MSECONDS(duration);
3566 AAMPLOG_WARN(
"Duration query failed");
3572 AAMPLOG_WARN(
"Duration query is NULL");
3577 AAMPLOG_WARN(
"Pipeline is in %s state", gst_element_state_get_name(privateContext->
pipelineState) );
3582 AAMPLOG_WARN(
"Pipeline is null");
3592 FN_TRACE( __FUNCTION__ );
3594 if (privateContext->
pipeline == NULL)
3596 AAMPLOG_ERR(
"Pipeline is NULL");
3602 AAMPLOG_ERR(
"Position query is NULL");
3610 GST_STATE_TARGET(privateContext->
pipeline) != GST_STATE_PLAYING)
3612 AAMPLOG_INFO(
"Pipeline is in %s state, returning position as %ld", gst_element_state_get_name(privateContext->
pipelineState), rc);
3621 GstQuery *segmentQuery = gst_query_new_segment(GST_FORMAT_TIME);
3624 if (gst_element_query(video->
source, segmentQuery) ==
TRUE)
3627 gst_query_parse_segment(segmentQuery, NULL, NULL, &start, NULL);
3628 privateContext->
segmentStart = GST_TIME_AS_MSECONDS(start);
3629 AAMPLOG_WARN(
"AAMPGstPlayer: Segment start: %" G_GINT64_FORMAT, privateContext->
segmentStart);
3633 AAMPLOG_ERR(
"AAMPGstPlayer: segment query failed");
3635 gst_query_unref(segmentQuery);
3641 int rate = privateContext->
rate;
3642 gst_query_parse_position(privateContext->
positionQuery, NULL, &pos);
3648 #if !defined(REALTEKCE) // Pos always start from "0" in Realtek
3652 rc = (GST_TIME_AS_MSECONDS(pos) - privateContext->
segmentStart) * rate;
3657 rc = GST_TIME_AS_MSECONDS(pos) * rate;
3671 FN_TRACE( __FUNCTION__ );
3672 bool retValue =
true;
3676 AAMPLOG_WARN(
"entering AAMPGstPlayer_Pause - pause(%d) stop-pre-buffering(%d)", pause, forceStopGstreamerPreBuffering);
3678 if (privateContext->
pipeline != NULL)
3680 GstState nextState = pause ? GST_STATE_PAUSED : GST_STATE_PLAYING;
3682 if (GST_STATE_PAUSED == nextState && forceStopGstreamerPreBuffering)
3694 if (GST_STATE_CHANGE_ASYNC == rc)
3699 AAMPLOG_WARN(
"AAMPGstPlayer_Pause - validateStateWithMsTimeout - FAILED GstState %d", nextState);
3702 else if (GST_STATE_CHANGE_SUCCESS != rc)
3704 AAMPLOG_WARN(
"AAMPGstPlayer_Pause - gst_element_set_state - FAILED rc %d", rc);
3707 privateContext->
paused = pause;
3714 AAMPLOG_WARN(
"Pipeline is NULL");
3719 GstStateChangeReturn rc;
3722 media_stream *stream = &privateContext->stream[iTrack];
3740 FN_TRACE( __FUNCTION__ );
3741 int currentX = 0, currentY = 0, currentW = 0, currentH = 0;
3748 sscanf(privateContext->
videoRectangle,
"%d,%d,%d,%d",¤tX,¤tY,¤tW,¤tH);
3751 if ((currentX == x) && (currentY == y) && (currentW == w) && (currentH == h))
3753 AAMPLOG_TRACE(
"Ignoring new co-ordinates, same as current Rect (x:%d, y:%d, w:%d, h:%d)", currentX, currentY, currentW, currentH);
3760 AAMPLOG_WARN(
"Rect %s, using_playersinkbin = %d, video_sink =%p",
3774 #if defined(INTELCE_USE_VIDRENDSINK)
3775 else if (privateContext->video_pproc)
3777 g_object_set(privateContext->video_pproc,
"rectangle", privateContext->
videoRectangle, NULL);
3788 AAMPLOG_WARN(
"Scaling not possible at this time");
3793 AAMPLOG_WARN(
"New co-ordinates ignored since westerossink is used");
3802 FN_TRACE( __FUNCTION__ );
3804 AAMPLOG_INFO(
"SetVideoZoom :: ZoomMode %d, using_playersinkbin = %d, video_sink =%p",
3807 privateContext->
zoom = zoom;
3810 g_object_set(stream->
sinkbin,
"zoom", zoom, NULL);
3817 #elif defined(INTELCE_USE_VIDRENDSINK)
3818 else if (privateContext->video_pproc)
3820 g_object_set(privateContext->video_pproc,
"scale-mode",
VIDEO_ZOOM_FULL == zoom ? 0 : 3, NULL);
3832 FN_TRACE( __FUNCTION__ );
3836 AAMPLOG_INFO(
"pts_offset %" G_GUINT64_FORMAT
", seek_pos_seconds %2f, subtitle_sink =%p", pts_offset, aamp->
seek_pos_seconds, privateContext->
subtitle_sink);
3838 g_object_set(privateContext->
subtitle_sink,
"pts-offset",
static_cast<std::uint64_t
>(pts_offset), NULL);
3841 AAMPLOG_INFO(
"subtitle_sink is NULL");
3846 FN_TRACE( __FUNCTION__ );
3852 AAMPLOG_INFO(
"muted %d, subtitle_sink =%p", muted, privateContext->
subtitle_sink);
3857 AAMPLOG_INFO(
"subtitle_sink is NULL");
3865 FN_TRACE( __FUNCTION__ );
3880 g_object_set(privateContext->
video_sink,
"show-video-window", !privateContext->
videoMuted, NULL);
3892 FN_TRACE( __FUNCTION__ );
3904 const std::lock_guard<std::mutex> lock(privateContext->
volumeMuteMutex);
3905 FN_TRACE( __FUNCTION__ );
3906 GstElement *gSource = NULL;
3907 char *propertyName = NULL;
3910 AAMPLOG_WARN(
" volume == %lf muted == %s", privateContext->
audioVolume, privateContext->
audioMuted?
"true":
"false");
3912 AAMPLOG_INFO(
"AAMPGstPlayer: using_playersinkbin = %d, audio_sink = %p",
3918 propertyName = (
char*)
"audio-mute";
3920 #if (defined(__APPLE__) || defined(REALTEKCE))
3924 propertyName = (
char*)
"mute";
3930 propertyName = (
char*)
"mute";
3939 AAMPLOG_WARN(
"AAMPGstPlayer: Setting Volume %f using stream-volume property of audio-sink", privateContext->
audioVolume);
3940 g_object_set(gSource,
"stream-volume", privateContext->
audioVolume, NULL);
3947 AAMPLOG_WARN(
"AAMPGstPlayer: Audio Muted");
3951 AAMPLOG_WARN(
"AAMPGstPlayer: Setting input-gain to %f", INPUT_GAIN_DB_MUTE);
3952 g_object_set(privateContext->
audio_sink,
"input-gain", INPUT_GAIN_DB_MUTE, NULL);
3957 g_object_set(gSource, propertyName,
true, NULL);
3965 AAMPLOG_WARN(
"AAMPGstPlayer: Audio Unmuted after a Mute");
3969 AAMPLOG_WARN(
"AAMPGstPlayer: Setting input-gain to %f", INPUT_GAIN_DB_UNMUTE);
3970 g_object_set(privateContext->
audio_sink,
"input-gain", INPUT_GAIN_DB_UNMUTE, NULL);
3975 g_object_set(gSource, propertyName,
false, NULL);
3980 AAMPLOG_WARN(
"AAMPGstPlayer: Setting Volume %f", privateContext->
audioVolume);
3981 g_object_set(gSource,
"volume", privateContext->
audioVolume, NULL);
3995 FN_TRACE( __FUNCTION__ );
3997 privateContext->
rate = rate;
4004 AAMPLOG_WARN(
"AAMPGstPlayer: Remove eosCallbackIdleTaskId %d", privateContext->
eosCallbackIdleTaskId);
4030 if (privateContext->
pipeline == NULL)
4032 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline is NULL");
4035 #if defined (REALTEKCE)
4036 bool bAsyncModify = FALSE;
4047 AAMPLOG_WARN(
"Disable async for audio stream at trickplay");
4048 if(gst_base_sink_is_async_enabled(GST_BASE_SINK(privateContext->
audio_sink)) ==
TRUE)
4050 gst_base_sink_set_async_enabled(GST_BASE_SINK(privateContext->
audio_sink), FALSE);
4051 bAsyncModify =
TRUE;
4058 GstState current, pending;
4059 GstStateChangeReturn ret;
4060 ret = gst_element_get_state(privateContext->
pipeline, ¤t, &pending, 100 * GST_MSECOND);
4061 if ((current != GST_STATE_PLAYING && current != GST_STATE_PAUSED) || ret == GST_STATE_CHANGE_FAILURE)
4063 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline state %s, ret %u", gst_element_state_get_name(current), ret);
4066 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline is not in playing/paused state, hence resetting it");
4067 if(rate > AAMP_NORMAL_PLAY_RATE)
4080 GstState aud_current, aud_pending;
4081 ret = gst_element_get_state(privateContext->
audio_dec, &aud_current, &aud_pending, 0);
4082 if ((aud_current != GST_STATE_PLAYING && aud_current != GST_STATE_PAUSED) || ret == GST_STATE_CHANGE_FAILURE)
4086 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline is in playing/paused state, but audio_dec is in %s state, resetting it ret %u\n",
4087 gst_element_state_get_name(aud_current), ret);
4093 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline is in %s state position %f ret %d\n", gst_element_state_get_name(current), position, ret);
4101 privateContext->stream[i].
flush =
false;
4102 privateContext->stream[i].
eosReached =
false;
4105 AAMPLOG_INFO(
"AAMPGstPlayer: Pipeline flush seek - start = %f rate = %d", position, rate);
4106 double playRate = 1.0;
4111 #if defined (REALTEKCE)
4118 GstState targetState, currentState;
4119 gst_element_get_state(privateContext->
pipeline, ¤tState, &targetState, 100 * GST_MSECOND);
4121 if((targetState != GST_STATE_PAUSED) &&
4122 ((targetState == GST_STATE_PLAYING) || (currentState == GST_STATE_PLAYING)))
4124 AAMPLOG_WARN(
"AAMPGstPlayer: Pause before seek, Setting Pipeline to GST_STATE_PAUSED.");
4129 AAMPLOG_WARN(
"AAMPGstPlayer: Pause before seek, not required (targetState=%s, currentState=%s)",
4130 gst_element_state_get_name(targetState),
4131 gst_element_state_get_name(currentState));
4136 AAMPLOG_INFO(
"AAMPGstPlayer: Pause before seek, not required (rate = %d).",rate);
4140 if (!gst_element_seek(privateContext->
pipeline, playRate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET,
4141 position * GST_SECOND, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
4143 AAMPLOG_WARN(
"Seek failed");
4145 #if defined (REALTEKCE)
4146 if(bAsyncModify ==
TRUE)
4148 gst_base_sink_set_async_enabled(GST_BASE_SINK(privateContext->
audio_sink),
TRUE);
4161 FN_TRACE( __FUNCTION__ );
4164 AAMPLOG_WARN(
"Entering AAMPGstPlayer: type(%d) format(%d) resetPosition(%d)", (
int)type, stream->
format, stream->
resetPosition);
4168 AAMPLOG_WARN(
"Discontinuity received before first buffer - ignoring");
4195 FN_TRACE( __FUNCTION__ );
4199 if (currentPTS != 0)
4203 AAMPLOG_WARN(
"AAMPGstPlayer: There is an update in PTS prevPTS:%" G_GINT64_FORMAT
" newPTS: %" G_GINT64_FORMAT
"\n",
4213 AAMPLOG_WARN(
"AAMPGstPlayer: Video PTS hasn't been updated for %ld ms and timeout - %ld ms", diff, timeout);
4220 AAMPLOG_WARN(
"AAMPGstPlayer: video-pts parsed is: %" G_GINT64_FORMAT
"\n",
4232 FN_TRACE( __FUNCTION__ );
4233 gint64 currentPTS = 0;
4234 GstElement *element;
4235 #if defined (REALTEKCE)
4242 g_object_get(element,
"video-pts", ¤tPTS, NULL);
4249 currentPTS = currentPTS * 2;
4253 return (
long long) currentPTS;
4269 FN_TRACE( __FUNCTION__ );
4271 media_stream *stream = &privateContext->stream[mediaType];
4274 guint64 cacheLevel = gst_app_src_get_current_level_bytes (GST_APP_SRC(stream->
source));
4277 AAMPLOG_TRACE(
"AAMPGstPlayer::Cache level %" G_GUINT64_FORMAT
"", cacheLevel);
4288 AAMPLOG_WARN(
"AAMPGstPlayer::Received buffer underrun signal for video(%d) or audio(%d) previously",privateContext->stream[
eMEDIATYPE_VIDEO].bufferUnderrun,
4298 AAMPLOG_WARN(
"AAMPGstPlayer: Appsrc cache is empty and PTS hasn't been updated for more than %dms and ret(%d)",
4317 FN_TRACE( __FUNCTION__ );
4320 AAMPLOG_WARN(
"AAMPGstPlayer: Setting pipeline to PLAYING state ");
4323 AAMPLOG_WARN(
"AAMPGstPlayer_Configure GST_STATE_PLAYING failed");
4329 AAMPLOG_WARN(
"AAMPGstPlayer: No pending PLAYING state");
4338 FN_TRACE( __FUNCTION__ );
4339 if(!privateContext->
paused)
4351 FN_TRACE( __FUNCTION__ );
4353 sscanf(privateContext->
videoRectangle,
"%d,%d,%d,%d", &x, &y, &w, &h);
4372 FN_TRACE( __FUNCTION__ );
4373 bool retValue =
false;
4374 GstRegistry* registry = gst_registry_get();
4377 GstPluginFeature* pluginFeature = gst_registry_lookup_feature(registry, componentName.c_str());
4378 if (pluginFeature != NULL)
4393 FN_TRACE( __FUNCTION__ );
4395 GstRegistry* registry = gst_registry_get();
4397 GstPluginFeature* pluginFeature = gst_registry_lookup_feature(registry,
GstPluginNamePR);
4399 if (pluginFeature == NULL)
4401 AAMPLOG_ERR(
"AAMPGstPlayer: %s plugin feature not available; reloading aamp plugin",
GstPluginNamePR);
4402 GstPlugin * plugin = gst_plugin_load_by_name (
"aamp");
4405 gst_object_unref(plugin);
4407 pluginFeature = gst_registry_lookup_feature(registry,
GstPluginNamePR);
4408 if(pluginFeature == NULL)
4409 AAMPLOG_ERR(
"AAMPGstPlayer: %s plugin feature not available",
GstPluginNamePR);
4413 gst_registry_remove_feature (registry, pluginFeature);
4414 gst_registry_add_feature (registry, pluginFeature);
4417 AAMPLOG_WARN(
"AAMPGstPlayer: %s plugin priority set to GST_RANK_PRIMARY + 111",
GstPluginNamePR);
4418 gst_plugin_feature_set_rank(pluginFeature, GST_RANK_PRIMARY + 111);
4419 gst_object_unref(pluginFeature);
4422 pluginFeature = gst_registry_lookup_feature(registry,
GstPluginNameWV);
4424 if (pluginFeature == NULL)
4426 AAMPLOG_ERR(
"AAMPGstPlayer: %s plugin feature not available",
GstPluginNameWV);
4430 AAMPLOG_WARN(
"AAMPGstPlayer: %s plugin priority set to GST_RANK_PRIMARY + 111",
GstPluginNameWV);
4431 gst_plugin_feature_set_rank(pluginFeature, GST_RANK_PRIMARY + 111);
4432 gst_object_unref(pluginFeature);
4435 pluginFeature = gst_registry_lookup_feature(registry,
GstPluginNameCK);
4437 if (pluginFeature == NULL)
4439 AAMPLOG_ERR(
"AAMPGstPlayer: %s plugin feature not available",
GstPluginNameCK);
4443 AAMPLOG_WARN(
"AAMPGstPlayer: %s plugin priority set to GST_RANK_PRIMARY + 111",
GstPluginNameCK);
4444 gst_plugin_feature_set_rank(pluginFeature, GST_RANK_PRIMARY + 111);
4445 gst_object_unref(pluginFeature);
4450 if (pluginFeature == NULL)
4452 AAMPLOG_ERR(
"AAMPGstPlayer::%s():%d %s plugin feature not available", __FUNCTION__, __LINE__,
GstPluginNameVMX);
4456 AAMPLOG_WARN(
"AAMPGstPlayer::%s():%d %s plugin priority set to GST_RANK_PRIMARY + 111", __FUNCTION__, __LINE__,
GstPluginNameVMX);
4457 gst_plugin_feature_set_rank(pluginFeature, GST_RANK_PRIMARY + 111);
4458 gst_object_unref(pluginFeature);
4464 gst_plugin_feature_set_rank(pluginFeature, GST_RANK_PRIMARY - 1);
4465 gst_object_unref(pluginFeature);
4466 AAMPLOG_WARN(
"AAMPGstPlayer: %s plugin priority set to GST_RANK_PRIMARY - 1\n",
plugins_to_lower_rank[i]);
4479 FN_TRACE( __FUNCTION__ );
4491 AAMPLOG_WARN(
"eosCallbackIdleTask scheduled, eosCallbackIdleTaskId %d", privateContext->
eosCallbackIdleTaskId);
4496 AAMPLOG_WARN(
"IdleCallbackOnEOS already registered previously, hence skip!");
4502 AAMPLOG_WARN(
"EOS already signaled, hence skip!");
4512 FILE *fp = fopen(fileName,
"r");
4515 printf(
"\n************************Dump %s **************************\n", fileName);
4523 printf(
"\n**********************Dump %s end *************************\n", fileName);
4527 AAMPLOG_WARN(
"Could not open %s", fileName);
4537 FN_TRACE( __FUNCTION__ );
4538 AAMPLOG_WARN(
"video_dec %p audio_dec %p video_sink %p audio_sink %p numberOfVideoBuffersSent %d",
4543 DumpFile(
"/proc/brcm/video_decoder");
4553 FN_TRACE( __FUNCTION__ );
4555 if (stream && (privateContext->
rate != AAMP_NORMAL_PLAY_RATE) )
4557 GstPad* sourceEleSrcPad = gst_element_get_static_pad(GST_ELEMENT(stream->
source),
"src");
4558 int vodTrickplayFPS;
4560 GstStructure * eventStruct = gst_structure_new(
"aamp-tm-disc",
"fps", G_TYPE_UINT, (guint)vodTrickplayFPS, NULL);
4561 if (!gst_pad_push_event(sourceEleSrcPad, gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, eventStruct)))
4563 AAMPLOG_WARN(
"Error on sending aamp-tm-disc");
4567 AAMPLOG_WARN(
"Sent aamp-tm-disc event");
4569 gst_object_unref(sourceEleSrcPad);
4578 FN_TRACE( __FUNCTION__ );
4582 Flush(position, rate,
false);
4591 FN_TRACE( __FUNCTION__ );
4600 FN_TRACE( __FUNCTION__ );
4601 pthread_mutex_lock(&mBufferingLock);
4605 bool stopBuffering = forceStop;
4606 #if ( !defined(INTELCE) && !defined(RPI) && !defined(__APPLE__) )
4608 g_object_get(privateContext->
video_dec,
"queued_frames",(uint*)&frames,NULL);
4615 stopBuffering =
true;
4619 #if ( !defined(INTELCE) && !defined(RPI) && !defined(__APPLE__) )
4620 AAMPLOG_WARN(
"Enough data available to stop buffering, frames %d !", frames);
4622 GstState current, pending;
4623 bool sendEndEvent =
false;
4625 if(GST_STATE_CHANGE_FAILURE != gst_element_get_state(privateContext->
pipeline, ¤t, &pending, 0 * GST_MSECOND))
4627 if (current == GST_STATE_PLAYING)
4629 sendEndEvent =
true;
4639 sendEndEvent =
false;
4644 AAMPLOG_ERR(
"Failed to un-pause pipeline for stop buffering!");
4653 static int bufferLogCount = 0;
4654 if (0 == (bufferLogCount++ % 10) )
4656 #if ( !defined(INTELCE) && !defined(RPI) && !defined(__APPLE__) )
4657 AAMPLOG_WARN(
"Not enough data available to stop buffering, frames %d !", frames);
4662 pthread_mutex_unlock(&mBufferingLock);
4668 AAMPLOG_WARN(
"%s %p type_check %d", str, elem, G_TYPE_CHECK_INSTANCE (elem));
4677 int timeRemaining = -1;
4679 media_stream *stream = &privateContext->stream[mediaType];
4681 int waitInterval = 100;
4683 AAMPLOG_WARN(
"Source element[%p] for track[%d] not configured, wait for setup to complete!", stream->
source, mediaType);
4684 while(timeRemaining >= 0)
4691 AAMPLOG_WARN(
"Source element[%p] for track[%d] setup completed!", stream->
source, mediaType);
4701 timeRemaining -= waitInterval;
4706 AAMPLOG_WARN(
"Wait for source element setup for track[%d] exited/timedout!", mediaType);
4727 GstBuffer *fwdBuffer = gst_buffer_new();
4728 if (fwdBuffer != NULL)
4730 if (FALSE == gst_buffer_copy_into(fwdBuffer, buffer, GST_BUFFER_COPY_ALL, 0, -1))
4732 AAMPLOG_ERR(
"Error while copying audio buffer to auxiliary buffer!!");
4733 gst_buffer_unref(fwdBuffer);
4737 GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(stream->
source), fwdBuffer);
4738 if (ret != GST_FLOW_OK)
4740 AAMPLOG_ERR(
"gst_app_src_push_buffer error: %d[%s] mediaType %d", ret, gst_flow_get_name (ret), (
int)
eMEDIATYPE_AUX_AUDIO);
4765 #if defined (REALTEKCE)
4766 GstStructure* s = gst_structure_new(
"custom-instant-rate-change",
"rate", G_TYPE_DOUBLE, rate, NULL);
4770 ret = gst_element_send_event( privateContext->
pipeline, gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s) );
4773 AAMPLOG_WARN(
"AAMPGstPlayer: Set custom rate change failed");
4776 AAMPLOG_WARN (
"Current rate: %g", rate);
4777 #elif defined (AMLOGIC)
4778 AAMPLOG_WARN(
"Setting new segment with rate as:%f to audiosink", rate);
4780 GstElement *audsink=NULL;
4782 GstSegment* segment = gst_segment_new();
4783 gst_segment_init(segment, GST_FORMAT_TIME);
4784 segment->rate = rate;
4785 segment->start = GST_CLOCK_TIME_NONE;
4786 segment->position = GST_CLOCK_TIME_NONE;
4788 AAMPLOG_WARN(
"Sending new segment");
4789 g_object_get (audstream->
sinkbin,
"audio-sink", &audsink, NULL);
4792 ret=gst_pad_send_event (GST_BASE_SINK_PAD(audsink), gst_event_new_segment(segment));
4793 AAMPLOG_WARN(
"send new segment to audio ret:%d", ret);
4797 AAMPLOG_WARN(
"audio-sink device not found");
4799 AAMPLOG_WARN (
"Current rate: %g", rate);
4802 GstEvent *seek_event=NULL, *vidseek=NULL;
4805 GstElement* vidsink = NULL, *audsink=NULL;
4807 if (privateContext->
pipeline == NULL)
4809 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline is NULL");
4814 if (!gst_element_query_position (privateContext->
pipeline, GST_FORMAT_TIME, &position))
4816 AAMPLOG_WARN (
"Unable to retrieve current position:%lld.", position);
4820 AAMPLOG_WARN (
"pipeline current position:%lld.", position);
4826 gst_query_parse_position(privateContext->
positionQuery, NULL, &position);
4827 AAMPLOG_WARN (
"video sink current position:%lld.", position);
4834 seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME,
4835 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), GST_SEEK_TYPE_SET,
4836 position, GST_SEEK_TYPE_END, 0);
4838 vidseek = gst_event_new_seek (rate, GST_FORMAT_TIME,
4839 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), GST_SEEK_TYPE_SET,
4840 position, GST_SEEK_TYPE_END, 0);
4844 AAMPLOG_WARN (
"Negative player rate for slow motion is not supported");
4848 g_object_get (stream->
sinkbin,
"video-sink", &vidsink, NULL);
4851 ret = gst_element_send_event (vidsink, vidseek);
4852 AAMPLOG_WARN(
"send seek event for video ret:%d", ret);
4855 g_object_get (audstream->
sinkbin,
"audio-sink", &audsink, NULL);
4859 ret=gst_element_send_event (audsink, seek_event);
4860 AAMPLOG_WARN(
"send seek event for audio ret:%d", ret);
4866 AAMPLOG_WARN (
"Current rate: %g, position:%lld", rate, position);
4877 FN_TRACE( __FUNCTION__ );
4878 bool ErrSuccess =
false;
4879 if (privateContext->
pipeline == NULL)
4881 AAMPLOG_WARN(
"AAMPGstPlayer: Pipeline is NULL");
4891 if (!gst_element_query_position (privateContext->
pipeline, GST_FORMAT_TIME, &position1))
4893 AAMPLOG_WARN(
"AAMPGstPlayer: Unable to query gst element position");
4897 if (!gst_element_seek(privateContext->
pipeline, rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
4898 GST_SEEK_TYPE_SET, position1, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
4900 AAMPLOG_WARN(
"AAMPGstPlayer: playrate adjustment failed");
4904 AAMPLOG_INFO(
"AAMPGstPlayer: playrate adjustment success");
4912 AAMPLOG_TRACE(
"AAMPGstPlayer: rate is already in %lf rate",rate);