Commit 91897ff5 authored by Adrien Béraud's avatar Adrien Béraud

android: support accelerated video rotation

Change-Id: Id19a9987a218ef94915e94df9635c11986d8a34e
parent dda1f61d
......@@ -149,7 +149,7 @@ int AndroidFormatToAVFormat(int androidformat) {
}
}
JNIEXPORT void JNICALL Java_cx_ring_daemon_RingserviceJNI_captureVideoPacket(JNIEnv *jenv, jclass jcls, jobject buffer, jint size, jint offset, jboolean keyframe, jlong timestamp)
JNIEXPORT void JNICALL Java_cx_ring_daemon_RingserviceJNI_captureVideoPacket(JNIEnv *jenv, jclass jcls, jobject buffer, jint size, jint offset, jboolean keyframe, jlong timestamp, jint rotation)
{
auto frame = DRing::getNewFrame();
if (not frame)
......@@ -163,6 +163,11 @@ JNIEXPORT void JNICALL Java_cx_ring_daemon_RingserviceJNI_captureVideoPacket(JNI
av_init_packet(packet.get());
if (keyframe)
packet->flags = AV_PKT_FLAG_KEY;
setRotation(rotation);
if (rotMatrix) {
auto buf = av_packet_new_side_data(packet.get(), AV_PKT_DATA_DISPLAYMATRIX, rotMatrix->size);
std::copy_n(rotMatrix->data, rotMatrix->size, buf);
}
auto data = (uint8_t*)jenv->GetDirectBufferAddress(buffer);
packet->data = data + offset;
packet->size = size;
......@@ -193,7 +198,6 @@ JNIEXPORT void JNICALL Java_cx_ring_daemon_RingserviceJNI_captureVideoFrame(JNIE
avframe->crop_right = avframe->width - jenv->GetIntField(crop, jenv->GetFieldID(rectClass, "right", "I"));
}
bool directPointer = true;
jobjectArray planes = (jobjectArray)jenv->CallObjectMethod(image, jenv->GetMethodID(imageClass, "getPlanes", "()[Landroid/media/Image$Plane;"));
jsize planeCount = jenv->GetArrayLength(planes);
if (avframe->format == AV_PIX_FMT_YUV420P) {
......@@ -243,26 +247,24 @@ JNIEXPORT void JNICALL Java_cx_ring_daemon_RingserviceJNI_captureVideoFrame(JNIE
if (rotMatrix)
av_frame_new_side_data_from_buf(avframe, AV_FRAME_DATA_DISPLAYMATRIX, av_buffer_ref(rotMatrix));
if (directPointer) {
image = jenv->NewGlobalRef(image);
imageClass = (jclass)jenv->NewGlobalRef(imageClass);
frame->setReleaseCb([jenv, image, imageClass](uint8_t *) mutable {
bool justAttached = false;
int envStat = gJavaVM->GetEnv((void**)&jenv, JNI_VERSION_1_6);
if (envStat == JNI_EDETACHED) {
justAttached = true;
if (gJavaVM->AttachCurrentThread(&jenv, nullptr) != 0)
return;
} else if (envStat == JNI_EVERSION) {
image = jenv->NewGlobalRef(image);
imageClass = (jclass)jenv->NewGlobalRef(imageClass);
frame->setReleaseCb([jenv, image, imageClass](uint8_t *) mutable {
bool justAttached = false;
int envStat = gJavaVM->GetEnv((void**)&jenv, JNI_VERSION_1_6);
if (envStat == JNI_EDETACHED) {
justAttached = true;
if (gJavaVM->AttachCurrentThread(&jenv, nullptr) != 0)
return;
}
jenv->CallVoidMethod(image, jenv->GetMethodID(imageClass, "close", "()V"));
jenv->DeleteGlobalRef(image);
jenv->DeleteGlobalRef(imageClass);
if (justAttached)
gJavaVM->DetachCurrentThread();
});
}
} else if (envStat == JNI_EVERSION) {
return;
}
jenv->CallVoidMethod(image, jenv->GetMethodID(imageClass, "close", "()V"));
jenv->DeleteGlobalRef(image);
jenv->DeleteGlobalRef(imageClass);
if (justAttached)
gJavaVM->DetachCurrentThread();
});
DRing::publishFrame();
}
......@@ -382,7 +384,7 @@ JNIEXPORT void JNICALL Java_cx_ring_daemon_RingserviceJNI_unregisterVideoCallbac
%native(unregisterVideoCallback) void unregisterVideoCallback(jstring, jlong);
%native(captureVideoFrame) void captureVideoFrame(jobject, jint);
%native(captureVideoPacket) void captureVideoPacket(jobject, jint, jint, jboolean, jlong);
%native(captureVideoPacket) void captureVideoPacket(jobject, jint, jint, jboolean, jlong, jint);
namespace DRing {
......
......@@ -83,6 +83,15 @@ VideoSender::encodeAndSendVideo(VideoFrame& input_frame)
forceKeyFrame_ = 0;
}
#endif
int size {0};
uint8_t* side_data = av_packet_get_side_data(packet, AV_PKT_DATA_DISPLAYMATRIX, &size);
auto angle = (side_data == nullptr || size == 0) ? 0 : av_display_rotation_get(reinterpret_cast<int32_t*>(side_data));
if (rotation_ != angle) {
rotation_ = angle;
if (changeOrientationCallback_)
changeOrientationCallback_(rotation_);
}
videoEncoder_->send(*packet);
} else {
bool is_keyframe = forceKeyFrame_ > 0
......@@ -92,14 +101,11 @@ VideoSender::encodeAndSendVideo(VideoFrame& input_frame)
--forceKeyFrame_;
AVFrameSideData* side_data = av_frame_get_side_data(input_frame.pointer(), AV_FRAME_DATA_DISPLAYMATRIX);
if (side_data) {
auto matrix_rotation = reinterpret_cast<int32_t*>(side_data->data);
auto angle = av_display_rotation_get(matrix_rotation);
if (rotation_ != angle) {
rotation_ = angle;
if (changeOrientationCallback_)
changeOrientationCallback_(rotation_);
}
auto angle = side_data == nullptr ? 0 : av_display_rotation_get(reinterpret_cast<int32_t*>(side_data->data));
if (rotation_ != angle) {
rotation_ = angle;
if (changeOrientationCallback_)
changeOrientationCallback_(rotation_);
}
#ifdef RING_ACCEL
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment