2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <Elementary.h>
18 #include <tbm_surface.h>
22 #include <appcore-efl.h>
24 #define KEY_END "XF86Stop"
25 #define ES_FEEDING_PATH "es_buff://push_mode"
26 //#define ES_FEEDING_PATH "es_buff://pull_mode"
28 #define ES_DEFAULT_DIR_PATH "/opt/usr/media/"
29 #define ES_DEFAULT_H264_VIDEO_PATH ES_DEFAULT_DIR_PATH"Simpsons.h264"
30 #define ES_DEFAULT_VIDEO_FORMAT_TYPE MEDIA_FORMAT_H264_SP
31 #define ES_DEFAULT_VIDEO_FORMAT_WIDTH 1280
32 #define ES_DEFAULT_VIDEO_FORMAT_HEIGHT 544
33 #define ES_DEFAULT_VIDEO_PTS_OFFSET 20000000
34 #define ES_DEFAULT_NUMBER_OF_FEED 2000
36 unsigned char sps[100];
37 unsigned char pps[100];
38 unsigned char tmp_buf[1000000];
39 static int sps_len, pps_len;
44 #define PACKAGE "player_es_push_test"
49 #define LOG_TAG "PLAYER_TEST"
51 static int app_create(void *data);
52 static int app_reset(bundle *b, void *data);
53 static int app_resume(void *data);
54 static int app_pause(void *data);
55 static int app_terminate(void *data);
57 struct appcore_ops ops = {
59 .terminate = app_terminate,
65 typedef struct appdata {
68 player_h player_handle;
69 media_packet_h video_pkt;
70 media_format_h video_fmt;
72 pthread_t feeding_thread_id;
76 win_delete_request_cb(void *data , Evas_Object *obj , void *event_info)
82 keydown_cb(void *data , int type , void *event)
84 //appdata_s *ad = data;
85 Ecore_Event_Key *ev = event;
89 if (!strcmp(ev->keyname, KEY_END)) {
90 /* Let window go to hide state. */
91 //elm_win_lower(ad->win);
95 return ECORE_CALLBACK_DONE;
100 return ECORE_CALLBACK_PASS_ON;
103 static void win_del(void *data, Evas_Object *obj, void *event)
108 static Evas_Object* create_win(const char *name)
110 Evas_Object *eo = NULL;
112 eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
114 elm_win_title_set(eo, name);
115 elm_win_borderless_set(eo, EINA_TRUE);
116 evas_object_smart_callback_add(eo, "delete,request",win_del, NULL);
117 elm_win_autodel_set(eo, EINA_TRUE);
122 static Evas_Object *create_render_rect(Evas_Object *pParent)
128 Evas *pEvas = evas_object_evas_get(pParent);
129 Evas_Object *pObj = evas_object_rectangle_add(pEvas);
134 evas_object_size_hint_weight_set(pObj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
135 evas_object_color_set(pObj, 0, 0, 0, 0);
136 evas_object_render_op_set(pObj, EVAS_RENDER_COPY);
137 evas_object_show(pObj);
138 elm_win_resize_object_add(pParent, pObj);
144 create_base_gui(appdata_s *ad)
146 /* Enable GLES Backened */
147 elm_config_preferred_engine_set("3d");
150 ad->win = create_win(PACKAGE);//elm_win_util_standard_add(PACKAGE, PACKAGE);
151 ad->rect = create_render_rect(ad->win);
152 /* This is not supported in 3.0
153 elm_win_wm_desktop_layout_support_set(ad->win, EINA_TRUE);*/
154 elm_win_autodel_set(ad->win, EINA_TRUE);
155 evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, ad);
157 /* Show window after base gui is set up */
158 elm_win_activate(ad->win);
159 evas_object_show(ad->win);
162 static int app_create(void *data)
164 /* Hook to take necessary actions before main event loop starts
165 Initialize UI resources and application's data
166 If this function returns true, the main loop of application starts
167 If this function returns false, the application is terminated */
168 appdata_s *ad = data;
173 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, keydown_cb, NULL);
176 ad->file_src = fopen(ES_DEFAULT_H264_VIDEO_PATH, "r");
183 static int app_pause(void *data)
185 /* Take necessary actions when application becomes invisible. */
186 appdata_s *ad = (appdata_s *)data;
187 int ret = PLAYER_ERROR_NONE;
192 LOGE("appdata is NULL");
196 if (ad->player_handle == NULL) {
197 printf("player_handle is NULL");
201 if (ad->feeding_thread_id)
203 pthread_join(ad->feeding_thread_id, NULL);
204 ad->feeding_thread_id = 0;
207 player_unset_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO);
208 player_unset_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO);
209 player_unset_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO);
210 player_unset_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO);
212 ret = player_unprepare(ad->player_handle);
213 if (ret != PLAYER_ERROR_NONE) {
214 printf("player_unprepare failed : 0x%x", ret);
218 /* unref media format */
220 media_format_unref(ad->video_fmt);
222 fclose(ad->file_src);
224 /* destroy player handle */
225 ret = player_destroy(ad->player_handle);
226 if (ret != PLAYER_ERROR_NONE) {
227 printf("player_destroy failed : 0x%x", ret);
231 ad->player_handle = NULL;
238 static int app_resume(void *data)
247 static void _player_prepared_cb(void *user_data)
249 int ret = PLAYER_ERROR_NONE;
250 appdata_s *ad = (appdata_s *)user_data;
254 ret = player_start(ad->player_handle);
255 if (ret != PLAYER_ERROR_NONE) {
256 LOGE("player start failed : 0x%x", ret);
261 unsigned int bytestream2nalunit(FILE *fd, unsigned char* nal)
266 unsigned char buffer[1000000];
267 unsigned char val, zero_count, i;
268 int nal_unit_type = 0;
275 result = fread(buffer, 1, read_size, fd);
277 if(result != read_size)
285 if ((zero_count == 2 || zero_count == 3) && val == 1)
290 result = fread(buffer, 1, read_size, fd);
292 if(result != read_size)
298 nal[nal_length++] = 0;
299 nal[nal_length++] = 0;
300 nal[nal_length++] = 0;
301 nal[nal_length++] = 1;
309 result = fread(buffer, 1, read_size, fd);
310 if(result != read_size)
317 nal_unit_type = val & 0xf;
326 if ((zero_count == 2 || zero_count == 3 || zero_count == 4) && (val == 1))
332 for (i = 0; i<zero_count; i++)
334 nal[nal_length++] = 0;
336 nal[nal_length++] = val;
342 fseek(fd, -(zero_count + 1), SEEK_CUR);
344 if (nal_unit_type == 0x7)
346 sps_len = nal_length;
347 memcpy(sps, nal, nal_length);
350 else if (nal_unit_type == 0x8)
352 pps_len = nal_length;
353 memcpy(pps, nal, nal_length);
356 else if (nal_unit_type == 0x5)
358 memcpy(tmp_buf, nal, nal_length);
359 memcpy(nal, sps, sps_len);
360 memcpy(nal + sps_len, pps, pps_len);
361 memcpy(nal + sps_len + pps_len, tmp_buf, nal_length);
362 nal_length += sps_len + pps_len;
368 static void feed_video_data(appdata_s *appdata)
371 static guint64 pts = 0L;
372 void *buf_data_ptr = NULL;
373 appdata_s *ad = appdata;
375 if (media_packet_create_alloc(ad->video_fmt, NULL, NULL, &ad->video_pkt) != MEDIA_PACKET_ERROR_NONE) {
376 LOGE("media_packet_create_alloc failed\n");
380 if (media_packet_get_buffer_data_ptr(ad->video_pkt, &buf_data_ptr) != MEDIA_PACKET_ERROR_NONE) {
381 LOGE("media_packet_get_buffer_data_ptr failed\n");
385 if (media_packet_set_pts(ad->video_pkt, (uint64_t)(pts/1000000)) != MEDIA_PACKET_ERROR_NONE) {
386 LOGE("media_packet_set_pts failed\n");
390 /* NOTE: In case of H.264 video, stream format for feeding is NAL unit.
391 * And, SPS(0x67) and PPS(0x68) should be located before IDR.(0x65).
393 read = bytestream2nalunit(ad->file_src, buf_data_ptr);
394 LOGD("real length = %d\n", read);
396 LOGD("input file read failed\n");
400 if (media_packet_set_buffer_size(ad->video_pkt, (uint64_t)read) != MEDIA_PACKET_ERROR_NONE) {
401 LOGE("media_packet_set_buffer_size failed\n");
405 /* push media packet */
406 player_push_media_stream(ad->player_handle, ad->video_pkt);
407 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
409 /* destroy media packet after use*/
410 media_packet_destroy(ad->video_pkt);
411 ad->video_pkt = NULL;
415 static void feed_video_data_thread_func(void *data)
417 gboolean exit = FALSE;
418 appdata_s *ad = (appdata_s *)data;
422 static int frame_count = 0;
424 if (frame_count < ES_DEFAULT_NUMBER_OF_FEED) {
433 void _video_buffer_status_cb (player_media_stream_buffer_status_e status, void *user_data)
435 if (status == PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN)
437 LOGE("video buffer is underrun state");
439 else if (status == PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW)
441 LOGE("video buffer is overrun state");
445 void _audio_buffer_status_cb (player_media_stream_buffer_status_e status, void *user_data)
447 if (status == PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN)
448 LOGE("audio buffer is underrun state");
449 else if (status == PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW)
450 LOGE("audio buffer is overrun state");
453 void _video_seek_data_cb (unsigned long long offset, void *user_data)
455 LOGE("seek offset of video is %llu", offset);
458 void _audio_seek_data_cb (unsigned long long offset, void *user_data)
460 LOGE("seek offset of audio is %llu", offset);
463 static int app_reset(bundle *b, void *data)
465 /* Take necessary actions when application becomes visible. */
466 appdata_s *ad = (appdata_s *)data;
467 int ret = PLAYER_ERROR_NONE;
472 LOGE("appdata is NULL");
476 ret = player_create(&ad->player_handle);
477 if (ret != PLAYER_ERROR_NONE) {
478 LOGE("player_create failed : 0x%x", ret);
482 ret = player_set_display(ad->player_handle, PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(ad->win));
483 if (ret != PLAYER_ERROR_NONE) {
484 LOGE("player_set_display failed : 0x%x", ret);
488 ret = player_set_uri(ad->player_handle, ES_FEEDING_PATH);
489 if (ret != PLAYER_ERROR_NONE) {
490 LOGE("player_set_uri failed : 0x%x", ret);
494 /* get media format format */
495 ret = media_format_create(&ad->video_fmt);
496 if (ret != MEDIA_FORMAT_ERROR_NONE) {
497 LOGE("media_format_create : 0x%x", ret);
501 /* set video format */
502 media_format_set_video_mime(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_TYPE);
503 media_format_set_video_width(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_WIDTH);
504 media_format_set_video_height(ad->video_fmt,ES_DEFAULT_VIDEO_FORMAT_HEIGHT);
506 ret = player_set_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_buffer_status_cb, (void*)ad);
507 if (ret != PLAYER_ERROR_NONE) {
508 LOGE("player set video buffer status cb failed : 0x%x", ret);
511 ret = player_set_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_buffer_status_cb, (void*)ad);
512 if (ret != PLAYER_ERROR_NONE) {
513 LOGE("player set audio buffer status cb failed : 0x%x", ret);
517 ret = player_set_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_seek_data_cb, (void*)ad);
518 if (ret != PLAYER_ERROR_NONE) {
519 LOGE("player set seek data cb for video failed : 0x%x", ret);
522 ret = player_set_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_seek_data_cb, (void*)ad);
523 if (ret != PLAYER_ERROR_NONE) {
524 LOGE("player set seek data cb for audio failed : 0x%x", ret);
528 /* send media packet to player */
529 player_set_media_stream_info(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, ad->video_fmt);
531 ret = player_prepare_async(ad->player_handle, _player_prepared_cb, (void*)ad);
532 if (ret != PLAYER_ERROR_NONE) {
533 LOGE("player prepare failed : 0x%x", ret);
537 pthread_create(&ad->feeding_thread_id, NULL, (void*)feed_video_data_thread_func, (void *)ad);
544 if (ad->player_handle) {
545 player_destroy(ad->player_handle);
546 ad->player_handle = NULL;
552 static int app_terminate(void *data)
554 /* Release all resources. */
555 appdata_s *ad = (appdata_s *)data;
560 LOGE("appdata is NULL");
571 int main(int argc, char *argv[])
574 static appdata_s ad = {0,};
578 memset(&ad, 0x0, sizeof(appdata_s));
580 LOGD("call appcore_efl_main");
584 ret = appcore_efl_main(PACKAGE, &argc, &argv, &ops);
586 LOGD("appcore_efl_main() ret = 0x%x", ret);