summaryrefslogtreecommitdiff
path: root/src/codec
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/codec.h46
-rw-r--r--src/codec/ffmpeg/demuxer.c31
-rw-r--r--src/codec/ffmpeg/packet_ext.c2
-rw-r--r--src/codec/stb_image.c14
4 files changed, 49 insertions, 44 deletions
diff --git a/src/codec/codec.h b/src/codec/codec.h
index 0829847..f32283e 100644
--- a/src/codec/codec.h
+++ b/src/codec/codec.h
@@ -18,12 +18,6 @@ enum {
CAMU_LANG_JAPANESE
};
-enum {
- CAMU_MASK_AUDIO = 1,
- CAMU_MASK_VIDEO = 1 << 1,
- CAMU_MASK_SUBTITLE = 1 << 2
-};
-
#ifdef CAMU_HAVE_FFMPEG
enum {
CAMU_OK = 0,
@@ -36,33 +30,31 @@ enum {
CAMU_SEEK_SIZE = AVSEEK_SIZE
};
+// Stream types must be >= 0 and < 7 because we use them as shifts for a u8 mask and 7
+// is reserved for STREAM_UNKNOWN which is different than AVMEDIA_TYPE_UNKNOWN(-1).
enum {
- CAMU_STREAM_UNKNOWN = AVMEDIA_TYPE_UNKNOWN,
CAMU_STREAM_VIDEO = AVMEDIA_TYPE_VIDEO, // 0
CAMU_STREAM_AUDIO = AVMEDIA_TYPE_AUDIO, // 1
CAMU_STREAM_SUBTITLE = AVMEDIA_TYPE_SUBTITLE,
- CAMU_STREAM_ATTACHMENT = AVMEDIA_TYPE_ATTACHMENT
+ CAMU_STREAM_ATTACHMENT = AVMEDIA_TYPE_ATTACHMENT,
+ CAMU_STREAM_UNKNOWN = 7
};
+AL_STATIC_ASSERT(stream_type_count, AVMEDIA_TYPE_NB, <, 7);
enum {
- CAMU_SAMPLE_FORMAT_NONE = AV_SAMPLE_FMT_NONE,
+ CAMU_SAMPLE_FORMAT_NONE = AV_SAMPLE_FMT_NONE, // -1
CAMU_SAMPLE_FORMAT_U8 = AV_SAMPLE_FMT_U8,
CAMU_SAMPLE_FORMAT_S16 = AV_SAMPLE_FMT_S16,
CAMU_SAMPLE_FORMAT_S32 = AV_SAMPLE_FMT_S32,
CAMU_SAMPLE_FORMAT_FLT = AV_SAMPLE_FMT_FLT,
- CAMU_SAMPLE_FORMAT_DBL = AV_SAMPLE_FMT_DBL,
CAMU_SAMPLE_FORMAT_U8P = AV_SAMPLE_FMT_U8P,
CAMU_SAMPLE_FORMAT_S16P = AV_SAMPLE_FMT_S16P,
CAMU_SAMPLE_FORMAT_S32P = AV_SAMPLE_FMT_S32P,
- CAMU_SAMPLE_FORMAT_FLTP = AV_SAMPLE_FMT_FLTP,
- CAMU_SAMPLE_FORMAT_DBLP = AV_SAMPLE_FMT_DBLP,
-#ifndef CAMU_OLD_FFMPEG
- CAMU_SAMPLE_FORMAT_S64 = AV_SAMPLE_FMT_S64,
- CAMU_SAMPLE_FORMAT_S64P = AV_SAMPLE_FMT_S64P
-#endif
+ CAMU_SAMPLE_FORMAT_FLTP = AV_SAMPLE_FMT_FLTP
};
enum {
+ CAMU_PIXEL_FORMAT_NONE = AV_PIX_FMT_NONE, // -1
CAMU_PIXEL_FORMAT_RGBA = AV_PIX_FMT_RGBA,
CAMU_PIXEL_FORMAT_RGB24 = AV_PIX_FMT_RGB24,
CAMU_PIXEL_FORMAT_RGB32 = AV_PIX_FMT_RGB32,
@@ -91,13 +83,13 @@ enum {
CAMU_SEEK_SIZE = 0x10000
};
-// Using values from FFmpeg for potentially less confusing errors.
+// Using values from FFmpeg for less confusing errors.
enum {
- CAMU_STREAM_UNKNOWN = -1,
CAMU_STREAM_VIDEO = 0,
CAMU_STREAM_AUDIO = 1,
CAMU_STREAM_SUBTITLE = 3,
- CAMU_STREAM_ATTACHMENT = 4
+ CAMU_STREAM_ATTACHMENT = 4,
+ CAMU_STREAM_UNKNOWN = 7
};
enum {
@@ -106,18 +98,15 @@ enum {
CAMU_SAMPLE_FORMAT_S16,
CAMU_SAMPLE_FORMAT_S32,
CAMU_SAMPLE_FORMAT_FLT,
- CAMU_SAMPLE_FORMAT_DBL,
CAMU_SAMPLE_FORMAT_U8P,
CAMU_SAMPLE_FORMAT_S16P,
CAMU_SAMPLE_FORMAT_S32P,
- CAMU_SAMPLE_FORMAT_FLTP,
- CAMU_SAMPLE_FORMAT_DBLP,
- CAMU_SAMPLE_FORMAT_S64,
- CAMU_SAMPLE_FORMAT_S64P
+ CAMU_SAMPLE_FORMAT_FLTP
};
enum {
- CAMU_PIXEL_FORMAT_RGBA = 0,
+ CAMU_PIXEL_FORMAT_NONE = -1,
+ CAMU_PIXEL_FORMAT_RGBA,
CAMU_PIXEL_FORMAT_RGB24,
CAMU_PIXEL_FORMAT_RGB32,
CAMU_PIXEL_FORMAT_GREYA,
@@ -344,11 +333,6 @@ static inline size_t camu_audio_format_bytes_per_sample(struct camu_audio_format
case CAMU_SAMPLE_FORMAT_FLT:
case CAMU_SAMPLE_FORMAT_FLTP:
return 4;
- case CAMU_SAMPLE_FORMAT_S64:
- case CAMU_SAMPLE_FORMAT_S64P:
- case CAMU_SAMPLE_FORMAT_DBL:
- case CAMU_SAMPLE_FORMAT_DBLP:
- return 8;
default:
al_assert_and_return(0);
}
@@ -419,7 +403,7 @@ static inline s32 camu_pixel_format_from_channels(s32 channels)
case 3: return CAMU_PIXEL_FORMAT_RGB24;
case 2: return CAMU_PIXEL_FORMAT_GREYA;
case 1: return CAMU_PIXEL_FORMAT_GREY;
- default: al_assert_and_return(CAMU_PIXEL_FORMAT_GREY);
+ default: al_assert_and_return(CAMU_PIXEL_FORMAT_NONE);
}
}
diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c
index e5aa2f6..32068f3 100644
--- a/src/codec/ffmpeg/demuxer.c
+++ b/src/codec/ffmpeg/demuxer.c
@@ -89,6 +89,7 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
// @TODO:
// - 1 frame .gif.
// - No-duration video. (ex: data/test_resources/no_duration.mkv)
+ // - Incomplete video files with no duration. .temp.webm.
#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)) || \
@@ -105,6 +106,7 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
#endif
enum AVMediaType type = stream->codecpar->codec_type;
u64 duration = 0;
+ u8 mapped_type;
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)) {
@@ -117,15 +119,24 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
i, stream->duration * av_q2d(stream->time_base));
}
duration = (u64)av_rescale_q(stream->duration, stream->time_base, AV_TIME_BASE_Q);
- if (duration > av->duration) av->duration = duration;
+ 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 = 0;
- } else if (type != AVMEDIA_TYPE_ATTACHMENT) {
- type = AVMEDIA_TYPE_UNKNOWN; // Mapped to CAMU_STREAM_UNKNOWN.
+ mapped_type = type;
+ } else if (type == AVMEDIA_TYPE_ATTACHMENT) {
+ mapped_type = CAMU_STREAM_ATTACHMENT;
+ } else {
+ // CAMU_STREAM_UNKNOWN(7) is a different value than AVMEDIA_TYPE_UNKNOWN(-1) because
+ // we don't support negative stream types.
+ mapped_type = CAMU_STREAM_UNKNOWN;
}
al_array_push(av->demux.streams, ((struct camu_codec_stream){
.mode = CAMU_FFMPEG_COMPAT,
- .type = type,
+ .type = mapped_type,
.duration = duration,
.index = stream->index,
.av.stream = stream
@@ -184,12 +195,10 @@ static u64 ff_demuxer_get_duration(struct camu_demuxer *demux)
static bool ff_demuxer_seek(struct camu_demuxer *demux, u64 pos, bool bytes)
{
struct camu_ff_demuxer *av = (struct camu_ff_demuxer *)demux;
- if (av->eof) {
- // avio_flush() here probably does nothing.
- avio_flush(av->io_context);
- avformat_flush(av->format_context);
- av->eof = false;
- }
+ // avio_flush() here probably does nothing.
+ avio_flush(av->io_context);
+ avformat_flush(av->format_context);
+ if (av->eof) av->eof = false;
al_assert(pos <= INT64_MAX);
al_assert(!(bytes && av->format_context->flags & AVFMT_NO_BYTE_SEEK));
if (!bytes && pos > av->duration) pos = av->duration;
diff --git a/src/codec/ffmpeg/packet_ext.c b/src/codec/ffmpeg/packet_ext.c
index 6b66dd1..68f1b4c 100644
--- a/src/codec/ffmpeg/packet_ext.c
+++ b/src/codec/ffmpeg/packet_ext.c
@@ -221,7 +221,7 @@ void nn_packet_read_av_packet(struct nn_packet *packet, AVPacket *pkt)
enum AVPacketSideDataType type;
s64 storage_for_size;
NNWT_PACKET_READ_TYPE(packet, s64, storage_for_size);
- al_assert((sizeof(size_t) > 4 || storage_for_size <= INT32_MAX));
+ al_assert(sizeof(size_t) > 4 || storage_for_size <= INT32_MAX);
size_t size = (size_t)storage_for_size;
NNWT_PACKET_READ_DATA(packet, size, data);
NNWT_PACKET_READ_TYPE(packet, enum AVPacketSideDataType, type);
diff --git a/src/codec/stb_image.c b/src/codec/stb_image.c
index b4fabc2..1d790dd 100644
--- a/src/codec/stb_image.c
+++ b/src/codec/stb_image.c
@@ -2,6 +2,7 @@
#define STBI_MALLOC camu_page_alloc
#define STBI_FREE al_free
#define STBI_REALLOC camu_page_realloc
+#define STBI_ASSERT al_assert
#define STBI_NO_STDIO
#define STBI_NO_FAILURE_STRINGS
#define STB_IMAGE_IMPLEMENTATION
@@ -10,7 +11,7 @@
#include "stb_image.h"
#ifdef LIANA_SERVER
-#include "../../cache/entry.h"
+#include "../cache/entry.h"
static bool stbi_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handle)
{
@@ -114,7 +115,14 @@ static s32 stbi_decoder_push(struct camu_decoder *dec, struct camu_codec_packet
s32 w, h, channels;
u8 *data = nn_buffer_get_ptr(packet->buffer, 0);
+#ifdef NAUNET_ON_WINDOWS
+#define STB_FORCE_RGBA
+#endif
+#ifdef STB_FORCE_RGBA
+ u8 *pixels = stbi_load_from_memory(data, packet->buffer->size, &w, &h, &channels, 4);
+#else
u8 *pixels = stbi_load_from_memory(data, packet->buffer->size, &w, &h, &channels, 0);
+#endif
if (!pixels) return CAMU_ERR_ERROR;
struct camu_video_format *fmt = &stb->stream->video.fmt;
@@ -126,8 +134,12 @@ static s32 stbi_decoder_push(struct camu_decoder *dec, struct camu_codec_packet
frame->data = pixels;
frame->video.width = (u32)w;
frame->video.height = (u32)h;
+#ifdef STB_FORCE_RGBA
+ frame->format = camu_pixel_format_from_channels(4);
+#else
frame->format = camu_pixel_format_from_channels(channels);
al_assert(frame->format == fmt->format);
+#endif
frame->pts = 0.0;
stb->callback(stb->userdata, frame);