From 219b6a15c44d5eeb876f6e12358c86d1fbb73fab Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Fri, 22 Jul 2011 12:42:46 +0200 Subject: [PATCH] core: Refactor audio transcoders Share a common base class and simplify transcoder code. https://bugzilla.gnome.org/show_bug.cgi?id=661891 --- src/rygel/Makefile.am | 1 + src/rygel/rygel-aac-transcoder.vala | 72 +++------------------ src/rygel/rygel-audio-transcoder.vala | 114 ++++++++++++++++++++++++++++++++++ src/rygel/rygel-l16-transcoder.vala | 36 +++++------ src/rygel/rygel-mp3-transcoder.vala | 46 +++----------- 5 files changed, 147 insertions(+), 122 deletions(-) create mode 100644 src/rygel/rygel-audio-transcoder.vala diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am index 0308b71..05872f7 100644 --- a/src/rygel/Makefile.am +++ b/src/rygel/Makefile.am @@ -95,6 +95,7 @@ VAPI_SOURCE_FILES = \ rygel-logical-expression.vala \ rygel-search-criteria-parser.vala \ rygel-transcoder.vala \ + rygel-audio-transcoder.vala \ rygel-mp2ts-transcoder.vala \ rygel-mp3-transcoder.vala \ rygel-l16-transcoder.vala \ diff --git a/src/rygel/rygel-aac-transcoder.vala b/src/rygel/rygel-aac-transcoder.vala index 5dfd878..805ad18 100644 --- a/src/rygel/rygel-aac-transcoder.vala +++ b/src/rygel/rygel-aac-transcoder.vala @@ -19,74 +19,20 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -using Gst; -using GUPnP; -using Gee; - -internal enum Rygel.AACProfile { - SD = 0, - HD -} /** - * Transcoder for aac stream containing mpeg 4 audio. + * Transcoder for 3GP stream containing MPEG4 audio (AAC). */ -internal class Rygel.AACTranscoder : Rygel.Transcoder { +internal class Rygel.AACTranscoder : Rygel.AudioTranscoder { private const int BITRATE = 256; + private const string CONTAINER = "application/x-3gp,profile=basic"; + private const string CODEC = "audio/mpeg,mpegversion=4," + + "framed=true,stream-format=raw," + + //"level=2," + + "profile=lc,codec_data=1208,rate=44100," + + "channels=1"; public AACTranscoder () { - base ("audio/3gpp", "AAC_ISO_320", AudioItem.UPNP_CLASS); - } - - public override DIDLLiteResource? add_resource (DIDLLiteItem didl_item, - MediaItem item, - TranscodeManager manager) - throws Error { - var resource = base.add_resource (didl_item, item, manager); - if (resource == null) { - return null; - } - - resource.bitrate = (BITRATE * 1000) / 8; - - return resource; - } - - public override uint get_distance (MediaItem item) { - if (!(item is AudioItem) || item is VideoItem) { - return uint.MAX; - } - - var audio_item = item as AudioItem; - var distance = uint.MIN; - - if (audio_item.bitrate > 0) { - distance += (audio_item.bitrate - BITRATE).abs (); - } - - return distance; - } - - protected override EncodingProfile get_encoding_profile () { - var container_format = Caps.from_string ("application/x-3gp,profile=basic"); - var audio_format = Caps.from_string ("audio/mpeg," + - "mpegversion=4," + - "framed=true," + - "stream-format=raw," + - /* "level=2," + */ - "profile=lc," + - "codec_data=1208,rate=44100,channels=1"); - var enc_container_profile = new EncodingContainerProfile ("container", - null, - container_format, - null); - var enc_audio_profile = new EncodingAudioProfile (audio_format, - null, - null, - 1); - - enc_container_profile.add_profile (enc_audio_profile); - - return enc_container_profile; + base ("audio/3gpp", "AAC_ISO_320", BITRATE, CONTAINER, CODEC); } } diff --git a/src/rygel/rygel-audio-transcoder.vala b/src/rygel/rygel-audio-transcoder.vala new file mode 100644 index 0000000..6a299b2 --- /dev/null +++ b/src/rygel/rygel-audio-transcoder.vala @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2011 Nokia Corporation. + * + * Author: Jens Georg + * + * This file is part of Rygel. + * + * Rygel is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rygel is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +using Gst; +using GUPnP; + +/** + * Base class for all transcoders that handle audio. + */ +internal class Rygel.AudioTranscoder : Rygel.Transcoder { + protected int audio_bitrate; + protected Caps container_format = null; + protected Caps audio_codec_format = null; + + public const string NO_CONTAINER = null; + + public AudioTranscoder (string content_type, + string dlna_profile, + int audio_bitrate, + string? container_caps, + string audio_codec_caps) { + base (content_type, dlna_profile, AudioItem.UPNP_CLASS); + + this.audio_bitrate = audio_bitrate; + if (container_caps != null) { + this.container_format = Caps.from_string (container_caps); + } + + this.audio_codec_format = Caps.from_string (audio_codec_caps); + } + + public AudioTranscoder.with_class (string content_type, + string dlna_profile, + string upnp_class, + int audio_bitrate, + string? container_caps, + string audio_codec_caps) { + base (content_type, dlna_profile, upnp_class); + + this.audio_bitrate = audio_bitrate; + if (container_caps != null) { + this.container_format = Caps.from_string (container_caps); + } + + this.audio_codec_format = Caps.from_string (audio_codec_caps); + } + + + public override DIDLLiteResource? add_resource (DIDLLiteItem didl_item, + MediaItem item, + TranscodeManager manager) + throws Error { + var resource = base.add_resource (didl_item, item, manager); + if (resource == null) { + return null; + } + + resource.bitrate = (this.audio_bitrate * 1000) / 8; + + return resource; + } + + public override uint get_distance (MediaItem item) { + if (!(item is AudioItem) || item is VideoItem) { + return uint.MAX; + } + + var audio_item = item as AudioItem; + var distance = uint.MIN; + + if (audio_item.bitrate > 0) { + distance += (audio_item.bitrate - this.audio_bitrate).abs (); + } + + return distance; + } + + protected override EncodingProfile get_encoding_profile () { + var enc_audio_profile = new EncodingAudioProfile (audio_codec_format, + null, + null, + 1); + + if (this.container_format != null) { + var enc_container_profile = new EncodingContainerProfile ("container", + null, + container_format, + null); + enc_container_profile.add_profile (enc_audio_profile); + + return enc_container_profile; + } + + return enc_audio_profile; + } +} diff --git a/src/rygel/rygel-l16-transcoder.vala b/src/rygel/rygel-l16-transcoder.vala index 9dcf8d5..e9e0c77 100644 --- a/src/rygel/rygel-l16-transcoder.vala +++ b/src/rygel/rygel-l16-transcoder.vala @@ -27,7 +27,7 @@ using Gee; /** * Transcoder for linear PCM audio (LPCM). */ -internal class Rygel.L16Transcoder : Rygel.Transcoder { +internal class Rygel.L16Transcoder : Rygel.AudioTranscoder { private const int CHANNELS = 2; private const int FREQUENCY = 44100; private const int WIDTH = 16; @@ -40,7 +40,19 @@ internal class Rygel.L16Transcoder : Rygel.Transcoder { ";rate=" + L16Transcoder.FREQUENCY.to_string () + ";channels=" + L16Transcoder.CHANNELS.to_string (); - base (mime_type, "LPCM", AudioItem.UPNP_CLASS); + var caps_str = "audio/x-raw-int" + + ",channels=" + CHANNELS.to_string () + + ",rate=" + FREQUENCY.to_string () + + ",width=" + WIDTH.to_string () + + ",depth=" + DEPTH.to_string () + + ",signed=" + SIGNED.to_string () + + ",endianness=" + ENDIANNESS.to_string(); + + base (mime_type, + "LPCM", + 0, + AudioTranscoder.NO_CONTAINER, + caps_str); } public override DIDLLiteResource? add_resource (DIDLLiteItem didl_item, @@ -48,8 +60,9 @@ internal class Rygel.L16Transcoder : Rygel.Transcoder { TranscodeManager manager) throws Error { var resource = base.add_resource (didl_item, item, manager); - if (resource == null) + if (resource == null) { return null; + } resource.sample_freq = L16Transcoder.FREQUENCY; resource.audio_channels = L16Transcoder.CHANNELS; @@ -84,21 +97,4 @@ internal class Rygel.L16Transcoder : Rygel.Transcoder { return distance; } - - protected override EncodingProfile get_encoding_profile () { - var caps_str = "audio/x-raw-int" + - ",channels=" + CHANNELS.to_string () + - ",rate=" + FREQUENCY.to_string () + - ",width=" + WIDTH.to_string () + - ",depth=" + DEPTH.to_string () + - ",signed=" + SIGNED.to_string () + - ",endianness=" + ENDIANNESS.to_string(); - var format = Caps.from_string (caps_str); - - var encoding_profile = new EncodingAudioProfile (format, - null, - null, - 1); - return encoding_profile; - } } diff --git a/src/rygel/rygel-mp3-transcoder.vala b/src/rygel/rygel-mp3-transcoder.vala index d72daf9..6eb7206 100644 --- a/src/rygel/rygel-mp3-transcoder.vala +++ b/src/rygel/rygel-mp3-transcoder.vala @@ -27,47 +27,15 @@ using Gee; /** * Transcoder for mpeg 1 layer 3 audio. */ -internal class Rygel.MP3Transcoder : Rygel.Transcoder { +internal class Rygel.MP3Transcoder : Rygel.AudioTranscoder { public const int BITRATE = 256; + private const string FORMAT = "audio/mpeg,mpegversion=1,layer=3"; public MP3Transcoder () { - base ("audio/mpeg", "MP3", AudioItem.UPNP_CLASS); - } - - public override DIDLLiteResource? add_resource (DIDLLiteItem didl_item, - MediaItem item, - TranscodeManager manager) - throws Error { - var resource = base.add_resource (didl_item, item, manager); - if (resource == null) - return null; - - // Convert bitrate to bytes/second - resource.bitrate = BITRATE * 1000 / 8; - - return resource; - } - - public override uint get_distance (MediaItem item) { - if (!(item is AudioItem) || item is VideoItem) { - return uint.MAX; - } - - var audio_item = item as AudioItem; - var distance = uint.MIN; - - if (audio_item.bitrate > 0) { - distance += (audio_item.bitrate - BITRATE).abs (); - } - - return distance; - } - - protected override EncodingProfile get_encoding_profile () { - var format = Caps.from_string ("audio/mpeg,mpegversion=1,layer=3"); - // FIXME: We should use the preset to set bitrate - var encoding_profile = new EncodingAudioProfile (format, null, null, 1); - - return encoding_profile; + base ("audio/mpeg", + "MP3", + BITRATE, + AudioTranscoder.NO_CONTAINER, + FORMAT); } } -- 2.7.4