static int __parse_media_format(MMPlayerVideoStreamInfo *video, MMPlayerAudioStreamInfo *audio, media_format_h format);
static int __convert_media_format_video_mime_to_str(MMPlayerVideoStreamInfo *video, media_format_mimetype_e mime);
static int __convert_media_format_audio_mime_to_str(MMPlayerAudioStreamInfo *audio, media_format_mimetype_e mime);
+static gboolean __mm_player_is_codec_data_changed(mm_player_t *player, media_packet_h packet, MMPlayerStreamType streamtype);
/*===========================================================================================
| |
GstElement *element = NULL;
MMPlayerStreamType streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
media_format_h fmt = NULL;
- bool flag = FALSE;
- bool is_eos = FALSE;
+ bool flag = false;
+ bool is_eos = false;
+ gboolean need_update_caps = false;
MMPLAYER_RETURN_VAL_IF_FAIL(packet, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_RETURN_VAL_IF_FAIL(player &&
streamtype = MM_PLAYER_STREAM_TYPE_TEXT;
}
+ need_update_caps = __mm_player_is_codec_data_changed(player, packet, streamtype);
+
element = __mmplayer_get_source_element(player, streamtype);
if (!element) {
LOGE("there is no source element of type %d", streamtype);
/* get format to check video format */
media_packet_get_format(packet, &fmt);
if (fmt) {
- if (__mmplayer_update_video_info(hplayer, fmt)) {
- LOGD("update video caps");
- g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
- "caps", player->v_stream_caps, NULL);
- }
+ need_update_caps |= __mmplayer_update_video_info(hplayer, fmt);
media_format_unref(fmt);
}
+ if (need_update_caps)
+ g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
+ "caps", player->v_stream_caps, NULL);
+
/* get duration */
if (media_packet_get_duration(packet, &duration) != MEDIA_PACKET_ERROR_NONE) {
LOGW("failed to get duration info");
duration = DEFAULT_VIDEO_FRAME_DURATION * GST_MSECOND;
GST_BUFFER_DURATION(_buffer) = (GstClockTime)duration;
+ } else if ((streamtype == MM_PLAYER_STREAM_TYPE_AUDIO) && need_update_caps) {
+ LOGD("update audio caps");
+ g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
+ "caps", player->a_stream_caps, NULL);
}
/* get pts */
return ret;
}
+
+static gboolean
+__mm_player_is_codec_data_changed(mm_player_t *player, media_packet_h packet,
+ MMPlayerStreamType streamtype)
+{
+ GstCaps *cur_caps = NULL;
+ GstCaps *new_caps = NULL;
+ GstStructure *str = NULL;
+ const GValue *value = NULL;
+ GstBuffer *buffer = NULL;
+ GstMapInfo codec_data_map = GST_MAP_INFO_INIT;
+ GstBuffer *new_buffer = NULL;
+ char *codec_data;
+ unsigned int codec_data_size;
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+ MMPLAYER_RETURN_VAL_IF_FAIL(packet, FALSE);
+
+ if (media_packet_get_codec_data(packet, (void **)&codec_data, &codec_data_size)
+ != MEDIA_PACKET_ERROR_NONE) {
+ LOGD("Failed to get coodec data in media_packet");
+ return FALSE;
+ }
+
+ if (codec_data_size == 0) {
+ LOGW("codec_data_size is zero");
+ return FALSE;
+ }
+
+ if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO) {
+ cur_caps = player->a_stream_caps;
+ } else if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
+ cur_caps = player->v_stream_caps;
+ } else {
+ LOGW("streamtype is not audio or video");
+ return FALSE;
+ }
+
+ if (!cur_caps) {
+ LOGW("Current caps is NULL");
+ return FALSE;
+ }
+
+ str = gst_caps_get_structure(cur_caps, 0);
+ if (!str) {
+ LOGW("Failed to get caps info");
+ return FALSE;
+ }
+
+ /* Check if the codec data in the saved caps have been changed */
+ value = gst_structure_get_value(str, "codec_data");
+ if (value) {
+ int i = 0;
+ buffer = gst_value_get_buffer(value);
+ if (!gst_buffer_map(buffer, &codec_data_map, GST_MAP_READ)) {
+ LOGW("codec data buffer map failed");
+ return FALSE;
+ }
+ if (codec_data_map.size == codec_data_size) {
+ for (i = 0; i <= codec_data_map.size; i++) {
+ if (codec_data_map.data[i] != codec_data[i])
+ break;
+ }
+ gst_buffer_unmap(buffer, &codec_data_map);
+ return FALSE;
+ }
+ gst_buffer_unmap(buffer, &codec_data_map);
+ }
+
+ new_caps = gst_caps_copy(cur_caps);
+ if (!new_caps) {
+ LOGW("Failed to copy caps");
+ return FALSE;
+ }
+
+ new_buffer = gst_buffer_new_allocate(NULL, codec_data_size, NULL);
+ if (!new_buffer) {
+ LOGW("Failed to alloc gst buffer for codec data");
+ gst_caps_unref(new_caps);
+ return FALSE;
+ }
+ gst_buffer_fill(new_buffer, 0, codec_data, codec_data_size);
+ gst_caps_set_simple(new_caps, "codec_data", GST_TYPE_BUFFER, new_buffer, NULL);
+ gst_buffer_unref(new_buffer);
+
+ if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO)
+ player->a_stream_caps = new_caps;
+ else if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO)
+ player->v_stream_caps = new_caps;
+
+ gst_caps_unref(cur_caps);
+
+ LOGD("need to update caps due to codec data is changed");
+ return TRUE;
+}
\ No newline at end of file