1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
| static int mediacodec_encode_header(AMediaCodec* codec, AMediaFormat* format); static int mediacodec_encode_receive_packet(AMediaCodec* codec); static void mediacodec_encode_send_frame(AMediaCodec* codec);
void TestRun() { AMediaCodec* codec = NULL; AMediaFormat* format = NULL;
do { const char* mime = "video/avc"; codec = AMediaCodec_createEncoderByType(mime); if (!codec) { break; }
format = AMediaFormat_new(); if (!format) { break; }
AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "video/avc"); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, 720); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, 1280); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, 21);//19 yuv420p 21 nv12 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);//FIXME AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, 2000000); AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, 25); AMediaFormat_setInt32(format, "bitrate-mode", 1);
LOGI("%s %d format: %s", __FUNCTION__, __LINE__, AMediaFormat_toString(format));
mediacodec_encode_header(codec, format);
media_status_t status = AMEDIA_OK; if ((status = AMediaCodec_configure(codec, format, NULL, 0, AMEDIACODEC_CONFIGURE_FLAG_ENCODE)) != AMEDIA_OK) { LOGI("%s %d status: %d", __FUNCTION__, __LINE__, status); break; }
status = AMediaCodec_start(codec); if (status != AMEDIA_OK) { LOGI("%s %d status: %d", __FUNCTION__, __LINE__, status); break; }
int cnt = 10; while (cnt -- ) { mediacodec_encode_send_frame(codec); mediacodec_encode_receive_packet(codec); usleep(10000); }
LOGI("%s %d", __FUNCTION__, __LINE__);
} while (false);
if (format) { AMediaFormat_delete(format); }
if (codec) { AMediaCodec_stop(codec); AMediaCodec_delete(codec); } }
static void mediacodec_encode_send_frame(AMediaCodec* codec) { ssize_t bufferIndex = AMediaCodec_dequeueInputBuffer(codec, TIMEOUT_USEC); if (bufferIndex < 0) { LOGE("%s %d No input buffers available (%d)", __FUNCTION__, __LINE__, bufferIndex); return; }
size_t bufferSize = 0; uint8_t* buffer = AMediaCodec_getInputBuffer(codec, bufferIndex, &bufferSize); if (!buffer) { LOGE("%s %d AMediaCodec_getInputBuffer failed idx: %d !", __FUNCTION__, __LINE__, bufferIndex); return; }
static uint64_t stamp = 0; media_status_t status = AMediaCodec_queueInputBuffer(codec, bufferIndex, 0, bufferSize, stamp, 0); stamp += 30000;
LOGI("%s %d buffInfo (idx: %u size: %u)", __FUNCTION__, __LINE__, bufferIndex, bufferSize); }
static int mediacodec_encode_receive_packet(AMediaCodec* codec) { int try_times = 5; while (try_times --) { int buff_idx = -1;
do { AMediaCodecBufferInfo bufferInfo; buff_idx = AMediaCodec_dequeueOutputBuffer(codec, &bufferInfo, TIMEOUT_USEC); if (buff_idx < 0) { if (buff_idx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) { //AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED = -3, // AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED = -2, LOGE("%s %d AMediaCodec_dequeueOutputBuffer idx: %d", __FUNCTION__, __LINE__, buff_idx); } break; }
if (bufferInfo.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { LOGE("%s %d Got EOS at output", __FUNCTION__, __LINE__); break; }
size_t buff_size = 0; uint8_t *buffer = AMediaCodec_getOutputBuffer(codec, buff_idx, &buff_size); if (!buffer) { LOGE("%s %d AMediaCodec_getOutputBuffer failed, flags: %d status: %d size: %u", __FUNCTION__, __LINE__, bufferInfo.flags, buff_idx, buff_size); break; }
bool config_frame = bufferInfo.flags & LOCAL_BUFFER_FLAG_CODECCONFIG ? true : false; bool key_frame = bufferInfo.flags & LOCAL_BUFFER_FLAG_SYNCFRAME ? true : false;
LOGI("%s %d AMediaCodec OutputBuffer idx: %d outsize: %u flags: %d offset: %d size: %d pts: %lld nalu: [%x %x %x %x %x %x]", __FUNCTION__, __LINE__, buff_idx, buff_size, bufferInfo.flags, bufferInfo.offset, bufferInfo.size, bufferInfo.presentationTimeUs, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); } while (false);
if (buff_idx >= 0) { AMediaCodec_releaseOutputBuffer(codec, buff_idx, false); } } return 0; }
int mediacodec_encode_header(AMediaCodec* codec, AMediaFormat* format) { int ret = -1; do { media_status_t status = AMEDIA_OK; if ((status = AMediaCodec_configure(codec, format, NULL, 0, AMEDIACODEC_CONFIGURE_FLAG_ENCODE)) != AMEDIA_OK) { LOGI("%s %d status: %d", __FUNCTION__, __LINE__, status); break; }
status = AMediaCodec_start(codec); if (status != AMEDIA_OK) { LOGI("%s %d status: %d", __FUNCTION__, __LINE__, status); break; }
LOGI("%s %d", __FUNCTION__, __LINE__); mediacodec_encode_send_frame(codec); mediacodec_encode_receive_packet(codec); LOGI("%s %d", __FUNCTION__, __LINE__); ret = 0; } while (false);
LOGI("%s %d", __FUNCTION__, __LINE__); // AMediaCodec_flush(codec); AMediaCodec_stop(codec); LOGI("%s %d", __FUNCTION__, __LINE__); return -1; }
|