2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
23 #include <tbm_surface.h>
26 #include <media_codec.h>
27 #include <media_packet.h>
28 #include <media_packet_internal.h>
29 #include <media_packet_pool.h>
30 #include <media_codec_internal.h>
31 #ifdef TIZEN_FEATURE_INTEGRATION
33 #include <mediademuxer.h>
34 #include <mediamuxer.h>
37 #define PACKAGE "media_codec_test"
39 #define TEST_FILE_SIZE (10 * 1024 * 1024)
40 #define MAX_STRING_LEN 256
42 #define DEFAULT_SAMPPLERATE 44100
43 #define DEFAULT_CHANNEL 2
44 #define DEFAULT_BIT 16
45 #define DEFAULT_BITRATE 128
46 #define DEFAULT_SAMPLEBYTE 1024
47 #define ADTS_HEADER_SIZE 7
48 #define AMRNB_PCM_INPUT_SIZE 320
49 #define AMRWB_PCM_INPUT_SIZE 640
51 #define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
52 #define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
53 #define GET_IS_DECODER(x) CHECK_BIT(x, 1)
54 #define GET_IS_HW(x) CHECK_BIT(x, 2)
55 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000
56 #define CHECK_VALID_PACKET(state, expected_state) \
57 ((state & (expected_state)) == (expected_state))
59 #define AAC_CODECDATA_SIZE 16
61 guint8 buf_adts[ADTS_HEADER_SIZE];
64 MC_EXIST_SPS = 1 << 0,
65 MC_EXIST_PPS = 1 << 1,
66 MC_EXIST_IDR = 1 << 2,
67 MC_EXIST_SLICE = 1 << 3,
69 MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS),
70 MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR)
73 typedef struct _App App;
76 CURRENT_STATUS_MAINMENU,
77 CURRENT_STATUS_FILENAME,
78 CURRENT_STATUS_CREATE,
79 CURRENT_STATUS_DESTROY,
80 CURRENT_STATUS_SET_CODEC,
81 CURRENT_STATUS_SET_VDEC_INFO,
82 CURRENT_STATUS_SET_VENC_INFO,
83 CURRENT_STATUS_SET_ADEC_INFO,
84 CURRENT_STATUS_SET_AENC_INFO,
85 CURRENT_STATUS_PREPARE,
86 CURRENT_STATUS_UNPREPARE,
87 CURRENT_STATUS_PROCESS_INPUT,
88 CURRENT_STATUS_GET_OUTPUT,
89 CURRENT_STATUS_RESET_OUTPUT_BUFFER,
90 CURRENT_STATUS_SET_SIZE,
91 CURRENT_STATUS_AUTO_TEST,
95 NAL_SLICE_NO_PARTITIONING = 1,
101 NAL_SEQUENCE_PARAMETER_SET,
102 NAL_PICTURE_PARAMETER_SET,
103 NAL_PICTURE_DELIMITER,
141 gboolean enable_dump;
142 gboolean enable_muxer;
146 #ifdef TIZEN_FEATURE_INTEGRATION
147 camera_h camera_handle;
148 mediademuxer_h demuxer;
163 media_format_h format[MAX_HANDLE];
165 mediacodec_h mc_handle[MAX_HANDLE];
170 media_format_mimetype_e mime;
185 media_packet_h packet;
197 media_format_h fmt = NULL;
198 media_packet_pool_h pkt_pool = NULL;
200 /* Internal Functions */
201 void displaymenu(void);
202 void display_sub_basic();
204 void _mediacodec_unprepare(App *app);
205 void _mediacodec_destroy(App *app);
206 void _mediacodec_auto_test(App *app, char *path);
207 void input_filepath(char *filename, App *app);
209 void mc_hex_dump(char *desc, void *addr, gint len);
210 void decoder_output_dump(App *app, media_packet_h pkt);
211 void output_dump(App *app, media_packet_h pkt);
213 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id);
215 void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data);
217 gint g_menu_state = CURRENT_STATUS_MAINMENU;
219 static const guint mp3types_bitrates[2][3][16] = {
221 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
222 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
223 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
226 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
227 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
228 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
232 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
233 {22050, 24000, 16000},
237 void h264_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
239 guint8 val, zero_count;
240 guint8 *pNal = app->data + app->offset;
241 gint max = app->length - app->offset;
243 gint nal_unit_type = 0;
271 if ((zero_count >= 2) && (val == 1))
281 read = (index - zero_count - 1);
283 nal_unit_type = *(app->data+app->offset+4) & 0x1F;
284 g_print("nal_unit_type : %x\n", nal_unit_type);
286 switch (nal_unit_type) {
287 case NAL_SEQUENCE_PARAMETER_SET:
288 g_print("nal_unit_type : SPS\n");
289 state |= MC_EXIST_SPS;
291 case NAL_PICTURE_PARAMETER_SET:
292 g_print("nal_unit_type : PPS\n");
293 state |= MC_EXIST_PPS;
297 g_print ("nal_unit_type : IDR\n");
298 state |= MC_EXIST_IDR;
300 case NAL_SLICE_NO_PARTITIONING:
301 case NAL_SLICE_PART_A:
302 case NAL_SLICE_PART_B:
303 case NAL_SLICE_PART_C:
304 state |= MC_EXIST_SLICE;
307 g_print ("nal_unit_type : %x", nal_unit_type);
311 init = CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE) ? 1 : 0;
312 slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
313 idr = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
314 g_print("status : %d, slice : %d, idr : %d\n", init, slice, idr);
316 if (init || idr || slice) {
320 *size = app->offset + read;
322 *data = app->data+app->offset;
327 *data = app->data+app->offset;
334 void h263_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
337 int read_size = 1, state = 1, bStart = 0;
339 guint8 *pH263 = app->data + app->offset;
341 int max = app->length - app->offset;
345 read_size = (len - 1);
362 if ((val & 0xFC) == 0x80) {
375 app->offset += read_size;
379 void mpeg4_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
383 int state = 1, bType = 0;
385 guint8 *pMpeg4 = app->data + app->offset;
387 int max = app->length - app->offset;
416 if (val == 0xB0 || val == 0xB6) {
432 app->offset += result;
437 * Extract Input data for AMR-NB/WB decoder
438 * - AMR-NB : mime type ("audio/AMR") / 8Khz / 1 ch / 16 bits
439 * - AMR-WB : mime type ("audio/AMR-WB") / 16Khz / 1 ch / 16 bits
441 gint write_amr_header = 1; /* write magic number for AMR Header at one time */
442 static const gchar AMR_header[] = "#!AMR\n";
443 static const gchar AMRWB_header[] = "#!AMR-WB\n";
444 #define AMR_NB_MIME_HDR_SIZE 6
445 #define AMR_WB_MIME_HDR_SIZE 9
446 static const gint block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
447 static const gint block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
450 void amrdec_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
452 gint readsize = 0, mode_temp;
454 guint8 *pAmr = app->data + app->offset;
455 /* change the below one to frame count */
456 if (app->offset == 0) {
457 if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
458 blocksize_tbl = (int *)block_size_nb;
459 mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
460 pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
461 app->offset += AMR_NB_MIME_HDR_SIZE;
463 if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
464 blocksize_tbl = (int *)block_size_wb;
465 mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
466 pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
467 app->offset += AMR_WB_MIME_HDR_SIZE;
469 g_print("[ERROR] AMR-NB/WB don't detected..\n");
475 if ((mode_temp & 0x83) == 0) {
476 mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
477 fsize = blocksize_tbl[mode];
478 readsize = fsize + 1;
481 g_print("[FAIL] Not found amr frame sync.....\n");
485 app->offset += readsize;
490 void nv12_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
493 gint offset = app->length - app->offset;
495 yuv_size = app->width * app->height * 3 / 2;
497 if (offset >= yuv_size)
501 *data = app->data + app->offset;
503 if (yuv_size >= offset)
508 app->offset += *size;
511 void yuv_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
514 gint offset = app->length - app->offset;
516 yuv_size = app->width * app->height * 3 / 2;
518 if (yuv_size >= offset)
522 *data = app->data + app->offset;
524 if (yuv_size >= offset)
529 app->offset += *size;
532 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
535 gint offset = app->length - app->offset;
537 read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2);
540 *data = app->data + app->offset;
542 if (read_size >= offset)
547 app->offset += *size;
550 void amrenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
553 gint offset = app->length - app->offset;
556 read_size = AMRNB_PCM_INPUT_SIZE;
558 read_size = AMRWB_PCM_INPUT_SIZE;
561 *data = app->data + app->offset;
563 if (read_size >= offset)
568 app->offset += *size;
572 * Extract Input data for AAC decoder
573 * (case of (LC profile) ADTS format)
574 * codec_data : Don't need
576 void aacdec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
579 int offset = app->length - app->offset;
580 guint8 *pData = app->data + app->offset;
582 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
583 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
586 g_print("[FAIL] Not found aac frame sync.....\n");
590 *data = app->data + app->offset;
592 if (read_size >= offset)
597 app->offset += *size;
600 void mp3dec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
604 guint padding, bitrate, lsf = 0, layer = 0, mpg25 = 0;
605 guint hdr_bitrate = 0, sf = 0;
606 gint offset = app->length - app->offset;
607 guint8 *pData = app->data + app->offset;
609 header = GST_READ_UINT32_BE(pData);
612 g_print ("[ERROR] read header size is 0\n");
617 /* if it's not a valid sync */
618 if ((header & 0xffe00000) != 0xffe00000) {
619 g_print ("[ERROR] invalid sync\n");
624 if (((header >> 19) & 3) == 0x1) {
625 g_print ("[ERROR] invalid MPEG version: %d\n", (header >> 19) & 3);
629 if (header & (1 << 20)) {
630 lsf = (header & (1 << 19)) ? 0 : 1;
638 /* if it's an invalid layer */
639 if (!((header >> 17) & 3)) {
640 g_print("[ERROR] invalid layer: %d\n", (header >> 17) & 3);
644 layer = 4 - ((header >> 17) & 0x3);
647 /* if it's an invalid bitrate */
648 if (((header >> 12) & 0xf) == 0xf) {
649 g_print ("[ERROR] invalid bitrate: %d\n", (header >> 12) & 0xf);
653 bitrate = (header >> 12) & 0xF;
654 hdr_bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
655 /* The caller has ensured we have a valid header, so bitrate can't be zero here. */
656 if (hdr_bitrate == 0) {
662 /* if it's an invalid samplerate */
663 if (((header >> 10) & 0x3) == 0x3) {
664 g_print ("[ERROR] invalid samplerate: %d\n", (header >> 10) & 0x3);
668 sf = (header >> 10) & 0x3;
669 sf = mp3types_freqs[lsf + mpg25][sf];
672 padding = (header >> 9) & 0x1;
676 read_size = 4 * ((hdr_bitrate * 12) / sf + padding);
679 read_size = (hdr_bitrate * 144) / sf + padding;
683 read_size = (hdr_bitrate * 144) / (sf << lsf) + padding;
686 g_print("header : %d, read : %d\n", header, read_size);
689 *data = app->data + app->offset;
691 if (read_size >= offset)
696 app->offset += *size;
700 * Extract Input data for AAC encoder
703 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame)
706 int offset = app->length - app->offset;
708 read_size = ((DEFAULT_SAMPLEBYTE*DEFAULT_CHANNEL)*(DEFAULT_BIT/8));
710 if (read_size >= offset)
714 *data = app->data + app->offset;
716 if (read_size >= offset)
721 app->offset += *size;
724 int _configure(App *app, int codecid, int flag, gboolean *hardware, media_format_mimetype_e *codec_mime)
727 media_format_mimetype_e mime = 0;
728 encoder = GET_IS_ENCODER(flag) ? 1 : 0;
729 *hardware = GET_IS_HW(flag) ? 1 : 0;
730 app->is_encoder = encoder;
733 case MEDIACODEC_H264:
735 extractor = yuv_extractor;
736 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
737 *codec_mime = MEDIA_FORMAT_H264_SP;
739 extractor = h264_extractor;
740 mime = MEDIA_FORMAT_H264_SP;
743 case MEDIACODEC_MPEG4:
745 extractor = yuv_extractor;
746 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
747 *codec_mime = MEDIA_FORMAT_MPEG4_SP;
749 extractor = mpeg4_extractor;
750 mime = MEDIA_FORMAT_MPEG4_SP;
753 case MEDIACODEC_H263:
755 extractor = yuv_extractor;
756 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
757 *codec_mime = MEDIA_FORMAT_H263;
759 extractor = h263_extractor;
760 mime = MEDIA_FORMAT_H263;
765 extractor = aacenc_extractor;
766 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
767 *codec_mime = MEDIA_FORMAT_AAC;
769 extractor = aacdec_extractor;
770 mime = MEDIA_FORMAT_AAC;
773 case MEDIACODEC_AAC_HE:
775 extractor = aacenc_extractor;
776 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
777 *codec_mime = MEDIA_FORMAT_AAC_HE;
780 case MEDIACODEC_AAC_HE_PS:
783 extractor = mp3dec_extractor;
784 mime = MEDIA_FORMAT_MP3;
786 case MEDIACODEC_VORBIS:
788 case MEDIACODEC_FLAC:
790 case MEDIACODEC_WMAV1:
792 case MEDIACODEC_WMAV2:
794 case MEDIACODEC_WMAPRO:
796 case MEDIACODEC_WMALSL:
798 case MEDIACODEC_AMR_NB:
800 extractor = amrenc_extractor;
801 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
802 app->is_amr_nb = TRUE;
804 extractor = amrdec_extractor;
805 mime = MEDIA_FORMAT_AMR_NB;
808 case MEDIACODEC_AMR_WB:
810 extractor = amrenc_extractor;
811 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
812 app->is_amr_nb = FALSE;
814 extractor = amrdec_extractor;
815 mime = MEDIA_FORMAT_AMR_WB;
819 LOGE("NOT SUPPORTED!!!!");
825 void _mediacodec_process_input(App *app)
828 gboolean have_frame = FALSE;
830 static guint64 pts = 0L;
831 guint8 *buf_data_ptr = NULL;
832 media_packet_h pkt = NULL;
838 gboolean codec_config = FALSE;
840 for (i = 0; i < app->frame; i++) {
841 g_print("----------read data------------\n");
843 extractor(app, &tmp, &read, &have_frame, &codec_config);
847 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
848 g_print("media_packet_pool_aquire_packet failed\n");
852 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
853 g_print("media_packet_create_alloc failed\n");
858 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
859 g_print("media_packet_set_pts failed\n");
863 if (app->type != VIDEO_ENC) {
864 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
865 media_packet_set_buffer_size(pkt, (uint64_t)read);
866 memcpy(buf_data_ptr, tmp, read);
867 g_print("tmp:%p, read:%d\n", tmp, read);
870 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
871 media_packet_get_video_stride_width(pkt, 0, &stride_width);
872 offset = app->width*app->height;
874 for (j = 0; j < app->height; j++) {
875 memcpy(buf_data_ptr, tmp, app->width);
876 buf_data_ptr += stride_width;
880 if (app->hardware == TRUE) {
881 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
882 media_packet_get_video_stride_width(pkt, 1, &stride_width);
883 size = app->width * app->height / 2;
885 for (j = 0; j < app->height / 2; j++) {
886 memcpy(buf_data_ptr, tmp, app->width);
887 buf_data_ptr += stride_width;
892 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
893 media_packet_get_video_stride_width(pkt, 1, &stride_width);
894 size = (app->width>>1) * (app->height>>1);
896 for (j = 0; j < app->height/2; j++) {
897 memcpy(buf_data_ptr, tmp, app->width/2);
898 buf_data_ptr += stride_width;
903 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
904 media_packet_get_video_stride_width(pkt, 2, &stride_width);
907 for (j = 0; j < app->height/2; j++) {
908 memcpy(buf_data_ptr, tmp, app->width/2);
909 buf_data_ptr += stride_width;
915 mc_hex_dump("inbuf", tmp, 48);
917 ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000);
918 if (ret != MEDIACODEC_ERROR_NONE)
921 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
926 gboolean read_data(App *app)
929 gboolean have_frame = FALSE;
930 gboolean codec_config = FALSE;
932 static guint64 pts = 0L;
933 guint8 *buf_data_ptr = NULL;
934 media_packet_h pkt = NULL;
942 if (app->offset == 0) {
943 app->frame_count = 0;
944 app->start = clock();
947 g_print("----------read data------------\n");
948 extractor(app, &tmp, &read, &have_frame, &codec_config);
950 if (app->offset >= app->length - 4) {
953 app->finish = clock();
954 g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start)));
955 g_print("---------------------------\n");
958 g_print("length : %d, offset : %d\n", app->length, app->offset);
960 if (app->offset + len > app->length)
961 len = app->length - app->offset;
963 g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read);
967 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
968 g_print("media_packet_pool_aquire_packet failed\n");
972 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
973 g_print("media_packet_create_alloc failed\n");
977 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
978 g_print("media_packet_set_pts failed\n");
983 if (app->type != VIDEO_ENC) {
984 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
985 media_packet_set_buffer_size(pkt, (uint64_t)read);
987 memcpy(buf_data_ptr, tmp, read);
988 g_print("tmp:%p, read:%d\n", tmp, read);
991 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
992 media_packet_get_video_stride_width(pkt, 0, &stride_width);
993 offset = app->width*app->height;
995 for (i = 0; i < app->height; i++) {
996 memcpy(buf_data_ptr, tmp, app->width);
997 buf_data_ptr += stride_width;
1001 if (app->hardware == TRUE) {
1002 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1003 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1004 size = app->width * app->height>>1;
1006 for (i = 0; i < app->height>>1; i++) {
1007 memcpy(buf_data_ptr, tmp, app->width);
1008 buf_data_ptr += stride_width;
1014 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1015 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1016 size = (app->width>>1) * (app->height>>1);
1018 for (i = 0; i < app->height/2; i++) {
1019 memcpy(buf_data_ptr, tmp, app->width>>1);
1020 buf_data_ptr += stride_width;
1021 tmp += (app->width>>1);
1025 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
1026 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1029 for (i = 0; i < app->height/2; i++) {
1030 memcpy(buf_data_ptr, tmp, app->width>>1);
1031 buf_data_ptr += stride_width;
1032 tmp += (app->width>>1);
1037 mc_hex_dump("inbuf", tmp, 48);
1039 ret = mediacodec_process_input(app->mc_handle[0], pkt, 0);
1040 if (ret != MEDIACODEC_ERROR_NONE)
1043 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
1049 void av_feed_suspend(App *app)
1051 g_mutex_lock(&app->thread_mutex);
1053 g_print("suspend thread\n");
1054 g_mutex_unlock(&app->thread_mutex);
1057 void av_feed_resume(App *app)
1059 g_mutex_lock(&app->thread_mutex);
1061 g_print("resume thread\n");
1062 g_cond_broadcast(&app->thread_cond);
1063 g_mutex_unlock(&app->thread_mutex);
1066 #ifdef TIZEN_FEATURE_INTEGRATION
1067 gpointer av_feed_thread(gpointer data)
1069 App *app = (App *)data;
1073 media_packet_h packet = NULL;
1074 track = app->audio_track;
1077 g_mutex_lock(&app->thread_mutex);
1079 while (app->suspend != 0) g_cond_wait(&app->thread_cond, &app->thread_mutex);
1081 g_mutex_unlock(&app->thread_mutex);
1083 if (app->demux_eos == 1) {
1084 g_print("got eos!!!\n");
1088 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1089 if (ret != MEDIACODEC_ERROR_NONE)
1092 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1093 if (ret != MEDIACODEC_ERROR_NONE)
1103 gboolean feed_audio(App *app)
1108 media_packet_h packet = NULL;
1109 track = app->audio_track;
1111 g_print("read audio sample!!!\n");
1112 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1113 if (ret != MEDIACODEC_ERROR_NONE)
1116 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1117 if (ret != MEDIACODEC_ERROR_NONE)
1123 gboolean feed_video(App *app)
1128 media_packet_h packet = NULL;
1129 track = app->video_track;
1131 g_print("read video sample!!!\n");
1132 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1133 if (ret != MEDIACODEC_ERROR_NONE)
1136 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1137 if (ret != MEDIACODEC_ERROR_NONE)
1144 void start_feed(App *app)
1146 if (app->sourceid == 0) {
1147 app->sourceid = g_idle_add((GSourceFunc)read_data, app);
1148 g_print("start_feed\n");
1152 void stop_feed(App *app)
1154 if (app->sourceid != 0) {
1155 g_source_remove(app->sourceid);
1157 g_print("stop_feed\n");
1161 void _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
1163 App *app = (App *)user_data;
1165 g_print("_mediacodec_inbuf_used_cb!!!\n");
1167 media_packet_pool_release_packet(pkt_pool, pkt);
1169 media_packet_destroy(pkt);
1176 void _audio_outbuf_available_cb(media_packet_h pkt, void *user_data)
1178 media_packet_h out_pkt = NULL;
1181 App *app = (App*)user_data;
1183 g_print("_audio_outbuf_available_cb\n");
1185 g_mutex_lock(&app->lock);
1187 ret = mediacodec_get_output(app->mc_handle[app->audio_track], &out_pkt, 0);
1189 if (ret != MEDIACODEC_ERROR_NONE)
1190 g_print("get_output failed\n");
1192 if (app->enable_dump)
1193 output_dump(app, out_pkt);
1199 g_mutex_unlock(&app->lock);
1201 media_packet_destroy(out_pkt);
1208 void _video_outbuf_available_cb(media_packet_h pkt, void *user_data)
1210 media_packet_h out_pkt = NULL;
1213 App *app = (App*)user_data;
1215 g_print("_video_outbuf_available_cb\n");
1217 g_mutex_lock(&app->lock);
1219 ret = mediacodec_get_output(app->mc_handle[app->video_track], &out_pkt, 0);
1221 if (ret != MEDIACODEC_ERROR_NONE)
1222 g_print("get_output failed\n");
1224 if (app->enable_dump)
1225 decoder_output_dump(app, out_pkt);
1231 g_mutex_unlock(&app->lock);
1233 media_packet_destroy(out_pkt);
1240 void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
1242 media_packet_h out_pkt = NULL;
1245 App *app = (App*)user_data;
1247 g_print("_mediacodec_outbuf_available_cb\n");
1249 g_mutex_lock(&app->lock);
1251 ret = mediacodec_get_output(app->mc_handle[0], &out_pkt, 0);
1253 if (ret != MEDIACODEC_ERROR_NONE)
1254 g_print("get_output failed\n");
1256 if (app->enable_dump) {
1257 if (app->type == VIDEO_DEC)
1258 decoder_output_dump(app, out_pkt);
1260 output_dump(app, out_pkt);
1262 #ifdef TIZEN_FEATURE_INTEGRATION
1263 if (app->enable_muxer) {
1264 if (mediamuxer_write_sample(app->muxer, app->track, out_pkt) != MEDIAMUXER_ERROR_NONE)
1265 g_print("mediamuxer_write_sample failed\n");
1266 g_print("write sample!!!\n");
1273 g_mutex_unlock(&app->lock);
1275 media_packet_destroy(out_pkt);
1282 void _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
1284 g_print("_mediacodec_buffer_status_cb %d\n", status);
1286 App *app = (App*)user_data;
1288 if (status == MEDIACODEC_NEED_DATA)
1290 else if (status == MEDIACODEC_ENOUGH_DATA)
1296 void _av_buffer_status_cb(mediacodec_status_e status, void *user_data)
1298 g_print("_av_buffer_status_cb %d\n", status);
1300 App *app = (App*)user_data;
1302 if (status == MEDIACODEC_NEED_DATA)
1303 av_feed_resume(app);
1304 else if (status == MEDIACODEC_ENOUGH_DATA)
1305 av_feed_suspend(app);
1310 void _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
1316 void _mediacodec_eos_cb(void *user_data)
1318 App *app = (App *)user_data;
1320 g_print("mediacodec eos\n");
1321 g_mutex_lock(&app->eos_mutex);
1323 g_mutex_unlock(&app->eos_mutex);
1324 g_cond_broadcast(&app->dst_eos_cond);
1328 #ifdef TIZEN_FEATURE_INTEGRATION
1329 void demuxer_error_cb(mediademuxer_error_e error, void *user_data)
1331 g_print("Got Error %d from Mediademuxer\n", error);
1335 void _mediademuxer_eos_cb(int track, void *user_data)
1337 App *app = (App *)user_data;
1339 g_print("eos track : %d\n", track);
1340 av_feed_suspend(app);
1341 g_print("suspended\n");
1343 av_feed_resume(app);
1344 g_cond_broadcast(&app->eos_cond);
1349 void _mediamuxer_eos_cb(void *user_data)
1351 if (user_data == NULL) {
1352 g_print("invalid param");
1356 App *app = (App *)user_data;
1358 g_print("muxer eos\n");
1360 if (mediamuxer_stop(app->muxer) != MEDIAMUXER_ERROR_NONE)
1361 g_print(" mediamuxer_stop failed\n");
1363 if (mediamuxer_unprepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1364 g_print(" mediamuxer_unprepare failed\n");
1366 if (mediamuxer_destroy(app->muxer) != MEDIAMUXER_ERROR_NONE)
1367 g_print(" mediamuxer_destory failed\n");
1369 g_print("mediamuxer destroyed\n");
1373 gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data)
1375 g_print("codec type : %x %s\n", codec_type, codec_type_to_string(codec_type));
1379 void _mediacodec_prepare(App *app, gboolean frame_all)
1382 media_format_mimetype_e codec_mime;
1383 media_format_h codec_format;
1385 g_print("supported codec lists -internal-\n");
1386 mediacodec_foreach_supported_codec_static((mediacodec_supported_codec_cb)_foreach_cb, app);
1388 /* create instance */
1389 ret = mediacodec_create(&app->mc_handle[0]);
1390 if (ret != MEDIACODEC_ERROR_NONE) {
1391 g_print("mediacodec_create failed\n");
1396 ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag);
1397 if (ret != MEDIACODEC_ERROR_NONE) {
1398 g_print("mediacodec_set_codec failed\n");
1402 /* get mime and link to each codec parser */
1403 app->mime = _configure(app, app->codecid, app->flag, &app->hardware, &codec_mime);
1405 /* set codec info */
1406 ret = media_format_create(&fmt);
1408 switch (app->type) {
1410 media_format_set_video_mime(fmt, app->mime);
1411 media_format_set_video_width(fmt, app->width);
1412 media_format_set_video_height(fmt, app->height);
1414 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1415 if (ret != MEDIACODEC_ERROR_NONE)
1416 g_print("mediacodec_configure failed\n");
1419 media_format_set_video_mime(fmt, app->mime);
1420 media_format_set_video_width(fmt, app->width);
1421 media_format_set_video_height(fmt, app->height);
1422 media_format_set_video_avg_bps(fmt, app->target_bits);
1424 media_format_create(&codec_format);
1425 media_format_set_video_mime(codec_format, codec_mime);
1426 media_format_set_video_width(codec_format, app->width);
1427 media_format_set_video_height(codec_format, app->height);
1428 media_format_set_video_avg_bps(codec_format, app->target_bits);
1429 media_format_set_video_frame_rate(codec_format, app->fps);
1431 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1432 if (ret != MEDIACODEC_ERROR_NONE)
1433 g_print("mediacodec_configure failed\n");
1434 media_format_unref(codec_format);
1437 media_format_set_audio_mime(fmt, app->mime);
1438 media_format_set_audio_channel(fmt, app->channel);
1439 media_format_set_audio_samplerate(fmt, app->samplerate);
1440 media_format_set_audio_bit(fmt, app->bit);
1442 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1443 if (ret != MEDIACODEC_ERROR_NONE)
1444 g_print("mediacodec_configure failed\n");
1447 media_format_set_audio_mime(fmt, app->mime);
1448 media_format_set_audio_channel(fmt, app->channel);
1449 media_format_set_audio_samplerate(fmt, app->samplerate);
1450 media_format_set_audio_bit(fmt, app->bit);
1452 media_format_create(&codec_format);
1453 media_format_set_audio_mime(codec_format, codec_mime);
1454 media_format_set_audio_channel(codec_format, app->channel);
1455 media_format_set_audio_samplerate(codec_format, app->samplerate);
1456 media_format_set_audio_bit(codec_format, app->bit);
1457 media_format_set_audio_avg_bps(codec_format, app->bitrate);
1459 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1460 if (ret != MEDIACODEC_ERROR_NONE)
1461 g_print("mediacodec_set_configure failed\n");
1462 media_format_unref(codec_format);
1465 g_print("invaild type\n");
1469 if (ret != MEDIACODEC_ERROR_NONE) {
1470 g_print("mediacodec_set_xxxc(%d)_info failed\n", app->type);
1475 g_print("supported codec lists\n");
1476 mediacodec_foreach_supported_codec(app->mc_handle[0], (mediacodec_supported_codec_cb)_foreach_cb, app);
1477 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, app);
1478 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app);
1480 mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app);
1481 mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, app);
1482 mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL);
1485 ret = mediacodec_prepare(app->mc_handle[0]);
1486 if (ret != MEDIACODEC_ERROR_NONE) {
1487 g_print("mediacodec_prepare failed\n");
1491 #ifdef TIZEN_FEATURE_INTEGRATION
1492 if (app->enable_muxer) {
1493 if (mediamuxer_create(&app->muxer) != MEDIAMUXER_ERROR_NONE)
1494 g_print("mediamuxer_create failed\n");
1496 if (mediamuxer_set_data_sink(app->muxer, "/tmp/muxtest.mp4", MEDIAMUXER_CONTAINER_FORMAT_MP4) != MEDIAMUXER_ERROR_NONE)
1497 g_print("mediamuxer_set_data_sink failed\n");
1499 media_format_create(&app->format[0]);
1500 if (app->type == AUDIO_ENC)
1501 media_format_set_audio_mime(app->format[0], codec_mime);
1502 else if (app->type == VIDEO_ENC)
1503 media_format_set_video_mime(app->format[0], codec_mime);
1505 g_print("invalid format\n");
1507 if (mediamuxer_set_eos_cb(app->muxer, _mediamuxer_eos_cb, app) != MEDIAMUXER_ERROR_NONE)
1508 g_print("mediamuxer_set_eos_cb failed\n");
1510 if (mediamuxer_add_track(app->muxer, app->format[0], &app->track) != MEDIAMUXER_ERROR_NONE)
1511 g_print("mediamuxer_add_track failed\n");
1513 if (mediamuxer_prepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1514 g_print("mediamuxer_prepare failed\n");
1516 if (mediamuxer_start(app->muxer) != MEDIAMUXER_ERROR_NONE)
1517 g_print("mediamuxer_start failed\n");
1522 /* get packet pool instance */
1523 ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool);
1524 if (ret != MEDIA_PACKET_ERROR_NONE) {
1525 g_print("mediacodec_get_packet_pool failed\n");
1528 g_print("\n\nmediacodec start\n\n");
1533 void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1535 /* release input raw packet */
1536 media_packet_destroy(pkt);
1539 /* this callback is called when the input buffer for codec has done to use */
1540 void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1542 /* release input encoded packet */
1543 media_packet_destroy(pkt);
1546 void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1548 App *app = (App*)user_data;
1550 mediacodec_h media_codec_handle = app->mc_handle[1];
1551 media_packet_h output_buf = NULL;
1552 mediacodec_get_output(media_codec_handle, &output_buf, 0);
1553 /* decode encoded camera preview */
1554 mediacodec_process_input(app->mc_handle[0], output_buf, 0);
1557 void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1559 App *app = (App*)user_data;
1561 mediacodec_h media_codec_handle = app->mc_handle[0];
1562 media_packet_h output_buf = NULL;
1564 mediacodec_get_output(media_codec_handle, &output_buf, 0);
1566 if (app->enable_dump)
1567 decoder_output_dump(app, output_buf);
1569 media_packet_destroy(output_buf);
1572 void _media_packet_preview_cb(media_packet_h packet, void *user_data)
1574 App *app = user_data;
1575 g_mutex_lock(&app->lock);
1576 mediacodec_process_input(app->mc_handle[1], packet, 0);
1577 g_mutex_unlock(&app->lock);
1582 #ifdef TIZEN_FEATURE_INTEGRATION
1583 void _mediacodec_camera_start(App *app)
1585 int default_format = CAMERA_PIXEL_FORMAT_NV12;
1588 app->hardware = TRUE;
1590 /*create decoder instance and setup */
1591 mediacodec_create(&app->mc_handle[0]);
1592 mediacodec_set_codec(app->mc_handle[0], MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1593 mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height);
1595 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], _mediacodec_dec_input_buffer_used_cb, NULL);
1596 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], _mediacodec_dec_output_buffer_available_cb, app);
1597 mediacodec_prepare(app->mc_handle[0]);
1599 /*create encoder instance and setup */
1600 mediacodec_create(&app->mc_handle[1]);
1601 mediacodec_set_codec(app->mc_handle[1], MEDIACODEC_H264, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW);
1602 mediacodec_set_venc_info(app->mc_handle[1], app->width, app->height, 30, 1000);
1604 mediacodec_set_input_buffer_used_cb(app->mc_handle[1], _mediacodec_enc_input_buffer_used_cb, NULL);
1605 mediacodec_set_output_buffer_available_cb(app->mc_handle[1], _mediacodec_enc_output_buffer_available_cb, app);
1606 mediacodec_prepare(app->mc_handle[1]);
1608 /* create camera instance and setup and then start preview */
1609 camera_create(CAMERA_DEVICE_CAMERA0, &app->camera_handle);
1610 camera_set_media_packet_preview_cb(app->camera_handle, _media_packet_preview_cb, app);
1611 camera_get_preview_format(app->camera_handle, &default_format);
1612 camera_set_preview_format(app->camera_handle, default_format);
1613 camera_set_preview_resolution(app->camera_handle, app->width, app->height);
1614 camera_set_display(app->camera_handle, CAMERA_DISPLAY_TYPE_NONE, NULL);
1615 camera_start_preview(app->camera_handle);
1621 void _mediacodec_camera_stop(App *app)
1623 camera_state_e camera_state = CAMERA_STATE_NONE;
1625 camera_get_state(app->camera_handle, &camera_state);
1626 camera_stop_preview(app->camera_handle);
1627 camera_destroy(app->camera_handle);
1629 mediacodec_unprepare(app->mc_handle[0]);
1630 mediacodec_unprepare(app->mc_handle[1]);
1631 mediacodec_destroy(app->mc_handle[0]);
1632 mediacodec_destroy(app->mc_handle[1]);
1637 #ifdef TIZEN_FEATURE_INTEGRATION
1638 void _mediacodec_auto_test(App *app, char *path)
1641 gint num_tracks = 0;
1646 gint samplerate = 0;
1648 media_format_type_e formattype;
1649 media_format_mimetype_e video_mime;
1650 media_format_mimetype_e audio_mime;
1651 gint codec_mask = 0xFFF0;
1660 ret = mediademuxer_create(&app->demuxer);
1661 if (ret != MEDIACODEC_ERROR_NONE) {
1662 g_print("failed to create demuxer\n");
1666 ret = mediademuxer_set_data_source(app->demuxer, path);
1667 if (ret != MEDIACODEC_ERROR_NONE) {
1668 g_print("failed to mediademuxer_set_data_source\n");
1672 ret = mediademuxer_set_error_cb(app->demuxer, demuxer_error_cb, app->demuxer);
1673 if (ret != MEDIACODEC_ERROR_NONE) {
1674 g_print("failed to mediademuxer_set_error_cb\n");
1678 mediademuxer_set_eos_cb(app->demuxer, _mediademuxer_eos_cb, app);
1680 ret = mediademuxer_prepare(app->demuxer);
1681 if (ret != MEDIACODEC_ERROR_NONE) {
1682 g_print("failed to prepare\n");
1687 ret = mediademuxer_get_track_count(app->demuxer, &num_tracks);
1688 if (ret != MEDIACODEC_ERROR_NONE) {
1689 g_print("failed to get track\n");
1693 for (track = 0; track < num_tracks; track++) {
1694 ret = mediademuxer_get_track_info(app->demuxer, track, &app->format[track]);
1695 if (ret != MEDIACODEC_ERROR_NONE) {
1696 g_print("failed to get track info\n");
1700 media_format_get_type(app->format[track], &formattype);
1702 if (!app->is_video && formattype == MEDIA_FORMAT_AUDIO) {
1703 app->audio_track = track;
1704 app->type = AUDIO_DEC;
1705 media_format_get_audio_info(app->format[track], &audio_mime, &channel, &samplerate, &bit, NULL);
1707 mediademuxer_select_track(app->demuxer, track);
1709 ret = mediacodec_create(&app->mc_handle[track]);
1710 if (ret != MEDIACODEC_ERROR_NONE) {
1711 g_print("failed to create mediacocec\n");
1715 codec_id = audio_mime & codec_mask;
1716 g_print("auido codec_id : %x\n", codec_id);
1718 ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW);
1719 if (ret != MEDIACODEC_ERROR_NONE) {
1720 g_print("failed to set codec\n");
1724 ret = mediacodec_set_adec_info(app->mc_handle[track], samplerate, channel, bit);
1725 if (ret != MEDIACODEC_ERROR_NONE) {
1726 g_print("failed to set adec info\n");
1730 mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1731 mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1732 mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _audio_outbuf_available_cb, app);
1733 mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1734 mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1736 } else if (app->is_video && formattype == MEDIA_FORMAT_VIDEO) {
1737 app->video_track = track;
1738 app->type = VIDEO_DEC;
1739 media_format_get_video_info(app->format[track], &video_mime, &width, &height, NULL, NULL);
1741 mediademuxer_select_track(app->demuxer, track);
1743 ret = mediacodec_create(&app->mc_handle[track]);
1744 if (ret != MEDIACODEC_ERROR_NONE) {
1745 g_print("failed to create mediacocec\n");
1750 app->height = height;
1752 codec_id = video_mime & codec_mask;
1753 g_print("video codec_id : %x\n", codec_id);
1755 ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1756 if (ret != MEDIACODEC_ERROR_NONE) {
1757 g_print("failed to set codec\n");
1761 ret = mediacodec_set_vdec_info(app->mc_handle[track], width, height);
1762 if (ret != MEDIACODEC_ERROR_NONE) {
1763 g_print("failed to set vdec info\n");
1767 mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1768 mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1769 mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _video_outbuf_available_cb, app);
1770 mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1771 mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1775 ret = mediademuxer_start(app->demuxer);
1776 if (ret != MEDIACODEC_ERROR_NONE) {
1777 g_print("failed to start mediademuxer\n");
1781 track = app->is_video ? app->video_track : app->audio_track;
1782 ret = mediacodec_prepare(app->mc_handle[track]);
1783 if (ret != MEDIACODEC_ERROR_NONE) {
1784 g_print("failed to prepare mediacodec\n");
1788 g_cond_init(&app->thread_cond);
1789 g_cond_init(&app->eos_cond);
1790 g_cond_init(&app->dst_eos_cond);
1791 g_mutex_init(&app->thread_mutex);
1792 g_mutex_init(&app->eos_mutex);
1794 app->thread = g_thread_new("feed thread", &av_feed_thread, app);
1795 app->start = clock();
1797 g_mutex_lock(&app->eos_mutex);
1798 while (app->codec_eos != 1) g_cond_wait(&app->dst_eos_cond, &app->eos_mutex);
1799 g_mutex_unlock(&app->eos_mutex);
1800 g_print("now try to destroy thread!!\n");
1801 g_thread_join(app->thread);
1802 app->finish = clock();
1804 ret = mediademuxer_stop(app->demuxer);
1805 if (ret != MEDIACODEC_ERROR_NONE) {
1806 g_print("failed to stop mediademuxer\n");
1810 ret = mediademuxer_unselect_track(app->demuxer, track);
1811 if (ret != MEDIACODEC_ERROR_NONE) {
1812 g_print("failed to unselect mediademuxer\n");
1816 ret = mediacodec_unprepare(app->mc_handle[track]);
1817 if (ret != MEDIACODEC_ERROR_NONE) {
1818 g_print("failed to unprepare mediacodec\n");
1822 ret = mediacodec_destroy(app->mc_handle[track]);
1823 if (ret != MEDIACODEC_ERROR_NONE) {
1824 g_print("failed to destroy mediacodec\n");
1828 ret = mediademuxer_unprepare(app->demuxer);
1829 if (ret != MEDIACODEC_ERROR_NONE) {
1830 g_print("failed to unprepare mediademuxer\n");
1834 ret = mediademuxer_destroy(app->demuxer);
1835 if (ret != MEDIACODEC_ERROR_NONE) {
1836 g_print("failed to destroy mediademuxer\n");
1840 g_cond_clear(&app->thread_cond);
1841 g_cond_clear(&app->eos_cond);
1842 g_cond_clear(&app->dst_eos_cond);
1843 g_mutex_clear(&app->thread_mutex);
1844 g_mutex_clear(&app->eos_mutex);
1846 g_print("resources are released!!!\n\n\n");
1847 g_print("-----------------------------------------------------\n");
1848 g_print("Input - queued packets : %d, finalized packets : %d\n", app->etb, app->ebd);
1849 g_print("Output - queued packets : %d, finalized packets : %d\n", app->fbd, app->fbd);
1850 g_print("Average FPS = %3.3f\n", ((double)app->fbd*1000000/(app->finish - app->start)));
1851 g_print("-----------------------------------------------------\n");
1857 void _mediacodec_unprepare(App *app)
1859 mediacodec_unprepare(app->mc_handle[0]);
1862 void _mediacodec_destroy(App *app)
1865 g_print("invalid param");
1869 if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1871 g_print("media_packet_pool_deallocatet failed\n");
1875 if (media_packet_pool_destroy(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1877 g_print(" media_packet_pool_destroy failed\n");
1880 g_print("media packet pool destroyed! \n");
1882 mediacodec_destroy(app->mc_handle[0]);
1883 #ifdef TIZEN_FEATURE_INTEGRATION
1884 if (app->enable_muxer) {
1885 if (mediamuxer_close_track(app->muxer, app->track) != MEDIAMUXER_ERROR_NONE)
1886 g_print("mediamuxer_close_track failed\n");
1891 void input_filepath(char *filename, App *app)
1893 GError *error = NULL;
1896 app->file = g_mapped_file_new(filename, FALSE, &error);
1898 g_print("failed to open file : %s\n", error->message);
1899 g_error_free(error);
1903 app->length = g_mapped_file_get_length(app->file);
1904 app->data = (guint8 *)g_mapped_file_get_contents(app->file);
1906 g_print("len : %d, offset : %d, obj : %d", app->length, app->offset, app->obj);
1911 void quit_program(App *app)
1913 g_mutex_clear(&app->lock);
1914 media_format_unref(fmt);
1915 g_main_loop_quit(app->loop);
1919 void reset_menu_state()
1921 g_menu_state = CURRENT_STATUS_MAINMENU;
1925 void _interpret_main_menu(char *cmd, App *app)
1927 gint len = strlen(cmd);
1929 if (strncmp(cmd, "a", 1) == 0)
1930 g_menu_state = CURRENT_STATUS_FILENAME;
1931 else if (strncmp(cmd, "o", 1) == 0)
1932 g_menu_state = CURRENT_STATUS_GET_OUTPUT;
1933 else if (strncmp(cmd, "q", 1) == 0)
1936 g_print("unknown menu \n");
1937 } else if (len == 2) {
1938 if (strncmp(cmd, "pr", 2) == 0)
1939 _mediacodec_prepare(app, 0);
1940 else if (strncmp(cmd, "pa", 2) == 0)
1941 _mediacodec_prepare(app, 1);
1942 else if (strncmp(cmd, "sc", 2) == 0)
1943 g_menu_state = CURRENT_STATUS_SET_CODEC;
1944 else if (strncmp(cmd, "vd", 2) == 0)
1945 g_menu_state = CURRENT_STATUS_SET_VDEC_INFO;
1946 else if (strncmp(cmd, "ve", 2) == 0)
1947 g_menu_state = CURRENT_STATUS_SET_VENC_INFO;
1948 else if (strncmp(cmd, "ad", 2) == 0)
1949 g_menu_state = CURRENT_STATUS_SET_ADEC_INFO;
1950 else if (strncmp(cmd, "ae", 2) == 0)
1951 g_menu_state = CURRENT_STATUS_SET_AENC_INFO;
1952 else if (strncmp(cmd, "pi", 2) == 0)
1953 g_menu_state = CURRENT_STATUS_PROCESS_INPUT;
1954 else if (strncmp(cmd, "un", 2) == 0)
1955 _mediacodec_unprepare(app);
1956 else if (strncmp(cmd, "dt", 2) == 0)
1957 _mediacodec_destroy(app);
1958 #ifdef TIZEN_FEATURE_INTEGRATION
1959 else if (strncmp(cmd, "cr", 2) == 0)
1960 _mediacodec_camera_start(app);
1961 else if (strncmp(cmd, "ct", 2) == 0)
1962 _mediacodec_camera_stop(app);
1963 else if (strncmp(cmd, "au", 2) == 0)
1964 g_menu_state = CURRENT_STATUS_AUTO_TEST;
1965 else if (strncmp(cmd, "mp", 2) == 0) {
1966 if (!app->enable_muxer) {
1967 app->enable_muxer = TRUE;
1968 g_print("muxer enabled\n");
1970 app->enable_dump = FALSE;
1971 g_print("dump disabled\n");
1975 else if (strncmp(cmd, "dp", 2) == 0) {
1976 if (!app->enable_dump) {
1977 app->enable_dump = TRUE;
1978 g_print("dump enabled\n");
1980 app->enable_dump = FALSE;
1981 g_print("dump disabled\n");
1984 display_sub_basic();
1986 g_print("unknown menu \n");
1992 void displaymenu(void)
1994 if (g_menu_state == CURRENT_STATUS_MAINMENU) {
1995 display_sub_basic();
1996 } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
1997 g_print("*** input mediapath.\n");
1998 } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) {
1999 g_print("*** Codec id : Select Codec ID Numbe (e.g. AAC_LC = 96)\n");
2000 g_print(" L16 = 16 (0x10)\n");
2001 g_print(" ALAW = 32 (0x20)\n");
2002 g_print(" ULAW = 48 (0x30)\n");
2003 g_print(" AMR_NB = 64 (0x40)\n");
2004 g_print(" AMR_WB = 65 (0x41)\n");
2005 g_print(" G729 = 80 (0x50)\n");
2006 g_print(" AAC_LC = 96 (0x60)\n");
2007 g_print(" AAC_HE = 97 (0x61)\n");
2008 g_print(" AAC_PS = 98 (0x62)\n");
2009 g_print(" MP3 = 112 (0x70)\n");
2010 g_print(" VORBIS = 128 (0x80)\n");
2011 g_print(" FLAC = 144 (0x90)\n");
2012 g_print(" WMAV1 = 160 (0xA0)\n");
2013 g_print(" WMAV2 = 161 (0xA1)\n");
2014 g_print(" WMAPRO = 162 (0xA2)\n");
2015 g_print(" WMALSL = 163 (0xA3)\n");
2016 g_print(" -------------------\n");
2017 g_print(" H261 = 101\n");
2018 g_print(" H263 = 102\n");
2019 g_print(" H264 = 103\n");
2020 g_print(" MJPEG = 104\n");
2021 g_print(" MPEG1 = 105\n");
2022 g_print(" MPEG2 = 106\n");
2023 g_print(" MPEG4 = 107\n");
2024 g_print(" -------------------\n");
2025 g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
2026 g_print(" CODEC : ENCODER = 1 DECODER = 2\n");
2027 g_print(" TYPE : HW = 4 SW = 8\n");
2028 g_print("*** input codec id, falgs.\n");
2029 } else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO) {
2030 g_print("*** input video decode configure.(width, height)\n");
2031 } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
2032 g_print("*** input video encode configure.(width, height, fps, target_bits)\n");
2033 } else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO) {
2034 g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000, 2, 16))\n");
2035 } else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO) {
2036 g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000, 2, 16, 128000))\n");
2037 } else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT) {
2038 g_print("*** input dec process number\n");
2039 } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
2040 g_print("*** input get output buffer number\n");
2041 #ifdef TIZEN_FEATURE_INTEGRATION
2042 } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) {
2043 g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n");
2046 g_print("*** unknown status.\n");
2051 gboolean timeout_menu_display(void* data)
2057 void interpret(char *cmd)
2062 switch (g_menu_state) {
2063 case CURRENT_STATUS_MAINMENU:
2064 _interpret_main_menu(cmd, app);
2066 case CURRENT_STATUS_FILENAME:
2067 input_filepath(cmd, app);
2070 case CURRENT_STATUS_SET_CODEC:
2072 static gint cnt = 0;
2082 (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) {
2083 tmp = strtol(cmd, ptr, 16);
2084 app->codecid = 0x2000 + ((tmp & 0xFF) << 4);
2086 app->codecid = 0x1000 + tmp;
2091 app->flag = atoi(cmd);
2100 case CURRENT_STATUS_SET_VDEC_INFO:
2102 static gint cnt = 0;
2105 app->width = atoi(cmd);
2109 app->height = atoi(cmd);
2110 app->type = VIDEO_DEC;
2120 case CURRENT_STATUS_SET_VENC_INFO:
2122 static gint cnt = 0;
2125 app->width = atoi(cmd);
2129 app->height = atoi(cmd);
2133 app->fps = atol(cmd);
2137 app->target_bits = atoi(cmd);
2138 app->type = VIDEO_ENC;
2148 case CURRENT_STATUS_SET_ADEC_INFO:
2150 static gint cnt = 0;
2153 app->samplerate = atoi(cmd);
2157 app->channel = atoi(cmd);
2161 app->bit = atoi(cmd);
2162 app->type = AUDIO_DEC;
2172 case CURRENT_STATUS_SET_AENC_INFO:
2179 if (tmp <= 0 || tmp > 96000) {
2180 g_print("Invalid value\n");
2184 app->samplerate = tmp;
2190 if (tmp <= 0 || tmp > 6) {
2191 g_print("Invalid value\n");
2201 if (tmp <= 0 || tmp > 32) {
2202 g_print("Invalid value\n");
2212 if (tmp <= 0 || tmp >= INT_MAX) {
2213 g_print(";;Invalid value\n");
2217 app->type = AUDIO_ENC;
2228 case CURRENT_STATUS_PROCESS_INPUT:
2232 if (tmp <= 0 || tmp >= 10) {
2233 g_print("Invalid value\n");
2239 _mediacodec_process_input(app);
2243 case CURRENT_STATUS_GET_OUTPUT:
2248 #ifdef TIZEN_FEATURE_INTEGRATION
2249 case CURRENT_STATUS_AUTO_TEST:
2256 strncpy(app->filepath, cmd, len + 1);
2257 g_print("%s, %d\n", app->filepath, len);
2261 app->is_video = atoi(cmd) ? 1 : 0;
2262 _mediacodec_auto_test(app, app->filepath);
2274 g_timeout_add(100, timeout_menu_display, 0);
2277 void display_sub_basic()
2280 g_print("=========================================================================================\n");
2281 g_print(" media codec test\n");
2282 g_print("-----------------------------------------------------------------------------------------\n");
2283 g_print("a. Create \t\t");
2284 g_print("sc. Set codec \n");
2285 g_print("vd. Set vdec info \t");
2286 g_print("ve. Set venc info \n");
2287 g_print("ad. Set adec info \t");
2288 g_print("ae. Set aenc info \n");
2289 g_print("pr. Prepare \t");
2290 g_print("pa. Prepare and process all\t\t");
2291 g_print("pi. process input with num\n");
2292 g_print("o. Get output \t\t");
2293 g_print("rb. Reset output buffer \n");
2294 g_print("un. Unprepare \t\t");
2295 g_print("dt. Destroy \t\t");
2296 g_print("q. quit test suite \n");
2297 g_print("dp. enable dump \n");
2298 #ifdef TIZEN_FEATURE_INTEGRATION
2299 g_print("mp. enable muxer \n");
2300 g_print("-----------------------------------------------------------------------------------------\n");
2301 g_print("cr. camera preview -> encoder -> decoder\n");
2302 g_print("au. integration test with mediademuxer\n");
2303 g_print("ct. quit camera test\n");
2306 g_print("=========================================================================================\n");
2309 gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
2311 gchar buf[MAX_STRING_LEN];
2313 GError *error = NULL;
2315 g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
2323 void mc_hex_dump(char *desc, void *addr, gint len)
2327 guint8 *pc = (guint8 *)addr;
2330 g_print("%s:\n", desc);
2332 for (i = 0; i < len; i++) {
2334 if ((i % 16) == 0) {
2336 g_print(" %s\n", buff);
2338 g_print(" %04x ", i);
2341 g_print(" %02x", pc[i]);
2343 if ((pc[i] < 0x20) || (pc[i] > 0x7e))
2346 buff[i % 16] = pc[i];
2347 buff[(i % 16) + 1] = '\0';
2350 while ((i % 16) != 0) {
2354 g_print(" %s\n", buff);
2357 void decoder_output_dump(App *app, media_packet_h pkt)
2361 int stride_width, stride_height;
2362 gchar filename[100] = {0};
2366 g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height);
2367 fp = fopen(filename, "ab");
2369 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&temp);
2370 media_packet_get_video_stride_width(pkt, 0, &stride_width);
2371 media_packet_get_video_stride_height(pkt, 0, &stride_height);
2372 g_print("stride : %d, %d\n", stride_width, stride_height);
2374 for (i = 0; i < app->height; i++) {
2375 ret = fwrite(temp, app->width, 1, fp);
2376 temp += stride_width;
2379 if (app->hardware == TRUE) {
2380 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2381 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2382 for (i = 0; i < app->height/2; i++) {
2383 ret = fwrite(temp, app->width, 1, fp);
2384 temp += stride_width;
2387 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2388 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2389 for (i = 0; i < app->height/2; i++) {
2390 ret = fwrite(temp, app->width/2, 1, fp);
2391 temp += stride_width;
2394 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&temp);
2395 media_packet_get_video_stride_width(pkt, 2, &stride_width);
2396 for (i = 0; i < app->height/2; i++) {
2397 ret = fwrite(temp, app->width/2, 1, fp);
2398 temp += stride_width;
2402 g_print("codec dec output dumped!!%d\n", ret);
2408 * Add ADTS header at the beginning of each and every AAC packet.
2409 * This is needed as MediaCodec encoder generates a packet of raw AAC data.
2410 * Note the packetLen must count in the ADTS header itself.
2412 void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen)
2414 int profile = 2; /* AAC LC (0x01) */
2415 int freqIdx = 3; /* 48KHz (0x03) */
2416 int chanCfg = 2; /* CPE (0x02) */
2418 if (app->samplerate == 96000) freqIdx = 0;
2419 else if (app->samplerate == 88200) freqIdx = 1;
2420 else if (app->samplerate == 64000) freqIdx = 2;
2421 else if (app->samplerate == 48000) freqIdx = 3;
2422 else if (app->samplerate == 44100) freqIdx = 4;
2423 else if (app->samplerate == 32000) freqIdx = 5;
2424 else if (app->samplerate == 24000) freqIdx = 6;
2425 else if (app->samplerate == 22050) freqIdx = 7;
2426 else if (app->samplerate == 16000) freqIdx = 8;
2427 else if (app->samplerate == 12000) freqIdx = 9;
2428 else if (app->samplerate == 11025) freqIdx = 10;
2429 else if (app->samplerate == 8000) freqIdx = 11;
2431 if ((app->channel == 1) || (app->channel == 2))
2432 chanCfg = app->channel;
2434 /* fill in ADTS data */
2435 buffer[0] = (char)0xFF;
2436 buffer[1] = (char)0xF1;
2437 buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
2438 buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11));
2439 buffer[4] = (char)((packetLen&0x7FF) >> 3);
2440 buffer[5] = (char)(((packetLen&7)<<5) + 0x1F);
2441 buffer[6] = (char)0xFC;
2444 void output_dump(App *app, media_packet_h pkt)
2448 gchar filename[100] = {0};
2451 char adts[100] = {0, };
2453 g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d.out", app->type);
2454 fp = fopen(filename, "ab");
2456 media_packet_get_buffer_data_ptr(pkt, &temp);
2457 media_packet_get_buffer_size(pkt, &buf_size);
2458 g_print("output data : %p, size %d\n", temp, (int)buf_size);
2460 if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) {
2461 add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE));
2462 fwrite(&adts, 1, ADTS_HEADER_SIZE, fp);
2463 g_print("adts appended\n");
2464 } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) {
2465 /* This is used only AMR encoder case for adding AMR masic header in only first frame */
2466 g_print("%s - AMR_header write in first frame\n", __func__);
2467 fwrite(&AMR_header[0], 1, sizeof(AMR_header) - 1, fp); /* AMR-NB magic number */
2468 write_amr_header = 0;
2471 fwrite(temp, (int)buf_size, 1, fp);
2473 g_print("codec dec output dumped!!%d\n", ret);
2478 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id)
2480 guint media_codec_id_u = (guint)media_codec_id;
2482 switch (media_codec_id_u) {
2483 case MEDIACODEC_L16:
2485 case MEDIACODEC_ALAW:
2487 case MEDIACODEC_ULAW:
2489 case MEDIACODEC_AMR_NB:
2491 case MEDIACODEC_AMR_WB:
2493 case MEDIACODEC_G729:
2495 case MEDIACODEC_AAC_LC:
2497 case MEDIACODEC_AAC_HE:
2499 case MEDIACODEC_AAC_HE_PS:
2501 case MEDIACODEC_MP3:
2503 case MEDIACODEC_VORBIS:
2505 case MEDIACODEC_FLAC:
2507 case MEDIACODEC_WMAV1:
2509 case MEDIACODEC_WMAV2:
2511 case MEDIACODEC_WMAPRO:
2513 case MEDIACODEC_WMALSL:
2515 case MEDIACODEC_H261:
2517 case MEDIACODEC_H263:
2519 case MEDIACODEC_H264:
2521 case MEDIACODEC_MJPEG:
2523 case MEDIACODEC_MPEG1:
2525 case MEDIACODEC_MPEG2:
2527 case MEDIACODEC_MPEG4:
2529 case MEDIACODEC_HEVC:
2531 case MEDIACODEC_VP8:
2533 case MEDIACODEC_VP9:
2535 case MEDIACODEC_VC1:
2543 int main(int argc, char *argv[])
2545 GIOChannel *stdin_channel;
2546 stdin_channel = g_io_channel_unix_new(0);
2547 g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
2548 g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
2552 g_mutex_init(&app->lock);
2554 app->loop = g_main_loop_new(NULL, TRUE);
2555 app->timer = g_timer_new();
2556 g_main_loop_run(app->loop);