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.
24 #include <tbm_surface.h>
27 #include <media_codec.h>
28 #include <media_packet.h>
29 #include <media_packet_internal.h>
30 #include <media_packet_pool.h>
31 #include <media_codec_internal.h>
32 #ifdef TIZEN_FEATURE_INTEGRATION
34 #include <mediademuxer.h>
35 #include <mediamuxer.h>
38 #define PACKAGE "media_codec_test"
40 #define TEST_FILE_SIZE (10 * 1024 * 1024)
41 #define MAX_STRING_LEN 256
43 #define DEFAULT_SAMPPLERATE 44100
44 #define DEFAULT_CHANNEL 2
45 #define DEFAULT_BIT 16
46 #define DEFAULT_BITRATE 128
47 #define DEFAULT_SAMPLEBYTE 1024
48 #define ADTS_HEADER_SIZE 7
49 #define AMRNB_PCM_INPUT_SIZE 320
50 #define AMRWB_PCM_INPUT_SIZE 640
51 #define OPUS_PCM_INPUT_SIZE 4096
53 #define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
54 #define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
55 #define GET_IS_DECODER(x) CHECK_BIT(x, 1)
56 #define GET_IS_HW(x) CHECK_BIT(x, 2)
57 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000
58 #define CHECK_VALID_PACKET(state, expected_state) \
59 ((state & (expected_state)) == (expected_state))
61 #define AAC_CODECDATA_SIZE 16
63 guint8 buf_adts[ADTS_HEADER_SIZE];
66 MC_EXIST_SPS = 1 << 0,
67 MC_EXIST_PPS = 1 << 1,
68 MC_EXIST_IDR = 1 << 2,
69 MC_EXIST_SLICE = 1 << 3,
71 MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS),
72 MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR)
75 typedef struct _App App;
78 CURRENT_STATUS_MAINMENU,
79 CURRENT_STATUS_FILENAME,
80 CURRENT_STATUS_CREATE,
81 CURRENT_STATUS_DESTROY,
82 CURRENT_STATUS_SET_CODEC,
83 CURRENT_STATUS_SET_VDEC_INFO,
84 CURRENT_STATUS_SET_VENC_INFO,
85 CURRENT_STATUS_SET_ADEC_INFO,
86 CURRENT_STATUS_SET_AENC_INFO,
87 CURRENT_STATUS_PREPARE,
88 CURRENT_STATUS_UNPREPARE,
89 CURRENT_STATUS_PROCESS_INPUT,
90 CURRENT_STATUS_GET_OUTPUT,
91 CURRENT_STATUS_RESET_OUTPUT_BUFFER,
92 CURRENT_STATUS_SET_SIZE,
93 CURRENT_STATUS_AUTO_TEST,
97 NAL_SLICE_NO_PARTITIONING = 1,
103 NAL_SEQUENCE_PARAMETER_SET,
104 NAL_PICTURE_PARAMETER_SET,
105 NAL_PICTURE_DELIMITER,
143 gboolean enable_dump;
144 gboolean enable_muxer;
148 #ifdef TIZEN_FEATURE_INTEGRATION
149 camera_h camera_handle;
150 mediademuxer_h demuxer;
165 media_format_h format[MAX_HANDLE];
167 mediacodec_h mc_handle[MAX_HANDLE];
172 media_format_mimetype_e mime;
187 media_packet_h packet;
199 media_format_h fmt = NULL;
200 media_packet_pool_h pkt_pool = NULL;
202 /* Internal Functions */
203 void displaymenu(void);
204 void display_sub_basic();
206 void _mediacodec_unprepare(App *app);
207 void _mediacodec_destroy(App *app);
208 void _mediacodec_auto_test(App *app, char *path);
209 void input_filepath(char *filename, App *app);
211 void mc_hex_dump(char *desc, void *addr, gint len);
212 void decoder_output_dump(App *app, media_packet_h pkt);
213 void output_dump(App *app, media_packet_h pkt);
215 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id);
217 void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data);
219 gint g_menu_state = CURRENT_STATUS_MAINMENU;
221 static const guint mp3types_bitrates[2][3][16] = {
223 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
224 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
225 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
228 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
229 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
230 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
234 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
235 {22050, 24000, 16000},
239 void h264_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
241 guint8 val, zero_count;
242 guint8 *pNal = app->data + app->offset;
243 gint max = app->length - app->offset;
245 gint nal_unit_type = 0;
273 if ((zero_count >= 2) && (val == 1))
283 read = (index - zero_count - 1);
285 nal_unit_type = *(app->data+app->offset+4) & 0x1F;
286 g_print("nal_unit_type : %x\n", nal_unit_type);
288 switch (nal_unit_type) {
289 case NAL_SEQUENCE_PARAMETER_SET:
290 g_print("nal_unit_type : SPS\n");
291 state |= MC_EXIST_SPS;
293 case NAL_PICTURE_PARAMETER_SET:
294 g_print("nal_unit_type : PPS\n");
295 state |= MC_EXIST_PPS;
299 g_print ("nal_unit_type : IDR\n");
300 state |= MC_EXIST_IDR;
302 case NAL_SLICE_NO_PARTITIONING:
303 case NAL_SLICE_PART_A:
304 case NAL_SLICE_PART_B:
305 case NAL_SLICE_PART_C:
306 state |= MC_EXIST_SLICE;
309 g_print ("nal_unit_type : %x", nal_unit_type);
313 init = CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE) ? 1 : 0;
314 slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
315 idr = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
316 g_print("status : %d, slice : %d, idr : %d\n", init, slice, idr);
318 if (init || idr || slice) {
322 *size = app->offset + read;
324 *data = app->data+app->offset;
329 *data = app->data+app->offset;
336 void h263_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
339 int read_size = 1, state = 1, bStart = 0;
341 guint8 *pH263 = app->data + app->offset;
343 int max = app->length - app->offset;
347 read_size = (len - 1);
364 if ((val & 0xFC) == 0x80) {
377 app->offset += read_size;
381 void mpeg4_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
385 int state = 1, bType = 0;
387 guint8 *pMpeg4 = app->data + app->offset;
389 int max = app->length - app->offset;
418 if (val == 0xB0 || val == 0xB6) {
434 app->offset += result;
439 * Extract Input data for AMR-NB/WB decoder
440 * - AMR-NB : mime type ("audio/AMR") / 8Khz / 1 ch / 16 bits
441 * - AMR-WB : mime type ("audio/AMR-WB") / 16Khz / 1 ch / 16 bits
443 gint write_amr_header = 1; /* write magic number for AMR Header at one time */
444 static const gchar AMR_header[] = "#!AMR\n";
445 static const gchar AMRWB_header[] = "#!AMR-WB\n";
446 #define AMR_NB_MIME_HDR_SIZE 6
447 #define AMR_WB_MIME_HDR_SIZE 9
448 static const gint block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
449 static const gint block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
452 void amrdec_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
454 gint readsize = 0, mode_temp;
456 guint8 *pAmr = app->data + app->offset;
457 /* change the below one to frame count */
458 if (app->offset == 0) {
459 if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
460 blocksize_tbl = (int *)block_size_nb;
461 mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
462 pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
463 app->offset += AMR_NB_MIME_HDR_SIZE;
465 if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
466 blocksize_tbl = (int *)block_size_wb;
467 mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
468 pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
469 app->offset += AMR_WB_MIME_HDR_SIZE;
471 g_print("[ERROR] AMR-NB/WB don't detected..\n");
477 if ((mode_temp & 0x83) == 0) {
478 mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
479 fsize = blocksize_tbl[mode];
480 readsize = fsize + 1;
483 g_print("[FAIL] Not found amr frame sync.....\n");
487 app->offset += readsize;
492 void nv12_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
495 gint offset = app->length - app->offset;
497 yuv_size = app->width * app->height * 3 / 2;
499 if (offset >= yuv_size)
503 *data = app->data + app->offset;
505 if (yuv_size >= offset)
510 app->offset += *size;
513 void yuv_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
516 gint offset = app->length - app->offset;
518 yuv_size = app->width * app->height * 3 / 2;
520 if (yuv_size >= offset)
524 *data = app->data + app->offset;
526 if (yuv_size >= offset)
531 app->offset += *size;
534 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
537 gint offset = app->length - app->offset;
539 read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2);
542 *data = app->data + app->offset;
544 if (read_size >= offset)
549 app->offset += *size;
552 void amrenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
555 gint offset = app->length - app->offset;
558 read_size = AMRNB_PCM_INPUT_SIZE;
560 read_size = AMRWB_PCM_INPUT_SIZE;
563 *data = app->data + app->offset;
565 if (read_size >= offset)
570 app->offset += *size;
573 void opusenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
575 gint read_size = OPUS_PCM_INPUT_SIZE;
576 gint offset = app->length - app->offset;
579 *data = app->data + app->offset;
581 if (read_size >= offset)
586 app->offset += *size;
590 * Extract Input data for AAC decoder
591 * (case of (LC profile) ADTS format)
592 * codec_data : Don't need
594 void aacdec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
597 int offset = app->length - app->offset;
598 guint8 *pData = app->data + app->offset;
600 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
601 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
604 g_print("[FAIL] Not found aac frame sync.....\n");
608 *data = app->data + app->offset;
610 if (read_size >= offset)
615 app->offset += *size;
618 void mp3dec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
622 guint padding, bitrate, lsf = 0, layer = 0, mpg25 = 0;
623 guint hdr_bitrate = 0, sf = 0;
624 gint offset = app->length - app->offset;
625 guint8 *pData = app->data + app->offset;
627 header = GST_READ_UINT32_BE(pData);
630 g_print ("[ERROR] read header size is 0\n");
635 /* if it's not a valid sync */
636 if ((header & 0xffe00000) != 0xffe00000) {
637 g_print ("[ERROR] invalid sync\n");
642 if (((header >> 19) & 3) == 0x1) {
643 g_print ("[ERROR] invalid MPEG version: %d\n", (header >> 19) & 3);
647 if (header & (1 << 20)) {
648 lsf = (header & (1 << 19)) ? 0 : 1;
656 /* if it's an invalid layer */
657 if (!((header >> 17) & 3)) {
658 g_print("[ERROR] invalid layer: %d\n", (header >> 17) & 3);
662 layer = 4 - ((header >> 17) & 0x3);
665 /* if it's an invalid bitrate */
666 if (((header >> 12) & 0xf) == 0xf) {
667 g_print ("[ERROR] invalid bitrate: %d\n", (header >> 12) & 0xf);
671 bitrate = (header >> 12) & 0xF;
672 hdr_bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
673 /* The caller has ensured we have a valid header, so bitrate can't be zero here. */
674 if (hdr_bitrate == 0) {
680 /* if it's an invalid samplerate */
681 if (((header >> 10) & 0x3) == 0x3) {
682 g_print ("[ERROR] invalid samplerate: %d\n", (header >> 10) & 0x3);
686 sf = (header >> 10) & 0x3;
687 sf = mp3types_freqs[lsf + mpg25][sf];
690 padding = (header >> 9) & 0x1;
694 read_size = 4 * ((hdr_bitrate * 12) / sf + padding);
697 read_size = (hdr_bitrate * 144) / sf + padding;
701 read_size = (hdr_bitrate * 144) / (sf << lsf) + padding;
704 g_print("header : %d, read : %d\n", header, read_size);
707 *data = app->data + app->offset;
709 if (read_size >= offset)
714 app->offset += *size;
718 * Extract Input data for AAC encoder
721 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame)
724 int offset = app->length - app->offset;
726 read_size = ((DEFAULT_SAMPLEBYTE*DEFAULT_CHANNEL)*(DEFAULT_BIT/8));
728 if (read_size >= offset)
732 *data = app->data + app->offset;
734 if (read_size >= offset)
739 app->offset += *size;
742 int _configure(App *app, int codecid, int flag, gboolean *hardware, media_format_mimetype_e *codec_mime)
745 media_format_mimetype_e mime = 0;
746 encoder = GET_IS_ENCODER(flag) ? 1 : 0;
747 *hardware = GET_IS_HW(flag) ? 1 : 0;
748 app->is_encoder = encoder;
751 case MEDIACODEC_H264:
753 extractor = yuv_extractor;
754 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
755 *codec_mime = MEDIA_FORMAT_H264_SP;
757 extractor = h264_extractor;
758 mime = MEDIA_FORMAT_H264_SP;
761 case MEDIACODEC_MPEG4:
763 extractor = yuv_extractor;
764 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
765 *codec_mime = MEDIA_FORMAT_MPEG4_SP;
767 extractor = mpeg4_extractor;
768 mime = MEDIA_FORMAT_MPEG4_SP;
771 case MEDIACODEC_H263:
773 extractor = yuv_extractor;
774 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
775 *codec_mime = MEDIA_FORMAT_H263;
777 extractor = h263_extractor;
778 mime = MEDIA_FORMAT_H263;
783 extractor = aacenc_extractor;
784 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
785 *codec_mime = MEDIA_FORMAT_AAC;
787 extractor = aacdec_extractor;
788 mime = MEDIA_FORMAT_AAC;
791 case MEDIACODEC_AAC_HE:
793 extractor = aacenc_extractor;
794 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
795 *codec_mime = MEDIA_FORMAT_AAC_HE;
798 case MEDIACODEC_AAC_HE_PS:
801 extractor = mp3dec_extractor;
802 mime = MEDIA_FORMAT_MP3;
804 case MEDIACODEC_VORBIS:
806 case MEDIACODEC_FLAC:
808 case MEDIACODEC_WMAV1:
810 case MEDIACODEC_WMAV2:
812 case MEDIACODEC_WMAPRO:
814 case MEDIACODEC_WMALSL:
816 case MEDIACODEC_AMR_NB:
818 extractor = amrenc_extractor;
819 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
820 *codec_mime = MEDIA_FORMAT_AMR_NB;
821 app->is_amr_nb = TRUE;
823 extractor = amrdec_extractor;
824 mime = MEDIA_FORMAT_AMR_NB;
827 case MEDIACODEC_AMR_WB:
829 extractor = amrenc_extractor;
830 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
831 app->is_amr_nb = FALSE;
833 extractor = amrdec_extractor;
834 mime = MEDIA_FORMAT_AMR_WB;
837 case MEDIACODEC_OPUS:
839 extractor = opusenc_extractor;
840 mime = MEDIA_FORMAT_OPUS; /* FIXME need to check according to verdor */
841 *codec_mime = MEDIA_FORMAT_OPUS;
842 app->is_amr_nb = FALSE;
844 mime = MEDIA_FORMAT_OPUS;
845 *codec_mime = MEDIA_FORMAT_OPUS;
850 LOGE("NOT SUPPORTED!!!!");
856 void _mediacodec_process_input(App *app)
859 gboolean have_frame = FALSE;
861 static guint64 pts = 0L;
862 guint8 *buf_data_ptr = NULL;
863 media_packet_h pkt = NULL;
867 gboolean codec_config = FALSE;
869 for (i = 0; i < app->frame; i++) {
870 g_print("----------read data------------\n");
872 extractor(app, &tmp, &read, &have_frame, &codec_config);
876 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
877 g_print("media_packet_pool_aquire_packet failed\n");
881 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
882 g_print("media_packet_create_alloc failed\n");
887 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
888 g_print("media_packet_set_pts failed\n");
892 if (app->type != VIDEO_ENC) {
893 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
894 media_packet_set_buffer_size(pkt, (uint64_t)read);
895 memcpy(buf_data_ptr, tmp, read);
896 g_print("tmp:%p, read:%d\n", tmp, read);
899 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
900 media_packet_get_video_stride_width(pkt, 0, &stride_width);
902 for (j = 0; j < app->height; j++) {
903 memcpy(buf_data_ptr, tmp, app->width);
904 buf_data_ptr += stride_width;
908 if (app->hardware == TRUE) {
909 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
910 media_packet_get_video_stride_width(pkt, 1, &stride_width);
912 for (j = 0; j < app->height / 2; j++) {
913 memcpy(buf_data_ptr, tmp, app->width);
914 buf_data_ptr += stride_width;
919 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
920 media_packet_get_video_stride_width(pkt, 1, &stride_width);
922 for (j = 0; j < app->height/2; j++) {
923 memcpy(buf_data_ptr, tmp, app->width/2);
924 buf_data_ptr += stride_width;
929 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
930 media_packet_get_video_stride_width(pkt, 2, &stride_width);
932 for (j = 0; j < app->height/2; j++) {
933 memcpy(buf_data_ptr, tmp, app->width/2);
934 buf_data_ptr += stride_width;
940 mc_hex_dump("inbuf", tmp, 48);
942 ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000);
943 if (ret != MEDIACODEC_ERROR_NONE)
946 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
951 gboolean read_data(App *app)
954 gboolean have_frame = FALSE;
955 gboolean codec_config = FALSE;
957 static guint64 pts = 0L;
958 guint8 *buf_data_ptr = NULL;
959 media_packet_h pkt = NULL;
965 if (app->offset == 0) {
966 app->frame_count = 0;
967 app->start = clock();
970 g_print("----------read data------------\n");
971 extractor(app, &tmp, &read, &have_frame, &codec_config);
973 if (app->offset >= app->length - 4) {
976 app->finish = clock();
977 g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start)));
978 g_print("---------------------------\n");
981 g_print("length : %d, offset : %d\n", app->length, app->offset);
983 if (app->offset + len > app->length)
984 len = app->length - app->offset;
986 g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read);
990 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
991 g_print("media_packet_pool_aquire_packet failed\n");
995 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
996 g_print("media_packet_create_alloc failed\n");
1000 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
1001 g_print("media_packet_set_pts failed\n");
1006 if (app->type != VIDEO_ENC) {
1007 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
1008 media_packet_set_buffer_size(pkt, (uint64_t)read);
1010 memcpy(buf_data_ptr, tmp, read);
1011 g_print("tmp:%p, read:%d\n", tmp, read);
1014 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
1015 media_packet_get_video_stride_width(pkt, 0, &stride_width);
1017 for (i = 0; i < app->height; i++) {
1018 memcpy(buf_data_ptr, tmp, app->width);
1019 buf_data_ptr += stride_width;
1023 if (app->hardware == TRUE) {
1024 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1025 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1027 for (i = 0; i < app->height>>1; i++) {
1028 memcpy(buf_data_ptr, tmp, app->width);
1029 buf_data_ptr += stride_width;
1035 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1036 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1038 for (i = 0; i < app->height/2; i++) {
1039 memcpy(buf_data_ptr, tmp, app->width>>1);
1040 buf_data_ptr += stride_width;
1041 tmp += (app->width>>1);
1045 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
1046 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1048 for (i = 0; i < app->height/2; i++) {
1049 memcpy(buf_data_ptr, tmp, app->width>>1);
1050 buf_data_ptr += stride_width;
1051 tmp += (app->width>>1);
1056 mc_hex_dump("inbuf", tmp, 48);
1058 ret = mediacodec_process_input(app->mc_handle[0], pkt, 0);
1059 if (ret != MEDIACODEC_ERROR_NONE)
1062 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
1068 void av_feed_suspend(App *app)
1070 g_mutex_lock(&app->thread_mutex);
1072 g_print("suspend thread\n");
1073 g_mutex_unlock(&app->thread_mutex);
1076 void av_feed_resume(App *app)
1078 g_mutex_lock(&app->thread_mutex);
1080 g_print("resume thread\n");
1081 g_cond_broadcast(&app->thread_cond);
1082 g_mutex_unlock(&app->thread_mutex);
1085 #ifdef TIZEN_FEATURE_INTEGRATION
1086 gpointer av_feed_thread(gpointer data)
1088 App *app = (App *)data;
1092 media_packet_h packet = NULL;
1093 track = app->audio_track;
1096 g_mutex_lock(&app->thread_mutex);
1098 while (app->suspend != 0) g_cond_wait(&app->thread_cond, &app->thread_mutex);
1100 g_mutex_unlock(&app->thread_mutex);
1102 if (app->demux_eos == 1) {
1103 g_print("got eos!!!\n");
1107 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1108 if (ret != MEDIACODEC_ERROR_NONE)
1111 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1112 if (ret != MEDIACODEC_ERROR_NONE)
1122 gboolean feed_audio(App *app)
1127 media_packet_h packet = NULL;
1128 track = app->audio_track;
1130 g_print("read audio sample!!!\n");
1131 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1132 if (ret != MEDIACODEC_ERROR_NONE)
1135 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1136 if (ret != MEDIACODEC_ERROR_NONE)
1142 gboolean feed_video(App *app)
1147 media_packet_h packet = NULL;
1148 track = app->video_track;
1150 g_print("read video sample!!!\n");
1151 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1152 if (ret != MEDIACODEC_ERROR_NONE)
1155 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1156 if (ret != MEDIACODEC_ERROR_NONE)
1163 void start_feed(App *app)
1165 if (app->sourceid == 0) {
1166 app->sourceid = g_idle_add((GSourceFunc)read_data, app);
1167 g_print("start_feed\n");
1171 void stop_feed(App *app)
1173 if (app->sourceid != 0) {
1174 g_source_remove(app->sourceid);
1176 g_print("stop_feed\n");
1180 void _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
1182 App *app = (App *)user_data;
1184 g_print("_mediacodec_inbuf_used_cb!!!\n");
1186 media_packet_pool_release_packet(pkt_pool, pkt);
1188 media_packet_unref(pkt);
1195 void _audio_outbuf_available_cb(media_packet_h pkt, void *user_data)
1197 media_packet_h out_pkt = NULL;
1200 App *app = (App*)user_data;
1202 g_print("_audio_outbuf_available_cb\n");
1204 g_mutex_lock(&app->lock);
1206 ret = mediacodec_get_output(app->mc_handle[app->audio_track], &out_pkt, 0);
1208 if (ret != MEDIACODEC_ERROR_NONE)
1209 g_print("get_output failed\n");
1211 if (app->enable_dump)
1212 output_dump(app, out_pkt);
1218 g_mutex_unlock(&app->lock);
1220 media_packet_unref(out_pkt);
1227 void _video_outbuf_available_cb(media_packet_h pkt, void *user_data)
1229 media_packet_h out_pkt = NULL;
1232 App *app = (App*)user_data;
1234 g_print("_video_outbuf_available_cb\n");
1236 g_mutex_lock(&app->lock);
1238 ret = mediacodec_get_output(app->mc_handle[app->video_track], &out_pkt, 0);
1240 if (ret != MEDIACODEC_ERROR_NONE)
1241 g_print("get_output failed\n");
1243 if (app->enable_dump)
1244 decoder_output_dump(app, out_pkt);
1250 g_mutex_unlock(&app->lock);
1252 media_packet_unref(out_pkt);
1259 void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
1261 media_packet_h out_pkt = NULL;
1264 App *app = (App*)user_data;
1266 g_print("_mediacodec_outbuf_available_cb\n");
1268 g_mutex_lock(&app->lock);
1270 ret = mediacodec_get_output(app->mc_handle[0], &out_pkt, 0);
1272 if (ret != MEDIACODEC_ERROR_NONE)
1273 g_print("get_output failed\n");
1275 if (app->enable_dump) {
1276 if (app->type == VIDEO_DEC)
1277 decoder_output_dump(app, out_pkt);
1279 output_dump(app, out_pkt);
1281 #ifdef TIZEN_FEATURE_INTEGRATION
1282 if (app->enable_muxer) {
1283 if (mediamuxer_write_sample(app->muxer, app->track, out_pkt) != MEDIAMUXER_ERROR_NONE)
1284 g_print("mediamuxer_write_sample failed\n");
1285 g_print("write sample!!!\n");
1292 g_mutex_unlock(&app->lock);
1294 media_packet_unref(out_pkt);
1301 void _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
1303 g_print("_mediacodec_buffer_status_cb %d\n", status);
1305 App *app = (App*)user_data;
1307 if (status == MEDIACODEC_NEED_DATA)
1309 else if (status == MEDIACODEC_ENOUGH_DATA)
1315 void _av_buffer_status_cb(mediacodec_status_e status, void *user_data)
1317 g_print("_av_buffer_status_cb %d\n", status);
1319 App *app = (App*)user_data;
1321 if (status == MEDIACODEC_NEED_DATA)
1322 av_feed_resume(app);
1323 else if (status == MEDIACODEC_ENOUGH_DATA)
1324 av_feed_suspend(app);
1329 void _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
1335 void _mediacodec_eos_cb(void *user_data)
1337 App *app = (App *)user_data;
1339 g_print("mediacodec eos\n");
1340 g_mutex_lock(&app->eos_mutex);
1342 g_mutex_unlock(&app->eos_mutex);
1343 g_cond_broadcast(&app->dst_eos_cond);
1347 #ifdef TIZEN_FEATURE_INTEGRATION
1348 void demuxer_error_cb(mediademuxer_error_e error, void *user_data)
1350 g_print("Got Error %d from Mediademuxer\n", error);
1354 void _mediademuxer_eos_cb(int track, void *user_data)
1356 App *app = (App *)user_data;
1358 g_print("eos track : %d\n", track);
1359 av_feed_suspend(app);
1360 g_print("suspended\n");
1362 av_feed_resume(app);
1363 g_cond_broadcast(&app->eos_cond);
1368 void _mediamuxer_eos_cb(void *user_data)
1370 if (user_data == NULL) {
1371 g_print("invalid param");
1375 App *app = (App *)user_data;
1377 g_print("muxer eos\n");
1379 if (mediamuxer_stop(app->muxer) != MEDIAMUXER_ERROR_NONE)
1380 g_print(" mediamuxer_stop failed\n");
1382 if (mediamuxer_unprepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1383 g_print(" mediamuxer_unprepare failed\n");
1385 if (mediamuxer_destroy(app->muxer) != MEDIAMUXER_ERROR_NONE)
1386 g_print(" mediamuxer_destory failed\n");
1388 g_print("mediamuxer destroyed\n");
1392 gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data)
1394 g_print("codec type : %x %s\n", codec_type, codec_type_to_string(codec_type));
1398 void _mediacodec_prepare(App *app, gboolean frame_all)
1401 media_format_mimetype_e codec_mime;
1402 media_format_h codec_format;
1404 g_print("supported codec lists -internal-\n");
1405 mediacodec_foreach_supported_codec_static((mediacodec_supported_codec_cb)_foreach_cb, app);
1407 /* create instance */
1408 ret = mediacodec_create(&app->mc_handle[0]);
1409 if (ret != MEDIACODEC_ERROR_NONE) {
1410 g_print("mediacodec_create failed\n");
1415 ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag);
1416 if (ret != MEDIACODEC_ERROR_NONE) {
1417 g_print("mediacodec_set_codec failed\n");
1421 /* get mime and link to each codec parser */
1422 app->mime = _configure(app, app->codecid, app->flag, &app->hardware, &codec_mime);
1424 /* set codec info */
1425 ret = media_format_create(&fmt);
1427 switch (app->type) {
1429 media_format_set_video_mime(fmt, app->mime);
1430 media_format_set_video_width(fmt, app->width);
1431 media_format_set_video_height(fmt, app->height);
1433 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1434 if (ret != MEDIACODEC_ERROR_NONE)
1435 g_print("mediacodec_configure failed\n");
1438 media_format_set_video_mime(fmt, app->mime);
1439 media_format_set_video_width(fmt, app->width);
1440 media_format_set_video_height(fmt, app->height);
1441 media_format_set_video_avg_bps(fmt, app->target_bits);
1442 media_format_set_video_frame_rate(fmt, app->fps);
1444 media_format_create(&codec_format);
1445 media_format_set_video_mime(codec_format, codec_mime);
1446 media_format_set_video_width(codec_format, app->width);
1447 media_format_set_video_height(codec_format, app->height);
1448 media_format_set_video_avg_bps(codec_format, app->target_bits);
1449 media_format_set_video_frame_rate(codec_format, app->fps);
1451 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1452 if (ret != MEDIACODEC_ERROR_NONE)
1453 g_print("mediacodec_configure failed\n");
1454 media_format_unref(codec_format);
1457 media_format_set_audio_mime(fmt, app->mime);
1458 media_format_set_audio_channel(fmt, app->channel);
1459 media_format_set_audio_samplerate(fmt, app->samplerate);
1460 media_format_set_audio_bit(fmt, app->bit);
1462 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1463 if (ret != MEDIACODEC_ERROR_NONE)
1464 g_print("mediacodec_configure failed\n");
1467 media_format_set_audio_mime(fmt, app->mime);
1468 media_format_set_audio_channel(fmt, app->channel);
1469 media_format_set_audio_samplerate(fmt, app->samplerate);
1470 media_format_set_audio_bit(fmt, app->bit);
1471 media_format_set_audio_avg_bps(fmt, app->bitrate);
1473 media_format_create(&codec_format);
1474 media_format_set_audio_mime(codec_format, codec_mime);
1475 media_format_set_audio_channel(codec_format, app->channel);
1476 media_format_set_audio_samplerate(codec_format, app->samplerate);
1477 media_format_set_audio_bit(codec_format, app->bit);
1478 media_format_set_audio_avg_bps(codec_format, app->bitrate);
1480 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1481 if (ret != MEDIACODEC_ERROR_NONE)
1482 g_print("mediacodec_set_configure failed\n");
1483 media_format_unref(codec_format);
1486 g_print("invaild type\n");
1490 if (ret != MEDIACODEC_ERROR_NONE) {
1491 g_print("mediacodec_set_xxxc(%d)_info failed\n", app->type);
1496 g_print("supported codec lists\n");
1497 mediacodec_foreach_supported_codec(app->mc_handle[0], (mediacodec_supported_codec_cb)_foreach_cb, app);
1498 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, app);
1499 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app);
1501 mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app);
1502 mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, app);
1503 mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL);
1506 ret = mediacodec_prepare(app->mc_handle[0]);
1507 if (ret != MEDIACODEC_ERROR_NONE) {
1508 g_print("mediacodec_prepare failed\n");
1512 #ifdef TIZEN_FEATURE_INTEGRATION
1513 if (app->enable_muxer) {
1514 if (mediamuxer_create(&app->muxer) != MEDIAMUXER_ERROR_NONE)
1515 g_print("mediamuxer_create failed\n");
1517 if (mediamuxer_set_data_sink(app->muxer, "/tmp/muxtest.mp4", MEDIAMUXER_CONTAINER_FORMAT_MP4) != MEDIAMUXER_ERROR_NONE)
1518 g_print("mediamuxer_set_data_sink failed\n");
1520 media_format_create(&app->format[0]);
1521 if (app->type == AUDIO_ENC)
1522 media_format_set_audio_mime(app->format[0], codec_mime);
1523 else if (app->type == VIDEO_ENC)
1524 media_format_set_video_mime(app->format[0], codec_mime);
1526 g_print("invalid format\n");
1528 if (mediamuxer_set_eos_cb(app->muxer, _mediamuxer_eos_cb, app) != MEDIAMUXER_ERROR_NONE)
1529 g_print("mediamuxer_set_eos_cb failed\n");
1531 if (mediamuxer_add_track(app->muxer, app->format[0], &app->track) != MEDIAMUXER_ERROR_NONE)
1532 g_print("mediamuxer_add_track failed\n");
1534 if (mediamuxer_prepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1535 g_print("mediamuxer_prepare failed\n");
1537 if (mediamuxer_start(app->muxer) != MEDIAMUXER_ERROR_NONE)
1538 g_print("mediamuxer_start failed\n");
1543 /* get packet pool instance */
1544 ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool);
1545 if (ret != MEDIA_PACKET_ERROR_NONE) {
1546 g_print("mediacodec_get_packet_pool failed\n");
1549 g_print("\n\nmediacodec start\n\n");
1554 void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1556 /* release input raw packet */
1557 media_packet_unref(pkt);
1560 /* this callback is called when the input buffer for codec has done to use */
1561 void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1563 /* release input encoded packet */
1564 media_packet_unref(pkt);
1567 void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1569 App *app = (App*)user_data;
1571 mediacodec_h media_codec_handle = app->mc_handle[1];
1572 media_packet_h output_buf = NULL;
1573 mediacodec_get_output(media_codec_handle, &output_buf, 0);
1574 /* decode encoded camera preview */
1575 mediacodec_process_input(app->mc_handle[0], output_buf, 0);
1578 void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1580 App *app = (App*)user_data;
1582 mediacodec_h media_codec_handle = app->mc_handle[0];
1583 media_packet_h output_buf = NULL;
1585 mediacodec_get_output(media_codec_handle, &output_buf, 0);
1587 if (app->enable_dump)
1588 decoder_output_dump(app, output_buf);
1590 media_packet_unref(output_buf);
1593 void _media_packet_preview_cb(media_packet_h packet, void *user_data)
1595 App *app = user_data;
1596 g_mutex_lock(&app->lock);
1597 mediacodec_process_input(app->mc_handle[1], packet, 0);
1598 g_mutex_unlock(&app->lock);
1603 #ifdef TIZEN_FEATURE_INTEGRATION
1604 void _mediacodec_camera_start(App *app)
1606 int default_format = CAMERA_PIXEL_FORMAT_NV12;
1609 app->hardware = TRUE;
1611 /*create decoder instance and setup */
1612 mediacodec_create(&app->mc_handle[0]);
1613 mediacodec_set_codec(app->mc_handle[0], MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1614 mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height);
1616 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], _mediacodec_dec_input_buffer_used_cb, NULL);
1617 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], _mediacodec_dec_output_buffer_available_cb, app);
1618 mediacodec_prepare(app->mc_handle[0]);
1620 /*create encoder instance and setup */
1621 mediacodec_create(&app->mc_handle[1]);
1622 mediacodec_set_codec(app->mc_handle[1], MEDIACODEC_H264, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW);
1623 mediacodec_set_venc_info(app->mc_handle[1], app->width, app->height, 30, 1000);
1625 mediacodec_set_input_buffer_used_cb(app->mc_handle[1], _mediacodec_enc_input_buffer_used_cb, NULL);
1626 mediacodec_set_output_buffer_available_cb(app->mc_handle[1], _mediacodec_enc_output_buffer_available_cb, app);
1627 mediacodec_prepare(app->mc_handle[1]);
1629 /* create camera instance and setup and then start preview */
1630 camera_create(CAMERA_DEVICE_CAMERA0, &app->camera_handle);
1631 camera_set_media_packet_preview_cb(app->camera_handle, _media_packet_preview_cb, app);
1632 camera_get_preview_format(app->camera_handle, &default_format);
1633 camera_set_preview_format(app->camera_handle, default_format);
1634 camera_set_preview_resolution(app->camera_handle, app->width, app->height);
1635 camera_set_display(app->camera_handle, CAMERA_DISPLAY_TYPE_NONE, NULL);
1636 camera_start_preview(app->camera_handle);
1642 void _mediacodec_camera_stop(App *app)
1644 camera_state_e camera_state = CAMERA_STATE_NONE;
1646 camera_get_state(app->camera_handle, &camera_state);
1647 camera_stop_preview(app->camera_handle);
1648 camera_destroy(app->camera_handle);
1650 mediacodec_unprepare(app->mc_handle[0]);
1651 mediacodec_unprepare(app->mc_handle[1]);
1652 mediacodec_destroy(app->mc_handle[0]);
1653 mediacodec_destroy(app->mc_handle[1]);
1658 #ifdef TIZEN_FEATURE_INTEGRATION
1659 void _mediacodec_auto_test(App *app, char *path)
1662 gint num_tracks = 0;
1667 gint samplerate = 0;
1669 media_format_type_e formattype;
1670 media_format_mimetype_e video_mime;
1671 media_format_mimetype_e audio_mime;
1672 gint codec_mask = 0xFFF0;
1681 ret = mediademuxer_create(&app->demuxer);
1682 if (ret != MEDIACODEC_ERROR_NONE) {
1683 g_print("failed to create demuxer\n");
1687 ret = mediademuxer_set_data_source(app->demuxer, path);
1688 if (ret != MEDIACODEC_ERROR_NONE) {
1689 g_print("failed to mediademuxer_set_data_source\n");
1693 ret = mediademuxer_set_error_cb(app->demuxer, demuxer_error_cb, app->demuxer);
1694 if (ret != MEDIACODEC_ERROR_NONE) {
1695 g_print("failed to mediademuxer_set_error_cb\n");
1699 mediademuxer_set_eos_cb(app->demuxer, _mediademuxer_eos_cb, app);
1701 ret = mediademuxer_prepare(app->demuxer);
1702 if (ret != MEDIACODEC_ERROR_NONE) {
1703 g_print("failed to prepare\n");
1708 ret = mediademuxer_get_track_count(app->demuxer, &num_tracks);
1709 if (ret != MEDIACODEC_ERROR_NONE) {
1710 g_print("failed to get track\n");
1714 for (track = 0; track < num_tracks; track++) {
1715 ret = mediademuxer_get_track_info(app->demuxer, track, &app->format[track]);
1716 if (ret != MEDIACODEC_ERROR_NONE) {
1717 g_print("failed to get track info\n");
1721 media_format_get_type(app->format[track], &formattype);
1723 if (!app->is_video && formattype == MEDIA_FORMAT_AUDIO) {
1724 app->audio_track = track;
1725 app->type = AUDIO_DEC;
1726 media_format_get_audio_info(app->format[track], &audio_mime, &channel, &samplerate, &bit, NULL);
1728 mediademuxer_select_track(app->demuxer, track);
1730 ret = mediacodec_create(&app->mc_handle[track]);
1731 if (ret != MEDIACODEC_ERROR_NONE) {
1732 g_print("failed to create mediacocec\n");
1736 codec_id = audio_mime & codec_mask;
1737 g_print("auido codec_id : %x\n", codec_id);
1739 ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW);
1740 if (ret != MEDIACODEC_ERROR_NONE) {
1741 g_print("failed to set codec\n");
1745 ret = mediacodec_set_adec_info(app->mc_handle[track], samplerate, channel, bit);
1746 if (ret != MEDIACODEC_ERROR_NONE) {
1747 g_print("failed to set adec info\n");
1751 mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1752 mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1753 mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _audio_outbuf_available_cb, app);
1754 mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1755 mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1757 } else if (app->is_video && formattype == MEDIA_FORMAT_VIDEO) {
1758 app->video_track = track;
1759 app->type = VIDEO_DEC;
1760 media_format_get_video_info(app->format[track], &video_mime, &width, &height, NULL, NULL);
1762 mediademuxer_select_track(app->demuxer, track);
1764 ret = mediacodec_create(&app->mc_handle[track]);
1765 if (ret != MEDIACODEC_ERROR_NONE) {
1766 g_print("failed to create mediacocec\n");
1771 app->height = height;
1773 codec_id = video_mime & codec_mask;
1774 g_print("video codec_id : %x\n", codec_id);
1776 ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1777 if (ret != MEDIACODEC_ERROR_NONE) {
1778 g_print("failed to set codec\n");
1782 ret = mediacodec_set_vdec_info(app->mc_handle[track], width, height);
1783 if (ret != MEDIACODEC_ERROR_NONE) {
1784 g_print("failed to set vdec info\n");
1788 mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1789 mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1790 mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _video_outbuf_available_cb, app);
1791 mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1792 mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1796 ret = mediademuxer_start(app->demuxer);
1797 if (ret != MEDIACODEC_ERROR_NONE) {
1798 g_print("failed to start mediademuxer\n");
1802 track = app->is_video ? app->video_track : app->audio_track;
1803 ret = mediacodec_prepare(app->mc_handle[track]);
1804 if (ret != MEDIACODEC_ERROR_NONE) {
1805 g_print("failed to prepare mediacodec\n");
1809 g_cond_init(&app->thread_cond);
1810 g_cond_init(&app->eos_cond);
1811 g_cond_init(&app->dst_eos_cond);
1812 g_mutex_init(&app->thread_mutex);
1813 g_mutex_init(&app->eos_mutex);
1815 app->thread = g_thread_new("feed thread", &av_feed_thread, app);
1816 app->start = clock();
1818 g_mutex_lock(&app->eos_mutex);
1819 while (app->codec_eos != 1) g_cond_wait(&app->dst_eos_cond, &app->eos_mutex);
1820 g_mutex_unlock(&app->eos_mutex);
1821 g_print("now try to destroy thread!!\n");
1822 g_thread_join(app->thread);
1823 app->finish = clock();
1825 ret = mediademuxer_stop(app->demuxer);
1826 if (ret != MEDIACODEC_ERROR_NONE) {
1827 g_print("failed to stop mediademuxer\n");
1831 ret = mediademuxer_unselect_track(app->demuxer, track);
1832 if (ret != MEDIACODEC_ERROR_NONE) {
1833 g_print("failed to unselect mediademuxer\n");
1837 ret = mediacodec_unprepare(app->mc_handle[track]);
1838 if (ret != MEDIACODEC_ERROR_NONE) {
1839 g_print("failed to unprepare mediacodec\n");
1843 ret = mediacodec_destroy(app->mc_handle[track]);
1844 if (ret != MEDIACODEC_ERROR_NONE) {
1845 g_print("failed to destroy mediacodec\n");
1849 ret = mediademuxer_unprepare(app->demuxer);
1850 if (ret != MEDIACODEC_ERROR_NONE) {
1851 g_print("failed to unprepare mediademuxer\n");
1855 ret = mediademuxer_destroy(app->demuxer);
1856 if (ret != MEDIACODEC_ERROR_NONE) {
1857 g_print("failed to destroy mediademuxer\n");
1861 g_cond_clear(&app->thread_cond);
1862 g_cond_clear(&app->eos_cond);
1863 g_cond_clear(&app->dst_eos_cond);
1864 g_mutex_clear(&app->thread_mutex);
1865 g_mutex_clear(&app->eos_mutex);
1867 g_print("resources are released!!!\n\n\n");
1868 g_print("-----------------------------------------------------\n");
1869 g_print("Input - queued packets : %d, finalized packets : %d\n", app->etb, app->ebd);
1870 g_print("Output - queued packets : %d, finalized packets : %d\n", app->fbd, app->fbd);
1871 g_print("Average FPS = %3.3f\n", ((double)app->fbd*1000000/(app->finish - app->start)));
1872 g_print("-----------------------------------------------------\n");
1878 void _mediacodec_unprepare(App *app)
1880 mediacodec_unprepare(app->mc_handle[0]);
1883 void _mediacodec_destroy(App *app)
1886 g_print("invalid param");
1890 if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1892 g_print("media_packet_pool_deallocatet failed\n");
1896 if (media_packet_pool_destroy(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1898 g_print(" media_packet_pool_destroy failed\n");
1901 g_print("media packet pool destroyed! \n");
1903 mediacodec_destroy(app->mc_handle[0]);
1904 #ifdef TIZEN_FEATURE_INTEGRATION
1905 if (app->enable_muxer) {
1906 if (mediamuxer_close_track(app->muxer, app->track) != MEDIAMUXER_ERROR_NONE)
1907 g_print("mediamuxer_close_track failed\n");
1912 void input_filepath(char *filename, App *app)
1914 GError *error = NULL;
1917 app->file = g_mapped_file_new(filename, FALSE, &error);
1919 g_print("failed to open file : %s\n", error->message);
1920 g_error_free(error);
1924 app->length = g_mapped_file_get_length(app->file);
1925 app->data = (guint8 *)g_mapped_file_get_contents(app->file);
1927 g_print("len : %d, offset : %d, obj : %d", app->length, app->offset, app->obj);
1932 void quit_program(App *app)
1934 g_mutex_clear(&app->lock);
1935 media_format_unref(fmt);
1936 g_main_loop_quit(app->loop);
1940 void reset_menu_state()
1942 g_menu_state = CURRENT_STATUS_MAINMENU;
1946 void _interpret_main_menu(char *cmd, App *app)
1948 gint len = strlen(cmd);
1950 if (strncmp(cmd, "a", 1) == 0)
1951 g_menu_state = CURRENT_STATUS_FILENAME;
1952 else if (strncmp(cmd, "o", 1) == 0)
1953 g_menu_state = CURRENT_STATUS_GET_OUTPUT;
1954 else if (strncmp(cmd, "q", 1) == 0)
1957 g_print("unknown menu \n");
1958 } else if (len == 2) {
1959 if (strncmp(cmd, "pr", 2) == 0)
1960 _mediacodec_prepare(app, 0);
1961 else if (strncmp(cmd, "pa", 2) == 0)
1962 _mediacodec_prepare(app, 1);
1963 else if (strncmp(cmd, "sc", 2) == 0)
1964 g_menu_state = CURRENT_STATUS_SET_CODEC;
1965 else if (strncmp(cmd, "vd", 2) == 0)
1966 g_menu_state = CURRENT_STATUS_SET_VDEC_INFO;
1967 else if (strncmp(cmd, "ve", 2) == 0)
1968 g_menu_state = CURRENT_STATUS_SET_VENC_INFO;
1969 else if (strncmp(cmd, "ad", 2) == 0)
1970 g_menu_state = CURRENT_STATUS_SET_ADEC_INFO;
1971 else if (strncmp(cmd, "ae", 2) == 0)
1972 g_menu_state = CURRENT_STATUS_SET_AENC_INFO;
1973 else if (strncmp(cmd, "pi", 2) == 0)
1974 g_menu_state = CURRENT_STATUS_PROCESS_INPUT;
1975 else if (strncmp(cmd, "un", 2) == 0)
1976 _mediacodec_unprepare(app);
1977 else if (strncmp(cmd, "dt", 2) == 0)
1978 _mediacodec_destroy(app);
1979 #ifdef TIZEN_FEATURE_INTEGRATION
1980 else if (strncmp(cmd, "cr", 2) == 0)
1981 _mediacodec_camera_start(app);
1982 else if (strncmp(cmd, "ct", 2) == 0)
1983 _mediacodec_camera_stop(app);
1984 else if (strncmp(cmd, "au", 2) == 0)
1985 g_menu_state = CURRENT_STATUS_AUTO_TEST;
1986 else if (strncmp(cmd, "mp", 2) == 0) {
1987 if (!app->enable_muxer) {
1988 app->enable_muxer = TRUE;
1989 g_print("muxer enabled\n");
1991 app->enable_dump = FALSE;
1992 g_print("dump disabled\n");
1996 else if (strncmp(cmd, "dp", 2) == 0) {
1997 if (!app->enable_dump) {
1998 app->enable_dump = TRUE;
1999 g_print("dump enabled\n");
2001 app->enable_dump = FALSE;
2002 g_print("dump disabled\n");
2005 display_sub_basic();
2007 g_print("unknown menu \n");
2013 void displaymenu(void)
2015 if (g_menu_state == CURRENT_STATUS_MAINMENU) {
2016 display_sub_basic();
2017 } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
2018 g_print("*** input mediapath.\n");
2019 } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) {
2020 g_print("*** Codec id : Select Codec ID Numbe (e.g. AAC_LC = 96)\n");
2021 g_print(" L16 = 0\n");
2022 g_print(" ALAW = 1\n");
2023 g_print(" ULAW = 2\n");
2024 g_print(" AMR_NB = 3\n");
2025 g_print(" AMR_WB = 4\n");
2026 g_print(" G729 = 5\n");
2027 g_print(" AAC_LC = 6\n");
2028 g_print(" AAC_HE = 7\n");
2029 g_print(" AAC_PS = 8\n");
2030 g_print(" MP3 = 9\n");
2031 g_print(" VORBIS = 10\n");
2032 g_print(" FLAC = 11\n");
2033 g_print(" WMAV1 = 12\n");
2034 g_print(" WMAV2 = 13\n");
2035 g_print(" WMAPRO = 14\n");
2036 g_print(" WMALSL = 15\n");
2037 g_print(" OPUS = 16\n");
2038 g_print(" -------------------\n");
2039 g_print(" H261 = 17\n");
2040 g_print(" H263 = 18\n");
2041 g_print(" H264 = 19\n");
2042 g_print(" MJPEG = 20\n");
2043 g_print(" MPEG1 = 21\n");
2044 g_print(" MPEG2 = 22\n");
2045 g_print(" MPEG4 = 23\n");
2046 g_print(" HEVC = 24\n");
2047 g_print(" VP8 = 25\n");
2048 g_print(" VP9 = 26\n");
2049 g_print(" -------------------\n");
2050 g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
2051 g_print(" CODEC : ENCODER = 1 DECODER = 2\n");
2052 g_print(" TYPE : HW = 4 SW = 8\n");
2053 g_print("*** input codec id, falgs.\n");
2054 } else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO) {
2055 g_print("*** input video decode configure.(width, height)\n");
2056 } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
2057 g_print("*** input video encode configure.(width, height, fps, target_bits)\n");
2058 } else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO) {
2059 g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000, 2, 16))\n");
2060 } else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO) {
2061 g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000, 2, 16, 128000))\n");
2062 } else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT) {
2063 g_print("*** input dec process number\n");
2064 } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
2065 g_print("*** input get output buffer number\n");
2066 #ifdef TIZEN_FEATURE_INTEGRATION
2067 } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) {
2068 g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n");
2071 g_print("*** unknown status.\n");
2076 gboolean timeout_menu_display(void* data)
2082 void interpret(char *cmd)
2086 static gint cnt = 0;
2088 switch (g_menu_state) {
2089 case CURRENT_STATUS_MAINMENU:
2090 _interpret_main_menu(cmd, app);
2092 case CURRENT_STATUS_FILENAME:
2093 input_filepath(cmd, app);
2096 case CURRENT_STATUS_SET_CODEC:
2098 gint ids[] = { 0x1010, 0x1020, 0x1030, 0x1040, 0x1041,
2099 0x1050, 0x1060, 0x1061, 0x1062, 0x1070,
2100 0x1080, 0x1090, 0x10A0, 0x10A1, 0x10A2,
2101 0x10A3, 0x10D0, 0x2010, 0x2020, 0x2030,
2102 0x2040, 0x2050, 0x2060, 0x2070, 0x2080,
2103 0x2090, 0x20A0, 0x20B0 };
2106 gint n_sizes = G_N_ELEMENTS(ids);
2109 if (tmp < 0 || tmp >= n_sizes - 1) {
2111 g_print("Invalid value\n");
2115 app->codecid = ids[tmp];
2117 } else if (cnt == 1) {
2118 app->flag = atoi(cmd);
2124 case CURRENT_STATUS_SET_VDEC_INFO:
2127 app->width = atoi(cmd);
2129 } else if (cnt == 1) {
2130 app->height = atoi(cmd);
2131 app->type = VIDEO_DEC;
2138 case CURRENT_STATUS_SET_VENC_INFO:
2141 app->width = atol(cmd);
2143 } else if (cnt == 1) {
2144 app->height = atol(cmd);
2146 } else if (cnt == 2) {
2147 app->fps = atol(cmd);
2149 } else if (cnt == 3) {
2150 app->target_bits = atol(cmd);
2151 app->type = VIDEO_ENC;
2158 case CURRENT_STATUS_SET_ADEC_INFO:
2161 app->samplerate = atoi(cmd);
2163 } else if (cnt == 1) {
2164 app->channel = atoi(cmd);
2166 } else if (cnt == 2) {
2167 app->bit = atoi(cmd);
2168 app->type = AUDIO_DEC;
2175 case CURRENT_STATUS_SET_AENC_INFO:
2180 if (tmp <= 0 || tmp > 96000) {
2181 g_print("Invalid value\n");
2185 app->samplerate = tmp;
2187 } else if (cnt == 1) {
2190 if (tmp <= 0 || tmp > 6) {
2191 g_print("Invalid value\n");
2197 } else if (cnt == 2) {
2200 if (tmp <= 0 || tmp > 32) {
2201 g_print("Invalid value\n");
2207 } else if (cnt == 3) {
2210 if (tmp <= 0 || tmp >= INT_MAX) {
2211 g_print(";;Invalid value\n");
2215 app->type = AUDIO_ENC;
2223 case CURRENT_STATUS_PROCESS_INPUT:
2227 if (tmp <= 0 || tmp >= 10) {
2228 g_print("Invalid value\n");
2234 _mediacodec_process_input(app);
2238 case CURRENT_STATUS_GET_OUTPUT:
2243 #ifdef TIZEN_FEATURE_INTEGRATION
2244 case CURRENT_STATUS_AUTO_TEST:
2249 strncpy(app->filepath, cmd, sizeof(app->filepath) - 1);
2250 g_print("%s, %d\n", app->filepath, len);
2252 } else if (cnt == 1) {
2253 app->is_video = atoi(cmd) ? 1 : 0;
2254 _mediacodec_auto_test(app, app->filepath);
2263 g_timeout_add(100, timeout_menu_display, 0);
2266 void display_sub_basic()
2269 g_print("=========================================================================================\n");
2270 g_print(" media codec test\n");
2271 g_print("-----------------------------------------------------------------------------------------\n");
2272 g_print("a. Create \t\t");
2273 g_print("sc. Set codec \n");
2274 g_print("vd. Set vdec info \t");
2275 g_print("ve. Set venc info \n");
2276 g_print("ad. Set adec info \t");
2277 g_print("ae. Set aenc info \n");
2278 g_print("pr. Prepare \t");
2279 g_print("pa. Prepare and process all\t\t");
2280 g_print("pi. process input with num\n");
2281 g_print("o. Get output \t\t");
2282 g_print("rb. Reset output buffer \n");
2283 g_print("un. Unprepare \t\t");
2284 g_print("dt. Destroy \t\t");
2285 g_print("q. quit test suite \n");
2286 g_print("dp. enable dump \n");
2287 #ifdef TIZEN_FEATURE_INTEGRATION
2288 g_print("mp. enable muxer \n");
2289 g_print("-----------------------------------------------------------------------------------------\n");
2290 g_print("cr. camera preview -> encoder -> decoder\n");
2291 g_print("au. integration test with mediademuxer\n");
2292 g_print("ct. quit camera test\n");
2295 g_print("=========================================================================================\n");
2298 gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
2300 gchar buf[MAX_STRING_LEN];
2302 GError *error = NULL;
2304 g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
2312 void mc_hex_dump(char *desc, void *addr, gint len)
2316 guint8 *pc = (guint8 *)addr;
2319 g_print("%s:\n", desc);
2321 for (i = 0; i < len; i++) {
2323 if ((i % 16) == 0) {
2325 g_print(" %s\n", buff);
2327 g_print(" %04x ", i);
2330 g_print(" %02x", pc[i]);
2332 if ((pc[i] < 0x20) || (pc[i] > 0x7e))
2335 buff[i % 16] = pc[i];
2336 buff[(i % 16) + 1] = '\0';
2339 while ((i % 16) != 0) {
2343 g_print(" %s\n", buff);
2346 void decoder_output_dump(App *app, media_packet_h pkt)
2350 int stride_width, stride_height;
2351 gchar filename[256] = {0, };
2355 g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height);
2356 fp = fopen(filename, "ab");
2358 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&temp);
2359 media_packet_get_video_stride_width(pkt, 0, &stride_width);
2360 media_packet_get_video_stride_height(pkt, 0, &stride_height);
2361 g_print("stride : %d, %d\n", stride_width, stride_height);
2363 for (i = 0; i < app->height; i++) {
2364 ret = fwrite(temp, app->width, 1, fp);
2365 temp += stride_width;
2368 if (app->hardware == TRUE) {
2369 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2370 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2371 for (i = 0; i < app->height/2; i++) {
2372 ret = fwrite(temp, app->width, 1, fp);
2373 temp += stride_width;
2376 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2377 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2378 for (i = 0; i < app->height/2; i++) {
2379 ret = fwrite(temp, app->width/2, 1, fp);
2380 temp += stride_width;
2383 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&temp);
2384 media_packet_get_video_stride_width(pkt, 2, &stride_width);
2385 for (i = 0; i < app->height/2; i++) {
2386 ret = fwrite(temp, app->width/2, 1, fp);
2387 temp += stride_width;
2391 g_print("codec dec output dumped!!%d\n", ret);
2397 * Add ADTS header at the beginning of each and every AAC packet.
2398 * This is needed as MediaCodec encoder generates a packet of raw AAC data.
2399 * Note the packetLen must count in the ADTS header itself.
2401 void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen)
2403 int profile = 2; /* AAC LC (0x01) */
2404 int freqIdx = 3; /* 48KHz (0x03) */
2405 int chanCfg = 2; /* CPE (0x02) */
2407 if (app->samplerate == 96000) freqIdx = 0;
2408 else if (app->samplerate == 88200) freqIdx = 1;
2409 else if (app->samplerate == 64000) freqIdx = 2;
2410 else if (app->samplerate == 48000) freqIdx = 3;
2411 else if (app->samplerate == 44100) freqIdx = 4;
2412 else if (app->samplerate == 32000) freqIdx = 5;
2413 else if (app->samplerate == 24000) freqIdx = 6;
2414 else if (app->samplerate == 22050) freqIdx = 7;
2415 else if (app->samplerate == 16000) freqIdx = 8;
2416 else if (app->samplerate == 12000) freqIdx = 9;
2417 else if (app->samplerate == 11025) freqIdx = 10;
2418 else if (app->samplerate == 8000) freqIdx = 11;
2420 if ((app->channel == 1) || (app->channel == 2))
2421 chanCfg = app->channel;
2423 /* fill in ADTS data */
2424 buffer[0] = (char)0xFF;
2425 buffer[1] = (char)0xF1;
2426 buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
2427 buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11));
2428 buffer[4] = (char)((packetLen&0x7FF) >> 3);
2429 buffer[5] = (char)(((packetLen&7)<<5) + 0x1F);
2430 buffer[6] = (char)0xFC;
2433 void output_dump(App *app, media_packet_h pkt)
2437 gchar filename[256] = {0, };
2440 char adts[100] = {0, };
2442 g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d.out", app->type);
2443 fp = fopen(filename, "ab");
2445 g_print("open[%s] failed[errno:%d]\n", filename, errno);
2449 media_packet_get_buffer_data_ptr(pkt, &temp);
2450 media_packet_get_buffer_size(pkt, &buf_size);
2451 g_print("output data : %p, size %d\n", temp, (int)buf_size);
2453 if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) {
2454 add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE));
2455 fwrite(&adts, 1, ADTS_HEADER_SIZE, fp);
2456 g_print("adts appended\n");
2457 } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) {
2458 /* This is used only AMR encoder case for adding AMR masic header in only first frame */
2459 g_print("%s - AMR_header write in first frame\n", __func__);
2460 fwrite(&AMR_header[0], 1, sizeof(AMR_header) - 1, fp); /* AMR-NB magic number */
2461 write_amr_header = 0;
2464 fwrite(temp, (int)buf_size, 1, fp);
2466 g_print("codec dec output dumped!!%d\n", ret);
2471 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id)
2473 guint media_codec_id_u = (guint)media_codec_id;
2475 switch (media_codec_id_u) {
2476 case MEDIACODEC_L16:
2478 case MEDIACODEC_ALAW:
2480 case MEDIACODEC_ULAW:
2482 case MEDIACODEC_AMR_NB:
2484 case MEDIACODEC_AMR_WB:
2486 case MEDIACODEC_G729:
2488 case MEDIACODEC_AAC_LC:
2490 case MEDIACODEC_AAC_HE:
2492 case MEDIACODEC_AAC_HE_PS:
2494 case MEDIACODEC_MP3:
2496 case MEDIACODEC_VORBIS:
2498 case MEDIACODEC_FLAC:
2500 case MEDIACODEC_WMAV1:
2502 case MEDIACODEC_WMAV2:
2504 case MEDIACODEC_WMAPRO:
2506 case MEDIACODEC_WMALSL:
2508 case MEDIACODEC_H261:
2510 case MEDIACODEC_H263:
2512 case MEDIACODEC_H264:
2514 case MEDIACODEC_MJPEG:
2516 case MEDIACODEC_MPEG1:
2518 case MEDIACODEC_MPEG2:
2520 case MEDIACODEC_MPEG4:
2522 case MEDIACODEC_HEVC:
2524 case MEDIACODEC_VP8:
2526 case MEDIACODEC_VP9:
2528 case MEDIACODEC_VC1:
2530 case MEDIACODEC_OPUS:
2537 int main(int argc, char *argv[])
2539 GIOChannel *stdin_channel;
2540 stdin_channel = g_io_channel_unix_new(0);
2541 g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
2542 g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
2546 g_mutex_init(&app->lock);
2548 app->loop = g_main_loop_new(NULL, TRUE);
2549 app->timer = g_timer_new();
2550 g_main_loop_run(app->loop);