diff options
Diffstat (limited to 'src/codec')
| -rw-r--r-- | src/codec/ffmpeg/common.c | 22 | ||||
| -rw-r--r-- | src/codec/ffmpeg/decoder.c | 4 | ||||
| -rw-r--r-- | src/codec/ffmpeg/demuxer.c | 27 | ||||
| -rw-r--r-- | src/codec/ffmpeg/encoder.c | 22 |
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) |