mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-03-01 01:34:30 +01:00
Compare commits
1 Commits
issue702
...
record_dur
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8507fea271 |
@@ -87,6 +87,7 @@ recorder_init(struct recorder *recorder,
|
||||
recorder->format = format;
|
||||
recorder->declared_frame_size = declared_frame_size;
|
||||
recorder->header_written = false;
|
||||
recorder->previous = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -219,13 +220,22 @@ recorder_rescale_packet(struct recorder *recorder, AVPacket *packet) {
|
||||
|
||||
bool
|
||||
recorder_write(struct recorder *recorder, AVPacket *packet) {
|
||||
SDL_assert(packet->pts != AV_NOPTS_VALUE);
|
||||
if (!recorder->header_written) {
|
||||
if (packet->pts != AV_NOPTS_VALUE) {
|
||||
LOGE("The first packet is not a config packet");
|
||||
return false;
|
||||
}
|
||||
bool ok = recorder_write_header(recorder, packet);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
recorder->header_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (packet->pts == AV_NOPTS_VALUE) {
|
||||
// ignore config packets
|
||||
return true;
|
||||
}
|
||||
|
||||
recorder_rescale_packet(recorder, packet);
|
||||
@@ -248,6 +258,19 @@ run_recorder(void *data) {
|
||||
|
||||
if (recorder->stopped && queue_is_empty(&recorder->queue)) {
|
||||
mutex_unlock(recorder->mutex);
|
||||
struct record_packet *last = recorder->previous;
|
||||
if (last) {
|
||||
// assign an arbitrary duration to the last packet
|
||||
last->packet.duration = 100000;
|
||||
bool ok = recorder_write(recorder, &last->packet);
|
||||
if (!ok) {
|
||||
// failing to write the last frame is not very serious, no
|
||||
// future frame may depend on it, so the resulting file
|
||||
// will still be valid
|
||||
LOGW("Could not record last packet");
|
||||
}
|
||||
record_packet_delete(last);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -256,8 +279,20 @@ run_recorder(void *data) {
|
||||
|
||||
mutex_unlock(recorder->mutex);
|
||||
|
||||
bool ok = recorder_write(recorder, &rec->packet);
|
||||
record_packet_delete(rec);
|
||||
// recorder->previous is only written from this thread, no need to lock
|
||||
struct record_packet *previous = recorder->previous;
|
||||
recorder->previous = rec;
|
||||
|
||||
if (!previous) {
|
||||
// we just received the first packet
|
||||
continue;
|
||||
}
|
||||
|
||||
// we now know the duration of the previous packet
|
||||
previous->packet.duration = rec->packet.pts - previous->packet.pts;
|
||||
|
||||
bool ok = recorder_write(recorder, &previous->packet);
|
||||
record_packet_delete(previous);
|
||||
if (!ok) {
|
||||
LOGE("Could not record packet");
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ struct recorder {
|
||||
bool stopped; // set on recorder_stop() by the stream reader
|
||||
bool failed; // set on packet write failure
|
||||
struct recorder_queue queue;
|
||||
|
||||
// we can write a packet only once we received the next one so that we can
|
||||
// set its duration (next_pts - current_pts)
|
||||
// "previous" is only accessed from the recorder thread, so it does not
|
||||
// need to be protected by the mutex
|
||||
struct record_packet *previous;
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
@@ -69,6 +69,15 @@ notify_stopped(void) {
|
||||
SDL_PushEvent(&stop_event);
|
||||
}
|
||||
|
||||
static bool
|
||||
process_config_packet(struct stream *stream, AVPacket *packet) {
|
||||
if (stream->recorder && !recorder_push(stream->recorder, packet)) {
|
||||
LOGE("Could not send config packet to recorder");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
process_frame(struct stream *stream, AVPacket *packet) {
|
||||
if (stream->decoder && !decoder_push(stream->decoder, packet)) {
|
||||
@@ -148,7 +157,13 @@ stream_push_packet(struct stream *stream, AVPacket *packet) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_config) {
|
||||
if (is_config) {
|
||||
// config packet
|
||||
bool ok = process_config_packet(stream, packet);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// data packet
|
||||
bool ok = stream_parse(stream, packet);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user