Skip to content

Commit

Permalink
Added WebP image codec for thumbnails
Browse files Browse the repository at this point in the history
  • Loading branch information
Keukhan committed Jan 6, 2025
1 parent d344303 commit 26dbba7
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 24 deletions.
19 changes: 16 additions & 3 deletions misc/prerequisites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ OPENH264_VERSION=2.4.0
HIREDIS_VERSION=1.0.2
NVCC_HDR_VERSION=11.1.5.2
X264_VERSION=31e19f92

WEBP_VERSION=1.5.0
INTEL_QSV_HWACCELS=false
NETINT_LOGAN_HWACCELS=false
NETINT_LOGAN_PATCH_PATH=""
Expand Down Expand Up @@ -173,6 +173,18 @@ install_libvpx()
rm -rf ${DIR}) || fail_exit "vpx"
}

install_libwebp()
{
(DIR=${TEMP_PATH}/webp && \
mkdir -p ${DIR} && \
cd ${DIR} && \
curl -sSLf https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz | tar -xz --strip-components=1 && \
./configure --prefix="${PREFIX}" --enable-shared --disable-static && \
make -j$(nproc) && \
sudo make install && \
rm -rf ${DIR}) || fail_exit "webp"
}

install_fdk_aac()
{
(DIR=${TEMP_PATH}/aac && \
Expand Down Expand Up @@ -344,10 +356,10 @@ install_ffmpeg()
--extra-libs=-ldl ${ADDI_EXTRA_LIBS} \
${ADDI_LICENSE} \
--disable-everything --disable-programs --disable-avdevice --disable-dwt --disable-lsp --disable-lzo --disable-faan --disable-pixelutils \
--enable-shared --enable-zlib --enable-libopus --enable-libvpx --enable-libfdk_aac --enable-libopenh264 --enable-openssl --enable-network --enable-libsrt --enable-dct --enable-rdft ${ADDI_LIBS} \
--enable-shared --enable-zlib --enable-libopus --enable-libvpx --enable-libfdk_aac --enable-libopenh264 --enable-openssl --enable-network --enable-libsrt --enable-dct --enable-rdft --enable-libwebp ${ADDI_LIBS} \
${ADDI_HWACCEL} \
--enable-ffmpeg \
--enable-encoder=libvpx_vp8,libopus,libfdk_aac,libopenh264,mjpeg,png${ADDI_ENCODER} \
--enable-encoder=libvpx_vp8,libopus,libfdk_aac,libopenh264,mjpeg,png,libwebp${ADDI_ENCODER} \
--enable-decoder=aac,aac_latm,aac_fixed,mp3float,mp3,h264,hevc,opus,vp8${ADDI_DECODER} \
--enable-parser=aac,aac_latm,aac_fixed,h264,hevc,opus,vp8 \
--enable-protocol=tcp,udp,rtp,file,rtmp,tls,rtmps,libsrt \
Expand Down Expand Up @@ -597,6 +609,7 @@ install_libopus
install_libopenh264
install_libx264
install_libvpx
install_libwebp
install_fdk_aac
install_nvcc_hdr
install_ffmpeg
Expand Down
2 changes: 2 additions & 0 deletions src/projects/base/common_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ static ov::String StringFromMediaCodecId(const cmn::MediaCodecId &type)
return "JPEG";
case cmn::MediaCodecId::Png:
return "PNG";
case cmn::MediaCodecId::Webp:
return "WEBP";
case cmn::MediaCodecId::None:
default:
return "Unknown";
Expand Down
3 changes: 2 additions & 1 deletion src/projects/base/info/media_track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ bool MediaTrack::IsValid()
}
break;
case MediaCodecId::Jpeg:
case MediaCodecId::Png: {
case MediaCodecId::Png:
case MediaCodecId::Webp: {
if (_width > 0 &&
_height > 0 &&
_time_base.GetNum() > 0 &&
Expand Down
22 changes: 18 additions & 4 deletions src/projects/base/mediarouter/media_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace cmn
OPUS_RTP_RFC_7587,
JPEG,
PNG,
WEBP,

// For Data Track
ID3v2,
Expand Down Expand Up @@ -98,6 +99,7 @@ namespace cmn
Opus,
Jpeg,
Png,
Webp
};

enum class MediaCodecModuleId : uint8_t
Expand Down Expand Up @@ -138,9 +140,11 @@ namespace cmn
return false;
}

static bool IsImageCodec(cmn::MediaCodecId codec_id) {
if (codec_id == cmn::MediaCodecId::Jpeg ||
codec_id == cmn::MediaCodecId::Png)
static bool IsImageCodec(cmn::MediaCodecId codec_id)
{
if (codec_id == cmn::MediaCodecId::Jpeg ||
codec_id == cmn::MediaCodecId::Png ||
codec_id == cmn::MediaCodecId::Webp)
{
return true;
}
Expand Down Expand Up @@ -234,6 +238,8 @@ namespace cmn
return "JPEG";
case cmn::BitstreamFormat::PNG:
return "PNG";
case cmn::BitstreamFormat::WEBP:
return "WEBP";
case cmn::BitstreamFormat::ID3v2:
return "ID3v2";
case cmn::BitstreamFormat::OVEN_EVENT:
Expand Down Expand Up @@ -360,10 +366,13 @@ namespace cmn
return "VP9";
case cmn::MediaCodecId::Flv:
return "FLV";
// Image codecs
case cmn::MediaCodecId::Jpeg:
return "JPEG";
case cmn::MediaCodecId::Png:
return "PNG";
case cmn::MediaCodecId::Webp:
return "WEBP";
// Audio codecs
case cmn::MediaCodecId::Aac:
return "AAC";
Expand Down Expand Up @@ -403,6 +412,7 @@ namespace cmn
{
return cmn::MediaCodecId::Flv;
}
// Image codecs
else if (name.HasPrefix("JPEG"))
{
return cmn::MediaCodecId::Jpeg;
Expand All @@ -411,8 +421,12 @@ namespace cmn
{
return cmn::MediaCodecId::Png;
}
else if (name.HasPrefix("WEBP"))
{
return cmn::MediaCodecId::Webp;
}
// Audio codecs
if (name.HasPrefix("AAC"))
else if (name.HasPrefix("AAC"))
{
return cmn::MediaCodecId::Aac;
}
Expand Down
9 changes: 4 additions & 5 deletions src/projects/mediarouter/mediarouter_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -894,14 +894,12 @@ bool MediaRouteStream::NormalizeMediaPacket(std::shared_ptr<MediaTrack> &media_t
break;
case cmn::BitstreamFormat::JPEG:
case cmn::BitstreamFormat::PNG:
{
if (GetInoutType() == MediaRouterStreamType::OUTBOUND)
case cmn::BitstreamFormat::WEBP:
if (GetInoutType() == MediaRouterStreamType::OUTBOUND)
{
result = true;
}
break;
}

case cmn::BitstreamFormat::AAC_LATM:
case cmn::BitstreamFormat::Unknown:
default:
Expand Down Expand Up @@ -1055,11 +1053,12 @@ void MediaRouteStream::UpdateStatistics(std::shared_ptr<MediaTrack> &media_track

ov::String stat_stream_str = "";

stat_stream_str.AppendFormat("Stream. id: %10u, type: %s, name: %s/%s, uptime: %lldms, queue: %d, msid: %u, sync: %lldms",
stat_stream_str.AppendFormat("Stream. id: %10u, type: %s, name: %s/%s, status: %s, uptime: %lldms, queue: %d, msid: %u, sync: %lldms",
_stream->GetId(),
_inout_type == MediaRouterStreamType::INBOUND ? "Inbound" : "Outbound",
_stream->GetApplicationInfo().GetVHostAppName().CStr(),
_stream->GetName().CStr(),
IsStreamPrepared() ? "Started" : "Preapring",
(int64_t)uptime,
_packets_queue.Size(),
_stream->GetMsid(),
Expand Down
3 changes: 3 additions & 0 deletions src/projects/modules/segment_writer/writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ static AVCodecID AvCodecIdFromMediaCodecId(cmn::MediaCodecId codec_id)
WRITER_CASE(cmn::MediaCodecId::Opus, AV_CODEC_ID_OPUS)
WRITER_CASE(cmn::MediaCodecId::Jpeg, AV_CODEC_ID_JPEG2000)
WRITER_CASE(cmn::MediaCodecId::Png, AV_CODEC_ID_PNG)
WRITER_CASE(cmn::MediaCodecId::Webp, AV_CODEC_ID_WEBP)
}

return AV_CODEC_ID_NONE;
Expand Down Expand Up @@ -862,6 +863,8 @@ bool Writer::WritePacket(const std::shared_ptr<const MediaPacket> &packet)
[[fallthrough]];
case cmn::BitstreamFormat::PNG:
[[fallthrough]];
case cmn::BitstreamFormat::WEBP:
[[fallthrough]];
case cmn::BitstreamFormat::ID3v2:
[[fallthrough]];
case cmn::BitstreamFormat::MP3:
Expand Down
10 changes: 6 additions & 4 deletions src/projects/publishers/thumbnail/thumbnail_interceptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// OvenMediaEngine
//
// Created by Keukhan
// Created by Kwon Keuk Han
// Copyright (c) 2019 AirenSoft. All rights reserved.
//
//==============================================================================
Expand All @@ -25,9 +25,11 @@ bool ThumbnailInterceptor::IsInterceptorForRequest(const std::shared_ptr<const h
return false;
}

// ts/m3u8
if ((request->GetRequestTarget().LowerCaseString().IndexOf(".jpg") >= 0) ||
(request->GetRequestTarget().LowerCaseString().IndexOf(".png") >= 0))
const auto target = request->GetRequestTarget().LowerCaseString();

if ((target.IndexOf(".jpg") >= 0) ||
(target.IndexOf(".png") >= 0) ||
(target.IndexOf(".webp") >= 0))
{
return true;
}
Expand Down
24 changes: 21 additions & 3 deletions src/projects/publishers/thumbnail/thumbnail_publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ bool ThumbnailPublisher::OnDeletePublisherApplication(const std::shared_ptr<pub:

std::shared_ptr<ThumbnailInterceptor> ThumbnailPublisher::CreateInterceptor()
{
ov::String thumbnail_url_pattern = R"(.+thumb\.(jpg|png)$)";
ov::String thumbnail_url_pattern = R"(.+thumb\.(jpg|png|webp)$)";

auto http_interceptor = std::make_shared<ThumbnailInterceptor>();

Expand Down Expand Up @@ -355,6 +355,10 @@ std::shared_ptr<ThumbnailInterceptor> ThumbnailPublisher::CreateInterceptor()
{
media_codec_id = cmn::MediaCodecId::Png;
}
else if (request_url->File().LowerCaseString().IndexOf(".webp") >= 0)
{
media_codec_id = cmn::MediaCodecId::Webp;
}
else
{
response->AppendString(ov::String::FormatString("Unsupported file extension"));
Expand All @@ -377,7 +381,7 @@ std::shared_ptr<ThumbnailInterceptor> ThumbnailPublisher::CreateInterceptor()
return http::svr::NextHandler::DoNotCall;
}

response->SetHeader("Content-Type", (media_codec_id == cmn::MediaCodecId::Jpeg) ? "image/jpeg" : "image/png");
response->SetHeader("Content-Type", MimeTypeFromMediaCodecId(media_codec_id));
response->SetStatusCode(http::StatusCode::OK);
response->AppendData(std::move(endcoded_video_frame->Clone()));
auto sent_size = response->Response();
Expand All @@ -402,5 +406,19 @@ std::shared_ptr<ThumbnailInterceptor> ThumbnailPublisher::CreateInterceptor()
});

return http_interceptor;
}
}

ov::String ThumbnailPublisher::MimeTypeFromMediaCodecId(const cmn::MediaCodecId &type)
{
switch (type)
{
case cmn::MediaCodecId::Jpeg:
return "image/jpeg";
case cmn::MediaCodecId::Png:
return "image/png";
case cmn::MediaCodecId::Webp:
return "image/webp";
default:
return "application/octet-stream";
}
}
2 changes: 2 additions & 0 deletions src/projects/publishers/thumbnail/thumbnail_publisher.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class ThumbnailPublisher : public pub::Publisher
std::shared_ptr<pub::Application> OnCreatePublisherApplication(const info::Application &application_info) override;
bool OnDeletePublisherApplication(const std::shared_ptr<pub::Application> &application) override;

static ov::String MimeTypeFromMediaCodecId(const cmn::MediaCodecId &type);

private:
std::shared_ptr<ThumbnailInterceptor> CreateInterceptor();

Expand Down
9 changes: 7 additions & 2 deletions src/projects/publishers/thumbnail/thumbnail_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ bool ThumbnailStream::Start()
return false;
}

// Check if there is a supported codec
bool found = false;
for (const auto &[id, track] : _tracks)
{
if ((track->GetCodecId() == cmn::MediaCodecId::Png || track->GetCodecId() == cmn::MediaCodecId::Jpeg))
if ((track->GetCodecId() == cmn::MediaCodecId::Png ||
track->GetCodecId() == cmn::MediaCodecId::Jpeg ||
track->GetCodecId() == cmn::MediaCodecId::Webp))
{
found = true;
break;
Expand Down Expand Up @@ -75,7 +78,9 @@ void ThumbnailStream::SendVideoFrame(const std::shared_ptr<MediaPacket> &media_p
return;
}

if (!(track->GetCodecId() == cmn::MediaCodecId::Png || track->GetCodecId() == cmn::MediaCodecId::Jpeg))
if (!(track->GetCodecId() == cmn::MediaCodecId::Png ||
track->GetCodecId() == cmn::MediaCodecId::Jpeg ||
track->GetCodecId() == cmn::MediaCodecId::Webp))
{
// Could not support codec for image
return;
Expand Down
2 changes: 1 addition & 1 deletion src/projects/transcoder/codec/encoder/encoder_jpeg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bool EncoderJPEG::SetCodecParams()
_codec_context->color_range = AVCOL_RANGE_JPEG;
_codec_context->strict_std_compliance = FF_COMPLIANCE_STRICT;

_bitstream_format = cmn::BitstreamFormat::JPEG;
_bitstream_format = GetBitstreamFormat();

_packet_type = cmn::PacketType::RAW;

Expand Down
2 changes: 1 addition & 1 deletion src/projects/transcoder/codec/encoder/encoder_png.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ bool EncoderPNG::SetCodecParams()
// Set the compression level
_codec_context->compression_level = 1;

_bitstream_format = cmn::BitstreamFormat::PNG;
_bitstream_format = GetBitstreamFormat();

_packet_type = cmn::PacketType::RAW;

Expand Down
Loading

0 comments on commit 26dbba7

Please sign in to comment.