| 87 | } |
| 88 | |
| 89 | void doCodecWork(workerdata* d) { |
| 90 | ssize_t bufidx = -1; |
| 91 | if (!d->sawInputEOS) { |
| 92 | bufidx = AMediaCodec_dequeueInputBuffer(d->codec, 2000); |
| 93 | LOGV("input buffer %zd", bufidx); |
| 94 | if (bufidx >= 0) { |
| 95 | size_t bufsize; |
| 96 | auto buf = AMediaCodec_getInputBuffer(d->codec, bufidx, &bufsize); |
| 97 | auto sampleSize = AMediaExtractor_readSampleData(d->ex, buf, bufsize); |
| 98 | if (sampleSize < 0) { |
| 99 | sampleSize = 0; |
| 100 | d->sawInputEOS = true; |
| 101 | LOGV("EOS"); |
| 102 | } |
| 103 | auto presentationTimeUs = AMediaExtractor_getSampleTime(d->ex); |
| 104 | |
| 105 | AMediaCodec_queueInputBuffer( |
| 106 | d->codec, bufidx, 0, sampleSize, presentationTimeUs, |
| 107 | d->sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); |
| 108 | AMediaExtractor_advance(d->ex); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | if (!d->sawOutputEOS) { |
| 113 | AMediaCodecBufferInfo info; |
| 114 | auto status = AMediaCodec_dequeueOutputBuffer(d->codec, &info, 0); |
| 115 | if (status >= 0) { |
| 116 | if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { |
| 117 | LOGV("output EOS"); |
| 118 | d->sawOutputEOS = true; |
| 119 | } |
| 120 | int64_t presentationNano = info.presentationTimeUs * 1000; |
| 121 | if (d->renderstart < 0) { |
| 122 | d->renderstart = systemnanotime() - presentationNano; |
| 123 | } |
| 124 | int64_t delay = (d->renderstart + presentationNano) - systemnanotime(); |
| 125 | if (delay > 0) { |
| 126 | usleep(delay / 1000); |
| 127 | } |
| 128 | AMediaCodec_releaseOutputBuffer(d->codec, status, info.size != 0); |
| 129 | if (d->renderonce) { |
| 130 | d->renderonce = false; |
| 131 | return; |
| 132 | } |
| 133 | } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { |
| 134 | LOGV("output buffers changed"); |
| 135 | } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { |
| 136 | auto format = AMediaCodec_getOutputFormat(d->codec); |
| 137 | LOGV("format changed to: %s", AMediaFormat_toString(format)); |
| 138 | AMediaFormat_delete(format); |
| 139 | } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { |
| 140 | LOGV("no output buffer right now"); |
| 141 | } else { |
| 142 | LOGV("unexpected info code: %zd", status); |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | if (!d->sawInputEOS || !d->sawOutputEOS) { |
no test coverage detected