generic: make it parse ogg files
[platform/upstream/lightmediascanner.git] / src / plugins / generic / generic.c
index a7bd7e1..387c02f 100644 (file)
@@ -49,16 +49,20 @@ static const struct lms_string_size _exts[] = {
     LMS_STATIC_STRING_SIZE(".m3u"),
     LMS_STATIC_STRING_SIZE(".mp4"),
     LMS_STATIC_STRING_SIZE(".wma"),
+    LMS_STATIC_STRING_SIZE(".ogg"),
 };
 
 DECL_STR(_codec_mpeg1layer3, "mpeg1layer3");
 DECL_STR(_container_3gp, "3gp");
 DECL_STR(_container_mp4, "mp4");
+DECL_STR(_container_ogg, "ogg");
 
 DECL_STR(_container_audio_wmav1, "wmav1");
 DECL_STR(_container_audio_wmav2, "wmav2");
 DECL_STR(_container_audio_wmavpro, "wmavpro");
 
+DECL_STR(_codec_video_theora, "theora");
+DECL_STR(_codec_audio_vorbis, "vorbis");
 DECL_STR(_codec_audio_asf, "asf");
 DECL_STR(_codec_audio_mpeg4aac_main, "mpeg4aac-main");
 DECL_STR(_codec_audio_mpeg4aac_lc, "mpeg4aac-lc");
@@ -85,6 +89,8 @@ static const struct codec_container_descriptor _codec_list[] = {
     {AV_CODEC_ID_WMAV1, &_codec_audio_asf},
     {AV_CODEC_ID_WMAV2, &_codec_audio_asf},
     {AV_CODEC_ID_WMAPRO, &_codec_audio_asf},
+    {AV_CODEC_ID_VORBIS, &_codec_audio_vorbis},
+    {AV_CODEC_ID_THEORA, &_codec_video_theora},
 };
 
 static const struct codec_container_descriptor _container_list[] = {
@@ -94,6 +100,8 @@ static const struct codec_container_descriptor _container_list[] = {
     {AV_CODEC_ID_WMAV2, &_container_audio_wmav2},
     {AV_CODEC_ID_WMAPRO, &_container_audio_wmavpro},
     {AV_CODEC_ID_H264, &_container_mp4},
+    {AV_CODEC_ID_VORBIS, &_container_ogg},
+    {AV_CODEC_ID_THEORA, &_container_ogg},
 };
 
 static void
@@ -163,7 +171,7 @@ _mp4_get_video_codec(AVStream *stream, struct lms_string_size *value)
     else
         snprintf(str_level, sizeof(str_level), "%u.%u", level / 10, level % 10);
 
-    ret.len = snprintf(buf, sizeof(buf), "h264-%s-l%s", str_profile, str_level);
+    ret.len = snprintf(buf, sizeof(buf), "h264-p%s-l%s", str_profile, str_level);
     ret.str = buf;
 
     lms_string_size_dup(value, &ret);
@@ -172,11 +180,12 @@ _mp4_get_video_codec(AVStream *stream, struct lms_string_size *value)
 static void
 _mpeg2_get_video_codec(AVStream *stream, struct lms_string_size *value)
 {
-    const char *codec_name, *str_profile, *str_level;
+    const char *str_profile, *str_level;
+    const AVCodecDescriptor *codec;
     char buf[256];
 
-    codec_name = avcodec_get_name(stream->codec->codec_id);
-    if (!codec_name) return;
+    codec = avcodec_descriptor_get(stream->codec->codec_id);
+    if (!codec || !codec->name) return;
 
     str_profile = NULL;
     str_level = NULL;
@@ -204,7 +213,8 @@ _mpeg2_get_video_codec(AVStream *stream, struct lms_string_size *value)
         break;
     }
 
-    snprintf(buf, sizeof(buf), "%s-p%s-l%s", codec_name, str_profile, str_level);
+    snprintf(buf, sizeof(buf), "%s-p%s-l%s", codec->name, str_profile,
+             str_level);
     lms_string_size_strndup(value, buf, -1);
 }
 
@@ -245,6 +255,16 @@ static const struct codec_container _codecs[] = {
         .get_container = NULL,
     },
     {
+        .id = AV_CODEC_ID_VORBIS,
+        .get_codec = _get_common_codec,
+        .get_container = _get_common_container,
+    },
+    {
+        .id = AV_CODEC_ID_THEORA,
+        .get_codec = _get_common_codec,
+        .get_container = _get_common_container,
+    },
+    {
         .id = AV_CODEC_ID_AAC,
         .get_codec = _mp4_get_audio_codec,
         .get_container = _get_common_container,
@@ -379,7 +399,11 @@ _parse_audio_stream(AVFormatContext *fmt_ctx, struct lms_audio_info *info, AVStr
     AVCodecContext *ctx = stream->codec;
 
     info->bitrate = ctx->bit_rate;
-    info->channels = av_get_channel_layout_nb_channels(ctx->channel_layout);
+    info->channels = ctx->channels;
+
+    if (!info->channels)
+        info->channels = av_get_channel_layout_nb_channels(ctx->channel_layout);
+
     info->sampling_rate = ctx->sample_rate;
     info->length = _get_stream_duration(fmt_ctx);
 
@@ -437,6 +461,9 @@ _parse(struct plugin *plugin, struct lms_context *ctxt, const struct lms_file_in
     struct lms_string_size container = { };
     bool video = false;
 
+    if (finfo->parsed)
+        return 0;
+
     if ((ret = avformat_open_input(&fmt_ctx, finfo->path, NULL, NULL)))
         return ret;