diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp index b230df51790b4e1e96d948dd2f50e3a41dcc8a33..240848096acd7be6cab524163b8323c2bcfc703d 100644 --- a/media/ndk/NdkMediaCodec.cpp +++ b/media/ndk/NdkMediaCodec.cpp @@ -672,7 +672,13 @@ uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_ if (out_size != NULL) { *out_size = abuf->capacity(); } - return abuf->data(); + + // When an input buffer is provided to the application, it is essentially + // empty. Ignore its offset as we will set it upon queueInputBuffer. + // This actually works as expected as we do not provide visibility of + // a potential internal offset to the client, so it is equivalent to + // setting the offset to 0 prior to returning the buffer to the client. + return abuf->base(); } android::Vector > abufs; @@ -689,7 +695,7 @@ uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_ if (out_size != NULL) { *out_size = abufs[idx]->capacity(); } - return abufs[idx]->data(); + return abufs[idx]->base(); } ALOGE("couldn't get input buffers"); return NULL; @@ -704,8 +710,12 @@ uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *mData, size_t idx, size_t *out return NULL; } + // Note that we do not provide visibility of the internal offset to the + // client, but it also does not make sense to provide visibility of the + // buffer capacity vs the actual size. + if (out_size != NULL) { - *out_size = abuf->capacity(); + *out_size = abuf->size(); } return abuf->data(); } @@ -718,7 +728,7 @@ uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *mData, size_t idx, size_t *out return NULL; } if (out_size != NULL) { - *out_size = abufs[idx]->capacity(); + *out_size = abufs[idx]->size(); } return abufs[idx]->data(); } @@ -748,7 +758,8 @@ ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec *mData, requestActivityNotification(mData); switch (ret) { case OK: - info->offset = offset; + // the output buffer address is already offset in AMediaCodec_getOutputBuffer() + info->offset = 0; info->size = size; info->flags = flags; info->presentationTimeUs = presentationTimeUs; diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h index 598beb709d0ea7848160e37b2fb3d7355a312d23..223d2f890bfdac89d60894b7214384115c19c81d 100644 --- a/media/ndk/include/media/NdkMediaCodec.h +++ b/media/ndk/include/media/NdkMediaCodec.h @@ -251,6 +251,11 @@ uint8_t* AMediaCodec_getInputBuffer(AMediaCodec*, size_t idx, size_t *out_size) * dequeueOutputBuffer, and not yet queued. * * Available since API level 21. + *

+ * At or before API level 35, the out_size returned was invalid, and instead the + * size returned in the AMediaCodecBufferInfo struct from + * AMediaCodec_dequeueOutputBuffer() should be used. After API + * level 35, this API returns the correct output buffer size as well. */ uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec*, size_t idx, size_t *out_size) __INTRODUCED_IN(21); @@ -309,9 +314,16 @@ media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*, size_t idx, #undef _off_t_compat /** - * Get the index of the next available buffer of processed data. + * Get the index of the next available buffer of processed data along with the + * metadata associated with it. * * Available since API level 21. + *

+ * At or before API level 35, the offset in the AMediaCodecBufferInfo struct + * was invalid and should be ignored; however, at the same time + * the buffer size could only be obtained from this struct. After API + * level 35, the offset returned in the struct is always set to 0, and the + * buffer size can also be obtained from the AMediaCodec_getOutputBuffer() call. */ ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info, int64_t timeoutUs) __INTRODUCED_IN(21); @@ -468,7 +480,6 @@ void AMediaCodec_releaseName(AMediaCodec*, char* name) __INTRODUCED_IN(28); /** * Set an asynchronous callback for actionable AMediaCodec events. * When asynchronous callback is enabled, it is an error for the client to call - * AMediaCodec_getInputBuffers(), AMediaCodec_getOutputBuffers(), * AMediaCodec_dequeueInputBuffer() or AMediaCodec_dequeueOutputBuffer(). * * AMediaCodec_flush() behaves differently in asynchronous mode.