Skip to content

[camera] Fix preview freeze issue #275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@

## 0.2.0

* Apply new external texture APIs
* Apply new external texture APIs

## 0.2.1

* Fix a freezing preview issue
2 changes: 1 addition & 1 deletion packages/camera/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This package is not an _endorsed_ implementation of `camera`. Therefore, you hav
```yaml
dependencies:
camera: ^0.8.1
camera_tizen: ^0.2.0
camera_tizen: ^0.2.1
```

Then you can import `camera` in your Dart code:
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: camera_tizen
description: Tizen implementation of the camera plugin
homepage: https://github.com/flutter-tizen/plugins
repository: https://github.com/flutter-tizen/plugins/tree/master/packages/camera
version: 0.2.0
version: 0.2.1

dependencies:
flutter:
Expand Down
81 changes: 58 additions & 23 deletions packages/camera/tizen/src/camera_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@
#define VIDEO_ENCODE_BITRATE 40000000 /* bps */
#define AUDIO_SOURCE_SAMPLERATE_AAC 44100

static uint64_t Timestamp() {
namespace {

uint64_t Timestamp() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return (uint64_t)tv.tv_sec * 1000UL + tv.tv_usec / 1000UL;
}

static std::string CreateTempFileName(const std::string &prefix,
const std::string &extension) {
std::string CreateTempFileName(const std::string &prefix,
const std::string &extension) {
std::string file_name;
char *cache_dir_path = app_get_cache_path();
if (!cache_dir_path) {
Expand All @@ -38,8 +40,17 @@ static std::string CreateTempFileName(const std::string &prefix,
return file_name;
}

static ExifTagOrientation ChooseExifTagOrientatoin(
OrientationType device_orientation, bool is_front_lens_facing) {
bool IsValidMediaPacket(media_packet_h media_packet) {
tbm_surface_h surface = nullptr;
int ret = media_packet_get_tbm_surface(media_packet, &surface);
if (ret != MEDIA_PACKET_ERROR_NONE) {
return false;
}
return true;
}

ExifTagOrientation ChooseExifTagOrientatoin(OrientationType device_orientation,
bool is_front_lens_facing) {
ExifTagOrientation orientation = ExifTagOrientation::kTopLeft;

switch (device_orientation) {
Expand Down Expand Up @@ -79,7 +90,7 @@ static ExifTagOrientation ChooseExifTagOrientatoin(
return orientation;
}

static RecorderOrientationTag ChooseRecorderOrientationTag(
RecorderOrientationTag ChooseRecorderOrientationTag(
OrientationType device_orientation) {
RecorderOrientationTag tag = RecorderOrientationTag::kNone;
switch (device_orientation) {
Expand All @@ -102,6 +113,8 @@ static RecorderOrientationTag ChooseRecorderOrientationTag(
return tag;
}

} // namespace

bool StringToCameraPixelFormat(std::string Image_format,
CameraPixelFormat &pixel_format) {
if (Image_format == "bgra8888") {
Expand Down Expand Up @@ -330,28 +343,40 @@ CameraDevice::CameraDevice(flutter::PluginRegistrar *registrar,
[this](size_t width,
size_t height) -> const FlutterDesktopGpuBuffer * {
std::lock_guard<std::mutex> lock(mutex_);
if (packet_ == nullptr) {
if (prepared_packet_ && !IsValidMediaPacket(prepared_packet_)) {
media_packet_destroy(prepared_packet_);
prepared_packet_ = nullptr;
}
if (current_packet_ && !IsValidMediaPacket(current_packet_)) {
media_packet_destroy(current_packet_);
current_packet_ = nullptr;
}
if (!prepared_packet_ && !current_packet_) {
return nullptr;
}
tbm_surface_h surface;
int ret = media_packet_get_tbm_surface(packet_, &surface);
if (prepared_packet_ && !current_packet_) {
current_packet_ = prepared_packet_;
prepared_packet_ = nullptr;
}

tbm_surface_h surface = nullptr;
int ret = media_packet_get_tbm_surface(current_packet_, &surface);
if (ret != MEDIA_PACKET_ERROR_NONE) {
LOG_ERROR("media_packet_get_tbm_surface failed, error: %d", ret);
media_packet_destroy(packet_);
packet_ = nullptr;
media_packet_destroy(current_packet_);
current_packet_ = nullptr;
return nullptr;
}

flutter_desktop_gpu_buffer_->buffer = surface;
flutter_desktop_gpu_buffer_->width = width;
flutter_desktop_gpu_buffer_->height = height;
return flutter_desktop_gpu_buffer_.get();
},
[this](void *buffer) -> void {
std::lock_guard<std::mutex> lock(mutex_);
if (packet_) {
media_packet_destroy(packet_);
packet_ = nullptr;
if (current_packet_) {
media_packet_destroy(current_packet_);
current_packet_ = nullptr;
}
}));
texture_id_ =
Expand Down Expand Up @@ -431,6 +456,16 @@ void CameraDevice::Dispose() {
if (texture_id_ != 0) {
registrar_->texture_registrar()->UnregisterTexture(texture_id_);
}

if (current_packet_) {
media_packet_destroy(current_packet_);
current_packet_ = nullptr;
}

if (prepared_packet_) {
media_packet_destroy(prepared_packet_);
prepared_packet_ = nullptr;
}
}

bool CameraDevice::ForeachCameraSupportedCaptureResolutions(
Expand Down Expand Up @@ -950,17 +985,17 @@ void CameraDevice::Open(
SetCameraPreviewFormat(pixel_format);
}

if (!SetCameraMediaPacketPreviewCb([](media_packet_h pkt, void *data) {
if (!SetCameraMediaPacketPreviewCb([](media_packet_h packet, void *data) {
auto self = static_cast<CameraDevice *>(data);
std::lock_guard<std::mutex> lock(self->mutex_);
media_packet_h unused_packet = self->packet_;
self->packet_ = pkt;
if (unused_packet != nullptr) {
media_packet_destroy(unused_packet);
} else {
self->registrar_->texture_registrar()->MarkTextureFrameAvailable(
self->texture_id_);
if (self->prepared_packet_) {
media_packet_destroy(self->prepared_packet_);
self->prepared_packet_ = packet;
return;
}
self->prepared_packet_ = packet;
self->registrar_->texture_registrar()->MarkTextureFrameAvailable(
self->texture_id_);
})) {
result->Error(kCameraDeviceError, "Failed to set media callback");
return;
Expand Down
4 changes: 3 additions & 1 deletion packages/camera/tizen/src/camera_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ class CameraDevice {
flutter::PluginRegistrar *registrar_{nullptr};
std::unique_ptr<flutter::TextureVariant> texture_variant_;
std::unique_ptr<FlutterDesktopGpuBuffer> flutter_desktop_gpu_buffer_;
media_packet_h packet_{nullptr};
media_packet_h current_packet_{nullptr};
media_packet_h prepared_packet_{nullptr};

std::mutex mutex_;

std::unique_ptr<CameraMethodChannel> camera_method_channel_;
Expand Down