Allow Video Callback to Fail

This commit is contained in:
Florian Märkl 2019-11-01 17:00:28 +01:00
commit 34b7d61295
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
8 changed files with 33 additions and 16 deletions

View file

@ -24,7 +24,7 @@
#include <oboe/Oboe.h> #include <oboe/Oboe.h>
#define BUFFER_CHUNK_SIZE 512 #define BUFFER_CHUNK_SIZE 1024
#define BUFFER_CHUNKS_COUNT 32 #define BUFFER_CHUNKS_COUNT 32
using AudioBuffer = CircularBuffer<BUFFER_CHUNKS_COUNT, BUFFER_CHUNK_SIZE>; using AudioBuffer = CircularBuffer<BUFFER_CHUNKS_COUNT, BUFFER_CHUNK_SIZE>;

View file

@ -262,7 +262,7 @@ JNIEXPORT void JNICALL JNI_FCN(sessionCreate)(JNIEnv *env, jobject obj, jobject
} }
memset(session, 0, sizeof(AndroidChiakiSession)); memset(session, 0, sizeof(AndroidChiakiSession));
session->log = log; session->log = log;
err = android_chiaki_video_decoder_init(&session->video_decoder, log); err = android_chiaki_video_decoder_init(&session->video_decoder, log, connect_info.video_profile.width, connect_info.video_profile.height);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
{ {
free(session); free(session);

View file

@ -29,11 +29,13 @@
static void *android_chiaki_video_decoder_output_thread_func(void *user); static void *android_chiaki_video_decoder_output_thread_func(void *user);
ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log) ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log, int32_t target_width, int32_t target_height)
{ {
decoder->log = log; decoder->log = log;
decoder->codec = NULL; decoder->codec = NULL;
decoder->timestamp_cur = 0; decoder->timestamp_cur = 0;
decoder->target_width = target_width;
decoder->target_height = target_height;
return chiaki_mutex_init(&decoder->codec_mutex, false); return chiaki_mutex_init(&decoder->codec_mutex, false);
} }
@ -91,8 +93,8 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder
AMediaFormat *format = AMediaFormat_new(); AMediaFormat *format = AMediaFormat_new();
AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime); AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, 1280); // TODO: correct values AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, decoder->target_width);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, 720); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, decoder->target_height);
media_status_t r = AMediaCodec_configure(decoder->codec, format, decoder->window, NULL, 0); media_status_t r = AMediaCodec_configure(decoder->codec, format, decoder->window, NULL, 0);
if(r != AMEDIA_OK) if(r != AMEDIA_OK)
@ -131,8 +133,9 @@ beach:
chiaki_mutex_unlock(&decoder->codec_mutex); chiaki_mutex_unlock(&decoder->codec_mutex);
} }
void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user) bool android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user)
{ {
bool r = true;
AndroidChiakiVideoDecoder *decoder = user; AndroidChiakiVideoDecoder *decoder = user;
chiaki_mutex_lock(&decoder->codec_mutex); chiaki_mutex_lock(&decoder->codec_mutex);
@ -148,7 +151,7 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo
if(codec_buf_index < 0) if(codec_buf_index < 0)
{ {
CHIAKI_LOGE(decoder->log, "Failed to get input buffer"); CHIAKI_LOGE(decoder->log, "Failed to get input buffer");
// TODO: report corrupt r = false;
goto beach; goto beach;
} }
@ -173,6 +176,7 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo
beach: beach:
chiaki_mutex_unlock(&decoder->codec_mutex); chiaki_mutex_unlock(&decoder->codec_mutex);
return r;
} }
static void *android_chiaki_video_decoder_output_thread_func(void *user) static void *android_chiaki_video_decoder_output_thread_func(void *user)

View file

@ -34,11 +34,13 @@ typedef struct android_chiaki_video_decoder_t
ANativeWindow *window; ANativeWindow *window;
uint64_t timestamp_cur; uint64_t timestamp_cur;
ChiakiThread output_thread; ChiakiThread output_thread;
int32_t target_width;
int32_t target_height;
} AndroidChiakiVideoDecoder; } AndroidChiakiVideoDecoder;
ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log); ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log, int32_t target_width, int32_t target_height);
void android_chiaki_video_decoder_fini(AndroidChiakiVideoDecoder *decoder); void android_chiaki_video_decoder_fini(AndroidChiakiVideoDecoder *decoder);
void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder, JNIEnv *env, jobject surface); void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder, JNIEnv *env, jobject surface);
void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user); bool android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user);
#endif #endif

View file

@ -43,7 +43,7 @@ class StreamInput(val preferences: Preferences)
fun dispatchKeyEvent(event: KeyEvent): Boolean fun dispatchKeyEvent(event: KeyEvent): Boolean
{ {
Log.i("StreamSession", "key event $event") //Log.i("StreamSession", "key event $event")
if(event.action != KeyEvent.ACTION_DOWN && event.action != KeyEvent.ACTION_UP) if(event.action != KeyEvent.ACTION_DOWN && event.action != KeyEvent.ACTION_UP)
return false return false

View file

@ -52,7 +52,7 @@ StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, QString h
static void AudioSettingsCb(uint32_t channels, uint32_t rate, void *user); static void AudioSettingsCb(uint32_t channels, uint32_t rate, void *user);
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user); static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user);
static void VideoSampleCb(uint8_t *buf, size_t buf_size, void *user); static bool VideoSampleCb(uint8_t *buf, size_t buf_size, void *user);
static void EventCb(ChiakiEvent *event, void *user); static void EventCb(ChiakiEvent *event, void *user);
StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent) StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent)
@ -373,10 +373,11 @@ static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user)
StreamSessionPrivate::PushAudioFrame(session, buf, samples_count); StreamSessionPrivate::PushAudioFrame(session, buf, samples_count);
} }
static void VideoSampleCb(uint8_t *buf, size_t buf_size, void *user) static bool VideoSampleCb(uint8_t *buf, size_t buf_size, void *user)
{ {
auto session = reinterpret_cast<StreamSession *>(user); auto session = reinterpret_cast<StreamSession *>(user);
StreamSessionPrivate::PushVideoSample(session, buf, buf_size); StreamSessionPrivate::PushVideoSample(session, buf, buf_size);
return true;
} }
static void EventCb(ChiakiEvent *event, void *user) static void EventCb(ChiakiEvent *event, void *user)

View file

@ -152,8 +152,9 @@ typedef void (*ChiakiEventCallback)(ChiakiEvent *event, void *user);
/** /**
* buf will always have an allocated padding of at least CHIAKI_VIDEO_BUFFER_PADDING_SIZE after buf_size * buf will always have an allocated padding of at least CHIAKI_VIDEO_BUFFER_PADDING_SIZE after buf_size
* @return whether the sample was successfully pushed into the decoder. On false, a corrupt frame will be reported to get a new keyframe.
*/ */
typedef void (*ChiakiVideoSampleCallback)(uint8_t *buf, size_t buf_size, void *user); typedef bool (*ChiakiVideoSampleCallback)(uint8_t *buf, size_t buf_size, void *user);

View file

@ -100,7 +100,7 @@ CHIAKI_EXPORT void chiaki_video_receiver_av_packet(ChiakiVideoReceiver *video_re
if(video_receiver->frame_index_cur >= 0 && video_receiver->frame_index_prev != video_receiver->frame_index_cur) if(video_receiver->frame_index_cur >= 0 && video_receiver->frame_index_prev != video_receiver->frame_index_cur)
chiaki_video_receiver_flush_frame(video_receiver); chiaki_video_receiver_flush_frame(video_receiver);
ChiakiSeqNum16 next_frame_expected = (ChiakiSeqNum16)video_receiver->frame_index_prev_complete + 1; ChiakiSeqNum16 next_frame_expected = (ChiakiSeqNum16)(video_receiver->frame_index_prev_complete + 1);
if(chiaki_seq_num_16_gt(frame_index, next_frame_expected) if(chiaki_seq_num_16_gt(frame_index, next_frame_expected)
&& !(frame_index == 1 && video_receiver->frame_index_cur < 0)) // ok for frame 1 && !(frame_index == 1 && video_receiver->frame_index_cur < 0)) // ok for frame 1
{ {
@ -143,12 +143,21 @@ static ChiakiErrorCode chiaki_video_receiver_flush_frame(ChiakiVideoReceiver *vi
// TODO: Error Concealment on CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED // TODO: Error Concealment on CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED
bool succ = flush_result != CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED;
if(video_receiver->session->video_sample_cb) if(video_receiver->session->video_sample_cb)
video_receiver->session->video_sample_cb(frame, frame_size, video_receiver->session->video_sample_cb_user); {
bool cb_succ = video_receiver->session->video_sample_cb(frame, frame_size, video_receiver->session->video_sample_cb_user);
if(!cb_succ)
{
succ = false;
CHIAKI_LOGW(video_receiver->log, "Video callback did not process frame successfully.");
}
}
video_receiver->frame_index_prev = video_receiver->frame_index_cur; video_receiver->frame_index_prev = video_receiver->frame_index_cur;
if(flush_result != CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED) if(succ)
video_receiver->frame_index_prev_complete = video_receiver->frame_index_cur; video_receiver->frame_index_prev_complete = video_receiver->frame_index_cur;
return CHIAKI_ERR_SUCCESS; return CHIAKI_ERR_SUCCESS;