summaryrefslogtreecommitdiff
path: root/src/codec/ffmpeg
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec/ffmpeg')
-rw-r--r--src/codec/ffmpeg/common.c22
-rw-r--r--src/codec/ffmpeg/decoder.c4
-rw-r--r--src/codec/ffmpeg/demuxer.c27
-rw-r--r--src/codec/ffmpeg/encoder.c22
4 files changed, 40 insertions, 35 deletions
diff --git a/src/codec/ffmpeg/common.c b/src/codec/ffmpeg/common.c
index b7a232e..c147d81 100644
--- a/src/codec/ffmpeg/common.c
+++ b/src/codec/ffmpeg/common.c
@@ -9,30 +9,32 @@ void camu_ff_set_log_callback(void (*callback)(void *, int, const char *, va_lis
av_log_set_callback(callback);
}
-static char *av_log_buf = NULL;
-static s32 av_log_pos = 0;
+static char *buf = NULL;
+static s32 pos = 0;
+
+// If a line takes more than 2 steps to print, make sure we stay within AL_LOG_MESSAGE_SIZE.
+#define CHUNK_SIZE (AL_LOG_MESSAGE_SIZE / 2)
static void av_log_callback(void *userdata, int level, const char *fmt, va_list args)
{
(void)userdata;
- al_assert(av_log_buf);
+ al_assert(buf);
if (level < AV_LOG_DEBUG) {
- av_log_pos += al_vsnprintf(&av_log_buf[av_log_pos], 512, fmt, args);
- if (av_log_buf[av_log_pos - 1] == '\n' || av_log_pos >= 512) {
- al_log_info("ff_log", av_log_buf);
- av_log_pos = 0;
+ pos += al_vsnprintf(&buf[pos], CHUNK_SIZE, fmt, args);
+ if (buf[pos - 1] == '\n' || pos >= CHUNK_SIZE) {
+ al_log_info("ff_log", buf);
+ pos = 0;
}
}
}
void camu_ff_set_default_log_callback()
{
- av_log_buf = (char *)al_malloc(1024);
+ buf = (char *)al_malloc(AL_LOG_MESSAGE_SIZE);
camu_ff_set_log_callback(av_log_callback);
}
-
void camu_ff_free_default_log_callback()
{
- al_free(av_log_buf);
+ al_free(buf);
}
diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c
index 51eca40..47fcc0c 100644
--- a/src/codec/ffmpeg/decoder.c
+++ b/src/codec/ffmpeg/decoder.c
@@ -92,7 +92,7 @@ static s32 send_packet(struct camu_ff_decoder *av, AVPacket *pkt)
s32 ret = avcodec_send_packet(av->codec_context, pkt);
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
- al_log_error("ff_decoder", "Error sending packet to the decoder: (%s).", av_err2str(ret));
+ al_log_error("ff_decoder", "Error sending packet to the decoder (%s).", av_err2str(ret));
}
return ret;
@@ -123,7 +123,7 @@ static s32 receive_frames(struct camu_ff_decoder *av)
al_free(frame);
// Checking for EAGAIN should prevent an infinite loop.
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;
- al_log_error("ff_decoder", "Error receiving packet from the decoder: (%s).", av_err2str(ret));
+ al_log_error("ff_decoder", "Error receiving packet from the decoder (%s).", av_err2str(ret));
continue;
}
// Track pts and duration of the previous frame so we can handle multiple frames in a single packet.
diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c
index 24c1ba6..f756168 100644
--- a/src/codec/ffmpeg/demuxer.c
+++ b/src/codec/ffmpeg/demuxer.c
@@ -3,7 +3,7 @@
#include "demuxer.h"
#include "avio.h"
-#define DEMUX_BUF_SIZE (4096 * 4)
+#define DEMUX_BUFFER_SIZE (4096 * 4)
static void close_internal(struct camu_ff_demuxer *av)
{
@@ -28,8 +28,8 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
goto err;
}
- u8 *buf = (u8 *)av_malloc(DEMUX_BUF_SIZE);
- av->io_context = avio_alloc_context(buf, DEMUX_BUF_SIZE, 0, handle, camu_avio_read, NULL, camu_avio_seek);
+ u8 *buf = (u8 *)av_malloc(DEMUX_BUFFER_SIZE);
+ av->io_context = avio_alloc_context(buf, DEMUX_BUFFER_SIZE, 0, handle, camu_avio_read, NULL, camu_avio_seek);
if (!av->io_context) {
al_log_error("ff_demuxer", "Failed to create custom io context.");
goto err;
@@ -70,31 +70,30 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
}
#define GUESS_STREAM_IS_IMAGE(stream) \
- (stream->duration >= 0 && stream->nb_frames <= 1 && (stream->avg_frame_rate.den == 0 && stream->r_frame_rate.den > 0))
+ (stream->duration >= 0L && stream->nb_frames <= 1L && (stream->avg_frame_rate.den == 0 && stream->r_frame_rate.den > 0))
- av->duration = 0;
+ s64 default_duration = av->format_context->duration < 0L ? 0L : av->format_context->duration;
+ av->duration = 0Lu;
for (u32 i = 0; i < av->format_context->nb_streams; i++) {
AVStream *stream = av->format_context->streams[i];
enum AVMediaType type = stream->codecpar->codec_type;
- u64 duration = 0;
+ u64 duration = 0Lu;
if (type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_SUBTITLE) {
// Try to detect attached images.
if (type == AVMEDIA_TYPE_VIDEO && GUESS_STREAM_IS_IMAGE(stream)) {
- al_log_info("ff_demuxer", "Guessing that stream #%u is an image.", i);
+ al_log_info("ff_demuxer", "Assuming stream #%u is an image.", i);
} else {
- if (stream->duration < 0) {
- al_log_warn("ff_demuxer", "Stream #%u has an invalid duration (%ld).", i, stream->duration);
- stream->duration = av->format_context->duration < 0 ? 0 :
- av_rescale_q(av->format_context->duration, AV_TIME_BASE_Q, stream->time_base);
- al_log_info("ff_demuxer", "Defaulting stream #%u to a duration of %.3fs.",
+ if (stream->duration < 0L) {
+ stream->duration = av_rescale_q(default_duration, AV_TIME_BASE_Q, stream->time_base);
+ al_assert(stream->duration >= 0L);
+ al_log_info("ff_demuxer", "Stream #%u has an invalid duration, defaulting to %.3fs.",
i, stream->duration * av_q2d(stream->time_base));
- al_assert(stream->duration >= 0);
}
duration = (u64)av_rescale_q(stream->duration, stream->time_base, AV_TIME_BASE_Q);
if (duration > av->duration) av->duration = duration;
}
- if (stream->start_time == AV_NOPTS_VALUE) stream->start_time = 0;
+ if (stream->start_time == AV_NOPTS_VALUE) stream->start_time = 0L;
} else if (type != AVMEDIA_TYPE_ATTACHMENT) {
continue;
}
diff --git a/src/codec/ffmpeg/encoder.c b/src/codec/ffmpeg/encoder.c
index 11aaaff..6e914c8 100644
--- a/src/codec/ffmpeg/encoder.c
+++ b/src/codec/ffmpeg/encoder.c
@@ -27,7 +27,7 @@ bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char
const AVCodec *codec = avcodec_find_encoder_by_name(encoder_name);
if (!codec) {
- al_log_error("ff_encoder", "Failed to find codec with name: %s.", encoder_name);
+ al_log_error("ff_encoder", "Failed to find codec by name %s.", encoder_name);
goto err;
}
@@ -95,17 +95,21 @@ void camu_ff_encoder_push(struct camu_ff_encoder *enc, u8 **data, s32 sample_cou
enc->frame->data[0] = data[0];
s32 ret = avcodec_send_frame(enc->codec_context, enc->frame);
if (ret < 0 && ret != AVERROR_EOF) {
- al_log_error("ff_encoder", "Error sending frame to the encoder: (%s).", av_err2str(ret));
+ al_log_error("ff_encoder", "Error sending frame to the encoder (%s).", av_err2str(ret));
return;
}
AVPacket pkt = { 0 };
- ret = avcodec_receive_packet(enc->codec_context, &pkt);
- if (ret < 0 && ret != AVERROR_EOF) {
- al_log_error("ff_encoder", "Error receiving packet from the encoder: (%s).", av_err2str(ret));
- return;
- }
- enc->callback(enc->userdata, &pkt);
- enc->frame->pts += SAMPLES_PER_FRAME;
+ do {
+ ret = avcodec_receive_packet(enc->codec_context, &pkt);
+ if (ret < 0) {
+ if (!(ret = AVERROR_EOF || ret == AVERROR(EAGAIN))) {
+ al_log_error("ff_encoder", "Error receiving packet from the encoder (%s).", av_err2str(ret));
+ }
+ return;
+ }
+ enc->callback(enc->userdata, &pkt);
+ enc->frame->pts += SAMPLES_PER_FRAME;
+ } while (1);
}
void camu_ff_encoder_reset(struct camu_ff_encoder *enc)